?? pgtypes.c
字號:
/*-------- * Module: pgtypes.c * * Description: This module contains routines for getting information * about the supported Postgres data types. Only the * function pgtype_to_sqltype() returns an unknown condition. * All other functions return a suitable default so that * even data types that are not directly supported can be * used (it is handled as char data). * * Classes: n/a * * API functions: none * * Comments: See "notice.txt" for copyright and license information. *-------- */#include "pgtypes.h"#include "dlg_specific.h"#include "statement.h"#include "connection.h"#include "environ.h"#include "qresult.h"#define EXPERIMENTAL_CURRENTLYInt4 getCharColumnSize(StatementClass *stmt, OID type, int col, int handle_unknown_size_as);/* * these are the types we support. all of the pgtype_ functions should * return values for each one of these. * Even types not directly supported are handled as character types * so all types should work (points, etc.) *//* * ALL THESE TYPES ARE NO LONGER REPORTED in SQLGetTypeInfo. Instead, all * the SQL TYPES are reported and mapped to a corresponding Postgres Type *//*OID pgtypes_defined[][2] = { {PG_TYPE_CHAR, 0} ,{PG_TYPE_CHAR2, 0} ,{PG_TYPE_CHAR4, 0} ,{PG_TYPE_CHAR8, 0} ,{PG_TYPE_CHAR16, 0} ,{PG_TYPE_NAME, 0} ,{PG_TYPE_VARCHAR, 0} ,{PG_TYPE_BPCHAR, 0} ,{PG_TYPE_DATE, 0} ,{PG_TYPE_TIME, 0} ,{PG_TYPE_TIME_WITH_TMZONE, 0} ,{PG_TYPE_DATETIME, 0} ,{PG_TYPE_ABSTIME, 0} ,{PG_TYPE_TIMESTAMP_NO_TMZONE, 0} ,{PG_TYPE_TIMESTAMP, 0} ,{PG_TYPE_TEXT, 0} ,{PG_TYPE_INT2, 0} ,{PG_TYPE_INT4, 0} ,{PG_TYPE_FLOAT4, 0} ,{PG_TYPE_FLOAT8, 0} ,{PG_TYPE_OID, 0} ,{PG_TYPE_MONEY, 0} ,{PG_TYPE_BOOL, 0} ,{PG_TYPE_BYTEA, 0} ,{PG_TYPE_NUMERIC, 0} ,{PG_TYPE_XID, 0} ,{PG_TYPE_LO_UNDEFINED, 0} ,{0, 0} };*//* These are NOW the SQL Types reported in SQLGetTypeInfo. */SQLSMALLINT sqlTypes[] = { SQL_BIGINT, /* SQL_BINARY, -- Commented out because VarBinary is more correct. */ SQL_BIT, SQL_CHAR,#if (ODBCVER >= 0x0300) SQL_TYPE_DATE,#endif /* ODBCVER */ SQL_DATE, SQL_DECIMAL, SQL_DOUBLE, SQL_FLOAT, SQL_INTEGER, SQL_LONGVARBINARY, SQL_LONGVARCHAR, SQL_NUMERIC, SQL_REAL, SQL_SMALLINT,#if (ODBCVER >= 0x0300) SQL_TYPE_TIME, SQL_TYPE_TIMESTAMP,#endif /* ODBCVER */ SQL_TIME, SQL_TIMESTAMP, SQL_TINYINT, SQL_VARBINARY, SQL_VARCHAR,#ifdef UNICODE_SUPPORT SQL_WCHAR, SQL_WVARCHAR, SQL_WLONGVARCHAR,#endif /* UNICODE_SUPPORT */ 0};#if (ODBCVER >= 0x0300) && defined(ODBCINT64)#define ALLOWED_C_BIGINT SQL_C_SBIGINT/* #define ALLOWED_C_BIGINT SQL_C_CHAR */ /* Delphi should be either ? */#else#define ALLOWED_C_BIGINT SQL_C_CHAR#endifOIDsqltype_to_pgtype(StatementClass *stmt, SQLSMALLINT fSqlType){ OID pgType; ConnectionClass *conn = SC_get_conn(stmt); ConnInfo *ci = &(conn->connInfo); switch (fSqlType) { case SQL_BINARY: pgType = PG_TYPE_BYTEA; break; case SQL_CHAR: pgType = PG_TYPE_BPCHAR; break;#ifdef UNICODE_SUPPORT case SQL_WCHAR: pgType = PG_TYPE_BPCHAR; break;#endif /* UNICODE_SUPPORT */ case SQL_BIT: pgType = ci->drivers.bools_as_char ? PG_TYPE_CHAR : PG_TYPE_BOOL; break;#if (ODBCVER >= 0x0300) case SQL_TYPE_DATE:#endif /* ODBCVER */ case SQL_DATE: pgType = PG_TYPE_DATE; break; case SQL_DOUBLE: case SQL_FLOAT: pgType = PG_TYPE_FLOAT8; break; case SQL_DECIMAL: case SQL_NUMERIC: pgType = PG_TYPE_NUMERIC; break; case SQL_BIGINT: pgType = PG_TYPE_INT8; break; case SQL_INTEGER: pgType = PG_TYPE_INT4; break; case SQL_LONGVARBINARY: if (ci->bytea_as_longvarbinary) pgType = PG_TYPE_BYTEA; else pgType = conn->lobj_type; break; case SQL_LONGVARCHAR: pgType = ci->drivers.text_as_longvarchar ? PG_TYPE_TEXT : PG_TYPE_VARCHAR; break;#ifdef UNICODE_SUPPORT case SQL_WLONGVARCHAR: pgType = ci->drivers.text_as_longvarchar ? PG_TYPE_TEXT : PG_TYPE_VARCHAR; break;#endif /* UNICODE_SUPPORT */ case SQL_REAL: pgType = PG_TYPE_FLOAT4; break; case SQL_SMALLINT: case SQL_TINYINT: pgType = PG_TYPE_INT2; break; case SQL_TIME:#if (ODBCVER >= 0x0300) case SQL_TYPE_TIME:#endif /* ODBCVER */ pgType = PG_TYPE_TIME; break; case SQL_TIMESTAMP:#if (ODBCVER >= 0x0300) case SQL_TYPE_TIMESTAMP:#endif /* ODBCVER */ pgType = PG_TYPE_DATETIME; break; case SQL_VARBINARY: pgType = PG_TYPE_BYTEA; break; case SQL_VARCHAR: pgType = PG_TYPE_VARCHAR; break;#if UNICODE_SUPPORT case SQL_WVARCHAR: pgType = PG_TYPE_VARCHAR; break;#endif /* UNICODE_SUPPORT */ default: pgType = 0; /* ??? */ break; } return pgType;}/* * There are two ways of calling this function: * * 1. When going through the supported PG types (SQLGetTypeInfo) * * 2. When taking any type id (SQLColumns, SQLGetData) * * The first type will always work because all the types defined are returned here. * The second type will return a default based on global parameter when it does not * know. This allows for supporting * types that are unknown. All other pg routines in here return a suitable default. */SQLSMALLINTpgtype_to_concise_type(StatementClass *stmt, OID type, int col){ ConnectionClass *conn = SC_get_conn(stmt); ConnInfo *ci = &(conn->connInfo);#if (ODBCVER >= 0x0300) EnvironmentClass *env = (EnvironmentClass *) (conn->henv);#endif /* ODBCVER */ switch (type) { case PG_TYPE_CHAR: case PG_TYPE_CHAR2: case PG_TYPE_CHAR4: case PG_TYPE_CHAR8: return ALLOW_WCHAR(conn) ? SQL_WCHAR : SQL_CHAR; case PG_TYPE_NAME: return ALLOW_WCHAR(conn) ? SQL_WVARCHAR : SQL_VARCHAR;#ifdef UNICODE_SUPPORT case PG_TYPE_BPCHAR: if (col >= 0 && getCharColumnSize(stmt, type, col, UNKNOWNS_AS_MAX) > ci->drivers.max_varchar_size) return ALLOW_WCHAR(conn) ? SQL_WLONGVARCHAR : SQL_LONGVARCHAR; return ALLOW_WCHAR(conn) ? SQL_WCHAR : SQL_CHAR; case PG_TYPE_VARCHAR: if (col >= 0 && getCharColumnSize(stmt, type, col, UNKNOWNS_AS_MAX) > ci->drivers.max_varchar_size) return ALLOW_WCHAR(conn) ? SQL_WLONGVARCHAR : SQL_LONGVARCHAR; return ALLOW_WCHAR(conn) ? SQL_WVARCHAR : SQL_VARCHAR; case PG_TYPE_TEXT: return ci->drivers.text_as_longvarchar ? (ALLOW_WCHAR(conn) ? SQL_WLONGVARCHAR : SQL_LONGVARCHAR) : (ALLOW_WCHAR(conn) ? SQL_WVARCHAR : SQL_VARCHAR);#else case PG_TYPE_BPCHAR: if (col >= 0 && getCharColumnSize(stmt, type, col, UNKNOWNS_AS_MAX) > ci->drivers.max_varchar_size) return SQL_LONGVARCHAR; return SQL_CHAR; case PG_TYPE_VARCHAR: if (col >= 0 && getCharColumnSize(stmt, type, col, UNKNOWNS_AS_MAX) > ci->drivers.max_varchar_size) return SQL_LONGVARCHAR; return SQL_VARCHAR; case PG_TYPE_TEXT: return ci->drivers.text_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR;#endif /* UNICODE_SUPPORT */ case PG_TYPE_BYTEA: if (ci->bytea_as_longvarbinary) return SQL_LONGVARBINARY; else return SQL_VARBINARY; case PG_TYPE_LO_UNDEFINED: return SQL_LONGVARBINARY; case PG_TYPE_INT2: return SQL_SMALLINT; case PG_TYPE_OID: case PG_TYPE_XID: case PG_TYPE_INT4: return SQL_INTEGER; /* Change this to SQL_BIGINT for ODBC v3 bjm 2001-01-23 */ case PG_TYPE_INT8: if (ci->int8_as != 0) return ci->int8_as; if (conn->ms_jet) return SQL_NUMERIC; /* maybe a little better than SQL_VARCHAR */#if (ODBCVER >= 0x0300) return SQL_BIGINT;#else return SQL_VARCHAR;#endif /* ODBCVER */ case PG_TYPE_NUMERIC: return SQL_NUMERIC; case PG_TYPE_FLOAT4: return SQL_REAL; case PG_TYPE_FLOAT8: return SQL_FLOAT; case PG_TYPE_DATE:#if (ODBCVER >= 0x0300) if (EN_is_odbc3(env)) return SQL_TYPE_DATE;#endif /* ODBCVER */ return SQL_DATE; case PG_TYPE_TIME:#if (ODBCVER >= 0x0300) if (EN_is_odbc3(env)) return SQL_TYPE_TIME;#endif /* ODBCVER */ return SQL_TIME; case PG_TYPE_ABSTIME: case PG_TYPE_DATETIME: case PG_TYPE_TIMESTAMP_NO_TMZONE: case PG_TYPE_TIMESTAMP:#if (ODBCVER >= 0x0300) if (EN_is_odbc3(env)) return SQL_TYPE_TIMESTAMP;#endif /* ODBCVER */ return SQL_TIMESTAMP; case PG_TYPE_MONEY: return SQL_FLOAT; case PG_TYPE_BOOL: return ci->drivers.bools_as_char ? SQL_CHAR : SQL_BIT; default: /* * first, check to see if 'type' is in list. If not, look up * with query. Add oid, name to list. If it's already in * list, just return. */ /* hack until permanent type is available */ if (type == stmt->hdbc->lobj_type) return SQL_LONGVARBINARY;#ifdef EXPERIMENTAL_CURRENTLY if (ALLOW_WCHAR(conn)) return ci->drivers.unknowns_as_longvarchar ? SQL_WLONGVARCHAR : SQL_WVARCHAR;#endif /* EXPERIMENTAL_CURRENTLY */ return ci->drivers.unknowns_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR; }}SQLSMALLINTpgtype_to_sqldesctype(StatementClass *stmt, OID type, int col){ SQLSMALLINT rettype; switch (rettype = pgtype_to_concise_type(stmt, type, col)) {#if (ODBCVER >= 0x0300) case SQL_TYPE_DATE: case SQL_TYPE_TIME: case SQL_TYPE_TIMESTAMP: return SQL_DATETIME;#endif /* ODBCVER */ } return rettype;}SQLSMALLINTpgtype_to_datetime_sub(StatementClass *stmt, OID type){ switch (pgtype_to_concise_type(stmt, type, PG_STATIC)) {#if (ODBCVER >= 0x0300) case SQL_TYPE_DATE: return SQL_CODE_DATE; case SQL_TYPE_TIME: return SQL_CODE_TIME; case SQL_TYPE_TIMESTAMP: return SQL_CODE_TIMESTAMP;#endif /* ODBCVER */ } return -1;}SQLSMALLINTpgtype_to_ctype(StatementClass *stmt, OID type){ ConnectionClass *conn = SC_get_conn(stmt); ConnInfo *ci = &(conn->connInfo);#if (ODBCVER >= 0x0300) EnvironmentClass *env = (EnvironmentClass *) (conn->henv);#endif /* ODBCVER */ switch (type) { case PG_TYPE_INT8:#if (ODBCVER >= 0x0300) if (!conn->ms_jet) return ALLOWED_C_BIGINT;#endif /* ODBCVER */ return SQL_C_CHAR; case PG_TYPE_NUMERIC: return SQL_C_CHAR; case PG_TYPE_INT2: return SQL_C_SSHORT; case PG_TYPE_OID: case PG_TYPE_XID: return SQL_C_ULONG; case PG_TYPE_INT4: return SQL_C_SLONG; case PG_TYPE_FLOAT4: return SQL_C_FLOAT; case PG_TYPE_FLOAT8: return SQL_C_DOUBLE; case PG_TYPE_DATE:#if (ODBCVER >= 0x0300) if (EN_is_odbc3(env)) return SQL_C_TYPE_DATE;#endif /* ODBCVER */ return SQL_C_DATE; case PG_TYPE_TIME:#if (ODBCVER >= 0x0300) if (EN_is_odbc3(env)) return SQL_C_TYPE_TIME;#endif /* ODBCVER */ return SQL_C_TIME; case PG_TYPE_ABSTIME: case PG_TYPE_DATETIME: case PG_TYPE_TIMESTAMP_NO_TMZONE: case PG_TYPE_TIMESTAMP:#if (ODBCVER >= 0x0300) if (EN_is_odbc3(env)) return SQL_C_TYPE_TIMESTAMP;#endif /* ODBCVER */ return SQL_C_TIMESTAMP; case PG_TYPE_MONEY: return SQL_C_FLOAT; case PG_TYPE_BOOL: return ci->drivers.bools_as_char ? SQL_C_CHAR : SQL_C_BIT; case PG_TYPE_BYTEA: return SQL_C_BINARY; case PG_TYPE_LO_UNDEFINED: return SQL_C_BINARY;#ifdef UNICODE_SUPPORT case PG_TYPE_BPCHAR: case PG_TYPE_VARCHAR: case PG_TYPE_TEXT: if (CC_is_in_unicode_driver(conn)#ifdef NOT_USED && ! stmt->catalog_result)#endif /* NOT USED */ ) return SQL_C_WCHAR; return SQL_C_CHAR;#endif /* UNICODE_SUPPORT */ default: /* hack until permanent type is available */ if (type == stmt->hdbc->lobj_type) return SQL_C_BINARY; /* Experimental, Does this work ? */#ifdef EXPERIMENTAL_CURRENTLY if (ALLOW_WCHAR(conn)) return SQL_C_WCHAR;#endif /* EXPERIMENTAL_CURRENTLY */ return SQL_C_CHAR; }}const char *pgtype_to_name(StatementClass *stmt, OID type, BOOL auto_increment){ ConnectionClass *conn = SC_get_conn(stmt); switch (type) { case PG_TYPE_CHAR: return "char"; case PG_TYPE_CHAR2: return "char2"; case PG_TYPE_CHAR4: return "char4"; case PG_TYPE_CHAR8: return "char8"; case PG_TYPE_INT8: return auto_increment ? "bigserial" : "int8"; case PG_TYPE_NUMERIC: return "numeric"; case PG_TYPE_VARCHAR: return "varchar"; case PG_TYPE_BPCHAR: return "char"; case PG_TYPE_TEXT: return "text"; case PG_TYPE_NAME: return "name"; case PG_TYPE_INT2: return "int2"; case PG_TYPE_OID: return OID_NAME; case PG_TYPE_XID: return "xid"; case PG_TYPE_INT4:inolog("pgtype_to_name int4\n"); return auto_increment ? "serial" : "int4"; case PG_TYPE_FLOAT4: return "float4"; case PG_TYPE_FLOAT8: return "float8";
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -