1 /*-------
2 * Module: pgapi30.c
3 *
4 * Description: This module contains routines related to ODBC 3.0
5 * most of their implementations are temporary
6 * and must be rewritten properly.
7 * 2001/07/23 inoue
8 *
9 * Classes: n/a
10 *
11 * API functions: PGAPI_ColAttribute, PGAPI_GetDiagRec,
12 PGAPI_GetConnectAttr, PGAPI_GetStmtAttr,
13 PGAPI_SetConnectAttr, PGAPI_SetStmtAttr
14 *-------
15 */
16
17 #include "psqlodbc.h"
18 #include "misc.h"
19
20 #include <stdio.h>
21 #include <string.h>
22
23
24 #include "environ.h"
25 #include "connection.h"
26 #include "statement.h"
27 #include "descriptor.h"
28 #include "qresult.h"
29 #include "pgapifunc.h"
30 #include "loadlib.h"
31 #include "dlg_specific.h"
32
33
34 /* SQLError -> SQLDiagRec */
35 RETCODE SQL_API
PGAPI_GetDiagRec(SQLSMALLINT HandleType,SQLHANDLE Handle,SQLSMALLINT RecNumber,SQLCHAR * Sqlstate,SQLINTEGER * NativeError,SQLCHAR * MessageText,SQLSMALLINT BufferLength,SQLSMALLINT * TextLength)36 PGAPI_GetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle,
37 SQLSMALLINT RecNumber, SQLCHAR *Sqlstate,
38 SQLINTEGER *NativeError, SQLCHAR *MessageText,
39 SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
40 {
41 RETCODE ret;
42
43 MYLOG(0, "entering type=%d rec=%d\n", HandleType, RecNumber);
44 switch (HandleType)
45 {
46 case SQL_HANDLE_ENV:
47 ret = PGAPI_EnvError(Handle, RecNumber, Sqlstate,
48 NativeError, MessageText,
49 BufferLength, TextLength, 0);
50 break;
51 case SQL_HANDLE_DBC:
52 ret = PGAPI_ConnectError(Handle, RecNumber, Sqlstate,
53 NativeError, MessageText, BufferLength,
54 TextLength, 0);
55 break;
56 case SQL_HANDLE_STMT:
57 ret = PGAPI_StmtError(Handle, RecNumber, Sqlstate,
58 NativeError, MessageText, BufferLength,
59 TextLength, 0);
60 break;
61 case SQL_HANDLE_DESC:
62 ret = PGAPI_DescError(Handle, RecNumber, Sqlstate,
63 NativeError,
64 MessageText, BufferLength,
65 TextLength, 0);
66 break;
67 default:
68 ret = SQL_ERROR;
69 }
70 MYLOG(0, "leaving %d\n", ret);
71 return ret;
72 }
73
74 /*
75 * Minimal implementation.
76 *
77 */
78 RETCODE SQL_API
PGAPI_GetDiagField(SQLSMALLINT HandleType,SQLHANDLE Handle,SQLSMALLINT RecNumber,SQLSMALLINT DiagIdentifier,PTR DiagInfoPtr,SQLSMALLINT BufferLength,SQLSMALLINT * StringLengthPtr)79 PGAPI_GetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle,
80 SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier,
81 PTR DiagInfoPtr, SQLSMALLINT BufferLength,
82 SQLSMALLINT *StringLengthPtr)
83 {
84 RETCODE ret = SQL_ERROR, rtn;
85 ConnectionClass *conn;
86 StatementClass *stmt;
87 SQLLEN rc;
88 SQLSMALLINT pcbErrm;
89 ssize_t rtnlen = -1;
90 int rtnctype = SQL_C_CHAR;
91
92 MYLOG(0, "entering rec=%d\n", RecNumber);
93 switch (HandleType)
94 {
95 case SQL_HANDLE_ENV:
96 switch (DiagIdentifier)
97 {
98 case SQL_DIAG_CLASS_ORIGIN:
99 case SQL_DIAG_SUBCLASS_ORIGIN:
100 case SQL_DIAG_CONNECTION_NAME:
101 case SQL_DIAG_SERVER_NAME:
102 rtnlen = 0;
103 if (DiagInfoPtr && BufferLength > rtnlen)
104 {
105 ret = SQL_SUCCESS;
106 *((char *) DiagInfoPtr) = '\0';
107 }
108 else
109 ret = SQL_SUCCESS_WITH_INFO;
110 break;
111 case SQL_DIAG_MESSAGE_TEXT:
112 ret = PGAPI_EnvError(Handle, RecNumber,
113 NULL, NULL, DiagInfoPtr,
114 BufferLength, StringLengthPtr, 0);
115 break;
116 case SQL_DIAG_NATIVE:
117 rtnctype = SQL_C_LONG;
118 ret = PGAPI_EnvError(Handle, RecNumber,
119 NULL, (SQLINTEGER *) DiagInfoPtr, NULL,
120 0, NULL, 0);
121 break;
122 case SQL_DIAG_NUMBER:
123 rtnctype = SQL_C_LONG;
124 ret = PGAPI_EnvError(Handle, RecNumber,
125 NULL, NULL, NULL,
126 0, NULL, 0);
127 if (SQL_SUCCEEDED(ret))
128 {
129 *((SQLINTEGER *) DiagInfoPtr) = 1;
130 }
131 break;
132 case SQL_DIAG_SQLSTATE:
133 rtnlen = 5;
134 ret = PGAPI_EnvError(Handle, RecNumber,
135 DiagInfoPtr, NULL, NULL,
136 0, NULL, 0);
137 if (SQL_SUCCESS_WITH_INFO == ret)
138 ret = SQL_SUCCESS;
139 break;
140 case SQL_DIAG_RETURNCODE: /* driver manager returns */
141 break;
142 case SQL_DIAG_CURSOR_ROW_COUNT:
143 case SQL_DIAG_ROW_COUNT:
144 case SQL_DIAG_DYNAMIC_FUNCTION:
145 case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
146 /* options for statement type only */
147 break;
148 }
149 break;
150 case SQL_HANDLE_DBC:
151 conn = (ConnectionClass *) Handle;
152 switch (DiagIdentifier)
153 {
154 case SQL_DIAG_CLASS_ORIGIN:
155 case SQL_DIAG_SUBCLASS_ORIGIN:
156 case SQL_DIAG_CONNECTION_NAME:
157 rtnlen = 0;
158 if (DiagInfoPtr && BufferLength > rtnlen)
159 {
160 ret = SQL_SUCCESS;
161 *((char *) DiagInfoPtr) = '\0';
162 }
163 else
164 ret = SQL_SUCCESS_WITH_INFO;
165 break;
166 case SQL_DIAG_SERVER_NAME:
167 rtnlen = strlen(CC_get_DSN(conn));
168 if (DiagInfoPtr)
169 {
170 strncpy_null(DiagInfoPtr, CC_get_DSN(conn), BufferLength);
171 ret = (BufferLength > rtnlen ? SQL_SUCCESS : SQL_SUCCESS_WITH_INFO);
172 }
173 else
174 ret = SQL_SUCCESS_WITH_INFO;
175 break;
176 case SQL_DIAG_MESSAGE_TEXT:
177 ret = PGAPI_ConnectError(Handle, RecNumber,
178 NULL, NULL, DiagInfoPtr,
179 BufferLength, StringLengthPtr, 0);
180 break;
181 case SQL_DIAG_NATIVE:
182 rtnctype = SQL_C_LONG;
183 ret = PGAPI_ConnectError(Handle, RecNumber,
184 NULL, (SQLINTEGER *) DiagInfoPtr, NULL,
185 0, NULL, 0);
186 break;
187 case SQL_DIAG_NUMBER:
188 rtnctype = SQL_C_LONG;
189 ret = PGAPI_ConnectError(Handle, RecNumber,
190 NULL, NULL, NULL,
191 0, NULL, 0);
192 if (SQL_SUCCEEDED(ret))
193 {
194 *((SQLINTEGER *) DiagInfoPtr) = 1;
195 }
196 break;
197 case SQL_DIAG_SQLSTATE:
198 rtnlen = 5;
199 ret = PGAPI_ConnectError(Handle, RecNumber,
200 DiagInfoPtr, NULL, NULL,
201 0, NULL, 0);
202 if (SQL_SUCCESS_WITH_INFO == ret)
203 ret = SQL_SUCCESS;
204 break;
205 case SQL_DIAG_RETURNCODE: /* driver manager returns */
206 break;
207 case SQL_DIAG_CURSOR_ROW_COUNT:
208 case SQL_DIAG_ROW_COUNT:
209 case SQL_DIAG_DYNAMIC_FUNCTION:
210 case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
211 /* options for statement type only */
212 break;
213 }
214 break;
215 case SQL_HANDLE_STMT:
216 conn = (ConnectionClass *) SC_get_conn(((StatementClass *) Handle));
217 switch (DiagIdentifier)
218 {
219 case SQL_DIAG_CLASS_ORIGIN:
220 case SQL_DIAG_SUBCLASS_ORIGIN:
221 case SQL_DIAG_CONNECTION_NAME:
222 rtnlen = 0;
223 if (DiagInfoPtr && BufferLength > rtnlen)
224 {
225 ret = SQL_SUCCESS;
226 *((char *) DiagInfoPtr) = '\0';
227 }
228 else
229 ret = SQL_SUCCESS_WITH_INFO;
230 break;
231 case SQL_DIAG_SERVER_NAME:
232 rtnlen = strlen(CC_get_DSN(conn));
233 if (DiagInfoPtr)
234 {
235 strncpy_null(DiagInfoPtr, CC_get_DSN(conn), BufferLength);
236 ret = (BufferLength > rtnlen ? SQL_SUCCESS : SQL_SUCCESS_WITH_INFO);
237 }
238 else
239 ret = SQL_SUCCESS_WITH_INFO;
240 break;
241 case SQL_DIAG_MESSAGE_TEXT:
242 ret = PGAPI_StmtError(Handle, RecNumber,
243 NULL, NULL, DiagInfoPtr,
244 BufferLength, StringLengthPtr, 0);
245 break;
246 case SQL_DIAG_NATIVE:
247 rtnctype = SQL_C_LONG;
248 ret = PGAPI_StmtError(Handle, RecNumber,
249 NULL, (SQLINTEGER *) DiagInfoPtr, NULL,
250 0, NULL, 0);
251 break;
252 case SQL_DIAG_NUMBER:
253 rtnctype = SQL_C_LONG;
254 *((SQLINTEGER *) DiagInfoPtr) = 0;
255 ret = SQL_NO_DATA_FOUND;
256 stmt = (StatementClass *) Handle;
257 rtn = PGAPI_StmtError(Handle, -1, NULL,
258 NULL, NULL, 0, &pcbErrm, 0);
259 switch (rtn)
260 {
261 case SQL_SUCCESS:
262 case SQL_SUCCESS_WITH_INFO:
263 ret = SQL_SUCCESS;
264 if (pcbErrm > 0 && stmt->pgerror)
265
266 *((SQLINTEGER *) DiagInfoPtr) = (pcbErrm - 1)/ stmt->pgerror->recsize + 1;
267 break;
268 default:
269 break;
270 }
271 break;
272 case SQL_DIAG_SQLSTATE:
273 rtnlen = 5;
274 ret = PGAPI_StmtError(Handle, RecNumber,
275 DiagInfoPtr, NULL, NULL,
276 0, NULL, 0);
277 if (SQL_SUCCESS_WITH_INFO == ret)
278 ret = SQL_SUCCESS;
279 break;
280 case SQL_DIAG_CURSOR_ROW_COUNT:
281 rtnctype = SQL_C_LONG;
282 stmt = (StatementClass *) Handle;
283 rc = -1;
284 if (stmt->status == STMT_FINISHED)
285 {
286 QResultClass *res = SC_get_Curres(stmt);
287
288 /*if (!res)
289 return SQL_ERROR;*/
290 if (stmt->proc_return > 0)
291 rc = 0;
292 else if (res && QR_NumResultCols(res) > 0 && !SC_is_fetchcursor(stmt))
293 rc = QR_get_num_total_tuples(res) - res->dl_count;
294 }
295 *((SQLLEN *) DiagInfoPtr) = rc;
296 MYLOG(DETAIL_LOG_LEVEL, "rc=" FORMAT_LEN "\n", rc);
297 ret = SQL_SUCCESS;
298 break;
299 case SQL_DIAG_ROW_COUNT:
300 rtnctype = SQL_C_LONG;
301 stmt = (StatementClass *) Handle;
302 *((SQLLEN *) DiagInfoPtr) = stmt->diag_row_count;
303 ret = SQL_SUCCESS;
304 break;
305 case SQL_DIAG_ROW_NUMBER:
306 rtnctype = SQL_C_LONG;
307 *((SQLLEN *) DiagInfoPtr) = SQL_ROW_NUMBER_UNKNOWN;
308 ret = SQL_SUCCESS;
309 break;
310 case SQL_DIAG_COLUMN_NUMBER:
311 rtnctype = SQL_C_LONG;
312 *((SQLINTEGER *) DiagInfoPtr) = SQL_COLUMN_NUMBER_UNKNOWN;
313 ret = SQL_SUCCESS;
314 break;
315 case SQL_DIAG_RETURNCODE: /* driver manager returns */
316 break;
317 }
318 break;
319 case SQL_HANDLE_DESC:
320 conn = DC_get_conn(((DescriptorClass *) Handle));
321 switch (DiagIdentifier)
322 {
323 case SQL_DIAG_CLASS_ORIGIN:
324 case SQL_DIAG_SUBCLASS_ORIGIN:
325 case SQL_DIAG_CONNECTION_NAME:
326 rtnlen = 0;
327 if (DiagInfoPtr && BufferLength > rtnlen)
328 {
329 ret = SQL_SUCCESS;
330 *((char *) DiagInfoPtr) = '\0';
331 }
332 else
333 ret = SQL_SUCCESS_WITH_INFO;
334 break;
335 case SQL_DIAG_SERVER_NAME:
336 rtnlen = strlen(CC_get_DSN(conn));
337 if (DiagInfoPtr)
338 {
339 strncpy_null(DiagInfoPtr, CC_get_DSN(conn), BufferLength);
340 ret = (BufferLength > rtnlen ? SQL_SUCCESS : SQL_SUCCESS_WITH_INFO);
341 }
342 else
343 ret = SQL_SUCCESS_WITH_INFO;
344 break;
345 case SQL_DIAG_MESSAGE_TEXT:
346 case SQL_DIAG_NATIVE:
347 case SQL_DIAG_NUMBER:
348 break;
349 case SQL_DIAG_SQLSTATE:
350 rtnlen = 5;
351 ret = PGAPI_DescError(Handle, RecNumber,
352 DiagInfoPtr, NULL, NULL,
353 0, NULL, 0);
354 if (SQL_SUCCESS_WITH_INFO == ret)
355 ret = SQL_SUCCESS;
356 break;
357 case SQL_DIAG_RETURNCODE: /* driver manager returns */
358 break;
359 case SQL_DIAG_CURSOR_ROW_COUNT:
360 case SQL_DIAG_ROW_COUNT:
361 case SQL_DIAG_DYNAMIC_FUNCTION:
362 case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
363 rtnctype = SQL_C_LONG;
364 /* options for statement type only */
365 break;
366 }
367 break;
368 default:
369 ret = SQL_ERROR;
370 }
371 if (SQL_C_LONG == rtnctype)
372 {
373 if (SQL_SUCCESS_WITH_INFO == ret)
374 ret = SQL_SUCCESS;
375 if (StringLengthPtr)
376 *StringLengthPtr = sizeof(SQLINTEGER);
377 }
378 else if (rtnlen >= 0)
379 {
380 if (rtnlen >= BufferLength)
381 {
382 if (SQL_SUCCESS == ret)
383 ret = SQL_SUCCESS_WITH_INFO;
384 if (BufferLength > 0)
385 ((char *) DiagInfoPtr) [BufferLength - 1] = '\0';
386 }
387 if (StringLengthPtr)
388 *StringLengthPtr = (SQLSMALLINT) rtnlen;
389 }
390 MYLOG(0, "leaving %d\n", ret);
391 return ret;
392 }
393
394 /* SQLGetConnectOption -> SQLGetconnectAttr */
395 RETCODE SQL_API
PGAPI_GetConnectAttr(HDBC ConnectionHandle,SQLINTEGER Attribute,PTR Value,SQLINTEGER BufferLength,SQLINTEGER * StringLength)396 PGAPI_GetConnectAttr(HDBC ConnectionHandle,
397 SQLINTEGER Attribute, PTR Value,
398 SQLINTEGER BufferLength, SQLINTEGER *StringLength)
399 {
400 ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
401 RETCODE ret = SQL_SUCCESS;
402 SQLINTEGER len = 4;
403
404 MYLOG(0, "entering " FORMAT_INTEGER "\n", Attribute);
405 switch (Attribute)
406 {
407 case SQL_ATTR_ASYNC_ENABLE:
408 *((SQLINTEGER *) Value) = SQL_ASYNC_ENABLE_OFF;
409 break;
410 case SQL_ATTR_AUTO_IPD:
411 *((SQLINTEGER *) Value) = SQL_FALSE;
412 break;
413 case SQL_ATTR_CONNECTION_DEAD:
414 *((SQLUINTEGER *) Value) = CC_not_connected(conn);
415 break;
416 case SQL_ATTR_CONNECTION_TIMEOUT:
417 *((SQLUINTEGER *) Value) = 0;
418 break;
419 case SQL_ATTR_METADATA_ID:
420 *((SQLUINTEGER *) Value) = conn->stmtOptions.metadata_id;
421 break;
422 case SQL_ATTR_PGOPT_DEBUG:
423 *((SQLINTEGER *) Value) = conn->connInfo.drivers.debug;
424 break;
425 case SQL_ATTR_PGOPT_COMMLOG:
426 *((SQLINTEGER *) Value) = conn->connInfo.drivers.commlog;
427 break;
428 case SQL_ATTR_PGOPT_PARSE:
429 *((SQLINTEGER *) Value) = conn->connInfo.drivers.parse;
430 break;
431 case SQL_ATTR_PGOPT_USE_DECLAREFETCH:
432 *((SQLINTEGER *) Value) = conn->connInfo.drivers.use_declarefetch;
433 break;
434 case SQL_ATTR_PGOPT_SERVER_SIDE_PREPARE:
435 *((SQLINTEGER *) Value) = conn->connInfo.use_server_side_prepare;
436 break;
437 case SQL_ATTR_PGOPT_FETCH:
438 *((SQLINTEGER *) Value) = conn->connInfo.drivers.fetch_max;
439 break;
440 case SQL_ATTR_PGOPT_UNKNOWNSIZES:
441 *((SQLINTEGER *) Value) = conn->connInfo.drivers.unknown_sizes;
442 break;
443 case SQL_ATTR_PGOPT_TEXTASLONGVARCHAR:
444 *((SQLINTEGER *) Value) = conn->connInfo.drivers.text_as_longvarchar;
445 break;
446 case SQL_ATTR_PGOPT_UNKNOWNSASLONGVARCHAR:
447 *((SQLINTEGER *) Value) = conn->connInfo.drivers.unknowns_as_longvarchar;
448 break;
449 case SQL_ATTR_PGOPT_BOOLSASCHAR:
450 *((SQLINTEGER *) Value) = conn->connInfo.drivers.bools_as_char;
451 break;
452 case SQL_ATTR_PGOPT_MAXVARCHARSIZE:
453 *((SQLINTEGER *) Value) = conn->connInfo.drivers.max_varchar_size;
454 break;
455 case SQL_ATTR_PGOPT_MAXLONGVARCHARSIZE:
456 *((SQLINTEGER *) Value) = conn->connInfo.drivers.max_longvarchar_size;
457 break;
458 case SQL_ATTR_PGOPT_MSJET:
459 *((SQLINTEGER *) Value) = conn->ms_jet;
460 break;
461 case SQL_ATTR_PGOPT_BATCHSIZE:
462 *((SQLINTEGER *) Value) = conn->connInfo.batch_size;
463 break;
464 case SQL_ATTR_PGOPT_IGNORETIMEOUT:
465 *((SQLINTEGER *) Value) = conn->connInfo.ignore_timeout;
466 break;
467 default:
468 ret = PGAPI_GetConnectOption(ConnectionHandle, (UWORD) Attribute, Value, &len, BufferLength);
469 }
470 if (StringLength)
471 *StringLength = len;
472 return ret;
473 }
474
475 static SQLHDESC
descHandleFromStatementHandle(HSTMT StatementHandle,SQLINTEGER descType)476 descHandleFromStatementHandle(HSTMT StatementHandle, SQLINTEGER descType)
477 {
478 StatementClass *stmt = (StatementClass *) StatementHandle;
479
480 switch (descType)
481 {
482 case SQL_ATTR_APP_ROW_DESC: /* 10010 */
483 return (HSTMT) stmt->ard;
484 case SQL_ATTR_APP_PARAM_DESC: /* 10011 */
485 return (HSTMT) stmt->apd;
486 case SQL_ATTR_IMP_ROW_DESC: /* 10012 */
487 return (HSTMT) stmt->ird;
488 case SQL_ATTR_IMP_PARAM_DESC: /* 10013 */
489 return (HSTMT) stmt->ipd;
490 }
491 return (HSTMT) 0;
492 }
493
column_bindings_set(ARDFields * opts,int cols,BOOL maxset)494 static void column_bindings_set(ARDFields *opts, int cols, BOOL maxset)
495 {
496 int i;
497
498 if (cols == opts->allocated)
499 return;
500 if (cols > opts->allocated)
501 {
502 extend_column_bindings(opts, cols);
503 return;
504 }
505 if (maxset) return;
506
507 for (i = opts->allocated; i > cols; i--)
508 reset_a_column_binding(opts, i);
509 opts->allocated = cols;
510 if (0 == cols)
511 {
512 free(opts->bindings);
513 opts->bindings = NULL;
514 }
515 }
516
517 static RETCODE SQL_API
ARDSetField(DescriptorClass * desc,SQLSMALLINT RecNumber,SQLSMALLINT FieldIdentifier,PTR Value,SQLINTEGER BufferLength)518 ARDSetField(DescriptorClass *desc, SQLSMALLINT RecNumber,
519 SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength)
520 {
521 RETCODE ret = SQL_SUCCESS;
522 ARDFields *opts = &(desc->ardf);
523 SQLSMALLINT row_idx;
524 BOOL unbind = TRUE;
525
526 switch (FieldIdentifier)
527 {
528 case SQL_DESC_ARRAY_SIZE:
529 opts->size_of_rowset = CAST_UPTR(SQLULEN, Value);
530 return ret;
531 case SQL_DESC_ARRAY_STATUS_PTR:
532 opts->row_operation_ptr = Value;
533 return ret;
534 case SQL_DESC_BIND_OFFSET_PTR:
535 opts->row_offset_ptr = Value;
536 return ret;
537 case SQL_DESC_BIND_TYPE:
538 opts->bind_size = CAST_UPTR(SQLUINTEGER, Value);
539 return ret;
540 case SQL_DESC_COUNT:
541 column_bindings_set(opts, CAST_PTR(SQLSMALLINT, Value), FALSE);
542 return ret;
543
544 case SQL_DESC_TYPE:
545 case SQL_DESC_DATETIME_INTERVAL_CODE:
546 case SQL_DESC_CONCISE_TYPE:
547 column_bindings_set(opts, RecNumber, TRUE);
548 break;
549 }
550 if (RecNumber < 0 || RecNumber > opts->allocated)
551 {
552 DC_set_error(desc, DESC_INVALID_COLUMN_NUMBER_ERROR, "invalid column number");
553 return SQL_ERROR;
554 }
555 if (0 == RecNumber) /* bookmark column */
556 {
557 BindInfoClass *bookmark = ARD_AllocBookmark(opts);
558
559 switch (FieldIdentifier)
560 {
561 case SQL_DESC_DATA_PTR:
562 bookmark->buffer = Value;
563 break;
564 case SQL_DESC_INDICATOR_PTR:
565 bookmark->indicator = Value;
566 break;
567 case SQL_DESC_OCTET_LENGTH_PTR:
568 bookmark->used = Value;
569 break;
570 default:
571 DC_set_error(desc, DESC_INVALID_COLUMN_NUMBER_ERROR, "invalid column number");
572 ret = SQL_ERROR;
573 }
574 return ret;
575 }
576 row_idx = RecNumber - 1;
577 switch (FieldIdentifier)
578 {
579 case SQL_DESC_TYPE:
580 opts->bindings[row_idx].returntype = CAST_PTR(SQLSMALLINT, Value);
581 break;
582 case SQL_DESC_DATETIME_INTERVAL_CODE:
583 switch (opts->bindings[row_idx].returntype)
584 {
585 case SQL_DATETIME:
586 case SQL_C_TYPE_DATE:
587 case SQL_C_TYPE_TIME:
588 case SQL_C_TYPE_TIMESTAMP:
589 switch ((LONG_PTR) Value)
590 {
591 case SQL_CODE_DATE:
592 opts->bindings[row_idx].returntype = SQL_C_TYPE_DATE;
593 break;
594 case SQL_CODE_TIME:
595 opts->bindings[row_idx].returntype = SQL_C_TYPE_TIME;
596 break;
597 case SQL_CODE_TIMESTAMP:
598 opts->bindings[row_idx].returntype = SQL_C_TYPE_TIMESTAMP;
599 break;
600 }
601 break;
602 }
603 break;
604 case SQL_DESC_CONCISE_TYPE:
605 opts->bindings[row_idx].returntype = CAST_PTR(SQLSMALLINT, Value);
606 break;
607 case SQL_DESC_DATA_PTR:
608 unbind = FALSE;
609 opts->bindings[row_idx].buffer = Value;
610 break;
611 case SQL_DESC_INDICATOR_PTR:
612 unbind = FALSE;
613 opts->bindings[row_idx].indicator = Value;
614 break;
615 case SQL_DESC_OCTET_LENGTH_PTR:
616 unbind = FALSE;
617 opts->bindings[row_idx].used = Value;
618 break;
619 case SQL_DESC_OCTET_LENGTH:
620 opts->bindings[row_idx].buflen = CAST_PTR(SQLLEN, Value);
621 break;
622 case SQL_DESC_PRECISION:
623 opts->bindings[row_idx].precision = CAST_PTR(SQLSMALLINT, Value);
624 break;
625 case SQL_DESC_SCALE:
626 opts->bindings[row_idx].scale = CAST_PTR(SQLSMALLINT, Value);
627 break;
628 case SQL_DESC_ALLOC_TYPE: /* read-only */
629 case SQL_DESC_DATETIME_INTERVAL_PRECISION:
630 case SQL_DESC_LENGTH:
631 case SQL_DESC_NUM_PREC_RADIX:
632 default:ret = SQL_ERROR;
633 DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
634 "invalid descriptor identifier");
635 }
636 if (unbind)
637 opts->bindings[row_idx].buffer = NULL;
638 return ret;
639 }
640
parameter_bindings_set(APDFields * opts,int params,BOOL maxset)641 static void parameter_bindings_set(APDFields *opts, int params, BOOL maxset)
642 {
643 int i;
644
645 if (params == opts->allocated)
646 return;
647 if (params > opts->allocated)
648 {
649 extend_parameter_bindings(opts, params);
650 return;
651 }
652 if (maxset) return;
653
654 for (i = opts->allocated; i > params; i--)
655 reset_a_parameter_binding(opts, i);
656 opts->allocated = params;
657 if (0 == params)
658 {
659 free(opts->parameters);
660 opts->parameters = NULL;
661 }
662 }
663
parameter_ibindings_set(IPDFields * opts,int params,BOOL maxset)664 static void parameter_ibindings_set(IPDFields *opts, int params, BOOL maxset)
665 {
666 int i;
667
668 if (params == opts->allocated)
669 return;
670 if (params > opts->allocated)
671 {
672 extend_iparameter_bindings(opts, params);
673 return;
674 }
675 if (maxset) return;
676
677 for (i = opts->allocated; i > params; i--)
678 reset_a_iparameter_binding(opts, i);
679 opts->allocated = params;
680 if (0 == params)
681 {
682 free(opts->parameters);
683 opts->parameters = NULL;
684 }
685 }
686
687 static RETCODE SQL_API
APDSetField(DescriptorClass * desc,SQLSMALLINT RecNumber,SQLSMALLINT FieldIdentifier,PTR Value,SQLINTEGER BufferLength)688 APDSetField(DescriptorClass *desc, SQLSMALLINT RecNumber,
689 SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength)
690 {
691 RETCODE ret = SQL_SUCCESS;
692 APDFields *opts = &(desc->apdf);
693 SQLSMALLINT para_idx;
694 BOOL unbind = TRUE;
695
696 switch (FieldIdentifier)
697 {
698 case SQL_DESC_ARRAY_SIZE:
699 opts->paramset_size = CAST_UPTR(SQLUINTEGER, Value);
700 return ret;
701 case SQL_DESC_ARRAY_STATUS_PTR:
702 opts->param_operation_ptr = Value;
703 return ret;
704 case SQL_DESC_BIND_OFFSET_PTR:
705 opts->param_offset_ptr = Value;
706 return ret;
707 case SQL_DESC_BIND_TYPE:
708 opts->param_bind_type = CAST_UPTR(SQLUINTEGER, Value);
709 return ret;
710 case SQL_DESC_COUNT:
711 parameter_bindings_set(opts, CAST_PTR(SQLSMALLINT, Value), FALSE);
712 return ret;
713
714 case SQL_DESC_TYPE:
715 case SQL_DESC_DATETIME_INTERVAL_CODE:
716 case SQL_DESC_CONCISE_TYPE:
717 parameter_bindings_set(opts, RecNumber, TRUE);
718 break;
719 }
720 if (RecNumber <=0)
721 {
722 MYLOG(DETAIL_LOG_LEVEL, "RecN=%d allocated=%d\n", RecNumber, opts->allocated);
723 DC_set_error(desc, DESC_BAD_PARAMETER_NUMBER_ERROR,
724 "bad parameter number");
725 return SQL_ERROR;
726 }
727 if (RecNumber > opts->allocated)
728 {
729 MYLOG(DETAIL_LOG_LEVEL, "RecN=%d allocated=%d\n", RecNumber, opts->allocated);
730 parameter_bindings_set(opts, RecNumber, TRUE);
731 /* DC_set_error(desc, DESC_BAD_PARAMETER_NUMBER_ERROR,
732 "bad parameter number");
733 return SQL_ERROR;*/
734 }
735 para_idx = RecNumber - 1;
736 switch (FieldIdentifier)
737 {
738 case SQL_DESC_TYPE:
739 opts->parameters[para_idx].CType = CAST_PTR(SQLSMALLINT, Value);
740 break;
741 case SQL_DESC_DATETIME_INTERVAL_CODE:
742 switch (opts->parameters[para_idx].CType)
743 {
744 case SQL_DATETIME:
745 case SQL_C_TYPE_DATE:
746 case SQL_C_TYPE_TIME:
747 case SQL_C_TYPE_TIMESTAMP:
748 switch ((LONG_PTR) Value)
749 {
750 case SQL_CODE_DATE:
751 opts->parameters[para_idx].CType = SQL_C_TYPE_DATE;
752 break;
753 case SQL_CODE_TIME:
754 opts->parameters[para_idx].CType = SQL_C_TYPE_TIME;
755 break;
756 case SQL_CODE_TIMESTAMP:
757 opts->parameters[para_idx].CType = SQL_C_TYPE_TIMESTAMP;
758 break;
759 }
760 break;
761 }
762 break;
763 case SQL_DESC_CONCISE_TYPE:
764 opts->parameters[para_idx].CType = CAST_PTR(SQLSMALLINT, Value);
765 break;
766 case SQL_DESC_DATA_PTR:
767 unbind = FALSE;
768 opts->parameters[para_idx].buffer = Value;
769 break;
770 case SQL_DESC_INDICATOR_PTR:
771 unbind = FALSE;
772 opts->parameters[para_idx].indicator = Value;
773 break;
774 case SQL_DESC_OCTET_LENGTH:
775 opts->parameters[para_idx].buflen = CAST_PTR(Int4, Value);
776 break;
777 case SQL_DESC_OCTET_LENGTH_PTR:
778 unbind = FALSE;
779 opts->parameters[para_idx].used = Value;
780 break;
781 case SQL_DESC_PRECISION:
782 opts->parameters[para_idx].precision = CAST_PTR(SQLSMALLINT, Value);
783 break;
784 case SQL_DESC_SCALE:
785 opts->parameters[para_idx].scale = CAST_PTR(SQLSMALLINT, Value);
786 break;
787 case SQL_DESC_ALLOC_TYPE: /* read-only */
788 case SQL_DESC_DATETIME_INTERVAL_PRECISION:
789 case SQL_DESC_LENGTH:
790 case SQL_DESC_NUM_PREC_RADIX:
791 default:ret = SQL_ERROR;
792 DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
793 "invaid descriptor identifier");
794 }
795 if (unbind)
796 opts->parameters[para_idx].buffer = NULL;
797
798 return ret;
799 }
800
801 static RETCODE SQL_API
IRDSetField(DescriptorClass * desc,SQLSMALLINT RecNumber,SQLSMALLINT FieldIdentifier,PTR Value,SQLINTEGER BufferLength)802 IRDSetField(DescriptorClass *desc, SQLSMALLINT RecNumber,
803 SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength)
804 {
805 RETCODE ret = SQL_SUCCESS;
806 IRDFields *opts = &(desc->irdf);
807
808 switch (FieldIdentifier)
809 {
810 case SQL_DESC_ARRAY_STATUS_PTR:
811 opts->rowStatusArray = (SQLUSMALLINT *) Value;
812 break;
813 case SQL_DESC_ROWS_PROCESSED_PTR:
814 opts->rowsFetched = (SQLULEN *) Value;
815 break;
816 case SQL_DESC_ALLOC_TYPE: /* read-only */
817 case SQL_DESC_COUNT: /* read-only */
818 case SQL_DESC_AUTO_UNIQUE_VALUE: /* read-only */
819 case SQL_DESC_BASE_COLUMN_NAME: /* read-only */
820 case SQL_DESC_BASE_TABLE_NAME: /* read-only */
821 case SQL_DESC_CASE_SENSITIVE: /* read-only */
822 case SQL_DESC_CATALOG_NAME: /* read-only */
823 case SQL_DESC_CONCISE_TYPE: /* read-only */
824 case SQL_DESC_DATETIME_INTERVAL_CODE: /* read-only */
825 case SQL_DESC_DATETIME_INTERVAL_PRECISION: /* read-only */
826 case SQL_DESC_DISPLAY_SIZE: /* read-only */
827 case SQL_DESC_FIXED_PREC_SCALE: /* read-only */
828 case SQL_DESC_LABEL: /* read-only */
829 case SQL_DESC_LENGTH: /* read-only */
830 case SQL_DESC_LITERAL_PREFIX: /* read-only */
831 case SQL_DESC_LITERAL_SUFFIX: /* read-only */
832 case SQL_DESC_LOCAL_TYPE_NAME: /* read-only */
833 case SQL_DESC_NAME: /* read-only */
834 case SQL_DESC_NULLABLE: /* read-only */
835 case SQL_DESC_NUM_PREC_RADIX: /* read-only */
836 case SQL_DESC_OCTET_LENGTH: /* read-only */
837 case SQL_DESC_PRECISION: /* read-only */
838 case SQL_DESC_ROWVER: /* read-only */
839 case SQL_DESC_SCALE: /* read-only */
840 case SQL_DESC_SCHEMA_NAME: /* read-only */
841 case SQL_DESC_SEARCHABLE: /* read-only */
842 case SQL_DESC_TABLE_NAME: /* read-only */
843 case SQL_DESC_TYPE: /* read-only */
844 case SQL_DESC_TYPE_NAME: /* read-only */
845 case SQL_DESC_UNNAMED: /* read-only */
846 case SQL_DESC_UNSIGNED: /* read-only */
847 case SQL_DESC_UPDATABLE: /* read-only */
848 default:ret = SQL_ERROR;
849 DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
850 "invalid descriptor identifier");
851 }
852 return ret;
853 }
854
855 static RETCODE SQL_API
IPDSetField(DescriptorClass * desc,SQLSMALLINT RecNumber,SQLSMALLINT FieldIdentifier,PTR Value,SQLINTEGER BufferLength)856 IPDSetField(DescriptorClass *desc, SQLSMALLINT RecNumber,
857 SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength)
858 {
859 RETCODE ret = SQL_SUCCESS;
860 IPDFields *ipdopts = &(desc->ipdf);
861 SQLSMALLINT para_idx;
862
863 switch (FieldIdentifier)
864 {
865 case SQL_DESC_ARRAY_STATUS_PTR:
866 ipdopts->param_status_ptr = (SQLUSMALLINT *) Value;
867 return ret;
868 case SQL_DESC_ROWS_PROCESSED_PTR:
869 ipdopts->param_processed_ptr = (SQLULEN *) Value;
870 return ret;
871 case SQL_DESC_COUNT:
872 parameter_ibindings_set(ipdopts, CAST_PTR(SQLSMALLINT, Value), FALSE);
873 return ret;
874 case SQL_DESC_UNNAMED: /* only SQL_UNNAMED is allowed */
875 if (SQL_UNNAMED != CAST_PTR(SQLSMALLINT, Value))
876 {
877 ret = SQL_ERROR;
878 DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
879 "invalid descriptor identifier");
880 return ret;
881 }
882 case SQL_DESC_NAME:
883 case SQL_DESC_TYPE:
884 case SQL_DESC_DATETIME_INTERVAL_CODE:
885 case SQL_DESC_CONCISE_TYPE:
886 parameter_ibindings_set(ipdopts, RecNumber, TRUE);
887 break;
888 }
889 if (RecNumber <= 0 || RecNumber > ipdopts->allocated)
890 {
891 MYLOG(DETAIL_LOG_LEVEL, "RecN=%d allocated=%d\n", RecNumber, ipdopts->allocated);
892 DC_set_error(desc, DESC_BAD_PARAMETER_NUMBER_ERROR,
893 "bad parameter number");
894 return SQL_ERROR;
895 }
896 para_idx = RecNumber - 1;
897 switch (FieldIdentifier)
898 {
899 case SQL_DESC_TYPE:
900 if (ipdopts->parameters[para_idx].SQLType != CAST_PTR(SQLSMALLINT, Value))
901 {
902 reset_a_iparameter_binding(ipdopts, RecNumber);
903 ipdopts->parameters[para_idx].SQLType = CAST_PTR(SQLSMALLINT, Value);
904 }
905 break;
906 case SQL_DESC_DATETIME_INTERVAL_CODE:
907 switch (ipdopts->parameters[para_idx].SQLType)
908 {
909 case SQL_DATETIME:
910 case SQL_TYPE_DATE:
911 case SQL_TYPE_TIME:
912 case SQL_TYPE_TIMESTAMP:
913 switch ((LONG_PTR) Value)
914 {
915 case SQL_CODE_DATE:
916 ipdopts->parameters[para_idx].SQLType = SQL_TYPE_DATE;
917 break;
918 case SQL_CODE_TIME:
919 ipdopts->parameters[para_idx].SQLType = SQL_TYPE_TIME;
920 break;
921 case SQL_CODE_TIMESTAMP:
922 ipdopts->parameters[para_idx].SQLType = SQL_TYPE_TIMESTAMP;
923 break;
924 }
925 break;
926 }
927 break;
928 case SQL_DESC_CONCISE_TYPE:
929 ipdopts->parameters[para_idx].SQLType = CAST_PTR(SQLSMALLINT, Value);
930 break;
931 case SQL_DESC_NAME:
932 if (Value)
933 STR_TO_NAME(ipdopts->parameters[para_idx].paramName, Value);
934 else
935 NULL_THE_NAME(ipdopts->parameters[para_idx].paramName);
936 break;
937 case SQL_DESC_PARAMETER_TYPE:
938 ipdopts->parameters[para_idx].paramType = CAST_PTR(SQLSMALLINT, Value);
939 break;
940 case SQL_DESC_SCALE:
941 ipdopts->parameters[para_idx].decimal_digits = CAST_PTR(SQLSMALLINT, Value);
942 break;
943 case SQL_DESC_UNNAMED: /* only SQL_UNNAMED is allowed */
944 if (SQL_UNNAMED != CAST_PTR(SQLSMALLINT, Value))
945 {
946 ret = SQL_ERROR;
947 DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
948 "invalid descriptor identifier");
949 }
950 else
951 NULL_THE_NAME(ipdopts->parameters[para_idx].paramName);
952 break;
953 case SQL_DESC_ALLOC_TYPE: /* read-only */
954 case SQL_DESC_CASE_SENSITIVE: /* read-only */
955 case SQL_DESC_DATETIME_INTERVAL_PRECISION:
956 case SQL_DESC_FIXED_PREC_SCALE: /* read-only */
957 case SQL_DESC_LENGTH:
958 case SQL_DESC_LOCAL_TYPE_NAME: /* read-only */
959 case SQL_DESC_NULLABLE: /* read-only */
960 case SQL_DESC_NUM_PREC_RADIX:
961 case SQL_DESC_OCTET_LENGTH:
962 case SQL_DESC_PRECISION:
963 case SQL_DESC_ROWVER: /* read-only */
964 case SQL_DESC_TYPE_NAME: /* read-only */
965 case SQL_DESC_UNSIGNED: /* read-only */
966 default:ret = SQL_ERROR;
967 DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
968 "invalid descriptor identifier");
969 }
970 return ret;
971 }
972
973
974 static RETCODE SQL_API
ARDGetField(DescriptorClass * desc,SQLSMALLINT RecNumber,SQLSMALLINT FieldIdentifier,PTR Value,SQLINTEGER BufferLength,SQLINTEGER * StringLength)975 ARDGetField(DescriptorClass *desc, SQLSMALLINT RecNumber,
976 SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength,
977 SQLINTEGER *StringLength)
978 {
979 RETCODE ret = SQL_SUCCESS;
980 SQLLEN ival = 0;
981 SQLINTEGER len, rettype = 0;
982 PTR ptr = NULL;
983 const ARDFields *opts = &(desc->ardf);
984 SQLSMALLINT row_idx;
985
986 len = sizeof(SQLINTEGER);
987 if (0 == RecNumber) /* bookmark */
988 {
989 BindInfoClass *bookmark = opts->bookmark;
990 switch (FieldIdentifier)
991 {
992 case SQL_DESC_DATA_PTR:
993 rettype = SQL_IS_POINTER;
994 ptr = bookmark ? bookmark->buffer : NULL;
995 break;
996 case SQL_DESC_INDICATOR_PTR:
997 rettype = SQL_IS_POINTER;
998 ptr = bookmark ? bookmark->indicator : NULL;
999 break;
1000 case SQL_DESC_OCTET_LENGTH_PTR:
1001 rettype = SQL_IS_POINTER;
1002 ptr = bookmark ? bookmark->used : NULL;
1003 break;
1004 }
1005 if (ptr)
1006 {
1007 *((void **) Value) = ptr;
1008 if (StringLength)
1009 *StringLength = len;
1010 return ret;
1011 }
1012 }
1013 switch (FieldIdentifier)
1014 {
1015 case SQL_DESC_ARRAY_SIZE:
1016 case SQL_DESC_ARRAY_STATUS_PTR:
1017 case SQL_DESC_BIND_OFFSET_PTR:
1018 case SQL_DESC_BIND_TYPE:
1019 case SQL_DESC_COUNT:
1020 break;
1021 default:
1022 if (RecNumber <= 0 || RecNumber > opts->allocated)
1023 {
1024 DC_set_error(desc, DESC_INVALID_COLUMN_NUMBER_ERROR,
1025 "invalid column number");
1026 return SQL_ERROR;
1027 }
1028 }
1029 row_idx = RecNumber - 1;
1030 switch (FieldIdentifier)
1031 {
1032 case SQL_DESC_ARRAY_SIZE:
1033 ival = opts->size_of_rowset;
1034 break;
1035 case SQL_DESC_ARRAY_STATUS_PTR:
1036 rettype = SQL_IS_POINTER;
1037 ptr = opts->row_operation_ptr;
1038 break;
1039 case SQL_DESC_BIND_OFFSET_PTR:
1040 rettype = SQL_IS_POINTER;
1041 ptr = opts->row_offset_ptr;
1042 break;
1043 case SQL_DESC_BIND_TYPE:
1044 ival = opts->bind_size;
1045 break;
1046 case SQL_DESC_TYPE:
1047 rettype = SQL_IS_SMALLINT;
1048 switch (opts->bindings[row_idx].returntype)
1049 {
1050 case SQL_C_TYPE_DATE:
1051 case SQL_C_TYPE_TIME:
1052 case SQL_C_TYPE_TIMESTAMP:
1053 ival = SQL_DATETIME;
1054 break;
1055 default:
1056 ival = opts->bindings[row_idx].returntype;
1057 }
1058 break;
1059 case SQL_DESC_DATETIME_INTERVAL_CODE:
1060 rettype = SQL_IS_SMALLINT;
1061 switch (opts->bindings[row_idx].returntype)
1062 {
1063 case SQL_C_TYPE_DATE:
1064 ival = SQL_CODE_DATE;
1065 break;
1066 case SQL_C_TYPE_TIME:
1067 ival = SQL_CODE_TIME;
1068 break;
1069 case SQL_C_TYPE_TIMESTAMP:
1070 ival = SQL_CODE_TIMESTAMP;
1071 break;
1072 default:
1073 ival = 0;
1074 break;
1075 }
1076 break;
1077 case SQL_DESC_CONCISE_TYPE:
1078 rettype = SQL_IS_SMALLINT;
1079 ival = opts->bindings[row_idx].returntype;
1080 break;
1081 case SQL_DESC_DATA_PTR:
1082 rettype = SQL_IS_POINTER;
1083 ptr = opts->bindings[row_idx].buffer;
1084 break;
1085 case SQL_DESC_INDICATOR_PTR:
1086 rettype = SQL_IS_POINTER;
1087 ptr = opts->bindings[row_idx].indicator;
1088 break;
1089 case SQL_DESC_OCTET_LENGTH_PTR:
1090 rettype = SQL_IS_POINTER;
1091 ptr = opts->bindings[row_idx].used;
1092 break;
1093 case SQL_DESC_COUNT:
1094 rettype = SQL_IS_SMALLINT;
1095 ival = opts->allocated;
1096 break;
1097 case SQL_DESC_OCTET_LENGTH:
1098 ival = opts->bindings[row_idx].buflen;
1099 break;
1100 case SQL_DESC_ALLOC_TYPE: /* read-only */
1101 rettype = SQL_IS_SMALLINT;
1102 if (DC_get_embedded(desc))
1103 ival = SQL_DESC_ALLOC_AUTO;
1104 else
1105 ival = SQL_DESC_ALLOC_USER;
1106 break;
1107 case SQL_DESC_PRECISION:
1108 rettype = SQL_IS_SMALLINT;
1109 ival = opts->bindings[row_idx].precision;
1110 break;
1111 case SQL_DESC_SCALE:
1112 rettype = SQL_IS_SMALLINT;
1113 ival = opts->bindings[row_idx].scale;
1114 break;
1115 case SQL_DESC_NUM_PREC_RADIX:
1116 ival = 10;
1117 break;
1118 case SQL_DESC_DATETIME_INTERVAL_PRECISION:
1119 case SQL_DESC_LENGTH:
1120 default:
1121 ret = SQL_ERROR;
1122 DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
1123 "invalid descriptor identifier");
1124 }
1125 switch (rettype)
1126 {
1127 case 0:
1128 case SQL_IS_INTEGER:
1129 len = sizeof(SQLINTEGER);
1130 *((SQLINTEGER *) Value) = (SQLINTEGER) ival;
1131 break;
1132 case SQL_IS_SMALLINT:
1133 len = sizeof(SQLSMALLINT);
1134 *((SQLSMALLINT *) Value) = (SQLSMALLINT) ival;
1135 break;
1136 case SQL_IS_POINTER:
1137 len = sizeof(SQLPOINTER);
1138 *((void **) Value) = ptr;
1139 break;
1140 }
1141
1142 if (StringLength)
1143 *StringLength = len;
1144 return ret;
1145 }
1146
1147 static RETCODE SQL_API
APDGetField(DescriptorClass * desc,SQLSMALLINT RecNumber,SQLSMALLINT FieldIdentifier,PTR Value,SQLINTEGER BufferLength,SQLINTEGER * StringLength)1148 APDGetField(DescriptorClass *desc, SQLSMALLINT RecNumber,
1149 SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength,
1150 SQLINTEGER *StringLength)
1151 {
1152 RETCODE ret = SQL_SUCCESS;
1153 SQLLEN ival = 0;
1154 SQLINTEGER len, rettype = 0;
1155 PTR ptr = NULL;
1156 const APDFields *opts = (const APDFields *) &(desc->apdf);
1157 SQLSMALLINT para_idx;
1158
1159 len = sizeof(SQLINTEGER);
1160 switch (FieldIdentifier)
1161 {
1162 case SQL_DESC_ARRAY_SIZE:
1163 case SQL_DESC_ARRAY_STATUS_PTR:
1164 case SQL_DESC_BIND_OFFSET_PTR:
1165 case SQL_DESC_BIND_TYPE:
1166 case SQL_DESC_COUNT:
1167 break;
1168 default:if (RecNumber <= 0 || RecNumber > opts->allocated)
1169 {
1170 MYLOG(DETAIL_LOG_LEVEL, "RecN=%d allocated=%d\n", RecNumber, opts->allocated);
1171 DC_set_error(desc, DESC_BAD_PARAMETER_NUMBER_ERROR,
1172 "bad parameter number");
1173 return SQL_ERROR;
1174 }
1175 }
1176 para_idx = RecNumber - 1;
1177 switch (FieldIdentifier)
1178 {
1179 case SQL_DESC_ARRAY_SIZE:
1180 rettype = SQL_IS_LEN;
1181 ival = opts->paramset_size;
1182 break;
1183 case SQL_DESC_ARRAY_STATUS_PTR:
1184 rettype = SQL_IS_POINTER;
1185 ptr = opts->param_operation_ptr;
1186 break;
1187 case SQL_DESC_BIND_OFFSET_PTR:
1188 rettype = SQL_IS_POINTER;
1189 ptr = opts->param_offset_ptr;
1190 break;
1191 case SQL_DESC_BIND_TYPE:
1192 ival = opts->param_bind_type;
1193 break;
1194
1195 case SQL_DESC_TYPE:
1196 rettype = SQL_IS_SMALLINT;
1197 switch (opts->parameters[para_idx].CType)
1198 {
1199 case SQL_C_TYPE_DATE:
1200 case SQL_C_TYPE_TIME:
1201 case SQL_C_TYPE_TIMESTAMP:
1202 ival = SQL_DATETIME;
1203 break;
1204 default:
1205 ival = opts->parameters[para_idx].CType;
1206 }
1207 break;
1208 case SQL_DESC_DATETIME_INTERVAL_CODE:
1209 rettype = SQL_IS_SMALLINT;
1210 switch (opts->parameters[para_idx].CType)
1211 {
1212 case SQL_C_TYPE_DATE:
1213 ival = SQL_CODE_DATE;
1214 break;
1215 case SQL_C_TYPE_TIME:
1216 ival = SQL_CODE_TIME;
1217 break;
1218 case SQL_C_TYPE_TIMESTAMP:
1219 ival = SQL_CODE_TIMESTAMP;
1220 break;
1221 default:
1222 ival = 0;
1223 break;
1224 }
1225 break;
1226 case SQL_DESC_CONCISE_TYPE:
1227 rettype = SQL_IS_SMALLINT;
1228 ival = opts->parameters[para_idx].CType;
1229 break;
1230 case SQL_DESC_DATA_PTR:
1231 rettype = SQL_IS_POINTER;
1232 ptr = opts->parameters[para_idx].buffer;
1233 break;
1234 case SQL_DESC_INDICATOR_PTR:
1235 rettype = SQL_IS_POINTER;
1236 ptr = opts->parameters[para_idx].indicator;
1237 break;
1238 case SQL_DESC_OCTET_LENGTH:
1239 ival = opts->parameters[para_idx].buflen;
1240 break;
1241 case SQL_DESC_OCTET_LENGTH_PTR:
1242 rettype = SQL_IS_POINTER;
1243 ptr = opts->parameters[para_idx].used;
1244 break;
1245 case SQL_DESC_COUNT:
1246 rettype = SQL_IS_SMALLINT;
1247 ival = opts->allocated;
1248 break;
1249 case SQL_DESC_ALLOC_TYPE: /* read-only */
1250 rettype = SQL_IS_SMALLINT;
1251 if (DC_get_embedded(desc))
1252 ival = SQL_DESC_ALLOC_AUTO;
1253 else
1254 ival = SQL_DESC_ALLOC_USER;
1255 break;
1256 case SQL_DESC_NUM_PREC_RADIX:
1257 ival = 10;
1258 break;
1259 case SQL_DESC_PRECISION:
1260 rettype = SQL_IS_SMALLINT;
1261 ival = opts->parameters[para_idx].precision;
1262 break;
1263 case SQL_DESC_SCALE:
1264 rettype = SQL_IS_SMALLINT;
1265 ival = opts->parameters[para_idx].scale;
1266 break;
1267 case SQL_DESC_DATETIME_INTERVAL_PRECISION:
1268 case SQL_DESC_LENGTH:
1269 default:ret = SQL_ERROR;
1270 DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
1271 "invalid descriptor identifer");
1272 }
1273 switch (rettype)
1274 {
1275 case SQL_IS_LEN:
1276 len = sizeof(SQLLEN);
1277 *((SQLLEN *) Value) = ival;
1278 break;
1279 case 0:
1280 case SQL_IS_INTEGER:
1281 len = sizeof(SQLINTEGER);
1282 *((SQLINTEGER *) Value) = (SQLINTEGER) ival;
1283 break;
1284 case SQL_IS_SMALLINT:
1285 len = sizeof(SQLSMALLINT);
1286 *((SQLSMALLINT *) Value) = (SQLSMALLINT) ival;
1287 break;
1288 case SQL_IS_POINTER:
1289 len = sizeof(SQLPOINTER);
1290 *((void **) Value) = ptr;
1291 break;
1292 }
1293
1294 if (StringLength)
1295 *StringLength = len;
1296 return ret;
1297 }
1298
1299 static RETCODE SQL_API
IRDGetField(DescriptorClass * desc,SQLSMALLINT RecNumber,SQLSMALLINT FieldIdentifier,PTR Value,SQLINTEGER BufferLength,SQLINTEGER * StringLength)1300 IRDGetField(DescriptorClass *desc, SQLSMALLINT RecNumber,
1301 SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength,
1302 SQLINTEGER *StringLength)
1303 {
1304 RETCODE ret = SQL_SUCCESS;
1305 SQLLEN ival = 0;
1306 SQLINTEGER len = 0, rettype = 0;
1307 PTR ptr = NULL;
1308 BOOL bCallColAtt = FALSE;
1309 const IRDFields *opts = &(desc->irdf);
1310
1311 switch (FieldIdentifier)
1312 {
1313 case SQL_DESC_ARRAY_STATUS_PTR:
1314 rettype = SQL_IS_POINTER;
1315 ptr = opts->rowStatusArray;
1316 break;
1317 case SQL_DESC_ROWS_PROCESSED_PTR:
1318 rettype = SQL_IS_POINTER;
1319 ptr = opts->rowsFetched;
1320 break;
1321 case SQL_DESC_ALLOC_TYPE: /* read-only */
1322 rettype = SQL_IS_SMALLINT;
1323 ival = SQL_DESC_ALLOC_AUTO;
1324 break;
1325 case SQL_DESC_COUNT: /* read-only */
1326 case SQL_DESC_AUTO_UNIQUE_VALUE: /* read-only */
1327 case SQL_DESC_CASE_SENSITIVE: /* read-only */
1328 case SQL_DESC_CONCISE_TYPE: /* read-only */
1329 case SQL_DESC_DATETIME_INTERVAL_CODE: /* read-only */
1330 case SQL_DESC_DATETIME_INTERVAL_PRECISION: /* read-only */
1331 case SQL_DESC_DISPLAY_SIZE: /* read-only */
1332 case SQL_DESC_FIXED_PREC_SCALE: /* read-only */
1333 case SQL_DESC_LENGTH: /* read-only */
1334 case SQL_DESC_NULLABLE: /* read-only */
1335 case SQL_DESC_NUM_PREC_RADIX: /* read-only */
1336 case SQL_DESC_OCTET_LENGTH: /* read-only */
1337 case SQL_DESC_PRECISION: /* read-only */
1338 case SQL_DESC_ROWVER: /* read-only */
1339 case SQL_DESC_SCALE: /* read-only */
1340 case SQL_DESC_SEARCHABLE: /* read-only */
1341 case SQL_DESC_TYPE: /* read-only */
1342 case SQL_DESC_UNNAMED: /* read-only */
1343 case SQL_DESC_UNSIGNED: /* read-only */
1344 case SQL_DESC_UPDATABLE: /* read-only */
1345 bCallColAtt = TRUE;
1346 break;
1347 case SQL_DESC_BASE_COLUMN_NAME: /* read-only */
1348 case SQL_DESC_BASE_TABLE_NAME: /* read-only */
1349 case SQL_DESC_CATALOG_NAME: /* read-only */
1350 case SQL_DESC_LABEL: /* read-only */
1351 case SQL_DESC_LITERAL_PREFIX: /* read-only */
1352 case SQL_DESC_LITERAL_SUFFIX: /* read-only */
1353 case SQL_DESC_LOCAL_TYPE_NAME: /* read-only */
1354 case SQL_DESC_NAME: /* read-only */
1355 case SQL_DESC_SCHEMA_NAME: /* read-only */
1356 case SQL_DESC_TABLE_NAME: /* read-only */
1357 case SQL_DESC_TYPE_NAME: /* read-only */
1358 rettype = SQL_NTS;
1359 bCallColAtt = TRUE;
1360 break;
1361 default:
1362 ret = SQL_ERROR;
1363 DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
1364 "invalid descriptor identifier");
1365 }
1366 if (bCallColAtt)
1367 {
1368 SQLSMALLINT pcbL;
1369 StatementClass *stmt;
1370
1371 stmt = opts->stmt;
1372 ret = PGAPI_ColAttributes(stmt, RecNumber,
1373 FieldIdentifier, Value, (SQLSMALLINT) BufferLength,
1374 &pcbL, &ival);
1375 len = pcbL;
1376 }
1377 switch (rettype)
1378 {
1379 case 0:
1380 case SQL_IS_INTEGER:
1381 len = sizeof(SQLINTEGER);
1382 *((SQLINTEGER *) Value) = (SQLINTEGER) ival;
1383 break;
1384 case SQL_IS_UINTEGER:
1385 len = sizeof(SQLUINTEGER);
1386 *((SQLUINTEGER *) Value) = (SQLUINTEGER) ival;
1387 break;
1388 case SQL_IS_SMALLINT:
1389 len = sizeof(SQLSMALLINT);
1390 *((SQLSMALLINT *) Value) = (SQLSMALLINT) ival;
1391 break;
1392 case SQL_IS_POINTER:
1393 len = sizeof(SQLPOINTER);
1394 *((void **) Value) = ptr;
1395 break;
1396 case SQL_NTS:
1397 break;
1398 }
1399
1400 if (StringLength)
1401 *StringLength = len;
1402 return ret;
1403 }
1404
1405 static RETCODE SQL_API
IPDGetField(DescriptorClass * desc,SQLSMALLINT RecNumber,SQLSMALLINT FieldIdentifier,PTR Value,SQLINTEGER BufferLength,SQLINTEGER * StringLength)1406 IPDGetField(DescriptorClass *desc, SQLSMALLINT RecNumber,
1407 SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength,
1408 SQLINTEGER *StringLength)
1409 {
1410 RETCODE ret = SQL_SUCCESS;
1411 SQLINTEGER ival = 0, len = 0, rettype = 0;
1412 PTR ptr = NULL;
1413 const IPDFields *ipdopts = (const IPDFields *) &(desc->ipdf);
1414 SQLSMALLINT para_idx;
1415
1416 switch (FieldIdentifier)
1417 {
1418 case SQL_DESC_ARRAY_STATUS_PTR:
1419 case SQL_DESC_ROWS_PROCESSED_PTR:
1420 case SQL_DESC_COUNT:
1421 break;
1422 default:if (RecNumber <= 0 || RecNumber > ipdopts->allocated)
1423 {
1424 MYLOG(DETAIL_LOG_LEVEL, "RecN=%d allocated=%d\n", RecNumber, ipdopts->allocated);
1425 DC_set_error(desc, DESC_BAD_PARAMETER_NUMBER_ERROR,
1426 "bad parameter number");
1427 return SQL_ERROR;
1428 }
1429 }
1430 para_idx = RecNumber - 1;
1431 switch (FieldIdentifier)
1432 {
1433 case SQL_DESC_ARRAY_STATUS_PTR:
1434 rettype = SQL_IS_POINTER;
1435 ptr = ipdopts->param_status_ptr;
1436 break;
1437 case SQL_DESC_ROWS_PROCESSED_PTR:
1438 rettype = SQL_IS_POINTER;
1439 ptr = ipdopts->param_processed_ptr;
1440 break;
1441 case SQL_DESC_UNNAMED:
1442 rettype = SQL_IS_SMALLINT;
1443 ival = NAME_IS_NULL(ipdopts->parameters[para_idx].paramName) ? SQL_UNNAMED : SQL_NAMED;
1444 break;
1445 case SQL_DESC_TYPE:
1446 rettype = SQL_IS_SMALLINT;
1447 switch (ipdopts->parameters[para_idx].SQLType)
1448 {
1449 case SQL_TYPE_DATE:
1450 case SQL_TYPE_TIME:
1451 case SQL_TYPE_TIMESTAMP:
1452 ival = SQL_DATETIME;
1453 break;
1454 default:
1455 ival = ipdopts->parameters[para_idx].SQLType;
1456 }
1457 break;
1458 case SQL_DESC_DATETIME_INTERVAL_CODE:
1459 rettype = SQL_IS_SMALLINT;
1460 switch (ipdopts->parameters[para_idx].SQLType)
1461 {
1462 case SQL_TYPE_DATE:
1463 ival = SQL_CODE_DATE;
1464 break;
1465 case SQL_TYPE_TIME:
1466 ival = SQL_CODE_TIME;
1467 break;
1468 case SQL_TYPE_TIMESTAMP:
1469 ival = SQL_CODE_TIMESTAMP;
1470 break;
1471 default:
1472 ival = 0;
1473 }
1474 break;
1475 case SQL_DESC_CONCISE_TYPE:
1476 rettype = SQL_IS_SMALLINT;
1477 ival = ipdopts->parameters[para_idx].SQLType;
1478 break;
1479 case SQL_DESC_COUNT:
1480 rettype = SQL_IS_SMALLINT;
1481 ival = ipdopts->allocated;
1482 break;
1483 case SQL_DESC_PARAMETER_TYPE:
1484 rettype = SQL_IS_SMALLINT;
1485 ival = ipdopts->parameters[para_idx].paramType;
1486 break;
1487 case SQL_DESC_PRECISION:
1488 rettype = SQL_IS_SMALLINT;
1489 switch (ipdopts->parameters[para_idx].SQLType)
1490 {
1491 case SQL_TYPE_DATE:
1492 case SQL_TYPE_TIME:
1493 case SQL_TYPE_TIMESTAMP:
1494 case SQL_DATETIME:
1495 ival = ipdopts->parameters[para_idx].decimal_digits;
1496 break;
1497 }
1498 break;
1499 case SQL_DESC_SCALE:
1500 rettype = SQL_IS_SMALLINT;
1501 switch (ipdopts->parameters[para_idx].SQLType)
1502 {
1503 case SQL_NUMERIC:
1504 ival = ipdopts->parameters[para_idx].decimal_digits;
1505 break;
1506 }
1507 break;
1508 case SQL_DESC_ALLOC_TYPE: /* read-only */
1509 rettype = SQL_IS_SMALLINT;
1510 ival = SQL_DESC_ALLOC_AUTO;
1511 break;
1512 case SQL_DESC_CASE_SENSITIVE: /* read-only */
1513 case SQL_DESC_DATETIME_INTERVAL_PRECISION:
1514 case SQL_DESC_FIXED_PREC_SCALE: /* read-only */
1515 case SQL_DESC_LENGTH:
1516 case SQL_DESC_LOCAL_TYPE_NAME: /* read-only */
1517 case SQL_DESC_NAME:
1518 case SQL_DESC_NULLABLE: /* read-only */
1519 case SQL_DESC_NUM_PREC_RADIX:
1520 case SQL_DESC_OCTET_LENGTH:
1521 case SQL_DESC_ROWVER: /* read-only */
1522 case SQL_DESC_TYPE_NAME: /* read-only */
1523 case SQL_DESC_UNSIGNED: /* read-only */
1524 default:ret = SQL_ERROR;
1525 DC_set_error(desc, DESC_INVALID_DESCRIPTOR_IDENTIFIER,
1526 "invalid descriptor identifier");
1527 }
1528 switch (rettype)
1529 {
1530 case 0:
1531 case SQL_IS_INTEGER:
1532 len = sizeof(SQLINTEGER);
1533 *((SQLINTEGER *) Value) = ival;
1534 break;
1535 case SQL_IS_SMALLINT:
1536 len = sizeof(SQLSMALLINT);
1537 *((SQLSMALLINT *) Value) = (SQLSMALLINT) ival;
1538 break;
1539 case SQL_IS_POINTER:
1540 len = sizeof(SQLPOINTER);
1541 *((void **)Value) = ptr;
1542 break;
1543 }
1544
1545 if (StringLength)
1546 *StringLength = len;
1547 return ret;
1548 }
1549
1550 /* SQLGetStmtOption -> SQLGetStmtAttr */
1551 RETCODE SQL_API
PGAPI_GetStmtAttr(HSTMT StatementHandle,SQLINTEGER Attribute,PTR Value,SQLINTEGER BufferLength,SQLINTEGER * StringLength)1552 PGAPI_GetStmtAttr(HSTMT StatementHandle,
1553 SQLINTEGER Attribute, PTR Value,
1554 SQLINTEGER BufferLength, SQLINTEGER *StringLength)
1555 {
1556 CSTR func = "PGAPI_GetStmtAttr";
1557 StatementClass *stmt = (StatementClass *) StatementHandle;
1558 RETCODE ret = SQL_SUCCESS;
1559 SQLINTEGER len = 0;
1560
1561 MYLOG(0, "entering Handle=%p " FORMAT_INTEGER "\n", StatementHandle, Attribute);
1562 switch (Attribute)
1563 {
1564 case SQL_ATTR_FETCH_BOOKMARK_PTR: /* 16 */
1565 *((void **) Value) = stmt->options.bookmark_ptr;
1566 len = sizeof(SQLPOINTER);
1567 break;
1568 case SQL_ATTR_PARAM_BIND_OFFSET_PTR: /* 17 */
1569 *((SQLULEN **) Value) = SC_get_APDF(stmt)->param_offset_ptr;
1570 len = sizeof(SQLPOINTER);
1571 break;
1572 case SQL_ATTR_PARAM_BIND_TYPE: /* 18 */
1573 *((SQLUINTEGER *) Value) = SC_get_APDF(stmt)->param_bind_type;
1574 len = sizeof(SQLUINTEGER);
1575 break;
1576 case SQL_ATTR_PARAM_OPERATION_PTR: /* 19 */
1577 *((SQLUSMALLINT **) Value) = SC_get_APDF(stmt)->param_operation_ptr;
1578 len = sizeof(SQLPOINTER);
1579 break;
1580 case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */
1581 *((SQLUSMALLINT **) Value) = SC_get_IPDF(stmt)->param_status_ptr;
1582 len = sizeof(SQLPOINTER);
1583 break;
1584 case SQL_ATTR_PARAMS_PROCESSED_PTR: /* 21 */
1585 *((SQLULEN **) Value) = SC_get_IPDF(stmt)->param_processed_ptr;
1586 len = sizeof(SQLPOINTER);
1587 break;
1588 case SQL_ATTR_PARAMSET_SIZE: /* 22 */
1589 *((SQLULEN *) Value) = SC_get_APDF(stmt)->paramset_size;
1590 len = sizeof(SQLUINTEGER);
1591 break;
1592 case SQL_ATTR_ROW_BIND_OFFSET_PTR: /* 23 */
1593 *((SQLULEN **) Value) = SC_get_ARDF(stmt)->row_offset_ptr;
1594 len = 4;
1595 break;
1596 case SQL_ATTR_ROW_OPERATION_PTR: /* 24 */
1597 *((SQLUSMALLINT **) Value) = SC_get_ARDF(stmt)->row_operation_ptr;
1598 len = 4;
1599 break;
1600 case SQL_ATTR_ROW_STATUS_PTR: /* 25 */
1601 *((SQLUSMALLINT **) Value) = SC_get_IRDF(stmt)->rowStatusArray;
1602 len = 4;
1603 break;
1604 case SQL_ATTR_ROWS_FETCHED_PTR: /* 26 */
1605 *((SQLULEN **) Value) = SC_get_IRDF(stmt)->rowsFetched;
1606 len = 4;
1607 break;
1608 case SQL_ATTR_ROW_ARRAY_SIZE: /* 27 */
1609 *((SQLULEN *) Value) = SC_get_ARDF(stmt)->size_of_rowset;
1610 len = 4;
1611 break;
1612 case SQL_ATTR_APP_ROW_DESC: /* 10010 */
1613 case SQL_ATTR_APP_PARAM_DESC: /* 10011 */
1614 case SQL_ATTR_IMP_ROW_DESC: /* 10012 */
1615 case SQL_ATTR_IMP_PARAM_DESC: /* 10013 */
1616 len = 4;
1617 *((HSTMT *) Value) = descHandleFromStatementHandle(StatementHandle, Attribute);
1618 break;
1619
1620 case SQL_ATTR_CURSOR_SCROLLABLE: /* -1 */
1621 len = 4;
1622 if (SQL_CURSOR_FORWARD_ONLY == stmt->options.cursor_type)
1623 *((SQLUINTEGER *) Value) = SQL_NONSCROLLABLE;
1624 else
1625 *((SQLUINTEGER *) Value) = SQL_SCROLLABLE;
1626 break;
1627 case SQL_ATTR_CURSOR_SENSITIVITY: /* -2 */
1628 len = 4;
1629 if (SQL_CONCUR_READ_ONLY == stmt->options.scroll_concurrency)
1630 *((SQLUINTEGER *) Value) = SQL_INSENSITIVE;
1631 else
1632 *((SQLUINTEGER *) Value) = SQL_UNSPECIFIED;
1633 break;
1634 case SQL_ATTR_METADATA_ID: /* 10014 */
1635 *((SQLUINTEGER *) Value) = stmt->options.metadata_id;
1636 break;
1637 case SQL_ATTR_ENABLE_AUTO_IPD: /* 15 */
1638 *((SQLUINTEGER *) Value) = SQL_FALSE;
1639 break;
1640 case SQL_ATTR_AUTO_IPD: /* 10001 */
1641 /* case SQL_ATTR_ROW_BIND_TYPE: ** == SQL_BIND_TYPE(ODBC2.0) */
1642 SC_set_error(stmt, DESC_INVALID_OPTION_IDENTIFIER, "Unsupported statement option (Get)", func);
1643 return SQL_ERROR;
1644 default:
1645 ret = PGAPI_GetStmtOption(StatementHandle, (SQLSMALLINT) Attribute, Value, &len, BufferLength);
1646 }
1647 if (ret == SQL_SUCCESS && StringLength)
1648 *StringLength = len;
1649 return ret;
1650 }
1651
1652 /* SQLSetConnectOption -> SQLSetConnectAttr */
1653 RETCODE SQL_API
PGAPI_SetConnectAttr(HDBC ConnectionHandle,SQLINTEGER Attribute,PTR Value,SQLINTEGER StringLength)1654 PGAPI_SetConnectAttr(HDBC ConnectionHandle,
1655 SQLINTEGER Attribute, PTR Value,
1656 SQLINTEGER StringLength)
1657 {
1658 CSTR func = "PGAPI_SetConnectAttr";
1659 ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
1660 RETCODE ret = SQL_SUCCESS;
1661 BOOL unsupported = FALSE;
1662 int newValue;
1663
1664 MYLOG(0, "entering for %p: " FORMAT_INTEGER " %p\n", ConnectionHandle, Attribute, Value);
1665 switch (Attribute)
1666 {
1667 case SQL_ATTR_METADATA_ID:
1668 conn->stmtOptions.metadata_id = CAST_UPTR(SQLUINTEGER, Value);
1669 break;
1670 case SQL_ATTR_ANSI_APP:
1671 if (SQL_AA_FALSE != CAST_PTR(SQLINTEGER, Value))
1672 {
1673 MYLOG(0, "the application is ansi\n");
1674 if (CC_is_in_unicode_driver(conn)) /* the driver is unicode */
1675 CC_set_in_ansi_app(conn); /* but the app is ansi */
1676 }
1677 else
1678 {
1679 MYLOG(0, "the application is unicode\n");
1680 }
1681 /*return SQL_ERROR;*/
1682 return SQL_SUCCESS;
1683 case SQL_ATTR_ENLIST_IN_DTC:
1684 #ifdef WIN32
1685 #ifdef _HANDLE_ENLIST_IN_DTC_
1686 MYLOG(0, "SQL_ATTR_ENLIST_IN_DTC %p request received\n", Value);
1687 if (conn->connInfo.xa_opt != 0)
1688 {
1689 /*
1690 * When a new global transaction is about
1691 * to begin, isolate the existent global
1692 * transaction.
1693 */
1694 if (NULL != Value && CC_is_in_global_trans(conn))
1695 CALL_IsolateDtcConn(conn, TRUE);
1696 return CALL_EnlistInDtc(conn, Value, conn->connInfo.xa_opt);
1697 }
1698 #endif /* _HANDLE_ENLIST_IN_DTC_ */
1699 #endif /* WIN32 */
1700 unsupported = TRUE;
1701 break;
1702 case SQL_ATTR_AUTO_IPD:
1703 if (SQL_FALSE != Value)
1704 unsupported = TRUE;
1705 break;
1706 case SQL_ATTR_ASYNC_ENABLE:
1707 case SQL_ATTR_CONNECTION_DEAD:
1708 case SQL_ATTR_CONNECTION_TIMEOUT:
1709 unsupported = TRUE;
1710 break;
1711 case SQL_ATTR_PGOPT_DEBUG:
1712 newValue = CAST_UPTR(SQLCHAR, Value);
1713 if (newValue > 0)
1714 {
1715 logs_on_off(-1, conn->connInfo.drivers.debug, 0);
1716 conn->connInfo.drivers.debug = newValue;
1717 logs_on_off(1, conn->connInfo.drivers.debug, 0);
1718 MYLOG(0, "debug => %d\n", conn->connInfo.drivers.debug);
1719 }
1720 else if (newValue == 0 && conn->connInfo.drivers.debug > 0)
1721 {
1722 MYLOG(0, "debug => %d\n", newValue);
1723 logs_on_off(-1, conn->connInfo.drivers.debug, 0);
1724 conn->connInfo.drivers.debug = newValue;
1725 logs_on_off(1, 0, 0);
1726 }
1727 break;
1728 case SQL_ATTR_PGOPT_COMMLOG:
1729 newValue = CAST_UPTR(SQLCHAR, Value);
1730 if (newValue > 0)
1731 {
1732 logs_on_off(-1, 0, conn->connInfo.drivers.commlog);
1733 conn->connInfo.drivers.commlog = newValue;
1734 logs_on_off(1, 0, conn->connInfo.drivers.commlog);
1735 MYLOG(0, "commlog => %d\n", conn->connInfo.drivers.commlog);
1736 }
1737 else if (newValue == 0 && conn->connInfo.drivers.commlog > 0)
1738 {
1739 MYLOG(0, "commlog => %d\n", newValue);
1740 logs_on_off(-1, 0, conn->connInfo.drivers.commlog);
1741 conn->connInfo.drivers.debug = newValue;
1742 logs_on_off(1, 0, 0);
1743 }
1744 break;
1745 case SQL_ATTR_PGOPT_PARSE:
1746 conn->connInfo.drivers.parse = CAST_UPTR(SQLCHAR, Value);
1747 MYLOG(0, "parse => %d\n", conn->connInfo.drivers.parse);
1748 break;
1749 case SQL_ATTR_PGOPT_USE_DECLAREFETCH:
1750 conn->connInfo.drivers.use_declarefetch = CAST_UPTR(SQLCHAR, Value);
1751 ci_updatable_cursors_set(&conn->connInfo);
1752 MYLOG(0, "declarefetch => %d\n", conn->connInfo.drivers.use_declarefetch);
1753 break;
1754 case SQL_ATTR_PGOPT_SERVER_SIDE_PREPARE:
1755 conn->connInfo.use_server_side_prepare = CAST_UPTR(SQLCHAR, Value);
1756 MYLOG(0, "server_side_prepare => %d\n", conn->connInfo.use_server_side_prepare);
1757 break;
1758 case SQL_ATTR_PGOPT_FETCH:
1759 conn->connInfo.drivers.fetch_max = CAST_PTR(SQLINTEGER, Value);
1760 MYLOG(0, "fetch => %d\n", conn->connInfo.drivers.fetch_max);
1761 break;
1762 case SQL_ATTR_PGOPT_UNKNOWNSIZES:
1763 conn->connInfo.drivers.unknown_sizes = CAST_PTR(SQLINTEGER, Value);
1764 MYLOG(0, "unknown_sizes => %d\n", conn->connInfo.drivers.unknown_sizes);
1765 break;
1766 case SQL_ATTR_PGOPT_TEXTASLONGVARCHAR:
1767 conn->connInfo.drivers.text_as_longvarchar = CAST_PTR(SQLINTEGER, Value);
1768 MYLOG(0, "text_as_longvarchar => %d\n", conn->connInfo.drivers.text_as_longvarchar);
1769 break;
1770 case SQL_ATTR_PGOPT_UNKNOWNSASLONGVARCHAR:
1771 conn->connInfo.drivers.unknowns_as_longvarchar = CAST_PTR(SQLINTEGER, Value);
1772 MYLOG(0, "unknowns_as_long_varchar => %d\n", conn->connInfo.drivers.unknowns_as_longvarchar);
1773 break;
1774 case SQL_ATTR_PGOPT_BOOLSASCHAR:
1775 conn->connInfo.drivers.bools_as_char = CAST_PTR(SQLINTEGER, Value);
1776 MYLOG(0, "bools_as_char => %d\n", conn->connInfo.drivers.bools_as_char);
1777 break;
1778 case SQL_ATTR_PGOPT_MAXVARCHARSIZE:
1779 conn->connInfo.drivers.max_varchar_size = CAST_PTR(SQLINTEGER, Value);
1780 MYLOG(0, "max_varchar_size => %d\n", conn->connInfo.drivers.max_varchar_size);
1781 break;
1782 case SQL_ATTR_PGOPT_MAXLONGVARCHARSIZE:
1783 conn->connInfo.drivers.max_longvarchar_size = CAST_PTR(SQLINTEGER, Value);
1784 MYLOG(0, "max_longvarchar_size => %d\n", conn->connInfo.drivers.max_longvarchar_size);
1785 break;
1786 case SQL_ATTR_PGOPT_WCSDEBUG:
1787 conn->connInfo.wcs_debug = CAST_PTR(SQLINTEGER, Value);
1788 MYLOG(0, "wcs_debug => %d\n", conn->connInfo.wcs_debug);
1789 break;
1790 case SQL_ATTR_PGOPT_MSJET:
1791 conn->ms_jet = CAST_PTR(SQLINTEGER, Value);
1792 MYLOG(0, "ms_jet => %d\n", conn->ms_jet);
1793 break;
1794 case SQL_ATTR_PGOPT_BATCHSIZE:
1795 conn->connInfo.batch_size = CAST_PTR(SQLINTEGER, Value);
1796 MYLOG(0, "batch size => %d\n", conn->connInfo.batch_size);
1797 break;
1798 case SQL_ATTR_PGOPT_IGNORETIMEOUT:
1799 conn->connInfo.ignore_timeout = CAST_PTR(SQLINTEGER, Value);
1800 MYLOG(0, "ignore_timeout => %d\n", conn->connInfo.ignore_timeout);
1801 break;
1802 default:
1803 if (Attribute < 65536)
1804 ret = PGAPI_SetConnectOption(ConnectionHandle, (SQLUSMALLINT) Attribute, (SQLLEN) Value);
1805 else
1806 unsupported = TRUE;
1807 }
1808 if (unsupported)
1809 {
1810 char msg[64];
1811 SPRINTF_FIXED(msg, "Couldn't set unsupported connect attribute " FORMAT_INTEGER, Attribute);
1812 CC_set_error(conn, CONN_OPTION_NOT_FOR_THE_DRIVER, msg, func);
1813 return SQL_ERROR;
1814 }
1815 return ret;
1816 }
1817
1818 /* new function */
1819 RETCODE SQL_API
PGAPI_GetDescField(SQLHDESC DescriptorHandle,SQLSMALLINT RecNumber,SQLSMALLINT FieldIdentifier,PTR Value,SQLINTEGER BufferLength,SQLINTEGER * StringLength)1820 PGAPI_GetDescField(SQLHDESC DescriptorHandle,
1821 SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
1822 PTR Value, SQLINTEGER BufferLength,
1823 SQLINTEGER *StringLength)
1824 {
1825 CSTR func = "PGAPI_GetDescField";
1826 RETCODE ret = SQL_SUCCESS;
1827 DescriptorClass *desc = (DescriptorClass *) DescriptorHandle;
1828
1829 MYLOG(0, "entering h=%p rec=" FORMAT_SMALLI " field=" FORMAT_SMALLI " blen=" FORMAT_INTEGER "\n", DescriptorHandle, RecNumber, FieldIdentifier, BufferLength);
1830 switch (DC_get_desc_type(desc))
1831 {
1832 case SQL_ATTR_APP_ROW_DESC:
1833 ret = ARDGetField(desc, RecNumber, FieldIdentifier, Value, BufferLength, StringLength);
1834 break;
1835 case SQL_ATTR_APP_PARAM_DESC:
1836 ret = APDGetField(desc, RecNumber, FieldIdentifier, Value, BufferLength, StringLength);
1837 break;
1838 case SQL_ATTR_IMP_ROW_DESC:
1839 ret = IRDGetField(desc, RecNumber, FieldIdentifier, Value, BufferLength, StringLength);
1840 break;
1841 case SQL_ATTR_IMP_PARAM_DESC:
1842 ret = IPDGetField(desc, RecNumber, FieldIdentifier, Value, BufferLength, StringLength);
1843 break;
1844 default:ret = SQL_ERROR;
1845 DC_set_error(desc, DESC_INTERNAL_ERROR, "Error not implemented");
1846 }
1847 if (ret == SQL_ERROR)
1848 {
1849 if (!DC_get_errormsg(desc))
1850 {
1851 switch (DC_get_errornumber(desc))
1852 {
1853 case DESC_INVALID_DESCRIPTOR_IDENTIFIER:
1854 DC_set_errormsg(desc, "can't SQLGetDescField for this descriptor identifier");
1855 break;
1856 case DESC_INVALID_COLUMN_NUMBER_ERROR:
1857 DC_set_errormsg(desc, "can't SQLGetDescField for this column number");
1858 break;
1859 case DESC_BAD_PARAMETER_NUMBER_ERROR:
1860 DC_set_errormsg(desc, "can't SQLGetDescField for this parameter number");
1861 break;
1862 }
1863 }
1864 DC_log_error(func, "", desc);
1865 }
1866 return ret;
1867 }
1868
1869 /* new function */
1870 RETCODE SQL_API
PGAPI_SetDescField(SQLHDESC DescriptorHandle,SQLSMALLINT RecNumber,SQLSMALLINT FieldIdentifier,PTR Value,SQLINTEGER BufferLength)1871 PGAPI_SetDescField(SQLHDESC DescriptorHandle,
1872 SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
1873 PTR Value, SQLINTEGER BufferLength)
1874 {
1875 CSTR func = "PGAPI_SetDescField";
1876 RETCODE ret = SQL_SUCCESS;
1877 DescriptorClass *desc = (DescriptorClass *) DescriptorHandle;
1878
1879 MYLOG(0, "entering h=%p(%d) rec=" FORMAT_SMALLI " field=" FORMAT_SMALLI " val=%p," FORMAT_INTEGER "\n", DescriptorHandle, DC_get_desc_type(desc), RecNumber, FieldIdentifier, Value, BufferLength);
1880 switch (DC_get_desc_type(desc))
1881 {
1882 case SQL_ATTR_APP_ROW_DESC:
1883 ret = ARDSetField(desc, RecNumber, FieldIdentifier, Value, BufferLength);
1884 break;
1885 case SQL_ATTR_APP_PARAM_DESC:
1886 ret = APDSetField(desc, RecNumber, FieldIdentifier, Value, BufferLength);
1887 break;
1888 case SQL_ATTR_IMP_ROW_DESC:
1889 ret = IRDSetField(desc, RecNumber, FieldIdentifier, Value, BufferLength);
1890 break;
1891 case SQL_ATTR_IMP_PARAM_DESC:
1892 ret = IPDSetField(desc, RecNumber, FieldIdentifier, Value, BufferLength);
1893 break;
1894 default:ret = SQL_ERROR;
1895 DC_set_error(desc, DESC_INTERNAL_ERROR, "Error not implemented");
1896 }
1897 if (ret == SQL_ERROR)
1898 {
1899 if (!DC_get_errormsg(desc))
1900 {
1901 switch (DC_get_errornumber(desc))
1902 {
1903 case DESC_INVALID_DESCRIPTOR_IDENTIFIER:
1904 DC_set_errormsg(desc, "can't SQLSetDescField for this descriptor identifier");
1905 break;
1906 case DESC_INVALID_COLUMN_NUMBER_ERROR:
1907 DC_set_errormsg(desc, "can't SQLSetDescField for this column number");
1908 break;
1909 case DESC_BAD_PARAMETER_NUMBER_ERROR:
1910 DC_set_errormsg(desc, "can't SQLSetDescField for this parameter number");
1911 break;
1912 break;
1913 }
1914 }
1915 DC_log_error(func, "", desc);
1916 }
1917 return ret;
1918 }
1919
1920 /* SQLSet(Param/Scroll/Stmt)Option -> SQLSetStmtAttr */
1921 RETCODE SQL_API
PGAPI_SetStmtAttr(HSTMT StatementHandle,SQLINTEGER Attribute,PTR Value,SQLINTEGER StringLength)1922 PGAPI_SetStmtAttr(HSTMT StatementHandle,
1923 SQLINTEGER Attribute, PTR Value,
1924 SQLINTEGER StringLength)
1925 {
1926 RETCODE ret = SQL_SUCCESS;
1927 CSTR func = "PGAPI_SetStmtAttr";
1928 StatementClass *stmt = (StatementClass *) StatementHandle;
1929
1930 MYLOG(0, "entering Handle=%p " FORMAT_INTEGER "," FORMAT_ULEN "(%p)\n", StatementHandle, Attribute, (SQLULEN) Value, Value);
1931 switch (Attribute)
1932 {
1933 case SQL_ATTR_ENABLE_AUTO_IPD: /* 15 */
1934 if (SQL_FALSE == Value)
1935 break;
1936 case SQL_ATTR_CURSOR_SCROLLABLE: /* -1 */
1937 case SQL_ATTR_CURSOR_SENSITIVITY: /* -2 */
1938 case SQL_ATTR_AUTO_IPD: /* 10001 */
1939 SC_set_error(stmt, DESC_OPTION_NOT_FOR_THE_DRIVER, "Unsupported statement option (Set)", func);
1940 return SQL_ERROR;
1941 /* case SQL_ATTR_ROW_BIND_TYPE: ** == SQL_BIND_TYPE(ODBC2.0) */
1942 case SQL_ATTR_IMP_ROW_DESC: /* 10012 (read-only) */
1943 case SQL_ATTR_IMP_PARAM_DESC: /* 10013 (read-only) */
1944
1945 /*
1946 * case SQL_ATTR_PREDICATE_PTR: case
1947 * SQL_ATTR_PREDICATE_OCTET_LENGTH_PTR:
1948 */
1949 SC_set_error(stmt, DESC_INVALID_OPTION_IDENTIFIER, "Unsupported statement option (Set)", func);
1950 return SQL_ERROR;
1951
1952 case SQL_ATTR_METADATA_ID: /* 10014 */
1953 stmt->options.metadata_id = CAST_UPTR(SQLUINTEGER, Value);
1954 break;
1955 case SQL_ATTR_APP_ROW_DESC: /* 10010 */
1956 if (SQL_NULL_HDESC == Value)
1957 {
1958 stmt->ard = &(stmt->ardi);
1959 }
1960 else
1961 {
1962 stmt->ard = (DescriptorClass *) Value;
1963 MYLOG(DETAIL_LOG_LEVEL, "set ard=%p\n", stmt->ard);
1964 }
1965 break;
1966 case SQL_ATTR_APP_PARAM_DESC: /* 10011 */
1967 if (SQL_NULL_HDESC == Value)
1968 {
1969 stmt->apd = &(stmt->apdi);
1970 }
1971 else
1972 {
1973 stmt->apd = (DescriptorClass *) Value;
1974 }
1975 break;
1976 case SQL_ATTR_FETCH_BOOKMARK_PTR: /* 16 */
1977 stmt->options.bookmark_ptr = Value;
1978 break;
1979 case SQL_ATTR_PARAM_BIND_OFFSET_PTR: /* 17 */
1980 SC_get_APDF(stmt)->param_offset_ptr = (SQLULEN *) Value;
1981 break;
1982 case SQL_ATTR_PARAM_BIND_TYPE: /* 18 */
1983 SC_get_APDF(stmt)->param_bind_type = CAST_UPTR(SQLUINTEGER, Value);
1984 break;
1985 case SQL_ATTR_PARAM_OPERATION_PTR: /* 19 */
1986 SC_get_APDF(stmt)->param_operation_ptr = Value;
1987 break;
1988 case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */
1989 SC_get_IPDF(stmt)->param_status_ptr = (SQLUSMALLINT *) Value;
1990 break;
1991 case SQL_ATTR_PARAMS_PROCESSED_PTR: /* 21 */
1992 SC_get_IPDF(stmt)->param_processed_ptr = (SQLULEN *) Value;
1993 break;
1994 case SQL_ATTR_PARAMSET_SIZE: /* 22 */
1995 SC_get_APDF(stmt)->paramset_size = CAST_UPTR(SQLULEN, Value);
1996 break;
1997 case SQL_ATTR_ROW_BIND_OFFSET_PTR: /* 23 */
1998 SC_get_ARDF(stmt)->row_offset_ptr = (SQLULEN *) Value;
1999 break;
2000 case SQL_ATTR_ROW_OPERATION_PTR: /* 24 */
2001 SC_get_ARDF(stmt)->row_operation_ptr = Value;
2002 break;
2003 case SQL_ATTR_ROW_STATUS_PTR: /* 25 */
2004 SC_get_IRDF(stmt)->rowStatusArray = (SQLUSMALLINT *) Value;
2005 break;
2006 case SQL_ATTR_ROWS_FETCHED_PTR: /* 26 */
2007 SC_get_IRDF(stmt)->rowsFetched = (SQLULEN *) Value;
2008 break;
2009 case SQL_ATTR_ROW_ARRAY_SIZE: /* 27 */
2010 SC_get_ARDF(stmt)->size_of_rowset = CAST_UPTR(SQLULEN, Value);
2011 break;
2012 default:
2013 return PGAPI_SetStmtOption(StatementHandle, (SQLUSMALLINT) Attribute, (SQLULEN) Value);
2014 }
2015 return ret;
2016 }
2017
2018 /* SQL_NEED_DATA callback for PGAPI_BulkOperations */
2019 typedef struct
2020 {
2021 StatementClass *stmt;
2022 SQLSMALLINT operation;
2023 char need_data_callback;
2024 char auto_commit_needed;
2025 ARDFields *opts;
2026 int idx, processed;
2027 } bop_cdata;
2028
2029 static
bulk_ope_callback(RETCODE retcode,void * para)2030 RETCODE bulk_ope_callback(RETCODE retcode, void *para)
2031 {
2032 CSTR func = "bulk_ope_callback";
2033 RETCODE ret = retcode;
2034 bop_cdata *s = (bop_cdata *) para;
2035 SQLULEN global_idx;
2036 ConnectionClass *conn;
2037 QResultClass *res;
2038 IRDFields *irdflds;
2039 PG_BM pg_bm;
2040
2041 if (s->need_data_callback)
2042 {
2043 MYLOG(0, "entering in\n");
2044 s->processed++;
2045 s->idx++;
2046 }
2047 else
2048 {
2049 s->idx = s->processed = 0;
2050 }
2051 s->need_data_callback = FALSE;
2052 res = SC_get_Curres(s->stmt);
2053 for (; SQL_ERROR != ret && s->idx < s->opts->size_of_rowset; s->idx++)
2054 {
2055 if (SQL_ADD != s->operation)
2056 {
2057 pg_bm = SC_Resolve_bookmark(s->opts, s->idx);
2058 QR_get_last_bookmark(res, s->idx, &pg_bm.keys);
2059 global_idx = pg_bm.index;
2060 }
2061 /* Note opts->row_operation_ptr is ignored */
2062 switch (s->operation)
2063 {
2064 case SQL_ADD:
2065 ret = SC_pos_add(s->stmt, (UWORD) s->idx);
2066 break;
2067 case SQL_UPDATE_BY_BOOKMARK:
2068 ret = SC_pos_update(s->stmt, (UWORD) s->idx, global_idx, &(pg_bm.keys));
2069 break;
2070 case SQL_DELETE_BY_BOOKMARK:
2071 ret = SC_pos_delete(s->stmt, (UWORD) s->idx, global_idx, &(pg_bm.keys));
2072 break;
2073 }
2074 if (SQL_NEED_DATA == ret)
2075 {
2076 bop_cdata *cbdata = (bop_cdata *) malloc(sizeof(bop_cdata));
2077 if (!cbdata)
2078 {
2079 SC_set_error(s->stmt, STMT_NO_MEMORY_ERROR, "Couldn't allocate memory for cbdata.", func);
2080 return SQL_ERROR;
2081 }
2082 memcpy(cbdata, s, sizeof(bop_cdata));
2083 cbdata->need_data_callback = TRUE;
2084 if (0 == enqueueNeedDataCallback(s->stmt, bulk_ope_callback, cbdata))
2085 ret = SQL_ERROR;
2086 return ret;
2087 }
2088 s->processed++;
2089 }
2090 conn = SC_get_conn(s->stmt);
2091 if (s->auto_commit_needed)
2092 CC_set_autocommit(conn, TRUE);
2093 irdflds = SC_get_IRDF(s->stmt);
2094 if (irdflds->rowsFetched)
2095 *(irdflds->rowsFetched) = s->processed;
2096
2097 if (res)
2098 res->recent_processed_row_count = s->stmt->diag_row_count = s->processed;
2099 return ret;
2100 }
2101
2102 RETCODE SQL_API
PGAPI_BulkOperations(HSTMT hstmt,SQLSMALLINT operationX)2103 PGAPI_BulkOperations(HSTMT hstmt, SQLSMALLINT operationX)
2104 {
2105 CSTR func = "PGAPI_BulkOperations";
2106 bop_cdata s;
2107 RETCODE ret;
2108 ConnectionClass *conn;
2109 BindInfoClass *bookmark;
2110
2111 MYLOG(0, "entering operation = %d\n", operationX);
2112 s.stmt = (StatementClass *) hstmt;
2113 s.operation = operationX;
2114 SC_clear_error(s.stmt);
2115 s.opts = SC_get_ARDF(s.stmt);
2116
2117 s.auto_commit_needed = FALSE;
2118 if (SQL_FETCH_BY_BOOKMARK != s.operation)
2119 {
2120 conn = SC_get_conn(s.stmt);
2121 if (s.auto_commit_needed = (char) CC_does_autocommit(conn), s.auto_commit_needed)
2122 CC_set_autocommit(conn, FALSE);
2123 }
2124 if (SQL_ADD != s.operation)
2125 {
2126 if (!(bookmark = s.opts->bookmark) || !(bookmark->buffer))
2127 {
2128 SC_set_error(s.stmt, DESC_INVALID_OPTION_IDENTIFIER, "bookmark isn't specified", func);
2129 return SQL_ERROR;
2130 }
2131 }
2132
2133 /* StartRollbackState(s.stmt); */
2134 if (SQL_FETCH_BY_BOOKMARK == operationX)
2135 ret = SC_fetch_by_bookmark(s.stmt);
2136 else
2137 {
2138 s.need_data_callback = FALSE;
2139 ret = bulk_ope_callback(SQL_SUCCESS, &s);
2140 }
2141 return ret;
2142 }
2143