Merge commit 'origin/master'
[versaplex.git] / vxodbc / options.cc
blob54211b596b936c1dd3851eb618a698901fb4eeff
1 /*
2 * Description: This module contains routines for getting/setting
3 * connection and statement options.
4 */
6 #include "psqlodbc.h"
7 #include <string.h>
9 #include "environ.h"
10 #include "connection.h"
11 #include "statement.h"
12 #include "qresult.h"
13 #include "pgapifunc.h"
17 RETCODE
18 set_statement_option(ConnectionClass * conn,
19 StatementClass * stmt,
20 SQLUSMALLINT fOption, SQLULEN vParam)
22 CSTR func = "set_statement_option";
23 char changed = FALSE;
24 ConnInfo *ci = NULL;
25 SQLULEN setval;
27 if (conn)
28 ci = &(conn->connInfo);
29 else if (stmt)
30 ci = &(SC_get_conn(stmt)->connInfo);
31 switch (fOption)
33 case SQL_ASYNC_ENABLE: /* ignored */
34 break;
36 case SQL_BIND_TYPE:
37 /* now support multi-column and multi-row binding */
38 if (conn)
39 conn->ardOptions.bind_size = (SQLUINTEGER) vParam;
40 if (stmt)
41 SC_get_ARDF(stmt)->bind_size = (SQLUINTEGER) vParam;
42 break;
44 case SQL_CONCURRENCY:
47 * positioned update isn't supported so cursor concurrency is
48 * read-only
50 mylog("SetStmtOption(): SQL_CONCURRENCY = %d ", vParam);
51 setval = SQL_CONCUR_READ_ONLY;
52 if (SQL_CONCUR_READ_ONLY == vParam)
54 else if (0 != ci->updatable_cursors)
55 setval = SQL_CONCUR_ROWVER;
56 if (conn)
57 conn->stmtOptions.scroll_concurrency = (SQLUINTEGER) setval;
58 else if (stmt)
60 if (SC_get_Result(stmt))
62 SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR,
63 "The attr can't be changed because the cursor is open.",
64 func);
65 return SQL_ERROR;
67 stmt->options.scroll_concurrency =
68 stmt->options_orig.scroll_concurrency =
69 (SQLUINTEGER) setval;
71 if (setval != vParam)
72 changed = TRUE;
73 mylog("-> %d\n", setval);
74 break;
76 case SQL_CURSOR_TYPE:
79 * if declare/fetch, then type can only be forward. otherwise,
80 * it can only be forward or static.
82 mylog("SetStmtOption(): SQL_CURSOR_TYPE = %d ", vParam);
83 setval = SQL_CURSOR_FORWARD_ONLY;
84 if (SQL_CURSOR_STATIC == vParam)
85 setval = vParam;
86 else if (SQL_CURSOR_KEYSET_DRIVEN == vParam ||
87 SQL_CURSOR_DYNAMIC == vParam)
89 if (0 !=
90 (ci->updatable_cursors & ALLOW_KEYSET_DRIVEN_CURSORS))
91 setval = vParam;
92 else
93 setval = SQL_CURSOR_STATIC; /* at least scrollable */
95 if (conn)
96 conn->stmtOptions.cursor_type = (SQLUINTEGER) setval;
97 else if (stmt)
99 if (SC_get_Result(stmt))
101 SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR,
102 "The attr can't be changed because the cursor is open.",
103 func);
104 return SQL_ERROR;
106 stmt->options_orig.cursor_type =
107 stmt->options.cursor_type = (SQLUINTEGER) setval;
109 if (setval != vParam)
110 changed = TRUE;
111 mylog("-> %d\n", setval);
112 break;
114 case SQL_KEYSET_SIZE: /* ignored, but saved and returned */
115 mylog("SetStmtOption(): SQL_KEYSET_SIZE, vParam = %d\n",
116 vParam);
118 if (conn)
119 conn->stmtOptions.keyset_size = vParam;
120 if (stmt)
122 stmt->options_orig.keyset_size = vParam;
123 if (!SC_get_Result(stmt))
124 stmt->options.keyset_size = vParam;
125 if (stmt->options.keyset_size != (int) vParam)
126 changed = TRUE;
129 break;
131 case SQL_MAX_LENGTH: /* ignored, but saved */
132 mylog("SetStmtOption(): SQL_MAX_LENGTH, vParam = %d\n", vParam);
133 if (conn)
134 conn->stmtOptions.maxLength = vParam;
135 if (stmt)
137 stmt->options_orig.maxLength = vParam;
138 if (!SC_get_Result(stmt))
139 stmt->options.maxLength = vParam;
140 if (stmt->options.maxLength != (int) vParam)
141 changed = TRUE;
143 break;
145 case SQL_MAX_ROWS: /* ignored, but saved */
146 mylog("SetStmtOption(): SQL_MAX_ROWS, vParam = %d\n", vParam);
147 if (conn)
148 conn->stmtOptions.maxRows = vParam;
149 if (stmt)
151 stmt->options_orig.maxRows = vParam;
152 if (!SC_get_Result(stmt))
153 stmt->options.maxRows = vParam;
154 if (stmt->options.maxRows != (int) vParam)
155 changed = TRUE;
157 break;
159 case SQL_NOSCAN: /* ignored */
160 mylog("SetStmtOption: SQL_NOSCAN, vParam = %d\n", vParam);
161 break;
163 case SQL_QUERY_TIMEOUT: /* ignored */
164 mylog("SetStmtOption: SQL_QUERY_TIMEOUT, vParam = %d\n",
165 vParam);
166 /* "0" returned in SQLGetStmtOption */
167 break;
169 case SQL_RETRIEVE_DATA:
170 mylog("SetStmtOption(): SQL_RETRIEVE_DATA, vParam = %d\n",
171 vParam);
172 if (conn)
173 conn->stmtOptions.retrieve_data = (SQLUINTEGER) vParam;
174 if (stmt)
175 stmt->options.retrieve_data = (SQLUINTEGER) vParam;
176 break;
178 case SQL_ROWSET_SIZE:
179 mylog("SetStmtOption(): SQL_ROWSET_SIZE, vParam = %d\n",
180 vParam);
183 * Save old rowset size for SQLExtendedFetch purposes If the
184 * rowset_size is being changed since the last call to fetch
185 * rows.
188 if (stmt && stmt->save_rowset_size <= 0
189 && stmt->last_fetch_count > 0)
190 stmt->save_rowset_size =
191 SC_get_ARDF(stmt)->size_of_rowset_odbc2;
193 if (vParam < 1)
195 vParam = 1;
196 changed = TRUE;
199 if (conn)
200 conn->ardOptions.size_of_rowset_odbc2 = vParam;
201 if (stmt)
202 SC_get_ARDF(stmt)->size_of_rowset_odbc2 = vParam;
203 break;
205 case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */
206 if (stmt)
208 SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR,
209 "Simulated positioned update/delete not supported. Use the cursor library.",
210 func);
212 if (conn)
214 CC_set_error(conn, CONN_NOT_IMPLEMENTED_ERROR,
215 "Simulated positioned update/delete not supported. Use the cursor library.",
216 func);
218 return SQL_ERROR;
220 case SQL_USE_BOOKMARKS:
221 if (stmt)
223 mylog("USE_BOOKMARKS %s\n",
224 (vParam ==
225 SQL_UB_OFF) ? "off" : ((vParam ==
226 SQL_UB_VARIABLE) ? "variable"
227 : "fixed"));
228 setval = vParam;
229 stmt->options.use_bookmarks = (SQLUINTEGER) setval;
231 if (conn)
232 conn->stmtOptions.use_bookmarks = (SQLUINTEGER) vParam;
233 break;
235 case 1204: /* SQL_COPT_SS_PRESERVE_CURSORS ? */
236 case 1227: /* SQL_SOPT_SS_HIDDEN_COLUMNS ? */
237 case 1228: /* SQL_SOPT_SS_NOBROWSETABLE ? */
238 if (stmt)
240 SC_set_error(stmt, STMT_OPTION_NOT_FOR_THE_DRIVER,
241 "The option may be for MS SQL Server(Set)",
242 func);
243 } else if (conn)
245 CC_set_error(conn, CONN_OPTION_NOT_FOR_THE_DRIVER,
246 "The option may be for MS SQL Server(Set)",
247 func);
249 return SQL_ERROR;
250 default:
252 char option[64];
254 if (stmt)
256 SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR,
257 "Unknown statement option (Set)", NULL);
258 sprintf(option, "fOption=%d, vParam=" FORMAT_LEN,
259 fOption, vParam);
260 SC_log_error(func, option, stmt);
262 if (conn)
264 CC_set_error(conn, CONN_NOT_IMPLEMENTED_ERROR,
265 "Unknown statement option (Set)", func);
266 sprintf(option, "fOption=%d, vParam=" FORMAT_LEN,
267 fOption, vParam);
268 CC_log_error(func, option, conn);
271 return SQL_ERROR;
275 if (changed)
277 if (stmt)
279 SC_set_error(stmt, STMT_OPTION_VALUE_CHANGED,
280 "Requested value changed.", func);
282 if (conn)
284 CC_set_error(conn, CONN_OPTION_VALUE_CHANGED,
285 "Requested value changed.", func);
287 return SQL_SUCCESS_WITH_INFO;
288 } else
289 return SQL_SUCCESS;
293 // VX_CLEANUP: Some of these are probably irrelevant
294 /* Implements only SQL_AUTOCOMMIT */
295 RETCODE SQL_API
296 PGAPI_SetConnectOption(HDBC hdbc, SQLUSMALLINT fOption, SQLULEN vParam)
298 CSTR func = "PGAPI_SetConnectOption";
299 ConnectionClass *conn = (ConnectionClass *) hdbc;
300 char changed = FALSE;
301 RETCODE retval;
303 mylog("%s: entering fOption = %d vParam = %d\n", func, fOption,
304 vParam);
305 if (!conn)
307 CC_log_error(func, "", NULL);
308 return SQL_INVALID_HANDLE;
311 switch (fOption)
314 * Statement Options (apply to all stmts on the connection and
315 * become defaults for new stmts)
317 case SQL_ASYNC_ENABLE:
318 case SQL_BIND_TYPE:
319 case SQL_CONCURRENCY:
320 case SQL_CURSOR_TYPE:
321 case SQL_KEYSET_SIZE:
322 case SQL_MAX_LENGTH:
323 case SQL_MAX_ROWS:
324 case SQL_NOSCAN:
325 case SQL_QUERY_TIMEOUT:
326 case SQL_RETRIEVE_DATA:
327 case SQL_ROWSET_SIZE:
328 case SQL_SIMULATE_CURSOR:
329 case SQL_USE_BOOKMARKS:
331 * Become the default for all future statements on this
332 * connection
334 retval = set_statement_option(conn, NULL, fOption, vParam);
336 if (retval == SQL_SUCCESS_WITH_INFO)
337 changed = TRUE;
338 else if (retval == SQL_ERROR)
339 return SQL_ERROR;
341 break;
344 * Connection Options
347 case SQL_ACCESS_MODE: /* ignored */
348 break;
350 case SQL_AUTOCOMMIT:
351 // Ignored.
352 mylog("Attempt to set SQL_AUTOCOMMIT ignored\n");
353 break;
355 case SQL_CURRENT_QUALIFIER: /* ignored */
356 break;
358 case SQL_LOGIN_TIMEOUT:
359 conn->login_timeout = (SQLUINTEGER) vParam;
360 break;
362 case SQL_PACKET_SIZE: /* ignored */
363 break;
365 case SQL_QUIET_MODE: /* ignored */
366 break;
368 case SQL_TXN_ISOLATION: /* ignored */
369 retval = SQL_SUCCESS;
370 if (conn->isolation == vParam)
371 break;
372 switch (vParam)
374 case SQL_TXN_SERIALIZABLE:
375 if (PG_VERSION_GE(conn, 6.5) && PG_VERSION_LE(conn, 7.0))
376 retval = SQL_ERROR;
377 break;
378 case SQL_TXN_READ_COMMITTED:
379 if (PG_VERSION_LT(conn, 6.5))
380 retval = SQL_ERROR;
381 break;
382 default:
383 retval = SQL_ERROR;
385 if (SQL_ERROR == retval)
387 CC_set_error(conn, CONN_INVALID_ARGUMENT_NO,
388 "Illegal parameter value for SQL_TXN_ISOLATION",
389 func);
390 return SQL_ERROR;
391 } else
393 char *query;
394 QResultClass *res;
396 if (vParam == SQL_TXN_SERIALIZABLE)
397 query =
398 "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL SERIALIZABLE";
399 else
400 query =
401 "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED";
402 res = CC_send_query(conn, query, NULL, 0, NULL);
403 if (!QR_command_maybe_successful(res))
404 retval = SQL_ERROR;
405 else
406 conn->isolation = (UInt4) vParam;
407 QR_Destructor(res);
408 if (SQL_ERROR == retval)
410 CC_set_error(conn, CONN_EXEC_ERROR,
411 "ISOLATION change request to the server error",
412 func);
413 return SQL_ERROR;
416 break;
418 /* These options should be handled by driver manager */
419 case SQL_ODBC_CURSORS:
420 case SQL_OPT_TRACE:
421 case SQL_OPT_TRACEFILE:
422 case SQL_TRANSLATE_DLL:
423 case SQL_TRANSLATE_OPTION:
424 CC_log_error(func,
425 "This connect option (Set) is only used by the Driver Manager",
426 conn);
427 break;
429 default:
431 char option[64];
433 CC_set_error(conn, CONN_UNSUPPORTED_OPTION,
434 "Unknown connect option (Set)", func);
435 sprintf(option, "fOption=%d, vParam=" FORMAT_LEN, fOption,
436 vParam);
437 if (fOption == 30002 && vParam)
439 int cmp;
440 #ifdef UNICODE_SUPPORT
441 if (CC_is_in_unicode_driver(conn))
443 char *asPara =
444 ucs2_to_utf8((SQLWCHAR *) vParam, SQL_NTS, NULL,
445 FALSE);
446 cmp = strcmp(asPara, "Microsoft Jet");
447 free(asPara);
448 } else
449 #endif /* UNICODE_SUPPORT */
450 cmp = strncmp((char *) vParam, "Microsoft Jet", 13);
451 if (0 == cmp)
453 mylog("Microsoft Jet !!!!\n");
454 CC_set_errornumber(conn, 0);
455 conn->ms_jet = 1;
456 return SQL_SUCCESS;
459 CC_log_error(func, option, conn);
460 return SQL_ERROR;
464 if (changed)
466 CC_set_error(conn, CONN_OPTION_VALUE_CHANGED,
467 "Requested value changed.", func);
468 return SQL_SUCCESS_WITH_INFO;
469 } else
470 return SQL_SUCCESS;
474 // VX_CLEANUP: Most of these are probably irrelevant
475 /* This function just can tell you whether you are in Autcommit mode or not */
476 RETCODE SQL_API
477 PGAPI_GetConnectOption(HDBC hdbc,
478 SQLUSMALLINT fOption,
479 PTR pvParam,
480 SQLINTEGER * StringLength,
481 SQLINTEGER BufferLength)
483 CSTR func = "PGAPI_GetConnectOption";
484 ConnectionClass *conn = (ConnectionClass *) hdbc;
485 const char *p = NULL;
486 SQLLEN len = sizeof(SQLINTEGER);
487 SQLRETURN result = SQL_SUCCESS;
489 mylog("%s: entering...\n", func);
491 if (!conn)
493 CC_log_error(func, "", NULL);
494 return SQL_INVALID_HANDLE;
497 switch (fOption)
499 case SQL_ACCESS_MODE: /* NOT SUPPORTED */
500 *((SQLUINTEGER *) pvParam) = SQL_MODE_READ_WRITE;
501 break;
503 case SQL_AUTOCOMMIT:
504 // VX_CLEANUP: FIXME: We don't do any committing at all, does that
505 // mean autocommit is on or off?
506 *((SQLUINTEGER *) pvParam) = (SQLUINTEGER) SQL_AUTOCOMMIT_OFF;
507 break;
509 case SQL_CURRENT_QUALIFIER: /* don't use qualifiers */
510 len = 0;
511 p = CurrCatString(conn);
512 break;
514 case SQL_LOGIN_TIMEOUT:
515 *((SQLUINTEGER *) pvParam) = conn->login_timeout;
516 break;
518 case SQL_PACKET_SIZE: /* NOT SUPPORTED */
519 *((SQLUINTEGER *) pvParam) = SOCK_BUFFER_SIZE;
520 break;
522 case SQL_QUIET_MODE: /* NOT SUPPORTED */
523 *((SQLULEN *) pvParam) = (SQLULEN) NULL;
524 break;
526 case SQL_TXN_ISOLATION:
527 *((SQLUINTEGER *) pvParam) = conn->isolation;
528 break;
530 #ifdef SQL_ATTR_CONNECTION_DEAD
531 case SQL_ATTR_CONNECTION_DEAD:
532 #else
533 case 1209:
534 #endif /* SQL_ATTR_CONNECTION_DEAD */
535 mylog("CONNECTION_DEAD status=%d", conn->status);
536 *((SQLUINTEGER *) pvParam) = (conn->status == CONN_NOT_CONNECTED
537 || conn->status == CONN_DOWN);
538 mylog(" val=%d\n", *((SQLUINTEGER *) pvParam));
539 break;
541 case SQL_ATTR_ANSI_APP:
542 *((SQLUINTEGER *) pvParam) = CC_is_in_ansi_app(conn);
543 mylog("ANSI_APP val=%d\n", *((SQLUINTEGER *) pvParam));
544 break;
546 /* These options should be handled by driver manager */
547 case SQL_ODBC_CURSORS:
548 case SQL_OPT_TRACE:
549 case SQL_OPT_TRACEFILE:
550 case SQL_TRANSLATE_DLL:
551 case SQL_TRANSLATE_OPTION:
552 CC_log_error(func,
553 "This connect option (Get) is only used by the Driver Manager",
554 conn);
555 break;
557 default:
559 char option[64];
561 CC_set_error(conn, CONN_UNSUPPORTED_OPTION,
562 "Unknown connect option (Get)", func);
563 sprintf(option, "fOption=%d", fOption);
564 CC_log_error(func, option, conn);
565 return SQL_ERROR;
566 break;
570 if (NULL != p && 0 == len)
572 /* char/binary data */
573 len = strlen(p);
575 if (pvParam)
577 #ifdef UNICODE_SUPPORT
578 if (CC_is_in_unicode_driver(conn))
580 len =
581 utf8_to_ucs2(p, len, (SQLWCHAR *) pvParam,
582 BufferLength / WCLEN);
583 len *= WCLEN;
584 } else
585 #endif /* UNICODE_SUPPORT */
586 strncpy_null((char *) pvParam, p,
587 (size_t) BufferLength);
589 if (len >= BufferLength)
591 result = SQL_SUCCESS_WITH_INFO;
592 CC_set_error(conn, CONN_TRUNCATED,
593 "The buffer was too small for the pvParam.",
594 func);
598 if (StringLength)
599 *StringLength = (SQLINTEGER) len;
600 return result;
604 RETCODE SQL_API
605 PGAPI_SetStmtOption(HSTMT hstmt, SQLUSMALLINT fOption, SQLULEN vParam)
607 CSTR func = "PGAPI_SetStmtOption";
608 StatementClass *stmt = (StatementClass *) hstmt;
609 RETCODE retval;
611 mylog("%s: entering...\n", func);
614 * Though we could fake Access out by just returning SQL_SUCCESS all
615 * the time, but it tries to set a huge value for SQL_MAX_LENGTH and
616 * expects the driver to reduce it to the real value.
618 if (!stmt)
620 SC_log_error(func, "", NULL);
621 return SQL_INVALID_HANDLE;
624 /* StartRollbackState(stmt); */
625 retval = set_statement_option(NULL, stmt, fOption, vParam);
626 if (stmt->internal)
627 retval = DiscardStatementSvp(stmt, retval, FALSE);
628 return retval;
632 RETCODE SQL_API
633 PGAPI_GetStmtOption(HSTMT hstmt,
634 SQLUSMALLINT fOption,
635 PTR pvParam,
636 SQLINTEGER * StringLength, SQLINTEGER BufferLength)
638 CSTR func = "PGAPI_GetStmtOption";
639 StatementClass *stmt = (StatementClass *) hstmt;
640 QResultClass *res;
641 SQLLEN ridx;
642 SQLINTEGER len = sizeof(SQLINTEGER);
644 mylog("%s: entering...\n", func);
647 * thought we could fake Access out by just returning SQL_SUCCESS all
648 * the time, but it tries to set a huge value for SQL_MAX_LENGTH and
649 * expects the driver to reduce it to the real value
651 if (!stmt)
653 SC_log_error(func, "", NULL);
654 return SQL_INVALID_HANDLE;
657 switch (fOption)
659 case SQL_GET_BOOKMARK:
660 case SQL_ROW_NUMBER:
662 res = SC_get_Curres(stmt);
663 if (!res)
665 SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR,
666 "The cursor has no result.", func);
667 return SQL_ERROR;
670 ridx = GIdx2CacheIdx(stmt->currTuple, stmt, res);
672 /* make sure we're positioned on a valid row */
673 if ((ridx < 0) || (ridx >= QR_get_num_cached_tuples(res)))
675 SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR,
676 "Not positioned on a valid row.", func);
677 return SQL_ERROR;
681 if (fOption == SQL_GET_BOOKMARK
682 && stmt->options.use_bookmarks == SQL_UB_OFF)
684 SC_set_error(stmt, STMT_OPERATION_INVALID,
685 "Operation invalid because use bookmarks not enabled.",
686 func);
687 return SQL_ERROR;
690 *((SQLULEN *) pvParam) = SC_get_bookmark(stmt);
692 break;
694 case SQL_ASYNC_ENABLE: /* NOT SUPPORTED */
695 *((SQLINTEGER *) pvParam) = SQL_ASYNC_ENABLE_OFF;
696 break;
698 case SQL_BIND_TYPE:
699 *((SQLINTEGER *) pvParam) = SC_get_ARDF(stmt)->bind_size;
700 break;
702 case SQL_CONCURRENCY: /* NOT REALLY SUPPORTED */
703 mylog("GetStmtOption(): SQL_CONCURRENCY %d\n",
704 stmt->options.scroll_concurrency);
705 *((SQLINTEGER *) pvParam) = stmt->options.scroll_concurrency;
706 break;
708 case SQL_CURSOR_TYPE: /* PARTIAL SUPPORT */
709 mylog("GetStmtOption(): SQL_CURSOR_TYPE %d\n",
710 stmt->options.cursor_type);
711 *((SQLINTEGER *) pvParam) = stmt->options.cursor_type;
712 break;
714 case SQL_KEYSET_SIZE: /* NOT SUPPORTED, but saved */
715 mylog("GetStmtOption(): SQL_KEYSET_SIZE\n");
716 *((SQLLEN *) pvParam) = stmt->options.keyset_size;
717 break;
719 case SQL_MAX_LENGTH: /* NOT SUPPORTED, but saved */
720 *((SQLLEN *) pvParam) = stmt->options.maxLength;
721 break;
723 case SQL_MAX_ROWS: /* NOT SUPPORTED, but saved */
724 *((SQLLEN *) pvParam) = stmt->options.maxRows;
725 mylog("GetSmtOption: MAX_ROWS, returning %d\n",
726 stmt->options.maxRows);
727 break;
729 case SQL_NOSCAN: /* NOT SUPPORTED */
730 *((SQLINTEGER *) pvParam) = SQL_NOSCAN_ON;
731 break;
733 case SQL_QUERY_TIMEOUT: /* NOT SUPPORTED */
734 *((SQLINTEGER *) pvParam) = 0;
735 break;
737 case SQL_RETRIEVE_DATA:
738 *((SQLINTEGER *) pvParam) = stmt->options.retrieve_data;
739 break;
741 case SQL_ROWSET_SIZE:
742 *((SQLLEN *) pvParam) = SC_get_ARDF(stmt)->size_of_rowset_odbc2;
743 break;
745 case SQL_SIMULATE_CURSOR: /* NOT SUPPORTED */
746 *((SQLINTEGER *) pvParam) = SQL_SC_NON_UNIQUE;
747 break;
749 case SQL_USE_BOOKMARKS:
750 *((SQLINTEGER *) pvParam) = stmt->options.use_bookmarks;
751 break;
753 default:
755 char option[64];
757 SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR,
758 "Unknown statement option (Get)", NULL);
759 sprintf(option, "fOption=%d", fOption);
760 SC_log_error(func, option, stmt);
761 return SQL_ERROR;
764 if (StringLength)
765 *StringLength = len;
767 return SQL_SUCCESS;