4 * Description: This module contains routines for getting information
5 * about the supported Postgres data types. Only the
6 * function pgtype_to_sqltype() returns an unknown condition.
7 * All other functions return a suitable default so that
8 * even data types that are not directly supported can be
9 * used (it is handled as char data).
15 * Comments: See "notice.txt" for copyright and license information.
21 #include "dlg_specific.h"
22 #include "statement.h"
23 #include "connection.h"
38 Int4 getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
41 * these are the types we support. all of the pgtype_ functions should
42 * return values for each one of these.
43 * Even types not directly supported are handled as character types
44 * so all types should work (points, etc.)
48 * ALL THESE TYPES ARE NO LONGER REPORTED in SQLGetTypeInfo. Instead, all
49 * the SQL TYPES are reported and mapped to a corresponding Postgres Type
53 Int4 pgtypes_defined[] = {
81 /* These are NOW the SQL Types reported in SQLGetTypeInfo. */
84 /* SQL_BINARY, -- Commented out because VarBinary is more correct. */
107 sqltype_to_pgtype(StatementClass *stmt, SWORD fSqlType)
110 ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
115 pgType = PG_TYPE_BYTEA;
119 pgType = PG_TYPE_BPCHAR;
123 pgType = ci->drivers.bools_as_char ? PG_TYPE_CHAR : PG_TYPE_BOOL;
127 pgType = PG_TYPE_DATE;
132 pgType = PG_TYPE_FLOAT8;
137 pgType = PG_TYPE_NUMERIC;
141 pgType = PG_TYPE_INT8;
145 pgType = PG_TYPE_INT4;
148 case SQL_LONGVARBINARY:
152 case SQL_LONGVARCHAR:
153 pgType = ci->drivers.text_as_longvarchar ? PG_TYPE_TEXT : PG_TYPE_VARCHAR;
157 pgType = PG_TYPE_FLOAT4;
162 pgType = PG_TYPE_INT2;
166 pgType = PG_TYPE_TIME;
170 pgType = PG_TYPE_DATETIME;
174 pgType = PG_TYPE_BYTEA;
178 pgType = PG_TYPE_VARCHAR;
182 pgType = 0; /* ??? */
191 * There are two ways of calling this function:
193 * 1. When going through the supported PG types (SQLGetTypeInfo)
195 * 2. When taking any type id (SQLColumns, SQLGetData)
197 * The first type will always work because all the types defined are returned here.
198 * The second type will return a default based on global parameter when it does not
199 * know. This allows for supporting
200 * types that are unknown. All other pg routines in here return a suitable default.
203 pgtype_to_sqltype(StatementClass *stmt, Int4 type)
205 ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
218 case PG_TYPE_VARCHAR:
222 return ci->drivers.text_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR;
225 return SQL_VARBINARY;
227 return SQL_LONGVARBINARY;
237 /* Change this to SQL_BIGINT for ODBC v3 bjm 2001-01-23 */
241 case PG_TYPE_NUMERIC:
252 case PG_TYPE_ABSTIME:
253 case PG_TYPE_DATETIME:
254 case PG_TYPE_TIMESTAMP:
255 return SQL_TIMESTAMP;
259 return ci->drivers.bools_as_char ? SQL_CHAR : SQL_BIT;
264 * first, check to see if 'type' is in list. If not, look up
265 * with query. Add oid, name to list. If it's already in
268 /* hack until permanent type is available */
269 if (type == stmt->hdbc->lobj_type)
270 return SQL_LONGVARBINARY;
272 return ci->drivers.unknowns_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR;
278 pgtype_to_ctype(StatementClass *stmt, Int4 type)
280 ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
285 case PG_TYPE_NUMERIC:
301 case PG_TYPE_ABSTIME:
302 case PG_TYPE_DATETIME:
303 case PG_TYPE_TIMESTAMP:
304 return SQL_C_TIMESTAMP;
308 return ci->drivers.bools_as_char ? SQL_C_CHAR : SQL_C_BIT;
316 /* hack until permanent type is available */
317 if (type == stmt->hdbc->lobj_type)
326 pgtype_to_name(StatementClass *stmt, Int4 type)
340 case PG_TYPE_NUMERIC:
342 case PG_TYPE_VARCHAR:
364 case PG_TYPE_ABSTIME:
366 case PG_TYPE_DATETIME:
368 case PG_TYPE_TIMESTAMP:
378 return PG_TYPE_LO_NAME;
381 /* hack until permanent type is available */
382 if (type == stmt->hdbc->lobj_type)
383 return PG_TYPE_LO_NAME;
386 * "unknown" can actually be used in alter table because it is
395 getNumericScale(StatementClass *stmt, Int4 type, int col)
398 QResultClass *result;
399 ColumnInfoClass *flds;
401 mylog("getNumericScale: type=%d, col=%d\n", type, col);
404 return PG_NUMERIC_MAX_SCALE;
406 result = SC_get_Result(stmt);
409 * Manual Result Sets -- use assigned column width (i.e., from
410 * set_tuplefield_string)
412 if (stmt->manual_result)
414 flds = result->fields;
416 return flds->adtsize[col];
418 return PG_NUMERIC_MAX_SCALE;
421 atttypmod = QR_get_atttypmod(result, col);
423 return (atttypmod & 0xffff);
425 return (QR_get_display_size(result, col) ?
426 QR_get_display_size(result, col) :
427 PG_NUMERIC_MAX_SCALE);
432 getNumericPrecision(StatementClass *stmt, Int4 type, int col)
435 QResultClass *result;
436 ColumnInfoClass *flds;
438 mylog("getNumericPrecision: type=%d, col=%d\n", type, col);
441 return PG_NUMERIC_MAX_PRECISION;
443 result = SC_get_Result(stmt);
446 * Manual Result Sets -- use assigned column width (i.e., from
447 * set_tuplefield_string)
449 if (stmt->manual_result)
451 flds = result->fields;
453 return flds->adtsize[col];
455 return PG_NUMERIC_MAX_PRECISION;
458 atttypmod = QR_get_atttypmod(result, col);
460 return (atttypmod >> 16) & 0xffff;
462 return (QR_get_display_size(result, col) >= 0 ?
463 QR_get_display_size(result, col) :
464 PG_NUMERIC_MAX_PRECISION);
469 getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
473 QResultClass *result;
474 ColumnInfoClass *flds;
475 ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
477 mylog("getCharPrecision: type=%d, col=%d, unknown = %d\n", type, col, handle_unknown_size_as);
479 /* Assign Maximum size based on parameters */
483 if (ci->drivers.text_as_longvarchar)
484 maxsize = ci->drivers.max_longvarchar_size;
486 maxsize = ci->drivers.max_varchar_size;
489 case PG_TYPE_VARCHAR:
491 maxsize = ci->drivers.max_varchar_size;
495 if (ci->drivers.unknowns_as_longvarchar)
496 maxsize = ci->drivers.max_longvarchar_size;
498 maxsize = ci->drivers.max_varchar_size;
503 * Static Precision (i.e., the Maximum Precision of the datatype) This
504 * has nothing to do with a result set.
506 if (maxsize == TEXT_FIELD_SIZE + 1) /* magic length for testing */
508 if (PG_VERSION_GE(SC_get_conn(stmt), 7.1))
511 maxsize = TEXT_FIELD_SIZE;
516 result = SC_get_Result(stmt);
519 * Manual Result Sets -- use assigned column width (i.e., from
520 * set_tuplefield_string)
522 if (stmt->manual_result)
524 flds = result->fields;
526 return flds->adtsize[col];
531 /* Size is unknown -- handle according to parameter */
532 if (QR_get_atttypmod(result, col) > -1)
533 return QR_get_atttypmod(result, col);
535 if (type == PG_TYPE_BPCHAR || handle_unknown_size_as == UNKNOWNS_AS_LONGEST)
537 p = QR_get_display_size(result, col);
538 mylog("getCharPrecision: LONGEST: p = %d\n", p);
541 if (p < 0 && handle_unknown_size_as == UNKNOWNS_AS_MAX)
549 * For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, PG_TYPE_NUMERIC, SQLColumns will
550 * override this length with the atttypmod length from pg_attribute .
552 * If col >= 0, then will attempt to get the info from the result set.
553 * This is used for functions SQLDescribeCol and SQLColAttributes.
556 pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
570 return NAME_FIELD_SIZE;
581 return 19; /* signed */
583 case PG_TYPE_NUMERIC:
584 return getNumericPrecision(stmt, type, col);
598 case PG_TYPE_ABSTIME:
599 case PG_TYPE_DATETIME:
600 case PG_TYPE_TIMESTAMP:
612 if (type == stmt->hdbc->lobj_type) /* hack until permanent
613 * type is available */
616 /* Handle Character types and unknown types */
617 return getCharPrecision(stmt, type, col, handle_unknown_size_as);
623 pgtype_display_size(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
638 return 20; /* signed: 19 digits + sign */
640 case PG_TYPE_NUMERIC:
641 return getNumericPrecision(stmt, type, col) + 2;
644 return 15; /* ($9,999,999.99) */
652 /* Character types use regular precision */
654 return pgtype_precision(stmt, type, col, handle_unknown_size_as);
660 * For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, SQLColumns will
661 * override this length with the atttypmod length from pg_attribute
664 pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
677 return 20; /* signed: 19 digits + sign */
679 case PG_TYPE_NUMERIC:
680 return getNumericPrecision(stmt, type, col) + 2;
693 case PG_TYPE_ABSTIME:
694 case PG_TYPE_DATETIME:
695 case PG_TYPE_TIMESTAMP:
698 /* Character types (and NUMERIC) use the default precision */
699 case PG_TYPE_VARCHAR:
703 if (PG_VERSION_GE(SC_get_conn(stmt), 7.2))
704 return 3 * pgtype_precision(stmt, type, col, handle_unknown_size_as);
708 return 2 * pgtype_precision(stmt, type, col, handle_unknown_size_as);
709 #endif /* MULTIBYTE */
711 return pgtype_precision(stmt, type, col, handle_unknown_size_as);
717 pgtype_scale(StatementClass *stmt, Int4 type, int col)
732 * Number of digits to the right of the decimal point in
733 * "yyyy-mm=dd hh:mm:ss[.f...]"
735 case PG_TYPE_ABSTIME:
736 case PG_TYPE_DATETIME:
737 case PG_TYPE_TIMESTAMP:
740 case PG_TYPE_NUMERIC:
741 return getNumericScale(stmt, type, col);
750 pgtype_radix(StatementClass *stmt, Int4 type)
758 case PG_TYPE_NUMERIC:
770 pgtype_nullable(StatementClass *stmt, Int4 type)
772 return SQL_NULLABLE; /* everything should be nullable */
777 pgtype_auto_increment(StatementClass *stmt, Int4 type)
790 case PG_TYPE_NUMERIC:
794 case PG_TYPE_ABSTIME:
795 case PG_TYPE_DATETIME:
796 case PG_TYPE_TIMESTAMP:
806 pgtype_case_sensitive(StatementClass *stmt, Int4 type)
816 case PG_TYPE_VARCHAR:
829 pgtype_money(StatementClass *stmt, Int4 type)
842 pgtype_searchable(StatementClass *stmt, Int4 type)
851 case PG_TYPE_VARCHAR:
855 return SQL_SEARCHABLE;
858 return SQL_ALL_EXCEPT_LIKE;
864 pgtype_unsigned(StatementClass *stmt, Int4 type)
875 case PG_TYPE_NUMERIC:
888 pgtype_literal_prefix(StatementClass *stmt, Int4 type)
897 case PG_TYPE_NUMERIC:
900 case PG_TYPE_MONEY:return NULL;
909 pgtype_literal_suffix(StatementClass *stmt, Int4 type)
918 case PG_TYPE_NUMERIC:
921 case PG_TYPE_MONEY:return NULL;
930 pgtype_create_params(StatementClass *stmt, Int4 type)
935 case PG_TYPE_VARCHAR:return "max. length";
943 sqltype_to_default_ctype(Int2 sqltype)
947 * from the table on page 623 of ODBC 2.0 Programmer's Reference
954 case SQL_LONGVARCHAR:
964 return SQL_C_STINYINT;
981 case SQL_LONGVARBINARY:
991 return SQL_C_TIMESTAMP;
994 /* should never happen */
1000 ctype_length(Int2 ctype)
1006 return sizeof(SWORD);
1009 return sizeof(UWORD);
1013 return sizeof(SDWORD);
1016 return sizeof(UDWORD);
1019 return sizeof(SFLOAT);
1022 return sizeof(SDOUBLE);
1025 return sizeof(UCHAR);
1027 case SQL_C_STINYINT:
1029 return sizeof(SCHAR);
1031 case SQL_C_UTINYINT:
1032 return sizeof(UCHAR);
1035 return sizeof(DATE_STRUCT);
1038 return sizeof(TIME_STRUCT);
1040 case SQL_C_TIMESTAMP:
1041 return sizeof(TIMESTAMP_STRUCT);
1047 default: /* should never happen */