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:
Marc G. Fournier 1998-02-27 12:59:33 +00:00
parent 1a6de0760d
commit 96ac738269
13 changed files with 163 additions and 88 deletions

View File

@ -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'

View File

@ -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

View File

@ -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,...);

View File

@ -43,3 +43,5 @@ enum ECPGttype
};
#define IS_SIMPLE_TYPE(type) ((type) >= ECPGt_char && (type) <= ECPGt_varchar2)
const char * ECPGtype_name(enum ECPGttype);

View File

@ -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

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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; }

View File

@ -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
| '[' | ']' | ',' | '=' | '*' | '(' | ')'

View File

@ -3,6 +3,7 @@
#include <stdlib.h>
#include "type.h"
#include "extern.h"
/* malloc + error check */
void *

View File

@ -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);

View File

@ -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);
}

View File

@ -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;