diff --git a/src/interfaces/odbc/bind.c b/src/interfaces/odbc/bind.c index 906dfdcc9c..469edb6c2c 100644 --- a/src/interfaces/odbc/bind.c +++ b/src/interfaces/odbc/bind.c @@ -33,11 +33,12 @@ #include "sql.h" #include "sqlext.h" #endif +#include "pgapifunc.h" /* Bind parameters on a statement handle */ RETCODE SQL_API -SQLBindParameter( +PGAPI_BindParameter( HSTMT hstmt, UWORD ipar, SWORD fParamType, @@ -50,7 +51,7 @@ SQLBindParameter( SDWORD FAR *pcbValue) { StatementClass *stmt = (StatementClass *) hstmt; - static char *func = "SQLBindParameter"; + static char *func = "PGAPI_BindParameter"; mylog("%s: entering...\n", func); @@ -155,7 +156,7 @@ SQLBindParameter( if (stmt->status == STMT_PREMATURE) SC_recycle_statement(stmt); - mylog("SQLBindParamater: ipar=%d, paramType=%d, fCType=%d, fSqlType=%d, cbColDef=%d, ibScale=%d, rgbValue=%d, *pcbValue = %d, data_at_exec = %d\n", ipar, fParamType, fCType, fSqlType, cbColDef, ibScale, rgbValue, pcbValue ? *pcbValue : -777, stmt->parameters[ipar].data_at_exec); + mylog("PGAPI_BindParamater: ipar=%d, paramType=%d, fCType=%d, fSqlType=%d, cbColDef=%d, ibScale=%d, rgbValue=%d, *pcbValue = %d, data_at_exec = %d\n", ipar, fParamType, fCType, fSqlType, cbColDef, ibScale, rgbValue, pcbValue ? *pcbValue : -777, stmt->parameters[ipar].data_at_exec); return SQL_SUCCESS; } @@ -163,7 +164,7 @@ SQLBindParameter( /* Associate a user-supplied buffer with a database column. */ RETCODE SQL_API -SQLBindCol( +PGAPI_BindCol( HSTMT hstmt, UWORD icol, SWORD fCType, @@ -172,11 +173,12 @@ SQLBindCol( SDWORD FAR *pcbValue) { StatementClass *stmt = (StatementClass *) hstmt; - static char *func = "SQLBindCol"; + static char *func = "PGAPI_BindCol"; mylog("%s: entering...\n", func); - mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol); + mylog("**** PGAPI_BindCol: stmt = %u, icol = %d\n", stmt, icol); +mylog("**** : fCType=%d rgb=%x valusMax=%d pcb=%x\n", fCType, rgbValue, cbValueMax, pcbValue); if (!stmt) { @@ -275,7 +277,7 @@ SQLBindCol( * data type (most likely varchar). */ RETCODE SQL_API -SQLDescribeParam( +PGAPI_DescribeParam( HSTMT hstmt, UWORD ipar, SWORD FAR *pfSqlType, @@ -284,7 +286,7 @@ SQLDescribeParam( SWORD FAR *pfNullable) { StatementClass *stmt = (StatementClass *) hstmt; - static char *func = "SQLDescribeParam"; + static char *func = "PGAPI_DescribeParam"; mylog("%s: entering...\n", func); @@ -297,7 +299,7 @@ SQLDescribeParam( if ((ipar < 1) || (ipar > stmt->parameters_allocated)) { - stmt->errormsg = "Invalid parameter number for SQLDescribeParam."; + stmt->errormsg = "Invalid parameter number for PGAPI_DescribeParam."; stmt->errornumber = STMT_BAD_PARAMETER_NUMBER_ERROR; SC_log_error(func, "", stmt); return SQL_ERROR; @@ -328,15 +330,18 @@ SQLDescribeParam( /* Sets multiple values (arrays) for the set of parameter markers. */ RETCODE SQL_API -SQLParamOptions( +PGAPI_ParamOptions( HSTMT hstmt, UDWORD crow, UDWORD FAR *pirow) { - static char *func = "SQLParamOptions"; + static char *func = "PGAPI_ParamOptions"; + StatementClass *stmt = (StatementClass *) hstmt; mylog("%s: entering...\n", func); + stmt->errornumber = CONN_UNSUPPORTED_OPTION; + stmt->errormsg = "Function not implemented"; SC_log_error(func, "Function not implemented", (StatementClass *) hstmt); return SQL_ERROR; } @@ -352,14 +357,14 @@ SQLParamOptions( * If the statement does not have parameters, it should just return 0. */ RETCODE SQL_API -SQLNumParams( +PGAPI_NumParams( HSTMT hstmt, SWORD FAR *pcpar) { StatementClass *stmt = (StatementClass *) hstmt; char in_quote = FALSE; unsigned int i; - static char *func = "SQLNumParams"; + static char *func = "PGAPI_NumParams"; mylog("%s: entering...\n", func); @@ -382,7 +387,7 @@ SQLNumParams( if (!stmt->statement) { /* no statement has been allocated */ - stmt->errormsg = "SQLNumParams called with no statement ready."; + stmt->errormsg = "PGAPI_NumParams called with no statement ready."; stmt->errornumber = STMT_SEQUENCE_ERROR; SC_log_error(func, "", stmt); return SQL_ERROR; diff --git a/src/interfaces/odbc/columninfo.c b/src/interfaces/odbc/columninfo.c index edfc3816cf..1c63594507 100644 --- a/src/interfaces/odbc/columninfo.c +++ b/src/interfaces/odbc/columninfo.c @@ -17,6 +17,7 @@ #include "socket.h" #include #include +#include "pgapifunc.h" ColumnInfoClass * CI_Constructor() diff --git a/src/interfaces/odbc/connection.c b/src/interfaces/odbc/connection.c index 8c9719745f..1e6167098e 100644 --- a/src/interfaces/odbc/connection.c +++ b/src/interfaces/odbc/connection.c @@ -36,6 +36,7 @@ #ifdef WIN32 #include #endif +#include "pgapifunc.h" #define STMT_INCREMENT 16 /* how many statement holders to allocate * at a time */ @@ -46,13 +47,13 @@ extern GLOBAL_VALUES globals; RETCODE SQL_API -SQLAllocConnect( +PGAPI_AllocConnect( HENV henv, HDBC FAR *phdbc) { EnvironmentClass *env = (EnvironmentClass *) henv; ConnectionClass *conn; - static char *func = "SQLAllocConnect"; + static char *func = "PGAPI_AllocConnect"; mylog("%s: entering...\n", func); @@ -85,7 +86,7 @@ SQLAllocConnect( RETCODE SQL_API -SQLConnect( +PGAPI_Connect( HDBC hdbc, UCHAR FAR *szDSN, SWORD cbDSN, @@ -96,7 +97,7 @@ SQLConnect( { ConnectionClass *conn = (ConnectionClass *) hdbc; ConnInfo *ci; - static char *func = "SQLConnect"; + static char *func = "PGAPI_Connect"; mylog("%s: entering...\n", func); @@ -141,7 +142,7 @@ SQLConnect( RETCODE SQL_API -SQLBrowseConnect( +PGAPI_BrowseConnect( HDBC hdbc, UCHAR FAR *szConnStrIn, SWORD cbConnStrIn, @@ -149,7 +150,7 @@ SQLBrowseConnect( SWORD cbConnStrOutMax, SWORD FAR *pcbConnStrOut) { - static char *func = "SQLBrowseConnect"; + static char *func = "PGAPI_BrowseConnect"; mylog("%s: entering...\n", func); @@ -159,11 +160,11 @@ SQLBrowseConnect( /* Drop any hstmts open on hdbc and disconnect from database */ RETCODE SQL_API -SQLDisconnect( +PGAPI_Disconnect( HDBC hdbc) { ConnectionClass *conn = (ConnectionClass *) hdbc; - static char *func = "SQLDisconnect"; + static char *func = "PGAPI_Disconnect"; mylog("%s: entering...\n", func); @@ -197,11 +198,11 @@ SQLDisconnect( RETCODE SQL_API -SQLFreeConnect( +PGAPI_FreeConnect( HDBC hdbc) { ConnectionClass *conn = (ConnectionClass *) hdbc; - static char *func = "SQLFreeConnect"; + static char *func = "PGAPI_FreeConnect"; mylog("%s: entering...\n", func); mylog("**** in %s: hdbc=%u\n", func, hdbc); @@ -272,6 +273,7 @@ CC_Constructor() rv->translation_handle = NULL; rv->DataSourceToDriver = NULL; rv->DriverToDataSource = NULL; + rv->driver_version = ODBCVER; memset(rv->pg_version, 0, sizeof(rv->pg_version)); rv->pg_version_number = .0; rv->pg_version_major = 0; @@ -1409,7 +1411,7 @@ CC_send_settings(ConnectionClass *self) * has not transitioned to "connected" yet. */ - result = SQLAllocStmt(self, &hstmt); + result = PGAPI_AllocStmt(self, &hstmt); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) return FALSE; stmt = (StatementClass *) hstmt; @@ -1417,7 +1419,7 @@ CC_send_settings(ConnectionClass *self) stmt->internal = TRUE; /* ensure no BEGIN/COMMIT/ABORT stuff */ /* Set the Datestyle to the format the driver expects it to be in */ - result = SQLExecDirect(hstmt, "set DateStyle to 'ISO'", SQL_NTS); + result = PGAPI_ExecDirect(hstmt, "set DateStyle to 'ISO'", SQL_NTS); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) status = FALSE; @@ -1426,7 +1428,7 @@ CC_send_settings(ConnectionClass *self) /* Disable genetic optimizer based on global flag */ if (globals.disable_optimizer) { - result = SQLExecDirect(hstmt, "set geqo to 'OFF'", SQL_NTS); + result = PGAPI_ExecDirect(hstmt, "set geqo to 'OFF'", SQL_NTS); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) status = FALSE; @@ -1437,7 +1439,7 @@ CC_send_settings(ConnectionClass *self) /* KSQO */ if (globals.ksqo) { - result = SQLExecDirect(hstmt, "set ksqo to 'ON'", SQL_NTS); + result = PGAPI_ExecDirect(hstmt, "set ksqo to 'ON'", SQL_NTS); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) status = FALSE; @@ -1452,7 +1454,7 @@ CC_send_settings(ConnectionClass *self) ptr = strtok(cs, ";"); while (ptr) { - result = SQLExecDirect(hstmt, ptr, SQL_NTS); + result = PGAPI_ExecDirect(hstmt, ptr, SQL_NTS); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) status = FALSE; @@ -1471,7 +1473,7 @@ CC_send_settings(ConnectionClass *self) ptr = strtok(cs, ";"); while (ptr) { - result = SQLExecDirect(hstmt, ptr, SQL_NTS); + result = PGAPI_ExecDirect(hstmt, ptr, SQL_NTS); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) status = FALSE; @@ -1484,7 +1486,7 @@ CC_send_settings(ConnectionClass *self) } - SQLFreeStmt(hstmt, SQL_DROP); + PGAPI_FreeStmt(hstmt, SQL_DROP); return status; } @@ -1509,36 +1511,36 @@ CC_lookup_lo(ConnectionClass *self) * This function must use the local odbc API functions since the odbc state * has not transitioned to "connected" yet. */ - result = SQLAllocStmt(self, &hstmt); + result = PGAPI_AllocStmt(self, &hstmt); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) return; stmt = (StatementClass *) hstmt; - result = SQLExecDirect(hstmt, "select oid from pg_type where typname='" PG_TYPE_LO_NAME "'", SQL_NTS); + result = PGAPI_ExecDirect(hstmt, "select oid from pg_type where typname='" PG_TYPE_LO_NAME "'", SQL_NTS); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { - SQLFreeStmt(hstmt, SQL_DROP); + PGAPI_FreeStmt(hstmt, SQL_DROP); return; } - result = SQLFetch(hstmt); + result = PGAPI_Fetch(hstmt); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { - SQLFreeStmt(hstmt, SQL_DROP); + PGAPI_FreeStmt(hstmt, SQL_DROP); return; } - result = SQLGetData(hstmt, 1, SQL_C_SLONG, &self->lobj_type, sizeof(self->lobj_type), NULL); + result = PGAPI_GetData(hstmt, 1, SQL_C_SLONG, &self->lobj_type, sizeof(self->lobj_type), NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { - SQLFreeStmt(hstmt, SQL_DROP); + PGAPI_FreeStmt(hstmt, SQL_DROP); return; } mylog("Got the large object oid: %d\n", self->lobj_type); qlog(" [ Large Object oid = %d ]\n", self->lobj_type); - result = SQLFreeStmt(hstmt, SQL_DROP); + result = PGAPI_FreeStmt(hstmt, SQL_DROP); } @@ -1594,30 +1596,30 @@ CC_lookup_pg_version(ConnectionClass *self) * This function must use the local odbc API functions since the odbc state * has not transitioned to "connected" yet. */ - result = SQLAllocStmt(self, &hstmt); + result = PGAPI_AllocStmt(self, &hstmt); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) return; stmt = (StatementClass *) hstmt; /* get the server's version if possible */ - result = SQLExecDirect(hstmt, "select version()", SQL_NTS); + result = PGAPI_ExecDirect(hstmt, "select version()", SQL_NTS); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { - SQLFreeStmt(hstmt, SQL_DROP); + PGAPI_FreeStmt(hstmt, SQL_DROP); return; } - result = SQLFetch(hstmt); + result = PGAPI_Fetch(hstmt); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { - SQLFreeStmt(hstmt, SQL_DROP); + PGAPI_FreeStmt(hstmt, SQL_DROP); return; } - result = SQLGetData(hstmt, 1, SQL_C_CHAR, self->pg_version, MAX_INFO_STRING, NULL); + result = PGAPI_GetData(hstmt, 1, SQL_C_CHAR, self->pg_version, MAX_INFO_STRING, NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { - SQLFreeStmt(hstmt, SQL_DROP); + PGAPI_FreeStmt(hstmt, SQL_DROP); return; } @@ -1639,7 +1641,7 @@ CC_lookup_pg_version(ConnectionClass *self) qlog(" [ PostgreSQL version string = '%s' ]\n", self->pg_version); qlog(" [ PostgreSQL version number = '%1.1f' ]\n", self->pg_version_number); - result = SQLFreeStmt(hstmt, SQL_DROP); + result = PGAPI_FreeStmt(hstmt, SQL_DROP); } diff --git a/src/interfaces/odbc/connection.h b/src/interfaces/odbc/connection.h index 1038bf117b..67fb38dcaa 100644 --- a/src/interfaces/odbc/connection.h +++ b/src/interfaces/odbc/connection.h @@ -264,6 +264,7 @@ struct ConnectionClass_ HINSTANCE translation_handle; DataSourceToDriverProc DataSourceToDriver; DriverToDataSourceProc DriverToDataSource; + Int2 driver_version; /* prepared for ODBC3.0 */ char transact_status;/* Is a transaction is currently in * progress */ char errormsg_created; /* has an informative error msg diff --git a/src/interfaces/odbc/convert.c b/src/interfaces/odbc/convert.c index a99eba0af8..a87f84edb2 100644 --- a/src/interfaces/odbc/convert.c +++ b/src/interfaces/odbc/convert.c @@ -51,6 +51,7 @@ #include "pgtypes.h" #include "lobj.h" #include "connection.h" +#include "pgapifunc.h" #ifndef WIN32 #ifndef HAVE_STRICMP @@ -973,6 +974,9 @@ copy_statement_with_parameters(StatementClass *stmt) retval; BOOL check_select_into = FALSE; /* select into check */ unsigned int declare_pos; +#ifdef DRIVER_CURSOR_IMPLEMENT + BOOL ins_ctrl = FALSE; +#endif /* DRIVER_CURSOR_IMPLEMENT */ if (!old_statement) @@ -1003,9 +1007,27 @@ copy_statement_with_parameters(StatementClass *stmt) check_select_into = TRUE; declare_pos = npos; } - param_number = -1; +#ifdef DRIVER_CURSOR_IMPLEMENT + if (stmt->statement_type != STMT_TYPE_SELECT) + { + stmt->options.cursor_type = SQL_CURSOR_FORWARD_ONLY; + stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; + } + else if (stmt->options.cursor_type == SQL_CURSOR_FORWARD_ONLY) + stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; + else if (stmt->options.scroll_concurrency != SQL_CONCUR_READ_ONLY) + { + if (stmt->parse_status == STMT_PARSE_NONE) + parse_statement(stmt); + if (stmt->parse_status != STMT_PARSE_COMPLETE) + stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; + else if (!stmt->ti || stmt->ntab != 1) + stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; + else ins_ctrl = TRUE; + } +#endif /* DRIVER_CURSOR_IMPLEMENT */ #ifdef MULTIBYTE multibyte_init(); #endif @@ -1136,9 +1158,20 @@ copy_statement_with_parameters(StatementClass *stmt) into_table_from(&old_statement[opos])) { stmt->statement_type = STMT_TYPE_CREATE; + stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; memmove(new_statement, new_statement + declare_pos, npos - declare_pos); npos -= declare_pos; } +#ifdef DRIVER_CURSOR_IMPLEMENT + else if (ins_ctrl && /* select into check */ + opos > 0 && + isspace((unsigned char) old_statement[opos - 1]) && + strnicmp(&old_statement[opos], "from", 4) == 0) + { + ins_ctrl = FALSE; + CVT_APPEND_STR(", CTID, OID "); + } +#endif /* DRIVER_CURSOR_IMPLEMENT */ CVT_APPEND_CHAR(oldchar); continue; } @@ -1574,6 +1607,10 @@ copy_statement_with_parameters(StatementClass *stmt) NULL, 0, NULL); } +#ifdef DRIVER_CURSOR_IMPLEMENT + if (ins_ctrl) + stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; +#endif /* DRIVER_CURSOR_IMPLEMENT */ return SQL_SUCCESS; } @@ -1715,6 +1752,14 @@ parse_datetime(char *buf, SIMPLE_TIME *st) y = m = d = hh = mm = ss = 0; + /* escape sequence ? */ + if (buf[0] == '{') + { + while (*(++buf) && *buf != '\''); + if (!(*buf)) + return FALSE; + buf++; + } if (buf[4] == '-') /* year first */ nf = sscanf(buf, "%4d-%2d-%2d %2d:%2d:%2d", &y, &m, &d, &hh, &mm, &ss); else @@ -1835,13 +1880,18 @@ convert_special_chars(char *si, char *dst, int used) for (i = 0; i < max; i++) { +#ifdef MULTIBYTE + if (multibyte_char_check(si[i]) != 0) + { + if (p) + p[out] = si[i]; + out++; + continue; + } +#endif if (si[i] == '\r' && si[i + 1] == '\n') continue; -#ifdef MULTIBYTE - else if (multibyte_char_check(si[i]) == 0 && (si[i] == '\'' || si[i] == '\\')) -#else else if (si[i] == '\'' || si[i] == '\\') -#endif { if (p) p[out++] = '\\'; diff --git a/src/interfaces/odbc/dlg_specific.c b/src/interfaces/odbc/dlg_specific.c index 15bdd955ce..c465f3fc28 100644 --- a/src/interfaces/odbc/dlg_specific.c +++ b/src/interfaces/odbc/dlg_specific.c @@ -38,6 +38,7 @@ #ifdef MULTIBYTE #include "multibyte.h" #endif +#include "pgapifunc.h" #ifndef BOOL #define BOOL int diff --git a/src/interfaces/odbc/drvconn.c b/src/interfaces/odbc/drvconn.c index 764424ad7e..6a8c563faf 100644 --- a/src/interfaces/odbc/drvconn.c +++ b/src/interfaces/odbc/drvconn.c @@ -42,6 +42,7 @@ #include #include "resource.h" #endif +#include "pgapifunc.h" #ifndef TRUE #define TRUE (BOOL)1 @@ -67,7 +68,7 @@ extern GLOBAL_VALUES globals; RETCODE SQL_API -SQLDriverConnect( +PGAPI_DriverConnect( HDBC hdbc, HWND hwnd, UCHAR FAR *szConnStrIn, @@ -77,7 +78,7 @@ SQLDriverConnect( SWORD FAR *pcbConnStrOut, UWORD fDriverCompletion) { - static char *func = "SQLDriverConnect"; + static char *func = "PGAPI_DriverConnect"; ConnectionClass *conn = (ConnectionClass *) hdbc; ConnInfo *ci; @@ -103,8 +104,8 @@ SQLDriverConnect( make_string(szConnStrIn, cbConnStrIn, connStrIn); - mylog("**** SQLDriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, connStrIn); - qlog("conn=%u, SQLDriverConnect( in)='%s', fDriverCompletion=%d\n", conn, connStrIn, fDriverCompletion); + mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, connStrIn); + qlog("conn=%u, PGAPI_DriverConnect( in)='%s', fDriverCompletion=%d\n", conn, connStrIn, fDriverCompletion); ci = &(conn->connInfo); @@ -241,10 +242,10 @@ dialog: *pcbConnStrOut = len; mylog("szConnStrOut = '%s'\n", szConnStrOut); - qlog("conn=%u, SQLDriverConnect(out)='%s'\n", conn, szConnStrOut); + qlog("conn=%u, PGAPI_DriverConnect(out)='%s'\n", conn, szConnStrOut); - mylog("SQLDRiverConnect: returning %d\n", result); + mylog("PGAPI_DRiverConnect: returning %d\n", result); return result; } diff --git a/src/interfaces/odbc/environ.c b/src/interfaces/odbc/environ.c index 506ca5cf7b..2ea5f28ef4 100644 --- a/src/interfaces/odbc/environ.c +++ b/src/interfaces/odbc/environ.c @@ -19,6 +19,7 @@ #include "statement.h" #include #include +#include "pgapifunc.h" extern GLOBAL_VALUES globals; @@ -27,11 +28,11 @@ ConnectionClass *conns[MAX_CONNECTIONS]; RETCODE SQL_API -SQLAllocEnv(HENV FAR *phenv) +PGAPI_AllocEnv(HENV FAR *phenv) { - static char *func = "SQLAllocEnv"; + static char *func = "PGAPI_AllocEnv"; - mylog("**** in SQLAllocEnv ** \n"); + mylog("**** in PGAPI_AllocEnv ** \n"); /* * Hack for systems on which none of the constructor-making techniques @@ -51,18 +52,18 @@ SQLAllocEnv(HENV FAR *phenv) return SQL_ERROR; } - mylog("** exit SQLAllocEnv: phenv = %u **\n", *phenv); + mylog("** exit PGAPI_AllocEnv: phenv = %u **\n", *phenv); return SQL_SUCCESS; } RETCODE SQL_API -SQLFreeEnv(HENV henv) +PGAPI_FreeEnv(HENV henv) { - static char *func = "SQLFreeEnv"; + static char *func = "PGAPI_FreeEnv"; EnvironmentClass *env = (EnvironmentClass *) henv; - mylog("**** in SQLFreeEnv: env = %u ** \n", env); + mylog("**** in PGAPI_FreeEnv: env = %u ** \n", env); if (env && EN_Destructor(env)) { @@ -78,7 +79,7 @@ SQLFreeEnv(HENV henv) /* Returns the next SQL error information. */ RETCODE SQL_API -SQLError( +PGAPI_Error( HENV henv, HDBC hdbc, HSTMT hstmt, @@ -91,7 +92,7 @@ SQLError( char *msg; int status; - mylog("**** SQLError: henv=%u, hdbc=%u, hstmt=%u <%d>\n", henv, hdbc, hstmt, cbErrorMsgMax); + mylog("**** PGAPI_Error: henv=%u, hdbc=%u, hstmt=%u <%d>\n", henv, hdbc, hstmt, cbErrorMsgMax); if (cbErrorMsgMax < 0) return SQL_ERROR; @@ -140,6 +141,10 @@ SQLError( switch (status) { /* now determine the SQLSTATE to be returned */ + case STMT_ROW_VERSION_CHANGED: + strcpy(szSqlState, "01001"); + /* data truncated */ + break; case STMT_TRUNCATED: strcpy(szSqlState, "01004"); /* data truncated */ @@ -206,11 +211,14 @@ SQLError( strcpy(szSqlState, "07006"); break; case STMT_INVALID_CURSOR_STATE_ERROR: - strcpy(szSqlState, "24000"); + strcpy(szSqlState, "24000"); break; case STMT_OPTION_VALUE_CHANGED: strcpy(szSqlState, "01S02"); break; + case STMT_POS_BEFORE_RECORDSET: + strcpy(szSqlState, "01S06"); + break; case STMT_INVALID_CURSOR_NAME: strcpy(szSqlState, "34000"); break; @@ -230,6 +238,9 @@ SQLError( case STMT_OPERATION_INVALID: strcpy(szSqlState, "S1011"); break; + case STMT_INVALID_OPTION_IDENTIFIER: + strcpy(szSqlState, "HY092"); + break; case STMT_EXEC_ERROR: default: strcpy(szSqlState, "S1000"); diff --git a/src/interfaces/odbc/execute.c b/src/interfaces/odbc/execute.c index fb64e8fe81..38eabfea6e 100644 --- a/src/interfaces/odbc/execute.c +++ b/src/interfaces/odbc/execute.c @@ -36,17 +36,18 @@ #include "bind.h" #include "pgtypes.h" #include "lobj.h" +#include "pgapifunc.h" extern GLOBAL_VALUES globals; /* Perform a Prepare on the SQL statement */ RETCODE SQL_API -SQLPrepare(HSTMT hstmt, +PGAPI_Prepare(HSTMT hstmt, UCHAR FAR *szSqlStr, SDWORD cbSqlStr) { - static char *func = "SQLPrepare"; + static char *func = "PGAPI_Prepare"; StatementClass *self = (StatementClass *) hstmt; mylog("%s: entering...\n", func); @@ -66,31 +67,31 @@ SQLPrepare(HSTMT hstmt, switch (self->status) { case STMT_PREMATURE: - mylog("**** SQLPrepare: STMT_PREMATURE, recycle\n"); + mylog("**** PGAPI_Prepare: STMT_PREMATURE, recycle\n"); SC_recycle_statement(self); /* recycle the statement, but do * not remove parameter bindings */ break; case STMT_FINISHED: - mylog("**** SQLPrepare: STMT_FINISHED, recycle\n"); + mylog("**** PGAPI_Prepare: STMT_FINISHED, recycle\n"); SC_recycle_statement(self); /* recycle the statement, but do * not remove parameter bindings */ break; case STMT_ALLOCATED: - mylog("**** SQLPrepare: STMT_ALLOCATED, copy\n"); + mylog("**** PGAPI_Prepare: STMT_ALLOCATED, copy\n"); self->status = STMT_READY; break; case STMT_READY: - mylog("**** SQLPrepare: STMT_READY, change SQL\n"); + mylog("**** PGAPI_Prepare: STMT_READY, change SQL\n"); break; case STMT_EXECUTING: - mylog("**** SQLPrepare: STMT_EXECUTING, error!\n"); + mylog("**** PGAPI_Prepare: STMT_EXECUTING, error!\n"); self->errornumber = STMT_SEQUENCE_ERROR; - self->errormsg = "SQLPrepare(): The handle does not point to a statement that is ready to be executed"; + self->errormsg = "PGAPI_Prepare(): The handle does not point to a statement that is ready to be executed"; SC_log_error(func, "", self); return SQL_ERROR; @@ -132,14 +133,14 @@ SQLPrepare(HSTMT hstmt, /* Performs the equivalent of SQLPrepare, followed by SQLExecute. */ RETCODE SQL_API -SQLExecDirect( +PGAPI_ExecDirect( HSTMT hstmt, UCHAR FAR *szSqlStr, SDWORD cbSqlStr) { StatementClass *stmt = (StatementClass *) hstmt; RETCODE result; - static char *func = "SQLExecDirect"; + static char *func = "PGAPI_ExecDirect"; mylog("%s: entering...\n", func); @@ -188,21 +189,21 @@ SQLExecDirect( return SQL_ERROR; } - mylog("%s: calling SQLExecute...\n", func); + mylog("%s: calling PGAPI_Execute...\n", func); - result = SQLExecute(hstmt); + result = PGAPI_Execute(hstmt); - mylog("%s: returned %hd from SQLExecute\n", func, result); + mylog("%s: returned %hd from PGAPI_Execute\n", func, result); return result; } /* Execute a prepared SQL statement */ RETCODE SQL_API -SQLExecute( +PGAPI_Execute( HSTMT hstmt) { - static char *func = "SQLExecute"; + static char *func = "PGAPI_Execute"; StatementClass *stmt = (StatementClass *) hstmt; ConnectionClass *conn; int i, @@ -349,12 +350,12 @@ SQLExecute( RETCODE SQL_API -SQLTransact( +PGAPI_Transact( HENV henv, HDBC hdbc, UWORD fType) { - static char *func = "SQLTransact"; + static char *func = "PGAPI_Transact"; extern ConnectionClass *conns[]; ConnectionClass *conn; QResultClass *res; @@ -381,7 +382,7 @@ SQLTransact( conn = conns[lf]; if (conn && conn->henv == henv) - if (SQLTransact(henv, (HDBC) conn, fType) != SQL_SUCCESS) + if (PGAPI_Transact(henv, (HDBC) conn, fType) != SQL_SUCCESS) return SQL_ERROR; } return SQL_SUCCESS; @@ -396,7 +397,7 @@ SQLTransact( else { conn->errornumber = CONN_INVALID_ARGUMENT_NO; - conn->errormsg = "SQLTransact can only be called with SQL_COMMIT or SQL_ROLLBACK as parameter"; + conn->errormsg = "PGAPI_Transact can only be called with SQL_COMMIT or SQL_ROLLBACK as parameter"; CC_log_error(func, "", conn); return SQL_ERROR; } @@ -404,7 +405,7 @@ SQLTransact( /* If manual commit and in transaction, then proceed. */ if (!CC_is_in_autocommit(conn) && CC_is_in_trans(conn)) { - mylog("SQLTransact: sending on conn %d '%s'\n", conn, stmt_string); + mylog("PGAPI_Transact: sending on conn %d '%s'\n", conn, stmt_string); res = CC_send_query(conn, stmt_string, NULL); CC_set_no_trans(conn); @@ -430,10 +431,10 @@ SQLTransact( RETCODE SQL_API -SQLCancel( +PGAPI_Cancel( HSTMT hstmt) /* Statement to cancel. */ { - static char *func = "SQLCancel"; + static char *func = "PGAPI_Cancel"; StatementClass *stmt = (StatementClass *) hstmt; RETCODE result; @@ -476,12 +477,12 @@ SQLCancel( result = addr((char *) (stmt->phstmt) - 96, SQL_CLOSE); } else - result = SQLFreeStmt(hstmt, SQL_CLOSE); + result = PGAPI_FreeStmt(hstmt, SQL_CLOSE); #else - result = SQLFreeStmt(hstmt, SQL_CLOSE); + result = PGAPI_FreeStmt(hstmt, SQL_CLOSE); #endif - mylog("SQLCancel: SQLFreeStmt returned %d\n", result); + mylog("PGAPI_Cancel: PGAPI_FreeStmt returned %d\n", result); SC_clear_error(hstmt); return SQL_SUCCESS; @@ -509,7 +510,7 @@ SQLCancel( * observing buffer limits and truncation. */ RETCODE SQL_API -SQLNativeSql( +PGAPI_NativeSql( HDBC hdbc, UCHAR FAR *szSqlStrIn, SDWORD cbSqlStrIn, @@ -517,7 +518,7 @@ SQLNativeSql( SDWORD cbSqlStrMax, SDWORD FAR *pcbSqlStr) { - static char *func = "SQLNativeSql"; + static char *func = "PGAPI_NativeSql"; int len = 0; char *ptr; ConnectionClass *conn = (ConnectionClass *) hdbc; @@ -552,7 +553,8 @@ SQLNativeSql( if (pcbSqlStr) *pcbSqlStr = len; - free(ptr); + if (cbSqlStrIn) + free(ptr); return result; } @@ -563,11 +565,11 @@ SQLNativeSql( * Used in conjuction with SQLPutData. */ RETCODE SQL_API -SQLParamData( +PGAPI_ParamData( HSTMT hstmt, PTR FAR *prgbValue) { - static char *func = "SQLParamData"; + static char *func = "PGAPI_ParamData"; StatementClass *stmt = (StatementClass *) hstmt; int i, retval; @@ -672,12 +674,12 @@ SQLParamData( * Used in conjunction with SQLParamData. */ RETCODE SQL_API -SQLPutData( +PGAPI_PutData( HSTMT hstmt, PTR rgbValue, SDWORD cbValue) { - static char *func = "SQLPutData"; + static char *func = "PGAPI_PutData"; StatementClass *stmt = (StatementClass *) hstmt; int old_pos, retval; @@ -704,7 +706,7 @@ SQLPutData( if (!stmt->put_data) { /* first call */ - mylog("SQLPutData: (1) cbValue = %d\n", cbValue); + mylog("PGAPI_PutData: (1) cbValue = %d\n", cbValue); stmt->put_data = TRUE; @@ -712,7 +714,7 @@ SQLPutData( if (!current_param->EXEC_used) { stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Out of memory in SQLPutData (1)"; + stmt->errormsg = "Out of memory in PGAPI_PutData (1)"; SC_log_error(func, "", stmt); return SQL_ERROR; } @@ -790,7 +792,7 @@ SQLPutData( if (!current_param->EXEC_buffer) { stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Out of memory in SQLPutData (2)"; + stmt->errormsg = "Out of memory in PGAPI_PutData (2)"; SC_log_error(func, "", stmt); return SQL_ERROR; } @@ -807,7 +809,7 @@ SQLPutData( if (!current_param->EXEC_buffer) { stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Out of memory in SQLPutData (2)"; + stmt->errormsg = "Out of memory in PGAPI_PutData (2)"; SC_log_error(func, "", stmt); return SQL_ERROR; } @@ -822,7 +824,7 @@ SQLPutData( if (!current_param->EXEC_buffer) { stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Out of memory in SQLPutData (2)"; + stmt->errormsg = "Out of memory in PGAPI_PutData (2)"; SC_log_error(func, "", stmt); return SQL_ERROR; } @@ -834,7 +836,7 @@ SQLPutData( else { /* calling SQLPutData more than once */ - mylog("SQLPutData: (>1) cbValue = %d\n", cbValue); + mylog("PGAPI_PutData: (>1) cbValue = %d\n", cbValue); if (current_param->SQLType == SQL_LONGVARBINARY) { @@ -854,7 +856,7 @@ SQLPutData( if (!buffer) { stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Out of memory in SQLPutData (3)"; + stmt->errormsg = "Out of memory in PGAPI_PutData (3)"; SC_log_error(func, "", stmt); return SQL_ERROR; } @@ -880,7 +882,7 @@ SQLPutData( if (!buffer) { stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Out of memory in SQLPutData (3)"; + stmt->errormsg = "Out of memory in PGAPI_PutData (3)"; SC_log_error(func, "", stmt); return SQL_ERROR; } diff --git a/src/interfaces/odbc/info.c b/src/interfaces/odbc/info.c index a18778cedd..3da2708d3c 100644 --- a/src/interfaces/odbc/info.c +++ b/src/interfaces/odbc/info.c @@ -33,6 +33,8 @@ #include #include #include + +#include #endif #include "tuple.h" @@ -45,6 +47,7 @@ #include "bind.h" #include "misc.h" #include "pgtypes.h" +#include "pgapifunc.h" /* Trigger related stuff for SQLForeign Keys */ @@ -57,15 +60,16 @@ extern GLOBAL_VALUES globals; + RETCODE SQL_API -SQLGetInfo( +PGAPI_GetInfo( HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue, SWORD cbInfoValueMax, SWORD FAR *pcbInfoValue) { - static char *func = "SQLGetInfo"; + static char *func = "PGAPI_GetInfo"; ConnectionClass *conn = (ConnectionClass *) hdbc; ConnInfo *ci; char *p = NULL, @@ -165,11 +169,19 @@ SQLGetInfo( case SQL_CURSOR_COMMIT_BEHAVIOR: /* ODBC 1.0 */ len = 2; value = SQL_CB_CLOSE; +#ifdef DRIVER_CURSOR_IMPLEMENT + if (!globals.use_declarefetch) + value = SQL_CB_PRESERVE; +#endif /* DRIVER_CURSOR_IMPLEMENT */ break; case SQL_CURSOR_ROLLBACK_BEHAVIOR: /* ODBC 1.0 */ len = 2; value = SQL_CB_CLOSE; +#ifdef DRIVER_CURSOR_IMPLEMENT + if (!globals.use_declarefetch) + value = SQL_CB_PRESERVE; +#endif /* DRIVER_CURSOR_IMPLEMENT */ break; case SQL_DATA_SOURCE_NAME: /* ODBC 1.0 */ @@ -218,6 +230,28 @@ SQLGetInfo( case SQL_DRIVER_ODBC_VER: p = DRIVER_ODBC_VER; +#ifdef DRIVER_CURSOR_IMPLEMENT + { + static char dver[32]; + SQLGetPrivateProfileString(DBMS_NAME, + "DriverODBCVer", "", dver, sizeof(dver), "odbcinst.ini"); + if (dver[0]) + { + int major, minor; + mylog("REIGISTRY_ODBC_VER = %s\n", dver) +; + if (sscanf(dver, "%x.%x", &major, &minor) >= 2) + { + Int2 drv_ver = (major << 8) + minor; + if (drv_ver > ODBCVER) + { + conn->driver_version = drv_ver; + p = dver; + } + } + } + } +#endif /* DRIVER_CURSOR_IMPLEMENT */ break; case SQL_DRIVER_VER: /* ODBC 1.0 */ @@ -648,8 +682,9 @@ SQLGetInfo( break; default: +return PGAPI_GetInfo30(hdbc, fInfoType, rgbInfoValue, cbInfoValueMax,pcbInfoValue); /* unrecognized key */ - conn->errormsg = "Unrecognized key passed to SQLGetInfo."; + conn->errormsg = "Unrecognized key passed to PGAPI_GetInfo."; conn->errornumber = CONN_NOT_IMPLEMENTED_ERROR; CC_log_error(func, "", conn); return SQL_ERROR; @@ -657,7 +692,7 @@ SQLGetInfo( result = SQL_SUCCESS; - mylog("SQLGetInfo: p='%s', len=%d, value=%d, cbMax=%d\n", p ? p : "", len, value, cbInfoValueMax); + mylog("%s: p='%s', len=%d, value=%d, cbMax=%d\n", func, p ? p : "", len, value, cbInfoValueMax); /* * NOTE, that if rgbInfoValue is NULL, then no warnings or errors @@ -701,11 +736,11 @@ SQLGetInfo( RETCODE SQL_API -SQLGetTypeInfo( +PGAPI_GetTypeInfo( HSTMT hstmt, SWORD fSqlType) { - static char *func = "SQLGetTypeInfo"; + static char *func = "PGAPI_GetTypeInfo"; StatementClass *stmt = (StatementClass *) hstmt; TupleNode *row; int i; @@ -795,14 +830,15 @@ SQLGetTypeInfo( RETCODE SQL_API -SQLGetFunctions( +/*SQLGetFunctions(*/ +PGAPI_GetFunctions( HDBC hdbc, UWORD fFunction, UWORD FAR *pfExists) { - static char *func = "SQLGetFunctions"; + static char *func = "PGAPI_GetFunctions"; - mylog("%s: entering...%u\n", func); + mylog("%s: entering...%u\n", func, fFunction); if (fFunction == SQL_API_ALL_FUNCTIONS) { @@ -1077,7 +1113,7 @@ SQLGetFunctions( RETCODE SQL_API -SQLTables( +PGAPI_Tables( HSTMT hstmt, UCHAR FAR *szTableQualifier, SWORD cbTableQualifier, @@ -1088,7 +1124,7 @@ SQLTables( UCHAR FAR *szTableType, SWORD cbTableType) { - static char *func = "SQLTables"; + static char *func = "PGAPI_Tables"; StatementClass *stmt = (StatementClass *) hstmt; StatementClass *tbl_stmt; TupleNode *row; @@ -1127,11 +1163,11 @@ SQLTables( conn = (ConnectionClass *) (stmt->hdbc); ci = &stmt->hdbc->connInfo; - result = SQLAllocStmt(stmt->hdbc, &htbl_stmt); + result = PGAPI_AllocStmt(stmt->hdbc, &htbl_stmt); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Couldn't allocate statement for SQLTables result."; + stmt->errormsg = "Couldn't allocate statement for PGAPI_Tables result."; SC_log_error(func, "", stmt); return SQL_ERROR; } @@ -1225,55 +1261,55 @@ SQLTables( strcat(tables_query, " and usesysid = relowner"); strcat(tables_query, " order by relname"); - result = SQLExecDirect(htbl_stmt, tables_query, strlen(tables_query)); + result = PGAPI_ExecDirect(htbl_stmt, tables_query, strlen(tables_query)); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = SC_create_errormsg(htbl_stmt); stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(htbl_stmt, 1, SQL_C_CHAR, + result = PGAPI_BindCol(htbl_stmt, 1, SQL_C_CHAR, table_name, MAX_INFO_STRING, NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = tbl_stmt->errormsg; stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(htbl_stmt, 2, SQL_C_CHAR, + result = PGAPI_BindCol(htbl_stmt, 2, SQL_C_CHAR, table_owner, MAX_INFO_STRING, NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = tbl_stmt->errormsg; stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(htbl_stmt, 3, SQL_C_CHAR, + result = PGAPI_BindCol(htbl_stmt, 3, SQL_C_CHAR, relkind_or_hasrules, MAX_INFO_STRING, NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = tbl_stmt->errormsg; stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } stmt->result = QR_Constructor(); if (!stmt->result) { - stmt->errormsg = "Couldn't allocate memory for SQLTables result."; + stmt->errormsg = "Couldn't allocate memory for PGAPI_Tables result."; stmt->errornumber = STMT_NO_MEMORY_ERROR; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } @@ -1294,7 +1330,7 @@ SQLTables( QR_set_field_info(stmt->result, 4, "REMARKS", PG_TYPE_TEXT, 254); /* add the tuples */ - result = SQLFetch(htbl_stmt); + result = PGAPI_Fetch(htbl_stmt); while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) { @@ -1359,7 +1395,7 @@ SQLTables( * set_tuplefield_string(&row->tuple[1], table_owner); */ - mylog("SQLTables: table_name = '%s'\n", table_name); + mylog("%s: table_name = '%s'\n", func, table_name); set_tuplefield_string(&row->tuple[1], ""); set_tuplefield_string(&row->tuple[2], table_name); @@ -1368,14 +1404,14 @@ SQLTables( QR_add_tuple(stmt->result, row); } - result = SQLFetch(htbl_stmt); + result = PGAPI_Fetch(htbl_stmt); } if (result != SQL_NO_DATA_FOUND) { stmt->errormsg = SC_create_errormsg(htbl_stmt); stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } @@ -1390,14 +1426,14 @@ SQLTables( stmt->rowset_start = -1; stmt->current_col = -1; - SQLFreeStmt(htbl_stmt, SQL_DROP); - mylog("SQLTables(): EXIT, stmt=%u\n", stmt); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); + mylog("%s: EXIT, stmt=%u\n", func, stmt); return SQL_SUCCESS; } RETCODE SQL_API -SQLColumns( +PGAPI_Columns( HSTMT hstmt, UCHAR FAR *szTableQualifier, SWORD cbTableQualifier, @@ -1408,7 +1444,7 @@ SQLColumns( UCHAR FAR *szColumnName, SWORD cbColumnName) { - static char *func = "SQLColumns"; + static char *func = "PGAPI_Columns"; StatementClass *stmt = (StatementClass *) hstmt; TupleNode *row; HSTMT hcol_stmt; @@ -1469,146 +1505,146 @@ SQLColumns( */ strcat(columns_query, " order by attnum"); - result = SQLAllocStmt(stmt->hdbc, &hcol_stmt); + result = PGAPI_AllocStmt(stmt->hdbc, &hcol_stmt); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Couldn't allocate statement for SQLColumns result."; + stmt->errormsg = "Couldn't allocate statement for PGAPI_Columns result."; SC_log_error(func, "", stmt); return SQL_ERROR; } col_stmt = (StatementClass *) hcol_stmt; - mylog("SQLColumns: hcol_stmt = %u, col_stmt = %u\n", hcol_stmt, col_stmt); + mylog("%s: hcol_stmt = %u, col_stmt = %u\n", func, hcol_stmt, col_stmt); - result = SQLExecDirect(hcol_stmt, columns_query, + result = PGAPI_ExecDirect(hcol_stmt, columns_query, strlen(columns_query)); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = SC_create_errormsg(hcol_stmt); stmt->errornumber = col_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(hcol_stmt, 1, SQL_C_CHAR, + result = PGAPI_BindCol(hcol_stmt, 1, SQL_C_CHAR, table_owner, MAX_INFO_STRING, NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = col_stmt->errormsg; stmt->errornumber = col_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(hcol_stmt, 2, SQL_C_CHAR, + result = PGAPI_BindCol(hcol_stmt, 2, SQL_C_CHAR, table_name, MAX_INFO_STRING, NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = col_stmt->errormsg; stmt->errornumber = col_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(hcol_stmt, 3, SQL_C_CHAR, + result = PGAPI_BindCol(hcol_stmt, 3, SQL_C_CHAR, field_name, MAX_INFO_STRING, NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = col_stmt->errormsg; stmt->errornumber = col_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(hcol_stmt, 4, SQL_C_LONG, + result = PGAPI_BindCol(hcol_stmt, 4, SQL_C_LONG, &field_type, 4, NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = col_stmt->errormsg; stmt->errornumber = col_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(hcol_stmt, 5, SQL_C_CHAR, + result = PGAPI_BindCol(hcol_stmt, 5, SQL_C_CHAR, field_type_name, MAX_INFO_STRING, NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = col_stmt->errormsg; stmt->errornumber = col_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(hcol_stmt, 6, SQL_C_SHORT, + result = PGAPI_BindCol(hcol_stmt, 6, SQL_C_SHORT, &field_number, MAX_INFO_STRING, NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = col_stmt->errormsg; stmt->errornumber = col_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(hcol_stmt, 7, SQL_C_LONG, + result = PGAPI_BindCol(hcol_stmt, 7, SQL_C_LONG, &field_length, MAX_INFO_STRING, NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = col_stmt->errormsg; stmt->errornumber = col_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(hcol_stmt, 8, SQL_C_LONG, + result = PGAPI_BindCol(hcol_stmt, 8, SQL_C_LONG, &mod_length, MAX_INFO_STRING, NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = col_stmt->errormsg; stmt->errornumber = col_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(hcol_stmt, 9, SQL_C_CHAR, + result = PGAPI_BindCol(hcol_stmt, 9, SQL_C_CHAR, not_null, MAX_INFO_STRING, NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = col_stmt->errormsg; stmt->errornumber = col_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(hcol_stmt, 10, SQL_C_CHAR, + result = PGAPI_BindCol(hcol_stmt, 10, SQL_C_CHAR, relhasrules, MAX_INFO_STRING, NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = col_stmt->errormsg; stmt->errornumber = col_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } stmt->result = QR_Constructor(); if (!stmt->result) { - stmt->errormsg = "Couldn't allocate memory for SQLColumns result."; + stmt->errormsg = "Couldn't allocate memory for PGAPI_Columns result."; stmt->errornumber = STMT_NO_MEMORY_ERROR; SC_log_error(func, "", stmt); - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } @@ -1640,7 +1676,7 @@ SQLColumns( QR_set_field_info(stmt->result, 12, "DISPLAY_SIZE", PG_TYPE_INT4, 4); QR_set_field_info(stmt->result, 13, "FIELD_TYPE", PG_TYPE_INT4, 4); - result = SQLFetch(hcol_stmt); + result = PGAPI_Fetch(hcol_stmt); /* * Only show oid if option AND there are other columns AND it's not @@ -1712,7 +1748,7 @@ SQLColumns( * *---------- */ - qlog("SQLColumns: table='%s',field_name='%s',type=%d,sqltype=%d,name='%s'\n", + qlog("PGAPI_Columns: table='%s',field_name='%s',type=%d,sqltype=%d,name='%s'\n", table_name, field_name, field_type, pgtype_to_sqltype, field_type_name); useStaticPrecision = TRUE; @@ -1729,7 +1765,7 @@ SQLColumns( precision = (mod_length >> 16) & 0xffff; scale = mod_length & 0xffff; - mylog("SQLColumns: field type is NUMERIC: field_type = %d, mod_length=%d, precision=%d, scale=%d\n", field_type, mod_length, precision, scale); + mylog("%s: field type is NUMERIC: field_type = %d, mod_length=%d, precision=%d, scale=%d\n", func, field_type, mod_length, precision, scale); set_tuplefield_int4(&row->tuple[7], precision + 2); /* sign+dec.point */ set_tuplefield_int4(&row->tuple[6], precision); @@ -1749,7 +1785,7 @@ SQLColumns( if (mod_length > globals.max_varchar_size || mod_length <= 0) mod_length = globals.max_varchar_size; - mylog("SQLColumns: field type is VARCHAR,BPCHAR: field_type = %d, mod_length = %d\n", field_type, mod_length); + mylog("%s: field type is VARCHAR,BPCHAR: field_type = %d, mod_length = %d\n", func, field_type, mod_length); set_tuplefield_int4(&row->tuple[7], mod_length); set_tuplefield_int4(&row->tuple[6], mod_length); @@ -1759,7 +1795,7 @@ SQLColumns( if (useStaticPrecision) { - mylog("SQLColumns: field type is OTHER: field_type = %d, pgtype_length = %d\n", field_type, pgtype_length(stmt, field_type, PG_STATIC, PG_STATIC)); + mylog("%s: field type is OTHER: field_type = %d, pgtype_length = %d\n", func, field_type, pgtype_length(stmt, field_type, PG_STATIC, PG_STATIC)); set_tuplefield_int4(&row->tuple[7], pgtype_length(stmt, field_type, PG_STATIC, PG_STATIC)); set_tuplefield_int4(&row->tuple[6], pgtype_precision(stmt, field_type, PG_STATIC, PG_STATIC)); @@ -1775,7 +1811,7 @@ SQLColumns( QR_add_tuple(stmt->result, row); - result = SQLFetch(hcol_stmt); + result = PGAPI_Fetch(hcol_stmt); } if (result != SQL_NO_DATA_FOUND) @@ -1783,7 +1819,7 @@ SQLColumns( stmt->errormsg = SC_create_errormsg(hcol_stmt); stmt->errornumber = col_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } @@ -1828,14 +1864,14 @@ SQLColumns( stmt->rowset_start = -1; stmt->current_col = -1; - SQLFreeStmt(hcol_stmt, SQL_DROP); - mylog("SQLColumns(): EXIT, stmt=%u\n", stmt); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); + mylog("%s: EXIT, stmt=%u\n", func, stmt); return SQL_SUCCESS; } RETCODE SQL_API -SQLSpecialColumns( +PGAPI_SpecialColumns( HSTMT hstmt, UWORD fColType, UCHAR FAR *szTableQualifier, @@ -1847,7 +1883,7 @@ SQLSpecialColumns( UWORD fScope, UWORD fNullable) { - static char *func = "SQLSpecialColumns"; + static char *func = "PGAPI_SpecialColumns"; TupleNode *row; StatementClass *stmt = (StatementClass *) hstmt; ConnInfo *ci; @@ -1879,7 +1915,7 @@ SQLSpecialColumns( my_strcat(columns_query, " and u.usename like '%.*s'", szTableOwner, cbTableOwner); - result = SQLAllocStmt(stmt->hdbc, &hcol_stmt); + result = PGAPI_AllocStmt(stmt->hdbc, &hcol_stmt); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errornumber = STMT_NO_MEMORY_ERROR; @@ -1889,32 +1925,32 @@ SQLSpecialColumns( } col_stmt = (StatementClass *) hcol_stmt; - mylog("SQLSpecialColumns: hcol_stmt = %u, col_stmt = %u\n", hcol_stmt, col_stmt); + mylog("%s: hcol_stmt = %u, col_stmt = %u\n", func, hcol_stmt, col_stmt); - result = SQLExecDirect(hcol_stmt, columns_query, + result = PGAPI_ExecDirect(hcol_stmt, columns_query, strlen(columns_query)); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = SC_create_errormsg(hcol_stmt); stmt->errornumber = col_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(hcol_stmt, 1, SQL_C_CHAR, + result = PGAPI_BindCol(hcol_stmt, 1, SQL_C_CHAR, relhasrules, MAX_INFO_STRING, NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = col_stmt->errormsg; stmt->errornumber = col_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLFetch(hcol_stmt); - SQLFreeStmt(hcol_stmt, SQL_DROP); + result = PGAPI_Fetch(hcol_stmt); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); stmt->result = QR_Constructor(); extend_bindings(stmt, 8); @@ -1975,13 +2011,13 @@ SQLSpecialColumns( stmt->rowset_start = -1; stmt->current_col = -1; - mylog("SQLSpecialColumns(): EXIT, stmt=%u\n", stmt); + mylog("%s: EXIT, stmt=%u\n", func, stmt); return SQL_SUCCESS; } RETCODE SQL_API -SQLStatistics( +PGAPI_Statistics( HSTMT hstmt, UCHAR FAR *szTableQualifier, SWORD cbTableQualifier, @@ -1992,7 +2028,7 @@ SQLStatistics( UWORD fUnique, UWORD fAccuracy) { - static char *func = "SQLStatistics"; + static char *func = "PGAPI_Statistics"; StatementClass *stmt = (StatementClass *) hstmt; char index_query[INFO_INQUIRY_LEN]; HSTMT hindx_stmt; @@ -2035,7 +2071,7 @@ SQLStatistics( stmt->result = QR_Constructor(); if (!stmt->result) { - stmt->errormsg = "Couldn't allocate memory for SQLStatistics result."; + stmt->errormsg = "Couldn't allocate memory for PGAPI_Statistics result."; stmt->errornumber = STMT_NO_MEMORY_ERROR; SC_log_error(func, "", stmt); return SQL_ERROR; @@ -2072,7 +2108,7 @@ SQLStatistics( table_name = make_string(szTableName, cbTableName, NULL); if (!table_name) { - stmt->errormsg = "No table name passed to SQLStatistics."; + stmt->errormsg = "No table name passed to PGAPI_Statistics."; stmt->errornumber = STMT_INTERNAL_ERROR; SC_log_error(func, "", stmt); return SQL_ERROR; @@ -2082,10 +2118,10 @@ SQLStatistics( * we need to get a list of the field names first, so we can return * them later. */ - result = SQLAllocStmt(stmt->hdbc, &hcol_stmt); + result = PGAPI_AllocStmt(stmt->hdbc, &hcol_stmt); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { - stmt->errormsg = "SQLAllocStmt failed in SQLStatistics for columns."; + stmt->errormsg = "PGAPI_AllocStmt failed in PGAPI_Statistics for columns."; stmt->errornumber = STMT_NO_MEMORY_ERROR; goto SEEYA; } @@ -2097,7 +2133,7 @@ SQLStatistics( * being shown. This would throw everything off. */ col_stmt->internal = TRUE; - result = SQLColumns(hcol_stmt, "", 0, "", 0, + result = PGAPI_Columns(hcol_stmt, "", 0, "", 0, table_name, (SWORD) strlen(table_name), "", 0); col_stmt->internal = FALSE; @@ -2106,21 +2142,21 @@ SQLStatistics( stmt->errormsg = col_stmt->errormsg; /* "SQLColumns failed in * SQLStatistics."; */ stmt->errornumber = col_stmt->errornumber; /* STMT_EXEC_ERROR; */ - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); goto SEEYA; } - result = SQLBindCol(hcol_stmt, 4, SQL_C_CHAR, + result = PGAPI_BindCol(hcol_stmt, 4, SQL_C_CHAR, column_name, MAX_INFO_STRING, &column_name_len); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = col_stmt->errormsg; stmt->errornumber = col_stmt->errornumber; - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); goto SEEYA; } - result = SQLFetch(hcol_stmt); + result = PGAPI_Fetch(hcol_stmt); while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) { total_columns++; @@ -2132,9 +2168,9 @@ SQLStatistics( (char *) malloc(strlen(column_name) + 1); strcpy(column_names[total_columns - 1], column_name); - mylog("SQLStatistics: column_name = '%s'\n", column_name); + mylog("%s: column_name = '%s'\n", func, column_name); - result = SQLFetch(hcol_stmt); + result = PGAPI_Fetch(hcol_stmt); } if (result != SQL_NO_DATA_FOUND || total_columns == 0) @@ -2143,18 +2179,18 @@ SQLStatistics( * names in * SQLStatistics."; */ stmt->errornumber = col_stmt->errornumber; - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); goto SEEYA; } - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); /* get a list of indexes on this table */ - result = SQLAllocStmt(stmt->hdbc, &hindx_stmt); + result = PGAPI_AllocStmt(stmt->hdbc, &hindx_stmt); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { - stmt->errormsg = "SQLAllocStmt failed in SQLStatistics for indices."; + stmt->errormsg = "PGAPI_AllocStmt failed in SQLStatistics for indices."; stmt->errornumber = STMT_NO_MEMORY_ERROR; goto SEEYA; @@ -2170,7 +2206,7 @@ SQLStatistics( " and c.relam = a.oid" , table_name); - result = SQLExecDirect(hindx_stmt, index_query, strlen(index_query)); + result = PGAPI_ExecDirect(hindx_stmt, index_query, strlen(index_query)); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { /* @@ -2180,79 +2216,79 @@ SQLStatistics( stmt->errormsg = SC_create_errormsg(hindx_stmt); stmt->errornumber = indx_stmt->errornumber; - SQLFreeStmt(hindx_stmt, SQL_DROP); + PGAPI_FreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } /* bind the index name column */ - result = SQLBindCol(hindx_stmt, 1, SQL_C_CHAR, + result = PGAPI_BindCol(hindx_stmt, 1, SQL_C_CHAR, index_name, MAX_INFO_STRING, &index_name_len); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = indx_stmt->errormsg; /* "Couldn't bind column * in SQLStatistics."; */ stmt->errornumber = indx_stmt->errornumber; - SQLFreeStmt(hindx_stmt, SQL_DROP); + PGAPI_FreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } /* bind the vector column */ - result = SQLBindCol(hindx_stmt, 2, SQL_C_DEFAULT, + result = PGAPI_BindCol(hindx_stmt, 2, SQL_C_DEFAULT, fields_vector, 32, &fields_vector_len); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = indx_stmt->errormsg; /* "Couldn't bind column * in SQLStatistics."; */ stmt->errornumber = indx_stmt->errornumber; - SQLFreeStmt(hindx_stmt, SQL_DROP); + PGAPI_FreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } /* bind the "is unique" column */ - result = SQLBindCol(hindx_stmt, 3, SQL_C_CHAR, + result = PGAPI_BindCol(hindx_stmt, 3, SQL_C_CHAR, isunique, sizeof(isunique), NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = indx_stmt->errormsg; /* "Couldn't bind column * in SQLStatistics."; */ stmt->errornumber = indx_stmt->errornumber; - SQLFreeStmt(hindx_stmt, SQL_DROP); + PGAPI_FreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } /* bind the "is clustered" column */ - result = SQLBindCol(hindx_stmt, 4, SQL_C_CHAR, + result = PGAPI_BindCol(hindx_stmt, 4, SQL_C_CHAR, isclustered, sizeof(isclustered), NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = indx_stmt->errormsg; /* "Couldn't bind column * in SQLStatistics."; */ stmt->errornumber = indx_stmt->errornumber; - SQLFreeStmt(hindx_stmt, SQL_DROP); + PGAPI_FreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } /* bind the "is hash" column */ - result = SQLBindCol(hindx_stmt, 5, SQL_C_CHAR, + result = PGAPI_BindCol(hindx_stmt, 5, SQL_C_CHAR, ishash, sizeof(ishash), NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = indx_stmt->errormsg; /* "Couldn't bind column * in SQLStatistics."; */ stmt->errornumber = indx_stmt->errornumber; - SQLFreeStmt(hindx_stmt, SQL_DROP); + PGAPI_FreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } - result = SQLBindCol(hindx_stmt, 6, SQL_C_CHAR, + result = PGAPI_BindCol(hindx_stmt, 6, SQL_C_CHAR, relhasrules, MAX_INFO_STRING, NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = indx_stmt->errormsg; stmt->errornumber = indx_stmt->errornumber; - SQLFreeStmt(hindx_stmt, SQL_DROP); + PGAPI_FreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } @@ -2292,7 +2328,7 @@ SQLStatistics( QR_add_tuple(stmt->result, row); } - result = SQLFetch(hindx_stmt); + result = PGAPI_Fetch(hindx_stmt); while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) { /* If only requesting unique indexs, then just return those. */ @@ -2333,17 +2369,17 @@ SQLStatistics( if (fields_vector[i] == OID_ATTNUM) { set_tuplefield_string(&row->tuple[8], "oid"); - mylog("SQLStatistics: column name = oid\n"); + mylog("%s: column name = oid\n", func); } else if (fields_vector[i] < 0 || fields_vector[i] > total_columns) { set_tuplefield_string(&row->tuple[8], "UNKNOWN"); - mylog("SQLStatistics: column name = UNKNOWN\n"); + mylog("%s: column name = UNKNOWN\n", func); } else { set_tuplefield_string(&row->tuple[8], column_names[fields_vector[i] - 1]); - mylog("SQLStatistics: column name = '%s'\n", column_names[fields_vector[i] - 1]); + mylog("%s: column name = '%s'\n", func, column_names[fields_vector[i] - 1]); } set_tuplefield_string(&row->tuple[9], "A"); @@ -2356,18 +2392,18 @@ SQLStatistics( } } - result = SQLFetch(hindx_stmt); + result = PGAPI_Fetch(hindx_stmt); } if (result != SQL_NO_DATA_FOUND) { /* "SQLFetch failed in SQLStatistics."; */ stmt->errormsg = SC_create_errormsg(hindx_stmt); stmt->errornumber = indx_stmt->errornumber; - SQLFreeStmt(hindx_stmt, SQL_DROP); + PGAPI_FreeStmt(hindx_stmt, SQL_DROP); goto SEEYA; } - SQLFreeStmt(hindx_stmt, SQL_DROP); + PGAPI_FreeStmt(hindx_stmt, SQL_DROP); /* * also, things need to think that this statement is finished so the @@ -2389,7 +2425,7 @@ SEEYA: free(column_names[i]); free(column_names); - mylog("SQLStatistics(): EXIT, %s, stmt=%u\n", error ? "error" : "success", stmt); + mylog("%s: EXIT, %s, stmt=%u\n", func, error ? "error" : "success", stmt); if (error) { @@ -2402,7 +2438,7 @@ SEEYA: RETCODE SQL_API -SQLColumnPrivileges( +PGAPI_ColumnPrivileges( HSTMT hstmt, UCHAR FAR *szTableQualifier, SWORD cbTableQualifier, @@ -2413,7 +2449,7 @@ SQLColumnPrivileges( UCHAR FAR *szColumnName, SWORD cbColumnName) { - static char *func = "SQLColumnPrivileges"; + static char *func = "PGAPI_ColumnPrivileges"; mylog("%s: entering...\n", func); @@ -2430,7 +2466,7 @@ SQLColumnPrivileges( * Retrieve the primary key columns for the specified table. */ RETCODE SQL_API -SQLPrimaryKeys( +PGAPI_PrimaryKeys( HSTMT hstmt, UCHAR FAR *szTableQualifier, SWORD cbTableQualifier, @@ -2439,7 +2475,7 @@ SQLPrimaryKeys( UCHAR FAR *szTableName, SWORD cbTableName) { - static char *func = "SQLPrimaryKeys"; + static char *func = "PGAPI_PrimaryKeys"; StatementClass *stmt = (StatementClass *) hstmt; ConnectionClass *conn; TupleNode *row; @@ -2467,7 +2503,7 @@ SQLPrimaryKeys( stmt->result = QR_Constructor(); if (!stmt->result) { - stmt->errormsg = "Couldn't allocate memory for SQLPrimaryKeys result."; + stmt->errormsg = "Couldn't allocate memory for PGAPI_PrimaryKeys result."; stmt->errornumber = STMT_NO_MEMORY_ERROR; SC_log_error(func, "", stmt); return SQL_ERROR; @@ -2492,7 +2528,7 @@ SQLPrimaryKeys( QR_set_field_info(stmt->result, 5, "PK_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); - result = SQLAllocStmt(stmt->hdbc, &htbl_stmt); + result = PGAPI_AllocStmt(stmt->hdbc, &htbl_stmt); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errornumber = STMT_NO_MEMORY_ERROR; @@ -2506,21 +2542,21 @@ SQLPrimaryKeys( make_string(szTableName, cbTableName, pktab); if (pktab[0] == '\0') { - stmt->errormsg = "No Table specified to SQLPrimaryKeys."; + stmt->errormsg = "No Table specified to PGAPI_PrimaryKeys."; stmt->errornumber = STMT_INTERNAL_ERROR; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(htbl_stmt, 1, SQL_C_CHAR, + result = PGAPI_BindCol(htbl_stmt, 1, SQL_C_CHAR, attname, MAX_INFO_STRING, &attname_len); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = tbl_stmt->errormsg; stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } @@ -2563,19 +2599,19 @@ SQLPrimaryKeys( " order by ia.attnum", pktab); break; } - mylog("SQLPrimaryKeys: tables_query='%s'\n", tables_query); + mylog("%s: tables_query='%s'\n", func, tables_query); - result = SQLExecDirect(htbl_stmt, tables_query, strlen(tables_query)); + result = PGAPI_ExecDirect(htbl_stmt, tables_query, strlen(tables_query)); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = SC_create_errormsg(htbl_stmt); stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLFetch(htbl_stmt); + result = PGAPI_Fetch(htbl_stmt); if (result != SQL_NO_DATA_FOUND) break; } @@ -2602,7 +2638,7 @@ SQLPrimaryKeys( mylog(">> primaryKeys: pktab = '%s', attname = '%s', seq = %d\n", pktab, attname, seq); - result = SQLFetch(htbl_stmt); + result = PGAPI_Fetch(htbl_stmt); } if (result != SQL_NO_DATA_FOUND) @@ -2610,11 +2646,11 @@ SQLPrimaryKeys( stmt->errormsg = SC_create_errormsg(htbl_stmt); stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); /* @@ -2628,13 +2664,13 @@ SQLPrimaryKeys( stmt->rowset_start = -1; stmt->current_col = -1; - mylog("SQLPrimaryKeys(): EXIT, stmt=%u\n", stmt); + mylog("%s: EXIT, stmt=%u\n", func, stmt); return SQL_SUCCESS; } RETCODE SQL_API -SQLForeignKeys( +PGAPI_ForeignKeys( HSTMT hstmt, UCHAR FAR *szPkTableQualifier, SWORD cbPkTableQualifier, @@ -2649,7 +2685,7 @@ SQLForeignKeys( UCHAR FAR *szFkTableName, SWORD cbFkTableName) { - static char *func = "SQLForeignKeys"; + static char *func = "PGAPI_ForeignKeys"; StatementClass *stmt = (StatementClass *) hstmt; TupleNode *row; HSTMT htbl_stmt, @@ -2698,7 +2734,7 @@ SQLForeignKeys( stmt->result = QR_Constructor(); if (!stmt->result) { - stmt->errormsg = "Couldn't allocate memory for SQLForeignKeys result."; + stmt->errormsg = "Couldn't allocate memory for PGAPI_ForeignKeys result."; stmt->errornumber = STMT_NO_MEMORY_ERROR; SC_log_error(func, "", stmt); return SQL_ERROR; @@ -2745,11 +2781,11 @@ SQLForeignKeys( stmt->current_col = -1; - result = SQLAllocStmt(stmt->hdbc, &htbl_stmt); + result = PGAPI_AllocStmt(stmt->hdbc, &htbl_stmt); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Couldn't allocate statement for SQLForeignKeys result."; + stmt->errormsg = "Couldn't allocate statement for PGAPI_ForeignKeys result."; SC_log_error(func, "", stmt); return SQL_ERROR; } @@ -2798,84 +2834,84 @@ SQLForeignKeys( "AND (pg_trigger_1.tgconstrname=pt.tgconstrname))", fk_table_needed); - result = SQLExecDirect(htbl_stmt, tables_query, strlen(tables_query)); + result = PGAPI_ExecDirect(htbl_stmt, tables_query, strlen(tables_query)); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = SC_create_errormsg(htbl_stmt); stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(htbl_stmt, 1, SQL_C_BINARY, + result = PGAPI_BindCol(htbl_stmt, 1, SQL_C_BINARY, trig_args, sizeof(trig_args), NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = tbl_stmt->errormsg; stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(htbl_stmt, 2, SQL_C_SHORT, + result = PGAPI_BindCol(htbl_stmt, 2, SQL_C_SHORT, &trig_nargs, 0, NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = tbl_stmt->errormsg; stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(htbl_stmt, 3, SQL_C_CHAR, + result = PGAPI_BindCol(htbl_stmt, 3, SQL_C_CHAR, trig_deferrable, sizeof(trig_deferrable), NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = tbl_stmt->errormsg; stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(htbl_stmt, 4, SQL_C_CHAR, + result = PGAPI_BindCol(htbl_stmt, 4, SQL_C_CHAR, trig_initdeferred, sizeof(trig_initdeferred), NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = tbl_stmt->errormsg; stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(htbl_stmt, 5, SQL_C_CHAR, + result = PGAPI_BindCol(htbl_stmt, 5, SQL_C_CHAR, upd_rule, sizeof(upd_rule), NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = tbl_stmt->errormsg; stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(htbl_stmt, 6, SQL_C_CHAR, + result = PGAPI_BindCol(htbl_stmt, 6, SQL_C_CHAR, del_rule, sizeof(del_rule), NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = tbl_stmt->errormsg; stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLFetch(htbl_stmt); + result = PGAPI_Fetch(htbl_stmt); if (result == SQL_NO_DATA_FOUND) return SQL_SUCCESS; @@ -2884,27 +2920,27 @@ SQLForeignKeys( stmt->errormsg = SC_create_errormsg(htbl_stmt); stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - keyresult = SQLAllocStmt(stmt->hdbc, &hpkey_stmt); + keyresult = PGAPI_AllocStmt(stmt->hdbc, &hpkey_stmt); if ((keyresult != SQL_SUCCESS) && (keyresult != SQL_SUCCESS_WITH_INFO)) { stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Couldn't allocate statement for SQLForeignKeys (pkeys) result."; + stmt->errormsg = "Couldn't allocate statement for PGAPI_ForeignKeys (pkeys) result."; SC_log_error(func, "", stmt); return SQL_ERROR; } - keyresult = SQLBindCol(hpkey_stmt, 4, SQL_C_CHAR, + keyresult = PGAPI_BindCol(hpkey_stmt, 4, SQL_C_CHAR, pkey, sizeof(pkey), NULL); if (keyresult != SQL_SUCCESS) { stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Couldn't bindcol for primary keys for SQLForeignKeys result."; + stmt->errormsg = "Couldn't bindcol for primary keys for PGAPI_ForeignKeys result."; SC_log_error(func, "", stmt); - SQLFreeStmt(hpkey_stmt, SQL_DROP); + PGAPI_FreeStmt(hpkey_stmt, SQL_DROP); return SQL_ERROR; } @@ -2927,23 +2963,23 @@ SQLForeignKeys( /* If it doesn't match, then continue */ if (strcmp(pk_table, pk_table_needed)) { - result = SQLFetch(htbl_stmt); + result = PGAPI_Fetch(htbl_stmt); continue; } } - keyresult = SQLPrimaryKeys(hpkey_stmt, NULL, 0, NULL, 0, pk_table, SQL_NTS); + keyresult = PGAPI_PrimaryKeys(hpkey_stmt, NULL, 0, NULL, 0, pk_table, SQL_NTS); if (keyresult != SQL_SUCCESS) { stmt->errornumber = STMT_NO_MEMORY_ERROR; - stmt->errormsg = "Couldn't get primary keys for SQLForeignKeys result."; + stmt->errormsg = "Couldn't get primary keys for PGAPI_ForeignKeys result."; SC_log_error(func, "", stmt); - SQLFreeStmt(hpkey_stmt, SQL_DROP); + PGAPI_FreeStmt(hpkey_stmt, SQL_DROP); return SQL_ERROR; } /* Check that the key listed is the primary key */ - keyresult = SQLFetch(hpkey_stmt); + keyresult = PGAPI_Fetch(hpkey_stmt); /* Get to first primary key */ pkey_ptr = trig_args; @@ -2962,7 +2998,7 @@ SQLForeignKeys( for (k = 0; k < 2; k++) pkey_ptr += strlen(pkey_ptr) + 1; - keyresult = SQLFetch(hpkey_stmt); + keyresult = PGAPI_Fetch(hpkey_stmt); } /* Set to first fk column */ @@ -3045,9 +3081,9 @@ SQLForeignKeys( } } - result = SQLFetch(htbl_stmt); + result = PGAPI_Fetch(htbl_stmt); } - SQLFreeStmt(hpkey_stmt, SQL_DROP); + PGAPI_FreeStmt(hpkey_stmt, SQL_DROP); } /* @@ -3087,83 +3123,83 @@ SQLForeignKeys( " )", pk_table_needed); - result = SQLExecDirect(htbl_stmt, tables_query, strlen(tables_query)); + result = PGAPI_ExecDirect(htbl_stmt, tables_query, strlen(tables_query)); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = SC_create_errormsg(htbl_stmt); stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(htbl_stmt, 1, SQL_C_BINARY, + result = PGAPI_BindCol(htbl_stmt, 1, SQL_C_BINARY, trig_args, sizeof(trig_args), NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = tbl_stmt->errormsg; stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(htbl_stmt, 2, SQL_C_SHORT, + result = PGAPI_BindCol(htbl_stmt, 2, SQL_C_SHORT, &trig_nargs, 0, NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = tbl_stmt->errormsg; stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(htbl_stmt, 3, SQL_C_CHAR, + result = PGAPI_BindCol(htbl_stmt, 3, SQL_C_CHAR, trig_deferrable, sizeof(trig_deferrable), NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = tbl_stmt->errormsg; stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(htbl_stmt, 4, SQL_C_CHAR, + result = PGAPI_BindCol(htbl_stmt, 4, SQL_C_CHAR, trig_initdeferred, sizeof(trig_initdeferred), NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = tbl_stmt->errormsg; stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(htbl_stmt, 5, SQL_C_CHAR, + result = PGAPI_BindCol(htbl_stmt, 5, SQL_C_CHAR, upd_rule, sizeof(upd_rule), NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = tbl_stmt->errormsg; stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLBindCol(htbl_stmt, 6, SQL_C_CHAR, + result = PGAPI_BindCol(htbl_stmt, 6, SQL_C_CHAR, del_rule, sizeof(del_rule), NULL); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { stmt->errormsg = tbl_stmt->errormsg; stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - result = SQLFetch(htbl_stmt); + result = PGAPI_Fetch(htbl_stmt); if (result == SQL_NO_DATA_FOUND) return SQL_SUCCESS; @@ -3172,7 +3208,7 @@ SQLForeignKeys( stmt->errormsg = SC_create_errormsg(htbl_stmt); stmt->errornumber = tbl_stmt->errornumber; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } @@ -3273,27 +3309,27 @@ SQLForeignKeys( fkey_ptr += strlen(fkey_ptr) + 1; } } - result = SQLFetch(htbl_stmt); + result = PGAPI_Fetch(htbl_stmt); } } else { - stmt->errormsg = "No tables specified to SQLForeignKeys."; + stmt->errormsg = "No tables specified to PGAPI_ForeignKeys."; stmt->errornumber = STMT_INTERNAL_ERROR; SC_log_error(func, "", stmt); - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); return SQL_ERROR; } - SQLFreeStmt(htbl_stmt, SQL_DROP); + PGAPI_FreeStmt(htbl_stmt, SQL_DROP); - mylog("SQLForeignKeys(): EXIT, stmt=%u\n", stmt); + mylog("PGAPI_ForeignKeys(): EXIT, stmt=%u\n", stmt); return SQL_SUCCESS; } RETCODE SQL_API -SQLProcedureColumns( +PGAPI_ProcedureColumns( HSTMT hstmt, UCHAR FAR *szProcQualifier, SWORD cbProcQualifier, @@ -3304,7 +3340,7 @@ SQLProcedureColumns( UCHAR FAR *szColumnName, SWORD cbColumnName) { - static char *func = "SQLProcedureColumns"; + static char *func = "PGAPI_ProcedureColumns"; mylog("%s: entering...\n", func); @@ -3314,7 +3350,7 @@ SQLProcedureColumns( RETCODE SQL_API -SQLProcedures( +PGAPI_Procedures( HSTMT hstmt, UCHAR FAR *szProcQualifier, SWORD cbProcQualifier, @@ -3323,7 +3359,7 @@ SQLProcedures( UCHAR FAR *szProcName, SWORD cbProcName) { - static char *func = "SQLProcedures"; + static char *func = "PGAPI_Procedures"; mylog("%s: entering...\n", func); @@ -3333,7 +3369,7 @@ SQLProcedures( RETCODE SQL_API -SQLTablePrivileges( +PGAPI_TablePrivileges( HSTMT hstmt, UCHAR FAR *szTableQualifier, SWORD cbTableQualifier, @@ -3342,10 +3378,29 @@ SQLTablePrivileges( UCHAR FAR *szTableName, SWORD cbTableName) { - static char *func = "SQLTablePrivileges"; + StatementClass *stmt = (StatementClass *) hstmt; + static char *func = "PGAPI_TablePrivileges"; + Int2 result_cols; mylog("%s: entering...\n", func); + /* + * a statement is actually executed, so we'll have to do this + * ourselves. + */ + result_cols = 7; + extend_bindings(stmt, result_cols); + + /* set the field names */ + QR_set_num_fields(stmt->result, result_cols); + QR_set_field_info(stmt->result, 0, "TABLE_CAT", PG_TYPE_TEXT, MAX_INFO_STRING); + QR_set_field_info(stmt->result, 1, "TABLE_SCHEM", PG_TYPE_TEXT, MAX_INFO_STRING); + QR_set_field_info(stmt->result, 2, "TABLE_NAME", PG_TYPE_TEXT, MAX_INFO_STRING); + QR_set_field_info(stmt->result, 3, "GRANTOR", PG_TYPE_TEXT, MAX_INFO_STRING); + QR_set_field_info(stmt->result, 4, "GRANTEE", PG_TYPE_TEXT, MAX_INFO_STRING); + QR_set_field_info(stmt->result, 5, "PRIVILEGE", PG_TYPE_TEXT, MAX_INFO_STRING); + QR_set_field_info(stmt->result, 6, "IS_GRANTABLE", PG_TYPE_TEXT, MAX_INFO_STRING); + SC_log_error(func, "Function not implemented", (StatementClass *) hstmt); return SQL_ERROR; } diff --git a/src/interfaces/odbc/options.c b/src/interfaces/odbc/options.c index 5e373f8bef..82b651cdc5 100644 --- a/src/interfaces/odbc/options.c +++ b/src/interfaces/odbc/options.c @@ -34,6 +34,7 @@ #include "connection.h" #include "statement.h" #include "qresult.h" +#include "pgapifunc.h" extern GLOBAL_VALUES globals; @@ -72,34 +73,23 @@ set_statement_option(ConnectionClass *conn, * positioned update isn't supported so cursor concurrency is * read-only */ - if (conn) - conn->stmtOptions.scroll_concurrency = vParam; - if (stmt) - stmt->options.scroll_concurrency = vParam; - break; - - /*---------- - * if (globals.lie) - * { - * if (conn) - * conn->stmtOptions.scroll_concurrency = vParam; - * if (stmt) - * stmt->options.scroll_concurrency = vParam; - * } else { - * if (conn) - * conn->stmtOptions.scroll_concurrency = - * SQL_CONCUR_READ_ONLY; - * if (stmt) - * stmt->options.scroll_concurrency = - * SQL_CONCUR_READ_ONLY; - * - * if (vParam != SQL_CONCUR_READ_ONLY) - * changed = TRUE; - * } - * break; - * } - *---------- - */ + mylog("SetStmtOption(): SQL_CONCURRENCY = %d\n", vParam); + if (globals.lie || vParam == SQL_CONCUR_READ_ONLY || vParam == SQL_CONCUR_ROWVER) + { + if (conn) + conn->stmtOptions.scroll_concurrency = vParam; + if (stmt) + stmt->options.scroll_concurrency = vParam; + } + else + { + if (conn) + conn->stmtOptions.scroll_concurrency = SQL_CONCUR_ROWVER; + if (stmt) + stmt->options.scroll_concurrency = SQL_CONCUR_ROWVER; + changed = TRUE; + } + break; case SQL_CURSOR_TYPE: @@ -296,19 +286,18 @@ set_statement_option(ConnectionClass *conn, /* Implements only SQL_AUTOCOMMIT */ RETCODE SQL_API -SQLSetConnectOption( +PGAPI_SetConnectOption( HDBC hdbc, UWORD fOption, UDWORD vParam) { - static char *func = "SQLSetConnectOption"; + static char *func = "PGAPI_SetConnectOption"; ConnectionClass *conn = (ConnectionClass *) hdbc; char changed = FALSE; RETCODE retval; int i; - mylog("%s: entering...\n", func); - + mylog("%s: entering fOption = %d vParam = %d\n", func, fOption, vParam); if (!conn) { CC_log_error(func, "", NULL); @@ -372,7 +361,7 @@ SQLSetConnectOption( return SQL_ERROR; } - mylog("SQLSetConnectOption: AUTOCOMMIT: transact_status=%d, vparam=%d\n", conn->transact_status, vParam); + mylog("PGAPI_SetConnectOption: AUTOCOMMIT: transact_status=%d, vparam=%d\n", conn->transact_status, vParam); switch (vParam) { @@ -441,12 +430,12 @@ SQLSetConnectOption( /* This function just can tell you whether you are in Autcommit mode or not */ RETCODE SQL_API -SQLGetConnectOption( +PGAPI_GetConnectOption( HDBC hdbc, UWORD fOption, PTR pvParam) { - static char *func = "SQLGetConnectOption"; + static char *func = "PGAPI_GetConnectOption"; ConnectionClass *conn = (ConnectionClass *) hdbc; mylog("%s: entering...\n", func); @@ -517,12 +506,12 @@ SQLGetConnectOption( RETCODE SQL_API -SQLSetStmtOption( +PGAPI_SetStmtOption( HSTMT hstmt, UWORD fOption, UDWORD vParam) { - static char *func = "SQLSetStmtOption"; + static char *func = "PGAPI_SetStmtOption"; StatementClass *stmt = (StatementClass *) hstmt; mylog("%s: entering...\n", func); @@ -543,12 +532,12 @@ SQLSetStmtOption( RETCODE SQL_API -SQLGetStmtOption( +PGAPI_GetStmtOption( HSTMT hstmt, UWORD fOption, PTR pvParam) { - static char *func = "SQLGetStmtOption"; + static char *func = "PGAPI_GetStmtOption"; StatementClass *stmt = (StatementClass *) hstmt; QResultClass *res; diff --git a/src/interfaces/odbc/parse.c b/src/interfaces/odbc/parse.c index 6c583b0a05..8916db2072 100644 --- a/src/interfaces/odbc/parse.c +++ b/src/interfaces/odbc/parse.c @@ -34,6 +34,7 @@ #include "connection.h" #include "qresult.h" #include "pgtypes.h" +#include "pgapifunc.h" #ifdef MULTIBYTE #include "multibyte.h" @@ -75,7 +76,7 @@ getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dqu i++; } - if (s[0] == '\0') + if (s[i] == '\0') { token[0] = '\0'; return NULL; @@ -92,6 +93,13 @@ getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dqu while (!isspace((unsigned char) s[i]) && s[i] != ',' && s[i] != '\0' && out != smax) { +#ifdef MULTIBYTE + if (multibyte_char_check(s[i]) != 0) + { + token[out++] = s[i++]; + continue; + } +#endif /* Handle quoted stuff */ if (out == 0 && (s[i] == '\"' || s[i] == '\'')) { @@ -110,15 +118,17 @@ getNextToken(char *s, char *token, int smax, char *delim, char *quote, char *dqu i++; /* dont return the quote */ while (s[i] != '\0' && out != smax) { +#ifdef MULTIBYTE + if (multibyte_char_check(s[i]) != 0) + { + token[out++] = s[i++]; + continue; + } +#endif if (s[i] == qc && !in_escape) break; -#ifdef MULTIBYTE - if (multibyte_char_check(s[i]) == 0 && s[i] == '\\' && !in_escape) - { -#else if (s[i] == '\\' && !in_escape) { -#endif in_escape = TRUE; } else @@ -269,11 +279,12 @@ parse_statement(StatementClass *stmt) dquote, numeric, unquoted; - char *ptr; + char *ptr, *pptr = NULL; char in_select = FALSE, in_distinct = FALSE, in_on = FALSE, in_from = FALSE, + from_found = FALSE, in_where = FALSE, in_table = FALSE; char in_field = FALSE, @@ -285,6 +296,7 @@ parse_statement(StatementClass *stmt) i, k = 0, n, + first_where = 0, blevel = 0; FIELD_INFO **fi; TABLE_INFO **ti; @@ -303,12 +315,107 @@ parse_statement(StatementClass *stmt) stmt->nfld = 0; stmt->ntab = 0; - while ((ptr = getNextToken(ptr, token, sizeof(token), &delim, "e, &dquote, &numeric)) != NULL) +#ifdef MULTIBYTE + multibyte_init(); +#endif + while (pptr = ptr, (ptr = getNextToken(pptr, token, sizeof(token), &delim, "e, &dquote, &numeric)) != NULL) { unquoted = !(quote || dquote); mylog("unquoted=%d, quote=%d, dquote=%d, numeric=%d, delim='%c', token='%s', ptr='%s'\n", unquoted, quote, dquote, numeric, delim, token, ptr); + if (in_select && unquoted && blevel == 0) + { + if (!stricmp(token, "distinct")) + { + in_distinct = TRUE; + + mylog("DISTINCT\n"); + continue; + } + if (!stricmp(token, "into")) + { + in_select = FALSE; + mylog("INTO\n"); + stmt->statement_type = STMT_TYPE_CREATE; + stmt->parse_status = STMT_PARSE_FATAL; + return FALSE; + } + if (!stricmp(token, "from")) + { + in_select = FALSE; + in_from = TRUE; + if (!from_found && + (!strnicmp(pptr, "from", 4))) + { + mylog("First "); + from_found = TRUE; + } + + mylog("FROM\n"); + continue; + } + } + if (unquoted && blevel == 0) + { + if ((!stricmp(token, "where") || + !stricmp(token, "union") || + !stricmp(token, "intersect") || + !stricmp(token, "except") || + !stricmp(token, "order") || + !stricmp(token, "group") || + !stricmp(token, "having"))) + { + in_select = FALSE; + in_from = FALSE; + in_where = TRUE; + + if (!first_where && + (!stricmp(token, "where"))) + first_where = ptr - stmt->statement; + + mylog("WHERE...\n"); + break; + } + } + if (in_select && (in_expr || in_func)) + { + /* just eat the expression */ + mylog("in_expr=%d or func=%d\n", in_expr, in_func); + if (!unquoted) + continue; + + if (token[0] == '(') + { + blevel++; + mylog("blevel++ = %d\n", blevel); + } + else if (token[0] == ')') + { + blevel--; + mylog("blevel-- = %d\n", blevel); + } + if (blevel == 0) + { + if (delim == ',') + { + mylog("**** Got comma in_expr/func\n"); + in_func = FALSE; + in_expr = FALSE; + in_field = FALSE; + } + else if (!stricmp(token, "as")) + { + mylog("got AS in_expr\n"); + in_func = FALSE; + in_expr = FALSE; + in_as = TRUE; + in_field = TRUE; + } + } + continue; + } + if (unquoted && !stricmp(token, "select")) { in_select = TRUE; @@ -316,46 +423,6 @@ parse_statement(StatementClass *stmt) mylog("SELECT\n"); continue; } - - if (unquoted && in_select && !stricmp(token, "distinct")) - { - in_distinct = TRUE; - - mylog("DISTINCT\n"); - continue; - } - - if (unquoted && !stricmp(token, "into")) - { - in_select = FALSE; - - mylog("INTO\n"); - continue; - } - - if (unquoted && !stricmp(token, "from")) - { - in_select = FALSE; - in_from = TRUE; - - mylog("FROM\n"); - continue; - } - - if (unquoted && (!stricmp(token, "where") || - !stricmp(token, "union") || - !stricmp(token, "order") || - !stricmp(token, "group") || - !stricmp(token, "having"))) - { - in_select = FALSE; - in_from = FALSE; - in_where = TRUE; - - mylog("WHERE...\n"); - break; - } - if (in_select) { if (in_distinct) @@ -378,41 +445,6 @@ parse_statement(StatementClass *stmt) in_distinct = FALSE; } - if (in_expr || in_func) - { - /* just eat the expression */ - mylog("in_expr=%d or func=%d\n", in_expr, in_func); - if (quote || dquote) - continue; - - if (in_expr && blevel == 0 && delim == ',') - { - mylog("**** in_expr and Got comma\n"); - in_expr = FALSE; - in_field = FALSE; - } - else if (token[0] == '(') - { - blevel++; - mylog("blevel++ = %d\n", blevel); - } - else if (token[0] == ')') - { - blevel--; - mylog("blevel-- = %d\n", blevel); - } - if (blevel == 0) - { - if (delim == ',') - { - in_func = FALSE; - in_expr = FALSE; - in_field = FALSE; - } - } - continue; - } - if (!in_field) { if (!token[0]) @@ -447,6 +479,7 @@ parse_statement(StatementClass *stmt) if (quote) { fi[stmt->nfld++]->quote = TRUE; +in_expr = TRUE; continue; } else if (numeric) @@ -619,8 +652,12 @@ parse_statement(StatementClass *stmt) else if (fi[i]->quote) { /* handle as text */ fi[i]->ti = NULL; + /* fi[i]->type = PG_TYPE_TEXT; fi[i]->precision = 0; + the following may be better */ + fi[i]->type = PG_TYPE_UNKNOWN; + fi[i]->precision = 254; continue; } /* it's a dot, resolve to table or alias */ @@ -680,12 +717,12 @@ parse_statement(StatementClass *stmt) if (!found) { - mylog("PARSE: Getting SQLColumns for table[%d]='%s'\n", i, ti[i]->name); + mylog("PARSE: Getting PG_Columns for table[%d]='%s'\n", i, ti[i]->name); - result = SQLAllocStmt(stmt->hdbc, &hcol_stmt); + result = PGAPI_AllocStmt(stmt->hdbc, &hcol_stmt); if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { - stmt->errormsg = "SQLAllocStmt failed in parse_statement for columns."; + stmt->errormsg = "PGAPI_AllocStmt failed in parse_statement for columns."; stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->parse_status = STMT_PARSE_FATAL; return FALSE; @@ -694,10 +731,10 @@ parse_statement(StatementClass *stmt) col_stmt = (StatementClass *) hcol_stmt; col_stmt->internal = TRUE; - result = SQLColumns(hcol_stmt, "", 0, "", 0, + result = PGAPI_Columns(hcol_stmt, "", 0, "", 0, ti[i]->name, (SWORD) strlen(ti[i]->name), "", 0); - mylog(" Past SQLColumns\n"); + mylog(" Past PG_Columns\n"); if (result == SQL_SUCCESS) { mylog(" Success\n"); @@ -736,12 +773,12 @@ parse_statement(StatementClass *stmt) conn->ntables++; - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); mylog("Created col_info table='%s', ntables=%d\n", ti[i]->name, conn->ntables); } else { - SQLFreeStmt(hcol_stmt, SQL_DROP); + PGAPI_FreeStmt(hcol_stmt, SQL_DROP); break; } } @@ -751,7 +788,7 @@ parse_statement(StatementClass *stmt) mylog("associate col_info: i=%d, k=%d\n", i, k); } - mylog("Done SQLColumns\n"); + mylog("Done PG_Columns\n"); /* * Now resolve the fields to point to column info diff --git a/src/interfaces/odbc/pgtypes.c b/src/interfaces/odbc/pgtypes.c index ca6b7a2387..83f9574d2a 100644 --- a/src/interfaces/odbc/pgtypes.c +++ b/src/interfaces/odbc/pgtypes.c @@ -329,7 +329,8 @@ pgtype_to_name(StatementClass *stmt, Int4 type) { switch (type) { - case PG_TYPE_CHAR:return "char"; + case PG_TYPE_CHAR: + return "char"; case PG_TYPE_CHAR2: return "char2"; case PG_TYPE_CHAR4: @@ -399,7 +400,7 @@ getNumericScale(StatementClass *stmt, Int4 type, int col) QResultClass *result; ColumnInfoClass *flds; - mylog("getNumericScale: type=%d, col=%d, unknown = %d\n", type, col); + mylog("getNumericScale: type=%d, col=%d\n", type, col); if (col < 0) return PG_NUMERIC_MAX_SCALE; @@ -436,7 +437,7 @@ getNumericPrecision(StatementClass *stmt, Int4 type, int col) QResultClass *result; ColumnInfoClass *flds; - mylog("getNumericPrecision: type=%d, col=%d, unknown = %d\n", type, col); + mylog("getNumericPrecision: type=%d, col=%d\n", type, col); if (col < 0) return PG_NUMERIC_MAX_PRECISION; @@ -598,7 +599,8 @@ pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_si case PG_TYPE_ABSTIME: case PG_TYPE_DATETIME: case PG_TYPE_TIMESTAMP: - return 19; + /*return 19;*/ +return 21; case PG_TYPE_BOOL: return 1; diff --git a/src/interfaces/odbc/psqlodbc.def b/src/interfaces/odbc/psqlodbc.def index 23a5a82b39..25cd554745 100644 --- a/src/interfaces/odbc/psqlodbc.def +++ b/src/interfaces/odbc/psqlodbc.def @@ -53,6 +53,28 @@ SQLSetPos @68 SQLSetScrollOptions @69 SQLTablePrivileges @70 SQLBindParameter @72 + +SQLAllocHandle @80 +SQLBindParam @81 +SQLCloseCursor @82 +SQLColAttribute @83 +SQLCopyDesc @84 +SQLEndTran @85 +SQLFetchScroll @86 +SQLFreeHandle @87 +SQLGetDescField @88 +SQLGetDescRec @89 +SQLGetDiagField @90 +SQLGetDiagRec @91 +SQLGetEnvAttr @92 +SQLGetConnectAttr @93 +SQLGetStmtAttr @94 +SQLSetConnectAttr @95 +SQLSetDescField @96 +SQLSetDescRec @97 +SQLSetEnvAttr @98 +SQLSetStmtAttr @99 + SQLDummyOrdinal @199 dconn_FDriverConnectProc @200 DllMain @201 diff --git a/src/interfaces/odbc/psqlodbc.h b/src/interfaces/odbc/psqlodbc.h index 156ec458c2..df07710651 100644 --- a/src/interfaces/odbc/psqlodbc.h +++ b/src/interfaces/odbc/psqlodbc.h @@ -5,7 +5,7 @@ * * Comments: See "notice.txt" for copyright and license information. * - * $Id: psqlodbc.h,v 1.44 2001/06/27 07:38:07 inoue Exp $ + * $Id: psqlodbc.h,v 1.45 2001/08/18 04:30:47 inoue Exp $ * */ @@ -163,6 +163,9 @@ typedef struct StatementOptions_ int bind_size; /* size of each structure if using Row * Binding */ int use_bookmarks; + UInt4 *rowsFetched; + UInt2 *rowStatusArray; + void *bookmark_ptr; } StatementOptions; /* Used to pass extra query info to send_query */ diff --git a/src/interfaces/odbc/qresult.c b/src/interfaces/odbc/qresult.c index 9baecee7dc..086f4b8752 100644 --- a/src/interfaces/odbc/qresult.c +++ b/src/interfaces/odbc/qresult.c @@ -290,6 +290,7 @@ QR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor) QR_set_message(self, "Could not get memory for tuple cache."); return FALSE; } + self->count_allocated = tuple_size; self->inTuples = TRUE; @@ -464,7 +465,8 @@ QR_next_tuple(QResultClass *self) self->fetch_count++; } - self->backend_tuples = (TupleField *) realloc(self->backend_tuples, self->num_fields * sizeof(TupleField) * self->cache_size); + if (self->cache_size > self->count_allocated) + self->backend_tuples = (TupleField *) realloc(self->backend_tuples, self->num_fields * sizeof(TupleField) * self->cache_size); if (!self->backend_tuples) { self->status = PGRES_FATAL_ERROR; @@ -524,19 +526,21 @@ QR_next_tuple(QResultClass *self) case 'B': /* Tuples in binary format */ case 'D': /* Tuples in ASCII format */ - if (!globals.use_declarefetch && self->fcount > 0 && !(self->fcount % TUPLE_MALLOC_INC)) + if (!globals.use_declarefetch && self->fcount >= self->count_allocated) { - size_t old_size = self->fcount * self->num_fields * sizeof(TupleField); + int tuple_size = self->count_allocated; - mylog("REALLOC: old_size = %d\n", old_size); - - self->backend_tuples = (TupleField *) realloc(self->backend_tuples, old_size + (self->num_fields * sizeof(TupleField) * TUPLE_MALLOC_INC)); + mylog("REALLOC: old_count = %d, size = %d\n", tuple_size, self->num_fields * sizeof(TupleField) * tuple_size); + tuple_size *= 2; + self->backend_tuples = (TupleField *) realloc(self->backend_tuples, + tuple_size * self->num_fields * sizeof(TupleField)); if (!self->backend_tuples) { self->status = PGRES_FATAL_ERROR; QR_set_message(self, "Out of memory while reading tuples."); return FALSE; } + self->count_allocated = tuple_size; } if (!QR_read_tuple(self, (char) (id == 0))) diff --git a/src/interfaces/odbc/qresult.h b/src/interfaces/odbc/qresult.h index aca89b575e..7da2a0201e 100644 --- a/src/interfaces/odbc/qresult.h +++ b/src/interfaces/odbc/qresult.h @@ -46,6 +46,7 @@ struct QResultClass_ * (backend) */ /* Stuff for declare/fetch tuples */ + int count_allocated; /* m(re)alloced count */ int fetch_count; /* logical rows read so far */ int fcount; /* actual rows read in the fetch */ int currTuple; diff --git a/src/interfaces/odbc/results.c b/src/interfaces/odbc/results.c index d861a3324e..098c5581d6 100644 --- a/src/interfaces/odbc/results.c +++ b/src/interfaces/odbc/results.c @@ -39,16 +39,17 @@ #include #include #endif +#include "pgapifunc.h" extern GLOBAL_VALUES globals; RETCODE SQL_API -SQLRowCount( +PGAPI_RowCount( HSTMT hstmt, SDWORD FAR *pcrow) { - static char *func = "SQLRowCount"; + static char *func = "PGAPI_RowCount"; StatementClass *stmt = (StatementClass *) hstmt; QResultClass *res; char *msg, @@ -91,12 +92,12 @@ SQLRowCount( if (ptr) { *pcrow = atoi(ptr + 1); - mylog("**** SQLRowCount(): THE ROWS: *pcrow = %d\n", *pcrow); + mylog("**** PGAPI_RowCount(): THE ROWS: *pcrow = %d\n", *pcrow); } else { *pcrow = -1; - mylog("**** SQLRowCount(): NO ROWS: *pcrow = %d\n", *pcrow); + mylog("**** PGAPI_RowCount(): NO ROWS: *pcrow = %d\n", *pcrow); } return SQL_SUCCESS; @@ -113,11 +114,11 @@ SQLRowCount( * attached to "hstmt". */ RETCODE SQL_API -SQLNumResultCols( +PGAPI_NumResultCols( HSTMT hstmt, SWORD FAR *pccol) { - static char *func = "SQLNumResultCols"; + static char *func = "PGAPI_NumResultCols"; StatementClass *stmt = (StatementClass *) hstmt; QResultClass *result; char parse_ok; @@ -135,7 +136,7 @@ SQLNumResultCols( { if (stmt->parse_status == STMT_PARSE_NONE) { - mylog("SQLNumResultCols: calling parse_statement on stmt=%u\n", stmt); + mylog("PGAPI_NumResultCols: calling parse_statement on stmt=%u\n", stmt); parse_statement(stmt); } @@ -143,7 +144,7 @@ SQLNumResultCols( { parse_ok = TRUE; *pccol = stmt->nfld; - mylog("PARSE: SQLNumResultCols: *pccol = %d\n", *pccol); + mylog("PARSE: PGAPI_NumResultCols: *pccol = %d\n", *pccol); } } @@ -152,7 +153,7 @@ SQLNumResultCols( SC_pre_execute(stmt); result = SC_get_Result(stmt); - mylog("SQLNumResultCols: result = %u, status = %d, numcols = %d\n", result, stmt->status, result != NULL ? QR_NumResultCols(result) : -1); + mylog("PGAPI_NumResultCols: result = %u, status = %d, numcols = %d\n", result, stmt->status, result != NULL ? QR_NumResultCols(result) : -1); if ((!result) || ((stmt->status != STMT_FINISHED) && (stmt->status != STMT_PREMATURE))) { /* no query has been executed on this statement */ @@ -163,6 +164,12 @@ SQLNumResultCols( } *pccol = QR_NumResultCols(result); +#ifdef DRIVER_CURSOR_IMPLEMENT + if (stmt->options.scroll_concurrency != SQL_CONCUR_READ_ONLY) + { + *pccol -= 2; + } +#endif /* DRIVER_CURSOR_IMPLEMENT */ } return SQL_SUCCESS; @@ -174,7 +181,7 @@ SQLNumResultCols( * information about. */ RETCODE SQL_API -SQLDescribeCol( +PGAPI_DescribeCol( HSTMT hstmt, UWORD icol, UCHAR FAR *szColName, @@ -185,7 +192,7 @@ SQLDescribeCol( SWORD FAR *pibScale, SWORD FAR *pfNullable) { - static char *func = "SQLDescribeCol"; + static char *func = "PGAPI_DescribeCol"; /* gets all the information about a specific column */ StatementClass *stmt = (StatementClass *) hstmt; @@ -223,7 +230,7 @@ SQLDescribeCol( { if (stmt->parse_status == STMT_PARSE_NONE) { - mylog("SQLDescribeCol: calling parse_statement on stmt=%u\n", stmt); + mylog("PGAPI_DescribeCol: calling parse_statement on stmt=%u\n", stmt); parse_statement(stmt); } @@ -261,7 +268,7 @@ SQLDescribeCol( res = SC_get_Result(stmt); - mylog("**** SQLDescribeCol: res = %u, stmt->status = %d, !finished=%d, !premature=%d\n", res, stmt->status, stmt->status != STMT_FINISHED, stmt->status != STMT_PREMATURE); + mylog("**** PGAPI_DescribeCol: res = %u, stmt->status = %d, !finished=%d, !premature=%d\n", res, stmt->status, stmt->status != STMT_FINISHED, stmt->status != STMT_PREMATURE); if ((NULL == res) || ((stmt->status != STMT_FINISHED) && (stmt->status != STMT_PREMATURE))) { /* no query has been executed on this statement */ @@ -367,7 +374,7 @@ SQLDescribeCol( /* Returns result column descriptor information for a result set. */ RETCODE SQL_API -SQLColAttributes( +PGAPI_ColAttributes( HSTMT hstmt, UWORD icol, UWORD fDescType, @@ -376,7 +383,7 @@ SQLColAttributes( SWORD FAR *pcbDesc, SDWORD FAR *pfDesc) { - static char *func = "SQLColAttributes"; + static char *func = "PGAPI_ColAttributes"; StatementClass *stmt = (StatementClass *) hstmt; Int4 field_type = 0; ConnInfo *ci; @@ -418,7 +425,7 @@ SQLColAttributes( { if (stmt->parse_status == STMT_PARSE_NONE) { - mylog("SQLColAttributes: calling parse_statement\n"); + mylog("PGAPI_ColAttributes: calling parse_statement\n"); parse_statement(stmt); } @@ -455,7 +462,7 @@ SQLColAttributes( { SC_pre_execute(stmt); - mylog("**** SQLColAtt: result = %u, status = %d, numcols = %d\n", stmt->result, stmt->status, stmt->result != NULL ? QR_NumResultCols(stmt->result) : -1); + mylog("**** PGAPI_ColAtt: result = %u, status = %d, numcols = %d\n", stmt->result, stmt->status, stmt->result != NULL ? QR_NumResultCols(stmt->result) : -1); if ((NULL == stmt->result) || ((stmt->status != STMT_FINISHED) && (stmt->status != STMT_PREMATURE))) { @@ -513,7 +520,7 @@ SQLColAttributes( case SQL_COLUMN_DISPLAY_SIZE: value = (parse_ok) ? stmt->fi[icol]->display_size : pgtype_display_size(stmt, field_type, icol, unknown_sizes); - mylog("SQLColAttributes: col %d, display_size= %d\n", icol, value); + mylog("PGAPI_ColAttributes: col %d, display_size= %d\n", icol, value); break; @@ -522,7 +529,7 @@ SQLColAttributes( { p = stmt->fi[icol]->alias; - mylog("SQLColAttr: COLUMN_LABEL = '%s'\n", p); + mylog("PGAPI_ColAttr: COLUMN_LABEL = '%s'\n", p); break; } @@ -531,13 +538,13 @@ SQLColAttributes( case SQL_COLUMN_NAME: p = (parse_ok) ? stmt->fi[icol]->name : QR_get_fieldname(stmt->result, icol); - mylog("SQLColAttr: COLUMN_NAME = '%s'\n", p); + mylog("PGAPI_ColAttr: COLUMN_NAME = '%s'\n", p); break; case SQL_COLUMN_LENGTH: value = (parse_ok) ? stmt->fi[icol]->length : pgtype_length(stmt, field_type, icol, unknown_sizes); - mylog("SQLColAttributes: col %d, length = %d\n", icol, value); + mylog("PGAPI_ColAttributes: col %d, length = %d\n", icol, value); break; case SQL_COLUMN_MONEY: @@ -555,7 +562,7 @@ SQLColAttributes( case SQL_COLUMN_PRECISION: value = (parse_ok) ? stmt->fi[icol]->precision : pgtype_precision(stmt, field_type, icol, unknown_sizes); - mylog("SQLColAttributes: col %d, precision = %d\n", icol, value); + mylog("PGAPI_ColAttributes: col %d, precision = %d\n", icol, value); break; case SQL_COLUMN_QUALIFIER_NAME: @@ -573,7 +580,7 @@ SQLColAttributes( case SQL_COLUMN_TABLE_NAME: p = (parse_ok && stmt->fi[icol]->ti) ? stmt->fi[icol]->ti->name : ""; - mylog("SQLColAttr: TABLE_NAME = '%s'\n", p); + mylog("PGAPI_ColAttr: TABLE_NAME = '%s'\n", p); break; case SQL_COLUMN_TYPE: @@ -601,7 +608,7 @@ SQLColAttributes( */ value = SQL_ATTR_WRITE; - mylog("SQLColAttr: UPDATEABLE = %d\n", value); + mylog("PGAPI_ColAttr: UPDATEABLE = %d\n", value); break; } @@ -639,7 +646,7 @@ SQLColAttributes( /* Returns result data for a single column in the current row. */ RETCODE SQL_API -SQLGetData( +PGAPI_GetData( HSTMT hstmt, UWORD icol, SWORD fCType, @@ -647,7 +654,7 @@ SQLGetData( SDWORD cbValueMax, SDWORD FAR *pcbValue) { - static char *func = "SQLGetData"; + static char *func = "PGAPI_GetData"; QResultClass *res; StatementClass *stmt = (StatementClass *) hstmt; int num_cols, @@ -657,7 +664,7 @@ SQLGetData( int result; char get_bookmark = FALSE; - mylog("SQLGetData: enter, stmt=%u\n", stmt); + mylog("PGAPI_GetData: enter, stmt=%u\n", stmt); if (!stmt) { @@ -771,7 +778,7 @@ SQLGetData( field_type = QR_get_field_type(res, icol); - mylog("**** SQLGetData: icol = %d, fCType = %d, field_type = %d, value = '%s'\n", icol, fCType, field_type, value); + mylog("**** PGAPI_GetData: icol = %d, fCType = %d, field_type = %d, value = '%s'\n", icol, fCType, field_type, value); stmt->current_col = icol; @@ -824,14 +831,14 @@ SQLGetData( * advances the cursor. */ RETCODE SQL_API -SQLFetch( +PGAPI_Fetch( HSTMT hstmt) { - static char *func = "SQLFetch"; + static char *func = "PGAPI_Fetch"; StatementClass *stmt = (StatementClass *) hstmt; QResultClass *res; - mylog("SQLFetch: stmt = %u, stmt->result= %u\n", stmt, stmt->result); + mylog("PGAPI_Fetch: stmt = %u, stmt->result= %u\n", stmt, stmt->result); if (!stmt) { @@ -843,7 +850,7 @@ SQLFetch( if (!(res = stmt->result)) { - stmt->errormsg = "Null statement result in SQLFetch."; + stmt->errormsg = "Null statement result in PGAPI_Fetch."; stmt->errornumber = STMT_SEQUENCE_ERROR; SC_log_error(func, "", stmt); return SQL_ERROR; @@ -853,7 +860,7 @@ SQLFetch( if (stmt->bookmark.buffer) { stmt->errornumber = STMT_COLNUM_ERROR; - stmt->errormsg = "Not allowed to bind a bookmark column when using SQLFetch"; + stmt->errormsg = "Not allowed to bind a bookmark column when using PGAPI_Fetch"; SC_log_error(func, "", stmt); return SQL_ERROR; } @@ -893,14 +900,14 @@ SQLFetch( /* This fetchs a block of data (rowset). */ RETCODE SQL_API -SQLExtendedFetch( +PGAPI_ExtendedFetch( HSTMT hstmt, UWORD fFetchType, SDWORD irow, UDWORD FAR *pcrow, UWORD FAR *rgfRowStatus) { - static char *func = "SQLExtendedFetch"; + static char *func = "PGAPI_ExtendedFetch"; StatementClass *stmt = (StatementClass *) hstmt; QResultClass *res; int num_tuples, @@ -910,7 +917,7 @@ SQLExtendedFetch( char truncated, error; - mylog("SQLExtendedFetch: stmt=%u\n", stmt); + mylog("PGAPI_ExtendedFetch: stmt=%u\n", stmt); if (!stmt) { @@ -923,7 +930,7 @@ SQLExtendedFetch( if (fFetchType != SQL_FETCH_NEXT) { stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; - stmt->errormsg = "Unsupported fetch type for SQLExtendedFetch with UseDeclareFetch option."; + stmt->errormsg = "Unsupported fetch type for PGAPI_ExtendedFetch with UseDeclareFetch option."; return SQL_ERROR; } } @@ -932,7 +939,7 @@ SQLExtendedFetch( if (!(res = stmt->result)) { - stmt->errormsg = "Null statement result in SQLExtendedFetch."; + stmt->errormsg = "Null statement result in PGAPI_ExtendedFetch."; stmt->errornumber = STMT_SEQUENCE_ERROR; SC_log_error(func, "", stmt); return SQL_ERROR; @@ -1019,11 +1026,23 @@ SQLExtendedFetch( */ if (stmt->rowset_start >= num_tuples) { + if (stmt->options.rowset_size > num_tuples) + { + stmt->errornumber = STMT_POS_BEFORE_RECORDSET; + stmt->errormsg = "fetch prior from eof and before the beggining"; + } stmt->rowset_start = num_tuples <= 0 ? 0 : (num_tuples - stmt->options.rowset_size); } else + { + if (stmt->rowset_start < stmt->options.rowset_size) + { + stmt->errormsg = "fetch prior and before the beggining"; + stmt->errornumber = STMT_POS_BEFORE_RECORDSET; + } stmt->rowset_start -= stmt->options.rowset_size; + } break; case SQL_FETCH_FIRST: @@ -1073,7 +1092,7 @@ SQLExtendedFetch( break; default: - SC_log_error(func, "Unsupported SQLExtendedFetch Direction", stmt); + SC_log_error(func, "Unsupported PGAPI_ExtendedFetch Direction", stmt); return SQL_ERROR; } @@ -1120,11 +1139,13 @@ SQLExtendedFetch( /* increment the base row in the tuple cache */ QR_set_rowset_size(res, stmt->options.rowset_size); - QR_inc_base(res, stmt->last_fetch_count); + /* QR_inc_base(res, stmt->last_fetch_count); */ + /* Is inc_base right ? */ + res->base = stmt->rowset_start; /* Physical Row advancement occurs for each row fetched below */ - mylog("SQLExtendedFetch: new currTuple = %d\n", stmt->currTuple); + mylog("PGAPI_ExtendedFetch: new currTuple = %d\n", stmt->currTuple); truncated = error = FALSE; for (i = 0; i < stmt->options.rowset_size; i++) @@ -1145,6 +1166,11 @@ SQLExtendedFetch( { if (result == SQL_ERROR) *(rgfRowStatus + i) = SQL_ROW_ERROR; +#ifdef DRIVER_CURSOR_IMPLEMENT + /* this should be refined */ + else if (result > 10 && result < 20) + *(rgfRowStatus + i) = result - 10; +#endif /* DRIVER_CURSOR_IMPLEMENT */ else *(rgfRowStatus + i) = SQL_ROW_SUCCESS; } @@ -1174,6 +1200,8 @@ SQLExtendedFetch( return SQL_ERROR; else if (truncated) return SQL_SUCCESS_WITH_INFO; + else if (stmt->errornumber == STMT_POS_BEFORE_RECORDSET) + return SQL_SUCCESS_WITH_INFO; else return SQL_SUCCESS; } @@ -1185,25 +1213,500 @@ SQLExtendedFetch( */ /* CC: return SQL_NO_DATA_FOUND since we do not support multiple result sets */ RETCODE SQL_API -SQLMoreResults( +PGAPI_MoreResults( HSTMT hstmt) { return SQL_NO_DATA_FOUND; } +#ifdef DRIVER_CURSOR_IMPLEMENT +RETCODE SQL_API +SC_pos_reload(StatementClass *stmt, UWORD irow, UWORD *count) +{ + int i, res_cols; + UWORD rcnt, global_ridx; + QResultClass *res, *qres; + char selstr[4096]; + RETCODE ret = SQL_ERROR; + char *tidval, *oidval; + + mylog("positioned load fi=%x ti=%x\n", stmt->fi, stmt->ti); + rcnt = 0; + if (count) + *count = 0; + if (!(res = stmt->result)) + return SQL_ERROR; + if (!stmt->ti) + parse_statement(stmt); /* not preferable */ + if (!stmt->ti || stmt->ntab != 1) + { + stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; + return SQL_ERROR; + } + strcpy(selstr, "select"); + global_ridx = irow + stmt->rowset_start; + res_cols = QR_NumResultCols(res); + if (!(oidval = QR_get_value_backend_row(res, global_ridx, res_cols - 1))) + { + return SQL_SUCCESS_WITH_INFO; + } + tidval = QR_get_value_backend_row(res, global_ridx, res_cols - 2); + res_cols -= 2; + for (i = 0; i < res_cols; i++) + sprintf(selstr, "%s \"%s\",", selstr, stmt->fi[i]->name); + sprintf(selstr, "%s CTID, OID from \"%s\" where ctid = currtid2('%s', '%s') and oid = %s", + selstr, stmt->ti[0]->name, stmt->ti[0]->name, tidval, oidval), + mylog("selstr=%s\n", selstr); + qres = CC_send_query(SC_get_conn(stmt), selstr, NULL); + if (qres && QR_command_successful(qres)) + { + TupleField *tupleo, *tuplen; + + rcnt = QR_get_num_tuples(qres); + tupleo = res->backend_tuples + res->num_fields * global_ridx; + if (rcnt == 1) + { + QR_set_position(qres, 0); + tuplen = res->tupleField; + for (i = 0; i < res->num_fields; i++) + { + if (tupleo[i].value) + free(tupleo[i].value); + tupleo[i].len = tuplen[i].len; + tuplen[i].len = 0; + tupleo[i].value = tuplen[i].value; + tuplen[i].value = NULL; + } + ret = SQL_SUCCESS; + } + else + { + stmt->errornumber = STMT_ROW_VERSION_CHANGED; + stmt->errormsg = "the content was deleted after last fetch"; + ret = SQL_SUCCESS_WITH_INFO; + if (stmt->options.cursor_type == SQL_CURSOR_KEYSET_DRIVEN) + { + if (tupleo[res_cols + 1].value) + free(tupleo[res_cols + 1].value); + tupleo[res_cols + 1].value = NULL; + tupleo[res_cols + 1].len = 0; + } + } + } + else if (stmt->errornumber == 0) + stmt->errornumber = STMT_ERROR_TAKEN_FROM_BACKEND; + if (qres) + QR_Destructor(qres); + if (count) + *count = rcnt; + return ret; +} + +RETCODE SQL_API +SC_pos_newload(StatementClass *stmt, Int4 oid, const char *tidval) +{ + int i, res_cols; + QResultClass *res, *qres; + char selstr[4096]; + RETCODE ret = SQL_ERROR; + + mylog("positioned new fi=%x ti=%x\n", stmt->fi, stmt->ti); + if (!(res = stmt->result)) + return SQL_ERROR; + if (!stmt->ti) + parse_statement(stmt); /* not preferable */ + if (!stmt->ti || stmt->ntab != 1) + { + stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; + return SQL_ERROR; + } + sprintf(selstr, "select"); + res_cols = QR_NumResultCols(res); + res_cols -= 2; + for (i = 0; i < res_cols; i++) + sprintf(selstr, "%s \"%s\",", selstr, stmt->fi[i]->name); + sprintf(selstr, "%s CTID, OID from \"%s\" where", selstr, stmt->ti[0]->name); + if (tidval) + sprintf(selstr, "%s ctid = currtid2('%s', '%s') and", + selstr, stmt->ti[0]->name, tidval); + sprintf(selstr, "%s oid = %u", selstr, oid), + mylog("selstr=%s\n", selstr); + qres = CC_send_query(SC_get_conn(stmt), selstr, NULL); + if (qres && QR_command_successful(qres)) + { + TupleField *tupleo, *tuplen; + int count = QR_get_num_tuples(qres); + QR_set_position(qres, 0); + if (count == 1) + { + tuplen = qres->tupleField; + if (res->fcount >= res->count_allocated) + { + int tuple_size; + if (!res->count_allocated) + tuple_size = TUPLE_MALLOC_INC; + else + tuple_size = res->count_allocated * 2; + res->backend_tuples = (TupleField *) realloc( + res->backend_tuples, + res->num_fields * sizeof(TupleField) * tuple_size); + if (!res->backend_tuples) + { + stmt->errornumber = res->status = PGRES_FATAL_ERROR; + stmt->errormsg = "Out of memory while reading tuples."; + QR_Destructor(qres); + return SQL_ERROR; + } + res->count_allocated = tuple_size; + } + tupleo = res->backend_tuples + res->num_fields * res->fcount; + for (i = 0; i < res->num_fields; i++) + { + tupleo[i].len = tuplen[i].len; + tuplen[i].len = 0; + tupleo[i].value = tuplen[i].value; + tuplen[i].value = NULL; + } + res->fcount++; + ret = SQL_SUCCESS; + } + else + { + stmt->errornumber = STMT_ROW_VERSION_CHANGED; + stmt->errormsg = "the content was changed before updation"; + ret = SQL_SUCCESS_WITH_INFO; + } + /*stmt->currTuple = stmt->rowset_start + irow;*/ + } + if (qres) + QR_Destructor(qres); + return ret; +} + +RETCODE SQL_API +SC_pos_update(StatementClass *stmt, + UWORD irow) +{ + int i, res_cols, num_cols, upd_cols; + UWORD global_ridx; + QResultClass *res; + BindInfoClass *bindings = stmt->bindings; + char updstr[4096]; + RETCODE ret; + char *tidval, *oidval; + + mylog("POS UPDATE %d+%d fi=%x ti=%x\n", irow, stmt->result->base, stmt->fi, stmt->ti); + if (!(res = stmt->result)) + return SQL_ERROR; + if (!stmt->ti) + parse_statement(stmt); /* not preferable */ + if (!stmt->ti || stmt->ntab != 1) + { + stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; + return SQL_ERROR; + } + global_ridx = irow + stmt->rowset_start; + res_cols = QR_NumResultCols(res); + if (!(oidval = QR_get_value_backend_row(res, global_ridx, res_cols - 1))) + { + stmt->errormsg = "The row is already deleted"; + return SQL_ERROR; + } + tidval = QR_get_value_backend_row(res, global_ridx, res_cols - 2); + + sprintf(updstr, "update \"%s\" set", stmt->ti[0]->name); + num_cols = stmt->nfld; + for (i = upd_cols = 0; i < num_cols; i++) + { + if (bindings[i].used) + { + mylog("%d used=%d\n", i, *bindings[i].used); + if (*bindings[i].used != SQL_IGNORE) + { + if (upd_cols) + sprintf(updstr, "%s, \"%s\" = ?", updstr, stmt->fi[i]->name); + else + sprintf(updstr, "%s \"%s\" = ?", updstr, stmt->fi[i]->name); + upd_cols++; + } + } + else + mylog("%d null bind\n", i); + } + if (upd_cols > 0) + { + HSTMT hstmt; + int j; + int res_cols = QR_NumResultCols(res); + StatementClass *qstmt; + + sprintf(updstr, "%s where ctid = '%s' and oid = %s", updstr, + tidval, oidval); + mylog("updstr=%s\n", updstr); + if (PGAPI_AllocStmt(SC_get_conn(stmt), &hstmt) != SQL_SUCCESS) + return SQL_ERROR; + qstmt = (StatementClass *) hstmt; + for (i = j = 0; i < num_cols; i++) + { + if (bindings[i].used) + { + mylog("%d used=%d\n", i, *bindings[i].used); + if (*bindings[i].used != SQL_IGNORE) + { + PGAPI_BindParameter(hstmt, (SQLUSMALLINT) ++j, + SQL_PARAM_INPUT, bindings[i].returntype, + pgtype_to_sqltype(stmt, QR_get_field_type(res, i)), + QR_get_fieldsize(res, i), + (SQLSMALLINT) stmt->fi[i]->precision, + bindings[i].buffer, + bindings[i].buflen, + bindings[i].used); + } + } + } + ret = PGAPI_ExecDirect(hstmt, updstr, strlen(updstr)); + if (ret == SQL_ERROR) + { + stmt->errornumber = qstmt->errornumber; + stmt->errormsg = qstmt->errormsg; + } + else if (ret == SQL_NEED_DATA) /* must be fixed */ + { + stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; + stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR; + stmt->errormsg = "SetPos with data_at_exec not yet supported"; + ret = SQL_ERROR; + } + if (ret != SQL_ERROR) + { + int updcnt; + const char *cmdstr = QR_get_command(qstmt->result); + if (cmdstr && + sscanf(cmdstr, "UPDATE %d", &updcnt) == 1) + { + if (updcnt == 1) + SC_pos_reload(stmt, irow, (UWORD *) 0); + else if (updcnt == 0) + { + stmt->errornumber = STMT_ROW_VERSION_CHANGED; + stmt->errormsg = "the content was changed before updation"; + ret = SQL_ERROR; + if (stmt->options.cursor_type == SQL_CURSOR_KEYSET_DRIVEN) + SC_pos_reload(stmt, irow, (UWORD *) 0); + } + else + ret = SQL_ERROR; + stmt->currTuple = stmt->rowset_start + irow; + } + else + ret = SQL_ERROR; + if (ret == SQL_ERROR && stmt->errornumber == 0) + { + stmt->errornumber = STMT_ERROR_TAKEN_FROM_BACKEND; + stmt->errormsg = "SetPos update return error"; + } + } + PGAPI_FreeStmt(hstmt, SQL_DROP); + } + else + ret = SQL_SUCCESS_WITH_INFO; + return ret; +} +RETCODE SQL_API +SC_pos_delete(StatementClass *stmt, + UWORD irow) +{ + int res_cols; + UWORD global_ridx; + QResultClass *res, *qres; + BindInfoClass *bindings = stmt->bindings; + char dltstr[4096]; + RETCODE ret; + char *oidval; + + mylog("POS DELETE fi=%x ti=%x\n", stmt->fi, stmt->ti); + if (!(res = stmt->result)) + return SQL_ERROR; + if (!stmt->ti) + parse_statement(stmt); /* not preferable */ + if (!stmt->ti || stmt->ntab != 1) + { + stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; + return SQL_ERROR; + } + res_cols = QR_NumResultCols(res); + global_ridx = irow + stmt->rowset_start; + if (!(oidval = QR_get_value_backend_row(res, global_ridx, res_cols - 1))) + { + stmt->errormsg = "The row is already deleted"; + return SQL_ERROR; + } + sprintf(dltstr, "delete from \"%s\" where ctid = '%s' and oid = %s", + stmt->ti[0]->name, + QR_get_value_backend_row(stmt->result, global_ridx, res_cols - 2), + oidval); + + mylog("dltstr=%s\n", dltstr); + qres = CC_send_query(SC_get_conn(stmt), dltstr, NULL); + if (qres && QR_command_successful(qres)) + { + int dltcnt; + const char *cmdstr = QR_get_command(qres); + if (cmdstr && + sscanf(cmdstr, "DELETE %d", &dltcnt) == 1) + { + if (dltcnt == 1) + SC_pos_reload(stmt, irow, (UWORD *) 0); + else if (dltcnt == 0) + { + stmt->errornumber = STMT_ROW_VERSION_CHANGED; + stmt->errormsg = "the content was changed before deletion"; + ret = SQL_ERROR; + if (stmt->options.cursor_type == SQL_CURSOR_KEYSET_DRIVEN) + SC_pos_reload(stmt, irow, (UWORD *) 0); + } + else + ret = SQL_ERROR; + stmt->currTuple = stmt->rowset_start + irow; + } + else + ret = SQL_ERROR; + } + else + ret = SQL_ERROR; + if (ret == SQL_ERROR && stmt->errornumber == 0) + { + stmt->errornumber = STMT_ERROR_TAKEN_FROM_BACKEND; + stmt->errormsg = "SetPos delete return error"; + } + if (qres) + QR_Destructor(qres); + return ret; +} +RETCODE SQL_API +SC_pos_add(StatementClass *stmt, + UWORD irow) +{ + int num_cols, add_cols, i; + HSTMT hstmt; + QResultClass *res; + BindInfoClass *bindings = stmt->bindings; + char addstr[4096]; + RETCODE ret; + + mylog("POS ADD fi=%x ti=%x\n", stmt->fi, stmt->ti); + if (!(res = stmt->result)) + return SQL_ERROR; + if (!stmt->ti) + parse_statement(stmt); /* not preferable */ + if (!stmt->ti || stmt->ntab != 1) + { + stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; + return SQL_ERROR; + } + num_cols = stmt->nfld; + sprintf(addstr, "insert into \"%s\" (", stmt->ti[0]->name); + if (PGAPI_AllocStmt(SC_get_conn(stmt), &hstmt) != SQL_SUCCESS) + return SQL_ERROR; + for (i = add_cols = 0; i < num_cols; i++) + { + if (bindings[i].used) + { + mylog("%d used=%d\n", i, *bindings[i].used); + if (*bindings[i].used != SQL_IGNORE) + { + if (add_cols) + sprintf(addstr, "%s, \"%s\"", addstr, stmt->fi[i]->name); + else + sprintf(addstr, "%s\"%s\"", addstr, stmt->fi[i]->name); + PGAPI_BindParameter(hstmt, (SQLUSMALLINT) ++add_cols, + SQL_PARAM_INPUT, bindings[i].returntype, + pgtype_to_sqltype(stmt, QR_get_field_type(res, i)), + QR_get_fieldsize(res, i), + (SQLSMALLINT) stmt->fi[i]->precision, + bindings[i].buffer, + bindings[i].buflen, + bindings[i].used); + } + } + else + mylog("%d null bind\n", i); + } + if (add_cols > 0) + { + StatementClass *qstmt = (StatementClass *) hstmt; + + sprintf(addstr, "%s) values (", addstr); + for (i = 0; i < add_cols; i++) + { + if (i) + strcat(addstr, ", ?"); + else + strcat(addstr, "?"); + } + strcat(addstr, ")"); + mylog("addstr=%s\n", addstr); + ret = PGAPI_ExecDirect(hstmt, addstr, strlen(addstr)); + if (ret == SQL_NEED_DATA) /* must be fixed */ + { + stmt->options.scroll_concurrency = SQL_CONCUR_READ_ONLY; + stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR; + stmt->errormsg = "SetPos with data_at_exec not yet supported"; + ret = SQL_ERROR; + } + if (ret == SQL_ERROR) + { + stmt->errornumber = qstmt->errornumber; + stmt->errormsg = qstmt->errormsg; + } + else + { + int addcnt; + Int4 oid; + const char *cmdstr = QR_get_command(qstmt->result); + if (cmdstr && + sscanf(cmdstr, "INSERT %u %d", &oid, &addcnt) == 2 && + addcnt == 1) + { + SC_pos_newload(stmt, oid, NULL); + if (stmt->bookmark.buffer) + { + char buf[32]; + + sprintf(buf, "%ld", res->fcount); + copy_and_convert_field(stmt, 0, buf, + SQL_C_ULONG, stmt->bookmark.buffer, + 0, stmt->bookmark.used); + } + } + else + { + stmt->errornumber = STMT_ERROR_TAKEN_FROM_BACKEND; + stmt->errormsg = "SetPos insert return error"; + ret = SQL_ERROR; + } + } + } + else + ret = SQL_SUCCESS_WITH_INFO; + PGAPI_FreeStmt(hstmt, SQL_DROP); + return ret; +} +#endif /* DRIVER_CURSOR_IMPLEMENT */ + /* * This positions the cursor within a rowset, that was positioned using SQLExtendedFetch. * This will be useful (so far) only when using SQLGetData after SQLExtendedFetch. */ RETCODE SQL_API -SQLSetPos( +PGAPI_SetPos( HSTMT hstmt, UWORD irow, UWORD fOption, UWORD fLock) { - static char *func = "SQLSetPos"; + static char *func = "PGAPI_SetPos"; StatementClass *stmt = (StatementClass *) hstmt; QResultClass *res; int num_cols, @@ -1216,17 +1719,23 @@ SQLSetPos( return SQL_INVALID_HANDLE; } +#ifdef DRIVER_CURSOR_IMPLEMENT + mylog("SetPos fOption=%d irow=%d lock=%d currt=%d\n", fOption, irow, fLock, stmt->currTuple); + if (stmt->options.scroll_concurrency != SQL_CONCUR_READ_ONLY) + ; + else +#endif /* DRIVER_CURSOR_IMPLEMENT */ if (fOption != SQL_POSITION && fOption != SQL_REFRESH) { stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; - stmt->errormsg = "Only SQL_POSITION/REFRESH is supported for SQLSetPos"; + stmt->errormsg = "Only SQL_POSITION/REFRESH is supported for PGAPI_SetPos"; SC_log_error(func, "", stmt); return SQL_ERROR; } if (!(res = stmt->result)) { - stmt->errormsg = "Null statement result in SQLSetPos."; + stmt->errormsg = "Null statement result in PGAPI_SetPos."; stmt->errornumber = STMT_SEQUENCE_ERROR; SC_log_error(func, "", stmt); return SQL_ERROR; @@ -1251,13 +1760,41 @@ SQLSetPos( irow--; +#ifdef DRIVER_CURSOR_IMPLEMENT + switch (fOption) + { + case SQL_UPDATE: + return SC_pos_update(stmt, irow); + case SQL_DELETE: + return SC_pos_delete(stmt, irow); + case SQL_ADD: + return SC_pos_add(stmt, irow); + } +#endif /* DRIVER_CURSOR_IMPLEMENT */ /* Reset for SQLGetData */ for (i = 0; i < num_cols; i++) bindings[i].data_left = -1; - QR_set_position(res, irow); + if (fOption == SQL_REFRESH) + { + /* save the last_fetch_count */ + int last_fetch = stmt->last_fetch_count; + int bind_save = stmt->bind_row; - stmt->currTuple = stmt->rowset_start + irow; +#ifdef DRIVER_CURSOR_IMPLEMENT + if (stmt->options.cursor_type == SQL_CURSOR_KEYSET_DRIVEN) + SC_pos_reload(stmt, irow, (UWORD *) 0); +#endif /* DRIVER_CURSOR_IMPLEMENT */ + stmt->currTuple = stmt->rowset_start + irow - 1; + stmt->bind_row = irow; + SC_fetch(stmt); + /* restore the last_fetch_count */ + stmt->last_fetch_count = last_fetch; + stmt->bind_row = bind_save; + } + else + stmt->currTuple = stmt->rowset_start + irow; + QR_set_position(res, irow); return SQL_SUCCESS; } @@ -1265,31 +1802,36 @@ SQLSetPos( /* Sets options that control the behavior of cursors. */ RETCODE SQL_API -SQLSetScrollOptions( +PGAPI_SetScrollOptions( HSTMT hstmt, UWORD fConcurrency, SDWORD crowKeyset, UWORD crowRowset) { - static char *func = "SQLSetScrollOptions"; + static char *func = "PGAPI_SetScrollOptions"; + StatementClass *stmt = (StatementClass *) hstmt; + mylog("PGAPI_SetScrollOptions fConcurrency=%d crowKeyset=%d crowRowset=%d\n", + fConcurrency, crowKeyset, crowRowset); + stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; + stmt->errormsg = "SetScroll option not implemeted"; - SC_log_error(func, "Function not implemented", (StatementClass *) hstmt); + SC_log_error(func, "Function not implemented", hstmt); return SQL_ERROR; } /* Set the cursor name on a statement handle */ RETCODE SQL_API -SQLSetCursorName( +PGAPI_SetCursorName( HSTMT hstmt, UCHAR FAR *szCursor, SWORD cbCursor) { - static char *func = "SQLSetCursorName"; + static char *func = "PGAPI_SetCursorName"; StatementClass *stmt = (StatementClass *) hstmt; int len; - mylog("SQLSetCursorName: hstmt=%u, szCursor=%u, cbCursorMax=%d\n", hstmt, szCursor, cbCursor); + mylog("PGAPI_SetCursorName: hstmt=%u, szCursor=%u, cbCursorMax=%d\n", hstmt, szCursor, cbCursor); if (!stmt) { @@ -1314,18 +1856,18 @@ SQLSetCursorName( /* Return the cursor name for a statement handle */ RETCODE SQL_API -SQLGetCursorName( +PGAPI_GetCursorName( HSTMT hstmt, UCHAR FAR *szCursor, SWORD cbCursorMax, SWORD FAR *pcbCursor) { - static char *func = "SQLGetCursorName"; + static char *func = "PGAPI_GetCursorName"; StatementClass *stmt = (StatementClass *) hstmt; int len = 0; RETCODE result; - mylog("SQLGetCursorName: hstmt=%u, szCursor=%u, cbCursorMax=%d, pcbCursor=%u\n", hstmt, szCursor, cbCursorMax, pcbCursor); + mylog("PGAPI_GetCursorName: hstmt=%u, szCursor=%u, cbCursorMax=%d, pcbCursor=%u\n", hstmt, szCursor, cbCursorMax, pcbCursor); if (!stmt) { diff --git a/src/interfaces/odbc/statement.c b/src/interfaces/odbc/statement.c index 165700dc09..4459bdb15d 100644 --- a/src/interfaces/odbc/statement.c +++ b/src/interfaces/odbc/statement.c @@ -34,6 +34,7 @@ #include #include #endif +#include "pgapifunc.h" extern GLOBAL_VALUES globals; @@ -91,10 +92,10 @@ static struct RETCODE SQL_API -SQLAllocStmt(HDBC hdbc, +PGAPI_AllocStmt(HDBC hdbc, HSTMT FAR *phstmt) { - static char *func = "SQLAllocStmt"; + static char *func = "PGAPI_AllocStmt"; ConnectionClass *conn = (ConnectionClass *) hdbc; StatementClass *stmt; @@ -108,7 +109,7 @@ SQLAllocStmt(HDBC hdbc, stmt = SC_Constructor(); - mylog("**** SQLAllocStmt: hdbc = %u, stmt = %u\n", hdbc, stmt); + mylog("**** PGAPI_AllocStmt: hdbc = %u, stmt = %u\n", hdbc, stmt); if (!stmt) { @@ -143,10 +144,10 @@ SQLAllocStmt(HDBC hdbc, RETCODE SQL_API -SQLFreeStmt(HSTMT hstmt, +PGAPI_FreeStmt(HSTMT hstmt, UWORD fOption) { - static char *func = "SQLFreeStmt"; + static char *func = "PGAPI_FreeStmt"; StatementClass *stmt = (StatementClass *) hstmt; mylog("%s: entering...hstmt=%u, fOption=%d\n", func, hstmt, fOption); @@ -205,7 +206,7 @@ SQLFreeStmt(HSTMT hstmt, SC_free_params(stmt, STMT_FREE_PARAMS_ALL); else { - stmt->errormsg = "Invalid option passed to SQLFreeStmt."; + stmt->errormsg = "Invalid option passed to PGAPI_FreeStmt."; stmt->errornumber = STMT_OPTION_OUT_OF_RANGE_ERROR; SC_log_error(func, "", stmt); return SQL_ERROR; @@ -570,7 +571,7 @@ SC_pre_execute(StatementClass *self) self->pre_executing = TRUE; self->inaccurate_result = FALSE; - SQLExecute(self); + PGAPI_Execute(self); self->pre_executing = old_pre_executing; @@ -713,13 +714,13 @@ SC_fetch(StatementClass *self) static char *func = "SC_fetch"; QResultClass *res = self->result; int retval, - result; + result, updret; Int2 num_cols, lf; Oid type; char *value; ColumnInfoClass *ci; - +extern WORD addrow; /* TupleField *tupleField; */ self->last_fetch_count = 0; @@ -741,7 +742,7 @@ SC_fetch(StatementClass *self) return SQL_NO_DATA_FOUND; } - mylog("**** SQLFetch: manual_result\n"); + mylog("**** SC_fetch: manual_result\n"); (self->currTuple)++; } else @@ -750,14 +751,14 @@ SC_fetch(StatementClass *self) retval = QR_next_tuple(res); if (retval < 0) { - mylog("**** SQLFetch: end_tuples\n"); + mylog("**** SC_fetch: end_tuples\n"); return SQL_NO_DATA_FOUND; } else if (retval > 0) (self->currTuple)++;/* all is well */ else { - mylog("SQLFetch: error\n"); + mylog("SC_fetch: error\n"); self->errornumber = STMT_EXEC_ERROR; self->errormsg = "Error fetching next row"; SC_log_error(func, "", self); @@ -785,6 +786,17 @@ SC_fetch(StatementClass *self) SQL_C_ULONG, self->bookmark.buffer, 0, self->bookmark.used); } +#ifdef DRIVER_CURSOR_IMPLEMENT + updret = 0; + if (self->options.scroll_concurrency != SQL_CONCUR_READ_ONLY) + { + if (!QR_get_value_backend_row(res, self->currTuple, num_cols - 1)) + updret = SQL_ROW_DELETED; + num_cols -= 2; + } + if (!self->options.retrieve_data) /* data isn't required */ + return updret ? updret + 10 : SQL_SUCCESS; +#endif /* DRIVER_CURSOR_IMPLEMENT */ for (lf = 0; lf < num_cols; lf++) { mylog("fetch: cols=%d, lf=%d, self = %u, self->bindings = %u, buffer[] = %u\n", num_cols, lf, self, self->bindings, self->bindings[lf].buffer); @@ -865,6 +877,10 @@ SC_fetch(StatementClass *self) } } +#ifdef DRIVER_CURSOR_IMPLEMENT + if (updret) + result = updret + 10; +#endif /* DRIVER_CURSOR_IMPLEMENT */ return result; } @@ -910,7 +926,7 @@ SC_execute(StatementClass *self) ok = QR_command_successful(res); - mylog("SQLExecute: ok = %d, status = %d\n", ok, QR_get_status(res)); + mylog("SC_exec: begin ok = %d, status = %d\n", ok, QR_get_status(res)); QR_Destructor(res); @@ -1066,7 +1082,7 @@ SC_execute(StatementClass *self) { /* get the return value of the procedure call */ RETCODE ret; HSTMT hstmt = (HSTMT) self; - ret = SQLBindCol(hstmt, 1, self->parameters[0].CType, self->parameters[0].buffer, self->parameters[0].buflen, self->parameters[0].used); + ret = PGAPI_BindCol(hstmt, 1, self->parameters[0].CType, self->parameters[0].buffer, self->parameters[0].buflen, self->parameters[0].used); if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) SC_fetch(hstmt); else @@ -1075,7 +1091,7 @@ SC_execute(StatementClass *self) self->errormsg = "BindCol to Procedure return failed."; } if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO) - SQLBindCol(hstmt, 1, self->parameters[0].CType, NULL, 0, NULL); + PGAPI_BindCol(hstmt, 1, self->parameters[0].CType, NULL, 0, NULL); else { self->errornumber = STMT_EXEC_ERROR; diff --git a/src/interfaces/odbc/statement.h b/src/interfaces/odbc/statement.h index f27c4cc138..6250a934a5 100644 --- a/src/interfaces/odbc/statement.h +++ b/src/interfaces/odbc/statement.h @@ -49,6 +49,8 @@ typedef enum STMT_EXECUTING /* statement execution is still going on */ } STMT_Status; +#define STMT_ROW_VERSION_CHANGED (-4) +#define STMT_POS_BEFORE_RECORDSET (-3) #define STMT_TRUNCATED (-2) #define STMT_INFO_ONLY (-1) /* not an error message, * just a notification @@ -83,6 +85,7 @@ typedef enum #define STMT_OPERATION_INVALID 25 #define STMT_PROGRAM_TYPE_OUT_OF_RANGE 26 #define STMT_BAD_ERROR 27 +#define STMT_INVALID_OPTION_IDENTIFIER 28 /* statement types */ enum diff --git a/src/interfaces/odbc/win32.mak b/src/interfaces/odbc/win32.mak index c0104f38bf..8b83e054ef 100644 --- a/src/interfaces/odbc/win32.mak +++ b/src/interfaces/odbc/win32.mak @@ -83,6 +83,8 @@ CLEAN : -@erase "$(INTDIR)\statement.obj" -@erase "$(INTDIR)\tuple.obj" -@erase "$(INTDIR)\tuplelist.obj" + -@erase "$(INTDIR)\odbcapi.obj" + -@erase "$(INTDIR)\odbcapi30.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "$(OUTDIR)\psqlodbc.dll" -@erase "$(OUTDIR)\psqlodbc.exp" @@ -166,6 +168,8 @@ LINK32_OBJS= \ "$(INTDIR)\statement.obj" \ "$(INTDIR)\tuple.obj" \ "$(INTDIR)\tuplelist.obj" \ + "$(INTDIR)\odbcapi.obj" \ + "$(INTDIR)\odbcapi30.obj" \ "$(INTDIR)\psqlodbc.res" "$(OUTDIR)\psqlodbc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) @@ -214,6 +218,8 @@ CLEAN : -@erase "$(INTDIR)\statement.obj" -@erase "$(INTDIR)\tuple.obj" -@erase "$(INTDIR)\tuplelist.obj" + -@erase "$(INTDIR)\odbcapi.obj" + -@erase "$(INTDIR)\odbcapi30.obj" -@erase "$(INTDIR)\vc60.idb" -@erase "$(INTDIR)\vc60.pdb" -@erase "$(OUTDIR)\psqlodbc.dll" @@ -300,6 +306,8 @@ LINK32_OBJS= \ "$(INTDIR)\statement.obj" \ "$(INTDIR)\tuple.obj" \ "$(INTDIR)\tuplelist.obj" \ + "$(INTDIR)\odbcapi.obj" \ + "$(INTDIR)\odbcapi30.obj" \ "$(INTDIR)\psqlodbc.res" "$(OUTDIR)\psqlodbc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS) @@ -482,5 +490,17 @@ SOURCE=tuplelist.c $(CPP) $(CPP_PROJ) $(SOURCE) +SOURCE=odbcapi.c + +"$(INTDIR)\odbcapi.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + +SOURCE=odbcapi30.c + +"$(INTDIR)\odbcapi30.obj" : $(SOURCE) "$(INTDIR)" + $(CPP) $(CPP_PROJ) $(SOURCE) + + !ENDIF