/* Description This is a simple test program used to test fix for BUG 3797. Requirements/Test Environment XP MySQL v4.0.20a MyODBC v3.51 (post v3.51.08 bk ver used) Enjoy Peter Harvey 12.JUL.04 */ #include #include #include #include #include #include #define MAX_STR_LEN 1024 #define MAX_DATA_LEN 1024 SQLHENV hEnv = SQL_NULL_HENV; SQLHDBC hDbc = SQL_NULL_HDBC; SQLCHAR * szConnStrIn = "DRIVER=MySQL ODBC 3.51 Driver;SERVER=localhost;DATABASE=test;"; void do_errors( SQLRETURN nReturn, SQLSMALLINT nHandleType, SQLHANDLE h ) { if ( h ) { SQLSMALLINT nRec = 1; SQLCHAR szSQLState[6]; SQLINTEGER nNative; SQLCHAR szMessage[MAX_STR_LEN]; SQLSMALLINT nMessage; *szSQLState = '\0'; *szMessage = '\0'; while ( SQL_SUCCEEDED( SQLGetDiagRec( nHandleType, h, nRec, szSQLState, &nNative, szMessage, MAX_STR_LEN, &nMessage ) ) ) { szSQLState[5] = '\0'; szMessage[MAX_STR_LEN - 1] = '\0'; fprintf( stderr, "[%s] %d %s\n", szSQLState, nNative, szMessage ); nRec++; *szSQLState = '\0'; *szMessage = '\0'; } } if ( !SQL_SUCCEEDED( nReturn ) ) assert( "test failed" ); } void do_init() { SQLRETURN nReturn; SQLCHAR szConnStrOut[MAX_STR_LEN]; SQLSMALLINT nConnStrOut; nReturn = SQLAllocHandle( SQL_HANDLE_ENV, SQL_NULL_HENV, &hEnv ); do_errors( nReturn, SQL_HANDLE_ENV, hEnv ); nReturn = SQLSetEnvAttr( hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0 ); do_errors( nReturn, SQL_HANDLE_ENV, hEnv ); nReturn = SQLAllocHandle( SQL_HANDLE_DBC, hEnv, &hDbc ); do_errors( nReturn, SQL_HANDLE_ENV, hEnv ); nReturn = SQLDriverConnect( hDbc, NULL, szConnStrIn, MAX_STR_LEN, szConnStrOut, MAX_STR_LEN, &nConnStrOut, SQL_DRIVER_NOPROMPT ); do_errors( nReturn, SQL_HANDLE_DBC, hDbc ); nReturn = SQLSetConnectAttr( hDbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER)SQL_AUTOCOMMIT_ON, 0 ); do_errors( nReturn, SQL_HANDLE_DBC, hDbc ); } void do_fini() { SQLRETURN nReturn; nReturn = SQLDisconnect( hDbc ); do_errors( nReturn, SQL_HANDLE_DBC, hDbc ); if ( hDbc ) { nReturn = SQLFreeHandle( SQL_HANDLE_DBC, hDbc ); hDbc = SQL_NULL_HDBC; } if ( hEnv ) { nReturn = SQLFreeHandle( SQL_HANDLE_ENV, hEnv ); hEnv = SQL_NULL_HENV; } } void do_create() { SQLHSTMT hStmt; SQLRETURN nReturn; nReturn = SQLAllocHandle( SQL_HANDLE_STMT, hDbc, &hStmt ); do_errors( nReturn, SQL_HANDLE_DBC, hDbc ); nReturn = SQLExecDirect( hStmt, "CREATE TABLE IF NOT EXISTS tb3797 (nID int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, vcName VARCHAR(50))", SQL_NTS ); do_errors( nReturn, SQL_HANDLE_STMT, hStmt ); nReturn = SQLFreeHandle( SQL_HANDLE_STMT, hStmt ); } void do_describecol( SQLHSTMT hStmt, SQLUSMALLINT nCol ) { SQLRETURN nReturn; SQLCHAR szColumnName[MAX_STR_LEN]; SQLSMALLINT nBufferLength = MAX_STR_LEN - 1; SQLSMALLINT nNameLength; SQLSMALLINT nDataType; SQLUINTEGER nColumnSize; SQLSMALLINT nDecimalDigits; SQLSMALLINT bNullable; nReturn = SQLDescribeCol( hStmt, nCol, szColumnName, nBufferLength, &nNameLength, &nDataType, &nColumnSize, &nDecimalDigits, &bNullable ); do_errors( nReturn, SQL_HANDLE_STMT, hStmt ); } void do_columns() { SQLRETURN nReturn; SQLHSTMT hStmt; SQLSMALLINT nCols; SQLSMALLINT nCol; /* Declare buffers for result set data */ SQLCHAR szCatalog[MAX_STR_LEN], szSchema[MAX_STR_LEN]; SQLCHAR szTableName[MAX_STR_LEN], szColumnName[MAX_STR_LEN]; SQLCHAR szTypeName[MAX_STR_LEN], szRemarks[MAX_STR_LEN]; SQLCHAR szColumnDefault[MAX_STR_LEN], szIsNullable[MAX_STR_LEN]; SQLINTEGER ColumnSize, BufferLength, CharOctetLength, OrdinalPosition; SQLSMALLINT DataType, DecimalDigits, NumPrecRadix, Nullable; SQLSMALLINT SQLDataType, DatetimeSubtypeCode; /* Declare buffers for bytes available to return */ SQLINTEGER cbCatalog, cbSchema, cbTableName, cbColumnName; SQLINTEGER cbDataType, cbTypeName, cbColumnSize, cbBufferLength; SQLINTEGER cbDecimalDigits, cbNumPrecRadix, cbNullable, cbRemarks; SQLINTEGER cbColumnDefault, cbSQLDataType, cbDatetimeSubtypeCode, cbCharOctetLength; SQLINTEGER cbOrdinalPosition, cbIsNullable; printf("COLUMNS:\n"); nReturn = SQLAllocHandle( SQL_HANDLE_STMT, hDbc, &hStmt ); do_errors( nReturn, SQL_HANDLE_DBC, hDbc ); nReturn = SQLColumns(hStmt, NULL, 0, /* All catalogs */ NULL, 0, /* All schemas */ "tb3797", SQL_NTS, /* table */ NULL, 0); /* All columns */ do_errors( nReturn, SQL_HANDLE_STMT, hStmt ); /* Bind columns in result set to buffers */ SQLBindCol(hStmt, 1, SQL_C_CHAR, szCatalog, MAX_STR_LEN,&cbCatalog); SQLBindCol(hStmt, 2, SQL_C_CHAR, szSchema, MAX_STR_LEN, &cbSchema); SQLBindCol(hStmt, 3, SQL_C_CHAR, szTableName, MAX_STR_LEN,&cbTableName); SQLBindCol(hStmt, 4, SQL_C_CHAR, szColumnName, MAX_STR_LEN, &cbColumnName); SQLBindCol(hStmt, 5, SQL_C_SSHORT, &DataType, 0, &cbDataType); SQLBindCol(hStmt, 6, SQL_C_CHAR, szTypeName, MAX_STR_LEN, &cbTypeName); SQLBindCol(hStmt, 7, SQL_C_SLONG, &ColumnSize, 0, &cbColumnSize); SQLBindCol(hStmt, 8, SQL_C_SLONG, &BufferLength, 0, &cbBufferLength); SQLBindCol(hStmt, 9, SQL_C_SSHORT, &DecimalDigits, 0, &cbDecimalDigits); SQLBindCol(hStmt, 10, SQL_C_SSHORT, &NumPrecRadix, 0, &cbNumPrecRadix); SQLBindCol(hStmt, 11, SQL_C_SSHORT, &Nullable, 0, &cbNullable); SQLBindCol(hStmt, 12, SQL_C_CHAR, szRemarks, MAX_STR_LEN, &cbRemarks); SQLBindCol(hStmt, 13, SQL_C_CHAR, szColumnDefault, MAX_STR_LEN, &cbColumnDefault); SQLBindCol(hStmt, 14, SQL_C_SSHORT, &SQLDataType, 0, &cbSQLDataType); SQLBindCol(hStmt, 15, SQL_C_SSHORT, &DatetimeSubtypeCode, 0, &cbDatetimeSubtypeCode); SQLBindCol(hStmt, 16, SQL_C_SLONG, &CharOctetLength, 0, &cbCharOctetLength); SQLBindCol(hStmt, 17, SQL_C_SLONG, &OrdinalPosition, 0, &cbOrdinalPosition); SQLBindCol(hStmt, 18, SQL_C_CHAR, szIsNullable, MAX_STR_LEN, &cbIsNullable); SQLNumResultCols(hStmt, &nCols); for ( nCol = 1; nCol <= nCols; nCol++ ) { do_describecol( hStmt, nCol ); } while ( TRUE ) { nReturn = SQLFetchScroll(hStmt, SQL_FETCH_NEXT, 0); if ( nReturn == SQL_NO_DATA ) break; do_errors( nReturn, SQL_HANDLE_STMT, hStmt ); printf("%s\n", szColumnName); } nReturn = SQLFreeHandle( SQL_HANDLE_STMT, hStmt ); do_errors( nReturn, SQL_HANDLE_STMT, hStmt ); } void do_primarykeys() { SQLRETURN nReturn; SQLHSTMT hStmt; SQLSMALLINT nCols; SQLSMALLINT nCol; /* Declare buffers for result set data */ SQLCHAR szColumnName[MAX_STR_LEN]; /* Declare buffers for bytes available to return */ SQLINTEGER cbColumnName; printf("PRIMARY KEYS:\n"); nReturn = SQLAllocHandle( SQL_HANDLE_STMT, hDbc, &hStmt ); do_errors( nReturn, SQL_HANDLE_DBC, hDbc ); nReturn = SQLPrimaryKeys(hStmt, NULL, 0, /* All catalogs */ NULL, 0, /* All schemas */ "tb3797", SQL_NTS); /* table */ do_errors( nReturn, SQL_HANDLE_STMT, hStmt ); /* Bind columns in result set to buffers */ SQLBindCol(hStmt, 4, SQL_C_CHAR, szColumnName, MAX_STR_LEN, &cbColumnName); SQLNumResultCols(hStmt, &nCols); for ( nCol = 1; nCol <= nCols; nCol++ ) { do_describecol( hStmt, nCol ); } while ( TRUE ) { nReturn = SQLFetchScroll(hStmt, SQL_FETCH_NEXT, 0); if ( nReturn == SQL_NO_DATA ) break; do_errors( nReturn, SQL_HANDLE_STMT, hStmt ); printf("%s\n", szColumnName); } nReturn = SQLFreeHandle( SQL_HANDLE_STMT, hStmt ); do_errors( nReturn, SQL_HANDLE_STMT, hStmt ); } int main(int argc, char **argv){ do_init(); do_create(); do_primarykeys(); do_columns(); do_fini(); }