Commit 80f7c413 authored by Bruce Momjian's avatar Bruce Momjian

Here's my next patch to bring ecpg to version 1.1. It now correctly

handles all transaction commands and the exec sql include command.

Michael Meskes
parent 561aead3
...@@ -71,3 +71,18 @@ Fri Feb 27 12:00:55 CET 1998 ...@@ -71,3 +71,18 @@ Fri Feb 27 12:00:55 CET 1998
- removed all shift/reduce conflicts - removed all shift/reduce conflicts
- allow syntax 'fetch cursor' as well as 'fetch in cursor' - allow syntax 'fetch cursor' as well as 'fetch in cursor'
Fri Mar 13 11:37:16 CET 1998
- finished transaction handling, needs only one function in ecpglib now
old functions are still supported for compatibility
- set library to version 1.1.0
Fri Mar 13 13:35:13 CET 1998
- exec sql include includes files during parsing
- set parser to version 1.1.0
- added -I option to ecpg to set include path
Mon Mar 16 15:09:10 CET 1998
- fixed parser to print correct filename and line number
...@@ -59,4 +59,7 @@ There is no way yet to fill a complete array with one call except arrays of ...@@ -59,4 +59,7 @@ There is no way yet to fill a complete array with one call except arrays of
ecpg cannot use pointer variables except [unsigned] char * ecpg cannot use pointer variables except [unsigned] char *
List all commands as sqlcommand, not just S_SYMBOL List all commands as sqlcommand, not just S_SYMBOL or even better rewrite
pareser to be equivalent to backend´s parser.
Set standard include paths.
#include <c.h> #include <c.h>
#ifdef __cplusplus
extern "C" {
#endif
void ECPGdebug(int, FILE *); void ECPGdebug(int, FILE *);
bool ECPGconnect(const char *dbname); bool ECPGconnect(const char *dbname);
bool ECPGdo(int, char *,...); bool ECPGdo(int, char *,...);
bool ECPGcommit(int); bool ECPGtrans(int, const char *);
bool ECPGrollback(int);
bool ECPGfinish(void); bool ECPGfinish(void);
bool ECPGstatus(void); bool ECPGstatus(void);
void ECPGlog(const char *format,...); void ECPGlog(const char *format,...);
/* These functions are only kept for compatibility reasons. */
/* Use ECPGtrans instead. */
bool ECPGcommit(int);
bool ECPGrollback(int);
#ifdef LIBPQ_FE_H #ifdef LIBPQ_FE_H
bool ECPGsetdb(PGconn *); bool ECPGsetdb(PGconn *);
...@@ -32,3 +40,7 @@ void sqlprint(void); ...@@ -32,3 +40,7 @@ void sqlprint(void);
/* define this for simplicity as well as compatibility */ /* define this for simplicity as well as compatibility */
#define SQLCODE sqlca.sqlcode #define SQLCODE sqlca.sqlcode
#ifdef __cplusplus
}
#endif
...@@ -29,6 +29,10 @@ ...@@ -29,6 +29,10 @@
*/ */
#include <stdio.h> #include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
enum ECPGttype enum ECPGttype
{ {
ECPGt_char = 1, ECPGt_unsigned_char, ECPGt_short, ECPGt_unsigned_short, ECPGt_char = 1, ECPGt_unsigned_char, ECPGt_short, ECPGt_unsigned_short,
...@@ -45,3 +49,7 @@ enum ECPGttype ...@@ -45,3 +49,7 @@ enum ECPGttype
#define IS_SIMPLE_TYPE(type) ((type) >= ECPGt_char && (type) <= ECPGt_varchar2) #define IS_SIMPLE_TYPE(type) ((type) >= ECPGt_char && (type) <= ECPGt_varchar2)
const char * ECPGtype_name(enum ECPGttype); const char * ECPGtype_name(enum ECPGttype);
#ifdef __cplusplus
}
#endif
#ifndef POSTGRES_SQLCA_H #ifndef POSTGRES_SQLCA_H
#define POSTGRES_SQLCA_H #define POSTGRES_SQLCA_H
#ifdef __cplusplus
extern "C" {
#endif
struct sqlca struct sqlca
{ {
int sqlcode; int sqlcode;
...@@ -12,3 +16,8 @@ struct sqlca ...@@ -12,3 +16,8 @@ struct sqlca
} sqlca; } sqlca;
#endif #endif
#ifdef __cplusplus
}
#endif
...@@ -4,7 +4,7 @@ include $(SRCDIR)/Makefile.global ...@@ -4,7 +4,7 @@ include $(SRCDIR)/Makefile.global
PQ_INCLUDE=-I$(SRCDIR)/interfaces/libpq PQ_INCLUDE=-I$(SRCDIR)/interfaces/libpq
SO_MAJOR_VERSION=1 SO_MAJOR_VERSION=1
SO_MINOR_VERSION=0 SO_MINOR_VERSION=1
PORTNAME=@PORTNAME@ PORTNAME=@PORTNAME@
......
...@@ -572,14 +572,14 @@ ECPGdo(int lineno, char *query,...) ...@@ -572,14 +572,14 @@ ECPGdo(int lineno, char *query,...)
bool bool
ECPGcommit(int lineno) ECPGtrans(int lineno, const char * transaction)
{ {
PGresult *res; PGresult *res;
ECPGlog("ECPGcommit line %d\n", lineno); ECPGlog("ECPGtrans line %d action = %s\n", lineno, transaction);
if ((res = PQexec(simple_connection, "end")) == NULL) if ((res = PQexec(simple_connection, transaction)) == NULL)
{ {
register_error(-1, "Error committing line %d.", lineno); register_error(-1, "Error in transaction processing line %d.", lineno);
return (FALSE); return (FALSE);
} }
PQclear(res); PQclear(res);
...@@ -587,23 +587,18 @@ ECPGcommit(int lineno) ...@@ -587,23 +587,18 @@ ECPGcommit(int lineno)
return (TRUE); return (TRUE);
} }
/* include these for compatibility */
bool bool
ECPGrollback(int lineno) ECPGcommit(int lineno)
{ {
PGresult *res; return(ECPGtrans(lineno, "end"));
ECPGlog("ECPGrollback line %d\n", lineno);
if ((res = PQexec(simple_connection, "abort")) == NULL)
{
register_error(-1, "Error rolling back line %d.", lineno);
return (FALSE);
}
PQclear(res);
committed = 1;
return (TRUE);
} }
bool
ECPGrollback(int lineno)
{
return(ECPGtrans(lineno, "abort"));
}
bool bool
ECPGsetdb(PGconn *newcon) ECPGsetdb(PGconn *newcon)
......
...@@ -2,10 +2,12 @@ SRCDIR= ../../.. ...@@ -2,10 +2,12 @@ SRCDIR= ../../..
include $(SRCDIR)/Makefile.global include $(SRCDIR)/Makefile.global
MAJOR_VERSION=1 MAJOR_VERSION=1
MINOR_VERSION=0 MINOR_VERSION=1
PATCHLEVEL=0 PATCHLEVEL=0
CFLAGS+=-I../include -DMAJOR_VERSION=$(MAJOR_VERSION) -DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL) CFLAGS+=-I../include -DMAJOR_VERSION=$(MAJOR_VERSION) \
-DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL) \
-DINCLUDE_PATH=\"$(DESTDIR)$(HEADERDIR)\"
all:: ecpg all:: ecpg
......
...@@ -9,6 +9,8 @@ ...@@ -9,6 +9,8 @@
#include <getopt.h> #include <getopt.h>
#else #else
#include <unistd.h> #include <unistd.h>
extern int optind;
extern char *optarg;
#endif #endif
#include <stdlib.h> #include <stdlib.h>
#if defined(HAVE_STRING_H) #if defined(HAVE_STRING_H)
...@@ -19,19 +21,37 @@ ...@@ -19,19 +21,37 @@
#include "extern.h" #include "extern.h"
struct _include_path *include_paths;
static void static void
usage(char *progname) usage(char *progname)
{ {
fprintf(stderr, "ecpg - the postgresql preprocessor, version: %d.%d.%d\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL); fprintf(stderr, "ecpg - the postgresql preprocessor, version: %d.%d.%d\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL);
fprintf(stderr, "Usage: %s: [-v] [-d] [ -o outout file name] file1 [file2] ...\n", progname); fprintf(stderr, "Usage: %s: [-v] [-d] [-I include path] [ -o output file name] file1 [file2] ...\n", progname);
}
static void
add_include_path(char * path)
{
struct _include_path *ip = include_paths;
include_paths = mm_alloc(sizeof(struct _include_path));
include_paths->path = path;
include_paths->next = ip;
} }
int int
main(int argc, char *const argv[]) main(int argc, char *const argv[])
{ {
int fnr, c, out_option = 0; int fnr, c, out_option = 0;
struct _include_path *ip;
while ((c = getopt(argc, argv, "vdo:")) != EOF)
add_include_path("/usr/include");
add_include_path(INCLUDE_PATH);
add_include_path("/usr/local/include");
add_include_path(".");
while ((c = getopt(argc, argv, "vdo:I:")) != EOF)
{ {
switch (c) switch (c)
{ {
...@@ -45,64 +65,71 @@ main(int argc, char *const argv[]) ...@@ -45,64 +65,71 @@ main(int argc, char *const argv[])
case 'd': case 'd':
debugging = 1; debugging = 1;
break; break;
case 'I':
add_include_path(optarg);
break;
case 'v': case 'v':
fprintf(stderr, "ecpg - the postgresql preprocessor, version: %d.%d.%d\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL);
fprintf(stderr, "exec sql include ... search starts here:\n");
for (ip = include_paths; ip != NULL; ip = ip->next)
fprintf(stderr, " %s\n", ip->path);
fprintf(stderr, "End of search list.\n");
return (0);
default: default:
usage(argv[0]); usage(argv[0]);
return (1);
} }
} }
if (optind >= argc) /* no files specified */ if (optind >= argc) /* no files specified */
{
usage(argv[0]); usage(argv[0]);
return(1);
}
else else
{ {
/* after the options there must not be anything but filenames */ /* after the options there must not be anything but filenames */
for (fnr = optind; fnr < argc; fnr++) for (fnr = optind; fnr < argc; fnr++)
{ {
char *filename, char *output_filename, *ptr2ext;
*ptr2ext;
int ext = 0;
filename = mm_alloc(strlen(argv[fnr]) + 4); input_filename = mm_alloc(strlen(argv[fnr]) + 5);
strcpy(filename, argv[fnr]); strcpy(input_filename, argv[fnr]);
ptr2ext = strrchr(filename, '.'); ptr2ext = strrchr(input_filename, '.');
/* no extension or extension not equal .pgc */ /* no extension? */
if (ptr2ext == NULL || strcmp(ptr2ext, ".pgc") != 0) if (ptr2ext == NULL)
{ {
if (ptr2ext == NULL) ptr2ext = input_filename + strlen(input_filename);
ext = 1; /* we need this information a while later */
ptr2ext = filename + strlen(filename); /* no extension => add .pgc */
ptr2ext[0] = '.'; ptr2ext[0] = '.';
ptr2ext[1] = 'p';
ptr2ext[2] = 'g';
ptr2ext[3] = 'c';
ptr2ext[4] = '\0';
} }
/* make extension = .c */
ptr2ext[1] = 'c';
ptr2ext[2] = '\0';
if (out_option == 0)/* calculate the output name */ if (out_option == 0)/* calculate the output name */
{ {
yyout = fopen(filename, "w"); output_filename = strdup(input_filename);
ptr2ext = strrchr(output_filename, '.');
/* make extension = .c */
ptr2ext[1] = 'c';
ptr2ext[2] = '\0';
yyout = fopen(output_filename, "w");
if (yyout == NULL) if (yyout == NULL)
{ {
perror(filename); perror(output_filename);
free(filename); free(output_filename);
free(input_filename);
continue; continue;
} }
} }
if (ext == 1)
{
/* no extension => add .pgc */
ptr2ext = strrchr(filename, '.');
ptr2ext[1] = 'p';
ptr2ext[2] = 'g';
ptr2ext[3] = 'c';
ptr2ext[4] = '\0';
input_filename = filename;
}
else
input_filename = argv[fnr];
yyin = fopen(input_filename, "r"); yyin = fopen(input_filename, "r");
if (yyin == NULL) if (yyin == NULL)
perror(argv[fnr]); perror(argv[fnr]);
...@@ -117,12 +144,14 @@ main(int argc, char *const argv[]) ...@@ -117,12 +144,14 @@ main(int argc, char *const argv[])
/* and parse the source */ /* and parse the source */
yyparse(); yyparse();
fclose(yyin); if (yyin != NULL)
fclose(yyin);
if (out_option == 0) if (out_option == 0)
fclose(yyout); fclose(yyout);
} }
free(filename); free(output_filename);
free(input_filename);
} }
} }
return (0); return (0);
......
...@@ -8,6 +8,11 @@ extern int yylineno, ...@@ -8,6 +8,11 @@ extern int yylineno,
extern FILE *yyin, extern FILE *yyin,
*yyout; *yyout;
struct _include_path { char * path;
struct _include_path * next;
};
extern struct _include_path *include_paths;
/* functions */ /* functions */
......
/* Copyright comment! */ /* Copyright comment! */
%{ %{
#include <sys/types.h> #include <sys/types.h>
#include <limits.h>
#if defined(HAVE_STRING_H)
#include <string.h>
#else
#include <strings.h>
#endif
#include "type.h" #include "type.h"
#include "y.tab.h" #include "y.tab.h"
#include "extern.h" #include "extern.h"
struct _yy_buffer { YY_BUFFER_STATE buffer;
long lineno;
char * filename;
struct _yy_buffer * next;
} *yy_buffer = NULL;
#define dbg(arg) if (debugging) fprintf(stderr, "DEBUG, %d: %s\n", yylineno, #arg); #define dbg(arg) if (debugging) fprintf(stderr, "DEBUG, %d: %s\n", yylineno, #arg);
%} %}
%option yylineno %option yylineno
%s C SQL %s C SQL incl
ccomment \/\*([^*]|\*[^/]|\*\*[^/])*\*\/ ccomment \/\*([^*]|\*[^/]|\*\*[^/])*\*\/
ws ([ \t\n][ \t\n]*|{ccomment})* ws ([ \t\n][ \t\n]*|{ccomment})*
letter [A-Za-z_] letter [A-Za-z_]
...@@ -19,6 +32,7 @@ symbol {letter}({letter}|{digit})* ...@@ -19,6 +32,7 @@ symbol {letter}({letter}|{digit})*
label ({letter}|{digit})* label ({letter}|{digit})*
string '[^']*' string '[^']*'
abort [aA][bB][oO][rR][tT]
begin [bB][eE][gG][iI][nN] begin [bB][eE][gG][iI][nN]
commit [cC][oO][mM][mM][iI][tT] commit [cC][oO][mM][mM][iI][tT]
connect [cC][oO][nN][nN][eE][cC][tT] connect [cC][oO][nN][nN][eE][cC][tT]
...@@ -46,21 +60,23 @@ sql [sS][qQ][lL] ...@@ -46,21 +60,23 @@ sql [sS][qQ][lL]
sqlerror [sS][qQ][lL][eE][rR][rR][oO][rR] sqlerror [sS][qQ][lL][eE][rR][rR][oO][rR]
sqlprint [sS][qQ][lL][pP][rR][iI][nN][tT] sqlprint [sS][qQ][lL][pP][rR][iI][nN][tT]
stop [sS][tT][oO][pP] stop [sS][tT][oO][pP]
transaction [tT][rR][aA][nN][sS][aA][cC][tT][iI][oO][nN]
to [tT][oO] to [tT][oO]
varchar [vV][aA][rR][cC][hH][aA][rR] varchar [vV][aA][rR][cC][hH][aA][rR]
varchar2 [vV][aA][rR][cC][hH][aA][rR]2 varchar2 [vV][aA][rR][cC][hH][aA][rR]2
whenever [wW][hH][eE][nN][eE][vV][eE][rR] whenever [wW][hH][eE][nN][eE][vV][eE][rR]
work [wW][oO][rR][kK] work [wW][oO][rR][kK]
vacuum [vV][aA][cC][uU][uU][mM]
%% %%
<C>{exec}{ws}{sql} { BEGIN SQL; dbg(SQL_START); return SQL_START; } <C>{exec}{ws}{sql} { BEGIN SQL; dbg(SQL_START); return SQL_START; }
<SQL>";" { BEGIN C; dbg(SQL_SEMI); return SQL_SEMI; } <SQL>";" { BEGIN C; dbg(SQL_SEMI); return SQL_SEMI; }
<SQL>{abort} { dbg(SQL_ABORT); return SQL_ABORT; }
<SQL>{begin} { dbg(SQL_BEGIN); return SQL_BEGIN; } <SQL>{begin} { dbg(SQL_BEGIN); return SQL_BEGIN; }
<SQL>{end} { dbg(SQL_END); return SQL_END; } <SQL>{end} { dbg(SQL_END); return SQL_END; }
<SQL>{declare} { dbg(SQL_DECLARE); return SQL_DECLARE; } <SQL>{declare} { dbg(SQL_DECLARE); return SQL_DECLARE; }
<SQL>{execute} { dbg(SQL_EXECUTE); return SQL_EXECUTE; } <SQL>{execute} { dbg(SQL_EXECUTE); return SQL_EXECUTE; }
<SQL>{immediate} { dbg(SQL_IMMEDIATE); return SQL_IMMEDIATE; } <SQL>{immediate} { dbg(SQL_IMMEDIATE); return SQL_IMMEDIATE; }
<SQL>{section} { dbg(SQL_SECTION); return SQL_SECTION; } <SQL>{section} { dbg(SQL_SECTION); return SQL_SECTION; }
<SQL>{include} { dbg(SQL_INCLUDE); return SQL_INCLUDE; }
<SQL>{connect} { dbg(SQL_CONNECT); return SQL_CONNECT; } <SQL>{connect} { dbg(SQL_CONNECT); return SQL_CONNECT; }
<SQL>{open} { dbg(SQL_OPEN); return SQL_OPEN; } <SQL>{open} { dbg(SQL_OPEN); return SQL_OPEN; }
<SQL>{commit} { dbg(SQL_COMMIT); return SQL_COMMIT; } <SQL>{commit} { dbg(SQL_COMMIT); return SQL_COMMIT; }
...@@ -80,7 +96,62 @@ work [wW][oO][rR][kK] ...@@ -80,7 +96,62 @@ work [wW][oO][rR][kK]
<SQL>{stop} { dbg(SQL_STOP); return SQL_STOP; } <SQL>{stop} { dbg(SQL_STOP); return SQL_STOP; }
<SQL>{do} { dbg(SQL_DO); return SQL_DO; } <SQL>{do} { dbg(SQL_DO); return SQL_DO; }
<SQL>{from} { dbg(SQL_FROM); return SQL_FROM; } <SQL>{from} { dbg(SQL_FROM); return SQL_FROM; }
<SQL>{transaction} { dbg(SQL_TRANSACTION); return SQL_TRANSACTION; }
<SQL>{vacuum} { dbg(SQL_VACUUM); return SQL_VACUUM; }
<C>{exec}{ws}{sql}{ws}{include} { BEGIN(incl); }
<incl>{ws} /* eat the whitespace */
<incl>[^ \t\n]+ { /* got the include file name */
struct _yy_buffer *yb;
struct _include_path *ip;
char inc_file[PATH_MAX];
yb = mm_alloc(sizeof(struct _yy_buffer));
yb->buffer = YY_CURRENT_BUFFER;
yb->lineno = yylineno;
yb->filename = input_filename;
yb->next = yy_buffer;
yy_buffer = yb;
if (yytext[strlen(yytext) - 1] == ';')
yytext[strlen(yytext) - 1] = '\0';
yyin = NULL;
for (ip = include_paths; yyin == NULL && ip != NULL; ip = ip->next)
{
if (strlen(ip->path) + strlen(yytext) + 3 > PATH_MAX)
{
fprintf(stderr, "Path %s/%s is too long, skipping.\n", ip->path, yytext);
continue;
}
sprintf (inc_file, "%s/%s", ip->path, yytext);
yyin = fopen( inc_file, "r" );
if (!yyin)
{
if (strcmp(inc_file + strlen(inc_file) - 2, ".h"))
{
strcat(inc_file, ".h");
yyin = fopen( inc_file, "r" );
}
}
}
if (!yyin)
{
fprintf(stderr, "Cannot open include file %s\n", yytext);
exit(1);
}
input_filename = strdup(inc_file);
yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE ));
yylineno = 0;
BEGIN C;
}
<incl>";" { BEGIN C; }
{length} { dbg(S_LENGTH); return S_LENGTH; } {length} { dbg(S_LENGTH); return S_LENGTH; }
{varchar} { dbg(S_VARCHAR); return S_VARCHAR; } {varchar} { dbg(S_VARCHAR); return S_VARCHAR; }
...@@ -154,6 +225,28 @@ struct { dbg(S_STRUCT); return S_STRUCT; } ...@@ -154,6 +225,28 @@ struct { dbg(S_STRUCT); return S_STRUCT; }
{ws} { ECHO; } {ws} { ECHO; }
. { dbg(.); return S_ANYTHING; } . { dbg(.); return S_ANYTHING; }
<<EOF>> { if (yy_buffer == NULL)
yyterminate();
else
{
struct _yy_buffer *yb = yy_buffer;
if (yyin != NULL)
fclose(yyin);
yy_delete_buffer( YY_CURRENT_BUFFER );
yy_switch_to_buffer(yy_buffer->buffer);
yylineno = yy_buffer->lineno;
free(input_filename);
input_filename = yy_buffer->filename;
yy_buffer = yy_buffer->next;
free(yb);
}
}
%% %%
void void
lex_init(void) lex_init(void)
......
...@@ -226,6 +226,7 @@ dump_variables(struct arguments * list) ...@@ -226,6 +226,7 @@ dump_variables(struct arguments * list)
%token <tagname> SQL_COMMIT SQL_ROLLBACK SQL_RELEASE SQL_WORK SQL_WHENEVER %token <tagname> SQL_COMMIT SQL_ROLLBACK SQL_RELEASE SQL_WORK SQL_WHENEVER
%token <tagname> SQL_SQLERROR SQL_NOT_FOUND SQL_CONTINUE SQL_FROM SQL_FETCH %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> SQL_DO SQL_GOTO SQL_SQLPRINT SQL_STOP SQL_CONV
%token <tagname> SQL_ABORT SQL_TRANSACTION SQL_VACUUM
%token <tagname> S_SYMBOL S_LENGTH S_ANYTHING S_LABEL %token <tagname> S_SYMBOL S_LENGTH S_ANYTHING S_LABEL
%token <tagname> S_VARCHAR S_VARCHAR2 %token <tagname> S_VARCHAR S_VARCHAR2
...@@ -236,32 +237,31 @@ dump_variables(struct arguments * list) ...@@ -236,32 +237,31 @@ dump_variables(struct arguments * list)
%type <type> type type_detailed varchar_type simple_type struct_type string_type %type <type> type type_detailed varchar_type simple_type struct_type string_type
/* % type <type> array_type pointer_type */ /* % type <type> array_type pointer_type */
%type <symbolname> symbol label %type <symbolname> symbol label transactionstmt
%type <tagname> maybe_storage_clause varchar_tag db_name cursor %type <tagname> maybe_storage_clause varchar_tag db_name cursor
%type <type_enum> simple_tag char_tag %type <type_enum> simple_tag char_tag
%type <indexsize> index length %type <indexsize> index length
%type <action> action %type <action> action
%type <tagname> canything sqlanything both_anything vartext commit_release sqlcommand %type <tagname> canything sqlanything both_anything vartext sqlcommand
%type <tagname> transbegin, transend, transabort
%% %%
prog : statements; prog : statements;
statements : /* empty */ statements : /* empty */
| statements statement; | statements statement;
statement : sqldeclaration statement : sqlconnect
| sqldeclaration
| sqlexecute
| sqlfetch
| sqlinclude | sqlinclude
| sqlconnect
| sqlopen | sqlopen
| sqlcommit
| sqlrollback
| sqlexecute
| sqlwhenever
| sqlstatement | sqlstatement
| sqlfetch | sqltransaction
| cthing | sqlwhenever
| blockstart | blockstart
| blockend; | blockend
| cthing;
sqldeclaration : sql_startdeclare sqldeclaration : sql_startdeclare
variable_declarations variable_declarations
...@@ -489,19 +489,32 @@ sqlgarbage : /* Empty */ ...@@ -489,19 +489,32 @@ sqlgarbage : /* Empty */
| sqlgarbage sqlanything; | sqlgarbage sqlanything;
sqlcommit : SQL_START commit_release SQL_SEMI { sqltransaction : SQL_START transactionstmt SQL_SEMI {
fprintf(yyout, "ECPGcommit(__LINE__);"); fprintf(yyout, "ECPGtrans(__LINE__, \"%s\");", $<symbolname>2);
whenever_action(); whenever_action();
} }
commit_release : SQL_COMMIT
| SQL_COMMIT SQL_RELEASE
| SQL_COMMIT SQL_WORK SQL_RELEASE;
sqlrollback : SQL_START SQL_ROLLBACK SQL_SEMI { transactionstmt: transbegin
fprintf(yyout, "ECPGrollback(__LINE__);"); {
whenever_action(); $<symbolname>$="begin";
}; }
| transend
{
$<symbolname>$="end";
}
| transabort
{
$<symbolname>$="abort";
}
transabort: SQL_ABORT SQL_TRANSACTION | SQL_ROLLBACK SQL_WORK
| SQL_ABORT | SQL_ROLLBACK;
transend: SQL_END SQL_TRANSACTION | SQL_COMMIT | SQL_COMMIT SQL_RELEASE
| SQL_COMMIT SQL_WORK SQL_RELEASE;
transbegin: SQL_BEGIN SQL_TRANSACTION | SQL_BEGIN SQL_WORK;
sqlexecute : SQL_START SQL_EXECUTE SQL_IMMEDIATE ':' symbol SQL_SEMI { sqlexecute : SQL_START SQL_EXECUTE SQL_IMMEDIATE ':' symbol SQL_SEMI {
fprintf(yyout, "ECPGdo(__LINE__, %s, ECPGt_EOIT, ECPGt_EORT );", $5); fprintf(yyout, "ECPGdo(__LINE__, %s, ECPGt_EOIT, ECPGt_EORT );", $5);
...@@ -605,9 +618,9 @@ sqlstatement : SQL_START { /* Reset stack */ ...@@ -605,9 +618,9 @@ sqlstatement : SQL_START { /* Reset stack */
} }
/* FIXME: instead of S_SYMBOL we should list all possible commands */ /* FIXME: instead of S_SYMBOL we should list all possible commands */
sqlcommand : S_SYMBOL | SQL_DECLARE; sqlcommand : S_SYMBOL | SQL_DECLARE | SQL_VACUUM;
sqlstatement_words : sqlstatement_word sqlstatement_words : /* empty */
| sqlstatement_words sqlstatement_word; | sqlstatement_words sqlstatement_word;
sqlstatement_word : ':' symbol sqlstatement_word : ':' symbol
......
...@@ -16,6 +16,7 @@ print_result(long sec, long usec, char *text) ...@@ -16,6 +16,7 @@ print_result(long sec, long usec, char *text)
usec+=1000000; usec+=1000000;
} }
printf("I needed %ld seconds and %ld microseconds for the %s test.\n", sec, usec, text); printf("I needed %ld seconds and %ld microseconds for the %s test.\n", sec, usec, text);
exec sql vacuum analyze;
} }
int int
...@@ -107,7 +108,5 @@ exec sql end declare section; ...@@ -107,7 +108,5 @@ exec sql end declare section;
exec sql drop table perftest1; exec sql drop table perftest1;
exec sql commit;
return (0); return (0);
} }
#include <stdio.h> #include <stdio.h>
exec sql include sqlca; exec sql include header_test;
extern void ECPGdebug(int n, FILE *dbgs); extern void ECPGdebug(int n, FILE *dbgs);
exec sql whenever not found do set_not_found();
exec sql whenever sqlerror sqlprint;
static int not_found = 0; static int not_found = 0;
static void static void
set_not_found(void) set_not_found(void)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment