aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/interfaces/odbc/connection.c85
-rw-r--r--src/interfaces/odbc/connection.h4
-rw-r--r--src/interfaces/odbc/info.c302
-rw-r--r--src/interfaces/odbc/parse.c5
-rw-r--r--src/interfaces/odbc/results.c9
-rw-r--r--src/interfaces/odbc/statement.h1
6 files changed, 315 insertions, 91 deletions
diff --git a/src/interfaces/odbc/connection.c b/src/interfaces/odbc/connection.c
index 3c784ead445..9685c9358b5 100644
--- a/src/interfaces/odbc/connection.c
+++ b/src/interfaces/odbc/connection.c
@@ -14,6 +14,10 @@
*/
/* Multibyte support Eiji Tokuya 2001-03-15 */
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
#include "connection.h"
#include "environ.h"
@@ -27,9 +31,6 @@
#include "multibyte.h"
#endif
-#include <stdio.h>
-#include <string.h>
-
#ifdef WIN32
#include <odbcinst.h>
#endif
@@ -277,6 +278,10 @@ memcpy(&(rv->connInfo.drivers), &globals, sizeof(globals));
rv->pg_version_number = .0;
rv->pg_version_major = 0;
rv->pg_version_minor = 0;
+#ifdef MULTIBYTE
+ rv->client_encoding = NULL;
+ rv->server_encoding = NULL;
+#endif /* MULTIBYTE */
/* Initialize statement options to defaults */
@@ -302,6 +307,12 @@ CC_Destructor(ConnectionClass *self)
mylog("after CC_Cleanup\n");
+#ifdef MULTIBYTE
+ if (self->client_encoding)
+ free(self->client_encoding);
+ if (self->server_encoding)
+ free(self->server_encoding);
+#endif /* MULTIBYTE */
/* Free up statement holders */
if (self->stmts)
{
@@ -510,6 +521,9 @@ CC_connect(ConnectionClass *self, char do_password)
char msgbuffer[ERROR_MSG_LENGTH];
char salt[5];
static char *func = "CC_connect";
+#ifdef MULTIBYTE
+ char *encoding;
+#endif /* MULTIBYTE */
mylog("%s: entering...\n", func);
@@ -537,7 +551,9 @@ CC_connect(ConnectionClass *self, char do_password)
ci->drivers.bools_as_char);
#ifdef MULTIBYTE
- check_client_encoding(ci->drivers.conn_settings);
+ encoding = check_client_encoding(ci->drivers.conn_settings);
+ if (encoding && strcmp(encoding, "OTHER"))
+ self->client_encoding = strdup(encoding);
qlog(" extra_systable_prefixes='%s', conn_settings='%s' conn_encoding='%s'\n",
ci->drivers.extra_systable_prefixes,
ci->drivers.conn_settings,
@@ -1041,7 +1057,6 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
CC_set_no_trans(self);
ReadyToReturn = TRUE;
retres = NULL;
- break;
}
else
{
@@ -1059,6 +1074,7 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
QR_set_status(res, PGRES_COMMAND_OK);
QR_set_command(res, cmdbuffer);
query_completed = TRUE;
+ mylog("send_query: returning res = %u\n", res);
if (!before_64)
break;
/*
@@ -1069,71 +1085,14 @@ CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
* an 'I' is received
*/
-
if (empty_reqs == 0)
{
SOCK_put_string(sock, "Q ");
SOCK_flush_output(sock);
empty_reqs++;
}
- break;
-
- while (!clear)
- {
- id = SOCK_get_char(sock);
- mylog("got clear id = '%c'\n", id);
- switch (id)
- {
- case 'I':
- (void) SOCK_get_char(sock);
- clear = TRUE;
- break;
- case 'Z':
- break;
- case 'C':
- SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
- qlog("Command response: '%s'\n", cmdbuffer);
- break;
- case 'N':
- msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
- if (QR_command_successful(res))
- QR_set_status(res, PGRES_NONFATAL_ERROR);
- QR_set_notice(res, cmdbuffer); /* will dup this string */
- qlog("NOTICE from backend during clear: '%s'\n", cmdbuffer);
- while (msg_truncated)
- msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
- break;
- case 'E':
- msg_truncated = SOCK_get_string(sock, msgbuffer, ERROR_MSG_LENGTH);
- mylog("ERROR from backend during clear: '%s'\n", msgbuffer);
- qlog("ERROR from backend during clear: '%s'\n", msgbuffer);
-
- /*
- * We must report this type of error as
- * well (practically for reference
- * integrity violation error reporting,
- * from PostgreSQL 7.0). (Zoltan Kovacs,
- * 04/26/2000)
- */
- self->errormsg = msgbuffer;
- if (!strncmp(self->errormsg, "FATAL", 5))
- {
- self->errornumber = CONNECTION_SERVER_REPORTED_ERROR;
- CC_set_no_trans(self);
- }
- else
- self->errornumber = CONNECTION_SERVER_REPORTED_WARNING;
- QR_set_status(res, PGRES_FATAL_ERROR);
- QR_set_aborted(res, TRUE);
- while (msg_truncated)
- msg_truncated = SOCK_get_string(sock, cmdbuffer, ERROR_MSG_LENGTH);
- break;
- }
- }
-
- mylog("send_query: returning res = %u\n", res);
- break;
}
+ break;
case 'Z': /* Backend is ready for new query (6.4) */
if (empty_reqs == 0)
{
diff --git a/src/interfaces/odbc/connection.h b/src/interfaces/odbc/connection.h
index 24931cef2b2..fc77bc8a7b4 100644
--- a/src/interfaces/odbc/connection.h
+++ b/src/interfaces/odbc/connection.h
@@ -274,6 +274,10 @@ struct ConnectionClass_
float pg_version_number;
Int2 pg_version_major;
Int2 pg_version_minor;
+#ifdef MULTIBYTE
+ char *client_encoding;
+ char *server_encoding;
+#endif /* MULTIBYTE */
};
diff --git a/src/interfaces/odbc/info.c b/src/interfaces/odbc/info.c
index 2f5d4c88d03..663e207abb5 100644
--- a/src/interfaces/odbc/info.c
+++ b/src/interfaces/odbc/info.c
@@ -2666,6 +2666,180 @@ PGAPI_PrimaryKeys(
}
+#ifdef MULTIBYTE
+/*
+ * Multibyte support stuff for SQLForeignKeys().
+ * There may be much more effective way in the
+ * future version. The way is very forcive currently.
+ */
+static BOOL isMultibyte(const unsigned char *str)
+{
+ for (; *str; str++)
+ {
+ if (*str >= 0x80)
+ return TRUE;
+ }
+ return FALSE;
+}
+static char *getClientTableName(ConnectionClass *conn, char *serverTableName, BOOL *nameAlloced)
+{
+ char query[1024], saveoid[24], *ret = serverTableName;
+ BOOL continueExec = TRUE, bError = FALSE;
+ QResultClass *res;
+
+ *nameAlloced = FALSE;
+ if (!conn->client_encoding || !isMultibyte(serverTableName))
+ return ret;
+ if (!conn->server_encoding)
+ {
+ if (res = CC_send_query(conn, "select getdatabaseencoding()", NULL), res)
+ {
+ if (QR_get_num_tuples(res) > 0)
+ conn->server_encoding = strdup(QR_get_value_backend_row(res, 0, 0));
+ QR_Destructor(res);
+ }
+ }
+ if (!conn->server_encoding)
+ return ret;
+ sprintf(query, "SET CLIENT_ENCODING TO '%s'", conn->server_encoding);
+ if (res = CC_send_query(conn, query, NULL), res)
+ {
+ bError = QR_get_aborted(res);
+ QR_Destructor(res);
+ }
+ else
+ bError = TRUE;
+ if (!bError && continueExec)
+ {
+ sprintf(query, "select OID from pg_class where relname = '%s'", serverTableName);
+ if (res = CC_send_query(conn, query, NULL), res)
+ {
+ if (QR_get_num_tuples(res) > 0)
+ strcpy(saveoid, QR_get_value_backend_row(res, 0, 0));
+ else
+ {
+ continueExec = FALSE;
+ bError = QR_get_aborted(res);
+ }
+ QR_Destructor(res);
+ }
+ else
+ bError = TRUE;
+ }
+ continueExec = (continueExec && !bError);
+ if (bError && CC_is_in_trans(conn))
+ {
+ if (res = CC_send_query(conn, "abort", NULL), res)
+ QR_Destructor(res);
+ CC_set_no_trans(conn);
+ bError = FALSE;
+ }
+ /* restore the client encoding */
+ sprintf(query, "SET CLIENT_ENCODING TO '%s'", conn->client_encoding);
+ if (res = CC_send_query(conn, query, NULL), res)
+ {
+ bError = QR_get_aborted(res);
+ QR_Destructor(res);
+ }
+ else
+ bError = TRUE;
+ if (bError || !continueExec)
+ return ret;
+ sprintf(query, "select relname from pg_class where OID = %s", saveoid);
+ if (res = CC_send_query(conn, query, NULL), res)
+ {
+ if (QR_get_num_tuples(res) > 0)
+ {
+ ret = strdup(QR_get_value_backend_row(res, 0, 0));
+ *nameAlloced = TRUE;
+ }
+ QR_Destructor(res);
+ }
+ return ret;
+}
+static char *getClientColumnName(ConnectionClass *conn, const char *serverTableName, char *serverColumnName, BOOL *nameAlloced)
+{
+ char query[1024], saveattrelid[24], saveattnum[16], *ret = serverColumnName;
+ BOOL continueExec = TRUE, bError = FALSE;
+ QResultClass *res;
+
+ *nameAlloced = FALSE;
+ if (!conn->client_encoding || !isMultibyte(serverColumnName))
+ return ret;
+ if (!conn->server_encoding)
+ {
+ if (res = CC_send_query(conn, "select getdatabaseencoding()", NULL), res)
+ {
+ if (QR_get_num_tuples(res) > 0)
+ conn->server_encoding = strdup(QR_get_value_backend_row(res, 0, 0));
+ QR_Destructor(res);
+ }
+ }
+ if (!conn->server_encoding)
+ return ret;
+ sprintf(query, "SET CLIENT_ENCODING TO '%s'", conn->server_encoding);
+ if (res = CC_send_query(conn, query, NULL), res)
+ {
+ bError = QR_get_aborted(res);
+ QR_Destructor(res);
+ }
+ else
+ bError = TRUE;
+ if (!bError && continueExec)
+ {
+ sprintf(query, "select attrelid, attnum from pg_class, pg_attribute "
+ "where relname = '%s' and attrelid = pg_class.oid "
+ "and attname = '%s'", serverTableName, serverColumnName);
+ if (res = CC_send_query(conn, query, NULL), res)
+ {
+ if (QR_get_num_tuples(res) > 0)
+ {
+ strcpy(saveattrelid, QR_get_value_backend_row(res, 0, 0));
+ strcpy(saveattnum, QR_get_value_backend_row(res, 0, 1));
+ }
+ else
+ {
+ continueExec = FALSE;
+ bError = QR_get_aborted(res);
+ }
+ QR_Destructor(res);
+ }
+ else
+ bError = TRUE;
+ }
+ continueExec = (continueExec && !bError);
+ if (bError && CC_is_in_trans(conn))
+ {
+ if (res = CC_send_query(conn, "abort", NULL), res)
+ QR_Destructor(res);
+ CC_set_no_trans(conn);
+ bError = FALSE;
+ }
+ /* restore the cleint encoding */
+ sprintf(query, "SET CLIENT_ENCODING TO '%s'", conn->client_encoding);
+ if (res = CC_send_query(conn, query, NULL), res)
+ {
+ bError = QR_get_aborted(res);
+ QR_Destructor(res);
+ }
+ else
+ bError = TRUE;
+ if (bError || !continueExec)
+ return ret;
+ sprintf(query, "select attname from pg_attribute where attrelid = %s and attnum = %s", saveattrelid, saveattnum);
+ if (res = CC_send_query(conn, query, NULL), res)
+ {
+ if (QR_get_num_tuples(res) > 0)
+ {
+ ret = strdup(QR_get_value_backend_row(res, 0, 0));
+ *nameAlloced = TRUE;
+ }
+ QR_Destructor(res);
+ }
+ return ret;
+}
+#endif /* MULTIBYTE */
+
RETCODE SQL_API
PGAPI_ForeignKeys(
HSTMT hstmt,
@@ -2698,10 +2872,14 @@ PGAPI_ForeignKeys(
del_rule[MAX_TABLE_LEN];
char pk_table_needed[MAX_TABLE_LEN + 1];
char fk_table_needed[MAX_TABLE_LEN + 1];
- char *pkey_ptr,
- *fkey_ptr,
- *pk_table,
- *fk_table;
+ char *pkey_ptr, *pkey_text,
+ *fkey_ptr, *fkey_text,
+ *pk_table, *pkt_text,
+ *fk_table, *fkt_text;
+#ifdef MULTIBYTE
+ BOOL pkey_alloced, fkey_alloced, pkt_alloced, fkt_alloced;
+ ConnectionClass *conn;
+#endif /* MULTIBYTE */
int i,
j,
k,
@@ -2795,6 +2973,10 @@ PGAPI_ForeignKeys(
make_string(szPkTableName, cbPkTableName, pk_table_needed);
make_string(szFkTableName, cbFkTableName, fk_table_needed);
+#ifdef MULTIBYTE
+ pkey_alloced = fkey_alloced = pkt_alloced = fkt_alloced = FALSE;
+ conn = SC_get_conn(stmt);
+#endif /* MULTIBYTE */
/*
* Case #2 -- Get the foreign keys in the specified table (fktab) that
* refer to the primary keys of other table(s).
@@ -2954,18 +3136,24 @@ PGAPI_ForeignKeys(
for (k = 0; k < 2; k++)
pk_table += strlen(pk_table) + 1;
+#ifdef MULTIBYTE
+ fk_table = trig_args + strlen(trig_args) + 1;
+ pkt_text = getClientTableName(conn, pk_table, &pkt_alloced);
+#else
+ pkt_text = pk_table;
+#endif /* MULTIBYTE */
/* If there is a pk table specified, then check it. */
if (pk_table_needed[0] != '\0')
{
/* If it doesn't match, then continue */
- if (strcmp(pk_table, pk_table_needed))
+ if (strcmp(pkt_text, pk_table_needed))
{
result = PGAPI_Fetch(htbl_stmt);
continue;
}
}
- keyresult = PGAPI_PrimaryKeys(hpkey_stmt, NULL, 0, NULL, 0, pk_table, SQL_NTS);
+ keyresult = PGAPI_PrimaryKeys(hpkey_stmt, NULL, 0, NULL, 0, pkt_text, SQL_NTS);
if (keyresult != SQL_SUCCESS)
{
stmt->errornumber = STMT_NO_MEMORY_ERROR;
@@ -2975,8 +3163,6 @@ PGAPI_ForeignKeys(
return SQL_ERROR;
}
- /* Check that the key listed is the primary key */
- keyresult = PGAPI_Fetch(hpkey_stmt);
/* Get to first primary key */
pkey_ptr = trig_args;
@@ -2985,17 +3171,32 @@ PGAPI_ForeignKeys(
for (k = 0; k < num_keys; k++)
{
- mylog("%s: pkey_ptr='%s', pkey='%s'\n", func, pkey_ptr, pkey);
- if (keyresult != SQL_SUCCESS || strcmp(pkey_ptr, pkey))
+ /* Check that the key listed is the primary key */
+ keyresult = PGAPI_Fetch(hpkey_stmt);
+ if (keyresult != SQL_SUCCESS)
{
num_keys = 0;
break;
}
+#ifdef MULTIBYTE
+ pkey_text = getClientColumnName(conn, pk_table, pkey_ptr, &pkey_alloced);
+#else
+ pkey_text = pkey_ptr;
+#endif /* MULTIBYTE */
+ mylog("%s: pkey_ptr='%s', pkey='%s'\n", func, pkey_text, pkey);
+ if (strcmp(pkey_text, pkey))
+ {
+ num_keys = 0;
+ break;
+ }
+#ifdef MULTIBYTE
+ if (pkey_alloced)
+ free(pkey_text);
+#endif /* MULTIBYTE */
/* Get to next primary key */
for (k = 0; k < 2; k++)
pkey_ptr += strlen(pkey_ptr) + 1;
- keyresult = PGAPI_Fetch(hpkey_stmt);
}
/* Set to first fk column */
@@ -3045,17 +3246,24 @@ PGAPI_ForeignKeys(
{
row = (TupleNode *) malloc(sizeof(TupleNode) + (result_cols - 1) *sizeof(TupleField));
- mylog("%s: pk_table = '%s', pkey_ptr = '%s'\n", func, pk_table, pkey_ptr);
+#ifdef MULTIBYTE
+ pkey_text = getClientColumnName(conn, pk_table, pkey_ptr, &pkey_alloced);
+ fkey_text = getClientColumnName(conn, fk_table, fkey_ptr, &fkey_alloced);
+#else
+ pkey_text = pkey_ptr;
+ fkey_text = fkey_ptr;
+#endif /* MULTIBYTE */
+ mylog("%s: pk_table = '%s', pkey_ptr = '%s'\n", func, pkt_text, pkey_text);
set_tuplefield_null(&row->tuple[0]);
set_tuplefield_string(&row->tuple[1], "");
- set_tuplefield_string(&row->tuple[2], pk_table);
- set_tuplefield_string(&row->tuple[3], pkey_ptr);
+ set_tuplefield_string(&row->tuple[2], pkt_text);
+ set_tuplefield_string(&row->tuple[3], pkey_text);
- mylog("%s: fk_table_needed = '%s', fkey_ptr = '%s'\n", func, fk_table_needed, fkey_ptr);
+ mylog("%s: fk_table_needed = '%s', fkey_ptr = '%s'\n", func, fk_table_needed, fkey_text);
set_tuplefield_null(&row->tuple[4]);
set_tuplefield_string(&row->tuple[5], "");
set_tuplefield_string(&row->tuple[6], fk_table_needed);
- set_tuplefield_string(&row->tuple[7], fkey_ptr);
+ set_tuplefield_string(&row->tuple[7], fkey_text);
mylog("%s: upd_rule_type = '%i', del_rule_type = '%i'\n, trig_name = '%s'", func, upd_rule_type, del_rule_type, trig_args);
set_tuplefield_int2(&row->tuple[8], (Int2) (k + 1));
@@ -3069,7 +3277,14 @@ PGAPI_ForeignKeys(
#endif /* ODBCVER >= 0x0300 */
QR_add_tuple(stmt->result, row);
-
+#ifdef MULTIBYTE
+ if (fkey_alloced)
+ free(fkey_text);
+ fkey_alloced = FALSE;
+ if (pkey_alloced)
+ free(pkey_text);
+ pkey_alloced = FALSE;
+#endif /* MULTIBYTE */
/* next primary/foreign key */
for (i = 0; i < 2; i++)
{
@@ -3077,6 +3292,11 @@ PGAPI_ForeignKeys(
pkey_ptr += strlen(pkey_ptr) + 1;
}
}
+#ifdef MULTIBYTE
+ if (pkt_alloced)
+ free(pkt_text);
+ pkt_alloced = FALSE;
+#endif /* MULTIBYTE */
result = PGAPI_Fetch(htbl_stmt);
}
@@ -3257,6 +3477,12 @@ PGAPI_ForeignKeys(
/* Get to first foreign table */
fk_table = trig_args;
fk_table += strlen(fk_table) + 1;
+#ifdef MULTIBYTE
+ pk_table = fk_table + strlen(fk_table) + 1;
+ fkt_text = getClientTableName(conn, fk_table, &fkt_alloced);
+#else
+ fkt_text = fk_table;
+#endif /* MULTIBYTE */
/* Get to first foreign key */
fkey_ptr = trig_args;
@@ -3265,21 +3491,28 @@ PGAPI_ForeignKeys(
for (k = 0; k < num_keys; k++)
{
- mylog("pkey_ptr = '%s', fk_table = '%s', fkey_ptr = '%s'\n", pkey_ptr, fk_table, fkey_ptr);
+#ifdef MULTIBYTE
+ pkey_text = getClientColumnName(conn, pk_table, pkey_ptr, &pkey_alloced);
+ fkey_text = getClientColumnName(conn, fk_table, fkey_ptr, &fkey_alloced);
+#else
+ pkey_text = pkey_ptr;
+ fkey_text = fkey_ptr;
+#endif /* MULTIBYTE */
+ mylog("pkey_ptr = '%s', fk_table = '%s', fkey_ptr = '%s'\n", pkey_text, fkt_text, fkey_text);
row = (TupleNode *) malloc(sizeof(TupleNode) + (result_cols - 1) *sizeof(TupleField));
- mylog("pk_table_needed = '%s', pkey_ptr = '%s'\n", pk_table_needed, pkey_ptr);
+ mylog("pk_table_needed = '%s', pkey_ptr = '%s'\n", pk_table_needed, pkey_text);
set_tuplefield_null(&row->tuple[0]);
set_tuplefield_string(&row->tuple[1], "");
set_tuplefield_string(&row->tuple[2], pk_table_needed);
- set_tuplefield_string(&row->tuple[3], pkey_ptr);
+ set_tuplefield_string(&row->tuple[3], pkey_text);
- mylog("fk_table = '%s', fkey_ptr = '%s'\n", fk_table, fkey_ptr);
+ mylog("fk_table = '%s', fkey_ptr = '%s'\n", fkt_text, fkey_text);
set_tuplefield_null(&row->tuple[4]);
set_tuplefield_string(&row->tuple[5], "");
- set_tuplefield_string(&row->tuple[6], fk_table);
- set_tuplefield_string(&row->tuple[7], fkey_ptr);
+ set_tuplefield_string(&row->tuple[6], fkt_text);
+ set_tuplefield_string(&row->tuple[7], fkey_text);
set_tuplefield_int2(&row->tuple[8], (Int2) (k + 1));
@@ -3298,6 +3531,14 @@ PGAPI_ForeignKeys(
#endif /* ODBCVER >= 0x0300 */
QR_add_tuple(stmt->result, row);
+#ifdef MULTIBYTE
+ if (pkey_alloced)
+ free(pkey_text);
+ pkey_alloced = FALSE;
+ if (fkey_alloced)
+ free(fkey_text);
+ fkey_alloced = FALSE;
+#endif /* MULTIBYTE */
/* next primary/foreign key */
for (j = 0; j < 2; j++)
@@ -3306,6 +3547,11 @@ PGAPI_ForeignKeys(
fkey_ptr += strlen(fkey_ptr) + 1;
}
}
+#ifdef MULTIBYTE
+ if (fkt_alloced)
+ free(fkt_text);
+ fkt_alloced = FALSE;
+#endif /* MULTIBYTE */
result = PGAPI_Fetch(htbl_stmt);
}
}
@@ -3317,6 +3563,16 @@ PGAPI_ForeignKeys(
PGAPI_FreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR;
}
+#ifdef MULTIBYTE
+ if (pkt_alloced)
+ free(pkt_text);
+ if (pkey_alloced)
+ free(pkey_text);
+ if (fkt_alloced)
+ free(fkt_text);
+ if (fkey_alloced)
+ free(fkey_text);
+#endif /* MULTIBYTE */
PGAPI_FreeStmt(htbl_stmt, SQL_DROP);
diff --git a/src/interfaces/odbc/parse.c b/src/interfaces/odbc/parse.c
index eb0589e4c4b..f6254cae947 100644
--- a/src/interfaces/odbc/parse.c
+++ b/src/interfaces/odbc/parse.c
@@ -227,12 +227,17 @@ QR_set_field_info(stmt->result, 13, "FIELD_TYPE", PG_TYPE_INT4, 4);
void
getColInfo(COL_INFO *col_info, FIELD_INFO *fi, int k)
{
+ char *str;
if (fi->name[0] == '\0')
strcpy(fi->name, QR_get_value_manual(col_info->result, k, 3));
fi->type = atoi(QR_get_value_manual(col_info->result, k, 13));
fi->precision = atoi(QR_get_value_manual(col_info->result, k, 6));
fi->length = atoi(QR_get_value_manual(col_info->result, k, 7));
+ if (str = QR_get_value_manual(col_info->result, k, 8), str)
+ fi->scale = atoi(str);
+ else
+ fi->scale = -1;
fi->nullable = atoi(QR_get_value_manual(col_info->result, k, 10));
fi->display_size = atoi(QR_get_value_manual(col_info->result, k, 12));
}
diff --git a/src/interfaces/odbc/results.c b/src/interfaces/odbc/results.c
index 7d29fb0ce22..3cfe5fb74b1 100644
--- a/src/interfaces/odbc/results.c
+++ b/src/interfaces/odbc/results.c
@@ -199,7 +199,7 @@ PGAPI_DescribeCol(
QResultClass *res;
char *col_name = NULL;
Int4 fieldtype = 0;
- int precision = 0;
+ int precision = 0, scale = 0;
ConnInfo *ci;
char parse_ok;
char buf[255];
@@ -250,6 +250,7 @@ PGAPI_DescribeCol(
fieldtype = stmt->fi[icol]->type;
col_name = stmt->fi[icol]->name;
precision = stmt->fi[icol]->precision;
+ scale = stmt->fi[icol]->scale;
mylog("PARSE: fieldtype=%d, col_name='%s', precision=%d\n", fieldtype, col_name, precision);
if (fieldtype > 0)
@@ -292,6 +293,7 @@ PGAPI_DescribeCol(
/* atoi(ci->unknown_sizes) */
precision = pgtype_precision(stmt, fieldtype, icol, ci->drivers.unknown_sizes);
+ scale = pgtype_scale(stmt, fieldtype, icol);
}
mylog("describeCol: col %d fieldname = '%s'\n", icol, col_name);
@@ -348,10 +350,7 @@ PGAPI_DescribeCol(
*/
if (pibScale)
{
- Int2 scale;
-
- scale = pgtype_scale(stmt, fieldtype, icol);
- if (scale == -1)
+ if (scale < 0)
scale = 0;
*pibScale = scale;
diff --git a/src/interfaces/odbc/statement.h b/src/interfaces/odbc/statement.h
index bea157b1187..834eb005b3d 100644
--- a/src/interfaces/odbc/statement.h
+++ b/src/interfaces/odbc/statement.h
@@ -131,6 +131,7 @@ typedef struct
{
TABLE_INFO *ti; /* resolve to explicit table names */
int precision;
+ int scale;
int display_size;
int length;
int type;