{
StatementClass *stmt = (StatementClass *) hstmt;
static char *func = "PGAPI_BindParameter";
- APDFields *opts;
+ APDFields *apdopts;
+ IPDFields *ipdopts;
mylog("%s: entering...\n", func);
}
SC_clear_error(stmt);
- opts = SC_get_APD(stmt);
- if (opts->allocated < ipar)
- extend_parameter_bindings(opts, ipar);
+ apdopts = SC_get_APD(stmt);
+ if (apdopts->allocated < ipar)
+ extend_parameter_bindings(apdopts, ipar);
+ ipdopts = SC_get_IPD(stmt);
+ if (ipdopts->allocated < ipar)
+ extend_iparameter_bindings(ipdopts, ipar);
/* use zero based column numbers for the below part */
ipar--;
/* store the given info */
- opts->parameters[ipar].buflen = cbValueMax;
- opts->parameters[ipar].buffer = rgbValue;
- opts->parameters[ipar].used = pcbValue;
- opts->parameters[ipar].paramType = fParamType;
- opts->parameters[ipar].CType = fCType;
- opts->parameters[ipar].SQLType = fSqlType;
- opts->parameters[ipar].column_size = cbColDef;
- opts->parameters[ipar].decimal_digits = ibScale;
- opts->parameters[ipar].precision = 0;
- opts->parameters[ipar].scale = 0;
+ apdopts->parameters[ipar].buflen = cbValueMax;
+ apdopts->parameters[ipar].buffer = rgbValue;
+ apdopts->parameters[ipar].used = pcbValue;
+ apdopts->parameters[ipar].paramType = fParamType;
+ apdopts->parameters[ipar].CType = fCType;
+ ipdopts->parameters[ipar].SQLType = fSqlType;
+ ipdopts->parameters[ipar].paramType = fParamType;
+ ipdopts->parameters[ipar].column_size = cbColDef;
+ ipdopts->parameters[ipar].decimal_digits = ibScale;
+ ipdopts->parameters[ipar].precision = 0;
+ ipdopts->parameters[ipar].scale = 0;
+ ipdopts->parameters[ipar].PGType = sqltype_to_pgtype(stmt, fSqlType);
#if (ODBCVER >= 0x0300)
switch (fCType)
{
case SQL_C_NUMERIC:
if (cbColDef > 0)
- opts->parameters[ipar].precision = (UInt2) cbColDef;
+ ipdopts->parameters[ipar].precision = (UInt2) cbColDef;
if (ibScale > 0)
- opts->parameters[ipar].scale = ibScale;
+ ipdopts->parameters[ipar].scale = ibScale;
break;
case SQL_C_TYPE_TIMESTAMP:
if (ibScale > 0)
- opts->parameters[ipar].precision = ibScale;
+ ipdopts->parameters[ipar].precision = ibScale;
break;
}
+ apdopts->parameters[ipar].precision = ipdopts->parameters[ipar].precision;
+ apdopts->parameters[ipar].scale = ipdopts->parameters[ipar].scale;
#endif /* ODBCVER */
/*
* If rebinding a parameter that had data-at-exec stuff in it, then
* free that stuff
*/
- if (opts->parameters[ipar].EXEC_used)
+ if (apdopts->parameters[ipar].EXEC_used)
{
- free(opts->parameters[ipar].EXEC_used);
- opts->parameters[ipar].EXEC_used = NULL;
+ free(apdopts->parameters[ipar].EXEC_used);
+ apdopts->parameters[ipar].EXEC_used = NULL;
}
- if (opts->parameters[ipar].EXEC_buffer)
+ if (apdopts->parameters[ipar].EXEC_buffer)
{
- if (opts->parameters[ipar].SQLType != SQL_LONGVARBINARY)
- free(opts->parameters[ipar].EXEC_buffer);
- opts->parameters[ipar].EXEC_buffer = NULL;
+ free(apdopts->parameters[ipar].EXEC_buffer);
+ apdopts->parameters[ipar].EXEC_buffer = NULL;
}
- if (pcbValue && opts->param_offset_ptr)
- pcbValue += (*opts->param_offset_ptr >> 2);
+ if (pcbValue && apdopts->param_offset_ptr)
+ pcbValue += (*apdopts->param_offset_ptr >> 2);
/* Data at exec macro only valid for C char/binary data */
if (pcbValue && (*pcbValue == SQL_DATA_AT_EXEC ||
*pcbValue <= SQL_LEN_DATA_AT_EXEC_OFFSET))
- opts->parameters[ipar].data_at_exec = TRUE;
+ apdopts->parameters[ipar].data_at_exec = TRUE;
else
- opts->parameters[ipar].data_at_exec = FALSE;
+ apdopts->parameters[ipar].data_at_exec = FALSE;
/* Clear premature result */
if (stmt->status == STMT_PREMATURE)
SC_recycle_statement(stmt);
- mylog("PGAPI_BindParamater: ipar=%d, paramType=%d, fCType=%d, fSqlType=%d, cbColDef=%d, ibScale=%d, rgbValue=%d, *pcbValue = %d, data_at_exec = %d\n", ipar, fParamType, fCType, fSqlType, cbColDef, ibScale, rgbValue, pcbValue ? *pcbValue : -777, opts->parameters[ipar].data_at_exec);
+ mylog("PGAPI_BindParamater: ipar=%d, paramType=%d, fCType=%d, fSqlType=%d, cbColDef=%d, ibScale=%d, rgbValue=%d, *pcbValue = %d, data_at_exec = %d\n", ipar, fParamType, fCType, fSqlType, cbColDef, ibScale, rgbValue, pcbValue ? *pcbValue : -777, apdopts->parameters[ipar].data_at_exec);
return SQL_SUCCESS;
}
free(opts->bindings[icol].ttlbuf);
opts->bindings[icol].ttlbuf = NULL;
opts->bindings[icol].ttlbuflen = 0;
+ opts->bindings[icol].ttlbufused = 0;
opts->bindings[icol].precision = 0;
opts->bindings[icol].scale = 0;
}
{
StatementClass *stmt = (StatementClass *) hstmt;
static char *func = "PGAPI_DescribeParam";
- APDFields *opts;
+ APDFields *apdopts;
+ IPDFields *ipdopts;
mylog("%s: entering...\n", func);
}
SC_clear_error(stmt);
- opts = SC_get_APD(stmt);
- if ((ipar < 1) || (ipar > opts->allocated))
+ apdopts = SC_get_APD(stmt);
+ if ((ipar < 1) || (ipar > apdopts->allocated))
{
SC_set_error(stmt, STMT_BAD_PARAMETER_NUMBER_ERROR, "Invalid parameter number for PGAPI_DescribeParam.");
SC_log_error(func, "", stmt);
return SQL_ERROR;
}
+ ipdopts = SC_get_IPD(stmt);
ipar--;
*/
/* parameter markers, not bound parameters. */
if (pfSqlType)
- *pfSqlType = opts->parameters[ipar].SQLType;
+ *pfSqlType = ipdopts->parameters[ipar].SQLType;
if (pcbColDef)
- *pcbColDef = opts->parameters[ipar].column_size;
+ *pcbColDef = ipdopts->parameters[ipar].column_size;
if (pibScale)
- *pibScale = opts->parameters[ipar].decimal_digits;
+ *pibScale = ipdopts->parameters[ipar].decimal_digits;
if (pfNullable)
- *pfNullable = pgtype_nullable(stmt, opts->parameters[ipar].paramType);
+ *pfNullable = pgtype_nullable(stmt, apdopts->parameters[ipar].paramType);
return SQL_SUCCESS;
}
{
static char *func = "PGAPI_ParamOptions";
StatementClass *stmt = (StatementClass *) hstmt;
- APDFields *opts;
+ APDFields *apdopts;
mylog("%s: entering... %d %x\n", func, crow, pirow);
- opts = SC_get_APD(stmt);
- opts->paramset_size = crow;
+ apdopts = SC_get_APD(stmt);
+ apdopts->paramset_size = crow;
SC_get_IPD(stmt)->param_processed_ptr = (UInt4 *) pirow;
return SQL_SUCCESS;
}
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE;
}
- SC_clear_error(stmt);
if (pcpar)
*pcpar = 0;
new_bindings[i].data_left = -1;
new_bindings[i].ttlbuf = NULL;
new_bindings[i].ttlbuflen = 0;
+ new_bindings[i].ttlbufused = 0;
}
return new_bindings;
mylog("exit extend_parameter_bindings\n");
}
+void
+extend_iparameter_bindings(IPDFields *self, int num_params)
+{
+ static char *func = "extend_iparameter_bindings";
+ ParameterImplClass *new_bindings;
+
+ mylog("%s: entering ... self=%u, parameters_allocated=%d, num_params=%d\n", func, self, self->allocated, num_params);
+
+ /*
+ * if we have too few, allocate room for more, and copy the old
+ * entries into the new structure
+ */
+ if (self->allocated < num_params)
+ {
+ new_bindings = (ParameterImplClass *) realloc(self->parameters, sizeof(ParameterImplClass) * num_params);
+ if (!new_bindings)
+ {
+ mylog("%s: unable to create %d new bindings from %d old bindings\n", func, num_params, self->allocated);
+
+ self->parameters = NULL;
+ self->allocated = 0;
+ return;
+ }
+ memset(&new_bindings[self->allocated], 0,
+ sizeof(ParameterImplClass) * (num_params - self->allocated));
+
+ self->parameters = new_bindings;
+ self->allocated = num_params;
+ }
+
+ mylog("exit extend_iparameter_bindings\n");
+}
+
void
reset_a_parameter_binding(APDFields *self, int ipar)
{
self->parameters[ipar].used = 0;
self->parameters[ipar].paramType = 0;
self->parameters[ipar].CType = 0;
+ self->parameters[ipar].data_at_exec = FALSE;
if (self->parameters[ipar].EXEC_used)
{
free(self->parameters[ipar].EXEC_used);
if (self->parameters[ipar].EXEC_buffer)
{
- if (self->parameters[ipar].SQLType != SQL_LONGVARBINARY)
- free(self->parameters[ipar].EXEC_buffer);
+ free(self->parameters[ipar].EXEC_buffer);
self->parameters[ipar].EXEC_buffer = NULL;
}
+ self->parameters[ipar].lobj_oid = 0;
+ self->parameters[ipar].precision = 0;
+ self->parameters[ipar].scale = 0;
+}
+
+void
+reset_a_iparameter_binding(IPDFields *self, int ipar)
+{
+ static char *func = "reset_a_iparameter_binding";
+
+ mylog("%s: entering ... self=%u, parameters_allocated=%d, ipar=%d\n", func, self, self->allocated, ipar);
+
+ if (ipar < 1 || ipar > self->allocated)
+ return;
+
+ ipar--;
+ self->parameters[ipar].paramType = 0;
self->parameters[ipar].SQLType = 0;
self->parameters[ipar].column_size = 0;
self->parameters[ipar].decimal_digits = 0;
self->parameters[ipar].precision = 0;
self->parameters[ipar].scale = 0;
- self->parameters[ipar].data_at_exec = FALSE;
- self->parameters[ipar].lobj_oid = 0;
}
/*
* Free parameters and free the memory.
*/
void
-APD_free_params(APDFields *self, char option)
+APD_free_params(APDFields *apdopts, char option)
{
int i;
- mylog("APD_free_params: ENTER, self=%d\n", self);
+ mylog("APD_free_params: ENTER, self=%d\n", apdopts);
- if (!self->parameters)
+ if (!apdopts->parameters)
return;
- for (i = 0; i < self->allocated; i++)
+ for (i = 0; i < apdopts->allocated; i++)
{
- if (self->parameters[i].data_at_exec)
+ if (apdopts->parameters[i].data_at_exec)
{
- if (self->parameters[i].EXEC_used)
+ if (apdopts->parameters[i].EXEC_used)
{
- free(self->parameters[i].EXEC_used);
- self->parameters[i].EXEC_used = NULL;
+ free(apdopts->parameters[i].EXEC_used);
+ apdopts->parameters[i].EXEC_used = NULL;
}
-
- if (self->parameters[i].EXEC_buffer)
+ if (apdopts->parameters[i].EXEC_buffer)
{
- if (self->parameters[i].SQLType != SQL_LONGVARBINARY)
- free(self->parameters[i].EXEC_buffer);
- self->parameters[i].EXEC_buffer = NULL;
+ free(apdopts->parameters[i].EXEC_buffer);
+ apdopts->parameters[i].EXEC_buffer = NULL;
}
}
}
if (option == STMT_FREE_PARAMS_ALL)
{
- if (self->parameters)
- free(self->parameters);
- self->parameters = NULL;
- self->allocated = 0;
+ if (apdopts->parameters)
+ free(apdopts->parameters);
+ apdopts->parameters = NULL;
+ apdopts->allocated = 0;
}
mylog("APD_free_params: EXIT\n");
}
+/*
+ * Free parameters and free the memory.
+ */
+void
+IPD_free_params(IPDFields *ipdopts, char option)
+{
+ mylog("IPD_free_params: ENTER, self=%d\n", ipdopts);
+
+ if (ipdopts->parameters &&
+ option == STMT_FREE_PARAMS_ALL)
+ {
+ if (ipdopts->parameters)
+ free(ipdopts->parameters);
+ ipdopts->parameters = NULL;
+ ipdopts->allocated = 0;
+ }
+
+ mylog("IPD_free_params: EXIT\n");
+}
+
void
extend_column_bindings(ARDFields *self, int num_columns)
{
free(self->bindings[icol].ttlbuf);
self->bindings[icol].ttlbuf = NULL;
self->bindings[icol].ttlbuflen = 0;
+ self->bindings[icol].ttlbufused = 0;
}
}
* not counting the '\0') */
char *ttlbuf; /* to save the large result */
Int4 ttlbuflen; /* the buffer length */
+ Int4 ttlbufused; /* used length of the buffer */
Int2 returntype; /* kind of conversion to be applied when
* returning (SQL_C_DEFAULT,
* SQL_C_CHAR...) */
Int4 *used;
Int2 paramType;
Int2 CType;
- Int2 SQLType;
- Int2 decimal_digits;
- UInt4 column_size;
Oid lobj_oid;
- Int4 *EXEC_used; /* amount of data OR the oid of the large
- * object */
- char *EXEC_buffer; /* the data or the FD of the large object */
+ Int4 *EXEC_used; /* amount of data */
+ char *EXEC_buffer; /* the data */
Int2 precision; /* the precision for numeric or timestamp type */
Int2 scale; /* the scale for numeric type */
char data_at_exec;
};
+/*
+ * ParameterImplClass -- stores implemntation information about a parameter
+ */
+struct ParameterImplClass_
+{
+ Int2 paramType;
+ Int2 SQLType;
+ Int4 PGType;
+ UInt4 column_size;
+ Int2 decimal_digits;
+ Int2 precision; /* the precision for numeric or timestamp type */
+ Int2 scale; /* the scale for numeric type */
+};
+
BindInfoClass *create_empty_bindings(int num_columns);
void extend_column_bindings(ARDFields *opts, int num_columns);
void reset_a_column_binding(ARDFields *opts, int icol);
void extend_parameter_bindings(APDFields *opts, int num_columns);
+void extend_iparameter_bindings(IPDFields *opts, int num_columns);
void reset_a_parameter_binding(APDFields *opts, int ipar);
+void reset_a_iparameter_binding(IPDFields *opts, int ipar);
#endif
conninfo->lf_conversion = -1;
conninfo->true_is_minus1 = -1;
conninfo->int8_as = -101;
+ conninfo->bytea_as_longvarbinary = -1;
+ conninfo->use_server_side_prepare = -1;
memcpy(&(conninfo->drivers), &globals, sizeof(globals));
}
/*
rv->num_stmts = STMT_INCREMENT;
- rv->lobj_type = PG_TYPE_LO;
+ rv->lobj_type = PG_TYPE_LO_UNDEFINED;
rv->ntables = 0;
rv->col_info = NULL;
#define CC_set_errornumber(x, n) (x->__error_number = n)
/* For Multi-thread */
-#if defined(WIN_MULTITHREAD_SUPPORT)
+#if defined(WIN_FREETHREAD_SUPPORT)
#define INIT_CONN_CS(x) InitializeCriticalSection(&((x)->cs))
#define ENTER_CONN_CS(x) EnterCriticalSection(&((x)->cs))
#define LEAVE_CONN_CS(x) LeaveCriticalSection(&((x)->cs))
char lf_conversion;
char true_is_minus1;
char int8_as;
+ char bytea_as_longvarbinary;
+ char use_server_side_prepare;
GLOBAL_VALUES drivers; /* moved from driver's option */
} ConnInfo;
static unsigned int conv_from_octal(const unsigned char *s);
static unsigned int conv_from_hex(const unsigned char *s);
static char *conv_to_octal(unsigned char val, char *octal);
+static int pg_bin2hex(UCHAR *src, UCHAR *dst, int length);
+static int pg_hex2bin(UCHAR *src, UCHAR *dst, int length);
/*---------
* A Guide for date/time/timestamp conversions
* This is a large object OID, which is used to store
* LONGVARBINARY objects.
*/
- case PG_TYPE_LO:
+ case PG_TYPE_LO_UNDEFINED:
return convert_lo(stmt, value, fCType, ((char *) rgbValue + rgbValueOffset), cbValueMax, (SDWORD *) ((char *) pcbValue + pcbValueOffset));
*/
case PG_TYPE_BYTEA:/* convert binary data to hex strings
* (i.e, 255 = "FF") */
- len = convert_pgbinary_to_char(neut_str, rgbValueBindRow, cbValueMax);
-
- /***** THIS IS NOT PROPERLY IMPLEMENTED *****/
- break;
default:
if (stmt->current_col < 0)
}
else
#endif /* UNICODE_SUPPORT */
- /* convert linefeeds to carriage-return/linefeed */
- len = convert_linefeeds(neut_str, NULL, 0, lf_conv, &changed);
+ if (PG_TYPE_BYTEA == field_type)
+ {
+ len = convert_from_pgbinary(neut_str, NULL, 0);
+ len *= 2;
+ changed = TRUE;
+ }
+ else
+ /* convert linefeeds to carriage-return/linefeed */
+ len = convert_linefeeds(neut_str, NULL, 0, lf_conv, &changed);
if (cbValueMax == 0) /* just returns length
* info */
{
}
else
#endif /* UNICODE_SUPPORT */
- convert_linefeeds(neut_str, pbic->ttlbuf, pbic->ttlbuflen, lf_conv, &changed);
+ if (PG_TYPE_BYTEA == field_type)
+ {
+ len = convert_from_pgbinary(neut_str, pbic->ttlbuf, pbic->ttlbuflen);
+ pg_bin2hex(pbic->ttlbuf, pbic->ttlbuf, len);
+ len *= 2;
+ }
+ else
+ convert_linefeeds(neut_str, pbic->ttlbuf, pbic->ttlbuflen, lf_conv, &changed);
ptr = pbic->ttlbuf;
+ pbic->ttlbufused = len;
}
else
{
}
}
else
+ {
ptr = pbic->ttlbuf;
+ len = pbic->ttlbufused;
+ }
mylog("DEFAULT: len = %d, ptr = '%s'\n", len, ptr);
{
if (pbic->data_left > 0)
{
- ptr += strlen(ptr) - pbic->data_left;
+ ptr += len - pbic->data_left;
len = pbic->data_left;
}
else
#endif /* ODBCINT64 */
case SQL_C_BINARY:
+ if (PG_TYPE_BYTEA != field_type)
+ {
+ mylog("couldn't convert the type %d to SQL_C_BINARY\n", field_type);
+ return COPY_UNSUPPORTED_TYPE;
+ }
/* truncate if necessary */
/* convert octal escapes to bytes */
pbic = &opts->bindings[stmt->current_col];
if (!pbic->ttlbuf)
pbic->ttlbuflen = 0;
- if (len = strlen(neut_str), len >= (int) pbic->ttlbuflen)
+ if (pbic->data_left < 0)
{
- pbic->ttlbuf = realloc(pbic->ttlbuf, len + 1);
- pbic->ttlbuflen = len + 1;
+ if (cbValueMax <= 0)
+ {
+ len = convert_from_pgbinary(neut_str, NULL, 0);
+ result = COPY_RESULT_TRUNCATED;
+ break;
+ }
+ 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);
+ pbic->ttlbufused = len;
}
- len = convert_from_pgbinary(neut_str, pbic->ttlbuf, pbic->ttlbuflen);
+ else
+ len = pbic->ttlbufused;
ptr = pbic->ttlbuf;
if (stmt->current_col >= 0)
*/
if (len > cbValueMax)
result = COPY_RESULT_TRUNCATED;
-
- if (pbic->ttlbuf)
+ else if (pbic->ttlbuf)
{
free(pbic->ttlbuf);
pbic->ttlbuf = NULL;
#define FLGP_CURSOR_CHECK_OK (1L << 1)
#define FLGP_SELECT_INTO (1L << 2)
#define FLGP_SELECT_FOR_UPDATE (1L << 3)
+#define FLGP_BUILDING_PREPARE_STATEMENT (1L << 4)
typedef struct _QueryParse {
const char *statement;
int statement_type;
static int
QP_initialize(QueryParse *q, const StatementClass *stmt)
{
- q->statement = stmt->statement;
+ q->statement = stmt->execute_statement ? stmt->execute_statement : stmt->statement;
q->statement_type = stmt->statement_type;
q->opos = 0;
q->from_pos = -1;
#define FLGB_INACCURATE_RESULT (1L << 1)
#define FLGB_CREATE_KEYSET (1L << 2)
#define FLGB_KEYSET_DRIVEN (1L << 3)
+#define FLGB_BUILDING_PREPARE_STATEMENT (1L << 4)
typedef struct _QueryBuild {
char *query_statement;
UInt4 str_size_limit;
int current_row;
int param_number;
APDFields *apdopts;
+ IPDFields *ipdopts;
UInt4 load_stmt_len;
UInt4 flags;
BOOL lf_conv;
qb->load_stmt_len = 0;
qb->stmt = stmt;
qb->apdopts = NULL;
+ qb->ipdopts = NULL;
if (conn)
qb->conn = conn;
else if (stmt)
{
qb->apdopts = SC_get_APD(stmt);
+ qb->ipdopts = SC_get_IPD(stmt);
qb->conn = SC_get_conn(stmt);
if (stmt->pre_executing)
qb->flags |= FLGB_PRE_EXECUTING;
|| ';' == wstmt[0];
}
+static int
+Prepare_and_convert(StatementClass *stmt, QueryParse *qp, QueryBuild *qb)
+{
+ const static char *func = "Prepare_and_convert";
+ char *new_statement, *exe_statement = NULL;
+ int retval;
+
+ if (QB_initialize(qb, qp->stmt_len, stmt, NULL) < 0)
+ return SQL_ERROR;
+ if (!stmt->prepared) /* not yet prepared */
+ {
+ int i, elen;
+ SWORD marker_count;
+ const IPDFields *ipdopts = qb->ipdopts;
+
+ new_statement = qb->query_statement;
+ qb->flags = FLGB_BUILDING_PREPARE_STATEMENT;
+ sprintf(new_statement, "PREPARE _PLAN%0x", stmt);
+ qb->npos = strlen(new_statement);
+ if (SQL_SUCCESS != PGAPI_NumParams(stmt, &marker_count))
+ {
+ QB_Destructor(qb);
+ return SQL_ERROR;
+ }
+ if (marker_count > 0)
+ {
+ CVT_APPEND_CHAR(qb, '(');
+ for (i = 0; i < marker_count; i++)
+ {
+ if (i > 0)
+ CVT_APPEND_STR(qb, ", ");
+ CVT_APPEND_STR(qb, pgtype_to_name(stmt, ipdopts->parameters[i].PGType));
+ }
+ CVT_APPEND_CHAR(qb, ')');
+ }
+ CVT_APPEND_STR(qb, " as ");
+ for (qp->opos = 0; qp->opos < qp->stmt_len; qp->opos++)
+ {
+ retval = inner_process_tokens(qp, qb);
+ if (SQL_ERROR == retval)
+ {
+ if (0 == SC_get_errornumber(stmt))
+ {
+ SC_set_error(stmt, qb->errornumber, qb->errormsg);
+ }
+ SC_log_error(func, "", stmt);
+ QB_Destructor(qb);
+ return retval;
+ }
+ }
+ CVT_APPEND_CHAR(qb, ';');
+ /* build the execute statement */
+ exe_statement = malloc(30 + 2 * marker_count);
+ sprintf(exe_statement, "EXECUTE _PLAN%0x", stmt);
+ if (marker_count > 0)
+ {
+ elen = strlen(exe_statement);
+ exe_statement[elen++] = '(';
+ for (i = 0; i < marker_count; i++)
+ {
+ if (i > 0)
+ exe_statement[elen++] = ',';
+ exe_statement[elen++] = '?';
+ }
+ exe_statement[elen++] = ')';
+ exe_statement[elen] = '\0';
+ }
+ stmt->execute_statement = exe_statement;
+ QP_initialize(qp, stmt);
+ }
+ qb->flags = 0;
+ qb->param_number = -1;
+ for (qp->opos = 0; qp->opos < qp->stmt_len; qp->opos++)
+ {
+ retval = inner_process_tokens(qp, qb);
+ if (SQL_ERROR == retval)
+ {
+ if (0 == SC_get_errornumber(stmt))
+ {
+ SC_set_error(stmt, qb->errornumber, qb->errormsg);
+ }
+ SC_log_error(func, "", stmt);
+ if (exe_statement)
+ {
+ free(exe_statement);
+ stmt->execute_statement = NULL;
+ }
+ QB_Destructor(qb);
+ return retval;
+ }
+ }
+ /* make sure new_statement is always null-terminated */
+ CVT_TERMINATE(qb);
+
+ if (exe_statement)
+ SC_set_prepare_before_exec(stmt);
+ stmt->stmt_with_params = qb->query_statement;
+ return SQL_SUCCESS;
+}
+
#define my_strchr(conn, s1,c1) pg_mbschr(conn->ccsc, s1,c1)
/*
* This function does a dynamic memory allocation to get rid of query size limit!
*/
int
-copy_statement_with_parameters(StatementClass *stmt)
+copy_statement_with_parameters(StatementClass *stmt, BOOL buildPrepareStatement)
{
static char *func = "copy_statement_with_parameters";
RETCODE retval;
qp = &query_org;
QP_initialize(qp, stmt);
- if (ci->disallow_premature)
- prepare_dummy_cursor = stmt->pre_executing;
- if (prepare_dummy_cursor)
- qp->flags |= FLGP_PREPARE_DUMMY_CURSOR;
-
-
#ifdef DRIVER_CURSOR_IMPLEMENT
if (stmt->statement_type != STMT_TYPE_SELECT)
{
stmt->options.cursor_type = SQL_CURSOR_STATIC;
#endif /* DRIVER_CURSOR_IMPLEMENT */
+ stmt->miscinfo = 0;
/* If the application hasn't set a cursor name, then generate one */
if (stmt->cursor_name[0] == '\0')
sprintf(stmt->cursor_name, "SQL_CUR%p", stmt);
free(stmt->stmt_with_params);
stmt->stmt_with_params = NULL;
}
+
qb = &query_crt;
+ if (stmt->prepared || (buildPrepareStatement && stmt->options.scroll_concurrency == SQL_CONCUR_READ_ONLY))
+ {
+ return Prepare_and_convert(stmt, qp, qb);
+ }
+
+ if (ci->disallow_premature)
+ prepare_dummy_cursor = stmt->pre_executing;
+ if (prepare_dummy_cursor)
+ qp->flags |= FLGP_PREPARE_DUMMY_CURSOR;
if (QB_initialize(qb, qp->stmt_len, stmt, NULL) < 0)
return SQL_ERROR;
new_statement = qb->query_statement;
- stmt->miscinfo = 0;
/* For selects, prepend a declare cursor to the statement */
if (stmt->statement_type == STMT_TYPE_SELECT)
{
ConnectionClass *conn = qb->conn;
ConnInfo *ci = &(conn->connInfo);
- APDFields *opts = qb->apdopts;
+ const APDFields *apdopts = qb->apdopts;
+ const IPDFields *ipdopts = qb->ipdopts;
int param_number;
char param_string[128], tmp[256],
cbuf[PG_NUMERIC_MAX_PRECISION * 2]; /* seems big enough to handle the data in this function */
+ Int4 param_pgtype;
Int2 param_ctype, param_sqltype;
SIMPLE_TIME st;
time_t t;
char *buffer, *buf, *allocbuf;
Oid lobj_oid;
int lobj_fd, retval;
- UInt4 offset = opts->param_offset_ptr ? *opts->param_offset_ptr : 0;
+ UInt4 offset = apdopts->param_offset_ptr ? *apdopts->param_offset_ptr : 0;
UInt4 current_row = qb->current_row;
+ BOOL handling_large_object = FALSE;
/*
* Its a '?' parameter alright
*/
param_number = ++qb->param_number;
- if (param_number >= opts->allocated)
+ if (param_number >= apdopts->allocated)
{
if (0 != (qb->flags & FLGB_PRE_EXECUTING))
{
}
else
{
- CVT_APPEND_CHAR(qb, '?');
- return SQL_SUCCESS;
+ qb->errormsg = "The # of binded parameters < the # of parameter markers";
+ qb->errornumber = STMT_COUNT_FIELD_INCORRECT;
+ CVT_TERMINATE(qb); /* just in case */
+ return SQL_ERROR;
}
}
+ if (SQL_PARAM_OUTPUT == apdopts->parameters[param_number].paramType)
+ {
+ qb->errormsg = "Output parameter isn't available";
+ qb->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
+ CVT_TERMINATE(qb); /* just in case */
+ return SQL_ERROR;
+ }
+ if (0 != (qb->flags & FLGB_BUILDING_PREPARE_STATEMENT))
+ {
+ char pnum[16];
+
+ sprintf(pnum, "$%d", param_number + 1);
+ CVT_APPEND_STR(qb, pnum);
+ return SQL_SUCCESS;
+ }
/* Assign correct buffers based on data at exec param or not */
- if (opts->parameters[param_number].data_at_exec)
+ if (apdopts->parameters[param_number].data_at_exec)
{
- used = opts->parameters[param_number].EXEC_used ? *opts->parameters[param_number].EXEC_used : SQL_NTS;
- buffer = opts->parameters[param_number].EXEC_buffer;
+ used = apdopts->parameters[param_number].EXEC_used ? *apdopts->parameters[param_number].EXEC_used : SQL_NTS;
+ buffer = apdopts->parameters[param_number].EXEC_buffer;
+ if (apdopts->parameters[param_number].lobj_oid)
+ handling_large_object = TRUE;
}
else
{
- UInt4 bind_size = opts->param_bind_type;
+ UInt4 bind_size = apdopts->param_bind_type;
UInt4 ctypelen;
- buffer = opts->parameters[param_number].buffer + offset;
+ buffer = apdopts->parameters[param_number].buffer + offset;
if (current_row > 0)
{
if (bind_size > 0)
buffer += (bind_size * current_row);
- else if (ctypelen = ctype_length(opts->parameters[param_number].CType), ctypelen > 0)
+ else if (ctypelen = ctype_length(apdopts->parameters[param_number].CType), ctypelen > 0)
buffer += current_row * ctypelen;
else
- buffer += current_row * opts->parameters[param_number].buflen;
+ buffer += current_row * apdopts->parameters[param_number].buflen;
}
- if (opts->parameters[param_number].used)
+ if (apdopts->parameters[param_number].used)
{
UInt4 p_offset = offset;
if (bind_size > 0)
p_offset = offset + bind_size * current_row;
else
p_offset = offset + sizeof(SDWORD) * current_row;
- used = *(SDWORD *)((char *)opts->parameters[param_number].used + p_offset);
+ used = *(SDWORD *)((char *)apdopts->parameters[param_number].used + p_offset);
}
else
used = SQL_NTS;
qb->flags |= FLGB_INACCURATE_RESULT;
return SQL_SUCCESS;
}
- else
+ else if (!handling_large_object)
{
CVT_APPEND_CHAR(qb, '?');
return SQL_SUCCESS;
}
}
- param_ctype = opts->parameters[param_number].CType;
- param_sqltype = opts->parameters[param_number].SQLType;
+ param_ctype = apdopts->parameters[param_number].CType;
+ param_sqltype = ipdopts->parameters[param_number].SQLType;
+ param_pgtype = ipdopts->parameters[param_number].PGType;
mylog("%s: from(fcType)=%d, to(fSqlType)=%d\n", func,
param_ctype, param_sqltype);
break;
case SQL_BINARY:
- case SQL_VARBINARY:/* non-ascii characters should be
- * converted to octal */
- CVT_APPEND_CHAR(qb, '\''); /* Open Quote */
-
- mylog("SQL_VARBINARY: about to call convert_to_pgbinary, used = %d\n", used);
+ case SQL_VARBINARY:
+ case SQL_LONGVARBINARY:
+ switch (param_ctype)
+ {
+ case SQL_C_BINARY:
+ break;
+ case SQL_C_CHAR:
+ switch (used)
+ {
+ case SQL_NTS:
+ used = strlen(buf);
+ break;
+ }
+ allocbuf = malloc(used / 2 + 1);
+ if (allocbuf)
+ {
+ pg_hex2bin(buf, allocbuf, used);
+ buf = allocbuf;
+ used /= 2;
+ }
+ break;
+ default:
+ qb->errormsg = "Could not convert the ctype to binary type";
+ qb->errornumber = STMT_EXEC_ERROR;
+ return SQL_ERROR;
+ }
+ if (param_pgtype == PG_TYPE_BYTEA)
+ {
+ /* non-ascii characters should be
+ * converted to octal
+ */
+ CVT_APPEND_CHAR(qb, '\''); /* Open Quote */
- CVT_APPEND_BINARY(qb, buf, used);
+ mylog("SQL_VARBINARY: about to call convert_to_pgbinary, used = %d\n", used);
- CVT_APPEND_CHAR(qb, '\''); /* Close Quote */
+ CVT_APPEND_BINARY(qb, buf, used);
- break;
+ CVT_APPEND_CHAR(qb, '\''); /* Close Quote */
- case SQL_LONGVARBINARY:
+ break;
+ }
+ if (param_pgtype != conn->lobj_type)
+ {
+ qb->errormsg = "Could not convert binary other than LO type";
+ qb->errornumber = STMT_EXEC_ERROR;
+ return SQL_ERROR;
+ }
- if (opts->parameters[param_number].data_at_exec)
- lobj_oid = opts->parameters[param_number].lobj_oid;
+ if (apdopts->parameters[param_number].data_at_exec)
+ lobj_oid = apdopts->parameters[param_number].lobj_oid;
else
{
/* begin transaction if needed */
* parameter marker -- the data has already been sent to
* the large object
*/
- sprintf(param_string, "'%d'", lobj_oid);
+ sprintf(param_string, "'%d'::lo", lobj_oid);
CVT_APPEND_STR(qb, param_string);
break;
break;
}
-#ifdef UNICODE_SUPPORT
if (allocbuf)
free(allocbuf);
-#endif /* UNICODE_SUPPORT */
return SQL_SUCCESS;
}
{
if (value[i + 1] == '\\')
{
- rgbValue[o] = value[i];
+ if (rgbValue)
+ rgbValue[o] = value[i];
i += 2;
}
else
{
- rgbValue[o] = conv_from_octal(&value[i]);
+ if (rgbValue)
+ rgbValue[o] = conv_from_octal(&value[i]);
i += 4;
}
}
else
- rgbValue[o] = value[i++];
- mylog("convert_from_pgbinary: i=%d, rgbValue[%d] = %d, %c\n", i, o, rgbValue[o], rgbValue[o]);
+ {
+ if (rgbValue)
+ rgbValue[o] = value[i];
+ i++;
+ }
+ /** if (rgbValue)
+ mylog("convert_from_pgbinary: i=%d, rgbValue[%d] = %d, %c\n", i, o, rgbValue[o], rgbValue[o]); ***/
o++;
}
- rgbValue[o] = '\0'; /* extra protection */
+ if (rgbValue)
+ rgbValue[o] = '\0'; /* extra protection */
+
+ mylog("convert_from_pgbinary: in=%d, out = %d\n", ilen, o);
return o;
}
return length;
}
+static int
+pg_hex2bin(UCHAR *src, UCHAR *dst, int length)
+{
+ UCHAR chr,
+ *src_wk,
+ *dst_wk;
+ int i, val;
+ BOOL HByte = TRUE;
+
+ for (i = 0, src_wk = src, dst_wk = dst; i < length; i++, src_wk++)
+ {
+ chr = *src_wk;
+ if (chr >= 'a' && chr <= 'f')
+ val = chr - 'a' + 10;
+ else if (chr >= 'A' && chr <= 'F')
+ val = chr - 'A' + 10;
+ else
+ val = chr - '0';
+ if (HByte)
+ *dst_wk = (val << 4);
+ else
+ {
+ *dst_wk += val;
+ dst_wk++;
+ }
+ HByte = !HByte;
+ }
+ *dst_wk = '\0';
+ return length;
+}
+
/*-------
* 1. get oid (from 'value')
* 2. open the large object
ConnectionClass *conn = SC_get_conn(stmt);
ConnInfo *ci = &(conn->connInfo);
ARDFields *opts = SC_get_ARD(stmt);
- int factor = (fCType == SQL_C_CHAR ? 2 : 1);
+ int factor;
+ switch (fCType)
+ {
+ case SQL_C_CHAR:
+ factor = 2;
+ break;
+ case SQL_C_BINARY:
+ factor = 1;
+ break;
+ default:
+ SC_set_error(stmt, STMT_EXEC_ERROR, "Could not convert lo to the c-type");
+ return COPY_GENERAL_ERROR;
+ }
/* If using SQLGetData, then current_col will be set */
if (stmt->current_col >= 0)
{
int copy_and_convert_field(StatementClass *stmt, Int4 field_type, void *value, Int2 fCType,
PTR rgbValue, SDWORD cbValueMax, SDWORD *pcbValue);
-int copy_statement_with_parameters(StatementClass *stmt);
+int copy_statement_with_parameters(StatementClass *stmt, BOOL);
BOOL convert_money(const char *s, char *sout, size_t soutmax);
char parse_datetime(const char *buf, SIMPLE_TIME *st);
int convert_linefeeds(const char *s, char *dst, size_t max, BOOL convlf, BOOL *changed);
*
* Comments: See "notice.txt" for copyright and license information.
*
- * $Id: descriptor.h,v 1.8 2002/09/23 08:08:21 hinoue Exp $
+ * $Id: descriptor.h,v 1.9 2002/12/16 15:01:33 hinoue Exp $
*
*/
StatementClass *stmt;
UInt4 *param_processed_ptr;
UInt2 *param_status_ptr;
+ ParameterImplClass *parameters;
+ int allocated;
};
void InitializeARDFields(ARDFields *self);
void IPDFields_free(IPDFields *self);
void ARD_unbind_cols(ARDFields *self, BOOL freeall);
void APD_free_params(APDFields *self, char option);
+void IPD_free_params(IPDFields *self, char option);
#if (ODBCVER >= 0x0300)
void Desc_set_error(SQLHDESC hdesc, int errornumber, const char * errormsg);
#endif /* ODBCVER */
hlen = strlen(connect_string);
if (!abbrev)
sprintf(&connect_string[hlen],
- ";%s=%s;%s=%s;%s=%s;%s=%s;%s=%s;%s=%s;%s=%s;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%s;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d",
+ ";%s=%s;%s=%s;%s=%s;%s=%s;%s=%s;%s=%s;%s=%s;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%s;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d;%s=%d",
INI_READONLY,
ci->onlyread,
INI_PROTOCOL,
INI_TRUEISMINUS1,
ci->true_is_minus1,
INI_INT8AS,
- ci->int8_as);
+ ci->int8_as,
+ INI_BYTEAASLONGVARBINARY,
+ ci->bytea_as_longvarbinary,
+ INI_USESERVERSIDEPREPARE,
+ ci->use_server_side_prepare);
/* Abbrebiation is needed ? */
if (abbrev || strlen(connect_string) >= len)
{
flag |= BIT_FAKEOIDINDEX;
if (ci->true_is_minus1)
flag |= BIT_TRUEISMINUS1;
+ if (ci->bytea_as_longvarbinary)
+ flag |= BIT_BYTEAASLONGVARBINARY;
+ if (ci->use_server_side_prepare)
+ flag |= BIT_USESERVERSIDEPREPARE;
sprintf(&connect_string[hlen],
";A6=%s;A7=%d;A8=%d;B0=%d;B1=%d;%s=%d;C2=%s;CX=%02x%lx",
sprintf(ci->show_oid_column, "%d", (char)((flag & BIT_SHOWOIDCOLUMN) != 0));
sprintf(ci->fake_oid_index, "%d", (char)((flag & BIT_FAKEOIDINDEX) != 0));
ci->true_is_minus1 = (char)((flag & BIT_TRUEISMINUS1) != 0);
+ ci->bytea_as_longvarbinary = (char)((flag & BIT_BYTEAASLONGVARBINARY) != 0);
+ ci->use_server_side_prepare = (char)((flag & BIT_USESERVERSIDEPREPARE) != 0);
}
void
copyAttributes(ConnInfo *ci, const char *attribute, const char *value)
ci->true_is_minus1 = atoi(value);
else if (stricmp(attribute, INI_INT8AS) == 0)
ci->int8_as = atoi(value);
+ else if (stricmp(attribute, INI_BYTEAASLONGVARBINARY) == 0)
+ ci->bytea_as_longvarbinary = atoi(value);
+ else if (stricmp(attribute, INI_USESERVERSIDEPREPARE) == 0)
+ ci->use_server_side_prepare = atoi(value);
else if (stricmp(attribute, "CX") == 0)
unfoldCXAttribute(ci, value);
ci->true_is_minus1 = DEFAULT_TRUEISMINUS1;
if (ci->int8_as < -100)
ci->int8_as = DEFAULT_INT8AS;
+ if (ci->bytea_as_longvarbinary < 0)
+ ci->bytea_as_longvarbinary = DEFAULT_BYTEAASLONGVARBINARY;
+ if (ci->use_server_side_prepare < 0)
+ ci->use_server_side_prepare = DEFAULT_USESERVERSIDEPREPARE;
}
ci->int8_as = atoi(temp);
}
+ if (ci->bytea_as_longvarbinary < 0 || overwrite)
+ {
+ SQLGetPrivateProfileString(DSN, INI_BYTEAASLONGVARBINARY, "", temp, sizeof(temp), ODBC_INI);
+ if (temp[0])
+ ci->bytea_as_longvarbinary = atoi(temp);
+ }
+
+ if (ci->use_server_side_prepare < 0 || overwrite)
+ {
+ SQLGetPrivateProfileString(DSN, INI_USESERVERSIDEPREPARE, "", temp, sizeof(temp), ODBC_INI);
+ if (temp[0])
+ ci->use_server_side_prepare = atoi(temp);
+ }
+
/* Allow override of odbcinst.ini parameters here */
getCommonDefaults(DSN, ODBC_INI, ci);
INI_INT8AS,
temp,
ODBC_INI);
+ sprintf(temp, "%d", ci->bytea_as_longvarbinary);
+ SQLWritePrivateProfileString(DSN,
+ INI_INT8AS,
+ temp,
+ ODBC_INI);
}
#define INI_LFCONVERSION "LFConversion"
#define INI_TRUEISMINUS1 "TrueIsMinus1"
#define INI_INT8AS "BI"
+#define INI_BYTEAASLONGVARBINARY "ByteaAsLongVarBinary"
+#define INI_USESERVERSIDEPREPARE "UseServerSidePrepare"
/* Bit representaion for abbreviated connection strings */
#define BIT_LFCONVERSION (1L)
#define BIT_UPDATABLECURSORS (1L<<1)
#define BIT_SHOWOIDCOLUMN (1L<<21)
#define BIT_FAKEOIDINDEX (1L<<22)
#define BIT_TRUEISMINUS1 (1L<<23)
+#define BIT_BYTEAASLONGVARBINARY (1L<<24)
+#define BIT_USESERVERSIDEPREPARE (1L<<25)
-#define EFFECTIVE_BIT_COUNT 24
+#define EFFECTIVE_BIT_COUNT 26
/* Connection Defaults */
#define DEFAULT_LFCONVERSION 0
#endif /* WIN32 */
#define DEFAULT_INT8AS 0
+#define DEFAULT_BYTEAASLONGVARBINARY 0
+#define DEFAULT_USESERVERSIDEPREPARE 0
/* prototypes */
void getCommonDefaults(const char *section, const char *filename, ConnInfo *ci);
case STMT_OPTION_NOT_FOR_THE_DRIVER:
pg_sqlstate_set(env, szSqlState, "HYC00", "HYC00");
break;
+ case STMT_COUNT_FIELD_INCORRECT:
+ pg_sqlstate_set(env, szSqlState, "07002", "07002");
+ break;
case STMT_EXEC_ERROR:
default:
pg_sqlstate_set(env, szSqlState, "HY000", "S1000");
#define LEAVE_CONNS_CS LeaveCriticalSection(&conns_cs)
#define DELETE_CONNS_CS DeleteCriticalSection(&conns_cs)
#define INIT_ENV_CS(x) InitializeCriticalSection(&((x)->cs))
-#define ENTER_ENV_CS(x) EnterCriticalSection(&((x)->cs))
+#define ENTER_ENV_CS(x) EnterCriticalSection(&((x)->cs))
#define LEAVE_ENV_CS(x) LeaveCriticalSection(&((x)->cs))
#define DELETE_ENV_CS(x) DeleteCriticalSection(&((x)->cs))
#elif defined(POSIX_MULTITHREAD_SUPPORT)
return SQL_ERROR;
}
- if (self->statement)
- free(self->statement);
- if (self->stmt_with_params)
- free(self->stmt_with_params);
- self->stmt_with_params = NULL;
- if (self->load_statement)
- free(self->load_statement);
- self->load_statement = NULL;
+ SC_initialize_stmts(self, TRUE);
self->statement = make_string(szSqlStr, cbSqlStr, NULL);
if (!self->statement)
}
self->prepare = TRUE;
+ self->prepared = FALSE;
self->statement_type = statement_type(self->statement);
/* Check if connection is onlyread (only selects are allowed) */
return SQL_INVALID_HANDLE;
}
- if (stmt->statement)
- free(stmt->statement);
- if (stmt->stmt_with_params)
- free(stmt->stmt_with_params);
- stmt->stmt_with_params = NULL;
- if (stmt->load_statement)
- free(stmt->load_statement);
- stmt->load_statement = NULL;
+ SC_initialize_stmts(stmt, TRUE);
/*
* keep a copy of the un-parametrized statement, in case they try to
mylog("**** %s: hstmt=%u, statement='%s'\n", func, hstmt, stmt->statement);
stmt->prepare = FALSE;
+ stmt->prepared = FALSE;
/*
* If an SQLPrepare was performed prior to this, but was left in the
return result;
}
+/*
+ * The execution after all parameters were resolved.
+ */
+static
+RETCODE Exec_with_parameters_resolved(StatementClass *stmt, BOOL *exec_end)
+{
+ static const char *func = "Exec_with_parameters_resolved";
+ RETCODE retval;
+ int end_row, cursor_type, scroll_concurrency;
+ ConnectionClass *conn;
+ QResultClass *res;
+ APDFields *apdopts;
+ IPDFields *ipdopts;
+ BOOL prepare_before_exec = FALSE;
+
+ *exec_end = FALSE;
+ conn = SC_get_conn(stmt);
+ mylog("%s: copying statement params: trans_status=%d, len=%d, stmt='%s'\n", func, conn->transact_status, strlen(stmt->statement), stmt->statement);
+
+ /* save the cursor's info before the execution */
+ cursor_type = stmt->options.cursor_type;
+ scroll_concurrency = stmt->options.scroll_concurrency;
+ /* Prepare the statement if possible at backend side */
+ if (stmt->prepare &&
+ !stmt->prepared &&
+ !stmt->inaccurate_result &&
+ conn->connInfo.use_server_side_prepare &&
+ PG_VERSION_GE(conn, 7.3))
+ prepare_before_exec = TRUE;
+ /* Create the statement with parameters substituted. */
+ retval = copy_statement_with_parameters(stmt, prepare_before_exec);
+ stmt->current_exec_param = -1;
+ if (retval != SQL_SUCCESS)
+ {
+ stmt->exec_current_row = -1;
+ *exec_end = TRUE;
+ return retval; /* error msg is passed from the above */
+ }
+
+ mylog(" stmt_with_params = '%s'\n", stmt->stmt_with_params);
+
+ /*
+ * Dummy exection to get the column info.
+ */
+ if (stmt->inaccurate_result && conn->connInfo.disallow_premature)
+ {
+ BOOL in_trans = CC_is_in_trans(conn);
+ BOOL issued_begin = FALSE,
+ begin_included = FALSE;
+ QResultClass *curres;
+
+ stmt->exec_current_row = -1;
+ *exec_end = TRUE;
+ if (!SC_is_pre_executable(stmt))
+ return SQL_SUCCESS;
+ if (strnicmp(stmt->stmt_with_params, "BEGIN;", 6) == 0)
+ begin_included = TRUE;
+ else if (!in_trans)
+ {
+ if (issued_begin = CC_begin(conn), !issued_begin)
+ {
+ SC_set_error(stmt, STMT_EXEC_ERROR, "Handle prepare error");
+ return SQL_ERROR;
+ }
+ }
+ /* we are now in a transaction */
+ res = CC_send_query(conn, stmt->stmt_with_params, NULL, CLEAR_RESULT_ON_ABORT);
+ if (!res)
+ {
+ CC_abort(conn);
+ SC_set_error(stmt, STMT_EXEC_ERROR, "Handle prepare error");
+ return SQL_ERROR;
+ }
+ SC_set_Result(stmt, res);
+ for (curres = res; !curres->num_fields; curres = curres->next)
+ ;
+ SC_set_Curres(stmt, curres);
+ if (CC_is_in_autocommit(conn))
+ {
+ if (issued_begin)
+ CC_commit(conn);
+ }
+ stmt->status = STMT_FINISHED;
+ return SQL_SUCCESS;
+ }
+ /*
+ * The real execution.
+ */
+ retval = SC_execute(stmt);
+ if (retval == SQL_ERROR)
+ {
+ stmt->exec_current_row = -1;
+ *exec_end = TRUE;
+ return retval;
+ }
+ res = SC_get_Result(stmt);
+ /* special handling of result for keyset driven cursors */
+ if (SQL_CURSOR_KEYSET_DRIVEN == stmt->options.cursor_type &&
+ SQL_CONCUR_READ_ONLY != stmt->options.scroll_concurrency)
+ {
+ QResultClass *kres;
+
+ if (kres = res->next, kres)
+ {
+ kres->fields = res->fields;
+ res->fields = NULL;
+ kres->num_fields = res->num_fields;
+ res->next = NULL;
+ QR_Destructor(res);
+ SC_set_Result(stmt, kres);
+ res = kres;
+ }
+ }
+ else if (SC_is_prepare_before_exec(stmt))
+ {
+ if (res && QR_command_maybe_successful(res))
+ {
+ QResultClass *kres;
+
+ kres = res->next;
+ SC_set_Result(stmt, kres);
+ res->next = NULL;
+ QR_Destructor(res);
+ res = kres;
+ stmt->prepared = TRUE;
+ }
+ else
+ {
+ retval = SQL_ERROR;
+ if (stmt->execute_statement)
+ free(stmt->execute_statement);
+ stmt->execute_statement = NULL;
+ }
+ }
+#if (ODBCVER >= 0x0300)
+ ipdopts = SC_get_IPD(stmt);
+ if (ipdopts->param_status_ptr)
+ {
+ switch (retval)
+ {
+ case SQL_SUCCESS:
+ ipdopts->param_status_ptr[stmt->exec_current_row] = SQL_PARAM_SUCCESS;
+ break;
+ case SQL_SUCCESS_WITH_INFO:
+ ipdopts->param_status_ptr[stmt->exec_current_row] = SQL_PARAM_SUCCESS_WITH_INFO;
+ break;
+ default:
+ ipdopts->param_status_ptr[stmt->exec_current_row] = SQL_PARAM_ERROR;
+ break;
+ }
+ }
+#endif /* ODBCVER */
+ if (end_row = stmt->exec_end_row, end_row < 0)
+ {
+ apdopts = SC_get_APD(stmt);
+ end_row = apdopts->paramset_size - 1;
+ }
+ if (stmt->inaccurate_result ||
+ stmt->exec_current_row >= end_row)
+ {
+ *exec_end = TRUE;
+ stmt->exec_current_row = -1;
+ }
+ else
+ stmt->exec_current_row++;
+ if (res)
+ stmt->diag_row_count = res->recent_processed_row_count;
+ /*
+ * The cursor's info was changed ?
+ */
+ if (retval == SQL_SUCCESS &&
+ (stmt->options.cursor_type != cursor_type ||
+ stmt->options.scroll_concurrency != scroll_concurrency))
+ {
+ SC_set_error(stmt, STMT_OPTION_VALUE_CHANGED, "cursor updatability changed");
+ retval = SQL_SUCCESS_WITH_INFO;
+ }
+ return retval;
+}
/* Execute a prepared SQL statement */
RETCODE SQL_API
{
static char *func = "PGAPI_Execute";
StatementClass *stmt = (StatementClass *) hstmt;
- APDFields *opts;
+ APDFields *apdopts;
IPDFields *ipdopts;
ConnectionClass *conn;
int i,
retval, start_row, end_row;
- int cursor_type, scroll_concurrency;
- QResultClass *res;
+ BOOL exec_end, recycled = FALSE, recycle = TRUE;
mylog("%s: entering...\n", func);
return SQL_INVALID_HANDLE;
}
- opts = SC_get_APD(stmt);
- cursor_type = stmt->options.cursor_type;
- scroll_concurrency = stmt->options.scroll_concurrency;
+ apdopts = SC_get_APD(stmt);
/*
* If the statement is premature, it means we already executed it from
* an SQLPrepare/SQLDescribeCol type of scenario. So just return
return SQL_ERROR;
}
+ if (stmt->exec_current_row > 0)
+ {
+ /*
+ * executing an array of parameters.
+ * Don't recycle the statement.
+ */
+ recycle = FALSE;
+ }
+ else if (stmt->prepared)
+ {
+ QResultClass *res;
+
+ /*
+ * re-executing an prepared statement.
+ * Don't recycle the statement but
+ * discard the old result.
+ */
+ recycle = FALSE;
+ if (res = SC_get_Result(stmt), res)
+ {
+ QR_Destructor(res);
+ SC_set_Result(stmt, NULL);
+ }
+ }
/*
* If SQLExecute is being called again, recycle the statement. Note
* this should have been done by the application in a call to
* SQLFreeStmt(SQL_CLOSE) or SQLCancel.
*/
- if (stmt->status == STMT_FINISHED)
+ else if (stmt->status == STMT_FINISHED)
{
mylog("%s: recycling statement (should have been done by app)...\n", func);
/******** Is this really NEEDED ? ******/
SC_recycle_statement(stmt);
+ recycled = TRUE;
}
-
/* Check if the statement is in the correct state */
- if ((stmt->prepare && stmt->status != STMT_READY) ||
+ else if ((stmt->prepare && stmt->status != STMT_READY) ||
(stmt->status != STMT_ALLOCATED && stmt->status != STMT_READY))
{
SC_set_error(stmt, STMT_STATUS_ERROR, "The handle does not point to a statement that is ready to be executed");
if (start_row = stmt->exec_start_row, start_row < 0)
start_row = 0;
if (end_row = stmt->exec_end_row, end_row < 0)
- end_row = opts->paramset_size - 1;
+ end_row = apdopts->paramset_size - 1;
if (stmt->exec_current_row < 0)
stmt->exec_current_row = start_row;
ipdopts = SC_get_IPD(stmt);
ipdopts->param_status_ptr[i] = SQL_PARAM_UNUSED;
}
#endif /* ODBCVER */
- SC_recycle_statement(stmt);
+ if (recycle && !recycled)
+ SC_recycle_statement(stmt);
}
next_param_row:
#if (ODBCVER >= 0x0300)
- if (opts->param_operation_ptr)
+ if (apdopts->param_operation_ptr)
{
- while (opts->param_operation_ptr[stmt->exec_current_row] == SQL_PARAM_IGNORE)
+ while (apdopts->param_operation_ptr[stmt->exec_current_row] == SQL_PARAM_IGNORE)
{
if (stmt->exec_current_row >= end_row)
{
* execute of this statement? Therefore check for params and
* re-copy.
*/
- UInt4 offset = opts->param_offset_ptr ? *opts->param_offset_ptr : 0;
- Int4 bind_size = opts->param_bind_type;
+ UInt4 offset = apdopts->param_offset_ptr ? *apdopts->param_offset_ptr : 0;
+ Int4 bind_size = apdopts->param_bind_type;
Int4 current_row = stmt->exec_current_row < 0 ? 0 : stmt->exec_current_row;
/*
if (ipdopts->param_processed_ptr)
(*ipdopts->param_processed_ptr)++;
stmt->data_at_exec = -1;
- for (i = 0; i < opts->allocated; i++)
+ for (i = 0; i < apdopts->allocated; i++)
{
- Int4 *pcVal = opts->parameters[i].used;
+ Int4 *pcVal = apdopts->parameters[i].used;
- opts->parameters[i].data_at_exec = FALSE;
+ apdopts->parameters[i].data_at_exec = FALSE;
if (pcVal)
{
if (bind_size > 0)
else
pcVal = (Int4 *)((char *)pcVal + offset + sizeof(SDWORD) * current_row);
if (*pcVal == SQL_DATA_AT_EXEC || *pcVal <= SQL_LEN_DATA_AT_EXEC_OFFSET)
- opts->parameters[i].data_at_exec = TRUE;
+ apdopts->parameters[i].data_at_exec = TRUE;
}
/* Check for data at execution parameters */
- if (opts->parameters[i].data_at_exec)
+ if (apdopts->parameters[i].data_at_exec)
{
if (stmt->data_at_exec < 0)
stmt->data_at_exec = 1;
}
-
- mylog("%s: copying statement params: trans_status=%d, len=%d, stmt='%s'\n", func, conn->transact_status, strlen(stmt->statement), stmt->statement);
-
- /* Create the statement with parameters substituted. */
- retval = copy_statement_with_parameters(stmt);
- if (retval != SQL_SUCCESS)
- /* error msg passed from above */
- return retval;
-
- mylog(" stmt_with_params = '%s'\n", stmt->stmt_with_params);
-
- if (!stmt->inaccurate_result || !conn->connInfo.disallow_premature)
- {
- retval = SC_execute(stmt);
- if (retval != SQL_ERROR)
- {
- /* special handling of result for keyset driven cursors */
- if (SQL_CURSOR_KEYSET_DRIVEN == stmt->options.cursor_type &&
- SQL_CONCUR_READ_ONLY != stmt->options.scroll_concurrency)
- {
- QResultClass *kres;
-
- res = SC_get_Result(stmt);
- if (kres = res->next, kres)
- {
- kres->fields = res->fields;
- res->fields = NULL;
- kres->num_fields = res->num_fields;
- res->next = NULL;
- QR_Destructor(res);
- SC_set_Result(stmt, kres);
- }
- }
- }
-#if (ODBCVER >= 0x0300)
- if (ipdopts->param_status_ptr)
- {
- switch (retval)
- {
- case SQL_SUCCESS:
- ipdopts->param_status_ptr[stmt->exec_current_row] = SQL_PARAM_SUCCESS;
- break;
- case SQL_SUCCESS_WITH_INFO:
- ipdopts->param_status_ptr[stmt->exec_current_row] = SQL_PARAM_SUCCESS_WITH_INFO;
- break;
- default:
- ipdopts->param_status_ptr[stmt->exec_current_row] = SQL_PARAM_ERROR;
- break;
- }
- }
-#endif /* ODBCVER */
- if (retval == SQL_ERROR ||
- stmt->inaccurate_result ||
- stmt->exec_current_row >= end_row)
- {
- stmt->exec_current_row = -1;
- return retval;
- }
- stmt->exec_current_row++;
+ retval = Exec_with_parameters_resolved(stmt, &exec_end);
+ if (!exec_end)
goto next_param_row;
- }
- /*
- * Get the field info for the prepared query using dummy backward
- * fetch.
- */
- if (SC_is_pre_executable(stmt))
- {
- BOOL in_trans = CC_is_in_trans(conn);
- BOOL issued_begin = FALSE,
- begin_included = FALSE;
- QResultClass *curres;
-
- if (strnicmp(stmt->stmt_with_params, "BEGIN;", 6) == 0)
- begin_included = TRUE;
- else if (!in_trans)
- {
- if (issued_begin = CC_begin(conn), !issued_begin)
- {
- SC_set_error(stmt, STMT_EXEC_ERROR, "Handle prepare error");
- return SQL_ERROR;
- }
- }
- /* we are now in a transaction */
- res = CC_send_query(conn, stmt->stmt_with_params, NULL, CLEAR_RESULT_ON_ABORT);
- if (!res)
- {
- CC_abort(conn);
- SC_set_error(stmt, STMT_EXEC_ERROR, "Handle prepare error");
- return SQL_ERROR;
- }
- SC_set_Result(stmt, res);
- for (curres = res; !curres->num_fields; curres = curres->next)
- ;
- SC_set_Curres(stmt, curres);
- if (CC_is_in_autocommit(conn))
- {
- if (issued_begin)
- CC_commit(conn);
- }
- stmt->status = STMT_FINISHED;
- return SQL_SUCCESS;
- }
- if (res = SC_get_Curres(stmt), res)
- stmt->diag_row_count = res->recent_processed_row_count;
- if (stmt->options.cursor_type != cursor_type ||
- stmt->options.scroll_concurrency != scroll_concurrency)
- {
- SC_set_error(stmt, STMT_OPTION_VALUE_CHANGED, "cursor updatability changed");
- return SQL_SUCCESS_WITH_INFO;
- }
- else
- return SQL_SUCCESS;
+ return retval;
}
{
static char *func = "PGAPI_ParamData";
StatementClass *stmt = (StatementClass *) hstmt;
- APDFields *opts;
+ APDFields *apdopts;
IPDFields *ipdopts;
int i,
retval;
return SQL_INVALID_HANDLE;
}
ci = &(SC_get_conn(stmt)->connInfo);
- opts = SC_get_APD(stmt);
+ apdopts = SC_get_APD(stmt);
- mylog("%s: data_at_exec=%d, params_alloc=%d\n", func, stmt->data_at_exec, opts->allocated);
+ mylog("%s: data_at_exec=%d, params_alloc=%d\n", func, stmt->data_at_exec, apdopts->allocated);
if (stmt->data_at_exec < 0)
{
return SQL_ERROR;
}
- if (stmt->data_at_exec > opts->allocated)
+ if (stmt->data_at_exec > apdopts->allocated)
{
SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Too many execution-time parameters were present");
SC_log_error(func, "", stmt);
ipdopts = SC_get_IPD(stmt);
if (stmt->data_at_exec == 0)
{
- int end_row;
+ BOOL exec_end;
- retval = copy_statement_with_parameters(stmt);
- if (retval != SQL_SUCCESS)
+ retval = Exec_with_parameters_resolved(stmt, &exec_end);
+ if (exec_end)
return retval;
-
- stmt->current_exec_param = -1;
-
- retval = SC_execute(stmt);
-#if (ODBCVER >= 0x0300)
- if (ipdopts->param_status_ptr)
- {
- switch (retval)
- {
- case SQL_SUCCESS:
- ipdopts->param_status_ptr[stmt->exec_current_row] = SQL_PARAM_SUCCESS;
- break;
- case SQL_SUCCESS_WITH_INFO:
- ipdopts->param_status_ptr[stmt->exec_current_row] = SQL_PARAM_SUCCESS_WITH_INFO;
- break;
- default:
- ipdopts->param_status_ptr[stmt->exec_current_row] = SQL_PARAM_ERROR;
- break;
- }
- }
-#endif /* ODBCVER */
- end_row = stmt->exec_end_row;
- if (end_row < 0)
- end_row = opts->paramset_size - 1;
- if (retval == SQL_ERROR ||
- stmt->exec_current_row >= end_row)
- {
- stmt->exec_current_row = -1;
- return retval;
- }
- stmt->exec_current_row++;
return PGAPI_Execute(stmt);
}
i = stmt->current_exec_param >= 0 ? stmt->current_exec_param + 1 : 0;
/* At least 1 data at execution parameter, so Fill in the token value */
- for (; i < opts->allocated; i++)
+ for (; i < apdopts->allocated; i++)
{
- if (opts->parameters[i].data_at_exec)
+ if (apdopts->parameters[i].data_at_exec)
{
stmt->data_at_exec--;
stmt->current_exec_param = i;
stmt->put_data = FALSE;
- *prgbValue = opts->parameters[i].buffer; /* token */
+ *prgbValue = apdopts->parameters[i].buffer; /* token */
break;
}
}
{
static char *func = "PGAPI_PutData";
StatementClass *stmt = (StatementClass *) hstmt;
- APDFields *opts;
+ ConnectionClass *conn;
+ APDFields *apdopts;
+ IPDFields *ipdopts;
int old_pos,
retval;
ParameterInfoClass *current_param;
+ ParameterImplClass *current_iparam;
char *buffer;
mylog("%s: entering...\n", func);
return SQL_INVALID_HANDLE;
}
- opts = SC_get_APD(stmt);
+ apdopts = SC_get_APD(stmt);
if (stmt->current_exec_param < 0)
{
SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Previous call was not SQLPutData or SQLParamData");
return SQL_ERROR;
}
- current_param = &(opts->parameters[stmt->current_exec_param]);
+ current_param = &(apdopts->parameters[stmt->current_exec_param]);
+ ipdopts = SC_get_IPD(stmt);
+ current_iparam = &(ipdopts->parameters[stmt->current_exec_param]);
+ conn = SC_get_conn(stmt);
if (!stmt->put_data)
{ /* first call */
mylog("PGAPI_PutData: (1) cbValue = %d\n", cbValue);
return SQL_SUCCESS;
/* Handle Long Var Binary with Large Objects */
- if (current_param->SQLType == SQL_LONGVARBINARY)
+ /* if (current_iparam->SQLType == SQL_LONGVARBINARY) */
+ if (current_iparam->PGType == conn->lobj_type)
{
/* begin transaction if needed */
if (!CC_is_in_trans(stmt->hdbc))
* 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;
+ /***current_param->EXEC_buffer = (char *) ¤t_param->lobj_oid;***/
/* store the fd */
stmt->lobj_fd = lo_open(stmt->hdbc, current_param->lobj_oid, INV_WRITE);
{
Int2 ctype = current_param->CType;
if (ctype == SQL_C_DEFAULT)
- ctype = sqltype_to_default_ctype(current_param->SQLType);
+ ctype = sqltype_to_default_ctype(current_iparam->SQLType);
#ifdef UNICODE_SUPPORT
if (SQL_NTS == cbValue && SQL_C_WCHAR == ctype)
/* calling SQLPutData more than once */
mylog("PGAPI_PutData: (>1) cbValue = %d\n", cbValue);
- if (current_param->SQLType == SQL_LONGVARBINARY)
+ /* if (current_iparam->SQLType == SQL_LONGVARBINARY) */
+ if (current_iparam->PGType == conn->lobj_type)
{
/* the large object fd is in EXEC_buffer */
retval = lo_write(stmt->hdbc, stmt->lobj_fd, rgbValue, cbValue);
Int2 ctype = current_param->CType;
if (ctype == SQL_C_DEFAULT)
- ctype = sqltype_to_default_ctype(current_param->SQLType);
+ ctype = sqltype_to_default_ctype(current_iparam->SQLType);
buffer = current_param->EXEC_buffer;
if (old_pos = *current_param->EXEC_used, SQL_NTS == old_pos)
{
ordinal;
char useStaticPrecision;
char not_null[MAX_INFO_STRING],
- relhasrules[MAX_INFO_STRING];
+ relhasrules[MAX_INFO_STRING], relkind[8];
+ BOOL relisaview;
ConnInfo *ci;
ConnectionClass *conn;
*/
if (conn->schema_support)
sprintf(columns_query, "select u.nspname, c.relname, a.attname, a.atttypid"
- ", t.typname, a.attnum, a.attlen, %s, a.attnotnull, c.relhasrules"
+ ", t.typname, a.attnum, a.attlen, %s, a.attnotnull, c.relhasrules, c.relkind"
" from pg_namespace u, pg_class c, pg_attribute a, pg_type t"
" where u.oid = c.relnamespace"
- " and c.oid= a.attrelid and a.atttypid = t.oid and (a.attnum > 0) and not(attisdropped)",
+ " and (not a.attisdropped)"
+ " and c.oid= a.attrelid and a.atttypid = t.oid and (a.attnum > 0)",
"a.atttypmod");
else
sprintf(columns_query, "select u.usename, c.relname, a.attname, a.atttypid"
- ", t.typname, a.attnum, a.attlen, %s, a.attnotnull, c.relhasrules"
+ ", t.typname, a.attnum, a.attlen, %s, a.attnotnull, c.relhasrules, c.relkind"
" from pg_user u, pg_class c, pg_attribute a, pg_type t"
" where u.usesysid = c.relowner"
" and c.oid= a.attrelid and a.atttypid = t.oid and (a.attnum > 0)",
return SQL_ERROR;
}
+ result = PGAPI_BindCol(hcol_stmt, 11, SQL_C_CHAR,
+ relkind, sizeof(relkind), NULL);
+ if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
+ {
+ SC_error_copy(stmt, col_stmt);
+ SC_log_error(func, "", stmt);
+ PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
+ return SQL_ERROR;
+ }
+
if (res = QR_Constructor(), !res)
{
SC_set_error(stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for PGAPI_Columns result.");
* table
*/
+ if (PG_VERSION_GE(conn, 7.1))
+ relisaview = (relkind[0] == 'v');
+ else
+ relisaview = (relhasrules[0] == '1');
if (result != SQL_ERROR && !stmt->internal)
{
- if (relhasrules[0] != '1' &&
+ if (!relisaview &&
(atoi(ci->show_oid_column) ||
strncmp(table_name, POSTGRES_SYS_PREFIX, strlen(POSTGRES_SYS_PREFIX)) == 0))
{
* 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))
+ if (!relisaview && !stmt->internal && atoi(ci->row_versioning))
{
/* For Row Versioning fields */
the_type = PG_TYPE_INT4;
StatementClass *col_stmt;
char columns_query[INFO_INQUIRY_LEN];
RETCODE result;
- char relhasrules[MAX_INFO_STRING];
+ char relhasrules[MAX_INFO_STRING], relkind[8];
+ BOOL relisaview;
mylog("%s: entering...stmt=%u scnm=%x len=%d colType=%d\n", func, stmt, szTableOwner, cbTableOwner, fColType);
* Create the query to find out if this is a view or not...
*/
if (conn->schema_support)
- sprintf(columns_query, "select c.relhasrules "
+ sprintf(columns_query, "select c.relhasrules, c.relkind "
"from pg_namespace u, pg_class c where "
"u.oid = c.relnamespace");
else
- sprintf(columns_query, "select c.relhasrules "
+ sprintf(columns_query, "select c.relhasrules, c.relkind "
"from pg_user u, pg_class c where "
"u.usesysid = c.relowner");
return SQL_ERROR;
}
+ result = PGAPI_BindCol(hcol_stmt, 2, SQL_C_CHAR,
+ relkind, sizeof(relkind), NULL);
+ if ((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO))
+ {
+ SC_error_copy(stmt, col_stmt);
+ SC_log_error(func, "", stmt);
+ PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
+ return SQL_ERROR;
+ }
+
result = PGAPI_Fetch(hcol_stmt);
+ if (PG_VERSION_GE(conn, 7.1))
+ relisaview = (relkind[0] == 'v');
+ else
+ relisaview = (relhasrules[0] == '1');
PGAPI_FreeStmt(hcol_stmt, SQL_DROP);
res = QR_Constructor();
QR_set_field_info(res, 6, "SCALE", PG_TYPE_INT2, 2);
QR_set_field_info(res, 7, "PSEUDO_COLUMN", PG_TYPE_INT2, 2);
- if (relhasrules[0] != '1')
+ if (!relisaview)
{
/* use the oid value for the rowid */
if (fColType == SQL_BEST_ROWID)
*indx_stmt;
char column_name[MAX_INFO_STRING],
table_qualifier[MAX_INFO_STRING],
- relhasrules[10];
+ relhasrules[10], relkind[8];
char **column_names = 0;
SQLINTEGER column_name_len;
int total_columns = 0;
goto SEEYA;
}
+ relhasrules[0] = '0';
+ result = PGAPI_Fetch(hindx_stmt);
/* fake index of OID */
if (relhasrules[0] != '1' && atoi(ci->show_oid_column) && atoi(ci->fake_oid_index))
{
QR_add_tuple(res, row);
}
- result = PGAPI_Fetch(hindx_stmt);
while ((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO))
{
/* If only requesting unique indexs, then just return those. */
" AND ia.attrelid = i.indexrelid"
" AND ta.attrelid = i.indrelid"
" AND ta.attnum = i.indkey[ia.attnum-1]"
- " AND NOT(ta.attisdropped)"
- " AND NOT(ia.attisdropped)"
+ " AND (NOT ta.attisdropped)"
+ " AND (NOT ia.attisdropped)"
" order by ia.attnum", pktab, pkscm);
else
sprintf(tables_query, "select ta.attname, ia.attnum"
" AND ia.attrelid = i.indexrelid"
" AND ta.attrelid = i.indrelid"
" AND ta.attnum = i.indkey[ia.attnum-1]"
- " AND NOT(ta.attisdropped)"
- " AND NOT(ia.attisdropped)"
+ " AND (NOT ta.attisdropped)"
+ " AND (NOT ia.attisdropped)"
" order by ia.attnum", pktab, pkscm);
else
sprintf(tables_query, "select ta.attname, ia.attnum"
if (conn->schema_support)
sprintf(query, "select attrelid, attnum from pg_class, pg_attribute "
"where relname = '%s' and attrelid = pg_class.oid "
- "and attname = '%s' and pg_namespace.oid = relnamespace and pg_namespace.nspname = '%s' and not(attisdropped)", serverTableName, serverColumnName, serverSchemaName);
+ "and (not attisdropped) "
+ "and attname = '%s' and pg_namespace.oid = relnamespace and pg_namespace.nspname = '%s'", serverTableName, serverColumnName, serverSchemaName);
else
sprintf(query, "select attrelid, attnum from pg_class, pg_attribute "
"where relname = '%s' and attrelid = pg_class.oid "
break;
case SQL_CREATE_TABLE:
len = 4;
- value = SQL_CT_CREATE_TABLE | SQL_CT_TABLE_CONSTRAINT
- | SQL_CT_CONSTRAINT_NAME_DEFINITION
- | SQL_CT_LOCAL_TEMPORARY | SQL_CT_COLUMN_CONSTRAINT
- | SQL_CT_COLUMN_DEFAULT | SQL_CT_CONSTRAINT_INITIALLY_DEFERRED
- | SQL_CT_CONSTRAINT_INITIALLY_IMMEDIATE | SQL_CT_CONSTRAINT_DEFERRABLE;
+ value = SQL_CT_CREATE_TABLE | SQL_CT_COLUMN_CONSTRAINT
+ | SQL_CT_COLUMN_DEFAULT;
+ if (PG_VERSION_GE(conn, 6.5))
+ value |= SQL_CT_GLOBAL_TEMPORARY;
+ if (PG_VERSION_GE(conn, 7.0))
+ value |= SQL_CT_TABLE_CONSTRAINT
+ | SQL_CT_CONSTRAINT_NAME_DEFINITION
+ | SQL_CT_CONSTRAINT_INITIALLY_DEFERRED
+ | SQL_CT_CONSTRAINT_INITIALLY_IMMEDIATE
+ | SQL_CT_CONSTRAINT_DEFERRABLE;
break;
case SQL_CREATE_TRANSLATION:
len = 4;
wenc = "SJIS";
break;
case 936:
- if (!encstr || PG_VERSION_LE(self, 7.2))
+ if (!encstr || PG_VERSION_GT(self, 7.2))
wenc = "GBK";
break;
case 949:
- if (!encstr || PG_VERSION_LE(self, 7.2) ||
- stricmp(encstr, "EUC_KR"))
+ if (!encstr ||
+ (PG_VERSION_GT(self, 7.2) && stricmp(encstr, "EUC_KR")))
wenc = "UHC";
break;
case 950:
HDBC FAR * ConnectionHandle)
{
RETCODE ret;
+ EnvironmentClass *env = (EnvironmentClass *) EnvironmentHandle;
mylog("[SQLAllocConnect]");
- ENTER_ENV_CS((EnvironmentClass *) EnvironmentHandle);
+ ENTER_ENV_CS(env);
ret = PGAPI_AllocConnect(EnvironmentHandle, ConnectionHandle);
- LEAVE_ENV_CS((EnvironmentClass *) EnvironmentHandle);
+ LEAVE_ENV_CS(env);
return ret;
}
HSTMT *StatementHandle)
{
RETCODE ret;
+ ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
mylog("[SQLAllocStmt]");
- ENTER_CONN_CS((ConnectionClass *) ConnectionHandle);
- CC_clear_error((ConnectionClass *) ConnectionHandle);
+ ENTER_CONN_CS(conn);
+ CC_clear_error(conn);
ret = PGAPI_AllocStmt(ConnectionHandle, StatementHandle);
- LEAVE_CONN_CS((ConnectionClass *) ConnectionHandle);
+ LEAVE_CONN_CS(conn);
return ret;
}
SQLINTEGER *StrLen_or_Ind)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLBindCol]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_BindCol(StatementHandle, ColumnNumber,
TargetType, TargetValue, BufferLength, StrLen_or_Ind);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLCHAR *ColumnName, SQLSMALLINT NameLength4)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLColumns]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_Columns(StatementHandle, CatalogName, NameLength1,
SchemaName, NameLength2, TableName, NameLength3,
ColumnName, NameLength4, 0);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLCHAR *Authentication, SQLSMALLINT NameLength3)
{
RETCODE ret;
+ ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
mylog("[SQLConnect]");
- ENTER_CONN_CS((ConnectionClass *) ConnectionHandle);
- CC_clear_error((ConnectionClass *) ConnectionHandle);
+ ENTER_CONN_CS(conn);
+ CC_clear_error(conn);
ret = PGAPI_Connect(ConnectionHandle, ServerName, NameLength1,
UserName, NameLength2, Authentication, NameLength3);
- LEAVE_CONN_CS((ConnectionClass *) ConnectionHandle);
+ LEAVE_CONN_CS(conn);
return ret;
}
UWORD fDriverCompletion)
{
RETCODE ret;
+ ConnectionClass *conn = (ConnectionClass *) hdbc;
mylog("[SQLDriverConnect]");
- ENTER_CONN_CS((ConnectionClass *) hdbc);
- CC_clear_error((ConnectionClass *) hdbc);
+ ENTER_CONN_CS(conn);
+ CC_clear_error(conn);
ret = PGAPI_DriverConnect(hdbc, hwnd, szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut, fDriverCompletion);
- LEAVE_CONN_CS((ConnectionClass *) hdbc);
+ LEAVE_CONN_CS(conn);
return ret;
}
RETCODE SQL_API
SQLSMALLINT *pcbConnStrOut)
{
RETCODE ret;
+ ConnectionClass *conn = (ConnectionClass *) hdbc;
mylog("[SQLBrowseConnect]");
- ENTER_CONN_CS((ConnectionClass *) hdbc);
- CC_clear_error((ConnectionClass *) hdbc);
+ ENTER_CONN_CS(conn);
+ CC_clear_error(conn);
ret = PGAPI_BrowseConnect(hdbc, szConnStrIn, cbConnStrIn,
szConnStrOut, cbConnStrOutMax, pcbConnStrOut);
- LEAVE_CONN_CS((ConnectionClass *) hdbc);
+ LEAVE_CONN_CS(conn);
return ret;
}
SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLDescribeCol]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_DescribeCol(StatementHandle, ColumnNumber,
ColumnName, BufferLength, NameLength,
DataType, ColumnSize, DecimalDigits, Nullable);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLDisconnect(HDBC ConnectionHandle)
{
RETCODE ret;
+ ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
mylog("[SQLDisconnect]");
- ENTER_CONN_CS((ConnectionClass *) ConnectionHandle);
- CC_clear_error((ConnectionClass *) ConnectionHandle);
+ ENTER_CONN_CS(conn);
+ CC_clear_error(conn);
ret = PGAPI_Disconnect(ConnectionHandle);
- LEAVE_CONN_CS((ConnectionClass *) ConnectionHandle);
+ LEAVE_CONN_CS(conn);
return ret;
}
SQLCHAR *StatementText, SQLINTEGER TextLength)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLExecDirect]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_ExecDirect(StatementHandle, StatementText, TextLength);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLExecute(HSTMT StatementHandle)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLExecute]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_Execute(StatementHandle);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLUSMALLINT Option, PTR Value)
{
RETCODE ret;
+ ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
mylog("[SQLGetConnectOption]");
- ENTER_CONN_CS((ConnectionClass *) ConnectionHandle);
- CC_clear_error((ConnectionClass *) ConnectionHandle);
+ ENTER_CONN_CS(conn);
+ CC_clear_error(conn);
ret = PGAPI_GetConnectOption(ConnectionHandle, Option, Value);
- LEAVE_CONN_CS((ConnectionClass *) ConnectionHandle);
+ LEAVE_CONN_CS(conn);
return ret;
}
RETCODE SQL_API
SQLSMALLINT *NameLength)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLGetCursorName]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_GetCursorName(StatementHandle, CursorName, BufferLength,
NameLength);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLINTEGER *StrLen_or_Ind)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLGetData]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_GetData(StatementHandle, ColumnNumber, TargetType,
TargetValue, BufferLength, StrLen_or_Ind);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLUSMALLINT FunctionId, SQLUSMALLINT *Supported)
{
RETCODE ret;
+ ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
mylog("[SQLGetFunctions]");
- ENTER_CONN_CS((ConnectionClass *) ConnectionHandle);
- CC_clear_error((ConnectionClass *) ConnectionHandle);
+ ENTER_CONN_CS(conn);
+ CC_clear_error(conn);
#if (ODBCVER >= 0x0300)
if (FunctionId == SQL_API_ODBC3_ALL_FUNCTIONS)
ret = PGAPI_GetFunctions30(ConnectionHandle, FunctionId, Supported);
{
ret = PGAPI_GetFunctions(ConnectionHandle, FunctionId, Supported);
}
- LEAVE_CONN_CS((ConnectionClass *) ConnectionHandle);
+ LEAVE_CONN_CS(conn);
return ret;
}
RETCODE SQL_API
RETCODE ret;
ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
- ENTER_CONN_CS((ConnectionClass *) ConnectionHandle);
+ ENTER_CONN_CS(conn);
CC_clear_error(conn);
#if (ODBCVER >= 0x0300)
mylog("[SQLGetInfo(30)]");
BufferLength, StringLength), SQL_ERROR == ret)
CC_log_error("PGAPI_GetInfo", "", conn);
#endif
- LEAVE_CONN_CS((ConnectionClass *) ConnectionHandle);
+ LEAVE_CONN_CS(conn);
return ret;
}
SQLUSMALLINT Option, PTR Value)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLGetStmtOption]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_GetStmtOption(StatementHandle, Option, Value);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLSMALLINT DataType)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLGetTypeInfo]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_GetTypeInfo(StatementHandle, DataType);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLSMALLINT *ColumnCount)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLNumResultCols]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_NumResultCols(StatementHandle, ColumnCount);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
PTR *Value)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLParamData]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_ParamData(StatementHandle, Value);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLCHAR *StatementText, SQLINTEGER TextLength)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLPrepare]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_Prepare(StatementHandle, StatementText, TextLength);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
PTR Data, SQLINTEGER StrLen_or_Ind)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLPutData]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_PutData(StatementHandle, Data, StrLen_or_Ind);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLINTEGER *RowCount)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLRowCount]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_RowCount(StatementHandle, RowCount);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLUSMALLINT Option, SQLUINTEGER Value)
{
RETCODE ret;
+ ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
mylog("[SQLSetConnectionOption]");
- ENTER_CONN_CS((ConnectionClass *) ConnectionHandle);
- CC_clear_error((ConnectionClass *) ConnectionHandle);
+ ENTER_CONN_CS(conn);
+ CC_clear_error(conn);
ret = PGAPI_SetConnectOption(ConnectionHandle, Option, Value);
- LEAVE_CONN_CS((ConnectionClass *) ConnectionHandle);
+ LEAVE_CONN_CS(conn);
return ret;
}
SQLCHAR *CursorName, SQLSMALLINT NameLength)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLSetCursorName]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_SetCursorName(StatementHandle, CursorName, NameLength);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLUSMALLINT Option, SQLUINTEGER Value)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLSetStmtOption]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_SetStmtOption(StatementHandle, Option, Value);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLUSMALLINT Nullable)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLSpecialColumns]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_SpecialColumns(StatementHandle, IdentifierType, CatalogName,
NameLength1, SchemaName, NameLength2, TableName, NameLength3,
Scope, Nullable);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLUSMALLINT Unique, SQLUSMALLINT Reserved)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLStatistics]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_Statistics(StatementHandle, CatalogName, NameLength1,
SchemaName, NameLength2, TableName, NameLength3, Unique,
Reserved);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLCHAR *TableType, SQLSMALLINT NameLength4)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) StatementHandle;
mylog("[SQLTables]");
- ENTER_STMT_CS((StatementClass *) StatementHandle);
- SC_clear_error((StatementClass *) StatementHandle);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_Tables(StatementHandle, CatalogName, NameLength1,
SchemaName, NameLength2, TableName, NameLength3,
TableType, NameLength4);
- LEAVE_STMT_CS((StatementClass *) StatementHandle);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLINTEGER *pfDesc)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) hstmt;
mylog("[SQLColAttributes]");
- ENTER_STMT_CS((StatementClass *) hstmt);
- SC_clear_error((StatementClass *) hstmt);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_ColAttributes(hstmt, icol, fDescType, rgbDesc,
cbDescMax, pcbDesc, pfDesc);
- LEAVE_STMT_CS((StatementClass *) hstmt);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLSMALLINT cbColumnName)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) hstmt;
mylog("[SQLColumnPrivileges]");
- ENTER_STMT_CS((StatementClass *) hstmt);
- SC_clear_error((StatementClass *) hstmt);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_ColumnPrivileges(hstmt, szCatalogName, cbCatalogName,
szSchemaName, cbSchemaName, szTableName, cbTableName,
szColumnName, cbColumnName);
- LEAVE_STMT_CS((StatementClass *) hstmt);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLSMALLINT *pfNullable)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) hstmt;
mylog("[SQLDescribeParam]");
- ENTER_STMT_CS((StatementClass *) hstmt);
- SC_clear_error((StatementClass *) hstmt);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_DescribeParam(hstmt, ipar, pfSqlType, pcbParamDef,
pibScale, pfNullable);
- LEAVE_STMT_CS((StatementClass *) hstmt);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLUSMALLINT *rgfRowStatus)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) hstmt;
mylog("[SQLExtendedFetch]");
- ENTER_STMT_CS((StatementClass *) hstmt);
- SC_clear_error((StatementClass *) hstmt);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_ExtendedFetch(hstmt, fFetchType, irow, pcrow, rgfRowStatus, 0);
- LEAVE_STMT_CS((StatementClass *) hstmt);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLSMALLINT cbFkTableName)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) hstmt;
mylog("[SQLForeignKeys]");
- SC_clear_error((StatementClass *) hstmt);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_ForeignKeys(hstmt, szPkCatalogName, cbPkCatalogName,
szPkSchemaName, cbPkSchemaName, szPkTableName,
cbPkTableName, szFkCatalogName, cbFkCatalogName,
szFkSchemaName, cbFkSchemaName, szFkTableName, cbFkTableName);
- LEAVE_STMT_CS((StatementClass *) hstmt);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLMoreResults(HSTMT hstmt)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) hstmt;
mylog("[SQLMoreResults]");
- ENTER_STMT_CS((StatementClass *) hstmt);
- SC_clear_error((StatementClass *) hstmt);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_MoreResults(hstmt);
- LEAVE_STMT_CS((StatementClass *) hstmt);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLINTEGER *pcbSqlStr)
{
RETCODE ret;
+ ConnectionClass *conn = (ConnectionClass *) hdbc;
mylog("[SQLNativeSql]");
- ENTER_CONN_CS((ConnectionClass *) hdbc);
- CC_clear_error((ConnectionClass *) hdbc);
+ ENTER_CONN_CS(conn);
+ CC_clear_error(conn);
ret = PGAPI_NativeSql(hdbc, szSqlStrIn, cbSqlStrIn, szSqlStr,
cbSqlStrMax, pcbSqlStr);
- LEAVE_CONN_CS((ConnectionClass *) hdbc);
+ LEAVE_CONN_CS(conn);
return ret;
}
SQLSMALLINT *pcpar)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) hstmt;
mylog("[SQLNumParams]");
- ENTER_STMT_CS((StatementClass *) hstmt);
- SC_clear_error((StatementClass *) hstmt);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_NumParams(hstmt, pcpar);
- LEAVE_STMT_CS((StatementClass *) hstmt);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLUINTEGER *pirow)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) hstmt;
mylog("[SQLParamOptions]");
- ENTER_STMT_CS((StatementClass *) hstmt);
- SC_clear_error((StatementClass *) hstmt);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_ParamOptions(hstmt, crow, pirow);
- LEAVE_STMT_CS((StatementClass *) hstmt);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLSMALLINT cbTableName)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) hstmt;
mylog("[SQLPrimaryKeys]");
- ENTER_STMT_CS((StatementClass *) hstmt);
- SC_clear_error((StatementClass *) hstmt);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_PrimaryKeys(hstmt, szCatalogName, cbCatalogName,
szSchemaName, cbSchemaName, szTableName, cbTableName);
- LEAVE_STMT_CS((StatementClass *) hstmt);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLSMALLINT cbColumnName)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) hstmt;
mylog("[SQLProcedureColumns]");
- ENTER_STMT_CS((StatementClass *) hstmt);
- SC_clear_error((StatementClass *) hstmt);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_ProcedureColumns(hstmt, szCatalogName, cbCatalogName,
szSchemaName, cbSchemaName, szProcName, cbProcName,
szColumnName, cbColumnName);
- LEAVE_STMT_CS((StatementClass *) hstmt);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLSMALLINT cbProcName)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) hstmt;
mylog("[SQLProcedures]");
- ENTER_STMT_CS((StatementClass *) hstmt);
- SC_clear_error((StatementClass *) hstmt);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_Procedures(hstmt, szCatalogName, cbCatalogName,
szSchemaName, cbSchemaName, szProcName, cbProcName);
- LEAVE_STMT_CS((StatementClass *) hstmt);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLUSMALLINT fLock)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) hstmt;
mylog("[SQLSetPos]");
- ENTER_STMT_CS((StatementClass *) hstmt);
- SC_clear_error((StatementClass *) hstmt);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_SetPos(hstmt, irow, fOption, fLock);
- LEAVE_STMT_CS((StatementClass *) hstmt);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLSMALLINT cbTableName)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) hstmt;
mylog("[SQLTablePrivileges]");
- ENTER_STMT_CS((StatementClass *) hstmt);
- SC_clear_error((StatementClass *) hstmt);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_TablePrivileges(hstmt, szCatalogName, cbCatalogName,
szSchemaName, cbSchemaName, szTableName, cbTableName, 0);
- LEAVE_STMT_CS((StatementClass *) hstmt);
+ LEAVE_STMT_CS(stmt);
return ret;
}
SQLINTEGER *pcbValue)
{
RETCODE ret;
+ StatementClass *stmt = (StatementClass *) hstmt;
mylog("[SQLBindParameter]");
- ENTER_STMT_CS((StatementClass *) hstmt);
- SC_clear_error((StatementClass *) hstmt);
+ ENTER_STMT_CS(stmt);
+ SC_clear_error(stmt);
ret = PGAPI_BindParameter(hstmt, ipar, fParamType, fCType,
fSqlType, cbColDef, ibScale, rgbValue, cbValueMax,
pcbValue);
- LEAVE_STMT_CS((StatementClass *) hstmt);
+ LEAVE_STMT_CS(stmt);
return ret;
}
{
RETCODE ret;
+ mylog("[SQLGetInfoW]");
ENTER_STMT_CS((StatementClass *) StatementHandle);
ret = PGAPI_GetTypeInfo(StatementHandle, DataType);
LEAVE_STMT_CS((StatementClass *) StatementHandle);
*((SQLINTEGER *) DiagInfoPtr) = 0;
ret = SQL_NO_DATA_FOUND;
stmt = (StatementClass *) Handle;
- do
+ rtn = PGAPI_StmtError(Handle, -1, NULL,
+ NULL, NULL, 0, &pcbErrm, 0);
+ switch (rtn)
{
- rtn = PGAPI_StmtError(Handle, RecNumber,
- NULL, NULL, NULL,
- 0, &pcbErrm, 0);
- if (SQL_SUCCESS == rtn ||
- SQL_SUCCESS_WITH_INFO == rtn)
- {
- *((SQLINTEGER *) DiagInfoPtr)++;
+ case SQL_SUCCESS:
+ case SQL_SUCCESS_WITH_INFO:
ret = SQL_SUCCESS;
- }
- } while (pcbErrm >= stmt->error_recsize);
+ if (pcbErrm > 0)
+ *((SQLINTEGER *) DiagInfoPtr) = (pcbErrm - 1)/ stmt->error_recsize + 1;
+ break;
+ default:
+ break;
+ }
if (StringLengthPtr)
*StringLengthPtr = sizeof(SQLINTEGER);
break;
}
}
+static void parameter_ibindings_set(IPDFields *opts, int params, BOOL maxset)
+{
+ int i;
+
+ if (params == opts->allocated)
+ return;
+ if (params > opts->allocated)
+ {
+ extend_iparameter_bindings(opts, params);
+ return;
+ }
+ if (maxset) return;
+
+ for (i = opts->allocated; i > params; i--)
+ reset_a_iparameter_binding(opts, i);
+ opts->allocated = params;
+ if (0 == params)
+ {
+ free(opts->parameters);
+ opts->parameters = NULL;
+ }
+}
+
static RETCODE SQL_API
APDSetField(StatementClass *stmt, SQLSMALLINT RecNumber,
SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength)
{
RETCODE ret = SQL_SUCCESS;
IPDFields *ipdopts = SC_get_IPD(stmt);
- APDFields *apdopts = SC_get_APD(stmt);
switch (FieldIdentifier)
{
}
break;
case SQL_DESC_TYPE:
- parameter_bindings_set(apdopts, RecNumber, TRUE);
- apdopts->parameters[RecNumber - 1].SQLType = (Int4) Value;
+ parameter_ibindings_set(ipdopts, RecNumber, TRUE);
+ reset_a_iparameter_binding(ipdopts, RecNumber);
+ ipdopts->parameters[RecNumber - 1].SQLType = (Int4) Value;
break;
case SQL_DESC_DATETIME_INTERVAL_CODE:
- parameter_bindings_set(apdopts, RecNumber, TRUE);
- switch (apdopts->parameters[RecNumber - 1].SQLType)
+ parameter_ibindings_set(ipdopts, RecNumber, TRUE);
+ switch (ipdopts->parameters[RecNumber - 1].SQLType)
{
case SQL_DATETIME:
case SQL_TYPE_DATE:
switch ((Int4) Value)
{
case SQL_CODE_DATE:
- apdopts->parameters[RecNumber - 1].SQLType = SQL_TYPE_DATE;
+ ipdopts->parameters[RecNumber - 1].SQLType = SQL_TYPE_DATE;
break;
case SQL_CODE_TIME:
- apdopts->parameters[RecNumber - 1].SQLType = SQL_TYPE_TIME;
+ ipdopts->parameters[RecNumber - 1].SQLType = SQL_TYPE_TIME;
break;
case SQL_CODE_TIMESTAMP:
- apdopts->parameters[RecNumber - 1].SQLType = SQL_TYPE_TIMESTAMP;
+ ipdopts->parameters[RecNumber - 1].SQLType = SQL_TYPE_TIMESTAMP;
break;
}
break;
}
break;
case SQL_DESC_CONCISE_TYPE:
- parameter_bindings_set(apdopts, RecNumber, TRUE);
- apdopts->parameters[RecNumber - 1].SQLType = (Int4) Value;
+ parameter_ibindings_set(ipdopts, RecNumber, TRUE);
+ ipdopts->parameters[RecNumber - 1].SQLType = (Int4) Value;
break;
case SQL_DESC_COUNT:
- parameter_bindings_set(apdopts, (SQLUINTEGER) Value, FALSE);
+ parameter_ibindings_set(ipdopts, (SQLUINTEGER) Value, FALSE);
break;
case SQL_DESC_PARAMETER_TYPE:
- apdopts->parameters[RecNumber - 1].paramType = (Int2) Value;
+ ipdopts->parameters[RecNumber - 1].paramType = (Int2) Value;
break;
case SQL_DESC_SCALE:
- apdopts->parameters[RecNumber - 1].decimal_digits = (Int2) Value;
+ ipdopts->parameters[RecNumber - 1].decimal_digits = (Int2) Value;
break;
case SQL_DESC_ALLOC_TYPE: /* read-only */
case SQL_DESC_CASE_SENSITIVE: /* read-only */
SQLINTEGER ival = 0, len, rettype = 0;
PTR ptr = NULL;
const IPDFields *ipdopts = SC_get_IPD(stmt);
- const APDFields *apdopts = SC_get_APD(stmt);
switch (FieldIdentifier)
{
ival = SQL_UNNAMED;
break;
case SQL_DESC_TYPE:
- switch (apdopts->parameters[RecNumber - 1].SQLType)
+ switch (ipdopts->parameters[RecNumber - 1].SQLType)
{
case SQL_TYPE_DATE:
case SQL_TYPE_TIME:
ival = SQL_DATETIME;
break;
default:
- ival = apdopts->parameters[RecNumber - 1].SQLType;
+ ival = ipdopts->parameters[RecNumber - 1].SQLType;
}
break;
case SQL_DESC_DATETIME_INTERVAL_CODE:
- switch (apdopts->parameters[RecNumber - 1].SQLType)
+ switch (ipdopts->parameters[RecNumber - 1].SQLType)
{
case SQL_TYPE_DATE:
ival = SQL_CODE_DATE;
}
break;
case SQL_DESC_CONCISE_TYPE:
- ival = apdopts->parameters[RecNumber - 1].SQLType;
+ ival = ipdopts->parameters[RecNumber - 1].SQLType;
break;
case SQL_DESC_COUNT:
- ival = apdopts->allocated;
+ ival = ipdopts->allocated;
break;
case SQL_DESC_PARAMETER_TYPE:
- ival = apdopts->parameters[RecNumber - 1].paramType;
+ ival = ipdopts->parameters[RecNumber - 1].paramType;
break;
case SQL_DESC_PRECISION:
- switch (apdopts->parameters[RecNumber - 1].CType)
+ switch (ipdopts->parameters[RecNumber - 1].SQLType)
{
- case SQL_C_TYPE_DATE:
- case SQL_C_TYPE_TIME:
- case SQL_C_TYPE_TIMESTAMP:
+ case SQL_TYPE_DATE:
+ case SQL_TYPE_TIME:
+ case SQL_TYPE_TIMESTAMP:
case SQL_DATETIME:
- ival = apdopts->parameters[RecNumber - 1].decimal_digits;
+ ival = ipdopts->parameters[RecNumber - 1].decimal_digits;
break;
}
break;
case SQL_DESC_SCALE:
- switch (apdopts->parameters[RecNumber - 1].CType)
+ switch (ipdopts->parameters[RecNumber - 1].SQLType)
{
- case SQL_C_NUMERIC:
- ival = apdopts->parameters[RecNumber - 1].decimal_digits;
+ case SQL_NUMERIC:
+ ival = ipdopts->parameters[RecNumber - 1].decimal_digits;
break;
}
break;
PG_TYPE_MONEY,
PG_TYPE_BOOL,
PG_TYPE_BYTEA,
- PG_TYPE_LO,
+ PG_TYPE_LO_UNDEFINED,
0 };
*/
break;
case SQL_LONGVARBINARY:
- pgType = PG_TYPE_LO;
+ switch (conn->lobj_type)
+ {
+ case PG_TYPE_LO_UNDEFINED:
+ if (ci->bytea_as_longvarbinary)
+ {
+ pgType = PG_TYPE_BYTEA;
+ break;
+ }
+ default:
+ pgType = conn->lobj_type;
+ break;
+ }
break;
case SQL_LONGVARCHAR:
#endif /* UNICODE_SUPPORT */
case PG_TYPE_BYTEA:
+ switch (conn->lobj_type)
+ {
+ case PG_TYPE_LO_UNDEFINED:
+ if (ci->bytea_as_longvarbinary)
+ return SQL_LONGVARBINARY;
+ }
return SQL_VARBINARY;
- case PG_TYPE_LO:
+ case PG_TYPE_LO_UNDEFINED:
return SQL_LONGVARBINARY;
case PG_TYPE_INT2:
case PG_TYPE_BYTEA:
return SQL_C_BINARY;
- case PG_TYPE_LO:
+ case PG_TYPE_LO_UNDEFINED:
return SQL_C_BINARY;
#ifdef UNICODE_SUPPORT
case PG_TYPE_BPCHAR:
}
-char *
+const char *
pgtype_to_name(StatementClass *stmt, Int4 type)
{
ConnectionClass *conn = SC_get_conn(stmt);
case PG_TYPE_BYTEA:
return "bytea";
- case PG_TYPE_LO:
+ case PG_TYPE_LO_UNDEFINED:
return PG_TYPE_LO_NAME;
default:
return true_is_minus1 ? 2 : 1;
}
- case PG_TYPE_LO:
+ case PG_TYPE_LO_UNDEFINED:
return SQL_NO_TOTAL;
default:
Int2 pgtype_to_sqldesctype(StatementClass *stmt, Int4 type);
Int2 pgtype_to_datetime_sub(StatementClass *stmt, Int4 type);
Int2 pgtype_to_ctype(StatementClass *stmt, Int4 type);
-char *pgtype_to_name(StatementClass *stmt, Int4 type);
+const char *pgtype_to_name(StatementClass *stmt, Int4 type);
/* These functions can use static numbers or result sets(col parameter) */
Int4 pgtype_column_size(StatementClass *stmt, Int4 type, int col, int handle_unknown_size_as); /* corresponds to "precision" in ODBC 2.x */
case DLL_PROCESS_DETACH:
DELETE_CONNS_CS;
- DELETE_MYLOG_CS;
DELETE_QLOG_CS;
+ DELETE_MYLOG_CS;
WSACleanup();
return TRUE;
*
* Comments: See "notice.txt" for copyright and license information.
*
- * $Id: psqlodbc.h,v 1.72 2002/10/16 07:39:53 dpage Exp $
+ * $Id: psqlodbc.h,v 1.73 2002/12/16 15:01:34 hinoue Exp $
*
*/
/* Driver stuff */
-#define DRIVERNAME "PostgreSQL ODBC"
+#define DRIVERNAME "PostgreSQL ODBC"
#if (ODBCVER >= 0x0300)
#define DRIVER_ODBC_VER "03.00"
#ifdef UNICODE_SUPPORT
#endif /* UNICODE_SUPPORT */
#else
#define DRIVER_ODBC_VER "02.50"
-#define DBMS_NAME "PostgreSQL"
+#define DBMS_NAME "PostgreSQL"
#endif /* ODBCVER */
#ifdef WIN32
typedef struct SocketClass_ SocketClass;
typedef struct BindInfoClass_ BindInfoClass;
typedef struct ParameterInfoClass_ ParameterInfoClass;
+typedef struct ParameterImplClass_ ParameterImplClass;
typedef struct ColumnInfoClass_ ColumnInfoClass;
typedef struct TupleListClass_ TupleListClass;
typedef struct EnvironmentClass_ EnvironmentClass;
void logs_on_off(int cnopen, int, int);
-#define PG_TYPE_LO (-999) /* hack until permanent
+#define PG_TYPE_LO_UNDEFINED (-999) /* hack until permanent
* type available */
#define PG_TYPE_LO_NAME "lo"
#define OID_ATTNUM (-2) /* the attnum in pg_index
*pcrow = -1;
return SQL_SUCCESS;
+ /* SC_set_errornumber(stmt, STMT_SEQUENCE_ERROR);
+ SC_log_error(func, "Bad return value", stmt);
+ return SQL_ERROR; */
}
rv->curres = NULL;
rv->manual_result = FALSE;
rv->prepare = FALSE;
+ rv->prepared = FALSE;
rv->status = STMT_ALLOCATED;
rv->internal = FALSE;
rv->statement = NULL;
rv->stmt_with_params = NULL;
rv->load_statement = NULL;
+ rv->execute_statement = NULL;
rv->stmt_size_limit = -1;
rv->statement_type = STMT_TYPE_UNKNOWN;
void IPDFields_free(IPDFields * self)
{
+ /* param bindings */
+ IPD_free_params(self, STMT_FREE_PARAMS_ALL);
}
char
QR_Destructor(res);
}
- if (self->statement)
- free(self->statement);
- if (self->stmt_with_params)
- {
- free(self->stmt_with_params);
- self->stmt_with_params = NULL;
- }
- if (self->load_statement)
- free(self->load_statement);
+ SC_initialize_stmts(self, TRUE);
/* Free the parsed table information */
if (self->ti)
SC_free_params(StatementClass *self, char option)
{
APD_free_params(SC_get_APD(self), option);
+ IPD_free_params(SC_get_IPD(self), option);
self->data_at_exec = -1;
self->current_exec_param = -1;
self->put_data = FALSE;
return STMT_TYPE_OTHER;
}
+/*
+ * Initialize stmt_with_params, load_statement and execute_statement
+ * member pointer deallocating corresponding prepared plan.
+ * Also initialize statement member pointer if specified.
+ */
+RETCODE
+SC_initialize_stmts(StatementClass *self, BOOL initializeOriginal)
+{
+ if (initializeOriginal && self->statement)
+ {
+ free(self->statement);
+ self->statement = NULL;
+ }
+ if (self->stmt_with_params)
+ {
+ free(self->stmt_with_params);
+ self->stmt_with_params = NULL;
+ }
+ if (self->load_statement)
+ {
+ free(self->load_statement);
+ self->load_statement = NULL;
+ }
+ if (self->execute_statement)
+ {
+ free(self->execute_statement);
+ self->execute_statement = NULL;
+ }
+ if (self->prepared)
+ {
+ ConnectionClass *conn = SC_get_conn(self);
+ if (CONN_CONNECTED == conn->status)
+ {
+ QResultClass *res;
+ char dealloc_stmt[128];
+
+ sprintf(dealloc_stmt, "DEALLOCATE _PLAN%0x", self);
+ res = CC_send_query(conn, dealloc_stmt, NULL, 0);
+ if (res)
+ QR_Destructor(res);
+ }
+ self->prepared = FALSE;
+ }
+ return 0;
+}
/*
* Called from SQLPrepare if STMT_PREMATURE, or
* SQLParamData/SQLPutData is called.
*/
SC_free_params(self, STMT_FREE_PARAMS_DATA_AT_EXEC_ONLY);
- if (self->stmt_with_params)
- free(self->stmt_with_params);
- self->stmt_with_params = NULL;
- if (self->load_statement)
- free(self->load_statement);
- self->load_statement = NULL;
+ SC_initialize_stmts(self, FALSE);
/*
* reset the current attr setting to the original one.
*/
}
else
{
+ QResultClass *tres;
+
/* see if the query did return any result columns */
- numcols = QR_NumResultCols(res);
+ for (tres = res, numcols = 0; !numcols && tres; tres = tres->next)
+ {
+ numcols = QR_NumResultCols(tres);
+ }
/* now allocate the array to hold the binding info */
if (numcols > 0)
{
#define STMT_INVALID_DESCRIPTOR_IDENTIFIER 31
#define STMT_OPTION_NOT_FOR_THE_DRIVER 32
#define STMT_FETCH_OUT_OF_RANGE 33
+#define STMT_COUNT_FIELD_INCORRECT 34
/* statement types */
enum
char errormsg_created; /* has an informative error msg
* been created? */
char manual_result; /* Is the statement result manually built? */
- char prepare; /* is this statement a prepared statement
- * or direct */
-
+ char prepare; /* is this statement a prepared statement ? */
+ char prepared; /* is this statement already
+ * prepared at the server ? */
char internal; /* Is this statement being called
* internally? */
SWORD error_recsize;
Int4 diag_row_count;
char *load_statement; /* to (re)load updatable individual rows */
+ char *execute_statement; /* to execute the prepared plans */
Int4 from_pos;
Int4 where_pos;
Int4 last_fetch_count_include_ommitted;
#define SC_set_fetchcursor(a) (a->miscinfo |= 2L)
#define SC_no_fetchcursor(a) (a->miscinfo &= ~2L)
#define SC_is_fetchcursor(a) ((a->miscinfo & 2L) != 0)
+#define SC_set_prepare_before_exec(a) (a->miscinfo |= 4L)
+#define SC_no_prepare_before_exec(a) (a->miscinfo &= ~4L)
+#define SC_is_prepare_before_exec(a) ((a->miscinfo & 4L) != 0)
/* For Multi-thread */
-#if defined(WIN_MULTITHREAD_SUPPORT)
+#if defined(WIN_FREETHREAD_SUPPORT)
#define INIT_STMT_CS(x) InitializeCriticalSection(&((x)->cs))
#define ENTER_STMT_CS(x) EnterCriticalSection(&((x)->cs))
#define LEAVE_STMT_CS(x) LeaveCriticalSection(&((x)->cs))
void SC_full_error_copy(StatementClass *self, const StatementClass *from);
char SC_get_error(StatementClass *self, int *number, char **message);
char *SC_create_errormsg(const StatementClass *self);
+RETCODE SC_initialize_stmts(StatementClass *self, BOOL);
RETCODE SC_execute(StatementClass *self);
RETCODE SC_fetch(StatementClass *self);
void SC_free_params(StatementClass *self, char option);
void
-set_tuplefield_string(TupleField *tuple_field, char *string)
+set_tuplefield_string(TupleField *tuple_field, const char *string)
{
tuple_field->len = strlen(string);
tuple_field->value = malloc(strlen(string) + 1);
#define set_nullfield_int4(FLD, VAL) ((VAL) != -1 ? set_tuplefield_int4(FLD, (VAL)) : set_tuplefield_null(FLD))
void set_tuplefield_null(TupleField *tuple_field);
-void set_tuplefield_string(TupleField *tuple_field, char *string);
+void set_tuplefield_string(TupleField *tuple_field, const char *string);
void set_tuplefield_int2(TupleField *tuple_field, Int2 value);
void set_tuplefield_int4(TupleField *tuple_field, Int4 value);