📄 info.c
字号:
len = 2; value = 0; break; case SQL_MAX_USER_NAME_LEN: len = 2; value = 0; break; case SQL_MULT_RESULT_SETS: /* ODBC 1.0 */ /* Don't support multiple result sets but say yes anyway? */ p = "Y"; break; case SQL_MULTIPLE_ACTIVE_TXN: /* ODBC 1.0 */ p = "Y"; break; case SQL_NEED_LONG_DATA_LEN: /* ODBC 2.0 */ /* * Don't need the length, SQLPutData can handle any size and * multiple calls */ p = "N"; break; case SQL_NON_NULLABLE_COLUMNS: /* ODBC 1.0 */ len = 2; value = SQL_NNC_NON_NULL; break; case SQL_NULL_COLLATION: /* ODBC 2.0 */ /* where are nulls sorted? */ len = 2; if (PG_VERSION_GE(conn, 7.2)) value = SQL_NC_HIGH; else value = SQL_NC_END; break; case SQL_NUMERIC_FUNCTIONS: /* ODBC 1.0 */ len = 4; value = 0; break; case SQL_ODBC_API_CONFORMANCE: /* ODBC 1.0 */ len = 2; value = SQL_OAC_LEVEL1; break; case SQL_ODBC_SAG_CLI_CONFORMANCE: /* ODBC 1.0 */ len = 2; value = SQL_OSCC_NOT_COMPLIANT; break; case SQL_ODBC_SQL_CONFORMANCE: /* ODBC 1.0 */ len = 2; value = SQL_OSC_CORE; break; case SQL_ODBC_SQL_OPT_IEF: /* ODBC 1.0 */ p = "N"; break; case SQL_OJ_CAPABILITIES: /* ODBC 2.01 */ len = 4; if (PG_VERSION_GE(conn, 7.1)) { /* OJs in 7.1+ */ value = (SQL_OJ_LEFT | SQL_OJ_RIGHT | SQL_OJ_FULL | SQL_OJ_NESTED | SQL_OJ_NOT_ORDERED | SQL_OJ_INNER | SQL_OJ_ALL_COMPARISON_OPS); } else /* OJs not in <7.1 */ value = 0; break; case SQL_ORDER_BY_COLUMNS_IN_SELECT: /* ODBC 2.0 */ p = (PG_VERSION_LE(conn, 6.3)) ? "Y" : "N"; break; case SQL_OUTER_JOINS: /* ODBC 1.0 */ if (PG_VERSION_GE(conn, 7.1)) /* OJs in 7.1+ */ p = "Y"; else /* OJs not in <7.1 */ p = "N"; break; case SQL_OWNER_TERM: /* ODBC 1.0 */ if (conn->schema_support) p = "schema"; else p = "owner"; break; case SQL_OWNER_USAGE: /* ODBC 2.0 */ len = 4; value = 0; if (conn->schema_support) value = SQL_OU_DML_STATEMENTS | SQL_OU_TABLE_DEFINITION | SQL_OU_INDEX_DEFINITION | SQL_OU_PRIVILEGE_DEFINITION ; break; case SQL_POS_OPERATIONS: /* ODBC 2.0 */ len = 4; value = (SQL_POS_POSITION | SQL_POS_REFRESH); if (0 != ci->updatable_cursors) value |= (SQL_POS_UPDATE | SQL_POS_DELETE | SQL_POS_ADD); break; case SQL_POSITIONED_STATEMENTS: /* ODBC 2.0 */ len = 4; value = ci->drivers.lie ? (SQL_PS_POSITIONED_DELETE | SQL_PS_POSITIONED_UPDATE | SQL_PS_SELECT_FOR_UPDATE) : 0; break; case SQL_PROCEDURE_TERM: /* ODBC 1.0 */ p = "procedure"; break; case SQL_PROCEDURES: /* ODBC 1.0 */ p = "Y"; break; case SQL_QUALIFIER_LOCATION: /* ODBC 2.0 */ len = 2; if (CurrCat(conn)) value = SQL_QL_START; else value = 0; break; case SQL_QUALIFIER_NAME_SEPARATOR: /* ODBC 1.0 */ if (CurrCat(conn)) p = "."; else p = NULL_STRING; break; case SQL_QUALIFIER_TERM: /* ODBC 1.0 */ if (CurrCat(conn)) p = "catalog"; else p = NULL_STRING; break; case SQL_QUALIFIER_USAGE: /* ODBC 2.0 */ len = 4; if (CurrCat(conn)) value = SQL_CU_DML_STATEMENTS; else value = 0; break; case SQL_QUOTED_IDENTIFIER_CASE: /* ODBC 2.0 */ /* are "quoted" identifiers case-sensitive? YES! */ len = 2; value = SQL_IC_SENSITIVE; break; case SQL_ROW_UPDATES: /* ODBC 1.0 */ /* * Driver doesn't support keyset-driven or mixed cursors, so * not much point in saying row updates are supported */ p = (0 != ci->updatable_cursors) ? "Y" : "N"; break; case SQL_SCROLL_CONCURRENCY: /* ODBC 1.0 */ len = 4; value = SQL_SCCO_READ_ONLY; if (0 != ci->updatable_cursors) value |= SQL_SCCO_OPT_ROWVER; if (ci->drivers.lie) value |= (SQL_SCCO_LOCK | SQL_SCCO_OPT_VALUES); break; case SQL_SCROLL_OPTIONS: /* ODBC 1.0 */ len = 4; value = SQL_SO_FORWARD_ONLY | SQL_SO_STATIC; if (0 != (ci->updatable_cursors & ALLOW_KEYSET_DRIVEN_CURSORS)) value |= SQL_SO_KEYSET_DRIVEN; if (ci->drivers.lie) value |= (SQL_SO_DYNAMIC | SQL_SO_MIXED); break; case SQL_SEARCH_PATTERN_ESCAPE: /* ODBC 1.0 */ if (PG_VERSION_GE(conn, 6.5)) p = "\\"; else p = NULL_STRING; break; case SQL_SERVER_NAME: /* ODBC 1.0 */ p = CC_get_server(conn); break; case SQL_SPECIAL_CHARACTERS: /* ODBC 2.0 */ p = "_"; break; case SQL_STATIC_SENSITIVITY: /* ODBC 2.0 */ len = 4; value = 0; if (0 != ci->updatable_cursors) value |= (SQL_SS_ADDITIONS | SQL_SS_DELETIONS | SQL_SS_UPDATES); break; case SQL_STRING_FUNCTIONS: /* ODBC 1.0 */ len = 4; value = (SQL_FN_STR_CONCAT | SQL_FN_STR_LCASE | SQL_FN_STR_LENGTH | SQL_FN_STR_LOCATE | SQL_FN_STR_LTRIM | SQL_FN_STR_RTRIM | SQL_FN_STR_SUBSTRING | SQL_FN_STR_UCASE); break; case SQL_SUBQUERIES: /* ODBC 2.0 */ /* postgres 6.3 supports subqueries */ len = 4; value = (SQL_SQ_QUANTIFIED | SQL_SQ_IN | SQL_SQ_EXISTS | SQL_SQ_COMPARISON); break; case SQL_SYSTEM_FUNCTIONS: /* ODBC 1.0 */ len = 4; value = 0; break; case SQL_TABLE_TERM: /* ODBC 1.0 */ p = "table"; break; case SQL_TIMEDATE_ADD_INTERVALS: /* ODBC 2.0 */ len = 4; value = 0; break; case SQL_TIMEDATE_DIFF_INTERVALS: /* ODBC 2.0 */ len = 4; value = 0; break; case SQL_TIMEDATE_FUNCTIONS: /* ODBC 1.0 */ len = 4; value = (SQL_FN_TD_NOW); break; case SQL_TXN_CAPABLE: /* ODBC 1.0 */ /* * Postgres can deal with create or drop table statements in a * transaction */ len = 2; value = SQL_TC_ALL; break; case SQL_TXN_ISOLATION_OPTION: /* ODBC 1.0 */ len = 4; if (PG_VERSION_LT(conn, 6.5)) value = SQL_TXN_SERIALIZABLE; else if (PG_VERSION_GE(conn, 7.1)) value = SQL_TXN_READ_COMMITTED | SQL_TXN_SERIALIZABLE; else value = SQL_TXN_READ_COMMITTED; break; case SQL_UNION: /* ODBC 2.0 */ /* unions with all supported in postgres 6.3 */ len = 4; value = (SQL_U_UNION | SQL_U_UNION_ALL); break; case SQL_USER_NAME: /* ODBC 1.0 */ p = CC_get_username(conn); break; default: /* unrecognized key */ CC_set_error(conn, CONN_NOT_IMPLEMENTED_ERROR, "Unrecognized key passed to PGAPI_GetInfo.", NULL); return SQL_ERROR; } result = SQL_SUCCESS; mylog("%s: p='%s', len=%d, value=%d, cbMax=%d\n", func, p ? p : "<NULL>", len, value, cbInfoValueMax); /* * NOTE, that if rgbInfoValue is NULL, then no warnings or errors * should result and just pcbInfoValue is returned, which indicates * what length would be required if a real buffer had been passed in. */ if (p) { /* char/binary data */ len = strlen(p); if (rgbInfoValue) {#ifdef UNICODE_SUPPORT if (CC_is_in_unicode_driver(conn)) { len = utf8_to_ucs2(p, len, (SQLWCHAR *) rgbInfoValue, cbInfoValueMax / WCLEN); len *= WCLEN; } else#endif /* UNICODE_SUPPORT */ strncpy_null((char *) rgbInfoValue, p, (size_t) cbInfoValueMax); if (len >= cbInfoValueMax) { result = SQL_SUCCESS_WITH_INFO; CC_set_error(conn, CONN_TRUNCATED, "The buffer was too small for the InfoValue.", func); } }#ifdef UNICODE_SUPPORT else if (CC_is_in_unicode_driver(conn)) len *= WCLEN;#endif /* UNICODE_SUPPORT */ } else { /* numeric data */ if (rgbInfoValue) { if (len == sizeof(SQLSMALLINT)) *((SQLUSMALLINT *) rgbInfoValue) = (SQLUSMALLINT) value; else if (len == sizeof(SQLINTEGER)) *((SQLUINTEGER *) rgbInfoValue) = (SQLUINTEGER) value; } } if (pcbInfoValue) *pcbInfoValue = (SQLSMALLINT) len;cleanup: return result;}RETCODE SQL_APIPGAPI_GetTypeInfo( HSTMT hstmt, SQLSMALLINT fSqlType){ CSTR func = "PGAPI_GetTypeInfo"; StatementClass *stmt = (StatementClass *) hstmt; ConnectionClass *conn; QResultClass *res; TupleField *tuple; int i, result_cols; /* Int4 type; */ Int4 pgType; Int2 sqlType; RETCODE result = SQL_SUCCESS; mylog("%s: entering...fSqlType = %d\n", func, fSqlType); if (result = SC_initialize_and_recycle(stmt), SQL_SUCCESS != result) return result; conn = SC_get_conn(stmt); if (res = QR_Constructor(), !res) { SC_set_error(stmt, STMT_INTERNAL_ERROR, "Error creating result.", func); return SQL_ERROR; } SC_set_Result(stmt, res);#define return DONT_CALL_RETURN_FROM_HERE???#if (ODBCVER >= 0x0300) result_cols = 19;#else result_cols = 15;#endif /* ODBCVER */ extend_column_bindings(SC_get_ARDF(stmt), result_cols); stmt->catalog_result = TRUE; QR_set_num_fields(res, result_cols); QR_set_field_info_v(res, 0, "TYPE_NAME", PG_TYPE_VARCHAR, MAX_INFO_STRING); QR_set_field_info_v(res, 1, "DATA_TYPE", PG_TYPE_INT2, 2); QR_set_field_info_v(res, 2, "PRECISION", PG_TYPE_INT4, 4); QR_set_field_info_v(res, 3, "LITERAL_PREFIX", PG_TYPE_VARCHAR, MAX_INFO_STRING); QR_set_field_info_v(res, 4, "LITERAL_SUFFIX", PG_TYPE_VARCHAR, MAX_INFO_STRING); QR_set_field_info_v(res, 5, "CREATE_PARAMS", PG_TYPE_VARCHAR, MAX_INFO_STRING); QR_set_field_info_v(res, 6, "NULLABLE", PG_TYPE_INT2, 2); QR_set_field_info_v(res, 7, "CASE_SENSITIVE", PG_TYPE_INT2, 2); QR_set_field_info_v(res, 8, "SEARCHABLE", PG_TYPE_INT2, 2); QR_set_field_info_v(res, 9, "UNSIGNED_ATTRIBUTE", PG_TYPE_INT2, 2); QR_set_field_info_v(res, 10, "MONEY", PG_TYPE_INT2, 2); QR_set_field_info_v(res, 11, "AUTO_INCREMENT", PG_TYPE_INT2, 2); QR_set_field_info_v(res, 12, "LOCAL_TYPE_NAME", PG_TYPE_VARCHAR, MAX_INFO_STRING); QR_set_field_info_v(res, 13, "MINIMUM_SCALE", PG_TYPE_INT2, 2); QR_set_field_info_v(res, 14, "MAXIMUM_SCALE", PG_TYPE_INT2, 2);#if (ODBCVER >=0x0300) QR_set_field_info_v(res, 15, "SQL_DATA_TYPE", PG_TYPE_INT2, 2); QR_set_field_info_v(res, 16, "SQL_DATETIME_SUB", PG_TYPE_INT2, 2); QR_set_field_info_v(res, 17, "NUM_PREC_RADIX", PG_TYPE_INT4, 4); QR_set_field_info_v(res, 18, "INTERVAL_PRECISION", PG_TYPE_INT2, 2);#endif /* ODBCVER */ for (i = 0, sqlType = sqlTypes[0]; sqlType; sqlType = sqlTypes[++i]) { pgType = sqltype_to_pgtype(stmt, sqlType);if (sqlType == SQL_LONGVARBINARY){ConnInfo *ci = &(conn->connInfo);inolog("%d sqltype=%d -> pgtype=%d\n", ci->bytea_as_longvarbinary, sqlType, pgType);} if (fSqlType == SQL_ALL_TYPES || fSqlType == sqlType) { int pgtcount = 1, aunq_match = -1, cnt; /*if (SQL_INTEGER == sqlType || SQL_TINYINT == sqlType)*/ if (SQL_INTEGER == sqlType) {mylog("sqlType=%d ms_jet=%d\n", sqlType, conn->ms_jet); if (conn->ms_jet && PG_VERSION_GE(conn, 6.4)) { aunq_match = 1; pgtcount = 2; }mylog("aunq_match=%d pgtcount=%d\n", aunq_match, pgtcount); } for (cnt = 0; cnt < pgtcount; cnt ++) { tuple = QR_AddNew(res); /* These values can't be NULL */ if (aunq_match == cnt) { set_tuplefield_string(&tuple[0], pgtype_to_name(stmt, pgType, TRUE)); set_tuplefield_int2(&tuple[6], SQL_NO_NULLS);inolog("serial in\n"); } else { set_tuplefield_string(&tuple[0], pgtype_to_name(stmt, pgType, FALSE)); set_tuplefield_int2(&tuple[6], pgtype_nullable(stmt, pgType)); } set_tuplefield_int2(&tuple[1], (Int2) sqlType); set_tuplefield_int2(&tuple[7], pgtype_case_sensitive(stmt, pgType)); set_tuplefield_int2(&tuple[8], pgtype_searchable(stmt, pgType)); set_tuplefield_int2(&tuple[10], pgtype_money(stmt, pgType)); /* * Localized data-source dependent data type name (always * NULL) */ set_tuplefield_null(&tuple[12]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -