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); stmt->exec_current_row = -1; ret = PGAPI_Execute(StatementHandle, flag); ret = DiscardStatementSvp(stmt, ret, FALSE); } LEAVE_STMT_CS(stmt); return ret; }
/* Performs the equivalent of SQLPrepare, followed by SQLExecute. */ RETCODE SQL_API PGAPI_ExecDirect( HSTMT hstmt, const SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStr, UWORD flag) { StatementClass *stmt = (StatementClass *) hstmt; RETCODE result; CSTR func = "PGAPI_ExecDirect"; const ConnectionClass *conn = SC_get_conn(stmt); mylog("%s: entering...%x\n", func, flag); if (result = SC_initialize_and_recycle(stmt), SQL_SUCCESS != result) return result; /* * keep a copy of the un-parametrized statement, in case they try to * execute this statement again */ stmt->statement = make_string(szSqlStr, cbSqlStr, NULL, 0); inolog("a2\n"); if (!stmt->statement) { SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "No memory available to store statement", func); return SQL_ERROR; } mylog("**** %s: hstmt=%p, statement='%s'\n", func, hstmt, stmt->statement); if (0 != (flag & PODBC_WITH_HOLD)) SC_set_with_hold(stmt); /* * If an SQLPrepare was performed prior to this, but was left in the * premature state because an error occurred prior to SQLExecute then * set the statement to finished so it can be recycled. */ if (stmt->status == STMT_PREMATURE) stmt->status = STMT_FINISHED; stmt->statement_type = statement_type(stmt->statement); /* Check if connection is onlyread (only selects are allowed) */ if (CC_is_onlyread(conn) && STMT_UPDATE(stmt)) { SC_set_error(stmt, STMT_EXEC_ERROR, "Connection is readonly, only select statements are allowed.", func); return SQL_ERROR; } mylog("%s: calling PGAPI_Execute...\n", func); flag = SC_is_with_hold(stmt) ? PODBC_WITH_HOLD : 0; result = PGAPI_Execute(hstmt, flag); mylog("%s: returned %hd from PGAPI_Execute\n", func, result); return result; }
/* * 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; }