📄 statement.c
字号:
{ mylog(" preprocess: after status = FINISHED, so set PREMATURE\n"); self->status = STMT_PREMATURE; } } if (res = SC_get_Curres(self), NULL != res) { num_fields = QR_NumResultCols(res); return num_fields; } } if (!SC_is_pre_executable(self)) { SC_set_Result(self, QR_Constructor()); QR_set_rstatus(SC_get_Result(self), PORES_TUPLES_OK); self->inaccurate_result = TRUE; self->status = STMT_PREMATURE; num_fields = 0; } } return num_fields;}/* This is only called from SQLFreeStmt(SQL_UNBIND) */charSC_unbind_cols(StatementClass *self){ ARDFields *opts = SC_get_ARDF(self); GetDataInfo *gdata = SC_get_GDTI(self); BindInfoClass *bookmark; ARD_unbind_cols(opts, FALSE); GDATA_unbind_cols(gdata, FALSE); if (bookmark = opts->bookmark, bookmark != NULL) { bookmark->buffer = NULL; bookmark->used = NULL; } return 1;}voidSC_clear_error(StatementClass *self){ QResultClass *res; self->__error_number = 0; if (self->__error_message) { free(self->__error_message); self->__error_message = NULL; } if (self->pgerror) { ER_Destructor(self->pgerror); self->pgerror = NULL; } self->diag_row_count = 0; if (res = SC_get_Curres(self), res) { QR_set_message(res, NULL); QR_set_notice(res, NULL); res->sqlstate[0] = '\0'; } self->stmt_time = 0; SC_unref_CC_error(self);}/* * This function creates an error info which is the concatenation * of the result, statement, connection, and socket messages. *//* Map sql commands to statement types */static struct{ int number; const char * ver3str; const char * ver2str;} Statement_sqlstate[] ={ { STMT_ERROR_IN_ROW, "01S01", "01S01" }, { STMT_OPTION_VALUE_CHANGED, "01S02", "01S02" }, { STMT_ROW_VERSION_CHANGED, "01001", "01001" }, /* data changed */ { STMT_POS_BEFORE_RECORDSET, "01S06", "01S06" }, { STMT_TRUNCATED, "01004", "01004" }, /* data truncated */ { STMT_INFO_ONLY, "00000", "00000" }, /* just an information that is returned, no error */ { STMT_OK, "00000", "00000" }, /* OK */ { STMT_EXEC_ERROR, "HY000", "S1000" }, /* also a general error */ { STMT_STATUS_ERROR, "HY010", "S1010" }, { STMT_SEQUENCE_ERROR, "HY010", "S1010" }, /* Function sequence error */ { STMT_NO_MEMORY_ERROR, "HY001", "S1001" }, /* memory allocation failure */ { STMT_COLNUM_ERROR, "07009", "S1002" }, /* invalid column number */ { STMT_NO_STMTSTRING, "HY001", "S1001" }, /* having no stmtstring is also a malloc problem */ { STMT_ERROR_TAKEN_FROM_BACKEND, "HY000", "S1000" }, /* general error */ { STMT_INTERNAL_ERROR, "HY000", "S1000" }, /* general error */ { STMT_STILL_EXECUTING, "HY010", "S1010" }, { STMT_NOT_IMPLEMENTED_ERROR, "HYC00", "S1C00" }, /* == 'driver not * capable' */ { STMT_BAD_PARAMETER_NUMBER_ERROR, "07009", "S1093" }, { STMT_OPTION_OUT_OF_RANGE_ERROR, "HY092", "S1092" }, { STMT_INVALID_COLUMN_NUMBER_ERROR, "07009", "S1002" }, { STMT_RESTRICTED_DATA_TYPE_ERROR, "07006", "07006" }, { STMT_INVALID_CURSOR_STATE_ERROR, "07005", "24000" }, { STMT_CREATE_TABLE_ERROR, "42S01", "S0001" }, /* table already exists */ { STMT_NO_CURSOR_NAME, "S1015", "S1015" }, { STMT_INVALID_CURSOR_NAME, "34000", "34000" }, { STMT_INVALID_ARGUMENT_NO, "HY024", "S1009" }, /* invalid argument value */ { STMT_ROW_OUT_OF_RANGE, "HY107", "S1107" }, { STMT_OPERATION_CANCELLED, "HY008", "S1008" }, { STMT_INVALID_CURSOR_POSITION, "HY109", "S1109" }, { STMT_VALUE_OUT_OF_RANGE, "HY019", "22003" }, { STMT_OPERATION_INVALID, "HY011", "S1011" }, { STMT_PROGRAM_TYPE_OUT_OF_RANGE, "?????", "?????" }, { STMT_BAD_ERROR, "08S01", "08S01" }, /* communication link failure */ { STMT_INVALID_OPTION_IDENTIFIER, "HY092", "HY092" }, { STMT_RETURN_NULL_WITHOUT_INDICATOR, "22002", "22002" }, { STMT_INVALID_DESCRIPTOR_IDENTIFIER, "HY091", "HY091" }, { STMT_OPTION_NOT_FOR_THE_DRIVER, "HYC00", "HYC00" }, { STMT_FETCH_OUT_OF_RANGE, "HY106", "S1106" }, { STMT_COUNT_FIELD_INCORRECT, "07002", "07002" }, { STMT_INVALID_NULL_ARG, "HY009", "S1009" }};static PG_ErrorInfo *SC_create_errorinfo(const StatementClass *self){ QResultClass *res = SC_get_Curres(self); ConnectionClass *conn = SC_get_conn(self); Int4 errornum; size_t pos; BOOL resmsg = FALSE, detailmsg = FALSE, msgend = FALSE; char msg[4096], *wmsg; char *ermsg = NULL, *sqlstate = NULL; PG_ErrorInfo *pgerror; if (self->pgerror) return self->pgerror; errornum = self->__error_number; if (errornum == 0) return NULL; msg[0] = '\0'; if (res) { if (res->sqlstate[0]) sqlstate = res->sqlstate; if (res->message) { strncpy(msg, res->message, sizeof(msg)); detailmsg = resmsg = TRUE; } if (msg[0]) ermsg = msg; else if (QR_get_notice(res)) { char *notice = QR_get_notice(res); size_t len = strlen(notice); if (len < sizeof(msg)) { memcpy(msg, notice, len); msg[len] = '\0'; ermsg = msg; } else { ermsg = notice; msgend = TRUE; } } } if (!msgend && (wmsg = SC_get_errormsg(self)) && wmsg[0]) { pos = strlen(msg); if (detailmsg) { msg[pos++] = ';'; msg[pos++] = '\n'; } strncpy(msg + pos, wmsg, sizeof(msg) - pos); ermsg = msg; detailmsg = TRUE; } if (!self->ref_CC_error) msgend = TRUE; if (conn && !msgend) { SocketClass *sock = conn->sock; const char *sockerrmsg; if (!resmsg && (wmsg = CC_get_errormsg(conn)) && wmsg[0] != '\0') { pos = strlen(msg); snprintf(&msg[pos], sizeof(msg) - pos, ";\n%s", CC_get_errormsg(conn)); } if (sock && NULL != (sockerrmsg = SOCK_get_errmsg(sock)) && '\0' != sockerrmsg[0]) { pos = strlen(msg); snprintf(&msg[pos], sizeof(msg) - pos, ";\n%s", sockerrmsg); } ermsg = msg; } pgerror = ER_Constructor(self->__error_number, ermsg); if (sqlstate) strcpy(pgerror->sqlstate, sqlstate); else if (conn) { if (!msgend && conn->sqlstate[0]) strcpy(pgerror->sqlstate, conn->sqlstate); else { EnvironmentClass *env = (EnvironmentClass *) conn->henv; errornum -= LOWEST_STMT_ERROR; if (errornum < 0 || errornum >= sizeof(Statement_sqlstate) / sizeof(Statement_sqlstate[0])) errornum = 1 - LOWEST_STMT_ERROR; strcpy(pgerror->sqlstate, EN_is_odbc3(env) ? Statement_sqlstate[errornum].ver3str : Statement_sqlstate[errornum].ver2str); } } return pgerror;}StatementClass *SC_get_ancestor(StatementClass *stmt){ StatementClass *child = stmt, *parent;inolog("SC_get_ancestor in stmt=%p\n", stmt); for (child = stmt, parent = child->execute_parent; parent; child = parent, parent = child->execute_parent) { inolog("parent=%p\n", parent); } return child;}void SC_reset_delegate(RETCODE retcode, StatementClass *stmt){ StatementClass *delegate = stmt->execute_delegate; if (!delegate) return; PGAPI_FreeStmt(delegate, SQL_DROP);}voidSC_set_error(StatementClass *self, int number, const char *message, const char *func){ if (self->__error_message) free(self->__error_message); self->__error_number = number; self->__error_message = message ? strdup(message) : NULL; if (func && number != STMT_OK && number != STMT_INFO_ONLY) SC_log_error(func, "", self);}voidSC_set_errormsg(StatementClass *self, const char *message){ if (self->__error_message) free(self->__error_message); self->__error_message = message ? strdup(message) : NULL;}voidSC_replace_error_with_res(StatementClass *self, int number, const char *message, const QResultClass *from_res, BOOL check){ QResultClass *self_res; BOOL repstate;inolog("SC_set_error_from_res %p->%p check=%i\n", from_res ,self, check); if (check) { if (0 == number) return; if (0 > number && /* SQL_SUCCESS_WITH_INFO */ 0 < self->__error_number) return; } self->__error_number = number; if (!check || message) { if (self->__error_message) free(self->__error_message); self->__error_message = message ? strdup(message) : NULL; } if (self->pgerror) { ER_Destructor(self->pgerror); self->pgerror = NULL; } self_res = SC_get_Curres(self); if (!self_res) return; if (self_res == from_res) return; QR_add_message(self_res, QR_get_message(from_res)); QR_add_notice(self_res, QR_get_notice(from_res)); repstate = FALSE; if (!check) repstate = TRUE; else if (from_res->sqlstate[0]) { if (!self_res->sqlstate[0] || strncmp(self_res->sqlstate, "00", 2) == 0) repstate = TRUE; else if (strncmp(from_res->sqlstate, "01", 2) >= 0) repstate = TRUE; } if (repstate) strcpy(self_res->sqlstate, from_res->sqlstate);}voidSC_error_copy(StatementClass *self, const StatementClass *from, BOOL check){ QResultClass *self_res, *from_res; BOOL repstate;inolog("SC_error_copy %p->%p check=%i\n", from ,self, check); if (self == from) return; if (check) { if (0 == from->__error_number) /* SQL_SUCCESS */ return; if (0 > from->__error_number && /* SQL_SUCCESS_WITH_INFO */ 0 < self->__error_number) return; } self->__error_number = from->__error_number; if (!check || from->__error_message) { if (self->__error_message) free(self->__error_message); self->__error_message = from->__error_message ? strdup(from->__error_message) : NULL; } if (self->pgerror) { ER_Destructor(self->pgerror); self->pgerror = NULL; } self_res = SC_get_Curres(self); from_res = SC_get_Curres(from); if (!self_res || !from_res) return; QR_add_message(self_res, QR_get_message(from_res)); QR_add_notice(self_res, QR_get_notice(from_res)); repstate = FALSE; if (!check) repstate = TRUE; else if (from_res->sqlstate[0]) { if (!self_res->sqlstate[0] || strncmp(self_res->sqlstate, "00", 2) == 0) repstate = TRUE; else if (strncmp(from_res->sqlstate, "01", 2) >= 0) repstate = TRUE; } if (repstate) strcpy(self_res->sqlstate, from_res->sqlstate);}voidSC_full_error_copy(StatementClass *self, const StatementClass *from, BOOL allres){ PG_ErrorInfo *pgerror;inolog("SC_full_error_copy %p->%p\n", from ,self); if (self->__error_message) { free(self->__error_message); self->__error_message = NULL; } if (from->__error_message) self->__error_message = strdup(from->__error_message); self->__error_number = from->__error_number; if (from->pgerror) { if (self->pgerror) ER_Destructor(self->pgerror); self->pgerror = ER_Dup(from->pgerror); return; } else if (!allres) return; pgerror = SC_create_errorinfo(from); if (!pgerror->__error_message[0]) { ER_Destructor(pgerror); return; } if (self->pgerror) ER_Destructor(self->pgerror); self->pgerror = pgerror;}/* Returns the next SQL error information. */RETCODE SQL_APIPGAPI_StmtError( SQLHSTMT hstmt, SQLSMALLINT RecNumber, SQLCHAR FAR * szSqlState, SQLINTEGER FAR * pfNativeError, SQLCHAR FAR * szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT FAR * pcbErrorMsg, UWORD flag){ /* CC: return an error of a hdesc */ StatementClass *stmt = (StatementClass *) hstmt; stmt->pgerror = SC_create_errorinfo(stmt); return ER_ReturnError(&(stmt->pgerror), RecNumber, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg, flag);}time_tSC_get_time(StatementClass *stmt){ if (!stmt) return time(NULL); if (0 == stmt->stmt_time) stmt->stmt_time = time(NULL); return stmt->stmt_time;}/* * Currently, the driver offers very simple bookmark support -- it is * just the current row number. But it could be more sophisticated * someday, such as mapping a key to a 32 bit value */SQLULENSC_get_bookmark(StatementClass *self){ return SC_make_bookmark(self->currTuple);}RETCODESC_fetch(StatementClass *self){ CSTR func = "SC_fetch"; QResultClass *res = SC_get_Curres(self); ARDFields *opts; GetDataInfo *gdata; int retval; RETCODE result; Int2 num_cols, lf; OID type; char *value; ColumnInfoClass *coli; BindInfoClass *bookmark; /* TupleField *tupleField; */inolog("%s statement=%p ommitted=0\n", func, self); self->last_fetch_count = self->last_fetch_count_include_ommitted = 0; coli = QR_get_fields(res); /* the column info */ mylog("fetch_cursor=%d, %p->total_read=%d\n", SC_is_fetchcursor(self), res, res->num_total_read); if (!SC_is_fetchcursor(self)) { if (self->currTuple >= (Int4) QR_get_num_total_tuples(res) - 1 || (self->options.maxRows > 0 && self->currTuple == self->options.maxRows - 1)) { /* * if at the end of the tuples, return "no data found" and set * the cursor past the end of the result set */ self->currTuple = QR_get_num_total_tuples(res); return SQL_NO_DATA_FOUND; } mylog("**** %s: non-cursor_result\n", func); (self->currTuple)++; } else { /* read from the cache or the physical next tuple */ retval = QR_next_tuple(res, self); if (retval < 0) { mylog("**** %s: end_tuples\n", func); if (QR_get_cursor(res) && SQL_CURSOR_FORWARD_ONLY == self->options.cursor_type && QR_once_reached_eof(res)) QR_close(res); return SQL_NO_DATA_FOUND; } else if (retval > 0) (self->currTuple)++; /* all is well */ else { ConnectionClass *conn = SC_get_conn(self);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -