1 /*-------
2 * Module: descriptor.c
3 *
4 * Description: This module contains functions related to creating
5 * and manipulating a statement.
6 *
7 * Classes: DescriptorClass (Functions prefix: "DC_")
8 *
9 *
10 * Comments: See "readme.txt" for copyright and license information.
11 *-------
12 */
13
14 #include "environ.h"
15 #include "connection.h"
16 #include "descriptor.h"
17 #include "statement.h"
18 #include "qresult.h"
19 #include "misc.h"
20
21 #include <stdio.h>
22 #include <string.h>
23 #include <ctype.h>
24
25 #include "pgapifunc.h"
26
27
TI_Constructor(TABLE_INFO * self,const ConnectionClass * conn)28 void TI_Constructor(TABLE_INFO *self, const ConnectionClass *conn)
29 {
30 memset(self, 0, sizeof(TABLE_INFO));
31 TI_set_updatable(self);
32 }
TI_Destructor(TABLE_INFO ** ti,int count)33 void TI_Destructor(TABLE_INFO **ti, int count)
34 {
35 int i;
36
37 MYLOG(DETAIL_LOG_LEVEL, "entering count=%d\n", count);
38 if (ti)
39 {
40 for (i = 0; i < count; i++)
41 {
42 if (ti[i])
43 {
44 COL_INFO *coli = ti[i]->col_info;
45 if (coli)
46 {
47 MYLOG(0, "!!!refcnt %p:%d -> %d\n", coli, coli->refcnt, coli->refcnt - 1);
48 coli->refcnt--;
49 if (coli->refcnt <= 0 && 0 == coli->acc_time) /* acc_time == 0 means the table is dropped */
50 free_col_info_contents(coli);
51 }
52 NULL_THE_NAME(ti[i]->schema_name);
53 NULL_THE_NAME(ti[i]->table_name);
54 NULL_THE_NAME(ti[i]->table_alias);
55 NULL_THE_NAME(ti[i]->bestitem);
56 NULL_THE_NAME(ti[i]->bestqual);
57 TI_Destroy_IH(ti[i]);
58 free(ti[i]);
59 ti[i] = NULL;
60 }
61 }
62 }
63 }
FI_Constructor(FIELD_INFO * self,BOOL reuse)64 void FI_Constructor(FIELD_INFO *self, BOOL reuse)
65 {
66 MYLOG(DETAIL_LOG_LEVEL, "entering reuse=%d\n", reuse);
67 if (reuse)
68 FI_Destructor(&self, 1, FALSE);
69 memset(self, 0, sizeof(FIELD_INFO));
70 self->nullable = TRUE;
71 self->columnkey = -1;
72 self->typmod = -1;
73 }
FI_Destructor(FIELD_INFO ** fi,int count,BOOL freeFI)74 void FI_Destructor(FIELD_INFO **fi, int count, BOOL freeFI)
75 {
76 int i;
77
78 MYLOG(DETAIL_LOG_LEVEL, "entering count=%d\n", count);
79 if (fi)
80 {
81 for (i = 0; i < count; i++)
82 {
83 if (fi[i])
84 {
85 NULL_THE_NAME(fi[i]->column_name);
86 NULL_THE_NAME(fi[i]->column_alias);
87 NULL_THE_NAME(fi[i]->schema_name);
88 NULL_THE_NAME(fi[i]->before_dot);
89 if (freeFI)
90 {
91 free(fi[i]);
92 fi[i] = NULL;
93 }
94 }
95 }
96 if (freeFI)
97 free(fi);
98 }
99 }
100
101 static const pgNAME invNAME = {NULL};
102
103 #define INIT_IH 32
TI_Create_IH(TABLE_INFO * ti)104 void TI_Create_IH(TABLE_INFO *ti)
105 {
106 int alloc = INIT_IH;
107 InheritanceClass *ih;
108
109 ih = (InheritanceClass *) malloc(sizeof(InheritanceClass) + (alloc - 1) * sizeof(ih->inf[0]));
110 memset(ih, 0, sizeof(InheritanceClass));
111 ih->allocated = alloc;
112 ti->ih = ih;
113 }
114
TI_Destroy_IH(TABLE_INFO * ti)115 void TI_Destroy_IH(TABLE_INFO *ti)
116 {
117 InheritanceClass *ih;
118 int i;
119
120 if (NULL == (ih = ti->ih))
121 return;
122 for (i = 0; i < ih->count; i++)
123 {
124 NULL_THE_NAME(ih->inf[i].fullTable);
125 }
126 free(ih);
127 ti->ih = NULL;
128 }
129
TI_From_IH(TABLE_INFO * ti,OID tableoid)130 const pgNAME TI_From_IH(TABLE_INFO *ti, OID tableoid)
131 {
132 InheritanceClass *ih;
133 int i;
134
135 if (NULL == (ih = ti->ih))
136 return invNAME;
137 if (tableoid == ih->cur_tableoid)
138 return ih->cur_fullTable;
139 for (i = 0; i < ih->count; i++)
140 {
141 if (ih->inf[i].tableoid == tableoid)
142 {
143 ih->cur_tableoid = tableoid;
144 ih->cur_fullTable = ih->inf[i].fullTable;
145 return ih->cur_fullTable;
146 }
147 }
148 return invNAME;
149 }
150
TI_Ins_IH(TABLE_INFO * ti,OID tableoid,const char * fullName)151 const pgNAME TI_Ins_IH(TABLE_INFO *ti, OID tableoid, const char *fullName)
152 {
153 InheritanceClass *ih;
154 int count;
155
156 if (NULL == (ih = ti->ih))
157 {
158 TI_Create_IH(ti);
159 if (ih = ti->ih, NULL == ih)
160 return invNAME;
161 }
162 if ((count = ih->count) >= ih->allocated)
163 {
164 int alloc = ih->allocated * 2;
165 InheritanceClass *nih;
166
167 if (nih = (InheritanceClass *) realloc(ih, sizeof(InheritanceClass) + (alloc - 1) * sizeof(ih->inf[0])), NULL == nih)
168 {
169 TI_Destroy_IH(ti);
170 return invNAME;
171 }
172 ti->ih = ih = nih;
173 ih->allocated = alloc;
174 }
175 ih->inf[count].tableoid = tableoid;
176 INIT_NAME(ih->inf[count].fullTable);
177 STR_TO_NAME(ih->inf[count].fullTable, fullName);
178 ih->cur_tableoid = tableoid;
179 ih->cur_fullTable = ih->inf[count].fullTable;
180 ih->count++;
181
182 return ih->inf[count].fullTable;
183 }
184
DC_Constructor(DescriptorClass * self,BOOL embedded,StatementClass * stmt)185 void DC_Constructor(DescriptorClass *self, BOOL embedded, StatementClass *stmt)
186 {
187 memset(self, 0, sizeof(DescriptorClass));
188 self->deschd.embedded = embedded;
189 }
190
ARDFields_free(ARDFields * self)191 static void ARDFields_free(ARDFields * self)
192 {
193 MYLOG(DETAIL_LOG_LEVEL, "entering %p bookmark=%p\n", self, self->bookmark);
194 if (self->bookmark)
195 {
196 free(self->bookmark);
197 self->bookmark = NULL;
198 }
199 /*
200 * the memory pointed to by the bindings is not deallocated by the
201 * driver but by the application that uses that driver, so we don't
202 * have to care
203 */
204 ARD_unbind_cols(self, TRUE);
205 }
206
APDFields_free(APDFields * self)207 static void APDFields_free(APDFields * self)
208 {
209 if (self->bookmark)
210 {
211 free(self->bookmark);
212 self->bookmark = NULL;
213 }
214 /* param bindings */
215 APD_free_params(self, STMT_FREE_PARAMS_ALL);
216 }
217
IRDFields_free(IRDFields * self)218 static void IRDFields_free(IRDFields * self)
219 {
220 /* Free the parsed field information */
221 if (self->fi)
222 {
223 FI_Destructor(self->fi, self->allocated, TRUE);
224 self->fi = NULL;
225 }
226 self->allocated = 0;
227 self->nfields = 0;
228 }
229
IPDFields_free(IPDFields * self)230 static void IPDFields_free(IPDFields * self)
231 {
232 /* param bindings */
233 IPD_free_params(self, STMT_FREE_PARAMS_ALL);
234 }
235
DC_Destructor(DescriptorClass * self)236 void DC_Destructor(DescriptorClass *self)
237 {
238 DescriptorHeader *deschd = &(self->deschd);
239 if (deschd->__error_message)
240 {
241 free(deschd->__error_message);
242 deschd->__error_message = NULL;
243 }
244 if (deschd->pgerror)
245 {
246 ER_Destructor(deschd->pgerror);
247 deschd->pgerror = NULL;
248 }
249 if (deschd->type_defined)
250 {
251 switch (deschd->desc_type)
252 {
253 case SQL_ATTR_APP_ROW_DESC:
254 ARDFields_free(&(self->ardf));
255 break;
256 case SQL_ATTR_APP_PARAM_DESC:
257 APDFields_free(&(self->apdf));
258 break;
259 case SQL_ATTR_IMP_ROW_DESC:
260 IRDFields_free(&(self->irdf));
261 break;
262 case SQL_ATTR_IMP_PARAM_DESC:
263 IPDFields_free(&(self->ipdf));
264 break;
265 }
266 }
267 }
268
InitializeEmbeddedDescriptor(DescriptorClass * self,StatementClass * stmt,UInt4 desc_type)269 void InitializeEmbeddedDescriptor(DescriptorClass *self, StatementClass *stmt,
270 UInt4 desc_type)
271 {
272 DescriptorHeader *deschd = &(self->deschd);
273 DC_Constructor(self, TRUE, stmt);
274 DC_get_conn(self) = SC_get_conn(stmt);
275 deschd->type_defined = TRUE;
276 deschd->desc_type = desc_type;
277 switch (desc_type)
278 {
279 case SQL_ATTR_APP_ROW_DESC:
280 memset(&(self->ardf), 0, sizeof(ARDFields));
281 InitializeARDFields(&(self->ardf));
282 stmt->ard = self;
283 break;
284 case SQL_ATTR_APP_PARAM_DESC:
285 memset(&(self->apdf), 0, sizeof(APDFields));
286 InitializeAPDFields(&(self->apdf));
287 stmt->apd = self;
288 break;
289 case SQL_ATTR_IMP_ROW_DESC:
290 memset(&(self->irdf), 0, sizeof(IRDFields));
291 stmt->ird = self;
292 stmt->ird->irdf.stmt = stmt;
293 break;
294 case SQL_ATTR_IMP_PARAM_DESC:
295 memset(&(self->ipdf), 0, sizeof(IPDFields));
296 stmt->ipd = self;
297 break;
298 }
299 }
300
301 /*
302 * ARDFields initialize
303 */
304 void
InitializeARDFields(ARDFields * opt)305 InitializeARDFields(ARDFields *opt)
306 {
307 memset(opt, 0, sizeof(ARDFields));
308 opt->size_of_rowset = 1;
309 opt->bind_size = 0; /* default is to bind by column */
310 opt->size_of_rowset_odbc2 = 1;
311 }
312 /*
313 * APDFields initialize
314 */
315 void
InitializeAPDFields(APDFields * opt)316 InitializeAPDFields(APDFields *opt)
317 {
318 memset(opt, 0, sizeof(APDFields));
319 opt->paramset_size = 1;
320 opt->param_bind_type = 0; /* default is to bind by column */
321 opt->paramset_size_dummy = 1; /* dummy setting */
322 }
323
ARD_AllocBookmark(ARDFields * ardopts)324 BindInfoClass *ARD_AllocBookmark(ARDFields *ardopts)
325 {
326 if (!ardopts->bookmark)
327 {
328 ardopts->bookmark = (BindInfoClass *) malloc(sizeof(BindInfoClass));
329 memset(ardopts->bookmark, 0, sizeof(BindInfoClass));
330 }
331 return ardopts->bookmark;
332 }
333
334 #define DESC_INCREMENT 10
CC_add_descriptor(ConnectionClass * self,DescriptorClass * desc)335 char CC_add_descriptor(ConnectionClass *self, DescriptorClass *desc)
336 {
337 int i;
338 int new_num_descs;
339 DescriptorClass **descs;
340
341 MYLOG(0, "entering self=%p, desc=%p\n", self, desc);
342
343 for (i = 0; i < self->num_descs; i++)
344 {
345 if (!self->descs[i])
346 {
347 DC_get_conn(desc) = self;
348 self->descs[i] = desc;
349 return TRUE;
350 }
351 }
352 /* no more room -- allocate more memory */
353 new_num_descs = DESC_INCREMENT + self->num_descs;
354 descs = (DescriptorClass **) realloc(self->descs, sizeof(DescriptorClass *) * new_num_descs);
355 if (!descs)
356 return FALSE;
357 self->descs = descs;
358
359 memset(&self->descs[self->num_descs], 0, sizeof(DescriptorClass *) *
360 DESC_INCREMENT);
361 DC_get_conn(desc) = self;
362 self->descs[self->num_descs] = desc;
363 self->num_descs = new_num_descs;
364
365 return TRUE;
366 }
367
368 /*
369 * This API allocates a Application descriptor.
370 */
371 RETCODE SQL_API
PGAPI_AllocDesc(HDBC ConnectionHandle,SQLHDESC * DescriptorHandle)372 PGAPI_AllocDesc(HDBC ConnectionHandle,
373 SQLHDESC *DescriptorHandle)
374 {
375 CSTR func = "PGAPI_AllocDesc";
376 ConnectionClass *conn = (ConnectionClass *) ConnectionHandle;
377 RETCODE ret = SQL_SUCCESS;
378 DescriptorClass *desc;
379
380 MYLOG(0, "entering...\n");
381
382 desc = (DescriptorClass *) malloc(sizeof(DescriptorClass));
383 if (desc)
384 {
385 memset(desc, 0, sizeof(DescriptorClass));
386 DC_get_conn(desc) = conn;
387 if (CC_add_descriptor(conn, desc))
388 *DescriptorHandle = desc;
389 else
390 {
391 free(desc);
392 CC_set_error(conn, CONN_STMT_ALLOC_ERROR, "Maximum number of descriptors exceeded", func);
393 ret = SQL_ERROR;
394 }
395 }
396 else
397 {
398 CC_set_error(conn, CONN_STMT_ALLOC_ERROR, "No more memory ti allocate a further descriptor", func);
399 ret = SQL_ERROR;
400 }
401 return ret;
402 }
403
404 RETCODE SQL_API
PGAPI_FreeDesc(SQLHDESC DescriptorHandle)405 PGAPI_FreeDesc(SQLHDESC DescriptorHandle)
406 {
407 DescriptorClass *desc = (DescriptorClass *) DescriptorHandle;
408 RETCODE ret = SQL_SUCCESS;
409
410 MYLOG(0, "entering...\n");
411 DC_Destructor(desc);
412 if (!desc->deschd.embedded)
413 {
414 int i;
415 ConnectionClass *conn = DC_get_conn(desc);
416
417 for (i = 0; i < conn->num_descs; i++)
418 {
419 if (conn->descs[i] == desc)
420 {
421 conn->descs[i] = NULL;
422 break;
423 }
424 }
425 free(desc);
426 }
427 return ret;
428 }
429
BindInfoClass_copy(const BindInfoClass * src,BindInfoClass * target)430 static void BindInfoClass_copy(const BindInfoClass *src, BindInfoClass *target)
431 {
432 memcpy(target, src, sizeof(BindInfoClass));
433 }
ARDFields_copy(const ARDFields * src,ARDFields * target)434 static void ARDFields_copy(const ARDFields *src, ARDFields *target)
435 {
436 memcpy(target, src, sizeof(ARDFields));
437 target->bookmark = NULL;
438 if (src->bookmark)
439 {
440 BindInfoClass *bookmark = ARD_AllocBookmark(target);
441 if (bookmark)
442 BindInfoClass_copy(src->bookmark, bookmark);
443 }
444 if (src->allocated <= 0)
445 {
446 target->allocated = 0;
447 target->bindings = NULL;
448 }
449 else
450 {
451 int i;
452
453 target->bindings = malloc(target->allocated * sizeof(BindInfoClass));
454 if (!target->bindings)
455 target->allocated = 0;
456 for (i = 0; i < target->allocated; i++)
457 BindInfoClass_copy(&src->bindings[i], &target->bindings[i]);
458 }
459 }
460
ParameterInfoClass_copy(const ParameterInfoClass * src,ParameterInfoClass * target)461 static void ParameterInfoClass_copy(const ParameterInfoClass *src, ParameterInfoClass *target)
462 {
463 memcpy(target, src, sizeof(ParameterInfoClass));
464 }
APDFields_copy(const APDFields * src,APDFields * target)465 static void APDFields_copy(const APDFields *src, APDFields *target)
466 {
467 memcpy(target, src, sizeof(APDFields));
468 if (src->bookmark)
469 {
470 target->bookmark = malloc(sizeof(ParameterInfoClass));
471 if (target->bookmark)
472 ParameterInfoClass_copy(src->bookmark, target->bookmark);
473 }
474 if (src->allocated <= 0)
475 {
476 target->allocated = 0;
477 target->parameters = NULL;
478 }
479 else
480 {
481 int i;
482
483 target->parameters = malloc(target->allocated * sizeof(ParameterInfoClass));
484 if (!target->parameters)
485 target->allocated = 0;
486 for (i = 0; i < target->allocated; i++)
487 ParameterInfoClass_copy(&src->parameters[i], &target->parameters[i]);
488 }
489 }
490
ParameterImplClass_copy(const ParameterImplClass * src,ParameterImplClass * target)491 static void ParameterImplClass_copy(const ParameterImplClass *src, ParameterImplClass *target)
492 {
493 memcpy(target, src, sizeof(ParameterImplClass));
494 }
IPDFields_copy(const IPDFields * src,IPDFields * target)495 static void IPDFields_copy(const IPDFields *src, IPDFields *target)
496 {
497 memcpy(target, src, sizeof(IPDFields));
498 if (src->allocated <= 0)
499 {
500 target->allocated = 0;
501 target->parameters = NULL;
502 }
503 else
504 {
505 int i;
506
507 target->parameters = (ParameterImplClass *) malloc(target->allocated * sizeof(ParameterImplClass));
508 if (!target->parameters)
509 target->allocated = 0;
510 for (i = 0; i < target->allocated; i++)
511 ParameterImplClass_copy(&src->parameters[i], &target->parameters[i]);
512 }
513 }
514
515 RETCODE SQL_API
PGAPI_CopyDesc(SQLHDESC SourceDescHandle,SQLHDESC TargetDescHandle)516 PGAPI_CopyDesc(SQLHDESC SourceDescHandle,
517 SQLHDESC TargetDescHandle)
518 {
519 RETCODE ret = SQL_ERROR;
520 DescriptorClass *src, *target;
521 DescriptorHeader *srchd, *targethd;
522 ARDFields *ard_src, *ard_tgt;
523 APDFields *apd_src, *apd_tgt;
524 IPDFields *ipd_src, *ipd_tgt;
525
526 MYLOG(0, "entering...\n");
527 src = (DescriptorClass *) SourceDescHandle;
528 target = (DescriptorClass *) TargetDescHandle;
529 srchd = &(src->deschd);
530 targethd = &(target->deschd);
531 if (!srchd->type_defined)
532 {
533 MYLOG(0, "source type undefined\n");
534 DC_set_error(target, DESC_EXEC_ERROR, "source handle type undefined");
535 return ret;
536 }
537 if (targethd->type_defined)
538 {
539 MYLOG(DETAIL_LOG_LEVEL, "source type=%d -> target type=%d\n", srchd->desc_type, targethd->desc_type);
540 if (SQL_ATTR_IMP_ROW_DESC == targethd->desc_type)
541 {
542 MYLOG(0, "can't modify IRD\n");
543 DC_set_error(target, DESC_EXEC_ERROR, "can't copy to IRD");
544 return ret;
545 }
546 else if (targethd->desc_type != srchd->desc_type)
547 {
548 if (targethd->embedded)
549 {
550 MYLOG(0, "src type != target type\n");
551 DC_set_error(target, DESC_EXEC_ERROR, "copying different type descriptor to embedded one");
552 return ret;
553 }
554 }
555 DC_Destructor(target);
556 }
557 ret = SQL_SUCCESS;
558 switch (srchd->desc_type)
559 {
560 case SQL_ATTR_APP_ROW_DESC:
561 MYLOG(DETAIL_LOG_LEVEL, "src=%p target=%p type=%d", src, target, srchd->desc_type);
562 if (!targethd->type_defined)
563 {
564 targethd->desc_type = srchd->desc_type;
565 }
566 ard_src = &(src->ardf);
567 MYPRINTF(DETAIL_LOG_LEVEL, " rowset_size=" FORMAT_LEN " bind_size=" FORMAT_UINTEGER " ope_ptr=%p off_ptr=%p\n",
568 ard_src->size_of_rowset, ard_src->bind_size,
569 ard_src->row_operation_ptr, ard_src->row_offset_ptr);
570 ard_tgt = &(target->ardf);
571 MYPRINTF(DETAIL_LOG_LEVEL, " target=%p", ard_tgt);
572 ARDFields_copy(ard_src, ard_tgt);
573 MYPRINTF(DETAIL_LOG_LEVEL, " offset_ptr=%p\n", ard_tgt->row_offset_ptr);
574 break;
575 case SQL_ATTR_APP_PARAM_DESC:
576 if (!targethd->type_defined)
577 {
578 targethd->desc_type = srchd->desc_type;
579 }
580 apd_src = &(src->apdf);
581 apd_tgt = &(target->apdf);
582 APDFields_copy(apd_src, apd_tgt);
583 break;
584 case SQL_ATTR_IMP_PARAM_DESC:
585 if (!targethd->type_defined)
586 {
587 targethd->desc_type = srchd->desc_type;
588 }
589 ipd_src = &(src->ipdf);
590 ipd_tgt = &(target->ipdf);
591 IPDFields_copy(ipd_src, ipd_tgt);
592 break;
593 default:
594 MYLOG(0, "invalid descriptor handle type=%d\n", srchd->desc_type);
595 DC_set_error(target, DESC_EXEC_ERROR, "invalid descriptor type");
596 ret = SQL_ERROR;
597 }
598
599 if (SQL_SUCCESS == ret)
600 targethd->type_defined = TRUE;
601 return ret;
602 }
603
DC_clear_error(DescriptorClass * self)604 void DC_clear_error(DescriptorClass *self)
605 {
606 DescriptorHeader *deschd = &(self->deschd);
607 if (deschd->__error_message)
608 {
609 free(deschd->__error_message);
610 deschd->__error_message = NULL;
611 }
612 if (deschd->pgerror)
613 {
614 ER_Destructor(deschd->pgerror);
615 deschd->pgerror = NULL;
616 }
617 deschd->__error_number = 0;
618 deschd->error_row = 0;
619 deschd->error_index = 0;
620 }
621
DC_set_error(DescriptorClass * self,int errornumber,const char * errormsg)622 void DC_set_error(DescriptorClass *self, int errornumber, const char *errormsg)
623 {
624 DescriptorHeader *deschd = &(self->deschd);
625 if (deschd->__error_message)
626 free(deschd->__error_message);
627 deschd->__error_number = errornumber;
628 deschd->__error_message = errormsg ? strdup(errormsg) : NULL;
629 }
DC_set_errormsg(DescriptorClass * self,const char * errormsg)630 void DC_set_errormsg(DescriptorClass *self, const char *errormsg)
631 {
632 DescriptorHeader *deschd = &(self->deschd);
633 if (deschd->__error_message)
634 free(deschd->__error_message);
635 deschd->__error_message = errormsg ? strdup(errormsg) : NULL;
636 }
DC_get_errormsg(const DescriptorClass * desc)637 const char *DC_get_errormsg(const DescriptorClass *desc)
638 {
639 return desc->deschd.__error_message;
640 }
DC_get_errornumber(const DescriptorClass * desc)641 int DC_get_errornumber(const DescriptorClass *desc)
642 {
643 return desc->deschd.__error_number;
644 }
645
646 /* Map sql commands to statement types */
647 static const struct
648 {
649 int number;
650 const char ver3str[6];
651 const char ver2str[6];
652 } Descriptor_sqlstate[] =
653
654 {
655 { DESC_ERROR_IN_ROW, "01S01", "01S01" },
656 { DESC_OPTION_VALUE_CHANGED, "01S02", "01S02" },
657 { DESC_OK, "00000", "00000" }, /* OK */
658 { DESC_EXEC_ERROR, "HY000", "S1000" }, /* also a general error */
659 { DESC_STATUS_ERROR, "HY010", "S1010" },
660 { DESC_SEQUENCE_ERROR, "HY010", "S1010" }, /* Function sequence error */
661 { DESC_NO_MEMORY_ERROR, "HY001", "S1001" }, /* memory allocation failure */
662 { DESC_COLNUM_ERROR, "07009", "S1002" }, /* invalid column number */
663 { DESC_NO_STMTSTRING, "HY001", "S1001" }, /* having no stmtstring is also a malloc problem */
664 { DESC_ERROR_TAKEN_FROM_BACKEND, "HY000", "S1000" }, /* general error */
665 { DESC_INTERNAL_ERROR, "HY000", "S1000" }, /* general error */
666 { DESC_STILL_EXECUTING, "HY010", "S1010" },
667 { DESC_NOT_IMPLEMENTED_ERROR, "HYC00", "S1C00" }, /* == 'driver not
668 * capable' */
669 { DESC_BAD_PARAMETER_NUMBER_ERROR, "07009", "S1093" },
670 { DESC_OPTION_OUT_OF_RANGE_ERROR, "HY092", "S1092" },
671 { DESC_INVALID_COLUMN_NUMBER_ERROR, "07009", "S1002" },
672 { DESC_RESTRICTED_DATA_TYPE_ERROR, "07006", "07006" },
673 { DESC_INVALID_CURSOR_STATE_ERROR, "07005", "24000" },
674 { DESC_CREATE_TABLE_ERROR, "42S01", "S0001" }, /* table already exists */
675 { DESC_NO_CURSOR_NAME, "S1015", "S1015" },
676 { DESC_INVALID_CURSOR_NAME, "34000", "34000" },
677 { DESC_INVALID_ARGUMENT_NO, "HY024", "S1009" }, /* invalid argument value */
678 { DESC_ROW_OUT_OF_RANGE, "HY107", "S1107" },
679 { DESC_OPERATION_CANCELLED, "HY008", "S1008" },
680 { DESC_INVALID_CURSOR_POSITION, "HY109", "S1109" },
681 { DESC_VALUE_OUT_OF_RANGE, "HY019", "22003" },
682 { DESC_OPERATION_INVALID, "HY011", "S1011" },
683 { DESC_PROGRAM_TYPE_OUT_OF_RANGE, "?????", "?????" },
684 { DESC_BAD_ERROR, "08S01", "08S01" }, /* communication link failure */
685 { DESC_INVALID_OPTION_IDENTIFIER, "HY092", "HY092" },
686 { DESC_RETURN_NULL_WITHOUT_INDICATOR, "22002", "22002" },
687 { DESC_INVALID_DESCRIPTOR_IDENTIFIER, "HY091", "HY091" },
688 { DESC_OPTION_NOT_FOR_THE_DRIVER, "HYC00", "HYC00" },
689 { DESC_FETCH_OUT_OF_RANGE, "HY106", "S1106" },
690 { DESC_COUNT_FIELD_INCORRECT, "07002", "07002" },
691 };
692
DC_create_errorinfo(const DescriptorClass * self)693 static PG_ErrorInfo *DC_create_errorinfo(const DescriptorClass *self)
694 {
695 const DescriptorHeader *deschd = &(self->deschd);
696 PG_ErrorInfo *error;
697 ConnectionClass *conn;
698 EnvironmentClass *env;
699 Int4 errornum;
700 BOOL env_is_odbc3 = TRUE;
701
702 if (deschd->pgerror)
703 return deschd->pgerror;
704 errornum = deschd->__error_number;
705 error = ER_Constructor(errornum, deschd->__error_message);
706 if (!error)
707 return error;
708 conn = DC_get_conn(self);
709 if (conn && (env = (EnvironmentClass *) conn->henv))
710 env_is_odbc3 = EN_is_odbc3(env);
711 errornum -= LOWEST_DESC_ERROR;
712 if (errornum < 0 ||
713 errornum >= sizeof(Descriptor_sqlstate) / sizeof(Descriptor_sqlstate[0]))
714 errornum = 1 - LOWEST_DESC_ERROR;
715 STRCPY_FIXED(error->sqlstate, env_is_odbc3 ? Descriptor_sqlstate[errornum].ver3str : Descriptor_sqlstate[errornum].ver2str);
716 return error;
717 }
718 void
DC_log_error(const char * func,const char * desc,const DescriptorClass * self)719 DC_log_error(const char *func, const char *desc, const DescriptorClass *self)
720 {
721 #define nullcheck(a) (a ? a : "(NULL)")
722 if (self)
723 {
724 MYLOG(0, "DESCRIPTOR ERROR: func=%s, desc='%s', errnum=%d, errmsg='%s'\n", func, desc, self->deschd.__error_number, nullcheck(self->deschd.__error_message));
725 }
726 }
727
728 /* Returns the next SQL error information. */
729 RETCODE SQL_API
PGAPI_DescError(SQLHDESC hdesc,SQLSMALLINT RecNumber,SQLCHAR * szSqlState,SQLINTEGER * pfNativeError,SQLCHAR * szErrorMsg,SQLSMALLINT cbErrorMsgMax,SQLSMALLINT * pcbErrorMsg,UWORD flag)730 PGAPI_DescError(SQLHDESC hdesc,
731 SQLSMALLINT RecNumber,
732 SQLCHAR * szSqlState,
733 SQLINTEGER * pfNativeError,
734 SQLCHAR * szErrorMsg,
735 SQLSMALLINT cbErrorMsgMax,
736 SQLSMALLINT * pcbErrorMsg,
737 UWORD flag)
738 {
739 /* CC: return an error of a hdesc */
740 DescriptorClass *desc = (DescriptorClass *) hdesc;
741 DescriptorHeader *deschd = &(desc->deschd);
742
743 MYLOG(0, "entering RecN=%hd\n", RecNumber);
744 deschd->pgerror = DC_create_errorinfo(desc);
745 return ER_ReturnError(deschd->pgerror, RecNumber, szSqlState,
746 pfNativeError, szErrorMsg, cbErrorMsgMax,
747 pcbErrorMsg, flag);
748 }
749