pgtypes.c 17.7 KB
Newer Older
1

B
Bruce Momjian 已提交
2
/* Module:			pgtypes.c
3
 *
B
Bruce Momjian 已提交
4 5 6 7 8
 * 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).
9
 *
B
Bruce Momjian 已提交
10
 * Classes:			n/a
11
 *
B
Bruce Momjian 已提交
12
 * API functions:	none
13
 *
B
Bruce Momjian 已提交
14
 * Comments:		See "notice.txt" for copyright and license information.
15 16
 *
 */
17

B
Byron Nikolaidis 已提交
18
#ifdef HAVE_CONFIG_H
19
#include "config.h"
B
Byron Nikolaidis 已提交
20 21
#endif

22
#include "psqlodbc.h"
23
#include "dlg_specific.h"
24
#include "pgtypes.h"
25 26 27
#include "statement.h"
#include "connection.h"
#include "qresult.h"
B
Byron Nikolaidis 已提交
28

29
#ifndef WIN32
B
Byron Nikolaidis 已提交
30 31 32 33
#include "iodbc.h"
#include "isql.h"
#include "isqlext.h"
#else
34 35 36
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
B
Byron Nikolaidis 已提交
37
#endif
38

39 40 41

extern GLOBAL_VALUES globals;

B
Bruce Momjian 已提交
42
Int4		getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
43

44

B
Bruce Momjian 已提交
45 46 47
/* 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
B
Byron Nikolaidis 已提交
48
   so all types should work (points, etc.) */
49

B
Byron Nikolaidis 已提交
50
/* ALL THESE TYPES ARE NO LONGER REPORTED in SQLGetTypeInfo.  Instead, all
B
Bruce Momjian 已提交
51
   the SQL TYPES are reported and mapped to a corresponding Postgres Type
B
Byron Nikolaidis 已提交
52 53
*/
/*
B
Bruce Momjian 已提交
54
Int4 pgtypes_defined[]	= {
55 56 57
				PG_TYPE_CHAR,
				PG_TYPE_CHAR2,
				PG_TYPE_CHAR4,
B
Bruce Momjian 已提交
58
				PG_TYPE_CHAR8,
59
				PG_TYPE_CHAR16,
B
Bruce Momjian 已提交
60 61 62
				PG_TYPE_NAME,
				PG_TYPE_VARCHAR,
				PG_TYPE_BPCHAR,
63 64
				PG_TYPE_DATE,
				PG_TYPE_TIME,
B
Byron Nikolaidis 已提交
65
				PG_TYPE_DATETIME,
B
Byron Nikolaidis 已提交
66
				PG_TYPE_ABSTIME,
B
Byron Nikolaidis 已提交
67
				PG_TYPE_TIMESTAMP,
B
Bruce Momjian 已提交
68 69 70 71 72 73
				PG_TYPE_TEXT,
				PG_TYPE_INT2,
				PG_TYPE_INT4,
				PG_TYPE_FLOAT4,
				PG_TYPE_FLOAT8,
				PG_TYPE_OID,
74 75
				PG_TYPE_MONEY,
				PG_TYPE_BOOL,
76 77
				PG_TYPE_BYTEA,
				PG_TYPE_LO,
B
Bruce Momjian 已提交
78
				0 };
B
Byron Nikolaidis 已提交
79 80
*/

81

B
Byron Nikolaidis 已提交
82
/*	These are NOW the SQL Types reported in SQLGetTypeInfo.  */
B
Bruce Momjian 已提交
83
Int2		sqlTypes[] = {
84
	SQL_BIGINT,
B
Byron Nikolaidis 已提交
85
	/* SQL_BINARY, -- Commented out because VarBinary is more correct. */
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
	SQL_BIT,
	SQL_CHAR,
	SQL_DATE,
	SQL_DECIMAL,
	SQL_DOUBLE,
	SQL_FLOAT,
	SQL_INTEGER,
	SQL_LONGVARBINARY,
	SQL_LONGVARCHAR,
	SQL_NUMERIC,
	SQL_REAL,
	SQL_SMALLINT,
	SQL_TIME,
	SQL_TIMESTAMP,
	SQL_TINYINT,
	SQL_VARBINARY,
	SQL_VARCHAR,
	0
};

B
Bruce Momjian 已提交
106 107
Int4
sqltype_to_pgtype(SWORD fSqlType)
108
{
B
Bruce Momjian 已提交
109
	Int4		pgType;
110

B
Bruce Momjian 已提交
111 112
	switch (fSqlType)
	{
113

B
Bruce Momjian 已提交
114 115 116
		case SQL_BINARY:
			pgType = PG_TYPE_BYTEA;
			break;
117

B
Bruce Momjian 已提交
118 119 120
		case SQL_CHAR:
			pgType = PG_TYPE_BPCHAR;
			break;
121

B
Bruce Momjian 已提交
122 123 124
		case SQL_BIT:
			pgType = globals.bools_as_char ? PG_TYPE_CHAR : PG_TYPE_BOOL;
			break;
125

B
Bruce Momjian 已提交
126 127 128
		case SQL_DATE:
			pgType = PG_TYPE_DATE;
			break;
129

B
Bruce Momjian 已提交
130 131 132 133
		case SQL_DOUBLE:
		case SQL_FLOAT:
			pgType = PG_TYPE_FLOAT8;
			break;
134

B
Bruce Momjian 已提交
135 136 137 138
		case SQL_DECIMAL:
		case SQL_NUMERIC:
			pgType = PG_TYPE_NUMERIC;
			break;
139

B
Bruce Momjian 已提交
140 141 142
		case SQL_BIGINT:
			pgType = PG_TYPE_INT8;
			break;
143

B
Bruce Momjian 已提交
144 145 146
		case SQL_INTEGER:
			pgType = PG_TYPE_INT4;
			break;
147

B
Bruce Momjian 已提交
148 149 150
		case SQL_LONGVARBINARY:
			pgType = PG_TYPE_LO;
			break;
151

B
Bruce Momjian 已提交
152 153 154
		case SQL_LONGVARCHAR:
			pgType = globals.text_as_longvarchar ? PG_TYPE_TEXT : PG_TYPE_VARCHAR;
			break;
155

B
Bruce Momjian 已提交
156 157 158
		case SQL_REAL:
			pgType = PG_TYPE_FLOAT4;
			break;
159

B
Bruce Momjian 已提交
160 161 162 163
		case SQL_SMALLINT:
		case SQL_TINYINT:
			pgType = PG_TYPE_INT2;
			break;
164

B
Bruce Momjian 已提交
165 166 167
		case SQL_TIME:
			pgType = PG_TYPE_TIME;
			break;
168

B
Bruce Momjian 已提交
169 170 171
		case SQL_TIMESTAMP:
			pgType = PG_TYPE_DATETIME;
			break;
172

B
Bruce Momjian 已提交
173 174 175
		case SQL_VARBINARY:
			pgType = PG_TYPE_BYTEA;
			break;
176

B
Bruce Momjian 已提交
177 178 179
		case SQL_VARCHAR:
			pgType = PG_TYPE_VARCHAR;
			break;
180

B
Bruce Momjian 已提交
181 182 183
		default:
			pgType = 0;			/* ??? */
			break;
184 185 186 187
	}

	return pgType;
}
188

B
Bruce Momjian 已提交
189
/*	There are two ways of calling this function:
190 191 192 193
	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.
B
Bruce Momjian 已提交
194 195
	The second type will return a default based on global parameter when it does not
	know.	This allows for supporting
196 197
	types that are unknown.  All other pg routines in here return a suitable default.
*/
B
Bruce Momjian 已提交
198 199
Int2
pgtype_to_sqltype(StatementClass *stmt, Int4 type)
200
{
B
Bruce Momjian 已提交
201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
	switch (type)
	{
			case PG_TYPE_CHAR:
			case PG_TYPE_CHAR2:
			case PG_TYPE_CHAR4:
			case PG_TYPE_CHAR8:
			case PG_TYPE_NAME:return SQL_CHAR;

		case PG_TYPE_BPCHAR:
			return SQL_CHAR;

		case PG_TYPE_VARCHAR:
			return SQL_VARCHAR;

		case PG_TYPE_TEXT:
			return globals.text_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR;

		case PG_TYPE_BYTEA:
			return SQL_VARBINARY;
		case PG_TYPE_LO:
221 222
			return SQL_LONGVARBINARY;

B
Bruce Momjian 已提交
223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
		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:
			return SQL_CHAR;

		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:
			return SQL_DATE;
		case PG_TYPE_TIME:
			return SQL_TIME;
		case PG_TYPE_ABSTIME:
		case PG_TYPE_DATETIME:
		case PG_TYPE_TIMESTAMP:
			return SQL_TIMESTAMP;
		case PG_TYPE_MONEY:
			return SQL_FLOAT;
		case PG_TYPE_BOOL:
			return globals.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.
			 */
			if (type == stmt->hdbc->lobj_type)	/* hack until permanent
												 * type is available */
				return SQL_LONGVARBINARY;

			return globals.unknowns_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR;
267
	}
268 269
}

B
Bruce Momjian 已提交
270 271
Int2
pgtype_to_ctype(StatementClass *stmt, Int4 type)
272
{
B
Bruce Momjian 已提交
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
	switch (type)
	{
			case PG_TYPE_INT8: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:
		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:
			return SQL_C_DATE;
		case PG_TYPE_TIME:
			return SQL_C_TIME;
		case PG_TYPE_ABSTIME:
		case PG_TYPE_DATETIME:
		case PG_TYPE_TIMESTAMP:
			return SQL_C_TIMESTAMP;
		case PG_TYPE_MONEY:
			return SQL_C_FLOAT;
		case PG_TYPE_BOOL:
			return globals.bools_as_char ? SQL_C_CHAR : SQL_C_BIT;

		case PG_TYPE_BYTEA:
302
			return SQL_C_BINARY;
B
Bruce Momjian 已提交
303 304 305 306 307 308 309 310
		case PG_TYPE_LO:
			return SQL_C_BINARY;

		default:

			if (type == stmt->hdbc->lobj_type)	/* hack until permanent
												 * type is available */
				return SQL_C_BINARY;
311

B
Bruce Momjian 已提交
312
			return SQL_C_CHAR;
313
	}
314 315
}

B
Bruce Momjian 已提交
316 317
char *
pgtype_to_name(StatementClass *stmt, Int4 type)
318
{
B
Bruce Momjian 已提交
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367
	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 "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";
		case PG_TYPE_INT4:
			return "int4";
		case PG_TYPE_FLOAT4:
			return "float4";
		case PG_TYPE_FLOAT8:
			return "float8";
		case PG_TYPE_DATE:
			return "date";
		case PG_TYPE_TIME:
			return "time";
		case PG_TYPE_ABSTIME:
			return "abstime";
		case PG_TYPE_DATETIME:
			return "datetime";
		case PG_TYPE_TIMESTAMP:
			return "timestamp";
		case PG_TYPE_MONEY:
			return "money";
		case PG_TYPE_BOOL:
			return "bool";
		case PG_TYPE_BYTEA:
			return "bytea";

		case PG_TYPE_LO:
368 369
			return PG_TYPE_LO_NAME;

B
Bruce Momjian 已提交
370 371 372 373 374 375 376 377 378 379 380
		default:
			if (type == stmt->hdbc->lobj_type)	/* hack until permanent
												 * type is available */
				return PG_TYPE_LO_NAME;

			/*
			 * "unknown" can actually be used in alter table because it is
			 * a real PG type!
			 */
			return "unknown";
	}
381 382
}

T
Tom Lane 已提交
383
static Int2
B
Bruce Momjian 已提交
384
getNumericScale(StatementClass *stmt, Int4 type, int col)
B
Byron Nikolaidis 已提交
385
{
B
Bruce Momjian 已提交
386 387 388
	Int4		atttypmod;
	QResultClass *result;
	ColumnInfoClass *flds;
B
Byron Nikolaidis 已提交
389

B
Bruce Momjian 已提交
390
	mylog("getNumericScale: type=%d, col=%d, unknown = %d\n", type, col);
B
Byron Nikolaidis 已提交
391 392 393 394 395 396

	if (col < 0)
		return PG_NUMERIC_MAX_SCALE;

	result = SC_get_Result(stmt);

B
Bruce Momjian 已提交
397 398 399 400 401 402
	/*
	 * Manual Result Sets -- use assigned column width (i.e., from
	 * set_tuplefield_string)
	 */
	if (stmt->manual_result)
	{
B
Byron Nikolaidis 已提交
403 404 405 406 407 408 409 410
		flds = result->fields;
		if (flds)
			return flds->adtsize[col];
		else
			return PG_NUMERIC_MAX_SCALE;
	}

	atttypmod = QR_get_atttypmod(result, col);
B
Bruce Momjian 已提交
411
	if (atttypmod > -1)
B
Byron Nikolaidis 已提交
412 413
		return (atttypmod & 0xffff);
	else
B
Bruce Momjian 已提交
414 415 416
		return (QR_get_display_size(result, col) ?
				QR_get_display_size(result, col) :
				PG_NUMERIC_MAX_SCALE);
B
Byron Nikolaidis 已提交
417 418
}

T
Tom Lane 已提交
419
static Int4
B
Bruce Momjian 已提交
420
getNumericPrecision(StatementClass *stmt, Int4 type, int col)
B
Byron Nikolaidis 已提交
421
{
B
Bruce Momjian 已提交
422 423 424
	Int4		atttypmod;
	QResultClass *result;
	ColumnInfoClass *flds;
B
Byron Nikolaidis 已提交
425

B
Bruce Momjian 已提交
426
	mylog("getNumericPrecision: type=%d, col=%d, unknown = %d\n", type, col);
B
Byron Nikolaidis 已提交
427 428 429 430 431 432

	if (col < 0)
		return PG_NUMERIC_MAX_PRECISION;

	result = SC_get_Result(stmt);

B
Bruce Momjian 已提交
433 434 435 436 437 438
	/*
	 * Manual Result Sets -- use assigned column width (i.e., from
	 * set_tuplefield_string)
	 */
	if (stmt->manual_result)
	{
B
Byron Nikolaidis 已提交
439 440 441 442 443 444 445 446
		flds = result->fields;
		if (flds)
			return flds->adtsize[col];
		else
			return PG_NUMERIC_MAX_PRECISION;
	}

	atttypmod = QR_get_atttypmod(result, col);
B
Bruce Momjian 已提交
447
	if (atttypmod > -1)
B
Byron Nikolaidis 已提交
448 449
		return (atttypmod >> 16) & 0xffff;
	else
B
Bruce Momjian 已提交
450 451 452
		return (QR_get_display_size(result, col) >= 0 ?
				QR_get_display_size(result, col) :
				PG_NUMERIC_MAX_PRECISION);
B
Byron Nikolaidis 已提交
453 454
}

455
Int4
B
Bruce Momjian 已提交
456
getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
457
{
B
Bruce Momjian 已提交
458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476
	int			p = -1,
				maxsize;
	QResultClass *result;
	ColumnInfoClass *flds;

	mylog("getCharPrecision: type=%d, col=%d, unknown = %d\n", type, col, handle_unknown_size_as);

	/* Assign Maximum size based on parameters */
	switch (type)
	{
		case PG_TYPE_TEXT:
			if (globals.text_as_longvarchar)
				maxsize = globals.max_longvarchar_size;
			else
				maxsize = globals.max_varchar_size;
			break;

		case PG_TYPE_VARCHAR:
		case PG_TYPE_BPCHAR:
477
			maxsize = globals.max_varchar_size;
B
Bruce Momjian 已提交
478 479 480 481 482 483 484 485
			break;

		default:
			if (globals.unknowns_as_longvarchar)
				maxsize = globals.max_longvarchar_size;
			else
				maxsize = globals.max_varchar_size;
			break;
486 487
	}

B
Bruce Momjian 已提交
488 489 490 491
	/*
	 * Static Precision (i.e., the Maximum Precision of the datatype) This
	 * has nothing to do with a result set.
	 */
492 493 494 495 496
	if (col < 0)
		return maxsize;

	result = SC_get_Result(stmt);

B
Bruce Momjian 已提交
497 498 499 500 501 502
	/*
	 * Manual Result Sets -- use assigned column width (i.e., from
	 * set_tuplefield_string)
	 */
	if (stmt->manual_result)
	{
503 504
		flds = result->fields;
		if (flds)
B
Byron Nikolaidis 已提交
505
			return flds->adtsize[col];
506 507 508 509
		else
			return maxsize;
	}

B
Bruce Momjian 已提交
510
	/* Size is unknown -- handle according to parameter */
B
 
Byron Nikolaidis 已提交
511 512 513
	if (QR_get_atttypmod(result, col) > -1)
		return QR_get_atttypmod(result, col);

B
Bruce Momjian 已提交
514 515
	if (type == PG_TYPE_BPCHAR || handle_unknown_size_as == UNKNOWNS_AS_LONGEST)
	{
516 517 518 519 520 521 522 523
		p = QR_get_display_size(result, col);
		mylog("getCharPrecision: LONGEST: p = %d\n", p);
	}

	if (p < 0 && handle_unknown_size_as == UNKNOWNS_AS_MAX)
		return maxsize;
	else
		return p;
524 525
}

B
Bruce Momjian 已提交
526
/*	For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, PG_TYPE_NUMERIC, SQLColumns will
527 528 529 530
	override this length with the atttypmod length from pg_attribute .

	If col >= 0, then will attempt to get the info from the result set.
	This is used for functions SQLDescribeCol and SQLColAttributes.
531
*/
B
Bruce Momjian 已提交
532 533
Int4
pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
534
{
535

B
Bruce Momjian 已提交
536 537
	switch (type)
	{
538

B
Bruce Momjian 已提交
539 540 541 542 543 544 545
			case PG_TYPE_CHAR:return 1;
		case PG_TYPE_CHAR2:
			return 2;
		case PG_TYPE_CHAR4:
			return 4;
		case PG_TYPE_CHAR8:
			return 8;
546

B
Bruce Momjian 已提交
547 548
		case PG_TYPE_NAME:
			return NAME_FIELD_SIZE;
549

B
Bruce Momjian 已提交
550 551
		case PG_TYPE_INT2:
			return 5;
552

B
Bruce Momjian 已提交
553 554 555 556
		case PG_TYPE_OID:
		case PG_TYPE_XID:
		case PG_TYPE_INT4:
			return 10;
557

B
Bruce Momjian 已提交
558 559
		case PG_TYPE_INT8:
			return 19;			/* signed */
560

B
Bruce Momjian 已提交
561 562
		case PG_TYPE_NUMERIC:
			return getNumericPrecision(stmt, type, col);
563

B
Bruce Momjian 已提交
564 565 566
		case PG_TYPE_FLOAT4:
		case PG_TYPE_MONEY:
			return 7;
567

B
Bruce Momjian 已提交
568 569
		case PG_TYPE_FLOAT8:
			return 15;
570

B
Bruce Momjian 已提交
571 572 573 574
		case PG_TYPE_DATE:
			return 10;
		case PG_TYPE_TIME:
			return 8;
575

B
Bruce Momjian 已提交
576 577 578 579
		case PG_TYPE_ABSTIME:
		case PG_TYPE_DATETIME:
		case PG_TYPE_TIMESTAMP:
			return 19;
580

B
Bruce Momjian 已提交
581 582
		case PG_TYPE_BOOL:
			return 1;
583

B
Bruce Momjian 已提交
584 585
		case PG_TYPE_LO:
			return SQL_NO_TOTAL;
586

B
Bruce Momjian 已提交
587
		default:
588

B
Bruce Momjian 已提交
589 590 591
			if (type == stmt->hdbc->lobj_type)	/* hack until permanent
												 * type is available */
				return SQL_NO_TOTAL;
592

B
Bruce Momjian 已提交
593 594 595
			/* Handle Character types and unknown types */
			return getCharPrecision(stmt, type, col, handle_unknown_size_as);
	}
596 597
}

B
Bruce Momjian 已提交
598 599
Int4
pgtype_display_size(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
600
{
601

B
Bruce Momjian 已提交
602 603 604 605 606 607 608
	switch (type)
	{
			case PG_TYPE_INT2:return 6;

		case PG_TYPE_OID:
		case PG_TYPE_XID:
			return 10;
609

B
Bruce Momjian 已提交
610 611
		case PG_TYPE_INT4:
			return 11;
612

B
Bruce Momjian 已提交
613 614
		case PG_TYPE_INT8:
			return 20;			/* signed: 19 digits + sign */
615

B
Bruce Momjian 已提交
616 617
		case PG_TYPE_NUMERIC:
			return getNumericPrecision(stmt, type, col) + 2;
B
Byron Nikolaidis 已提交
618

B
Bruce Momjian 已提交
619 620
		case PG_TYPE_MONEY:
			return 15;			/* ($9,999,999.99) */
B
Byron Nikolaidis 已提交
621

B
Bruce Momjian 已提交
622 623
		case PG_TYPE_FLOAT4:
			return 13;
624

B
Bruce Momjian 已提交
625 626
		case PG_TYPE_FLOAT8:
			return 22;
627

B
Bruce Momjian 已提交
628 629 630
			/* Character types use regular precision */
		default:
			return pgtype_precision(stmt, type, col, handle_unknown_size_as);
631 632 633
	}
}

B
Bruce Momjian 已提交
634 635
/*	For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, SQLColumns will
	override this length with the atttypmod length from pg_attribute
636
*/
B
Bruce Momjian 已提交
637 638
Int4
pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
639 640
{

B
Bruce Momjian 已提交
641 642
	switch (type)
	{
643

B
Bruce Momjian 已提交
644
			case PG_TYPE_INT2:return 2;
B
Byron Nikolaidis 已提交
645

B
Bruce Momjian 已提交
646 647 648 649
		case PG_TYPE_OID:
		case PG_TYPE_XID:
		case PG_TYPE_INT4:
			return 4;
B
Byron Nikolaidis 已提交
650

B
Bruce Momjian 已提交
651 652
		case PG_TYPE_INT8:
			return 20;			/* signed: 19 digits + sign */
653

B
Bruce Momjian 已提交
654 655
		case PG_TYPE_NUMERIC:
			return getNumericPrecision(stmt, type, col) + 2;
656

B
Bruce Momjian 已提交
657 658 659
		case PG_TYPE_FLOAT4:
		case PG_TYPE_MONEY:
			return 4;
660

B
Bruce Momjian 已提交
661 662
		case PG_TYPE_FLOAT8:
			return 8;
663

B
Bruce Momjian 已提交
664 665 666
		case PG_TYPE_DATE:
		case PG_TYPE_TIME:
			return 6;
667

B
Bruce Momjian 已提交
668 669 670 671
		case PG_TYPE_ABSTIME:
		case PG_TYPE_DATETIME:
		case PG_TYPE_TIMESTAMP:
			return 16;
672 673


B
Bruce Momjian 已提交
674 675 676 677
			/* Character types (and NUMERIC) use the default precision */
		default:
			return pgtype_precision(stmt, type, col, handle_unknown_size_as);
	}
678 679
}

B
Bruce Momjian 已提交
680 681
Int2
pgtype_scale(StatementClass *stmt, Int4 type, int col)
682
{
B
Bruce Momjian 已提交
683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708
	switch (type)
	{

			case PG_TYPE_INT2:
			case PG_TYPE_OID:
			case PG_TYPE_XID:
			case PG_TYPE_INT4:
			case PG_TYPE_INT8:
			case PG_TYPE_FLOAT4:
			case PG_TYPE_FLOAT8:
			case PG_TYPE_MONEY:
			case PG_TYPE_BOOL:

			/*
			 * Number of digits to the right of the decimal point in
			 * "yyyy-mm=dd hh:mm:ss[.f...]"
			 */
			case PG_TYPE_ABSTIME:
			case PG_TYPE_DATETIME:
			case PG_TYPE_TIMESTAMP:return 0;

		case PG_TYPE_NUMERIC:
			return getNumericScale(stmt, type, col);

		default:
			return -1;
709 710 711 712
	}
}


B
Bruce Momjian 已提交
713 714
Int2
pgtype_radix(StatementClass *stmt, Int4 type)
715
{
B
Bruce Momjian 已提交
716 717 718 719 720 721 722 723 724 725 726 727 728 729
	switch (type)
	{
			case PG_TYPE_INT2:
			case PG_TYPE_OID:
			case PG_TYPE_INT4:
			case PG_TYPE_INT8:
			case PG_TYPE_NUMERIC:
			case PG_TYPE_FLOAT4:
			case PG_TYPE_MONEY:
			case PG_TYPE_FLOAT8:return 10;

		default:
			return -1;
	}
730 731
}

B
Bruce Momjian 已提交
732 733
Int2
pgtype_nullable(StatementClass *stmt, Int4 type)
734
{
B
Bruce Momjian 已提交
735
	return SQL_NULLABLE;		/* everything should be nullable */
736 737
}

B
Bruce Momjian 已提交
738 739
Int2
pgtype_auto_increment(StatementClass *stmt, Int4 type)
740
{
B
Bruce Momjian 已提交
741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763
	switch (type)
	{

			case PG_TYPE_INT2:
			case PG_TYPE_OID:
			case PG_TYPE_XID:
			case PG_TYPE_INT4:
			case PG_TYPE_FLOAT4:
			case PG_TYPE_MONEY:
			case PG_TYPE_BOOL:
			case PG_TYPE_FLOAT8:
			case PG_TYPE_INT8:
			case PG_TYPE_NUMERIC:

			case PG_TYPE_DATE:
			case PG_TYPE_TIME:
			case PG_TYPE_ABSTIME:
			case PG_TYPE_DATETIME:
			case PG_TYPE_TIMESTAMP:return FALSE;

		default:
			return -1;
	}
764 765
}

B
Bruce Momjian 已提交
766 767
Int2
pgtype_case_sensitive(StatementClass *stmt, Int4 type)
768
{
B
Bruce Momjian 已提交
769 770 771
	switch (type)
	{
			case PG_TYPE_CHAR:
772

B
Bruce Momjian 已提交
773 774 775
			case PG_TYPE_CHAR2:
			case PG_TYPE_CHAR4:
			case PG_TYPE_CHAR8:
776

B
Bruce Momjian 已提交
777 778 779 780
			case PG_TYPE_VARCHAR:
			case PG_TYPE_BPCHAR:
			case PG_TYPE_TEXT:
			case PG_TYPE_NAME:return TRUE;
781

B
Bruce Momjian 已提交
782 783 784
		default:
			return FALSE;
	}
785 786
}

B
Bruce Momjian 已提交
787 788
Int2
pgtype_money(StatementClass *stmt, Int4 type)
789
{
B
Bruce Momjian 已提交
790 791 792 793 794 795
	switch (type)
	{
			case PG_TYPE_MONEY:return TRUE;
		default:
			return FALSE;
	}
796 797
}

B
Bruce Momjian 已提交
798 799
Int2
pgtype_searchable(StatementClass *stmt, Int4 type)
800
{
B
Bruce Momjian 已提交
801 802 803 804 805 806 807 808 809 810 811 812 813 814 815
	switch (type)
	{
			case PG_TYPE_CHAR:
			case PG_TYPE_CHAR2:
			case PG_TYPE_CHAR4:
			case PG_TYPE_CHAR8:

			case PG_TYPE_VARCHAR:
			case PG_TYPE_BPCHAR:
			case PG_TYPE_TEXT:
			case PG_TYPE_NAME:return SQL_SEARCHABLE;

		default:
			return SQL_ALL_EXCEPT_LIKE;
	}
816 817
}

B
Bruce Momjian 已提交
818 819
Int2
pgtype_unsigned(StatementClass *stmt, Int4 type)
820
{
B
Bruce Momjian 已提交
821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836
	switch (type)
	{
			case PG_TYPE_OID:
			case PG_TYPE_XID:return TRUE;

		case PG_TYPE_INT2:
		case PG_TYPE_INT4:
		case PG_TYPE_INT8:
		case PG_TYPE_NUMERIC:
		case PG_TYPE_FLOAT4:
		case PG_TYPE_FLOAT8:
		case PG_TYPE_MONEY:
			return FALSE;

		default:
			return -1;
837 838 839
	}
}

B
Bruce Momjian 已提交
840 841
char *
pgtype_literal_prefix(StatementClass *stmt, Int4 type)
842
{
B
Bruce Momjian 已提交
843 844 845 846 847 848 849 850 851 852 853 854 855 856 857
	switch (type)
	{

			case PG_TYPE_INT2:
			case PG_TYPE_OID:
			case PG_TYPE_XID:
			case PG_TYPE_INT4:
			case PG_TYPE_INT8:
			case PG_TYPE_NUMERIC:
			case PG_TYPE_FLOAT4:
			case PG_TYPE_FLOAT8:
			case PG_TYPE_MONEY:return NULL;

		default:
			return "'";
858 859 860
	}
}

B
Bruce Momjian 已提交
861 862
char *
pgtype_literal_suffix(StatementClass *stmt, Int4 type)
863
{
B
Bruce Momjian 已提交
864 865 866 867 868 869 870 871 872 873 874 875 876 877 878
	switch (type)
	{

			case PG_TYPE_INT2:
			case PG_TYPE_OID:
			case PG_TYPE_XID:
			case PG_TYPE_INT4:
			case PG_TYPE_INT8:
			case PG_TYPE_NUMERIC:
			case PG_TYPE_FLOAT4:
			case PG_TYPE_FLOAT8:
			case PG_TYPE_MONEY:return NULL;

		default:
			return "'";
879 880 881
	}
}

B
Bruce Momjian 已提交
882 883
char *
pgtype_create_params(StatementClass *stmt, Int4 type)
884
{
B
Bruce Momjian 已提交
885 886 887 888 889 890
	switch (type)
	{
			case PG_TYPE_CHAR:
			case PG_TYPE_VARCHAR:return "max. length";
		default:
			return NULL;
891 892 893 894
	}
}


B
Bruce Momjian 已提交
895 896
Int2
sqltype_to_default_ctype(Int2 sqltype)
897
{
B
Bruce Momjian 已提交
898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932
	/* from the table on page 623 of ODBC 2.0 Programmer's Reference */
	/* (Appendix D) */
	switch (sqltype)
	{
			case SQL_CHAR:
			case SQL_VARCHAR:
			case SQL_LONGVARCHAR:
			case SQL_DECIMAL:
			case SQL_NUMERIC:
			case SQL_BIGINT:
			return SQL_C_CHAR;

		case SQL_BIT:
			return SQL_C_BIT;

		case SQL_TINYINT:
			return SQL_C_STINYINT;

		case SQL_SMALLINT:
			return SQL_C_SSHORT;

		case SQL_INTEGER:
			return SQL_C_SLONG;

		case SQL_REAL:
			return SQL_C_FLOAT;

		case SQL_FLOAT:
		case SQL_DOUBLE:
			return SQL_C_DOUBLE;

		case SQL_BINARY:
		case SQL_VARBINARY:
		case SQL_LONGVARBINARY:
			return SQL_C_BINARY;
933

B
Bruce Momjian 已提交
934 935
		case SQL_DATE:
			return SQL_C_DATE;
936

B
Bruce Momjian 已提交
937 938
		case SQL_TIME:
			return SQL_C_TIME;
939

B
Bruce Momjian 已提交
940 941
		case SQL_TIMESTAMP:
			return SQL_C_TIMESTAMP;
942

B
Bruce Momjian 已提交
943 944 945
		default:				/* should never happen */
			return SQL_C_CHAR;
	}
946
}