RETCODE SQL_API SQLBindCol(HSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, PTR TargetValue, SQLLEN BufferLength, SQLLEN *StrLen_or_Ind) { RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; mylog("[SQLBindCol]"); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); ret = PGAPI_BindCol(StatementHandle, ColumnNumber, TargetType, TargetValue, BufferLength, StrLen_or_Ind); ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret; }
RETCODE SQL_API SQLSetPos( HSTMT hstmt, SQLSETPOSIROW irow, SQLUSMALLINT fOption, SQLUSMALLINT fLock) { RETCODE ret; StatementClass *stmt = (StatementClass *) hstmt; mylog("[SQLSetPos]"); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); ret = PGAPI_SetPos(hstmt, irow, fOption, fLock); ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret; }
RETCODE SQL_API SQLSetStmtAttrW(SQLHSTMT hstmt, SQLINTEGER fAttribute, PTR rgbValue, SQLINTEGER cbValueMax) { CSTR func = "SQLSetStmtAttrW"; RETCODE ret; StatementClass *stmt = (StatementClass *) hstmt; mylog("[%s]", func); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); ret = PGAPI_SetStmtAttr(hstmt, fAttribute, rgbValue, cbValueMax); ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret; }
RETCODE SQL_API SQLStatisticsW(HSTMT StatementHandle, SQLWCHAR *CatalogName, SQLSMALLINT NameLength1, SQLWCHAR *SchemaName, SQLSMALLINT NameLength2, SQLWCHAR *TableName, SQLSMALLINT NameLength3, SQLUSMALLINT Unique, SQLUSMALLINT Reserved) { CSTR func = "SQLStatisticsW"; RETCODE ret; char *ctName, *scName, *tbName; SQLLEN nmlen1, nmlen2, nmlen3; StatementClass *stmt = (StatementClass *) StatementHandle; ConnectionClass *conn; BOOL lower_id; mylog("[%s]", func); conn = SC_get_conn(stmt); lower_id = SC_is_lower_case(stmt, conn); ctName = ucs2_to_utf8(CatalogName, NameLength1, &nmlen1, lower_id); scName = ucs2_to_utf8(SchemaName, NameLength2, &nmlen2, lower_id); tbName = ucs2_to_utf8(TableName, NameLength3, &nmlen3, lower_id); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); if (SC_opencheck(stmt, func)) ret = SQL_ERROR; else ret = PGAPI_Statistics(StatementHandle, (SQLCHAR *) ctName, (SQLSMALLINT) nmlen1, (SQLCHAR *) scName, (SQLSMALLINT) nmlen2, (SQLCHAR *) tbName, (SQLSMALLINT) nmlen3, Unique, Reserved); ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); if (ctName) free(ctName); if (scName) free(scName); if (tbName) free(tbName); return ret; }
RETCODE SQL_API SQLGetTypeInfoW(SQLHSTMT StatementHandle, SQLSMALLINT DataType) { CSTR func = "SQLGetTypeInfoW"; RETCODE ret; StatementClass * stmt = (StatementClass *) StatementHandle; mylog("[%s]", func); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); if (SC_opencheck(stmt, func)) ret = SQL_ERROR; else ret = PGAPI_GetTypeInfo(StatementHandle, DataType); ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret; }
RETCODE SQL_API SQLPrimaryKeysW( HSTMT hstmt, SQLWCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLWCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLWCHAR *szTableName, SQLSMALLINT cbTableName) { CSTR func = "SQLPrimaryKeysW"; RETCODE ret; char *ctName, *scName, *tbName; SQLLEN nmlen1, nmlen2, nmlen3; StatementClass *stmt = (StatementClass *) hstmt; ConnectionClass *conn; BOOL lower_id; mylog("[%s]", func); conn = SC_get_conn(stmt); lower_id = SC_is_lower_case(stmt, conn); ctName = ucs2_to_utf8(szCatalogName, cbCatalogName, &nmlen1, lower_id); scName = ucs2_to_utf8(szSchemaName, cbSchemaName, &nmlen2, lower_id); tbName = ucs2_to_utf8(szTableName, cbTableName, &nmlen3, lower_id); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); if (SC_opencheck(stmt, func)) ret = SQL_ERROR; else ret = PGAPI_PrimaryKeys(hstmt, ctName, (SQLSMALLINT) nmlen1, scName, (SQLSMALLINT) nmlen2, tbName, (SQLSMALLINT) nmlen3, 0); ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); if (ctName) free(ctName); if (scName) free(scName); if (tbName) free(tbName); return ret; }
RETCODE SQL_API SQLDescribeParam(HSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT *pfSqlType, SQLULEN *pcbParamDef, SQLSMALLINT *pibScale, SQLSMALLINT *pfNullable) { RETCODE ret; StatementClass *stmt = (StatementClass *) hstmt; mylog("[SQLDescribeParam]"); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); ret = PGAPI_DescribeParam(hstmt, ipar, pfSqlType, pcbParamDef, pibScale, pfNullable); ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret; }
/* SQLBindParameter/SQLSetParam -> SQLBindParam */ RETCODE SQL_API SQLBindParam(HSTMT StatementHandle, SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType, SQLSMALLINT ParameterType, SQLULEN LengthPrecision, SQLSMALLINT ParameterScale, PTR ParameterValue, SQLLEN *StrLen_or_Ind) { CSTR func = "SQLBindParam"; RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; int BufferLength = 512; /* Is it OK ? */ mylog("[[%s]]", func); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); ret = PGAPI_BindParameter(StatementHandle, ParameterNumber, SQL_PARAM_INPUT, ValueType, ParameterType, LengthPrecision, ParameterScale, ParameterValue, BufferLength, StrLen_or_Ind); ret = DiscardStatementSvp(stmt,ret, FALSE); LEAVE_STMT_CS(stmt); return ret; }
RETCODE SQL_API SQLSetCursorNameW(HSTMT StatementHandle, SQLWCHAR *CursorName, SQLSMALLINT NameLength) { CSTR func = "SQLSetCursorNameW"; RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; char *crName; SQLLEN nlen; mylog("[%s]", func); crName = ucs2_to_utf8(CursorName, NameLength, &nlen, FALSE); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); ret = PGAPI_SetCursorName(StatementHandle, crName, (SQLSMALLINT) nlen); ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); if (crName) free(crName); return ret; }
RETCODE SQL_API SQLDescribeCol(HSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLCHAR *ColumnName, SQLSMALLINT BufferLength, SQLSMALLINT *NameLength, SQLSMALLINT *DataType, SQLULEN *ColumnSize, SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable) { RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; mylog("[SQLDescribeCol]"); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); ret = PGAPI_DescribeCol(StatementHandle, ColumnNumber, ColumnName, BufferLength, NameLength, DataType, ColumnSize, DecimalDigits, Nullable); ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret; }
RETCODE SQL_API SQLColAttributes(HSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, PTR rgbDesc, SQLSMALLINT cbDescMax, SQLSMALLINT *pcbDesc, SQLLEN *pfDesc) { RETCODE ret; StatementClass *stmt = (StatementClass *) hstmt; mylog("[SQLColAttributes]"); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); ret = PGAPI_ColAttributes(hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc); ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret; }
RETCODE SQL_API SQLPrepare(HSTMT StatementHandle, SQLCHAR *StatementText, SQLINTEGER TextLength) { CSTR func = "SQLPrepare"; RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; mylog("[SQLPrepare]"); ENTER_STMT_CS(stmt); SC_clear_error(stmt); if (SC_opencheck(stmt, func)) ret = SQL_ERROR; else { StartRollbackState(stmt); ret = PGAPI_Prepare(StatementHandle, StatementText, TextLength); ret = DiscardStatementSvp(stmt, ret, FALSE); } LEAVE_STMT_CS(stmt); return ret; }
RETCODE SQL_API SQLPrepareW(HSTMT StatementHandle, SQLWCHAR *StatementText, SQLINTEGER TextLength) { CSTR func = "SQLPrepareW"; StatementClass *stmt = (StatementClass *) StatementHandle; RETCODE ret; char *stxt; SQLLEN slen; mylog("[%s]", func); stxt = ucs2_to_utf8(StatementText, TextLength, &slen, FALSE); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); if (SC_opencheck(stmt, func)) ret = SQL_ERROR; else ret = PGAPI_Prepare(StatementHandle, stxt, (SQLINTEGER) slen); ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); if (stxt) free(stxt); return ret; }
RETCODE SQL_API SQLExecute(HSTMT StatementHandle) { CSTR func = "SQLExecute"; RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; UWORD flag = 0; mylog("[%s]", func); ENTER_STMT_CS(stmt); SC_clear_error(stmt); if (PG_VERSION_GE(SC_get_conn(stmt), 7.4)) flag |= PODBC_WITH_HOLD; if (SC_opencheck(stmt, func)) ret = SQL_ERROR; else { StartRollbackState(stmt); ret = PGAPI_Execute(StatementHandle, flag); ret = DiscardStatementSvp(stmt, ret, FALSE); } LEAVE_STMT_CS(stmt); return ret; }
/* * Supplies parameter data at execution time. * Used in conjuction with SQLPutData. */ RETCODE SQL_API PGAPI_ParamData( HSTMT hstmt, PTR FAR * prgbValue) { CSTR func = "PGAPI_ParamData"; StatementClass *stmt = (StatementClass *) hstmt, *estmt; APDFields *apdopts; IPDFields *ipdopts; RETCODE retval; int i; Int2 num_p; ConnectionClass *conn = NULL; mylog("%s: entering...\n", func); if (!stmt) { SC_log_error(func, "", NULL); retval = SQL_INVALID_HANDLE; goto cleanup; } conn = SC_get_conn(stmt); estmt = stmt->execute_delegate ? stmt->execute_delegate : stmt; apdopts = SC_get_APDF(estmt); mylog("%s: data_at_exec=%d, params_alloc=%d\n", func, estmt->data_at_exec, apdopts->allocated); #define return DONT_CALL_RETURN_FROM_HERE??? if (SC_AcceptedCancelRequest(stmt)) { SC_set_error(stmt, STMT_OPERATION_CANCELLED, "Cancel the statement, sorry", func); retval = SQL_ERROR; goto cleanup; } if (estmt->data_at_exec < 0) { SC_set_error(stmt, STMT_SEQUENCE_ERROR, "No execution-time parameters for this statement", func); retval = SQL_ERROR; goto cleanup; } if (estmt->data_at_exec > apdopts->allocated) { SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Too many execution-time parameters were present", func); retval = SQL_ERROR; goto cleanup; } /* close the large object */ if (estmt->lobj_fd >= 0) { odbc_lo_close(conn, estmt->lobj_fd); /* commit transaction if needed */ if (!CC_cursor_count(conn) && CC_does_autocommit(conn)) { if (!CC_commit(conn)) { SC_set_error(stmt, STMT_EXEC_ERROR, "Could not commit (in-line) a transaction", func); retval = SQL_ERROR; goto cleanup; } } estmt->lobj_fd = -1; } /* Done, now copy the params and then execute the statement */ ipdopts = SC_get_IPDF(estmt); inolog("ipdopts=%p\n", ipdopts); if (estmt->data_at_exec == 0) { BOOL exec_end; UWORD flag = SC_is_with_hold(stmt) ? PODBC_WITH_HOLD : 0; retval = Exec_with_parameters_resolved(estmt, &exec_end); if (exec_end) { /**SC_reset_delegate(retval, stmt);**/ retval = dequeueNeedDataCallback(retval, stmt); goto cleanup; } if (retval = PGAPI_Execute(estmt, flag), SQL_NEED_DATA != retval) { goto cleanup; } } /* * Set beginning param; if first time SQLParamData is called , start * at 0. Otherwise, start at the last parameter + 1. */ i = estmt->current_exec_param >= 0 ? estmt->current_exec_param + 1 : 0; num_p = estmt->num_params; if (num_p < 0) PGAPI_NumParams(estmt, &num_p); inolog("i=%d allocated=%d num_p=%d\n", i, apdopts->allocated, num_p); if (num_p > apdopts->allocated) num_p = apdopts->allocated; /* At least 1 data at execution parameter, so Fill in the token value */ for (; i < num_p; i++) { inolog("i=%d", i); if (apdopts->parameters[i].data_at_exec) { inolog(" at exec buffer=%p", apdopts->parameters[i].buffer); estmt->data_at_exec--; estmt->current_exec_param = i; estmt->put_data = FALSE; if (prgbValue) { /* returns token here */ if (stmt->execute_delegate) { SQLULEN offset = apdopts->param_offset_ptr ? *apdopts->param_offset_ptr : 0; SQLLEN perrow = apdopts->param_bind_type > 0 ? apdopts->param_bind_type : apdopts->parameters[i].buflen; inolog(" offset=%d perrow=%d", offset, perrow); *prgbValue = apdopts->parameters[i].buffer + offset + estmt->exec_current_row * perrow; } else *prgbValue = apdopts->parameters[i].buffer; } break; } inolog("\n"); } retval = SQL_NEED_DATA; inolog("return SQL_NEED_DATA\n"); cleanup: #undef return SC_setInsertedTable(stmt, retval); if (stmt->internal) retval = DiscardStatementSvp(stmt, retval, FALSE); mylog("%s: returning %d\n", func, retval); return retval; }
RETCODE SQL_API SQLProcedures( HSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szProcName, SQLSMALLINT cbProcName) { CSTR func = "SQLProcedures"; RETCODE ret; StatementClass *stmt = (StatementClass *) hstmt; SQLCHAR *ctName = szCatalogName, *scName = szSchemaName, *prName = szProcName; UWORD flag = 0; mylog("[%s]", func); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); #if (ODBCVER >= 0x0300) if (stmt->options.metadata_id) flag |= PODBC_NOT_SEARCH_PATTERN; #endif if (SC_opencheck(stmt, func)) ret = SQL_ERROR; else ret = PGAPI_Procedures(hstmt, ctName, cbCatalogName, scName, cbSchemaName, prName, cbProcName, flag); if (SQL_SUCCESS == ret && 0 == QR_get_num_total_tuples(SC_get_Result(stmt))) { BOOL ifallupper = TRUE, reexec = FALSE; char *newCt = NULL, *newSc = NULL, *newPr = NULL; ConnectionClass *conn = SC_get_conn(stmt); if (SC_is_lower_case(stmt, conn)) /* case-insensitive identifier */ ifallupper = FALSE; if (newCt = make_lstring_ifneeded(conn, szCatalogName, cbCatalogName, ifallupper), NULL != newCt) { ctName = newCt; reexec = TRUE; } if (newSc = make_lstring_ifneeded(conn, szSchemaName, cbSchemaName, ifallupper), NULL != newSc) { scName = newSc; reexec = TRUE; } if (newPr = make_lstring_ifneeded(conn, szProcName, cbProcName, ifallupper), NULL != newPr) { prName = newPr; reexec = TRUE; } if (reexec) { ret = PGAPI_Procedures(hstmt, ctName, cbCatalogName, scName, cbSchemaName, prName, cbProcName, flag); if (newCt) free(newCt); if (newSc) free(newSc); if (newPr) free(newPr); } } ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret; }
/* * Returns the description of a parameter marker. * This function is listed as not being supported by SQLGetFunctions() because it is * used to describe "parameter markers" (not bound parameters), in which case, * the dbms should return info on the markers. Since Postgres doesn't support that, * it is best to say this function is not supported and let the application assume a * data type (most likely varchar). */ RETCODE SQL_API PGAPI_DescribeParam(HSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT FAR * pfSqlType, SQLULEN FAR * pcbParamDef, SQLSMALLINT FAR * pibScale, SQLSMALLINT FAR * pfNullable) { StatementClass *stmt = (StatementClass *) hstmt; CSTR func = "PGAPI_DescribeParam"; IPDFields *ipdopts; RETCODE ret = SQL_SUCCESS; int num_params; OID pgtype; mylog("%s: entering...%d\n", func, ipar); if (!stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } SC_clear_error(stmt); ipdopts = SC_get_IPDF(stmt); /*if ((ipar < 1) || (ipar > ipdopts->allocated))*/ num_params = stmt->num_params; if (num_params < 0) { SQLSMALLINT num_p; PGAPI_NumParams(stmt, &num_p); num_params = num_p; } if ((ipar < 1) || (ipar > num_params)) { inolog("num_params=%d\n", stmt->num_params); SC_set_error(stmt, STMT_BAD_PARAMETER_NUMBER_ERROR, "Invalid parameter number for PGAPI_DescribeParam.", func); return SQL_ERROR; } extend_iparameter_bindings(ipdopts, stmt->num_params); #define return DONT_CALL_RETURN_FROM_HERE??? /* StartRollbackState(stmt); */ if (NOT_YET_PREPARED == stmt->prepared) { decideHowToPrepare(stmt, FALSE); inolog("howTo=%d\n", SC_get_prepare_method(stmt)); switch (SC_get_prepare_method(stmt)) { case NAMED_PARSE_REQUEST: case PARSE_TO_EXEC_ONCE: case PARSE_REQ_FOR_INFO: if (ret = prepareParameters(stmt), SQL_ERROR == ret) goto cleanup; } } ipar--; pgtype = PIC_get_pgtype(ipdopts->parameters[ipar]); /* * This implementation is not very good, since it is supposed to * describe */ /* parameter markers, not bound parameters. */ if (pfSqlType) { inolog("[%d].SQLType=%d .PGType=%d\n", ipar, ipdopts->parameters[ipar].SQLType, pgtype); if (ipdopts->parameters[ipar].SQLType) *pfSqlType = ipdopts->parameters[ipar].SQLType; else if (pgtype) *pfSqlType = pgtype_to_concise_type(stmt, pgtype, PG_STATIC); else { ret = SQL_ERROR; SC_set_error(stmt, STMT_EXEC_ERROR, "Unfortunatley couldn't get this paramater's info", func); goto cleanup; } } if (pcbParamDef) { *pcbParamDef = 0; if (ipdopts->parameters[ipar].SQLType) *pcbParamDef = ipdopts->parameters[ipar].column_size; if (0 == *pcbParamDef && pgtype) *pcbParamDef = pgtype_column_size(stmt, pgtype, PG_STATIC, PG_STATIC); } if (pibScale) { *pibScale = 0; if (ipdopts->parameters[ipar].SQLType) *pibScale = ipdopts->parameters[ipar].decimal_digits; else if (pgtype) *pibScale = pgtype_scale(stmt, pgtype, -1); } if (pfNullable) *pfNullable = pgtype_nullable(SC_get_conn(stmt), ipdopts->parameters[ipar].paramType); cleanup: #undef return if (stmt->internal) ret = DiscardStatementSvp(stmt, ret, FALSE); return ret; }
RETCODE SQL_API SQLForeignKeys( HSTMT hstmt, SQLCHAR *szPkCatalogName, SQLSMALLINT cbPkCatalogName, SQLCHAR *szPkSchemaName, SQLSMALLINT cbPkSchemaName, SQLCHAR *szPkTableName, SQLSMALLINT cbPkTableName, SQLCHAR *szFkCatalogName, SQLSMALLINT cbFkCatalogName, SQLCHAR *szFkSchemaName, SQLSMALLINT cbFkSchemaName, SQLCHAR *szFkTableName, SQLSMALLINT cbFkTableName) { CSTR func = "SQLForeignKeys"; RETCODE ret; StatementClass *stmt = (StatementClass *) hstmt; SQLCHAR *pkctName = szPkCatalogName, *pkscName = szPkSchemaName, *pktbName = szPkTableName, *fkctName = szFkCatalogName, *fkscName = szFkSchemaName, *fktbName = szFkTableName; mylog("[%s]", func); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); if (SC_opencheck(stmt, func)) ret = SQL_ERROR; else ret = PGAPI_ForeignKeys(hstmt, pkctName, cbPkCatalogName, pkscName, cbPkSchemaName, pktbName, cbPkTableName, fkctName, cbFkCatalogName, fkscName, cbFkSchemaName, fktbName, cbFkTableName); if (SQL_SUCCESS == ret && 0 == QR_get_num_total_tuples(SC_get_Result(stmt))) { BOOL ifallupper = TRUE, reexec = FALSE; char *newPkct = NULL, *newPksc = NULL, *newPktb = NULL, *newFkct = NULL, *newFksc = NULL, *newFktb = NULL; ConnectionClass *conn = SC_get_conn(stmt); if (SC_is_lower_case(stmt, conn)) /* case-insensitive identifier */ ifallupper = FALSE; if (newPkct = make_lstring_ifneeded(conn, szPkCatalogName, cbPkCatalogName, ifallupper), NULL != newPkct) { pkctName = newPkct; reexec = TRUE; } if (newPksc = make_lstring_ifneeded(conn, szPkSchemaName, cbPkSchemaName, ifallupper), NULL != newPksc) { pkscName = newPksc; reexec = TRUE; } if (newPktb = make_lstring_ifneeded(conn, szPkTableName, cbPkTableName, ifallupper), NULL != newPktb) { pktbName = newPktb; reexec = TRUE; } if (newFkct = make_lstring_ifneeded(conn, szFkCatalogName, cbFkCatalogName, ifallupper), NULL != newFkct) { fkctName = newFkct; reexec = TRUE; } if (newFksc = make_lstring_ifneeded(conn, szFkSchemaName, cbFkSchemaName, ifallupper), NULL != newFksc) { fkscName = newFksc; reexec = TRUE; } if (newFktb = make_lstring_ifneeded(conn, szFkTableName, cbFkTableName, ifallupper), NULL != newFktb) { fktbName = newFktb; reexec = TRUE; } if (reexec) { ret = PGAPI_ForeignKeys(hstmt, pkctName, cbPkCatalogName, pkscName, cbPkSchemaName, pktbName, cbPkTableName, fkctName, cbFkCatalogName, fkscName, cbFkSchemaName, fktbName, cbFkTableName); if (newPkct) free(newPkct); if (newPksc) free(newPksc); if (newPktb) free(newPktb); if (newFkct) free(newFkct); if (newFksc) free(newFksc); if (newFktb) free(newFktb); } } ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret; }
RETCODE SQL_API SQLPrimaryKeys( HSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szTableName, SQLSMALLINT cbTableName) { CSTR func = "SQLPrimaryKeys"; RETCODE ret; StatementClass *stmt = (StatementClass *) hstmt; SQLCHAR *ctName = szCatalogName, *scName = szSchemaName, *tbName = szTableName; mylog("[%s]", func); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); if (SC_opencheck(stmt, func)) ret = SQL_ERROR; else ret = PGAPI_PrimaryKeys(hstmt, ctName, cbCatalogName, scName, cbSchemaName, tbName, cbTableName, 0); if (SQL_SUCCESS == ret && 0 == QR_get_num_total_tuples(SC_get_Result(stmt))) { BOOL ifallupper = TRUE, reexec = FALSE; char *newCt = NULL, *newSc = NULL, *newTb = NULL; ConnectionClass *conn = SC_get_conn(stmt); if (SC_is_lower_case(stmt, conn)) /* case-insensitive identifier */ ifallupper = FALSE; if (newCt = make_lstring_ifneeded(conn, szCatalogName, cbCatalogName, ifallupper), NULL != newCt) { ctName = newCt; reexec = TRUE; } if (newSc = make_lstring_ifneeded(conn, szSchemaName, cbSchemaName, ifallupper), NULL != newSc) { scName = newSc; reexec = TRUE; } if (newTb = make_lstring_ifneeded(conn, szTableName, cbTableName, ifallupper), NULL != newTb) { tbName = newTb; reexec = TRUE; } if (reexec) { ret = PGAPI_PrimaryKeys(hstmt, ctName, cbCatalogName, scName, cbSchemaName, tbName, cbTableName, 0); if (newCt) free(newCt); if (newSc) free(newSc); if (newTb) free(newTb); } } ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret; }
/* Perform a Prepare on the SQL statement */ RETCODE SQL_API PGAPI_Prepare(HSTMT hstmt, const SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStr) { CSTR func = "PGAPI_Prepare"; StatementClass *self = (StatementClass *) hstmt; RETCODE retval = SQL_SUCCESS; mylog("%s: entering...\n", func); #define return DONT_CALL_RETURN_FROM_HERE??? /* StartRollbackState(self); */ if (!self) { SC_log_error(func, "", NULL); retval = SQL_INVALID_HANDLE; goto cleanup; } /* * According to the ODBC specs it is valid to call SQLPrepare multiple * times. In that case, the bound SQL statement is replaced by the new * one */ SC_set_prepared(self, NOT_YET_PREPARED); switch (self->status) { case STMT_PREMATURE: 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("**** PGAPI_Prepare: STMT_FINISHED, recycle\n"); SC_recycle_statement(self); /* recycle the statement, but do * not remove parameter bindings */ break; case STMT_ALLOCATED: mylog("**** PGAPI_Prepare: STMT_ALLOCATED, copy\n"); self->status = STMT_READY; break; case STMT_READY: mylog("**** PGAPI_Prepare: STMT_READY, change SQL\n"); break; case STMT_EXECUTING: mylog("**** PGAPI_Prepare: STMT_EXECUTING, error!\n"); SC_set_error(self, STMT_SEQUENCE_ERROR, "PGAPI_Prepare(): The handle does not point to a statement that is ready to be executed", func); retval = SQL_ERROR; goto cleanup; default: SC_set_error(self, STMT_INTERNAL_ERROR, "An Internal Error has occured -- Unknown statement status.", func); retval = SQL_ERROR; goto cleanup; } SC_initialize_stmts(self, TRUE); if (!szSqlStr) { SC_set_error(self, STMT_NO_MEMORY_ERROR, "the query is NULL", func); retval = SQL_ERROR; goto cleanup; } if (!szSqlStr[0]) self->statement = strdup(""); else self->statement = make_string(szSqlStr, cbSqlStr, NULL, 0); if (!self->statement) { SC_set_error(self, STMT_NO_MEMORY_ERROR, "No memory available to store statement", func); retval = SQL_ERROR; goto cleanup; } self->prepare = PREPARE_STATEMENT; self->statement_type = statement_type(self->statement); /* Check if connection is onlyread (only selects are allowed) */ if (CC_is_onlyread(SC_get_conn(self)) && STMT_UPDATE(self)) { SC_set_error(self, STMT_EXEC_ERROR, "Connection is readonly, only select statements are allowed.", func); retval = SQL_ERROR; goto cleanup; } cleanup: #undef return inolog("SQLPrepare return=%d\n", retval); if (self->internal) retval = DiscardStatementSvp(self, retval, FALSE); return retval; }
/* Execute a prepared SQL statement */ RETCODE SQL_API PGAPI_Execute(HSTMT hstmt, UWORD flag) { CSTR func = "PGAPI_Execute"; StatementClass *stmt = (StatementClass *) hstmt; RETCODE retval = SQL_SUCCESS; ConnectionClass *conn; APDFields *apdopts; IPDFields *ipdopts; SQLLEN i, start_row, end_row; BOOL exec_end, recycled = FALSE, recycle = TRUE; SQLSMALLINT num_params; mylog("%s: entering...%x\n", func, flag); if (!stmt) { SC_log_error(func, "", NULL); mylog("%s: NULL statement so return SQL_INVALID_HANDLE\n", func); return SQL_INVALID_HANDLE; } conn = SC_get_conn(stmt); apdopts = SC_get_APDF(stmt); /* * If the statement is premature, it means we already executed it from * an SQLPrepare/SQLDescribeCol type of scenario. So just return * success. */ if (stmt->prepare && stmt->status == STMT_PREMATURE) { if (stmt->inaccurate_result) { stmt->exec_current_row = -1; SC_recycle_statement(stmt); } else { stmt->status = STMT_FINISHED; if (NULL == SC_get_errormsg(stmt)) { mylog("%s: premature statement but return SQL_SUCCESS\n", func); retval = SQL_SUCCESS; goto cleanup; } else { SC_set_error(stmt,STMT_INTERNAL_ERROR, "premature statement so return SQL_ERROR", func); retval = SQL_ERROR; goto cleanup; } } } mylog("%s: clear errors...\n", func); SC_clear_error(stmt); if (!stmt->statement) { SC_set_error(stmt, STMT_NO_STMTSTRING, "This handle does not have a SQL statement stored in it", func); mylog("%s: problem with handle\n", func); return SQL_ERROR; } #define return DONT_CALL_RETURN_FROM_HERE??? if (stmt->exec_current_row > 0) { /* * executing an array of parameters. * Don't recycle the statement. */ recycle = FALSE; } else if (PREPARED_PERMANENTLY == stmt->prepared || PREPARED_TEMPORARILY == stmt->prepared) { QResultClass *res; /* * re-executing an prepared statement. * Don't recycle the statement but * discard the old result. */ recycle = FALSE; if (res = SC_get_Result(stmt), res) QR_close_result(res, FALSE); } /* * If SQLExecute is being called again, recycle the statement. Note * this should have been done by the application in a call to * SQLFreeStmt(SQL_CLOSE) or SQLCancel. */ else if (stmt->status == STMT_FINISHED) { mylog("%s: recycling statement (should have been done by app)...\n", func); /******** Is this really NEEDED ? ******/ SC_recycle_statement(stmt); recycled = TRUE; } /* Check if the statement is in the correct state */ else if ((stmt->prepare && stmt->status != STMT_READY) || (stmt->status != STMT_ALLOCATED && stmt->status != STMT_READY)) { SC_set_error(stmt, STMT_STATUS_ERROR, "The handle does not point to a statement that is ready to be executed", func); mylog("%s: problem with statement\n", func); retval = SQL_ERROR; goto cleanup; } if (start_row = stmt->exec_start_row, start_row < 0) start_row = 0; if (end_row = stmt->exec_end_row, end_row < 0) end_row = (SQLINTEGER) apdopts->paramset_size - 1; if (stmt->exec_current_row < 0) stmt->exec_current_row = start_row; ipdopts = SC_get_IPDF(stmt); num_params = stmt->num_params; if (num_params < 0) PGAPI_NumParams(stmt, &num_params); if (stmt->exec_current_row == start_row) { /* We sometimes need to know about the PG type of binding parameters even in case of non-prepared statements. */ int nCallParse = doNothing; if (NOT_YET_PREPARED == stmt->prepared) { switch (nCallParse = HowToPrepareBeforeExec(stmt, TRUE)) { case shouldParse: if (retval = prepareParameters(stmt, TRUE), SQL_ERROR == retval) goto cleanup; break; } } mylog("prepareParameters was %s called, prepare state:%d\n", shouldParse == nCallParse ? "" : "not", stmt->prepare); if (ipdopts->param_processed_ptr) *ipdopts->param_processed_ptr = 0; #if (ODBCVER >= 0x0300) /* * Initialize the param_status_ptr */ if (ipdopts->param_status_ptr) { for (i = 0; i <= end_row; i++) ipdopts->param_status_ptr[i] = SQL_PARAM_UNUSED; } #endif /* ODBCVER */ if (recycle && !recycled) SC_recycle_statement(stmt); if (isSqlServr() && !stmt->internal && 0 != stmt->prepare && PG_VERSION_LT(conn, 8.4) && SC_can_parse_statement(stmt)) parse_sqlsvr(stmt); } /* * Clear any old result sets before executing. The prepare stage might've * created one. */ SC_set_Result(stmt, NULL); next_param_row: #if (ODBCVER >= 0x0300) if (apdopts->param_operation_ptr) { while (apdopts->param_operation_ptr[stmt->exec_current_row] == SQL_PARAM_IGNORE) { if (stmt->exec_current_row >= end_row) { stmt->exec_current_row = -1; retval = SQL_SUCCESS; goto cleanup; } ++stmt->exec_current_row; } } /* * Initialize the current row status */ if (ipdopts->param_status_ptr) ipdopts->param_status_ptr[stmt->exec_current_row] = SQL_PARAM_ERROR; #endif /* ODBCVER */ /* * Check if statement has any data-at-execute parameters when it is * not in SC_pre_execute. */ if (!stmt->pre_executing) { /* * The bound parameters could have possibly changed since the last * execute of this statement? Therefore check for params and * re-copy. */ SQLULEN offset = apdopts->param_offset_ptr ? *apdopts->param_offset_ptr : 0; SQLINTEGER bind_size = apdopts->param_bind_type; SQLLEN current_row = stmt->exec_current_row < 0 ? 0 : stmt->exec_current_row; Int4 num_p = num_params < apdopts->allocated ? num_params : apdopts->allocated; /* * Increment the number of currently processed rows */ if (ipdopts->param_processed_ptr) (*ipdopts->param_processed_ptr)++; stmt->data_at_exec = -1; for (i = 0; i < num_p; i++) { SQLLEN *pcVal = apdopts->parameters[i].used; apdopts->parameters[i].data_at_exec = FALSE; if (pcVal) { if (bind_size > 0) pcVal = LENADDR_SHIFT(pcVal, offset + bind_size * current_row); else pcVal = LENADDR_SHIFT(pcVal, offset) + current_row; if (*pcVal == SQL_DATA_AT_EXEC || *pcVal <= SQL_LEN_DATA_AT_EXEC_OFFSET) apdopts->parameters[i].data_at_exec = TRUE; } /* Check for data at execution parameters */ if (apdopts->parameters[i].data_at_exec) { mylog("The %dth parameter of %d-row is data at exec(%d)\n", i, current_row, *pcVal); if (stmt->data_at_exec < 0) stmt->data_at_exec = 1; else stmt->data_at_exec++; } } /* * If there are some data at execution parameters, return need * data */ /* * SQLParamData and SQLPutData will be used to send params and * execute the statement. */ if (stmt->data_at_exec > 0) { retval = SQL_NEED_DATA; goto cleanup; } } if (0 != (flag & PODBC_WITH_HOLD)) SC_set_with_hold(stmt); retval = Exec_with_parameters_resolved(stmt, &exec_end); if (!exec_end) { stmt->curr_param_result = 0; goto next_param_row; } cleanup: mylog("retval=%d\n", retval); SC_setInsertedTable(stmt, retval); #undef return if (stmt->internal) retval = DiscardStatementSvp(stmt, retval, FALSE); return retval; }
RETCODE SQL_API SQLSpecialColumns(HSTMT StatementHandle, SQLUSMALLINT IdentifierType, SQLCHAR *CatalogName, SQLSMALLINT NameLength1, SQLCHAR *SchemaName, SQLSMALLINT NameLength2, SQLCHAR *TableName, SQLSMALLINT NameLength3, SQLUSMALLINT Scope, SQLUSMALLINT Nullable) { CSTR func = "SQLSpecialColumns"; RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; SQLCHAR *ctName = CatalogName, *scName = SchemaName, *tbName = TableName; mylog("[%s]", func); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); if (SC_opencheck(stmt, func)) ret = SQL_ERROR; else ret = PGAPI_SpecialColumns(StatementHandle, IdentifierType, ctName, NameLength1, scName, NameLength2, tbName, NameLength3, Scope, Nullable); if (SQL_SUCCESS == ret && 0 == QR_get_num_total_tuples(SC_get_Result(stmt))) { BOOL ifallupper = TRUE, reexec = FALSE; char *newCt =NULL, *newSc = NULL, *newTb = NULL; ConnectionClass *conn = SC_get_conn(stmt); if (SC_is_lower_case(stmt, conn)) /* case-insensitive identifier */ ifallupper = FALSE; if (newCt = make_lstring_ifneeded(conn, CatalogName, NameLength1, ifallupper), NULL != newCt) { ctName = newCt; reexec = TRUE; } if (newSc = make_lstring_ifneeded(conn, SchemaName, NameLength2, ifallupper), NULL != newSc) { scName = newSc; reexec = TRUE; } if (newTb = make_lstring_ifneeded(conn, TableName, NameLength3, ifallupper), NULL != newTb) { tbName = newTb; reexec = TRUE; } if (reexec) { ret = PGAPI_SpecialColumns(StatementHandle, IdentifierType, ctName, NameLength1, scName, NameLength2, tbName, NameLength3, Scope, Nullable); if (newCt) free(newCt); if (newSc) free(newSc); if (newTb) free(newTb); } } ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret; }
/* Associate a user-supplied buffer with a database column. */ RETCODE SQL_API PGAPI_BindCol(HSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, PTR rgbValue, SQLLEN cbValueMax, SQLLEN FAR * pcbValue) { StatementClass *stmt = (StatementClass *) hstmt; CSTR func = "PGAPI_BindCol"; ARDFields *opts; GetDataInfo *gdata_info; BindInfoClass *bookmark; RETCODE ret = SQL_SUCCESS; mylog("%s: entering...\n", func); mylog("**** PGAPI_BindCol: stmt = %p, icol = %d\n", stmt, icol); mylog("**** : fCType=%d rgb=%p valusMax=%d pcb=%p\n", fCType, rgbValue, cbValueMax, pcbValue); if (!stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } opts = SC_get_ARDF(stmt); if (stmt->status == STMT_EXECUTING) { SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Can't bind columns while statement is still executing.", func); return SQL_ERROR; } #define return DONT_CALL_RETURN_FROM_HERE ??? SC_clear_error(stmt); /* If the bookmark column is being bound, then just save it */ if (icol == 0) { bookmark = opts->bookmark; if (rgbValue == NULL) { if (bookmark) { bookmark->buffer = NULL; bookmark->used = bookmark->indicator = NULL; } } else { /* Make sure it is the bookmark data type */ switch (fCType) { case SQL_C_BOOKMARK: #if (ODBCVER >= 0x0300) case SQL_C_VARBOOKMARK: #endif /* ODBCVER */ break; default: SC_set_error(stmt, STMT_PROGRAM_TYPE_OUT_OF_RANGE, "Bind column 0 is not of type SQL_C_BOOKMARK", func); inolog("Bind column 0 is type %d not of type SQL_C_BOOKMARK", fCType); ret = SQL_ERROR; goto cleanup; } bookmark = ARD_AllocBookmark(opts); bookmark->buffer = rgbValue; bookmark->used = bookmark->indicator = pcbValue; bookmark->buflen = cbValueMax; bookmark->returntype = fCType; } goto cleanup; } /* * Allocate enough bindings if not already done. Most likely, * execution of a statement would have setup the necessary bindings. * But some apps call BindCol before any statement is executed. */ if (icol > opts->allocated) extend_column_bindings(opts, icol); gdata_info = SC_get_GDTI(stmt); if (icol > gdata_info->allocated) extend_getdata_info(gdata_info, icol, FALSE); /* check to see if the bindings were allocated */ if (!opts->bindings) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Could not allocate memory for bindings.", func); ret = SQL_ERROR; goto cleanup; } /* use zero based col numbers from here out */ icol--; /* Reset for SQLGetData */ gdata_info->gdata[icol].data_left = -1; if (rgbValue == NULL) { /* we have to unbind the column */ opts->bindings[icol].buflen = 0; opts->bindings[icol].buffer = NULL; opts->bindings[icol].used = opts->bindings[icol].indicator = NULL; opts->bindings[icol].returntype = SQL_C_CHAR; opts->bindings[icol].precision = 0; opts->bindings[icol].scale = 0; if (gdata_info->gdata[icol].ttlbuf) free(gdata_info->gdata[icol].ttlbuf); gdata_info->gdata[icol].ttlbuf = NULL; gdata_info->gdata[icol].ttlbuflen = 0; gdata_info->gdata[icol].ttlbufused = 0; } else { /* ok, bind that column */ opts->bindings[icol].buflen = cbValueMax; opts->bindings[icol].buffer = rgbValue; opts->bindings[icol].used = opts->bindings[icol].indicator = pcbValue; opts->bindings[icol].returntype = fCType; opts->bindings[icol].precision = 0; #if (ODBCVER >= 0x0300) switch (fCType) { case SQL_C_NUMERIC: opts->bindings[icol].precision = 32; break; case SQL_C_TIMESTAMP: case SQL_C_INTERVAL_DAY_TO_SECOND: case SQL_C_INTERVAL_HOUR_TO_SECOND: case SQL_C_INTERVAL_MINUTE_TO_SECOND: case SQL_C_INTERVAL_SECOND: opts->bindings[icol].precision = 6; break; } #endif /* ODBCVER */ opts->bindings[icol].scale = 0; mylog(" bound buffer[%d] = %p\n", icol, opts->bindings[icol].buffer); } cleanup: #undef return if (stmt->internal) ret = DiscardStatementSvp(stmt, ret, FALSE); return ret; }
RETCODE SQL_API PGAPI_Cancel( HSTMT hstmt) /* Statement to cancel. */ { CSTR func = "PGAPI_Cancel"; StatementClass *stmt = (StatementClass *) hstmt, *estmt; ConnectionClass *conn; RETCODE ret = SQL_SUCCESS; BOOL entered_cs = FALSE; mylog("%s: entering...\n", func); /* Check if this can handle canceling in the middle of a SQLPutData? */ if (!stmt) { SC_log_error(func, "", NULL); return SQL_INVALID_HANDLE; } conn = SC_get_conn(stmt); #define return DONT_CALL_RETURN_FROM_HERE??? /* StartRollbackState(stmt); */ if (stmt->execute_delegate) estmt = stmt->execute_delegate; else estmt = stmt; /* * Not in the middle of SQLParamData/SQLPutData so cancel like a * close. */ if (estmt->data_at_exec < 0) { /* * Tell the Backend that we're cancelling this request */ if (estmt->status == STMT_EXECUTING) { if (!CC_send_cancel_request(conn)) { ret = SQL_ERROR; } goto cleanup; } /* * MAJOR HACK for Windows to reset the driver manager's cursor * state: Because of what seems like a bug in the Odbc driver * manager, SQLCancel does not act like a SQLFreeStmt(CLOSE), as * many applications depend on this behavior. So, this brute * force method calls the driver manager's function on behalf of * the application. */ if (conn->driver_version < 0x0350) { #ifdef WIN32 ConnInfo *ci = &(conn->connInfo); if (ci->drivers.cancel_as_freestmt) { typedef SQLRETURN (SQL_API *SQLAPIPROC)(); HMODULE hmodule; SQLAPIPROC addr; hmodule = GetModuleHandle("ODBC32"); addr = (SQLAPIPROC) GetProcAddress(hmodule, "SQLFreeStmt"); ret = addr((char *) (stmt->phstmt) - 96, SQL_CLOSE); } else #endif /* WIN32 */ { ENTER_STMT_CS(stmt); entered_cs = TRUE; SC_clear_error(hstmt); ret = PGAPI_FreeStmt(hstmt, SQL_CLOSE); } mylog("PGAPI_Cancel: PGAPI_FreeStmt returned %d\n", ret); } goto cleanup; } /* In the middle of SQLParamData/SQLPutData, so cancel that. */ /* * Note, any previous data-at-exec buffers will be freed in the * recycle */ /* if they call SQLExecDirect or SQLExecute again. */ ENTER_STMT_CS(stmt); entered_cs = TRUE; SC_clear_error(stmt); estmt->data_at_exec = -1; estmt->current_exec_param = -1; estmt->put_data = FALSE; cancelNeedDataState(estmt); cleanup: #undef return if (entered_cs) { if (stmt->internal) ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); } return ret; }
SQLRETURN SQL_API SQLColAttributeW( SQLHSTMT hstmt, SQLUSMALLINT iCol, SQLUSMALLINT iField, SQLPOINTER pCharAttr, SQLSMALLINT cbCharAttrMax, SQLSMALLINT *pcbCharAttr, #if defined(WITH_UNIXODBC) || (defined(WIN32) && ! defined(_WIN64)) SQLPOINTER pNumAttr #else SQLLEN *pNumAttr #endif ) { CSTR func = "SQLColAttributeW"; RETCODE ret; StatementClass *stmt = (StatementClass *) hstmt; SQLSMALLINT *rgbL, blen = 0, bMax; char *rgbD = NULL; mylog("[%s]", func); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); switch (iField) { case SQL_DESC_BASE_COLUMN_NAME: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_CATALOG_NAME: case SQL_DESC_LABEL: case SQL_DESC_LITERAL_PREFIX: case SQL_DESC_LITERAL_SUFFIX: case SQL_DESC_LOCAL_TYPE_NAME: case SQL_DESC_NAME: case SQL_DESC_SCHEMA_NAME: case SQL_DESC_TABLE_NAME: case SQL_DESC_TYPE_NAME: case SQL_COLUMN_NAME: bMax = cbCharAttrMax * 3 / WCLEN; rgbD = malloc(bMax); rgbL = &blen; for (;; bMax = blen + 1, rgbD = realloc(rgbD, bMax)) { ret = PGAPI_ColAttributes(hstmt, iCol, iField, rgbD, bMax, rgbL, pNumAttr); if (SQL_SUCCESS_WITH_INFO != ret || blen < bMax) break; } if (SQL_SUCCEEDED(ret)) { blen = (SQLSMALLINT) utf8_to_ucs2(rgbD, blen, (SQLWCHAR *) pCharAttr, cbCharAttrMax / WCLEN); if (SQL_SUCCESS == ret && blen * WCLEN >= cbCharAttrMax) { ret = SQL_SUCCESS_WITH_INFO; SC_set_error(stmt, STMT_TRUNCATED, "The buffer was too small for the pCharAttr.", func); } if (pcbCharAttr) *pcbCharAttr = blen * WCLEN; } if (rgbD) free(rgbD); break; default: rgbD = pCharAttr; bMax = cbCharAttrMax; rgbL = pcbCharAttr; ret = PGAPI_ColAttributes(hstmt, iCol, iField, rgbD, bMax, rgbL, pNumAttr); break; } ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret; }
RETCODE SQL_API SQLForeignKeysW(HSTMT hstmt, SQLWCHAR *szPkCatalogName, SQLSMALLINT cbPkCatalogName, SQLWCHAR *szPkSchemaName, SQLSMALLINT cbPkSchemaName, SQLWCHAR *szPkTableName, SQLSMALLINT cbPkTableName, SQLWCHAR *szFkCatalogName, SQLSMALLINT cbFkCatalogName, SQLWCHAR *szFkSchemaName, SQLSMALLINT cbFkSchemaName, SQLWCHAR *szFkTableName, SQLSMALLINT cbFkTableName) { CSTR func = "SQLForeignKeysW"; RETCODE ret; char *ctName, *scName, *tbName, *fkctName, *fkscName, *fktbName; SQLLEN nmlen1, nmlen2, nmlen3, nmlen4, nmlen5, nmlen6; StatementClass *stmt = (StatementClass *) hstmt; ConnectionClass *conn; BOOL lower_id; mylog("[%s]", func); conn = SC_get_conn(stmt); lower_id = SC_is_lower_case(stmt, conn); ctName = ucs2_to_utf8(szPkCatalogName, cbPkCatalogName, &nmlen1, lower_id); scName = ucs2_to_utf8(szPkSchemaName, cbPkSchemaName, &nmlen2, lower_id); tbName = ucs2_to_utf8(szPkTableName, cbPkTableName, &nmlen3, lower_id); fkctName = ucs2_to_utf8(szFkCatalogName, cbFkCatalogName, &nmlen4, lower_id); fkscName = ucs2_to_utf8(szFkSchemaName, cbFkSchemaName, &nmlen5, lower_id); fktbName = ucs2_to_utf8(szFkTableName, cbFkTableName, &nmlen6, lower_id); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); if (SC_opencheck(stmt, func)) ret = SQL_ERROR; else ret = PGAPI_ForeignKeys(hstmt, (SQLCHAR *) ctName, (SQLSMALLINT) nmlen1, (SQLCHAR *) scName, (SQLSMALLINT) nmlen2, (SQLCHAR *) tbName, (SQLSMALLINT) nmlen3, (SQLCHAR *) fkctName, (SQLSMALLINT) nmlen4, (SQLCHAR *) fkscName, (SQLSMALLINT) nmlen5, (SQLCHAR *) fktbName, (SQLSMALLINT) nmlen6); ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); if (ctName) free(ctName); if (scName) free(scName); if (tbName) free(tbName); if (fkctName) free(fkctName); if (fkscName) free(fkscName); if (fktbName) free(fktbName); return ret; }
SQLPOINTER NumericAttribute #endif ) { CSTR func = "SQLColAttribute"; RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; mylog("[[%s]]", func); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); ret = PGAPI_ColAttributes(StatementHandle, ColumnNumber, FieldIdentifier, CharacterAttribute, BufferLength, StringLength, NumericAttribute); ret = DiscardStatementSvp(stmt,ret, FALSE); LEAVE_STMT_CS(stmt); return ret; } /* new function */ RETCODE SQL_API SQLCopyDesc(SQLHDESC SourceDescHandle, SQLHDESC TargetDescHandle) { CSTR func = "SQLCopyDesc"; RETCODE ret; mylog("[[%s]]\n", func); ret = PGAPI_CopyDesc(SourceDescHandle, TargetDescHandle); return ret;
RETCODE SQL_API SQLColumnPrivileges(HSTMT hstmt, SQLCHAR *szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR *szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR *szTableName, SQLSMALLINT cbTableName, SQLCHAR *szColumnName, SQLSMALLINT cbColumnName) { CSTR func = "SQLColumnPrivileges"; RETCODE ret; StatementClass *stmt = (StatementClass *) hstmt; SQLCHAR *ctName = szCatalogName, *scName = szSchemaName, *tbName = szTableName, *clName = szColumnName; UWORD flag = 0; mylog("[%s]", func); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); #if (ODBCVER >= 0x0300) if (stmt->options.metadata_id) flag |= PODBC_NOT_SEARCH_PATTERN; #endif if (SC_opencheck(stmt, func)) ret = SQL_ERROR; else ret = PGAPI_ColumnPrivileges(hstmt, ctName, cbCatalogName, scName, cbSchemaName, tbName, cbTableName, clName, cbColumnName, flag); if (SQL_SUCCESS == ret && theResultIsEmpty(stmt)) { BOOL ifallupper = TRUE, reexec = FALSE; SQLCHAR *newCt = NULL, *newSc = NULL, *newTb = NULL, *newCl = NULL; ConnectionClass *conn = SC_get_conn(stmt); if (SC_is_lower_case(stmt, conn)) /* case-insensitive identifier */ ifallupper = FALSE; if (newCt = make_lstring_ifneeded(conn, szCatalogName, cbCatalogName, ifallupper), NULL != newCt) { ctName = newCt; reexec = TRUE; } if (newSc = make_lstring_ifneeded(conn, szSchemaName, cbSchemaName, ifallupper), NULL != newSc) { scName = newSc; reexec = TRUE; } if (newTb = make_lstring_ifneeded(conn, szTableName, cbTableName, ifallupper), NULL != newTb) { tbName = newTb; reexec = TRUE; } if (newCl = make_lstring_ifneeded(conn, szColumnName, cbColumnName, ifallupper), NULL != newCl) { clName = newCl; reexec = TRUE; } if (reexec) { ret = PGAPI_ColumnPrivileges(hstmt, ctName, cbCatalogName, scName, cbSchemaName, tbName, cbTableName, clName, cbColumnName, flag); if (newCt) free(newCt); if (newSc) free(newSc); if (newTb) free(newTb); if (newCl) free(newCl); } } ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret; }
RETCODE SQL_API SQLTables(HSTMT StatementHandle, SQLCHAR *CatalogName, SQLSMALLINT NameLength1, SQLCHAR *SchemaName, SQLSMALLINT NameLength2, SQLCHAR *TableName, SQLSMALLINT NameLength3, SQLCHAR *TableType, SQLSMALLINT NameLength4) { CSTR func = "SQLTables"; RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; SQLCHAR *ctName = CatalogName, *scName = SchemaName, *tbName = TableName; UWORD flag = 0; mylog("[%s]", func); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); #if (ODBCVER >= 0x0300) if (stmt->options.metadata_id) flag |= PODBC_NOT_SEARCH_PATTERN; #endif if (SC_opencheck(stmt, func)) ret = SQL_ERROR; else ret = PGAPI_Tables(StatementHandle, ctName, NameLength1, scName, NameLength2, tbName, NameLength3, TableType, NameLength4, flag); if (SQL_SUCCESS == ret && 0 == QR_get_num_total_tuples(SC_get_Result(stmt))) { BOOL ifallupper = TRUE, reexec = FALSE; char *newCt =NULL, *newSc = NULL, *newTb = NULL; ConnectionClass *conn = SC_get_conn(stmt); if (SC_is_lower_case(stmt, conn)) /* case-insensitive identifier */ ifallupper = FALSE; if (newCt = make_lstring_ifneeded(conn, CatalogName, NameLength1, ifallupper), NULL != newCt) { ctName = newCt; reexec = TRUE; } if (newSc = make_lstring_ifneeded(conn, SchemaName, NameLength2, ifallupper), NULL != newSc) { scName = newSc; reexec = TRUE; } if (newTb = make_lstring_ifneeded(conn, TableName, NameLength3, ifallupper), NULL != newTb) { tbName = newTb; reexec = TRUE; } if (reexec) { ret = PGAPI_Tables(StatementHandle, ctName, NameLength1, scName, NameLength2, tbName, NameLength3, TableType, NameLength4, flag); if (newCt) free(newCt); if (newSc) free(newSc); if (newTb) free(newTb); } } ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret; }
/* * Supplies parameter data at execution time. * Used in conjunction with SQLParamData. */ RETCODE SQL_API PGAPI_PutData( HSTMT hstmt, PTR rgbValue, SQLLEN cbValue) { CSTR func = "PGAPI_PutData"; StatementClass *stmt = (StatementClass *) hstmt, *estmt; ConnectionClass *conn; RETCODE retval = SQL_SUCCESS; APDFields *apdopts; IPDFields *ipdopts; PutDataInfo *pdata; SQLLEN old_pos; ParameterInfoClass *current_param; ParameterImplClass *current_iparam; PutDataClass *current_pdata; char *buffer, *putbuf, *allocbuf = NULL; Int2 ctype; SQLLEN putlen; BOOL lenset = FALSE, handling_lo = FALSE; mylog("%s: entering...\n", func); #define return DONT_CALL_RETURN_FROM_HERE??? if (!stmt) { SC_log_error(func, "", NULL); retval = SQL_INVALID_HANDLE; goto cleanup; } if (SC_AcceptedCancelRequest(stmt)) { SC_set_error(stmt, STMT_OPERATION_CANCELLED, "Cancel the statement, sorry.", func); retval = SQL_ERROR; goto cleanup; } estmt = stmt->execute_delegate ? stmt->execute_delegate : stmt; apdopts = SC_get_APDF(estmt); if (estmt->current_exec_param < 0) { SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Previous call was not SQLPutData or SQLParamData", func); retval = SQL_ERROR; goto cleanup; } current_param = &(apdopts->parameters[estmt->current_exec_param]); ipdopts = SC_get_IPDF(estmt); current_iparam = &(ipdopts->parameters[estmt->current_exec_param]); pdata = SC_get_PDTI(estmt); current_pdata = &(pdata->pdata[estmt->current_exec_param]); ctype = current_param->CType; conn = SC_get_conn(estmt); if (ctype == SQL_C_DEFAULT) { ctype = sqltype_to_default_ctype(conn, current_iparam->SQLType); if (SQL_C_WCHAR == ctype && CC_default_is_c(conn)) ctype = SQL_C_CHAR; } if (SQL_NTS == cbValue) { #ifdef UNICODE_SUPPORT if (SQL_C_WCHAR == ctype) { putlen = WCLEN * ucs2strlen((SQLWCHAR *) rgbValue); lenset = TRUE; } else #endif /* UNICODE_SUPPORT */ if (SQL_C_CHAR == ctype) { putlen = strlen(rgbValue); lenset = TRUE; } } if (!lenset) { if (cbValue < 0) putlen = cbValue; else #ifdef UNICODE_SUPPORT if (ctype == SQL_C_CHAR || ctype == SQL_C_BINARY || ctype == SQL_C_WCHAR) #else if (ctype == SQL_C_CHAR || ctype == SQL_C_BINARY) #endif /* UNICODE_SUPPORT */ putlen = cbValue; else putlen = ctype_length(ctype); } putbuf = rgbValue; handling_lo = (PIC_dsp_pgtype(conn, *current_iparam) == conn->lobj_type); if (handling_lo && SQL_C_CHAR == ctype) { allocbuf = malloc(putlen / 2 + 1); if (allocbuf) { pg_hex2bin(rgbValue, allocbuf, putlen); putbuf = allocbuf; putlen /= 2; } } if (!estmt->put_data) { /* first call */ mylog("PGAPI_PutData: (1) cbValue = %d\n", cbValue); estmt->put_data = TRUE; current_pdata->EXEC_used = (SQLLEN *) malloc(sizeof(SQLLEN)); if (!current_pdata->EXEC_used) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Out of memory in PGAPI_PutData (1)", func); retval = SQL_ERROR; goto cleanup; } *current_pdata->EXEC_used = putlen; if (cbValue == SQL_NULL_DATA) { retval = SQL_SUCCESS; goto cleanup; } /* Handle Long Var Binary with Large Objects */ /* if (current_iparam->SQLType == SQL_LONGVARBINARY) */ if (handling_lo) { /* begin transaction if needed */ if (!CC_is_in_trans(conn)) { if (!CC_begin(conn)) { SC_set_error(stmt, STMT_EXEC_ERROR, "Could not begin (in-line) a transaction", func); retval = SQL_ERROR; goto cleanup; } } /* store the oid */ current_pdata->lobj_oid = odbc_lo_creat(conn, INV_READ | INV_WRITE); if (current_pdata->lobj_oid == 0) { SC_set_error(stmt, STMT_EXEC_ERROR, "Couldnt create large object.", func); retval = SQL_ERROR; goto cleanup; } /* * major hack -- to allow convert to see somethings there have * to modify convert to handle this better */ /***current_param->EXEC_buffer = (char *) ¤t_param->lobj_oid;***/ /* store the fd */ estmt->lobj_fd = odbc_lo_open(conn, current_pdata->lobj_oid, INV_WRITE); if (estmt->lobj_fd < 0) { SC_set_error(stmt, STMT_EXEC_ERROR, "Couldnt open large object for writing.", func); retval = SQL_ERROR; goto cleanup; } retval = odbc_lo_write(conn, estmt->lobj_fd, putbuf, (Int4) putlen); mylog("lo_write: cbValue=%d, wrote %d bytes\n", putlen, retval); } else { current_pdata->EXEC_buffer = malloc(putlen + 1); if (!current_pdata->EXEC_buffer) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Out of memory in PGAPI_PutData (2)", func); retval = SQL_ERROR; goto cleanup; } memcpy(current_pdata->EXEC_buffer, putbuf, putlen); current_pdata->EXEC_buffer[putlen] = '\0'; } } else { /* calling SQLPutData more than once */ mylog("PGAPI_PutData: (>1) cbValue = %d\n", cbValue); /* if (current_iparam->SQLType == SQL_LONGVARBINARY) */ if (handling_lo) { /* the large object fd is in EXEC_buffer */ retval = odbc_lo_write(conn, estmt->lobj_fd, putbuf, (Int4) putlen); mylog("lo_write(2): cbValue = %d, wrote %d bytes\n", putlen, retval); *current_pdata->EXEC_used += putlen; } else { buffer = current_pdata->EXEC_buffer; old_pos = *current_pdata->EXEC_used; if (putlen > 0) { SQLLEN used = *current_pdata->EXEC_used + putlen, allocsize; for (allocsize = (1 << 4); allocsize <= used; allocsize <<= 1) ; mylog(" cbValue = %d, old_pos = %d, *used = %d\n", putlen, old_pos, used); /* dont lose the old pointer in case out of memory */ buffer = realloc(current_pdata->EXEC_buffer, allocsize); if (!buffer) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR,"Out of memory in PGAPI_PutData (3)", func); retval = SQL_ERROR; goto cleanup; } memcpy(&buffer[old_pos], putbuf, putlen); buffer[used] = '\0'; /* reassign buffer incase realloc moved it */ *current_pdata->EXEC_used = used; current_pdata->EXEC_buffer = buffer; } else { SC_set_error(stmt, STMT_INTERNAL_ERROR, "bad cbValue", func); retval = SQL_ERROR; goto cleanup; } } } retval = SQL_SUCCESS; cleanup: #undef return if (allocbuf) free(allocbuf); if (stmt->internal) retval = DiscardStatementSvp(stmt, retval, TRUE); return retval; }