Index: driver/utility.c
===================================================================
--- driver/utility.c (revision 161)
+++ driver/utility.c (working copy)
@@ -757,7 +757,7 @@
case SQL_C_LONG:
case SQL_C_SLONG:
case SQL_C_ULONG:
- return sizeof(long);
+ return sizeof(SQLINTEGER);
case SQL_C_FLOAT:
return sizeof(float);
case SQL_C_DOUBLE:
Index: driver/cursor.c
===================================================================
--- driver/cursor.c (revision 161)
+++ driver/cursor.c (working copy)
@@ -615,83 +615,108 @@
/*
@type : myodbc3 internal
- @purpose : copies all resultset column data to where clause
+ @purpose : generate a WHERE clause based on the fields in the result set
*/
-static SQLRETURN insert_fields( STMT FAR * stmt,
- DYNAMIC_STRING *dynQuery )
+static SQLRETURN append_all_fields(STMT FAR *stmt,
+ DYNAMIC_STRING *dynQuery)
{
- MYSQL_RES * result = stmt->result;
- MYSQL_FIELD * field;
- SQLUSMALLINT ncol;
- MYSQL_RES * presultAllColumns;
- char select[NAME_LEN+15];
+ MYSQL_RES *result= stmt->result;
+ MYSQL_RES *presultAllColumns;
+ char select[NAME_LEN+30];
+ int i, j;
- /* get base table name - fails if we have more than one */
- if ( !( find_used_table( stmt ) ) )
- return ( SQL_ERROR );
+ MYODBCDbgEnter;
- /* get a list of all table cols using "SELECT & LIMIT 0" method */
- strxmov( select, "SELECT * FROM `", stmt->table_name, "` LIMIT 0", NullS );
- MYLOG_QUERY( stmt, select );
- pthread_mutex_lock( &stmt->dbc->lock );
- if ( ( mysql_query( &stmt->dbc->mysql, select ) || !( presultAllColumns = mysql_store_result( &stmt->dbc->mysql ) ) ) )
- {
- set_error( stmt, MYERR_S1000, mysql_error( &stmt->dbc->mysql ), mysql_errno( &stmt->dbc->mysql ) );
- pthread_mutex_unlock( &stmt->dbc->lock );
- return ( SQL_ERROR );
- }
- pthread_mutex_unlock( &stmt->dbc->lock );
+ /*
+ Get the base table name. If there was more than one table underlying
+ the result set, this will fail, and we couldn't build a suitable
+ list of fields.
+ */
+ if (!(find_used_table(stmt)))
+ MYODBCDbgReturn(SQL_ERROR);
+ /*
+ Get the list of all of the columns of the underlying table by using
+ SELECT * FROM
LIMIT 0.
+ */
+ strxmov(select, "SELECT * FROM `", stmt->table_name, "` LIMIT 0", NullS);
+ MYLOG_QUERY(stmt, select);
+ pthread_mutex_lock(&stmt->dbc->lock);
+ if (mysql_query(&stmt->dbc->mysql, select) ||
+ !(presultAllColumns= mysql_store_result(&stmt->dbc->mysql)))
+ {
+ set_error(stmt, MYERR_S1000, mysql_error(&stmt->dbc->mysql),
+ mysql_errno(&stmt->dbc->mysql));
+ pthread_mutex_unlock(&stmt->dbc->lock);
+ MYODBCDbgReturn(SQL_ERROR);
+ }
+ pthread_mutex_unlock(&stmt->dbc->lock);
+
+ /*
+ If the number of fields in the underlying table is not the same as
+ our result set, we bail out -- we need them all!
+ */
+ if (presultAllColumns->field_count != result->field_count)
+ {
+ mysql_free_result(presultAllColumns);
+ MYODBCDbgReturn(SQL_ERROR);
+ }
+
+ /*
+ Now we walk through the list of columns in the underlying table,
+ appending them to the query along with the value from the row at the
+ current cursor position.
+ */
+ for (i= 0; i < presultAllColumns->field_count; i++)
+ {
+ MYSQL_FIELD *table_field= presultAllColumns->fields + i;
+
/*
- If current result set field count is not the total
- count from the actual table, then use the temp result
- to have a search condition from all table fields ..
-
- This can be buggy, if multiple times the same
- column is used in the select ..rare case ..
+ We also can't handle floating-point fields because their comparison
+ is inexact.
*/
-/* printf( "\n[PAH][%s][%d]\n", __FILE__, __LINE__ ); */
- if ( presultAllColumns->row_count != result->row_count && !if_dynamic_cursor(stmt) )
+ if (if_float_field(stmt, table_field))
{
-/* printf( "\n[PAH][%s][%d]\n", __FILE__, __LINE__ ); */
- mysql_free_result(presultAllColumns);
- presultAllColumns= 0;
+ MYODBCDbgInfo("field '%s' is a floating-point field",
+ table_field->name);
+ mysql_free_result(presultAllColumns);
+ MYODBCDbgReturn(SQL_ERROR);
}
- else if ( presultAllColumns->field_count != result->field_count ||
- !result->data_cursor ||
- (if_dynamic_cursor(stmt) &&
- presultAllColumns->row_count != result->row_count) )
+
+ for (j= 0; j < result->field_count; j++)
{
- for ( ncol= 0; ncol < (SQLUSMALLINT)stmt->current_row; ncol++ )
+ MYSQL_FIELD *cursor_field= result->fields + j;
+ if (cursor_field->org_name &&
+ !strcmp(cursor_field->org_name, table_field->name))
+ {
+ dynstr_append_quoted_name(dynQuery, table_field->name);
+ dynstr_append_mem(dynQuery, "=", 1);
+ if (insert_field(stmt, result, dynQuery, j))
{
-/* printf( "\n[PAH][%s][%d] Column %d of %d\n", __FILE__, __LINE__, ncol, stmt->current_row ); */
- presultAllColumns->data_cursor = presultAllColumns->data_cursor->next;
+ MYODBCDbgInfo("failed to append value for '%s'", table_field->name);
+ mysql_free_result(presultAllColumns);
+ MYODBCDbgReturn(SQL_ERROR);
}
- result = presultAllColumns;
+ j= -1;
+ break;
+ }
}
-/* printf( "\n[PAH][%s][%d]\n", __FILE__, __LINE__ ); */
- pthread_mutex_lock( &stmt->dbc->lock );
- /* Copy all row buffers to query search clause */
- for ( ncol = 0; ncol < result->field_count; ncol++ )
+ /*
+ If we didn't find the field, we have failed.
+ */
+ if (j > 0)
{
- field = result->fields + ncol;
- dynstr_append_quoted_name( dynQuery, field->name );
- dynstr_append_mem( dynQuery, "=", 1 );
-
- if ( if_float_field( stmt, field ) || insert_field( stmt, result, dynQuery, ncol ) )
- {
- mysql_free_result( presultAllColumns );
- pthread_mutex_unlock( &stmt->dbc->lock );
- return ( SQL_ERROR );
- }
+ MYODBCDbgInfo("could not find field '%s' in result set",
+ table_field->name);
+ mysql_free_result(presultAllColumns);
+ MYODBCDbgReturn(SQL_ERROR);
}
+ }
- mysql_free_result( presultAllColumns );
- pthread_mutex_unlock( &stmt->dbc->lock );
-
- return( SQL_SUCCESS );
+ mysql_free_result(presultAllColumns);
+ MYODBCDbgReturn(SQL_SUCCESS);
}
/*
@@ -717,9 +742,10 @@
}
else
{
- if ( insert_fields( pStmt, dynQuery ) != SQL_SUCCESS )
+ if ( append_all_fields( pStmt, dynQuery ) != SQL_SUCCESS )
return set_stmt_error( pStmt, "HY000", "Build WHERE -> insert_fields() failed.", 0 );
}
+ /* Remove the trailing ' AND ' */
dynQuery->length -= 5;
/* IF irow = 0 THEN delete all rows in the rowset ELSE specific (as in one) row */
@@ -971,9 +997,7 @@
dynQuery->length= query_length;
/* append our WHERE clause to our DELETE statement */
-/* printf( "\n[PAH][%s][%d] %d\n", __FILE__, __LINE__, rowset_pos ); */
nReturn = build_where_clause( stmt, dynQuery, (SQLUSMALLINT)rowset_pos );
-/* printf( "\n[PAH][%s][%d] (%s)\n", __FILE__, __LINE__, dynQuery ); */
if ( !SQL_SUCCEEDED( nReturn ) )
return nReturn;
Index: test/dyn_cursor/my_dyn_cursor.c
===================================================================
--- test/dyn_cursor/my_dyn_cursor.c (revision 164)
+++ test/dyn_cursor/my_dyn_cursor.c (working copy)
@@ -18,12 +18,11 @@
SQLCHAR *mysock= NULL;
-/********************************************************
-* perform positioned update and delete *
+/******************************************************** perform positioned
+ * update and delete *
*********************************************************/
void my_dynamic_pos_cursor(SQLHDBC hdbc, SQLHSTMT hstmt)
{
-#if BUG_22796_FIXED
SQLRETURN rc;
SQLLEN nRowCount;
SQLHSTMT hstmt_pos;
@@ -149,7 +148,6 @@
SQLFreeStmt(hstmt, SQL_RESET_PARAMS);
SQLFreeStmt(hstmt, SQL_UNBIND);
SQLFreeStmt(hstmt, SQL_CLOSE);
-#endif
}
@@ -310,7 +308,10 @@
*/
void my_setpos_delete_ignore(SQLHDBC hdbc, SQLHSTMT hstmt)
{
-#if BUG_22796_FIXED
+#if ALLOW_CRAZY_TESTS
+ /*
+ This test does not actually test what it claims to test.
+ */
SQLRETURN rc;
SQLLEN nlen;
char szData[255]={0};
@@ -355,11 +356,9 @@
mystmt(hstmt,rc);
strcpy(szData,"mysql2");
-printf( "\n[PAH][%s][%d]\n", __FILE__, __LINE__ );
/* SQL_DELETE all rows by passing row=0 */
rc = SQLSetPos( hstmt, 0, SQL_DELETE, SQL_LOCK_NO_CHANGE );
mystmt( hstmt, rc );
-printf( "\n[PAH][%s][%d]\n", __FILE__, __LINE__ );
rc = SQLRowCount(hstmt,&nlen);
mystmt(hstmt,rc);
@@ -387,7 +386,10 @@
*/
void my_setpos_update_ignore(SQLHDBC hdbc, SQLHSTMT hstmt)
{
-#if BUG_22796_FIXED
+#if ALLOW_CRAZY_TESTS
+ /*
+ This test does not actually test what it claims to test.
+ */
SQLRETURN rc;
SQLLEN nlen;
char szData[255]={0};
@@ -460,7 +462,10 @@
*/
void my_setpos_update_ignore1(SQLHDBC hdbc, SQLHSTMT hstmt)
{
-#if BUG_22796_FIXED
+#if ALLOW_CRAZY_TESTS
+ /*
+ This test does not actually test what it claims to test.
+ */
SQLRETURN rc;
SQLLEN nlen;
char szData[255]={0};
@@ -533,7 +538,6 @@
*/
void my_position(SQLHDBC hdbc, SQLHSTMT hstmt)
{
-#if BUG_22796_FIXED
SQLRETURN rc;
SQLLEN nlen;
char szData[255]={0};
@@ -632,7 +636,6 @@
rc = SQLFreeStmt(hstmt,SQL_CLOSE);
mystmt(hstmt,rc);
-#endif
}
/*
@@ -640,11 +643,10 @@
*/
void my_position1(SQLHDBC hdbc, SQLHSTMT hstmt)
{
-#if BUG_22796_FIXED
SQLRETURN rc;
- SQLLEN nlen[15];
+ SQLINTEGER nData[15];
+ SQLLEN nlen[15]= {0}, nrow[15]= {0};
char szData[15][15]={0};
- long nData[15], nrow[15];
SQLExecDirect(hstmt,"drop table my_position",SQL_NTS);
rc = SQLExecDirect(hstmt,"create table my_position(col1 int, col2 varchar(30))",SQL_NTS);
@@ -693,18 +695,18 @@
rc = SQLExecDirect(hstmt,"select * from my_position",SQL_NTS);
mystmt(hstmt,rc);
- rc = SQLBindCol(hstmt,1,SQL_C_LONG,&nData,0,(long *)&nrow);
+ rc = SQLBindCol(hstmt,1,SQL_C_LONG,&nData,0,nrow);
mystmt(hstmt,rc);
- rc = SQLBindCol(hstmt,2,SQL_C_CHAR,szData,sizeof(szData[0]),(long *)&nlen);
+ rc = SQLBindCol(hstmt,2,SQL_C_CHAR,szData,sizeof(szData[0]),nlen);
mystmt(hstmt,rc);
rc = SQLFetchScroll(hstmt,SQL_FETCH_ABSOLUTE,4);
mystmt(hstmt,rc);
- nData[0] = 888;
+ nData[0] = 888;
nData[1] = 999; nrow[1] = SQL_COLUMN_IGNORE;
- nData[2] = 1000;
+ nData[2] = 1000;
strcpy(szData[0],"updatex"); nlen[0] = 15;
strcpy(szData[1],"updatey"); nlen[1] = 15;
@@ -717,17 +719,17 @@
mystmt(hstmt,rc);
rc = SQLFreeStmt(hstmt,SQL_CLOSE);
- mystmt(hstmt,rc);
+ mystmt(hstmt,rc);
rc = SQLExecDirect(hstmt,"select * from my_position",SQL_NTS);
- mystmt(hstmt,rc);
+ mystmt(hstmt,rc);
rc = SQLFetchScroll(hstmt,SQL_FETCH_ABSOLUTE,4);
mystmt(hstmt,rc);
- printMessage("\n updated data1:%d,%s",nData[0],szData[0]);
- printMessage("\n updated data2:%d,%s",nData[1],szData[1]);
- printMessage("\n updated data3:%d,%s",nData[2],szData[2]);
+ printMessage("updated data1:%d,%s\n",nData[0],szData[0]);
+ printMessage("updated data2:%d,%s\n",nData[1],szData[1]);
+ printMessage("updated data3:%d,%s\n",nData[2],szData[2]);
myassert(nData[0] == 4);myassert(strcmp(szData[0],"MySQL4")== 0);
myassert(nData[1] == 5);myassert(strcmp(szData[1],"updatey")== 0);
myassert(nData[2] == 1000);myassert(strcmp(szData[2],"updatez")== 0);
@@ -740,7 +742,6 @@
rc = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE ,(SQLPOINTER)1 , 0);
mystmt(hstmt, rc);
-#endif
}
/*
@@ -748,11 +749,10 @@
*/
void my_zero_irow_update(SQLHDBC hdbc, SQLHSTMT hstmt)
{
-#if BUG_22796_FIXED
SQLRETURN rc;
- SQLLEN nlen[15];
+ SQLLEN nlen[15]= {0}, nrow[15]= {0};
char szData[15][15]={0};
- long nData[15], nrow[15];
+ SQLINTEGER nData[15];
SQLExecDirect(hstmt,"drop table my_zero_irow",SQL_NTS);
rc = SQLExecDirect(hstmt,"create table my_zero_irow(col1 int, col2 varchar(30))",SQL_NTS);
@@ -789,10 +789,10 @@
rc = SQLExecDirect(hstmt,"select * from my_zero_irow",SQL_NTS);
mystmt(hstmt,rc);
- rc = SQLBindCol(hstmt,1,SQL_C_LONG,&nData,0,(long *)&nrow);
+ rc = SQLBindCol(hstmt,1,SQL_C_LONG,&nData,0,nrow);
mystmt(hstmt,rc);
- rc = SQLBindCol(hstmt,2,SQL_C_CHAR,szData,sizeof(szData[0]),(long *)&nlen);
+ rc = SQLBindCol(hstmt,2,SQL_C_CHAR,szData,sizeof(szData[0]),nlen);
mystmt(hstmt,rc);
rc = SQLFetchScroll(hstmt,SQL_FETCH_ABSOLUTE,2);
@@ -833,18 +833,16 @@
rc = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE ,(SQLPOINTER)1 , 0);
mystmt(hstmt, rc);
-#endif
}
/*
IROW VALUE - 0 - DELETE
*/
void my_zero_irow_delete(SQLHDBC hdbc, SQLHSTMT hstmt)
{
-#if BUG_22796_FIXED
SQLRETURN rc;
- SQLLEN nlen[15];
+ SQLLEN nlen[15]= {0}, nrow[15]= {0};
char szData[15][15]={0};
- long nData[15], nrow[15];
+ SQLINTEGER nData[15];
SQLExecDirect(hstmt,"drop table my_zero_irow",SQL_NTS);
rc = SQLExecDirect(hstmt,"create table my_zero_irow(col1 int, col2 varchar(30))",SQL_NTS);
@@ -881,10 +879,10 @@
rc = SQLExecDirect(hstmt,"select * from my_zero_irow",SQL_NTS);
mystmt(hstmt,rc);
- rc = SQLBindCol(hstmt,1,SQL_C_LONG,&nData,0,&nrow);
+ rc = SQLBindCol(hstmt,1,SQL_C_LONG,&nData,0,nrow);
mystmt(hstmt,rc);
- rc = SQLBindCol(hstmt,2,SQL_C_CHAR,szData,sizeof(szData[0]),(long *)&nlen);
+ rc = SQLBindCol(hstmt,2,SQL_C_CHAR,szData,sizeof(szData[0]),nlen);
mystmt(hstmt,rc);
rc = SQLFetchScroll(hstmt,SQL_FETCH_ABSOLUTE,2);
@@ -920,7 +918,6 @@
rc = SQLSetStmtAttr(hstmt, SQL_ATTR_ROW_ARRAY_SIZE ,(SQLPOINTER)1 , 0);
mystmt(hstmt, rc);
-#endif
}
/**
Index: test/keys/my_keys.c
===================================================================
--- test/keys/my_keys.c (revision 164)
+++ test/keys/my_keys.c (working copy)
@@ -532,6 +532,13 @@
*/
void my_no_keys_all_dups(SQLHDBC hdbc, SQLHSTMT hstmt)
{
+#if ALLOW_CRAZY_TESTS
+
+ /*
+ This test does not make any sense. You can't update a table based
+ on a cursor against one non-primary-key column.
+ */
+
SQLRETURN rc;
SQLLEN rowcount;
long nData;
@@ -624,6 +631,7 @@
SQLFreeStmt(hstmt,SQL_UNBIND);
SQLFreeStmt(hstmt,SQL_CLOSE);
+#endif
}
/*
Initialize the foreignkey tables (MySQL specific)