2 * Description: This module contains functions related to creating
3 * and manipulating a statement.
6 #include "connection.h"
7 #include "descriptor.h"
14 #include "pgapifunc.h"
17 void TI_Constructor(TABLE_INFO
* self
, const ConnectionClass
* conn
)
19 memset(self
, 0, sizeof(TABLE_INFO
));
20 TI_set_updatable(self
);
21 if (PG_VERSION_LT(conn
, 7.2))
25 STR_TO_NAME(self
->bestitem
, OID_NAME
);
26 sprintf(qual
, "\"oid\" = %%u");
27 STR_TO_NAME(self
->bestqual
, qual
);
29 TI_set_hasoids_checked(self
);
32 void TI_Destructor(TABLE_INFO
** ti
, int count
)
36 inolog("TI_Destructor count=%d\n", count
);
39 for (i
= 0; i
< count
; i
++)
43 NULL_THE_NAME(ti
[i
]->schema_name
);
44 NULL_THE_NAME(ti
[i
]->table_name
);
45 NULL_THE_NAME(ti
[i
]->table_alias
);
46 NULL_THE_NAME(ti
[i
]->bestitem
);
47 NULL_THE_NAME(ti
[i
]->bestqual
);
54 void FI_Constructor(FIELD_INFO
* self
, BOOL reuse
)
56 inolog("FI_Constructor reuse=%d\n", reuse
);
58 FI_Destructor(&self
, 1, FALSE
);
59 memset(self
, 0, sizeof(FIELD_INFO
));
60 self
->nullable
= TRUE
;
62 void FI_Destructor(FIELD_INFO
** fi
, int count
, BOOL freeFI
)
66 inolog("FI_Destructor count=%d\n", count
);
69 for (i
= 0; i
< count
; i
++)
73 NULL_THE_NAME(fi
[i
]->column_name
);
74 NULL_THE_NAME(fi
[i
]->column_alias
);
75 NULL_THE_NAME(fi
[i
]->schema_name
);
76 NULL_THE_NAME(fi
[i
]->before_dot
);
89 void DC_Constructor(DescriptorClass
* self
, BOOL embedded
,
90 StatementClass
* stmt
)
92 memset(self
, 0, sizeof(DescriptorClass
));
93 self
->embedded
= embedded
;
96 static void ARDFields_free(ARDFields
* self
)
98 inolog("ARDFields_free %p bookmark=%p", self
, self
->bookmark
);
101 free(self
->bookmark
);
102 self
->bookmark
= NULL
;
106 * the memory pointed to by the bindings is not deallocated by the
107 * driver but by the application that uses that driver, so we don't
110 ARD_unbind_cols(self
, TRUE
);
113 static void APDFields_free(APDFields
* self
)
117 free(self
->bookmark
);
118 self
->bookmark
= NULL
;
121 APD_free_params(self
, STMT_FREE_PARAMS_ALL
);
124 static void IRDFields_free(IRDFields
* self
)
126 /* Free the parsed field information */
129 FI_Destructor(self
->fi
, self
->allocated
, TRUE
);
136 static void IPDFields_free(IPDFields
* self
)
139 IPD_free_params(self
, STMT_FREE_PARAMS_ALL
);
142 void DC_Destructor(DescriptorClass
* self
)
144 if (self
->__error_message
)
146 free(self
->__error_message
);
147 self
->__error_message
= NULL
;
151 ER_Destructor(self
->pgerror
);
152 self
->pgerror
= NULL
;
154 if (self
->type_defined
)
156 switch (self
->desc_type
)
158 case SQL_ATTR_APP_ROW_DESC
:
159 ARDFields_free((ARDFields
*) (self
+ 1));
161 case SQL_ATTR_APP_PARAM_DESC
:
162 APDFields_free((APDFields
*) (self
+ 1));
164 case SQL_ATTR_IMP_ROW_DESC
:
165 IRDFields_free((IRDFields
*) (self
+ 1));
167 case SQL_ATTR_IMP_PARAM_DESC
:
168 IPDFields_free((IPDFields
*) (self
+ 1));
174 void InitializeEmbeddedDescriptor(DescriptorClass
* desc
,
175 StatementClass
* stmt
,
178 DC_Constructor(desc
, TRUE
, stmt
);
179 DC_get_conn(desc
) = SC_get_conn(stmt
);
180 desc
->type_defined
= TRUE
;
181 desc
->desc_type
= desc_type
;
184 case SQL_ATTR_APP_ROW_DESC
:
185 memset(desc
+ 1, 0, sizeof(ARDFields
));
186 stmt
->ard
= (ARDClass
*) desc
;
188 case SQL_ATTR_APP_PARAM_DESC
:
189 memset(desc
+ 1, 0, sizeof(APDFields
));
190 stmt
->apd
= (APDClass
*) desc
;
192 case SQL_ATTR_IMP_ROW_DESC
:
193 memset(desc
+ 1, 0, sizeof(IRDFields
));
194 stmt
->ird
= (IRDClass
*) desc
;
195 stmt
->ird
->irdopts
.stmt
= stmt
;
197 case SQL_ATTR_IMP_PARAM_DESC
:
198 memset(desc
+ 1, 0, sizeof(IPDFields
));
199 stmt
->ipd
= (IPDClass
*) desc
;
205 * ARDFields initialize
207 void InitializeARDFields(ARDFields
* opt
)
209 memset(opt
, 0, sizeof(ARDFields
));
210 opt
->size_of_rowset
= 1;
211 opt
->bind_size
= 0; /* default is to bind by column */
212 opt
->size_of_rowset_odbc2
= 1;
216 * APDFields initialize
218 void InitializeAPDFields(APDFields
* opt
)
220 memset(opt
, 0, sizeof(APDFields
));
221 opt
->paramset_size
= 1;
222 opt
->param_bind_type
= 0; /* default is to bind by column */
223 opt
->paramset_size_dummy
= 1; /* dummy setting */
226 BindInfoClass
*ARD_AllocBookmark(ARDFields
* ardopts
)
228 if (!ardopts
->bookmark
)
231 (BindInfoClass
*) malloc(sizeof(BindInfoClass
));
232 memset(ardopts
->bookmark
, 0, sizeof(BindInfoClass
));
234 return ardopts
->bookmark
;
238 #define DESC_INCREMENT 10
239 char CC_add_descriptor(ConnectionClass
* self
, DescriptorClass
* desc
)
243 mylog("CC_add_descriptor: self=%p, desc=%p\n", self
, desc
);
245 for (i
= 0; i
< self
->num_descs
; i
++)
249 DC_get_conn(desc
) = self
;
250 self
->descs
[i
] = desc
;
254 /* no more room -- allocate more memory */
256 (DescriptorClass
**) realloc(self
->descs
,
257 sizeof(DescriptorClass
*) *
263 memset(&self
->descs
[self
->num_descs
], 0, sizeof(DescriptorClass
*) *
265 DC_get_conn(desc
) = self
;
266 self
->descs
[self
->num_descs
] = desc
;
267 self
->num_descs
+= DESC_INCREMENT
;
273 * This API allocates a Application descriptor.
275 RETCODE SQL_API
PGAPI_AllocDesc(HDBC ConnectionHandle
,
276 SQLHDESC
* DescriptorHandle
)
278 CSTR func
= "PGAPI_AllocDesc";
279 ConnectionClass
*conn
= (ConnectionClass
*) ConnectionHandle
;
280 RETCODE ret
= SQL_SUCCESS
;
281 DescriptorClass
*desc
=
282 (DescriptorClass
*) malloc(sizeof(DescriptorAlloc
));
284 mylog("%s: entering...\n", func
);
287 memset(desc
, 0, sizeof(DescriptorAlloc
));
288 DC_get_conn(desc
) = conn
;
289 if (CC_add_descriptor(conn
, desc
))
290 *DescriptorHandle
= desc
;
294 CC_set_error(conn
, CONN_STMT_ALLOC_ERROR
,
295 "Maximum number of descriptors exceeded",
301 CC_set_error(conn
, CONN_STMT_ALLOC_ERROR
,
302 "No more memory ti allocate a further descriptor",
309 RETCODE SQL_API
PGAPI_FreeDesc(SQLHDESC DescriptorHandle
)
311 CSTR func
= "PGAPI_FreeDesc";
312 DescriptorClass
*desc
= (DescriptorClass
*) DescriptorHandle
;
313 RETCODE ret
= SQL_SUCCESS
;
315 mylog("%s: entering...\n", func
);
320 ConnectionClass
*conn
= DC_get_conn(desc
);
322 for (i
= 0; i
< conn
->num_descs
; i
++)
324 if (conn
->descs
[i
] == desc
)
326 conn
->descs
[i
] = NULL
;
335 static void BindInfoClass_copy(const BindInfoClass
* src
,
336 BindInfoClass
* target
)
338 memcpy(target
, src
, sizeof(BindInfoClass
));
340 static void ARDFields_copy(const ARDFields
* src
, ARDFields
* target
)
342 memcpy(target
, src
, sizeof(ARDFields
));
343 target
->bookmark
= NULL
;
346 BindInfoClass
*bookmark
= ARD_AllocBookmark(target
);
347 BindInfoClass_copy(src
->bookmark
, bookmark
);
349 if (src
->allocated
<= 0)
351 target
->allocated
= 0;
352 target
->bindings
= NULL
;
357 target
->bindings
= (BindInfoClass
*)
358 malloc(target
->allocated
* sizeof(BindInfoClass
));
359 for (i
= 0; i
< target
->allocated
; i
++)
360 BindInfoClass_copy(&src
->bindings
[i
], &target
->bindings
[i
]);
364 static void ParameterInfoClass_copy(const ParameterInfoClass
* src
,
365 ParameterInfoClass
* target
)
367 memcpy(target
, src
, sizeof(ParameterInfoClass
));
369 static void APDFields_copy(const APDFields
* src
, APDFields
* target
)
371 memcpy(target
, src
, sizeof(APDFields
));
374 target
->bookmark
= (ParameterInfoClass
*)
375 malloc(sizeof(ParameterInfoClass
));
376 ParameterInfoClass_copy(src
->bookmark
, target
->bookmark
);
378 if (src
->allocated
<= 0)
380 target
->allocated
= 0;
381 target
->parameters
= NULL
;
386 target
->parameters
= (ParameterInfoClass
*)
387 malloc(target
->allocated
* sizeof(ParameterInfoClass
));
388 for (i
= 0; i
< target
->allocated
; i
++)
389 ParameterInfoClass_copy(&src
->parameters
[i
],
390 &target
->parameters
[i
]);
394 static void ParameterImplClass_copy(const ParameterImplClass
* src
,
395 ParameterImplClass
* target
)
397 memcpy(target
, src
, sizeof(ParameterImplClass
));
399 static void IPDFields_copy(const IPDFields
* src
, IPDFields
* target
)
401 memcpy(target
, src
, sizeof(IPDFields
));
402 if (src
->allocated
<= 0)
404 target
->allocated
= 0;
405 target
->parameters
= NULL
;
411 (ParameterImplClass
*) malloc(target
->allocated
*
412 sizeof(ParameterInfoClass
));
413 for (i
= 0; i
< target
->allocated
; i
++)
414 ParameterImplClass_copy(&src
->parameters
[i
],
415 &target
->parameters
[i
]);
420 PGAPI_CopyDesc(SQLHDESC SourceDescHandle
, SQLHDESC TargetDescHandle
)
422 CSTR func
= "PGAPI_CopyDesc";
423 RETCODE ret
= SQL_ERROR
;
424 DescriptorClass
*src
, *target
;
425 ARDFields
*ard_src
, *ard_tgt
;
426 APDFields
*apd_src
, *apd_tgt
;
427 IPDFields
*ipd_src
, *ipd_tgt
;
429 mylog("%s: entering...\n", func
);
430 src
= (DescriptorClass
*) SourceDescHandle
;
431 target
= (DescriptorClass
*) TargetDescHandle
;
432 if (!src
->type_defined
)
434 mylog("source type undefined\n");
435 DC_set_error(target
, DESC_EXEC_ERROR
,
436 "source handle type undefined");
439 if (target
->type_defined
)
441 inolog("source type=%d -> target type=%d\n", src
->desc_type
,
443 if (SQL_ATTR_IMP_ROW_DESC
== target
->desc_type
)
445 mylog("can't modify IRD\n");
446 DC_set_error(target
, DESC_EXEC_ERROR
, "can't copy to IRD");
448 } else if (target
->desc_type
!= src
->desc_type
)
450 mylog("src type != target type\n");
451 DC_set_error(target
, DESC_EXEC_ERROR
,
452 "src descriptor != target type");
455 DC_Destructor(target
);
458 switch (src
->desc_type
)
460 case SQL_ATTR_APP_ROW_DESC
:
461 inolog("src=%p target=%p type=%d", src
, target
, src
->desc_type
);
462 if (!target
->type_defined
)
464 target
->desc_type
= src
->desc_type
;
466 ard_src
= (ARDFields
*) (src
+ 1);
467 inolog(" rowset_size=%d bind_size=%d ope_ptr=%p off_ptr=%p\n",
468 ard_src
->size_of_rowset
, ard_src
->bind_size
,
469 ard_src
->row_operation_ptr
, ard_src
->row_offset_ptr
);
470 ard_tgt
= (ARDFields
*) (target
+ 1);
471 inolog(" target=%p", ard_tgt
);
472 ARDFields_copy(ard_src
, ard_tgt
);
473 inolog(" offset_ptr=%p\n", ard_tgt
->row_offset_ptr
);
475 case SQL_ATTR_APP_PARAM_DESC
:
476 if (!target
->type_defined
)
478 target
->desc_type
= src
->desc_type
;
480 apd_src
= (APDFields
*) (src
+ 1);
481 apd_tgt
= (APDFields
*) (target
+ 1);
482 APDFields_copy(apd_src
, apd_tgt
);
484 case SQL_ATTR_IMP_PARAM_DESC
:
485 if (!target
->type_defined
)
487 target
->desc_type
= src
->desc_type
;
489 ipd_src
= (IPDFields
*) (src
+ 1);
490 ipd_tgt
= (IPDFields
*) (target
+ 1);
491 IPDFields_copy(ipd_src
, ipd_tgt
);
494 mylog("invalid descriptor handle type=%d\n", src
->desc_type
);
495 DC_set_error(target
, DESC_EXEC_ERROR
,
496 "invalid descriptor type");
500 if (SQL_SUCCESS
== ret
)
501 target
->type_defined
= TRUE
;
505 void DC_clear_error(DescriptorClass
* self
)
507 if (self
->__error_message
)
509 free(self
->__error_message
);
510 self
->__error_message
= NULL
;
514 ER_Destructor(self
->pgerror
);
515 self
->pgerror
= NULL
;
517 self
->__error_number
= 0;
519 self
->error_index
= 0;
522 void DC_set_error(DescriptorClass
* desc
, int errornumber
,
523 const char *errormsg
)
525 if (desc
->__error_message
)
526 free(desc
->__error_message
);
527 desc
->__error_number
= errornumber
;
528 desc
->__error_message
= errormsg
? strdup(errormsg
) : NULL
;
530 void DC_set_errormsg(DescriptorClass
* desc
, const char *errormsg
)
532 if (desc
->__error_message
)
533 free(desc
->__error_message
);
534 desc
->__error_message
= errormsg
? strdup(errormsg
) : NULL
;
536 const char *DC_get_errormsg(const DescriptorClass
* desc
)
538 return desc
->__error_message
;
540 int DC_get_errornumber(const DescriptorClass
* desc
)
542 return desc
->__error_number
;
545 /* Map sql commands to statement types */
550 } Descriptor_sqlstate
[] =
553 DESC_ERROR_IN_ROW
, "01S01", "01S01"},
555 DESC_OPTION_VALUE_CHANGED
, "01S02", "01S02"},
557 DESC_OK
, "00000", "00000"}, /* OK */
559 DESC_EXEC_ERROR
, "HY000", "S1000"}, /* also a general error */
561 DESC_STATUS_ERROR
, "HY010", "S1010"},
563 DESC_SEQUENCE_ERROR
, "HY010", "S1010"}, /* Function sequence error */
565 DESC_NO_MEMORY_ERROR
, "HY001", "S1001"}, /* memory allocation failure */
567 DESC_COLNUM_ERROR
, "07009", "S1002"}, /* invalid column number */
569 DESC_NO_STMTSTRING
, "HY001", "S1001"}, /* having no stmtstring is also a malloc problem */
571 DESC_ERROR_TAKEN_FROM_BACKEND
, "HY000", "S1000"}, /* general error */
573 DESC_INTERNAL_ERROR
, "HY000", "S1000"}, /* general error */
575 DESC_STILL_EXECUTING
, "HY010", "S1010"},
577 DESC_NOT_IMPLEMENTED_ERROR
, "HYC00", "S1C00"}, /* == 'driver not
580 DESC_BAD_PARAMETER_NUMBER_ERROR
, "07009", "S1093"},
582 DESC_OPTION_OUT_OF_RANGE_ERROR
, "HY092", "S1092"},
584 DESC_INVALID_COLUMN_NUMBER_ERROR
, "07009", "S1002"},
586 DESC_RESTRICTED_DATA_TYPE_ERROR
, "07006", "07006"},
588 DESC_INVALID_CURSOR_STATE_ERROR
, "07005", "24000"},
590 DESC_CREATE_TABLE_ERROR
, "42S01", "S0001"}, /* table already exists */
592 DESC_NO_CURSOR_NAME
, "S1015", "S1015"},
594 DESC_INVALID_CURSOR_NAME
, "34000", "34000"},
596 DESC_INVALID_ARGUMENT_NO
, "HY024", "S1009"}, /* invalid argument value */
598 DESC_ROW_OUT_OF_RANGE
, "HY107", "S1107"},
600 DESC_OPERATION_CANCELLED
, "HY008", "S1008"},
602 DESC_INVALID_CURSOR_POSITION
, "HY109", "S1109"},
604 DESC_VALUE_OUT_OF_RANGE
, "HY019", "22003"},
606 DESC_OPERATION_INVALID
, "HY011", "S1011"},
608 DESC_PROGRAM_TYPE_OUT_OF_RANGE
, "?????", "?????"},
610 DESC_BAD_ERROR
, "08S01", "08S01"}, /* communication link failure */
612 DESC_INVALID_OPTION_IDENTIFIER
, "HY092", "HY092"},
614 DESC_RETURN_NULL_WITHOUT_INDICATOR
, "22002", "22002"},
616 DESC_INVALID_DESCRIPTOR_IDENTIFIER
, "HY091", "HY091"},
618 DESC_OPTION_NOT_FOR_THE_DRIVER
, "HYC00", "HYC00"},
620 DESC_FETCH_OUT_OF_RANGE
, "HY106", "S1106"},
622 DESC_COUNT_FIELD_INCORRECT
, "07002", "07002"},};
624 static PG_ErrorInfo
*DC_create_errorinfo(const DescriptorClass
* desc
)
627 ConnectionClass
*conn
;
628 EnvironmentClass
*env
;
630 BOOL env_is_odbc3
= TRUE
;
633 return desc
->pgerror
;
634 errornum
= desc
->__error_number
;
635 error
= ER_Constructor(errornum
, desc
->__error_message
);
638 conn
= DC_get_conn(desc
);
639 if (conn
&& (env
= (EnvironmentClass
*) conn
->henv
))
640 env_is_odbc3
= EN_is_odbc3(env
);
641 errornum
-= LOWEST_DESC_ERROR
;
644 sizeof(Descriptor_sqlstate
) / sizeof(Descriptor_sqlstate
[0]))
645 errornum
= 1 - LOWEST_DESC_ERROR
;
646 strcpy(error
->sqlstate
,
647 env_is_odbc3
? Descriptor_sqlstate
[errornum
].
648 ver3str
: Descriptor_sqlstate
[errornum
].ver2str
);
652 DC_log_error(const char *func
, const char *desc
,
653 const DescriptorClass
* self
)
655 #define nullcheck(a) (a ? a : "(NULL)")
658 qlog("DESCRIPTOR ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func
, desc
, self
->__error_number
, nullcheck(self
->__error_message
));
660 ("DESCRIPTOR ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n",
661 func
, desc
, self
->__error_number
,
662 nullcheck(self
->__error_message
));
666 /* Returns the next SQL error information. */
668 PGAPI_DescError(SQLHDESC hdesc
,
669 SQLSMALLINT RecNumber
,
670 SQLCHAR FAR
* szSqlState
,
671 SQLINTEGER FAR
* pfNativeError
,
672 SQLCHAR FAR
* szErrorMsg
,
673 SQLSMALLINT cbErrorMsgMax
,
674 SQLSMALLINT FAR
* pcbErrorMsg
, UWORD flag
)
676 CSTR func
= "PGAPI_DescError";
677 /* CC: return an error of a hdesc */
678 DescriptorClass
*desc
= (DescriptorClass
*) hdesc
;
680 mylog("%s RecN=%d\n", func
);
681 desc
->pgerror
= DC_create_errorinfo(desc
);
682 return ER_ReturnError(&(desc
->pgerror
), RecNumber
, szSqlState
,
683 pfNativeError
, szErrorMsg
, cbErrorMsgMax
,