📄 results.c
字号:
}#endif /* ODBCVER */ col_idx = icol - 1; /* atoi(ci->unknown_sizes); */ unknown_sizes = ci->drivers.unknown_sizes; /* not appropriate for SQLColAttributes() */ if (unknown_sizes == UNKNOWNS_AS_DONTKNOW) unknown_sizes = UNKNOWNS_AS_MAX; if (!stmt->catalog_result && SC_is_parse_forced(stmt) && stmt->statement_type == STMT_TYPE_SELECT) { if (SC_parsed_status(stmt) == STMT_PARSE_NONE) { mylog("%s: calling parse_statement\n", func); parse_statement(stmt, FALSE); } cols = irdflds->nfields; /* * Column Count is a special case. The Column number is ignored * in this case. */#if (ODBCVER >= 0x0300) if (fDescType == SQL_DESC_COUNT)#else if (fDescType == SQL_COLUMN_COUNT)#endif /* ODBCVER */ { if (pfDesc) *pfDesc = cols; return SQL_SUCCESS; } if (SC_parsed_status(stmt) != STMT_PARSE_FATAL && irdflds->fi) { if (col_idx >= cols) { SC_set_error(stmt, STMT_INVALID_COLUMN_NUMBER_ERROR, "Invalid column number in ColAttributes.", func); return SQL_ERROR; } } } if (col_idx < irdflds->nfields && irdflds->fi) fi = irdflds->fi[col_idx]; if (FI_is_applicable(fi)) field_type = (conn->lobj_type == fi->columntype) ? fi->columntype : FI_type(fi); else { BOOL build_fi = FALSE; fi = NULL; if (PROTOCOL_74(ci)) { switch (fDescType) { case SQL_COLUMN_OWNER_NAME: case SQL_COLUMN_TABLE_NAME: case SQL_COLUMN_TYPE: case SQL_COLUMN_TYPE_NAME: case SQL_COLUMN_AUTO_INCREMENT:#if (ODBCVER >= 0x0300) case SQL_DESC_NULLABLE: case SQL_DESC_BASE_TABLE_NAME: case SQL_DESC_BASE_COLUMN_NAME:#else case SQL_COLUMN_NULLABLE:#endif /* ODBCVER */ case SQL_COLUMN_UPDATABLE: case 1212: /* SQL_CA_SS_COLUMN_KEY ? */ build_fi = TRUE; break; } } if (!SC_pre_execute_ok(stmt, build_fi, col_idx, func)) return SQL_ERROR; res = SC_get_Curres(stmt); cols = QR_NumPublicResultCols(res); /* * Column Count is a special case. The Column number is ignored * in this case. */#if (ODBCVER >= 0x0300) if (fDescType == SQL_DESC_COUNT)#else if (fDescType == SQL_COLUMN_COUNT)#endif /* ODBCVER */ { if (pfDesc) *pfDesc = cols; return SQL_SUCCESS; } if (col_idx >= cols) { SC_set_error(stmt, STMT_INVALID_COLUMN_NUMBER_ERROR, "Invalid column number in ColAttributes.", func); return SQL_ERROR; } field_type = QR_get_field_type(res, col_idx); if (col_idx < irdflds->nfields && irdflds->fi) fi = irdflds->fi[col_idx]; } if (FI_is_applicable(fi)) { ti = fi->ti; field_type = (conn->lobj_type == fi->columntype) ? fi->columntype : FI_type(fi); } mylog("colAttr: col %d field_type=%d fi,ti=%p,%p\n", col_idx, field_type, fi, ti); switch (fDescType) { case SQL_COLUMN_AUTO_INCREMENT: /* == SQL_DESC_AUTO_UNIQUE_VALUE */ if (fi && fi->auto_increment) value = TRUE; else value = pgtype_auto_increment(stmt, field_type); if (value == -1) /* non-numeric becomes FALSE (ODBC Doc) */ value = FALSE; mylog("AUTO_INCREMENT=%d\n", value); break; case SQL_COLUMN_CASE_SENSITIVE: /* == SQL_DESC_CASE_SENSITIVE */ value = pgtype_case_sensitive(stmt, field_type); break; /* * This special case is handled above. * * case SQL_COLUMN_COUNT: */ case SQL_COLUMN_DISPLAY_SIZE: /* == SQL_DESC_DISPLAY_SIZE */ value = (fi && 0 != fi->display_size) ? fi->display_size : pgtype_display_size(stmt, field_type, col_idx, unknown_sizes); mylog("%s: col %d, display_size= %d\n", func, col_idx, value); break; case SQL_COLUMN_LABEL: /* == SQL_DESC_LABEL */ if (fi && (NAME_IS_VALID(fi->column_alias))) { p = GET_NAME(fi->column_alias); mylog("%s: COLUMN_LABEL = '%s'\n", func, p); break; } /* otherwise same as column name -- FALL THROUGH!!! */#if (ODBCVER >= 0x0300) case SQL_DESC_NAME:#else case SQL_COLUMN_NAME:#endif /* ODBCVER */inolog("fi=%p", fi);if (fi)inolog(" (%s,%s)", PRINT_NAME(fi->column_alias), PRINT_NAME(fi->column_name)); p = fi ? (NAME_IS_NULL(fi->column_alias) ? SAFE_NAME(fi->column_name) : GET_NAME(fi->column_alias)) : QR_get_fieldname(res, col_idx); mylog("%s: COLUMN_NAME = '%s'\n", func, p); break; case SQL_COLUMN_LENGTH: value = (fi && fi->length > 0) ? fi->length : pgtype_buffer_length(stmt, field_type, col_idx, unknown_sizes); if (0 > value) /* if (-1 == value) I'm not sure which is right */ value = 0; mylog("%s: col %d, column_length = %d\n", func, col_idx, value); break; case SQL_COLUMN_MONEY: /* == SQL_DESC_FIXED_PREC_SCALE */ value = pgtype_money(stmt, field_type);inolog("COLUMN_MONEY=%d\n", value); break;#if (ODBCVER >= 0x0300) case SQL_DESC_NULLABLE:#else case SQL_COLUMN_NULLABLE:#endif /* ODBCVER */ if (SC_has_outer_join(stmt)) value = TRUE; else value = fi ? fi->nullable : pgtype_nullable(stmt, field_type);inolog("COLUMN_NULLABLE=%d\n", value); break; case SQL_COLUMN_OWNER_NAME: /* == SQL_DESC_SCHEMA_NAME */ p = ti ? SAFE_NAME(ti->schema_name) : NULL_STRING; mylog("%s: SCHEMA_NAME = '%s'\n", func, p); break; case SQL_COLUMN_PRECISION: /* in 2.x */ value = (fi && fi->column_size > 0) ? fi->column_size : pgtype_column_size(stmt, field_type, col_idx, unknown_sizes); if (value < 0) value = 0; mylog("%s: col %d, column_size = %d\n", func, col_idx, value); break; case SQL_COLUMN_QUALIFIER_NAME: /* == SQL_DESC_CATALOG_NAME */ p = ti ? CurrCatString(conn) : NULL_STRING; /* empty string means *not supported* */ break; case SQL_COLUMN_SCALE: /* in 2.x */ value = pgtype_decimal_digits(stmt, field_type, col_idx);inolog("COLUMN_SCALE=%d\n", value); if (value < 0) value = 0; break; case SQL_COLUMN_SEARCHABLE: /* == SQL_DESC_SEARCHABLE */ value = pgtype_searchable(stmt, field_type); break; case SQL_COLUMN_TABLE_NAME: /* == SQL_DESC_TABLE_NAME */ p = ti ? SAFE_NAME(ti->table_name) : NULL_STRING; mylog("%s: TABLE_NAME = '%s'\n", func, p); break; case SQL_COLUMN_TYPE: /* == SQL_DESC_CONCISE_TYPE */ value = pgtype_to_concise_type(stmt, field_type, col_idx); mylog("COLUMN_TYPE=%d\n", value); break; case SQL_COLUMN_TYPE_NAME: /* == SQL_DESC_TYPE_NAME */ p = pgtype_to_name(stmt, field_type, fi && fi->auto_increment); break; case SQL_COLUMN_UNSIGNED: /* == SQL_DESC_UNSINGED */ value = pgtype_unsigned(stmt, field_type); if (value == -1) /* non-numeric becomes TRUE (ODBC Doc) */ value = SQL_TRUE; break; case SQL_COLUMN_UPDATABLE: /* == SQL_DESC_UPDATABLE */ /* * Neither Access or Borland care about this. * * if (field_type == PG_TYPE_OID) pfDesc = SQL_ATTR_READONLY; * else */ value = fi ? (fi->updatable ? SQL_ATTR_WRITE : SQL_ATTR_READONLY) : (QR_get_attid(res, col_idx) > 0 ? SQL_ATTR_WRITE : (PROTOCOL_74(ci) ? SQL_ATTR_READONLY : SQL_ATTR_READWRITE_UNKNOWN)); if (SQL_ATTR_READONLY != value) { const char *name = fi ? SAFE_NAME(fi->column_name) : QR_get_fieldname(res, col_idx); if (stricmp(name, OID_NAME) == 0 || stricmp(name, "ctid") == 0 || stricmp(name, "xmin") == 0) value = SQL_ATTR_READONLY; else if (conn->ms_jet && fi && fi->auto_increment) value = SQL_ATTR_READONLY; } mylog("%s: UPDATEABLE = %d\n", func, value); break;#if (ODBCVER >= 0x0300) case SQL_DESC_BASE_COLUMN_NAME: p = fi ? SAFE_NAME(fi->column_name) : QR_get_fieldname(res, col_idx); mylog("%s: BASE_COLUMN_NAME = '%s'\n", func, p); break; case SQL_DESC_BASE_TABLE_NAME: /* the same as TABLE_NAME ok ? */ p = ti ? SAFE_NAME(ti->table_name) : NULL_STRING; mylog("%s: BASE_TABLE_NAME = '%s'\n", func, p); break; case SQL_DESC_LENGTH: /* different from SQL_COLUMN_LENGTH */ value = (fi && fi->length > 0) ? fi->length : pgtype_desclength(stmt, field_type, col_idx, unknown_sizes); if (-1 == value) value = 0; mylog("%s: col %d, desc_length = %d\n", func, col_idx, value); break; case SQL_DESC_OCTET_LENGTH: value = (fi && fi->length > 0) ? fi->length : pgtype_transfer_octet_length(stmt, field_type, col_idx, unknown_sizes); if (-1 == value) value = 0; mylog("%s: col %d, octet_length = %d\n", func, col_idx, value); break; case SQL_DESC_PRECISION: /* different from SQL_COLUMN_PRECISION */ if (value = FI_precision(fi), value <= 0) value = pgtype_precision(stmt, field_type, col_idx, unknown_sizes); if (value < 0) value = 0; mylog("%s: col %d, desc_precision = %d\n", func, col_idx, value); break; case SQL_DESC_SCALE: /* different from SQL_COLUMN_SCALE */ value = pgtype_scale(stmt, field_type, col_idx); if (value < 0) value = 0; break; case SQL_DESC_LOCAL_TYPE_NAME: p = pgtype_to_name(stmt, field_type, fi && fi->auto_increment); break; case SQL_DESC_TYPE: value = pgtype_to_sqldesctype(stmt, field_type, col_idx); break; case SQL_DESC_NUM_PREC_RADIX: value = pgtype_radix(stmt, field_type); break; case SQL_DESC_LITERAL_PREFIX: p = pgtype_literal_prefix(stmt, field_type); break; case SQL_DESC_LITERAL_SUFFIX: p = pgtype_literal_suffix(stmt, field_type); break; case SQL_DESC_UNNAMED: value = (fi && NAME_IS_NULL(fi->column_name) && NAME_IS_NULL(fi->column_alias)) ? SQL_UNNAMED : SQL_NAMED; break;#endif /* ODBCVER */ case 1211: /* SQL_CA_SS_COLUMN_HIDDEN ? */ value = 0; break; case 1212: /* SQL_CA_SS_COLUMN_KEY ? */ if (fi) { if (fi->columnkey < 0) { SC_set_SS_columnkey(stmt); } value = fi->columnkey; mylog("%s:SS_COLUMN_KEY=%d\n", func, value); break; } SC_set_error(stmt, STMT_OPTION_NOT_FOR_THE_DRIVER, "this request may be for MS SQL Server", func); return SQL_ERROR; default: SC_set_error(stmt, STMT_INVALID_OPTION_IDENTIFIER, "ColAttribute for this type not implemented yet", func); return SQL_ERROR; } result = SQL_SUCCESS; if (p) { /* char/binary data */ size_t len = strlen(p); if (rgbDesc) { strncpy_null((char *) rgbDesc, p, (size_t) cbDescMax); if (len >= cbDescMax) { result = SQL_SUCCESS_WITH_INFO; SC_set_error(stmt, STMT_TRUNCATED, "The buffer was too small for the rgbDesc.", func); } } if (pcbDesc) *pcbDesc = (SQLSMALLINT) len; } else { /* numeric data */ if (pfDesc) *pfDesc = value; } return result;}/* Returns result data for a single column in the current row. */RETCODE SQL_APIPGAPI_GetData( HSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, PTR rgbValue, SQLLEN cbValueMax, SQLLEN FAR * pcbValue){ CSTR func = "PGAPI_GetData"; QResultClass *res; StatementClass *stmt = (StatementClass *) hstmt; UInt2 num_cols; SQLLEN num_rows; OID field_type; void *value = NULL; RETCODE result = SQL_SUCCESS; char get_bookmark = FALSE; ConnInfo *ci; SQLSMALLINT target_type; mylog("%s: enter, stmt=%p icol=%d\n", func, stmt, icol); if (!stmt) { SC_log_error(func, NULL_STRING, NULL); return SQL_INVALID_HANDLE; } ci = &(SC_get_conn(stmt)->connInfo); res = SC_get_Curres(stmt); if (STMT_EXECUTING == stmt->status) { SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Can't get data while statement is still executing.", func); return SQL_ERROR; } if (stmt->status != STMT_FINISHED) { SC_set_error(stmt, STMT_STATUS_ERROR, "GetData can only be called after the successful execution on a SQL statement", func); return SQL_ERROR; } if (SQL_ARD_TYPE == fCType) { ARDFields *opts; BindInfoClass *binfo = NULL; opts = SC_get_ARDF(stmt); if (0 == icol) binfo = opts->bookmark; else if (icol <= opts->allocated && opts->bindings) binfo = &opts->bindings[icol - 1]; if (binfo) { target_type = binfo->returntype; mylog("SQL_ARD_TYPE=%d\n", target_type); } else { SC_set_error(stmt, STMT_STATUS_ERROR, "GetData can't determine the type via ARD", func); return SQL_ERROR; } } else target_type = fCType; if (icol == 0) { if (stmt->options.use_bookmarks == SQL_UB_OFF) { SC_set_error(stmt, STMT_COLNUM_ERROR, "Attempt to retrieve bookmark with bookmark usage disabled", func); return SQL_ERROR; } /* Make sure it is the bookmark data type */ switch (target_type) { case SQL_C_BOOKMARK:#if (ODBCVER >= 0x0300) case SQL_C_VARBOOKMARK:#endif /* ODBCVER */ break; default:inolog("GetData Column 0 is type %d not of type SQL_C_BOOKMARK", target_type); SC_set_error(stmt, STMT_PROGRAM_TYPE_OUT_OF_RANGE, "Column 0 is not of type SQL_C_BOOKMARK", func); return SQL_ERROR; } get_bookmark = TRUE; } else { /* use zero-based column numbers */ icol--; /* make sure the column number is valid */ num_cols = QR_NumPublicResultCols(res); if (icol >= num_cols) { SC_set_error(stmt, STMT_INVALID_COLUMN_NUMBER_ERROR, "Invalid column number.", func); return SQL_ERROR; } }#define return DONT_CALL_RETURN_FROM_HERE??? /* StartRollbackState(stmt); */ if (!SC_is_fetchcursor(stmt)) { /* make sure we're positioned on a valid row */ num_rows = QR_get_num_total_tuples(res); if ((stmt->currTuple < 0) || (stmt->currTuple >= num_rows)) { SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row for GetData.", func); result = SQL_ERROR; goto cleanup; } mylog(" num_rows = %d\n", num_rows); if (!get_bookmark) { SQLLEN curt = GIdx2CacheIdx(stmt->currTuple, stmt, res); value = QR_get_value_backend_row(res, curt, icol);inolog("currT=%d base=%d rowset=%d\n", stmt->currTuple, QR_get_rowstart_in_cache(res), SC_get_rowset_start(stmt)); mylog(" value = '%s'\n", value ? value : "(null)"); } } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -