diff options
author | Michael Meskes <meskes@postgresql.org> | 2000-02-22 19:57:12 +0000 |
---|---|---|
committer | Michael Meskes <meskes@postgresql.org> | 2000-02-22 19:57:12 +0000 |
commit | 991b9740acc80bb00778fe2fb2199c5e6130046e (patch) | |
tree | 08774826d9869a5558f7b147e46580b9cc53b4fb /src | |
parent | 62f064592f2adab546848b5f3328ac12f17b8bbd (diff) | |
download | postgresql-991b9740acc80bb00778fe2fb2199c5e6130046e.tar.gz postgresql-991b9740acc80bb00778fe2fb2199c5e6130046e.zip |
*** empty log message ***
Diffstat (limited to 'src')
21 files changed, 623 insertions, 333 deletions
diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog index d733e9e0df0..b9384070be7 100644 --- a/src/interfaces/ecpg/ChangeLog +++ b/src/interfaces/ecpg/ChangeLog @@ -819,5 +819,10 @@ Thu Feb 17 19:37:44 CET 2000 - Synced preproc.y with gram.y. - Started to clean up preproc.y. + +Tue Feb 22 13:48:18 CET 2000 + + - Synced preproc.y with gram.y. + - Much more clean ups. - Set library version to 3.1.0. - Set ecpg version to 2.7.0. diff --git a/src/interfaces/ecpg/TODO b/src/interfaces/ecpg/TODO index d7546c7925e..84edb5a2b55 100644 --- a/src/interfaces/ecpg/TODO +++ b/src/interfaces/ecpg/TODO @@ -28,6 +28,8 @@ instead of libpq so we can write backend functions using ecpg. make ECPGnumeric_lvalue more accurate by using something like ECPGdump_a_* +remove space_or_nl and line_end from pgc.l + Missing statements: - exec sql ifdef - SQLSTATE diff --git a/src/interfaces/ecpg/include/ecpgerrno.h b/src/interfaces/ecpg/include/ecpgerrno.h index 429703a29ca..2bc59f4b785 100644 --- a/src/interfaces/ecpg/include/ecpgerrno.h +++ b/src/interfaces/ecpg/include/ecpgerrno.h @@ -32,6 +32,8 @@ /* dynamic SQL related */ #define ECPG_UNKNOWN_DESCRIPTOR -240 #define ECPG_INVALID_DESCRIPTOR_INDEX -241 +#define ECPG_UNKNOWN_DESCRIPTOR_ITEM -242 +#define ECPG_VAR_NOT_NUMERIC -243 /* finally the backend error messages, they start at 400 */ #define ECPG_PGSQL -400 diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h index 3cb3255c4a8..0617412a1e9 100644 --- a/src/interfaces/ecpg/include/ecpglib.h +++ b/src/interfaces/ecpg/include/ecpglib.h @@ -61,6 +61,7 @@ extern "C" bool ECPGallocate_desc(int line,const char *name); void ECPGraise(int line, int code, const char *str); bool ECPGget_desc_header(int, char *, int *); + bool ECPGget_desc(int, char *, int, ...); #ifdef __cplusplus diff --git a/src/interfaces/ecpg/include/ecpgtype.h b/src/interfaces/ecpg/include/ecpgtype.h index 443d2cb04ec..f766d374f1b 100644 --- a/src/interfaces/ecpg/include/ecpgtype.h +++ b/src/interfaces/ecpg/include/ecpgtype.h @@ -49,6 +49,26 @@ extern "C" ECPGt_EORT, /* End of result types. */ ECPGt_NO_INDICATOR /* no indicator */ }; + + enum ECPGdtype + { + ECPGd_count, + ECPGd_data, + ECPGd_di_code, + ECPGd_di_precision, + ECPGd_indicator, + ECPGd_key_member, + ECPGd_length, + ECPGd_name, + ECPGd_nullable, + ECPGd_octet, + ECPGd_precision, + ECPGd_ret_length, + ECPGd_ret_octet, + ECPGd_scale, + ECPGd_type, + ECPGd_EODT, /* End of descriptor types. */ + }; #define IS_SIMPLE_TYPE(type) ((type) >= ECPGt_char && (type) <= ECPGt_varchar2) diff --git a/src/interfaces/ecpg/lib/Makefile.in b/src/interfaces/ecpg/lib/Makefile.in index 947f9fd1a96..eee0d03ba44 100644 --- a/src/interfaces/ecpg/lib/Makefile.in +++ b/src/interfaces/ecpg/lib/Makefile.in @@ -6,7 +6,7 @@ # Copyright (c) 1994, Regents of the University of California # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile.in,v 1.58 2000/02/16 16:18:05 meskes Exp $ +# $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/Makefile.in,v 1.59 2000/02/22 19:57:05 meskes Exp $ # #------------------------------------------------------------------------- @@ -23,7 +23,7 @@ ifdef KRBVERS CFLAGS+= $(KRBFLAGS) endif -OBJS= ecpglib.o typename.o +OBJS= ecpglib.o typename.o descriptor.o SHLIB_LINK= -L../../libpq -lpq diff --git a/src/interfaces/ecpg/lib/descriptor.c b/src/interfaces/ecpg/lib/descriptor.c index 09815b2d103..8169f1d2f2b 100644 --- a/src/interfaces/ecpg/lib/descriptor.c +++ b/src/interfaces/ecpg/lib/descriptor.c @@ -10,6 +10,157 @@ ECPGget_desc_header(int lineno, char * desc_name, int *count) return false; *count = PQnfields(ECPGresult); - ECPGlog("ECPGget-desc_header: found %d sttributes.\n", *count); + ECPGlog("ECPGget_desc_header: found %d attributes.\n", *count); return true; } + +static bool +get_int_item(int lineno, void *var, enum ECPGdtype vartype, int value) +{ + switch (vartype) + { + case ECPGt_short: + *(short *)var = value; + break; + case ECPGt_int: + *(int *)var = value; + break; + case ECPGt_long: + *(long *)var = value; + break; + case ECPGt_unsigned_short: + *(unsigned short *)var = value; + break; + case ECPGt_unsigned_int: + *(unsigned int *)var = value; + break; + case ECPGt_unsigned_long: + *(unsigned long *)var = value; + break; + case ECPGt_float: + *(float *)var = value; + break; + case ECPGt_double: + *(double *)var = value; + break; + default: + ECPGraise(lineno, ECPG_VAR_NOT_NUMERIC, NULL); + return (false); + } + + return(true); +} + +bool +ECPGget_desc(int lineno, char *desc_name, int index, ...) +{ + va_list args; + PGresult *ECPGresult = ECPGresultByDescriptor(lineno, desc_name); + enum ECPGdtype type; + bool DataButNoIndicator = false; + + va_start(args, index); + if (!ECPGresult) + return (false); + + if (PQntuples(ECPGresult) < 1) + { + ECPGraise(lineno, ECPG_NOT_FOUND, NULL); + return (false); + } + + if (index < 1 || index >PQnfields(ECPGresult)) + { + ECPGraise(lineno, ECPG_INVALID_DESCRIPTOR_INDEX, NULL); + return (false); + } + + ECPGlog("ECPGget_desc: reading items for tuple %d\n", index); + --index; + + type = va_arg(args, enum ECPGdtype); + + while (type != ECPGd_EODT) + { + char type_str[20]; + long varcharsize; + long offset; + long arrsize; + enum ECPGttype vartype; + void *var; + + vartype = va_arg(args, enum ECPGttype); + var = va_arg(args, void *); + varcharsize = va_arg(args, long); + arrsize = va_arg(args, long); + offset = va_arg(args, long); + + switch (type) + { + case (ECPGd_indicator): + if (!get_int_item(lineno, var, vartype, -PQgetisnull(ECPGresult, 0, index))) + return (false); + break; + + case ECPGd_name: + strncpy((char *)var, PQfname(ECPGresult, index), varcharsize); + break; + + case ECPGd_nullable: + if (!get_int_item(lineno, var, vartype, 1)) + return (false); + break; + + case ECPGd_key_member: + if (!get_int_item(lineno, var, vartype, 0)) + return (false); + break; + + case ECPGd_scale: + if (!get_int_item(lineno, var, vartype, (PQfmod(ECPGresult, index) - VARHDRSZ) & 0xffff)) + return (false); + break; + + case ECPGd_precision: + if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) >> 16)) + return (false); + break; + + case ECPGd_ret_length: + case ECPGd_ret_octet: + if (!get_int_item(lineno, var, vartype, PQgetlength(ECPGresult, 0, index))) + return (false); + break; + + case ECPGd_octet: + if (!get_int_item(lineno, var, vartype, PQfsize(ECPGresult, index))) + return (false); + break; + + case ECPGd_length: + if (!get_int_item(lineno, var, vartype, PQfmod(ECPGresult, index) - VARHDRSZ)) + return (false); + break; + + case ECPGd_type: + if (!get_int_item(lineno, var, vartype, ECPGDynamicType(PQftype(ECPGresult, index)))) + return (false); + break; + + default: + snprintf(type_str, sizeof(type_str), "%d", type); + ECPGraise(lineno, ECPG_UNKNOWN_DESCRIPTOR_ITEM, type_str); + return(false); + } + + type = va_arg(args, enum ECPGdtype); + } + + if (DataButNoIndicator && PQgetisnull(ECPGresult, 0, index)) + { + ECPGraise(lineno, ECPG_MISSING_INDICATOR, NULL); + return (false); + } + + return (true); +} diff --git a/src/interfaces/ecpg/lib/dynamic.c b/src/interfaces/ecpg/lib/dynamic.c index fb2f28e69c5..12aac32a458 100644 --- a/src/interfaces/ecpg/lib/dynamic.c +++ b/src/interfaces/ecpg/lib/dynamic.c @@ -2,7 +2,7 @@ * * Copyright (c) 2000, Christof Petig <christof.petig@wtal.de> * - * $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/dynamic.c,v 1.4 2000/02/18 16:02:49 meskes Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/ecpg/lib/Attic/dynamic.c,v 1.5 2000/02/22 19:57:05 meskes Exp $ */ /* I borrowed the include files from ecpglib.c, maybe we don't need all of them */ @@ -198,7 +198,7 @@ bool ECPGdo_descriptor(int line,const char *connection, /* free previous result */ if (i->result) PQclear(i->result); - i->result=NULL; + i->result=NULL; status=do_descriptor2(line,connection,&i->result,query); @@ -206,7 +206,8 @@ bool ECPGdo_descriptor(int line,const char *connection, return (status); } } - ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, NULL); + + ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, descriptor); return false; } @@ -219,7 +220,7 @@ PGresult *ECPGresultByDescriptor(int line,const char *name) if (!strcmp(name, i->name)) return i->result; } - ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, NULL); + ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, name); return NULL; } @@ -238,7 +239,7 @@ bool ECPGdeallocate_desc(int line,const char *name) return true; } } - ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, NULL); + ECPGraise(line, ECPG_UNKNOWN_DESCRIPTOR, name); return false; } @@ -259,7 +260,7 @@ ECPGraise(int line, int code, const char *str) { struct auto_mem *am; - sqlca.sqlcode=code; + sqlca.sqlcode = code; switch (code) { case ECPG_NOT_FOUND: @@ -294,15 +295,25 @@ ECPGraise(int line, int code, const char *str) case ECPG_UNKNOWN_DESCRIPTOR: snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc), - "descriptor not found, line %d.", line); + "descriptor %s not found, line %d.", str, line); break; case ECPG_INVALID_DESCRIPTOR_INDEX: snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc), "descriptor index out of range, line %d.", line); break; + + case ECPG_UNKNOWN_DESCRIPTOR_ITEM: + snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc), + "unknown descriptor item %s, line %d.", str, line); + break; + + case ECPG_VAR_NOT_NUMERIC: + snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc), + "variable is not a numeric type, line %d.", line); + break; - default: + default: snprintf(sqlca.sqlerrm.sqlerrmc,sizeof(sqlca.sqlerrm.sqlerrmc), "SQL error #%d, line %d.",code, line); break; diff --git a/src/interfaces/ecpg/lib/ecpglib.c b/src/interfaces/ecpg/lib/ecpglib.c index 72c38e48a18..afdf93bda24 100644 --- a/src/interfaces/ecpg/lib/ecpglib.c +++ b/src/interfaces/ecpg/lib/ecpglib.c @@ -190,7 +190,7 @@ ecpg_alloc(long size, int lineno) if (!new) { ECPGlog("out of memory\n"); - ECPGraise(ECPG_OUT_OF_MEMORY, lineno, NULL); + ECPGraise(lineno, ECPG_OUT_OF_MEMORY, NULL); return NULL; } @@ -206,7 +206,7 @@ ecpg_strdup(const char *string, int lineno) if (!new) { ECPGlog("out of memory\n"); - ECPGraise(ECPG_OUT_OF_MEMORY, lineno, NULL); + ECPGraise(lineno, ECPG_OUT_OF_MEMORY, NULL); return NULL; } @@ -634,7 +634,7 @@ ECPGexecute(struct statement * stmt) default: /* Not implemented yet */ - ECPGraise(ECPG_UNSUPPORTED, stmt->lineno, ECPGtype_name(var->type)); + ECPGraise(stmt->lineno, ECPG_UNSUPPORTED, ECPGtype_name(var->type)); return false; break; } @@ -657,7 +657,7 @@ ECPGexecute(struct statement * stmt) * We have an argument but we dont have the matched up string * in the string */ - ECPGraise(ECPG_TOO_MANY_ARGUMENTS, stmt->lineno, NULL); + ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, NULL); return false; } else @@ -694,7 +694,7 @@ ECPGexecute(struct statement * stmt) /* Check if there are unmatched things left. */ if (next_insert(copiedquery) != NULL) { - ECPGraise(ECPG_TOO_FEW_ARGUMENTS, stmt->lineno, NULL); + ECPGraise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, NULL); return false; } @@ -742,7 +742,7 @@ ECPGexecute(struct statement * stmt) { ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d\n", stmt->lineno, ntuples); - ECPGraise(ECPG_NOT_FOUND, stmt->lineno, NULL); + ECPGraise(stmt->lineno, ECPG_NOT_FOUND, NULL); status = false; break; } @@ -756,7 +756,7 @@ ECPGexecute(struct statement * stmt) if (var == NULL) { ECPGlog("ECPGexecute line %d: Too few arguments.\n", stmt->lineno); - ECPGraise(ECPG_TOO_FEW_ARGUMENTS, stmt->lineno, NULL); + ECPGraise(stmt->lineno, ECPG_TOO_FEW_ARGUMENTS, NULL); return (false); } @@ -778,7 +778,7 @@ ECPGexecute(struct statement * stmt) { ECPGlog("ECPGexecute line %d: Incorrect number of matches: %d don't fit into array of %d\n", stmt->lineno, ntuples, var->arrsize); - ECPGraise(ECPG_TOO_MANY_MATCHES, stmt->lineno, NULL); + ECPGraise(stmt->lineno, ECPG_TOO_MANY_MATCHES, NULL); status = false; break; } @@ -853,7 +853,7 @@ ECPGexecute(struct statement * stmt) } break; default: - ECPGraise(ECPG_UNSUPPORTED, stmt->lineno, ECPGtype_name(var->ind_type)); + ECPGraise(stmt->lineno, ECPG_UNSUPPORTED, ECPGtype_name(var->ind_type)); status = false; break; } @@ -1057,7 +1057,7 @@ ECPGexecute(struct statement * stmt) break; default: - ECPGraise(ECPG_UNSUPPORTED, stmt->lineno, ECPGtype_name(var->type)); + ECPGraise(stmt->lineno, ECPG_UNSUPPORTED, ECPGtype_name(var->type)); status = false; break; } @@ -1067,7 +1067,7 @@ ECPGexecute(struct statement * stmt) if (status && var != NULL) { - ECPGraise(ECPG_TOO_MANY_ARGUMENTS, stmt->lineno, NULL); + ECPGraise(stmt->lineno, ECPG_TOO_MANY_ARGUMENTS, NULL); status = false; } @@ -1123,7 +1123,7 @@ ECPGexecute(struct statement * stmt) } bool -ECPGdo(int lineno, const char *connection_name, char *query,...) +ECPGdo(int lineno, const char *connection_name, char *query, ...) { va_list args; struct statement *stmt; diff --git a/src/interfaces/ecpg/preproc/descriptor.c b/src/interfaces/ecpg/preproc/descriptor.c index 247e48f234d..845a70c0aa8 100644 --- a/src/interfaces/ecpg/preproc/descriptor.c +++ b/src/interfaces/ecpg/preproc/descriptor.c @@ -11,15 +11,14 @@ struct assignment *assignments; -void push_assignment(char *var, char *value) +void push_assignment(char *var, enum ECPGdtype value) { struct assignment *new = (struct assignment *)mm_alloc(sizeof(struct assignment)); new->next = assignments; - new->variable = mm_alloc(strlen(var)+1); - strcpy(new->variable,var); - new->value = mm_alloc(strlen(value)+1); - strcpy(new->value,value); + new->variable = mm_alloc(strlen(var) + 1); + strcpy(new->variable, var); + new->value = value; assignments = new; } @@ -32,7 +31,6 @@ drop_assignments(void) assignments = old_head->next; free(old_head->variable); - free(old_head->value); free(old_head); } } @@ -61,7 +59,7 @@ static void ECPGnumeric_lvalue(FILE *f,char *name) static void ECPGstring_buffer(FILE *f, char *name) { - const struct variable *v=find_variable(name); + const struct variable *v = find_variable(name); switch(v->type->typ) { @@ -177,17 +175,18 @@ static struct descriptor *descriptors; void add_descriptor(char *name,char *connection) { - struct descriptor *new=(struct descriptor *)mm_alloc(sizeof(struct descriptor)); + struct descriptor *new = (struct descriptor *)mm_alloc(sizeof(struct descriptor)); - new->next=descriptors; - new->name=mm_alloc(strlen(name)+1); + new->next = descriptors; + new->name = mm_alloc(strlen(name) + 1); strcpy(new->name,name); if (connection) - { new->connection=mm_alloc(strlen(connection)+1); - strcpy(new->connection,connection); + { + new->connection = mm_alloc(strlen(connection) + 1); + strcpy(new->connection, connection); } - else new->connection=connection; - descriptors=new; + else new->connection = connection; + descriptors = new; } void @@ -217,13 +216,13 @@ drop_descriptor(char *name,char *connection) } struct descriptor -*lookup_descriptor(char *name,char *connection) +*lookup_descriptor(char *name, char *connection) { struct descriptor *i; - for (i=descriptors;i;i=i->next) + for (i = descriptors; i; i = i->next) { - if (!strcmp(name,i->name)) + if (!strcmp(name, i->name)) { if ((!connection && !i->connection) || (connection && i->connection @@ -233,8 +232,8 @@ struct descriptor } } } - snprintf(errortext,sizeof errortext,"unknown descriptor %s",name); - mmerror(ET_WARN,errortext); + snprintf(errortext, sizeof errortext, "unknown descriptor %s", name); + mmerror(ET_WARN, errortext); return NULL; } @@ -246,10 +245,11 @@ output_get_descr_header(char *desc_name) fprintf(yyout, "{ ECPGget_desc_header(%d, \"%s\", &(", yylineno, desc_name); for (results = assignments; results != NULL; results = results->next) { - if (!strcasecmp(results->value, "count")) + if (results->value == ECPGd_count) ECPGnumeric_lvalue(yyout,results->variable); else - { snprintf(errortext, sizeof errortext, "unknown descriptor header item '%s'", results->value); + { + snprintf(errortext, sizeof errortext, "unknown descriptor header item '%d'", results->value); mmerror(ET_WARN, errortext); } } @@ -260,114 +260,31 @@ output_get_descr_header(char *desc_name) } void -output_get_descr(char *desc_name) +output_get_descr(char *desc_name, char *index) { struct assignment *results; - int flags=0; - const int DATA_SEEN=1; - const int INDICATOR_SEEN=2; - - fprintf(yyout,"{\tPGresult *ECPGresult=ECPGresultByDescriptor(%d, \"%s\");\n" - ,yylineno,desc_name); - fputs("\tif (ECPGresult)\n\t{",yyout); - fprintf(yyout,"\tif (PQntuples(ECPGresult)<1) ECPGraise(%d,ECPG_NOT_FOUND);\n",yylineno); - fprintf(yyout,"\t\telse if (%s<1 || %s>PQnfields(ECPGresult))\n" - "\t\t\tECPGraise(%d,ECPG_INVALID_DESCRIPTOR_INDEX);\n" - ,descriptor_index,descriptor_index,yylineno); - fputs("\t\telse\n\t\t{\n",yyout); - for (results=assignments;results!=NULL;results=results->next) + + fprintf(yyout, "{ ECPGget_desc(%d,\"%s\",%s,", yylineno, desc_name, index); + for (results = assignments; results != NULL; results = results->next) { - if (!strcasecmp(results->value,"type")) - { - fputs("\t\t\t",yyout); - ECPGnumeric_lvalue(yyout,results->variable); - fprintf(yyout,"=ECPGDynamicType(PQftype(ECPGresult,(%s)-1));\n",descriptor_index); - } - else if (!strcasecmp(results->value,"datetime_interval_code")) - { - fputs("\t\t\t",yyout); - ECPGnumeric_lvalue(yyout,results->variable); - fprintf(yyout,"=ECPGDynamicType_DDT(PQftype(ECPGresult,(%s)-1));\n",descriptor_index); - } - else if (!strcasecmp(results->value,"length")) - { - fputs("\t\t\t",yyout); - ECPGnumeric_lvalue(yyout,results->variable); - fprintf(yyout,"=PQfmod(ECPGresult,(%s)-1)-VARHDRSZ;\n",descriptor_index); - } - else if (!strcasecmp(results->value,"octet_length")) - { - fputs("\t\t\t",yyout); - ECPGnumeric_lvalue(yyout,results->variable); - fprintf(yyout,"=PQfsize(ECPGresult,(%s)-1);\n",descriptor_index); - } - else if (!strcasecmp(results->value,"returned_length") - || !strcasecmp(results->value,"returned_octet_length")) - { - fputs("\t\t\t",yyout); - ECPGnumeric_lvalue(yyout,results->variable); - fprintf(yyout,"=PQgetlength(ECPGresult,0,(%s)-1);\n",descriptor_index); - } - else if (!strcasecmp(results->value,"precision")) - { - fputs("\t\t\t",yyout); - ECPGnumeric_lvalue(yyout,results->variable); - fprintf(yyout,"=PQfmod(ECPGresult,(%s)-1)>>16;\n",descriptor_index); - } - else if (!strcasecmp(results->value,"scale")) - { - fputs("\t\t\t",yyout); - ECPGnumeric_lvalue(yyout,results->variable); - fprintf(yyout,"=(PQfmod(ECPGresult,(%s)-1)-VARHDRSZ)&0xffff;\n",descriptor_index); - } - else if (!strcasecmp(results->value,"nullable")) - { - mmerror(ET_WARN,"nullable is always 1"); - fputs("\t\t\t",yyout); - ECPGnumeric_lvalue(yyout,results->variable); - fprintf(yyout,"=1;\n"); - } - else if (!strcasecmp(results->value,"key_member")) - { - mmerror(ET_WARN,"key_member is always 0"); - fputs("\t\t\t",yyout); - ECPGnumeric_lvalue(yyout,results->variable); - fprintf(yyout,"=0;\n"); - } - else if (!strcasecmp(results->value,"name")) - { - fputs("\t\t\tstrncpy(",yyout); - ECPGstring_buffer(yyout,results->variable); - fprintf(yyout,",PQfname(ECPGresult,(%s)-1),",descriptor_index); - ECPGstring_length(yyout,results->variable); - fputs(");\n",yyout); - } - else if (!strcasecmp(results->value,"indicator")) - { - flags|=INDICATOR_SEEN; - fputs("\t\t\t",yyout); - ECPGnumeric_lvalue(yyout,results->variable); - fprintf(yyout,"=-PQgetisnull(ECPGresult,0,(%s)-1);\n",descriptor_index); - } - else if (!strcasecmp(results->value,"data")) - { - flags|=DATA_SEEN; - ECPGdata_assignment(results->variable,descriptor_index); - } - else + const struct variable *v = find_variable(results->variable); + + switch (results->value) { - snprintf(errortext,sizeof errortext,"unknown descriptor header item '%s'",results->value); - mmerror(ET_WARN,errortext); + case ECPGd_nullable: + mmerror(ET_WARN,"nullable is always 1"); + break; + case ECPGd_key_member: + mmerror(ET_WARN,"key_member is always 0"); + break; + default: + break; } - } - if (flags==DATA_SEEN) /* no indicator */ - { - fprintf(yyout,"\t\t\tif (PQgetisnull(ECPGresult,0,(%s)-1))\n" - "\t\t\t\tECPGraise(%d,ECPG_MISSING_INDICATOR);\n" - ,descriptor_index,yylineno); + fprintf(yyout, "%s,", get_dtype(results->value)); + ECPGdump_a_type(yyout, v->name, v->type, NULL, NULL, NULL, NULL); } drop_assignments(); - fputs("\t\t}\n\t}\n",yyout); + fputs("ECPGd_EODT);\n",yyout); whenever_action(2|1); } diff --git a/src/interfaces/ecpg/preproc/ecpg_keywords.c b/src/interfaces/ecpg/preproc/ecpg_keywords.c index 0cc7699a6dc..e59dceafca3 100644 --- a/src/interfaces/ecpg/preproc/ecpg_keywords.c +++ b/src/interfaces/ecpg/preproc/ecpg_keywords.c @@ -28,6 +28,10 @@ static ScanKeyword ScanKeywords[] = { {"connect", SQL_CONNECT}, {"connection", SQL_CONNECTION}, {"continue", SQL_CONTINUE}, + {"count", SQL_COUNT}, + {"data", SQL_DATA}, + {"datetime_interval_code", SQL_DATETIME_INTERVAL_CODE}, + {"datetime_interval_precision", SQL_DATETIME_INTERVAL_PRECISION}, {"deallocate", SQL_DEALLOCATE}, {"descriptor", SQL_DESCRIPTOR}, {"disconnect", SQL_DISCONNECT}, @@ -40,12 +44,20 @@ static ScanKeyword ScanKeywords[] = { {"identified", SQL_IDENTIFIED}, {"indicator", SQL_INDICATOR}, {"int", SQL_INT}, + {"key_member", SQL_KEY_MEMBER}, + {"length", SQL_LENGTH}, {"long", SQL_LONG}, + {"name", SQL_NAME}, + {"nullable", SQL_NULLABLE}, + {"octet_length", SQL_OCTET_LENGTH}, {"off", SQL_OFF}, {"open", SQL_OPEN}, {"prepare", SQL_PREPARE}, {"reference", SQL_REFERENCE}, {"release", SQL_RELEASE}, + {"returned_length", SQL_RETURNED_LENGTH}, + {"returned_octet_length", SQL_RETURNED_OCTET_LENGTH}, + {"scale", SQL_SCALE}, {"section", SQL_SECTION}, {"short", SQL_SHORT}, {"signed", SQL_SIGNED}, diff --git a/src/interfaces/ecpg/preproc/extern.h b/src/interfaces/ecpg/preproc/extern.h index 3ec8a596b1e..7cf42946f41 100644 --- a/src/interfaces/ecpg/preproc/extern.h +++ b/src/interfaces/ecpg/preproc/extern.h @@ -35,6 +35,7 @@ extern struct descriptor *descriptors; /* functions */ +extern const char *get_dtype(enum ECPGdtype); extern void lex_init(void); extern char *make_str(const char *); extern void output_line_number(void); @@ -50,8 +51,8 @@ extern void mmerror(enum errortype, char * ); extern ScanKeyword *ScanECPGKeywordLookup(char *); extern ScanKeyword *ScanCKeywordLookup(char *); extern void output_get_descr_header(char *); -extern void output_get_descr(char *); -extern void push_assignment(char *, char *); +extern void output_get_descr(char *, char *); +extern void push_assignment(char *, enum ECPGdtype); extern struct variable * find_variable(char *); extern void whenever_action(int); extern void add_descriptor(char *,char *); diff --git a/src/interfaces/ecpg/preproc/keywords.c b/src/interfaces/ecpg/preproc/keywords.c index e8fd0d0bb64..a82975056ff 100644 --- a/src/interfaces/ecpg/preproc/keywords.c +++ b/src/interfaces/ecpg/preproc/keywords.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.22 2000/02/15 12:15:54 meskes Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.23 2000/02/22 19:57:10 meskes Exp $ * *------------------------------------------------------------------------- */ @@ -108,6 +108,7 @@ static ScanKeyword ScanKeywords[] = { {"fetch", FETCH}, {"float", FLOAT}, {"for", FOR}, + {"force", FORCE}, {"foreign", FOREIGN}, {"forward", FORWARD}, {"from", FROM}, @@ -197,6 +198,7 @@ static ScanKeyword ScanKeywords[] = { {"public", PUBLIC}, {"read", READ}, {"references", REFERENCES}, + {"reindex", REINDEX}, {"relative", RELATIVE}, {"rename", RENAME}, {"reset", RESET}, diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l index f69f21b94d0..fcb033787c5 100644 --- a/src/interfaces/ecpg/preproc/pgc.l +++ b/src/interfaces/ecpg/preproc/pgc.l @@ -12,7 +12,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.50 2000/01/27 19:00:39 meskes Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.51 2000/02/22 19:57:10 meskes Exp $ * *------------------------------------------------------------------------- */ @@ -70,29 +70,26 @@ static struct _if_value { } stacked_if_value[MAX_NESTED_IF]; %} + %option yylineno %s C SQL incl def def_ident -/* OK, here is a short description of lex/flex rules behavior. + +/* + * OK, here is a short description of lex/flex rules behavior. * The longest pattern which matches an input string is always chosen. * For equal-length patterns, the first occurring in the rules list is chosen. - * INITIAL is the starting condition, to which all non-conditional rules apply. - * When in an exclusive condition, only those rules defined for that condition apply. + * INITIAL is the starting state, to which all non-conditional rules apply. + * Exclusive states change parsing rules while the state is active. When in + * an exclusive state, only those rules defined for that state apply. * - * Exclusive states change parsing rules while the state is active. - * There are exclusive states for quoted strings, extended comments, - * and to eliminate parsing troubles for numeric strings. + * We use exclusive states for quoted strings, extended comments, + * and to eliminate parsing troubles for numeric strings. * Exclusive states: * <xb> binary numeric string - thomas 1997-11-16 * <xc> extended C-style comments - tgl 1997-07-12 * <xd> delimited identifiers (double-quoted identifiers) - tgl 1997-10-27 * <xh> hexadecimal numeric string - thomas 1997-11-16 * <xq> quoted strings - tgl 1997-07-30 - * - * The "extended comment" syntax closely resembles allowable operator syntax. - * So, when in condition <xc>, only strings which would terminate the - * "extended comment" trigger any action other than "ignore". - * Be sure to match _any_ candidate comment, including those with appended - * operator-like symbols. - thomas 1997-07-14 */ %x xb @@ -109,15 +106,15 @@ static struct _if_value { */ xbstart [bB]{quote} xbstop {quote} -xbinside [^']* -xbcat {quote}{space}*\n{space}*{quote} +xbinside [^']+ +xbcat {quote}{whitespace_with_newline}{quote} /* Hexadecimal number */ xhstart [xX]{quote} xhstop {quote} -xhinside [^']* -xhcat {quote}{space}*\n{space}*{quote} +xhinside [^']+ +xhcat {quote}{whitespace_with_newline}{quote} /* C version of hex number */ @@ -131,9 +128,9 @@ quote ' xqstart {quote} xqstop {quote} xqdouble {quote}{quote} -xqinside [^\\']* +xqinside [^\\']+ xqliteral [\\](.|\n) -xqcat {quote}{space}*\n{space}*{quote} +xqcat {quote}{whitespace_with_newline}{quote} /* Delimited quote * Allows embedded spaces and other special characters into identifiers. @@ -141,7 +138,7 @@ xqcat {quote}{space}*\n{space}*{quote} dquote \" xdstart {dquote} xdstop {dquote} -xdinside [^"]* +xdinside [^"]+ /* special stuff for C strings */ xdcqq \\\\ @@ -149,14 +146,25 @@ xdcqdq \\\" xdcother [^"] xdcinside ({xdcqq}|{xdcqdq}|{xdcother}) -/* Comments +/* C-Style Comments * Ignored by the scanner and parser. + * The "extended comment" syntax closely resembles allowable operator syntax. + * The tricky part here is to get lex to recognize a string starting with + * slash-star as a comment, when interpreting it as an operator would produce + * a longer match --- remember lex will prefer a longer match! So, we have + * to provide a special rule for xcline (a complete comment that could + * otherwise look like an operator), as well as append {op_and_self}* to + * xcstart so that it matches at least as much as {operator} would. + * Then the tie-breaker (first matching rule of same length) wins. + * There is still a problem if someone writes, eg, slash-star-star-slash-plus. + * It'll be taken as an xcstart, rather than xcline and an operator as one + * could wish. I don't see any way around that given lex's behavior; + * that someone will just have to write a space after the comment. */ -xcline [\/][\*].*[\*][\/]{line_end}+ -xcstart [\/][\*]{op_and_self}* -xcstop {op_and_self}*[\*][\/]{space_or_nl}* -xcinside [^*]* -xcstar [^/] +xcline \/\*{op_and_self}*\*\/ +xcstart \/\*{op_and_self}* +xcstop \*+\/ +xcinside ([^*]+)|(\*+[^/]) digit [0-9] letter [\200-\377_A-Za-z] @@ -181,12 +189,44 @@ real ((({digit}*\.{digit}+)|({digit}+\.{digit}*)|({digit}+))([Ee][-+]?{digit}+ param \${integer} -comment ("--"|"//").* +/* + * In order to make the world safe for Windows and Mac clients as well as + * Unix ones, we accept either \n or \r as a newline. A DOS-style \r\n + * sequence will be seen as two successive newlines, but that doesn't cause + * any problems. SQL92-style comments, which start with -- and extend to the + * next newline, are treated as equivalent to a single whitespace character. + * + * NOTE a fine point: if there is no newline following --, we will absorb + * everything to the end of the input as a comment. This is correct. Older + * versions of Postgres failed to recognize -- as a comment if the input + * did not end with a newline. + * + * XXX perhaps \f (formfeed) should be treated as a newline as well? + */ + ccomment "//".*\n space [ \t\r\f] space_or_nl [ \t\r\f\n] -line_end {space}*\n +line_end {space}*\n +horiz_space [ \t\f] +newline [\n\r] +non_newline [^\n\r] + +comment (("--"|"//"){non_newline}*) + +whitespace ({space}|{comment}) + +/* + * SQL92 requires at least one newline in the whitespace separating + * string literals that are to be concatenated. Silly, but who are we + * to argue? Note that {whitespace_with_newline} should not have * after + * it, whereas {whitespace} should generally have a * after it... + */ + +horiz_whitespace ({horiz_space}|{comment}) +whitespace_with_newline ({horiz_whitespace}*{newline}{whitespace}*) + other . /* some stuff needed for ecpg */ @@ -217,14 +257,16 @@ cppline {space}*#(.*\\{line_end})*.* * of escaped-quote "\'". * Other embedded escaped characters are matched explicitly and the leading * backslash is dropped from the string. - thomas 1997-09-24 + * Note that xcline must appear before xcstart, which must appear before + * operator, as explained above! Also whitespace (comment) must appear + * before operator. */ %% -<SQL>{comment} { /* ignore */ } +<SQL>{whitespace} { /* ignore */ } {xcline} { ECHO; } -<xc>{xcstar} { ECHO; } {xcstart} { before_comment = YYSTATE; ECHO; @@ -254,7 +296,7 @@ cppline {space}*#(.*\\{line_end})*.* addlit(yytext, yyleng); } <xh>{xhcat} | -<xb>{xbcat} { +<xb>{xbcat} { /* ignore */ } <SQL>{xhstart} { @@ -286,7 +328,7 @@ cppline {space}*#(.*\\{line_end})*.* <xq>{xqliteral} { addlit(yytext, yyleng); } -<xq>{xqcat} { +<xq>{xqcat} { /* ignore */ } <SQL>{xdstart} { @@ -331,43 +373,28 @@ cppline {space}*#(.*\\{line_end})*.* return Op; } <SQL>{param} { - yylval.ival = atoi((char*)&yytext[1]); + yylval.ival = atol((char*)&yytext[1]); return PARAM; } <C,SQL>{integer} { char* endptr; errno = 0; - yylval.ival = strtol((char *)yytext,&endptr,10); + yylval.ival = strtol((char *)yytext, &endptr,10); if (*endptr != '\0' || errno == ERANGE) { errno = 0; yylval.str = mm_strdup((char*)yytext); - return SCONST; + return FCONST; } return ICONST; } {decimal} { - char* endptr; - - if (strlen((char *)yytext) <= 17) - { - errno = 0; - yylval.dval = strtod((char *)yytext,&endptr); - if (*endptr != '\0' || errno == ERANGE) - mmerror(ET_ERROR, "Bad float8 input"); - return FCONST; - } yylval.str = mm_strdup((char*)yytext); - return SCONST; + return FCONST; } <C,SQL>{real} { - char* endptr; - - errno = 0; - yylval.dval = strtod((char *)yytext,&endptr); - if (*endptr != '\0' || errno == ERANGE) - mmerror(ET_ERROR, "Bad float input"); + yylval.str = mm_strdup((char*)yytext); return FCONST; } <SQL>:{identifier}(("->"|\.){identifier})* { @@ -433,7 +460,6 @@ cppline {space}*#(.*\\{line_end})*.* } } } -<SQL>{space_or_nl} { /* ignore */ } <SQL>{other} { return yytext[0]; } <C>{exec_sql} { BEGIN SQL; return SQL_START; } <C>{ccomment} { /* ignore */ } diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y index 2b1f1c304aa..a42b68f7deb 100644 --- a/src/interfaces/ecpg/preproc/preproc.y +++ b/src/interfaces/ecpg/preproc/preproc.y @@ -21,7 +21,6 @@ int struct_level = 0; int braces_open; /* brace level counter */ char errortext[128]; -char *descriptor_index= NULL; char *connection = NULL; char *input_filename = NULL; @@ -154,17 +153,23 @@ make_name(void) int tagname; struct this_type type; enum ECPGttype type_enum; + enum ECPGdtype dtype_enum; struct fetch_desc descriptor; } /* special embedded SQL token */ %token SQL_ALLOCATE SQL_AT SQL_AUTOCOMMIT SQL_BOOL SQL_BREAK -%token SQL_CALL SQL_CONNECT SQL_CONNECTION SQL_CONTINUE +%token SQL_CALL SQL_CONNECT SQL_CONNECTION SQL_CONTINUE SQL_COUNT +%token SQL_DATA SQL_DATETIME_INTERVAL_CODE SQL_DATETIME_INTERVAL_PRECISION %token SQL_DEALLOCATE SQL_DESCRIPTOR SQL_DISCONNECT SQL_ENUM %token SQL_FOUND SQL_FREE SQL_GET SQL_GO SQL_GOTO -%token SQL_IDENTIFIED SQL_INDICATOR SQL_INT SQL_LONG -%token SQL_OFF SQL_OPEN SQL_PREPARE SQL_RELEASE SQL_REFERENCE -%token SQL_SECTION SQL_SHORT SQL_SIGNED SQL_SQL +%token SQL_IDENTIFIED SQL_INDICATOR SQL_INT SQL_KEY_MEMBER +%token SQL_LENGTH SQL_LONG +%token SQL_NAME SQL_NULLABLE +%token SQL_OCTET_LENGTH SQL_OFF SQL_OPEN SQL_PREPARE +%token SQL_RELEASE SQL_REFERENCE SQL_RETURNED_LENGTH +%token SQL_RETURNED_OCTET_LENGTH +%token SQL_SCALE SQL_SECTION SQL_SHORT SQL_SIGNED SQL_SQL %token SQL_SQLERROR SQL_SQLPRINT %token SQL_SQLWARNING SQL_START SQL_STOP SQL_STRUCT SQL_UNSIGNED %token SQL_VALUE SQL_VAR SQL_WHENEVER @@ -222,13 +227,13 @@ make_name(void) CACHE, CLUSTER, COMMENT, COPY, CREATEDB, CREATEUSER, CYCLE, DATABASE, DELIMITERS, DO, EACH, ENCODING, EXCLUSIVE, EXPLAIN, EXTEND, - FORWARD, FUNCTION, HANDLER, + FORCE, FORWARD, FUNCTION, HANDLER, INCREMENT, INDEX, INHERITS, INSTEAD, ISNULL, LANCOMPILER, LIMIT, LISTEN, UNLISTEN, LOAD, LOCATION, LOCK_P, MAXVALUE, MINVALUE, MODE, MOVE, NEW, NOCREATEDB, NOCREATEUSER, NONE, NOTHING, NOTIFY, NOTNULL, OFFSET, OIDS, OPERATOR, PASSWORD, PROCEDURAL, - RENAME, RESET, RETURNS, ROW, RULE, + REINDEX, RENAME, RESET, RETURNS, ROW, RULE, SEQUENCE, SERIAL, SETOF, SHARE, SHOW, START, STATEMENT, STDIN, STDOUT, SYSID TRUNCATE, TRUSTED, UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION @@ -270,11 +275,11 @@ make_name(void) %type <str> Iconst Fconst Sconst TransactionStmt CreateStmt UserId %type <str> CreateAsElement OptCreateAs CreateAsList CreateAsStmt -%type <str> OptInherit key_reference key_action comment_text +%type <str> OptInherit key_reference comment_text %type <str> key_match ColLabel SpecialRuleRelation ColId columnDef %type <str> ColConstraint ColConstraintElem NumericOnly FloatOnly %type <str> OptTableElementList OptTableElement TableConstraint -%type <str> ConstraintElem key_actions ColPrimaryKey ColQualList +%type <str> ConstraintElem key_actions ColQualList %type <str> target_list target_el update_target_list alias_clause %type <str> update_target_el opt_id relation_name database_name %type <str> access_method attr_name class index_name name func_name @@ -304,7 +309,7 @@ make_name(void) %type <str> func_args_list func_args opt_with ProcedureStmt def_arg %type <str> def_elem def_list definition def_name def_type DefineStmt %type <str> opt_instead event event_object RuleActionList opt_using -%type <str> RuleActionStmtOrEmpty RuleActionMulti func_as +%type <str> RuleActionStmtOrEmpty RuleActionMulti func_as reindex_type %type <str> RuleStmt opt_column opt_name oper_argtypes sysid_clause %type <str> MathOp RemoveFuncStmt aggr_argtype for_update_clause %type <str> RemoveAggrStmt remove_type RemoveStmt ExtendStmt @@ -324,18 +329,18 @@ make_name(void) %type <str> GrantStmt privileges operation_commalist operation %type <str> opt_cursor opt_lmode ConstraintsSetStmt comment_tg %type <str> case_expr when_clause_list case_default case_arg when_clause -%type <str> select_clause opt_select_limit select_limit_value -%type <str> select_offset_value using_expr join_expr +%type <str> select_clause opt_select_limit select_limit_value TimeClause +%type <str> select_offset_value using_expr join_expr ReindexStmt %type <str> using_list from_expr join_clause join_type %type <str> join_qual update_list join_clause join_clause_with_union %type <str> opt_level opt_lock lock_type users_in_new_group_clause -%type <str> OptConstrFromTable comment_op ConstraintAttributeSpec +%type <str> OptConstrFromTable comment_op ConstraintAttribute %type <str> constraints_set_list constraints_set_namelist comment_fn %type <str> constraints_set_mode comment_type comment_cl comment_ag -%type <str> ConstraintDeferrabilitySpec ConstraintTimeSpec -%type <str> CreateGroupStmt AlterGroupStmt DropGroupStmt -%type <str> ColConstraintWithNull ColConstraintElemWithNull -%type <str> join_expr_with_union +%type <str> CreateGroupStmt AlterGroupStmt DropGroupStmt key_delete +%type <str> ColConstraintWithNull ColConstraintElemWithNull NotNull +%type <str> join_expr_with_union DefaultClause DefaultExpr PrimaryKey +%type <str> DeferrabilityClause opt_force key_update /*** #ifdef ENABLE_ORACLE_JOIN_SYNTAX %type <str> oracle_list oracle_expr oracle_outer @@ -357,12 +362,14 @@ make_name(void) %type <str> struct_type s_struct declaration declarations variable_declarations %type <str> s_struct s_union union_type ECPGSetAutocommit on_off %type <str> ECPGAllocateDescr ECPGDeallocateDescr -%type <str> ECPGGetDescriptor ECPGGetDescriptorHeader +%type <str> ECPGGetDescriptorHeader -%type <descriptor> ECPGFetchDescStmt +%type <descriptor> ECPGFetchDescStmt ECPGGetDescriptor %type <type_enum> simple_type signed_type unsigned_type varchar_type +%type <dtype_enum> descriptor_item desc_header_item + %type <type> type %type <action> action @@ -416,6 +423,7 @@ stmt: AlterTableStmt { output_statement($1, 0, NULL); } | UnlistenStmt { output_statement($1, 0, NULL); } | LockStmt { output_statement($1, 0, NULL); } | ProcedureStmt { output_statement($1, 0, NULL); } + | ReindexStmt { output_statement($1, 0, NULL); } | RemoveAggrStmt { output_statement($1, 0, NULL); } | RemoveOperStmt { output_statement($1, 0, NULL); } | RemoveFuncStmt { output_statement($1, 0, NULL); } @@ -483,7 +491,11 @@ stmt: AlterTableStmt { output_statement($1, 0, NULL); } free($1); } | ECPGExecute { output_statement($1, 0, NULL); } - | ECPGFetchDescStmt { output_statement($1.str, 1, $1.name); } + | ECPGFetchDescStmt { + output_statement($1.str, 1, $1.name); + free($1.str); + free($1.name); + } | ECPGFree { fprintf(yyout, "{ ECPGdeallocate(__LINE__, \"%s\");", $1); @@ -491,12 +503,15 @@ stmt: AlterTableStmt { output_statement($1, 0, NULL); } free($1); } | ECPGGetDescriptor { - lookup_descriptor($1,connection); - output_get_descr($1); + lookup_descriptor($1.name, connection); + output_get_descr($1.name, $1.str); + free($1.name); + free($1.str); } | ECPGGetDescriptorHeader { - lookup_descriptor($1,connection); + lookup_descriptor($1, connection); output_get_descr_header($1); + free($1); } | ECPGOpen { struct cursor *ptr; @@ -1013,42 +1028,64 @@ OptTableElement: columnDef { $$ = $1; } | TableConstraint { $$ = $1; } ; -columnDef: ColId Typename ColQualifier +columnDef: ColId Typename ColQualifier opt_collate { - $$ = cat_str(3, $1, $2, $3); + if (strlen($4) > 0) + { + sprintf(errortext, "CREATE TABLE/COLLATE %s not yet implemented; clause ignored", $4); + mmerror(ET_WARN, errortext); + } + $$ = cat_str(4, $1, $2, $3, $4); } - | ColId SERIAL ColPrimaryKey + | ColId SERIAL ColQualifier opt_collate { - $$ = cat_str(3, $1, make_str(" serial "), $3); + if (strlen($4) > 0) + { + sprintf(errortext, "CREATE TABLE/COLLATE %s not yet implemented; clause ignored", $4); + mmerror(ET_WARN, errortext); + } + $$ = cat_str(4, $1, make_str(" serial "), $3, $4); } ; -ColQualifier: ColQualList { $$ = $1; } - | NULL_P ColQualListWithNull { $$ = cat2_str(make_str("null"), $2); } - | NULL_P { $$ = make_str("null"); } - | /*EMPTY*/ { $$ = EMPTY; } +/* + * ColQualifier encapsulates an entire column qualification, + * including DEFAULT, constraints, and constraint attributes. + * Note that the DefaultClause handles the empty case. + */ +ColQualifier: DefaultClause ColQualList { $$ = cat2_str($1, $2); } + | NotNull DefaultClause ColQualListWithNull { $$ = cat_str(3, $1, $2, $3); } + | DefaultExpr NotNull ColQualListWithNull { $$ = cat_str(3, $1, $2, $3); } + | DefaultExpr NotNull { $$ = cat2_str($1, $2); } + | NotNull DefaultClause { $$ = cat2_str($1, $2); } + | NULL_P DefaultClause ColQualListWithNull { $$ = cat_str(3, make_str("null"), $2, $3); } + | NULL_P DefaultClause { $$ = cat2_str(make_str("null"), $2); } + | DefaultClause { $$ = $1; } + ; + +/* + * DEFAULT expression must be b_expr not a_expr to prevent shift/reduce + * conflict on NOT (since NOT might start a subsequent NOT NULL constraint, + * or be part of a_expr NOT LIKE or similar constructs). + */ +DefaultClause: DefaultExpr { $$ = $1; } + | /*EMPTY*/ { $$ = EMPTY; } + ; + +DefaultExpr: DEFAULT NULL_P { $$ = make_str("default null"); } + | DEFAULT b_expr { $$ = cat2_str(make_str("default"), $2); } ; ColQualList: ColQualList ColConstraint { $$ = cat2_str($1,$2); } | ColConstraint { $$ = $1; } ; -ColQualListWithNull: ColQualListWithNull ColConstraintWithNull +ColQualListWithNull: ColConstraintWithNull ColQualListWithNull { $$ = cat2_str($1, $2); } | ColConstraintWithNull { $$ = $1; } -ColPrimaryKey: PRIMARY KEY - { - $$ = make_str("primary key"); - } - | /*EMPTY*/ - { - $$ = EMPTY; - } - ; -ColConstraint: - CONSTRAINT name ColConstraintElem +ColConstraint: CONSTRAINT name ColConstraintElem { $$ = cat_str(3, make_str("constraint"), $2, $3); } @@ -1056,8 +1093,7 @@ ColConstraint: { $$ = $1; } ; -ColConstraintWithNull: - CONSTRAINT name ColConstraintElemWithNull +ColConstraintWithNull: CONSTRAINT name ColConstraintElemWithNull { $$ = cat_str(3, make_str("constraint"), $2, $3); } | ColConstraintElemWithNull { $$ = $1; } @@ -1073,26 +1109,18 @@ ColConstraintWithNull: * that a column may have that value. WITH NULL leads to * shift/reduce conflicts with WITH TIME ZONE anyway. * - thomas 1999-01-08 - * - * DEFAULT expression must be b_expr not a_expr to prevent shift/reduce - * conflict on NOT (since NOT might start a subsequent NOT NULL constraint, - * or be part of a_expr NOT LIKE or similar constructs). */ ColConstraintElem: ColConstraintElemWithNull { $$ = $1; } - | NOT NULL_P - { - $$ = make_str("not null"); - } | UNIQUE { $$ = make_str("unique"); } - | PRIMARY KEY + | PrimaryKey { - $$ = make_str("primary key"); + $$ = $1; } ; @@ -1101,20 +1129,22 @@ ColConstraintElemWithNull: CHECK '(' a_expr ')' { $$ = cat_str(3, make_str("check("), $3, make_str(")")); } - | DEFAULT NULL_P - { - $$ = make_str("default null"); - } - | DEFAULT b_expr + | REFERENCES ColId opt_column_list + key_match key_actions ConstraintAttribute { - $$ = cat2_str(make_str("default"), $2); + $$ = cat_str(6, make_str("references"), $2, $3, $4, $5, $6); } - | REFERENCES ColId opt_column_list key_match key_actions + | REFERENCES ColId opt_column_list + key_match key_actions { $$ = cat_str(5, make_str("references"), $2, $3, $4, $5); } ; +PrimaryKey: PRIMARY KEY { $$ = make_str("primary key"); } + +NotNull: NOT NULL_P { $$ = make_str("not null"); } + /* ConstraintElem specifies constraint syntax which is not embedded into * a column definition. ColConstraintElem specifies the embedded form. * - thomas 1997-12-03 @@ -1135,11 +1165,17 @@ ConstraintElem: CHECK '(' a_expr ')' { $$ = cat_str(3, make_str("unique("), $3, make_str(")")); } - | PRIMARY KEY '(' columnList ')' + | PrimaryKey '(' columnList ')' + { + $$ = cat_str(3, make_str("primary key("), $3, make_str(")")); + } + | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list + key_match key_actions ConstraintAttribute { - $$ = cat_str(3, make_str("primary key("), $4, make_str(")")); + $$ = cat_str(8, make_str("foreign key("), $4, make_str(") references"), $7, $8, $9, $10, $11); } - | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list key_match key_actions + | FOREIGN KEY '(' columnList ')' REFERENCES ColId opt_column_list + key_match key_actions { $$ = cat_str(7, make_str("foreign key("), $4, make_str(") references"), $7, $8, $9, $10); } @@ -1151,7 +1187,7 @@ key_match: MATCH FULL } | MATCH PARTIAL { - mmerror(ET_WARN, "FOREIGN KEY match type PARTIAL not implemented yet"); + mmerror(ET_WARN, "FOREIGN KEY/MATCH PARTIAL not yet implemented"); $$ = make_str("match partial"); } | /*EMPTY*/ @@ -1160,14 +1196,16 @@ key_match: MATCH FULL } ; -key_actions: key_action key_action { $$ = cat2_str($1, $2); } - | key_action { $$ = $1; } +key_actions: key_delete { $$ = $1; } + | key_update { $$ = $1; } + | key_delete key_update { $$ = cat2_str($1, $2); } + | key_update key_delete { $$ = cat2_str($1, $2); } | /*EMPTY*/ { $$ = EMPTY; } ; -key_action: ON DELETE key_reference { $$ = cat2_str(make_str("on delete"), $3); } - | ON UPDATE key_reference { $$ = cat2_str(make_str("on update"), $3); } - ; +key_delete: ON DELETE key_reference { $$ = cat2_str(make_str("on delete"), $3); } + +key_update: ON UPDATE key_reference { $$ = cat2_str(make_str("on update"), $3); } key_reference: NO ACTION { $$ = make_str("no action"); } | RESTRICT { $$ = make_str("restrict"); } @@ -1313,7 +1351,7 @@ CreateTrigStmt: CREATE TRIGGER name TriggerActionTime TriggerEvents ON } | CREATE CONSTRAINT TRIGGER name AFTER TriggerEvents ON relation_name OptConstrFromTable - ConstraintAttributeSpec + ConstraintAttribute FOR EACH ROW EXECUTE PROCEDURE name '(' TriggerFuncArgs ')' { @@ -1388,46 +1426,32 @@ OptConstrFromTable: /* Empty */ } ; -ConstraintAttributeSpec: ConstraintDeferrabilitySpec +ConstraintAttribute: DeferrabilityClause { $$ = $1; } - | ConstraintDeferrabilitySpec ConstraintTimeSpec + | TimeClause + { $$ = $1; } + | DeferrabilityClause TimeClause { if (strcmp($1, "deferrable") != 0 && strcmp($2, "initially deferrable") == 0 ) mmerror(ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE"); $$ = cat2_str($1, $2); } - | ConstraintTimeSpec - { $$ = $1; } - | ConstraintTimeSpec ConstraintDeferrabilitySpec + | TimeClause DeferrabilityClause { if (strcmp($2, "deferrable") != 0 && strcmp($1, "initially deferrable") == 0 ) mmerror(ET_ERROR, "INITIALLY DEFERRED constraint must be DEFERRABLE"); $$ = cat2_str($1, $2); } - | /* Empty */ - { $$ = 0; } ; -ConstraintDeferrabilitySpec: NOT DEFERRABLE - { - $$ = make_str("not deferrable"); - } - | DEFERRABLE - { - $$ = make_str("deferrable"); - } +DeferrabilityClause: NOT DEFERRABLE { $$ = make_str("not deferrable"); } + | DEFERRABLE { $$ = make_str("deferrable"); } ; -ConstraintTimeSpec: INITIALLY IMMEDIATE - { - $$ = make_str("initially immediate"); - } - | INITIALLY DEFERRED - { - $$ = make_str("initially deferrable"); - } +TimeClause: INITIALLY IMMEDIATE { $$ = make_str("initially immediate"); } + | INITIALLY DEFERRED { $$ = make_str("initially deferrable"); } ; DropTrigStmt: DROP TRIGGER name ON relation_name @@ -1961,6 +1985,25 @@ oper_argtypes: name { $$ = cat2_str($1, make_str(", none")); } ; +/***************************************************************************** + * + * QUERY: + * + * REINDEX type <typename> [FORCE] [ALL] + * + *****************************************************************************/ +ReindexStmt: REINDEX reindex_type name opt_force + { + $$ = cat_str(4, make_str("reindex"), $2, $3, $4); + } + +reindex_type: INDEX { $$ = make_str("index"); } + | TABLE { $$ = make_str("table"); } + | DATABASE { $$ = make_str("database"); } + ; +opt_force: FORCE { $$ = make_str("force"); } + | /* EMPTY */ { $$ = EMPTY; } + ; /***************************************************************************** * @@ -2864,6 +2907,10 @@ generic: ident { $$ = $1; } | SQL_CONNECT { $$ = make_str("connect"); } | SQL_CONNECTION { $$ = make_str("connection"); } | SQL_CONTINUE { $$ = make_str("continue"); } + | SQL_COUNT { $$ = make_str("count"); } + | SQL_DATA { $$ = make_str("data"); } + | SQL_DATETIME_INTERVAL_CODE { $$ = make_str("datetime_interval_code"); } + | SQL_DATETIME_INTERVAL_PRECISION { $$ = make_str("datetime_interval_precision"); } | SQL_DEALLOCATE { $$ = make_str("deallocate"); } | SQL_DISCONNECT { $$ = make_str("disconnect"); } | SQL_FOUND { $$ = make_str("found"); } @@ -2872,11 +2919,19 @@ generic: ident { $$ = $1; } | SQL_IDENTIFIED { $$ = make_str("identified"); } | SQL_INDICATOR { $$ = make_str("indicator"); } | SQL_INT { $$ = make_str("int"); } + | SQL_KEY_MEMBER { $$ = make_str("key_member"); } + | SQL_LENGTH { $$ = make_str("length"); } | SQL_LONG { $$ = make_str("long"); } + | SQL_NAME { $$ = make_str("name"); } + | SQL_NULLABLE { $$ = make_str("nullable"); } + | SQL_OCTET_LENGTH { $$ = make_str("octet_length"); } | SQL_OFF { $$ = make_str("off"); } | SQL_OPEN { $$ = make_str("open"); } | SQL_PREPARE { $$ = make_str("prepare"); } | SQL_RELEASE { $$ = make_str("release"); } + | SQL_RETURNED_LENGTH { $$ = make_str("returned_length"); } + | SQL_RETURNED_OCTET_LENGTH { $$ = make_str("returned_octet_length"); } + | SQL_SCALE { $$ = make_str("scale"); } | SQL_SECTION { $$ = make_str("section"); } | SQL_SHORT { $$ = make_str("short"); } | SQL_SIGNED { $$ = make_str("signed"); } @@ -3019,15 +3074,9 @@ Character: character '(' Iconst ')' } ; -character: CHARACTER opt_varying opt_charset opt_collate +character: CHARACTER opt_varying opt_charset { - if (strlen($4) > 0) - { - sprintf(errortext, "COLLATE %s not yet implemented", $4); - mmerror(ET_WARN, errortext); - } - - $$ = cat_str(4, make_str("character"), $2, $3, $4); + $$ = cat_str(3, make_str("character"), $2, $3); } | CHAR opt_varying { $$ = cat2_str(make_str("char"), $2); } | VARCHAR { $$ = make_str("varchar"); } @@ -3401,6 +3450,8 @@ c_expr: attr { $$ = cat2_str($1, make_str("()")); } | func_name '(' expr_list ')' { $$ = cat_str(4, $1, make_str("("), $3, make_str(")")); } + | func_name '(' ALL expr_list ')' + { $$ = cat_str(4, $1, make_str("( all"), $4, make_str(")")); } | func_name '(' DISTINCT expr_list ')' { $$ = cat_str(4, $1, make_str("( distinct"), $4, make_str(")")); } | func_name '(' '*' ')' @@ -3870,6 +3921,10 @@ ColId: ident { $$ = $1; } | SQL_CALL { $$ = make_str("call"); } | SQL_CONNECT { $$ = make_str("connect"); } | SQL_CONTINUE { $$ = make_str("continue"); } + | SQL_COUNT { $$ = make_str("count"); } + | SQL_DATA { $$ = make_str("data"); } + | SQL_DATETIME_INTERVAL_CODE { $$ = make_str("datetime_interval_code"); } + | SQL_DATETIME_INTERVAL_PRECISION { $$ = make_str("datetime_interval_precision"); } | SQL_DEALLOCATE { $$ = make_str("deallocate"); } | SQL_DISCONNECT { $$ = make_str("disconnect"); } | SQL_FOUND { $$ = make_str("found"); } @@ -3878,11 +3933,19 @@ ColId: ident { $$ = $1; } | SQL_IDENTIFIED { $$ = make_str("identified"); } | SQL_INDICATOR { $$ = make_str("indicator"); } | SQL_INT { $$ = make_str("int"); } + | SQL_KEY_MEMBER { $$ = make_str("key_member"); } + | SQL_LENGTH { $$ = make_str("length"); } | SQL_LONG { $$ = make_str("long"); } + | SQL_NAME { $$ = make_str("name"); } + | SQL_NULLABLE { $$ = make_str("nullable"); } + | SQL_OCTET_LENGTH { $$ = make_str("octet_length"); } | SQL_OFF { $$ = make_str("off"); } | SQL_OPEN { $$ = make_str("open"); } | SQL_PREPARE { $$ = make_str("prepare"); } | SQL_RELEASE { $$ = make_str("release"); } + | SQL_RETURNED_LENGTH { $$ = make_str("returned_length"); } + | SQL_RETURNED_OCTET_LENGTH { $$ = make_str("returned_octet_length"); } + | SQL_SCALE { $$ = make_str("scale"); } | SQL_SECTION { $$ = make_str("section"); } | SQL_SHORT { $$ = make_str("short"); } | SQL_SIGNED { $$ = make_str("signed"); } @@ -4586,23 +4649,32 @@ ECPGAllocateDescr: SQL_ALLOCATE SQL_DESCRIPTOR ident * read from descriptor */ -ECPGGetDescHeaderItem: cvariable '=' ident { - push_assignment($1,$3); +ECPGGetDescHeaderItem: cvariable '=' desc_header_item { + push_assignment($1, $3); } -ECPGGetDescItem: cvariable '=' ident { - push_assignment($1,$3); -} - | cvariable '=' TYPE_P { - push_assignment($1,"type"); -} - | cvariable '=' PRECISION { - push_assignment($1,"precision"); -} - | cvariable '=' SQL_INDICATOR { - push_assignment($1,"indicator"); +desc_header_item: SQL_COUNT { $$ = ECPGd_count; } + +ECPGGetDescItem: cvariable '=' descriptor_item { + push_assignment($1, $3); } +descriptor_item: SQL_DATA { $$ = ECPGd_data; } + | SQL_DATETIME_INTERVAL_CODE { $$ = ECPGd_di_code; } + | SQL_DATETIME_INTERVAL_PRECISION { $$ = ECPGd_di_precision; } + | SQL_INDICATOR { $$ = ECPGd_indicator; } + | SQL_KEY_MEMBER { $$ = ECPGd_key_member; } + | SQL_LENGTH { $$ = ECPGd_length; } + | SQL_NAME { $$ = ECPGd_name; } + | SQL_NULLABLE { $$ = ECPGd_nullable; } + | SQL_OCTET_LENGTH { $$ = ECPGd_octet; } + | PRECISION { $$ = ECPGd_precision; } + | SQL_RETURNED_LENGTH { $$ = ECPGd_length; } + | SQL_RETURNED_OCTET_LENGTH { $$ = ECPGd_ret_octet; } + | SQL_SCALE { $$ = ECPGd_scale; } + | TYPE_P { $$ = ECPGd_type; } + ; + ECPGGetDescHeaderItems: ECPGGetDescHeaderItem | ECPGGetDescHeaderItems ',' ECPGGetDescHeaderItem; @@ -4613,9 +4685,9 @@ ECPGGetDescriptorHeader: SQL_GET SQL_DESCRIPTOR ident ECPGGetDescHeaderItems { $$ = $3; } ECPGGetDescriptor: SQL_GET SQL_DESCRIPTOR ident SQL_VALUE cvariable ECPGGetDescItems - { $$ = $3; descriptor_index = $5; } + { $$.str = $5; $$.name = $3; } | SQL_GET SQL_DESCRIPTOR ident SQL_VALUE Iconst ECPGGetDescItems - { $$ = $3; descriptor_index = $5; } + { $$.str = $5; $$.name = $3; } /***************************************************************************** * @@ -5049,7 +5121,7 @@ ident: IDENT { $$ = $1; } * C stuff */ -symbol: IDENT { $$ = $1; } +symbol: ident { $$ = $1; } cpp_line: CPP_LINE { $$ = $1; } diff --git a/src/interfaces/ecpg/preproc/type.c b/src/interfaces/ecpg/preproc/type.c index 039939fe035..eff50f6a812 100644 --- a/src/interfaces/ecpg/preproc/type.c +++ b/src/interfaces/ecpg/preproc/type.c @@ -163,7 +163,7 @@ get_type(enum ECPGttype typ) return ("ECPGt_NO_INDICATOR"); break; case ECPGt_char_variable: /* string that should not be - * quoted */ + * quoted */ return ("ECPGt_char_variable"); break; default: @@ -198,12 +198,13 @@ static void ECPGdump_a_struct(FILE *o, const char *name, const char *ind_name, l void ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * typ, const char *ind_name, struct ECPGtype * ind_typ, const char *prefix, const char *ind_prefix) { +#if 0 if (ind_typ == NULL) { ind_typ = &ecpg_no_indicator; ind_name = "no_indicator"; } - +#endif switch (typ->typ) { case ECPGt_array: @@ -248,7 +249,8 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * typ, const char *in break; default: ECPGdump_a_simple(o, name, typ->typ, typ->size, -1, NULL, prefix); - ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix); + if (ind_typ != NULL) + ECPGdump_a_simple(o, ind_name, ind_typ->typ, ind_typ->size, -1, NULL, ind_prefix); break; } } @@ -399,3 +401,60 @@ ECPGfree_type(struct ECPGtype * typ) } free(typ); } + +const char * +get_dtype(enum ECPGdtype typ) +{ + switch (typ) + { + case ECPGd_count: + return ("ECPGd_countr"); + break; + case ECPGd_data: + return ("ECPGd_data"); + break; + case ECPGd_di_code: + return ("ECPGd_di_code"); + break; + case ECPGd_di_precision: + return ("ECPGd_di_precision"); + break; + case ECPGd_indicator: + return ("ECPGd_indicator"); + break; + case ECPGd_key_member: + return ("ECPGd_key_member"); + break; + case ECPGd_length: + return ("ECPGd_length"); + break; + case ECPGd_name: + return ("ECPGd_name"); + break; + case ECPGd_nullable: + return ("ECPGd_nullable"); + break; + case ECPGd_octet: + return ("ECPGd_octet"); + break; + case ECPGd_precision: + return ("ECPGd_precision"); + break; + case ECPGd_ret_length: + return ("ECPGd_ret_length"); + case ECPGd_ret_octet: + return ("ECPGd_ret_octet"); + break; + case ECPGd_scale: + return ("ECPGd_scale"); + break; + case ECPGd_type: + return ("ECPGd_type"); + break; + default: + sprintf(errortext, "illegal descriptor item %d\n", typ); + yyerror(errortext); + } + + return NULL; +} diff --git a/src/interfaces/ecpg/preproc/type.h b/src/interfaces/ecpg/preproc/type.h index dd393d0d40e..29525c392c3 100644 --- a/src/interfaces/ecpg/preproc/type.h +++ b/src/interfaces/ecpg/preproc/type.h @@ -148,9 +148,9 @@ struct descriptor struct assignment { - char *variable; - char *value; - struct assignment *next; + char *variable; + enum ECPGdtype value; + struct assignment *next; }; enum errortype {ET_WARN, ET_ERROR, ET_FATAL}; diff --git a/src/interfaces/ecpg/preproc/variable.c b/src/interfaces/ecpg/preproc/variable.c index df458dcc070..8cbb1d38777 100644 --- a/src/interfaces/ecpg/preproc/variable.c +++ b/src/interfaces/ecpg/preproc/variable.c @@ -222,8 +222,9 @@ dump_variables(struct arguments * list, int mode) /* Then the current element and its indicator */ ECPGdump_a_type(yyout, list->variable->name, list->variable->type, - (list->indicator->type->typ != ECPGt_NO_INDICATOR) ? list->indicator->name : NULL, - (list->indicator->type->typ != ECPGt_NO_INDICATOR) ? list->indicator->type : NULL, NULL, NULL); +/* (list->indicator->type->typ != ECPGt_NO_INDICATOR) ? list->indicator->name : NULL, + (list->indicator->type->typ != ECPGt_NO_INDICATOR) ? list->indicator->type : NULL, NULL, NULL);*/ + list->indicator->name, list->indicator->type, NULL, NULL); /* Then release the list element. */ if (mode != 0) diff --git a/src/interfaces/ecpg/test/dyntest.pgc b/src/interfaces/ecpg/test/dyntest.pgc index 6317ba5fe02..3698cf685f5 100644 --- a/src/interfaces/ecpg/test/dyntest.pgc +++ b/src/interfaces/ecpg/test/dyntest.pgc @@ -2,7 +2,7 @@ * * Copyright (c) 2000, Christof Petig <christof.petig@wtal.de> * - * $Header: /cvsroot/pgsql/src/interfaces/ecpg/test/Attic/dyntest.pgc,v 1.2 2000/02/17 19:48:58 meskes Exp $ + * $Header: /cvsroot/pgsql/src/interfaces/ecpg/test/Attic/dyntest.pgc,v 1.3 2000/02/22 19:57:12 meskes Exp $ */ #include <stdio.h> @@ -30,6 +30,10 @@ int main(int argc,char **argv) char QUERY[1024]; exec sql end declare section; int done=0; + FILE *dbgs; + + if ((dbgs = fopen("log", "w")) != NULL) + ECPGdebug(1, dbgs); snprintf(QUERY,sizeof QUERY,"select * from %s",argc>1?argv[1]:"pg_tables"); @@ -123,5 +127,9 @@ int main(int argc,char **argv) exec sql close MYCURS; exec sql deallocate descriptor MYDESC; + + if (dbgs != NULL) + fclose(dbgs); + return 0; } diff --git a/src/interfaces/ecpg/test/test2.pgc b/src/interfaces/ecpg/test/test2.pgc index 2c5d16c4448..99175d39a9f 100644 --- a/src/interfaces/ecpg/test/test2.pgc +++ b/src/interfaces/ecpg/test/test2.pgc @@ -47,8 +47,8 @@ exec sql end declare section; strcpy(msg, "insert"); exec sql insert into meskes(name, married, children) values ('Petra', '19900404', 3); - exec sql insert into meskes(name, born, age, married, children) values ('Michael', 19660117, 33, '19900404', 3); - exec sql insert into meskes(name, born, age) values ('Carsten', 19910103, 8); + exec sql insert into meskes(name, born, age, married, children) values ('Michael', 19660117, 34, '19900404', 3); + exec sql insert into meskes(name, born, age) values ('Carsten', 19910103,9); exec sql insert into meskes(name, born, age) values ('Marc', 19930907, 6); exec sql insert into meskes(name, born, age) values ('Chris', 19970923, 2); diff --git a/src/interfaces/ecpg/test/test3.pgc b/src/interfaces/ecpg/test/test3.pgc index 8ba8995e334..9e3e4398df5 100644 --- a/src/interfaces/ecpg/test/test3.pgc +++ b/src/interfaces/ecpg/test/test3.pgc @@ -39,8 +39,8 @@ exec sql end declare section; strcpy(msg, "insert"); exec sql insert into meskes(name, married, children) values (:wifesname, '19900404', 3); - exec sql insert into meskes(name, born, age, married, children) values ('Michael', 19660117, 33, '19900404', 3); - exec sql insert into meskes(name, born, age) values ('Carsten', 19910103, 8); + exec sql insert into meskes(name, born, age, married, children) values ('Michael', 19660117, 34, '19900404', 3); + exec sql insert into meskes(name, born, age) values ('Carsten', 19910103, 9); exec sql insert into meskes(name, born, age) values ('Marc', 19930907, 6); exec sql insert into meskes(name, born, age) values ('Chris', 19970923, 2); |