Commit a80771f0 authored by Byron Nikolaidis's avatar Byron Nikolaidis

Update to v.0246

parent fd262dac
...@@ -37,9 +37,12 @@ RETCODE SQL_API SQLBindParameter( ...@@ -37,9 +37,12 @@ RETCODE SQL_API SQLBindParameter(
SDWORD FAR *pcbValue) SDWORD FAR *pcbValue)
{ {
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
char *func="SQLBindParameter";
if( ! stmt) if( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
if(stmt->parameters_allocated < ipar) { if(stmt->parameters_allocated < ipar) {
ParameterInfoClass *old_parameters; ParameterInfoClass *old_parameters;
...@@ -52,6 +55,7 @@ StatementClass *stmt = (StatementClass *) hstmt; ...@@ -52,6 +55,7 @@ StatementClass *stmt = (StatementClass *) hstmt;
if ( ! stmt->parameters) { if ( ! stmt->parameters) {
stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errornumber = STMT_NO_MEMORY_ERROR;
stmt->errormsg = "Could not allocate memory for statement parameters"; stmt->errormsg = "Could not allocate memory for statement parameters";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -133,53 +137,51 @@ RETCODE SQL_API SQLBindCol( ...@@ -133,53 +137,51 @@ RETCODE SQL_API SQLBindCol(
SDWORD FAR *pcbValue) SDWORD FAR *pcbValue)
{ {
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
Int2 numcols; Int2 numcols = 0;
char *func="SQLBindCol";
mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol); mylog("**** SQLBindCol: stmt = %u, icol = %d\n", stmt, icol);
if ( ! stmt) if ( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
if (icol < 1) { if (icol < 1) {
/* currently we do not support bookmarks */ /* currently we do not support bookmarks */
stmt->errormsg = "Bookmarks are not currently supported."; stmt->errormsg = "Bookmarks are not currently supported.";
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
icol--; /* use zero based col numbers */
SC_clear_error(stmt); SC_clear_error(stmt);
if( ! stmt->result) {
stmt->errormsg = "Can't bind columns with a NULL query result structure.";
stmt->errornumber = STMT_SEQUENCE_ERROR;
return SQL_ERROR;
}
if( stmt->status == STMT_EXECUTING) { if( stmt->status == STMT_EXECUTING) {
stmt->errormsg = "Can't bind columns while statement is still executing."; stmt->errormsg = "Can't bind columns while statement is still executing.";
stmt->errornumber = STMT_SEQUENCE_ERROR; stmt->errornumber = STMT_SEQUENCE_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
numcols = QR_NumResultCols(stmt->result); // allocate enough bindings if not already done
// Most likely, execution of a statement would have setup the
mylog("SQLBindCol: numcols = %d\n", numcols); // necessary bindings. But some apps call BindCol before any
// statement is executed.
if (icol >= numcols) { if ( icol > stmt->bindings_allocated)
stmt->errornumber = STMT_COLNUM_ERROR; extend_bindings(stmt, icol);
stmt->errormsg = "Column number too big";
return SQL_ERROR;
}
// check to see if the bindings were allocated
if ( ! stmt->bindings) { if ( ! stmt->bindings) {
stmt->errormsg = "Bindings were not allocated properly."; stmt->errormsg = "Could not allocate memory for bindings.";
stmt->errornumber = STMT_SEQUENCE_ERROR; stmt->errornumber = STMT_NO_MEMORY_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
if ((cbValueMax == 0) || (rgbValue == NULL)) { icol--; /* use zero based col numbers from here out */
if (rgbValue == NULL) {
/* we have to unbind the column */ /* we have to unbind the column */
stmt->bindings[icol].buflen = 0; stmt->bindings[icol].buflen = 0;
stmt->bindings[icol].buffer = NULL; stmt->bindings[icol].buffer = NULL;
...@@ -216,13 +218,17 @@ RETCODE SQL_API SQLDescribeParam( ...@@ -216,13 +218,17 @@ RETCODE SQL_API SQLDescribeParam(
SWORD FAR *pfNullable) SWORD FAR *pfNullable)
{ {
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
char *func = "SQLDescribeParam";
if( ! stmt) if( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
if( (ipar < 1) || (ipar > stmt->parameters_allocated) ) { if( (ipar < 1) || (ipar > stmt->parameters_allocated) ) {
stmt->errormsg = "Invalid parameter number for SQLDescribeParam."; stmt->errormsg = "Invalid parameter number for SQLDescribeParam.";
stmt->errornumber = STMT_BAD_PARAMETER_NUMBER_ERROR; stmt->errornumber = STMT_BAD_PARAMETER_NUMBER_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -254,6 +260,9 @@ RETCODE SQL_API SQLParamOptions( ...@@ -254,6 +260,9 @@ RETCODE SQL_API SQLParamOptions(
UDWORD crow, UDWORD crow,
UDWORD FAR *pirow) UDWORD FAR *pirow)
{ {
char *func = "SQLParamOptions";
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -273,21 +282,26 @@ RETCODE SQL_API SQLNumParams( ...@@ -273,21 +282,26 @@ RETCODE SQL_API SQLNumParams(
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
char in_quote = FALSE; char in_quote = FALSE;
unsigned int i; unsigned int i;
char *func = "SQLNumParams";
if(!stmt) {
if(!stmt) SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
if (pcpar) if (pcpar)
*pcpar = 0; *pcpar = 0;
else else {
SC_log_error(func, "pcpar was null", stmt);
return SQL_ERROR; return SQL_ERROR;
}
if(!stmt->statement) { if(!stmt->statement) {
// no statement has been allocated // no statement has been allocated
stmt->errormsg = "SQLNumParams called with no statement ready."; stmt->errormsg = "SQLNumParams called with no statement ready.";
stmt->errornumber = STMT_SEQUENCE_ERROR; stmt->errornumber = STMT_SEQUENCE_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} else { } else {
...@@ -341,6 +355,14 @@ mylog("in extend_bindings: stmt=%u, bindings_allocated=%d, num_columns=%d\n", st ...@@ -341,6 +355,14 @@ mylog("in extend_bindings: stmt=%u, bindings_allocated=%d, num_columns=%d\n", st
if(stmt->bindings_allocated < num_columns) { if(stmt->bindings_allocated < num_columns) {
new_bindings = create_empty_bindings(num_columns); new_bindings = create_empty_bindings(num_columns);
if ( ! new_bindings) {
if (stmt->bindings) {
free(stmt->bindings);
stmt->bindings = NULL;
}
stmt->bindings_allocated = 0;
return;
}
if(stmt->bindings) { if(stmt->bindings) {
for(i=0; i<stmt->bindings_allocated; i++) for(i=0; i<stmt->bindings_allocated; i++)
...@@ -349,18 +371,17 @@ mylog("in extend_bindings: stmt=%u, bindings_allocated=%d, num_columns=%d\n", st ...@@ -349,18 +371,17 @@ mylog("in extend_bindings: stmt=%u, bindings_allocated=%d, num_columns=%d\n", st
free(stmt->bindings); free(stmt->bindings);
} }
stmt->bindings = new_bindings; // null indicates error stmt->bindings = new_bindings;
stmt->bindings_allocated = num_columns; stmt->bindings_allocated = num_columns;
} else {
/* if we have too many, make sure the extra ones are emptied out */
/* so we don't accidentally try to use them for anything */
for(i = num_columns; i < stmt->bindings_allocated; i++) {
stmt->bindings[i].buflen = 0;
stmt->bindings[i].buffer = NULL;
stmt->bindings[i].used = NULL;
}
} }
// There is no reason to zero out extra bindings if there are
// more than needed. If an app has allocated extra bindings,
// let it worry about it by unbinding those columns.
// SQLBindCol(1..) ... SQLBindCol(10...) # got 10 bindings
// SQLExecDirect(...) # returns 5 cols
// SQLExecDirect(...) # returns 10 cols (now OK)
mylog("exit extend_bindings\n"); mylog("exit extend_bindings\n");
} }
...@@ -35,7 +35,7 @@ RETCODE SQL_API SQLAllocConnect( ...@@ -35,7 +35,7 @@ RETCODE SQL_API SQLAllocConnect(
{ {
EnvironmentClass *env = (EnvironmentClass *)henv; EnvironmentClass *env = (EnvironmentClass *)henv;
ConnectionClass *conn; ConnectionClass *conn;
char *func="SQLAllocConnect";
conn = CC_Constructor(); conn = CC_Constructor();
mylog("**** SQLAllocConnect: henv = %u, conn = %u\n", henv, conn); mylog("**** SQLAllocConnect: henv = %u, conn = %u\n", henv, conn);
...@@ -44,6 +44,7 @@ ConnectionClass *conn; ...@@ -44,6 +44,7 @@ ConnectionClass *conn;
env->errormsg = "Couldn't allocate memory for Connection object."; env->errormsg = "Couldn't allocate memory for Connection object.";
env->errornumber = ENV_ALLOC_ERROR; env->errornumber = ENV_ALLOC_ERROR;
*phdbc = SQL_NULL_HDBC; *phdbc = SQL_NULL_HDBC;
EN_log_error(func, "", env);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -52,6 +53,7 @@ ConnectionClass *conn; ...@@ -52,6 +53,7 @@ ConnectionClass *conn;
env->errornumber = ENV_ALLOC_ERROR; env->errornumber = ENV_ALLOC_ERROR;
CC_Destructor(conn); CC_Destructor(conn);
*phdbc = SQL_NULL_HDBC; *phdbc = SQL_NULL_HDBC;
EN_log_error(func, "", env);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -74,9 +76,12 @@ RETCODE SQL_API SQLConnect( ...@@ -74,9 +76,12 @@ RETCODE SQL_API SQLConnect(
{ {
ConnectionClass *conn = (ConnectionClass *) hdbc; ConnectionClass *conn = (ConnectionClass *) hdbc;
ConnInfo *ci; ConnInfo *ci;
char *func = "SQLConnect";
if ( ! conn) if ( ! conn) {
CC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
ci = &conn->connInfo; ci = &conn->connInfo;
...@@ -96,9 +101,11 @@ ConnInfo *ci; ...@@ -96,9 +101,11 @@ ConnInfo *ci;
qlog("conn = %u, SQLConnect(DSN='%s', UID='%s', PWD='%s')\n", ci->dsn, ci->username, ci->password); qlog("conn = %u, SQLConnect(DSN='%s', UID='%s', PWD='%s')\n", ci->dsn, ci->username, ci->password);
if ( CC_connect(conn, FALSE) <= 0) if ( CC_connect(conn, FALSE) <= 0) {
// Error messages are filled in // Error messages are filled in
CC_log_error(func, "Error on CC_connect", conn);
return SQL_ERROR; return SQL_ERROR;
}
return SQL_SUCCESS; return SQL_SUCCESS;
} }
...@@ -123,17 +130,21 @@ RETCODE SQL_API SQLDisconnect( ...@@ -123,17 +130,21 @@ RETCODE SQL_API SQLDisconnect(
HDBC hdbc) HDBC hdbc)
{ {
ConnectionClass *conn = (ConnectionClass *) hdbc; ConnectionClass *conn = (ConnectionClass *) hdbc;
char *func = "SQLDisconnect";
mylog("**** in SQLDisconnect\n"); mylog("**** in SQLDisconnect\n");
if ( ! conn) if ( ! conn) {
CC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
qlog("conn=%u, SQLDisconnect\n", conn); qlog("conn=%u, SQLDisconnect\n", conn);
if (conn->status == CONN_EXECUTING) { if (conn->status == CONN_EXECUTING) {
conn->errornumber = CONN_IN_USE; conn->errornumber = CONN_IN_USE;
conn->errormsg = "A transaction is currently being executed"; conn->errormsg = "A transaction is currently being executed";
CC_log_error(func, "", conn);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -155,16 +166,20 @@ RETCODE SQL_API SQLFreeConnect( ...@@ -155,16 +166,20 @@ RETCODE SQL_API SQLFreeConnect(
HDBC hdbc) HDBC hdbc)
{ {
ConnectionClass *conn = (ConnectionClass *) hdbc; ConnectionClass *conn = (ConnectionClass *) hdbc;
char *func = "SQLFreeConnect";
mylog("**** in SQLFreeConnect: hdbc=%u\n", hdbc); mylog("**** in SQLFreeConnect: hdbc=%u\n", hdbc);
if ( ! conn) if ( ! conn) {
CC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
/* Remove the connection from the environment */ /* Remove the connection from the environment */
if ( ! EN_remove_connection(conn->henv, conn)) { if ( ! EN_remove_connection(conn->henv, conn)) {
conn->errornumber = CONN_IN_USE; conn->errornumber = CONN_IN_USE;
conn->errormsg = "A transaction is currently being executed"; conn->errormsg = "A transaction is currently being executed";
CC_log_error(func, "", conn);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -577,8 +592,9 @@ char salt[2]; ...@@ -577,8 +592,9 @@ char salt[2];
/******* Send any initial settings *********/ /******* Send any initial settings *********/
/**********************************************/ /**********************************************/
if ( ! CC_send_settings(self)) // The Unix iodbc errors out on this call because it allocates a statement
return 0; // before the connection is established. Therefore, don't check for error here.
CC_send_settings(self);
CC_lookup_lo(self); /* a hack to get the oid of our large object oid type */ CC_lookup_lo(self); /* a hack to get the oid of our large object oid type */
...@@ -1155,6 +1171,27 @@ RETCODE result; ...@@ -1155,6 +1171,27 @@ RETCODE result;
result = SQLFreeStmt(hstmt, SQL_DROP); result = SQLFreeStmt(hstmt, SQL_DROP);
} }
void
CC_log_error(char *func, char *desc, ConnectionClass *self)
{
if (self) {
qlog("CONN ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, self->errormsg);
qlog(" ------------------------------------------------------------\n");
qlog(" henv=%u, conn=%u, status=%u, num_stmts=%d\n", self->henv, self, self->status, self->num_stmts);
qlog(" sock=%u, stmts=%u, lobj_type=%d\n", self->sock, self->stmts, self->lobj_type);
qlog(" ---------------- Socket Info -------------------------------\n");
if (self->sock) {
SocketClass *sock = self->sock;
qlog(" socket=%d, reverse=%d, errornumber=%d, errormsg='%s'\n", sock->socket, sock->reverse, sock->errornumber, sock->errormsg);
qlog(" buffer_in=%u, buffer_out=%u\n", sock->buffer_in, sock->buffer_out);
qlog(" buffer_filled_in=%d, buffer_filled_out=%d, buffer_read_in=%d\n", sock->buffer_filled_in, sock->buffer_filled_out, sock->buffer_read_in);
}
}
else
qlog("INVALID CONNECTION HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
}
/* /*
void void
CC_test(ConnectionClass *self) CC_test(ConnectionClass *self)
...@@ -1165,23 +1202,28 @@ SDWORD pcbValue; ...@@ -1165,23 +1202,28 @@ SDWORD pcbValue;
UDWORD pcrow; UDWORD pcrow;
UWORD rgfRowStatus; UWORD rgfRowStatus;
char buf[255]; char buf[255];
SDWORD buflen;
DATE_STRUCT *ds;
result = SQLAllocStmt( self, &hstmt1); result = SQLAllocStmt( self, &hstmt1);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
return; return;
} }
result = SQLExtendedFetch(hstmt1, SQL_FETCH_ABSOLUTE, -2, &pcrow, &rgfRowStatus); result = SQLExecDirect(hstmt1, "select * from cpar", SQL_NTS);
SQLGetData(hstmt1, 1, SQL_C_CHAR, buf, sizeof(buf), &pcbValue); qlog("exec result = %d\n", result);
qlog("FETCH_ABSOLUTE, -2: result=%d, Col1 = '%s'\n", result, buf);
result = SQLBindCol(hstmt1, 2, SQL_C_DATE, buf, 0, &buflen);
qlog("bind result = %d\n", result);
result = SQLFetch(hstmt1); result = SQLFetch(hstmt1);
while (result != SQL_NO_DATA_FOUND) { while (result != SQL_NO_DATA_FOUND) {
ds = (DATE_STRUCT *) buf;
qlog("fetch on stmt1: result=%d, buflen=%d: year=%d, month=%d, day=%d\n", result, buflen, ds->year, ds->month, ds->day);
result = SQLFetch(hstmt1); result = SQLFetch(hstmt1);
qlog("fetch on stmt1\n");
} }
SQLFreeStmt(hstmt1, SQL_DROP); SQLFreeStmt(hstmt1, SQL_DROP);
} }
*/ */
...@@ -133,6 +133,7 @@ typedef struct { ...@@ -133,6 +133,7 @@ typedef struct {
// char unknown_sizes[SMALL_REGISTRY_LEN]; // char unknown_sizes[SMALL_REGISTRY_LEN];
char fake_oid_index[SMALL_REGISTRY_LEN]; char fake_oid_index[SMALL_REGISTRY_LEN];
char show_oid_column[SMALL_REGISTRY_LEN]; char show_oid_column[SMALL_REGISTRY_LEN];
char row_versioning[SMALL_REGISTRY_LEN];
char show_system_tables[SMALL_REGISTRY_LEN]; char show_system_tables[SMALL_REGISTRY_LEN];
char focus_password; char focus_password;
} ConnInfo; } ConnInfo;
...@@ -188,5 +189,6 @@ char *CC_create_errormsg(ConnectionClass *self); ...@@ -188,5 +189,6 @@ char *CC_create_errormsg(ConnectionClass *self);
int CC_send_function(ConnectionClass *conn, int fnid, void *result_buf, int *actual_result_len, int result_is_int, LO_ARG *argv, int nargs); int CC_send_function(ConnectionClass *conn, int fnid, void *result_buf, int *actual_result_len, int result_is_int, LO_ARG *argv, int nargs);
char CC_send_settings(ConnectionClass *self); char CC_send_settings(ConnectionClass *self);
void CC_lookup_lo(ConnectionClass *conn); void CC_lookup_lo(ConnectionClass *conn);
void CC_log_error(char *func, char *desc, ConnectionClass *self);
#endif #endif
...@@ -94,7 +94,15 @@ struct tm *tim; ...@@ -94,7 +94,15 @@ struct tm *tim;
st.y = tim->tm_year + 1900; st.y = tim->tm_year + 1900;
mylog("copy_and_convert: field_type = %d, fctype = %d, value = '%s', cbValueMax=%d\n", field_type, fCType, value, cbValueMax); mylog("copy_and_convert: field_type = %d, fctype = %d, value = '%s', cbValueMax=%d\n", field_type, fCType, value, cbValueMax);
if(value) {
if ( ! value) {
/* handle a null just by returning SQL_NULL_DATA in pcbValue, */
/* and doing nothing to the buffer. */
if(pcbValue) {
*pcbValue = SQL_NULL_DATA;
}
return COPY_OK;
}
/******************************************************************** /********************************************************************
First convert any specific postgres types into more First convert any specific postgres types into more
...@@ -115,6 +123,7 @@ struct tm *tim; ...@@ -115,6 +123,7 @@ struct tm *tim;
case PG_TYPE_ABSTIME: case PG_TYPE_ABSTIME:
case PG_TYPE_DATETIME: case PG_TYPE_DATETIME:
case PG_TYPE_TIMESTAMP:
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); sscanf(value, "%4d-%2d-%2d %2d:%2d:%2d", &st.y, &st.m, &st.d, &st.hh, &st.mm, &st.ss);
...@@ -185,23 +194,25 @@ struct tm *tim; ...@@ -185,23 +194,25 @@ struct tm *tim;
if(fCType == SQL_C_CHAR) { if(fCType == SQL_C_CHAR) {
/* Special character formatting as required */ /* Special character formatting as required */
/* These really should return error if cbValueMax is not big enough. */
switch(field_type) { switch(field_type) {
case PG_TYPE_DATE: case PG_TYPE_DATE:
len = 11; len = 10;
if (cbValueMax >= len) if (cbValueMax > len)
sprintf((char *)rgbValue, "%.4d-%.2d-%.2d", st.y, st.m, st.d); sprintf((char *)rgbValue, "%.4d-%.2d-%.2d", st.y, st.m, st.d);
break; break;
case PG_TYPE_TIME: case PG_TYPE_TIME:
len = 9; len = 8;
if (cbValueMax >= len) if (cbValueMax > len)
sprintf((char *)rgbValue, "%.2d:%.2d:%.2d", st.hh, st.mm, st.ss); sprintf((char *)rgbValue, "%.2d:%.2d:%.2d", st.hh, st.mm, st.ss);
break; break;
case PG_TYPE_ABSTIME: case PG_TYPE_ABSTIME:
case PG_TYPE_DATETIME: case PG_TYPE_DATETIME:
case PG_TYPE_TIMESTAMP:
len = 19; len = 19;
if (cbValueMax >= len) if (cbValueMax > len)
sprintf((char *) rgbValue, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d", sprintf((char *) rgbValue, "%.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);
break; break;
...@@ -214,6 +225,16 @@ struct tm *tim; ...@@ -214,6 +225,16 @@ struct tm *tim;
} }
break; break;
/* Currently, data is SILENTLY TRUNCATED for BYTEA and character data
types if there is not enough room in cbValueMax because the driver
can't handle multiple calls to SQLGetData for these, yet. Most likely,
the buffer passed in will be big enough to handle the maximum limit of
postgres, anyway.
LongVarBinary types are handled correctly above, observing truncation
and all that stuff since there is essentially no limit on the large
object used to store those.
*/
case PG_TYPE_BYTEA: // convert binary data to hex strings (i.e, 255 = "FF") case PG_TYPE_BYTEA: // convert binary data to hex strings (i.e, 255 = "FF")
len = convert_pgbinary_to_char(value, rgbValue, cbValueMax); len = convert_pgbinary_to_char(value, rgbValue, cbValueMax);
break; break;
...@@ -227,6 +248,7 @@ struct tm *tim; ...@@ -227,6 +248,7 @@ struct tm *tim;
break; break;
} }
} else { } else {
/* for SQL_C_CHAR, its probably ok to leave currency symbols in. But /* for SQL_C_CHAR, its probably ok to leave currency symbols in. But
...@@ -238,7 +260,7 @@ struct tm *tim; ...@@ -238,7 +260,7 @@ struct tm *tim;
switch(fCType) { switch(fCType) {
case SQL_C_DATE: case SQL_C_DATE:
len = 6; len = 6;
if (cbValueMax >= len) { {
DATE_STRUCT *ds = (DATE_STRUCT *) rgbValue; DATE_STRUCT *ds = (DATE_STRUCT *) rgbValue;
ds->year = st.y; ds->year = st.y;
ds->month = st.m; ds->month = st.m;
...@@ -248,7 +270,7 @@ struct tm *tim; ...@@ -248,7 +270,7 @@ struct tm *tim;
case SQL_C_TIME: case SQL_C_TIME:
len = 6; len = 6;
if (cbValueMax >= len) { {
TIME_STRUCT *ts = (TIME_STRUCT *) rgbValue; TIME_STRUCT *ts = (TIME_STRUCT *) rgbValue;
ts->hour = st.hh; ts->hour = st.hh;
ts->minute = st.mm; ts->minute = st.mm;
...@@ -258,7 +280,7 @@ struct tm *tim; ...@@ -258,7 +280,7 @@ struct tm *tim;
case SQL_C_TIMESTAMP: case SQL_C_TIMESTAMP:
len = 16; len = 16;
if (cbValueMax >= len) { {
TIMESTAMP_STRUCT *ts = (TIMESTAMP_STRUCT *) rgbValue; TIMESTAMP_STRUCT *ts = (TIMESTAMP_STRUCT *) rgbValue;
ts->year = st.y; ts->year = st.y;
ts->month = st.m; ts->month = st.m;
...@@ -272,60 +294,50 @@ struct tm *tim; ...@@ -272,60 +294,50 @@ struct tm *tim;
case SQL_C_BIT: case SQL_C_BIT:
len = 1; len = 1;
if (cbValueMax >= len || field_type == PG_TYPE_BOOL) {
*((UCHAR *)rgbValue) = atoi(value); *((UCHAR *)rgbValue) = atoi(value);
mylog("SQL_C_BIT: val = %d, cb = %d, rgb=%d\n", atoi(value), cbValueMax, *((UCHAR *)rgbValue)); mylog("SQL_C_BIT: val = %d, cb = %d, rgb=%d\n", atoi(value), cbValueMax, *((UCHAR *)rgbValue));
}
break; break;
case SQL_C_STINYINT: case SQL_C_STINYINT:
case SQL_C_TINYINT: case SQL_C_TINYINT:
len = 1; len = 1;
if (cbValueMax >= len)
*((SCHAR *) rgbValue) = atoi(value); *((SCHAR *) rgbValue) = atoi(value);
break; break;
case SQL_C_UTINYINT: case SQL_C_UTINYINT:
len = 1; len = 1;
if (cbValueMax >= len)
*((UCHAR *) rgbValue) = atoi(value); *((UCHAR *) rgbValue) = atoi(value);
break; break;
case SQL_C_FLOAT: case SQL_C_FLOAT:
len = 4; len = 4;
if(cbValueMax >= len)
*((SFLOAT *)rgbValue) = (float) atof(value); *((SFLOAT *)rgbValue) = (float) atof(value);
break; break;
case SQL_C_DOUBLE: case SQL_C_DOUBLE:
len = 8; len = 8;
if(cbValueMax >= len)
*((SDOUBLE *)rgbValue) = atof(value); *((SDOUBLE *)rgbValue) = atof(value);
break; break;
case SQL_C_SSHORT: case SQL_C_SSHORT:
case SQL_C_SHORT: case SQL_C_SHORT:
len = 2; len = 2;
if(cbValueMax >= len)
*((SWORD *)rgbValue) = atoi(value); *((SWORD *)rgbValue) = atoi(value);
break; break;
case SQL_C_USHORT: case SQL_C_USHORT:
len = 2; len = 2;
if(cbValueMax >= len)
*((UWORD *)rgbValue) = atoi(value); *((UWORD *)rgbValue) = atoi(value);
break; break;
case SQL_C_SLONG: case SQL_C_SLONG:
case SQL_C_LONG: case SQL_C_LONG:
len = 4; len = 4;
if(cbValueMax >= len)
*((SDWORD *)rgbValue) = atol(value); *((SDWORD *)rgbValue) = atol(value);
break; break;
case SQL_C_ULONG: case SQL_C_ULONG:
len = 4; len = 4;
if(cbValueMax >= len)
*((UDWORD *)rgbValue) = atol(value); *((UDWORD *)rgbValue) = atol(value);
break; break;
...@@ -341,42 +353,13 @@ struct tm *tim; ...@@ -341,42 +353,13 @@ struct tm *tim;
return COPY_UNSUPPORTED_TYPE; return COPY_UNSUPPORTED_TYPE;
} }
} }
} else {
/* handle a null just by returning SQL_NULL_DATA in pcbValue, */
/* and doing nothing to the buffer. */
if(pcbValue) {
*pcbValue = SQL_NULL_DATA;
}
}
// store the length of what was copied, if there's a place for it // store the length of what was copied, if there's a place for it
// unless it was a NULL (in which case it was already set above) if(pcbValue)
if(pcbValue && value)
*pcbValue = len; *pcbValue = len;
if(len > cbValueMax) {
mylog("!!! COPY_RESULT_TRUNCATED !!!\n");
// Don't return truncated because an application
// (like Access) will try to call GetData again
// to retrieve the rest of the data. Since we
// are not currently ready for this, and the result
// is an endless loop, we better just silently
// truncate the data.
// return COPY_RESULT_TRUNCATED;
// LongVarBinary types do handle truncated multiple get calls
// through convert_lo().
if (pcbValue)
*pcbValue = cbValueMax -1;
return COPY_OK; return COPY_OK;
} else {
return COPY_OK;
}
} }
/* This function inserts parameters into an SQL statements. /* This function inserts parameters into an SQL statements.
...@@ -386,6 +369,7 @@ struct tm *tim; ...@@ -386,6 +369,7 @@ struct tm *tim;
int int
copy_statement_with_parameters(StatementClass *stmt) copy_statement_with_parameters(StatementClass *stmt)
{ {
char *func="copy_statement_with_parameters";
unsigned int opos, npos; unsigned int opos, npos;
char param_string[128], tmp[256], cbuf[TEXT_FIELD_SIZE+5]; char param_string[128], tmp[256], cbuf[TEXT_FIELD_SIZE+5];
int param_number; int param_number;
...@@ -400,8 +384,10 @@ char *buffer, *buf; ...@@ -400,8 +384,10 @@ char *buffer, *buf;
char in_quote = FALSE; char in_quote = FALSE;
if ( ! old_statement) if ( ! old_statement) {
SC_log_error(func, "No statement string", stmt);
return SQL_ERROR; return SQL_ERROR;
}
memset(&st, 0, sizeof(SIMPLE_TIME)); memset(&st, 0, sizeof(SIMPLE_TIME));
...@@ -624,6 +610,7 @@ char in_quote = FALSE; ...@@ -624,6 +610,7 @@ char in_quote = FALSE;
stmt->errormsg = "Unrecognized C_parameter type in copy_statement_with_parameters"; stmt->errormsg = "Unrecognized C_parameter type in copy_statement_with_parameters";
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
new_statement[npos] = '\0'; // just in case new_statement[npos] = '\0'; // just in case
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
......
...@@ -226,6 +226,7 @@ char buf[128]; ...@@ -226,6 +226,7 @@ char buf[128];
CheckDlgButton(hdlg, DS_SHOWOIDCOLUMN, atoi(ci->show_oid_column)); CheckDlgButton(hdlg, DS_SHOWOIDCOLUMN, atoi(ci->show_oid_column));
CheckDlgButton(hdlg, DS_FAKEOIDINDEX, atoi(ci->fake_oid_index)); CheckDlgButton(hdlg, DS_FAKEOIDINDEX, atoi(ci->fake_oid_index));
CheckDlgButton(hdlg, DS_ROWVERSIONING, atoi(ci->row_versioning));
CheckDlgButton(hdlg, DS_SHOWSYSTEMTABLES, atoi(ci->show_system_tables)); CheckDlgButton(hdlg, DS_SHOWSYSTEMTABLES, atoi(ci->show_system_tables));
EnableWindow(GetDlgItem(hdlg, DS_FAKEOIDINDEX), atoi(ci->show_oid_column)); EnableWindow(GetDlgItem(hdlg, DS_FAKEOIDINDEX), atoi(ci->show_oid_column));
...@@ -273,6 +274,8 @@ char buf[128]; ...@@ -273,6 +274,8 @@ char buf[128];
sprintf(ci->show_system_tables, "%d", IsDlgButtonChecked(hdlg, DS_SHOWSYSTEMTABLES)); sprintf(ci->show_system_tables, "%d", IsDlgButtonChecked(hdlg, DS_SHOWSYSTEMTABLES));
sprintf(ci->row_versioning, "%d", IsDlgButtonChecked(hdlg, DS_ROWVERSIONING));
/* OID Options*/ /* OID Options*/
sprintf(ci->fake_oid_index, "%d", IsDlgButtonChecked(hdlg, DS_FAKEOIDINDEX)); sprintf(ci->fake_oid_index, "%d", IsDlgButtonChecked(hdlg, DS_FAKEOIDINDEX));
sprintf(ci->show_oid_column, "%d", IsDlgButtonChecked(hdlg, DS_SHOWOIDCOLUMN)); sprintf(ci->show_oid_column, "%d", IsDlgButtonChecked(hdlg, DS_SHOWOIDCOLUMN));
...@@ -297,7 +300,7 @@ makeConnectString(char *connect_string, ConnInfo *ci) ...@@ -297,7 +300,7 @@ makeConnectString(char *connect_string, ConnInfo *ci)
{ {
char got_dsn = (ci->dsn[0] != '\0'); char got_dsn = (ci->dsn[0] != '\0');
sprintf(connect_string, "%s=%s;DATABASE=%s;SERVER=%s;PORT=%s;UID=%s;READONLY=%s;PWD=%s;PROTOCOL=%s;FAKEOIDINDEX=%s;SHOWOIDCOLUMN=%s;SHOWSYSTEMTABLES=%s;CONNSETTINGS=%s", sprintf(connect_string, "%s=%s;DATABASE=%s;SERVER=%s;PORT=%s;UID=%s;READONLY=%s;PWD=%s;PROTOCOL=%s;FAKEOIDINDEX=%s;SHOWOIDCOLUMN=%s;ROWVERSIONING=%s;SHOWSYSTEMTABLES=%s;CONNSETTINGS=%s",
got_dsn ? "DSN" : "DRIVER", got_dsn ? "DSN" : "DRIVER",
got_dsn ? ci->dsn : ci->driver, got_dsn ? ci->dsn : ci->driver,
ci->database, ci->database,
...@@ -310,6 +313,7 @@ char got_dsn = (ci->dsn[0] != '\0'); ...@@ -310,6 +313,7 @@ char got_dsn = (ci->dsn[0] != '\0');
// ci->unknown_sizes, -- currently only needed in Driver options. // ci->unknown_sizes, -- currently only needed in Driver options.
ci->fake_oid_index, ci->fake_oid_index,
ci->show_oid_column, ci->show_oid_column,
ci->row_versioning,
ci->show_system_tables, ci->show_system_tables,
ci->conn_settings); ci->conn_settings);
} }
...@@ -355,6 +359,9 @@ copyAttributes(ConnInfo *ci, char *attribute, char *value) ...@@ -355,6 +359,9 @@ copyAttributes(ConnInfo *ci, char *attribute, char *value)
else if (stricmp(attribute, INI_FAKEOIDINDEX) == 0) else if (stricmp(attribute, INI_FAKEOIDINDEX) == 0)
strcpy(ci->fake_oid_index, value); strcpy(ci->fake_oid_index, value);
else if (stricmp(attribute, INI_ROWVERSIONING) == 0)
strcpy(ci->row_versioning, value);
else if (stricmp(attribute, INI_SHOWSYSTEMTABLES) == 0) else if (stricmp(attribute, INI_SHOWSYSTEMTABLES) == 0)
strcpy(ci->show_system_tables, value); strcpy(ci->show_system_tables, value);
...@@ -398,6 +405,8 @@ getDSNdefaults(ConnInfo *ci) ...@@ -398,6 +405,8 @@ getDSNdefaults(ConnInfo *ci)
if (ci->show_system_tables[0] == '\0') if (ci->show_system_tables[0] == '\0')
sprintf(ci->show_system_tables, "%d", DEFAULT_SHOWSYSTEMTABLES); sprintf(ci->show_system_tables, "%d", DEFAULT_SHOWSYSTEMTABLES);
if (ci->row_versioning[0] == '\0')
sprintf(ci->row_versioning, "%d", DEFAULT_ROWVERSIONING);
} }
...@@ -448,6 +457,9 @@ char *DSN = ci->dsn; ...@@ -448,6 +457,9 @@ char *DSN = ci->dsn;
if ( ci->fake_oid_index[0] == '\0' || overwrite) if ( ci->fake_oid_index[0] == '\0' || overwrite)
SQLGetPrivateProfileString(DSN, INI_FAKEOIDINDEX, "", ci->fake_oid_index, sizeof(ci->fake_oid_index), ODBC_INI); SQLGetPrivateProfileString(DSN, INI_FAKEOIDINDEX, "", ci->fake_oid_index, sizeof(ci->fake_oid_index), ODBC_INI);
if ( ci->row_versioning[0] == '\0' || overwrite)
SQLGetPrivateProfileString(DSN, INI_ROWVERSIONING, "", ci->row_versioning, sizeof(ci->row_versioning), ODBC_INI);
if ( ci->show_system_tables[0] == '\0' || overwrite) if ( ci->show_system_tables[0] == '\0' || overwrite)
SQLGetPrivateProfileString(DSN, INI_SHOWSYSTEMTABLES, "", ci->show_system_tables, sizeof(ci->show_system_tables), ODBC_INI); SQLGetPrivateProfileString(DSN, INI_SHOWSYSTEMTABLES, "", ci->show_system_tables, sizeof(ci->show_system_tables), ODBC_INI);
...@@ -533,6 +545,11 @@ char *DSN = ci->dsn; ...@@ -533,6 +545,11 @@ char *DSN = ci->dsn;
ci->fake_oid_index, ci->fake_oid_index,
ODBC_INI); ODBC_INI);
SQLWritePrivateProfileString(DSN,
INI_ROWVERSIONING,
ci->row_versioning,
ODBC_INI);
SQLWritePrivateProfileString(DSN, SQLWritePrivateProfileString(DSN,
INI_SHOWSYSTEMTABLES, INI_SHOWSYSTEMTABLES,
ci->show_system_tables, ci->show_system_tables,
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#define INI_FAKEOIDINDEX "FakeOidIndex" #define INI_FAKEOIDINDEX "FakeOidIndex"
#define INI_SHOWOIDCOLUMN "ShowOidColumn" #define INI_SHOWOIDCOLUMN "ShowOidColumn"
#define INI_ROWVERSIONING "RowVersioning"
#define INI_SHOWSYSTEMTABLES "ShowSystemTables" #define INI_SHOWSYSTEMTABLES "ShowSystemTables"
#define INI_LIE "Lie" #define INI_LIE "Lie"
#define INI_EXTRASYSTABLEPREFIXES "ExtraSysTablePrefixes" #define INI_EXTRASYSTABLEPREFIXES "ExtraSysTablePrefixes"
...@@ -74,6 +75,7 @@ ...@@ -74,6 +75,7 @@
#define DEFAULT_FAKEOIDINDEX 0 #define DEFAULT_FAKEOIDINDEX 0
#define DEFAULT_SHOWOIDCOLUMN 0 #define DEFAULT_SHOWOIDCOLUMN 0
#define DEFAULT_ROWVERSIONING 0
#define DEFAULT_SHOWSYSTEMTABLES 0 // dont show system tables #define DEFAULT_SHOWSYSTEMTABLES 0 // dont show system tables
#define DEFAULT_LIE 0 #define DEFAULT_LIE 0
......
...@@ -47,6 +47,7 @@ RETCODE SQL_API SQLDriverConnect( ...@@ -47,6 +47,7 @@ RETCODE SQL_API SQLDriverConnect(
SWORD FAR *pcbConnStrOut, SWORD FAR *pcbConnStrOut,
UWORD fDriverCompletion) UWORD fDriverCompletion)
{ {
char *func = "SQLDriverConnect";
ConnectionClass *conn = (ConnectionClass *) hdbc; ConnectionClass *conn = (ConnectionClass *) hdbc;
ConnInfo *ci; ConnInfo *ci;
RETCODE dialog_result; RETCODE dialog_result;
...@@ -56,8 +57,10 @@ char password_required = FALSE; ...@@ -56,8 +57,10 @@ char password_required = FALSE;
mylog("**** SQLDriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, szConnStrIn); mylog("**** SQLDriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, szConnStrIn);
if ( ! conn) if ( ! conn) {
CC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
qlog("conn=%u, SQLDriverConnect( in)='%s'\n", conn, szConnStrIn); qlog("conn=%u, SQLDriverConnect( in)='%s'\n", conn, szConnStrIn);
...@@ -135,8 +138,10 @@ dialog: ...@@ -135,8 +138,10 @@ dialog:
// do the actual connect // do the actual connect
retval = CC_connect(conn, password_required); retval = CC_connect(conn, password_required);
if (retval < 0) { /* need a password */ if (retval < 0) { /* need a password */
if (fDriverCompletion == SQL_DRIVER_NOPROMPT) if (fDriverCompletion == SQL_DRIVER_NOPROMPT) {
CC_log_error(func, "Need password but Driver_NoPrompt", conn);
return SQL_ERROR; /* need a password but not allowed to prompt so error */ return SQL_ERROR; /* need a password but not allowed to prompt so error */
}
else { else {
password_required = TRUE; password_required = TRUE;
goto dialog; goto dialog;
...@@ -144,6 +149,7 @@ dialog: ...@@ -144,6 +149,7 @@ dialog:
} }
else if (retval == 0) { else if (retval == 0) {
// error msg filled in above // error msg filled in above
CC_log_error(func, "Error from CC_Connect", conn);
return SQL_ERROR; return SQL_ERROR;
} }
......
...@@ -25,11 +25,14 @@ ConnectionClass *conns[MAX_CONNECTIONS]; ...@@ -25,11 +25,14 @@ ConnectionClass *conns[MAX_CONNECTIONS];
RETCODE SQL_API SQLAllocEnv(HENV FAR *phenv) RETCODE SQL_API SQLAllocEnv(HENV FAR *phenv)
{ {
char *func = "SQLAllocEnv";
mylog("**** in SQLAllocEnv ** \n"); mylog("**** in SQLAllocEnv ** \n");
*phenv = (HENV) EN_Constructor(); *phenv = (HENV) EN_Constructor();
if ( ! *phenv) { if ( ! *phenv) {
*phenv = SQL_NULL_HENV; *phenv = SQL_NULL_HENV;
EN_log_error(func, "Error allocating environment", NULL);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -39,6 +42,7 @@ mylog("**** in SQLAllocEnv ** \n"); ...@@ -39,6 +42,7 @@ mylog("**** in SQLAllocEnv ** \n");
RETCODE SQL_API SQLFreeEnv(HENV henv) RETCODE SQL_API SQLFreeEnv(HENV henv)
{ {
char *func = "SQLFreeEnv";
EnvironmentClass *env = (EnvironmentClass *) henv; EnvironmentClass *env = (EnvironmentClass *) henv;
mylog("**** in SQLFreeEnv: env = %u ** \n", env); mylog("**** in SQLFreeEnv: env = %u ** \n", env);
...@@ -49,6 +53,7 @@ mylog("**** in SQLFreeEnv: env = %u ** \n", env); ...@@ -49,6 +53,7 @@ mylog("**** in SQLFreeEnv: env = %u ** \n", env);
} }
mylog(" error\n"); mylog(" error\n");
EN_log_error(func, "Error freeing environment", env);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -73,9 +78,6 @@ int status; ...@@ -73,9 +78,6 @@ int status;
// CC: return an error of a hstmt // CC: return an error of a hstmt
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
if (NULL == stmt)
return SQL_INVALID_HANDLE;
if (SC_get_error(stmt, &status, &msg)) { if (SC_get_error(stmt, &status, &msg)) {
mylog("SC_get_error: status = %d, msg = #%s#\n", status, msg); mylog("SC_get_error: status = %d, msg = #%s#\n", status, msg);
if (NULL == msg) { if (NULL == msg) {
...@@ -424,3 +426,13 @@ int i; ...@@ -424,3 +426,13 @@ int i;
return FALSE; return FALSE;
} }
void
EN_log_error(char *func, char *desc, EnvironmentClass *self)
{
if (self) {
qlog("ENVIRON ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, self->errormsg);
}
else
qlog("INVALID ENVIRON HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
}
...@@ -29,5 +29,6 @@ char EN_Destructor(EnvironmentClass *self); ...@@ -29,5 +29,6 @@ char EN_Destructor(EnvironmentClass *self);
char EN_get_error(EnvironmentClass *self, int *number, char **message); char EN_get_error(EnvironmentClass *self, int *number, char **message);
char EN_add_connection(EnvironmentClass *self, ConnectionClass *conn); char EN_add_connection(EnvironmentClass *self, ConnectionClass *conn);
char EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn); char EN_remove_connection(EnvironmentClass *self, ConnectionClass *conn);
void EN_log_error(char *func, char *desc, EnvironmentClass *self);
#endif #endif
...@@ -32,10 +32,13 @@ RETCODE SQL_API SQLPrepare(HSTMT hstmt, ...@@ -32,10 +32,13 @@ RETCODE SQL_API SQLPrepare(HSTMT hstmt,
UCHAR FAR *szSqlStr, UCHAR FAR *szSqlStr,
SDWORD cbSqlStr) SDWORD cbSqlStr)
{ {
char *func = "SQLPrepare";
StatementClass *self = (StatementClass *) hstmt; StatementClass *self = (StatementClass *) hstmt;
if ( ! self) if ( ! self) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
/* According to the ODBC specs it is valid to call SQLPrepare mulitple times. /* According to the ODBC specs it is valid to call SQLPrepare mulitple times.
In that case, the bound SQL statement is replaced by the new one In that case, the bound SQL statement is replaced by the new one
...@@ -66,12 +69,14 @@ StatementClass *self = (StatementClass *) hstmt; ...@@ -66,12 +69,14 @@ StatementClass *self = (StatementClass *) hstmt;
self->errornumber = STMT_SEQUENCE_ERROR; self->errornumber = STMT_SEQUENCE_ERROR;
self->errormsg = "SQLPrepare(): The handle does not point to a statement that is ready to be executed"; self->errormsg = "SQLPrepare(): The handle does not point to a statement that is ready to be executed";
SC_log_error(func, "", self);
return SQL_ERROR; return SQL_ERROR;
default: default:
self->errornumber = STMT_INTERNAL_ERROR; self->errornumber = STMT_INTERNAL_ERROR;
self->errormsg = "An Internal Error has occured -- Unknown statement status."; self->errormsg = "An Internal Error has occured -- Unknown statement status.";
SC_log_error(func, "", self);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -82,6 +87,7 @@ StatementClass *self = (StatementClass *) hstmt; ...@@ -82,6 +87,7 @@ StatementClass *self = (StatementClass *) hstmt;
if ( ! self->statement) { if ( ! self->statement) {
self->errornumber = STMT_NO_MEMORY_ERROR; self->errornumber = STMT_NO_MEMORY_ERROR;
self->errormsg = "No memory available to store statement"; self->errormsg = "No memory available to store statement";
SC_log_error(func, "", self);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -92,6 +98,7 @@ StatementClass *self = (StatementClass *) hstmt; ...@@ -92,6 +98,7 @@ StatementClass *self = (StatementClass *) hstmt;
if ( CC_is_readonly(self->hdbc) && STMT_UPDATE(self)) { if ( CC_is_readonly(self->hdbc) && STMT_UPDATE(self)) {
self->errornumber = STMT_EXEC_ERROR; self->errornumber = STMT_EXEC_ERROR;
self->errormsg = "Connection is readonly, only select statements are allowed."; self->errormsg = "Connection is readonly, only select statements are allowed.";
SC_log_error(func, "", self);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -110,9 +117,12 @@ RETCODE SQL_API SQLExecDirect( ...@@ -110,9 +117,12 @@ RETCODE SQL_API SQLExecDirect(
SDWORD cbSqlStr) SDWORD cbSqlStr)
{ {
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
char *func = "SQLExecDirect";
if ( ! stmt) if ( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
if (stmt->statement) if (stmt->statement)
free(stmt->statement); free(stmt->statement);
...@@ -123,6 +133,7 @@ StatementClass *stmt = (StatementClass *) hstmt; ...@@ -123,6 +133,7 @@ StatementClass *stmt = (StatementClass *) hstmt;
if ( ! stmt->statement) { if ( ! stmt->statement) {
stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errornumber = STMT_NO_MEMORY_ERROR;
stmt->errormsg = "No memory available to store statement"; stmt->errormsg = "No memory available to store statement";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -135,6 +146,7 @@ StatementClass *stmt = (StatementClass *) hstmt; ...@@ -135,6 +146,7 @@ StatementClass *stmt = (StatementClass *) hstmt;
if ( CC_is_readonly(stmt->hdbc) && STMT_UPDATE(stmt)) { if ( CC_is_readonly(stmt->hdbc) && STMT_UPDATE(stmt)) {
stmt->errornumber = STMT_EXEC_ERROR; stmt->errornumber = STMT_EXEC_ERROR;
stmt->errormsg = "Connection is readonly, only select statements are allowed."; stmt->errormsg = "Connection is readonly, only select statements are allowed.";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -147,13 +159,16 @@ StatementClass *stmt = (StatementClass *) hstmt; ...@@ -147,13 +159,16 @@ StatementClass *stmt = (StatementClass *) hstmt;
RETCODE SQL_API SQLExecute( RETCODE SQL_API SQLExecute(
HSTMT hstmt) HSTMT hstmt)
{ {
char *func="SQLExecute";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
ConnectionClass *conn; ConnectionClass *conn;
int i, retval; int i, retval;
if ( ! stmt) if ( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
/* If the statement is premature, it means we already executed /* If the statement is premature, it means we already executed
it from an SQLPrepare/SQLDescribeCol type of scenario. So it from an SQLPrepare/SQLDescribeCol type of scenario. So
...@@ -161,7 +176,12 @@ int i, retval; ...@@ -161,7 +176,12 @@ int i, retval;
*/ */
if ( stmt->prepare && stmt->status == STMT_PREMATURE) { if ( stmt->prepare && stmt->status == STMT_PREMATURE) {
stmt->status = STMT_FINISHED; stmt->status = STMT_FINISHED;
return stmt->errormsg == NULL ? SQL_SUCCESS : SQL_ERROR; if (stmt->errormsg == NULL)
return SQL_SUCCESS;
else {
SC_log_error(func, "", stmt);
return SQL_ERROR;
}
} }
SC_clear_error(stmt); SC_clear_error(stmt);
...@@ -170,12 +190,14 @@ int i, retval; ...@@ -170,12 +190,14 @@ int i, retval;
if (conn->status == CONN_EXECUTING) { if (conn->status == CONN_EXECUTING) {
stmt->errormsg = "Connection is already in use."; stmt->errormsg = "Connection is already in use.";
stmt->errornumber = STMT_SEQUENCE_ERROR; stmt->errornumber = STMT_SEQUENCE_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
if ( ! stmt->statement) { if ( ! stmt->statement) {
stmt->errornumber = STMT_NO_STMTSTRING; stmt->errornumber = STMT_NO_STMTSTRING;
stmt->errormsg = "This handle does not have a SQL statement stored in it"; stmt->errormsg = "This handle does not have a SQL statement stored in it";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -193,6 +215,7 @@ int i, retval; ...@@ -193,6 +215,7 @@ int i, retval;
stmt->errornumber = STMT_STATUS_ERROR; stmt->errornumber = STMT_STATUS_ERROR;
stmt->errormsg = "The handle does not point to a statement that is ready to be executed"; stmt->errormsg = "The handle does not point to a statement that is ready to be executed";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -240,6 +263,7 @@ RETCODE SQL_API SQLTransact( ...@@ -240,6 +263,7 @@ RETCODE SQL_API SQLTransact(
HDBC hdbc, HDBC hdbc,
UWORD fType) UWORD fType)
{ {
char *func = "SQLTransact";
extern ConnectionClass *conns[]; extern ConnectionClass *conns[];
ConnectionClass *conn; ConnectionClass *conn;
QResultClass *res; QResultClass *res;
...@@ -248,8 +272,10 @@ int lf; ...@@ -248,8 +272,10 @@ int lf;
mylog("**** SQLTransact: hdbc=%u, henv=%u\n", hdbc, henv); mylog("**** SQLTransact: hdbc=%u, henv=%u\n", hdbc, henv);
if (hdbc == SQL_NULL_HDBC && henv == SQL_NULL_HENV) if (hdbc == SQL_NULL_HDBC && henv == SQL_NULL_HENV) {
CC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
/* If hdbc is null and henv is valid, /* If hdbc is null and henv is valid,
it means transact all connections on that henv. it means transact all connections on that henv.
...@@ -277,6 +303,7 @@ mylog("**** SQLTransact: hdbc=%u, henv=%u\n", hdbc, henv); ...@@ -277,6 +303,7 @@ mylog("**** SQLTransact: hdbc=%u, henv=%u\n", hdbc, henv);
} else { } else {
conn->errornumber = CONN_INVALID_ARGUMENT_NO; conn->errornumber = CONN_INVALID_ARGUMENT_NO;
conn->errormsg ="SQLTransact can only be called with SQL_COMMIT or SQL_ROLLBACK as parameter"; conn->errormsg ="SQLTransact can only be called with SQL_COMMIT or SQL_ROLLBACK as parameter";
CC_log_error(func, "", conn);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -288,16 +315,20 @@ mylog("**** SQLTransact: hdbc=%u, henv=%u\n", hdbc, henv); ...@@ -288,16 +315,20 @@ mylog("**** SQLTransact: hdbc=%u, henv=%u\n", hdbc, henv);
res = CC_send_query(conn, stmt_string, NULL, NULL); res = CC_send_query(conn, stmt_string, NULL, NULL);
CC_set_no_trans(conn); CC_set_no_trans(conn);
if ( ! res) if ( ! res) {
// error msg will be in the connection // error msg will be in the connection
CC_log_error(func, "", conn);
return SQL_ERROR; return SQL_ERROR;
}
ok = QR_command_successful(res); ok = QR_command_successful(res);
QR_Destructor(res); QR_Destructor(res);
if (!ok) if (!ok) {
CC_log_error(func, "", conn);
return SQL_ERROR; return SQL_ERROR;
} }
}
return SQL_SUCCESS; return SQL_SUCCESS;
} }
...@@ -307,11 +338,14 @@ mylog("**** SQLTransact: hdbc=%u, henv=%u\n", hdbc, henv); ...@@ -307,11 +338,14 @@ mylog("**** SQLTransact: hdbc=%u, henv=%u\n", hdbc, henv);
RETCODE SQL_API SQLCancel( RETCODE SQL_API SQLCancel(
HSTMT hstmt) // Statement to cancel. HSTMT hstmt) // Statement to cancel.
{ {
char *func="SQLCancel";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
// Check if this can handle canceling in the middle of a SQLPutData? // Check if this can handle canceling in the middle of a SQLPutData?
if ( ! stmt) if ( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
// Not in the middle of SQLParamData/SQLPutData so cancel like a close. // Not in the middle of SQLParamData/SQLPutData so cancel like a close.
if (stmt->data_at_exec < 0) if (stmt->data_at_exec < 0)
...@@ -354,11 +388,14 @@ RETCODE SQL_API SQLParamData( ...@@ -354,11 +388,14 @@ RETCODE SQL_API SQLParamData(
HSTMT hstmt, HSTMT hstmt,
PTR FAR *prgbValue) PTR FAR *prgbValue)
{ {
char *func = "SQLParamData";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
int i, retval; int i, retval;
if ( ! stmt) if ( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
mylog("SQLParamData, enter: data_at_exec=%d, params_alloc=%d\n", mylog("SQLParamData, enter: data_at_exec=%d, params_alloc=%d\n",
stmt->data_at_exec, stmt->parameters_allocated); stmt->data_at_exec, stmt->parameters_allocated);
...@@ -366,12 +403,14 @@ int i, retval; ...@@ -366,12 +403,14 @@ int i, retval;
if (stmt->data_at_exec < 0) { if (stmt->data_at_exec < 0) {
stmt->errornumber = STMT_SEQUENCE_ERROR; stmt->errornumber = STMT_SEQUENCE_ERROR;
stmt->errormsg = "No execution-time parameters for this statement"; stmt->errormsg = "No execution-time parameters for this statement";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
if (stmt->data_at_exec > stmt->parameters_allocated) { if (stmt->data_at_exec > stmt->parameters_allocated) {
stmt->errornumber = STMT_SEQUENCE_ERROR; stmt->errornumber = STMT_SEQUENCE_ERROR;
stmt->errormsg = "Too many execution-time parameters were present"; stmt->errormsg = "Too many execution-time parameters were present";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -422,19 +461,23 @@ RETCODE SQL_API SQLPutData( ...@@ -422,19 +461,23 @@ RETCODE SQL_API SQLPutData(
PTR rgbValue, PTR rgbValue,
SDWORD cbValue) SDWORD cbValue)
{ {
char *func = "SQLPutData";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
int old_pos, retval; int old_pos, retval;
ParameterInfoClass *current_param; ParameterInfoClass *current_param;
char *buffer; char *buffer;
if ( ! stmt) if ( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
if (stmt->current_exec_param < 0) { if (stmt->current_exec_param < 0) {
stmt->errornumber = STMT_SEQUENCE_ERROR; stmt->errornumber = STMT_SEQUENCE_ERROR;
stmt->errormsg = "Previous call was not SQLPutData or SQLParamData"; stmt->errormsg = "Previous call was not SQLPutData or SQLParamData";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -450,6 +493,7 @@ char *buffer; ...@@ -450,6 +493,7 @@ char *buffer;
if ( ! current_param->EXEC_used) { if ( ! current_param->EXEC_used) {
stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errornumber = STMT_NO_MEMORY_ERROR;
stmt->errormsg = "Out of memory in SQLPutData (1)"; stmt->errormsg = "Out of memory in SQLPutData (1)";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -467,6 +511,7 @@ char *buffer; ...@@ -467,6 +511,7 @@ char *buffer;
if (current_param->lobj_oid == 0) { if (current_param->lobj_oid == 0) {
stmt->errornumber = STMT_EXEC_ERROR; stmt->errornumber = STMT_EXEC_ERROR;
stmt->errormsg = "Couldnt create large object."; stmt->errormsg = "Couldnt create large object.";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -479,6 +524,7 @@ char *buffer; ...@@ -479,6 +524,7 @@ char *buffer;
if ( stmt->lobj_fd < 0) { if ( stmt->lobj_fd < 0) {
stmt->errornumber = STMT_EXEC_ERROR; stmt->errornumber = STMT_EXEC_ERROR;
stmt->errormsg = "Couldnt open large object for writing."; stmt->errormsg = "Couldnt open large object for writing.";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -493,6 +539,7 @@ char *buffer; ...@@ -493,6 +539,7 @@ char *buffer;
if ( ! current_param->EXEC_buffer) { if ( ! current_param->EXEC_buffer) {
stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errornumber = STMT_NO_MEMORY_ERROR;
stmt->errormsg = "Out of memory in SQLPutData (2)"; stmt->errormsg = "Out of memory in SQLPutData (2)";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
} }
...@@ -501,6 +548,7 @@ char *buffer; ...@@ -501,6 +548,7 @@ char *buffer;
if ( ! current_param->EXEC_buffer) { if ( ! current_param->EXEC_buffer) {
stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errornumber = STMT_NO_MEMORY_ERROR;
stmt->errormsg = "Out of memory in SQLPutData (2)"; stmt->errormsg = "Out of memory in SQLPutData (2)";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
memcpy(current_param->EXEC_buffer, rgbValue, cbValue); memcpy(current_param->EXEC_buffer, rgbValue, cbValue);
...@@ -530,6 +578,7 @@ char *buffer; ...@@ -530,6 +578,7 @@ char *buffer;
if ( ! buffer) { if ( ! buffer) {
stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errornumber = STMT_NO_MEMORY_ERROR;
stmt->errormsg = "Out of memory in SQLPutData (3)"; stmt->errormsg = "Out of memory in SQLPutData (3)";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
strcat(buffer, rgbValue); strcat(buffer, rgbValue);
...@@ -555,6 +604,7 @@ char *buffer; ...@@ -555,6 +604,7 @@ char *buffer;
if ( ! buffer) { if ( ! buffer) {
stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errornumber = STMT_NO_MEMORY_ERROR;
stmt->errormsg = "Out of memory in SQLPutData (3)"; stmt->errormsg = "Out of memory in SQLPutData (3)";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -565,8 +615,10 @@ char *buffer; ...@@ -565,8 +615,10 @@ char *buffer;
current_param->EXEC_buffer = buffer; current_param->EXEC_buffer = buffer;
} }
else else {
SC_log_error(func, "bad cbValue", stmt);
return SQL_ERROR; return SQL_ERROR;
}
} }
} }
......
...@@ -45,24 +45,19 @@ RETCODE SQL_API SQLGetInfo( ...@@ -45,24 +45,19 @@ RETCODE SQL_API SQLGetInfo(
SWORD cbInfoValueMax, SWORD cbInfoValueMax,
SWORD FAR *pcbInfoValue) SWORD FAR *pcbInfoValue)
{ {
char *func = "SQLGetInfo";
ConnectionClass *conn = (ConnectionClass *) hdbc; ConnectionClass *conn = (ConnectionClass *) hdbc;
char *p; char *p;
if ( ! conn) if ( ! conn) {
CC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
/* CC: Some sanity checks */ if (NULL == (char *)rgbInfoValue) {
if ((NULL == (char *)rgbInfoValue) || CC_log_error(func, "Bad rgbInfoValue", conn);
(cbInfoValueMax == 0))
/* removed: */
/* || (NULL == pcbInfoValue) */
/* pcbInfoValue is ignored for non-character output. */
/* some programs (at least Microsoft Query) seem to just send a NULL, */
/* so let them get away with it... */
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
switch (fInfoType) { switch (fInfoType) {
...@@ -70,13 +65,13 @@ char *p; ...@@ -70,13 +65,13 @@ char *p;
// can the user call all functions returned by SQLProcedures? // can the user call all functions returned by SQLProcedures?
// I assume access permissions could prevent this in some cases(?) // I assume access permissions could prevent this in some cases(?)
// anyway, SQLProcedures doesn't exist yet. // anyway, SQLProcedures doesn't exist yet.
*pcbInfoValue = 1; if (pcbInfoValue) *pcbInfoValue = 1;
strncpy_null((char *)rgbInfoValue, "N", (size_t)cbInfoValueMax); strncpy_null((char *)rgbInfoValue, "N", (size_t)cbInfoValueMax);
break; break;
case SQL_ACCESSIBLE_TABLES: /* ODBC 1.0 */ case SQL_ACCESSIBLE_TABLES: /* ODBC 1.0 */
// is the user guaranteed "SELECT" on every table? // is the user guaranteed "SELECT" on every table?
*pcbInfoValue = 1; if (pcbInfoValue) *pcbInfoValue = 1;
strncpy_null((char *)rgbInfoValue, "N", (size_t)cbInfoValueMax); strncpy_null((char *)rgbInfoValue, "N", (size_t)cbInfoValueMax);
break; break;
...@@ -108,7 +103,7 @@ char *p; ...@@ -108,7 +103,7 @@ char *p;
case SQL_COLUMN_ALIAS: /* ODBC 2.0 */ case SQL_COLUMN_ALIAS: /* ODBC 2.0 */
// do we support column aliases? guess not. // do we support column aliases? guess not.
*pcbInfoValue = 1; if (pcbInfoValue) *pcbInfoValue = 1;
strncpy_null((char *)rgbInfoValue, "N", (size_t)cbInfoValueMax); strncpy_null((char *)rgbInfoValue, "N", (size_t)cbInfoValueMax);
break; break;
...@@ -294,6 +289,7 @@ char *p; ...@@ -294,6 +289,7 @@ char *p;
// do this later // do this later
conn->errormsg = "SQL_KEYWORDS parameter to SQLGetInfo not implemented."; conn->errormsg = "SQL_KEYWORDS parameter to SQLGetInfo not implemented.";
conn->errornumber = CONN_NOT_IMPLEMENTED_ERROR; conn->errornumber = CONN_NOT_IMPLEMENTED_ERROR;
CC_log_error(func, "", conn);
return SQL_ERROR; return SQL_ERROR;
break; break;
...@@ -398,7 +394,7 @@ char *p; ...@@ -398,7 +394,7 @@ char *p;
case SQL_MAX_ROW_SIZE_INCLUDES_LONG: /* ODBC 2.0 */ case SQL_MAX_ROW_SIZE_INCLUDES_LONG: /* ODBC 2.0 */
// does the preceding value include LONGVARCHAR and LONGVARBINARY // does the preceding value include LONGVARCHAR and LONGVARBINARY
// fields? Well, it does include longvarchar, but not longvarbinary. // fields? Well, it does include longvarchar, but not longvarbinary.
*pcbInfoValue = 1; if (pcbInfoValue) *pcbInfoValue = 1;
strncpy_null((char *)rgbInfoValue, "Y", (size_t)cbInfoValueMax); strncpy_null((char *)rgbInfoValue, "Y", (size_t)cbInfoValueMax);
break; break;
...@@ -715,6 +711,7 @@ char *p; ...@@ -715,6 +711,7 @@ char *p;
/* unrecognized key */ /* unrecognized key */
conn->errormsg = "Unrecognized key passed to SQLGetInfo."; conn->errormsg = "Unrecognized key passed to SQLGetInfo.";
conn->errornumber = CONN_NOT_IMPLEMENTED_ERROR; conn->errornumber = CONN_NOT_IMPLEMENTED_ERROR;
CC_log_error(func, "", conn);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -728,6 +725,7 @@ RETCODE SQL_API SQLGetTypeInfo( ...@@ -728,6 +725,7 @@ RETCODE SQL_API SQLGetTypeInfo(
HSTMT hstmt, HSTMT hstmt,
SWORD fSqlType) SWORD fSqlType)
{ {
char *func = "SQLGetTypeInfo";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
TupleNode *row; TupleNode *row;
int i; int i;
...@@ -736,12 +734,14 @@ Int4 type; ...@@ -736,12 +734,14 @@ Int4 type;
mylog("**** in SQLGetTypeInfo: fSqlType = %d\n", fSqlType); mylog("**** in SQLGetTypeInfo: fSqlType = %d\n", fSqlType);
if( ! stmt) { if( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
} }
stmt->manual_result = TRUE; stmt->manual_result = TRUE;
stmt->result = QR_Constructor(); stmt->result = QR_Constructor();
if( ! stmt->result) { if( ! stmt->result) {
SC_log_error(func, "Error creating result.", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -976,6 +976,7 @@ RETCODE SQL_API SQLTables( ...@@ -976,6 +976,7 @@ RETCODE SQL_API SQLTables(
UCHAR FAR * szTableType, UCHAR FAR * szTableType,
SWORD cbTableType) SWORD cbTableType)
{ {
char *func = "SQLTables";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
StatementClass *tbl_stmt; StatementClass *tbl_stmt;
TupleNode *row; TupleNode *row;
...@@ -993,8 +994,10 @@ int i; ...@@ -993,8 +994,10 @@ int i;
mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt); mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt);
if( ! stmt) if( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
stmt->manual_result = TRUE; stmt->manual_result = TRUE;
stmt->errormsg_created = TRUE; stmt->errormsg_created = TRUE;
...@@ -1005,6 +1008,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt); ...@@ -1005,6 +1008,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errornumber = STMT_NO_MEMORY_ERROR;
stmt->errormsg = "Couldn't allocate statement for SQLTables result."; stmt->errormsg = "Couldn't allocate statement for SQLTables result.";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
tbl_stmt = (StatementClass *) htbl_stmt; tbl_stmt = (StatementClass *) htbl_stmt;
...@@ -1086,6 +1090,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt); ...@@ -1086,6 +1090,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = SC_create_errormsg(htbl_stmt); stmt->errormsg = SC_create_errormsg(htbl_stmt);
stmt->errornumber = tbl_stmt->errornumber; stmt->errornumber = tbl_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(htbl_stmt, SQL_DROP); SQLFreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1095,6 +1100,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt); ...@@ -1095,6 +1100,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = tbl_stmt->errormsg; stmt->errormsg = tbl_stmt->errormsg;
stmt->errornumber = tbl_stmt->errornumber; stmt->errornumber = tbl_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(htbl_stmt, SQL_DROP); SQLFreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1104,6 +1110,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt); ...@@ -1104,6 +1110,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = tbl_stmt->errormsg; stmt->errormsg = tbl_stmt->errormsg;
stmt->errornumber = tbl_stmt->errornumber; stmt->errornumber = tbl_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(htbl_stmt, SQL_DROP); SQLFreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1112,6 +1119,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt); ...@@ -1112,6 +1119,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = tbl_stmt->errormsg; stmt->errormsg = tbl_stmt->errormsg;
stmt->errornumber = tbl_stmt->errornumber; stmt->errornumber = tbl_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(htbl_stmt, SQL_DROP); SQLFreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1120,6 +1128,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt); ...@@ -1120,6 +1128,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt);
if(!stmt->result) { if(!stmt->result) {
stmt->errormsg = "Couldn't allocate memory for SQLTables result."; stmt->errormsg = "Couldn't allocate memory for SQLTables result.";
stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errornumber = STMT_NO_MEMORY_ERROR;
SC_log_error(func, "", stmt);
SQLFreeStmt(htbl_stmt, SQL_DROP); SQLFreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1201,6 +1210,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt); ...@@ -1201,6 +1210,7 @@ mylog("**** SQLTables(): ENTER, stmt=%u\n", stmt);
if(result != SQL_NO_DATA_FOUND) { if(result != SQL_NO_DATA_FOUND) {
stmt->errormsg = SC_create_errormsg(htbl_stmt); stmt->errormsg = SC_create_errormsg(htbl_stmt);
stmt->errornumber = tbl_stmt->errornumber; stmt->errornumber = tbl_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(htbl_stmt, SQL_DROP); SQLFreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1229,6 +1239,7 @@ RETCODE SQL_API SQLColumns( ...@@ -1229,6 +1239,7 @@ RETCODE SQL_API SQLColumns(
UCHAR FAR * szColumnName, UCHAR FAR * szColumnName,
SWORD cbColumnName) SWORD cbColumnName)
{ {
char *func = "SQLColumns";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
TupleNode *row; TupleNode *row;
HSTMT hcol_stmt; HSTMT hcol_stmt;
...@@ -1238,6 +1249,7 @@ RETCODE result; ...@@ -1238,6 +1249,7 @@ RETCODE result;
char table_owner[MAX_INFO_STRING], table_name[MAX_INFO_STRING], field_name[MAX_INFO_STRING], field_type_name[MAX_INFO_STRING]; char table_owner[MAX_INFO_STRING], table_name[MAX_INFO_STRING], field_name[MAX_INFO_STRING], field_type_name[MAX_INFO_STRING];
Int2 field_number, field_length, mod_length; Int2 field_number, field_length, mod_length;
Int4 field_type; Int4 field_type;
Int2 the_type;
char not_null[MAX_INFO_STRING]; char not_null[MAX_INFO_STRING];
ConnInfo *ci; ConnInfo *ci;
...@@ -1245,8 +1257,10 @@ ConnInfo *ci; ...@@ -1245,8 +1257,10 @@ ConnInfo *ci;
mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt); mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
if( ! stmt) if( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
stmt->manual_result = TRUE; stmt->manual_result = TRUE;
stmt->errormsg_created = TRUE; stmt->errormsg_created = TRUE;
...@@ -1273,6 +1287,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt); ...@@ -1273,6 +1287,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errornumber = STMT_NO_MEMORY_ERROR;
stmt->errormsg = "Couldn't allocate statement for SQLColumns result."; stmt->errormsg = "Couldn't allocate statement for SQLColumns result.";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
col_stmt = (StatementClass *) hcol_stmt; col_stmt = (StatementClass *) hcol_stmt;
...@@ -1282,6 +1297,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt); ...@@ -1282,6 +1297,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = SC_create_errormsg(hcol_stmt); stmt->errormsg = SC_create_errormsg(hcol_stmt);
stmt->errornumber = col_stmt->errornumber; stmt->errornumber = col_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(hcol_stmt, SQL_DROP); SQLFreeStmt(hcol_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1291,6 +1307,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt); ...@@ -1291,6 +1307,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = col_stmt->errormsg; stmt->errormsg = col_stmt->errormsg;
stmt->errornumber = col_stmt->errornumber; stmt->errornumber = col_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(hcol_stmt, SQL_DROP); SQLFreeStmt(hcol_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1300,6 +1317,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt); ...@@ -1300,6 +1317,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = col_stmt->errormsg; stmt->errormsg = col_stmt->errormsg;
stmt->errornumber = col_stmt->errornumber; stmt->errornumber = col_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(hcol_stmt, SQL_DROP); SQLFreeStmt(hcol_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1309,6 +1327,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt); ...@@ -1309,6 +1327,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = col_stmt->errormsg; stmt->errormsg = col_stmt->errormsg;
stmt->errornumber = col_stmt->errornumber; stmt->errornumber = col_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(hcol_stmt, SQL_DROP); SQLFreeStmt(hcol_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1318,6 +1337,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt); ...@@ -1318,6 +1337,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = col_stmt->errormsg; stmt->errormsg = col_stmt->errormsg;
stmt->errornumber = col_stmt->errornumber; stmt->errornumber = col_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(hcol_stmt, SQL_DROP); SQLFreeStmt(hcol_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1327,6 +1347,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt); ...@@ -1327,6 +1347,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = col_stmt->errormsg; stmt->errormsg = col_stmt->errormsg;
stmt->errornumber = col_stmt->errornumber; stmt->errornumber = col_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(hcol_stmt, SQL_DROP); SQLFreeStmt(hcol_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1336,6 +1357,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt); ...@@ -1336,6 +1357,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = col_stmt->errormsg; stmt->errormsg = col_stmt->errormsg;
stmt->errornumber = col_stmt->errornumber; stmt->errornumber = col_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(hcol_stmt, SQL_DROP); SQLFreeStmt(hcol_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1345,6 +1367,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt); ...@@ -1345,6 +1367,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = col_stmt->errormsg; stmt->errormsg = col_stmt->errormsg;
stmt->errornumber = col_stmt->errornumber; stmt->errornumber = col_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(hcol_stmt, SQL_DROP); SQLFreeStmt(hcol_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1354,6 +1377,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt); ...@@ -1354,6 +1377,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = col_stmt->errormsg; stmt->errormsg = col_stmt->errormsg;
stmt->errornumber = col_stmt->errornumber; stmt->errornumber = col_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(hcol_stmt, SQL_DROP); SQLFreeStmt(hcol_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1363,6 +1387,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt); ...@@ -1363,6 +1387,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = col_stmt->errormsg; stmt->errormsg = col_stmt->errormsg;
stmt->errornumber = col_stmt->errornumber; stmt->errornumber = col_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(hcol_stmt, SQL_DROP); SQLFreeStmt(hcol_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1371,6 +1396,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt); ...@@ -1371,6 +1396,7 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
if(!stmt->result) { if(!stmt->result) {
stmt->errormsg = "Couldn't allocate memory for SQLColumns result."; stmt->errormsg = "Couldn't allocate memory for SQLColumns result.";
stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errornumber = STMT_NO_MEMORY_ERROR;
SC_log_error(func, "", stmt);
SQLFreeStmt(hcol_stmt, SQL_DROP); SQLFreeStmt(hcol_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1402,10 +1428,12 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt); ...@@ -1402,10 +1428,12 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
Always show OID if its a system table Always show OID if its a system table
*/ */
if (result != SQL_ERROR && ! stmt->internal && if (result != SQL_ERROR && ! stmt->internal) {
(atoi(ci->show_oid_column) || strncmp(table_name, POSTGRES_SYS_PREFIX, strlen(POSTGRES_SYS_PREFIX)) == 0)) {
if (atoi(ci->show_oid_column) || strncmp(table_name, POSTGRES_SYS_PREFIX, strlen(POSTGRES_SYS_PREFIX)) == 0) {
/* For OID fields */ /* For OID fields */
the_type = PG_TYPE_OID;
row = (TupleNode *)malloc(sizeof(TupleNode) + row = (TupleNode *)malloc(sizeof(TupleNode) +
(12 - 1) * sizeof(TupleField)); (12 - 1) * sizeof(TupleField));
...@@ -1415,22 +1443,24 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt); ...@@ -1415,22 +1443,24 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
set_tuplefield_string(&row->tuple[1], ""); set_tuplefield_string(&row->tuple[1], "");
set_tuplefield_string(&row->tuple[2], table_name); set_tuplefield_string(&row->tuple[2], table_name);
set_tuplefield_string(&row->tuple[3], "oid"); set_tuplefield_string(&row->tuple[3], "oid");
set_tuplefield_int2(&row->tuple[4], pgtype_to_sqltype(stmt, PG_TYPE_OID)); set_tuplefield_int2(&row->tuple[4], pgtype_to_sqltype(stmt, the_type));
set_tuplefield_string(&row->tuple[5], "OID"); set_tuplefield_string(&row->tuple[5], "OID");
set_tuplefield_int4(&row->tuple[7], pgtype_length(stmt, PG_TYPE_OID, PG_STATIC, set_tuplefield_int4(&row->tuple[7], pgtype_length(stmt, the_type, PG_STATIC,
PG_STATIC)); PG_STATIC));
set_tuplefield_int4(&row->tuple[6], pgtype_precision(stmt, PG_TYPE_OID, PG_STATIC, set_tuplefield_int4(&row->tuple[6], pgtype_precision(stmt, the_type, PG_STATIC,
PG_STATIC)); PG_STATIC));
set_nullfield_int2(&row->tuple[8], pgtype_scale(stmt, PG_TYPE_OID)); set_nullfield_int2(&row->tuple[8], pgtype_scale(stmt, the_type));
set_nullfield_int2(&row->tuple[9], pgtype_radix(stmt, PG_TYPE_OID)); set_nullfield_int2(&row->tuple[9], pgtype_radix(stmt, the_type));
set_tuplefield_int2(&row->tuple[10], SQL_NO_NULLS); set_tuplefield_int2(&row->tuple[10], SQL_NO_NULLS);
set_tuplefield_string(&row->tuple[11], ""); set_tuplefield_string(&row->tuple[11], "");
QR_add_tuple(stmt->result, row); QR_add_tuple(stmt->result, row);
} }
}
while((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) { while((result == SQL_SUCCESS) || (result == SQL_SUCCESS_WITH_INFO)) {
row = (TupleNode *)malloc(sizeof(TupleNode) + row = (TupleNode *)malloc(sizeof(TupleNode) +
(12 - 1) * sizeof(TupleField)); (12 - 1) * sizeof(TupleField));
...@@ -1484,10 +1514,36 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt); ...@@ -1484,10 +1514,36 @@ mylog("**** SQLColumns(): ENTER, stmt=%u\n", stmt);
if(result != SQL_NO_DATA_FOUND) { if(result != SQL_NO_DATA_FOUND) {
stmt->errormsg = SC_create_errormsg(hcol_stmt); stmt->errormsg = SC_create_errormsg(hcol_stmt);
stmt->errornumber = col_stmt->errornumber; stmt->errornumber = col_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(hcol_stmt, SQL_DROP); SQLFreeStmt(hcol_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
// Put the row version column at the end so it might not be
// mistaken for a key field.
if ( ! stmt->internal && atoi(ci->row_versioning)) {
/* For Row Versioning fields */
the_type = PG_TYPE_INT4;
row = (TupleNode *)malloc(sizeof(TupleNode) +
(12 - 1) * sizeof(TupleField));
set_tuplefield_string(&row->tuple[0], "");
set_tuplefield_string(&row->tuple[1], "");
set_tuplefield_string(&row->tuple[2], table_name);
set_tuplefield_string(&row->tuple[3], "xmin");
set_tuplefield_int2(&row->tuple[4], pgtype_to_sqltype(stmt, the_type));
set_tuplefield_string(&row->tuple[5], pgtype_to_name(stmt, the_type));
set_tuplefield_int4(&row->tuple[6], pgtype_precision(stmt, the_type, PG_STATIC, PG_STATIC));
set_tuplefield_int4(&row->tuple[7], pgtype_length(stmt, the_type, PG_STATIC, PG_STATIC));
set_nullfield_int2(&row->tuple[8], pgtype_scale(stmt, the_type));
set_nullfield_int2(&row->tuple[9], pgtype_radix(stmt, the_type));
set_tuplefield_int2(&row->tuple[10], SQL_NO_NULLS);
set_tuplefield_string(&row->tuple[11], "");
QR_add_tuple(stmt->result, row);
}
// also, things need to think that this statement is finished so // also, things need to think that this statement is finished so
// the results can be retrieved. // the results can be retrieved.
stmt->status = STMT_FINISHED; stmt->status = STMT_FINISHED;
...@@ -1513,14 +1569,20 @@ RETCODE SQL_API SQLSpecialColumns( ...@@ -1513,14 +1569,20 @@ RETCODE SQL_API SQLSpecialColumns(
UWORD fScope, UWORD fScope,
UWORD fNullable) UWORD fNullable)
{ {
char *func = "SQLSpecialColumns";
TupleNode *row; TupleNode *row;
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
ConnInfo *ci;
mylog("**** SQLSpecialColumns(): ENTER, stmt=%u\n", stmt); mylog("**** SQLSpecialColumns(): ENTER, stmt=%u\n", stmt);
if( ! stmt) { if( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
} }
ci = &stmt->hdbc->connInfo;
stmt->manual_result = TRUE; stmt->manual_result = TRUE;
stmt->result = QR_Constructor(); stmt->result = QR_Constructor();
extend_bindings(stmt, 8); extend_bindings(stmt, 8);
...@@ -1551,11 +1613,24 @@ mylog("**** SQLSpecialColumns(): ENTER, stmt=%u\n", stmt); ...@@ -1551,11 +1613,24 @@ mylog("**** SQLSpecialColumns(): ENTER, stmt=%u\n", stmt);
QR_add_tuple(stmt->result, row); QR_add_tuple(stmt->result, row);
} else if(fColType == SQL_ROWVER) { } else if(fColType == SQL_ROWVER) {
/* can columns automatically update? */
/* for now assume no. */
/* return an empty result. */
}
Int2 the_type = PG_TYPE_INT4;
if (atoi(ci->row_versioning)) {
row = (TupleNode *)malloc(sizeof(TupleNode) + (8 - 1) * sizeof(TupleField));
set_tuplefield_null(&row->tuple[0]);
set_tuplefield_string(&row->tuple[1], "xmin");
set_tuplefield_int2(&row->tuple[2], pgtype_to_sqltype(stmt, the_type));
set_tuplefield_string(&row->tuple[3], pgtype_to_name(stmt, the_type));
set_tuplefield_int4(&row->tuple[4], pgtype_precision(stmt, the_type, PG_STATIC, PG_STATIC));
set_tuplefield_int4(&row->tuple[5], pgtype_length(stmt, the_type, PG_STATIC, PG_STATIC));
set_tuplefield_int2(&row->tuple[6], pgtype_scale(stmt, the_type));
set_tuplefield_int2(&row->tuple[7], SQL_PC_PSEUDO);
QR_add_tuple(stmt->result, row);
}
}
stmt->status = STMT_FINISHED; stmt->status = STMT_FINISHED;
stmt->currTuple = -1; stmt->currTuple = -1;
stmt->current_col = -1; stmt->current_col = -1;
...@@ -1575,6 +1650,7 @@ RETCODE SQL_API SQLStatistics( ...@@ -1575,6 +1650,7 @@ RETCODE SQL_API SQLStatistics(
UWORD fUnique, UWORD fUnique,
UWORD fAccuracy) UWORD fAccuracy)
{ {
char *func="SQLStatistics";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
char index_query[MAX_STATEMENT_LEN]; char index_query[MAX_STATEMENT_LEN];
HSTMT hindx_stmt; HSTMT hindx_stmt;
...@@ -1599,6 +1675,7 @@ char buf[256]; ...@@ -1599,6 +1675,7 @@ char buf[256];
mylog("**** SQLStatistics(): ENTER, stmt=%u\n", stmt); mylog("**** SQLStatistics(): ENTER, stmt=%u\n", stmt);
if( ! stmt) { if( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
} }
...@@ -1611,6 +1688,7 @@ mylog("**** SQLStatistics(): ENTER, stmt=%u\n", stmt); ...@@ -1611,6 +1688,7 @@ mylog("**** SQLStatistics(): ENTER, stmt=%u\n", stmt);
if(!stmt->result) { if(!stmt->result) {
stmt->errormsg = "Couldn't allocate memory for SQLStatistics result."; stmt->errormsg = "Couldn't allocate memory for SQLStatistics result.";
stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errornumber = STMT_NO_MEMORY_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1641,6 +1719,7 @@ mylog("**** SQLStatistics(): ENTER, stmt=%u\n", stmt); ...@@ -1641,6 +1719,7 @@ mylog("**** SQLStatistics(): ENTER, stmt=%u\n", stmt);
if ( ! table_name) { if ( ! table_name) {
stmt->errormsg = "No table name passed to SQLStatistics."; stmt->errormsg = "No table name passed to SQLStatistics.";
stmt->errornumber = STMT_INTERNAL_ERROR; stmt->errornumber = STMT_INTERNAL_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1887,8 +1966,10 @@ SEEYA: ...@@ -1887,8 +1966,10 @@ SEEYA:
mylog("SQLStatistics(): EXIT, %s, stmt=%u\n", error ? "error" : "success", stmt); mylog("SQLStatistics(): EXIT, %s, stmt=%u\n", error ? "error" : "success", stmt);
if (error) if (error) {
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
}
else else
return SQL_SUCCESS; return SQL_SUCCESS;
} }
...@@ -1904,13 +1985,17 @@ RETCODE SQL_API SQLColumnPrivileges( ...@@ -1904,13 +1985,17 @@ RETCODE SQL_API SQLColumnPrivileges(
UCHAR FAR * szColumnName, UCHAR FAR * szColumnName,
SWORD cbColumnName) SWORD cbColumnName)
{ {
char *func="SQLColumnPrivileges";
/* Neither Access or Borland care about this. */ /* Neither Access or Borland care about this. */
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
return SQL_ERROR; return SQL_ERROR;
} }
RETCODE RETCODE
getPrimaryKeyString(StatementClass *stmt, char *szTableName, SWORD cbTableName, char *svKey, int *nKey) getPrimaryKeyString(StatementClass *stmt, char *szTableName, SWORD cbTableName, char *svKey, int *nKey)
{ {
char *func = "getPrimaryKeyString";
HSTMT htbl_stmt; HSTMT htbl_stmt;
StatementClass *tbl_stmt; StatementClass *tbl_stmt;
RETCODE result; RETCODE result;
...@@ -1930,6 +2015,7 @@ int nk = 0; ...@@ -1930,6 +2015,7 @@ int nk = 0;
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errornumber = STMT_NO_MEMORY_ERROR;
stmt->errormsg = "Couldn't allocate statement for Primary Key result."; stmt->errormsg = "Couldn't allocate statement for Primary Key result.";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
tbl_stmt = (StatementClass *) htbl_stmt; tbl_stmt = (StatementClass *) htbl_stmt;
...@@ -1940,6 +2026,7 @@ int nk = 0; ...@@ -1940,6 +2026,7 @@ int nk = 0;
stmt->errormsg = "No Table specified to getPrimaryKeyString."; stmt->errormsg = "No Table specified to getPrimaryKeyString.";
stmt->errornumber = STMT_INTERNAL_ERROR; stmt->errornumber = STMT_INTERNAL_ERROR;
SC_log_error(func, "", stmt);
SQLFreeStmt(htbl_stmt, SQL_DROP); SQLFreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1950,6 +2037,7 @@ int nk = 0; ...@@ -1950,6 +2037,7 @@ int nk = 0;
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = SC_create_errormsg(htbl_stmt); stmt->errormsg = SC_create_errormsg(htbl_stmt);
stmt->errornumber = tbl_stmt->errornumber; stmt->errornumber = tbl_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(htbl_stmt, SQL_DROP); SQLFreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1959,6 +2047,7 @@ int nk = 0; ...@@ -1959,6 +2047,7 @@ int nk = 0;
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = tbl_stmt->errormsg; stmt->errormsg = tbl_stmt->errormsg;
stmt->errornumber = tbl_stmt->errornumber; stmt->errornumber = tbl_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(htbl_stmt, SQL_DROP); SQLFreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -1977,6 +2066,7 @@ int nk = 0; ...@@ -1977,6 +2066,7 @@ int nk = 0;
if(result != SQL_NO_DATA_FOUND) { if(result != SQL_NO_DATA_FOUND) {
stmt->errormsg = SC_create_errormsg(htbl_stmt); stmt->errormsg = SC_create_errormsg(htbl_stmt);
stmt->errornumber = tbl_stmt->errornumber; stmt->errornumber = tbl_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(htbl_stmt, SQL_DROP); SQLFreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -2034,6 +2124,7 @@ RETCODE SQL_API SQLPrimaryKeys( ...@@ -2034,6 +2124,7 @@ RETCODE SQL_API SQLPrimaryKeys(
UCHAR FAR * szTableName, UCHAR FAR * szTableName,
SWORD cbTableName) SWORD cbTableName)
{ {
char *func = "SQLPrimaryKeys";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
TupleNode *row; TupleNode *row;
RETCODE result; RETCODE result;
...@@ -2043,6 +2134,7 @@ int seq = 1, nkeys = 0; ...@@ -2043,6 +2134,7 @@ int seq = 1, nkeys = 0;
mylog("**** SQLPrimaryKeys(): ENTER, stmt=%u\n", stmt); mylog("**** SQLPrimaryKeys(): ENTER, stmt=%u\n", stmt);
if( ! stmt) { if( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
} }
stmt->manual_result = TRUE; stmt->manual_result = TRUE;
...@@ -2068,6 +2160,7 @@ mylog("**** SQLPrimaryKeys(): ENTER, stmt=%u\n", stmt); ...@@ -2068,6 +2160,7 @@ mylog("**** SQLPrimaryKeys(): ENTER, stmt=%u\n", stmt);
if(!stmt->result) { if(!stmt->result) {
stmt->errormsg = "Couldn't allocate memory for SQLPrimaryKeys result."; stmt->errormsg = "Couldn't allocate memory for SQLPrimaryKeys result.";
stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errornumber = STMT_NO_MEMORY_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -2137,6 +2230,7 @@ RETCODE SQL_API SQLForeignKeys( ...@@ -2137,6 +2230,7 @@ RETCODE SQL_API SQLForeignKeys(
UCHAR FAR * szFkTableName, UCHAR FAR * szFkTableName,
SWORD cbFkTableName) SWORD cbFkTableName)
{ {
char *func = "SQLForeignKeys";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
TupleNode *row; TupleNode *row;
HSTMT htbl_stmt; HSTMT htbl_stmt;
...@@ -2156,6 +2250,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt); ...@@ -2156,6 +2250,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt);
memset(primaryKey, 0, sizeof(primaryKey)); memset(primaryKey, 0, sizeof(primaryKey));
if( ! stmt) { if( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
} }
stmt->manual_result = TRUE; stmt->manual_result = TRUE;
...@@ -2165,6 +2260,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt); ...@@ -2165,6 +2260,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errornumber = STMT_NO_MEMORY_ERROR;
stmt->errormsg = "Couldn't allocate statement for SQLForeignKeys result."; stmt->errormsg = "Couldn't allocate statement for SQLForeignKeys result.";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -2224,6 +2320,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt); ...@@ -2224,6 +2320,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt);
else { else {
stmt->errormsg = "No tables specified to SQLForeignKeys."; stmt->errormsg = "No tables specified to SQLForeignKeys.";
stmt->errornumber = STMT_INTERNAL_ERROR; stmt->errornumber = STMT_INTERNAL_ERROR;
SC_log_error(func, "", stmt);
SQLFreeStmt(htbl_stmt, SQL_DROP); SQLFreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -2232,6 +2329,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt); ...@@ -2232,6 +2329,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = SC_create_errormsg(htbl_stmt); stmt->errormsg = SC_create_errormsg(htbl_stmt);
stmt->errornumber = tbl_stmt->errornumber; stmt->errornumber = tbl_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(htbl_stmt, SQL_DROP); SQLFreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -2241,6 +2339,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt); ...@@ -2241,6 +2339,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = tbl_stmt->errormsg; stmt->errormsg = tbl_stmt->errormsg;
stmt->errornumber = tbl_stmt->errornumber; stmt->errornumber = tbl_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(htbl_stmt, SQL_DROP); SQLFreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -2249,6 +2348,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt); ...@@ -2249,6 +2348,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = tbl_stmt->errormsg; stmt->errormsg = tbl_stmt->errormsg;
stmt->errornumber = tbl_stmt->errornumber; stmt->errornumber = tbl_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(htbl_stmt, SQL_DROP); SQLFreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -2258,6 +2358,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt); ...@@ -2258,6 +2358,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt);
if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) { if((result != SQL_SUCCESS) && (result != SQL_SUCCESS_WITH_INFO)) {
stmt->errormsg = tbl_stmt->errormsg; stmt->errormsg = tbl_stmt->errormsg;
stmt->errornumber = tbl_stmt->errornumber; stmt->errornumber = tbl_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(htbl_stmt, SQL_DROP); SQLFreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -2266,6 +2367,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt); ...@@ -2266,6 +2367,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt);
if(!stmt->result) { if(!stmt->result) {
stmt->errormsg = "Couldn't allocate memory for SQLForeignKeys result."; stmt->errormsg = "Couldn't allocate memory for SQLForeignKeys result.";
stmt->errornumber = STMT_NO_MEMORY_ERROR; stmt->errornumber = STMT_NO_MEMORY_ERROR;
SC_log_error(func, "", stmt);
SQLFreeStmt(htbl_stmt, SQL_DROP); SQLFreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -2356,6 +2458,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt); ...@@ -2356,6 +2458,7 @@ mylog("**** SQLForeignKeys(): ENTER, stmt=%u\n", stmt);
if(result != SQL_NO_DATA_FOUND) { if(result != SQL_NO_DATA_FOUND) {
stmt->errormsg = SC_create_errormsg(htbl_stmt); stmt->errormsg = SC_create_errormsg(htbl_stmt);
stmt->errornumber = tbl_stmt->errornumber; stmt->errornumber = tbl_stmt->errornumber;
SC_log_error(func, "", stmt);
SQLFreeStmt(htbl_stmt, SQL_DROP); SQLFreeStmt(htbl_stmt, SQL_DROP);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -2387,6 +2490,9 @@ RETCODE SQL_API SQLProcedureColumns( ...@@ -2387,6 +2490,9 @@ RETCODE SQL_API SQLProcedureColumns(
UCHAR FAR * szColumnName, UCHAR FAR * szColumnName,
SWORD cbColumnName) SWORD cbColumnName)
{ {
char *func="SQLProcedureColumns";
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -2399,6 +2505,9 @@ RETCODE SQL_API SQLProcedures( ...@@ -2399,6 +2505,9 @@ RETCODE SQL_API SQLProcedures(
UCHAR FAR * szProcName, UCHAR FAR * szProcName,
SWORD cbProcName) SWORD cbProcName)
{ {
char *func="SQLProcedures";
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -2411,5 +2520,8 @@ RETCODE SQL_API SQLTablePrivileges( ...@@ -2411,5 +2520,8 @@ RETCODE SQL_API SQLTablePrivileges(
UCHAR FAR * szTableName, UCHAR FAR * szTableName,
SWORD cbTableName) SWORD cbTableName)
{ {
char *func="SQLTablePrivileges";
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -31,10 +31,14 @@ RETCODE SQL_API SQLSetConnectOption( ...@@ -31,10 +31,14 @@ RETCODE SQL_API SQLSetConnectOption(
UWORD fOption, UWORD fOption,
UDWORD vParam) UDWORD vParam)
{ {
char *func="SQLSetConnectOption";
ConnectionClass *conn = (ConnectionClass *) hdbc; ConnectionClass *conn = (ConnectionClass *) hdbc;
if ( ! conn) if ( ! conn) {
CC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
switch (fOption) { switch (fOption) {
case SQL_AUTOCOMMIT: case SQL_AUTOCOMMIT:
...@@ -46,6 +50,7 @@ ConnectionClass *conn = (ConnectionClass *) hdbc; ...@@ -46,6 +50,7 @@ ConnectionClass *conn = (ConnectionClass *) hdbc;
if (CC_is_in_trans(conn)) { if (CC_is_in_trans(conn)) {
conn->errormsg = "Cannot switch commit mode while a transaction is in progres"; conn->errormsg = "Cannot switch commit mode while a transaction is in progres";
conn->errornumber = CONN_TRANSACT_IN_PROGRES; conn->errornumber = CONN_TRANSACT_IN_PROGRES;
CC_log_error(func, "", conn);
return SQL_ERROR; return SQL_ERROR;
} }
*/ */
...@@ -64,6 +69,7 @@ ConnectionClass *conn = (ConnectionClass *) hdbc; ...@@ -64,6 +69,7 @@ ConnectionClass *conn = (ConnectionClass *) hdbc;
default: default:
conn->errormsg = "Illegal parameter value for SQL_AUTOCOMMIT"; conn->errormsg = "Illegal parameter value for SQL_AUTOCOMMIT";
conn->errornumber = CONN_INVALID_ARGUMENT_NO; conn->errornumber = CONN_INVALID_ARGUMENT_NO;
CC_log_error(func, "", conn);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -76,9 +82,14 @@ ConnectionClass *conn = (ConnectionClass *) hdbc; ...@@ -76,9 +82,14 @@ ConnectionClass *conn = (ConnectionClass *) hdbc;
break; break;
default: default:
{
char option[32];
conn->errormsg = "This option is currently unsupported by the driver"; conn->errormsg = "This option is currently unsupported by the driver";
conn->errornumber = CONN_UNSUPPORTED_OPTION; conn->errornumber = CONN_UNSUPPORTED_OPTION;
sprintf(option, "fOption=%d", fOption);
CC_log_error(func, option, conn);
return SQL_ERROR; return SQL_ERROR;
}
} }
return SQL_SUCCESS; return SQL_SUCCESS;
...@@ -92,10 +103,13 @@ RETCODE SQL_API SQLGetConnectOption( ...@@ -92,10 +103,13 @@ RETCODE SQL_API SQLGetConnectOption(
UWORD fOption, UWORD fOption,
PTR pvParam) PTR pvParam)
{ {
char *func="SQLGetConnectOption";
ConnectionClass *conn = (ConnectionClass *) hdbc; ConnectionClass *conn = (ConnectionClass *) hdbc;
if (! conn) if (! conn) {
CC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
switch (fOption) { switch (fOption) {
case SQL_AUTOCOMMIT: case SQL_AUTOCOMMIT:
...@@ -111,10 +125,15 @@ ConnectionClass *conn = (ConnectionClass *) hdbc; ...@@ -111,10 +125,15 @@ ConnectionClass *conn = (ConnectionClass *) hdbc;
break; break;
default: default:
{
char option[32];
conn->errormsg = "This option is currently unsupported by the driver"; conn->errormsg = "This option is currently unsupported by the driver";
conn->errornumber = CONN_UNSUPPORTED_OPTION; conn->errornumber = CONN_UNSUPPORTED_OPTION;
sprintf(option, "fOption=%d", fOption);
CC_log_error(func, option, conn);
return SQL_ERROR; return SQL_ERROR;
break; break;
}
} }
...@@ -128,6 +147,7 @@ RETCODE SQL_API SQLSetStmtOption( ...@@ -128,6 +147,7 @@ RETCODE SQL_API SQLSetStmtOption(
UWORD fOption, UWORD fOption,
UDWORD vParam) UDWORD vParam)
{ {
char *func="SQLSetStmtOption";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
char changed = FALSE; char changed = FALSE;
...@@ -135,8 +155,10 @@ char changed = FALSE; ...@@ -135,8 +155,10 @@ char changed = FALSE;
// all the time, but it tries to set a huge value for SQL_MAX_LENGTH // all the time, but it tries to set a huge value for SQL_MAX_LENGTH
// and expects the driver to reduce it to the real value // and expects the driver to reduce it to the real value
if( ! stmt) if( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
switch(fOption) { switch(fOption) {
case SQL_QUERY_TIMEOUT: case SQL_QUERY_TIMEOUT:
...@@ -170,6 +192,7 @@ char changed = FALSE; ...@@ -170,6 +192,7 @@ char changed = FALSE;
else { else {
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
stmt->errormsg = "Driver does not support keyset size option"; stmt->errormsg = "Driver does not support keyset size option";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
break; break;
...@@ -214,13 +237,19 @@ char changed = FALSE; ...@@ -214,13 +237,19 @@ char changed = FALSE;
case SQL_SIMULATE_CURSOR: case SQL_SIMULATE_CURSOR:
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
stmt->errormsg = "Simulated positioned update/delete not supported. Use the cursor library."; stmt->errormsg = "Simulated positioned update/delete not supported. Use the cursor library.";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
default: default:
{
char option[32];
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
stmt->errormsg = "Driver does not support this statement option"; stmt->errormsg = "Driver does not support this statement option";
sprintf(option, "fOption=%d", fOption);
SC_log_error(func, option, stmt);
return SQL_ERROR; return SQL_ERROR;
} }
}
if (changed) { if (changed) {
stmt->errormsg = "Requested value changed."; stmt->errormsg = "Requested value changed.";
...@@ -239,14 +268,17 @@ RETCODE SQL_API SQLGetStmtOption( ...@@ -239,14 +268,17 @@ RETCODE SQL_API SQLGetStmtOption(
UWORD fOption, UWORD fOption,
PTR pvParam) PTR pvParam)
{ {
char *func="SQLGetStmtOption";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
// thought we could fake Access out by just returning SQL_SUCCESS // thought we could fake Access out by just returning SQL_SUCCESS
// all the time, but it tries to set a huge value for SQL_MAX_LENGTH // all the time, but it tries to set a huge value for SQL_MAX_LENGTH
// and expects the driver to reduce it to the real value // and expects the driver to reduce it to the real value
if( ! stmt) if( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
switch(fOption) { switch(fOption) {
case SQL_QUERY_TIMEOUT: case SQL_QUERY_TIMEOUT:
...@@ -289,13 +321,19 @@ StatementClass *stmt = (StatementClass *) hstmt; ...@@ -289,13 +321,19 @@ StatementClass *stmt = (StatementClass *) hstmt;
case SQL_SIMULATE_CURSOR: case SQL_SIMULATE_CURSOR:
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
stmt->errormsg = "Simulated positioned update/delete not supported. Use the cursor library."; stmt->errormsg = "Simulated positioned update/delete not supported. Use the cursor library.";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
default: default:
{
char option[32];
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
stmt->errormsg = "Driver does not support this statement option"; stmt->errormsg = "Driver does not support this statement option";
sprintf(option, "fOption=%d", fOption);
SC_log_error(func, option, stmt);
return SQL_ERROR; return SQL_ERROR;
} }
}
return SQL_SUCCESS; return SQL_SUCCESS;
} }
......
...@@ -46,7 +46,9 @@ Int4 pgtypes_defined[] = { ...@@ -46,7 +46,9 @@ Int4 pgtypes_defined[] = {
PG_TYPE_BPCHAR, PG_TYPE_BPCHAR,
PG_TYPE_DATE, PG_TYPE_DATE,
PG_TYPE_TIME, PG_TYPE_TIME,
PG_TYPE_DATETIME,
PG_TYPE_ABSTIME, /* a timestamp, sort of */ PG_TYPE_ABSTIME, /* a timestamp, sort of */
PG_TYPE_TIMESTAMP,
PG_TYPE_TEXT, PG_TYPE_TEXT,
PG_TYPE_INT2, PG_TYPE_INT2,
PG_TYPE_INT4, PG_TYPE_INT4,
...@@ -55,7 +57,6 @@ Int4 pgtypes_defined[] = { ...@@ -55,7 +57,6 @@ Int4 pgtypes_defined[] = {
PG_TYPE_OID, PG_TYPE_OID,
PG_TYPE_MONEY, PG_TYPE_MONEY,
PG_TYPE_BOOL, PG_TYPE_BOOL,
PG_TYPE_DATETIME,
PG_TYPE_BYTEA, PG_TYPE_BYTEA,
PG_TYPE_LO, PG_TYPE_LO,
0 }; 0 };
...@@ -97,7 +98,8 @@ Int2 pgtype_to_sqltype(StatementClass *stmt, Int4 type) ...@@ -97,7 +98,8 @@ Int2 pgtype_to_sqltype(StatementClass *stmt, Int4 type)
case PG_TYPE_DATE: return SQL_DATE; case PG_TYPE_DATE: return SQL_DATE;
case PG_TYPE_TIME: return SQL_TIME; case PG_TYPE_TIME: return SQL_TIME;
case PG_TYPE_ABSTIME: case PG_TYPE_ABSTIME:
case PG_TYPE_DATETIME: return SQL_TIMESTAMP; case PG_TYPE_DATETIME:
case PG_TYPE_TIMESTAMP: return SQL_TIMESTAMP;
case PG_TYPE_MONEY: return SQL_FLOAT; case PG_TYPE_MONEY: return SQL_FLOAT;
case PG_TYPE_BOOL: return globals.bools_as_char ? SQL_CHAR : SQL_BIT; case PG_TYPE_BOOL: return globals.bools_as_char ? SQL_CHAR : SQL_BIT;
...@@ -124,7 +126,8 @@ Int2 pgtype_to_ctype(StatementClass *stmt, Int4 type) ...@@ -124,7 +126,8 @@ Int2 pgtype_to_ctype(StatementClass *stmt, Int4 type)
case PG_TYPE_DATE: return SQL_C_DATE; case PG_TYPE_DATE: return SQL_C_DATE;
case PG_TYPE_TIME: return SQL_C_TIME; case PG_TYPE_TIME: return SQL_C_TIME;
case PG_TYPE_ABSTIME: case PG_TYPE_ABSTIME:
case PG_TYPE_DATETIME: return SQL_C_TIMESTAMP; case PG_TYPE_DATETIME:
case PG_TYPE_TIMESTAMP: return SQL_C_TIMESTAMP;
case PG_TYPE_MONEY: return SQL_C_FLOAT; case PG_TYPE_MONEY: return SQL_C_FLOAT;
case PG_TYPE_BOOL: return globals.bools_as_char ? SQL_C_CHAR : SQL_C_BIT; case PG_TYPE_BOOL: return globals.bools_as_char ? SQL_C_CHAR : SQL_C_BIT;
...@@ -161,6 +164,7 @@ char *pgtype_to_name(StatementClass *stmt, Int4 type) ...@@ -161,6 +164,7 @@ char *pgtype_to_name(StatementClass *stmt, Int4 type)
case PG_TYPE_TIME: return "time"; case PG_TYPE_TIME: return "time";
case PG_TYPE_ABSTIME: return "abstime"; case PG_TYPE_ABSTIME: return "abstime";
case PG_TYPE_DATETIME: return "datetime"; case PG_TYPE_DATETIME: return "datetime";
case PG_TYPE_TIMESTAMP: return "timestamp";
case PG_TYPE_MONEY: return "money"; case PG_TYPE_MONEY: return "money";
case PG_TYPE_BOOL: return "bool"; case PG_TYPE_BOOL: return "bool";
case PG_TYPE_BYTEA: return "bytea"; case PG_TYPE_BYTEA: return "bytea";
...@@ -269,7 +273,8 @@ Int4 pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unkno ...@@ -269,7 +273,8 @@ Int4 pgtype_precision(StatementClass *stmt, Int4 type, int col, int handle_unkno
case PG_TYPE_TIME: return 8; case PG_TYPE_TIME: return 8;
case PG_TYPE_ABSTIME: case PG_TYPE_ABSTIME:
case PG_TYPE_DATETIME: return 19; case PG_TYPE_DATETIME:
case PG_TYPE_TIMESTAMP: return 19;
case PG_TYPE_BOOL: return 1; case PG_TYPE_BOOL: return 1;
...@@ -327,7 +332,8 @@ Int4 pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_ ...@@ -327,7 +332,8 @@ Int4 pgtype_length(StatementClass *stmt, Int4 type, int col, int handle_unknown_
case PG_TYPE_TIME: return 6; case PG_TYPE_TIME: return 6;
case PG_TYPE_ABSTIME: case PG_TYPE_ABSTIME:
case PG_TYPE_DATETIME: return 16; case PG_TYPE_DATETIME:
case PG_TYPE_TIMESTAMP: return 16;
/* Character types use the default precision */ /* Character types use the default precision */
...@@ -350,7 +356,8 @@ Int2 pgtype_scale(StatementClass *stmt, Int4 type) ...@@ -350,7 +356,8 @@ Int2 pgtype_scale(StatementClass *stmt, Int4 type)
/* Number of digits to the right of the decimal point in "yyyy-mm=dd hh:mm:ss[.f...]" */ /* Number of digits to the right of the decimal point in "yyyy-mm=dd hh:mm:ss[.f...]" */
case PG_TYPE_ABSTIME: case PG_TYPE_ABSTIME:
case PG_TYPE_DATETIME: return 0; case PG_TYPE_DATETIME:
case PG_TYPE_TIMESTAMP: return 0;
default: return -1; default: return -1;
} }
...@@ -391,7 +398,8 @@ Int2 pgtype_auto_increment(StatementClass *stmt, Int4 type) ...@@ -391,7 +398,8 @@ Int2 pgtype_auto_increment(StatementClass *stmt, Int4 type)
case PG_TYPE_DATE: case PG_TYPE_DATE:
case PG_TYPE_TIME: case PG_TYPE_TIME:
case PG_TYPE_ABSTIME: case PG_TYPE_ABSTIME:
case PG_TYPE_DATETIME: return FALSE; case PG_TYPE_DATETIME:
case PG_TYPE_TIMESTAMP: return FALSE;
default: return -1; default: return -1;
} }
......
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
#define PG_TYPE_DATE 1082 #define PG_TYPE_DATE 1082
#define PG_TYPE_TIME 1083 #define PG_TYPE_TIME 1083
#define PG_TYPE_DATETIME 1184 #define PG_TYPE_DATETIME 1184
#define PG_TYPE_TIMESTAMP 1296
extern Int4 pgtypes_defined[]; extern Int4 pgtypes_defined[];
......
...@@ -50,8 +50,8 @@ typedef UInt4 Oid; ...@@ -50,8 +50,8 @@ typedef UInt4 Oid;
/* Driver stuff */ /* Driver stuff */
#define DRIVERNAME "PostgreSQL ODBC" #define DRIVERNAME "PostgreSQL ODBC"
#define DBMS_NAME "PostgreSQL" #define DBMS_NAME "PostgreSQL"
#define DBMS_VERSION "06.30.0244 PostgreSQL 6.3" #define DBMS_VERSION "06.30.0246 PostgreSQL 6.3"
#define POSTGRESDRIVERVERSION "06.30.0244" #define POSTGRESDRIVERVERSION "06.30.0246"
#define DRIVER_FILE_NAME "PSQLODBC.DLL" #define DRIVER_FILE_NAME "PSQLODBC.DLL"
......
...@@ -137,6 +137,8 @@ BEGIN ...@@ -137,6 +137,8 @@ BEGIN
WS_TABSTOP,130,10,60,14 WS_TABSTOP,130,10,60,14
CONTROL "Show System &Tables",DS_SHOWSYSTEMTABLES,"Button", CONTROL "Show System &Tables",DS_SHOWSYSTEMTABLES,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,25,30,85,10 BS_AUTOCHECKBOX | WS_TABSTOP,25,30,85,10
CONTROL "Row &Versioning",DS_ROWVERSIONING,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,130,30,85,10
GROUPBOX "OID Options",IDC_STATIC,15,50,180,25 GROUPBOX "OID Options",IDC_STATIC,15,50,180,25
CONTROL "Show &Column",DS_SHOWOIDCOLUMN,"Button",BS_AUTOCHECKBOX | CONTROL "Show &Column",DS_SHOWOIDCOLUMN,"Button",BS_AUTOCHECKBOX |
WS_GROUP | WS_TABSTOP,25,60,59,10 WS_GROUP | WS_TABSTOP,25,60,59,10
...@@ -198,8 +200,8 @@ END ...@@ -198,8 +200,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 6,30,2,44 FILEVERSION 6,30,2,46
PRODUCTVERSION 6,30,2,44 PRODUCTVERSION 6,30,2,46
FILEFLAGSMASK 0x3L FILEFLAGSMASK 0x3L
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
...@@ -217,12 +219,12 @@ BEGIN ...@@ -217,12 +219,12 @@ BEGIN
VALUE "Comments", "PostgreSQL ODBC driver for Windows 95\0" VALUE "Comments", "PostgreSQL ODBC driver for Windows 95\0"
VALUE "CompanyName", "Insight Distribution Systems\0" VALUE "CompanyName", "Insight Distribution Systems\0"
VALUE "FileDescription", "PostgreSQL Driver\0" VALUE "FileDescription", "PostgreSQL Driver\0"
VALUE "FileVersion", " 6.30.0244\0" VALUE "FileVersion", " 6.30.0246\0"
VALUE "InternalName", "psqlodbc\0" VALUE "InternalName", "psqlodbc\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 "ProductName", "Microsoft Open Database Connectivity\0" VALUE "ProductName", "Microsoft Open Database Connectivity\0"
VALUE "ProductVersion", " 6.30.0244\0" VALUE "ProductVersion", " 6.30.0246\0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
......
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
#define DRV_BOOLS_CHAR 1050 #define DRV_BOOLS_CHAR 1050
#define DS_SHOWSYSTEMTABLES 1051 #define DS_SHOWSYSTEMTABLES 1051
#define DRV_EXTRASYSTABLEPREFIXES 1051 #define DRV_EXTRASYSTABLEPREFIXES 1051
#define DS_ROWVERSIONING 1052
// Next default values for new objects // Next default values for new objects
// //
......
...@@ -36,12 +36,15 @@ RETCODE SQL_API SQLRowCount( ...@@ -36,12 +36,15 @@ RETCODE SQL_API SQLRowCount(
HSTMT hstmt, HSTMT hstmt,
SDWORD FAR *pcrow) SDWORD FAR *pcrow)
{ {
char *func="SQLRowCount";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
QResultClass *res; QResultClass *res;
char *msg, *ptr; char *msg, *ptr;
if ( ! stmt) if ( ! stmt) {
return SQL_ERROR; SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE;
}
if(stmt->statement_type == STMT_TYPE_SELECT) { if(stmt->statement_type == STMT_TYPE_SELECT) {
if (stmt->status == STMT_FINISHED) { if (stmt->status == STMT_FINISHED) {
...@@ -74,6 +77,7 @@ char *msg, *ptr; ...@@ -74,6 +77,7 @@ char *msg, *ptr;
} }
} }
SC_log_error(func, "Bad return value", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -86,11 +90,14 @@ RETCODE SQL_API SQLNumResultCols( ...@@ -86,11 +90,14 @@ RETCODE SQL_API SQLNumResultCols(
HSTMT hstmt, HSTMT hstmt,
SWORD FAR *pccol) SWORD FAR *pccol)
{ {
char *func="SQLNumResultCols";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
QResultClass *result; QResultClass *result;
if ( ! stmt) if ( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
SC_clear_error(stmt); SC_clear_error(stmt);
...@@ -109,6 +116,7 @@ QResultClass *result; ...@@ -109,6 +116,7 @@ QResultClass *result;
/* no query has been executed on this statement */ /* no query has been executed on this statement */
stmt->errornumber = STMT_SEQUENCE_ERROR; stmt->errornumber = STMT_SEQUENCE_ERROR;
stmt->errormsg = "No query has been executed with that handle"; stmt->errormsg = "No query has been executed with that handle";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -133,6 +141,7 @@ RETCODE SQL_API SQLDescribeCol( ...@@ -133,6 +141,7 @@ RETCODE SQL_API SQLDescribeCol(
SWORD FAR *pibScale, SWORD FAR *pibScale,
SWORD FAR *pfNullable) SWORD FAR *pfNullable)
{ {
char *func="SQLDescribeCol";
/* gets all the information about a specific column */ /* gets all the information about a specific column */
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
QResultClass *result; QResultClass *result;
...@@ -141,8 +150,10 @@ Int4 fieldtype; ...@@ -141,8 +150,10 @@ Int4 fieldtype;
int p; int p;
ConnInfo *ci; ConnInfo *ci;
if ( ! stmt) if ( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
ci = &(stmt->hdbc->connInfo); ci = &(stmt->hdbc->connInfo);
...@@ -162,6 +173,7 @@ ConnInfo *ci; ...@@ -162,6 +173,7 @@ ConnInfo *ci;
/* no query has been executed on this statement */ /* no query has been executed on this statement */
stmt->errornumber = STMT_SEQUENCE_ERROR; stmt->errornumber = STMT_SEQUENCE_ERROR;
stmt->errormsg = "No query has been assigned to this statement."; stmt->errormsg = "No query has been assigned to this statement.";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -169,6 +181,7 @@ ConnInfo *ci; ...@@ -169,6 +181,7 @@ ConnInfo *ci;
// we do not support bookmarks // we do not support bookmarks
stmt->errormsg = "Bookmarks are not currently supported."; stmt->errormsg = "Bookmarks are not currently supported.";
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -255,14 +268,17 @@ RETCODE SQL_API SQLColAttributes( ...@@ -255,14 +268,17 @@ RETCODE SQL_API SQLColAttributes(
SWORD FAR *pcbDesc, SWORD FAR *pcbDesc,
SDWORD FAR *pfDesc) SDWORD FAR *pfDesc)
{ {
char *func = "SQLColAttributes";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
char *value; char *value;
Int4 field_type; Int4 field_type;
ConnInfo *ci; ConnInfo *ci;
int unknown_sizes; int unknown_sizes;
if( ! stmt) if( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
ci = &(stmt->hdbc->connInfo); ci = &(stmt->hdbc->connInfo);
...@@ -277,6 +293,7 @@ int unknown_sizes; ...@@ -277,6 +293,7 @@ int unknown_sizes;
if ( (NULL == stmt->result) || ((stmt->status != STMT_FINISHED) && (stmt->status != STMT_PREMATURE)) ) { if ( (NULL == stmt->result) || ((stmt->status != STMT_FINISHED) && (stmt->status != STMT_PREMATURE)) ) {
stmt->errormsg = "Can't get column attributes: no result found."; stmt->errormsg = "Can't get column attributes: no result found.";
stmt->errornumber = STMT_SEQUENCE_ERROR; stmt->errornumber = STMT_SEQUENCE_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -284,6 +301,7 @@ int unknown_sizes; ...@@ -284,6 +301,7 @@ int unknown_sizes;
// we do not support bookmarks // we do not support bookmarks
stmt->errormsg = "Bookmarks are not currently supported."; stmt->errormsg = "Bookmarks are not currently supported.";
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -436,6 +454,7 @@ RETCODE SQL_API SQLGetData( ...@@ -436,6 +454,7 @@ RETCODE SQL_API SQLGetData(
SDWORD cbValueMax, SDWORD cbValueMax,
SDWORD FAR *pcbValue) SDWORD FAR *pcbValue)
{ {
char *func="SQLGetData";
QResultClass *res; QResultClass *res;
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
int num_cols, num_rows; int num_cols, num_rows;
...@@ -448,6 +467,7 @@ char multiple; ...@@ -448,6 +467,7 @@ char multiple;
mylog("SQLGetData: enter, stmt=%u\n", stmt); mylog("SQLGetData: enter, stmt=%u\n", stmt);
if( ! stmt) { if( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
} }
res = stmt->result; res = stmt->result;
...@@ -455,18 +475,21 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt); ...@@ -455,18 +475,21 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt);
if (STMT_EXECUTING == stmt->status) { if (STMT_EXECUTING == stmt->status) {
stmt->errormsg = "Can't get data while statement is still executing."; stmt->errormsg = "Can't get data while statement is still executing.";
stmt->errornumber = STMT_SEQUENCE_ERROR; stmt->errornumber = STMT_SEQUENCE_ERROR;
return 0; SC_log_error(func, "", stmt);
return SQL_ERROR;
} }
if (stmt->status != STMT_FINISHED) { if (stmt->status != STMT_FINISHED) {
stmt->errornumber = STMT_STATUS_ERROR; stmt->errornumber = STMT_STATUS_ERROR;
stmt->errormsg = "GetData can only be called after the successful execution on a SQL statement"; stmt->errormsg = "GetData can only be called after the successful execution on a SQL statement";
return 0; SC_log_error(func, "", stmt);
return SQL_ERROR;
} }
if (icol == 0) { if (icol == 0) {
stmt->errormsg = "Bookmarks are not currently supported."; stmt->errormsg = "Bookmarks are not currently supported.";
stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR; stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -478,6 +501,7 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt); ...@@ -478,6 +501,7 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt);
if (icol >= num_cols) { if (icol >= num_cols) {
stmt->errormsg = "Invalid column number."; stmt->errormsg = "Invalid column number.";
stmt->errornumber = STMT_INVALID_COLUMN_NUMBER_ERROR; stmt->errornumber = STMT_INVALID_COLUMN_NUMBER_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -488,6 +512,7 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt); ...@@ -488,6 +512,7 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt);
(stmt->currTuple >= num_rows)) { (stmt->currTuple >= num_rows)) {
stmt->errormsg = "Not positioned on a valid row for GetData."; stmt->errormsg = "Not positioned on a valid row for GetData.";
stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR; stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
mylog(" num_rows = %d\n", num_rows); mylog(" num_rows = %d\n", num_rows);
...@@ -503,6 +528,7 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt); ...@@ -503,6 +528,7 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt);
if (stmt->currTuple == -1 || ! res || QR_end_tuples(res)) { if (stmt->currTuple == -1 || ! res || QR_end_tuples(res)) {
stmt->errormsg = "Not positioned on a valid row for GetData."; stmt->errormsg = "Not positioned on a valid row for GetData.";
stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR; stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -531,11 +557,13 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt); ...@@ -531,11 +557,13 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt);
case COPY_UNSUPPORTED_TYPE: case COPY_UNSUPPORTED_TYPE:
stmt->errormsg = "Received an unsupported type from Postgres."; stmt->errormsg = "Received an unsupported type from Postgres.";
stmt->errornumber = STMT_RESTRICTED_DATA_TYPE_ERROR; stmt->errornumber = STMT_RESTRICTED_DATA_TYPE_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
case COPY_UNSUPPORTED_CONVERSION: case COPY_UNSUPPORTED_CONVERSION:
stmt->errormsg = "Couldn't handle the necessary data type conversion."; stmt->errormsg = "Couldn't handle the necessary data type conversion.";
stmt->errornumber = STMT_RESTRICTED_DATA_TYPE_ERROR; stmt->errornumber = STMT_RESTRICTED_DATA_TYPE_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
case COPY_RESULT_TRUNCATED: case COPY_RESULT_TRUNCATED:
...@@ -544,14 +572,17 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt); ...@@ -544,14 +572,17 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt);
return SQL_SUCCESS_WITH_INFO; return SQL_SUCCESS_WITH_INFO;
case COPY_GENERAL_ERROR: /* error msg already filled in */ case COPY_GENERAL_ERROR: /* error msg already filled in */
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
case COPY_NO_DATA_FOUND: case COPY_NO_DATA_FOUND:
SC_log_error(func, "no data found", stmt);
return SQL_NO_DATA_FOUND; return SQL_NO_DATA_FOUND;
default: default:
stmt->errormsg = "Unrecognized return value from copy_and_convert_field."; stmt->errormsg = "Unrecognized return value from copy_and_convert_field.";
stmt->errornumber = STMT_INTERNAL_ERROR; stmt->errornumber = STMT_INTERNAL_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
} }
...@@ -562,6 +593,7 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt); ...@@ -562,6 +593,7 @@ mylog("SQLGetData: enter, stmt=%u\n", stmt);
RETCODE SQL_API SQLFetch( RETCODE SQL_API SQLFetch(
HSTMT hstmt) HSTMT hstmt)
{ {
char *func = "SQLFetch";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
QResultClass *res; QResultClass *res;
int retval; int retval;
...@@ -571,14 +603,17 @@ char *value; ...@@ -571,14 +603,17 @@ char *value;
ColumnInfoClass *ci; ColumnInfoClass *ci;
// TupleField *tupleField; // TupleField *tupleField;
if ( ! stmt) if ( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
SC_clear_error(stmt); SC_clear_error(stmt);
if ( ! (res = stmt->result)) { if ( ! (res = stmt->result)) {
stmt->errormsg = "Null statement result in SQLFetch."; stmt->errormsg = "Null statement result in SQLFetch.";
stmt->errornumber = STMT_SEQUENCE_ERROR; stmt->errornumber = STMT_SEQUENCE_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -587,6 +622,7 @@ ColumnInfoClass *ci; ...@@ -587,6 +622,7 @@ ColumnInfoClass *ci;
if (stmt->status == STMT_EXECUTING) { if (stmt->status == STMT_EXECUTING) {
stmt->errormsg = "Can't fetch while statement is still executing."; stmt->errormsg = "Can't fetch while statement is still executing.";
stmt->errornumber = STMT_SEQUENCE_ERROR; stmt->errornumber = STMT_SEQUENCE_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -594,6 +630,7 @@ ColumnInfoClass *ci; ...@@ -594,6 +630,7 @@ ColumnInfoClass *ci;
if (stmt->status != STMT_FINISHED) { if (stmt->status != STMT_FINISHED) {
stmt->errornumber = STMT_STATUS_ERROR; stmt->errornumber = STMT_STATUS_ERROR;
stmt->errormsg = "Fetch can only be called after the successful execution on a SQL statement"; stmt->errormsg = "Fetch can only be called after the successful execution on a SQL statement";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -602,6 +639,7 @@ ColumnInfoClass *ci; ...@@ -602,6 +639,7 @@ ColumnInfoClass *ci;
// function even if SQL_ExecDirect has reported an Error // function even if SQL_ExecDirect has reported an Error
stmt->errormsg = "Bindings were not allocated properly."; stmt->errormsg = "Bindings were not allocated properly.";
stmt->errornumber = STMT_SEQUENCE_ERROR; stmt->errornumber = STMT_SEQUENCE_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -638,6 +676,7 @@ ColumnInfoClass *ci; ...@@ -638,6 +676,7 @@ ColumnInfoClass *ci;
mylog("SQLFetch: error\n"); mylog("SQLFetch: error\n");
stmt->errornumber = STMT_EXEC_ERROR; stmt->errornumber = STMT_EXEC_ERROR;
stmt->errormsg = "Error fetching next row"; stmt->errormsg = "Error fetching next row";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
} }
...@@ -675,11 +714,13 @@ ColumnInfoClass *ci; ...@@ -675,11 +714,13 @@ ColumnInfoClass *ci;
if(retval == COPY_UNSUPPORTED_TYPE) { if(retval == COPY_UNSUPPORTED_TYPE) {
stmt->errormsg = "Received an unsupported type from Postgres."; stmt->errormsg = "Received an unsupported type from Postgres.";
stmt->errornumber = STMT_RESTRICTED_DATA_TYPE_ERROR; stmt->errornumber = STMT_RESTRICTED_DATA_TYPE_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} else if(retval == COPY_UNSUPPORTED_CONVERSION) { } else if(retval == COPY_UNSUPPORTED_CONVERSION) {
stmt->errormsg = "Couldn't handle the necessary data type conversion."; stmt->errormsg = "Couldn't handle the necessary data type conversion.";
stmt->errornumber = STMT_RESTRICTED_DATA_TYPE_ERROR; stmt->errornumber = STMT_RESTRICTED_DATA_TYPE_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} else if(retval == COPY_RESULT_TRUNCATED) { } else if(retval == COPY_RESULT_TRUNCATED) {
...@@ -692,6 +733,7 @@ ColumnInfoClass *ci; ...@@ -692,6 +733,7 @@ ColumnInfoClass *ci;
} else if(retval != COPY_OK) { } else if(retval != COPY_OK) {
stmt->errormsg = "Unrecognized return value from copy_and_convert_field."; stmt->errormsg = "Unrecognized return value from copy_and_convert_field.";
stmt->errornumber = STMT_INTERNAL_ERROR; stmt->errornumber = STMT_INTERNAL_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -710,6 +752,7 @@ RETCODE SQL_API SQLExtendedFetch( ...@@ -710,6 +752,7 @@ RETCODE SQL_API SQLExtendedFetch(
UDWORD FAR *pcrow, UDWORD FAR *pcrow,
UWORD FAR *rgfRowStatus) UWORD FAR *rgfRowStatus)
{ {
char *func = "SQLExtendedFetch";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
int num_tuples; int num_tuples;
RETCODE result; RETCODE result;
...@@ -717,11 +760,15 @@ RETCODE result; ...@@ -717,11 +760,15 @@ RETCODE result;
mylog("SQLExtendedFetch: stmt=%u\n", stmt); mylog("SQLExtendedFetch: stmt=%u\n", stmt);
if ( ! stmt) if ( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
if ( globals.use_declarefetch) if ( globals.use_declarefetch) {
SC_log_error(func, "SQLExtendedFetch with UseDeclareFetch not yet supported", stmt);
return SQL_ERROR; return SQL_ERROR;
}
/* Initialize to no rows fetched */ /* Initialize to no rows fetched */
if (rgfRowStatus) if (rgfRowStatus)
...@@ -776,6 +823,7 @@ mylog("SQLExtendedFetch: stmt=%u\n", stmt); ...@@ -776,6 +823,7 @@ mylog("SQLExtendedFetch: stmt=%u\n", stmt);
break; break;
default: default:
SC_log_error(func, "Unsupported SQLExtendedFetch Direction", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -814,6 +862,9 @@ RETCODE SQL_API SQLSetPos( ...@@ -814,6 +862,9 @@ RETCODE SQL_API SQLSetPos(
UWORD fOption, UWORD fOption,
UWORD fLock) UWORD fLock)
{ {
char *func = "SQLSetPos";
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -825,6 +876,9 @@ RETCODE SQL_API SQLSetScrollOptions( ...@@ -825,6 +876,9 @@ RETCODE SQL_API SQLSetScrollOptions(
SDWORD crowKeyset, SDWORD crowKeyset,
UWORD crowRowset) UWORD crowRowset)
{ {
char *func = "SQLSetScrollOptions";
SC_log_error(func, "Function not implemented", (StatementClass *) hstmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -836,20 +890,24 @@ RETCODE SQL_API SQLSetCursorName( ...@@ -836,20 +890,24 @@ RETCODE SQL_API SQLSetCursorName(
UCHAR FAR *szCursor, UCHAR FAR *szCursor,
SWORD cbCursor) SWORD cbCursor)
{ {
char *func="SQLSetCursorName";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
int len; int len;
mylog("SQLSetCursorName: hstmt=%u, szCursor=%u, cbCursorMax=%d\n", mylog("SQLSetCursorName: hstmt=%u, szCursor=%u, cbCursorMax=%d\n",
hstmt, szCursor, cbCursor); hstmt, szCursor, cbCursor);
if ( ! stmt) if ( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
len = (cbCursor == SQL_NTS) ? strlen(szCursor) : cbCursor; len = (cbCursor == SQL_NTS) ? strlen(szCursor) : cbCursor;
mylog("cursor len = %d\n", len); mylog("cursor len = %d\n", len);
if (len <= 0 || len > sizeof(stmt->cursor_name) - 1) { if (len <= 0 || len > sizeof(stmt->cursor_name) - 1) {
stmt->errornumber = STMT_INVALID_CURSOR_NAME; stmt->errornumber = STMT_INVALID_CURSOR_NAME;
stmt->errormsg = "Invalid Cursor Name"; stmt->errormsg = "Invalid Cursor Name";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
strncpy_null(stmt->cursor_name, szCursor, cbCursor); strncpy_null(stmt->cursor_name, szCursor, cbCursor);
...@@ -864,18 +922,22 @@ RETCODE SQL_API SQLGetCursorName( ...@@ -864,18 +922,22 @@ RETCODE SQL_API SQLGetCursorName(
SWORD cbCursorMax, SWORD cbCursorMax,
SWORD FAR *pcbCursor) SWORD FAR *pcbCursor)
{ {
char *func="SQLGetCursorName";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
mylog("SQLGetCursorName: hstmt=%u, szCursor=%u, cbCursorMax=%d, pcbCursor=%u\n", mylog("SQLGetCursorName: hstmt=%u, szCursor=%u, cbCursorMax=%d, pcbCursor=%u\n",
hstmt, szCursor, cbCursorMax, pcbCursor); hstmt, szCursor, cbCursorMax, pcbCursor);
if ( ! stmt) if ( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
if ( stmt->cursor_name[0] == '\0') { if ( stmt->cursor_name[0] == '\0') {
stmt->errornumber = STMT_NO_CURSOR_NAME; stmt->errornumber = STMT_NO_CURSOR_NAME;
stmt->errormsg = "No Cursor name available"; stmt->errormsg = "No Cursor name available";
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
......
...@@ -46,11 +46,14 @@ static struct { ...@@ -46,11 +46,14 @@ static struct {
RETCODE SQL_API SQLAllocStmt(HDBC hdbc, RETCODE SQL_API SQLAllocStmt(HDBC hdbc,
HSTMT FAR *phstmt) HSTMT FAR *phstmt)
{ {
char *func="SQLAllocStmt";
ConnectionClass *conn = (ConnectionClass *) hdbc; ConnectionClass *conn = (ConnectionClass *) hdbc;
StatementClass *stmt; StatementClass *stmt;
if( ! conn) if( ! conn) {
CC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
stmt = SC_Constructor(); stmt = SC_Constructor();
...@@ -60,12 +63,14 @@ StatementClass *stmt; ...@@ -60,12 +63,14 @@ StatementClass *stmt;
conn->errornumber = CONN_STMT_ALLOC_ERROR; conn->errornumber = CONN_STMT_ALLOC_ERROR;
conn->errormsg = "No more memory to allocate a further SQL-statement"; conn->errormsg = "No more memory to allocate a further SQL-statement";
*phstmt = SQL_NULL_HSTMT; *phstmt = SQL_NULL_HSTMT;
CC_log_error(func, "", conn);
return SQL_ERROR; return SQL_ERROR;
} }
if ( ! CC_add_statement(conn, stmt)) { if ( ! CC_add_statement(conn, stmt)) {
conn->errormsg = "Maximum number of connections exceeded."; conn->errormsg = "Maximum number of connections exceeded.";
conn->errornumber = CONN_STMT_ALLOC_ERROR; conn->errornumber = CONN_STMT_ALLOC_ERROR;
CC_log_error(func, "", conn);
SC_Destructor(stmt); SC_Destructor(stmt);
*phstmt = SQL_NULL_HSTMT; *phstmt = SQL_NULL_HSTMT;
return SQL_ERROR; return SQL_ERROR;
...@@ -80,12 +85,15 @@ StatementClass *stmt; ...@@ -80,12 +85,15 @@ StatementClass *stmt;
RETCODE SQL_API SQLFreeStmt(HSTMT hstmt, RETCODE SQL_API SQLFreeStmt(HSTMT hstmt,
UWORD fOption) UWORD fOption)
{ {
char *func="SQLFreeStmt";
StatementClass *stmt = (StatementClass *) hstmt; StatementClass *stmt = (StatementClass *) hstmt;
mylog("**** enter SQLFreeStmt: hstmt=%u, fOption=%d\n", hstmt, fOption); mylog("**** enter SQLFreeStmt: hstmt=%u, fOption=%d\n", hstmt, fOption);
if ( ! stmt) if ( ! stmt) {
SC_log_error(func, "", NULL);
return SQL_INVALID_HANDLE; return SQL_INVALID_HANDLE;
}
if (fOption == SQL_DROP) { if (fOption == SQL_DROP) {
ConnectionClass *conn = stmt->hdbc; ConnectionClass *conn = stmt->hdbc;
...@@ -95,6 +103,7 @@ StatementClass *stmt = (StatementClass *) hstmt; ...@@ -95,6 +103,7 @@ StatementClass *stmt = (StatementClass *) hstmt;
if ( ! CC_remove_statement(conn, stmt)) { if ( ! CC_remove_statement(conn, stmt)) {
stmt->errornumber = STMT_SEQUENCE_ERROR; stmt->errornumber = STMT_SEQUENCE_ERROR;
stmt->errormsg = "Statement is currently executing a transaction."; stmt->errormsg = "Statement is currently executing a transaction.";
SC_log_error(func, "", stmt);
return SQL_ERROR; /* stmt may be executing a transaction */ return SQL_ERROR; /* stmt may be executing a transaction */
} }
...@@ -116,9 +125,11 @@ StatementClass *stmt = (StatementClass *) hstmt; ...@@ -116,9 +125,11 @@ StatementClass *stmt = (StatementClass *) hstmt;
/* this should discard all the results, but leave the statement */ /* this should discard all the results, but leave the statement */
/* itself in place (it can be executed again) */ /* itself in place (it can be executed again) */
if (!SC_recycle_statement(stmt)) if (!SC_recycle_statement(stmt)) {
// errormsg passed in above // errormsg passed in above
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
}
} else if(fOption == SQL_RESET_PARAMS) { } else if(fOption == SQL_RESET_PARAMS) {
SC_free_params(stmt, STMT_FREE_PARAMS_ALL); SC_free_params(stmt, STMT_FREE_PARAMS_ALL);
...@@ -126,6 +137,7 @@ StatementClass *stmt = (StatementClass *) hstmt; ...@@ -126,6 +137,7 @@ StatementClass *stmt = (StatementClass *) hstmt;
} else { } else {
stmt->errormsg = "Invalid option passed to SQLFreeStmt."; stmt->errormsg = "Invalid option passed to SQLFreeStmt.";
stmt->errornumber = STMT_OPTION_OUT_OF_RANGE_ERROR; stmt->errornumber = STMT_OPTION_OUT_OF_RANGE_ERROR;
SC_log_error(func, "", stmt);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -447,6 +459,7 @@ char rv; ...@@ -447,6 +459,7 @@ char rv;
RETCODE SC_execute(StatementClass *self) RETCODE SC_execute(StatementClass *self)
{ {
char *func="SC_execute";
ConnectionClass *conn; ConnectionClass *conn;
QResultClass *res; QResultClass *res;
char ok, was_ok, was_nonfatal; char ok, was_ok, was_nonfatal;
...@@ -466,6 +479,7 @@ Int2 oldstatus, numcols; ...@@ -466,6 +479,7 @@ Int2 oldstatus, numcols;
if ( ! res) { if ( ! res) {
self->errormsg = "Could not begin a transaction"; self->errormsg = "Could not begin a transaction";
self->errornumber = STMT_EXEC_ERROR; self->errornumber = STMT_EXEC_ERROR;
SC_log_error(func, "", self);
return SQL_ERROR; return SQL_ERROR;
} }
...@@ -478,6 +492,7 @@ Int2 oldstatus, numcols; ...@@ -478,6 +492,7 @@ Int2 oldstatus, numcols;
if (!ok) { if (!ok) {
self->errormsg = "Could not begin a transaction"; self->errormsg = "Could not begin a transaction";
self->errornumber = STMT_EXEC_ERROR; self->errornumber = STMT_EXEC_ERROR;
SC_log_error(func, "", self);
return SQL_ERROR; return SQL_ERROR;
} }
else else
...@@ -554,6 +569,7 @@ Int2 oldstatus, numcols; ...@@ -554,6 +569,7 @@ Int2 oldstatus, numcols;
if (self->bindings == NULL) { if (self->bindings == NULL) {
self->errornumber = STMT_NO_MEMORY_ERROR; self->errornumber = STMT_NO_MEMORY_ERROR;
self->errormsg = "Could not get enough free memory to store the binding information"; self->errormsg = "Could not get enough free memory to store the binding information";
SC_log_error(func, "", self);
return SQL_ERROR; return SQL_ERROR;
} }
} }
...@@ -582,6 +598,43 @@ Int2 oldstatus, numcols; ...@@ -582,6 +598,43 @@ Int2 oldstatus, numcols;
else if (self->errornumber == STMT_INFO_ONLY) else if (self->errornumber == STMT_INFO_ONLY)
return SQL_SUCCESS_WITH_INFO; return SQL_SUCCESS_WITH_INFO;
else else {
SC_log_error(func, "", self);
return SQL_ERROR; return SQL_ERROR;
}
}
void
SC_log_error(char *func, char *desc, StatementClass *self)
{
if (self) {
qlog("STATEMENT ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->errornumber, self->errormsg);
qlog(" ------------------------------------------------------------\n");
qlog(" hdbc=%u, stmt=%u, result=%u\n", self->hdbc, self, self->result);
qlog(" manual_result=%d, prepare=%d, internal=%d\n", self->manual_result, self->prepare, self->internal);
qlog(" bindings=%u, bindings_allocated=%d\n", self->bindings, self->bindings_allocated);
qlog(" parameters=%u, parameters_allocated=%d\n", self->parameters, self->parameters_allocated);
qlog(" statement_type=%d, statement='%s'\n", self->statement_type, self->statement);
qlog(" stmt_with_params='%s'\n", self->stmt_with_params);
qlog(" data_at_exec=%d, current_exec_param=%d, put_data=%d\n", self->data_at_exec, self->current_exec_param, self->put_data);
qlog(" currTuple=%d, current_col=%d, lobj_fd=%d\n", self->currTuple, self->current_col, self->lobj_fd);
qlog(" maxRows=%d, rowset_size=%d, keyset_size=%d, cursor_type=%d, scroll_concurrency=%d\n", self->maxRows, self->rowset_size, self->keyset_size, self->cursor_type, self->scroll_concurrency);
qlog(" cursor_name='%s'\n", self->cursor_name);
qlog(" ----------------QResult Info -------------------------------\n");
if (self->result) {
QResultClass *res = self->result;
qlog(" fields=%u, manual_tuples=%u, backend_tuples=%u, tupleField=%d, conn=%u\n", res->fields, res->manual_tuples, res->backend_tuples, res->tupleField, res->conn);
qlog(" fetch_count=%d, fcount=%d, num_fields=%d, cursor='%s'\n", res->fetch_count, res->fcount, res->num_fields, res->cursor);
qlog(" message='%s', command='%s', notice='%s'\n", res->message, res->command, res->notice);
qlog(" status=%d, inTuples=%d\n", res->status, res->inTuples);
}
// Log the connection error if there is one
CC_log_error(func, desc, self->hdbc);
}
else
qlog("INVALID STATEMENT HANDLE ERROR: func=%s, desc='%s'\n", func, desc);
} }
...@@ -132,5 +132,6 @@ char SC_get_error(StatementClass *self, int *number, char **message); ...@@ -132,5 +132,6 @@ char SC_get_error(StatementClass *self, int *number, char **message);
char *SC_create_errormsg(StatementClass *self); char *SC_create_errormsg(StatementClass *self);
RETCODE SC_execute(StatementClass *stmt); RETCODE SC_execute(StatementClass *stmt);
void SC_free_params(StatementClass *self, char option); void SC_free_params(StatementClass *self, char option);
void SC_log_error(char *func, char *desc, StatementClass *self);
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment