1) Fix a few bugs about SQLGetData()
reported by Mika Mantyla. 2) Timestamp precision. 3) Separate ODBC3.0 files.
This commit is contained in:
parent
0f450dae8b
commit
c0b27c4feb
@ -424,6 +424,8 @@ create_empty_bindings(int num_columns)
|
|||||||
new_bindings[i].buffer = NULL;
|
new_bindings[i].buffer = NULL;
|
||||||
new_bindings[i].used = NULL;
|
new_bindings[i].used = NULL;
|
||||||
new_bindings[i].data_left = -1;
|
new_bindings[i].data_left = -1;
|
||||||
|
new_bindings[i].ttlbuf = NULL;
|
||||||
|
new_bindings[i].ttlbuflen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new_bindings;
|
return new_bindings;
|
||||||
|
@ -22,6 +22,8 @@ struct BindInfoClass_
|
|||||||
char *buffer; /* pointer to the buffer */
|
char *buffer; /* pointer to the buffer */
|
||||||
Int4 *used; /* used space in the buffer (for strings
|
Int4 *used; /* used space in the buffer (for strings
|
||||||
* not counting the '\0') */
|
* not counting the '\0') */
|
||||||
|
char *ttlbuf; /* to save the large result */
|
||||||
|
Int4 ttlbuflen; /* the buffer length */
|
||||||
Int2 returntype; /* kind of conversion to be applied when
|
Int2 returntype; /* kind of conversion to be applied when
|
||||||
* returning (SQL_C_DEFAULT,
|
* returning (SQL_C_DEFAULT,
|
||||||
* SQL_C_CHAR...) */
|
* SQL_C_CHAR...) */
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
*-------
|
*-------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "pgtypes.h"
|
||||||
#include "columninfo.h"
|
#include "columninfo.h"
|
||||||
|
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
@ -95,7 +96,16 @@ CI_read_fields(ColumnInfoClass *self, ConnectionClass *conn)
|
|||||||
new_atttypmod = (Int4) SOCK_get_int(sock, 4);
|
new_atttypmod = (Int4) SOCK_get_int(sock, 4);
|
||||||
|
|
||||||
/* Subtract the header length */
|
/* Subtract the header length */
|
||||||
new_atttypmod -= 4;
|
switch (new_adtid)
|
||||||
|
{
|
||||||
|
case PG_TYPE_DATETIME:
|
||||||
|
case PG_TYPE_TIMESTAMP_NO_TMZONE:
|
||||||
|
case PG_TYPE_TIME:
|
||||||
|
case PG_TYPE_TIME_WITH_TMZONE:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
new_atttypmod -= 4;
|
||||||
|
}
|
||||||
if (new_atttypmod < 0)
|
if (new_atttypmod < 0)
|
||||||
new_atttypmod = -1;
|
new_atttypmod = -1;
|
||||||
|
|
||||||
|
@ -38,6 +38,11 @@
|
|||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "pgapifunc.h"
|
#include "pgapifunc.h"
|
||||||
|
|
||||||
|
#ifdef __CYGWIN__
|
||||||
|
#define TIMEZONE_GLOBAL _timezone
|
||||||
|
#elif defined(WIN32) || defined(HAVE_INT_TIMEZONE)
|
||||||
|
#define TIMEZONE_GLOBAL timezone
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* How to map ODBC scalar functions {fn func(args)} to Postgres.
|
* How to map ODBC scalar functions {fn func(args)} to Postgres.
|
||||||
@ -136,6 +141,156 @@ static char *conv_to_octal(unsigned char val);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TIMESTAMP <-----> SIMPLE_TIME
|
||||||
|
* precision support since 7.2.
|
||||||
|
* time zone support is unavailable(the stuff is unreliable)
|
||||||
|
*/
|
||||||
|
static BOOL timestamp2stime(const char * str, SIMPLE_TIME *st, BOOL *bZone, int *zone)
|
||||||
|
{
|
||||||
|
char rest[64], *ptr;
|
||||||
|
int scnt, i;
|
||||||
|
long timediff;
|
||||||
|
BOOL withZone = *bZone;
|
||||||
|
|
||||||
|
*bZone = FALSE;
|
||||||
|
*zone = 0;
|
||||||
|
st->fr = 0;
|
||||||
|
if ((scnt = sscanf(str, "%4d-%2d-%2d %2d:%2d:%2d%s", &st->y, &st->m, &st->d, &st->hh, &st->mm, &st->ss, rest)) < 6)
|
||||||
|
return FALSE;
|
||||||
|
else if (scnt == 6)
|
||||||
|
return TRUE;
|
||||||
|
switch (rest[0])
|
||||||
|
{
|
||||||
|
case '+':
|
||||||
|
*bZone = TRUE;
|
||||||
|
*zone = atoi(&rest[1]);
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
*bZone = TRUE;
|
||||||
|
*zone = -atoi(&rest[1]);
|
||||||
|
break;
|
||||||
|
case '.':
|
||||||
|
if ((ptr = strchr(rest, '+')) != NULL)
|
||||||
|
{
|
||||||
|
*bZone = TRUE;
|
||||||
|
*zone = atoi(&ptr[1]);
|
||||||
|
*ptr = '\0';
|
||||||
|
}
|
||||||
|
else if ((ptr = strchr(rest, '-')) != NULL)
|
||||||
|
{
|
||||||
|
*bZone = TRUE;
|
||||||
|
*zone = -atoi(&ptr[1]);
|
||||||
|
*ptr = '\0';
|
||||||
|
}
|
||||||
|
for (i = 1; i < 10; i++)
|
||||||
|
{
|
||||||
|
if (!isdigit(rest[i]))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
for (; i < 10; i++)
|
||||||
|
rest[i] = '0';
|
||||||
|
rest[i] = '\0';
|
||||||
|
st->fr = atoi(&rest[1]);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
if (!withZone || !*bZone || st->y < 1970)
|
||||||
|
return TRUE;
|
||||||
|
#if defined(WIN32) || defined(HAVE_INT_TIMEZONE)
|
||||||
|
if (!tzname[0] || !tzname[0][0])
|
||||||
|
{
|
||||||
|
*bZone = FALSE;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
timediff = TIMEZONE_GLOBAL + (*zone) * 3600;
|
||||||
|
if (!daylight && timediff == 0) /* the same timezone */
|
||||||
|
return TRUE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct tm tm, *tm2;
|
||||||
|
time_t time0;
|
||||||
|
|
||||||
|
*bZone = FALSE;
|
||||||
|
tm.tm_year = st->y - 1900;
|
||||||
|
tm.tm_mon = st->m - 1;
|
||||||
|
tm.tm_mday = st->d;
|
||||||
|
tm.tm_hour = st->hh;
|
||||||
|
tm.tm_min = st->mm;
|
||||||
|
tm.tm_sec = st->ss;
|
||||||
|
tm.tm_isdst = -1;
|
||||||
|
time0 = mktime(&tm);
|
||||||
|
if (time0 < 0)
|
||||||
|
return TRUE;
|
||||||
|
if (tm.tm_isdst > 0)
|
||||||
|
timediff -= 3600;
|
||||||
|
if (timediff == 0) /* the same time zone */
|
||||||
|
return TRUE;
|
||||||
|
time0 -= timediff;
|
||||||
|
if (time0 >= 0 && (tm2 = localtime(&time0)) != NULL)
|
||||||
|
{
|
||||||
|
st->y = tm2->tm_year + 1900;
|
||||||
|
st->m = tm2->tm_mon + 1;
|
||||||
|
st->d = tm2->tm_mday;
|
||||||
|
st->hh= tm2->tm_hour;
|
||||||
|
st->mm= tm2->tm_min;
|
||||||
|
st->ss= tm2->tm_sec;
|
||||||
|
*bZone = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* WIN32 */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL stime2timestamp(const SIMPLE_TIME *st, char * str, BOOL bZone, BOOL precision)
|
||||||
|
{
|
||||||
|
char precstr[16], zonestr[16];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
precstr[0] = '\0';
|
||||||
|
if (precision && st->fr)
|
||||||
|
{
|
||||||
|
sprintf(precstr, ".%09d", st->fr);
|
||||||
|
for (i = 9; i > 0; i--)
|
||||||
|
{
|
||||||
|
if (precstr[i] != '0')
|
||||||
|
break;
|
||||||
|
precstr[i] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zonestr[0] = '\0';
|
||||||
|
#if defined(WIN32) || defined(HAVE_INT_TIMEZONE)
|
||||||
|
if (bZone && tzname[0] && tzname[0][0] && st->y >= 1970)
|
||||||
|
{
|
||||||
|
long zoneint;
|
||||||
|
struct tm tm;
|
||||||
|
time_t time0;
|
||||||
|
|
||||||
|
zoneint = TIMEZONE_GLOBAL;
|
||||||
|
if (daylight && st->y >=1900)
|
||||||
|
{
|
||||||
|
tm.tm_year = st->y - 1900;
|
||||||
|
tm.tm_mon = st->m - 1;
|
||||||
|
tm.tm_mday = st->d;
|
||||||
|
tm.tm_hour = st->hh;
|
||||||
|
tm.tm_min = st->mm;
|
||||||
|
tm.tm_sec = st->ss;
|
||||||
|
tm.tm_isdst = -1;
|
||||||
|
time0 = mktime(&tm);
|
||||||
|
if (time0 >= 0 && tm.tm_isdst > 0)
|
||||||
|
zoneint -= 3600;
|
||||||
|
}
|
||||||
|
if (zoneint > 0)
|
||||||
|
sprintf(zonestr, "-%02d", (int)zoneint / 3600);
|
||||||
|
else
|
||||||
|
sprintf(zonestr, "+%02d", -(int)zoneint / 3600);
|
||||||
|
}
|
||||||
|
#endif /* WIN32 */
|
||||||
|
sprintf(str, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d%s%s", st->y, st->m, st->d, st->hh, st->mm, st->ss, precstr, zonestr);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* This is called by SQLFetch() */
|
/* This is called by SQLFetch() */
|
||||||
int
|
int
|
||||||
copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, void *value, int col)
|
copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, void *value, int col)
|
||||||
@ -165,14 +320,29 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
|||||||
int bind_size = stmt->options.bind_size;
|
int bind_size = stmt->options.bind_size;
|
||||||
int result = COPY_OK;
|
int result = COPY_OK;
|
||||||
BOOL changed;
|
BOOL changed;
|
||||||
static char *tempBuf = NULL;
|
|
||||||
static unsigned int tempBuflen = 0;
|
|
||||||
const char *neut_str = value;
|
const char *neut_str = value;
|
||||||
char midtemp[2][32];
|
char midtemp[2][32];
|
||||||
int mtemp_cnt = 0;
|
int mtemp_cnt = 0;
|
||||||
|
static BindInfoClass sbic;
|
||||||
|
BindInfoClass *pbic;
|
||||||
|
|
||||||
if (!tempBuf)
|
if (stmt->current_col >= 0)
|
||||||
tempBuflen = 0;
|
{
|
||||||
|
pbic = &stmt->bindings[stmt->current_col];
|
||||||
|
if (pbic->data_left == -2)
|
||||||
|
pbic->data_left = (cbValueMax > 0) ? 0 : -1; /* This seems to be * needed for ADO ? */
|
||||||
|
if (pbic->data_left == 0)
|
||||||
|
{
|
||||||
|
if (pbic->ttlbuf != NULL)
|
||||||
|
{
|
||||||
|
free(pbic->ttlbuf);
|
||||||
|
pbic->ttlbuf = NULL;
|
||||||
|
pbic->ttlbuflen = 0;
|
||||||
|
}
|
||||||
|
pbic->data_left = -2; /* needed by ADO ? */
|
||||||
|
return COPY_NO_DATA_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
/*---------
|
/*---------
|
||||||
* rgbValueOffset is *ONLY* for character and binary data.
|
* rgbValueOffset is *ONLY* for character and binary data.
|
||||||
* pcbValueOffset is for computing any pcbValue location
|
* pcbValueOffset is for computing any pcbValue location
|
||||||
@ -243,8 +413,15 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
|||||||
case PG_TYPE_ABSTIME:
|
case PG_TYPE_ABSTIME:
|
||||||
case PG_TYPE_DATETIME:
|
case PG_TYPE_DATETIME:
|
||||||
case PG_TYPE_TIMESTAMP:
|
case PG_TYPE_TIMESTAMP:
|
||||||
|
st.fr = 0;
|
||||||
if (strnicmp(value, "invalid", 7) != 0)
|
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);
|
{
|
||||||
|
BOOL bZone = (field_type != PG_TYPE_TIMESTAMP_NO_TMZONE && PG_VERSION_GE(SC_get_conn(stmt), 7.2));
|
||||||
|
int zone;
|
||||||
|
/*sscanf(value, "%4d-%2d-%2d %2d:%2d:%2d", &st.y, &st.m, &st.d, &st.hh, &st.mm, &st.ss);*/
|
||||||
|
bZone = FALSE; /* time zone stuff is unreliable */
|
||||||
|
timestamp2stime(value, &st, &bZone, &zone);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -421,10 +598,14 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (stmt->current_col >= 0 && stmt->bindings[stmt->current_col].data_left == -2)
|
if (stmt->current_col < 0)
|
||||||
stmt->bindings[stmt->current_col].data_left = (cbValueMax > 0) ? 0 : -1; /* This seems to be
|
{
|
||||||
* needed for ADO ? */
|
pbic = &sbic;
|
||||||
if (stmt->current_col < 0 || stmt->bindings[stmt->current_col].data_left < 0)
|
pbic->data_left = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pbic = &stmt->bindings[stmt->current_col];
|
||||||
|
if (pbic->data_left < 0)
|
||||||
{
|
{
|
||||||
/* convert linefeeds to carriage-return/linefeed */
|
/* convert linefeeds to carriage-return/linefeed */
|
||||||
len = convert_linefeeds(neut_str, NULL, 0, &changed);
|
len = convert_linefeeds(neut_str, NULL, 0, &changed);
|
||||||
@ -434,51 +615,42 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
|||||||
result = COPY_RESULT_TRUNCATED;
|
result = COPY_RESULT_TRUNCATED;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (!pbic->ttlbuf)
|
||||||
|
pbic->ttlbuflen = 0;
|
||||||
if (changed || len >= cbValueMax)
|
if (changed || len >= cbValueMax)
|
||||||
{
|
{
|
||||||
if (len >= (int) tempBuflen)
|
if (len >= (int) pbic->ttlbuflen)
|
||||||
{
|
{
|
||||||
tempBuf = realloc(tempBuf, len + 1);
|
pbic->ttlbuf = realloc(pbic->ttlbuf, len + 1);
|
||||||
tempBuflen = len + 1;
|
pbic->ttlbuflen = len + 1;
|
||||||
}
|
}
|
||||||
convert_linefeeds(neut_str, tempBuf, tempBuflen, &changed);
|
convert_linefeeds(neut_str, pbic->ttlbuf, pbic->ttlbuflen, &changed);
|
||||||
ptr = tempBuf;
|
ptr = pbic->ttlbuf;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (tempBuf)
|
if (pbic->ttlbuf)
|
||||||
{
|
{
|
||||||
free(tempBuf);
|
free(pbic->ttlbuf);
|
||||||
tempBuf = NULL;
|
pbic->ttlbuf = NULL;
|
||||||
}
|
}
|
||||||
ptr = neut_str;
|
ptr = neut_str;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ptr = tempBuf;
|
ptr = pbic->ttlbuf;
|
||||||
|
|
||||||
mylog("DEFAULT: len = %d, ptr = '%s'\n", len, ptr);
|
mylog("DEFAULT: len = %d, ptr = '%s'\n", len, ptr);
|
||||||
|
|
||||||
if (stmt->current_col >= 0)
|
if (stmt->current_col >= 0)
|
||||||
{
|
{
|
||||||
if (stmt->bindings[stmt->current_col].data_left == 0)
|
if (pbic->data_left > 0)
|
||||||
{
|
{
|
||||||
if (tempBuf)
|
ptr += strlen(ptr) - pbic->data_left;
|
||||||
{
|
len = pbic->data_left;
|
||||||
free(tempBuf);
|
|
||||||
tempBuf = NULL;
|
|
||||||
}
|
|
||||||
/* The following seems to be needed for ADO ? */
|
|
||||||
stmt->bindings[stmt->current_col].data_left = -2;
|
|
||||||
return COPY_NO_DATA_FOUND;
|
|
||||||
}
|
|
||||||
else if (stmt->bindings[stmt->current_col].data_left > 0)
|
|
||||||
{
|
|
||||||
ptr += strlen(ptr) - stmt->bindings[stmt->current_col].data_left;
|
|
||||||
len = stmt->bindings[stmt->current_col].data_left;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
stmt->bindings[stmt->current_col].data_left = len;
|
pbic->data_left = len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cbValueMax > 0)
|
if (cbValueMax > 0)
|
||||||
@ -491,7 +663,7 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
|||||||
|
|
||||||
/* Adjust data_left for next time */
|
/* Adjust data_left for next time */
|
||||||
if (stmt->current_col >= 0)
|
if (stmt->current_col >= 0)
|
||||||
stmt->bindings[stmt->current_col].data_left -= copy_len;
|
pbic->data_left -= copy_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -502,10 +674,10 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
|||||||
result = COPY_RESULT_TRUNCATED;
|
result = COPY_RESULT_TRUNCATED;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (tempBuf)
|
if (pbic->ttlbuf != NULL)
|
||||||
{
|
{
|
||||||
free(tempBuf);
|
free(pbic->ttlbuf);
|
||||||
tempBuf = NULL;
|
pbic->ttlbuf = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -537,6 +709,9 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
|||||||
switch (fCType)
|
switch (fCType)
|
||||||
{
|
{
|
||||||
case SQL_C_DATE:
|
case SQL_C_DATE:
|
||||||
|
#if (ODBCVER >= 0x0300)
|
||||||
|
case SQL_C_TYPE_DATE: /* 91 */
|
||||||
|
#endif
|
||||||
len = 6;
|
len = 6;
|
||||||
{
|
{
|
||||||
DATE_STRUCT *ds;
|
DATE_STRUCT *ds;
|
||||||
@ -552,6 +727,9 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_C_TIME:
|
case SQL_C_TIME:
|
||||||
|
#if (ODBCVER >= 0x0300)
|
||||||
|
case SQL_C_TYPE_TIME: /* 92 */
|
||||||
|
#endif
|
||||||
len = 6;
|
len = 6;
|
||||||
{
|
{
|
||||||
TIME_STRUCT *ts;
|
TIME_STRUCT *ts;
|
||||||
@ -567,6 +745,9 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_C_TIMESTAMP:
|
case SQL_C_TIMESTAMP:
|
||||||
|
#if (ODBCVER >= 0x0300)
|
||||||
|
case SQL_C_TYPE_TIMESTAMP: /* 93 */
|
||||||
|
#endif
|
||||||
len = 16;
|
len = 16;
|
||||||
{
|
{
|
||||||
TIMESTAMP_STRUCT *ts;
|
TIMESTAMP_STRUCT *ts;
|
||||||
@ -581,7 +762,7 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
|||||||
ts->hour = st.hh;
|
ts->hour = st.hh;
|
||||||
ts->minute = st.mm;
|
ts->minute = st.mm;
|
||||||
ts->second = st.ss;
|
ts->second = st.ss;
|
||||||
ts->fraction = 0;
|
ts->fraction = st.fr;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -671,37 +852,38 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
|||||||
/* truncate if necessary */
|
/* truncate if necessary */
|
||||||
/* convert octal escapes to bytes */
|
/* convert octal escapes to bytes */
|
||||||
|
|
||||||
if (len = strlen(neut_str), len >= (int) tempBuflen)
|
if (stmt->current_col < 0)
|
||||||
{
|
{
|
||||||
tempBuf = realloc(tempBuf, len + 1);
|
pbic = &sbic;
|
||||||
tempBuflen = len + 1;
|
pbic->data_left = -1;
|
||||||
}
|
}
|
||||||
len = convert_from_pgbinary(neut_str, tempBuf, tempBuflen);
|
else
|
||||||
ptr = tempBuf;
|
pbic = &stmt->bindings[stmt->current_col];
|
||||||
|
if (!pbic->ttlbuf)
|
||||||
|
pbic->ttlbuflen = 0;
|
||||||
|
if (len = strlen(neut_str), len >= (int) pbic->ttlbuflen)
|
||||||
|
{
|
||||||
|
pbic->ttlbuf = realloc(pbic->ttlbuf, len + 1);
|
||||||
|
pbic->ttlbuflen = len + 1;
|
||||||
|
}
|
||||||
|
len = convert_from_pgbinary(neut_str, pbic->ttlbuf, pbic->ttlbuflen);
|
||||||
|
ptr = pbic->ttlbuf;
|
||||||
|
|
||||||
if (stmt->current_col >= 0)
|
if (stmt->current_col >= 0)
|
||||||
{
|
{
|
||||||
/* No more data left for this column */
|
|
||||||
if (stmt->bindings[stmt->current_col].data_left == 0)
|
|
||||||
{
|
|
||||||
free(tempBuf);
|
|
||||||
tempBuf = NULL;
|
|
||||||
return COPY_NO_DATA_FOUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Second (or more) call to SQLGetData so move the
|
* Second (or more) call to SQLGetData so move the
|
||||||
* pointer
|
* pointer
|
||||||
*/
|
*/
|
||||||
else if (stmt->bindings[stmt->current_col].data_left > 0)
|
if (pbic->data_left > 0)
|
||||||
{
|
{
|
||||||
ptr += len - stmt->bindings[stmt->current_col].data_left;
|
ptr += len - pbic->data_left;
|
||||||
len = stmt->bindings[stmt->current_col].data_left;
|
len = pbic->data_left;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First call to SQLGetData so initialize data_left */
|
/* First call to SQLGetData so initialize data_left */
|
||||||
else
|
else
|
||||||
stmt->bindings[stmt->current_col].data_left = len;
|
pbic->data_left = len;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -714,7 +896,7 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
|||||||
|
|
||||||
/* Adjust data_left for next time */
|
/* Adjust data_left for next time */
|
||||||
if (stmt->current_col >= 0)
|
if (stmt->current_col >= 0)
|
||||||
stmt->bindings[stmt->current_col].data_left -= copy_len;
|
pbic->data_left -= copy_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -724,10 +906,10 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
|||||||
if (len > cbValueMax)
|
if (len > cbValueMax)
|
||||||
result = COPY_RESULT_TRUNCATED;
|
result = COPY_RESULT_TRUNCATED;
|
||||||
|
|
||||||
if (tempBuf)
|
if (pbic->ttlbuf)
|
||||||
{
|
{
|
||||||
free(tempBuf);
|
free(pbic->ttlbuf);
|
||||||
tempBuf = NULL;
|
pbic->ttlbuf = NULL;
|
||||||
}
|
}
|
||||||
mylog("SQL_C_BINARY: len = %d, copy_len = %d\n", len, copy_len);
|
mylog("SQL_C_BINARY: len = %d, copy_len = %d\n", len, copy_len);
|
||||||
break;
|
break;
|
||||||
@ -741,6 +923,8 @@ copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2
|
|||||||
if (pcbValue)
|
if (pcbValue)
|
||||||
*(SDWORD *) ((char *) pcbValue + pcbValueOffset) = len;
|
*(SDWORD *) ((char *) pcbValue + pcbValueOffset) = len;
|
||||||
|
|
||||||
|
if (result == COPY_OK && stmt->current_col >=0)
|
||||||
|
stmt->bindings[stmt->current_col].data_left = 0;
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1406,6 +1590,9 @@ copy_statement_with_parameters(StatementClass *stmt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SQL_C_DATE:
|
case SQL_C_DATE:
|
||||||
|
#if (ODBCVER >= 0x0300)
|
||||||
|
case SQL_C_TYPE_DATE: /* 91 */
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
DATE_STRUCT *ds = (DATE_STRUCT *) buffer;
|
DATE_STRUCT *ds = (DATE_STRUCT *) buffer;
|
||||||
|
|
||||||
@ -1417,6 +1604,9 @@ copy_statement_with_parameters(StatementClass *stmt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SQL_C_TIME:
|
case SQL_C_TIME:
|
||||||
|
#if (ODBCVER >= 0x0300)
|
||||||
|
case SQL_C_TYPE_TIME: /* 92 */
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
TIME_STRUCT *ts = (TIME_STRUCT *) buffer;
|
TIME_STRUCT *ts = (TIME_STRUCT *) buffer;
|
||||||
|
|
||||||
@ -1428,6 +1618,9 @@ copy_statement_with_parameters(StatementClass *stmt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case SQL_C_TIMESTAMP:
|
case SQL_C_TIMESTAMP:
|
||||||
|
#if (ODBCVER >= 0x0300)
|
||||||
|
case SQL_C_TYPE_TIMESTAMP: /* 93 */
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
TIMESTAMP_STRUCT *tss = (TIMESTAMP_STRUCT *) buffer;
|
TIMESTAMP_STRUCT *tss = (TIMESTAMP_STRUCT *) buffer;
|
||||||
|
|
||||||
@ -1437,6 +1630,7 @@ copy_statement_with_parameters(StatementClass *stmt)
|
|||||||
st.hh = tss->hour;
|
st.hh = tss->hour;
|
||||||
st.mm = tss->minute;
|
st.mm = tss->minute;
|
||||||
st.ss = tss->second;
|
st.ss = tss->second;
|
||||||
|
st.fr = tss->fraction;
|
||||||
|
|
||||||
mylog("m=%d,d=%d,y=%d,hh=%d,mm=%d,ss=%d\n", st.m, st.d, st.y, st.hh, st.mm, st.ss);
|
mylog("m=%d,d=%d,y=%d,hh=%d,mm=%d,ss=%d\n", st.m, st.d, st.y, st.hh, st.mm, st.ss);
|
||||||
|
|
||||||
@ -1487,6 +1681,9 @@ copy_statement_with_parameters(StatementClass *stmt)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_DATE:
|
case SQL_DATE:
|
||||||
|
#if (ODBCVER >= 0x0300)
|
||||||
|
case SQL_TYPE_DATE: /* 91 */
|
||||||
|
#endif
|
||||||
if (buf)
|
if (buf)
|
||||||
{ /* copy char data to time */
|
{ /* copy char data to time */
|
||||||
my_strcpy(cbuf, sizeof(cbuf), buf, used);
|
my_strcpy(cbuf, sizeof(cbuf), buf, used);
|
||||||
@ -1499,6 +1696,9 @@ copy_statement_with_parameters(StatementClass *stmt)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_TIME:
|
case SQL_TIME:
|
||||||
|
#if (ODBCVER >= 0x0300)
|
||||||
|
case SQL_TYPE_TIME: /* 92 */
|
||||||
|
#endif
|
||||||
if (buf)
|
if (buf)
|
||||||
{ /* copy char data to time */
|
{ /* copy char data to time */
|
||||||
my_strcpy(cbuf, sizeof(cbuf), buf, used);
|
my_strcpy(cbuf, sizeof(cbuf), buf, used);
|
||||||
@ -1511,6 +1711,9 @@ copy_statement_with_parameters(StatementClass *stmt)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_TIMESTAMP:
|
case SQL_TIMESTAMP:
|
||||||
|
#if (ODBCVER >= 0x0300)
|
||||||
|
case SQL_TYPE_TIMESTAMP: /* 93 */
|
||||||
|
#endif
|
||||||
|
|
||||||
if (buf)
|
if (buf)
|
||||||
{
|
{
|
||||||
@ -1518,8 +1721,12 @@ copy_statement_with_parameters(StatementClass *stmt)
|
|||||||
parse_datetime(cbuf, &st);
|
parse_datetime(cbuf, &st);
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(tmp, "'%.4d-%.2d-%.2d %.2d:%.2d:%.2d'",
|
/* sprintf(tmp, "'%.4d-%.2d-%.2d %.2d:%.2d:%.2d'",
|
||||||
st.y, st.m, st.d, st.hh, st.mm, st.ss);
|
st.y, st.m, st.d, st.hh, st.mm, st.ss);*/
|
||||||
|
tmp[0] = '\'';
|
||||||
|
/* Time zone stuff is unreliable */
|
||||||
|
stime2timestamp(&st, tmp + 1, FALSE, PG_VERSION_GE(conn, 7.2));
|
||||||
|
strcat(tmp, "'");
|
||||||
|
|
||||||
CVT_APPEND_STR(tmp);
|
CVT_APPEND_STR(tmp);
|
||||||
|
|
||||||
@ -2203,7 +2410,43 @@ decode(const char *in, char *out)
|
|||||||
out[o++] = '\0';
|
out[o++] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *hextbl = "0123456789ABCDEF";
|
||||||
|
static int
|
||||||
|
pg_bin2hex(UCHAR *src, UCHAR *dst, int length)
|
||||||
|
{
|
||||||
|
UCHAR chr, *src_wk, *dst_wk;
|
||||||
|
BOOL backwards;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
backwards = FALSE;
|
||||||
|
if (dst < src)
|
||||||
|
{
|
||||||
|
if (dst + length > src + 1)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else if (dst < src + length)
|
||||||
|
backwards = TRUE;
|
||||||
|
if (backwards)
|
||||||
|
{
|
||||||
|
for (i = 0, src_wk = src + length - 1, dst_wk = dst + 2 * length - 1; i < length; i++, src_wk--)
|
||||||
|
{
|
||||||
|
chr = *src_wk;
|
||||||
|
*dst_wk-- = hextbl[chr % 16];
|
||||||
|
*dst_wk-- = hextbl[chr >> 4];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (i = 0, src_wk = src, dst_wk = dst; i < length; i++, src_wk++)
|
||||||
|
{
|
||||||
|
chr = *src_wk;
|
||||||
|
*dst_wk++ = hextbl[chr >> 4];
|
||||||
|
*dst_wk++ = hextbl[chr % 16];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dst[2 * length] = '\0';
|
||||||
|
return length;
|
||||||
|
}
|
||||||
/*-------
|
/*-------
|
||||||
* 1. get oid (from 'value')
|
* 1. get oid (from 'value')
|
||||||
* 2. open the large object
|
* 2. open the large object
|
||||||
@ -2231,6 +2474,7 @@ convert_lo(StatementClass *stmt, const void *value, Int2 fCType, PTR rgbValue,
|
|||||||
BindInfoClass *bindInfo = NULL;
|
BindInfoClass *bindInfo = NULL;
|
||||||
ConnectionClass *conn = SC_get_conn(stmt);
|
ConnectionClass *conn = SC_get_conn(stmt);
|
||||||
ConnInfo *ci = &(conn->connInfo);
|
ConnInfo *ci = &(conn->connInfo);
|
||||||
|
int factor = (fCType == SQL_C_CHAR ? 2 : 1);
|
||||||
|
|
||||||
/* If using SQLGetData, then current_col will be set */
|
/* If using SQLGetData, then current_col will be set */
|
||||||
if (stmt->current_col >= 0)
|
if (stmt->current_col >= 0)
|
||||||
@ -2304,7 +2548,7 @@ convert_lo(StatementClass *stmt, const void *value, Int2 fCType, PTR rgbValue,
|
|||||||
return COPY_GENERAL_ERROR;
|
return COPY_GENERAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = lo_read(conn, stmt->lobj_fd, (char *) rgbValue, cbValueMax);
|
retval = lo_read(conn, stmt->lobj_fd, (char *) rgbValue, factor > 1 ? (cbValueMax - 1) / factor : cbValueMax);
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
{
|
{
|
||||||
lo_close(conn, stmt->lobj_fd);
|
lo_close(conn, stmt->lobj_fd);
|
||||||
@ -2341,13 +2585,15 @@ convert_lo(StatementClass *stmt, const void *value, Int2 fCType, PTR rgbValue,
|
|||||||
return COPY_GENERAL_ERROR;
|
return COPY_GENERAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (factor > 1)
|
||||||
|
pg_bin2hex((char *) rgbValue, (char *) rgbValue, retval);
|
||||||
if (retval < left)
|
if (retval < left)
|
||||||
result = COPY_RESULT_TRUNCATED;
|
result = COPY_RESULT_TRUNCATED;
|
||||||
else
|
else
|
||||||
result = COPY_OK;
|
result = COPY_OK;
|
||||||
|
|
||||||
if (pcbValue)
|
if (pcbValue)
|
||||||
*pcbValue = left < 0 ? SQL_NO_TOTAL : left;
|
*pcbValue = left < 0 ? SQL_NO_TOTAL : left * factor;
|
||||||
|
|
||||||
if (bindInfo && bindInfo->data_left > 0)
|
if (bindInfo && bindInfo->data_left > 0)
|
||||||
bindInfo->data_left -= retval;
|
bindInfo->data_left -= retval;
|
||||||
|
@ -27,7 +27,8 @@ typedef struct
|
|||||||
int hh;
|
int hh;
|
||||||
int mm;
|
int mm;
|
||||||
int ss;
|
int ss;
|
||||||
} SIMPLE_TIME;
|
int fr;
|
||||||
|
} SIMPLE_TIME;
|
||||||
|
|
||||||
int copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, void *value, int col);
|
int copy_and_convert_field_bindinfo(StatementClass *stmt, Int4 field_type, void *value, int col);
|
||||||
int copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 fCType,
|
int copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 fCType,
|
||||||
|
@ -216,32 +216,6 @@ PGAPI_GetInfo(
|
|||||||
|
|
||||||
case SQL_DRIVER_ODBC_VER:
|
case SQL_DRIVER_ODBC_VER:
|
||||||
p = DRIVER_ODBC_VER;
|
p = DRIVER_ODBC_VER;
|
||||||
#ifdef DRIVER_CURSOR_IMPLEMENT
|
|
||||||
{
|
|
||||||
static char dver[32];
|
|
||||||
|
|
||||||
SQLGetPrivateProfileString(DBMS_NAME,
|
|
||||||
"DriverODBCVer", "", dver, sizeof(dver), "odbcinst.ini");
|
|
||||||
if (dver[0])
|
|
||||||
{
|
|
||||||
int major,
|
|
||||||
minor;
|
|
||||||
|
|
||||||
mylog("REGISTRY_ODBC_VER = %s\n", dver)
|
|
||||||
;
|
|
||||||
if (sscanf(dver, "%x.%x", &major, &minor) >= 2)
|
|
||||||
{
|
|
||||||
Int2 drv_ver = (major << 8) + minor;
|
|
||||||
|
|
||||||
if (drv_ver > ODBCVER)
|
|
||||||
{
|
|
||||||
conn->driver_version = drv_ver;
|
|
||||||
p = dver;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif /* DRIVER_CURSOR_IMPLEMENT */
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SQL_DRIVER_VER: /* ODBC 1.0 */
|
case SQL_DRIVER_VER: /* ODBC 1.0 */
|
||||||
@ -842,6 +816,7 @@ PGAPI_GetFunctions(
|
|||||||
|
|
||||||
if (fFunction == SQL_API_ALL_FUNCTIONS)
|
if (fFunction == SQL_API_ALL_FUNCTIONS)
|
||||||
{
|
{
|
||||||
|
#if (ODBCVER < 0x0300)
|
||||||
if (ci->drivers.lie)
|
if (ci->drivers.lie)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@ -856,6 +831,7 @@ PGAPI_GetFunctions(
|
|||||||
pfExists[i] = TRUE;
|
pfExists[i] = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
memset(pfExists, 0, sizeof(UWORD) * 100);
|
memset(pfExists, 0, sizeof(UWORD) * 100);
|
||||||
|
|
||||||
@ -2685,7 +2661,7 @@ PGAPI_PrimaryKeys(
|
|||||||
/*
|
/*
|
||||||
* Multibyte support stuff for SQLForeignKeys().
|
* Multibyte support stuff for SQLForeignKeys().
|
||||||
* There may be much more effective way in the
|
* There may be much more effective way in the
|
||||||
* future version. The way is very forcive currently.
|
* future version. The way is very forcible currently.
|
||||||
*/
|
*/
|
||||||
static BOOL
|
static BOOL
|
||||||
isMultibyte(const unsigned char *str)
|
isMultibyte(const unsigned char *str)
|
||||||
|
@ -18,8 +18,8 @@
|
|||||||
*-------
|
*-------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ODBCVER_REP
|
#ifndef ODBCVER
|
||||||
#define ODBCVER_REP 0x0300
|
#define ODBCVER 0x0300
|
||||||
#endif
|
#endif
|
||||||
#include "psqlodbc.h"
|
#include "psqlodbc.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -344,7 +344,7 @@ SQLGetStmtAttr(HSTMT StatementHandle,
|
|||||||
len = 4;
|
len = 4;
|
||||||
break;
|
break;
|
||||||
case SQL_ATTR_AUTO_IPD: /* 10001 */
|
case SQL_ATTR_AUTO_IPD: /* 10001 */
|
||||||
case SQL_ATTR_ROW_BIND_TYPE: /* == SQL_BIND_TYPE */
|
/* case SQL_ATTR_ROW_BIND_TYPE: ** == SQL_BIND_TYPE(ODBC2.0) */
|
||||||
case SQL_ATTR_PARAMSET_SIZE: /* 22 */
|
case SQL_ATTR_PARAMSET_SIZE: /* 22 */
|
||||||
case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */
|
case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */
|
||||||
case SQL_ATTR_PARAMS_PROCESSED_PTR: /* 21 */
|
case SQL_ATTR_PARAMS_PROCESSED_PTR: /* 21 */
|
||||||
@ -484,7 +484,7 @@ SQLSetStmtAttr(HSTMT StatementHandle,
|
|||||||
case SQL_ATTR_APP_ROW_DESC: /* 10010 */
|
case SQL_ATTR_APP_ROW_DESC: /* 10010 */
|
||||||
case SQL_ATTR_APP_PARAM_DESC: /* 10011 */
|
case SQL_ATTR_APP_PARAM_DESC: /* 10011 */
|
||||||
case SQL_ATTR_AUTO_IPD: /* 10001 */
|
case SQL_ATTR_AUTO_IPD: /* 10001 */
|
||||||
/* case SQL_ATTR_ROW_BIND_TYPE: */ /* == SQL_BIND_TYPE */
|
/* case SQL_ATTR_ROW_BIND_TYPE: ** == SQL_BIND_TYPE(ODBC2.0) */
|
||||||
case SQL_ATTR_IMP_ROW_DESC: /* 10012 */
|
case SQL_ATTR_IMP_ROW_DESC: /* 10012 */
|
||||||
case SQL_ATTR_IMP_PARAM_DESC: /* 10013 */
|
case SQL_ATTR_IMP_PARAM_DESC: /* 10013 */
|
||||||
case SQL_ATTR_METADATA_ID: /* 10014 */
|
case SQL_ATTR_METADATA_ID: /* 10014 */
|
||||||
|
@ -536,6 +536,67 @@ getCharPrecision(StatementClass *stmt, Int4 type, int col, int handle_unknown_si
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Int2
|
||||||
|
getTimestampScale(StatementClass *stmt, Int4 type, int col)
|
||||||
|
{
|
||||||
|
ConnectionClass *conn = SC_get_conn (stmt);
|
||||||
|
Int4 atttypmod;
|
||||||
|
QResultClass *result;
|
||||||
|
ColumnInfoClass *flds;
|
||||||
|
|
||||||
|
mylog("getTimestampScale: type=%d, col=%d\n", type, col);
|
||||||
|
|
||||||
|
if (col < 0)
|
||||||
|
return 0;
|
||||||
|
if (PG_VERSION_LT(conn, 7.2))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
result = SC_get_Result(stmt);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Manual Result Sets -- use assigned column width (i.e., from
|
||||||
|
* set_tuplefield_string)
|
||||||
|
*/
|
||||||
|
atttypmod = 0;
|
||||||
|
if (stmt->manual_result)
|
||||||
|
{
|
||||||
|
flds = result->fields;
|
||||||
|
if (flds)
|
||||||
|
atttypmod = flds->atttypmod[col];
|
||||||
|
mylog("atttypmod1=%d\n", atttypmod);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
atttypmod = QR_get_atttypmod(result, col);
|
||||||
|
mylog("atttypmod2=%d\n", atttypmod);
|
||||||
|
return (atttypmod > -1 ? atttypmod : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static Int4
|
||||||
|
getTimestampPrecision(StatementClass *stmt, Int4 type, int col)
|
||||||
|
{
|
||||||
|
Int4 fixed, scale;
|
||||||
|
|
||||||
|
mylog("getTimestampPrecision: type=%d, col=%d\n", type, col);
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case PG_TYPE_TIME:
|
||||||
|
fixed = 8;
|
||||||
|
break;
|
||||||
|
case PG_TYPE_TIME_WITH_TMZONE:
|
||||||
|
fixed = 11;
|
||||||
|
break;
|
||||||
|
case PG_TYPE_TIMESTAMP_NO_TMZONE:
|
||||||
|
fixed = 19;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fixed = 22;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
scale = getTimestampScale(stmt, type, col);
|
||||||
|
return (scale > 0) ? fixed + 1 + scale : fixed;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, PG_TYPE_NUMERIC, SQLColumns will
|
* For PG_TYPE_VARCHAR, PG_TYPE_BPCHAR, PG_TYPE_NUMERIC, SQLColumns will
|
||||||
@ -591,7 +652,8 @@ pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unknown_si
|
|||||||
case PG_TYPE_TIMESTAMP:
|
case PG_TYPE_TIMESTAMP:
|
||||||
return 22;
|
return 22;
|
||||||
case PG_TYPE_DATETIME:
|
case PG_TYPE_DATETIME:
|
||||||
return 22;
|
/* return 22; */
|
||||||
|
return getTimestampPrecision(stmt, type, col);
|
||||||
|
|
||||||
case PG_TYPE_BOOL:
|
case PG_TYPE_BOOL:
|
||||||
return 1;
|
return 1;
|
||||||
@ -728,7 +790,8 @@ pgtype_scale(StatementClass *stmt, Int4 type, int col)
|
|||||||
case PG_TYPE_TIMESTAMP:
|
case PG_TYPE_TIMESTAMP:
|
||||||
return 0;
|
return 0;
|
||||||
case PG_TYPE_DATETIME:
|
case PG_TYPE_DATETIME:
|
||||||
return 0;
|
/* return 0; */
|
||||||
|
return getTimestampScale(stmt, type, col);
|
||||||
|
|
||||||
case PG_TYPE_NUMERIC:
|
case PG_TYPE_NUMERIC:
|
||||||
return getNumericScale(stmt, type, col);
|
return getNumericScale(stmt, type, col);
|
||||||
|
@ -58,8 +58,10 @@
|
|||||||
#define PG_TYPE_VARCHAR 1043
|
#define PG_TYPE_VARCHAR 1043
|
||||||
#define PG_TYPE_DATE 1082
|
#define PG_TYPE_DATE 1082
|
||||||
#define PG_TYPE_TIME 1083
|
#define PG_TYPE_TIME 1083
|
||||||
|
#define PG_TYPE_TIMESTAMP_NO_TMZONE 1114 /* since 7.2 */
|
||||||
#define PG_TYPE_DATETIME 1184
|
#define PG_TYPE_DATETIME 1184
|
||||||
#define PG_TYPE_TIMESTAMP 1296
|
#define PG_TYPE_TIME_WITH_TMZONE 1266 /* since 7.1 */
|
||||||
|
#define PG_TYPE_TIMESTAMP 1296 /* deprecated since 7.0 */
|
||||||
#define PG_TYPE_NUMERIC 1700
|
#define PG_TYPE_NUMERIC 1700
|
||||||
|
|
||||||
/* extern Int4 pgtypes_defined[]; */
|
/* extern Int4 pgtypes_defined[]; */
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
*
|
*
|
||||||
* Comments: See "notice.txt" for copyright and license information.
|
* Comments: See "notice.txt" for copyright and license information.
|
||||||
*
|
*
|
||||||
* $Id: psqlodbc.h,v 1.53 2001/10/28 06:26:14 momjian Exp $
|
* $Id: psqlodbc.h,v 1.54 2001/11/05 09:46:17 inoue Exp $
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -21,9 +21,7 @@
|
|||||||
#include <stdio.h> /* for FILE* pointers: see GLOBAL_VALUES */
|
#include <stdio.h> /* for FILE* pointers: see GLOBAL_VALUES */
|
||||||
|
|
||||||
/* Must come before sql.h */
|
/* Must come before sql.h */
|
||||||
#ifdef ODBCVER_REP
|
#ifndef ODBCVER
|
||||||
#define ODBCVER ODBCVER_REP
|
|
||||||
#else
|
|
||||||
#define ODBCVER 0x0250
|
#define ODBCVER 0x0250
|
||||||
#endif /* ODBCVER_REP */
|
#endif /* ODBCVER_REP */
|
||||||
|
|
||||||
@ -77,18 +75,27 @@ typedef UInt4 Oid;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Driver stuff */
|
/* Driver stuff */
|
||||||
#define DRIVER_ODBC_VER "02.50"
|
|
||||||
|
|
||||||
#define DRIVERNAME "PostgreSQL ODBC"
|
#define DRIVERNAME "PostgreSQL ODBC"
|
||||||
|
#if (ODBCVER >= 0x0300)
|
||||||
|
#define DRIVER_ODBC_VER "03.00"
|
||||||
|
#define DBMS_NAME "PostgreSQL30"
|
||||||
|
#else
|
||||||
|
#define DRIVER_ODBC_VER "02.50"
|
||||||
#define DBMS_NAME "PostgreSQL"
|
#define DBMS_NAME "PostgreSQL"
|
||||||
|
#endif /* ODBCVER */
|
||||||
|
|
||||||
#define POSTGRESDRIVERVERSION "07.01.0008"
|
#define POSTGRESDRIVERVERSION "07.01.0009"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
#if (ODBCVER >= 0x0300)
|
||||||
|
#define DRIVER_FILE_NAME "PSQLODBC30.DLL"
|
||||||
|
#else
|
||||||
#define DRIVER_FILE_NAME "PSQLODBC.DLL"
|
#define DRIVER_FILE_NAME "PSQLODBC.DLL"
|
||||||
|
#endif /* ODBCVER */
|
||||||
#else
|
#else
|
||||||
#define DRIVER_FILE_NAME "libpsqlodbc.so"
|
#define DRIVER_FILE_NAME "libpsqlodbc.so"
|
||||||
#endif
|
#endif /* WIN32 */
|
||||||
|
|
||||||
/* Limits */
|
/* Limits */
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
@ -354,8 +354,8 @@ END
|
|||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 7,1,0,8
|
FILEVERSION 7,1,0,9
|
||||||
PRODUCTVERSION 7,1,0,8
|
PRODUCTVERSION 7,1,0,9
|
||||||
FILEFLAGSMASK 0x3L
|
FILEFLAGSMASK 0x3L
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@ -377,14 +377,14 @@ BEGIN
|
|||||||
VALUE "CompanyName", "Insight Distribution Systems\0"
|
VALUE "CompanyName", "Insight Distribution Systems\0"
|
||||||
#endif
|
#endif
|
||||||
VALUE "FileDescription", "PostgreSQL Driver\0"
|
VALUE "FileDescription", "PostgreSQL Driver\0"
|
||||||
VALUE "FileVersion", " 07.01.0008\0"
|
VALUE "FileVersion", " 07.01.0009\0"
|
||||||
VALUE "InternalName", "psqlodbc\0"
|
VALUE "InternalName", "psqlodbc\0"
|
||||||
VALUE "LegalCopyright", "\0"
|
VALUE "LegalCopyright", "\0"
|
||||||
VALUE "LegalTrademarks", "ODBC(TM) is a trademark of Microsoft Corporation. Microsoft® is a registered trademark of Microsoft Corporation. Windows(TM) is a trademark of Microsoft Corporation.\0"
|
VALUE "LegalTrademarks", "ODBC(TM) is a trademark of Microsoft Corporation. Microsoft® is a registered trademark of Microsoft Corporation. Windows(TM) is a trademark of Microsoft Corporation.\0"
|
||||||
VALUE "OriginalFilename", "psqlodbc.dll\0"
|
VALUE "OriginalFilename", "psqlodbc.dll\0"
|
||||||
VALUE "PrivateBuild", "\0"
|
VALUE "PrivateBuild", "\0"
|
||||||
VALUE "ProductName", "Microsoft Open Database Connectivity\0"
|
VALUE "ProductName", "Microsoft Open Database Connectivity\0"
|
||||||
VALUE "ProductVersion", " 07.01.0008\0"
|
VALUE "ProductVersion", " 07.01.0009\0"
|
||||||
VALUE "SpecialBuild", "\0"
|
VALUE "SpecialBuild", "\0"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
|
@ -320,7 +320,15 @@ SC_Destructor(StatementClass *self)
|
|||||||
*/
|
*/
|
||||||
/* about that here. */
|
/* about that here. */
|
||||||
if (self->bindings)
|
if (self->bindings)
|
||||||
|
{
|
||||||
|
int lf;
|
||||||
|
for (lf = 0; lf < self->bindings_allocated; lf++)
|
||||||
|
{
|
||||||
|
if (self->bindings[lf].ttlbuf != NULL)
|
||||||
|
free(self->bindings[lf].ttlbuf);
|
||||||
|
}
|
||||||
free(self->bindings);
|
free(self->bindings);
|
||||||
|
}
|
||||||
|
|
||||||
/* Free the parsed table information */
|
/* Free the parsed table information */
|
||||||
if (self->ti)
|
if (self->ti)
|
||||||
|
@ -84,7 +84,6 @@ CLEAN :
|
|||||||
-@erase "$(INTDIR)\tuple.obj"
|
-@erase "$(INTDIR)\tuple.obj"
|
||||||
-@erase "$(INTDIR)\tuplelist.obj"
|
-@erase "$(INTDIR)\tuplelist.obj"
|
||||||
-@erase "$(INTDIR)\odbcapi.obj"
|
-@erase "$(INTDIR)\odbcapi.obj"
|
||||||
-@erase "$(INTDIR)\odbcapi30.obj"
|
|
||||||
-@erase "$(INTDIR)\vc60.idb"
|
-@erase "$(INTDIR)\vc60.idb"
|
||||||
-@erase "$(OUTDIR)\psqlodbc.dll"
|
-@erase "$(OUTDIR)\psqlodbc.dll"
|
||||||
-@erase "$(OUTDIR)\psqlodbc.exp"
|
-@erase "$(OUTDIR)\psqlodbc.exp"
|
||||||
@ -169,7 +168,6 @@ LINK32_OBJS= \
|
|||||||
"$(INTDIR)\tuple.obj" \
|
"$(INTDIR)\tuple.obj" \
|
||||||
"$(INTDIR)\tuplelist.obj" \
|
"$(INTDIR)\tuplelist.obj" \
|
||||||
"$(INTDIR)\odbcapi.obj" \
|
"$(INTDIR)\odbcapi.obj" \
|
||||||
"$(INTDIR)\odbcapi30.obj" \
|
|
||||||
"$(INTDIR)\psqlodbc.res"
|
"$(INTDIR)\psqlodbc.res"
|
||||||
|
|
||||||
"$(OUTDIR)\psqlodbc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
"$(OUTDIR)\psqlodbc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||||
@ -219,7 +217,6 @@ CLEAN :
|
|||||||
-@erase "$(INTDIR)\tuple.obj"
|
-@erase "$(INTDIR)\tuple.obj"
|
||||||
-@erase "$(INTDIR)\tuplelist.obj"
|
-@erase "$(INTDIR)\tuplelist.obj"
|
||||||
-@erase "$(INTDIR)\odbcapi.obj"
|
-@erase "$(INTDIR)\odbcapi.obj"
|
||||||
-@erase "$(INTDIR)\odbcapi30.obj"
|
|
||||||
-@erase "$(INTDIR)\vc60.idb"
|
-@erase "$(INTDIR)\vc60.idb"
|
||||||
-@erase "$(INTDIR)\vc60.pdb"
|
-@erase "$(INTDIR)\vc60.pdb"
|
||||||
-@erase "$(OUTDIR)\psqlodbc.dll"
|
-@erase "$(OUTDIR)\psqlodbc.dll"
|
||||||
@ -307,7 +304,6 @@ LINK32_OBJS= \
|
|||||||
"$(INTDIR)\tuple.obj" \
|
"$(INTDIR)\tuple.obj" \
|
||||||
"$(INTDIR)\tuplelist.obj" \
|
"$(INTDIR)\tuplelist.obj" \
|
||||||
"$(INTDIR)\odbcapi.obj" \
|
"$(INTDIR)\odbcapi.obj" \
|
||||||
"$(INTDIR)\odbcapi30.obj" \
|
|
||||||
"$(INTDIR)\psqlodbc.res"
|
"$(INTDIR)\psqlodbc.res"
|
||||||
|
|
||||||
"$(OUTDIR)\psqlodbc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
"$(OUTDIR)\psqlodbc.dll" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
|
||||||
@ -496,11 +492,6 @@ SOURCE=odbcapi.c
|
|||||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
$(CPP) $(CPP_PROJ) $(SOURCE)
|
||||||
|
|
||||||
|
|
||||||
SOURCE=odbcapi30.c
|
|
||||||
|
|
||||||
"$(INTDIR)\odbcapi30.obj" : $(SOURCE) "$(INTDIR)"
|
|
||||||
$(CPP) $(CPP_PROJ) $(SOURCE)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
!ENDIF
|
!ENDIF
|
||||||
|
Loading…
x
Reference in New Issue
Block a user