Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit90326c0

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 parentc7beffc commit90326c0

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
#definePOSTGRES_ECPG_INTERNAL
@@ -110,6 +110,51 @@ get_int_item(int lineno, void *var, enum ECPGttype vartype, int value)
110110
return (true);
111111
}
112112

113+
staticbool
114+
set_int_item(intlineno,int*target,constvoid*var,enumECPGttypevartype)
115+
{
116+
switch (vartype)
117+
{
118+
caseECPGt_short:
119+
*target=*(short*)var;
120+
break;
121+
caseECPGt_int:
122+
*target=*(int*)var;
123+
break;
124+
caseECPGt_long:
125+
*target=*(long*)var;
126+
break;
127+
caseECPGt_unsigned_short:
128+
*target=*(unsigned short*)var;
129+
break;
130+
caseECPGt_unsigned_int:
131+
*target=*(unsignedint*)var;
132+
break;
133+
caseECPGt_unsigned_long:
134+
*target=*(unsigned long*)var;
135+
break;
136+
#ifdefHAVE_LONG_LONG_INT_64
137+
caseECPGt_long_long:
138+
*target=*(long longint*)var;
139+
break;
140+
caseECPGt_unsigned_long_long:
141+
*target=*(unsigned long longint*)var;
142+
break;
143+
#endif/* HAVE_LONG_LONG_INT_64 */
144+
caseECPGt_float:
145+
*target=*(float*)var;
146+
break;
147+
caseECPGt_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
staticbool
114159
get_char_item(intlineno,void*var,enumECPGttypevartype,char*value,intvarcharsize)
115160
{
@@ -385,6 +430,124 @@ ECPGget_desc(int lineno, char *desc_name, int index,...)
385430
return (true);
386431
}
387432

433+
bool
434+
ECPGset_desc(intlineno,char*desc_name,intindex,...)
435+
{
436+
va_listargs;
437+
structdescriptor*desc;
438+
structdescriptor_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+
enumECPGdtypeitemtype;
471+
longvarcharsize;
472+
longoffset;
473+
longarrsize;
474+
enumECPGttypevartype;
475+
void*var;
476+
477+
itemtype=va_arg(args,enumECPGdtype);
478+
479+
if (itemtype==ECPGd_EODT)
480+
break;
481+
482+
vartype=va_arg(args,enumECPGttype);
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+
caseECPGd_data:
491+
{
492+
// FIXME: how to do this in general?
493+
switch (vartype)
494+
{
495+
caseECPGt_char:
496+
desc_item->data=strdup((char*)var);
497+
break;
498+
caseECPGt_int:
499+
{
500+
charbuf[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+
caseECPGd_indicator:
512+
set_int_item(lineno,&desc_item->indicator,var,vartype);
513+
break;
514+
515+
caseECPGd_length:
516+
set_int_item(lineno,&desc_item->length,var,vartype);
517+
break;
518+
519+
caseECPGd_precision:
520+
set_int_item(lineno,&desc_item->precision,var,vartype);
521+
break;
522+
523+
caseECPGd_scale:
524+
set_int_item(lineno,&desc_item->scale,var,vartype);
525+
break;
526+
527+
caseECPGd_type:
528+
set_int_item(lineno,&desc_item->type,var,vartype);
529+
break;
530+
531+
default:
532+
{
533+
chartype_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(intline,constchar*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+
caseECPGt_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
structvariable*var;
1052+
intdesc_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-
constchar*tobeinserted=NULL;
1067+
constchar*tobeinserted;
10631068
char*p;
1064-
boolmalloced= FALSE;
1065-
inthostvarl=0;
1066-
1067-
if (!ECPGstore_input(stmt,var,&tobeinserted,&malloced))
1068-
return false;
1069+
boolmalloced= FALSE;
1070+
inthostvarl=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+
structvariabledesc_inlist;
1078+
structdescriptor*desc;
1079+
structdescriptor_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 isthe rest of the
1094-
*string fromtheold string
1125+
*Now tobeinserted points to an area that isto be inserted at
1126+
* thefirst %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)

[8]ページ先頭

©2009-2025 Movatter.jp