From: Michael Meskes <meskes@topsystem.de>
No more shift/reduce conflicts. Also all other bugs I know about are fixed.
This commit is contained in:
parent
1a6de0760d
commit
96ac738269
|
@ -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'
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,...);
|
||||
|
||||
|
|
|
@ -43,3 +43,5 @@ enum ECPGttype
|
|||
};
|
||||
|
||||
#define IS_SIMPLE_TYPE(type) ((type) >= ECPGt_char && (type) <= ECPGt_varchar2)
|
||||
|
||||
const char * ECPGtype_name(enum ECPGttype);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <libpq-fe.h>
|
||||
#include <libpq/pqcomm.h>
|
||||
#include <ecpgtype.h>
|
||||
#include <ecpglib.h>
|
||||
#include <sqlca.h>
|
||||
#include <libpq-fe.h>
|
||||
#include <libpq/pqcomm.h>
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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]
|
|||
<SQL>{commit} { dbg(SQL_COMMIT); return SQL_COMMIT; }
|
||||
<SQL>{release} { dbg(SQL_RELEASE); return SQL_RELEASE; }
|
||||
<SQL>{work} { dbg(SQL_WORK); return SQL_WORK; }
|
||||
<SQL>{fetch} { dbg(SQL_FETCH); return SQL_FETCH; }
|
||||
<SQL>{rollback} { dbg(SQL_ROLLBACK); return SQL_ROLLBACK; }
|
||||
<SQL>{whenever} { dbg(SQL_WHENEVER); return SQL_WHENEVER; }
|
||||
<SQL>{sqlerror} { dbg(SQL_SQLERROR); return SQL_SQLERROR; }
|
||||
|
@ -70,10 +74,12 @@ work [wW][oO][rR][kK]
|
|||
<SQL>{not}{ws}{found} { dbg(SQL_NOT_FOUND); return SQL_NOT_FOUND; }
|
||||
<SQL>{continue} { dbg(SQL_CONTINUE); return SQL_CONTINUE; }
|
||||
<SQL>{into} { dbg(SQL_INTO); return SQL_INTO; }
|
||||
<SQL>{in} { dbg(SQL_IN); return SQL_IN; }
|
||||
<SQL>{goto} { dbg(SQL_GOTO); return SQL_GOTO; }
|
||||
<SQL>{go}{ws}{to} { dbg(SQL_GOTO); return SQL_GOTO; }
|
||||
<SQL>{stop} { dbg(SQL_STOP); return SQL_STOP; }
|
||||
<SQL>{do} { dbg(SQL_DO); return SQL_DO; }
|
||||
<SQL>{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('*'); }
|
||||
|
||||
<SQL>":" { dbg(:); return ':'; }
|
||||
<SQL>"::" { dbg(SQL_CONV); return SQL_CONV; }
|
||||
|
||||
{ws} { ECHO; }
|
||||
. { dbg(.); return S_ANYTHING; }
|
||||
|
|
|
@ -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 <tagname> SQL_START SQL_SEMI SQL_STRING SQL_INTO
|
||||
%token <tagname> SQL_START SQL_SEMI SQL_STRING SQL_INTO SQL_IN
|
||||
%token <tagname> SQL_BEGIN SQL_END SQL_DECLARE SQL_SECTION SQL_INCLUDE
|
||||
%token <tagname> SQL_CONNECT SQL_OPEN SQL_EXECUTE SQL_IMMEDIATE
|
||||
%token <tagname> SQL_COMMIT SQL_ROLLBACK SQL_RELEASE SQL_WORK SQL_WHENEVER
|
||||
%token <tagname> SQL_SQLERROR SQL_NOT_FOUND SQL_CONTINUE
|
||||
%token <tagname> SQL_DO SQL_GOTO SQL_SQLPRINT SQL_STOP
|
||||
%token <tagname> SQL_SQLERROR SQL_NOT_FOUND SQL_CONTINUE SQL_FROM SQL_FETCH
|
||||
%token <tagname> SQL_DO SQL_GOTO SQL_SQLPRINT SQL_STOP SQL_CONV
|
||||
|
||||
%token <tagname> S_SYMBOL S_LENGTH S_ANYTHING S_LABEL
|
||||
%token <tagname> S_VARCHAR S_VARCHAR2
|
||||
|
@ -241,11 +237,11 @@ dump_variables(struct arguments * list)
|
|||
%type <type> type type_detailed varchar_type simple_type struct_type string_type
|
||||
/* % type <type> array_type pointer_type */
|
||||
%type <symbolname> symbol label
|
||||
%type <tagname> maybe_storage_clause varchar_tag db_name
|
||||
%type <tagname> maybe_storage_clause varchar_tag db_name cursor
|
||||
%type <type_enum> simple_tag char_tag
|
||||
%type <indexsize> index length
|
||||
%type <action> action
|
||||
%type <tagname> canything sqlanything both_anything vartext commit_release
|
||||
%type <tagname> 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 {
|
|||
$<symbolname>$ = 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
|
||||
| '[' | ']' | ',' | '=' | '*' | '(' | ')'
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include "type.h"
|
||||
#include "extern.h"
|
||||
|
||||
/* malloc + error check */
|
||||
void *
|
||||
|
|
|
@ -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);
|
||||
|
|
@ -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 number on perftest(number);
|
||||
if (SQLCODE)
|
||||
db_error ("create i");
|
||||
exec sql create unique index number1 on perftest1(number);
|
||||
|
||||
exec sql create table perftest2(number int4, next_number int4);
|
||||
|
||||
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;
|
||||
if (SQLCODE)
|
||||
db_error ("commit");
|
||||
}
|
||||
|
||||
exec sql drop index number;
|
||||
if (SQLCODE)
|
||||
db_error ("drop i");
|
||||
|
||||
exec sql drop table perftest;
|
||||
if (SQLCODE)
|
||||
db_error ("drop t");
|
||||
|
||||
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, "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;
|
||||
}
|
||||
|
||||
gettimeofday(&tve, NULL);
|
||||
|
||||
print_result(tve.tv_sec - tvs.tv_sec, tve.tv_usec - tvs.tv_usec, "join");
|
||||
|
||||
gettimeofday(&tvs, NULL);
|
||||
|
||||
exec sql update perftest2 set next_number = next_number + 1;
|
||||
|
||||
exec sql commit;
|
||||
|
||||
gettimeofday(&tve, NULL);
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue