Merge commit 'origin/master'
[versaplex.git] / vxodbc / pgapi30.cc
blob8bef46bfdffaf8aa8b1807203bfe0cf1d0e2deca
1 /*
2 * Description: This module contains routines related to ODBC 3.0
3 * most of their implementations are temporary
4 * and must be rewritten properly.
5 * 2001/07/23 inoue
6 */
8 #include "psqlodbc.h"
9 #include "misc.h"
11 #include <stdio.h>
12 #include <string.h>
14 #include "environ.h"
15 #include "connection.h"
16 #include "statement.h"
17 #include "descriptor.h"
18 #include "qresult.h"
19 #include "pgapifunc.h"
22 /* SQLError -> SQLDiagRec */
23 RETCODE SQL_API
24 PGAPI_GetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle,
25 SQLSMALLINT RecNumber, SQLCHAR * Sqlstate,
26 SQLINTEGER * NativeError, SQLCHAR * MessageText,
27 SQLSMALLINT BufferLength, SQLSMALLINT * TextLength)
29 RETCODE ret;
30 CSTR func = "PGAPI_GetDiagRec";
32 mylog("%s entering type=%d rec=%d\n", func, HandleType, RecNumber);
33 switch (HandleType)
35 case SQL_HANDLE_ENV:
36 ret = PGAPI_EnvError(Handle, RecNumber, Sqlstate,
37 NativeError, MessageText,
38 BufferLength, TextLength, 0);
39 break;
40 case SQL_HANDLE_DBC:
41 ret = PGAPI_ConnectError(Handle, RecNumber, Sqlstate,
42 NativeError, MessageText, BufferLength,
43 TextLength, 0);
44 break;
45 case SQL_HANDLE_STMT:
46 ret = PGAPI_StmtError(Handle, RecNumber, Sqlstate,
47 NativeError, MessageText, BufferLength,
48 TextLength, 0);
49 break;
50 case SQL_HANDLE_DESC:
51 ret = PGAPI_DescError(Handle, RecNumber, Sqlstate,
52 NativeError,
53 MessageText, BufferLength, TextLength, 0);
54 break;
55 default:
56 ret = SQL_ERROR;
58 mylog("%s exiting %d\n", func, ret);
59 return ret;
63 * Minimal implementation.
66 RETCODE SQL_API
67 PGAPI_GetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle,
68 SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier,
69 PTR DiagInfoPtr, SQLSMALLINT BufferLength,
70 SQLSMALLINT * StringLengthPtr)
72 RETCODE ret = SQL_ERROR, rtn;
73 ConnectionClass *conn;
74 StatementClass *stmt;
75 SQLLEN rc;
76 SQLSMALLINT pcbErrm;
77 ssize_t rtnlen = -1;
78 int rtnctype = SQL_C_CHAR;
79 CSTR func = "PGAPI_GetDiagField";
81 mylog("%s entering rec=%d", func, RecNumber);
82 switch (HandleType)
84 case SQL_HANDLE_ENV:
85 switch (DiagIdentifier)
87 case SQL_DIAG_CLASS_ORIGIN:
88 case SQL_DIAG_SUBCLASS_ORIGIN:
89 case SQL_DIAG_CONNECTION_NAME:
90 case SQL_DIAG_SERVER_NAME:
91 rtnlen = 0;
92 if (DiagInfoPtr && BufferLength > rtnlen)
94 ret = SQL_SUCCESS;
95 *((char *) DiagInfoPtr) = '\0';
96 } else
97 ret = SQL_SUCCESS_WITH_INFO;
98 break;
99 case SQL_DIAG_MESSAGE_TEXT:
100 ret = PGAPI_EnvError(Handle, RecNumber,
101 NULL, NULL, (UCHAR *)DiagInfoPtr,
102 BufferLength, StringLengthPtr, 0);
103 break;
104 case SQL_DIAG_NATIVE:
105 rtnctype = SQL_C_LONG;
106 ret = PGAPI_EnvError(Handle, RecNumber,
107 NULL, (SQLINTEGER *) DiagInfoPtr, NULL,
108 0, NULL, 0);
109 break;
110 case SQL_DIAG_NUMBER:
111 rtnctype = SQL_C_LONG;
112 ret = PGAPI_EnvError(Handle, RecNumber,
113 NULL, NULL, NULL, 0, NULL, 0);
114 if (SQL_SUCCEEDED(ret))
116 *((SQLINTEGER *) DiagInfoPtr) = 1;
118 break;
119 case SQL_DIAG_SQLSTATE:
120 rtnlen = 5;
121 ret = PGAPI_EnvError(Handle, RecNumber,
122 (UCHAR *)DiagInfoPtr,
123 NULL, NULL, 0, NULL, 0);
124 if (SQL_SUCCESS_WITH_INFO == ret)
125 ret = SQL_SUCCESS;
126 break;
127 case SQL_DIAG_RETURNCODE: /* driver manager returns */
128 break;
129 case SQL_DIAG_CURSOR_ROW_COUNT:
130 case SQL_DIAG_ROW_COUNT:
131 case SQL_DIAG_DYNAMIC_FUNCTION:
132 case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
133 /* options for statement type only */
134 break;
136 break;
137 case SQL_HANDLE_DBC:
138 conn = (ConnectionClass *) Handle;
139 switch (DiagIdentifier)
141 case SQL_DIAG_CLASS_ORIGIN:
142 case SQL_DIAG_SUBCLASS_ORIGIN:
143 case SQL_DIAG_CONNECTION_NAME:
144 rtnlen = 0;
145 if (DiagInfoPtr && BufferLength > rtnlen)
147 ret = SQL_SUCCESS;
148 *((char *) DiagInfoPtr) = '\0';
149 } else
150 ret = SQL_SUCCESS_WITH_INFO;
151 break;
152 case SQL_DIAG_SERVER_NAME:
153 rtnlen = strlen(CC_get_DSN(conn));
154 if (DiagInfoPtr)
156 strncpy_null((char *)DiagInfoPtr, CC_get_DSN(conn),
157 BufferLength);
158 ret =
159 (BufferLength >
160 rtnlen ? SQL_SUCCESS : SQL_SUCCESS_WITH_INFO);
161 } else
162 ret = SQL_SUCCESS_WITH_INFO;
163 break;
164 case SQL_DIAG_MESSAGE_TEXT:
165 ret = PGAPI_ConnectError(Handle, RecNumber,
166 NULL, NULL, (UCHAR *)DiagInfoPtr,
167 BufferLength, StringLengthPtr, 0);
168 break;
169 case SQL_DIAG_NATIVE:
170 rtnctype = SQL_C_LONG;
171 ret = PGAPI_ConnectError(Handle, RecNumber,
172 NULL, (SQLINTEGER *) DiagInfoPtr,
173 NULL, 0, NULL, 0);
174 break;
175 case SQL_DIAG_NUMBER:
176 rtnctype = SQL_C_LONG;
177 ret = PGAPI_ConnectError(Handle, RecNumber,
178 NULL, NULL, NULL, 0, NULL, 0);
179 if (SQL_SUCCEEDED(ret))
181 *((SQLINTEGER *) DiagInfoPtr) = 1;
183 break;
184 case SQL_DIAG_SQLSTATE:
185 rtnlen = 5;
186 ret = PGAPI_ConnectError(Handle, RecNumber,
187 (UCHAR *)DiagInfoPtr, NULL, NULL,
188 0, NULL, 0);
189 if (SQL_SUCCESS_WITH_INFO == ret)
190 ret = SQL_SUCCESS;
191 break;
192 case SQL_DIAG_RETURNCODE: /* driver manager returns */
193 break;
194 case SQL_DIAG_CURSOR_ROW_COUNT:
195 case SQL_DIAG_ROW_COUNT:
196 case SQL_DIAG_DYNAMIC_FUNCTION:
197 case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
198 /* options for statement type only */
199 break;
201 break;
202 case SQL_HANDLE_STMT:
203 conn =
204 (ConnectionClass *)
205 SC_get_conn(((StatementClass *) Handle));
206 switch (DiagIdentifier)
208 case SQL_DIAG_CLASS_ORIGIN:
209 case SQL_DIAG_SUBCLASS_ORIGIN:
210 case SQL_DIAG_CONNECTION_NAME:
211 rtnlen = 0;
212 if (DiagInfoPtr && BufferLength > rtnlen)
214 ret = SQL_SUCCESS;
215 *((char *) DiagInfoPtr) = '\0';
216 } else
217 ret = SQL_SUCCESS_WITH_INFO;
218 break;
219 case SQL_DIAG_SERVER_NAME:
220 rtnlen = strlen(CC_get_DSN(conn));
221 if (DiagInfoPtr)
223 strncpy_null((char *) DiagInfoPtr, CC_get_DSN(conn),
224 BufferLength);
225 ret =
226 (BufferLength >
227 rtnlen ? SQL_SUCCESS : SQL_SUCCESS_WITH_INFO);
228 } else
229 ret = SQL_SUCCESS_WITH_INFO;
230 break;
231 case SQL_DIAG_MESSAGE_TEXT:
232 ret = PGAPI_StmtError(Handle, RecNumber,
233 NULL, NULL, (UCHAR *)DiagInfoPtr,
234 BufferLength, StringLengthPtr, 0);
235 break;
236 case SQL_DIAG_NATIVE:
237 rtnctype = SQL_C_LONG;
238 ret = PGAPI_StmtError(Handle, RecNumber,
239 NULL, (SQLINTEGER *) DiagInfoPtr,
240 NULL, 0, NULL, 0);
241 break;
242 case SQL_DIAG_NUMBER:
243 rtnctype = SQL_C_LONG;
244 *((SQLINTEGER *) DiagInfoPtr) = 0;
245 ret = SQL_NO_DATA_FOUND;
246 stmt = (StatementClass *) Handle;
247 rtn = PGAPI_StmtError(Handle, -1, NULL,
248 NULL, NULL, 0, &pcbErrm, 0);
249 switch (rtn)
251 case SQL_SUCCESS:
252 case SQL_SUCCESS_WITH_INFO:
253 ret = SQL_SUCCESS;
254 if (pcbErrm > 0 && stmt->pgerror)
256 *((SQLINTEGER *) DiagInfoPtr) =
257 (pcbErrm - 1) / stmt->pgerror->recsize + 1;
258 break;
259 default:
260 break;
262 break;
263 case SQL_DIAG_SQLSTATE:
264 rtnlen = 5;
265 ret = PGAPI_StmtError(Handle, RecNumber,
266 (UCHAR *)DiagInfoPtr, NULL, NULL, 0, NULL, 0);
267 if (SQL_SUCCESS_WITH_INFO == ret)
268 ret = SQL_SUCCESS;
269 break;
270 case SQL_DIAG_CURSOR_ROW_COUNT:
271 rtnctype = SQL_C_LONG;
272 stmt = (StatementClass *) Handle;
273 rc = -1;
274 if (stmt->status == STMT_FINISHED)
276 QResultClass *res = SC_get_Curres(stmt);
278 /*if (!res)
279 return SQL_ERROR; */
280 if (stmt->proc_return > 0)
281 rc = 0;
282 else if (res && QR_NumResultCols(res) > 0)
283 rc = QR_get_num_total_tuples(res) - res->dl_count;
285 *((SQLLEN *) DiagInfoPtr) = rc;
286 inolog("rc=%d\n", rc);
287 ret = SQL_SUCCESS;
288 break;
289 case SQL_DIAG_ROW_COUNT:
290 rtnctype = SQL_C_LONG;
291 stmt = (StatementClass *) Handle;
292 *((SQLLEN *) DiagInfoPtr) = stmt->diag_row_count;
293 ret = SQL_SUCCESS;
294 break;
295 case SQL_DIAG_ROW_NUMBER:
296 rtnctype = SQL_C_LONG;
297 *((SQLLEN *) DiagInfoPtr) = SQL_ROW_NUMBER_UNKNOWN;
298 ret = SQL_SUCCESS;
299 break;
300 case SQL_DIAG_COLUMN_NUMBER:
301 rtnctype = SQL_C_LONG;
302 *((SQLINTEGER *) DiagInfoPtr) = SQL_COLUMN_NUMBER_UNKNOWN;
303 ret = SQL_SUCCESS;
304 break;
305 case SQL_DIAG_RETURNCODE: /* driver manager returns */
306 break;
308 break;
309 case SQL_HANDLE_DESC:
310 conn = DC_get_conn(((DescriptorClass *) Handle));
311 switch (DiagIdentifier)
313 case SQL_DIAG_CLASS_ORIGIN:
314 case SQL_DIAG_SUBCLASS_ORIGIN:
315 case SQL_DIAG_CONNECTION_NAME:
316 rtnlen = 0;
317 if (DiagInfoPtr && BufferLength > rtnlen)
319 ret = SQL_SUCCESS;
320 *((char *) DiagInfoPtr) = '\0';
321 } else
322 ret = SQL_SUCCESS_WITH_INFO;
323 break;
324 case SQL_DIAG_SERVER_NAME:
325 rtnlen = strlen(CC_get_DSN(conn));
326 if (DiagInfoPtr)
328 strncpy_null((char *)DiagInfoPtr, CC_get_DSN(conn),
329 BufferLength);
330 ret =
331 (BufferLength >
332 rtnlen ? SQL_SUCCESS : SQL_SUCCESS_WITH_INFO);
333 } else
334 ret = SQL_SUCCESS_WITH_INFO;
335 break;
336 case SQL_DIAG_MESSAGE_TEXT:
337 case SQL_DIAG_NATIVE:
338 case SQL_DIAG_NUMBER:
339 break;
340 case SQL_DIAG_SQLSTATE:
341 rtnlen = 5;
342 ret = PGAPI_DescError(Handle, RecNumber,
343 (UCHAR *)DiagInfoPtr, NULL, NULL, 0, NULL, 0);
344 if (SQL_SUCCESS_WITH_INFO == ret)
345 ret = SQL_SUCCESS;
346 break;
347 case SQL_DIAG_RETURNCODE: /* driver manager returns */
348 break;
349 case SQL_DIAG_CURSOR_ROW_COUNT:
350 case SQL_DIAG_ROW_COUNT:
351 case SQL_DIAG_DYNAMIC_FUNCTION:
352 case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
353 rtnctype = SQL_C_LONG;
354 /* options for statement type only */
355 break;
357 break;
358 default:
359 ret = SQL_ERROR;
361 if (SQL_C_LONG == rtnctype)
363 if (SQL_SUCCESS_WITH_INFO == ret)
364 ret = SQL_SUCCESS;
365 if (StringLengthPtr)
366 *StringLengthPtr = sizeof(SQLINTEGER);
367 } else if (rtnlen >= 0)
369 if (rtnlen >= BufferLength)
371 if (SQL_SUCCESS == ret)
372 ret = SQL_SUCCESS_WITH_INFO;
373 if (BufferLength > 0)
374 ((char *) DiagInfoPtr)[BufferLength - 1] = '\0';
376 if (StringLengthPtr)
377 *StringLengthPtr = (SQLSMALLINT) rtnlen;
379 mylog("%s exiting %d\n", func, ret);
380 return ret;
383 /* SQLGetConnectOption -> SQLGetconnectAttr */
384 RETCODE SQL_API
385 PGAPI_GetConnectAttr(HDBC ConnectionHandle,
386 SQLINTEGER Attribute, PTR Value,
387 SQLINTEGER BufferLength, SQLINTEGER * StringLength)
389 ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
390 RETCODE ret = SQL_SUCCESS;
391 SQLINTEGER len = 4;
393 mylog("PGAPI_GetConnectAttr %d\n", Attribute);
394 switch (Attribute)
396 case SQL_ATTR_ASYNC_ENABLE:
397 *((SQLINTEGER *) Value) = SQL_ASYNC_ENABLE_OFF;
398 break;
399 case SQL_ATTR_AUTO_IPD:
400 *((SQLINTEGER *) Value) = SQL_FALSE;
401 break;
402 case SQL_ATTR_CONNECTION_DEAD:
403 *((SQLUINTEGER *) Value) = (conn->status == CONN_NOT_CONNECTED
404 || conn->status == CONN_DOWN);
405 break;
406 case SQL_ATTR_CONNECTION_TIMEOUT:
407 *((SQLUINTEGER *) Value) = 0;
408 break;
409 case SQL_ATTR_METADATA_ID:
410 *((SQLUINTEGER *) Value) = conn->stmtOptions.metadata_id;
411 break;
412 default:
413 ret =
414 PGAPI_GetConnectOption(ConnectionHandle, (UWORD) Attribute,
415 Value, &len, BufferLength);
417 if (StringLength)
418 *StringLength = len;
419 return ret;
422 static SQLHDESC
423 descHandleFromStatementHandle(HSTMT StatementHandle,
424 SQLINTEGER descType)
426 StatementClass *stmt = (StatementClass *) StatementHandle;
428 switch (descType)
430 case SQL_ATTR_APP_ROW_DESC: /* 10010 */
431 return (HSTMT) stmt->ard;
432 case SQL_ATTR_APP_PARAM_DESC: /* 10011 */
433 return (HSTMT) stmt->apd;
434 case SQL_ATTR_IMP_ROW_DESC: /* 10012 */
435 return (HSTMT) stmt->ird;
436 case SQL_ATTR_IMP_PARAM_DESC: /* 10013 */
437 return (HSTMT) stmt->ipd;
439 return (HSTMT) 0;
442 static void column_bindings_set(ARDFields * opts, int cols, BOOL maxset)
444 int i;
446 if (cols == opts->allocated)
447 return;
448 if (cols > opts->allocated)
450 extend_column_bindings(opts, cols);
451 return;
453 if (maxset)
454 return;
456 for (i = opts->allocated; i > cols; i--)
457 reset_a_column_binding(opts, i);
458 opts->allocated = cols;
459 if (0 == cols)
461 free(opts->bindings);
462 opts->bindings = NULL;
466 /* SQLGetStmtOption -> SQLGetStmtAttr */
467 RETCODE SQL_API
468 PGAPI_GetStmtAttr(HSTMT StatementHandle,
469 SQLINTEGER Attribute, PTR Value,
470 SQLINTEGER BufferLength, SQLINTEGER * StringLength)
472 CSTR func = "PGAPI_GetStmtAttr";
473 StatementClass *stmt = (StatementClass *) StatementHandle;
474 RETCODE ret = SQL_SUCCESS;
475 SQLINTEGER len = 0;
477 mylog("%s Handle=%p %d\n", func, StatementHandle, Attribute);
478 switch (Attribute)
480 case SQL_ATTR_FETCH_BOOKMARK_PTR: /* 16 */
481 *((void **) Value) = stmt->options.bookmark_ptr;
482 len = sizeof(SQLPOINTER);
483 break;
484 case SQL_ATTR_PARAM_BIND_OFFSET_PTR: /* 17 */
485 *((SQLULEN **) Value) =
486 (SQLULEN *) SC_get_APDF(stmt)->param_offset_ptr;
487 len = sizeof(SQLPOINTER);
488 break;
489 case SQL_ATTR_PARAM_BIND_TYPE: /* 18 */
490 *((SQLUINTEGER *) Value) = SC_get_APDF(stmt)->param_bind_type;
491 len = sizeof(SQLUINTEGER);
492 break;
493 case SQL_ATTR_PARAM_OPERATION_PTR: /* 19 */
494 *((SQLUSMALLINT **) Value) =
495 SC_get_APDF(stmt)->param_operation_ptr;
496 len = sizeof(SQLPOINTER);
497 break;
498 case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */
499 *((SQLUSMALLINT **) Value) =
500 SC_get_IPDF(stmt)->param_status_ptr;
501 len = sizeof(SQLPOINTER);
502 break;
503 case SQL_ATTR_PARAMS_PROCESSED_PTR: /* 21 */
504 *((SQLUINTEGER **) Value) =
505 (SQLUINTEGER *) SC_get_IPDF(stmt)->param_processed_ptr;
506 len = sizeof(SQLPOINTER);
507 break;
508 case SQL_ATTR_PARAMSET_SIZE: /* 22 */
509 *((SQLUINTEGER *) Value) =
510 (SQLUINTEGER) SC_get_APDF(stmt)->paramset_size;
511 len = sizeof(SQLUINTEGER);
512 break;
513 case SQL_ATTR_ROW_BIND_OFFSET_PTR: /* 23 */
514 *((SQLULEN **) Value) =
515 (SQLULEN *) SC_get_ARDF(stmt)->row_offset_ptr;
516 len = 4;
517 break;
518 case SQL_ATTR_ROW_OPERATION_PTR: /* 24 */
519 *((SQLUSMALLINT **) Value) =
520 SC_get_ARDF(stmt)->row_operation_ptr;
521 len = 4;
522 break;
523 case SQL_ATTR_ROW_STATUS_PTR: /* 25 */
524 *((SQLUSMALLINT **) Value) = SC_get_IRDF(stmt)->rowStatusArray;
525 len = 4;
526 break;
527 case SQL_ATTR_ROWS_FETCHED_PTR: /* 26 */
528 *((SQLULEN **) Value) =
529 (SQLULEN *) SC_get_IRDF(stmt)->rowsFetched;
530 len = 4;
531 break;
532 case SQL_ATTR_ROW_ARRAY_SIZE: /* 27 */
533 *((SQLULEN *) Value) = SC_get_ARDF(stmt)->size_of_rowset;
534 len = 4;
535 break;
536 case SQL_ATTR_APP_ROW_DESC: /* 10010 */
537 case SQL_ATTR_APP_PARAM_DESC: /* 10011 */
538 case SQL_ATTR_IMP_ROW_DESC: /* 10012 */
539 case SQL_ATTR_IMP_PARAM_DESC: /* 10013 */
540 len = 4;
541 *((HSTMT *) Value) =
542 descHandleFromStatementHandle(StatementHandle, Attribute);
543 break;
545 case SQL_ATTR_CURSOR_SCROLLABLE: /* -1 */
546 len = 4;
547 if (SQL_CURSOR_FORWARD_ONLY == stmt->options.cursor_type)
548 *((SQLUINTEGER *) Value) = SQL_NONSCROLLABLE;
549 else
550 *((SQLUINTEGER *) Value) = SQL_SCROLLABLE;
551 break;
552 case SQL_ATTR_CURSOR_SENSITIVITY: /* -2 */
553 len = 4;
554 if (SQL_CONCUR_READ_ONLY == stmt->options.scroll_concurrency)
555 *((SQLUINTEGER *) Value) = SQL_INSENSITIVE;
556 else
557 *((SQLUINTEGER *) Value) = SQL_UNSPECIFIED;
558 break;
559 case SQL_ATTR_METADATA_ID: /* 10014 */
560 *((SQLUINTEGER *) Value) = stmt->options.metadata_id;
561 break;
562 case SQL_ATTR_ENABLE_AUTO_IPD: /* 15 */
563 *((SQLUINTEGER *) Value) = SQL_FALSE;
564 break;
565 case SQL_ATTR_AUTO_IPD: /* 10001 */
566 /* case SQL_ATTR_ROW_BIND_TYPE: ** == SQL_BIND_TYPE(ODBC2.0) */
567 SC_set_error(stmt, DESC_INVALID_OPTION_IDENTIFIER,
568 "Unsupported statement option (Get)", func);
569 return SQL_ERROR;
570 default:
571 ret =
572 PGAPI_GetStmtOption(StatementHandle,
573 (SQLSMALLINT) Attribute, Value, &len,
574 BufferLength);
576 if (ret == SQL_SUCCESS && StringLength)
577 *StringLength = len;
578 return ret;
581 /* SQLSetConnectOption -> SQLSetConnectAttr */
582 RETCODE SQL_API
583 PGAPI_SetConnectAttr(HDBC ConnectionHandle,
584 SQLINTEGER Attribute, PTR Value,
585 SQLINTEGER StringLength)
587 CSTR func = "PGAPI_SetConnectAttr";
588 ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
589 RETCODE ret = SQL_SUCCESS;
590 BOOL unsupported = FALSE;
592 mylog("%s for %p: %d %p\n", func, ConnectionHandle, Attribute,
593 Value);
594 switch (Attribute)
596 case SQL_ATTR_METADATA_ID:
597 conn->stmtOptions.metadata_id = CAST_UPTR(SQLUINTEGER, Value);
598 break;
599 case SQL_ATTR_ANSI_APP:
600 if (SQL_AA_FALSE != CAST_PTR(SQLINTEGER, Value))
602 mylog("the application is ansi\n");
603 if (CC_is_in_unicode_driver(conn)) /* the driver is unicode */
604 CC_set_in_ansi_app(conn); /* but the app is ansi */
605 } else
607 mylog("the application is unicode\n");
609 /*return SQL_ERROR; */
610 return SQL_SUCCESS;
611 case SQL_ATTR_ENLIST_IN_DTC:
612 #ifdef WIN32
613 #ifdef _HANDLE_ENLIST_IN_DTC_
614 mylog("SQL_ATTR_ENLIST_IN_DTC %p request received\n", Value);
615 if (conn->connInfo.xa_opt != 0)
616 return CALL_EnlistInDtc(conn, Value, conn->connInfo.xa_opt);
617 #endif /* _HANDLE_ENLIST_IN_DTC_ */
618 #endif /* WIN32 */
619 unsupported = TRUE;
620 break;
621 case SQL_ATTR_AUTO_IPD:
622 if (SQL_FALSE != Value)
623 unsupported = TRUE;
624 break;
625 case SQL_ATTR_ASYNC_ENABLE:
626 case SQL_ATTR_CONNECTION_DEAD:
627 case SQL_ATTR_CONNECTION_TIMEOUT:
628 unsupported = TRUE;
629 break;
630 default:
631 ret =
632 PGAPI_SetConnectOption(ConnectionHandle,
633 (SQLUSMALLINT) Attribute,
634 (SQLLEN) Value);
636 if (unsupported)
638 char msg[64];
639 snprintf(msg, sizeof(msg),
640 "Couldn't set unsupported connect attribute "
641 FORMAT_LPTR, (LONG_PTR) Value);
642 CC_set_error(conn, CONN_OPTION_NOT_FOR_THE_DRIVER, msg, func);
643 return SQL_ERROR;
645 return ret;
648 /* new function */
649 RETCODE SQL_API
650 PGAPI_GetDescField(SQLHDESC DescriptorHandle,
651 SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
652 PTR Value, SQLINTEGER BufferLength,
653 SQLINTEGER * StringLength)
655 CSTR func = "PGAPI_GetDescField";
656 RETCODE ret = SQL_SUCCESS;
657 DescriptorClass *desc = (DescriptorClass *) DescriptorHandle;
659 mylog("%s h=%p rec=%d field=%d blen=%d\n", func, DescriptorHandle,
660 RecNumber, FieldIdentifier, BufferLength);
662 mylog("PGAPI_GetDescField not yet implemented\n");
663 DC_set_error(desc, DESC_INTERNAL_ERROR, "Error not implemented");
664 return SQL_ERROR;
667 /* new function */
668 RETCODE SQL_API
669 PGAPI_SetDescField(SQLHDESC DescriptorHandle,
670 SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
671 PTR Value, SQLINTEGER BufferLength)
673 CSTR func = "PGAPI_SetDescField";
674 RETCODE ret = SQL_SUCCESS;
675 DescriptorClass *desc = (DescriptorClass *) DescriptorHandle;
677 mylog("PGAPI_SetDescField not yet implemented (Rec=%d, Field=%d)\n",
678 (int)RecNumber, (int)FieldIdentifier);
679 //DC_set_error(desc, DESC_INTERNAL_ERROR, "Error not implemented");
680 return SQL_SUCCESS;
683 /* SQLSet(Param/Scroll/Stmt)Option -> SQLSetStmtAttr */
684 RETCODE SQL_API
685 PGAPI_SetStmtAttr(HSTMT StatementHandle,
686 SQLINTEGER Attribute, PTR Value,
687 SQLINTEGER StringLength)
689 RETCODE ret = SQL_SUCCESS;
690 CSTR func = "PGAPI_SetStmtAttr";
691 StatementClass *stmt = (StatementClass *) StatementHandle;
693 mylog("%s Handle=%p %d,%u(%p)\n", func, StatementHandle, Attribute,
694 Value, Value);
695 switch (Attribute)
697 case SQL_ATTR_ENABLE_AUTO_IPD: /* 15 */
698 if (SQL_FALSE == Value)
699 break;
700 case SQL_ATTR_CURSOR_SCROLLABLE: /* -1 */
701 case SQL_ATTR_CURSOR_SENSITIVITY: /* -2 */
702 case SQL_ATTR_AUTO_IPD: /* 10001 */
703 SC_set_error(stmt, DESC_OPTION_NOT_FOR_THE_DRIVER,
704 "Unsupported statement option (Set)", func);
705 return SQL_ERROR;
706 /* case SQL_ATTR_ROW_BIND_TYPE: ** == SQL_BIND_TYPE(ODBC2.0) */
707 case SQL_ATTR_IMP_ROW_DESC: /* 10012 (read-only) */
708 case SQL_ATTR_IMP_PARAM_DESC: /* 10013 (read-only) */
711 * case SQL_ATTR_PREDICATE_PTR: case
712 * SQL_ATTR_PREDICATE_OCTET_LENGTH_PTR:
714 SC_set_error(stmt, DESC_INVALID_OPTION_IDENTIFIER,
715 "Unsupported statement option (Set)", func);
716 return SQL_ERROR;
718 case SQL_ATTR_METADATA_ID: /* 10014 */
719 stmt->options.metadata_id = CAST_UPTR(SQLUINTEGER, Value);
720 break;
721 case SQL_ATTR_APP_ROW_DESC: /* 10010 */
722 if (SQL_NULL_HDESC == Value)
724 stmt->ard = &(stmt->ardi);
725 } else
727 stmt->ard = (ARDClass *) Value;
728 inolog("set ard=%p\n", stmt->ard);
730 break;
731 case SQL_ATTR_APP_PARAM_DESC: /* 10011 */
732 if (SQL_NULL_HDESC == Value)
734 stmt->apd = &(stmt->apdi);
735 } else
737 stmt->apd = (APDClass *) Value;
739 break;
740 case SQL_ATTR_FETCH_BOOKMARK_PTR: /* 16 */
741 stmt->options.bookmark_ptr = Value;
742 break;
743 case SQL_ATTR_PARAM_BIND_OFFSET_PTR: /* 17 */
744 SC_get_APDF(stmt)->param_offset_ptr = (SQLULEN *) Value;
745 break;
746 case SQL_ATTR_PARAM_BIND_TYPE: /* 18 */
747 SC_get_APDF(stmt)->param_bind_type =
748 CAST_UPTR(SQLUINTEGER, Value);
749 break;
750 case SQL_ATTR_PARAM_OPERATION_PTR: /* 19 */
751 SC_get_APDF(stmt)->param_operation_ptr = (SQLUSMALLINT*)Value;
752 break;
753 case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */
754 SC_get_IPDF(stmt)->param_status_ptr = (SQLUSMALLINT *) Value;
755 break;
756 case SQL_ATTR_PARAMS_PROCESSED_PTR: /* 21 */
757 SC_get_IPDF(stmt)->param_processed_ptr = (SQLUINTEGER *) Value;
758 break;
759 case SQL_ATTR_PARAMSET_SIZE: /* 22 */
760 SC_get_APDF(stmt)->paramset_size =
761 CAST_UPTR(SQLUINTEGER, Value);
762 break;
763 case SQL_ATTR_ROW_BIND_OFFSET_PTR: /* 23 */
764 SC_get_ARDF(stmt)->row_offset_ptr = (SQLULEN *) Value;
765 break;
766 case SQL_ATTR_ROW_OPERATION_PTR: /* 24 */
767 SC_get_ARDF(stmt)->row_operation_ptr = (SQLUSMALLINT*)Value;
768 break;
769 case SQL_ATTR_ROW_STATUS_PTR: /* 25 */
770 SC_get_IRDF(stmt)->rowStatusArray = (SQLUSMALLINT *) Value;
771 break;
772 case SQL_ATTR_ROWS_FETCHED_PTR: /* 26 */
773 SC_get_IRDF(stmt)->rowsFetched = (SQLULEN *) Value;
774 break;
775 case SQL_ATTR_ROW_ARRAY_SIZE: /* 27 */
776 SC_get_ARDF(stmt)->size_of_rowset = (SQLULEN) Value;
777 break;
778 default:
779 return PGAPI_SetStmtOption(StatementHandle,
780 (SQLUSMALLINT) Attribute,
781 (SQLULEN) Value);
783 return ret;
786 #define CALC_BOOKMARK_ADDR(book, offset, bind_size, index) \
787 (book->buffer + offset + \
788 (bind_size > 0 ? bind_size : (SQL_C_VARBOOKMARK == book->returntype ? book->buflen : sizeof(UInt4))) * index)
791 RETCODE SQL_API
792 PGAPI_BulkOperations(HSTMT hstmt, SQLSMALLINT operationX)
794 CSTR func = "PGAPI_BulkOperations";
795 SC_set_error((StatementClass *)hstmt, DESC_INTERNAL_ERROR,
796 "Bulk operations are not yet supported.", func);
797 return SQL_ERROR;