]> granicus.if.org Git - postgresql/blob - src/interfaces/odbc/odbcapi30.c
Provide some initial support for building the ODBC driver for
[postgresql] / src / interfaces / odbc / odbcapi30.c
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 #undef ODBCVER
23 #define ODBCVER 0x0300
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,
34            SQLHANDLE InputHandle, SQLHANDLE *OutputHandle)
35 {
36         mylog("[[SQLAllocHandle]]");
37         switch (HandleType)
38         {
39                 case SQL_HANDLE_ENV:
40                         return PGAPI_AllocEnv(OutputHandle);
41                 case SQL_HANDLE_DBC:
42                         return PGAPI_AllocConnect(InputHandle, OutputHandle);
43                 case SQL_HANDLE_STMT:
44                         return PGAPI_AllocStmt(InputHandle, OutputHandle);
45                 default: break;
46         }
47         return SQL_ERROR;
48 }
49 /*      SQLBindParameter/SQLSetParam -> SQLBindParam */
50 RETCODE  SQL_API SQLBindParam(HSTMT StatementHandle,
51            SQLUSMALLINT ParameterNumber, SQLSMALLINT ValueType,
52            SQLSMALLINT ParameterType, SQLUINTEGER LengthPrecision,
53            SQLSMALLINT ParameterScale, PTR ParameterValue,
54            SQLINTEGER *StrLen_or_Ind)
55 {
56         int     BufferLength = 512; /* Is it OK ? */
57         mylog("[[SQLBindParam]]");
58         return PGAPI_BindParameter(StatementHandle, ParameterNumber, SQL_PARAM_INPUT, ValueType, ParameterType, LengthPrecision, ParameterScale, ParameterValue, BufferLength, StrLen_or_Ind);
59 }
60 /*      New function */
61 RETCODE  SQL_API SQLCloseCursor(HSTMT StatementHandle)
62 {
63         mylog("[[SQLCloseCursor]]");
64         return PGAPI_FreeStmt(StatementHandle, SQL_CLOSE);
65 }
66
67 /*      SQLColAttributes -> SQLColAttribute */
68 RETCODE  SQL_API SQLColAttribute (HSTMT StatementHandle,
69            SQLUSMALLINT ColumnNumber, SQLUSMALLINT FieldIdentifier,
70            PTR CharacterAttribute, SQLSMALLINT BufferLength,
71            SQLSMALLINT *StringLength, PTR NumericAttribute)
72 {
73         mylog("[[SQLColAttribute]]");
74         return PGAPI_ColAttributes(StatementHandle, ColumnNumber,
75                 FieldIdentifier, CharacterAttribute, BufferLength,
76                 StringLength, NumericAttribute);
77 }
78 /*      new function */
79 RETCODE  SQL_API SQLCopyDesc(SQLHDESC SourceDescHandle,
80            SQLHDESC TargetDescHandle)
81 {
82         mylog("[[SQLCopyDesc]]\n");
83         return SQL_ERROR;
84 }
85 /*      SQLTransact -> SQLEndTran */    
86 RETCODE  SQL_API SQLEndTran(SQLSMALLINT HandleType, SQLHANDLE Handle,
87            SQLSMALLINT CompletionType)
88 {
89         mylog("[[SQLEndTran]]");
90         switch (HandleType)
91         {
92                 case SQL_HANDLE_ENV:
93                         return PGAPI_Transact(Handle, SQL_NULL_HDBC, CompletionType);
94                  case SQL_HANDLE_DBC:
95                         return PGAPI_Transact(SQL_NULL_HENV, Handle, CompletionType);
96                 default:break;
97         }
98         return SQL_ERROR; /* SQLSTATE HY092 ("Invalid attribute/option identifier")*/
99
100 }
101 /*      SQLExtendedFetch -> SQLFetchScroll */
102 RETCODE  SQL_API SQLFetchScroll(HSTMT StatementHandle,
103            SQLSMALLINT FetchOrientation, SQLINTEGER FetchOffset)
104 {
105         static char *func = "SQLFetchScroll";
106         StatementClass  *stmt = (StatementClass *) StatementHandle;
107         RETCODE ret;
108         SQLUSMALLINT    *rowStatusArray = stmt->options.rowStatusArray;
109         SQLINTEGER      *pcRow = stmt->options.rowsFetched;
110         mylog("[[%s]] %d,%d\n", func, FetchOrientation, FetchOffset);
111         if (FetchOrientation == SQL_FETCH_BOOKMARK)
112         {
113                 if (stmt->options.bookmark_ptr)
114                         FetchOffset += *((Int4 *) stmt->options.bookmark_ptr);
115                 else
116                 {
117                         stmt->errornumber = STMT_SEQUENCE_ERROR;
118                         stmt->errormsg = "Bookmark isn't specifed yet";
119                         SC_log_error(func, "", stmt);
120                         return SQL_ERROR;
121                 }
122         }
123         ret = PGAPI_ExtendedFetch(StatementHandle, FetchOrientation, FetchOffset,
124                         pcRow, rowStatusArray);
125         if (ret != SQL_SUCCESS)
126                 mylog("%s return = %d\n", func, ret);
127         return ret;
128 }
129 /*      SQLFree(Connect/Env/Stmt) -> SQLFreeHandle */
130 RETCODE  SQL_API SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle)
131 {
132         mylog("[[SQLFreeHandle]]");
133         switch (HandleType)
134         {
135                 case SQL_HANDLE_ENV:
136                         return PGAPI_FreeEnv(Handle);
137                 case SQL_HANDLE_DBC:
138                         return PGAPI_FreeConnect(Handle);
139                 case SQL_HANDLE_STMT:
140                         return PGAPI_FreeStmt(Handle, SQL_DROP);
141                 default: break;
142         }
143         return SQL_ERROR;
144 }
145 /*      new function */
146 RETCODE  SQL_API SQLGetDescField(SQLHDESC DescriptorHandle,
147            SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
148            PTR Value, SQLINTEGER BufferLength,
149            SQLINTEGER *StringLength)
150 {
151         mylog("[[SQLGetDescField]]\n");
152         return SQL_ERROR;
153 }
154 /*      new function */
155 RETCODE  SQL_API SQLGetDescRec(SQLHDESC DescriptorHandle,
156            SQLSMALLINT RecNumber, SQLCHAR *Name,
157            SQLSMALLINT BufferLength, SQLSMALLINT *StringLength,
158            SQLSMALLINT *Type, SQLSMALLINT *SubType, 
159            SQLINTEGER *Length, SQLSMALLINT *Precision, 
160            SQLSMALLINT *Scale, SQLSMALLINT *Nullable)
161 {
162         mylog("[[SQLGetDescRec]]\n");
163         return SQL_ERROR;
164 }
165 /*      new function */
166 RETCODE  SQL_API SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle,
167            SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier,
168            PTR DiagInfo, SQLSMALLINT BufferLength,
169            SQLSMALLINT *StringLength)
170 {
171         mylog("[[SQLGetDiagField]]\n");
172         return SQL_ERROR;
173 }
174 /*      SQLError -> SQLDiagRec */
175 RETCODE  SQL_API SQLGetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle,
176            SQLSMALLINT RecNumber, SQLCHAR *Sqlstate,
177            SQLINTEGER *NativeError, SQLCHAR *MessageText,
178            SQLSMALLINT BufferLength, SQLSMALLINT *TextLength)
179 {
180         RETCODE ret;
181         mylog("[[SQLGetDiagRec]]\n");
182         switch (HandleType)
183         {
184                 case SQL_HANDLE_ENV:
185                         ret = PGAPI_Error(Handle, NULL, NULL, Sqlstate, NativeError,
186                                 MessageText, BufferLength, TextLength);
187                         break;
188                 case SQL_HANDLE_DBC:
189                         ret = PGAPI_Error(NULL, Handle,  NULL, Sqlstate, NativeError,
190                                 MessageText, BufferLength, TextLength);
191                         break;
192                 case SQL_HANDLE_STMT:
193                         ret = PGAPI_Error(NULL, NULL, Handle, Sqlstate, NativeError,
194                                 MessageText, BufferLength, TextLength);
195                         break;
196                 default:
197                         ret = SQL_ERROR;
198         }
199         if (ret == SQL_SUCCESS_WITH_INFO &&
200             BufferLength == 0 &&
201             *TextLength)
202         {
203                 SQLSMALLINT     BufferLength = *TextLength + 4;
204                 SQLCHAR *MessageText = malloc(BufferLength);
205                 ret = SQLGetDiagRec(HandleType, Handle, RecNumber, Sqlstate,
206                                 NativeError, MessageText, BufferLength,
207                                 TextLength);
208                 free(MessageText);
209         }
210         return ret;
211 }
212 /*      new function */
213 RETCODE  SQL_API SQLGetEnvAttr(HENV EnvironmentHandle,
214            SQLINTEGER Attribute, PTR Value,
215            SQLINTEGER BufferLength, SQLINTEGER *StringLength)
216 {
217         EnvironmentClass *env = (EnvironmentClass *) EnvironmentHandle;
218         mylog("[[SQLGetEnvAttr]] %d\n", Attribute);
219         switch (Attribute)
220         {
221                 case SQL_ATTR_CONNECTION_POOLING:
222                         *((unsigned int *) Value) = SQL_CP_OFF;
223                         break;
224                 case SQL_ATTR_CP_MATCH:
225                         *((unsigned int *) Value) = SQL_CP_RELAXED_MATCH;
226                         break;
227                 case SQL_ATTR_ODBC_VERSION:
228                         *((unsigned int *) Value) = SQL_OV_ODBC3;
229                         break;
230                 case SQL_ATTR_OUTPUT_NTS:
231                         *((unsigned int *) Value) = SQL_TRUE;
232                         break;
233                 default:
234                         env->errornumber = CONN_INVALID_ARGUMENT_NO;
235                         return SQL_ERROR;
236         }
237         return SQL_SUCCESS;
238 }
239 /*      SQLGetConnectOption -> SQLGetconnectAttr */
240 RETCODE  SQL_API SQLGetConnectAttr(HDBC ConnectionHandle,
241            SQLINTEGER Attribute, PTR Value,
242            SQLINTEGER BufferLength, SQLINTEGER *StringLength)
243 {
244         ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
245         mylog("[[SQLGetConnectAttr]] %d\n", Attribute);
246         switch (Attribute)
247         {
248                 case SQL_ATTR_ASYNC_ENABLE:
249                 case SQL_ATTR_AUTO_IPD:
250                 case SQL_ATTR_CONNECTION_DEAD:
251                 case SQL_ATTR_CONNECTION_TIMEOUT:
252                 case SQL_ATTR_METADATA_ID:
253                         conn->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
254                         conn->errormsg = "Unsupported connection option (Set)";
255                         return SQL_ERROR;
256         }
257         return PGAPI_GetConnectOption (ConnectionHandle, (UWORD) Attribute, Value);
258 }
259 /*      SQLGetStmtOption -> SQLGetStmtAttr */
260 RETCODE  SQL_API SQLGetStmtAttr(HSTMT StatementHandle,
261            SQLINTEGER Attribute, PTR Value,
262            SQLINTEGER BufferLength, SQLINTEGER *StringLength)
263 {
264         static char *func = "SQLGetStmtAttr";
265         StatementClass  *stmt = (StatementClass *) StatementHandle;
266         RETCODE ret = SQL_SUCCESS;
267         int     len = 0;
268         mylog("[[%s]] %d\n", func, Attribute);
269         switch (Attribute)
270         {
271                 case SQL_ATTR_FETCH_BOOKMARK_PTR:       /* 16 */
272                         Value = stmt->options.bookmark_ptr;
273                         len = 4;
274                         break;  
275                 case SQL_ATTR_ROW_STATUS_PTR:   /* 25 */
276                         Value = stmt->options.rowStatusArray;
277                         len = 4;
278                         break;
279                 case SQL_ATTR_ROWS_FETCHED_PTR: /* 26 */
280                         Value = stmt->options.rowsFetched;
281                         len = 4;
282                         break;
283                 case SQL_ATTR_ROW_ARRAY_SIZE:   /* 27 */
284                         *((SQLUINTEGER *) Value) = stmt->options.rowset_size;
285                         len = 4;
286                         break; 
287                 case SQL_ATTR_APP_ROW_DESC:     /* 10010 */
288                         *((HSTMT *) Value) = StatementHandle; /* this is useless */
289                         len = 4;
290                         break;  
291                 case SQL_ATTR_APP_PARAM_DESC:   /* 10011 */
292                         *((HSTMT *) Value) = StatementHandle; /* this is useless */
293                         len = 4;
294                         break;  
295                 case SQL_ATTR_IMP_ROW_DESC:     /* 10012 */
296                         *((HSTMT *) Value) = StatementHandle; /* this is useless */
297                         len = 4;
298                         break;  
299                 case SQL_ATTR_IMP_PARAM_DESC:   /* 10013 */
300                         *((HSTMT *) Value) = StatementHandle; /* this is useless */
301                         len = 4;
302                         break;  
303                 case SQL_ATTR_AUTO_IPD:         /* 10001 */
304                 case SQL_ATTR_ROW_BIND_TYPE:    /* == SQL_BIND_TYPE */
305                 case SQL_ATTR_PARAMSET_SIZE:    /* 22 */
306                 case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */
307                 case SQL_ATTR_PARAMS_PROCESSED_PTR:     /* 21 */
308
309                 case SQL_ATTR_CURSOR_SCROLLABLE:        /* -1 */
310                 case SQL_ATTR_CURSOR_SENSITIVITY:       /* -2 */
311
312                 case SQL_ATTR_ENABLE_AUTO_IPD:  /* 15 */
313                 case SQL_ATTR_METADATA_ID:      /* 10014 */
314                 /* case SQL_ATTR_PREDICATE_PTR:
315                 case SQL_ATTR_PREDICATE_OCTET_LENGTH_PTR: */
316                 case SQL_ATTR_PARAM_BIND_OFFSET_PTR:    /* 17 */
317                 case SQL_ATTR_PARAM_BIND_TYPE:          /* 18 */
318                 case SQL_ATTR_PARAM_OPERATION_PTR:      /* 19 */
319                 case SQL_ATTR_ROW_BIND_OFFSET_PTR:      /* 23 */
320                 case SQL_ATTR_ROW_OPERATION_PTR:        /* 24 */
321                         stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
322                         stmt->errormsg = "Unsupported statement option (Get)";
323                         SC_log_error(func, "", stmt);
324                         return SQL_ERROR;
325                 default:
326                         len = 4;
327                         ret = PGAPI_GetStmtOption(StatementHandle, (UWORD) Attribute, Value);
328         }
329         if (ret == SQL_SUCCESS && StringLength)
330                 *StringLength = len;
331         return ret;
332 }
333
334 /*      SQLSetConnectOption -> SQLSetConnectAttr */
335 RETCODE  SQL_API SQLSetConnectAttr(HDBC ConnectionHandle,
336            SQLINTEGER Attribute, PTR Value,
337            SQLINTEGER StringLength)
338 {
339         ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
340
341         mylog("[[SQLSetConnectAttr]] %d\n", Attribute);
342         switch (Attribute)
343         {
344                 case SQL_ATTR_ASYNC_ENABLE:
345                 case SQL_ATTR_AUTO_IPD:
346                 case SQL_ATTR_CONNECTION_DEAD:
347                 case SQL_ATTR_CONNECTION_TIMEOUT:
348                 case SQL_ATTR_METADATA_ID:
349                         conn->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
350                         conn->errormsg = "Unsupported connection option (Set)";
351                         return SQL_ERROR;
352         }
353         return PGAPI_SetConnectOption(ConnectionHandle, (UWORD) Attribute, (UDWORD) Value);
354 }
355 /*      new function */
356 RETCODE  SQL_API SQLSetDescField(SQLHDESC DescriptorHandle,
357            SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier,
358            PTR Value, SQLINTEGER BufferLength)
359 {
360         mylog("[[SQLSetDescField]]\n");
361         return SQL_ERROR;
362 }
363 /*      new fucntion */
364 RETCODE  SQL_API SQLSetDescRec(SQLHDESC DescriptorHandle,
365            SQLSMALLINT RecNumber, SQLSMALLINT Type,
366            SQLSMALLINT SubType, SQLINTEGER Length,
367            SQLSMALLINT Precision, SQLSMALLINT Scale,
368            PTR Data, SQLINTEGER *StringLength,
369            SQLINTEGER *Indicator)
370 {
371         mylog("[[SQLsetDescRec]]\n");
372         return SQL_ERROR;
373 }
374 /*      new function */
375 RETCODE  SQL_API SQLSetEnvAttr(HENV EnvironmentHandle,
376            SQLINTEGER Attribute, PTR Value,
377            SQLINTEGER StringLength)
378 {
379         EnvironmentClass *env = (EnvironmentClass *) EnvironmentHandle;
380         mylog("[[SQLSetEnvAttr]] att=%d,%u\n", Attribute, Value);
381         switch (Attribute)
382         {
383                 case SQL_ATTR_CONNECTION_POOLING:
384                         if ((SQLUINTEGER) Value == SQL_CP_OFF)
385                                 return SQL_SUCCESS;
386                         break;
387                 case SQL_ATTR_CP_MATCH:
388                         /* *((unsigned int *) Value) = SQL_CP_RELAXED_MATCH; */
389                         return SQL_SUCCESS;
390                 case SQL_ATTR_ODBC_VERSION:
391                         if ((SQLUINTEGER) Value == SQL_OV_ODBC2)
392                                 return SQL_SUCCESS;
393                         break;
394                 case SQL_ATTR_OUTPUT_NTS:
395                         if ((SQLUINTEGER) Value == SQL_TRUE)
396                                 return SQL_SUCCESS;
397                         break;
398                 default:
399                         env->errornumber = CONN_INVALID_ARGUMENT_NO;
400                         return SQL_ERROR;
401         }
402         env->errornumber = CONN_OPTION_VALUE_CHANGED;
403         env->errormsg = "SetEnv changed to ";
404         return SQL_SUCCESS_WITH_INFO;
405 }
406 /*      SQLSet(Param/Scroll/Stmt)Option -> SQLSetStmtAttr */
407 RETCODE  SQL_API SQLSetStmtAttr(HSTMT StatementHandle,
408            SQLINTEGER Attribute, PTR Value,
409            SQLINTEGER StringLength)
410 {
411         static char *func = "SQLSetStmtAttr";
412         StatementClass  *stmt = (StatementClass *) StatementHandle;
413         UDWORD  rowcount;
414         mylog("[[%s]] %d,%u\n", func, Attribute, Value);
415         switch (Attribute)
416         {
417                 case SQL_ATTR_PARAMSET_SIZE:    /* 22 */
418                         return PGAPI_ParamOptions(StatementHandle, (UWORD) Value, &rowcount);
419                 case SQL_ATTR_PARAM_STATUS_PTR: /* 20 */
420                 case SQL_ATTR_PARAMS_PROCESSED_PTR:     /* 21 */
421
422                 case SQL_ATTR_CURSOR_SCROLLABLE:        /* -1 */
423                 case SQL_ATTR_CURSOR_SENSITIVITY:       /* -2 */
424
425                 case SQL_ATTR_ENABLE_AUTO_IPD:  /* 15 */
426
427                 case SQL_ATTR_APP_ROW_DESC:     /* 10010 */
428                 case SQL_ATTR_APP_PARAM_DESC:   /* 10011 */
429                 case SQL_ATTR_AUTO_IPD:         /* 10001 */
430                 /*case SQL_ATTR_ROW_BIND_TYPE:*/        /* == SQL_BIND_TYPE */
431                 case SQL_ATTR_IMP_ROW_DESC:     /* 10012 */
432                 case SQL_ATTR_IMP_PARAM_DESC:   /* 10013 */
433                 case SQL_ATTR_METADATA_ID:      /* 10014 */
434                 /* case SQL_ATTR_PREDICATE_PTR:
435                 case SQL_ATTR_PREDICATE_OCTET_LENGTH_PTR: */
436                 case SQL_ATTR_PARAM_BIND_OFFSET_PTR:    /* 17 */
437                 case SQL_ATTR_PARAM_BIND_TYPE:          /* 18 */
438                 case SQL_ATTR_PARAM_OPERATION_PTR:      /* 19 */
439                 case SQL_ATTR_ROW_BIND_OFFSET_PTR:      /* 23 */
440                 case SQL_ATTR_ROW_OPERATION_PTR:        /* 24 */
441                         stmt->errornumber = STMT_INVALID_OPTION_IDENTIFIER;
442                         stmt->errormsg = "Unsupported statement option (Set)";
443                         SC_log_error(func, "", stmt);
444                         return SQL_ERROR;
445  
446                 case SQL_ATTR_FETCH_BOOKMARK_PTR:       /* 16 */
447                         stmt->options.bookmark_ptr = Value;
448                         break;
449                 case SQL_ATTR_ROW_STATUS_PTR:   /* 25 */
450                         stmt->options.rowStatusArray = (SQLUSMALLINT *) Value;
451                         break;
452                 case SQL_ATTR_ROWS_FETCHED_PTR: /* 26 */
453                         stmt->options.rowsFetched = (SQLUINTEGER *) Value;
454                         break;
455                 case SQL_ATTR_ROW_ARRAY_SIZE:   /* 27 */ 
456                         stmt->options.rowset_size = (SQLUINTEGER) Value;
457                         break;
458                 default: 
459                         return PGAPI_SetStmtOption(StatementHandle, (UWORD) Attribute, (UDWORD) Value);
460         }
461         return SQL_SUCCESS;
462 }
463
464 #define SQL_FUNC_ESET(pfExists, uwAPI) \
465                 (*(((UWORD*) (pfExists)) + ((uwAPI) >> 4)) \
466                         |= (1 << ((uwAPI) & 0x000F)) \
467                                 )
468 RETCODE SQL_API
469 PGAPI_GetFunctions30(HDBC hdbc, UWORD fFunction, UWORD FAR *pfExists)
470 {
471         if (fFunction != SQL_API_ODBC3_ALL_FUNCTIONS)
472                 return SQL_ERROR;
473         memset(pfExists, 0, sizeof(UWORD) * 250);
474
475         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCCONNECT); 1 deprecated */
476         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCENV); 2 deprecated */
477         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCSTMT); 3 deprecated */
478         /* for (i = SQL_API_SQLBINDCOL; i <= 23; i++)
479                 SQL_FUNC_ESET(pfExists, i); */
480         SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDCOL); /* 4 */
481         SQL_FUNC_ESET(pfExists, SQL_API_SQLCANCEL); /* 5 */
482         SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLATTRIBUTE); /* 6 */
483         SQL_FUNC_ESET(pfExists, SQL_API_SQLCONNECT); /* 7 */
484         SQL_FUNC_ESET(pfExists, SQL_API_SQLDESCRIBECOL); /* 8 */
485         SQL_FUNC_ESET(pfExists, SQL_API_SQLDISCONNECT); /* 9 */
486         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLERROR);  10 deprecated */
487         SQL_FUNC_ESET(pfExists, SQL_API_SQLEXECDIRECT); /* 11 */
488         SQL_FUNC_ESET(pfExists, SQL_API_SQLEXECUTE); /* 12 */
489         SQL_FUNC_ESET(pfExists, SQL_API_SQLFETCH); /* 13 */
490         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLFREECONNECT); 14 deprecated */
491         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLFREEENV); 15 deprecated */
492         SQL_FUNC_ESET(pfExists, SQL_API_SQLFREESTMT); /* 16 */
493         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETCURSORNAME); /* 17 */
494         SQL_FUNC_ESET(pfExists, SQL_API_SQLNUMRESULTCOLS); /* 18 */
495         SQL_FUNC_ESET(pfExists, SQL_API_SQLPREPARE); /* 19 */
496         SQL_FUNC_ESET(pfExists, SQL_API_SQLROWCOUNT); /* 20 */
497         SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCURSORNAME); /* 21 */
498         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETPARAM); 22 deprecated */
499         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLTRANSACT); 23 deprecated */
500         /*for (i = 40; i < SQL_API_SQLEXTENDEDFETCH; i++)
501                 SQL_FUNC_ESET(pfExists, i);*/
502         SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLUMNS); /* 40 */
503         SQL_FUNC_ESET(pfExists, SQL_API_SQLDRIVERCONNECT); /* 41 */
504         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLGETCONNECTOPTION); 42 deprecated */
505         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDATA); /* 43 */
506         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETFUNCTIONS); /* 44 */
507         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETINFO); /* 45 */
508         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLGETSTMTOPTION); 46 deprecated */
509         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETTYPEINFO); /* 47 */
510         SQL_FUNC_ESET(pfExists, SQL_API_SQLPARAMDATA); /* 48 */
511         SQL_FUNC_ESET(pfExists, SQL_API_SQLPUTDATA); /* 49 */
512         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTIONOPTION); 50 deprecated */
513         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSTMTOPTION); 51 deprecated */
514         SQL_FUNC_ESET(pfExists, SQL_API_SQLSPECIALCOLUMNS); /* 52 */
515         SQL_FUNC_ESET(pfExists, SQL_API_SQLSTATISTICS); /* 53 */
516         SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLES); /* 54 */
517         SQL_FUNC_ESET(pfExists, SQL_API_SQLBROWSECONNECT); /* 55 */
518         SQL_FUNC_ESET(pfExists, SQL_API_SQLCOLUMNPRIVILEGES); /* 56 */
519         SQL_FUNC_ESET(pfExists, SQL_API_SQLDATASOURCES); /* 57 */
520         SQL_FUNC_ESET(pfExists, SQL_API_SQLDESCRIBEPARAM); /* 58 */
521         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLEXTENDEDFETCH); 59 deprecated */
522         /*for (++i; i < SQL_API_SQLBINDPARAMETER; i++)
523                 SQL_FUNC_ESET(pfExists, i);*/
524         SQL_FUNC_ESET(pfExists, SQL_API_SQLFOREIGNKEYS); /* 60 */
525         SQL_FUNC_ESET(pfExists, SQL_API_SQLMORERESULTS); /* 61 */
526         SQL_FUNC_ESET(pfExists, SQL_API_SQLNATIVESQL); /* 62 */
527         SQL_FUNC_ESET(pfExists, SQL_API_SQLNUMPARAMS); /* 63 */
528         /* SQL_FUNC_ESET(pfExists, SQL_API_SQLPARAMOPTIONS); 64 deprecated */
529         SQL_FUNC_ESET(pfExists, SQL_API_SQLPRIMARYKEYS); /* 65 */
530         SQL_FUNC_ESET(pfExists, SQL_API_SQLPROCEDURECOLUMNS); /* 66 */
531         SQL_FUNC_ESET(pfExists, SQL_API_SQLPROCEDURES); /* 67 */
532         SQL_FUNC_ESET(pfExists, SQL_API_SQLSETPOS); /* 68 */
533         SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSCROLLOPTIONS); /* 69 deprecated */
534         SQL_FUNC_ESET(pfExists, SQL_API_SQLTABLEPRIVILEGES); /* 70 */
535         /*SQL_FUNC_ESET(pfExists, SQL_API_SQLDRIVERS);*/ /* 71 */
536         SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDPARAMETER); /* 72 */
537
538         SQL_FUNC_ESET(pfExists, SQL_API_SQLALLOCHANDLE); /* 1001 */
539         SQL_FUNC_ESET(pfExists, SQL_API_SQLBINDPARAM); /* 1002 */
540         SQL_FUNC_ESET(pfExists, SQL_API_SQLCLOSECURSOR); /* 1003 */
541         SQL_FUNC_ESET(pfExists, SQL_API_SQLCOPYDESC);/* 1004 not implemented yet */
542         SQL_FUNC_ESET(pfExists, SQL_API_SQLENDTRAN); /* 1005 */
543         SQL_FUNC_ESET(pfExists, SQL_API_SQLFREEHANDLE); /* 1006 */
544         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETCONNECTATTR); /* 1007 */
545         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDESCFIELD);/* 1008 not implemented yet */
546         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDESCREC);/* 1009 not implemented yet */
547         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDIAGFIELD);/* 1010 not implemented yet */
548         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETDIAGREC); /* 1011 */
549         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETENVATTR); /* 1012 */
550         SQL_FUNC_ESET(pfExists, SQL_API_SQLGETSTMTATTR); /* 1014 */
551         SQL_FUNC_ESET(pfExists, SQL_API_SQLSETCONNECTATTR); /* 1016 */
552         SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCFIELD); /* 1017 not implemeted yet */
553         SQL_FUNC_ESET(pfExists, SQL_API_SQLSETDESCREC); /* 1018 not implemented yet */
554         SQL_FUNC_ESET(pfExists, SQL_API_SQLSETENVATTR); /* 1019 */
555         SQL_FUNC_ESET(pfExists, SQL_API_SQLSETSTMTATTR); /* 1020 */
556         SQL_FUNC_ESET(pfExists, SQL_API_SQLFETCHSCROLL); /* 1021 */
557         SQL_FUNC_ESET(pfExists, SQL_API_SQLBULKOPERATIONS);/* 24 not implemented yet */
558
559         return SQL_SUCCESS;
560 }
561 RETCODE SQL_API
562 PGAPI_GetInfo30(HDBC hdbc, UWORD fInfoType, PTR rgbInfoValue,
563                 SWORD cbInfoValueMax, SWORD FAR *pcbInfoValue)
564 {
565         static char *func = "PGAPI_GetInfo30";
566         ConnectionClass *conn = (ConnectionClass *) hdbc;
567         char    *p = NULL;
568         int     len = 0, value = 0;
569         RETCODE result;
570
571         switch (fInfoType)
572         {
573                 case SQL_DYNAMIC_CURSOR_ATTRIBUTES1:
574                         len = 4;
575                         value = 0;
576                         break;
577                 case SQL_DYNAMIC_CURSOR_ATTRIBUTES2:
578                         len = 4;
579                         value = 0;
580                         break;
581
582                 case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1:
583                         len = 4;
584                         value = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE |
585                                 SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK;
586                         break;
587                 case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2:
588                         len = 4;
589                         value = 0;
590                         break;
591                 case SQL_KEYSET_CURSOR_ATTRIBUTES1:
592                         len = 4;
593                         value = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE
594                                 | SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK
595                                 | SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION
596                                 | SQL_CA1_POS_UPDATE | SQL_CA1_POS_DELETE
597                                 | SQL_CA1_POS_REFRESH
598                                 | SQL_CA1_BULK_ADD
599                                 | SQL_CA1_BULK_UPDATE_BY_BOOKMARK
600                                 | SQL_CA1_BULK_DELETE_BY_BOOKMARK
601                                 | SQL_CA1_BULK_FETCH_BY_BOOKMARK
602                                 ;
603                         break;
604                 case SQL_KEYSET_CURSOR_ATTRIBUTES2:
605                         len = 4;
606                         value = SQL_CA2_OPT_ROWVER_CONCURRENCY |
607                                 SQL_CA2_SENSITIVITY_ADDITIONS |
608                                 SQL_CA2_SENSITIVITY_DELETIONS |
609                                 SQL_CA2_SENSITIVITY_UPDATES;
610                         break;
611
612                 case SQL_STATIC_CURSOR_ATTRIBUTES1:
613                         len = 4;
614                         value = SQL_CA1_NEXT | SQL_CA1_ABSOLUTE |
615                                 SQL_CA1_RELATIVE | SQL_CA1_BOOKMARK |
616                                 SQL_CA1_LOCK_NO_CHANGE | SQL_CA1_POS_POSITION |
617                                 SQL_CA1_POS_UPDATE | SQL_CA1_POS_DELETE |
618                                 SQL_CA1_POS_REFRESH;
619                         break;
620                 case SQL_STATIC_CURSOR_ATTRIBUTES2:
621                         len = 4;
622                         value = SQL_CA2_OPT_ROWVER_CONCURRENCY |
623                                 SQL_CA2_SENSITIVITY_ADDITIONS |
624                                 SQL_CA2_SENSITIVITY_DELETIONS |
625                                 SQL_CA2_SENSITIVITY_UPDATES;
626                         break;
627                 default:
628                         /* unrecognized key */
629                         conn->errormsg = "Unrecognized key passed to SQLGetInfo.";
630                         conn->errornumber = CONN_NOT_IMPLEMENTED_ERROR;
631                         CC_log_error(func, "", conn);
632                         return SQL_ERROR;
633         }
634         result = SQL_SUCCESS;
635         if (p)
636         {
637                 /* char/binary data */
638                 len = strlen(p);
639
640                 if (rgbInfoValue)
641                 {
642                         strncpy_null((char *) rgbInfoValue, p, (size_t) cbInfoValueMax);
643
644                         if (len >= cbInfoValueMax)
645                         {
646                                 result = SQL_SUCCESS_WITH_INFO;
647                                 conn->errornumber = STMT_TRUNCATED;
648                                 conn->errormsg = "The buffer was too small for tthe InfoValue.";
649                         }
650                 }
651         }
652         else
653         {
654                 /* numeric data */
655                 if (rgbInfoValue)
656                 {
657                         if (len == 2)
658                                 *((WORD *) rgbInfoValue) = (WORD) value;
659                         else if (len == 4)
660                                 *((DWORD *) rgbInfoValue) = (DWORD) value;
661                 }
662         }
663
664         if (pcbInfoValue)
665                 *pcbInfoValue = len;
666         return result;
667 }