OK, here is the ODBC patch I am holding. I will run pgindent after I
apply it to 7.2 branch to properly wrap the comments.
> Bruce Momjian <pgman@candle.pha.pa.us> writes:
> > I am working to clean up the comments in ODBC, and remove some blank
> > lines that make no sense being there. This will not affect the code in
> > any way. I should commit in a few hours.
>
> Is it really appropriate to be doing this sort of work post-RC1?
> I see no gain and a nontrivial risk that you will break something
> without knowing it (and without providing adequate time to test it).
>
> It's bad enough to be running pgindent at this late stage of the cycle,
> but at least pgindent is automated and relatively unlikely to make
> errors. Massive hand edits are another story.
>
> In short: save it for 7.2.
>
> regards, tom lane
>
> ---------------------------(end of broadcast)---------------------------
> TIP 2: you can get off all lists at once with the unregister command
> (send "unregister YourEmailAddressHere" to majordomo@postgresql.org)
>
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 853-3000
+ If your life is a hard drive, | 830 Blythe Avenue
+ Christ can be your backup. | Drexel Hill, Pennsylvania 19026
Index: src/interfaces/odbc/bind.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/bind.c,v
retrieving revision 1.23
diff -c -r1.23 bind.c
*** src/interfaces/odbc/bind.c 2001/03/27 04:00:53 1.23
--- src/interfaces/odbc/bind.c 2001/03/28 16:53:12
***************
*** 1,4 ****
! /* Module: bind.c
*
* Description: This module contains routines related to binding
* columns and parameters.
--- 1,5 ----
! /*-------
! * Module: bind.c
*
* Description: This module contains routines related to binding
* columns and parameters.
***************
*** 9,15 ****
* SQLParamOptions(NI)
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
#ifdef HAVE_CONFIG_H
--- 10,16 ----
* SQLParamOptions(NI)
*
* Comments: See "notice.txt" for copyright and license information.
! *-------
*/
#ifdef HAVE_CONFIG_H
***************
*** 112,119 ****
}
}
! ipar--; /* use zero based column numbers for the
! * below part */
/* store the given info */
stmt->parameters[ipar].buflen = cbValueMax;
--- 113,120 ----
}
}
! /* use zero based column numbers for the below part */
! ipar--;
/* store the given info */
stmt->parameters[ipar].buflen = cbValueMax;
***************
*** 152,161 ****
return SQL_SUCCESS;
}
-
- /* - - - - - - - - - */
! /* Associate a user-supplied buffer with a database column. */
RETCODE SQL_API
SQLBindCol(
HSTMT hstmt,
--- 153,160 ----
return SQL_SUCCESS;
}
! /* Associate a user-supplied buffer with a database column. */
RETCODE SQL_API
SQLBindCol(
HSTMT hstmt,
***************
*** 192,198 ****
/* If the bookmark column is being bound, then just save it */
if (icol == 0)
{
-
if (rgbValue == NULL)
{
stmt->bookmark.buffer = NULL;
--- 191,196 ----
***************
*** 215,224 ****
return SQL_SUCCESS;
}
! /* allocate enough bindings if not already done */
! /* Most likely, execution of a statement would have setup the */
! /* necessary bindings. But some apps call BindCol before any */
! /* statement is executed. */
if (icol > stmt->bindings_allocated)
extend_bindings(stmt, icol);
--- 213,224 ----
return SQL_SUCCESS;
}
! /*
! * Allocate enough bindings if not already done.
! * Most likely, execution of a statement would have setup the
! * necessary bindings. But some apps call BindCol before any
! * statement is executed.
! */
if (icol > stmt->bindings_allocated)
extend_bindings(stmt, icol);
***************
*** 231,238 ****
return SQL_ERROR;
}
! icol--; /* use zero based col numbers from here
! * out */
/* Reset for SQLGetData */
stmt->bindings[icol].data_left = -1;
--- 231,238 ----
return SQL_ERROR;
}
! /* use zero based col numbers from here out */
! icol--;
/* Reset for SQLGetData */
stmt->bindings[icol].data_left = -1;
***************
*** 259,272 ****
return SQL_SUCCESS;
}
- /* - - - - - - - - - */
! /* Returns the description of a parameter marker. */
! /* This function is listed as not being supported by SQLGetFunctions() because it is */
! /* used to describe "parameter markers" (not bound parameters), in which case, */
! /* the dbms should return info on the markers. Since Postgres doesn't support that, */
! /* it is best to say this function is not supported and let the application assume a */
! /* data type (most likely varchar). */
RETCODE SQL_API
SQLDescribeParam(
--- 259,273 ----
return SQL_SUCCESS;
}
! /*
! * Returns the description of a parameter marker.
! * This function is listed as not being supported by SQLGetFunctions() because it is
! * used to describe "parameter markers" (not bound parameters), in which case,
! * the dbms should return info on the markers. Since Postgres doesn't support that,
! * it is best to say this function is not supported and let the application assume a
! * data type (most likely varchar).
! */
RETCODE SQL_API
SQLDescribeParam(
***************
*** 318,327 ****
return SQL_SUCCESS;
}
! /* - - - - - - - - - */
- /* Sets multiple values (arrays) for the set of parameter markers. */
-
RETCODE SQL_API
SQLParamOptions(
HSTMT hstmt,
--- 319,326 ----
return SQL_SUCCESS;
}
! /* Sets multiple values (arrays) for the set of parameter markers. */
RETCODE SQL_API
SQLParamOptions(
HSTMT hstmt,
***************
*** 336,350 ****
return SQL_ERROR;
}
- /* - - - - - - - - - */
! /* This function should really talk to the dbms to determine the number of */
! /* "parameter markers" (not bound parameters) in the statement. But, since */
! /* Postgres doesn't support that, the driver should just count the number of markers */
! /* and return that. The reason the driver just can't say this function is unsupported */
! /* like it does for SQLDescribeParam is that some applications don't care and try */
! /* to call it anyway. */
! /* If the statement does not have parameters, it should just return 0. */
RETCODE SQL_API
SQLNumParams(
HSTMT hstmt,
--- 335,350 ----
return SQL_ERROR;
}
! /*
! * This function should really talk to the dbms to determine the number of
! * "parameter markers" (not bound parameters) in the statement. But, since
! * Postgres doesn't support that, the driver should just count the number of markers
! * and return that. The reason the driver just can't say this function is unsupported
! * like it does for SQLDescribeParam is that some applications don't care and try
! * to call it anyway.
! * If the statement does not have parameters, it should just return 0.
! */
RETCODE SQL_API
SQLNumParams(
HSTMT hstmt,
***************
*** 382,391 ****
}
else
{
-
for (i = 0; i < strlen(stmt->statement); i++)
{
-
if (stmt->statement[i] == '?' && !in_quote)
(*pcpar)++;
else
--- 382,389 ----
***************
*** 394,405 ****
in_quote = (in_quote ? FALSE : TRUE);
}
}
-
return SQL_SUCCESS;
}
}
! /********************************************************************
* Bindings Implementation
*/
BindInfoClass *
--- 392,402 ----
in_quote = (in_quote ? FALSE : TRUE);
}
}
return SQL_SUCCESS;
}
}
! /*
* Bindings Implementation
*/
BindInfoClass *
***************
*** 432,442 ****
mylog("%s: entering ... stmt=%u, bindings_allocated=%d, num_columns=%d\n", func, stmt, stmt->bindings_allocated,
num_columns);
! /* if we have too few, allocate room for more, and copy the old */
! /* entries into the new structure */
if (stmt->bindings_allocated < num_columns)
{
-
new_bindings = create_empty_bindings(num_columns);
if (!new_bindings)
{
--- 429,440 ----
mylog("%s: entering ... stmt=%u, bindings_allocated=%d, num_columns=%d\n", func, stmt, stmt->bindings_allocated,
num_columns);
! /*
! * if we have too few, allocate room for more, and copy the old
! * entries into the new structure
! */
if (stmt->bindings_allocated < num_columns)
{
new_bindings = create_empty_bindings(num_columns);
if (!new_bindings)
{
***************
*** 461,471 ****
stmt->bindings = new_bindings;
stmt->bindings_allocated = num_columns;
-
}
! /* There is no reason to zero out extra bindings if there are */
! /* more than needed. If an app has allocated extra bindings, */
! /* let it worry about it by unbinding those columns. */
/* SQLBindCol(1..) ... SQLBindCol(10...) # got 10 bindings */
/* SQLExecDirect(...) # returns 5 cols */
--- 459,470 ----
stmt->bindings = new_bindings;
stmt->bindings_allocated = num_columns;
}
! /*
! * There is no reason to zero out extra bindings if there are
! * more than needed. If an app has allocated extra bindings,
! * let it worry about it by unbinding those columns.
! */
/* SQLBindCol(1..) ... SQLBindCol(10...) # got 10 bindings */
/* SQLExecDirect(...) # returns 5 cols */
Index: src/interfaces/odbc/columninfo.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/columninfo.c,v
retrieving revision 1.18
diff -c -r1.18 columninfo.c
*** src/interfaces/odbc/columninfo.c 2001/03/27 04:00:53 1.18
--- src/interfaces/odbc/columninfo.c 2001/03/28 16:53:12
***************
*** 1,4 ****
! /* Module: columninfo.c
*
* Description: This module contains routines related to
* reading and storing the field information from a query.
--- 1,5 ----
! /*-------
! * Module: columninfo.c
*
* Description: This module contains routines related to
* reading and storing the field information from a query.
***************
*** 8,14 ****
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
#include "columninfo.h"
--- 9,15 ----
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *-------
*/
#include "columninfo.h"
***************
*** 45,54 ****
free(self);
}
! /* Read in field descriptions.
! If self is not null, then also store the information.
! If self is null, then just read, don't store.
! */
char
CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
{
--- 46,56 ----
free(self);
}
! /*
! * Read in field descriptions.
! * If self is not null, then also store the information.
! * If self is null, then just read, don't store.
! */
char
CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
{
***************
*** 77,83 ****
/* now read in the descriptions */
for (lf = 0; lf < new_num_fields; lf++)
{
-
SOCK_get_string(sock, new_field_name, MAX_MESSAGE_LEN);
new_adtid = (Oid) SOCK_get_int(sock, 4);
new_adtsize = (Int2) SOCK_get_int(sock, 2);
--- 79,84 ----
***************
*** 85,91 ****
/* If 6.4 protocol, then read the atttypmod field */
if (PG_VERSION_GE(conn, 6.4))
{
-
mylog("READING ATTTYPMOD\n");
new_atttypmod = (Int4) SOCK_get_int(sock, 4);
--- 86,91 ----
***************
*** 106,112 ****
}
-
void
CI_free_memory(ColumnInfoClass *self)
{
--- 106,111 ----
***************
*** 146,152 ****
CI_set_field_info(ColumnInfoClass *self, int field_num, char *new_name,
Oid new_adtid, Int2 new_adtsize, Int4 new_atttypmod)
{
-
/* check bounds */
if ((field_num < 0) || (field_num >= self->num_fields))
return;
--- 145,150 ----
Index: src/interfaces/odbc/connection.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/connection.c,v
retrieving revision 1.27
diff -c -r1.27 connection.c
*** src/interfaces/odbc/connection.c 2001/03/27 04:00:53 1.27
--- src/interfaces/odbc/connection.c 2001/03/28 16:53:13
***************
*** 1,4 ****
! /* Module: connection.c
*
* Description: This module contains routines related to
* connecting to and disconnecting from the Postgres DBMS.
--- 1,5 ----
! /*------
! * Module: connection.c
*
* Description: This module contains routines related to
* connecting to and disconnecting from the Postgres DBMS.
***************
*** 9,15 ****
* SQLBrowseConnect(NI)
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
/* Multibyte support Eiji Tokuya 2001-03-15 */
--- 10,16 ----
* SQLBrowseConnect(NI)
*
* Comments: See "notice.txt" for copyright and license information.
! *-------
*/
/* Multibyte support Eiji Tokuya 2001-03-15 */
***************
*** 83,90 ****
}
- /* - - - - - - - - - */
-
RETCODE SQL_API
SQLConnect(
HDBC hdbc,
--- 84,89 ----
***************
*** 140,146 ****
return SQL_SUCCESS;
}
- /* - - - - - - - - - */
RETCODE SQL_API
SQLBrowseConnect(
--- 139,144 ----
***************
*** 158,164 ****
return SQL_SUCCESS;
}
- /* - - - - - - - - - */
/* Drop any hstmts open on hdbc and disconnect from database */
RETCODE SQL_API
--- 156,161 ----
***************
*** 199,206 ****
}
- /* - - - - - - - - - */
-
RETCODE SQL_API
SQLFreeConnect(
HDBC hdbc)
--- 196,201 ----
***************
*** 235,244 ****
/*
! *
! * IMPLEMENTATION CONNECTION CLASS
! *
! */
ConnectionClass *
CC_Constructor()
--- 230,237 ----
/*
! * IMPLEMENTATION CONNECTION CLASS
! */
ConnectionClass *
CC_Constructor()
***************
*** 249,255 ****
if (rv != NULL)
{
-
rv->henv = NULL; /* not yet associated with an environment */
rv->errormsg = NULL;
--- 242,247 ----
***************
*** 301,307 ****
char
CC_Destructor(ConnectionClass *self)
{
-
mylog("enter CC_Destructor, self=%u\n", self);
if (self->status == CONN_EXECUTING)
--- 293,298 ----
***************
*** 373,380 ****
self->errormsg_created = FALSE;
}
! /* Used to cancel a transaction */
! /* We are almost always in the middle of a transaction. */
char
CC_abort(ConnectionClass *self)
{
--- 364,373 ----
self->errormsg_created = FALSE;
}
! /*
! * Used to cancel a transaction.
! * We are almost always in the middle of a transaction.
! */
char
CC_abort(ConnectionClass *self)
{
***************
*** 434,440 ****
stmt = self->stmts[i];
if (stmt)
{
-
stmt->hdbc = NULL; /* prevent any more dbase interactions */
SC_Destructor(stmt);
--- 427,432 ----
***************
*** 521,527 ****
else
{
-
qlog("Global Options: Version='%s', fetch=%d, socket=%d, unknown_sizes=%d, max_varchar_size=%d,
max_longvarchar_size=%d\n",
POSTGRESDRIVERVERSION,
globals.fetch_max,
--- 513,518 ----
***************
*** 646,659 ****
mylog("gonna do authentication\n");
! /* *************************************************** */
! /* Now get the authentication request from backend */
! /* *************************************************** */
if (!PROTOCOL_62(ci))
do
{
-
if (do_password)
beresp = 'R';
else
--- 637,649 ----
mylog("gonna do authentication\n");
! /*
! * Now get the authentication request from backend
! */
if (!PROTOCOL_62(ci))
do
{
if (do_password)
beresp = 'R';
else
***************
*** 743,750 ****
CC_clear_error(self); /* clear any password error */
! /* send an empty query in order to find out whether the specified */
! /* database really exists on the server machine */
mylog("sending an empty query...\n");
res = CC_send_query(self, " ", NULL);
--- 733,742 ----
CC_clear_error(self); /* clear any password error */
! /*
! * send an empty query in order to find out whether the specified
! * database really exists on the server machine
! */
mylog("sending an empty query...\n");
res = CC_send_query(self, " ", NULL);
***************
*** 764,772 ****
CC_set_translation(self);
! /**********************************************/
! /******* Send any initial settings *********/
! /**********************************************/
/*
* Since these functions allocate statements, and since the connection
--- 756,764 ----
CC_set_translation(self);
! /*
! * Send any initial settings
! */
/*
* Since these functions allocate statements, and since the connection
***************
*** 838,846 ****
return FALSE;
}
! /* Create a more informative error message by concatenating the connection
! error message with its socket error message.
! */
char *
CC_create_errormsg(ConnectionClass *self)
{
--- 830,839 ----
return FALSE;
}
! /*
! * Create a more informative error message by concatenating the connection
! * error message with its socket error message.
! */
char *
CC_create_errormsg(ConnectionClass *self)
{
***************
*** 897,910 ****
}
! /* The "result_in" is only used by QR_next_tuple() to fetch another group of rows into
! the same existing QResultClass (this occurs when the tuple cache is depleted and
! needs to be re-filled).
!
! The "cursor" is used by SQLExecute to associate a statement handle as the cursor name
! (i.e., C3326857) for SQL select statements. This cursor is then used in future
! 'declare cursor C3326857 for ...' and 'fetch 100 in C3326857' statements.
! */
QResultClass *
CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
{
--- 890,904 ----
}
! /*
! * The "result_in" is only used by QR_next_tuple() to fetch another group of rows into
! * the same existing QResultClass (this occurs when the tuple cache is depleted and
! * needs to be re-filled).
! *
! * The "cursor" is used by SQLExecute to associate a statement handle as the cursor name
! * (i.e., C3326857) for SQL select statements. This cursor is then used in future
! * 'declare cursor C3326857 for ...' and 'fetch 100 in C3326857' statements.
! */
QResultClass *
CC_send_query(ConnectionClass *self, char *query, QueryInfo *qi)
{
***************
*** 914,923 ****
int id;
SocketClass *sock = self->sock;
static char msgbuffer[MAX_MESSAGE_LEN + 1];
! char cmdbuffer[MAX_MESSAGE_LEN + 1]; /* QR_set_command() dups
! * this string so dont
! * need static */
!
mylog("send_query(): conn=%u, query='%s'\n", self, query);
qlog("conn=%u, query='%s'\n", self, query);
--- 908,915 ----
int id;
SocketClass *sock = self->sock;
static char msgbuffer[MAX_MESSAGE_LEN + 1];
! /* QR_set_command() dups this string so don't need static */
! char cmdbuffer[MAX_MESSAGE_LEN + 1];
mylog("send_query(): conn=%u, query='%s'\n", self, query);
qlog("conn=%u, query='%s'\n", self, query);
***************
*** 1003,1009 ****
}
else
{
-
char clear = 0;
mylog("send_query: ok - 'C' - %s\n", cmdbuffer);
--- 995,1000 ----
***************
*** 1239,1245 ****
for (i = 0; i < nargs; ++i)
{
-
mylog(" arg[%d]: len = %d, isint = %d, integer = %d, ptr = %u\n", i, args[i].len, args[i].isint,
args[i].u.integer,args[i].u.ptr);
SOCK_put_int(sock, args[i].len, 4);
--- 1230,1235 ----
***************
*** 1371,1379 ****
mylog("%s: entering...\n", func);
! /* This function must use the local odbc API functions since the odbc state
! has not transitioned to "connected" yet.
! */
result = SQLAllocStmt(self, &hstmt);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
--- 1361,1370 ----
mylog("%s: entering...\n", func);
! /*
! * This function must use the local odbc API functions since the odbc state
! * has not transitioned to "connected" yet.
! */
result = SQLAllocStmt(self, &hstmt);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
***************
*** 1455,1464 ****
return status;
}
! /* This function is just a hack to get the oid of our Large Object oid type.
! If a real Large Object oid type is made part of Postgres, this function
! will go away and the define 'PG_TYPE_LO' will be updated.
! */
void
CC_lookup_lo(ConnectionClass *self)
{
--- 1446,1456 ----
return status;
}
! /*
! * This function is just a hack to get the oid of our Large Object oid type.
! * If a real Large Object oid type is made part of Postgres, this function
! * will go away and the define 'PG_TYPE_LO' will be updated.
! */
void
CC_lookup_lo(ConnectionClass *self)
{
***************
*** 1469,1477 ****
mylog("%s: entering...\n", func);
! /* This function must use the local odbc API functions since the odbc state
! has not transitioned to "connected" yet.
! */
result = SQLAllocStmt(self, &hstmt);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
return;
--- 1461,1470 ----
mylog("%s: entering...\n", func);
! /*
! * This function must use the local odbc API functions since the odbc state
! * has not transitioned to "connected" yet.
! */
result = SQLAllocStmt(self, &hstmt);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
return;
***************
*** 1504,1513 ****
result = SQLFreeStmt(hstmt, SQL_DROP);
}
! /* This function initializes the version of PostgreSQL from
! connInfo.protocol that we're connected to.
! h-inoue 01-2-2001
! */
void
CC_initialize_pg_version(ConnectionClass *self)
{
--- 1497,1507 ----
result = SQLFreeStmt(hstmt, SQL_DROP);
}
! /*
! * This function initializes the version of PostgreSQL from
! * connInfo.protocol that we're connected to.
! * h-inoue 01-2-2001
! */
void
CC_initialize_pg_version(ConnectionClass *self)
{
***************
*** 1532,1541 ****
}
}
! /* This function gets the version of PostgreSQL that we're connected to.
! This is used to return the correct info in SQLGetInfo
! DJP - 25-1-2001
! */
void
CC_lookup_pg_version(ConnectionClass *self)
{
--- 1526,1536 ----
}
}
! /*
! * This function gets the version of PostgreSQL that we're connected to.
! * This is used to return the correct info in SQLGetInfo
! * DJP - 25-1-2001
! */
void
CC_lookup_pg_version(ConnectionClass *self)
{
***************
*** 1549,1557 ****
mylog("%s: entering...\n", func);
! /* This function must use the local odbc API functions since the odbc state
! has not transitioned to "connected" yet.
! */
result = SQLAllocStmt(self, &hstmt);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
return;
--- 1544,1553 ----
mylog("%s: entering...\n", func);
! /*
! * This function must use the local odbc API functions since the odbc state
! * has not transitioned to "connected" yet.
! */
result = SQLAllocStmt(self, &hstmt);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
return;
***************
*** 1579,1586 ****
return;
}
! /* Extract the Major and Minor numbers from the string. */
! /* This assumes the string starts 'Postgresql X.X' */
strcpy(szVersion, "0.0");
if (sscanf(self->pg_version, "%*s %d.%d", &major, &minor) >= 2)
{
--- 1575,1584 ----
return;
}
! /*
! * Extract the Major and Minor numbers from the string.
! * This assumes the string starts 'Postgresql X.X'
! */
strcpy(szVersion, "0.0");
if (sscanf(self->pg_version, "%*s %d.%d", &major, &minor) >= 2)
{
Index: src/interfaces/odbc/convert.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/convert.c,v
retrieving revision 1.35
diff -c -r1.35 convert.c
*** src/interfaces/odbc/convert.c 2001/03/27 04:00:53 1.35
--- src/interfaces/odbc/convert.c 2001/03/28 16:53:14
***************
*** 1,4 ****
! /* Module: convert.c
*
* Description: This module contains routines related to
* converting parameters and columns into requested data types.
--- 1,5 ----
! /*-------
! * Module: convert.c
*
* Description: This module contains routines related to
* converting parameters and columns into requested data types.
***************
*** 12,18 ****
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
/* Multibyte support Eiji Tokuya 2001-03-15 */
--- 13,19 ----
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *-------
*/
/* Multibyte support Eiji Tokuya 2001-03-15 */
***************
*** 63,73 ****
extern GLOBAL_VALUES globals;
! /* How to map ODBC scalar functions {fn func(args)} to Postgres
! * This is just a simple substitution
! * List augmented from
! * http://www.merant.com/datadirect/download/docs/odbc16/Odbcref/rappc.htm
! * - thomas 2000-04-03
*/
char *mapFuncs[][2] = {
/* { "ASCII", "ascii" }, */
--- 64,74 ----
extern GLOBAL_VALUES globals;
! /*
! * How to map ODBC scalar functions {fn func(args)} to Postgres.
! * This is just a simple substitution. List augmented from:
! * http://www.merant.com/datadirect/download/docs/odbc16/Odbcref/rappc.htm
! * - thomas 2000-04-03
*/
char *mapFuncs[][2] = {
/* { "ASCII", "ascii" }, */
***************
*** 140,160 ****
unsigned int conv_from_hex(unsigned char *s);
char *conv_to_octal(unsigned char val);
! /******** A Guide for date/time/timestamp conversions **************
- field_type fCType Output
- ---------- ------ ----------
- PG_TYPE_DATE SQL_C_DEFAULT SQL_C_DATE
- PG_TYPE_DATE SQL_C_DATE SQL_C_DATE
- PG_TYPE_DATE SQL_C_TIMESTAMP SQL_C_TIMESTAMP (time = 0 (midnight))
- PG_TYPE_TIME SQL_C_DEFAULT SQL_C_TIME
- PG_TYPE_TIME SQL_C_TIME SQL_C_TIME
- PG_TYPE_TIME SQL_C_TIMESTAMP SQL_C_TIMESTAMP (date = current date)
- PG_TYPE_ABSTIME SQL_C_DEFAULT SQL_C_TIMESTAMP
- PG_TYPE_ABSTIME SQL_C_DATE SQL_C_DATE (time is truncated)
- PG_TYPE_ABSTIME SQL_C_TIME SQL_C_TIME (date is truncated)
- PG_TYPE_ABSTIME SQL_C_TIMESTAMP SQL_C_TIMESTAMP
- ******************************************************************************/
/* This is called by SQLFetch() */
--- 141,164 ----
unsigned int conv_from_hex(unsigned char *s);
char *conv_to_octal(unsigned char val);
! /*---------
! * A Guide for date/time/timestamp conversions
! *
! * field_type fCType Output
! * ---------- ------ ----------
! * PG_TYPE_DATE SQL_C_DEFAULT SQL_C_DATE
! * PG_TYPE_DATE SQL_C_DATE SQL_C_DATE
! * PG_TYPE_DATE SQL_C_TIMESTAMP SQL_C_TIMESTAMP (time = 0 (midnight))
! * PG_TYPE_TIME SQL_C_DEFAULT SQL_C_TIME
! * PG_TYPE_TIME SQL_C_TIME SQL_C_TIME
! * PG_TYPE_TIME SQL_C_TIMESTAMP SQL_C_TIMESTAMP (date = current date)
! * PG_TYPE_ABSTIME SQL_C_DEFAULT SQL_C_TIMESTAMP
! * PG_TYPE_ABSTIME SQL_C_DATE SQL_C_DATE (time is truncated)
! * PG_TYPE_ABSTIME SQL_C_TIME SQL_C_TIME (date is truncated)
! * PG_TYPE_ABSTIME SQL_C_TIMESTAMP SQL_C_TIMESTAMP
! *---------
! */
/* This is called by SQLFetch() */
***************
*** 186,202 ****
int result = COPY_OK;
char tempBuf[TEXT_FIELD_SIZE + 5];
! /* rgbValueOffset is *ONLY* for character and binary data */
! /* pcbValueOffset is for computing any pcbValue location */
if (bind_size > 0)
{
-
pcbValueOffset = rgbValueOffset = (bind_size * bind_row);
}
else
{
-
pcbValueOffset = bind_row * sizeof(SDWORD);
rgbValueOffset = bind_row * cbValueMax;
--- 190,207 ----
int result = COPY_OK;
char tempBuf[TEXT_FIELD_SIZE + 5];
! /*---------
! * rgbValueOffset is *ONLY* for character and binary data.
! * pcbValueOffset is for computing any pcbValue location
! *---------
! */
if (bind_size > 0)
{
pcbValueOffset = rgbValueOffset = (bind_size * bind_row);
}
else
{
pcbValueOffset = bind_row * sizeof(SDWORD);
rgbValueOffset = bind_row * cbValueMax;
***************
*** 214,227 ****
if (!value)
{
! /* handle a null just by returning SQL_NULL_DATA in pcbValue, */
! /* and doing nothing to the buffer. */
if (pcbValue)
*(SDWORD *) ((char *) pcbValue + pcbValueOffset) = SQL_NULL_DATA;
return COPY_OK;
}
-
if (stmt->hdbc->DataSourceToDriver != NULL)
{
int length = strlen(value);
--- 219,233 ----
if (!value)
{
! /*
! * handle a null just by returning SQL_NULL_DATA in pcbValue,
! * and doing nothing to the buffer.
! */
if (pcbValue)
*(SDWORD *) ((char *) pcbValue + pcbValueOffset) = SQL_NULL_DATA;
return COPY_OK;
}
if (stmt->hdbc->DataSourceToDriver != NULL)
{
int length = strlen(value);
***************
*** 233,253 ****
NULL, 0, NULL);
}
!
! /********************************************************************
! First convert any specific postgres types into more
! useable data.
!
! NOTE: Conversions from PG char/varchar of a date/time/timestamp
! value to SQL_C_DATE,SQL_C_TIME, SQL_C_TIMESTAMP not supported
! *********************************************************************/
switch (field_type)
{
!
! /*
! * $$$ need to add parsing for date/time/timestamp strings in
! * PG_TYPE_CHAR,VARCHAR $$$
! */
case PG_TYPE_DATE:
sscanf(value, "%4d-%2d-%2d", &st.y, &st.m, &st.d);
break;
--- 239,257 ----
NULL, 0, NULL);
}
! /*
! * First convert any specific postgres types into more
! * useable data.
! *
! * NOTE: Conversions from PG char/varchar of a date/time/timestamp
! * value to SQL_C_DATE,SQL_C_TIME, SQL_C_TIMESTAMP not supported
! */
switch (field_type)
{
! /*
! * $$$ need to add parsing for date/time/timestamp strings in
! * PG_TYPE_CHAR,VARCHAR $$$
! */
case PG_TYPE_DATE:
sscanf(value, "%4d-%2d-%2d", &st.y, &st.m, &st.d);
break;
***************
*** 260,272 ****
case PG_TYPE_DATETIME:
case PG_TYPE_TIMESTAMP:
if (strnicmp(value, "invalid", 7) != 0)
- {
sscanf(value, "%4d-%2d-%2d %2d:%2d:%2d", &st.y, &st.m, &st.d, &st.hh, &st.mm, &st.ss);
-
- }
else
! { /* The timestamp is invalid so set
! * something conspicuous, like the epoch */
t = 0;
tim = localtime(&t);
st.m = tim->tm_mon + 1;
--- 264,276 ----
case PG_TYPE_DATETIME:
case PG_TYPE_TIMESTAMP:
if (strnicmp(value, "invalid", 7) != 0)
sscanf(value, "%4d-%2d-%2d %2d:%2d:%2d", &st.y, &st.m, &st.d, &st.hh, &st.mm, &st.ss);
else
! {
! /*
! * The timestamp is invalid so set
! * something conspicuous, like the epoch
! */
t = 0;
tim = localtime(&t);
st.m = tim->tm_mon + 1;
***************
*** 289,295 ****
}
break;
! /* This is for internal use by SQLStatistics() */
case PG_TYPE_INT2VECTOR:
{
int nval,
--- 293,299 ----
}
break;
! /* This is for internal use by SQLStatistics() */
case PG_TYPE_INT2VECTOR:
{
int nval,
***************
*** 368,382 ****
mylog("copy_and_convert, SQL_C_DEFAULT: fCType = %d\n", fCType);
}
-
rgbValueBindRow = (char *) rgbValue + rgbValueOffset;
if (fCType == SQL_C_CHAR)
{
-
-
/* Special character formatting as required */
-
/*
* These really should return error if cbValueMax is not big
* enough.
--- 372,382 ----
***************
*** 455,461 ****
if (cbValueMax > 0)
{
-
copy_len = (len >= cbValueMax) ? cbValueMax - 1 : len;
/* Copy the data */
--- 455,460 ----
***************
*** 482,488 ****
}
else
{
-
/*
* for SQL_C_CHAR, it's probably ok to leave currency symbols in.
* But to convert to numeric types, it is necessary to get rid of
--- 481,486 ----
***************
*** 632,638 ****
if (stmt->current_col >= 0)
{
-
/* No more data left for this column */
if (stmt->bindings[stmt->current_col].data_left == 0)
return COPY_NO_DATA_FOUND;
--- 630,635 ----
***************
*** 689,698 ****
}
! /* This function inserts parameters into an SQL statements.
! It will also modify a SELECT statement for use with declare/fetch cursors.
! This function no longer does any dynamic memory allocation!
! */
int
copy_statement_with_parameters(StatementClass *stmt)
{
--- 686,696 ----
}
! /*
! * This function inserts parameters into an SQL statements.
! * It will also modify a SELECT statement for use with declare/fetch cursors.
! * This function no longer does any dynamic memory allocation!
! */
int
copy_statement_with_parameters(StatementClass *stmt)
{
***************
*** 759,765 ****
for (opos = 0; opos < oldstmtlen; opos++)
{
-
/* Squeeze carriage-return/linefeed pairs to linefeed only */
if (old_statement[opos] == '\r' && opos + 1 < oldstmtlen &&
old_statement[opos + 1] == '\n')
--- 757,762 ----
***************
*** 781,790 ****
#ifdef MULTIBYTE
char *end = multibyte_strchr(begin, '}');
-
#else
char *end = strchr(begin, '}');
-
#endif
if (!end)
--- 778,785 ----
***************
*** 806,817 ****
}
opos += end - begin + 1;
-
*end = '}';
-
continue;
}
-
/*
* Can you have parameter markers inside of quotes? I dont think
* so. All the queries I've seen expect the driver to put quotes
--- 801,809 ----
***************
*** 827,839 ****
new_statement[npos++] = old_statement[opos];
continue;
}
-
-
! /****************************************************/
! /* Its a '?' parameter alright */
! /****************************************************/
!
param_number++;
if (param_number >= stmt->parameters_allocated)
--- 819,828 ----
new_statement[npos++] = old_statement[opos];
continue;
}
! /*
! * Its a '?' parameter alright
! */
param_number++;
if (param_number >= stmt->parameters_allocated)
***************
*** 882,888 ****
param_string[0] = '\0';
cbuf[0] = '\0';
-
/* Convert input C type to a neutral format */
switch (param_ctype)
{
--- 871,876 ----
***************
*** 1089,1101 ****
if (stmt->parameters[param_number].data_at_exec)
{
-
lobj_oid = stmt->parameters[param_number].lobj_oid;
-
}
else
{
-
/* begin transaction if needed */
if (!CC_is_in_trans(stmt->hdbc))
{
--- 1077,1086 ----
***************
*** 1240,1254 ****
new_statement[npos++] = '\''; /* Close Quote */
break;
-
}
-
} /* end, for */
/* make sure new_statement is always null-terminated */
new_statement[npos] = '\0';
-
if (stmt->hdbc->DriverToDataSource != NULL)
{
int length = strlen(new_statement);
--- 1225,1236 ----
***************
*** 1260,1266 ****
NULL, 0, NULL);
}
-
return SQL_SUCCESS;
}
--- 1242,1247 ----
***************
*** 1276,1282 ****
return NULL;
}
! /* convert_escape()
* This function returns a pointer to static memory!
*/
char *
--- 1257,1265 ----
return NULL;
}
! /*
! * convert_escape()
! *
* This function returns a pointer to static memory!
*/
char *
***************
*** 1305,1311 ****
}
else if (strcmp(key, "fn") == 0)
{
-
/*
* Function invocation Separate off the func name, skipping
* trailing whitespace.
--- 1288,1293 ----
***************
*** 1356,1362 ****
}
return escape;
-
}
--- 1338,1343 ----
***************
*** 1381,1388 ****
! /* This function parses a character string for date/time info and fills in SIMPLE_TIME */
! /* It does not zero out SIMPLE_TIME in case it is desired to initialize it with a value */
char
parse_datetime(char *buf, SIMPLE_TIME *st)
{
--- 1362,1371 ----
! /*
! * This function parses a character string for date/time info and fills in SIMPLE_TIME
! * It does not zero out SIMPLE_TIME in case it is desired to initialize it with a value
! */
char
parse_datetime(char *buf, SIMPLE_TIME *st)
{
***************
*** 1468,1476 ****
return out;
}
! /* Change carriage-return/linefeed to just linefeed
! Plus, escape any special characters.
! */
char *
convert_special_chars(char *si, char *dst, int used)
{
--- 1451,1460 ----
return out;
}
! /*
! * Change carriage-return/linefeed to just linefeed
! * Plus, escape any special characters.
! */
char *
convert_special_chars(char *si, char *dst, int used)
{
***************
*** 1544,1550 ****
for (i = 1; i <= 2; i++)
{
-
if (s[i] >= 'a' && s[i] <= 'f')
val = s[i] - 'a' + 10;
else if (s[i] >= 'A' && s[i] <= 'F')
--- 1528,1533 ----
***************
*** 1611,1617 ****
int i,
o = 0;
-
for (i = 0; i < len; i++)
{
mylog("convert_to_pgbinary: in[%d] = %d, %c\n", i, in[i], in[i]);
--- 1594,1599 ----
***************
*** 1622,1628 ****
strcpy(&out[o], conv_to_octal(in[i]));
o += 5;
}
-
}
mylog("convert_to_pgbinary: returning %d, out='%.*s'\n", o, o, out);
--- 1604,1609 ----
***************
*** 1679,1700 ****
out[o++] = '\0';
}
-
! /* 1. get oid (from 'value')
! 2. open the large object
! 3. read from the large object (handle multiple GetData)
! 4. close when read less than requested? -OR-
! lseek/read each time
! handle case where application receives truncated and
! decides not to continue reading.
!
! CURRENTLY, ONLY LONGVARBINARY is handled, since that is the only
! data type currently mapped to a PG_TYPE_LO. But, if any other types
! are desired to map to a large object (PG_TYPE_LO), then that would
! need to be handled here. For example, LONGVARCHAR could possibly be
! mapped to PG_TYPE_LO someday, instead of PG_TYPE_TEXT as it is now.
! */
int
convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
SDWORD cbValueMax, SDWORD *pcbValue)
--- 1660,1682 ----
out[o++] = '\0';
}
! /*-------
! * 1. get oid (from 'value')
! * 2. open the large object
! * 3. read from the large object (handle multiple GetData)
! * 4. close when read less than requested? -OR-
! * lseek/read each time
! * handle case where application receives truncated and
! * decides not to continue reading.
! *
! * CURRENTLY, ONLY LONGVARBINARY is handled, since that is the only
! * data type currently mapped to a PG_TYPE_LO. But, if any other types
! * are desired to map to a large object (PG_TYPE_LO), then that would
! * need to be handled here. For example, LONGVARCHAR could possibly be
! * mapped to PG_TYPE_LO someday, instead of PG_TYPE_TEXT as it is now.
! *-------
! */
int
convert_lo(StatementClass *stmt, void *value, Int2 fCType, PTR rgbValue,
SDWORD cbValueMax, SDWORD *pcbValue)
***************
*** 1706,1712 ****
BindInfoClass *bindInfo = NULL;
! /* If using SQLGetData, then current_col will be set */
if (stmt->current_col >= 0)
{
bindInfo = &stmt->bindings[stmt->current_col];
--- 1688,1694 ----
BindInfoClass *bindInfo = NULL;
! /* If using SQLGetData, then current_col will be set */
if (stmt->current_col >= 0)
{
bindInfo = &stmt->bindings[stmt->current_col];
***************
*** 1720,1726 ****
if (!bindInfo || bindInfo->data_left == -1)
{
-
/* begin transaction if needed */
if (!CC_is_in_trans(stmt->hdbc))
{
--- 1702,1707 ----
***************
*** 1759,1765 ****
retval = lo_lseek(stmt->hdbc, stmt->lobj_fd, 0L, SEEK_END);
if (retval >= 0)
{
-
left = lo_tell(stmt->hdbc, stmt->lobj_fd);
if (bindInfo)
bindInfo->data_left = left;
--- 1740,1745 ----
***************
*** 1824,1834 ****
if (pcbValue)
*pcbValue = left < 0 ? SQL_NO_TOTAL : left;
-
if (bindInfo && bindInfo->data_left > 0)
bindInfo->data_left -= retval;
-
if (!bindInfo || bindInfo->data_left == 0)
{
lo_close(stmt->hdbc, stmt->lobj_fd);
--- 1804,1812 ----
***************
*** 1861,1867 ****
stmt->lobj_fd = -1; /* prevent further reading */
}
-
return result;
-
}
--- 1839,1843 ----
Index: src/interfaces/odbc/dlg_specific.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/dlg_specific.c,v
retrieving revision 1.28
diff -c -r1.28 dlg_specific.c
*** src/interfaces/odbc/dlg_specific.c 2001/03/27 04:00:53 1.28
--- src/interfaces/odbc/dlg_specific.c 2001/03/28 16:53:14
***************
*** 1,4 ****
! /* Module: dlg_specific.c
*
* Description: This module contains any specific code for handling
* dialog boxes such as driver/datasource options. Both the
--- 1,5 ----
! /*-------
! * Module: dlg_specific.c
*
* Description: This module contains any specific code for handling
* dialog boxes such as driver/datasource options. Both the
***************
*** 12,18 ****
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
/* Multibyte support Eiji Tokuya 2001-03-15 */
--- 13,19 ----
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *-------
*/
/* Multibyte support Eiji Tokuya 2001-03-15 */
***************
*** 54,60 ****
void
SetDlgStuff(HWND hdlg, ConnInfo *ci)
{
-
/*
* If driver attribute NOT present, then set the datasource name and
* description
--- 55,60 ----
***************
*** 85,91 ****
}
-
int CALLBACK
driver_optionsProc(HWND hdlg,
WORD wMsg,
--- 85,90 ----
***************
*** 141,147 ****
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case IDOK:
-
globals.commlog = IsDlgButtonChecked(hdlg, DRV_COMMLOG);
globals.disable_optimizer = IsDlgButtonChecked(hdlg, DRV_OPTIMIZER);
globals.ksqo = IsDlgButtonChecked(hdlg, DRV_KSQO);
--- 140,145 ----
***************
*** 228,234 ****
break;
}
-
}
return FALSE;
--- 226,231 ----
***************
*** 267,277 ****
else if (strncmp(ci->protocol, PG63, strlen(PG63)) == 0)
CheckDlgButton(hdlg, DS_PG63, 1);
else
! /* latest */
CheckDlgButton(hdlg, DS_PG64, 1);
!
!
!
CheckDlgButton(hdlg, DS_SHOWOIDCOLUMN, atoi(ci->show_oid_column));
CheckDlgButton(hdlg, DS_FAKEOIDINDEX, atoi(ci->fake_oid_index));
CheckDlgButton(hdlg, DS_ROWVERSIONING, atoi(ci->row_versioning));
--- 264,272 ----
else if (strncmp(ci->protocol, PG63, strlen(PG63)) == 0)
CheckDlgButton(hdlg, DS_PG63, 1);
else
! /* latest */
CheckDlgButton(hdlg, DS_PG64, 1);
!
CheckDlgButton(hdlg, DS_SHOWOIDCOLUMN, atoi(ci->show_oid_column));
CheckDlgButton(hdlg, DS_FAKEOIDINDEX, atoi(ci->fake_oid_index));
CheckDlgButton(hdlg, DS_ROWVERSIONING, atoi(ci->row_versioning));
***************
*** 283,289 ****
SetDlgItemText(hdlg, DS_CONNSETTINGS, ci->conn_settings);
break;
-
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
--- 278,283 ----
***************
*** 292,300 ****
EnableWindow(GetDlgItem(hdlg, DS_FAKEOIDINDEX), IsDlgButtonChecked(hdlg, DS_SHOWOIDCOLUMN));
return TRUE;
-
case IDOK:
-
ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
mylog("IDOK: got ci = %u\n", ci);
--- 286,292 ----
***************
*** 307,313 ****
else if (IsDlgButtonChecked(hdlg, DS_PG63))
strcpy(ci->protocol, PG63);
else
! /* latest */
strcpy(ci->protocol, PG64);
sprintf(ci->show_system_tables, "%d", IsDlgButtonChecked(hdlg, DS_SHOWSYSTEMTABLES));
--- 299,305 ----
else if (IsDlgButtonChecked(hdlg, DS_PG63))
strcpy(ci->protocol, PG63);
else
! /* latest */
strcpy(ci->protocol, PG64);
sprintf(ci->show_system_tables, "%d", IsDlgButtonChecked(hdlg, DS_SHOWSYSTEMTABLES));
***************
*** 321,327 ****
/* Datasource Connection Settings */
GetDlgItemText(hdlg, DS_CONNSETTINGS, ci->conn_settings, sizeof(ci->conn_settings));
-
/* fall through */
case IDCANCEL:
--- 313,318 ----
***************
*** 368,374 ****
void
copyAttributes(ConnInfo *ci, char *attribute, char *value)
{
-
if (stricmp(attribute, "DSN") == 0)
strcpy(ci->dsn, value);
--- 359,364 ----
***************
*** 415,421 ****
}
mylog("copyAttributes:
DSN='%s',server='%s',dbase='%s',user='%s',passwd='%s',port='%s',onlyread='%s',protocol='%s',conn_settings='%s')\n",
ci->dsn,ci->server, ci->database, ci->username, ci->password, ci->port, ci->onlyread, ci->protocol, ci->conn_settings);
-
}
void
--- 405,410 ----
***************
*** 450,457 ****
char *DSN = ci->dsn;
char encoded_conn_settings[LARGE_REGISTRY_LEN];
! /* If a driver keyword was present, then dont use a DSN and return. */
! /* If DSN is null and no driver, then use the default datasource. */
if (DSN[0] == '\0')
{
if (ci->driver[0] != '\0')
--- 439,448 ----
char *DSN = ci->dsn;
char encoded_conn_settings[LARGE_REGISTRY_LEN];
! /*
! * If a driver keyword was present, then dont use a DSN and return.
! * If DSN is null and no driver, then use the default datasource.
! */
if (DSN[0] == '\0')
{
if (ci->driver[0] != '\0')
***************
*** 514,524 ****
if (ci->translation_option[0] == '\0' || overwrite)
SQLGetPrivateProfileString(DSN, INI_TRANSLATIONOPTION, "", ci->translation_option,
sizeof(ci->translation_option),ODBC_INI);
-
/* Allow override of odbcinst.ini parameters here */
getGlobalDefaults(DSN, ODBC_INI, TRUE);
-
qlog("DSN info: DSN='%s',server='%s',port='%s',dbase='%s',user='%s',passwd='%s'\n",
DSN,
ci->server,
--- 505,513 ----
***************
*** 546,552 ****
qlog(" translation_dll='%s',translation_option='%s'\n",
ci->translation_dll,
ci->translation_option);
-
}
--- 535,540 ----
***************
*** 626,640 ****
}
! /* This function reads the ODBCINST.INI portion of
! the registry and gets any driver defaults.
! */
void
getGlobalDefaults(char *section, char *filename, char override)
{
char temp[256];
-
/* Fetch Count is stored in driver section */
SQLGetPrivateProfileString(section, INI_FETCH, "",
temp, sizeof(temp), filename);
--- 614,628 ----
}
! /*
! * This function reads the ODBCINST.INI portion of
! * the registry and gets any driver defaults.
! */
void
getGlobalDefaults(char *section, char *filename, char override)
{
char temp[256];
/* Fetch Count is stored in driver section */
SQLGetPrivateProfileString(section, INI_FETCH, "",
temp, sizeof(temp), filename);
***************
*** 648,654 ****
else if (!override)
globals.fetch_max = FETCH_MAX;
-
/* Socket Buffersize is stored in driver section */
SQLGetPrivateProfileString(section, INI_SOCKET, "",
temp, sizeof(temp), filename);
--- 636,641 ----
***************
*** 657,663 ****
else if (!override)
globals.socket_buffersize = SOCK_BUFFER_SIZE;
-
/* Debug is stored in the driver section */
SQLGetPrivateProfileString(section, INI_DEBUG, "",
temp, sizeof(temp), filename);
--- 644,649 ----
***************
*** 666,672 ****
else if (!override)
globals.debug = DEFAULT_DEBUG;
-
/* CommLog is stored in the driver section */
SQLGetPrivateProfileString(section, INI_COMMLOG, "",
temp, sizeof(temp), filename);
--- 652,657 ----
***************
*** 675,681 ****
else if (!override)
globals.commlog = DEFAULT_COMMLOG;
-
/* Optimizer is stored in the driver section only */
SQLGetPrivateProfileString(section, INI_OPTIMIZER, "",
temp, sizeof(temp), filename);
--- 660,665 ----
***************
*** 734,741 ****
else if (!override)
globals.cancel_as_freestmt = DEFAULT_CANCELASFREESTMT;
-
-
/* UseDeclareFetch is stored in the driver section only */
SQLGetPrivateProfileString(section, INI_USEDECLAREFETCH, "",
temp, sizeof(temp), filename);
--- 718,723 ----
***************
*** 744,750 ****
else if (!override)
globals.use_declarefetch = DEFAULT_USEDECLAREFETCH;
-
/* Max Varchar Size */
SQLGetPrivateProfileString(section, INI_MAXVARCHARSIZE, "",
temp, sizeof(temp), filename);
--- 726,731 ----
***************
*** 804,810 ****
/* Dont allow override of an override! */
if (!override)
{
-
/*
* ConnSettings is stored in the driver section and per datasource
* for override
--- 785,790 ----
***************
*** 831,844 ****
strcpy(globals.protocol, temp);
else
strcpy(globals.protocol, DEFAULT_PROTOCOL);
-
}
}
! /* This function writes any global parameters (that can be manipulated)
! to the ODBCINST.INI portion of the registry
! */
void
updateGlobals(void)
{
--- 811,824 ----
strcpy(globals.protocol, temp);
else
strcpy(globals.protocol, DEFAULT_PROTOCOL);
}
}
! /*
! * This function writes any global parameters (that can be manipulated)
! * to the ODBCINST.INI portion of the registry
! */
void
updateGlobals(void)
{
Index: src/interfaces/odbc/drvconn.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/drvconn.c,v
retrieving revision 1.22
diff -c -r1.22 drvconn.c
*** src/interfaces/odbc/drvconn.c 2001/03/27 04:00:53 1.22
--- src/interfaces/odbc/drvconn.c 2001/03/28 16:53:15
***************
*** 1,4 ****
! /* Module: drvconn.c
*
* Description: This module contains only routines related to
* implementing SQLDriverConnect.
--- 1,5 ----
! /*-------
! * Module: drvconn.c
*
* Description: This module contains only routines related to
* implementing SQLDriverConnect.
***************
*** 8,14 ****
* API functions: SQLDriverConnect
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
#ifdef HAVE_CONFIG_H
--- 9,15 ----
* API functions: SQLDriverConnect
*
* Comments: See "notice.txt" for copyright and license information.
! *-------
*/
#ifdef HAVE_CONFIG_H
***************
*** 110,118 ****
/* Parse the connect string and fill in conninfo for this hdbc. */
dconn_get_connect_attributes(connStrIn, ci);
! /* If the ConnInfo in the hdbc is missing anything, */
! /* this function will fill them in from the registry (assuming */
! /* of course there is a DSN given -- if not, it does nothing!) */
getDSNinfo(ci, CONN_DONT_OVERWRITE);
/* Fill in any default parameters if they are not there. */
--- 111,121 ----
/* Parse the connect string and fill in conninfo for this hdbc. */
dconn_get_connect_attributes(connStrIn, ci);
! /*
! * If the ConnInfo in the hdbc is missing anything,
! * this function will fill them in from the registry (assuming
! * of course there is a DSN given -- if not, it does nothing!)
! */
getDSNinfo(ci, CONN_DONT_OVERWRITE);
/* Fill in any default parameters if they are not there. */
***************
*** 147,153 ****
ci->port[0] == '\0' ||
password_required)
{
-
dialog_result = dconn_DoDialog(hwnd, ci);
if (dialog_result != SQL_SUCCESS)
return dialog_result;
--- 150,155 ----
***************
*** 173,184 ****
ci->database[0] == '\0' ||
ci->port[0] == '\0')
{
! /* (password_required && ci->password[0] == '\0')) */
return SQL_NO_DATA_FOUND;
}
-
/* do the actual connect */
retval = CC_connect(conn, password_required);
if (retval < 0)
--- 175,185 ----
ci->database[0] == '\0' ||
ci->port[0] == '\0')
{
! /* (password_required && ci->password[0] == '\0')) */
return SQL_NO_DATA_FOUND;
}
/* do the actual connect */
retval = CC_connect(conn, password_required);
if (retval < 0)
***************
*** 206,214 ****
return SQL_ERROR;
}
! /*********************************************/
! /* Create the Output Connection String */
! /*********************************************/
result = SQL_SUCCESS;
makeConnectString(connStrOut, ci);
--- 207,215 ----
return SQL_ERROR;
}
! /*
! * Create the Output Connection String
! */
result = SQL_SUCCESS;
makeConnectString(connStrOut, ci);
***************
*** 216,222 ****
if (szConnStrOut)
{
-
/*
* Return the completed string to the caller. The correct method
* is to only construct the connect string if a dialog was put up,
--- 217,222 ----
***************
*** 296,302 ****
SetWindowLong(hdlg, DWL_USER, lParam); /* Save the ConnInfo for
* the "OK" */
-
SetDlgStuff(hdlg, ci);
if (ci->database[0] == '\0')
--- 296,301 ----
***************
*** 309,346 ****
SetFocus(GetDlgItem(hdlg, IDC_USER));
else if (ci->focus_password)
SetFocus(GetDlgItem(hdlg, IDC_PASSWORD));
-
-
break;
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
case IDOK:
-
ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
GetDlgStuff(hdlg, ci);
-
case IDCANCEL:
EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
return TRUE;
case IDC_DRIVER:
-
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
hdlg, driver_optionsProc, (LPARAM) NULL);
-
-
break;
case IDC_DATASOURCE:
-
ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
hdlg, ds_optionsProc, (LPARAM) ci);
-
break;
}
}
--- 308,336 ----
***************
*** 392,398 ****
copyAttributes(ci, attribute, value);
}
-
free(our_connect_string);
}
--- 382,387 ----
Index: src/interfaces/odbc/environ.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/environ.c,v
retrieving revision 1.24
diff -c -r1.24 environ.c
*** src/interfaces/odbc/environ.c 2001/03/27 04:00:53 1.24
--- src/interfaces/odbc/environ.c 2001/03/28 16:53:15
***************
*** 1,4 ****
! /* Module: environ.c
*
* Description: This module contains routines related to
* the environment, such as storing connection handles,
--- 1,5 ----
! /*-------
! * Module: environ.c
*
* Description: This module contains routines related to
* the environment, such as storing connection handles,
***************
*** 9,15 ****
* API functions: SQLAllocEnv, SQLFreeEnv, SQLError
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
#include "environ.h"
--- 10,16 ----
* API functions: SQLAllocEnv, SQLFreeEnv, SQLError
*
* Comments: See "notice.txt" for copyright and license information.
! *-------
*/
#include "environ.h"
***************
*** 208,231 ****
case STMT_INVALID_CURSOR_POSITION:
strcpy(szSqlState, "S1109");
break;
-
case STMT_VALUE_OUT_OF_RANGE:
strcpy(szSqlState, "22003");
break;
-
case STMT_OPERATION_INVALID:
strcpy(szSqlState, "S1011");
break;
-
case STMT_EXEC_ERROR:
default:
strcpy(szSqlState, "S1000");
/* also a general error */
break;
}
-
mylog(" szSqlState = '%s', szError='%s'\n", szSqlState, szErrorMsg);
-
}
else
{
--- 209,227 ----
***************
*** 237,246 ****
szErrorMsg[0] = '\0';
mylog(" returning NO_DATA_FOUND\n");
return SQL_NO_DATA_FOUND;
}
- return SQL_SUCCESS;
}
else if (SQL_NULL_HDBC != hdbc)
{
--- 233,243 ----
szErrorMsg[0] = '\0';
mylog(" returning NO_DATA_FOUND\n");
+
return SQL_NO_DATA_FOUND;
}
+ return SQL_SUCCESS;
}
else if (SQL_NULL_HDBC != hdbc)
{
***************
*** 310,316 ****
break;
case CONN_TRANSACT_IN_PROGRES:
strcpy(szSqlState, "S1010");
-
/*
* when the user tries to switch commit mode in a
* transaction
--- 307,312 ----
***************
*** 324,341 ****
case STMT_NOT_IMPLEMENTED_ERROR:
strcpy(szSqlState, "S1C00");
break;
-
case CONN_VALUE_OUT_OF_RANGE:
case STMT_VALUE_OUT_OF_RANGE:
strcpy(szSqlState, "22003");
break;
-
default:
strcpy(szSqlState, "S1000");
/* general error */
break;
}
-
}
else
{
--- 320,334 ----
***************
*** 349,356 ****
return SQL_NO_DATA_FOUND;
}
- return SQL_SUCCESS;
}
else if (SQL_NULL_HENV != henv)
{
--- 342,349 ----
return SQL_NO_DATA_FOUND;
}
+ return SQL_SUCCESS;
}
else if (SQL_NULL_HENV != henv)
{
***************
*** 419,433 ****
}
- /*********************************************************************/
/*
* EnvironmentClass implementation
*/
!
!
!
! EnvironmentClass
! *
EN_Constructor(void)
{
EnvironmentClass *rv;
--- 412,421 ----
}
/*
* EnvironmentClass implementation
*/
! EnvironmentClass *
EN_Constructor(void)
{
EnvironmentClass *rv;
***************
*** 451,458 ****
mylog("in EN_Destructor, self=%u\n", self);
! /* the error messages are static strings distributed throughout */
! /* the source--they should not be freed */
/* Free any connections belonging to this environment */
for (lf = 0; lf < MAX_CONNECTIONS; lf++)
--- 439,448 ----
mylog("in EN_Destructor, self=%u\n", self);
! /*
! * the error messages are static strings distributed throughout
! * the source--they should not be freed
! */
/* Free any connections belonging to this environment */
for (lf = 0; lf < MAX_CONNECTIONS; lf++)
Index: src/interfaces/odbc/execute.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/execute.c,v
retrieving revision 1.25
diff -c -r1.25 execute.c
*** src/interfaces/odbc/execute.c 2001/03/27 04:00:53 1.25
--- src/interfaces/odbc/execute.c 2001/03/28 16:53:15
***************
*** 1,4 ****
! /* Module: execute.c
*
* Description: This module contains routines related to
* preparing and executing an SQL statement.
--- 1,5 ----
! /*-------
! * Module: execute.c
*
* Description: This module contains routines related to
* preparing and executing an SQL statement.
***************
*** 9,15 ****
* SQLCancel, SQLNativeSql, SQLParamData, SQLPutData
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
#ifdef HAVE_CONFIG_H
--- 10,16 ----
* SQLCancel, SQLNativeSql, SQLParamData, SQLPutData
*
* Comments: See "notice.txt" for copyright and license information.
! *-------
*/
#ifdef HAVE_CONFIG_H
***************
*** 125,138 ****
}
return SQL_SUCCESS;
-
-
}
- /* - - - - - - - - - */
-
/* Performs the equivalent of SQLPrepare, followed by SQLExecute. */
-
RETCODE SQL_API
SQLExecDirect(
HSTMT hstmt,
--- 126,134 ----
***************
*** 154,161 ****
if (stmt->statement)
free(stmt->statement);
! /* keep a copy of the un-parametrized statement, in case */
! /* they try to execute this statement again */
stmt->statement = make_string(szSqlStr, cbSqlStr, NULL);
if (!stmt->statement)
{
--- 150,159 ----
if (stmt->statement)
free(stmt->statement);
! /*
! * keep a copy of the un-parametrized statement, in case
! * they try to execute this statement again
! */
stmt->statement = make_string(szSqlStr, cbSqlStr, NULL);
if (!stmt->statement)
{
***************
*** 169,177 ****
stmt->prepare = FALSE;
! /* If an SQLPrepare was performed prior to this, but was left in */
! /* the premature state because an error occurred prior to SQLExecute */
! /* then set the statement to finished so it can be recycled. */
if (stmt->status == STMT_PREMATURE)
stmt->status = STMT_FINISHED;
--- 167,177 ----
stmt->prepare = FALSE;
! /*
! * If an SQLPrepare was performed prior to this, but was left in
! * the premature state because an error occurred prior to SQLExecute
! * then set the statement to finished so it can be recycled.
! */
if (stmt->status == STMT_PREMATURE)
stmt->status = STMT_FINISHED;
***************
*** 194,200 ****
return result;
}
! /* Execute a prepared SQL statement */
RETCODE SQL_API
SQLExecute(
HSTMT hstmt)
--- 194,200 ----
return result;
}
! /* Execute a prepared SQL statement */
RETCODE SQL_API
SQLExecute(
HSTMT hstmt)
***************
*** 205,211 ****
int i,
retval;
-
mylog("%s: entering...\n", func);
if (!stmt)
--- 205,210 ----
***************
*** 274,280 ****
if ((stmt->prepare && stmt->status != STMT_READY) ||
(stmt->status != STMT_ALLOCATED && stmt->status != STMT_READY))
{
-
stmt->errornumber = STMT_STATUS_ERROR;
stmt->errormsg = "The handle does not point to a statement that is ready to be executed";
SC_log_error(func, "", stmt);
--- 273,278 ----
***************
*** 282,288 ****
return SQL_ERROR;
}
-
/*
* The bound parameters could have possibly changed since the last
* execute of this statement? Therefore check for params and re-copy.
--- 280,285 ----
***************
*** 319,333 ****
mylog(" stmt_with_params = '%s'\n", stmt->stmt_with_params);
-
return SC_execute(stmt);
-
}
-
-
- /* - - - - - - - - - */
RETCODE SQL_API
SQLTransact(
HENV henv,
--- 316,325 ----
***************
*** 363,369 ****
if (conn && conn->henv == henv)
if (SQLTransact(henv, (HDBC) conn, fType) != SQL_SUCCESS)
return SQL_ERROR;
-
}
return SQL_SUCCESS;
}
--- 355,360 ----
***************
*** 371,385 ****
conn = (ConnectionClass *) hdbc;
if (fType == SQL_COMMIT)
- {
stmt_string = "COMMIT";
-
- }
else if (fType == SQL_ROLLBACK)
- {
stmt_string = "ROLLBACK";
-
- }
else
{
conn->errornumber = CONN_INVALID_ARGUMENT_NO;
--- 362,370 ----
***************
*** 391,397 ****
/* If manual commit and in transaction, then proceed. */
if (!CC_is_in_autocommit(conn) && CC_is_in_trans(conn))
{
-
mylog("SQLTransact: sending on conn %d '%s'\n", conn, stmt_string);
res = CC_send_query(conn, stmt_string, NULL);
--- 376,381 ----
***************
*** 416,422 ****
return SQL_SUCCESS;
}
- /* - - - - - - - - - */
RETCODE SQL_API
SQLCancel(
--- 400,405 ----
***************
*** 447,454 ****
*/
if (stmt->data_at_exec < 0)
{
-
-
/*
* MAJOR HACK for Windows to reset the driver manager's cursor
* state: Because of what seems like a bug in the Odbc driver
--- 430,435 ----
***************
*** 490,503 ****
stmt->put_data = FALSE;
return SQL_SUCCESS;
-
}
- /* - - - - - - - - - */
! /* Returns the SQL string as modified by the driver. */
! /* Currently, just copy the input string without modification */
! /* observing buffer limits and truncation. */
RETCODE SQL_API
SQLNativeSql(
HDBC hdbc,
--- 471,484 ----
stmt->put_data = FALSE;
return SQL_SUCCESS;
}
! /*
! * Returns the SQL string as modified by the driver.
! * Currently, just copy the input string without modification
! * observing buffer limits and truncation.
! */
RETCODE SQL_API
SQLNativeSql(
HDBC hdbc,
***************
*** 546,557 ****
return result;
}
-
- /* - - - - - - - - - */
! /* Supplies parameter data at execution time. Used in conjuction with */
! /* SQLPutData. */
!
RETCODE SQL_API
SQLParamData(
HSTMT hstmt,
--- 527,537 ----
return result;
}
! /*
! * Supplies parameter data at execution time.
! * Used in conjuction with SQLPutData.
! */
RETCODE SQL_API
SQLParamData(
HSTMT hstmt,
***************
*** 619,629 ****
CC_set_no_trans(stmt->hdbc);
}
-
stmt->lobj_fd = -1;
}
-
/* Done, now copy the params and then execute the statement */
if (stmt->data_at_exec == 0)
{
--- 599,607 ----
***************
*** 657,668 ****
return SQL_NEED_DATA;
}
-
- /* - - - - - - - - - */
! /* Supplies parameter data at execution time. Used in conjunction with */
! /* SQLParamData. */
!
RETCODE SQL_API
SQLPutData(
HSTMT hstmt,
--- 635,645 ----
return SQL_NEED_DATA;
}
! /*
! * Supplies parameter data at execution time.
! * Used in conjunction with SQLParamData.
! */
RETCODE SQL_API
SQLPutData(
HSTMT hstmt,
***************
*** 684,690 ****
return SQL_INVALID_HANDLE;
}
-
if (stmt->current_exec_param < 0)
{
stmt->errornumber = STMT_SEQUENCE_ERROR;
--- 661,666 ----
***************
*** 697,703 ****
if (!stmt->put_data)
{ /* first call */
-
mylog("SQLPutData: (1) cbValue = %d\n", cbValue);
stmt->put_data = TRUE;
--- 673,678 ----
***************
*** 716,726 ****
if (cbValue == SQL_NULL_DATA)
return SQL_SUCCESS;
-
/* Handle Long Var Binary with Large Objects */
if (current_param->SQLType == SQL_LONGVARBINARY)
{
-
/* begin transaction if needed */
if (!CC_is_in_trans(stmt->hdbc))
{
--- 691,699 ----
***************
*** 758,765 ****
return SQL_ERROR;
}
! /* major hack -- to allow convert to see somethings there */
! /* have to modify convert to handle this better */
current_param->EXEC_buffer = (char *) ¤t_param->lobj_oid;
/* store the fd */
--- 731,740 ----
return SQL_ERROR;
}
! /*
! * major hack -- to allow convert to see somethings there
! * have to modify convert to handle this better
! */
current_param->EXEC_buffer = (char *) ¤t_param->lobj_oid;
/* store the fd */
***************
*** 774,785 ****
retval = lo_write(stmt->hdbc, stmt->lobj_fd, rgbValue, cbValue);
mylog("lo_write: cbValue=%d, wrote %d bytes\n", cbValue, retval);
-
}
else
! { /* for handling text fields and small
! * binaries */
!
if (cbValue == SQL_NTS)
{
current_param->EXEC_buffer = strdup(rgbValue);
--- 749,758 ----
retval = lo_write(stmt->hdbc, stmt->lobj_fd, rgbValue, cbValue);
mylog("lo_write: cbValue=%d, wrote %d bytes\n", cbValue, retval);
}
else
! {
! /* for handling text fields and small binaries */
if (cbValue == SQL_NTS)
{
current_param->EXEC_buffer = strdup(rgbValue);
***************
*** 806,830 ****
}
}
}
-
else
! { /* calling SQLPutData more than once */
!
mylog("SQLPutData: (>1) cbValue = %d\n", cbValue);
if (current_param->SQLType == SQL_LONGVARBINARY)
{
-
/* the large object fd is in EXEC_buffer */
retval = lo_write(stmt->hdbc, stmt->lobj_fd, rgbValue, cbValue);
mylog("lo_write(2): cbValue = %d, wrote %d bytes\n", cbValue, retval);
*current_param->EXEC_used += cbValue;
-
}
else
{
-
buffer = current_param->EXEC_buffer;
if (cbValue == SQL_NTS)
--- 779,799 ----
}
}
}
else
! {
! /* calling SQLPutData more than once */
mylog("SQLPutData: (>1) cbValue = %d\n", cbValue);
if (current_param->SQLType == SQL_LONGVARBINARY)
{
/* the large object fd is in EXEC_buffer */
retval = lo_write(stmt->hdbc, stmt->lobj_fd, rgbValue, cbValue);
mylog("lo_write(2): cbValue = %d, wrote %d bytes\n", cbValue, retval);
*current_param->EXEC_used += cbValue;
}
else
{
buffer = current_param->EXEC_buffer;
if (cbValue == SQL_NTS)
***************
*** 845,855 ****
/* reassign buffer incase realloc moved it */
current_param->EXEC_buffer = buffer;
-
}
else if (cbValue > 0)
{
-
old_pos = *current_param->EXEC_used;
*current_param->EXEC_used += cbValue;
--- 814,822 ----
***************
*** 871,887 ****
/* reassign buffer incase realloc moved it */
current_param->EXEC_buffer = buffer;
-
}
else
{
SC_log_error(func, "bad cbValue", stmt);
return SQL_ERROR;
}
-
}
}
-
return SQL_SUCCESS;
}
--- 838,851 ----
Index: src/interfaces/odbc/gpps.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/gpps.c,v
retrieving revision 1.17
diff -c -r1.17 gpps.c
*** src/interfaces/odbc/gpps.c 2001/03/27 04:00:53 1.17
--- src/interfaces/odbc/gpps.c 2001/03/28 16:53:15
***************
*** 1,4 ****
! /* GetPrivateProfileString()
*
* approximate implementation of
* Windows NT System Services version of GetPrivateProfileString()
--- 1,5 ----
! /*-------
! * GetPrivateProfileString()
*
* approximate implementation of
* Windows NT System Services version of GetPrivateProfileString()
***************
*** 15,20 ****
--- 16,22 ----
* are allowed (that is an anachronism anyway)
* Added code to search for ODBC_INI file in users home directory on
* Unix
+ *-------
*/
#ifndef WIN32
***************
*** 46,52 ****
DWORD
GetPrivateProfileString(char *theSection, /* section name */
! char *theKey, /* search key name */
char *theDefault, /* default value if not
* found */
char *theReturnBuffer, /* return value stored
--- 48,54 ----
DWORD
GetPrivateProfileString(char *theSection, /* section name */
! char *theKey, /* search key name */
char *theDefault, /* default value if not
* found */
char *theReturnBuffer, /* return value stored
***************
*** 110,116 ****
aFile = (FILE *) (buf ? fopen(buf, PG_BINARY_R) : NULL);
}
-
aLength = (theDefault == NULL) ? 0 : strlen(theDefault);
if (theReturnBufferLength == 0 || theReturnBuffer == NULL)
--- 112,117 ----
***************
*** 123,129 ****
if (aFile == NULL)
{
/* no ini file specified, return the default */
-
++aLength; /* room for NULL char */
aLength = theReturnBufferLength < aLength ?
theReturnBufferLength : aLength;
--- 124,129 ----
***************
*** 132,138 ****
return aLength - 1;
}
-
while (fgets(aLine, sizeof(aLine), aFile) != NULL)
{
aLineLength = strlen(aLine);
--- 132,137 ----
***************
*** 147,153 ****
break;
case '[': /* section marker */
-
if ((aString = strchr(aLine, ']')))
{
aStart = aLine + 1;
--- 146,151 ----
***************
*** 159,188 ****
*(aString + 1) = '\0';
/* accept as matched if NULL key or exact match */
-
if (!theSection || !strcmp(aStart, theSection))
aSectionFound = TRUE;
else
aSectionFound = FALSE;
}
-
break;
default:
/* try to match value keys if in proper section */
-
if (aSectionFound)
{
/* try to match requested key */
-
if ((aString = aValue = strchr(aLine, '=')))
{
*aValue = '\0';
++aValue;
/* strip leading blanks in value field */
-
while (*aValue == ' ' && aValue < aLine + sizeof(aLine))
*aValue++ = '\0';
if (aValue >= aLine + sizeof(aLine))
--- 157,181 ----
***************
*** 196,202 ****
aStart++;
/* strip trailing blanks from key */
-
if (aString)
{
while (--aString >= aStart && *aString == ' ')
--- 189,194 ----
***************
*** 204,219 ****
}
/* see if key is matched */
-
if (theKey == NULL || !strcmp(theKey, aStart))
{
/* matched -- first, terminate value part */
-
aKeyFound = TRUE;
aLength = strlen(aValue);
/* remove trailing blanks from aValue if any */
-
aString = aValue + aLength - 1;
while (--aString > aValue && *aString == ' ')
--- 196,208 ----
***************
*** 223,229 ****
}
/* unquote value if quoted */
-
if (aLength >= 2 && aValue[0] == '"' &&
aValue[aLength - 1] == '"')
{
--- 212,217 ----
***************
*** 236,242 ****
else
{
/* single quotes allowed also... */
-
if (aLength >= 2 && aValue[0] == '\'' &&
aValue[aLength - 1] == '\'')
{
--- 224,229 ----
***************
*** 247,259 ****
}
/* compute maximum length copyable */
-
aLineLength = (aLength <
theReturnBufferLength - aReturnLength) ? aLength :
theReturnBufferLength - aReturnLength;
/* do the copy to return buffer */
-
if (aLineLength)
{
strncpy(&theReturnBuffer[aReturnLength],
--- 234,244 ----
***************
*** 270,280 ****
fclose(aFile);
aFile = NULL;
}
-
return aReturnLength > 0 ? aReturnLength - 1 : 0;
}
}
-
break;
}
}
--- 255,263 ----
***************
*** 283,289 ****
fclose(aFile);
if (!aKeyFound)
! { /* key wasn't found return default */
++aLength; /* room for NULL char */
aLength = theReturnBufferLength < aLength ?
theReturnBufferLength : aLength;
--- 266,273 ----
fclose(aFile);
if (!aKeyFound)
! {
! /* key wasn't found return default */
++aLength; /* room for NULL char */
aLength = theReturnBufferLength < aLength ?
theReturnBufferLength : aLength;
***************
*** 296,302 ****
DWORD
WritePrivateProfileString(char *theSection, /* section name */
! char *theKey, /* write key name */
char *theBuffer, /* input buffer */
char *theIniFileName) /* pathname of ini file to
* write */
--- 280,286 ----
DWORD
WritePrivateProfileString(char *theSection, /* section name */
! char *theKey, /* write key name */
char *theBuffer, /* input buffer */
char *theIniFileName) /* pathname of ini file to
* write */
***************
*** 305,317 ****
}
#if 0
! /* Ok. What the hell's the default behaviour for a null input buffer, and null
* section name. For now if either are null I ignore the request, until
* I find out different.
*/
DWORD
WritePrivateProfileString(char *theSection, /* section name */
! char *theKey, /* write key name */
char *theBuffer, /* input buffer */
char *theIniFileName) /* pathname of ini file to
* write */
--- 289,302 ----
}
#if 0
! /*
! * Ok. What the hell's the default behaviour for a null input buffer, and null
* section name. For now if either are null I ignore the request, until
* I find out different.
*/
DWORD
WritePrivateProfileString(char *theSection, /* section name */
! char *theKey, /* write key name */
char *theBuffer, /* input buffer */
char *theIniFileName) /* pathname of ini file to
* write */
***************
*** 353,363 ****
if (ptr == NULL || *ptr == '\0')
ptr = "/home";
! /* This doesn't make it so we find an ini file but allows normal */
! /* processing to continue further on down. The likelihood is that */
! /* the file won't be found and thus the default value will be */
! /* returned. */
! /* */
if (MAXPGPATH - 1 < strlen(ptr) + j)
{
if (MAXPGPATH - 1 < strlen(ptr))
--- 338,349 ----
if (ptr == NULL || *ptr == '\0')
ptr = "/home";
! /*
! * This doesn't make it so we find an ini file but allows normal
! * processing to continue further on down. The likelihood is that
! * the file won't be found and thus the default value will be
! * returned.
! */
if (MAXPGPATH - 1 < strlen(ptr) + j)
{
if (MAXPGPATH - 1 < strlen(ptr))
***************
*** 368,376 ****
sprintf(buf, "%s/%s", ptr, theIniFileName);
! /* This code makes it so that a file in the users home dir */
! /* overrides a the "default" file as passed in */
! /* */
aFile = (FILE *) (buf ? fopen(buf, "r+") : NULL);
if (!aFile)
{
--- 354,363 ----
sprintf(buf, "%s/%s", ptr, theIniFileName);
! /*
! * This code makes it so that a file in the users home dir
! * overrides a the "default" file as passed in
! */
aFile = (FILE *) (buf ? fopen(buf, "r+") : NULL);
if (!aFile)
{
***************
*** 380,392 ****
return 0;
}
-
aLength = strlen(theBuffer);
! /* We have to search for theKey, because if it already */
! /* exists we have to overwrite it. If it doesn't exist */
! /* we just write a new line to the file. */
! /* */
while (fgets(aLine, sizeof(aLine), aFile) != NULL)
{
aLineLength = strlen(aLine);
--- 367,379 ----
return 0;
}
aLength = strlen(theBuffer);
! /*
! * We have to search for theKey, because if it already
! * exists we have to overwrite it. If it doesn't exist
! * we just write a new line to the file.
! */
while (fgets(aLine, sizeof(aLine), aFile) != NULL)
{
aLineLength = strlen(aLine);
***************
*** 401,407 ****
break;
case '[': /* section marker */
-
if ((aString = strchr(aLine, ']')))
{
*aString = '\0';
--- 388,393 ----
***************
*** 411,423 ****
if (!strcmp(aLine + 1, theSection))
aSectionFound = TRUE;
}
-
break;
default:
-
/* try to match value keys if in proper section */
-
if (aSectionFound)
{
/* try to match requested key */
--- 397,406 ----
***************
*** 428,434 ****
++aValue;
/* strip leading blanks in value field */
-
while (*aValue == ' ' && aValue < aLine + sizeof(aLine))
*aValue++ = '\0';
if (aValue >= aLine + sizeof(aLine))
--- 411,416 ----
***************
*** 438,444 ****
aValue = "";
/* strip trailing blanks from key */
-
if (aString)
{
while (--aString >= aLine && *aString == ' ')
--- 420,425 ----
***************
*** 446,452 ****
}
/* see if key is matched */
-
if (!strcmp(theKey, aLine))
{
keyFound = TRUE;
--- 427,432 ----
***************
*** 460,466 ****
}
}
}
-
break;
}
}
--- 440,445 ----
Index: src/interfaces/odbc/info.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/info.c,v
retrieving revision 1.44
diff -c -r1.44 info.c
*** src/interfaces/odbc/info.c 2001/03/27 04:00:53 1.44
--- src/interfaces/odbc/info.c 2001/03/28 16:53:17
***************
*** 1,4 ****
! /* Module: info.c
*
* Description: This module contains routines related to
* ODBC informational functions.
--- 1,5 ----
! /*--------
! * Module: info.c
*
* Description: This module contains routines related to
* ODBC informational functions.
***************
*** 12,18 ****
* SQLTablePrivileges(NI), SQLColumnPrivileges(NI)
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
#ifdef HAVE_CONFIG_H
--- 13,19 ----
* SQLTablePrivileges(NI), SQLColumnPrivileges(NI)
*
* Comments: See "notice.txt" for copyright and license information.
! *--------
*/
#ifdef HAVE_CONFIG_H
***************
*** 56,63 ****
extern GLOBAL_VALUES globals;
- /* - - - - - - - - - */
-
RETCODE SQL_API
SQLGetInfo(
HDBC hdbc,
--- 57,62 ----
***************
*** 154,160 ****
break;
case SQL_CORRELATION_NAME: /* ODBC 1.0 */
-
/*
* Saying no correlation name makes Query not work right.
* value = SQL_CN_NONE;
--- 153,158 ----
***************
*** 182,192 ****
break;
case SQL_DATABASE_NAME:/* Support for old ODBC 1.0 Apps */
-
/*
* Returning the database name causes problems in MS Query. It
! * generates query like: "SELECT DISTINCT a FROM byronncrap3
! * crap3"
*
* p = CC_get_database(conn);
*/
--- 180,189 ----
break;
case SQL_DATABASE_NAME:/* Support for old ODBC 1.0 Apps */
/*
* Returning the database name causes problems in MS Query. It
! * generates query like: "SELECT DISTINCT a FROM byronnbad3
! * bad3"
*
* p = CC_get_database(conn);
*/
***************
*** 198,204 ****
break;
case SQL_DBMS_VER: /* ODBC 1.0 */
-
/*
* The ODBC spec wants ##.##.#### ...whatever... so prepend
* the driver
--- 195,200 ----
***************
*** 256,262 ****
break;
case SQL_IDENTIFIER_CASE: /* ODBC 1.0 */
-
/*
* are identifiers case-sensitive (yes, but only when quoted.
* If not quoted, they default to lowercase)
--- 252,257 ----
***************
*** 275,281 ****
break;
case SQL_LIKE_ESCAPE_CLAUSE: /* ODBC 2.0 */
-
/*
* is there a character that escapes '%' and '_' in a LIKE
* clause? not as far as I can tell
--- 270,275 ----
***************
*** 356,373 ****
case SQL_MAX_ROW_SIZE: /* ODBC 2.0 */
len = 4;
if (PG_VERSION_GE(conn, 7.1))
! { /* Large Rowa in 7.1+ */
value = MAX_ROW_SIZE;
}
else
! { /* Without the Toaster we're limited to
! * the blocksize */
value = BLCKSZ;
}
break;
case SQL_MAX_ROW_SIZE_INCLUDES_LONG: /* ODBC 2.0 */
-
/*
* does the preceding value include LONGVARCHAR and
* LONGVARBINARY fields? Well, it does include longvarchar,
--- 350,367 ----
case SQL_MAX_ROW_SIZE: /* ODBC 2.0 */
len = 4;
if (PG_VERSION_GE(conn, 7.1))
! {
! /* Large Rowa in 7.1+ */
value = MAX_ROW_SIZE;
}
else
! {
! /* Without the Toaster we're limited to the blocksize */
value = BLCKSZ;
}
break;
case SQL_MAX_ROW_SIZE_INCLUDES_LONG: /* ODBC 2.0 */
/*
* does the preceding value include LONGVARCHAR and
* LONGVARBINARY fields? Well, it does include longvarchar,
***************
*** 379,393 ****
case SQL_MAX_STATEMENT_LEN: /* ODBC 2.0 */
/* maybe this should be 0? */
len = 4;
if (PG_VERSION_GE(conn, 7.0))
- { /* Long Queries in 7.0+ */
value = MAX_STATEMENT_LEN;
! }
! else if (PG_VERSION_GE(conn, 6.5)) /* Prior to 7.0 we used
! * 2*BLCKSZ */
value = (2 * BLCKSZ);
else
! /* Prior to 6.5 we used BLCKSZ */
value = BLCKSZ;
break;
--- 373,386 ----
case SQL_MAX_STATEMENT_LEN: /* ODBC 2.0 */
/* maybe this should be 0? */
len = 4;
+ /* Long Queries in 7.0+ */
if (PG_VERSION_GE(conn, 7.0))
value = MAX_STATEMENT_LEN;
! /* Prior to 7.0 we used 2*BLCKSZ */
! else if (PG_VERSION_GE(conn, 6.5))
value = (2 * BLCKSZ);
else
! /* Prior to 6.5 we used BLCKSZ */
value = BLCKSZ;
break;
***************
*** 417,425 ****
break;
case SQL_NEED_LONG_DATA_LEN: /* ODBC 2.0 */
-
/*
! * Dont need the length, SQLPutData can handle any size and
* multiple calls
*/
p = "N";
--- 410,417 ----
break;
case SQL_NEED_LONG_DATA_LEN: /* ODBC 2.0 */
/*
! * Don't need the length, SQLPutData can handle any size and
* multiple calls
*/
p = "N";
***************
*** 463,469 ****
case SQL_OJ_CAPABILITIES: /* ODBC 2.01 */
len = 4;
if (PG_VERSION_GE(conn, 7.1))
! { /* OJs in 7.1+ */
value = (SQL_OJ_LEFT |
SQL_OJ_RIGHT |
SQL_OJ_FULL |
--- 455,462 ----
case SQL_OJ_CAPABILITIES: /* ODBC 2.01 */
len = 4;
if (PG_VERSION_GE(conn, 7.1))
! {
! /* OJs in 7.1+ */
value = (SQL_OJ_LEFT |
SQL_OJ_RIGHT |
SQL_OJ_FULL |
***************
*** 473,481 ****
SQL_OJ_ALL_COMPARISON_OPS);
}
else
! { /* OJs not in <7.1 */
value = 0;
- }
break;
case SQL_ORDER_BY_COLUMNS_IN_SELECT: /* ODBC 2.0 */
--- 466,473 ----
SQL_OJ_ALL_COMPARISON_OPS);
}
else
! /* OJs not in <7.1 */
value = 0;
break;
case SQL_ORDER_BY_COLUMNS_IN_SELECT: /* ODBC 2.0 */
***************
*** 484,496 ****
case SQL_OUTER_JOINS: /* ODBC 1.0 */
if (PG_VERSION_GE(conn, 7.1))
! { /* OJs in 7.1+ */
p = "Y";
- }
else
! { /* OJs not in <7.1 */
p = "N";
- }
break;
case SQL_OWNER_TERM: /* ODBC 1.0 */
--- 476,486 ----
case SQL_OUTER_JOINS: /* ODBC 1.0 */
if (PG_VERSION_GE(conn, 7.1))
! /* OJs in 7.1+ */
p = "Y";
else
! /* OJs not in <7.1 */
p = "N";
break;
case SQL_OWNER_TERM: /* ODBC 1.0 */
***************
*** 547,553 ****
break;
case SQL_ROW_UPDATES: /* ODBC 1.0 */
-
/*
* Driver doesn't support keyset-driven or mixed cursors, so
* not much point in saying row updates are supported
--- 537,542 ----
***************
*** 635,641 ****
break;
case SQL_TXN_CAPABLE: /* ODBC 1.0 */
-
/*
* Postgres can deal with create or drop table statements in a
* transaction
--- 624,629 ----
***************
*** 677,683 ****
* what length would be required if a real buffer had been passed in.
*/
if (p)
! { /* char/binary data */
len = strlen(p);
if (rgbInfoValue)
--- 665,672 ----
* what length would be required if a real buffer had been passed in.
*/
if (p)
! {
! /* char/binary data */
len = strlen(p);
if (rgbInfoValue)
***************
*** 692,704 ****
}
}
}
-
else
! { /* numeric data */
!
if (rgbInfoValue)
{
-
if (len == 2)
*((WORD *) rgbInfoValue) = (WORD) value;
else if (len == 4)
--- 681,691 ----
}
}
}
else
! {
! /* numeric data */
if (rgbInfoValue)
{
if (len == 2)
*((WORD *) rgbInfoValue) = (WORD) value;
else if (len == 4)
***************
*** 712,719 ****
return result;
}
- /* - - - - - - - - - */
-
RETCODE SQL_API
SQLGetTypeInfo(
--- 699,704 ----
***************
*** 725,731 ****
TupleNode *row;
int i;
! /* Int4 type; */
Int4 pgType;
Int2 sqlType;
--- 710,716 ----
TupleNode *row;
int i;
! /* Int4 type; */
Int4 pgType;
Int2 sqlType;
***************
*** 737,743 ****
return SQL_INVALID_HANDLE;
}
-
stmt->manual_result = TRUE;
stmt->result = QR_Constructor();
if (!stmt->result)
--- 722,727 ----
***************
*** 801,807 ****
}
}
-
stmt->status = STMT_FINISHED;
stmt->currTuple = -1;
stmt->rowset_start = -1;
--- 785,790 ----
***************
*** 810,816 ****
return SQL_SUCCESS;
}
- /* - - - - - - - - - */
RETCODE SQL_API
SQLGetFunctions(
--- 793,798 ----
***************
*** 824,830 ****
if (fFunction == SQL_API_ALL_FUNCTIONS)
{
-
if (globals.lie)
{
int i;
--- 806,811 ----
***************
*** 910,922 ****
}
else
{
-
if (globals.lie)
*pfExists = TRUE;
-
else
{
-
switch (fFunction)
{
case SQL_API_SQLALLOCCONNECT:
--- 891,900 ----
***************
*** 1094,1105 ****
}
}
}
-
return SQL_SUCCESS;
}
-
RETCODE SQL_API
SQLTables(
HSTMT hstmt,
--- 1072,1081 ----
***************
*** 1160,1173 ****
return SQL_ERROR;
}
tbl_stmt = (StatementClass *) htbl_stmt;
-
- /* ********************************************************************** */
- /* Create the query to find out the tables */
- /* ********************************************************************** */
if (PG_VERSION_GE(conn, 7.1))
! { /* view is represented by its relkind
! * since 7.1 */
strcpy(tables_query, "select relname, usename, relkind from pg_class, pg_user");
strcat(tables_query, " where relkind in ('r', 'v')");
}
--- 1136,1148 ----
return SQL_ERROR;
}
tbl_stmt = (StatementClass *) htbl_stmt;
+ /*
+ * Create the query to find out the tables
+ */
if (PG_VERSION_GE(conn, 7.1))
! {
! /* view is represented by its relkind since 7.1 */
strcpy(tables_query, "select relname, usename, relkind from pg_class, pg_user");
strcat(tables_query, " where relkind in ('r', 'v')");
}
***************
*** 1180,1194 ****
my_strcat(tables_query, " and usename like '%.*s'", szTableOwner, cbTableOwner);
my_strcat(tables_query, " and relname like '%.*s'", szTableName, cbTableName);
-
/* Parse the extra systable prefix */
strcpy(prefixes, globals.extra_systable_prefixes);
i = 0;
prefix[i] = strtok(prefixes, ";");
while (prefix[i] && i < 32)
- {
prefix[++i] = strtok(NULL, ";");
- }
/* Parse the desired table types to return */
show_system_tables = FALSE;
--- 1155,1166 ----
***************
*** 1216,1222 ****
show_regular_tables = TRUE;
else if (strstr(table_type[i], "VIEW"))
show_views = TRUE;
-
i++;
}
}
--- 1188,1193 ----
***************
*** 1243,1263 ****
strcat(tables_query, prefix[i]);
i++;
}
-
strcat(tables_query, "'");
}
-
/* match users */
! if (PG_VERSION_LT(conn, 7.1)) /* filter out large objects in
! * older versions */
strcat(tables_query, " and relname !~ '^xinv[0-9]+'");
strcat(tables_query, " and usesysid = relowner");
strcat(tables_query, " order by relname");
- /* ********************************************************************** */
-
result = SQLExecDirect(htbl_stmt, tables_query, strlen(tables_query));
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
{
--- 1214,1230 ----
strcat(tables_query, prefix[i]);
i++;
}
strcat(tables_query, "'");
}
/* match users */
! if (PG_VERSION_LT(conn, 7.1))
! /* filter out large objects in older versions */
strcat(tables_query, " and relname !~ '^xinv[0-9]+'");
strcat(tables_query, " and usesysid = relowner");
strcat(tables_query, " order by relname");
result = SQLExecDirect(htbl_stmt, tables_query, strlen(tables_query));
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
{
***************
*** 1330,1336 ****
result = SQLFetch(htbl_stmt);
while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO))
{
-
/*
* Determine if this table name is a system table. If treating
* system tables as regular tables, then no need to do this test.
--- 1297,1302 ----
***************
*** 1338,1349 ****
systable = FALSE;
if (!atoi(ci->show_system_tables))
{
-
if (strncmp(table_name, POSTGRES_SYS_PREFIX, strlen(POSTGRES_SYS_PREFIX)) == 0)
systable = TRUE;
else
! { /* Check extra system table prefixes */
i = 0;
while (prefix[i])
{
--- 1304,1315 ----
systable = FALSE;
if (!atoi(ci->show_system_tables))
{
if (strncmp(table_name, POSTGRES_SYS_PREFIX, strlen(POSTGRES_SYS_PREFIX)) == 0)
systable = TRUE;
else
! {
! /* Check extra system table prefixes */
i = 0;
while (prefix[i])
{
***************
*** 1359,1366 ****
}
/* Determine if the table name is a view */
! if (PG_VERSION_GE(conn, 7.1)) /* view is represented by its
! * relkind since 7.1 */
view = (relkind_or_hasrules[0] == 'v');
else
view = (relkind_or_hasrules[0] == '1');
--- 1325,1332 ----
}
/* Determine if the table name is a view */
! if (PG_VERSION_GE(conn, 7.1))
! /* view is represented by its relkind since 7.1 */
view = (relkind_or_hasrules[0] == 'v');
else
view = (relkind_or_hasrules[0] == '1');
***************
*** 1379,1394 ****
(view && show_views) ||
(regular_table && show_regular_tables))
{
-
row = (TupleNode *) malloc(sizeof(TupleNode) + (5 - 1) *sizeof(TupleField));
set_tuplefield_string(&row->tuple[0], "");
! /* I have to hide the table owner from Access, otherwise it */
! /* insists on referring to the table as 'owner.table'. */
! /* (this is valid according to the ODBC SQL grammar, but */
! /* Postgres won't support it.) */
! /* set_tuplefield_string(&row->tuple[1], table_owner); */
mylog("SQLTables: table_name = '%s'\n", table_name);
--- 1345,1362 ----
(view && show_views) ||
(regular_table && show_regular_tables))
{
row = (TupleNode *) malloc(sizeof(TupleNode) + (5 - 1) *sizeof(TupleField));
set_tuplefield_string(&row->tuple[0], "");
! /*
! * I have to hide the table owner from Access, otherwise it
! * insists on referring to the table as 'owner.table'.
! * (this is valid according to the ODBC SQL grammar, but
! * Postgres won't support it.)
! *
! * set_tuplefield_string(&row->tuple[1], table_owner);
! */
mylog("SQLTables: table_name = '%s'\n", table_name);
***************
*** 1410,1417 ****
return SQL_ERROR;
}
! /* also, things need to think that this statement is finished so */
! /* the results can be retrieved. */
stmt->status = STMT_FINISHED;
/* set up the current tuple pointer for SQLFetch */
--- 1378,1387 ----
return SQL_ERROR;
}
! /*
! * also, things need to think that this statement is finished so
! * the results can be retrieved.
! */
stmt->status = STMT_FINISHED;
/* set up the current tuple pointer for SQLFetch */
***************
*** 1425,1432 ****
}
-
-
RETCODE SQL_API
SQLColumns(
HSTMT hstmt,
--- 1395,1400 ----
***************
*** 1479,1491 ****
conn = (ConnectionClass *) (stmt->hdbc);
ci = &stmt->hdbc->connInfo;
- /* ********************************************************************** */
-
/*
* Create the query to find out the columns (Note: pre 6.3 did not
* have the atttypmod field)
*/
- /* ********************************************************************** */
sprintf(columns_query, "select u.usename, c.relname, a.attname, a.atttypid"
", t.typname, a.attnum, a.attlen, %s, a.attnotnull, c.relhasrules"
" from pg_user u, pg_class c, pg_attribute a, pg_type t"
--- 1447,1456 ----
***************
*** 1497,1506 ****
my_strcat(columns_query, " and u.usename like '%.*s'", szTableOwner, cbTableOwner);
my_strcat(columns_query, " and a.attname like '%.*s'", szColumnName, cbColumnName);
! /* give the output in the order the columns were defined */
! /* when the table was created */
strcat(columns_query, " order by attnum");
- /* ********************************************************************** */
result = SQLAllocStmt(stmt->hdbc, &hcol_stmt);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
--- 1462,1472 ----
my_strcat(columns_query, " and u.usename like '%.*s'", szTableOwner, cbTableOwner);
my_strcat(columns_query, " and a.attname like '%.*s'", szColumnName, cbColumnName);
! /*
! * give the output in the order the columns were defined
! * when the table was created
! */
strcat(columns_query, " order by attnum");
result = SQLAllocStmt(stmt->hdbc, &hcol_stmt);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
***************
*** 1673,1682 ****
QR_set_field_info(stmt->result, 12, "DISPLAY_SIZE", PG_TYPE_INT4, 4);
QR_set_field_info(stmt->result, 13, "FIELD_TYPE", PG_TYPE_INT4, 4);
-
result = SQLFetch(hcol_stmt);
-
/*
* Only show oid if option AND there are other columns AND it's not
* being called by SQLStatistics . Always show OID if it's a system
--- 1639,1646 ----
***************
*** 1685,1696 ****
if (result != SQL_ERROR && !stmt->internal)
{
-
if (relhasrules[0] != '1' &&
(atoi(ci->show_oid_column) ||
strncmp(table_name, POSTGRES_SYS_PREFIX, strlen(POSTGRES_SYS_PREFIX)) == 0))
{
-
/* For OID fields */
the_type = PG_TYPE_OID;
row = (TupleNode *) malloc(sizeof(TupleNode) +
--- 1649,1658 ----
***************
*** 1718,1724 ****
QR_add_tuple(stmt->result, row);
}
-
}
while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO))
--- 1680,1685 ----
***************
*** 1776,1786 ****
}
}
-
if ((field_type == PG_TYPE_VARCHAR) ||
(field_type == PG_TYPE_BPCHAR))
{
-
useStaticPrecision = FALSE;
if (mod_length >= 4)
--- 1737,1745 ----
***************
*** 1827,1834 ****
return SQL_ERROR;
}
! /* Put the row version column at the end so it might not be */
! /* mistaken for a key field. */
if (relhasrules[0] != '1' && !stmt->internal && atoi(ci->row_versioning))
{
/* For Row Versioning fields */
--- 1786,1795 ----
return SQL_ERROR;
}
! /*
! * Put the row version column at the end so it might not be
! * mistaken for a key field.
! */
if (relhasrules[0] != '1' && !stmt->internal && atoi(ci->row_versioning))
{
/* For Row Versioning fields */
***************
*** 1855,1862 ****
QR_add_tuple(stmt->result, row);
}
! /* also, things need to think that this statement is finished so */
! /* the results can be retrieved. */
stmt->status = STMT_FINISHED;
/* set up the current tuple pointer for SQLFetch */
--- 1816,1825 ----
QR_add_tuple(stmt->result, row);
}
! /*
! * also, things need to think that this statement is finished so
! * the results can be retrieved.
! */
stmt->status = STMT_FINISHED;
/* set up the current tuple pointer for SQLFetch */
***************
*** 1892,1899 ****
RETCODE result;
char relhasrules[MAX_INFO_STRING];
-
-
mylog("%s: entering...stmt=%u\n", func, stmt);
if (!stmt)
--- 1855,1860 ----
***************
*** 1904,1914 ****
ci = &stmt->hdbc->connInfo;
stmt->manual_result = TRUE;
-
! /* ********************************************************************** */
! /* Create the query to find out if this is a view or not... */
! /* ********************************************************************** */
sprintf(columns_query, "select c.relhasrules "
"from pg_user u, pg_class c where "
"u.usesysid = c.relowner");
--- 1865,1874 ----
ci = &stmt->hdbc->connInfo;
stmt->manual_result = TRUE;
! /*
! * Create the query to find out if this is a view or not...
! */
sprintf(columns_query, "select c.relhasrules "
"from pg_user u, pg_class c where "
"u.usesysid = c.relowner");
***************
*** 1988,1994 ****
}
else if (fColType == SQL_ROWVER)
{
-
Int2 the_type = PG_TYPE_INT4;
if (atoi(ci->row_versioning))
--- 1948,1953 ----
***************
*** 2009,2016 ****
}
}
-
-
stmt->status = STMT_FINISHED;
stmt->currTuple = -1;
stmt->rowset_start = -1;
--- 1968,1973 ----
***************
*** 2104,2112 ****
QR_set_field_info(stmt->result, 11, "PAGES", PG_TYPE_INT4, 4);
QR_set_field_info(stmt->result, 12, "FILTER_CONDITION", PG_TYPE_TEXT, MAX_INFO_STRING);
!
! /* only use the table name... the owner should be redundant, and */
! /* we never use qualifiers. */
table_name = make_string(szTableName, cbTableName, NULL);
if (!table_name)
{
--- 2061,2070 ----
QR_set_field_info(stmt->result, 11, "PAGES", PG_TYPE_INT4, 4);
QR_set_field_info(stmt->result, 12, "FILTER_CONDITION", PG_TYPE_TEXT, MAX_INFO_STRING);
! /*
! * only use the table name... the owner should be redundant, and
! * we never use qualifiers.
! */
table_name = make_string(szTableName, cbTableName, NULL);
if (!table_name)
{
***************
*** 2116,2123 ****
return SQL_ERROR;
}
! /* we need to get a list of the field names first, */
! /* so we can return them later. */
result = SQLAllocStmt(stmt->hdbc, &hcol_stmt);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
{
--- 2074,2083 ----
return SQL_ERROR;
}
! /*
! * we need to get a list of the field names first,
! * so we can return them later.
! */
result = SQLAllocStmt(stmt->hdbc, &hcol_stmt);
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
{
***************
*** 2172,2177 ****
--- 2132,2138 ----
result = SQLFetch(hcol_stmt);
}
+
if (result != SQL_NO_DATA_FOUND || total_columns == 0)
{
stmt->errormsg = SC_create_errormsg(hcol_stmt); /* "Couldn't get column
***************
*** 2205,2218 ****
result = SQLExecDirect(hindx_stmt, index_query, strlen(index_query));
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
{
! stmt->errormsg = SC_create_errormsg(hindx_stmt); /* "Couldn't execute
! * index query
! * (w/SQLExecDirect) in
! * SQLStatistics."; */
stmt->errornumber = indx_stmt->errornumber;
SQLFreeStmt(hindx_stmt, SQL_DROP);
goto SEEYA;
-
}
/* bind the index name column */
--- 2166,2180 ----
result = SQLExecDirect(hindx_stmt, index_query, strlen(index_query));
if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
{
! /*
! * "Couldn't execute index query (w/SQLExecDirect) in
! * SQLStatistics.";
! */
! stmt->errormsg = SC_create_errormsg(hindx_stmt);
!
stmt->errornumber = indx_stmt->errornumber;
SQLFreeStmt(hindx_stmt, SQL_DROP);
goto SEEYA;
}
/* bind the index name column */
***************
*** 2314,2320 ****
result = SQLFetch(hindx_stmt);
while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO))
{
-
/* If only requesting unique indexs, then just return those. */
if (fUnique == SQL_INDEX_ALL ||
(fUnique == SQL_INDEX_UNIQUE && atoi(isunique)))
--- 2276,2281 ----
***************
*** 2323,2329 ****
/* add a row in this table for each field in the index */
while (i < 16 && fields_vector[i] != 0)
{
-
row = (TupleNode *) malloc(sizeof(TupleNode) +
(13 - 1) *sizeof(TupleField));
--- 2284,2289 ----
***************
*** 2380,2387 ****
}
if (result != SQL_NO_DATA_FOUND)
{
! stmt->errormsg = SC_create_errormsg(hindx_stmt); /* "SQLFetch failed in
! * SQLStatistics."; */
stmt->errornumber = indx_stmt->errornumber;
SQLFreeStmt(hindx_stmt, SQL_DROP);
goto SEEYA;
--- 2340,2347 ----
}
if (result != SQL_NO_DATA_FOUND)
{
! /* "SQLFetch failed in SQLStatistics."; */
! stmt->errormsg = SC_create_errormsg(hindx_stmt);
stmt->errornumber = indx_stmt->errornumber;
SQLFreeStmt(hindx_stmt, SQL_DROP);
goto SEEYA;
***************
*** 2389,2396 ****
SQLFreeStmt(hindx_stmt, SQL_DROP);
! /* also, things need to think that this statement is finished so */
! /* the results can be retrieved. */
stmt->status = STMT_FINISHED;
/* set up the current tuple pointer for SQLFetch */
--- 2349,2358 ----
SQLFreeStmt(hindx_stmt, SQL_DROP);
! /*
! * also, things need to think that this statement is finished so
! * the results can be retrieved.
! */
stmt->status = STMT_FINISHED;
/* set up the current tuple pointer for SQLFetch */
***************
*** 2418,2423 ****
--- 2380,2386 ----
return SQL_SUCCESS;
}
+
RETCODE SQL_API
SQLColumnPrivileges(
HSTMT hstmt,
***************
*** 2434,2448 ****
mylog("%s: entering...\n", func);
! /* Neither Access or Borland care about this. */
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
return SQL_ERROR;
}
! /* SQLPrimaryKeys()
! * Retrieve the primary key columns for the specified table.
*/
RETCODE SQL_API
SQLPrimaryKeys(
--- 2397,2413 ----
mylog("%s: entering...\n", func);
! /* Neither Access or Borland care about this. */
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
return SQL_ERROR;
}
! /*
! * SQLPrimaryKeys()
! *
! * Retrieve the primary key columns for the specified table.
*/
RETCODE SQL_API
SQLPrimaryKeys(
***************
*** 2572,2578 ****
while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO))
{
-
row = (TupleNode *) malloc(sizeof(TupleNode) + (result_cols - 1) *sizeof(TupleField));
set_tuplefield_null(&row->tuple[0]);
--- 2537,2542 ----
***************
*** 2608,2615 ****
SQLFreeStmt(htbl_stmt, SQL_DROP);
! /* also, things need to think that this statement is finished so */
! /* the results can be retrieved. */
stmt->status = STMT_FINISHED;
/* set up the current tuple pointer for SQLFetch */
--- 2572,2581 ----
SQLFreeStmt(htbl_stmt, SQL_DROP);
! /*
! * also, things need to think that this statement is finished so
! * the results can be retrieved.
! */
stmt->status = STMT_FINISHED;
/* set up the current tuple pointer for SQLFetch */
***************
*** 2621,2626 ****
--- 2587,2593 ----
return SQL_SUCCESS;
}
+
RETCODE SQL_API
SQLForeignKeys(
HSTMT hstmt,
***************
*** 2667,2681 ****
#if (ODBCVER >= 0x0300)
SWORD defer_type;
-
#endif
char pkey[MAX_INFO_STRING];
Int2 result_cols;
- mylog("%s: entering...stmt=%u\n", func, stmt);
-
-
if (!stmt)
{
SC_log_error(func, "", NULL);
--- 2634,2645 ----
#if (ODBCVER >= 0x0300)
SWORD defer_type;
#endif
char pkey[MAX_INFO_STRING];
Int2 result_cols;
+ mylog("%s: entering...stmt=%u\n", func, stmt);
if (!stmt)
{
SC_log_error(func, "", NULL);
***************
*** 2723,2730 ****
QR_set_field_info(stmt->result, 14, "DEFERRABILITY", PG_TYPE_INT2, 2);
#endif /* ODBCVER >= 0x0300 */
! /* also, things need to think that this statement is finished so */
! /* the results can be retrieved. */
stmt->status = STMT_FINISHED;
/* set up the current tuple pointer for SQLFetch */
--- 2687,2696 ----
QR_set_field_info(stmt->result, 14, "DEFERRABILITY", PG_TYPE_INT2, 2);
#endif /* ODBCVER >= 0x0300 */
! /*
! * also, things need to think that this statement is finished so
! * the results can be retrieved.
! */
stmt->status = STMT_FINISHED;
/* set up the current tuple pointer for SQLFetch */
***************
*** 2898,2904 ****
while (result == SQL_SUCCESS)
{
-
/* Compute the number of keyparts. */
num_keys = (trig_nargs - 4) / 2;
--- 2864,2869 ----
***************
*** 2913,2919 ****
/* 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))
{
--- 2878,2883 ----
***************
*** 2932,2938 ****
return SQL_ERROR;
}
-
/* Check that the key listed is the primary key */
keyresult = SQLFetch(hpkey_stmt);
--- 2896,2901 ----
***************
*** 2949,2955 ****
num_keys = 0;
break;
}
-
/* Get to next primary key */
for (k = 0; k < 2; k++)
pkey_ptr += strlen(pkey_ptr) + 1;
--- 2912,2917 ----
***************
*** 3002,3008 ****
for (k = 0; k < num_keys; k++)
{
-
row = (TupleNode *) malloc(sizeof(TupleNode) + (result_cols - 1) *sizeof(TupleField));
mylog("%s: pk_table = '%s', pkey_ptr = '%s'\n", func, pk_table, pkey_ptr);
--- 2964,2969 ----
***************
*** 3050,3056 ****
*/
else if (pk_table_needed[0] != '\0')
{
-
sprintf(tables_query, "SELECT pg_trigger.tgargs, "
" pg_trigger.tgnargs, "
" pg_trigger.tgdeferrable, "
--- 3011,3016 ----
***************
*** 3172,3178 ****
while (result == SQL_SUCCESS)
{
-
/* Calculate the number of key parts */
num_keys = (trig_nargs - 4) / 2;;
--- 3132,3137 ----
***************
*** 3216,3222 ****
for (i = 0; i < 5; i++)
pkey_ptr += strlen(pkey_ptr) + 1;
-
/* Get to first foreign table */
fk_table = trig_args;
fk_table += strlen(fk_table) + 1;
--- 3175,3180 ----
***************
*** 3228,3234 ****
for (k = 0; k < num_keys; k++)
{
-
mylog("pkey_ptr = '%s', fk_table = '%s', fkey_ptr = '%s'\n", pkey_ptr, fk_table, fkey_ptr);
row = (TupleNode *) malloc(sizeof(TupleNode) + (result_cols - 1) *sizeof(TupleField));
--- 3186,3191 ----
***************
*** 3270,3276 ****
fkey_ptr += strlen(fkey_ptr) + 1;
}
}
-
result = SQLFetch(htbl_stmt);
}
}
--- 3227,3232 ----
***************
*** 3290,3296 ****
}
-
RETCODE SQL_API
SQLProcedureColumns(
HSTMT hstmt,
--- 3246,3251 ----
***************
*** 3311,3316 ****
--- 3266,3272 ----
return SQL_ERROR;
}
+
RETCODE SQL_API
SQLProcedures(
HSTMT hstmt,
***************
*** 3328,3333 ****
--- 3284,3290 ----
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
return SQL_ERROR;
}
+
RETCODE SQL_API
SQLTablePrivileges(
Index: src/interfaces/odbc/lobj.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/lobj.c,v
retrieving revision 1.11
diff -c -r1.11 lobj.c
*** src/interfaces/odbc/lobj.c 2001/03/27 04:00:54 1.11
--- src/interfaces/odbc/lobj.c 2001/03/28 16:53:17
***************
*** 1,4 ****
! /* Module: lobj.c
*
* Description: This module contains routines related to manipulating
* large objects.
--- 1,5 ----
! /*--------
! * Module: lobj.c
*
* Description: This module contains routines related to manipulating
* large objects.
***************
*** 8,14 ****
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
#include "lobj.h"
--- 9,15 ----
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *--------
*/
#include "lobj.h"
***************
*** 30,37 ****
return 0; /* invalid oid */
else
return retval;
-
-
}
int
--- 31,36 ----
***************
*** 40,47 ****
int fd;
int result_len;
LO_ARG argv[2];
!
!
argv[0].isint = 1;
argv[0].len = 4;
argv[0].u.integer = lobjId;
--- 39,45 ----
int fd;
int result_len;
LO_ARG argv[2];
!
argv[0].isint = 1;
argv[0].len = 4;
argv[0].u.integer = lobjId;
***************
*** 66,92 ****
int retval,
result_len;
-
argv[0].isint = 1;
argv[0].len = 4;
argv[0].u.integer = fd;
if (!CC_send_function(conn, LO_CLOSE, &retval, &result_len, 1, argv, 1))
return -1;
-
else
return retval;
-
}
-
int
lo_read(ConnectionClass *conn, int fd, char *buf, int len)
{
LO_ARG argv[2];
int result_len;
-
argv[0].isint = 1;
argv[0].len = 4;
argv[0].u.integer = fd;
--- 64,85 ----
***************
*** 97,103 ****
if (!CC_send_function(conn, LO_READ, (int *) buf, &result_len, 0, argv, 2))
return -1;
-
else
return result_len;
}
--- 90,95 ----
***************
*** 109,115 ****
int retval,
result_len;
-
if (len <= 0)
return 0;
--- 101,106 ----
***************
*** 123,129 ****
if (!CC_send_function(conn, LO_WRITE, &retval, &result_len, 1, argv, 2))
return -1;
-
else
return retval;
}
--- 114,119 ----
***************
*** 135,141 ****
int retval,
result_len;
-
argv[0].isint = 1;
argv[0].len = 4;
argv[0].u.integer = fd;
--- 125,130 ----
***************
*** 150,156 ****
if (!CC_send_function(conn, LO_LSEEK, &retval, &result_len, 1, argv, 3))
return -1;
-
else
return retval;
}
--- 139,144 ----
***************
*** 162,175 ****
int retval,
result_len;
-
argv[0].isint = 1;
argv[0].len = 4;
argv[0].u.integer = fd;
if (!CC_send_function(conn, LO_TELL, &retval, &result_len, 1, argv, 1))
return -1;
-
else
return retval;
}
--- 150,161 ----
***************
*** 181,194 ****
int retval,
result_len;
-
argv[0].isint = 1;
argv[0].len = 4;
argv[0].u.integer = lobjId;
if (!CC_send_function(conn, LO_UNLINK, &retval, &result_len, 1, argv, 1))
return -1;
-
else
return retval;
}
--- 167,178 ----
Index: src/interfaces/odbc/misc.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/misc.c,v
retrieving revision 1.20
diff -c -r1.20 misc.c
*** src/interfaces/odbc/misc.c 2001/03/27 04:00:54 1.20
--- src/interfaces/odbc/misc.c 2001/03/28 16:53:17
***************
*** 1,4 ****
! /* Module: misc.c
*
* Description: This module contains miscellaneous routines
* such as for debugging/logging and string functions.
--- 1,5 ----
! /*-------
! * Module: misc.c
*
* Description: This module contains miscellaneous routines
* such as for debugging/logging and string functions.
***************
*** 8,14 ****
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
#include <stdio.h>
--- 9,15 ----
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *-------
*/
#include <stdio.h>
***************
*** 83,89 ****
va_end(args);
}
}
-
#endif
--- 84,89 ----
***************
*** 114,120 ****
va_end(args);
}
}
-
#endif
/* Undefine these because windows.h will redefine and cause a warning */
--- 114,119 ----
***************
*** 137,143 ****
#endif
! /* returns STRCPY_FAIL, STRCPY_TRUNCATED, or #bytes copied (not including null term) */
int
my_strcpy(char *dst, int dst_len, char *src, int src_len)
{
--- 136,145 ----
#endif
! /*
! * returns STRCPY_FAIL, STRCPY_TRUNCATED, or #bytes copied
! * (not including null term)
! */
int
my_strcpy(char *dst, int dst_len, char *src, int src_len)
{
***************
*** 154,160 ****
if (src_len <= 0)
return STRCPY_FAIL;
-
else
{
if (src_len < dst_len)
--- 156,161 ----
***************
*** 173,182 ****
return strlen(dst);
}
! /* strncpy copies up to len characters, and doesn't terminate */
! /* the destination string if src has len characters or more. */
! /* instead, I want it to copy up to len-1 characters and always */
! /* terminate the destination string. */
char *
strncpy_null(char *dst, const char *src, int len)
{
--- 174,185 ----
return strlen(dst);
}
! /*
! * strncpy copies up to len characters, and doesn't terminate
! * the destination string if src has len characters or more.
! * instead, I want it to copy up to len-1 characters and always
! * terminate the destination string.
! */
char *
strncpy_null(char *dst, const char *src, int len)
{
***************
*** 185,191 ****
if (NULL != dst)
{
-
/* Just in case, check for special lengths */
if (len == SQL_NULL_DATA)
{
--- 188,193 ----
***************
*** 204,212 ****
return dst;
}
! /* Create a null terminated string (handling the SQL_NTS thing): */
! /* 1. If buf is supplied, place the string in there (assumes enough space) and return buf. */
! /* 2. If buf is not supplied, malloc space and return this string */
char *
make_string(char *s, int len, char *buf)
{
--- 206,218 ----
return dst;
}
! /*------
! * Create a null terminated string (handling the SQL_NTS thing):
! * 1. If buf is supplied, place the string in there
! * (assumes enough space) and return buf.
! * 2. If buf is not supplied, malloc space and return this string
! *------
! */
char *
make_string(char *s, int len, char *buf)
{
***************
*** 234,247 ****
return NULL;
}
! /* Concatenate a single formatted argument to a given buffer handling the SQL_NTS thing. */
! /* "fmt" must contain somewhere in it the single form '%.*s' */
! /* This is heavily used in creating queries for info routines (SQLTables, SQLColumns). */
! /* This routine could be modified to use vsprintf() to handle multiple arguments. */
char *
my_strcat(char *buf, char *fmt, char *s, int len)
{
-
if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0)))
{
int length = (len > 0) ? len : strlen(s);
--- 240,254 ----
return NULL;
}
! /*
! * Concatenate a single formatted argument to a given buffer handling the SQL_NTS thing.
! * "fmt" must contain somewhere in it the single form '%.*s'.
! * This is heavily used in creating queries for info routines (SQLTables, SQLColumns).
! * This routine could be modified to use vsprintf() to handle multiple arguments.
! */
char *
my_strcat(char *buf, char *fmt, char *s, int len)
{
if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0)))
{
int length = (len > 0) ? len : strlen(s);
Index: src/interfaces/odbc/multibyte.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/multibyte.c,v
retrieving revision 1.5
diff -c -r1.5 multibyte.c
*** src/interfaces/odbc/multibyte.c 2001/03/27 04:00:54 1.5
--- src/interfaces/odbc/multibyte.c 2001/03/28 16:53:17
***************
*** 1,10 ****
! /*
* Module : multibyte.c
*
* Description: Mlutibyte related additional function.
*
* Create 2001-03-03 Eiji Tokuya
! *
*/
#include <string.h>
--- 1,10 ----
! /*--------
* Module : multibyte.c
*
* Description: Mlutibyte related additional function.
*
* Create 2001-03-03 Eiji Tokuya
! *--------
*/
#include <string.h>
***************
*** 36,42 ****
}
break;
-
/* Chinese Big5 Support. */
case BIG5:
{
--- 36,41 ----
***************
*** 81,99 ****
return ("OHTER");
}
! /*
* Multibyte Status Function.
* Input char
* Output 0 : 1 Byte Character.
* 1 : MultibyteCharacter Last Byte.
* N : MultibyteCharacter Fast or Middle Byte.
*/
int
multibyte_char_check(unsigned char s)
{
switch (multibyte_client_encoding)
{
! /* Japanese Shift-JIS(CP932) Support. */
case SJIS:
{
if (multibyte_status < 2 && s > 0x80 && !(s > 0x9f && s < 0xE0))
--- 80,99 ----
return ("OHTER");
}
! /*--------
* Multibyte Status Function.
* Input char
* Output 0 : 1 Byte Character.
* 1 : MultibyteCharacter Last Byte.
* N : MultibyteCharacter Fast or Middle Byte.
+ *--------
*/
int
multibyte_char_check(unsigned char s)
{
switch (multibyte_client_encoding)
{
! /* Japanese Shift-JIS(CP932) Support. */
case SJIS:
{
if (multibyte_status < 2 && s > 0x80 && !(s > 0x9f && s < 0xE0))
***************
*** 104,124 ****
multibyte_status = 0;
}
break;
-
! /* Chinese Big5(CP950) Support. */
! case BIG5:
! {
! if (multibyte_status < 2 && s > 0xA0)
! multibyte_status = 2;
! else if (multibyte_status == 2)
! multibyte_status = 1;
! else
! multibyte_status = 0;
! }
! break;
! default:
! multibyte_status = 0;
}
#ifdef _DEBUG
qlog("multibyte_client_encoding = %d s = 0x%02X multibyte_stat = %d\n", multibyte_client_encoding, s,
multibyte_status);
--- 104,123 ----
multibyte_status = 0;
}
break;
! /* Chinese Big5(CP950) Support. */
! case BIG5:
! {
! if (multibyte_status < 2 && s > 0xA0)
! multibyte_status = 2;
! else if (multibyte_status == 2)
! multibyte_status = 1;
! else
! multibyte_status = 0;
! }
! break;
! default:
! multibyte_status = 0;
}
#ifdef _DEBUG
qlog("multibyte_client_encoding = %d s = 0x%02X multibyte_stat = %d\n", multibyte_client_encoding, s,
multibyte_status);
Index: src/interfaces/odbc/options.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/options.c,v
retrieving revision 1.27
diff -c -r1.27 options.c
*** src/interfaces/odbc/options.c 2001/03/27 04:00:54 1.27
--- src/interfaces/odbc/options.c 2001/03/28 16:53:18
***************
*** 1,4 ****
! /* Module: options.c
*
* Description: This module contains routines for getting/setting
* connection and statement options.
--- 1,5 ----
! /*--------
! * Module: options.c
*
* Description: This module contains routines for getting/setting
* connection and statement options.
***************
*** 9,15 ****
* SQLGetStmtOption
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
#ifdef HAVE_CONFIG_H
--- 10,16 ----
* SQLGetStmtOption
*
* Comments: See "notice.txt" for copyright and license information.
! *--------
*/
#ifdef HAVE_CONFIG_H
***************
*** 43,49 ****
UDWORD vParam);
-
RETCODE
set_statement_option(ConnectionClass *conn,
StatementClass *stmt,
--- 44,49 ----
***************
*** 53,59 ****
static char *func = "set_statement_option";
char changed = FALSE;
-
switch (fOption)
{
case SQL_ASYNC_ENABLE: /* ignored */
--- 53,58 ----
***************
*** 68,79 ****
break;
case SQL_CONCURRENCY:
-
/*
* positioned update isn't supported so cursor concurrency is
* read-only
*/
-
if (conn)
conn->stmtOptions.scroll_concurrency = vParam;
if (stmt)
--- 67,76 ----
***************
*** 104,110 ****
*/
case SQL_CURSOR_TYPE:
-
/*
* if declare/fetch, then type can only be forward. otherwise,
* it can only be forward or static.
--- 101,106 ----
***************
*** 113,130 ****
if (globals.lie)
{
-
if (conn)
conn->stmtOptions.cursor_type = vParam;
if (stmt)
stmt->options.cursor_type = vParam;
-
}
else
{
if (globals.use_declarefetch)
{
-
if (conn)
conn->stmtOptions.cursor_type = SQL_CURSOR_FORWARD_ONLY;
if (stmt)
--- 109,123 ----
***************
*** 137,143 ****
{
if (vParam == SQL_CURSOR_FORWARD_ONLY || vParam == SQL_CURSOR_STATIC)
{
-
if (conn)
conn->stmtOptions.cursor_type = vParam; /* valid type */
if (stmt)
--- 130,135 ----
***************
*** 145,151 ****
}
else
{
-
if (conn)
conn->stmtOptions.cursor_type = SQL_CURSOR_STATIC;
if (stmt)
--- 137,142 ----
***************
*** 167,180 ****
break;
! /*
! * if (globals.lie) stmt->keyset_size = vParam; else {
! * stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
! * stmt->errormsg = "Driver does not support keyset size
! * option"; SC_log_error(func, "", stmt); return SQL_ERROR; }
*/
! case SQL_MAX_LENGTH: /* ignored, but saved */
mylog("SetStmtOption(): SQL_MAX_LENGTH, vParam = %d\n", vParam);
if (conn)
conn->stmtOptions.maxLength = vParam;
--- 158,177 ----
break;
! /*-------
! * if (globals.lie)
! * stmt->keyset_size = vParam;
! * else
! * {
! * stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
! * stmt->errormsg = "Driver does not support keyset size option";
! * SC_log_error(func, "", stmt);
! * return SQL_ERROR;
! * }
! *-------
*/
! case SQL_MAX_LENGTH: /* ignored, but saved */
mylog("SetStmtOption(): SQL_MAX_LENGTH, vParam = %d\n", vParam);
if (conn)
conn->stmtOptions.maxLength = vParam;
***************
*** 182,188 ****
stmt->options.maxLength = vParam;
break;
! case SQL_MAX_ROWS: /* ignored, but saved */
mylog("SetStmtOption(): SQL_MAX_ROWS, vParam = %d\n", vParam);
if (conn)
conn->stmtOptions.maxRows = vParam;
--- 179,185 ----
stmt->options.maxLength = vParam;
break;
! case SQL_MAX_ROWS: /* ignored, but saved */
mylog("SetStmtOption(): SQL_MAX_ROWS, vParam = %d\n", vParam);
if (conn)
conn->stmtOptions.maxRows = vParam;
***************
*** 190,205 ****
stmt->options.maxRows = vParam;
break;
! case SQL_NOSCAN: /* ignored */
mylog("SetStmtOption: SQL_NOSCAN, vParam = %d\n", vParam);
break;
! case SQL_QUERY_TIMEOUT:/* ignored */
mylog("SetStmtOption: SQL_QUERY_TIMEOUT, vParam = %d\n", vParam);
/* "0" returned in SQLGetStmtOption */
break;
! case SQL_RETRIEVE_DATA:/* ignored, but saved */
mylog("SetStmtOption(): SQL_RETRIEVE_DATA, vParam = %d\n", vParam);
if (conn)
conn->stmtOptions.retrieve_data = vParam;
--- 187,202 ----
stmt->options.maxRows = vParam;
break;
! case SQL_NOSCAN: /* ignored */
mylog("SetStmtOption: SQL_NOSCAN, vParam = %d\n", vParam);
break;
! case SQL_QUERY_TIMEOUT: /* ignored */
mylog("SetStmtOption: SQL_QUERY_TIMEOUT, vParam = %d\n", vParam);
/* "0" returned in SQLGetStmtOption */
break;
! case SQL_RETRIEVE_DATA: /* ignored, but saved */
mylog("SetStmtOption(): SQL_RETRIEVE_DATA, vParam = %d\n", vParam);
if (conn)
conn->stmtOptions.retrieve_data = vParam;
***************
*** 210,216 ****
case SQL_ROWSET_SIZE:
mylog("SetStmtOption(): SQL_ROWSET_SIZE, vParam = %d\n", vParam);
-
/*
* Save old rowset size for SQLExtendedFetch purposes If the
* rowset_size is being changed since the last call to fetch
--- 207,212 ----
***************
*** 230,236 ****
conn->stmtOptions.rowset_size = vParam;
if (stmt)
stmt->options.rowset_size = vParam;
-
break;
case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */
--- 226,231 ----
***************
*** 249,255 ****
return SQL_ERROR;
case SQL_USE_BOOKMARKS:
-
if (stmt)
stmt->options.use_bookmarks = vParam;
if (conn)
--- 244,249 ----
***************
*** 298,304 ****
}
-
/* Implements only SQL_AUTOCOMMIT */
RETCODE SQL_API
SQLSetConnectOption(
--- 292,297 ----
***************
*** 320,333 ****
return SQL_INVALID_HANDLE;
}
-
switch (fOption)
{
!
! /*
! * Statement Options (apply to all stmts on the connection and
! * become defaults for new stmts)
! */
case SQL_ASYNC_ENABLE:
case SQL_BIND_TYPE:
case SQL_CONCURRENCY:
--- 313,324 ----
return SQL_INVALID_HANDLE;
}
switch (fOption)
{
! /*
! * Statement Options (apply to all stmts on the connection and
! * become defaults for new stmts)
! */
case SQL_ASYNC_ENABLE:
case SQL_BIND_TYPE:
case SQL_CONCURRENCY:
***************
*** 362,376 ****
break;
! /**********************************/
! /***** Connection Options *******/
! /**********************************/
case SQL_ACCESS_MODE: /* ignored */
break;
case SQL_AUTOCOMMIT:
-
if (CC_is_in_trans(conn))
{
conn->errormsg = "Cannot switch commit mode while a transaction is in progress";
--- 353,366 ----
break;
! /*
! * Connection Options
! */
case SQL_ACCESS_MODE: /* ignored */
break;
case SQL_AUTOCOMMIT:
if (CC_is_in_trans(conn))
{
conn->errormsg = "Cannot switch commit mode while a transaction is in progress";
***************
*** 397,409 ****
CC_log_error(func, "", conn);
return SQL_ERROR;
}
-
break;
case SQL_CURRENT_QUALIFIER: /* ignored */
break;
! case SQL_LOGIN_TIMEOUT:/* ignored */
break;
case SQL_PACKET_SIZE: /* ignored */
--- 387,398 ----
CC_log_error(func, "", conn);
return SQL_ERROR;
}
break;
case SQL_CURRENT_QUALIFIER: /* ignored */
break;
! case SQL_LOGIN_TIMEOUT: /* ignored */
break;
case SQL_PACKET_SIZE: /* ignored */
***************
*** 412,421 ****
case SQL_QUIET_MODE: /* ignored */
break;
! case SQL_TXN_ISOLATION:/* ignored */
break;
! /* These options should be handled by driver manager */
case SQL_ODBC_CURSORS:
case SQL_OPT_TRACE:
case SQL_OPT_TRACEFILE:
--- 401,410 ----
case SQL_QUIET_MODE: /* ignored */
break;
! case SQL_TXN_ISOLATION: /* ignored */
break;
! /* These options should be handled by driver manager */
case SQL_ODBC_CURSORS:
case SQL_OPT_TRACE:
case SQL_OPT_TRACEFILE:
***************
*** 434,440 ****
CC_log_error(func, option, conn);
return SQL_ERROR;
}
-
}
if (changed)
--- 423,428 ----
***************
*** 447,453 ****
return SQL_SUCCESS;
}
- /* - - - - - - - - - */
/* This function just can tell you whether you are in Autcommit mode or not */
RETCODE SQL_API
--- 435,440 ----
***************
*** 469,475 ****
switch (fOption)
{
! case SQL_ACCESS_MODE: /* NOT SUPPORTED */
*((UDWORD *) pvParam) = SQL_MODE_READ_WRITE;
break;
--- 456,462 ----
switch (fOption)
{
! case SQL_ACCESS_MODE: /* NOT SUPPORTED */
*((UDWORD *) pvParam) = SQL_MODE_READ_WRITE;
break;
***************
*** 484,506 ****
break;
! case SQL_LOGIN_TIMEOUT:/* NOT SUPPORTED */
*((UDWORD *) pvParam) = 0;
break;
! case SQL_PACKET_SIZE: /* NOT SUPPORTED */
*((UDWORD *) pvParam) = globals.socket_buffersize;
break;
! case SQL_QUIET_MODE: /* NOT SUPPORTED */
*((UDWORD *) pvParam) = (UDWORD) NULL;
break;
! case SQL_TXN_ISOLATION:/* NOT SUPPORTED */
*((UDWORD *) pvParam) = SQL_TXN_SERIALIZABLE;
break;
! /* These options should be handled by driver manager */
case SQL_ODBC_CURSORS:
case SQL_OPT_TRACE:
case SQL_OPT_TRACEFILE:
--- 471,493 ----
break;
! case SQL_LOGIN_TIMEOUT: /* NOT SUPPORTED */
*((UDWORD *) pvParam) = 0;
break;
! case SQL_PACKET_SIZE: /* NOT SUPPORTED */
*((UDWORD *) pvParam) = globals.socket_buffersize;
break;
! case SQL_QUIET_MODE: /* NOT SUPPORTED */
*((UDWORD *) pvParam) = (UDWORD) NULL;
break;
! case SQL_TXN_ISOLATION: /* NOT SUPPORTED */
*((UDWORD *) pvParam) = SQL_TXN_SERIALIZABLE;
break;
! /* These options should be handled by driver manager */
case SQL_ODBC_CURSORS:
case SQL_OPT_TRACE:
case SQL_OPT_TRACEFILE:
***************
*** 520,532 ****
return SQL_ERROR;
break;
}
-
}
return SQL_SUCCESS;
}
- /* - - - - - - - - - */
RETCODE SQL_API
SQLSetStmtOption(
--- 507,517 ----
***************
*** 538,548 ****
StatementClass *stmt = (StatementClass *) hstmt;
mylog("%s: entering...\n", func);
-
- /* thought we could fake Access out by just returning SQL_SUCCESS */
- /* all the time, but it tries to set a huge value for SQL_MAX_LENGTH */
- /* and expects the driver to reduce it to the real value */
if (!stmt)
{
SC_log_error(func, "", NULL);
--- 523,534 ----
StatementClass *stmt = (StatementClass *) hstmt;
mylog("%s: entering...\n", func);
+ /*
+ * Though we could fake Access out by just returning SQL_SUCCESS
+ * all the time, but it tries to set a huge value for SQL_MAX_LENGTH
+ * and expects the driver to reduce it to the real value.
+ */
if (!stmt)
{
SC_log_error(func, "", NULL);
***************
*** 553,560 ****
}
- /* - - - - - - - - - */
-
RETCODE SQL_API
SQLGetStmtOption(
HSTMT hstmt,
--- 539,544 ----
***************
*** 566,576 ****
QResultClass *res;
mylog("%s: entering...\n", func);
-
- /* thought we could fake Access out by just returning SQL_SUCCESS */
- /* all the time, but it tries to set a huge value for SQL_MAX_LENGTH */
- /* and expects the driver to reduce it to the real value */
if (!stmt)
{
SC_log_error(func, "", NULL);
--- 550,561 ----
QResultClass *res;
mylog("%s: entering...\n", func);
+ /*
+ * thought we could fake Access out by just returning SQL_SUCCESS
+ * all the time, but it tries to set a huge value for SQL_MAX_LENGTH
+ * and expects the driver to reduce it to the real value
+ */
if (!stmt)
{
SC_log_error(func, "", NULL);
***************
*** 689,693 ****
return SQL_SUCCESS;
}
-
- /* - - - - - - - - - */
--- 674,676 ----
Index: src/interfaces/odbc/parse.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/parse.c,v
retrieving revision 1.16
diff -c -r1.16 parse.c
*** src/interfaces/odbc/parse.c 2001/03/27 04:00:54 1.16
--- src/interfaces/odbc/parse.c 2001/03/28 16:53:18
***************
*** 1,20 ****
! /* Module: parse.c
*
! * Description: This module contains routines related to parsing SQL statements.
! * This can be useful for two reasons:
*
! * 1. So the query does not actually have to be executed to return data about it
*
! * 2. To be able to return information about precision, nullability, aliases, etc.
! * in the functions SQLDescribeCol and SQLColAttributes. Currently, Postgres
! * doesn't return any information about these things in a query.
*
* Classes: none
*
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
/* Multibyte support Eiji Tokuya 2001-03-15 */
--- 1,24 ----
! /*--------
! * Module: parse.c
*
! * Description: This module contains routines related to parsing SQL
! * statements. This can be useful for two reasons:
*
! * 1. So the query does not actually have to be executed
! * to return data about it
*
! * 2. To be able to return information about precision,
! * nullability, aliases, etc. in the functions
! * SQLDescribeCol and SQLColAttributes. Currently,
! * Postgres doesn't return any information about
! * these things in a query.
*
* Classes: none
*
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *--------
*/
/* Multibyte support Eiji Tokuya 2001-03-15 */
***************
*** 87,93 ****
while (!isspace((unsigned char) s[i]) && s[i] != ',' &&
s[i] != '\0' && out != smax)
{
-
/* Handle quoted stuff */
if (out == 0 && (s[i] == '\"' || s[i] == '\''))
{
--- 91,96 ----
***************
*** 225,237 ****
fi->display_size = atoi(QR_get_value_manual(col_info->result, k, 12));
}
char
searchColInfo(COL_INFO *col_info, FIELD_INFO *fi)
{
int k;
char *col;
-
for (k = 0; k < QR_get_num_tuples(col_info->result); k++)
{
col = QR_get_value_manual(col_info->result, k, 3);
--- 228,240 ----
fi->display_size = atoi(QR_get_value_manual(col_info->result, k, 12));
}
+
char
searchColInfo(COL_INFO *col_info, FIELD_INFO *fi)
{
int k;
char *col;
for (k = 0; k < QR_get_num_tuples(col_info->result); k++)
{
col = QR_get_value_manual(col_info->result, k, 3);
***************
*** 283,289 ****
StatementClass *col_stmt;
RETCODE result;
-
mylog("%s: entering...\n", func);
ptr = stmt->statement;
--- 286,291 ----
***************
*** 295,301 ****
while ((ptr = getNextToken(ptr, token, sizeof(token), &delim, "e, &dquote, &numeric)) != NULL)
{
-
unquoted = !(quote || dquote);
mylog("unquoted=%d, quote=%d, dquote=%d, numeric=%d, delim='%c', token='%s', ptr='%s'\n", unquoted, quote,
dquote,numeric, delim, token, ptr);
--- 297,302 ----
***************
*** 339,345 ****
!stricmp(token, "group") ||
!stricmp(token, "having")))
{
-
in_select = FALSE;
in_from = FALSE;
in_where = TRUE;
--- 340,345 ----
***************
*** 350,356 ****
if (in_select)
{
-
if (in_distinct)
{
mylog("in distinct\n");
--- 350,355 ----
***************
*** 372,378 ****
}
if (in_expr || in_func)
! { /* just eat the expression */
mylog("in_expr=%d or func=%d\n", in_expr, in_func);
if (quote || dquote)
continue;
--- 371,378 ----
}
if (in_expr || in_func)
! {
! /* just eat the expression */
mylog("in_expr=%d or func=%d\n", in_expr, in_func);
if (quote || dquote)
continue;
***************
*** 383,389 ****
in_expr = FALSE;
in_field = FALSE;
}
-
else if (token[0] == '(')
{
blevel++;
--- 383,388 ----
***************
*** 405,411 ****
if (!in_field)
{
-
if (!token[0])
continue;
--- 404,409 ----
***************
*** 453,459 ****
blevel = 1;
continue;
}
-
else
{
strcpy(fi[stmt->nfld]->name, token);
--- 451,456 ----
***************
*** 469,477 ****
continue;
}
! /**************************/
! /* We are in a field now */
! /**************************/
if (in_dot)
{
stmt->nfld--;
--- 466,474 ----
continue;
}
! /*
! * We are in a field now
! */
if (in_dot)
{
stmt->nfld--;
***************
*** 485,491 ****
mylog("in_dot: got comma\n");
in_field = FALSE;
}
-
continue;
}
--- 482,487 ----
***************
*** 538,549 ****
fi[stmt->nfld - 1]->expr = TRUE;
fi[stmt->nfld - 1]->name[0] = '\0';
mylog("*** setting expression\n");
-
}
if (in_from)
{
-
if (!in_table)
{
if (!token[0])
--- 534,543 ----
***************
*** 586,603 ****
mylog("more than 1 tables\n");
}
}
-
! /*************************************************/
! /* Resolve any possible field names with tables */
! /*************************************************/
parse = TRUE;
/* Resolve field names with tables */
for (i = 0; i < stmt->nfld; i++)
{
-
if (fi[i]->func || fi[i]->expr || fi[i]->numeric)
{
fi[i]->ti = NULL;
--- 580,595 ----
mylog("more than 1 tables\n");
}
}
! /*
! * Resolve any possible field names with tables
! */
parse = TRUE;
/* Resolve field names with tables */
for (i = 0; i < stmt->nfld; i++)
{
if (fi[i]->func || fi[i]->expr || fi[i]->numeric)
{
fi[i]->ti = NULL;
***************
*** 605,611 ****
parse = FALSE;
continue;
}
-
else if (fi[i]->quote)
{ /* handle as text */
fi[i]->ti = NULL;
--- 597,602 ----
***************
*** 613,619 ****
fi[i]->precision = 0;
continue;
}
-
/* it's a dot, resolve to table or alias */
else if (fi[i]->dot[0])
{
--- 604,609 ----
***************
*** 648,663 ****
for (i = 0; i < stmt->ntab; i++)
mylog("Table %d: name='%s', alias='%s'\n", i, ti[i]->name, ti[i]->alias);
-
- /******************************************************/
- /* Now save the SQLColumns Info for the parse tables */
- /******************************************************/
/* Call SQLColumns for each table and store the result */
for (i = 0; i < stmt->ntab; i++)
{
-
/* See if already got it */
char found = FALSE;
--- 638,651 ----
for (i = 0; i < stmt->ntab; i++)
mylog("Table %d: name='%s', alias='%s'\n", i, ti[i]->name, ti[i]->alias);
+ /*
+ * Now save the SQLColumns Info for the parse tables
+ */
/* Call SQLColumns for each table and store the result */
for (i = 0; i < stmt->ntab; i++)
{
/* See if already got it */
char found = FALSE;
***************
*** 673,679 ****
if (!found)
{
-
mylog("PARSE: Getting SQLColumns for table[%d]='%s'\n", i, ti[i]->name);
result = SQLAllocStmt(stmt->hdbc, &hcol_stmt);
--- 661,666 ----
***************
*** 697,703 ****
mylog(" Success\n");
if (!(conn->ntables % COL_INCR))
{
-
mylog("PARSE: Allocing col_info at ntables=%d\n", conn->ntables);
conn->col_info = (COL_INFO **) realloc(conn->col_info, (conn->ntables + COL_INCR) *
sizeof(COL_INFO*));
--- 684,689 ----
***************
*** 746,763 ****
mylog("associate col_info: i=%d, k=%d\n", i, k);
}
-
mylog("Done SQLColumns\n");
-
- /******************************************************/
- /* Now resolve the fields to point to column info */
- /******************************************************/
-
!
for (i = 0; i < stmt->nfld;)
{
-
/* Dont worry about functions or quotes */
if (fi[i]->func || fi[i]->quote || fi[i]->numeric)
{
--- 732,744 ----
mylog("associate col_info: i=%d, k=%d\n", i, k);
}
mylog("Done SQLColumns\n");
! /*
! * Now resolve the fields to point to column info
! */
for (i = 0; i < stmt->nfld;)
{
/* Dont worry about functions or quotes */
if (fi[i]->func || fi[i]->quote || fi[i]->numeric)
{
***************
*** 768,774 ****
/* Stars get expanded to all fields in the table */
else if (fi[i]->name[0] == '*')
{
-
char do_all_tables;
int total_cols,
old_alloc,
--- 749,754 ----
***************
*** 794,800 ****
increased_cols = total_cols - 1;
/* Allocate some more field pointers if necessary */
- /*------------------------------------------------------------- */
old_alloc = ((stmt->nfld - 1) / FLD_INCR + 1) * FLD_INCR;
new_size = stmt->nfld + increased_cols;
--- 774,779 ----
***************
*** 814,821 ****
stmt->fi = fi;
}
- /*------------------------------------------------------------- */
-
/*
* copy any other fields (if there are any) up past the
* expansion
--- 793,798 ----
***************
*** 827,847 ****
}
mylog("done copying fields\n");
- /*------------------------------------------------------------- */
/* Set the new number of fields */
stmt->nfld += increased_cols;
mylog("stmt->nfld now at %d\n", stmt->nfld);
- /*------------------------------------------------------------- */
/* copy the new field info */
-
-
do_all_tables = (fi[i]->ti ? FALSE : TRUE);
for (k = 0; k < (do_all_tables ? stmt->ntab : 1); k++)
{
-
TABLE_INFO *the_ti = do_all_tables ? ti[k] : fi[i]->ti;
cols = QR_get_num_tuples(the_ti->col_info->result);
--- 804,819 ----
***************
*** 874,881 ****
i += cols;
mylog("i now at %d\n", i);
}
-
- /*------------------------------------------------------------- */
}
/*
--- 846,851 ----
***************
*** 885,891 ****
*/
else if (fi[i]->ti)
{
-
if (!searchColInfo(fi[i]->ti->col_info, fi[i]))
parse = FALSE;
--- 855,860 ----
***************
*** 909,920 ****
}
}
-
if (!parse)
stmt->parse_status = STMT_PARSE_INCOMPLETE;
else
stmt->parse_status = STMT_PARSE_COMPLETE;
-
mylog("done parse_statement: parse=%d, parse_status=%d\n", parse, stmt->parse_status);
return parse;
--- 878,887 ----
Index: src/interfaces/odbc/pgtypes.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/pgtypes.c,v
retrieving revision 1.24
diff -c -r1.24 pgtypes.c
*** src/interfaces/odbc/pgtypes.c 2001/03/27 04:00:54 1.24
--- src/interfaces/odbc/pgtypes.c 2001/03/28 16:53:18
***************
*** 1,17 ****
! /* Module: pgtypes.c
*
* 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).
*
* Classes: n/a
*
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
#ifdef HAVE_CONFIG_H
--- 1,19 ----
! /*--------
! * Module: pgtypes.c
*
* 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).
*
* Classes: n/a
*
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *--------
*/
#ifdef HAVE_CONFIG_H
***************
*** 40,54 ****
Int4 getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
! /* 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.) */
- /* ALL THESE TYPES ARE NO LONGER REPORTED in SQLGetTypeInfo. Instead, all
- the SQL TYPES are reported and mapped to a corresponding Postgres Type
- */
/*
Int4 pgtypes_defined[] = {
PG_TYPE_CHAR,
--- 42,59 ----
Int4 getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as);
+ /*
+ * 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.)
+ */
! /*
! * ALL THESE TYPES ARE NO LONGER REPORTED in SQLGetTypeInfo. Instead, all
! * the SQL TYPES are reported and mapped to a corresponding Postgres Type
! */
/*
Int4 pgtypes_defined[] = {
PG_TYPE_CHAR,
***************
*** 109,115 ****
switch (fSqlType)
{
-
case SQL_BINARY:
pgType = PG_TYPE_BYTEA;
break;
--- 114,119 ----
***************
*** 185,199 ****
return pgType;
}
! /* 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.
! */
Int2
pgtype_to_sqltype(StatementClass *stmt, Int4 type)
{
--- 189,206 ----
return pgType;
}
! /*
! * 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.
! */
Int2
pgtype_to_sqltype(StatementClass *stmt, Int4 type)
{
***************
*** 228,234 ****
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;
--- 235,241 ----
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;
***************
*** 253,266 ****
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;
--- 260,272 ----
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.
*/
! /* hack until permanent type is available */
! if (type == stmt->hdbc->lobj_type)
return SQL_LONGVARBINARY;
return globals.unknowns_as_longvarchar ? SQL_LONGVARCHAR : SQL_VARCHAR;
***************
*** 305,313 ****
return SQL_C_BINARY;
default:
!
! if (type == stmt->hdbc->lobj_type) /* hack until permanent
! * type is available */
return SQL_C_BINARY;
return SQL_C_CHAR;
--- 311,318 ----
return SQL_C_BINARY;
default:
! /* hack until permanent type is available */
! if (type == stmt->hdbc->lobj_type)
return SQL_C_BINARY;
return SQL_C_CHAR;
***************
*** 319,325 ****
{
switch (type)
{
! case PG_TYPE_CHAR:return "char";
case PG_TYPE_CHAR2:
return "char2";
case PG_TYPE_CHAR4:
--- 324,330 ----
{
switch (type)
{
! case PG_TYPE_CHAR:return "char";
case PG_TYPE_CHAR2:
return "char2";
case PG_TYPE_CHAR4:
***************
*** 369,376 ****
return PG_TYPE_LO_NAME;
default:
! if (type == stmt->hdbc->lobj_type) /* hack until permanent
! * type is available */
return PG_TYPE_LO_NAME;
/*
--- 374,381 ----
return PG_TYPE_LO_NAME;
default:
! /* hack until permanent type is available */
! if (type == stmt->hdbc->lobj_type)
return PG_TYPE_LO_NAME;
/*
***************
*** 524,542 ****
return p;
}
! /* 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.
! */
Int4
pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
{
-
switch (type)
{
-
case PG_TYPE_CHAR:
return 1;
case PG_TYPE_CHAR2:
--- 529,546 ----
return p;
}
! /*
! * 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.
! */
Int4
pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
{
switch (type)
{
case PG_TYPE_CHAR:
return 1;
case PG_TYPE_CHAR2:
***************
*** 600,606 ****
Int4
pgtype_display_size(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
{
-
switch (type)
{
case PG_TYPE_INT2:
--- 604,609 ----
***************
*** 628,649 ****
case PG_TYPE_FLOAT8:
return 22;
! /* Character types use regular precision */
default:
return pgtype_precision(stmt, type, col, handle_unknown_size_as);
}
}
! /* For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, SQLColumns will
! override this length with the atttypmod length from pg_attribute
! */
Int4
pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
{
-
switch (type)
{
-
case PG_TYPE_INT2:
return 2;
--- 631,651 ----
case PG_TYPE_FLOAT8:
return 22;
! /* Character types use regular precision */
default:
return pgtype_precision(stmt, type, col, handle_unknown_size_as);
}
}
! /*
! * For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, SQLColumns will
! * override this length with the atttypmod length from pg_attribute
! */
Int4
pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as)
{
switch (type)
{
case PG_TYPE_INT2:
return 2;
***************
*** 673,681 ****
case PG_TYPE_DATETIME:
case PG_TYPE_TIMESTAMP:
return 16;
-
! /* Character types (and NUMERIC) use the default precision */
default:
return pgtype_precision(stmt, type, col, handle_unknown_size_as);
}
--- 675,682 ----
case PG_TYPE_DATETIME:
case PG_TYPE_TIMESTAMP:
return 16;
! /* Character types (and NUMERIC) use the default precision */
default:
return pgtype_precision(stmt, type, col, handle_unknown_size_as);
}
***************
*** 686,692 ****
{
switch (type)
{
-
case PG_TYPE_INT2:
case PG_TYPE_OID:
case PG_TYPE_XID:
--- 687,692 ----
***************
*** 697,706 ****
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:
--- 697,706 ----
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:
***************
*** 729,740 ****
case PG_TYPE_MONEY:
case PG_TYPE_FLOAT8:
return 10;
-
default:
return -1;
}
}
Int2
pgtype_nullable(StatementClass *stmt, Int4 type)
{
--- 729,740 ----
case PG_TYPE_MONEY:
case PG_TYPE_FLOAT8:
return 10;
default:
return -1;
}
}
+
Int2
pgtype_nullable(StatementClass *stmt, Int4 type)
{
***************
*** 746,752 ****
{
switch (type)
{
-
case PG_TYPE_INT2:
case PG_TYPE_OID:
case PG_TYPE_XID:
--- 746,751 ----
***************
*** 853,859 ****
{
switch (type)
{
-
case PG_TYPE_INT2:
case PG_TYPE_OID:
case PG_TYPE_XID:
--- 852,857 ----
***************
*** 874,880 ****
{
switch (type)
{
-
case PG_TYPE_INT2:
case PG_TYPE_OID:
case PG_TYPE_XID:
--- 872,877 ----
***************
*** 895,902 ****
{
switch (type)
{
! case PG_TYPE_CHAR:
! case PG_TYPE_VARCHAR:return "max. length";
default:
return NULL;
}
--- 892,899 ----
{
switch (type)
{
! case PG_TYPE_CHAR:
! case PG_TYPE_VARCHAR:return "max. length";
default:
return NULL;
}
***************
*** 906,913 ****
Int2
sqltype_to_default_ctype(Int2 sqltype)
{
! /* from the table on page 623 of ODBC 2.0 Programmer's Reference */
! /* (Appendix D) */
switch (sqltype)
{
case SQL_CHAR:
--- 903,912 ----
Int2
sqltype_to_default_ctype(Int2 sqltype)
{
! /*
! * from the table on page 623 of ODBC 2.0 Programmer's Reference
! * (Appendix D)
! */
switch (sqltype)
{
case SQL_CHAR:
***************
*** 951,957 ****
case SQL_TIMESTAMP:
return SQL_C_TIMESTAMP;
! default: /* should never happen */
return SQL_C_CHAR;
}
}
--- 950,957 ----
case SQL_TIMESTAMP:
return SQL_C_TIMESTAMP;
! default:
! /* should never happen */
return SQL_C_CHAR;
}
}
Index: src/interfaces/odbc/psqlodbc.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/psqlodbc.c,v
retrieving revision 1.15
diff -c -r1.15 psqlodbc.c
*** src/interfaces/odbc/psqlodbc.c 2001/03/27 04:00:54 1.15
--- src/interfaces/odbc/psqlodbc.c 2001/03/28 16:53:19
***************
*** 1,15 ****
! /* Module: psqlodbc.c
*
! * Description: This module contains the main entry point (DllMain) for the library.
! * It also contains functions to get and set global variables for the
! * driver in the registry.
*
* Classes: n/a
*
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
#ifdef HAVE_CONFIG_H
--- 1,16 ----
! /*--------
! * Module: psqlodbc.c
*
! * Description: This module contains the main entry point (DllMain)
! * for the library. It also contains functions to get
! * and set global variables for the driver in the registry.
*
* Classes: n/a
*
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *--------
*/
#ifdef HAVE_CONFIG_H
***************
*** 59,65 ****
if (LOBYTE(wsaData.wVersion) != 1 ||
HIBYTE(wsaData.wVersion) != 1)
{
-
WSACleanup();
return FALSE;
}
--- 60,65 ----
***************
*** 71,79 ****
break;
case DLL_PROCESS_DETACH:
-
WSACleanup();
-
return TRUE;
case DLL_THREAD_DETACH:
--- 71,77 ----
***************
*** 111,117 ****
#else /* not __GNUC__ */
! /* These two functions do shared library initialziation on UNIX, well at least
* on Linux. I don't know about other systems.
*/
BOOL
--- 109,116 ----
#else /* not __GNUC__ */
! /*
! * These two functions do shared library initialziation on UNIX, well at least
* on Linux. I don't know about other systems.
*/
BOOL
***************
*** 131,142 ****
#endif /* not WIN32 */
! /* This function is used to cause the Driver Manager to
! call functions by number rather than name, which is faster.
! The ordinal value of this function must be 199 to have the
! Driver Manager do this. Also, the ordinal values of the
! functions must match the value of fFunction in SQLGetFunctions()
! */
RETCODE SQL_API
SQLDummyOrdinal(void)
{
--- 130,142 ----
#endif /* not WIN32 */
! /*
! * This function is used to cause the Driver Manager to
! * call functions by number rather than name, which is faster.
! * The ordinal value of this function must be 199 to have the
! * Driver Manager do this. Also, the ordinal values of the
! * functions must match the value of fFunction in SQLGetFunctions()
! */
RETCODE SQL_API
SQLDummyOrdinal(void)
{
Index: src/interfaces/odbc/qresult.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/qresult.c,v
retrieving revision 1.21
diff -c -r1.21 qresult.c
*** src/interfaces/odbc/qresult.c 2001/03/27 04:00:55 1.21
--- src/interfaces/odbc/qresult.c 2001/03/28 16:53:19
***************
*** 1,20 ****
! /* Module: qresult.c
*
* Description: This module contains functions related to
! * managing result information (i.e, fetching rows from the backend,
! * managing the tuple cache, etc.) and retrieving it.
! * Depending on the situation, a QResultClass will hold either data
! * from the backend or a manually built result (see "qresult.h" to
! * see which functions/macros are for manual or backend results.
! * For manually built results, the QResultClass simply points to
! * TupleList and ColumnInfo structures, which actually hold the data.
*
* Classes: QResultClass (Functions prefix: "QR_")
*
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
#include "qresult.h"
--- 1,23 ----
! /*---------
! * Module: qresult.c
*
* Description: This module contains functions related to
! * managing result information (i.e, fetching rows
! * from the backend, managing the tuple cache, etc.)
! * and retrieving it. Depending on the situation, a
! * QResultClass will hold either data from the backend
! * or a manually built result (see "qresult.h" to
! * see which functions/macros are for manual or backend
! * results. For manually built results, the
! * QResultClass simply points to TupleList and
! * ColumnInfo structures, which actually hold the data.
*
* Classes: QResultClass (Functions prefix: "QR_")
*
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *---------
*/
#include "qresult.h"
***************
*** 31,38 ****
extern GLOBAL_VALUES globals;
! /* Used for building a Manual Result only */
! /* All info functions call this function to create the manual result set. */
void
QR_set_num_fields(QResultClass *self, int new_num_fields)
{
--- 34,43 ----
extern GLOBAL_VALUES globals;
! /*
! * Used for building a Manual Result only
! * All info functions call this function to create the manual result set.
! */
void
QR_set_num_fields(QResultClass *self, int new_num_fields)
{
***************
*** 70,80 ****
{
self->base += base_inc;
}
-
- /************************************/
- /* CLASS QResult */
- /************************************/
QResultClass *
QR_Constructor(void)
{
--- 75,84 ----
{
self->base += base_inc;
}
+ /*
+ * CLASS QResult
+ */
QResultClass *
QR_Constructor(void)
{
***************
*** 111,117 ****
rv->cache_size = globals.fetch_max;
rv->rowset_size = 1;
-
}
mylog("exit QR_Constructor\n");
--- 115,120 ----
***************
*** 127,134 ****
if (self->manual_tuples)
TL_Destructor(self->manual_tuples);
! /* If conn is defined, then we may have used "backend_tuples", */
! /* so in case we need to, free it up. Also, close the cursor. */
if (self->conn && self->conn->sock && CC_is_in_trans(self->conn))
QR_close(self); /* close the cursor if there is one */
--- 130,139 ----
if (self->manual_tuples)
TL_Destructor(self->manual_tuples);
! /*
! * If conn is defined, then we may have used "backend_tuples",
! * so in case we need to, free it up. Also, close the cursor.
! */
if (self->conn && self->conn->sock && CC_is_in_trans(self->conn))
QR_close(self); /* close the cursor if there is one */
***************
*** 153,159 ****
free(self);
mylog("QResult: exit DESTRUCTOR\n");
-
}
void
--- 158,163 ----
***************
*** 187,193 ****
if (self->backend_tuples)
{
-
for (row = 0; row < fcount; row++)
{
mylog("row = %d, num_fields = %d\n", row, num_fields);
--- 191,196 ----
***************
*** 217,227 ****
{
int tuple_size;
! /* If called from send_query the first time (conn != NULL), */
! /* then set the inTuples state, */
! /* and read the tuples. If conn is NULL, */
! /* it implies that we are being called from next_tuple(), */
! /* like to get more rows so don't call next_tuple again! */
if (conn != NULL)
{
self->conn = conn;
--- 220,232 ----
{
int tuple_size;
! /*
! * If called from send_query the first time (conn != NULL),
! * then set the inTuples state,
! * and read the tuples. If conn is NULL,
! * it implies that we are being called from next_tuple(),
! * like to get more rows so don't call next_tuple again!
! */
if (conn != NULL)
{
self->conn = conn;
***************
*** 242,249 ****
self->cursor = strdup(cursor);
}
! /* Read the field attributes. */
! /* $$$$ Should do some error control HERE! $$$$ */
if (CI_read_fields(self->fields, self->conn))
{
self->status = PGRES_FIELDS_OK;
--- 247,257 ----
self->cursor = strdup(cursor);
}
! /*
! * Read the field attributes.
! *
! * $$$$ Should do some error control HERE! $$$$
! */
if (CI_read_fields(self->fields, self->conn))
{
self->status = PGRES_FIELDS_OK;
***************
*** 275,281 ****
self->inTuples = TRUE;
-
/* Force a read to occur in next_tuple */
self->fcount = tuple_size + 1;
self->fetch_count = tuple_size + 1;
--- 283,288 ----
***************
*** 285,293 ****
}
else
{
!
! /* Always have to read the field attributes. */
! /* But we dont have to reallocate memory for them! */
if (!CI_read_fields(NULL, self->conn))
{
--- 292,301 ----
}
else
{
! /*
! * Always have to read the field attributes.
! * But we dont have to reallocate memory for them!
! */
if (!CI_read_fields(NULL, self->conn))
{
***************
*** 299,306 ****
}
}
! /* Close the cursor and end the transaction (if no cursors left) */
! /* We only close cursor/end the transaction if a cursor was used. */
int
QR_close(QResultClass *self)
{
--- 307,316 ----
}
}
! /*
! * Close the cursor and end the transaction (if no cursors left)
! * We only close cursor/end the transaction if a cursor was used.
! */
int
QR_close(QResultClass *self)
{
***************
*** 346,352 ****
}
QR_Destructor(res);
}
-
}
return TRUE;
--- 356,361 ----
***************
*** 360,366 ****
QResultClass *res;
SocketClass *sock;
! /* Speed up access */
int fetch_count = self->fetch_count;
int fcount = self->fcount;
int fetch_size,
--- 369,375 ----
QResultClass *res;
SocketClass *sock;
! /* Speed up access */
int fetch_count = self->fetch_count;
int fcount = self->fcount;
int fetch_size,
***************
*** 369,398 ****
char corrected = FALSE;
TupleField *the_tuples = self->backend_tuples;
static char msgbuffer[MAX_MESSAGE_LEN + 1];
! char cmdbuffer[MAX_MESSAGE_LEN + 1]; /* QR_set_command() dups
! * this string so dont
! * need static */
char fetch[128];
QueryInfo qi;
if (fetch_count < fcount)
! { /* return a row from cache */
mylog("next_tuple: fetch_count < fcount: returning tuple %d, fcount = %d\n", fetch_count, fcount);
self->tupleField = the_tuples + (fetch_count * self->num_fields); /* next row */
self->fetch_count++;
return TRUE;
}
else if (self->fcount < self->cache_size)
! { /* last row from cache */
/* We are done because we didn't even get CACHE_SIZE tuples */
mylog("next_tuple: fcount < CACHE_SIZE: fcount = %d, fetch_count = %d\n", fcount, fetch_count);
self->tupleField = NULL;
self->status = PGRES_END_TUPLES;
! return -1; /* end of tuples */
}
else
{
-
/*
* See if we need to fetch another group of rows. We may be being
* called from send_query(), and if so, don't send another fetch,
--- 378,408 ----
char corrected = FALSE;
TupleField *the_tuples = self->backend_tuples;
static char msgbuffer[MAX_MESSAGE_LEN + 1];
! /* QR_set_command() dups this string so don't need static */
! char cmdbuffer[MAX_MESSAGE_LEN + 1];
char fetch[128];
QueryInfo qi;
if (fetch_count < fcount)
! {
! /* return a row from cache */
mylog("next_tuple: fetch_count < fcount: returning tuple %d, fcount = %d\n", fetch_count, fcount);
self->tupleField = the_tuples + (fetch_count * self->num_fields); /* next row */
self->fetch_count++;
return TRUE;
}
else if (self->fcount < self->cache_size)
! {
! /* last row from cache */
/* We are done because we didn't even get CACHE_SIZE tuples */
mylog("next_tuple: fcount < CACHE_SIZE: fcount = %d, fetch_count = %d\n", fcount, fetch_count);
self->tupleField = NULL;
self->status = PGRES_END_TUPLES;
! /* end of tuples */
! return -1;
}
else
{
/*
* See if we need to fetch another group of rows. We may be being
* called from send_query(), and if so, don't send another fetch,
***************
*** 402,408 ****
if (!self->inTuples)
{
-
if (!globals.use_declarefetch)
{
mylog("next_tuple: ALL_ROWS: done, fcount = %d, fetch_count = %d\n", fcount, fetch_count);
--- 412,417 ----
***************
*** 412,419 ****
}
if (self->base == fcount)
! { /* not a correction */
!
/* Determine the optimum cache size. */
if (globals.fetch_max % self->rowset_size == 0)
fetch_size = globals.fetch_max;
--- 421,428 ----
}
if (self->base == fcount)
! {
! /* not a correction */
/* Determine the optimum cache size. */
if (globals.fetch_max % self->rowset_size == 0)
fetch_size = globals.fetch_max;
***************
*** 426,433 ****
self->fetch_count = 1;
}
else
! { /* need to correct */
!
corrected = TRUE;
fetch_size = end_tuple - fcount;
--- 435,442 ----
self->fetch_count = 1;
}
else
! {
! /* need to correct */
corrected = TRUE;
fetch_size = end_tuple - fcount;
***************
*** 436,445 ****
offset = self->fetch_count;
self->fetch_count++;
-
}
-
self->backend_tuples = (TupleField *) realloc(self->backend_tuples, self->num_fields * sizeof(TupleField)
*self->cache_size);
if (!self->backend_tuples)
{
--- 445,452 ----
***************
*** 483,499 ****
self->fcount = 0;
}
-
sock = CC_get_socket(self->conn);
self->tupleField = NULL;
for (;;)
{
-
id = SOCK_get_char(sock);
switch (id)
{
case 'T': /* Tuples within tuples cannot be handled */
self->status = PGRES_BAD_RESPONSE;
QR_set_message(self, "Tuples within tuples cannot be handled");
--- 490,505 ----
self->fcount = 0;
}
sock = CC_get_socket(self->conn);
self->tupleField = NULL;
for (;;)
{
id = SOCK_get_char(sock);
switch (id)
{
+
case 'T': /* Tuples within tuples cannot be handled */
self->status = PGRES_BAD_RESPONSE;
QR_set_message(self, "Tuples within tuples cannot be handled");
***************
*** 522,532 ****
QR_set_message(self, "Error reading the tuple");
return FALSE;
}
-
self->fcount++;
break; /* continue reading */
-
case 'C': /* End of tuple list */
SOCK_get_string(sock, cmdbuffer, MAX_MESSAGE_LEN);
QR_set_command(self, cmdbuffer);
--- 528,536 ----
***************
*** 536,542 ****
self->inTuples = FALSE;
if (self->fcount > 0)
{
-
qlog(" [ fetched %d rows ]\n", self->fcount);
mylog("_next_tuple: 'C' fetch_max && fcount = %d\n", self->fcount);
--- 540,545 ----
***************
*** 545,552 ****
return TRUE;
}
else
! { /* We are surely done here (we read 0
! * tuples) */
qlog(" [ fetched 0 rows ]\n");
mylog("_next_tuple: 'C': DONE (fcount == 0)\n");
return -1; /* end of tuples */
--- 548,555 ----
return TRUE;
}
else
! {
! /* We are surely done here (we read 0 tuples) */
qlog(" [ fetched 0 rows ]\n");
mylog("_next_tuple: 'C': DONE (fcount == 0)\n");
return -1; /* end of tuples */
***************
*** 600,606 ****
SocketClass *sock = CC_get_socket(self->conn);
ColumnInfoClass *flds;
-
/* set the current row to read the fields into */
this_tuplefield = self->backend_tuples + (self->fcount * num_fields);
--- 603,608 ----
***************
*** 629,635 ****
}
else
{
-
/*
* NO, the field is not null. so get at first the length of
* the field (four bytes)
--- 631,636 ----
Index: src/interfaces/odbc/results.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/results.c,v
retrieving revision 1.27
diff -c -r1.27 results.c
*** src/interfaces/odbc/results.c 2001/03/27 04:00:55 1.27
--- src/interfaces/odbc/results.c 2001/03/28 16:53:20
***************
*** 1,17 ****
! /* Module: results.c
*
* Description: This module contains functions related to
* retrieving result information through the ODBC API.
*
* Classes: n/a
*
! * API functions: SQLRowCount, SQLNumResultCols, SQLDescribeCol, SQLColAttributes,
! * SQLGetData, SQLFetch, SQLExtendedFetch,
* SQLMoreResults(NI), SQLSetPos, SQLSetScrollOptions(NI),
* SQLSetCursorName, SQLGetCursorName
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
#ifdef HAVE_CONFIG_H
--- 1,18 ----
! /*-------
! * Module: results.c
*
* Description: This module contains functions related to
* retrieving result information through the ODBC API.
*
* Classes: n/a
*
! * API functions: SQLRowCount, SQLNumResultCols, SQLDescribeCol,
! * SQLColAttributes, SQLGetData, SQLFetch, SQLExtendedFetch,
* SQLMoreResults(NI), SQLSetPos, SQLSetScrollOptions(NI),
* SQLSetCursorName, SQLGetCursorName
*
* Comments: See "notice.txt" for copyright and license information.
! *-------
*/
#ifdef HAVE_CONFIG_H
***************
*** 42,48 ****
extern GLOBAL_VALUES globals;
-
RETCODE SQL_API
SQLRowCount(
HSTMT hstmt,
--- 43,48 ----
***************
*** 81,87 ****
}
else
{
-
res = SC_get_Result(stmt);
if (res && pcrow)
{
--- 81,86 ----
***************
*** 97,103 ****
else
{
*pcrow = -1;
-
mylog("**** SQLRowCount(): NO ROWS: *pcrow = %d\n", *pcrow);
}
--- 96,101 ----
***************
*** 110,117 ****
}
! /* This returns the number of columns associated with the database */
! /* attached to "hstmt". */
RETCODE SQL_API
--- 108,117 ----
}
! /*
! * This returns the number of columns associated with the database
! * attached to "hstmt".
! */
RETCODE SQL_API
***************
*** 135,141 ****
parse_ok = FALSE;
if (globals.parse && stmt->statement_type == STMT_TYPE_SELECT)
{
-
if (stmt->parse_status == STMT_PARSE_NONE)
{
mylog("SQLNumResultCols: calling parse_statement on stmt=%u\n", stmt);
--- 135,140 ----
***************
*** 152,158 ****
if (!parse_ok)
{
-
SC_pre_execute(stmt);
result = SC_get_Result(stmt);
--- 151,156 ----
***************
*** 172,184 ****
return SQL_SUCCESS;
}
-
- /* - - - - - - - - - */
-
!
! /* Return information about the database column the user wants */
! /* information about. */
RETCODE SQL_API
SQLDescribeCol(
HSTMT hstmt,
--- 170,180 ----
return SQL_SUCCESS;
}
! /*
! * Return information about the database column the user wants
! * information about.
! */
RETCODE SQL_API
SQLDescribeCol(
HSTMT hstmt,
***************
*** 205,211 ****
int len = 0;
RETCODE result;
-
mylog("%s: entering...\n", func);
if (!stmt)
--- 201,206 ----
***************
*** 219,247 ****
SC_clear_error(stmt);
/*
! * Dont check for bookmark column. This is the responsibility of the
! * driver manager.
*/
icol--; /* use zero based column numbers */
-
parse_ok = FALSE;
if (globals.parse && stmt->statement_type == STMT_TYPE_SELECT)
{
-
if (stmt->parse_status == STMT_PARSE_NONE)
{
mylog("SQLDescribeCol: calling parse_statement on stmt=%u\n", stmt);
parse_statement(stmt);
}
-
mylog("PARSE: DescribeCol: icol=%d, stmt=%u, stmt->nfld=%d, stmt->fi=%u\n", icol, stmt, stmt->nfld,
stmt->fi);
if (stmt->parse_status != STMT_PARSE_FATAL && stmt->fi && stmt->fi[icol])
{
-
if (icol >= stmt->nfld)
{
stmt->errornumber = STMT_INVALID_COLUMN_NUMBER_ERROR;
--- 214,238 ----
SC_clear_error(stmt);
/*
! * Dont check for bookmark column. This is the responsibility of the
! * driver manager.
*/
icol--; /* use zero based column numbers */
parse_ok = FALSE;
if (globals.parse && stmt->statement_type == STMT_TYPE_SELECT)
{
if (stmt->parse_status == STMT_PARSE_NONE)
{
mylog("SQLDescribeCol: calling parse_statement on stmt=%u\n", stmt);
parse_statement(stmt);
}
mylog("PARSE: DescribeCol: icol=%d, stmt=%u, stmt->nfld=%d, stmt->fi=%u\n", icol, stmt, stmt->nfld,
stmt->fi);
if (stmt->parse_status != STMT_PARSE_FATAL && stmt->fi && stmt->fi[icol])
{
if (icol >= stmt->nfld)
{
stmt->errornumber = STMT_INVALID_COLUMN_NUMBER_ERROR;
***************
*** 261,271 ****
}
}
-
/*
! * If couldn't parse it OR the field being described was not parsed
! * (i.e., because it was a function or expression, etc, then do it the
! * old fashioned way.
*/
if (!parse_ok)
{
--- 252,261 ----
}
}
/*
! * If couldn't parse it OR the field being described was not parsed
! * (i.e., because it was a function or expression, etc, then do it the
! * old fashioned way.
*/
if (!parse_ok)
{
***************
*** 295,314 ****
col_name = QR_get_fieldname(res, icol);
fieldtype = QR_get_field_type(res, icol);
! precision = pgtype_precision(stmt, fieldtype, icol, globals.unknown_sizes); /* atoi(ci->unknown_sizes
! * ) */
! }
mylog("describeCol: col %d fieldname = '%s'\n", icol, col_name);
mylog("describeCol: col %d fieldtype = %d\n", icol, fieldtype);
mylog("describeCol: col %d precision = %d\n", icol, precision);
-
result = SQL_SUCCESS;
! /************************/
! /* COLUMN NAME */
! /************************/
len = strlen(col_name);
if (pcbColName)
--- 285,303 ----
col_name = QR_get_fieldname(res, icol);
fieldtype = QR_get_field_type(res, icol);
! /* atoi(ci->unknown_sizes) */
! precision = pgtype_precision(stmt, fieldtype, icol, globals.unknown_sizes);
! }
mylog("describeCol: col %d fieldname = '%s'\n", icol, col_name);
mylog("describeCol: col %d fieldtype = %d\n", icol, fieldtype);
mylog("describeCol: col %d precision = %d\n", icol, precision);
result = SQL_SUCCESS;
! /*
! * COLUMN NAME
! */
len = strlen(col_name);
if (pcbColName)
***************
*** 325,335 ****
stmt->errormsg = "The buffer was too small for the result.";
}
}
-
! /************************/
! /* SQL TYPE */
! /************************/
if (pfSqlType)
{
*pfSqlType = pgtype_to_sqltype(stmt, fieldtype);
--- 314,323 ----
stmt->errormsg = "The buffer was too small for the result.";
}
}
! /*
! * SQL TYPE
! */
if (pfSqlType)
{
*pfSqlType = pgtype_to_sqltype(stmt, fieldtype);
***************
*** 337,348 ****
mylog("describeCol: col %d *pfSqlType = %d\n", icol, *pfSqlType);
}
! /************************/
! /* PRECISION */
! /************************/
if (pcbColDef)
{
-
if (precision < 0)
precision = 0; /* "I dont know" */
--- 325,335 ----
mylog("describeCol: col %d *pfSqlType = %d\n", icol, *pfSqlType);
}
! /*
! * PRECISION
! */
if (pcbColDef)
{
if (precision < 0)
precision = 0; /* "I dont know" */
***************
*** 351,359 ****
mylog("describeCol: col %d *pcbColDef = %d\n", icol, *pcbColDef);
}
! /************************/
! /* SCALE */
! /************************/
if (pibScale)
{
Int2 scale;
--- 338,346 ----
mylog("describeCol: col %d *pcbColDef = %d\n", icol, *pcbColDef);
}
! /*
! * SCALE
! */
if (pibScale)
{
Int2 scale;
***************
*** 366,374 ****
mylog("describeCol: col %d *pibScale = %d\n", icol, *pibScale);
}
! /************************/
! /* NULLABILITY */
! /************************/
if (pfNullable)
{
*pfNullable = (parse_ok) ? stmt->fi[icol]->nullable : pgtype_nullable(stmt, fieldtype);
--- 353,361 ----
mylog("describeCol: col %d *pibScale = %d\n", icol, *pibScale);
}
! /*
! * NULLABILITY
! */
if (pfNullable)
{
*pfNullable = (parse_ok) ? stmt->fi[icol]->nullable : pgtype_nullable(stmt, fieldtype);
***************
*** 421,436 ****
icol--;
! unknown_sizes = globals.unknown_sizes; /* atoi(ci->unknown_sizes);
! * */
! if (unknown_sizes == UNKNOWNS_AS_DONTKNOW) /* not appropriate for
! * SQLColAttributes() */
unknown_sizes = UNKNOWNS_AS_MAX;
parse_ok = FALSE;
if (globals.parse && stmt->statement_type == STMT_TYPE_SELECT)
{
-
if (stmt->parse_status == STMT_PARSE_NONE)
{
mylog("SQLColAttributes: calling parse_statement\n");
--- 408,423 ----
icol--;
! /* atoi(ci->unknown_sizes); */
! unknown_sizes = globals.unknown_sizes;
!
! /* not appropriate for SQLColAttributes() */
! if (unknown_sizes == UNKNOWNS_AS_DONTKNOW)
unknown_sizes = UNKNOWNS_AS_MAX;
parse_ok = FALSE;
if (globals.parse && stmt->statement_type == STMT_TYPE_SELECT)
{
if (stmt->parse_status == STMT_PARSE_NONE)
{
mylog("SQLColAttributes: calling parse_statement\n");
***************
*** 453,459 ****
if (stmt->parse_status != STMT_PARSE_FATAL && stmt->fi && stmt->fi[icol])
{
-
if (icol >= cols)
{
stmt->errornumber = STMT_INVALID_COLUMN_NUMBER_ERROR;
--- 440,445 ----
***************
*** 461,467 ****
SC_log_error(func, "", stmt);
return SQL_ERROR;
}
-
field_type = stmt->fi[icol]->type;
if (field_type > 0)
parse_ok = TRUE;
--- 447,452 ----
***************
*** 521,533 ****
case SQL_COLUMN_CASE_SENSITIVE:
value = pgtype_case_sensitive(stmt, field_type);
break;
-
- /*
- * This special case is handled above.
- *
- * case SQL_COLUMN_COUNT:
- */
case SQL_COLUMN_DISPLAY_SIZE:
value = (parse_ok) ? stmt->fi[icol]->display_size : pgtype_display_size(stmt, field_type, icol,
unknown_sizes);
--- 506,517 ----
case SQL_COLUMN_CASE_SENSITIVE:
value = pgtype_case_sensitive(stmt, field_type);
break;
+ /*
+ * This special case is handled above.
+ *
+ * case SQL_COLUMN_COUNT:
+ */
case SQL_COLUMN_DISPLAY_SIZE:
value = (parse_ok) ? stmt->fi[icol]->display_size : pgtype_display_size(stmt, field_type, icol,
unknown_sizes);
***************
*** 543,553 ****
mylog("SQLColAttr: COLUMN_LABEL = '%s'\n", p);
break;
! } /* otherwise same as column name -- FALL
! * THROUGH!!! */
case SQL_COLUMN_NAME:
-
p = (parse_ok) ? stmt->fi[icol]->name : QR_get_fieldname(stmt->result, icol);
mylog("SQLColAttr: COLUMN_NAME = '%s'\n", p);
--- 527,536 ----
mylog("SQLColAttr: COLUMN_LABEL = '%s'\n", p);
break;
! }
! /* otherwise same as column name -- FALL THROUGH!!! */
case SQL_COLUMN_NAME:
p = (parse_ok) ? stmt->fi[icol]->name : QR_get_fieldname(stmt->result, icol);
mylog("SQLColAttr: COLUMN_NAME = '%s'\n", p);
***************
*** 590,596 ****
break;
case SQL_COLUMN_TABLE_NAME:
-
p = (parse_ok && stmt->fi[icol]->ti) ? stmt->fi[icol]->ti->name : "";
mylog("SQLColAttr: TABLE_NAME = '%s'\n", p);
--- 573,578 ----
***************
*** 612,625 ****
break;
case SQL_COLUMN_UPDATABLE:
-
/*
* Neither Access or Borland care about this.
*
* if (field_type == PG_TYPE_OID) pfDesc = SQL_ATTR_READONLY;
* else
*/
-
value = SQL_ATTR_WRITE;
mylog("SQLColAttr: UPDATEABLE = %d\n", value);
--- 594,605 ----
***************
*** 648,665 ****
*pcbDesc = len;
}
else
! { /* numeric data */
!
if (pfDesc)
*pfDesc = value;
-
}
-
return result;
}
! /* Returns result data for a single column in the current row. */
RETCODE SQL_API
SQLGetData(
--- 628,643 ----
*pcbDesc = len;
}
else
! {
! /* numeric data */
if (pfDesc)
*pfDesc = value;
}
return result;
}
! /* Returns result data for a single column in the current row. */
RETCODE SQL_API
SQLGetData(
***************
*** 707,713 ****
if (icol == 0)
{
-
if (stmt->options.use_bookmarks == SQL_UB_OFF)
{
stmt->errornumber = STMT_COLNUM_ERROR;
--- 685,690 ----
***************
*** 726,737 ****
}
get_bookmark = TRUE;
-
}
-
else
{
-
/* use zero-based column numbers */
icol--;
--- 703,711 ----
***************
*** 770,776 ****
}
}
else
! { /* it's a SOCKET result (backend data) */
if (stmt->currTuple == -1 || !res || !res->tupleField)
{
stmt->errormsg = "Not positioned on a valid row for GetData.";
--- 744,751 ----
}
}
else
! {
! /* it's a SOCKET result (backend data) */
if (stmt->currTuple == -1 || !res || !res->tupleField)
{
stmt->errormsg = "Not positioned on a valid row for GetData.";
***************
*** 844,854 ****
}
}
-
! /* Returns data for bound columns in the current row ("hstmt->iCursor"), */
! /* advances the cursor. */
!
RETCODE SQL_API
SQLFetch(
HSTMT hstmt)
--- 819,829 ----
}
}
! /*
! * Returns data for bound columns in the current row ("hstmt->iCursor"),
! * advances the cursor.
! */
RETCODE SQL_API
SQLFetch(
HSTMT hstmt)
***************
*** 892,898 ****
return SQL_ERROR;
}
-
if (stmt->status != STMT_FINISHED)
{
stmt->errornumber = STMT_STATUS_ERROR;
--- 867,872 ----
***************
*** 917,924 ****
return SC_fetch(stmt);
}
! /* This fetchs a block of data (rowset). */
!
RETCODE SQL_API
SQLExtendedFetch(
HSTMT hstmt,
--- 891,897 ----
return SC_fetch(stmt);
}
! /* This fetchs a block of data (rowset). */
RETCODE SQL_API
SQLExtendedFetch(
HSTMT hstmt,
***************
*** 1020,1026 ****
switch (fFetchType)
{
case SQL_FETCH_NEXT:
-
/*
* From the odbc spec... If positioned before the start of the
* RESULT SET, then this should be equivalent to
--- 993,998 ----
***************
*** 1031,1066 ****
stmt->rowset_start = 0;
else
- {
-
stmt->rowset_start += (save_rowset_size > 0 ? save_rowset_size : stmt->options.rowset_size);
- }
mylog("SQL_FETCH_NEXT: num_tuples=%d, currtuple=%d\n", num_tuples, stmt->currTuple);
break;
case SQL_FETCH_PRIOR:
mylog("SQL_FETCH_PRIOR: num_tuples=%d, currtuple=%d\n", num_tuples, stmt->currTuple);
-
-
/*
* From the odbc spec... If positioned after the end of the
* RESULT SET, then this should be equivalent to
* SQL_FETCH_LAST.
*/
-
if (stmt->rowset_start >= num_tuples)
{
stmt->rowset_start = num_tuples <= 0 ? 0 : (num_tuples - stmt->options.rowset_size);
}
else
- {
-
stmt->rowset_start -= stmt->options.rowset_size;
-
- }
-
break;
case SQL_FETCH_FIRST:
--- 1003,1027 ----
***************
*** 1091,1101 ****
/* Position with respect to the end of the result set */
else
stmt->rowset_start = num_tuples + irow;
-
break;
case SQL_FETCH_RELATIVE:
-
/*
* Refresh the current rowset -- not currently implemented,
* but lie anyway
--- 1052,1060 ----
***************
*** 1104,1128 ****
break;
stmt->rowset_start += irow;
-
-
break;
case SQL_FETCH_BOOKMARK:
-
stmt->rowset_start = irow - 1;
break;
default:
SC_log_error(func, "Unsupported SQLExtendedFetch Direction", stmt);
return SQL_ERROR;
-
}
!
! /***********************************/
! /* CHECK FOR PROPER CURSOR STATE */
! /***********************************/
/*
* Handle Declare Fetch style specially because the end is not really
--- 1063,1082 ----
break;
stmt->rowset_start += irow;
break;
case SQL_FETCH_BOOKMARK:
stmt->rowset_start = irow - 1;
break;
default:
SC_log_error(func, "Unsupported SQLExtendedFetch Direction", stmt);
return SQL_ERROR;
}
! /*
! * CHECK FOR PROPER CURSOR STATE
! */
/*
* Handle Declare Fetch style specially because the end is not really
***************
*** 1172,1178 ****
truncated = error = FALSE;
for (i = 0; i < stmt->options.rowset_size; i++)
{
-
stmt->bind_row = i; /* set the binding location */
result = SC_fetch(stmt);
--- 1126,1131 ----
***************
*** 1212,1232 ****
*pcrow = i;
if (i == 0)
! return SQL_NO_DATA_FOUND; /* Only DeclareFetch should wind
! * up here */
else if (error)
return SQL_ERROR;
else if (truncated)
return SQL_SUCCESS_WITH_INFO;
else
return SQL_SUCCESS;
-
}
-
- /* This determines whether there are more results sets available for */
- /* the "hstmt". */
/* CC: return SQL_NO_DATA_FOUND since we do not support multiple result sets */
RETCODE SQL_API
SQLMoreResults(
--- 1165,1185 ----
*pcrow = i;
if (i == 0)
! /* Only DeclareFetch should wind up here */
! return SQL_NO_DATA_FOUND;
else if (error)
return SQL_ERROR;
else if (truncated)
return SQL_SUCCESS_WITH_INFO;
else
return SQL_SUCCESS;
}
+ /*
+ * This determines whether there are more results sets available for
+ * the "hstmt".
+ */
/* CC: return SQL_NO_DATA_FOUND since we do not support multiple result sets */
RETCODE SQL_API
SQLMoreResults(
***************
*** 1235,1242 ****
return SQL_NO_DATA_FOUND;
}
! /* This positions the cursor within a rowset, that was positioned using SQLExtendedFetch. */
! /* This will be useful (so far) only when using SQLGetData after SQLExtendedFetch. */
RETCODE SQL_API
SQLSetPos(
HSTMT hstmt,
--- 1188,1197 ----
return SQL_NO_DATA_FOUND;
}
! /*
! * This positions the cursor within a rowset, that was positioned using SQLExtendedFetch.
! * This will be useful (so far) only when using SQLGetData after SQLExtendedFetch.
! */
RETCODE SQL_API
SQLSetPos(
HSTMT hstmt,
***************
*** 1301,1311 ****
stmt->currTuple = stmt->rowset_start + irow;
return SQL_SUCCESS;
-
}
/* Sets options that control the behavior of cursors. */
-
RETCODE SQL_API
SQLSetScrollOptions(
HSTMT hstmt,
--- 1256,1264 ----
***************
*** 1319,1327 ****
return SQL_ERROR;
}
-
- /* Set the cursor name on a statement handle */
RETCODE SQL_API
SQLSetCursorName(
HSTMT hstmt,
--- 1272,1279 ----
return SQL_ERROR;
}
+ /* Set the cursor name on a statement handle */
RETCODE SQL_API
SQLSetCursorName(
HSTMT hstmt,
***************
*** 1354,1361 ****
return SQL_SUCCESS;
}
- /* Return the cursor name for a statement handle */
RETCODE SQL_API
SQLGetCursorName(
HSTMT hstmt,
--- 1306,1313 ----
return SQL_SUCCESS;
}
+ /* Return the cursor name for a statement handle */
RETCODE SQL_API
SQLGetCursorName(
HSTMT hstmt,
Index: src/interfaces/odbc/setup.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/setup.c,v
retrieving revision 1.17
diff -c -r1.17 setup.c
*** src/interfaces/odbc/setup.c 2001/03/27 04:00:55 1.17
--- src/interfaces/odbc/setup.c 2001/03/28 16:53:22
***************
*** 1,4 ****
! /* Module: setup.c
*
* Description: This module contains the setup functions for
* adding/modifying a Data Source in the ODBC.INI portion
--- 1,5 ----
! /*-------
! * Module: setup.c
*
* Description: This module contains the setup functions for
* adding/modifying a Data Source in the ODBC.INI portion
***************
*** 9,15 ****
* API functions: ConfigDSN
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
#include "psqlodbc.h"
--- 10,16 ----
* API functions: ConfigDSN
*
* Comments: See "notice.txt" for copyright and license information.
! *-------
*/
#include "psqlodbc.h"
***************
*** 28,34 ****
extern HINSTANCE NEAR s_hModule;/* Saved module handle. */
extern GLOBAL_VALUES globals;
! /* Constants --------------------------------------------------------------- */
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#ifdef WIN32
--- 29,35 ----
extern HINSTANCE NEAR s_hModule;/* Saved module handle. */
extern GLOBAL_VALUES globals;
! /* Constants */
#define MIN(x,y) ((x) < (y) ? (x) : (y))
#ifdef WIN32
***************
*** 40,46 ****
#define MAXDSNAME (32+1) /* Max data source name length */
! /* Globals ----------------------------------------------------------------- */
/* NOTE: All these are used by the dialog procedures */
typedef struct tagSETUPDLG
{
--- 41,47 ----
#define MAXDSNAME (32+1) /* Max data source name length */
! /* Globals */
/* NOTE: All these are used by the dialog procedures */
typedef struct tagSETUPDLG
{
***************
*** 55,77 ****
! /* Prototypes -------------------------------------------------------------- */
void INTFUNC CenterDialog(HWND hdlg);
int CALLBACK ConfigDlgProc(HWND hdlg, WORD wMsg, WPARAM wParam, LPARAM lParam);
void INTFUNC ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg);
BOOL INTFUNC SetDSNAttributes(HWND hwnd, LPSETUPDLG lpsetupdlg);
! /* ConfigDSN ---------------------------------------------------------------
! Description: ODBC Setup entry point
! This entry point is called by the ODBC Installer
! (see file header for more details)
! Input : hwnd ----------- Parent window handle
! fRequest ------- Request type (i.e., add, config, or remove)
! lpszDriver ----- Driver name
! lpszAttributes - data source attribute string
! Output : TRUE success, FALSE otherwise
! --------------------------------------------------------------------------*/
BOOL CALLBACK
ConfigDSN(HWND hwnd,
--- 56,81 ----
! /* Prototypes */
void INTFUNC CenterDialog(HWND hdlg);
int CALLBACK ConfigDlgProc(HWND hdlg, WORD wMsg, WPARAM wParam, LPARAM lParam);
void INTFUNC ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg);
BOOL INTFUNC SetDSNAttributes(HWND hwnd, LPSETUPDLG lpsetupdlg);
! /*--------
! * ConfigDSN
! *
! * Description: ODBC Setup entry point
! * This entry point is called by the ODBC Installer
! * (see file header for more details)
! * Input : hwnd ----------- Parent window handle
! * fRequest ------- Request type (i.e., add, config, or remove)
! * lpszDriver ----- Driver name
! * lpszAttributes - data source attribute string
! * Output : TRUE success, FALSE otherwise
! *--------
! */
BOOL CALLBACK
ConfigDSN(HWND hwnd,
***************
*** 111,117 ****
else
fSuccess = SQLRemoveDSNFromIni(lpsetupdlg->ci.dsn);
}
-
/* Add or Configure data source */
else
{
--- 115,120 ----
***************
*** 134,140 ****
ConfigDlgProc,
(LONG) (LPSTR) lpsetupdlg));
}
-
else if (lpsetupdlg->ci.dsn[0])
fSuccess = SetDSNAttributes(hwnd, lpsetupdlg);
else
--- 137,142 ----
***************
*** 148,158 ****
}
! /* CenterDialog ------------------------------------------------------------
! Description: Center the dialog over the frame window
! Input : hdlg -- Dialog window handle
! Output : None
! --------------------------------------------------------------------------*/
void INTFUNC
CenterDialog(HWND hdlg)
{
--- 150,163 ----
}
! /*-------
! * CenterDialog
! *
! * Description: Center the dialog over the frame window
! * Input : hdlg -- Dialog window handle
! * Output : None
! *-------
! */
void INTFUNC
CenterDialog(HWND hdlg)
{
***************
*** 197,220 ****
MoveWindow(hdlg, rcDlg.left, rcDlg.top, cx, cy, TRUE);
return;
}
-
- /* ConfigDlgProc -----------------------------------------------------------
- Description: Manage add data source name dialog
- Input : hdlg --- Dialog window handle
- wMsg --- Message
- wParam - Message parameter
- lParam - Message parameter
- Output : TRUE if message processed, FALSE otherwise
- --------------------------------------------------------------------------*/
!
int CALLBACK
ConfigDlgProc(HWND hdlg,
WORD wMsg,
WPARAM wParam,
LPARAM lParam)
{
-
switch (wMsg)
{
/* Initialize the dialog */
--- 202,224 ----
MoveWindow(hdlg, rcDlg.left, rcDlg.top, cx, cy, TRUE);
return;
}
! /*-------
! * ConfigDlgProc
! * Description: Manage add data source name dialog
! * Input : hdlg --- Dialog window handle
! * wMsg --- Message
! * wParam - Message parameter
! * lParam - Message parameter
! * Output : TRUE if message processed, FALSE otherwise
! *-------
! */
int CALLBACK
ConfigDlgProc(HWND hdlg,
WORD wMsg,
WPARAM wParam,
LPARAM lParam)
{
switch (wMsg)
{
/* Initialize the dialog */
***************
*** 241,251 ****
/* Fill in any defaults */
getDSNdefaults(ci);
-
/* Initialize dialog fields */
SetDlgStuff(hdlg, ci);
-
if (lpsetupdlg->fDefault)
{
EnableWindow(GetDlgItem(hdlg, IDC_DSNAME), FALSE);
--- 245,253 ----
***************
*** 259,272 ****
EM_LIMITTEXT, (WPARAM) (MAXDESC - 1), 0L);
return TRUE; /* Focus was not set */
}
-
! /* Process buttons */
case WM_COMMAND:
-
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
-
/*
* Ensure the OK button is enabled only when a data
* source name
--- 261,271 ----
EM_LIMITTEXT, (WPARAM) (MAXDESC - 1), 0L);
return TRUE; /* Focus was not set */
}
! /* Process buttons */
case WM_COMMAND:
switch (GET_WM_COMMAND_ID(wParam, lParam))
{
/*
* Ensure the OK button is enabled only when a data
* source name
***************
*** 281,292 ****
EnableWindow(GetDlgItem(hdlg, IDOK),
GetDlgItemText(hdlg, IDC_DSNAME,
szItem, sizeof(szItem)));
-
return TRUE;
}
break;
! /* Accept results */
case IDOK:
{
LPSETUPDLG lpsetupdlg;
--- 280,290 ----
EnableWindow(GetDlgItem(hdlg, IDOK),
GetDlgItemText(hdlg, IDC_DSNAME,
szItem, sizeof(szItem)));
return TRUE;
}
break;
! /* Accept results */
case IDOK:
{
LPSETUPDLG lpsetupdlg;
***************
*** 297,304 ****
GetDlgItemText(hdlg, IDC_DSNAME,
lpsetupdlg->ci.dsn,
sizeof(lpsetupdlg->ci.dsn));
-
-
/* Get Dialog Values */
GetDlgStuff(hdlg, &lpsetupdlg->ci);
--- 295,300 ----
***************
*** 306,318 ****
SetDSNAttributes(hdlg, lpsetupdlg);
}
! /* Return to caller */
case IDCANCEL:
EndDialog(hdlg, wParam);
return TRUE;
case IDC_DRIVER:
-
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
hdlg, driver_optionsProc, (LPARAM) NULL);
--- 302,313 ----
SetDSNAttributes(hdlg, lpsetupdlg);
}
! /* Return to caller */
case IDCANCEL:
EndDialog(hdlg, wParam);
return TRUE;
case IDC_DRIVER:
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
hdlg, driver_optionsProc, (LPARAM) NULL);
***************
*** 330,336 ****
return TRUE;
}
}
-
break;
}
--- 325,330 ----
***************
*** 339,349 ****
}
! /* ParseAttributes ---------------------------------------------------------
! Description: Parse attribute string moving values into the aAttr array
! Input : lpszAttributes - Pointer to attribute string
! Output : None (global aAttr normally updated)
! --------------------------------------------------------------------------*/
void INTFUNC
ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg)
{
--- 333,346 ----
}
! /*-------
! * ParseAttributes
! *
! * Description: Parse attribute string moving values into the aAttr array
! * Input : lpszAttributes - Pointer to attribute string
! * Output : None (global aAttr normally updated)
! *-------
! */
void INTFUNC
ParseAttributes(LPCSTR lpszAttributes, LPSETUPDLG lpsetupdlg)
{
***************
*** 356,363 ****
memset(&lpsetupdlg->ci, 0, sizeof(ConnInfo));
for (lpsz = lpszAttributes; *lpsz; lpsz++)
! { /* Extract key name (e.g., DSN), it must
! * be terminated by an equals */
lpszStart = lpsz;
for (;; lpsz++)
{
--- 353,360 ----
memset(&lpsetupdlg->ci, 0, sizeof(ConnInfo));
for (lpsz = lpszAttributes; *lpsz; lpsz++)
! {
! /* Extract key name (e.g., DSN), it must be terminated by an equals */
lpszStart = lpsz;
for (;; lpsz++)
{
***************
*** 370,384 ****
cbKey = lpsz - lpszStart;
if (cbKey < sizeof(aszKey))
{
-
_fmemcpy(aszKey, lpszStart, cbKey);
aszKey[cbKey] = '\0';
}
/* Locate end of key value */
lpszStart = ++lpsz;
! for (; *lpsz; lpsz++);
!
/* lpsetupdlg->aAttr[iElement].fSupplied = TRUE; */
_fmemcpy(value, lpszStart, MIN(lpsz - lpszStart + 1, MAXPGPATH));
--- 367,380 ----
cbKey = lpsz - lpszStart;
if (cbKey < sizeof(aszKey))
{
_fmemcpy(aszKey, lpszStart, cbKey);
aszKey[cbKey] = '\0';
}
/* Locate end of key value */
lpszStart = ++lpsz;
! for (; *lpsz; lpsz++)
! ;
/* lpsetupdlg->aAttr[iElement].fSupplied = TRUE; */
_fmemcpy(value, lpszStart, MIN(lpsz - lpszStart + 1, MAXPGPATH));
***************
*** 392,403 ****
}
! /* SetDSNAttributes --------------------------------------------------------
! Description: Write data source attributes to ODBC.INI
! Input : hwnd - Parent window handle (plus globals)
! Output : TRUE if successful, FALSE otherwise
! --------------------------------------------------------------------------*/
!
BOOL INTFUNC
SetDSNAttributes(HWND hwndParent, LPSETUPDLG lpsetupdlg)
{
--- 388,401 ----
}
! /*--------
! * SetDSNAttributes
! *
! * Description: Write data source attributes to ODBC.INI
! * Input : hwnd - Parent window handle (plus globals)
! * Output : TRUE if successful, FALSE otherwise
! *--------
! */
BOOL INTFUNC
SetDSNAttributes(HWND hwndParent, LPSETUPDLG lpsetupdlg)
{
***************
*** 425,434 ****
return FALSE;
}
-
/* Update ODBC.INI */
writeDSNinfo(&lpsetupdlg->ci);
-
/* If the data source name has changed, remove the old name */
if (lstrcmpi(lpsetupdlg->szDSN, lpsetupdlg->ci.dsn))
--- 423,430 ----
Index: src/interfaces/odbc/socket.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/socket.c,v
retrieving revision 1.22
diff -c -r1.22 socket.c
*** src/interfaces/odbc/socket.c 2001/03/27 04:00:55 1.22
--- src/interfaces/odbc/socket.c 2001/03/28 16:53:22
***************
*** 1,4 ****
! /* Module: socket.c
*
* Description: This module contains functions for low level socket
* operations (connecting/reading/writing to the backend)
--- 1,5 ----
! /*-------
! * Module: socket.c
*
* Description: This module contains functions for low level socket
* operations (connecting/reading/writing to the backend)
***************
*** 8,14 ****
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
#ifdef HAVE_CONFIG_H
--- 9,15 ----
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *-------
*/
#ifdef HAVE_CONFIG_H
***************
*** 70,83 ****
free(rv);
return NULL;
}
-
rv->errormsg = NULL;
rv->errornumber = 0;
-
rv->reverse = FALSE;
}
return rv;
-
}
void
--- 71,81 ----
***************
*** 97,103 ****
free(self->buffer_out);
free(self);
-
}
--- 95,100 ----
***************
*** 149,155 ****
if (connect(self->socket, (struct sockaddr *) & (sadr),
sizeof(sadr)) < 0)
{
-
self->errornumber = SOCKET_COULD_NOT_CONNECT;
self->errormsg = "Could not connect to remote socket.";
closesocket(self->socket);
--- 146,151 ----
***************
*** 194,202 ****
}
! /* bufsize must include room for the null terminator
! will read at most bufsize-1 characters + null.
! */
void
SOCK_get_string(SocketClass *self, char *buffer, int bufsize)
{
--- 190,199 ----
}
! /*
! * bufsize must include room for the null terminator
! * will read at most bufsize-1 characters + null.
! */
void
SOCK_get_string(SocketClass *self, char *buffer, int bufsize)
{
***************
*** 300,311 ****
unsigned char
SOCK_get_next_byte(SocketClass *self)
{
-
if (self->buffer_read_in >= self->buffer_filled_in)
{
! /* there are no more bytes left in the buffer so */
! /* reload the buffer */
!
self->buffer_read_in = 0;
self->buffer_filled_in = recv(self->socket, (char *) self->buffer_in, globals.socket_buffersize, 0);
--- 297,308 ----
unsigned char
SOCK_get_next_byte(SocketClass *self)
{
if (self->buffer_read_in >= self->buffer_filled_in)
{
! /*
! * there are no more bytes left in the buffer so
! * reload the buffer
! */
self->buffer_read_in = 0;
self->buffer_filled_in = recv(self->socket, (char *) self->buffer_in, globals.socket_buffersize, 0);
Index: src/interfaces/odbc/statement.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/statement.c,v
retrieving revision 1.35
diff -c -r1.35 statement.c
*** src/interfaces/odbc/statement.c 2001/03/27 04:00:55 1.35
--- src/interfaces/odbc/statement.c 2001/03/28 16:53:22
***************
*** 1,4 ****
! /* Module: statement.c
*
* Description: This module contains functions related to creating
* and manipulating a statement.
--- 1,5 ----
! /*-------
! * Module: statement.c
*
* Description: This module contains functions related to creating
* and manipulating a statement.
***************
*** 8,14 ****
* API functions: SQLAllocStmt, SQLFreeStmt
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
#ifdef HAVE_CONFIG_H
--- 9,15 ----
* API functions: SQLAllocStmt, SQLFreeStmt
*
* Comments: See "notice.txt" for copyright and license information.
! *-------
*/
#ifdef HAVE_CONFIG_H
***************
*** 126,137 ****
*phstmt = (HSTMT) stmt;
! /*
! * Copy default statement options based from Connection options
! */
stmt->options = conn->stmtOptions;
-
/* Save the handle for later */
stmt->phstmt = phstmt;
--- 127,135 ----
*phstmt = (HSTMT) stmt;
! /* Copy default statement options based from Connection options */
stmt->options = conn->stmtOptions;
/* Save the handle for later */
stmt->phstmt = phstmt;
***************
*** 180,208 ****
/* Destroy the statement and free any results, cursors, etc. */
SC_Destructor(stmt);
-
}
else if (fOption == SQL_UNBIND)
{
SC_unbind_cols(stmt);
-
}
else if (fOption == SQL_CLOSE)
{
! /* this should discard all the results, but leave the statement */
! /* itself in place (it can be executed again) */
if (!SC_recycle_statement(stmt))
{
/* errormsg passed in above */
SC_log_error(func, "", stmt);
return SQL_ERROR;
}
-
}
else if (fOption == SQL_RESET_PARAMS)
{
SC_free_params(stmt, STMT_FREE_PARAMS_ALL);
-
}
else
{
--- 178,204 ----
/* Destroy the statement and free any results, cursors, etc. */
SC_Destructor(stmt);
}
else if (fOption == SQL_UNBIND)
{
SC_unbind_cols(stmt);
}
else if (fOption == SQL_CLOSE)
{
! /*
! * this should discard all the results, but leave the statement
! * itself in place (it can be executed again)
! */
if (!SC_recycle_statement(stmt))
{
/* errormsg passed in above */
SC_log_error(func, "", stmt);
return SQL_ERROR;
}
}
else if (fOption == SQL_RESET_PARAMS)
{
SC_free_params(stmt, STMT_FREE_PARAMS_ALL);
}
else
{
***************
*** 216,223 ****
}
!
! /**********************************************************************
* StatementClass implementation
*/
void
--- 212,218 ----
}
! /*
* StatementClass implementation
*/
void
***************
*** 288,294 ****
rv->nfld = 0;
rv->parse_status = STMT_PARSE_NONE;
-
/* Clear Statement Options -- defaults will be set in AllocStmt */
memset(&rv->options, 0, sizeof(StatementOptions));
}
--- 283,288 ----
***************
*** 298,304 ****
char
SC_Destructor(StatementClass *self)
{
-
mylog("SC_Destructor: self=%u, self->result=%u, self->hdbc=%u\n", self, self->result, self->hdbc);
if (STMT_EXECUTING == self->status)
{
--- 292,297 ----
***************
*** 322,339 ****
/*
* the memory pointed to by the bindings is not deallocated by the
! * driver
! */
!
! /*
! * by by the application that uses that driver, so we don't have to
* care
*/
/* about that here. */
if (self->bindings)
free(self->bindings);
-
/* Free the parsed table information */
if (self->ti)
{
--- 315,327 ----
/*
* the memory pointed to by the bindings is not deallocated by the
! * driver but by the application that uses that driver, so we don't have to
* care
*/
/* about that here. */
if (self->bindings)
free(self->bindings);
/* Free the parsed table information */
if (self->ti)
{
***************
*** 355,361 ****
free(self->fi);
}
-
free(self);
mylog("SC_Destructor: EXIT\n");
--- 343,348 ----
***************
*** 363,371 ****
return TRUE;
}
! /* Free parameters and free the memory from the
! data-at-execution parameters that was allocated in SQLPutData.
! */
void
SC_free_params(StatementClass *self, char option)
{
--- 350,359 ----
return TRUE;
}
! /*
! * Free parameters and free the memory from the
! * data-at-execution parameters that was allocated in SQLPutData.
! */
void
SC_free_params(StatementClass *self, char option)
{
***************
*** 380,386 ****
{
if (self->parameters[i].data_at_exec == TRUE)
{
-
if (self->parameters[i].EXEC_used)
{
free(self->parameters[i].EXEC_used);
--- 368,373 ----
***************
*** 427,435 ****
}
! /* Called from SQLPrepare if STMT_PREMATURE, or
! from SQLExecute if STMT_FINISHED, or
! from SQLFreeStmt(SQL_CLOSE)
*/
char
SC_recycle_statement(StatementClass *self)
--- 414,423 ----
}
! /*
! * Called from SQLPrepare if STMT_PREMATURE, or
! * from SQLExecute if STMT_FINISHED, or
! * from SQLFreeStmt(SQL_CLOSE)
*/
char
SC_recycle_statement(StatementClass *self)
***************
*** 469,475 ****
conn = SC_get_conn(self);
if (!CC_is_in_autocommit(conn) && CC_is_in_trans(conn))
{
-
QResultClass *res = CC_send_query(conn, "ABORT", NULL);
QR_Destructor(res);
--- 457,462 ----
***************
*** 518,528 ****
QR_Destructor(self->result);
self->result = NULL;
}
-
- /****************************************************************/
- /* Reset only parameters that have anything to do with results */
- /****************************************************************/
self->status = STMT_READY;
self->manual_result = FALSE;/* very important */
--- 505,514 ----
QR_Destructor(self->result);
self->result = NULL;
}
+ /*
+ * Reset only parameters that have anything to do with results
+ */
self->status = STMT_READY;
self->manual_result = FALSE;/* very important */
***************
*** 538,546 ****
self->lobj_fd = -1;
! /* Free any data at exec params before the statement is executed */
! /* again. If not, then there will be a memory leak when */
! /* the next SQLParamData/SQLPutData is called. */
SC_free_params(self, STMT_FREE_PARAMS_DATA_AT_EXEC_ONLY);
return TRUE;
--- 524,534 ----
self->lobj_fd = -1;
! /*
! * Free any data at exec params before the statement is executed
! * again. If not, then there will be a memory leak when
! * the next SQLParamData/SQLPutData is called.
! */
SC_free_params(self, STMT_FREE_PARAMS_DATA_AT_EXEC_ONLY);
return TRUE;
***************
*** 550,556 ****
void
SC_pre_execute(StatementClass *self)
{
-
mylog("SC_pre_execute: status = %d\n", self->status);
if (self->status == STMT_READY)
--- 538,543 ----
***************
*** 597,604 ****
}
! /* This function creates an error msg which is the concatenation */
! /* of the result, statement, connection, and socket messages. */
char *
SC_create_errormsg(StatementClass *self)
{
--- 584,593 ----
}
! /*
! * This function creates an error msg which is the concatenation
! * of the result, statement, connection, and socket messages.
! */
char *
SC_create_errormsg(StatementClass *self)
{
***************
*** 640,646 ****
{
char rv;
! /* Create a very informative errormsg if it hasn't been done yet. */
if (!self->errormsg_created)
{
self->errormsg = SC_create_errormsg(self);
--- 629,635 ----
{
char rv;
! /* Create a very informative errormsg if it hasn't been done yet. */
if (!self->errormsg_created)
{
self->errormsg = SC_create_errormsg(self);
***************
*** 660,669 ****
return rv;
}
! /* Currently, the driver offers very simple bookmark support -- it is
! just the current row number. But it could be more sophisticated
! someday, such as mapping a key to a 32 bit value
! */
unsigned long
SC_get_bookmark(StatementClass *self)
{
--- 649,659 ----
return rv;
}
! /*
! * Currently, the driver offers very simple bookmark support -- it is
! * just the current row number. But it could be more sophisticated
! * someday, such as mapping a key to a 32 bit value
! */
unsigned long
SC_get_bookmark(StatementClass *self)
{
***************
*** 683,689 ****
char *value;
ColumnInfoClass *ci;
! /* TupleField *tupleField; */
self->last_fetch_count = 0;
ci = QR_get_fields(res); /* the column info */
--- 673,679 ----
char *value;
ColumnInfoClass *ci;
! /* TupleField *tupleField; */
self->last_fetch_count = 0;
ci = QR_get_fields(res); /* the column info */
***************
*** 692,702 ****
if (self->manual_result || !globals.use_declarefetch)
{
-
if (self->currTuple >= QR_get_num_tuples(res) - 1 ||
(self->options.maxRows > 0 && self->currTuple == self->options.maxRows - 1))
{
-
/*
* if at the end of the tuples, return "no data found" and set
* the cursor past the end of the result set
--- 682,690 ----
***************
*** 710,716 ****
}
else
{
-
/* read from the cache or the physical next tuple */
retval = QR_next_tuple(res);
if (retval < 0)
--- 698,703 ----
***************
*** 720,726 ****
}
else if (retval > 0)
(self->currTuple)++;/* all is well */
-
else
{
mylog("SQLFetch: error\n");
--- 707,712 ----
***************
*** 753,759 ****
for (lf = 0; lf < num_cols; lf++)
{
-
mylog("fetch: cols=%d, lf=%d, self = %u, self->bindings = %u, buffer[] = %u\n", num_cols, lf, self,
self->bindings,self->bindings[lf].buffer);
/* reset for SQLGetData */
--- 739,744 ----
***************
*** 809,821 ****
result = SQL_SUCCESS_WITH_INFO;
break;
! case COPY_GENERAL_ERROR: /* error msg already
! * filled in */
SC_log_error(func, "", self);
result = SQL_ERROR;
break;
! /* This would not be meaningful in SQLFetch. */
case COPY_NO_DATA_FOUND:
break;
--- 794,806 ----
result = SQL_SUCCESS_WITH_INFO;
break;
! /* error msg already filled in */
! case COPY_GENERAL_ERROR:
SC_log_error(func, "", self);
result = SQL_ERROR;
break;
! /* This would not be meaningful in SQLFetch. */
case COPY_NO_DATA_FOUND:
break;
***************
*** 889,901 ****
CC_set_in_trans(conn);
}
-
-
oldstatus = conn->status;
conn->status = CONN_EXECUTING;
self->status = STMT_EXECUTING;
-
/* If it's a SELECT statement, use a cursor. */
/*
--- 874,883 ----
***************
*** 905,923 ****
/* in copy_statement... */
if (self->statement_type == STMT_TYPE_SELECT)
{
-
char fetch[128];
mylog(" Sending SELECT statement on stmt=%u, cursor_name='%s'\n", self, self->cursor_name);
-
/* send the declare/select */
self->result = CC_send_query(conn, self->stmt_with_params, NULL);
if (globals.use_declarefetch && self->result != NULL &&
QR_command_successful(self->result))
{
-
QR_Destructor(self->result);
/*
--- 887,902 ----
***************
*** 935,954 ****
* will correct for any discrepancies in sizes and adjust the
* cache accordingly.
*/
-
sprintf(fetch, "fetch %d in %s", qi.row_size, self->cursor_name);
self->result = CC_send_query(conn, fetch, &qi);
}
-
mylog(" done sending the query:\n");
-
-
-
}
else
! { /* not a SELECT statement so don't use a
! * cursor */
mylog(" it's NOT a select statement: stmt=%u\n", self);
self->result = CC_send_query(conn, self->stmt_with_params, NULL);
--- 914,928 ----
* will correct for any discrepancies in sizes and adjust the
* cache accordingly.
*/
sprintf(fetch, "fetch %d in %s", qi.row_size, self->cursor_name);
self->result = CC_send_query(conn, fetch, &qi);
}
mylog(" done sending the query:\n");
}
else
! {
! /* not a SELECT statement so don't use a cursor */
mylog(" it's NOT a select statement: stmt=%u\n", self);
self->result = CC_send_query(conn, self->stmt_with_params, NULL);
***************
*** 967,973 ****
QR_Destructor(res);
CC_set_no_trans(conn);
}
-
}
conn->status = oldstatus;
--- 941,946 ----
***************
*** 976,982 ****
/* Check the status of the result */
if (self->result)
{
-
was_ok = QR_command_successful(self->result);
was_nonfatal = QR_command_nonfatal(self->result);
--- 949,954 ----
***************
*** 985,992 ****
else
self->errornumber = was_nonfatal ? STMT_INFO_ONLY : STMT_ERROR_TAKEN_FROM_BACKEND;
! self->currTuple = -1; /* set cursor before the first tuple in
! * the list */
self->current_col = -1;
self->rowset_start = -1;
--- 957,964 ----
else
self->errornumber = was_nonfatal ? STMT_INFO_ONLY : STMT_ERROR_TAKEN_FROM_BACKEND;
! /* set cursor before the first tuple in the list */
! self->currTuple = -1;
self->current_col = -1;
self->rowset_start = -1;
***************
*** 1010,1018 ****
CC_abort(conn);
}
else
! { /* Bad Error -- The error message will be
! * in the Connection */
!
if (self->statement_type == STMT_TYPE_CREATE)
{
self->errornumber = STMT_CREATE_TABLE_ERROR;
--- 982,989 ----
CC_abort(conn);
}
else
! {
! /* Bad Error -- The error message will be in the Connection */
if (self->statement_type == STMT_TYPE_CREATE)
{
self->errornumber = STMT_CREATE_TABLE_ERROR;
Index: src/interfaces/odbc/tuple.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/tuple.c,v
retrieving revision 1.12
diff -c -r1.12 tuple.c
*** src/interfaces/odbc/tuple.c 2001/03/27 04:00:55 1.12
--- src/interfaces/odbc/tuple.c 2001/03/28 16:53:22
***************
*** 1,17 ****
! /* Module: tuple.c
*
! * Description: This module contains functions for setting the data for individual
! * fields (TupleField structure) of a manual result set.
*
- * Important Note: These functions are ONLY used in building manual result sets for
- * info functions (SQLTables, SQLColumns, etc.)
- *
* Classes: n/a
*
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
#include "tuple.h"
--- 1,20 ----
! /*-------
! * Module: tuple.c
*
! * Description: This module contains functions for setting the data
! * for individual fields (TupleField structure) of a
! * manual result set.
! *
! * Important Note: These functions are ONLY used in building manual
! * result sets for info functions (SQLTables,
! * SQLColumns, etc.)
*
* Classes: n/a
*
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *-------
*/
#include "tuple.h"
***************
*** 38,44 ****
set_tuplefield_int2(TupleField *tuple_field, Int2 value)
{
char buffer[10];
-
sprintf(buffer, "%d", value);
--- 41,46 ----
Index: src/interfaces/odbc/tuplelist.c
===================================================================
RCS file: /home/projects/pgsql/cvsroot/pgsql/src/interfaces/odbc/tuplelist.c,v
retrieving revision 1.11
diff -c -r1.11 tuplelist.c
*** src/interfaces/odbc/tuplelist.c 2001/03/27 04:00:55 1.11
--- src/interfaces/odbc/tuplelist.c 2001/03/28 16:53:22
***************
*** 1,14 ****
! /* Module: tuplelist.c
*
! * Description: This module contains functions for creating a manual result set
! * (the TupleList) and retrieving data from it for a specific row/column.
*
* Classes: TupleListClass (Functions prefix: "TL_")
*
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *
*/
#include <stdlib.h>
--- 1,16 ----
! /*--------
! * Module: tuplelist.c
*
! * Description: This module contains functions for creating a manual
! * result set (the TupleList) and retrieving data from
! * it for a specific row/column.
*
* Classes: TupleListClass (Functions prefix: "TL_")
*
* API functions: none
*
* Comments: See "notice.txt" for copyright and license information.
! *--------
*/
#include <stdlib.h>
***************
*** 25,31 ****
rv = (TupleListClass *) malloc(sizeof(TupleListClass));
if (rv)
{
-
rv->num_fields = fieldcnt;
rv->num_tuples = 0;
rv->list_start = NULL;
--- 27,32 ----
***************
*** 134,140 ****
}
else if (start_is_closer)
{
-
/*
* the shortest way is to start the search from the head of the
* list
--- 135,140 ----
***************
*** 177,187 ****
}
-
char
TL_add_tuple(TupleListClass *self, TupleNode *new_field)
{
-
/*
* we append the tuple at the end of the doubly linked list of the
* tuples we have already read in
--- 177,185 ----
***************
*** 200,206 ****
}
else
{
-
/*
* there is already an element in the list, so add the new one at
* the end of the list
--- 198,203 ----