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

19
#include "pgtypes.h"
B
Byron Nikolaidis 已提交
20

21 22 23 24
#include "dlg_specific.h"
#include "statement.h"
#include "connection.h"
#include "qresult.h"
B
Byron Nikolaidis 已提交
25

26 27


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

30 31 32 33 34 35
/*
 * 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.)
 */
36

37 38
/*
 * ALL THESE TYPES ARE NO LONGER REPORTED in SQLGetTypeInfo.  Instead, all
39
 *	the SQL TYPES are reported and mapped to a corresponding Postgres Type
40
 */
41

B
Byron Nikolaidis 已提交
42
/*
B
Bruce Momjian 已提交
43
Int4 pgtypes_defined[]	= {
44 45 46
				PG_TYPE_CHAR,
				PG_TYPE_CHAR2,
				PG_TYPE_CHAR4,
B
Bruce Momjian 已提交
47
				PG_TYPE_CHAR8,
48
				PG_TYPE_CHAR16,
B
Bruce Momjian 已提交
49 50 51
				PG_TYPE_NAME,
				PG_TYPE_VARCHAR,
				PG_TYPE_BPCHAR,
52 53
				PG_TYPE_DATE,
				PG_TYPE_TIME,
B
Byron Nikolaidis 已提交
54
				PG_TYPE_DATETIME,
B
Byron Nikolaidis 已提交
55
				PG_TYPE_ABSTIME,
B
Byron Nikolaidis 已提交
56
				PG_TYPE_TIMESTAMP,
B
Bruce Momjian 已提交
57 58 59 60 61 62
				PG_TYPE_TEXT,
				PG_TYPE_INT2,
				PG_TYPE_INT4,
				PG_TYPE_FLOAT4,
				PG_TYPE_FLOAT8,
				PG_TYPE_OID,
63 64
				PG_TYPE_MONEY,
				PG_TYPE_BOOL,
65 66
				PG_TYPE_BYTEA,
				PG_TYPE_LO,
B
Bruce Momjian 已提交
67
				0 };
B
Byron Nikolaidis 已提交
68 69
*/

70

B
Byron Nikolaidis 已提交
71
/*	These are NOW the SQL Types reported in SQLGetTypeInfo.  */
B
Bruce Momjian 已提交
72
Int2		sqlTypes[] = {
73
	SQL_BIGINT,
B
Byron Nikolaidis 已提交
74
	/* SQL_BINARY, -- Commented out because VarBinary is more correct. */
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
	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
};

95

B
Bruce Momjian 已提交
96
Int4
97
sqltype_to_pgtype(StatementClass *stmt, SWORD fSqlType)
98
{
B
Bruce Momjian 已提交
99
	Int4		pgType;
100
	ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
101

B
Bruce Momjian 已提交
102 103 104 105 106
	switch (fSqlType)
	{
		case SQL_BINARY:
			pgType = PG_TYPE_BYTEA;
			break;
107

B
Bruce Momjian 已提交
108 109 110
		case SQL_CHAR:
			pgType = PG_TYPE_BPCHAR;
			break;
111

B
Bruce Momjian 已提交
112
		case SQL_BIT:
113
			pgType = ci->drivers.bools_as_char ? PG_TYPE_CHAR : PG_TYPE_BOOL;
B
Bruce Momjian 已提交
114
			break;
115

B
Bruce Momjian 已提交
116 117 118
		case SQL_DATE:
			pgType = PG_TYPE_DATE;
			break;
119

B
Bruce Momjian 已提交
120 121 122 123
		case SQL_DOUBLE:
		case SQL_FLOAT:
			pgType = PG_TYPE_FLOAT8;
			break;
124

B
Bruce Momjian 已提交
125 126 127 128
		case SQL_DECIMAL:
		case SQL_NUMERIC:
			pgType = PG_TYPE_NUMERIC;
			break;
129

B
Bruce Momjian 已提交
130 131 132
		case SQL_BIGINT:
			pgType = PG_TYPE_INT8;
			break;
133

B
Bruce Momjian 已提交
134 135 136
		case SQL_INTEGER:
			pgType = PG_TYPE_INT4;
			break;
137

B
Bruce Momjian 已提交
138 139 140
		case SQL_LONGVARBINARY:
			pgType = PG_TYPE_LO;
			break;
141

B
Bruce Momjian 已提交
142
		case SQL_LONGVARCHAR:
143
			pgType = ci->drivers.text_as_longvarchar ? PG_TYPE_TEXT : PG_TYPE_VARCHAR;
B
Bruce Momjian 已提交
144
			break;
145

B
Bruce Momjian 已提交
146 147 148
		case SQL_REAL:
			pgType = PG_TYPE_FLOAT4;
			break;
149

B
Bruce Momjian 已提交
150 151 152 153
		case SQL_SMALLINT:
		case SQL_TINYINT:
			pgType = PG_TYPE_INT2;
			break;
154

B
Bruce Momjian 已提交
155 156 157
		case SQL_TIME:
			pgType = PG_TYPE_TIME;
			break;
158

B
Bruce Momjian 已提交
159 160 161
		case SQL_TIMESTAMP:
			pgType = PG_TYPE_DATETIME;
			break;
162

B
Bruce Momjian 已提交
163 164 165
		case SQL_VARBINARY:
			pgType = PG_TYPE_BYTEA;
			break;
166

B
Bruce Momjian 已提交
167 168 169
		case SQL_VARCHAR:
			pgType = PG_TYPE_VARCHAR;
			break;
170

B
Bruce Momjian 已提交
171 172 173
		default:
			pgType = 0;			/* ??? */
			break;
174 175 176 177
	}

	return pgType;
}
178 179


180 181 182 183 184 185 186 187 188 189 190 191
/*
 *	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.
 */
B
Bruce Momjian 已提交
192 193
Int2
pgtype_to_sqltype(StatementClass *stmt, Int4 type)
194
{
195
	ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
B
Bruce Momjian 已提交
196 197
	switch (type)
	{
198 199 200 201 202 203
		case PG_TYPE_CHAR:
		case PG_TYPE_CHAR2:
		case PG_TYPE_CHAR4:
		case PG_TYPE_CHAR8:
		case PG_TYPE_NAME:
			return SQL_CHAR;
B
Bruce Momjian 已提交
204 205 206 207 208 209 210 211

		case PG_TYPE_BPCHAR:
			return SQL_CHAR;

		case PG_TYPE_VARCHAR:
			return SQL_VARCHAR;

		case PG_TYPE_TEXT:
212
			return ci->drivers.text_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR;
B
Bruce Momjian 已提交
213 214 215 216

		case PG_TYPE_BYTEA:
			return SQL_VARBINARY;
		case PG_TYPE_LO:
217 218
			return SQL_LONGVARBINARY;

B
Bruce Momjian 已提交
219 220 221 222 223 224 225 226
		case PG_TYPE_INT2:
			return SQL_SMALLINT;

		case PG_TYPE_OID:
		case PG_TYPE_XID:
		case PG_TYPE_INT4:
			return SQL_INTEGER;

227
			/* Change this to SQL_BIGINT for ODBC v3 bjm 2001-01-23 */
B
Bruce Momjian 已提交
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
		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:
249
			return ci->drivers.bools_as_char ? SQL_CHAR : SQL_BIT;
B
Bruce Momjian 已提交
250 251

		default:
252

B
Bruce Momjian 已提交
253 254 255 256 257
			/*
			 * 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.
			 */
258
			/* hack until permanent type is available */
259
			if (type == stmt->hdbc->lobj_type)
B
Bruce Momjian 已提交
260 261
				return SQL_LONGVARBINARY;

262
			return ci->drivers.unknowns_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR;
263
	}
264 265
}

266

B
Bruce Momjian 已提交
267 268
Int2
pgtype_to_ctype(StatementClass *stmt, Int4 type)
269
{
270
	ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
B
Bruce Momjian 已提交
271 272
	switch (type)
	{
273 274
		case PG_TYPE_INT8:
			return SQL_C_CHAR;
B
Bruce Momjian 已提交
275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
		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:
298
			return ci->drivers.bools_as_char ? SQL_C_CHAR : SQL_C_BIT;
B
Bruce Momjian 已提交
299 300

		case PG_TYPE_BYTEA:
301
			return SQL_C_BINARY;
B
Bruce Momjian 已提交
302 303 304 305
		case PG_TYPE_LO:
			return SQL_C_BINARY;

		default:
306 307
			/* hack until permanent type is available */
			if (type == stmt->hdbc->lobj_type)
B
Bruce Momjian 已提交
308
				return SQL_C_BINARY;
309

B
Bruce Momjian 已提交
310
			return SQL_C_CHAR;
311
	}
312 313
}

314

B
Bruce Momjian 已提交
315 316
char *
pgtype_to_name(StatementClass *stmt, Int4 type)
317
{
B
Bruce Momjian 已提交
318 319
	switch (type)
	{
320 321
		case PG_TYPE_CHAR:
			return "char";
B
Bruce Momjian 已提交
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
		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
		default:
371 372
			/* hack until permanent type is available */
			if (type == stmt->hdbc->lobj_type)
B
Bruce Momjian 已提交
373 374 375 376 377 378 379 380
				return PG_TYPE_LO_NAME;

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

383

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

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

	if (col < 0)
		return PG_NUMERIC_MAX_SCALE;

	result = SC_get_Result(stmt);

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

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

420

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

428
	mylog("getNumericPrecision: type=%d, col=%d\n", type, col);
B
Byron Nikolaidis 已提交
429 430 431 432 433 434

	if (col < 0)
		return PG_NUMERIC_MAX_PRECISION;

	result = SC_get_Result(stmt);

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

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

457

458
Int4
B
Bruce Momjian 已提交
459
getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
460
{
B
Bruce Momjian 已提交
461 462 463 464
	int			p = -1,
				maxsize;
	QResultClass *result;
	ColumnInfoClass *flds;
465
	ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
B
Bruce Momjian 已提交
466 467 468 469 470 471 472

	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:
473 474
			if (ci->drivers.text_as_longvarchar)
				maxsize = ci->drivers.max_longvarchar_size;
B
Bruce Momjian 已提交
475
			else
476
				maxsize = ci->drivers.max_varchar_size;
B
Bruce Momjian 已提交
477 478 479 480
			break;

		case PG_TYPE_VARCHAR:
		case PG_TYPE_BPCHAR:
481
			maxsize = ci->drivers.max_varchar_size;
B
Bruce Momjian 已提交
482 483 484
			break;

		default:
485 486
			if (ci->drivers.unknowns_as_longvarchar)
				maxsize = ci->drivers.max_longvarchar_size;
B
Bruce Momjian 已提交
487
			else
488
				maxsize = ci->drivers.max_varchar_size;
B
Bruce Momjian 已提交
489
			break;
490 491
	}

B
Bruce Momjian 已提交
492 493 494 495
	/*
	 * Static Precision (i.e., the Maximum Precision of the datatype) This
	 * has nothing to do with a result set.
	 */
496 497 498 499 500 501 502
	if (maxsize == TEXT_FIELD_SIZE + 1) /* magic length for testing */
	{
		if (PG_VERSION_GE(SC_get_conn(stmt), 7.1))
			maxsize = 0;
		else 
			maxsize = TEXT_FIELD_SIZE;
	}
503 504 505 506 507
	if (col < 0)
		return maxsize;

	result = SC_get_Result(stmt);

B
Bruce Momjian 已提交
508 509 510 511 512 513
	/*
	 * Manual Result Sets -- use assigned column width (i.e., from
	 * set_tuplefield_string)
	 */
	if (stmt->manual_result)
	{
514 515
		flds = result->fields;
		if (flds)
B
Byron Nikolaidis 已提交
516
			return flds->adtsize[col];
517 518 519 520
		else
			return maxsize;
	}

B
Bruce Momjian 已提交
521
	/* Size is unknown -- handle according to parameter */
B
 
Byron Nikolaidis 已提交
522 523 524
	if (QR_get_atttypmod(result, col) > -1)
		return QR_get_atttypmod(result, col);

B
Bruce Momjian 已提交
525 526
	if (type == PG_TYPE_BPCHAR || handle_unknown_size_as == UNKNOWNS_AS_LONGEST)
	{
527 528 529 530 531 532 533 534
		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;
535 536
}

537

538 539 540 541 542 543 544
/*
 *	For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, PG_TYPE_NUMERIC, SQLColumns will
 *	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.
 */
B
Bruce Momjian 已提交
545 546
Int4
pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
547
{
B
Bruce Momjian 已提交
548 549
	switch (type)
	{
550 551
		case PG_TYPE_CHAR:
			return 1;
B
Bruce Momjian 已提交
552 553 554 555 556 557
		case PG_TYPE_CHAR2:
			return 2;
		case PG_TYPE_CHAR4:
			return 4;
		case PG_TYPE_CHAR8:
			return 8;
558

B
Bruce Momjian 已提交
559 560
		case PG_TYPE_NAME:
			return NAME_FIELD_SIZE;
561

B
Bruce Momjian 已提交
562 563
		case PG_TYPE_INT2:
			return 5;
564

B
Bruce Momjian 已提交
565 566 567 568
		case PG_TYPE_OID:
		case PG_TYPE_XID:
		case PG_TYPE_INT4:
			return 10;
569

B
Bruce Momjian 已提交
570 571
		case PG_TYPE_INT8:
			return 19;			/* signed */
572

B
Bruce Momjian 已提交
573 574
		case PG_TYPE_NUMERIC:
			return getNumericPrecision(stmt, type, col);
575

B
Bruce Momjian 已提交
576 577 578
		case PG_TYPE_FLOAT4:
		case PG_TYPE_MONEY:
			return 7;
579

B
Bruce Momjian 已提交
580 581
		case PG_TYPE_FLOAT8:
			return 15;
582

B
Bruce Momjian 已提交
583 584 585 586
		case PG_TYPE_DATE:
			return 10;
		case PG_TYPE_TIME:
			return 8;
587

B
Bruce Momjian 已提交
588 589 590
		case PG_TYPE_ABSTIME:
		case PG_TYPE_DATETIME:
		case PG_TYPE_TIMESTAMP:
591 592
			/*return 19;*/
return 21;
593

B
Bruce Momjian 已提交
594 595
		case PG_TYPE_BOOL:
			return 1;
596

B
Bruce Momjian 已提交
597 598
		case PG_TYPE_LO:
			return SQL_NO_TOTAL;
599

B
Bruce Momjian 已提交
600
		default:
601

B
Bruce Momjian 已提交
602 603 604
			if (type == stmt->hdbc->lobj_type)	/* hack until permanent
												 * type is available */
				return SQL_NO_TOTAL;
605

B
Bruce Momjian 已提交
606 607 608
			/* Handle Character types and unknown types */
			return getCharPrecision(stmt, type, col, handle_unknown_size_as);
	}
609 610
}

611

B
Bruce Momjian 已提交
612 613
Int4
pgtype_display_size(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
614
{
B
Bruce Momjian 已提交
615 616
	switch (type)
	{
617 618
		case PG_TYPE_INT2:
			return 6;
B
Bruce Momjian 已提交
619 620 621 622

		case PG_TYPE_OID:
		case PG_TYPE_XID:
			return 10;
623

B
Bruce Momjian 已提交
624 625
		case PG_TYPE_INT4:
			return 11;
626

B
Bruce Momjian 已提交
627 628
		case PG_TYPE_INT8:
			return 20;			/* signed: 19 digits + sign */
629

B
Bruce Momjian 已提交
630 631
		case PG_TYPE_NUMERIC:
			return getNumericPrecision(stmt, type, col) + 2;
B
Byron Nikolaidis 已提交
632

B
Bruce Momjian 已提交
633 634
		case PG_TYPE_MONEY:
			return 15;			/* ($9,999,999.99) */
B
Byron Nikolaidis 已提交
635

B
Bruce Momjian 已提交
636 637
		case PG_TYPE_FLOAT4:
			return 13;
638

B
Bruce Momjian 已提交
639 640
		case PG_TYPE_FLOAT8:
			return 22;
641

642
			/* Character types use regular precision */
B
Bruce Momjian 已提交
643 644
		default:
			return pgtype_precision(stmt, type, col, handle_unknown_size_as);
645 646 647
	}
}

648 649 650 651 652

/*
 *	For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, SQLColumns will
 *	override this length with the atttypmod length from pg_attribute
 */
B
Bruce Momjian 已提交
653 654
Int4
pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
655
{
B
Bruce Momjian 已提交
656 657
	switch (type)
	{
658 659
		case PG_TYPE_INT2:
			return 2;
B
Byron Nikolaidis 已提交
660

B
Bruce Momjian 已提交
661 662 663 664
		case PG_TYPE_OID:
		case PG_TYPE_XID:
		case PG_TYPE_INT4:
			return 4;
B
Byron Nikolaidis 已提交
665

B
Bruce Momjian 已提交
666 667
		case PG_TYPE_INT8:
			return 20;			/* signed: 19 digits + sign */
668

B
Bruce Momjian 已提交
669 670
		case PG_TYPE_NUMERIC:
			return getNumericPrecision(stmt, type, col) + 2;
671

B
Bruce Momjian 已提交
672 673 674
		case PG_TYPE_FLOAT4:
		case PG_TYPE_MONEY:
			return 4;
675

B
Bruce Momjian 已提交
676 677
		case PG_TYPE_FLOAT8:
			return 8;
678

B
Bruce Momjian 已提交
679 680 681
		case PG_TYPE_DATE:
		case PG_TYPE_TIME:
			return 6;
682

B
Bruce Momjian 已提交
683 684 685 686
		case PG_TYPE_ABSTIME:
		case PG_TYPE_DATETIME:
		case PG_TYPE_TIMESTAMP:
			return 16;
687

688
			/* Character types (and NUMERIC) use the default precision */
689 690
		case PG_TYPE_VARCHAR:
		case PG_TYPE_BPCHAR:
691 692
#ifdef MULTIBYTE
			/* after 7.2 */
693
			if (PG_VERSION_GE(SC_get_conn(stmt), 7.2))
694 695 696 697
				return 3 * pgtype_precision(stmt, type, col, handle_unknown_size_as);
			else
#else
			/* CR -> CR/LF */
698
				return 2 * pgtype_precision(stmt, type, col, handle_unknown_size_as);
699
#endif /* MULTIBYTE */
B
Bruce Momjian 已提交
700 701 702
		default:
			return pgtype_precision(stmt, type, col, handle_unknown_size_as);
	}
703 704
}

705

B
Bruce Momjian 已提交
706 707
Int2
pgtype_scale(StatementClass *stmt, Int4 type, int col)
708
{
B
Bruce Momjian 已提交
709 710
	switch (type)
	{
711 712 713 714 715 716 717 718 719
		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:
B
Bruce Momjian 已提交
720

721 722 723 724
			/*
			 * Number of digits to the right of the decimal point in
			 * "yyyy-mm=dd hh:mm:ss[.f...]"
			 */
725 726 727 728
		case PG_TYPE_ABSTIME:
		case PG_TYPE_DATETIME:
		case PG_TYPE_TIMESTAMP:
			return 0;
B
Bruce Momjian 已提交
729 730 731 732 733 734

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

		default:
			return -1;
735 736 737 738
	}
}


B
Bruce Momjian 已提交
739 740
Int2
pgtype_radix(StatementClass *stmt, Int4 type)
741
{
B
Bruce Momjian 已提交
742 743
	switch (type)
	{
744 745 746 747 748 749 750 751 752
		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;
B
Bruce Momjian 已提交
753 754 755
		default:
			return -1;
	}
756 757
}

758

B
Bruce Momjian 已提交
759 760
Int2
pgtype_nullable(StatementClass *stmt, Int4 type)
761
{
B
Bruce Momjian 已提交
762
	return SQL_NULLABLE;		/* everything should be nullable */
763 764
}

765

B
Bruce Momjian 已提交
766 767
Int2
pgtype_auto_increment(StatementClass *stmt, Int4 type)
768
{
B
Bruce Momjian 已提交
769 770
	switch (type)
	{
771 772 773 774 775 776 777 778 779 780
		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:
B
Bruce Momjian 已提交
781

782 783 784 785 786 787
		case PG_TYPE_DATE:
		case PG_TYPE_TIME:
		case PG_TYPE_ABSTIME:
		case PG_TYPE_DATETIME:
		case PG_TYPE_TIMESTAMP:
			return FALSE;
B
Bruce Momjian 已提交
788 789 790 791

		default:
			return -1;
	}
792 793
}

794

B
Bruce Momjian 已提交
795 796
Int2
pgtype_case_sensitive(StatementClass *stmt, Int4 type)
797
{
B
Bruce Momjian 已提交
798 799
	switch (type)
	{
800
		case PG_TYPE_CHAR:
801

802 803 804
		case PG_TYPE_CHAR2:
		case PG_TYPE_CHAR4:
		case PG_TYPE_CHAR8:
805

806 807 808 809 810
		case PG_TYPE_VARCHAR:
		case PG_TYPE_BPCHAR:
		case PG_TYPE_TEXT:
		case PG_TYPE_NAME:
			return TRUE;
811

B
Bruce Momjian 已提交
812 813 814
		default:
			return FALSE;
	}
815 816
}

817

B
Bruce Momjian 已提交
818 819
Int2
pgtype_money(StatementClass *stmt, Int4 type)
820
{
B
Bruce Momjian 已提交
821 822
	switch (type)
	{
823 824
		case PG_TYPE_MONEY:
			return TRUE;
B
Bruce Momjian 已提交
825 826 827
		default:
			return FALSE;
	}
828 829
}

830

B
Bruce Momjian 已提交
831 832
Int2
pgtype_searchable(StatementClass *stmt, Int4 type)
833
{
B
Bruce Momjian 已提交
834 835
	switch (type)
	{
836 837 838 839
		case PG_TYPE_CHAR:
		case PG_TYPE_CHAR2:
		case PG_TYPE_CHAR4:
		case PG_TYPE_CHAR8:
B
Bruce Momjian 已提交
840

841 842 843 844 845
		case PG_TYPE_VARCHAR:
		case PG_TYPE_BPCHAR:
		case PG_TYPE_TEXT:
		case PG_TYPE_NAME:
			return SQL_SEARCHABLE;
B
Bruce Momjian 已提交
846 847 848 849

		default:
			return SQL_ALL_EXCEPT_LIKE;
	}
850 851
}

852

B
Bruce Momjian 已提交
853 854
Int2
pgtype_unsigned(StatementClass *stmt, Int4 type)
855
{
B
Bruce Momjian 已提交
856 857
	switch (type)
	{
858 859 860
		case PG_TYPE_OID:
		case PG_TYPE_XID:
			return TRUE;
B
Bruce Momjian 已提交
861 862 863 864 865 866 867 868 869 870 871 872

		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;
873 874 875
	}
}

876

B
Bruce Momjian 已提交
877 878
char *
pgtype_literal_prefix(StatementClass *stmt, Int4 type)
879
{
B
Bruce Momjian 已提交
880 881 882 883 884 885 886 887 888 889 890 891 892 893
	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 "'";
894 895 896
	}
}

897

B
Bruce Momjian 已提交
898 899
char *
pgtype_literal_suffix(StatementClass *stmt, Int4 type)
900
{
B
Bruce Momjian 已提交
901 902 903 904 905 906 907 908 909 910 911 912 913 914
	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 "'";
915 916 917
	}
}

918

B
Bruce Momjian 已提交
919 920
char *
pgtype_create_params(StatementClass *stmt, Int4 type)
921
{
B
Bruce Momjian 已提交
922 923
	switch (type)
	{
924 925
			case PG_TYPE_CHAR:
			case PG_TYPE_VARCHAR:return "max. length";
B
Bruce Momjian 已提交
926 927
		default:
			return NULL;
928 929 930 931
	}
}


B
Bruce Momjian 已提交
932 933
Int2
sqltype_to_default_ctype(Int2 sqltype)
934
{
935

936
	/*
937 938
	 * from the table on page 623 of ODBC 2.0 Programmer's Reference
	 * (Appendix D)
939
	 */
B
Bruce Momjian 已提交
940 941
	switch (sqltype)
	{
942 943 944 945 946 947
		case SQL_CHAR:
		case SQL_VARCHAR:
		case SQL_LONGVARCHAR:
		case SQL_DECIMAL:
		case SQL_NUMERIC:
		case SQL_BIGINT:
B
Bruce Momjian 已提交
948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972
			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;
973

B
Bruce Momjian 已提交
974 975
		case SQL_DATE:
			return SQL_C_DATE;
976

B
Bruce Momjian 已提交
977 978
		case SQL_TIME:
			return SQL_C_TIME;
979

B
Bruce Momjian 已提交
980 981
		case SQL_TIMESTAMP:
			return SQL_C_TIMESTAMP;
982

983 984
		default:
			/* should never happen */
B
Bruce Momjian 已提交
985 986
			return SQL_C_CHAR;
	}
987
}
988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040

Int4
ctype_length(Int2 ctype)
{
	switch (ctype)
	{
		case SQL_C_SSHORT:
		case SQL_C_SHORT:
			return sizeof(SWORD);

		case SQL_C_USHORT:
			return sizeof(UWORD);

		case SQL_C_SLONG:
		case SQL_C_LONG:
			return sizeof(SDWORD);

		case SQL_C_ULONG:
			return sizeof(UDWORD);

		case SQL_C_FLOAT:
			return sizeof(SFLOAT);

		case SQL_C_DOUBLE:
			return sizeof(SDOUBLE);

		case SQL_C_BIT:
			return sizeof(UCHAR);

		case SQL_C_STINYINT:
		case SQL_C_TINYINT:
			return sizeof(SCHAR);

		case SQL_C_UTINYINT:
			return sizeof(UCHAR);

		case SQL_C_DATE:
			return sizeof(DATE_STRUCT);

		case SQL_C_TIME:
			return sizeof(TIME_STRUCT);

		case SQL_C_TIMESTAMP:
			return sizeof(TIMESTAMP_STRUCT);

		case SQL_C_BINARY:
		case SQL_C_CHAR:
			return 0;

		default:				/* should never happen */
			return 0;
	}
}