2) Cleanup copy_and_convert_field() a little.
3) Set an error number and an error message for SQLAllocHandle(
SQL_HANDLE_DESC).
#endif /* ODBCVER */
break;
default:
- SC_set_error(stmt, STMT_PROGRAM_TYPE_OUT_OF_RANGE, "Column 0 is not of type SQL_C_BOOKMARK");
-inolog("Column 0 is type %d not of type SQL_C_BOOKMARK", fCType);
+ SC_set_error(stmt, STMT_PROGRAM_TYPE_OUT_OF_RANGE, "Bind column 0 is not of type SQL_C_BOOKMARK");
+inolog("Bind column 0 is type %d not of type SQL_C_BOOKMARK", fCType);
SC_log_error(func, "", stmt);
return SQL_ERROR;
}
opts->bookmark->buffer = rgbValue;
opts->bookmark->used = pcbValue;
+ opts->bookmark->buflen = cbValueMax;
+ opts->bookmark->returntype = fCType;
}
return SQL_SUCCESS;
}
#endif /* HAVE_LOCALTIME_R */
int pcbValueOffset,
rgbValueOffset;
- char *rgbValueBindRow;
+ char *rgbValueBindRow, *pcbValueBindRow = NULL;
const char *ptr;
int bind_row = stmt->bind_row;
int bind_size = opts->bind_size;
{
pcbValueOffset = bind_row * sizeof(SDWORD);
rgbValueOffset = bind_row * cbValueMax;
-
}
+ /*
+ * The following is applicable in case bind_size > 0
+ * or the fCType is of variable length.
+ */
+ rgbValueBindRow = (char *) rgbValue + rgbValueOffset;
+ if (pcbValue)
+ pcbValueBindRow = (char *) pcbValue + pcbValueOffset;
memset(&std_time, 0, sizeof(SIMPLE_TIME));
*/
if (pcbValue)
{
- *(SDWORD *) ((char *) pcbValue + pcbValueOffset) = SQL_NULL_DATA;
+ *((SDWORD *) pcbValueBindRow) = SQL_NULL_DATA;
return COPY_OK;
}
else
const char *vp;
/* this is an array of eight integers */
- short *short_array = (short *) ((char *) rgbValue + rgbValueOffset);
+ short *short_array = (short *) rgbValueBindRow;
len = INDEX_KEYS_STORAGE_COUNT * 2;
vp = value;
/* There is no corresponding fCType for this. */
if (pcbValue)
- *(SDWORD *) ((char *) pcbValue + pcbValueOffset) = len;
+ *((SDWORD *) pcbValueBindRow) = len;
return COPY_OK; /* dont go any further or the data will be
* trashed */
*/
case PG_TYPE_LO_UNDEFINED:
- return convert_lo(stmt, value, fCType, ((char *) rgbValue + rgbValueOffset), cbValueMax, (SDWORD *) ((char *) pcbValue + pcbValueOffset));
+ return convert_lo(stmt, value, fCType, rgbValueBindRow, cbValueMax, (SDWORD *) pcbValueBindRow);
default:
if (field_type == stmt->hdbc->lobj_type) /* hack until permanent
* type available */
- return convert_lo(stmt, value, fCType, ((char *) rgbValue + rgbValueOffset), cbValueMax, (SDWORD *) ((char *) pcbValue + pcbValueOffset));
+ return convert_lo(stmt, value, fCType, rgbValueBindRow, cbValueMax, (SDWORD *) pcbValueBindRow);
}
/* Change default into something useable */
mylog("copy_and_convert, SQL_C_DEFAULT: fCType = %d\n", fCType);
}
- rgbValueBindRow = (char *) rgbValue + rgbValueOffset;
-
#ifdef UNICODE_SUPPORT
if (fCType == SQL_C_CHAR || fCType == SQL_C_WCHAR
#else
DATE_STRUCT *ds;
if (bind_size > 0)
- ds = (DATE_STRUCT *) ((char *) rgbValue + (bind_row * bind_size));
+ ds = (DATE_STRUCT *) rgbValueBindRow;
else
ds = (DATE_STRUCT *) rgbValue + bind_row;
ds->year = std_time.y;
TIME_STRUCT *ts;
if (bind_size > 0)
- ts = (TIME_STRUCT *) ((char *) rgbValue + (bind_row * bind_size));
+ ts = (TIME_STRUCT *) rgbValueBindRow;
else
ts = (TIME_STRUCT *) rgbValue + bind_row;
ts->hour = std_time.hh;
TIMESTAMP_STRUCT *ts;
if (bind_size > 0)
- ts = (TIMESTAMP_STRUCT *) ((char *) rgbValue + (bind_row * bind_size));
+ ts = (TIMESTAMP_STRUCT *) rgbValueBindRow;
else
ts = (TIMESTAMP_STRUCT *) rgbValue + bind_row;
ts->year = std_time.y;
case SQL_C_BIT:
len = 1;
if (bind_size > 0)
- *(UCHAR *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(neut_str);
+ *((UCHAR *) rgbValueBindRow) = atoi(neut_str);
else
*((UCHAR *) rgbValue + bind_row) = atoi(neut_str);
case SQL_C_TINYINT:
len = 1;
if (bind_size > 0)
- *(SCHAR *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(neut_str);
+ *((SCHAR *) rgbValueBindRow) = atoi(neut_str);
else
*((SCHAR *) rgbValue + bind_row) = atoi(neut_str);
break;
case SQL_C_UTINYINT:
len = 1;
if (bind_size > 0)
- *(UCHAR *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(neut_str);
+ *((UCHAR *) rgbValueBindRow) = atoi(neut_str);
else
*((UCHAR *) rgbValue + bind_row) = atoi(neut_str);
break;
#endif /* HAVE_LOCALE_H */
len = 4;
if (bind_size > 0)
- *(SFLOAT *) ((char *) rgbValue + (bind_row * bind_size)) = (float) atof(neut_str);
+ *((SFLOAT *) rgbValueBindRow) = (float) atof(neut_str);
else
*((SFLOAT *) rgbValue + bind_row) = (float) atof(neut_str);
#ifdef HAVE_LOCALE_H
#endif /* HAVE_LOCALE_H */
len = 8;
if (bind_size > 0)
- *(SDOUBLE *) ((char *) rgbValue + (bind_row * bind_size)) = atof(neut_str);
+ *((SDOUBLE *) rgbValueBindRow) = atof(neut_str);
else
*((SDOUBLE *) rgbValue + bind_row) = atof(neut_str);
#ifdef HAVE_LOCALE_H
len = sizeof(SQL_NUMERIC_STRUCT);
if (bind_size > 0)
- ns = (SQL_NUMERIC_STRUCT *) ((char *) rgbValue + (bind_row * bind_size));
+ ns = (SQL_NUMERIC_STRUCT *) rgbValueBindRow;
else
ns = (SQL_NUMERIC_STRUCT *) rgbValue + bind_row;
for (wv = neut_str; *wv && isspace(*wv); wv++)
case SQL_C_SHORT:
len = 2;
if (bind_size > 0)
- *(SWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(neut_str);
+ *((SWORD *) rgbValueBindRow) = atoi(neut_str);
else
*((SWORD *) rgbValue + bind_row) = atoi(neut_str);
break;
case SQL_C_USHORT:
len = 2;
if (bind_size > 0)
- *(UWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atoi(neut_str);
+ *((UWORD *) rgbValueBindRow) = atoi(neut_str);
else
*((UWORD *) rgbValue + bind_row) = atoi(neut_str);
break;
case SQL_C_LONG:
len = 4;
if (bind_size > 0)
- *(SDWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atol(neut_str);
+ *((SDWORD *) rgbValueBindRow) = atol(neut_str);
else
*((SDWORD *) rgbValue + bind_row) = atol(neut_str);
break;
case SQL_C_ULONG:
len = 4;
if (bind_size > 0)
- *(UDWORD *) ((char *) rgbValue + (bind_row * bind_size)) = atol(neut_str);
+ *((UDWORD *) rgbValueBindRow) = atol(neut_str);
else
*((UDWORD *) rgbValue + bind_row) = atol(neut_str);
break;
case SQL_C_SBIGINT:
len = 8;
if (bind_size > 0)
- *(SQLBIGINT *) ((char *) rgbValue + (bind_row * bind_size)) = ATOI64(neut_str);
+ *((SQLBIGINT *) rgbValueBindRow) = ATOI64(neut_str);
else
*((SQLBIGINT *) rgbValue + bind_row) = ATOI64(neut_str);
break;
case SQL_C_UBIGINT:
len = 8;
if (bind_size > 0)
- *(SQLUBIGINT *) ((char *) rgbValue + (bind_row * bind_size)) = ATOI64U(neut_str);
+ *((SQLUBIGINT *) rgbValueBindRow) = ATOI64U(neut_str);
else
*((SQLUBIGINT *) rgbValue + bind_row) = ATOI64U(neut_str);
break;
if (PG_TYPE_UNKNOWN == field_type)
{
if (pcbValue)
- *(SDWORD *) ((char *) pcbValue + pcbValueOffset) = SQL_NULL_DATA;
+ *((SDWORD *) pcbValueBindRow) = SQL_NULL_DATA;
return COPY_OK;
}
+ /* The following is for SQL_C_VARBOOKMARK */
+ else if (PG_TYPE_INT4 == field_type)
+ {
+ UInt4 ival = atol(neut_str);
+
+inolog("SQL_C_VARBOOKMARK value=%d\n", ival);
+ if (pcbValue)
+ *((SDWORD *) pcbValueBindRow) = sizeof(ival);
+ if (cbValueMax >= sizeof(ival))
+ {
+ memcpy(rgbValueBindRow, &ival, sizeof(ival));
+ return COPY_OK;
+ }
+ else
+ return COPY_RESULT_TRUNCATED;
+ }
else if (PG_TYPE_BYTEA != field_type)
{
mylog("couldn't convert the type %d to SQL_C_BINARY\n", field_type);
/* store the length of what was copied, if there's a place for it */
if (pcbValue)
- *(SDWORD *) ((char *) pcbValue + pcbValueOffset) = len;
+ *((SDWORD *) pcbValueBindRow) = len;
if (result == COPY_OK && stmt->current_col >= 0)
opts->bindings[stmt->current_col].data_left = 0;
if (ci->updatable_cursors)
value |= (SQL_CA1_POS_UPDATE | SQL_CA1_POS_DELETE
| SQL_CA1_BULK_ADD
+ | SQL_CA1_BULK_UPDATE_BY_BOOKMARK
+ | SQL_CA1_BULK_DELETE_BY_BOOKMARK
+ | SQL_CA1_BULK_FETCH_BY_BOOKMARK
);
break;
case SQL_STATIC_CURSOR_ATTRIBUTES2:
if (ci->updatable_cursors)
value |= (SQL_CA2_OPT_ROWVER_CONCURRENCY
| SQL_CA2_CRC_EXACT
- /* | SQL_CA2_SENSITIVITY_ADDITIONS
+ | SQL_CA2_SENSITIVITY_ADDITIONS
| SQL_CA2_SENSITIVITY_DELETIONS
- | SQL_CA2_SENSITIVITY_UPDATES */
+ | SQL_CA2_SENSITIVITY_UPDATES
);
break;
SQLHANDLE InputHandle, SQLHANDLE * OutputHandle)
{
RETCODE ret;
+ ConnectionClass *conn;
+
mylog("[[SQLAllocHandle]]");
switch (HandleType)
{
ret = PGAPI_AllocStmt(InputHandle, OutputHandle);
LEAVE_CONN_CS((ConnectionClass *) InputHandle);
break;
+ case SQL_HANDLE_DESC:
+ conn = (ConnectionClass *) InputHandle;
+ ENTER_CONN_CS(conn);
+ CC_set_error(conn, CONN_NOT_IMPLEMENTED_ERROR, "can't alloc Desc Handle yet");
+ LEAVE_CONN_CS(conn);
+ ret = SQL_ERROR;
+ break;
default:
ret = SQL_ERROR;
break;
opts->bindings[row_idx].buflen = (Int4) Value;
break;
case SQL_DESC_PRECISION:
- opts->bindings[row_idx].precision = (Int2) Value;
+ opts->bindings[row_idx].precision = (Int2)((Int4) Value);
break;
case SQL_DESC_SCALE:
opts->bindings[row_idx].scale = (Int4) Value;
opts->parameters[para_idx].used = Value;
break;
case SQL_DESC_PRECISION:
- opts->parameters[para_idx].precision = (Int2) Value;
+ opts->parameters[para_idx].precision = (Int2) ((Int4) Value);
break;
case SQL_DESC_SCALE:
- opts->parameters[para_idx].scale = (Int2) Value;
+ opts->parameters[para_idx].scale = (Int2) ((Int4) Value);
break;
case SQL_DESC_ALLOC_TYPE: /* read-only */
case SQL_DESC_DATETIME_INTERVAL_PRECISION:
ipdopts->parameters[para_idx].SQLType = (Int4) Value;
break;
case SQL_DESC_PARAMETER_TYPE:
- ipdopts->parameters[para_idx].paramType = (Int2) Value;
+ ipdopts->parameters[para_idx].paramType = (Int2) ((Int4) Value);
break;
case SQL_DESC_SCALE:
- ipdopts->parameters[para_idx].decimal_digits = (Int2) Value;
+ ipdopts->parameters[para_idx].decimal_digits = (Int2) ((Int4) Value);
break;
case SQL_DESC_ALLOC_TYPE: /* read-only */
case SQL_DESC_CASE_SENSITIVE: /* read-only */
}
#ifdef DRIVER_CURSOR_IMPLEMENT
+#define CALC_BOOKMARK_ADDR(book, offset, bind_size, index) \
+ (book->buffer + offset + \
+ (bind_size > 0 ? bind_size : (SQL_C_VARBOOKMARK == book->returntype ? book->buflen : sizeof(UInt4))) * index)
+
RETCODE SQL_API
PGAPI_BulkOperations(HSTMT hstmt, SQLSMALLINT operation)
{
StatementClass *stmt = (StatementClass *) hstmt;
ARDFields *opts = SC_get_ARD(stmt);
RETCODE ret;
- UInt4 offset, bind_size = opts->bind_size, *bmark = NULL,
+ UInt4 offset, bind_size = opts->bind_size,
global_idx;
int i, processed;
ConnectionClass *conn;
BOOL auto_commit_needed = FALSE;
QResultClass *res;
+ BindInfoClass *bookmark;
mylog("%s operation = %d\n", func, operation);
SC_clear_error(stmt);
}
if (SQL_ADD != operation)
{
- if (bmark = (UInt4 *) opts->bookmark->buffer, !bmark)
+ if (!(bookmark = opts->bookmark) || !(bookmark->buffer))
{
SC_set_error(stmt, STMT_INVALID_OPTION_IDENTIFIER, "bookmark isn't specified");
return SQL_ERROR;
}
- bmark = (UInt4 *)(((char *) bmark) + offset);
}
for (i = 0, processed = 0; i < opts->rowset_size; i++)
{
- if (bmark)
+ if (SQL_ADD != operation)
{
- global_idx = *bmark - 1;
+ memcpy(&global_idx, CALC_BOOKMARK_ADDR(bookmark, offset, bind_size, i), sizeof(UInt4));
+ global_idx--;
}
/* Note opts->row_operation_ptr is ignored */
switch (operation)
processed++;
if (SQL_ERROR == ret)
break;
- if (SQL_ADD != operation)
- {
- if (bind_size > 0)
- bmark += (bind_size >> 2);
- else
- bmark++;
- }
}
if (auto_commit_needed)
PGAPI_SetConnectOption(conn, SQL_AUTOCOMMIT, SQL_AUTOCOMMIT_ON);
#endif /* ODBCVER */
break;
default:
-inolog("Column 0 is type %d not of type SQL_C_BOOKMARK", fCType);
+inolog("GetData Column 0 is type %d not of type SQL_C_BOOKMARK", fCType);
SC_set_error(stmt, STMT_PROGRAM_TYPE_OUT_OF_RANGE, "Column 0 is not of type SQL_C_BOOKMARK");
SC_log_error(func, "", stmt);
return SQL_ERROR;
if (get_bookmark)
{
- *((UDWORD *) rgbValue) = SC_get_bookmark(stmt);
+ BOOL contents_get = FALSE;
+ if (rgbValue)
+ {
+ if (SQL_C_BOOKMARK == fCType || 4 <= cbValueMax)
+ {
+ contents_get = TRUE;
+ *((UDWORD *) rgbValue) = SC_get_bookmark(stmt);
+ }
+ }
if (pcbValue)
- *pcbValue = 4;
+ *pcbValue = sizeof(UDWORD);
- return SQL_SUCCESS;
+ if (contents_get)
+ return SQL_SUCCESS;
+ else
+ {
+ SC_set_error(stmt, STMT_TRUNCATED, "The buffer was too small for the GetData.");
+ return SQL_SUCCESS_WITH_INFO;
+ }
}
field_type = QR_get_field_type(res, icol);
ARDFields *opts = SC_get_ARD(stmt);
QResultClass *ires = SC_get_Curres(istmt);
const char *cmdstr;
+ BindInfoClass *bookmark;
cmdstr = QR_get_command((ires->next ? ires->next : ires));
if (cmdstr &&
if (SQL_ERROR == qret)
return qret;
}
- if (opts->bookmark->buffer)
+ bookmark = opts->bookmark;
+ if (bookmark->buffer)
{
char buf[32];
UInt4 offset = opts->row_offset_ptr ? *opts->row_offset_ptr : 0;
- sprintf(buf, "%ld", addpos + 1);
- copy_and_convert_field(stmt, 0, buf,
- SQL_C_ULONG, opts->bookmark->buffer + offset,
- 0, opts->bookmark->used ? opts->bookmark->used
+ sprintf(buf, "%lu", addpos + 1);
+ copy_and_convert_field(stmt,
+ PG_TYPE_INT4,
+ buf,
+ bookmark->returntype,
+ bookmark->buffer + offset,
+ bookmark->buflen,
+ bookmark->used ? bookmark->used
+ (offset >> 2) : NULL);
}
}
#ifndef __VERSION_H__
#define __VERSION_H__
-#define POSTGRESDRIVERVERSION "07.03.0106"
-#define POSTGRES_RESOURCE_VERSION "07.03.0106\0"
-#define PG_DRVFILE_VERSION 7,3,1,06
+#define POSTGRESDRIVERVERSION "07.03.0107"
+#define POSTGRES_RESOURCE_VERSION "07.03.0107\0"
+#define PG_DRVFILE_VERSION 7,3,1,07
#endif