Skip to content

Commit 90326c0

Browse files
author
Michael Meskes
committed
Added SET DESCRIPTOR command.
Note that this still has some bugs. The functionality is there though, it's just a matter of fixing the bugs now. Cleaned up error handling in preprocessor.
1 parent c7beffc commit 90326c0

File tree

11 files changed

+682
-287
lines changed

11 files changed

+682
-287
lines changed

src/interfaces/ecpg/ecpglib/descriptor.c

Lines changed: 165 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* dynamic SQL support routines
22
*
3-
* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.7 2003/11/29 19:52:08 pgsql Exp $
3+
* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.8 2004/06/30 15:01:56 meskes Exp $
44
*/
55

66
#define POSTGRES_ECPG_INTERNAL
@@ -110,6 +110,51 @@ get_int_item(int lineno, void *var, enum ECPGttype vartype, int value)
110110
return (true);
111111
}
112112

113+
static bool
114+
set_int_item(int lineno, int *target, const void *var, enum ECPGttype vartype)
115+
{
116+
switch (vartype)
117+
{
118+
case ECPGt_short:
119+
*target = *(short *) var;
120+
break;
121+
case ECPGt_int:
122+
*target = *(int *) var;
123+
break;
124+
case ECPGt_long:
125+
*target = *(long *) var;
126+
break;
127+
case ECPGt_unsigned_short:
128+
*target = *(unsigned short *) var;
129+
break;
130+
case ECPGt_unsigned_int:
131+
*target = *(unsigned int *) var;
132+
break;
133+
case ECPGt_unsigned_long:
134+
*target = *(unsigned long *) var;
135+
break;
136+
#ifdef HAVE_LONG_LONG_INT_64
137+
case ECPGt_long_long:
138+
*target = *(long long int *) var;
139+
break;
140+
case ECPGt_unsigned_long_long:
141+
*target = *(unsigned long long int *) var;
142+
break;
143+
#endif /* HAVE_LONG_LONG_INT_64 */
144+
case ECPGt_float:
145+
*target = *(float *) var;
146+
break;
147+
case ECPGt_double:
148+
*target = *(double *) var;
149+
break;
150+
default:
151+
ECPGraise(lineno, ECPG_VAR_NOT_NUMERIC, ECPG_SQLSTATE_RESTRICTED_DATA_TYPE_ATTRIBUTE_VIOLATION, NULL);
152+
return (false);
153+
}
154+
155+
return true;
156+
}
157+
113158
static bool
114159
get_char_item(int lineno, void *var, enum ECPGttype vartype, char *value, int varcharsize)
115160
{
@@ -385,6 +430,124 @@ ECPGget_desc(int lineno, char *desc_name, int index,...)
385430
return (true);
386431
}
387432

433+
bool
434+
ECPGset_desc(int lineno, char *desc_name, int index,...)
435+
{
436+
va_list args;
437+
struct descriptor *desc;
438+
struct descriptor_item *desc_item, *last_di;
439+
440+
for (desc = all_descriptors; desc; desc = desc->next)
441+
{
442+
if (strcmp(desc_name, desc->name)==0)
443+
break;
444+
}
445+
446+
if (desc == NULL)
447+
{
448+
ECPGraise(lineno, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, desc_name);
449+
return false;
450+
}
451+
452+
for (desc_item = desc->items; desc_item; desc_item = desc_item->next)
453+
{
454+
if (desc_item->num == index)
455+
break;
456+
}
457+
458+
if (desc_item == NULL)
459+
{
460+
desc_item = ECPGalloc(sizeof(*desc_item), lineno);
461+
desc_item->num = index;
462+
desc_item->next = desc->items;
463+
desc->items = desc_item;
464+
}
465+
466+
va_start(args, index);
467+
468+
do
469+
{
470+
enum ECPGdtype itemtype;
471+
long varcharsize;
472+
long offset;
473+
long arrsize;
474+
enum ECPGttype vartype;
475+
void *var;
476+
477+
itemtype = va_arg(args, enum ECPGdtype);
478+
479+
if (itemtype == ECPGd_EODT)
480+
break;
481+
482+
vartype = va_arg(args, enum ECPGttype);
483+
var = va_arg(args, void *);
484+
varcharsize = va_arg(args, long);
485+
arrsize = va_arg(args, long);
486+
offset = va_arg(args, long);
487+
488+
switch (itemtype)
489+
{
490+
case ECPGd_data:
491+
{
492+
// FIXME: how to do this in general?
493+
switch (vartype)
494+
{
495+
case ECPGt_char:
496+
desc_item->data = strdup((char *)var);
497+
break;
498+
case ECPGt_int:
499+
{
500+
char buf[20];
501+
snprintf(buf, 20, "%d", *(int *)var);
502+
desc_item->data = strdup(buf);
503+
break;
504+
}
505+
default:
506+
abort();
507+
}
508+
break;
509+
}
510+
511+
case ECPGd_indicator:
512+
set_int_item(lineno, &desc_item->indicator, var, vartype);
513+
break;
514+
515+
case ECPGd_length:
516+
set_int_item(lineno, &desc_item->length, var, vartype);
517+
break;
518+
519+
case ECPGd_precision:
520+
set_int_item(lineno, &desc_item->precision, var, vartype);
521+
break;
522+
523+
case ECPGd_scale:
524+
set_int_item(lineno, &desc_item->scale, var, vartype);
525+
break;
526+
527+
case ECPGd_type:
528+
set_int_item(lineno, &desc_item->type, var, vartype);
529+
break;
530+
531+
default:
532+
{
533+
char type_str[20];
534+
snprintf(type_str, sizeof(type_str), "%d", itemtype);
535+
ECPGraise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, ECPG_SQLSTATE_ECPG_INTERNAL_ERROR, type_str);
536+
return false;
537+
}
538+
}
539+
540+
/*if (itemtype == ECPGd_data)
541+
{
542+
free(desc_item->data);
543+
desc_item->data = NULL;
544+
}*/
545+
}
546+
while (true);
547+
548+
return true;
549+
}
550+
388551
bool
389552
ECPGdeallocate_desc(int line, const char *name)
390553
{
@@ -425,6 +588,7 @@ ECPGallocate_desc(int line, const char *name)
425588
ECPGfree(new);
426589
return false;
427590
}
591+
new->items = NULL;
428592
new->result = PQmakeEmptyPGresult(NULL, 0);
429593
if (!new->result)
430594
{

src/interfaces/ecpg/ecpglib/execute.c

Lines changed: 101 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.34 2004/06/27 12:28:40 meskes Exp $ */
1+
/* $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/execute.c,v 1.35 2004/06/30 15:01:56 meskes Exp $ */
22

33
/*
44
* The aim is to get a simpler inteface to the database routines.
@@ -1026,6 +1026,9 @@ ECPGstore_input(const struct statement * stmt, const struct variable * var,
10261026
free(str);
10271027
}
10281028
break;
1029+
1030+
case ECPGt_descriptor:
1031+
break;
10291032

10301033
default:
10311034
/* Not implemented yet */
@@ -1046,6 +1049,7 @@ ECPGexecute(struct statement * stmt)
10461049
PGresult *results;
10471050
PGnotify *notify;
10481051
struct variable *var;
1052+
int desc_counter = 0;
10491053

10501054
copiedquery = ECPGstrdup(stmt->command, stmt->lineno);
10511055

@@ -1056,64 +1060,116 @@ ECPGexecute(struct statement * stmt)
10561060
* so on.
10571061
*/
10581062
var = stmt->inlist;
1063+
10591064
while (var)
10601065
{
10611066
char *newcopy = NULL;
1062-
const char *tobeinserted = NULL;
1067+
const char *tobeinserted;
10631068
char *p;
1064-
bool malloced = FALSE;
1065-
int hostvarl = 0;
1066-
1067-
if (!ECPGstore_input(stmt, var, &tobeinserted, &malloced))
1068-
return false;
1069+
bool malloced = FALSE;
1070+
int hostvarl = 0;
10691071

1070-
/*
1071-
* Now tobeinserted points to an area that is to be inserted at
1072-
* the first %s
1073-
*/
1074-
if (!(newcopy = (char *) ECPGalloc(strlen(copiedquery) + strlen(tobeinserted) + 1, stmt->lineno)))
1075-
return false;
1076-
1077-
strcpy(newcopy, copiedquery);
1078-
if ((p = next_insert(newcopy + hostvarl)) == NULL)
1072+
tobeinserted = NULL;
1073+
/* A descriptor is a special case since it contains many variables but is listed only once. */
1074+
if (var->type == ECPGt_descriptor)
10791075
{
1080-
/*
1081-
* We have an argument but we dont have the matched up string
1082-
* in the string
1083-
*/
1084-
ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL);
1085-
return false;
1076+
/* We create an additional variable list here, so the same logic applies. */
1077+
struct variable desc_inlist;
1078+
struct descriptor *desc;
1079+
struct descriptor_item *desc_item;
1080+
for (desc = all_descriptors; desc; desc = desc->next)
1081+
{
1082+
if (strcmp(var->pointer, desc->name) == 0)
1083+
break;
1084+
}
1085+
1086+
if (desc == NULL)
1087+
{
1088+
ECPGraise(stmt->lineno, ECPG_UNKNOWN_DESCRIPTOR, ECPG_SQLSTATE_INVALID_SQL_DESCRIPTOR_NAME, var->pointer);
1089+
return false;
1090+
}
1091+
1092+
desc_counter++;
1093+
for (desc_item = desc->items; desc_item; desc_item = desc_item->next)
1094+
{
1095+
if (desc_item->num == desc_counter)
1096+
{
1097+
desc_inlist.type = ECPGt_char;
1098+
desc_inlist.value = desc_item->data;
1099+
desc_inlist.pointer = &(desc_item->data);
1100+
desc_inlist.varcharsize = strlen(desc_item->data);
1101+
desc_inlist.arrsize = 1;
1102+
desc_inlist.offset = 0;
1103+
desc_inlist.ind_type = ECPGt_NO_INDICATOR;
1104+
desc_inlist.ind_value = desc_inlist.ind_pointer = NULL;
1105+
desc_inlist.ind_varcharsize = desc_inlist.ind_arrsize = desc_inlist.ind_offset = 0;
1106+
1107+
if (!ECPGstore_input(stmt, &desc_inlist, &tobeinserted, &malloced))
1108+
return false;
1109+
1110+
break;
1111+
}
1112+
}
1113+
1114+
if (!desc_item) /* no more entries found in descriptor */
1115+
desc_counter = 0;
10861116
}
10871117
else
10881118
{
1089-
strcpy(p, tobeinserted);
1090-
hostvarl = strlen(newcopy);
1091-
1119+
if (!ECPGstore_input(stmt, var, &tobeinserted, &malloced))
1120+
return false;
1121+
}
1122+
if (tobeinserted)
1123+
{
10921124
/*
1093-
* The strange thing in the second argument is the rest of the
1094-
* string from the old string
1125+
* Now tobeinserted points to an area that is to be inserted at
1126+
* the first %s
10951127
*/
1096-
strcat(newcopy,
1097-
copiedquery
1098-
+ (p - newcopy)
1099-
+ sizeof("?") - 1 /* don't count the '\0' */ );
1100-
}
1128+
if (!(newcopy = (char *) ECPGalloc(strlen(copiedquery) + strlen(tobeinserted) + 1, stmt->lineno)))
1129+
return false;
11011130

1102-
/*
1103-
* Now everything is safely copied to the newcopy. Lets free the
1104-
* oldcopy and let the copiedquery get the var->value from the
1105-
* newcopy.
1106-
*/
1107-
if (malloced)
1108-
{
1109-
ECPGfree((char *) tobeinserted);
1110-
tobeinserted = NULL;
1111-
}
1131+
strcpy(newcopy, copiedquery);
1132+
if ((p = next_insert(newcopy + hostvarl)) == NULL)
1133+
{
1134+
/*
1135+
* We have an argument but we dont have the matched up string
1136+
* in the string
1137+
*/
1138+
ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, ECPG_SQLSTATE_USING_CLAUSE_DOES_NOT_MATCH_PARAMETERS, NULL);
1139+
return false;
1140+
}
1141+
else
1142+
{
1143+
strcpy(p, tobeinserted);
1144+
hostvarl = strlen(newcopy);
1145+
1146+
/*
1147+
* The strange thing in the second argument is the rest of the
1148+
* string from the old string
1149+
*/
1150+
strcat(newcopy,
1151+
copiedquery
1152+
+ (p - newcopy)
1153+
+ sizeof("?") - 1 /* don't count the '\0' */ );
1154+
}
11121155

1113-
ECPGfree(copiedquery);
1114-
copiedquery = newcopy;
1156+
/*
1157+
* Now everything is safely copied to the newcopy. Lets free the
1158+
* oldcopy and let the copiedquery get the var->value from the
1159+
* newcopy.
1160+
*/
1161+
if (malloced)
1162+
{
1163+
ECPGfree((char *) tobeinserted);
1164+
tobeinserted = NULL;
1165+
}
11151166

1116-
var = var->next;
1167+
ECPGfree(copiedquery);
1168+
copiedquery = newcopy;
1169+
}
1170+
1171+
if (desc_counter == 0)
1172+
var = var->next;
11171173
}
11181174

11191175
/* Check if there are unmatched things left. */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy