4 * Description: This module contains routines for getting/setting
5 * connection and statement options.
9 * API functions: SQLSetConnectOption, SQLSetStmtOption, SQLGetConnectOption,
12 * Comments: See "notice.txt" for copyright and license information.
20 #include "connection.h"
21 #include "statement.h"
23 #include "pgapifunc.h"
27 RETCODE set_statement_option(ConnectionClass *conn,
34 set_statement_option(ConnectionClass *conn,
39 static char *func = "set_statement_option";
44 ci = &(conn->connInfo);
46 ci = &(SC_get_conn(stmt)->connInfo);
49 case SQL_ASYNC_ENABLE: /* ignored */
53 /* now support multi-column and multi-row binding */
55 conn->stmtOptions.bind_size = vParam;
57 stmt->options.bind_size = vParam;
63 * positioned update isn't supported so cursor concurrency is
66 mylog("SetStmtOption(): SQL_CONCURRENCY = %d\n", vParam);
67 if (ci->drivers.lie || vParam == SQL_CONCUR_READ_ONLY || vParam == SQL_CONCUR_ROWVER)
70 conn->stmtOptions.scroll_concurrency = vParam;
72 stmt->options.scroll_concurrency = vParam;
77 conn->stmtOptions.scroll_concurrency = SQL_CONCUR_ROWVER;
79 stmt->options.scroll_concurrency = SQL_CONCUR_ROWVER;
87 * if declare/fetch, then type can only be forward. otherwise,
88 * it can only be forward or static.
90 mylog("SetStmtOption(): SQL_CURSOR_TYPE = %d\n", vParam);
95 conn->stmtOptions.cursor_type = vParam;
97 stmt->options.cursor_type = vParam;
101 if (ci->drivers.use_declarefetch)
104 conn->stmtOptions.cursor_type = SQL_CURSOR_FORWARD_ONLY;
106 stmt->options.cursor_type = SQL_CURSOR_FORWARD_ONLY;
108 if (vParam != SQL_CURSOR_FORWARD_ONLY)
113 if (vParam == SQL_CURSOR_FORWARD_ONLY || vParam == SQL_CURSOR_STATIC)
116 conn->stmtOptions.cursor_type = vParam; /* valid type */
118 stmt->options.cursor_type = vParam; /* valid type */
123 conn->stmtOptions.cursor_type = SQL_CURSOR_STATIC;
125 stmt->options.cursor_type = SQL_CURSOR_STATIC;
133 case SQL_KEYSET_SIZE: /* ignored, but saved and returned */
134 mylog("SetStmtOption(): SQL_KEYSET_SIZE, vParam = %d\n", vParam);
137 conn->stmtOptions.keyset_size = vParam;
139 stmt->options.keyset_size = vParam;
144 * if (ci->drivers.lie)
145 * stmt->keyset_size = vParam;
148 * stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
149 * stmt->errormsg = "Driver does not support keyset size option";
150 * SC_log_error(func, "", stmt);
156 case SQL_MAX_LENGTH: /* ignored, but saved */
157 mylog("SetStmtOption(): SQL_MAX_LENGTH, vParam = %d\n", vParam);
159 conn->stmtOptions.maxLength = vParam;
161 stmt->options.maxLength = vParam;
164 case SQL_MAX_ROWS: /* ignored, but saved */
165 mylog("SetStmtOption(): SQL_MAX_ROWS, vParam = %d\n", vParam);
167 conn->stmtOptions.maxRows = vParam;
169 stmt->options.maxRows = vParam;
172 case SQL_NOSCAN: /* ignored */
173 mylog("SetStmtOption: SQL_NOSCAN, vParam = %d\n", vParam);
176 case SQL_QUERY_TIMEOUT:/* ignored */
177 mylog("SetStmtOption: SQL_QUERY_TIMEOUT, vParam = %d\n", vParam);
178 /* "0" returned in SQLGetStmtOption */
181 case SQL_RETRIEVE_DATA:/* ignored, but saved */
182 mylog("SetStmtOption(): SQL_RETRIEVE_DATA, vParam = %d\n", vParam);
184 conn->stmtOptions.retrieve_data = vParam;
186 stmt->options.retrieve_data = vParam;
189 case SQL_ROWSET_SIZE:
190 mylog("SetStmtOption(): SQL_ROWSET_SIZE, vParam = %d\n", vParam);
193 * Save old rowset size for SQLExtendedFetch purposes If the
194 * rowset_size is being changed since the last call to fetch
198 if (stmt && stmt->save_rowset_size <= 0 && stmt->last_fetch_count > 0)
199 stmt->save_rowset_size = stmt->options.rowset_size;
208 conn->stmtOptions.rowset_size = vParam;
210 stmt->options.rowset_size = vParam;
213 case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */
216 stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
217 stmt->errormsg = "Simulated positioned update/delete not supported. Use the cursor library.";
218 SC_log_error(func, "", stmt);
222 conn->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
223 conn->errormsg = "Simulated positioned update/delete not supported. Use the cursor library.";
224 CC_log_error(func, "", conn);
228 case SQL_USE_BOOKMARKS:
230 stmt->options.use_bookmarks = vParam;
232 conn->stmtOptions.use_bookmarks = vParam;
241 stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
242 stmt->errormsg = "Unknown statement option (Set)";
243 sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam);
244 SC_log_error(func, option, stmt);
248 conn->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
249 conn->errormsg = "Unknown statement option (Set)";
250 sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam);
251 CC_log_error(func, option, conn);
262 stmt->errormsg = "Requested value changed.";
263 stmt->errornumber = STMT_OPTION_VALUE_CHANGED;
267 conn->errormsg = "Requested value changed.";
268 conn->errornumber = STMT_OPTION_VALUE_CHANGED;
270 return SQL_SUCCESS_WITH_INFO;
277 /* Implements only SQL_AUTOCOMMIT */
279 PGAPI_SetConnectOption(
284 static char *func = "PGAPI_SetConnectOption";
285 ConnectionClass *conn = (ConnectionClass *) hdbc;
286 char changed = FALSE;
290 mylog("%s: entering fOption = %d vParam = %d\n", func, fOption, vParam);
293 CC_log_error(func, "", NULL);
294 return SQL_INVALID_HANDLE;
301 * Statement Options (apply to all stmts on the connection and
302 * become defaults for new stmts)
304 case SQL_ASYNC_ENABLE:
306 case SQL_CONCURRENCY:
307 case SQL_CURSOR_TYPE:
308 case SQL_KEYSET_SIZE:
312 case SQL_QUERY_TIMEOUT:
313 case SQL_RETRIEVE_DATA:
314 case SQL_ROWSET_SIZE:
315 case SQL_SIMULATE_CURSOR:
316 case SQL_USE_BOOKMARKS:
318 /* Affect all current Statements */
319 for (i = 0; i < conn->num_stmts; i++)
322 set_statement_option(NULL, conn->stmts[i], fOption, vParam);
326 * Become the default for all future statements on this
329 retval = set_statement_option(conn, NULL, fOption, vParam);
331 if (retval == SQL_SUCCESS_WITH_INFO)
333 else if (retval == SQL_ERROR)
342 case SQL_ACCESS_MODE: /* ignored */
346 if (CC_is_in_trans(conn))
348 conn->errormsg = "Cannot switch commit mode while a transaction is in progress";
349 conn->errornumber = CONN_TRANSACT_IN_PROGRES;
350 CC_log_error(func, "", conn);
354 mylog("PGAPI_SetConnectOption: AUTOCOMMIT: transact_status=%d, vparam=%d\n", conn->transact_status, vParam);
358 case SQL_AUTOCOMMIT_OFF:
359 CC_set_autocommit_off(conn);
362 case SQL_AUTOCOMMIT_ON:
363 CC_set_autocommit_on(conn);
367 conn->errormsg = "Illegal parameter value for SQL_AUTOCOMMIT";
368 conn->errornumber = CONN_INVALID_ARGUMENT_NO;
369 CC_log_error(func, "", conn);
374 case SQL_CURRENT_QUALIFIER: /* ignored */
377 case SQL_LOGIN_TIMEOUT:/* ignored */
380 case SQL_PACKET_SIZE: /* ignored */
383 case SQL_QUIET_MODE: /* ignored */
386 case SQL_TXN_ISOLATION:/* ignored */
389 /* These options should be handled by driver manager */
390 case SQL_ODBC_CURSORS:
392 case SQL_OPT_TRACEFILE:
393 case SQL_TRANSLATE_DLL:
394 case SQL_TRANSLATE_OPTION:
395 CC_log_error(func, "This connect option (Set) is only used by the Driver Manager", conn);
402 conn->errormsg = "Unknown connect option (Set)";
403 conn->errornumber = CONN_UNSUPPORTED_OPTION;
404 sprintf(option, "fOption=%d, vParam=%ld", fOption, vParam);
405 if (fOption == 30002 && vParam)
407 if (strcmp((char *) vParam, "Microsoft Jet") == 0)
409 conn->errornumber = 0;
414 CC_log_error(func, option, conn);
421 conn->errornumber = CONN_OPTION_VALUE_CHANGED;
422 conn->errormsg = "Requested value changed.";
423 return SQL_SUCCESS_WITH_INFO;
430 /* This function just can tell you whether you are in Autcommit mode or not */
432 PGAPI_GetConnectOption(
437 static char *func = "PGAPI_GetConnectOption";
438 ConnectionClass *conn = (ConnectionClass *) hdbc;
439 ConnInfo *ci = &(conn->connInfo);
441 mylog("%s: entering...\n", func);
445 CC_log_error(func, "", NULL);
446 return SQL_INVALID_HANDLE;
451 case SQL_ACCESS_MODE: /* NOT SUPPORTED */
452 *((UDWORD *) pvParam) = SQL_MODE_READ_WRITE;
456 *((UDWORD *) pvParam) = (UDWORD) (CC_is_in_autocommit(conn) ?
457 SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF);
460 case SQL_CURRENT_QUALIFIER: /* don't use qualifiers */
466 case SQL_LOGIN_TIMEOUT:/* NOT SUPPORTED */
467 *((UDWORD *) pvParam) = 0;
470 case SQL_PACKET_SIZE: /* NOT SUPPORTED */
471 *((UDWORD *) pvParam) = ci->drivers.socket_buffersize;
474 case SQL_QUIET_MODE: /* NOT SUPPORTED */
475 *((UDWORD *) pvParam) = (UDWORD) NULL;
478 case SQL_TXN_ISOLATION:/* NOT SUPPORTED */
479 *((UDWORD *) pvParam) = SQL_TXN_SERIALIZABLE;
482 /* These options should be handled by driver manager */
483 case SQL_ODBC_CURSORS:
485 case SQL_OPT_TRACEFILE:
486 case SQL_TRANSLATE_DLL:
487 case SQL_TRANSLATE_OPTION:
488 CC_log_error(func, "This connect option (Get) is only used by the Driver Manager", conn);
495 conn->errormsg = "Unknown connect option (Get)";
496 conn->errornumber = CONN_UNSUPPORTED_OPTION;
497 sprintf(option, "fOption=%d", fOption);
498 CC_log_error(func, option, conn);
514 static char *func = "PGAPI_SetStmtOption";
515 StatementClass *stmt = (StatementClass *) hstmt;
517 mylog("%s: entering...\n", func);
520 * Though we could fake Access out by just returning SQL_SUCCESS all
521 * the time, but it tries to set a huge value for SQL_MAX_LENGTH and
522 * expects the driver to reduce it to the real value.
526 SC_log_error(func, "", NULL);
527 return SQL_INVALID_HANDLE;
530 return set_statement_option(NULL, stmt, fOption, vParam);
540 static char *func = "PGAPI_GetStmtOption";
541 StatementClass *stmt = (StatementClass *) hstmt;
543 ConnInfo *ci = &(SC_get_conn(stmt)->connInfo);
545 mylog("%s: entering...\n", func);
548 * thought we could fake Access out by just returning SQL_SUCCESS all
549 * the time, but it tries to set a huge value for SQL_MAX_LENGTH and
550 * expects the driver to reduce it to the real value
554 SC_log_error(func, "", NULL);
555 return SQL_INVALID_HANDLE;
560 case SQL_GET_BOOKMARK:
565 if (stmt->manual_result || !ci->drivers.use_declarefetch)
567 /* make sure we're positioned on a valid row */
568 if ((stmt->currTuple < 0) ||
569 (stmt->currTuple >= QR_get_num_tuples(res)))
571 stmt->errormsg = "Not positioned on a valid row.";
572 stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR;
573 SC_log_error(func, "", stmt);
579 if (stmt->currTuple == -1 || !res || !res->tupleField)
581 stmt->errormsg = "Not positioned on a valid row.";
582 stmt->errornumber = STMT_INVALID_CURSOR_STATE_ERROR;
583 SC_log_error(func, "", stmt);
588 if (fOption == SQL_GET_BOOKMARK && stmt->options.use_bookmarks == SQL_UB_OFF)
590 stmt->errormsg = "Operation invalid because use bookmarks not enabled.";
591 stmt->errornumber = STMT_OPERATION_INVALID;
592 SC_log_error(func, "", stmt);
596 *((UDWORD *) pvParam) = SC_get_bookmark(stmt);
600 case SQL_ASYNC_ENABLE: /* NOT SUPPORTED */
601 *((SDWORD *) pvParam) = SQL_ASYNC_ENABLE_OFF;
605 *((SDWORD *) pvParam) = stmt->options.bind_size;
608 case SQL_CONCURRENCY: /* NOT REALLY SUPPORTED */
609 mylog("GetStmtOption(): SQL_CONCURRENCY\n");
610 *((SDWORD *) pvParam) = stmt->options.scroll_concurrency;
613 case SQL_CURSOR_TYPE: /* PARTIAL SUPPORT */
614 mylog("GetStmtOption(): SQL_CURSOR_TYPE\n");
615 *((SDWORD *) pvParam) = stmt->options.cursor_type;
618 case SQL_KEYSET_SIZE: /* NOT SUPPORTED, but saved */
619 mylog("GetStmtOption(): SQL_KEYSET_SIZE\n");
620 *((SDWORD *) pvParam) = stmt->options.keyset_size;
623 case SQL_MAX_LENGTH: /* NOT SUPPORTED, but saved */
624 *((SDWORD *) pvParam) = stmt->options.maxLength;
627 case SQL_MAX_ROWS: /* NOT SUPPORTED, but saved */
628 *((SDWORD *) pvParam) = stmt->options.maxRows;
629 mylog("GetSmtOption: MAX_ROWS, returning %d\n", stmt->options.maxRows);
632 case SQL_NOSCAN: /* NOT SUPPORTED */
633 *((SDWORD *) pvParam) = SQL_NOSCAN_ON;
636 case SQL_QUERY_TIMEOUT:/* NOT SUPPORTED */
637 *((SDWORD *) pvParam) = 0;
640 case SQL_RETRIEVE_DATA:/* NOT SUPPORTED, but saved */
641 *((SDWORD *) pvParam) = stmt->options.retrieve_data;
644 case SQL_ROWSET_SIZE:
645 *((SDWORD *) pvParam) = stmt->options.rowset_size;
648 case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */
649 *((SDWORD *) pvParam) = SQL_SC_NON_UNIQUE;
652 case SQL_USE_BOOKMARKS:
653 *((SDWORD *) pvParam) = stmt->options.use_bookmarks;
660 stmt->errornumber = STMT_NOT_IMPLEMENTED_ERROR;
661 stmt->errormsg = "Unknown statement option (Get)";
662 sprintf(option, "fOption=%d", fOption);
663 SC_log_error(func, option, stmt);