⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgtypes.c

📁 postgresql-odbc,跨平台应用
💻 C
📖 第 1 页 / 共 3 页
字号:
/*-------- * 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 + -