No more shift/reduce conflicts. Also all other bugs I know about are fixed.
- 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'
+
ecpg cannot use pointer variables except [unsigned] char *
+List all commands as sqlcommand, not just S_SYMBOL
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,...);
};
#define IS_SIMPLE_TYPE(type) ((type) >= ECPGt_char && (type) <= ECPGt_varchar2)
+
+const char * ECPGtype_name(enum ECPGttype);
PORTNAME=@PORTNAME@
+ifdef KRBVERS
+CFLAGS+= $(KRBFLAGS)
+endif
+
# Shared library stuff
shlib :=
install-shlib-dep :=
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
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
#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;
bool
-ECPGstatus()
+ECPGstatus(void)
{
return PQstatus(simple_connection) != CONNECTION_BAD;
}
bool
-ECPGfinish()
+ECPGfinish(void)
{
if (simple_connection != NULL)
{
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)
{
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]
<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; }
<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; }
\* { dbg(*); return('*'); }
<SQL>":" { dbg(:); return ':'; }
+<SQL>"::" { dbg(SQL_CONV); return SQL_CONV; }
{ws} { ECHO; }
. { dbg(.); return S_ANYTHING; }
{
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);
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
%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;
| sqlexecute
| sqlwhenever
| sqlstatement
+ | sqlfetch
| cthing
| blockstart
| blockend;
$<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, "\", ");
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;
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);
into_list : ':' symbol {
add_variable(&argsresult, find_variable($2));
}
- | into_list ',' ':' symbol {
+ | into_list ',' ':' symbol{
add_variable(&argsresult, find_variable($4));
};
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
| '[' | ']' | ',' | '=' | '*' | '(' | ')'
#include <stdlib.h>
#include "type.h"
+#include "extern.h"
/* malloc + error check */
void *
-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);
-
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
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++)
{
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);
}
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
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;