1 /*-------
2 * Module: odbcapi30.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: SQLAllocHandle, SQLBindParam, SQLCloseCursor,
12 SQLColAttribute, SQLCopyDesc, SQLEndTran,
13 SQLFetchScroll, SQLFreeHandle, SQLGetDescField,
14 SQLGetDescRec, SQLGetDiagField, SQLGetDiagRec,
15 SQLGetEnvAttr, SQLGetConnectAttr, SQLGetStmtAttr,
16 SQLSetConnectAttr, SQLSetDescField, SQLSetDescRec,
17 SQLSetEnvAttr, SQLSetStmtAttr, SQLBulkOperations
18 *-------
19 */
20
21 #include "psqlodbc.h"
22 #include "misc.h"
23
24 #include <stdio.h>
25 #include <string.h>
26
27 #include "environ.h"
28 #include "connection.h"
29 #include "statement.h"
30 #include "pgapifunc.h"
31
32 /* SQLAllocConnect/SQLAllocEnv/SQLAllocStmt -> SQLAllocHandle */
33 RETCODE SQL_API
SQLAllocHandle(SQLSMALLINT HandleType,SQLHANDLE InputHandle,SQLHANDLE * OutputHandle)34 SQLAllocHandle(SQLSMALLINT HandleType,
35 SQLHANDLE InputHandle, SQLHANDLE * OutputHandle)
36 {
37 RETCODE ret;
38 ConnectionClass *conn;
39
40 MYLOG(0, "Entering\n");
41 switch (HandleType)
42 {
43 case SQL_HANDLE_ENV:
44 ret = PGAPI_AllocEnv(OutputHandle);
45 break;
46 case SQL_HANDLE_DBC:
47 ENTER_ENV_CS((EnvironmentClass *) InputHandle);
48 ret = PGAPI_AllocConnect(InputHandle, OutputHandle);
49 LEAVE_ENV_CS((EnvironmentClass *) InputHandle);
50 break;
51 case SQL_HANDLE_STMT:
52 conn = (ConnectionClass *) InputHandle;
53 CC_examine_global_transaction(conn);
54 ENTER_CONN_CS(conn);
55 ret = PGAPI_AllocStmt(InputHandle, OutputHandle, PODBC_EXTERNAL_STATEMENT | PODBC_INHERIT_CONNECT_OPTIONS);
56 if (*OutputHandle)
57 ((StatementClass *) (*OutputHandle))->external = 1;
58 LEAVE_CONN_CS(conn);
59 break;
60 case SQL_HANDLE_DESC:
61 conn = (ConnectionClass *) InputHandle;
62 CC_examine_global_transaction(conn);
63 ENTER_CONN_CS(conn);
64 ret = PGAPI_AllocDesc(InputHandle, OutputHandle);
65 LEAVE_CONN_CS(conn);
66 MYLOG(DETAIL_LOG_LEVEL, "OutputHandle=%p\n", *OutputHandle);
67 break;
68 default:
69 ret = SQL_ERROR;
70 break;
71 }
72 return ret;
73 }
74
75 /* SQLBindParameter/SQLSetParam -> SQLBindParam */
76 RETCODE SQL_API
SQLBindParam(HSTMT StatementHandle,SQLUSMALLINT ParameterNumber,SQLSMALLINT ValueType,SQLSMALLINT ParameterType,SQLULEN LengthPrecision,SQLSMALLINT ParameterScale,PTR ParameterValue,SQLLEN * StrLen_or_Ind)77 SQLBindParam(HSTMT StatementHandle,
78 SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType,
79 SQLSMALLINT ParameterType, SQLULEN LengthPrecision,
80 SQLSMALLINT ParameterScale, PTR ParameterValue,
81 SQLLEN *StrLen_or_Ind)
82 {
83 RETCODE ret;
84 StatementClass *stmt = (StatementClass *) StatementHandle;
85 int BufferLength = 512; /* Is it OK ? */
86
87 MYLOG(0, "Entering\n");
88 ENTER_STMT_CS(stmt);
89 SC_clear_error(stmt);
90 StartRollbackState(stmt);
91 ret = PGAPI_BindParameter(StatementHandle, ParameterNumber, SQL_PARAM_INPUT, ValueType, ParameterType, LengthPrecision, ParameterScale, ParameterValue, BufferLength, StrLen_or_Ind);
92 ret = DiscardStatementSvp(stmt,ret, FALSE);
93 LEAVE_STMT_CS(stmt);
94 return ret;
95 }
96
97 /* New function */
98 RETCODE SQL_API
SQLCloseCursor(HSTMT StatementHandle)99 SQLCloseCursor(HSTMT StatementHandle)
100 {
101 StatementClass *stmt = (StatementClass *) StatementHandle;
102 RETCODE ret;
103
104 MYLOG(0, "Entering\n");
105 if (SC_connection_lost_check(stmt, __FUNCTION__))
106 return SQL_ERROR;
107
108 ENTER_STMT_CS(stmt);
109 SC_clear_error(stmt);
110 StartRollbackState(stmt);
111 ret = PGAPI_FreeStmt(StatementHandle, SQL_CLOSE);
112 ret = DiscardStatementSvp(stmt,ret, FALSE);
113 LEAVE_STMT_CS(stmt);
114 return ret;
115 }
116
117 #ifndef UNICODE_SUPPORTXX
118 /* SQLColAttributes -> SQLColAttribute */
119 SQLRETURN SQL_API
SQLColAttribute(SQLHSTMT StatementHandle,SQLUSMALLINT ColumnNumber,SQLUSMALLINT FieldIdentifier,SQLPOINTER CharacterAttribute,SQLSMALLINT BufferLength,SQLSMALLINT * StringLength,SQLLEN * NumericAttribute)120 SQLColAttribute(SQLHSTMT StatementHandle,
121 SQLUSMALLINT ColumnNumber,
122 SQLUSMALLINT FieldIdentifier,
123 SQLPOINTER CharacterAttribute,
124 SQLSMALLINT BufferLength,
125 SQLSMALLINT *StringLength,
126 #if defined(_WIN64) || defined(SQLCOLATTRIBUTE_SQLLEN)
127 SQLLEN *NumericAttribute
128 #else
129 SQLPOINTER NumericAttribute
130 #endif
131 )
132 {
133 RETCODE ret;
134 StatementClass *stmt = (StatementClass *) StatementHandle;
135
136 MYLOG(0, "Entering\n");
137 if (SC_connection_lost_check(stmt, __FUNCTION__))
138 return SQL_ERROR;
139
140 ENTER_STMT_CS(stmt);
141 SC_clear_error(stmt);
142 StartRollbackState(stmt);
143 ret = PGAPI_ColAttributes(StatementHandle, ColumnNumber,
144 FieldIdentifier, CharacterAttribute, BufferLength,
145 StringLength, NumericAttribute);
146 ret = DiscardStatementSvp(stmt,ret, FALSE);
147 LEAVE_STMT_CS(stmt);
148 return ret;
149 }
150 #endif /* UNICODE_SUPPORTXX */
151
152 /* new function */
153 RETCODE SQL_API
SQLCopyDesc(SQLHDESC SourceDescHandle,SQLHDESC TargetDescHandle)154 SQLCopyDesc(SQLHDESC SourceDescHandle,
155 SQLHDESC TargetDescHandle)
156 {
157 RETCODE ret;
158
159 MYLOG(0, "Entering\n");
160 ret = PGAPI_CopyDesc(SourceDescHandle, TargetDescHandle);
161 return ret;
162 }
163
164 /* SQLTransact -> SQLEndTran */
165 RETCODE SQL_API
SQLEndTran(SQLSMALLINT HandleType,SQLHANDLE Handle,SQLSMALLINT CompletionType)166 SQLEndTran(SQLSMALLINT HandleType, SQLHANDLE Handle,
167 SQLSMALLINT CompletionType)
168 {
169 RETCODE ret;
170
171 MYLOG(0, "Entering\n");
172 switch (HandleType)
173 {
174 case SQL_HANDLE_ENV:
175 ENTER_ENV_CS((EnvironmentClass *) Handle);
176 ret = PGAPI_Transact(Handle, SQL_NULL_HDBC, CompletionType);
177 LEAVE_ENV_CS((EnvironmentClass *) Handle);
178 break;
179 case SQL_HANDLE_DBC:
180 CC_examine_global_transaction((ConnectionClass *) Handle);
181 ENTER_CONN_CS((ConnectionClass *) Handle);
182 CC_clear_error((ConnectionClass *) Handle);
183 ret = PGAPI_Transact(SQL_NULL_HENV, Handle, CompletionType);
184 LEAVE_CONN_CS((ConnectionClass *) Handle);
185 break;
186 default:
187 ret = SQL_ERROR;
188 break;
189 }
190 return ret;
191 }
192
193 /* SQLExtendedFetch -> SQLFetchScroll */
194 RETCODE SQL_API
SQLFetchScroll(HSTMT StatementHandle,SQLSMALLINT FetchOrientation,SQLLEN FetchOffset)195 SQLFetchScroll(HSTMT StatementHandle,
196 SQLSMALLINT FetchOrientation, SQLLEN FetchOffset)
197 {
198 CSTR func = "SQLFetchScroll";
199 StatementClass *stmt = (StatementClass *) StatementHandle;
200 RETCODE ret = SQL_SUCCESS;
201 IRDFields *irdopts = SC_get_IRDF(stmt);
202 SQLUSMALLINT *rowStatusArray = irdopts->rowStatusArray;
203 SQLULEN *pcRow = irdopts->rowsFetched;
204 SQLLEN bkmarkoff = 0;
205
206 MYLOG(0, "Entering %d," FORMAT_LEN "\n", FetchOrientation, FetchOffset);
207 if (SC_connection_lost_check(stmt, __FUNCTION__))
208 return SQL_ERROR;
209
210 ENTER_STMT_CS(stmt);
211 SC_clear_error(stmt);
212 StartRollbackState(stmt);
213 if (FetchOrientation == SQL_FETCH_BOOKMARK)
214 {
215 if (stmt->options.bookmark_ptr)
216 {
217 bkmarkoff = FetchOffset;
218 FetchOffset = *((Int4 *) stmt->options.bookmark_ptr);
219 MYLOG(0, "bookmark=" FORMAT_LEN " FetchOffset = " FORMAT_LEN "\n", FetchOffset, bkmarkoff);
220 }
221 else
222 {
223 SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Bookmark isn't specifed yet", func);
224 ret = SQL_ERROR;
225 }
226 }
227 if (SQL_SUCCESS == ret)
228 {
229 ARDFields *opts = SC_get_ARDF(stmt);
230
231 ret = PGAPI_ExtendedFetch(StatementHandle, FetchOrientation, FetchOffset,
232 pcRow, rowStatusArray, bkmarkoff, opts->size_of_rowset);
233 stmt->transition_status = STMT_TRANSITION_FETCH_SCROLL;
234 }
235 ret = DiscardStatementSvp(stmt,ret, FALSE);
236 LEAVE_STMT_CS(stmt);
237 if (ret != SQL_SUCCESS)
238 MYLOG(0, "leaving return = %d\n", ret);
239 return ret;
240 }
241
242 /* SQLFree(Connect/Env/Stmt) -> SQLFreeHandle */
243 RETCODE SQL_API
SQLFreeHandle(SQLSMALLINT HandleType,SQLHANDLE Handle)244 SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle)
245 {
246 RETCODE ret;
247 StatementClass *stmt;
248 ConnectionClass *conn = NULL;
249
250 MYLOG(0, "Entering\n");
251
252 switch (HandleType)
253 {
254 case SQL_HANDLE_ENV:
255 ret = PGAPI_FreeEnv(Handle);
256 break;
257 case SQL_HANDLE_DBC:
258 ret = PGAPI_FreeConnect(Handle);
259 break;
260 case SQL_HANDLE_STMT:
261 stmt = (StatementClass *) Handle;
262
263 if (stmt)
264 {
265 conn = stmt->hdbc;
266 if (conn)
267 ENTER_CONN_CS(conn);
268 }
269
270 ret = PGAPI_FreeStmt(Handle, SQL_DROP);
271
272 if (conn)
273 LEAVE_CONN_CS(conn);
274
275 break;
276 case SQL_HANDLE_DESC:
277 ret = PGAPI_FreeDesc(Handle);
278 break;
279 default:
280 ret = SQL_ERROR;
281 break;
282 }
283 return ret;
284 }
285
286 #ifndef UNICODE_SUPPORTXX
287 /* new function */
288 RETCODE SQL_API
SQLGetDescField(SQLHDESC DescriptorHandle,SQLSMALLINT RecNumber,SQLSMALLINT FieldIdentifier,PTR Value,SQLINTEGER BufferLength,SQLINTEGER * StringLength)289 SQLGetDescField(SQLHDESC DescriptorHandle,
290 SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
291 PTR Value, SQLINTEGER BufferLength,
292 SQLINTEGER *StringLength)
293 {
294 RETCODE ret;
295
296 MYLOG(0, "Entering\n");
297 ret = PGAPI_GetDescField(DescriptorHandle, RecNumber, FieldIdentifier,
298 Value, BufferLength, StringLength);
299 return ret;
300 }
301
302 /* new function */
303 RETCODE SQL_API
SQLGetDescRec(SQLHDESC DescriptorHandle,SQLSMALLINT RecNumber,SQLCHAR * Name,SQLSMALLINT BufferLength,SQLSMALLINT * StringLength,SQLSMALLINT * Type,SQLSMALLINT * SubType,SQLLEN * Length,SQLSMALLINT * Precision,SQLSMALLINT * Scale,SQLSMALLINT * Nullable)304 SQLGetDescRec(SQLHDESC DescriptorHandle,
305 SQLSMALLINT RecNumber, SQLCHAR *Name,
306 SQLSMALLINT BufferLength, SQLSMALLINT *StringLength,
307 SQLSMALLINT *Type, SQLSMALLINT *SubType,
308 SQLLEN *Length, SQLSMALLINT *Precision,
309 SQLSMALLINT *Scale, SQLSMALLINT *Nullable)
310 {
311 MYLOG(0, "Entering\n");
312 MYLOG(0, "Error not implemented\n");
313 return SQL_ERROR;
314 }
315
316 /* new function */
317 RETCODE SQL_API
SQLGetDiagField(SQLSMALLINT HandleType,SQLHANDLE Handle,SQLSMALLINT RecNumber,SQLSMALLINT DiagIdentifier,PTR DiagInfo,SQLSMALLINT BufferLength,SQLSMALLINT * StringLength)318 SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle,
319 SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier,
320 PTR DiagInfo, SQLSMALLINT BufferLength,
321 SQLSMALLINT *StringLength)
322 {
323 RETCODE ret;
324
325 MYLOG(0, "Entering Handle=(%u,%p) Rec=%d Id=%d info=(%p,%d)\n", HandleType, Handle, RecNumber, DiagIdentifier, DiagInfo, BufferLength);
326 ret = PGAPI_GetDiagField(HandleType, Handle, RecNumber, DiagIdentifier,
327 DiagInfo, BufferLength, StringLength);
328 return ret;
329 }
330
331 /* SQLError -> SQLDiagRec */
332 RETCODE SQL_API
SQLGetDiagRec(SQLSMALLINT HandleType,SQLHANDLE Handle,SQLSMALLINT RecNumber,SQLCHAR * Sqlstate,SQLINTEGER * NativeError,SQLCHAR * MessageText,SQLSMALLINT BufferLength,SQLSMALLINT * TextLength)333 SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle,
334 SQLSMALLINT RecNumber, SQLCHAR *Sqlstate,
335 SQLINTEGER *NativeError, SQLCHAR *MessageText,
336 SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
337 {
338 RETCODE ret;
339
340 MYLOG(0, "Entering\n");
341 ret = PGAPI_GetDiagRec(HandleType, Handle, RecNumber, Sqlstate,
342 NativeError, MessageText, BufferLength, TextLength);
343 return ret;
344 }
345 #endif /* UNICODE_SUPPORTXX */
346
347 /* new function */
348 RETCODE SQL_API
SQLGetEnvAttr(HENV EnvironmentHandle,SQLINTEGER Attribute,PTR Value,SQLINTEGER BufferLength,SQLINTEGER * StringLength)349 SQLGetEnvAttr(HENV EnvironmentHandle,
350 SQLINTEGER Attribute, PTR Value,
351 SQLINTEGER BufferLength, SQLINTEGER *StringLength)
352 {
353 RETCODE ret;
354 EnvironmentClass *env = (EnvironmentClass *) EnvironmentHandle;
355
356 MYLOG(0, "Entering " FORMAT_INTEGER "\n", Attribute);
357 ENTER_ENV_CS(env);
358 ret = SQL_SUCCESS;
359 switch (Attribute)
360 {
361 case SQL_ATTR_CONNECTION_POOLING:
362 *((unsigned int *) Value) = EN_is_pooling(env) ? SQL_CP_ONE_PER_DRIVER : SQL_CP_OFF;
363 break;
364 case SQL_ATTR_CP_MATCH:
365 *((unsigned int *) Value) = SQL_CP_RELAXED_MATCH;
366 break;
367 case SQL_ATTR_ODBC_VERSION:
368 *((unsigned int *) Value) = EN_is_odbc2(env) ? SQL_OV_ODBC2 : SQL_OV_ODBC3;
369 break;
370 case SQL_ATTR_OUTPUT_NTS:
371 *((unsigned int *) Value) = SQL_TRUE;
372 break;
373 default:
374 env->errornumber = CONN_INVALID_ARGUMENT_NO;
375 ret = SQL_ERROR;
376 }
377 LEAVE_ENV_CS(env);
378 return ret;
379 }
380
381 #ifndef UNICODE_SUPPORTXX
382 /* SQLGetConnectOption -> SQLGetconnectAttr */
383 RETCODE SQL_API
SQLGetConnectAttr(HDBC ConnectionHandle,SQLINTEGER Attribute,PTR Value,SQLINTEGER BufferLength,SQLINTEGER * StringLength)384 SQLGetConnectAttr(HDBC ConnectionHandle,
385 SQLINTEGER Attribute, PTR Value,
386 SQLINTEGER BufferLength, SQLINTEGER *StringLength)
387 {
388 RETCODE ret;
389
390 MYLOG(0, "Entering " FORMAT_UINTEGER "\n", Attribute);
391 CC_examine_global_transaction((ConnectionClass*) ConnectionHandle);
392 ENTER_CONN_CS((ConnectionClass *) ConnectionHandle);
393 CC_clear_error((ConnectionClass *) ConnectionHandle);
394 ret = PGAPI_GetConnectAttr(ConnectionHandle, Attribute,Value,
395 BufferLength, StringLength);
396 LEAVE_CONN_CS((ConnectionClass *) ConnectionHandle);
397 return ret;
398 }
399
400 /* SQLGetStmtOption -> SQLGetStmtAttr */
401 RETCODE SQL_API
SQLGetStmtAttr(HSTMT StatementHandle,SQLINTEGER Attribute,PTR Value,SQLINTEGER BufferLength,SQLINTEGER * StringLength)402 SQLGetStmtAttr(HSTMT StatementHandle,
403 SQLINTEGER Attribute, PTR Value,
404 SQLINTEGER BufferLength, SQLINTEGER *StringLength)
405 {
406 RETCODE ret;
407 StatementClass *stmt = (StatementClass *) StatementHandle;
408
409 MYLOG(0, "Entering Handle=%p " FORMAT_INTEGER "\n", StatementHandle, Attribute);
410 ENTER_STMT_CS(stmt);
411 SC_clear_error(stmt);
412 StartRollbackState(stmt);
413 ret = PGAPI_GetStmtAttr(StatementHandle, Attribute, Value,
414 BufferLength, StringLength);
415 ret = DiscardStatementSvp(stmt,ret, FALSE);
416 LEAVE_STMT_CS(stmt);
417 return ret;
418 }
419
420 /* SQLSetConnectOption -> SQLSetConnectAttr */
421 RETCODE SQL_API
SQLSetConnectAttr(HDBC ConnectionHandle,SQLINTEGER Attribute,PTR Value,SQLINTEGER StringLength)422 SQLSetConnectAttr(HDBC ConnectionHandle,
423 SQLINTEGER Attribute, PTR Value,
424 SQLINTEGER StringLength)
425 {
426 RETCODE ret;
427 ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
428
429 MYLOG(0, "Entering " FORMAT_INTEGER "\n", Attribute);
430 CC_examine_global_transaction(conn);
431 ENTER_CONN_CS(conn);
432 CC_clear_error(conn);
433 ret = PGAPI_SetConnectAttr(ConnectionHandle, Attribute, Value,
434 StringLength);
435 LEAVE_CONN_CS(conn);
436 return ret;
437 }
438
439 /* new function */
440 RETCODE SQL_API
SQLSetDescField(SQLHDESC DescriptorHandle,SQLSMALLINT RecNumber,SQLSMALLINT FieldIdentifier,PTR Value,SQLINTEGER BufferLength)441 SQLSetDescField(SQLHDESC DescriptorHandle,
442 SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
443 PTR Value, SQLINTEGER BufferLength)
444 {
445 RETCODE ret;
446
447 MYLOG(0, "Entering h=%p rec=%d field=%d val=%p\n", DescriptorHandle, RecNumber, FieldIdentifier, Value);
448 ret = PGAPI_SetDescField(DescriptorHandle, RecNumber, FieldIdentifier,
449 Value, BufferLength);
450 return ret;
451 }
452
453 /* new fucntion */
454 RETCODE SQL_API
SQLSetDescRec(SQLHDESC DescriptorHandle,SQLSMALLINT RecNumber,SQLSMALLINT Type,SQLSMALLINT SubType,SQLLEN Length,SQLSMALLINT Precision,SQLSMALLINT Scale,PTR Data,SQLLEN * StringLength,SQLLEN * Indicator)455 SQLSetDescRec(SQLHDESC DescriptorHandle,
456 SQLSMALLINT RecNumber, SQLSMALLINT Type,
457 SQLSMALLINT SubType, SQLLEN Length,
458 SQLSMALLINT Precision, SQLSMALLINT Scale,
459 PTR Data, SQLLEN *StringLength,
460 SQLLEN *Indicator)
461 {
462 MYLOG(0, "Entering\n");
463 MYLOG(0, "Error not implemented\n");
464 return SQL_ERROR;
465 }
466 #endif /* UNICODE_SUPPORTXX */
467
468 /* new function */
469 RETCODE SQL_API
SQLSetEnvAttr(HENV EnvironmentHandle,SQLINTEGER Attribute,PTR Value,SQLINTEGER StringLength)470 SQLSetEnvAttr(HENV EnvironmentHandle,
471 SQLINTEGER Attribute, PTR Value,
472 SQLINTEGER StringLength)
473 {
474 RETCODE ret;
475 EnvironmentClass *env = (EnvironmentClass *) EnvironmentHandle;
476
477 MYLOG(0, "Entering att=" FORMAT_INTEGER "," FORMAT_ULEN "\n", Attribute, (SQLULEN) Value);
478 ENTER_ENV_CS(env);
479 switch (Attribute)
480 {
481 case SQL_ATTR_CONNECTION_POOLING:
482 switch ((ULONG_PTR) Value)
483 {
484 case SQL_CP_OFF:
485 EN_unset_pooling(env);
486 ret = SQL_SUCCESS;
487 break;
488 #if defined(WIN_MULTITHREAD_SUPPORT) || defined(POSIX_MULTITHREAD_SUPPORT)
489 case SQL_CP_ONE_PER_DRIVER:
490 EN_set_pooling(env);
491 ret = SQL_SUCCESS;
492 break;
493 #endif /* WIN_MULTITHREAD_SUPPORT */
494 default:
495 ret = SQL_SUCCESS_WITH_INFO;
496 }
497 break;
498 case SQL_ATTR_CP_MATCH:
499 /* *((unsigned int *) Value) = SQL_CP_RELAXED_MATCH; */
500 ret = SQL_SUCCESS;
501 break;
502 case SQL_ATTR_ODBC_VERSION:
503 if (SQL_OV_ODBC2 == CAST_UPTR(SQLUINTEGER, Value))
504 EN_set_odbc2(env);
505 else
506 EN_set_odbc3(env);
507 ret = SQL_SUCCESS;
508 break;
509 case SQL_ATTR_OUTPUT_NTS:
510 if (SQL_TRUE == CAST_UPTR(SQLUINTEGER, Value))
511 ret = SQL_SUCCESS;
512 else
513 ret = SQL_SUCCESS_WITH_INFO;
514 break;
515 default:
516 env->errornumber = CONN_INVALID_ARGUMENT_NO;
517 ret = SQL_ERROR;
518 }
519 if (SQL_SUCCESS_WITH_INFO == ret)
520 {
521 env->errornumber = CONN_OPTION_VALUE_CHANGED;
522 env->errormsg = "SetEnv changed to ";
523 }
524 LEAVE_ENV_CS(env);
525 return ret;
526 }
527
528 #ifndef UNICODE_SUPPORTXX
529 /* SQLSet(Param/Scroll/Stmt)Option -> SQLSetStmtAttr */
530 RETCODE SQL_API
SQLSetStmtAttr(HSTMT StatementHandle,SQLINTEGER Attribute,PTR Value,SQLINTEGER StringLength)531 SQLSetStmtAttr(HSTMT StatementHandle,
532 SQLINTEGER Attribute, PTR Value,
533 SQLINTEGER StringLength)
534 {
535 StatementClass *stmt = (StatementClass *) StatementHandle;
536 RETCODE ret;
537
538 MYLOG(0, "Entering Handle=%p " FORMAT_INTEGER "," FORMAT_ULEN "\n", StatementHandle, Attribute, (SQLULEN) Value);
539 ENTER_STMT_CS(stmt);
540 SC_clear_error(stmt);
541 StartRollbackState(stmt);
542 ret = PGAPI_SetStmtAttr(StatementHandle, Attribute, Value, StringLength);
543 ret = DiscardStatementSvp(stmt,ret, FALSE);
544 LEAVE_STMT_CS(stmt);
545 return ret;
546 }
547 #endif /* UNICODE_SUPPORTXX */
548
549 #define SQL_FUNC_ESET(pfExists, uwAPI) \
550 (*(((UWORD*) (pfExists)) + ((uwAPI) >> 4)) \
551 |= (1 << ((uwAPI) & 0x000F)) \
552 )
553 RETCODE SQL_API
PGAPI_GetFunctions30(HDBC hdbc,SQLUSMALLINT fFunction,SQLUSMALLINT FAR * pfExists)554 PGAPI_GetFunctions30(HDBC hdbc, SQLUSMALLINT fFunction, SQLUSMALLINT FAR * pfExists)
555 {
556 ConnectionClass *conn = (ConnectionClass *) hdbc;
557 ConnInfo *ci = &(conn->connInfo);
558
559 MYLOG(DETAIL_LOG_LEVEL, "lie=%d\n", ci->drivers.lie);
560 CC_examine_global_transaction(conn);
561 CC_clear_error(conn);
562 if (fFunction != SQL_API_ODBC3_ALL_FUNCTIONS)
563 return SQL_ERROR;
564 memset(pfExists, 0, sizeof(UWORD) * SQL_API_ODBC3_ALL_FUNCTIONS_SIZE);
565
566 /* SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCCONNECT); 1 deprecated */
567 /* SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCENV); 2 deprecated */
568 /* SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCSTMT); 3 deprecated */
569
570 /*
571 * for (i = SQL_API_SQLBINDCOL; i <= 23; i++) SQL_FUNC_ESET(pfExists,
572 * i);
573 */
574 SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDCOL); /* 4 */
575 SQL_FUNC_ESET(pfExists, SQL_API_SQLCANCEL); /* 5 */
576 SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLATTRIBUTE); /* 6 */
577 SQL_FUNC_ESET(pfExists, SQL_API_SQLCONNECT); /* 7 */
578 SQL_FUNC_ESET(pfExists, SQL_API_SQLDESCRIBECOL); /* 8 */
579 SQL_FUNC_ESET(pfExists, SQL_API_SQLDISCONNECT); /* 9 */
580 /* SQL_FUNC_ESET(pfExists, SQL_API_SQLERROR); 10 deprecated */
581 SQL_FUNC_ESET(pfExists, SQL_API_SQLEXECDIRECT); /* 11 */
582 SQL_FUNC_ESET(pfExists, SQL_API_SQLEXECUTE); /* 12 */
583 SQL_FUNC_ESET(pfExists, SQL_API_SQLFETCH); /* 13 */
584 /* SQL_FUNC_ESET(pfExists, SQL_API_SQLFREECONNECT); 14 deprecated */
585 /* SQL_FUNC_ESET(pfExists, SQL_API_SQLFREEENV); 15 deprecated */
586 SQL_FUNC_ESET(pfExists, SQL_API_SQLFREESTMT); /* 16 */
587 SQL_FUNC_ESET(pfExists, SQL_API_SQLGETCURSORNAME); /* 17 */
588 SQL_FUNC_ESET(pfExists, SQL_API_SQLNUMRESULTCOLS); /* 18 */
589 SQL_FUNC_ESET(pfExists, SQL_API_SQLPREPARE); /* 19 */
590 SQL_FUNC_ESET(pfExists, SQL_API_SQLROWCOUNT); /* 20 */
591 SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCURSORNAME); /* 21 */
592 /* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETPARAM); 22 deprecated */
593 /* SQL_FUNC_ESET(pfExists, SQL_API_SQLTRANSACT); 23 deprecated */
594
595 /*
596 * for (i = 40; i < SQL_API_SQLEXTENDEDFETCH; i++)
597 * SQL_FUNC_ESET(pfExists, i);
598 */
599 SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLUMNS); /* 40 */
600 SQL_FUNC_ESET(pfExists, SQL_API_SQLDRIVERCONNECT); /* 41 */
601 /* SQL_FUNC_ESET(pfExists, SQL_API_SQLGETCONNECTOPTION); 42 deprecated */
602 SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDATA); /* 43 */
603 SQL_FUNC_ESET(pfExists, SQL_API_SQLGETFUNCTIONS); /* 44 */
604 SQL_FUNC_ESET(pfExists, SQL_API_SQLGETINFO); /* 45 */
605 /* SQL_FUNC_ESET(pfExists, SQL_API_SQLGETSTMTOPTION); 46 deprecated */
606 SQL_FUNC_ESET(pfExists, SQL_API_SQLGETTYPEINFO); /* 47 */
607 SQL_FUNC_ESET(pfExists, SQL_API_SQLPARAMDATA); /* 48 */
608 SQL_FUNC_ESET(pfExists, SQL_API_SQLPUTDATA); /* 49 */
609
610 /* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTIONOPTION); 50 deprecated */
611 /* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSTMTOPTION); 51 deprecated */
612 SQL_FUNC_ESET(pfExists, SQL_API_SQLSPECIALCOLUMNS); /* 52 */
613 SQL_FUNC_ESET(pfExists, SQL_API_SQLSTATISTICS); /* 53 */
614 SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLES); /* 54 */
615 if (ci->drivers.lie)
616 SQL_FUNC_ESET(pfExists, SQL_API_SQLBROWSECONNECT); /* 55 */
617 if (ci->drivers.lie)
618 SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLUMNPRIVILEGES); /* 56 */
619 SQL_FUNC_ESET(pfExists, SQL_API_SQLDATASOURCES); /* 57 */
620 if (SUPPORT_DESCRIBE_PARAM(ci) || ci->drivers.lie)
621 SQL_FUNC_ESET(pfExists, SQL_API_SQLDESCRIBEPARAM); /* 58 */
622 SQL_FUNC_ESET(pfExists, SQL_API_SQLEXTENDEDFETCH); /* 59 deprecated ? */
623
624 /*
625 * for (++i; i < SQL_API_SQLBINDPARAMETER; i++)
626 * SQL_FUNC_ESET(pfExists, i);
627 */
628 SQL_FUNC_ESET(pfExists, SQL_API_SQLFOREIGNKEYS); /* 60 */
629 SQL_FUNC_ESET(pfExists, SQL_API_SQLMORERESULTS); /* 61 */
630 SQL_FUNC_ESET(pfExists, SQL_API_SQLNATIVESQL); /* 62 */
631 SQL_FUNC_ESET(pfExists, SQL_API_SQLNUMPARAMS); /* 63 */
632 /* SQL_FUNC_ESET(pfExists, SQL_API_SQLPARAMOPTIONS); 64 deprecated */
633 SQL_FUNC_ESET(pfExists, SQL_API_SQLPRIMARYKEYS); /* 65 */
634 SQL_FUNC_ESET(pfExists, SQL_API_SQLPROCEDURECOLUMNS); /* 66 */
635 SQL_FUNC_ESET(pfExists, SQL_API_SQLPROCEDURES); /* 67 */
636 SQL_FUNC_ESET(pfExists, SQL_API_SQLSETPOS); /* 68 */
637 /* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSCROLLOPTIONS); 69 deprecated */
638 SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLEPRIVILEGES); /* 70 */
639 /* SQL_FUNC_ESET(pfExists, SQL_API_SQLDRIVERS); */ /* 71 */
640 SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDPARAMETER); /* 72 */
641
642 SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCHANDLE); /* 1001 */
643 SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDPARAM); /* 1002 */
644 SQL_FUNC_ESET(pfExists, SQL_API_SQLCLOSECURSOR); /* 1003 */
645 SQL_FUNC_ESET(pfExists, SQL_API_SQLCOPYDESC); /* 1004 */
646 SQL_FUNC_ESET(pfExists, SQL_API_SQLENDTRAN); /* 1005 */
647 SQL_FUNC_ESET(pfExists, SQL_API_SQLFREEHANDLE); /* 1006 */
648 SQL_FUNC_ESET(pfExists, SQL_API_SQLGETCONNECTATTR); /* 1007 */
649 SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDESCFIELD); /* 1008 */
650 if (ci->drivers.lie)
651 {
652 SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDESCREC); /* 1009 not implemented yet */
653 }
654 SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDIAGFIELD); /* 1010 minimal implementation */
655 SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDIAGREC); /* 1011 */
656 SQL_FUNC_ESET(pfExists, SQL_API_SQLGETENVATTR); /* 1012 */
657 SQL_FUNC_ESET(pfExists, SQL_API_SQLGETSTMTATTR); /* 1014 */
658 SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTATTR); /* 1016 */
659 SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCFIELD); /* 1017 */
660 if (ci->drivers.lie)
661 {
662 SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCREC); /* 1018 not implemented yet */
663 }
664 SQL_FUNC_ESET(pfExists, SQL_API_SQLSETENVATTR); /* 1019 */
665 SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSTMTATTR); /* 1020 */
666 SQL_FUNC_ESET(pfExists, SQL_API_SQLFETCHSCROLL); /* 1021 */
667 if (0 != (ALLOW_BULK_OPERATIONS & ci->updatable_cursors))
668 SQL_FUNC_ESET(pfExists, SQL_API_SQLBULKOPERATIONS); /* 24 */
669
670 return SQL_SUCCESS;
671 }
672
673 RETCODE SQL_API
SQLBulkOperations(HSTMT hstmt,SQLSMALLINT operation)674 SQLBulkOperations(HSTMT hstmt, SQLSMALLINT operation)
675 {
676 RETCODE ret;
677 StatementClass *stmt = (StatementClass *) hstmt;
678
679 if (SC_connection_lost_check(stmt, __FUNCTION__))
680 return SQL_ERROR;
681
682 ENTER_STMT_CS(stmt);
683 MYLOG(0, "Entering Handle=%p %d\n", hstmt, operation);
684 SC_clear_error(stmt);
685 StartRollbackState(stmt);
686 ret = PGAPI_BulkOperations(hstmt, operation);
687 ret = DiscardStatementSvp(stmt,ret, FALSE);
688 LEAVE_STMT_CS(stmt);
689 return ret;
690 }
691