From 96ac738269d04c1402f1f459bfdfe0a11d979471 Mon Sep 17 00:00:00 2001 From: "Marc G. Fournier" Date: Fri, 27 Feb 1998 12:59:33 +0000 Subject: [PATCH] From: Michael Meskes No more shift/reduce conflicts. Also all other bugs I know about are fixed. --- src/interfaces/ecpg/ChangeLog | 9 +++ src/interfaces/ecpg/TODO | 1 + src/interfaces/ecpg/include/ecpglib.h | 4 +- src/interfaces/ecpg/include/ecpgtype.h | 2 + src/interfaces/ecpg/lib/Makefile.in | 18 +++-- src/interfaces/ecpg/lib/ecpglib.c | 8 +- src/interfaces/ecpg/preproc/ecpg.c | 4 +- src/interfaces/ecpg/preproc/pgc.l | 7 ++ src/interfaces/ecpg/preproc/preproc.y | 54 +++++++++---- src/interfaces/ecpg/preproc/type.c | 1 + src/interfaces/ecpg/test/mm.sql | 8 -- src/interfaces/ecpg/test/perftest.pgc | 101 +++++++++++++++++-------- src/interfaces/ecpg/test/test2.pgc | 26 +++---- 13 files changed, 159 insertions(+), 84 deletions(-) diff --git a/src/interfaces/ecpg/ChangeLog b/src/interfaces/ecpg/ChangeLog index 8501e99dc2..44f87208f0 100644 --- a/src/interfaces/ecpg/ChangeLog +++ b/src/interfaces/ecpg/ChangeLog @@ -62,3 +62,12 @@ Wed Feb 25 15:46:50 CET 1998 - corrected whenever continue handling - removed whenever break +Fri Feb 27 10:51:38 CET 1998 + + - corrected parser to accept '::int2' + +Fri Feb 27 12:00:55 CET 1998 + + - removed all shift/reduce conflicts + - allow syntax 'fetch cursor' as well as 'fetch in cursor' + diff --git a/src/interfaces/ecpg/TODO b/src/interfaces/ecpg/TODO index a10dbd7521..8385553963 100644 --- a/src/interfaces/ecpg/TODO +++ b/src/interfaces/ecpg/TODO @@ -59,3 +59,4 @@ There is no way yet to fill a complete array with one call except arrays of ecpg cannot use pointer variables except [unsigned] char * +List all commands as sqlcommand, not just S_SYMBOL diff --git a/src/interfaces/ecpg/include/ecpglib.h b/src/interfaces/ecpg/include/ecpglib.h index a19b1a4f7a..b506908ebc 100644 --- a/src/interfaces/ecpg/include/ecpglib.h +++ b/src/interfaces/ecpg/include/ecpglib.h @@ -5,8 +5,8 @@ bool ECPGconnect(const char *dbname); bool ECPGdo(int, char *,...); bool ECPGcommit(int); bool ECPGrollback(int); -bool ECPGfinish(); -bool ECPGstatus(); +bool ECPGfinish(void); +bool ECPGstatus(void); void ECPGlog(const char *format,...); diff --git a/src/interfaces/ecpg/include/ecpgtype.h b/src/interfaces/ecpg/include/ecpgtype.h index 35bac4d028..5cecc9e2e1 100644 --- a/src/interfaces/ecpg/include/ecpgtype.h +++ b/src/interfaces/ecpg/include/ecpgtype.h @@ -43,3 +43,5 @@ enum ECPGttype }; #define IS_SIMPLE_TYPE(type) ((type) >= ECPGt_char && (type) <= ECPGt_varchar2) + +const char * ECPGtype_name(enum ECPGttype); diff --git a/src/interfaces/ecpg/lib/Makefile.in b/src/interfaces/ecpg/lib/Makefile.in index 9917d169c2..34faf548c1 100644 --- a/src/interfaces/ecpg/lib/Makefile.in +++ b/src/interfaces/ecpg/lib/Makefile.in @@ -8,6 +8,10 @@ SO_MINOR_VERSION=0 PORTNAME=@PORTNAME@ +ifdef KRBVERS +CFLAGS+= $(KRBFLAGS) +endif + # Shared library stuff shlib := install-shlib-dep := @@ -20,10 +24,12 @@ ifeq ($(PORTNAME), linux) endif endif ifeq ($(PORTNAME), bsd) - install-shlib-dep := install-shlib - shlib := libecpg.so.$(SO_MAJOR_VERSION).$(SO_MINOR_VERSION) - LDFLAGS_SL = -x -Bshareable -Bforcearchive - CFLAGS += $(CFLAGS_SL) + ifdef BSD_SHLIB + install-shlib-dep := install-shlib + shlib := libecpg.so.$(SO_MAJOR_VERSION).$(SO_MINOR_VERSION) + LDFLAGS_SL = -x -Bshareable -Bforcearchive + CFLAGS += $(CFLAGS_SL) + endif endif #ifeq ($(PORTNAME), i386_solaris) # install-shlib-dep := install-shlib @@ -61,6 +67,6 @@ uninstall:: libecpg.a : libecpg.a(ecpglib.o) libecpg.a(typename.o) ecpglib.o : ecpglib.c ../include/ecpglib.h ../include/ecpgtype.h - $(CC) -I../include $(PQ_INCLUDE) -c ecpglib.c + $(CC) $(CFLAGS) -I../include $(PQ_INCLUDE) -c ecpglib.c typename.o : typename.c ../include/ecpgtype.h - $(CC) -I../include $(PQ_INCLUDE) -c typename.c + $(CC) $(CFLAGS) -I../include $(PQ_INCLUDE) -c typename.c diff --git a/src/interfaces/ecpg/lib/ecpglib.c b/src/interfaces/ecpg/lib/ecpglib.c index f5778f9ac3..301b43d6c7 100644 --- a/src/interfaces/ecpg/lib/ecpglib.c +++ b/src/interfaces/ecpg/lib/ecpglib.c @@ -18,11 +18,11 @@ #include #include +#include +#include #include #include #include -#include -#include static PGconn *simple_connection = NULL; static int simple_debug = 0; @@ -639,14 +639,14 @@ ECPGconnect(const char *dbname) bool -ECPGstatus() +ECPGstatus(void) { return PQstatus(simple_connection) != CONNECTION_BAD; } bool -ECPGfinish() +ECPGfinish(void) { if (simple_connection != NULL) { diff --git a/src/interfaces/ecpg/preproc/ecpg.c b/src/interfaces/ecpg/preproc/ecpg.c index 483a7c52fc..e31d4cfd42 100644 --- a/src/interfaces/ecpg/preproc/ecpg.c +++ b/src/interfaces/ecpg/preproc/ecpg.c @@ -29,9 +29,7 @@ usage(char *progname) int main(int argc, char *const argv[]) { - char c, - out_option = 0; - int fnr; + int fnr, c, out_option = 0; while ((c = getopt(argc, argv, "vdo:")) != EOF) { diff --git a/src/interfaces/ecpg/preproc/pgc.l b/src/interfaces/ecpg/preproc/pgc.l index 68b22ed464..75a9708322 100644 --- a/src/interfaces/ecpg/preproc/pgc.l +++ b/src/interfaces/ecpg/preproc/pgc.l @@ -28,11 +28,14 @@ do [dD][oO] end [eE][nN][dD] exec [eE][xX][eE][cC] execute [eE][xX][eE][cC][uU][tT][eE] +fetch [fF][eE][tT][cC][hH] found [fF][oO][uU][nN][dD] +from [fF][rR][oO][mM] go [gG][oO] goto [gG][oO][tT][oO] immediate [iI][mM][mM][eE][dD][iI][aA][tT][eE] include [iI][nN][cC][lL][uU][dD][eE] +in [iI][nN] into [iI][nN][tT][oO] not [nN][oO][tT] open [oO][pP][eE][nN] @@ -63,6 +66,7 @@ work [wW][oO][rR][kK] {commit} { dbg(SQL_COMMIT); return SQL_COMMIT; } {release} { dbg(SQL_RELEASE); return SQL_RELEASE; } {work} { dbg(SQL_WORK); return SQL_WORK; } +{fetch} { dbg(SQL_FETCH); return SQL_FETCH; } {rollback} { dbg(SQL_ROLLBACK); return SQL_ROLLBACK; } {whenever} { dbg(SQL_WHENEVER); return SQL_WHENEVER; } {sqlerror} { dbg(SQL_SQLERROR); return SQL_SQLERROR; } @@ -70,10 +74,12 @@ work [wW][oO][rR][kK] {not}{ws}{found} { dbg(SQL_NOT_FOUND); return SQL_NOT_FOUND; } {continue} { dbg(SQL_CONTINUE); return SQL_CONTINUE; } {into} { dbg(SQL_INTO); return SQL_INTO; } +{in} { dbg(SQL_IN); return SQL_IN; } {goto} { dbg(SQL_GOTO); return SQL_GOTO; } {go}{ws}{to} { dbg(SQL_GOTO); return SQL_GOTO; } {stop} { dbg(SQL_STOP); return SQL_STOP; } {do} { dbg(SQL_DO); return SQL_DO; } +{from} { dbg(SQL_FROM); return SQL_FROM; } {length} { dbg(S_LENGTH); return S_LENGTH; } @@ -144,6 +150,7 @@ struct { dbg(S_STRUCT); return S_STRUCT; } \* { dbg(*); return('*'); } ":" { dbg(:); return ':'; } +"::" { dbg(SQL_CONV); return SQL_CONV; } {ws} { ECHO; } . { dbg(.); return S_ANYTHING; } diff --git a/src/interfaces/ecpg/preproc/preproc.y b/src/interfaces/ecpg/preproc/preproc.y index 30b9cb9ade..a3bdc7224a 100644 --- a/src/interfaces/ecpg/preproc/preproc.y +++ b/src/interfaces/ecpg/preproc/preproc.y @@ -42,10 +42,6 @@ print_action(struct when *w) { switch (w->code) { - case W_CONTINUE: fprintf(yyout, "continue;"); - break; - case W_BREAK: fprintf(yyout, "break;"); - break; case W_SQLPRINT: fprintf(yyout, "sqlprint();"); break; case W_GOTO: fprintf(yyout, "goto %s;", w->str); @@ -224,12 +220,12 @@ dump_variables(struct arguments * list) struct when action; } -%token SQL_START SQL_SEMI SQL_STRING SQL_INTO +%token SQL_START SQL_SEMI SQL_STRING SQL_INTO SQL_IN %token SQL_BEGIN SQL_END SQL_DECLARE SQL_SECTION SQL_INCLUDE %token SQL_CONNECT SQL_OPEN SQL_EXECUTE SQL_IMMEDIATE %token SQL_COMMIT SQL_ROLLBACK SQL_RELEASE SQL_WORK SQL_WHENEVER -%token SQL_SQLERROR SQL_NOT_FOUND SQL_CONTINUE -%token SQL_DO SQL_GOTO SQL_SQLPRINT SQL_STOP +%token SQL_SQLERROR SQL_NOT_FOUND SQL_CONTINUE SQL_FROM SQL_FETCH +%token SQL_DO SQL_GOTO SQL_SQLPRINT SQL_STOP SQL_CONV %token S_SYMBOL S_LENGTH S_ANYTHING S_LABEL %token S_VARCHAR S_VARCHAR2 @@ -241,11 +237,11 @@ dump_variables(struct arguments * list) %type type type_detailed varchar_type simple_type struct_type string_type /* % type array_type pointer_type */ %type symbol label -%type maybe_storage_clause varchar_tag db_name +%type maybe_storage_clause varchar_tag db_name cursor %type simple_tag char_tag %type index length %type action -%type canything sqlanything both_anything vartext commit_release +%type canything sqlanything both_anything vartext commit_release sqlcommand %% prog : statements; @@ -262,6 +258,7 @@ statement : sqldeclaration | sqlexecute | sqlwhenever | sqlstatement + | sqlfetch | cthing | blockstart | blockend; @@ -573,9 +570,30 @@ label : S_LABEL { $$ = name; } +sqlfetch: SQL_START SQL_FETCH { + reset_variables(); + fprintf(yyout, "ECPGdo(__LINE__, \"fetch in "); +} cursor { + fwrite(yytext, yyleng, 1, yyout); + fwrite(" ", 1, 1, yyout); +} SQL_INTO into_list SQL_SEMI { + /* Dump */ + fprintf(yyout, "\", "); + dump_variables(argsinsert); + fprintf(yyout, "ECPGt_EOIT, "); + dump_variables(argsresult); + fprintf(yyout, "ECPGt_EORT );"); + whenever_action(); +} + +cursor: SQL_IN S_SYMBOL | S_SYMBOL; + sqlstatement : SQL_START { /* Reset stack */ reset_variables(); fprintf(yyout, "ECPGdo(__LINE__, \""); +} sqlcommand { + fwrite(yytext, yyleng, 1, yyout); + fwrite(" ", 1, 1, yyout); } sqlstatement_words SQL_SEMI { /* Dump */ fprintf(yyout, "\", "); @@ -584,7 +602,10 @@ sqlstatement : SQL_START { /* Reset stack */ dump_variables(argsresult); fprintf(yyout, "ECPGt_EORT );"); whenever_action(); -}; +} + +/* FIXME: instead of S_SYMBOL we should list all possible commands */ +sqlcommand : S_SYMBOL | SQL_DECLARE; sqlstatement_words : sqlstatement_word | sqlstatement_words sqlstatement_word; @@ -594,7 +615,10 @@ sqlstatement_word : ':' symbol add_variable(&argsinsert, find_variable($2)); fprintf(yyout, " ;; "); } - | SQL_INTO into_list { } + | SQL_INTO into_list SQL_FROM { + fwrite(yytext, yyleng, 1, yyout); + fwrite(" ", 1, 1, yyout); + } | sqlanything { fwrite(yytext, yyleng, 1, yyout); @@ -610,7 +634,7 @@ sqlstatement_word : ':' symbol into_list : ':' symbol { add_variable(&argsresult, find_variable($2)); } - | into_list ',' ':' symbol { + | into_list ',' ':' symbol{ add_variable(&argsresult, find_variable($4)); }; @@ -627,10 +651,10 @@ sqlanything : both_anything; both_anything : S_LENGTH | S_VARCHAR | S_VARCHAR2 | S_LONG | S_SHORT | S_INT | S_CHAR | S_FLOAT | S_DOUBLE | S_BOOL | SQL_OPEN | SQL_CONNECT - | SQL_STRING + | SQL_STRING | SQL_CONV | SQL_BEGIN | SQL_END - | SQL_DECLARE | SQL_SECTION - | SQL_INCLUDE + | SQL_DECLARE | SQL_SECTION | SQL_FETCH | SQL_FROM + | SQL_INCLUDE | SQL_IN | S_SYMBOL | S_LABEL | S_STATIC | S_EXTERN | S_AUTO | S_CONST | S_REGISTER | S_STRUCT | '[' | ']' | ',' | '=' | '*' | '(' | ')' diff --git a/src/interfaces/ecpg/preproc/type.c b/src/interfaces/ecpg/preproc/type.c index f5ff41c8c7..074e8b7493 100644 --- a/src/interfaces/ecpg/preproc/type.c +++ b/src/interfaces/ecpg/preproc/type.c @@ -3,6 +3,7 @@ #include #include "type.h" +#include "extern.h" /* malloc + error check */ void * diff --git a/src/interfaces/ecpg/test/mm.sql b/src/interfaces/ecpg/test/mm.sql index 4f3357b7e8..e69de29bb2 100644 --- a/src/interfaces/ecpg/test/mm.sql +++ b/src/interfaces/ecpg/test/mm.sql @@ -1,8 +0,0 @@ -create table meskes(name char8, born int4, age int2); - -insert into meskes(name, born) values ('Petra', 19661202, 31); -insert into meskes(name, born) values ('Michael', 19660117, 32); -insert into meskes(name, born) values ('Carsten', 19910103, 7); -insert into meskes(name, born) values ('Marc', 19930907, 4); -insert into meskes(name, born) values ('Chris', 19970923, 0); - diff --git a/src/interfaces/ecpg/test/perftest.pgc b/src/interfaces/ecpg/test/perftest.pgc index 9fb63fe6fa..6e212cf6b9 100644 --- a/src/interfaces/ecpg/test/perftest.pgc +++ b/src/interfaces/ecpg/test/perftest.pgc @@ -4,14 +4,18 @@ exec sql include sqlca; -#define SQLCODE sqlca.sqlcode +exec sql whenever sqlerror sqlprint; +exec sql whenever not found sqlprint; -void -db_error (char *msg) +static void +print_result(long sec, long usec, char *text) { - sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0'; - printf ("%s: db error %s\n", msg, sqlca.sqlerrm.sqlerrmc); - exit (1); + if (usec < 0) + { + sec--; + usec+=1000000; + } + printf("I needed %ld seconds and %ld microseconds for the %s test.\n", sec, usec, text); } int @@ -22,19 +26,17 @@ exec sql begin declare section; exec sql end declare section; struct timeval tvs, tve; - gettimeofday(&tvs, NULL); - exec sql connect 'mm'; - if (SQLCODE) - db_error ("connect"); - exec sql create table perftest(number int4, ascii char16); - if (SQLCODE) - db_error ("create t"); + exec sql create table perftest1(number int4, ascii char16); + + exec sql create unique index number1 on perftest1(number); + + exec sql create table perftest2(number int4, next_number int4); - exec sql create unique index number on perftest(number); - if (SQLCODE) - db_error ("create i"); + exec sql create unique index number2 on perftest2(number); + + gettimeofday(&tvs, NULL); for (i = 0;i < 1407; i++) { @@ -43,30 +45,69 @@ exec sql end declare section; exec sql end declare section; sprintf(text, "%ld", i); - exec sql insert into perftest(number, ascii) values (:i, :text); - if (SQLCODE) - db_error ("insert"); + exec sql insert into perftest1(number, ascii) values (:i, :text); + exec sql insert into perftest2(number, next_number) values (:i, :i+1); + + exec sql commit; + } + + gettimeofday(&tve, NULL); + + print_result(tve.tv_sec - tvs.tv_sec, tve.tv_usec - tvs.tv_usec, "insert"); + + gettimeofday(&tvs, NULL); + + for (i = 0;i < 1407; i++) + { + exec sql begin declare section; + char text[16]; + exec sql end declare section; + + exec sql select ascii into :text from perftest1 where number = :i; + + exec sql commit; + } + + gettimeofday(&tve, NULL); + + print_result(tve.tv_sec - tvs.tv_sec, tve.tv_usec - tvs.tv_usec, "selection&projection"); + + gettimeofday(&tvs, NULL); + + for (i = 0;i < 1407; i++) + { + exec sql begin declare section; + char text[16]; + exec sql end declare section; + + exec sql select perftest1.ascii into :text from perftest1, perftest2 where perftest1.number = perftest2.number and perftest2.number = :i; exec sql commit; - if (SQLCODE) - db_error ("commit"); } - exec sql drop index number; - if (SQLCODE) - db_error ("drop i"); + gettimeofday(&tve, NULL); + + print_result(tve.tv_sec - tvs.tv_sec, tve.tv_usec - tvs.tv_usec, "join"); + + gettimeofday(&tvs, NULL); - exec sql drop table perftest; - if (SQLCODE) - db_error ("drop t"); + exec sql update perftest2 set next_number = next_number + 1; exec sql commit; - if (SQLCODE) - db_error ("commit"); gettimeofday(&tve, NULL); - printf("I needed %ld seconds and %ld microseconds for this test\n", tve.tv_sec - tvs.tv_sec, tve.tv_usec - tvs.tv_usec); + print_result(tve.tv_sec - tvs.tv_sec, tve.tv_usec - tvs.tv_usec, "update"); + + exec sql drop index number2; + + exec sql drop table perftest2; + + exec sql drop index number1; + + exec sql drop table perftest1; + + exec sql commit; return (0); } diff --git a/src/interfaces/ecpg/test/test2.pgc b/src/interfaces/ecpg/test/test2.pgc index ed11be6c2a..54a6d6e30a 100644 --- a/src/interfaces/ecpg/test/test2.pgc +++ b/src/interfaces/ecpg/test/test2.pgc @@ -4,15 +4,14 @@ exec sql include sqlca; extern void ECPGdebug(int n, FILE *dbgs); -exec sql whenever not found sqlprint; -exec sql whenever sqlerror do db_error(msg); +exec sql whenever not found do set_not_found(); +exec sql whenever sqlerror sqlprint; -void -db_error (char *msg) +static int not_found = 0; +static void +set_not_found(void) { - sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0'; - printf ("%s: db error %s\n", msg, sqlca.sqlerrm.sqlerrmc); - exit (1); + not_found = 1; } int @@ -50,18 +49,13 @@ exec sql end declare section; exec sql open cur; - while (1) { - /* make sure we leave this loop */ - exec sql whenever not found break; - + while (not_found == 0) { strcpy(msg, "fetch"); - exec sql fetch in cur into :personal; - printf ("%8.8s was born %d (age = %d)\n", personal.name.arr, personal.birth.born, personal.birth.age); + exec sql fetch cur into :personal; + if (not_found == 0) + printf ("%8.8s was born %d (age = %d)\n", personal.name.arr, personal.birth.born, personal.birth.age); } - /* back to normal behaviour */ - exec sql whenever not found sqlprint; - strcpy(msg, "close"); exec sql close cur; -- 2.40.0