#include <math.h>
#include "convert.h"
#include "statement.h"
+#include "qresult.h"
#include "bind.h"
#include "pgtypes.h"
#include "lobj.h"
}
else {
+
+ /* begin transaction if needed */
+ if(!CC_is_in_trans(stmt->hdbc)) {
+ QResultClass *res;
+ char ok;
+
+ res = CC_send_query(stmt->hdbc, "BEGIN", NULL);
+ if (!res) {
+ stmt->errormsg = "Could not begin (in-line) a transaction";
+ stmt->errornumber = STMT_EXEC_ERROR;
+ SC_log_error(func, "", stmt);
+ return SQL_ERROR;
+ }
+ ok = QR_command_successful(res);
+ QR_Destructor(res);
+ if (!ok) {
+ stmt->errormsg = "Could not begin (in-line) a transaction";
+ stmt->errornumber = STMT_EXEC_ERROR;
+ SC_log_error(func, "", stmt);
+ return SQL_ERROR;
+ }
+
+ CC_set_in_trans(stmt->hdbc);
+ }
/* store the oid */
lobj_oid = lo_creat(stmt->hdbc, INV_READ | INV_WRITE);
retval = lo_write(stmt->hdbc, lobj_fd, buffer, used);
lo_close(stmt->hdbc, lobj_fd);
+
+ /* commit transaction if needed */
+ if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) {
+ QResultClass *res;
+ char ok;
+
+ res = CC_send_query(stmt->hdbc, "COMMIT", NULL);
+ if (!res) {
+ stmt->errormsg = "Could not commit (in-line) a transaction";
+ stmt->errornumber = STMT_EXEC_ERROR;
+ SC_log_error(func, "", stmt);
+ return SQL_ERROR;
+ }
+ ok = QR_command_successful(res);
+ QR_Destructor(res);
+ if (!ok) {
+ stmt->errormsg = "Could not commit (in-line) a transaction";
+ stmt->errornumber = STMT_EXEC_ERROR;
+ SC_log_error(func, "", stmt);
+ return SQL_ERROR;
+ }
+
+ CC_set_no_trans(stmt->hdbc);
+ }
}
/* the oid of the large object -- just put that in for the
*/
if ( ! bindInfo || bindInfo->data_left == -1) {
+
+ /* begin transaction if needed */
+ if(!CC_is_in_trans(stmt->hdbc)) {
+ QResultClass *res;
+ char ok;
+
+ res = CC_send_query(stmt->hdbc, "BEGIN", NULL);
+ if (!res) {
+ stmt->errormsg = "Could not begin (in-line) a transaction";
+ stmt->errornumber = STMT_EXEC_ERROR;
+ return COPY_GENERAL_ERROR;
+ }
+ ok = QR_command_successful(res);
+ QR_Destructor(res);
+ if (!ok) {
+ stmt->errormsg = "Could not begin (in-line) a transaction";
+ stmt->errornumber = STMT_EXEC_ERROR;
+ return COPY_GENERAL_ERROR;
+ }
+
+ CC_set_in_trans(stmt->hdbc);
+ }
+
oid = atoi(value);
stmt->lobj_fd = lo_open(stmt->hdbc, oid, INV_READ);
if (stmt->lobj_fd < 0) {
retval = lo_read(stmt->hdbc, stmt->lobj_fd, (char *) rgbValue, cbValueMax);
if (retval < 0) {
lo_close(stmt->hdbc, stmt->lobj_fd);
+
+ /* commit transaction if needed */
+ if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) {
+ QResultClass *res;
+ char ok;
+
+ res = CC_send_query(stmt->hdbc, "COMMIT", NULL);
+ if (!res) {
+ stmt->errormsg = "Could not commit (in-line) a transaction";
+ stmt->errornumber = STMT_EXEC_ERROR;
+ return COPY_GENERAL_ERROR;
+ }
+ ok = QR_command_successful(res);
+ QR_Destructor(res);
+ if (!ok) {
+ stmt->errormsg = "Could not commit (in-line) a transaction";
+ stmt->errornumber = STMT_EXEC_ERROR;
+ return COPY_GENERAL_ERROR;
+ }
+
+ CC_set_no_trans(stmt->hdbc);
+ }
+
stmt->lobj_fd = -1;
stmt->errornumber = STMT_EXEC_ERROR;
if (! bindInfo || bindInfo->data_left == 0) {
lo_close(stmt->hdbc, stmt->lobj_fd);
+
+ /* commit transaction if needed */
+ if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) {
+ QResultClass *res;
+ char ok;
+
+ res = CC_send_query(stmt->hdbc, "COMMIT", NULL);
+ if (!res) {
+ stmt->errormsg = "Could not commit (in-line) a transaction";
+ stmt->errornumber = STMT_EXEC_ERROR;
+ return COPY_GENERAL_ERROR;
+ }
+ ok = QR_command_successful(res);
+ QR_Destructor(res);
+ if (!ok) {
+ stmt->errormsg = "Could not commit (in-line) a transaction";
+ stmt->errornumber = STMT_EXEC_ERROR;
+ return COPY_GENERAL_ERROR;
+ }
+
+ CC_set_no_trans(stmt->hdbc);
+ }
+
stmt->lobj_fd = -1; /* prevent further reading */
}
/* close the large object */
if ( stmt->lobj_fd >= 0) {
lo_close(stmt->hdbc, stmt->lobj_fd);
+
+ /* commit transaction if needed */
+ if (!globals.use_declarefetch && CC_is_in_autocommit(stmt->hdbc)) {
+ QResultClass *res;
+ char ok;
+
+ res = CC_send_query(stmt->hdbc, "COMMIT", NULL);
+ if (!res) {
+ stmt->errormsg = "Could not commit (in-line) a transaction";
+ stmt->errornumber = STMT_EXEC_ERROR;
+ SC_log_error(func, "", stmt);
+ return SQL_ERROR;
+ }
+ ok = QR_command_successful(res);
+ QR_Destructor(res);
+ if (!ok) {
+ stmt->errormsg = "Could not commit (in-line) a transaction";
+ stmt->errornumber = STMT_EXEC_ERROR;
+ SC_log_error(func, "", stmt);
+ return SQL_ERROR;
+ }
+
+ CC_set_no_trans(stmt->hdbc);
+ }
+
stmt->lobj_fd = -1;
}
/* Handle Long Var Binary with Large Objects */
if ( current_param->SQLType == SQL_LONGVARBINARY) {
+ /* begin transaction if needed */
+ if(!CC_is_in_trans(stmt->hdbc)) {
+ QResultClass *res;
+ char ok;
+
+ res = CC_send_query(stmt->hdbc, "BEGIN", NULL);
+ if (!res) {
+ stmt->errormsg = "Could not begin (in-line) a transaction";
+ stmt->errornumber = STMT_EXEC_ERROR;
+ SC_log_error(func, "", stmt);
+ return SQL_ERROR;
+ }
+ ok = QR_command_successful(res);
+ QR_Destructor(res);
+ if (!ok) {
+ stmt->errormsg = "Could not begin (in-line) a transaction";
+ stmt->errornumber = STMT_EXEC_ERROR;
+ SC_log_error(func, "", stmt);
+ return SQL_ERROR;
+ }
+
+ CC_set_in_trans(stmt->hdbc);
+ }
+
/* store the oid */
current_param->lobj_oid = lo_creat(stmt->hdbc, INV_READ | INV_WRITE);
if (current_param->lobj_oid == 0) {
set_nullfield_string(&row->tuple[5], pgtype_create_params(stmt, pgType));
set_nullfield_int2(&row->tuple[9], pgtype_unsigned(stmt, pgType));
set_nullfield_int2(&row->tuple[11], pgtype_auto_increment(stmt, pgType));
- set_nullfield_int2(&row->tuple[13], pgtype_scale(stmt, pgType));
- set_nullfield_int2(&row->tuple[14], pgtype_scale(stmt, pgType));
+ set_nullfield_int2(&row->tuple[13], pgtype_scale(stmt, pgType, PG_STATIC));
+ set_nullfield_int2(&row->tuple[14], pgtype_scale(stmt, pgType, PG_STATIC));
QR_add_tuple(stmt->result, row);
}
char columns_query[MAX_STATEMENT_LEN];
RETCODE result;
char table_owner[MAX_INFO_STRING], table_name[MAX_INFO_STRING], field_name[MAX_INFO_STRING], field_type_name[MAX_INFO_STRING];
-Int2 field_number, result_cols;
-Int4 field_type, the_type, field_length, mod_length;
+Int2 field_number, result_cols, scale;
+Int4 field_type, the_type, field_length, mod_length, precision;
+char useStaticPrecision;
char not_null[MAX_INFO_STRING], relhasrules[MAX_INFO_STRING];
ConnInfo *ci;
set_tuplefield_int4(&row->tuple[7], pgtype_length(stmt, the_type, PG_STATIC, PG_STATIC));
set_tuplefield_int4(&row->tuple[6], pgtype_precision(stmt, the_type, PG_STATIC, PG_STATIC));
- set_nullfield_int2(&row->tuple[8], pgtype_scale(stmt, the_type));
+ set_nullfield_int2(&row->tuple[8], pgtype_scale(stmt, the_type, PG_STATIC));
set_nullfield_int2(&row->tuple[9], pgtype_radix(stmt, the_type));
set_tuplefield_int2(&row->tuple[10], SQL_NO_NULLS);
set_tuplefield_string(&row->tuple[11], "");
VARCHAR - the length is stored in the pg_attribute.atttypmod field
BPCHAR - the length is also stored as varchar is
+ NUMERIC - the scale is stored in atttypmod as follows:
+ precision = ((atttypmod - VARHDRSZ) >> 16) & 0xffff
+ scale = (atttypmod - VARHDRSZ) & 0xffff
+
+
*/
+ qlog("SQLColumns: table='%s',field_name='%s',type=%d,sqltype=%d,name='%s'\n",
+ table_name,field_name,field_type,pgtype_to_sqltype,field_type_name);
+
+ useStaticPrecision = TRUE;
+
+ if (field_type == PG_TYPE_NUMERIC) {
+ if (mod_length >= 4)
+ mod_length -= 4; // the length is in atttypmod - 4
+
+ if (mod_length >= 0) {
+ useStaticPrecision = FALSE;
+
+ precision = (mod_length >> 16) & 0xffff;
+ scale = mod_length & 0xffff;
+
+ mylog("SQLColumns: field type is NUMERIC: field_type = %d, mod_length=%d, precision=%d, scale=%d\n", field_type, mod_length, precision, scale );
+
+ set_tuplefield_int4(&row->tuple[7], precision + 2); // sign+dec.point
+ set_tuplefield_int4(&row->tuple[6], precision);
+ set_tuplefield_int4(&row->tuple[12], precision + 2); // sign+dec.point
+ set_nullfield_int2(&row->tuple[8], scale);
+ }
+ }
+
+
if((field_type == PG_TYPE_VARCHAR) ||
(field_type == PG_TYPE_BPCHAR)) {
+ useStaticPrecision = FALSE;
+
if (mod_length >= 4)
mod_length -= 4; // the length is in atttypmod - 4
mylog("SQLColumns: field type is VARCHAR,BPCHAR: field_type = %d, mod_length = %d\n", field_type, mod_length);
- set_tuplefield_int4(&row->tuple[7], mod_length);
+ set_tuplefield_int4(&row->tuple[7], mod_length);
set_tuplefield_int4(&row->tuple[6], mod_length);
set_tuplefield_int4(&row->tuple[12], mod_length);
- } else {
+ set_nullfield_int2(&row->tuple[8], pgtype_scale(stmt, field_type, PG_STATIC));
+ }
+
+ if (useStaticPrecision) {
mylog("SQLColumns: field type is OTHER: field_type = %d, pgtype_length = %d\n", field_type, pgtype_length(stmt, field_type, PG_STATIC, PG_STATIC));
set_tuplefield_int4(&row->tuple[7], pgtype_length(stmt, field_type, PG_STATIC, PG_STATIC));
set_tuplefield_int4(&row->tuple[6], pgtype_precision(stmt, field_type, PG_STATIC, PG_STATIC));
set_tuplefield_int4(&row->tuple[12], pgtype_display_size(stmt, field_type, PG_STATIC, PG_STATIC));
-
+ set_nullfield_int2(&row->tuple[8], pgtype_scale(stmt, field_type, PG_STATIC));
}
- set_nullfield_int2(&row->tuple[8], pgtype_scale(stmt, field_type));
set_nullfield_int2(&row->tuple[9], pgtype_radix(stmt, field_type));
set_tuplefield_int2(&row->tuple[10], (Int2) (not_null[0] == '1' ? SQL_NO_NULLS : pgtype_nullable(stmt, field_type)));
set_tuplefield_string(&row->tuple[11], "");
set_tuplefield_string(&row->tuple[5], pgtype_to_name(stmt, the_type));
set_tuplefield_int4(&row->tuple[6], pgtype_precision(stmt, the_type, PG_STATIC, PG_STATIC));
set_tuplefield_int4(&row->tuple[7], pgtype_length(stmt, the_type, PG_STATIC, PG_STATIC));
- set_nullfield_int2(&row->tuple[8], pgtype_scale(stmt, the_type));
+ set_nullfield_int2(&row->tuple[8], pgtype_scale(stmt, the_type, PG_STATIC));
set_nullfield_int2(&row->tuple[9], pgtype_radix(stmt, the_type));
set_tuplefield_int2(&row->tuple[10], SQL_NO_NULLS);
set_tuplefield_string(&row->tuple[11], "");
set_tuplefield_string(&row->tuple[3], "OID");
set_tuplefield_int4(&row->tuple[4], pgtype_precision(stmt, PG_TYPE_OID, PG_STATIC, PG_STATIC));
set_tuplefield_int4(&row->tuple[5], pgtype_length(stmt, PG_TYPE_OID, PG_STATIC, PG_STATIC));
- set_tuplefield_int2(&row->tuple[6], pgtype_scale(stmt, PG_TYPE_OID));
+ set_tuplefield_int2(&row->tuple[6], pgtype_scale(stmt, PG_TYPE_OID, PG_STATIC));
set_tuplefield_int2(&row->tuple[7], SQL_PC_PSEUDO);
QR_add_tuple(stmt->result, row);
set_tuplefield_string(&row->tuple[3], pgtype_to_name(stmt, the_type));
set_tuplefield_int4(&row->tuple[4], pgtype_precision(stmt, the_type, PG_STATIC, PG_STATIC));
set_tuplefield_int4(&row->tuple[5], pgtype_length(stmt, the_type, PG_STATIC, PG_STATIC));
- set_tuplefield_int2(&row->tuple[6], pgtype_scale(stmt, the_type));
+ set_tuplefield_int2(&row->tuple[6], pgtype_scale(stmt, the_type, PG_STATIC));
set_tuplefield_int2(&row->tuple[7], SQL_PC_PSEUDO);
QR_add_tuple(stmt->result, row);
pgType = PG_TYPE_FLOAT8;
break;
- case SQL_INTEGER:
- case SQL_BIGINT:
- case SQL_NUMERIC:
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 PG_TYPE_CHAR2:
case PG_TYPE_CHAR4:
case PG_TYPE_CHAR8:
- case PG_TYPE_CHAR16:
case PG_TYPE_NAME: return SQL_CHAR;
case PG_TYPE_BPCHAR: return SQL_CHAR;
case PG_TYPE_XID:
case PG_TYPE_INT4: return SQL_INTEGER;
+ case PG_TYPE_INT8: return SQL_BIGINT;
+ 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;
Int2 pgtype_to_ctype(StatementClass *stmt, Int4 type)
{
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_CHAR2: return "char2";
case PG_TYPE_CHAR4: return "char4";
case PG_TYPE_CHAR8: return "char8";
- case PG_TYPE_CHAR16: return "char16";
+ 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";
}
}
+Int2
+getNumericScale(StatementClass *stmt, Int4 type, int col)
+{
+Int4 atttypmod;
+QResultClass *result;
+ColumnInfoClass *flds;
+
+mylog("getNumericScale: type=%d, col=%d, unknown = %d\n", type,col);
+
+ if (col < 0)
+ return PG_NUMERIC_MAX_SCALE;
+
+ result = SC_get_Result(stmt);
+
+ /* Manual Result Sets -- use assigned column width (i.e., from set_tuplefield_string) */
+ if (stmt->manual_result) {
+ flds = result->fields;
+ if (flds)
+ return flds->adtsize[col];
+ else
+ return PG_NUMERIC_MAX_SCALE;
+ }
+
+ atttypmod = QR_get_atttypmod(result, col);
+ if ( atttypmod > -1 )
+ return (atttypmod & 0xffff);
+ else
+ return ( QR_get_display_size(result, col) ?
+ QR_get_display_size(result, col) :
+ PG_NUMERIC_MAX_SCALE);
+}
+
+Int4
+getNumericPrecision(StatementClass *stmt, Int4 type, int col)
+{
+Int4 atttypmod;
+QResultClass *result;
+ColumnInfoClass *flds;
+
+mylog("getNumericPrecision: type=%d, col=%d, unknown = %d\n", type,col);
+
+ if (col < 0)
+ return PG_NUMERIC_MAX_PRECISION;
+
+ result = SC_get_Result(stmt);
+
+ /* Manual Result Sets -- use assigned column width (i.e., from set_tuplefield_string) */
+ if (stmt->manual_result) {
+ flds = result->fields;
+ if (flds)
+ return flds->adtsize[col];
+ else
+ return PG_NUMERIC_MAX_PRECISION;
+ }
+
+ atttypmod = QR_get_atttypmod(result, col);
+ if ( atttypmod > -1 )
+ return (atttypmod >> 16) & 0xffff;
+ else
+ return ( QR_get_display_size(result, col) >= 0 ?
+ QR_get_display_size(result, col) :
+ PG_NUMERIC_MAX_PRECISION );
+}
+
Int4
getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
{
return p;
}
-/* For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, SQLColumns will
+/* 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.
case PG_TYPE_CHAR2: return 2;
case PG_TYPE_CHAR4: return 4;
case PG_TYPE_CHAR8: return 8;
- case PG_TYPE_CHAR16: return 16;
case PG_TYPE_NAME: return NAME_FIELD_SIZE;
case PG_TYPE_XID:
case PG_TYPE_INT4: return 10;
+ case PG_TYPE_INT8: return 19; /* signed */
+
+ case PG_TYPE_NUMERIC: return getNumericPrecision(stmt,type,col);
+
case PG_TYPE_FLOAT4:
case PG_TYPE_MONEY: return 7;
Int4 pgtype_display_size(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
{
+
switch(type) {
case PG_TYPE_INT2: return 6;
case PG_TYPE_INT4: return 11;
+ case PG_TYPE_INT8: return 20; /* signed: 19 digits + sign */
+
+ case PG_TYPE_NUMERIC: return getNumericPrecision(stmt,type,col) + 2;
+
case PG_TYPE_MONEY: return 15; /* ($9,999,999.99) */
case PG_TYPE_FLOAT4: return 13;
*/
Int4 pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
{
+
switch(type) {
case PG_TYPE_INT2: return 2;
case PG_TYPE_XID:
case PG_TYPE_INT4: return 4;
+ case PG_TYPE_INT8: return 20; /* signed: 19 digits + sign */
+
+ case PG_TYPE_NUMERIC: return getNumericPrecision(stmt,type,col) + 2;
+
case PG_TYPE_FLOAT4:
case PG_TYPE_MONEY: return 4;
case PG_TYPE_TIMESTAMP: return 16;
- /* Character types use the default precision */
+ /* Character types (and NUMERIC) use the default precision */
default:
return pgtype_precision(stmt, type, col, handle_unknown_size_as);
}
}
-Int2 pgtype_scale(StatementClass *stmt, Int4 type)
+Int2 pgtype_scale(StatementClass *stmt, Int4 type, int col)
{
switch(type) {
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_DATETIME:
case PG_TYPE_TIMESTAMP: return 0;
+ case PG_TYPE_NUMERIC: return getNumericScale(stmt,type,col);
+
default: return -1;
}
}
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;
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_CHAR2:
case PG_TYPE_CHAR4:
case PG_TYPE_CHAR8:
- case PG_TYPE_CHAR16:
case PG_TYPE_VARCHAR:
case PG_TYPE_BPCHAR:
case PG_TYPE_CHAR2:
case PG_TYPE_CHAR4:
case PG_TYPE_CHAR8:
- case PG_TYPE_CHAR16:
case PG_TYPE_VARCHAR:
case PG_TYPE_BPCHAR:
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;
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;
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;
#define PG_TYPE_BYTEA 17
#define PG_TYPE_CHAR 18
#define PG_TYPE_NAME 19
-#define PG_TYPE_CHAR16 20
+#define PG_TYPE_INT8 20
#define PG_TYPE_INT2 21
#define PG_TYPE_INT2VECTOR 22
#define PG_TYPE_INT4 23
#define PG_TYPE_TIME 1083
#define PG_TYPE_DATETIME 1184
#define PG_TYPE_TIMESTAMP 1296
+#define PG_TYPE_NUMERIC 1700
/* extern Int4 pgtypes_defined[]; */
extern Int2 sqlTypes[];
Int4 pgtype_display_size(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
Int4 pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
-Int2 pgtype_scale(StatementClass *stmt, Int4 type);
+Int2 pgtype_scale(StatementClass *stmt, Int4 type, int col);
Int2 pgtype_radix(StatementClass *stmt, Int4 type);
Int2 pgtype_nullable(StatementClass *stmt, Int4 type);
Int2 pgtype_auto_increment(StatementClass *stmt, Int4 type);
#define DRIVERNAME "PostgreSQL ODBC"
#define DBMS_NAME "PostgreSQL"
-#define DBMS_VERSION "06.40.0007 PostgreSQL 6.4"
-#define POSTGRESDRIVERVERSION "06.40.0007"
+
+#define DBMS_VERSION "06.40.0008 PostgreSQL 6.4/6.5"
+#define POSTGRESDRIVERVERSION "06.40.0008"
#ifdef WIN32
#define DRIVER_FILE_NAME "PSQLODBC.DLL"
#define NAME_FIELD_SIZE 32 /* size of name fields */
#define MAX_VARCHAR_SIZE 254 /* maximum size of a varchar (not including null term) */
+#define PG_NUMERIC_MAX_PRECISION 1000
+#define PG_NUMERIC_MAX_SCALE 1000
#include "misc.h"
/************************/
if (pibScale) {
Int2 scale;
- scale = pgtype_scale(stmt, fieldtype);
+ scale = pgtype_scale(stmt, fieldtype, icol);
if(scale == -1) { scale = 0; }
*pibScale = scale;
break;
case SQL_COLUMN_SCALE:
- value = pgtype_scale(stmt, field_type);
+ value = pgtype_scale(stmt, field_type, icol);
break;
case SQL_COLUMN_SEARCHABLE: