Commit 186aeb1d authored by Marc G. Fournier's avatar Marc G. Fournier

From: Dr. Michael Meskes <meskes@online-club.de>

So this should finally get cursors working. There was an ugly bug in it.
parent 1c9a1250
...@@ -258,3 +258,15 @@ Tue Jul 7 15:14:14 CEST 1998 ...@@ -258,3 +258,15 @@ Tue Jul 7 15:14:14 CEST 1998
- Fixed some bugs in preproc.y - Fixed some bugs in preproc.y
- Set version to 2.3.4 - Set version to 2.3.4
Mon Jul 27 17:13:11 CEST 1998
- Changed text of error message to make emacs happy
Mon Aug 3 17:23:18 CEST 1998
- Added latest changes from gram.y resp. scan.l to
preproc.y resp. pgc.l
- Fixed cursor handling
- Set version to 2.3.5
- Set library version to 2.4
What happens to a cursor declaration with variables?
The complete structure definition has to be listed inside the declare The complete structure definition has to be listed inside the declare
section of the structure variable for ecpg to be able to understand it. section of the structure variable for ecpg to be able to understand it.
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#define ECPG_CONVERT_BOOL -207 #define ECPG_CONVERT_BOOL -207
#define ECPG_EMPTY -208 #define ECPG_EMPTY -208
#define ECPG_NO_CONN -209 #define ECPG_NO_CONN -209
#define ECPG_UNDECLARED_CURSOR -210
/* finally the backend error messages, they start at 300 */ /* finally the backend error messages, they start at 300 */
#define ECPG_PGSQL -300 #define ECPG_PGSQL -300
......
...@@ -13,6 +13,9 @@ bool ECPGdisconnect(int, const char *); ...@@ -13,6 +13,9 @@ bool ECPGdisconnect(int, const char *);
void ECPGlog(const char *format,...); void ECPGlog(const char *format,...);
bool ECPGdeclare(int, const char *, char *);
bool ECPGopen(int, const char *);
#ifdef LIBPQ_FE_H #ifdef LIBPQ_FE_H
bool ECPGsetdb(PGconn *); bool ECPGsetdb(PGconn *);
...@@ -32,6 +35,11 @@ struct ECPGgeneric_varchar ...@@ -32,6 +35,11 @@ struct ECPGgeneric_varchar
/* print an error message */ /* print an error message */
void sqlprint(void); void sqlprint(void);
struct cursor { const char *name;
char *command;
struct cursor *next;
};
/* define this for simplicity as well as compatibility */ /* define this for simplicity as well as compatibility */
#define SQLCODE sqlca.sqlcode #define SQLCODE sqlca.sqlcode
......
...@@ -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=2 SO_MAJOR_VERSION=2
SO_MINOR_VERSION=3 SO_MINOR_VERSION=4
PORTNAME=@PORTNAME@ PORTNAME=@PORTNAME@
......
...@@ -940,3 +940,56 @@ sqlprint(void) ...@@ -940,3 +940,56 @@ sqlprint(void)
sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0'; sqlca.sqlerrm.sqlerrmc[sqlca.sqlerrm.sqlerrml] = '\0';
printf("sql error %s\n", sqlca.sqlerrm.sqlerrmc); printf("sql error %s\n", sqlca.sqlerrm.sqlerrmc);
} }
/* keep a list of cursors */
struct cursor *cur = NULL;
bool ECPGdeclare(int lineno, const char *name, char *command)
{
struct cursor *ptr;
for (ptr = cur; ptr != NULL; ptr = ptr->next)
{
if (strcmp(name, ptr->name) == 0)
{
/* re-definition */
free(ptr->command);
ptr->command = command;
break;
}
}
if (ptr == NULL)
{
struct cursor *this = (struct cursor *) malloc(sizeof(struct cursor));
if (!this)
{
ECPGlog("out of memory\n");
register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
return false;
}
/* initial definition */
this->next = cur;
this->name = name;
this->command = command;
cur = this;
}
return(true);
}
bool ECPGopen(int lineno, const char *name)
{
struct cursor *ptr;
for (ptr = cur; ptr != NULL; ptr=ptr->next)
{
if (strcmp(ptr->name, name) == 0)
return(ECPGdo(lineno, ptr->command, ECPGt_EOIT, ECPGt_EORT));
}
ECPGlog("trying to open undeclared cursor %s\n", name);
register_error(ECPG_UNDECLARED_CURSOR, "trying to open undeclared cursor %s in line %d", name, lineno);
return(false);
}
...@@ -3,7 +3,7 @@ include $(SRCDIR)/Makefile.global ...@@ -3,7 +3,7 @@ include $(SRCDIR)/Makefile.global
MAJOR_VERSION=2 MAJOR_VERSION=2
MINOR_VERSION=3 MINOR_VERSION=3
PATCHLEVEL=4 PATCHLEVEL=5
CFLAGS+=-I../include -DMAJOR_VERSION=$(MAJOR_VERSION) \ CFLAGS+=-I../include -DMAJOR_VERSION=$(MAJOR_VERSION) \
-DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL) \ -DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL) \
......
...@@ -141,20 +141,6 @@ main(int argc, char *const argv[]) ...@@ -141,20 +141,6 @@ main(int argc, char *const argv[])
/* initialize lex */ /* initialize lex */
lex_init(); lex_init();
/* initialize cursor list */
for (ptr = cur; ptr != NULL;)
{
struct cursor *c;
free(ptr->name);
free(ptr->command);
c = ptr;
ptr = ptr->next;
free(c);
}
cur = NULL;
/* we need two includes and a constant */ /* we need two includes and a constant */
fprintf(yyout, "/* Processed by ecpg (%d.%d.%d) */\n/*These two include files are added by the preprocessor */\n#include <ecpgtype.h>\n#include <ecpglib.h>\n\nconst int no_auto_trans = %d;\n\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL, no_auto_trans); fprintf(yyout, "/* Processed by ecpg (%d.%d.%d) */\n/*These two include files are added by the preprocessor */\n#include <ecpgtype.h>\n#include <ecpglib.h>\n\nconst int no_auto_trans = %d;\n\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL, no_auto_trans);
......
...@@ -16,13 +16,6 @@ struct _include_path { char * path; ...@@ -16,13 +16,6 @@ struct _include_path { char * path;
extern struct _include_path *include_paths; extern struct _include_path *include_paths;
struct cursor { char *name;
char *command;
struct cursor *next;
};
extern struct cursor *cur;
/* This is a linked list of the variable names and types. */ /* This is a linked list of the variable names and types. */
struct variable struct variable
{ {
......
...@@ -335,7 +335,7 @@ cppline {space}*#.*(\\{space}*\n)*\n* ...@@ -335,7 +335,7 @@ cppline {space}*#.*(\\{space}*\n)*\n*
BEGIN(xm); BEGIN(xm);
for(i = 0; yytext[i]; i++) for(i = 0; yytext[i]; i++)
if (isupper(yytext[i])) if (isascii((unsigned char)yytext[i]) && isupper(yytext[i]))
yytext[i] = tolower(yytext[i]); yytext[i] = tolower(yytext[i]);
keyword = ScanKeywordLookup((char*)yytext); keyword = ScanKeywordLookup((char*)yytext);
...@@ -417,7 +417,7 @@ cppline {space}*#.*(\\{space}*\n)*\n* ...@@ -417,7 +417,7 @@ cppline {space}*#.*(\\{space}*\n)*\n*
ScanKeyword *keyword; ScanKeyword *keyword;
for(i = 0; yytext[i]; i++) for(i = 0; yytext[i]; i++)
if (isupper(yytext[i])) if (isascii((unsigned char)yytext[i]) && isupper(yytext[i]))
yytext[i] = tolower(yytext[i]); yytext[i] = tolower(yytext[i]);
keyword = ScanKeywordLookup((char*)yytext); keyword = ScanKeywordLookup((char*)yytext);
......
...@@ -8,6 +8,10 @@ ...@@ -8,6 +8,10 @@
#include "type.h" #include "type.h"
#include "extern.h" #include "extern.h"
#ifdef MULTIBYTE
#include "mb/pg_wchar.h"
#endif
#define STRUCT_DEPTH 128 #define STRUCT_DEPTH 128
/* /*
...@@ -22,9 +26,6 @@ static char *actual_storage[STRUCT_DEPTH]; ...@@ -22,9 +26,6 @@ static char *actual_storage[STRUCT_DEPTH];
/* temporarily store struct members while creating the data structure */ /* temporarily store struct members while creating the data structure */
struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL }; struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };
/* keep a list of cursors */
struct cursor *cur = NULL;
struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, {NULL}}; struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, 0L, {NULL}};
struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL}; struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
...@@ -542,7 +543,7 @@ output_statement(char * stmt, int mode) ...@@ -542,7 +543,7 @@ output_statement(char * stmt, int mode)
GRANT, GROUP, HAVING, HOUR_P, GRANT, GROUP, HAVING, HOUR_P,
IN, INNER_P, INSERT, INTERVAL, INTO, IS, IN, INNER_P, INSERT, INTERVAL, INTO, IS,
JOIN, KEY, LANGUAGE, LEADING, LEFT, LIKE, LOCAL, JOIN, KEY, LANGUAGE, LEADING, LEFT, LIKE, LOCAL,
MATCH, MINUTE_P, MONTH_P, MATCH, MINUTE_P, MONTH_P, NAMES,
NATIONAL, NATURAL, NCHAR, NO, NOT, NOTIFY, NULL_P, NUMERIC, NATIONAL, NATURAL, NCHAR, NO, NOT, NOTIFY, NULL_P, NUMERIC,
ON, OPTION, OR, ORDER, OUTER_P, ON, OPTION, OR, ORDER, OUTER_P,
PARTIAL, POSITION, PRECISION, PRIMARY, PRIVILEGES, PROCEDURE, PUBLIC, PARTIAL, POSITION, PRECISION, PRIMARY, PRIVILEGES, PROCEDURE, PUBLIC,
...@@ -570,7 +571,7 @@ output_statement(char * stmt, int mode) ...@@ -570,7 +571,7 @@ output_statement(char * stmt, int mode)
NEW, NONE, NOTHING, NOTNULL, OIDS, OPERATOR, PROCEDURAL, NEW, NONE, NOTHING, NOTNULL, OIDS, OPERATOR, PROCEDURAL,
RECIPE, RENAME, RESET, RETURNS, ROW, RULE, RECIPE, RENAME, RESET, RETURNS, ROW, RULE,
SEQUENCE, SETOF, SHOW, START, STATEMENT, STDIN, STDOUT, TRUSTED, SEQUENCE, SETOF, SHOW, START, STATEMENT, STDIN, STDOUT, TRUSTED,
VACUUM, VERBOSE, VERSION VACUUM, VERBOSE, VERSION, ENCODING
/* Keywords (obsolete; retain through next version for parser - thomas 1997-12-0 4) */ /* Keywords (obsolete; retain through next version for parser - thomas 1997-12-0 4) */
%token ARCHIVE %token ARCHIVE
...@@ -614,21 +615,20 @@ output_statement(char * stmt, int mode) ...@@ -614,21 +615,20 @@ output_statement(char * stmt, int mode)
%left '.' %left '.'
%left '[' ']' %left '[' ']'
%nonassoc TYPECAST %nonassoc TYPECAST
%nonassoc REDUCE
%left UNION %left UNION
%type <str> Iconst Sconst TransactionStmt CreateStmt UserId %type <str> Iconst Fconst Sconst TransactionStmt CreateStmt UserId
%type <str> CreateAsElement OptCreateAs CreateAsList CreateAsStmt %type <str> CreateAsElement OptCreateAs CreateAsList CreateAsStmt
%type <str> OptArchiveType OptInherit key_reference key_action %type <str> OptArchiveType OptInherit key_reference key_action
%type <str> key_match constraint_expr ColLabel SpecialRuleRelation %type <str> key_match constraint_expr ColLabel SpecialRuleRelation
%type <str> ColId default_expr ColQualifier columnDef ColQualList %type <str> ColId default_expr ColQualifier columnDef ColQualList
%type <str> ColConstraint ColConstraintElem default_list %type <str> ColConstraint ColConstraintElem default_list NumericOnly FloatOnly
%type <str> OptTableElementList OptTableElement TableConstraint %type <str> OptTableElementList OptTableElement TableConstraint
%type <str> ConstraintElem key_actions constraint_list TypeId %type <str> ConstraintElem key_actions constraint_list TypeId
%type <str> res_target_list res_target_el res_target_list2 %type <str> res_target_list res_target_el res_target_list2
%type <str> res_target_el2 opt_id relation_name database_name %type <str> res_target_el2 opt_id relation_name database_name
%type <str> access_method attr_name class index_name name func_name %type <str> access_method attr_name class index_name name func_name
%type <str> file_name recipe_name AexprConst ParamNo NumConst TypeId %type <str> file_name recipe_name AexprConst ParamNo TypeId
%type <str> in_expr_nodes not_in_expr_nodes a_expr b_expr %type <str> in_expr_nodes not_in_expr_nodes a_expr b_expr
%type <str> opt_indirection expr_list extract_list extract_arg %type <str> opt_indirection expr_list extract_list extract_arg
%type <str> position_list position_expr substr_list substr_from %type <str> position_list position_expr substr_list substr_from
...@@ -645,7 +645,7 @@ output_statement(char * stmt, int mode) ...@@ -645,7 +645,7 @@ output_statement(char * stmt, int mode)
%type <str> join_using where_clause relation_expr row_op sub_type %type <str> join_using where_clause relation_expr row_op sub_type
%type <str> opt_column_list insert_rest InsertStmt OptimizableStmt %type <str> opt_column_list insert_rest InsertStmt OptimizableStmt
%type <str> columnList DeleteStmt LockStmt UpdateStmt CursorStmt %type <str> columnList DeleteStmt LockStmt UpdateStmt CursorStmt
%type <str> NotifyStmt columnElem copy_dirn %type <str> NotifyStmt columnElem copy_dirn SubUnion
%type <str> copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary %type <str> copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
%type <str> opt_with_copy FetchStmt opt_direction fetch_how_many opt_portal_name %type <str> opt_with_copy FetchStmt opt_direction fetch_how_many opt_portal_name
%type <str> ClosePortalStmt DestroyStmt VacuumStmt opt_verbose %type <str> ClosePortalStmt DestroyStmt VacuumStmt opt_verbose
...@@ -661,15 +661,15 @@ output_statement(char * stmt, int mode) ...@@ -661,15 +661,15 @@ output_statement(char * stmt, int mode)
%type <str> RemoveOperStmt RenameStmt all_Op user_valid_clause %type <str> RemoveOperStmt RenameStmt all_Op user_valid_clause
%type <str> VariableSetStmt var_value zone_value VariableShowStmt %type <str> VariableSetStmt var_value zone_value VariableShowStmt
%type <str> VariableResetStmt AddAttrStmt alter_clause DropUserStmt %type <str> VariableResetStmt AddAttrStmt alter_clause DropUserStmt
%type <str> user_passwd_clause user_createdb_clause %type <str> user_passwd_clause user_createdb_clause opt_trans
%type <str> user_createuser_clause user_group_list user_group_clause %type <str> user_createuser_clause user_group_list user_group_clause
%type <str> CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList %type <str> CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList
%type <str> OptSeqElem TriggerForSpec TriggerForOpt TriggerForType %type <str> OptSeqElem TriggerForSpec TriggerForOpt TriggerForType
%type <str> TriggerFuncArgs DropTrigStmt TriggerOneEvent TriggerEvents %type <str> TriggerFuncArgs DropTrigStmt TriggerOneEvent TriggerEvents
%type <str> TriggerActionTime CreateTrigStmt DropPLangStmt PLangTrusted %type <str> TriggerActionTime CreateTrigStmt DropPLangStmt PLangTrusted
%type <str> CreatePLangStmt IntegerOnly TriggerFuncArgs TriggerFuncArg %type <str> CreatePLangStmt IntegerOnly TriggerFuncArgs TriggerFuncArg
%type <str> ViewStmt LoadStmt CreatedbStmt opt_database location %type <str> ViewStmt LoadStmt CreatedbStmt opt_database1 opt_database2 location
%type <str> DestroydbStmt ClusterStmt grantee RevokeStmt %type <str> DestroydbStmt ClusterStmt grantee RevokeStmt encoding
%type <str> GrantStmt privileges operation_commalist operation %type <str> GrantStmt privileges operation_commalist operation
%type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen open_opts %type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen open_opts
...@@ -737,10 +737,10 @@ stmt: AddAttrStmt { output_statement($1, 0); } ...@@ -737,10 +737,10 @@ stmt: AddAttrStmt { output_statement($1, 0); }
| RenameStmt { output_statement($1, 0); } | RenameStmt { output_statement($1, 0); }
| RevokeStmt { output_statement($1, 0); } | RevokeStmt { output_statement($1, 0); }
| OptimizableStmt { | OptimizableStmt {
if (strncmp($1, "/* declare" , sizeof("/* declare")-1) == 0) if (strncmp($1, "ECPGdeclare" , sizeof("ECPGdeclare")-1) == 0)
{ {
fputs($1, yyout); fputs($1, yyout);
output_line_number(); whenever_action(0);
free($1); free($1);
} }
else else
...@@ -775,7 +775,10 @@ stmt: AddAttrStmt { output_statement($1, 0); } ...@@ -775,7 +775,10 @@ stmt: AddAttrStmt { output_statement($1, 0); }
whenever_action(0); whenever_action(0);
free($1); free($1);
} }
| ECPGOpen { output_statement($1, 0); } | ECPGOpen { fprintf(yyout, "ECPGopen(__LINE__, %s);", $1);
whenever_action(0);
free($1);
}
| ECPGRelease { /* output already done */ } | ECPGRelease { /* output already done */ }
| ECPGSetConnection { | ECPGSetConnection {
fprintf(yyout, "ECPGsetconn(__LINE__, %s);", $1); fprintf(yyout, "ECPGsetconn(__LINE__, %s);", $1);
...@@ -898,7 +901,14 @@ VariableSetStmt: SET ColId TO var_value ...@@ -898,7 +901,14 @@ VariableSetStmt: SET ColId TO var_value
{ {
$$ = cat2_str(make1_str("set time zone"), $4); $$ = cat2_str(make1_str("set time zone"), $4);
} }
| SET NAMES encoding
{
#ifdef MB
$$ = cat2_str(make1_str("set names"), $3);
#else
yyerror("SET NAMES is not supported");
#endif
}
; ;
var_value: Sconst { $$ = $1; } var_value: Sconst { $$ = $1; }
...@@ -1403,6 +1413,20 @@ OptSeqElem: CACHE IntegerOnly ...@@ -1403,6 +1413,20 @@ OptSeqElem: CACHE IntegerOnly
} }
; ;
NumericOnly: FloatOnly { $$ = $1; }
| IntegerOnly { $$ = $1; }
FloatOnly: Fconst
{
$$ = $1;
}
| '-' Fconst
{
$$ = cat2_str(make1_str("-"), $2);
}
;
IntegerOnly: Iconst IntegerOnly: Iconst
{ {
$$ = $1; $$ = $1;
...@@ -1502,9 +1526,9 @@ TriggerFuncArg: Iconst ...@@ -1502,9 +1526,9 @@ TriggerFuncArg: Iconst
{ {
$$ = $1; $$ = $1;
} }
| FCONST | Fconst
{ {
$$ = make_name(); $$ = $1;
} }
| Sconst { $$ = $1; } | Sconst { $$ = $1; }
| ident { $$ = $1; } | ident { $$ = $1; }
...@@ -1569,7 +1593,7 @@ def_elem: def_name '=' def_arg { ...@@ -1569,7 +1593,7 @@ def_elem: def_name '=' def_arg {
def_arg: ColId { $$ = $1; } def_arg: ColId { $$ = $1; }
| all_Op { $$ = $1; } | all_Op { $$ = $1; }
| NumConst { $$ = $1; /* already a Value */ } | NumericOnly { $$ = $1; }
| Sconst { $$ = $1; } | Sconst { $$ = $1; }
| SETOF ColId | SETOF ColId
{ {
...@@ -2056,15 +2080,16 @@ ListenStmt: LISTEN relation_name ...@@ -2056,15 +2080,16 @@ ListenStmt: LISTEN relation_name
* (END) * (END)
* *
*****************************************************************************/ *****************************************************************************/
TransactionStmt: ABORT_TRANS TRANSACTION { $$ = make1_str("rollback"); } TransactionStmt: ABORT_TRANS opt_trans { $$ = make1_str("rollback"); }
| BEGIN_TRANS TRANSACTION { $$ = make1_str("begin transaction"); } | BEGIN_TRANS opt_trans { $$ = make1_str("begin transaction"); }
| BEGIN_TRANS WORK { $$ = make1_str("begin transaction"); } | COMMIT opt_trans { $$ = make1_str("commit"); }
| COMMIT WORK { $$ = make1_str("commit"); } | END_TRANS opt_trans { $$ = make1_str("commit"); }
| END_TRANS TRANSACTION { $$ = make1_str("commit"); } | ROLLBACK opt_trans { $$ = make1_str("rollback"); }
| ROLLBACK WORK { $$ = make1_str("rollback"); }
| ABORT_TRANS { $$ = make1_str("rollback"); } opt_trans: WORK { $$ = ""; }
| COMMIT { $$ = make1_str("commit"); } | TRANSACTION { $$ = ""; }
| ROLLBACK { $$ = make1_str("rollback"); } | /*EMPTY*/ { $$ = ""; }
;
/***************************************************************************** /*****************************************************************************
* *
...@@ -2101,21 +2126,40 @@ LoadStmt: LOAD file_name ...@@ -2101,21 +2126,40 @@ LoadStmt: LOAD file_name
* *
*****************************************************************************/ *****************************************************************************/
CreatedbStmt: CREATE DATABASE database_name opt_database CreatedbStmt: CREATE DATABASE database_name WITH opt_database1 opt_database2
{
if (strlen($5) == 0 || strlen($6) == 0)
yyerror("CREATE DATABASE WITH requires at least an option");
#ifndef MULTIBYTE
if (strlen($6) != 0)
yyerror("WITH ENCODING is not supported");
#endif
$$ = cat5_str(make1_str("create database"), $3, make1_str("with"), $5, $6);
}
| CREATE DATABASE database_name
{ {
$$ = cat3_str(make1_str("create database"), $3, $4); $$ = cat2_str(make1_str("create database"), $3);
} }
; ;
opt_database: WITH LOCATION '=' location { $$ = cat2_str(make1_str("with location ="), $4); } opt_database1: LOCATION '=' location { $$ = cat2_str(make1_str("location ="), $3); }
| /*EMPTY*/ { $$ = make1_str(""); } | /*EMPTY*/ { $$ = make1_str(""); }
; ;
opt_database2: ENCODING '=' encoding { $$ = cat2_str(make1_str("encoding ="), $3); }
| /*EMPTY*/ { $$ = NULL; }
;
location: Sconst { $$ = $1; } location: Sconst { $$ = $1; }
| DEFAULT { $$ = make1_str("default"); } | DEFAULT { $$ = make1_str("default"); }
| /*EMPTY*/ { $$ = make1_str(""); } | /*EMPTY*/ { $$ = make1_str(""); }
; ;
encoding: Sconst { $$ = $1; }
| DEFAULT { $$ = make1_str("default"); }
| /*EMPTY*/ { $$ = make1_str(""); }
;
/***************************************************************************** /*****************************************************************************
* *
* QUERY: * QUERY:
...@@ -2315,31 +2359,7 @@ CursorStmt: DECLARE name opt_binary CURSOR FOR ...@@ -2315,31 +2359,7 @@ CursorStmt: DECLARE name opt_binary CURSOR FOR
group_clause having_clause group_clause having_clause
union_clause sort_clause union_clause sort_clause
{ {
struct cursor *ptr, *this = (struct cursor *) mm_alloc(sizeof(struct cursor)); $$ = make5_str(make1_str("ECPGdeclare(__LINE__, \""), $2, make1_str("\", \""), cat4_str(cat5_str(cat5_str(make1_str("declare"), strdup($2), $3, make1_str("cursor for select"), $7), $8, $9, $10, $11), $12, $13, $14), make1_str("\");"));
this->name = strdup($2);
this->command = cat4_str(cat5_str(cat5_str(make1_str("declare"), strdup($2), $3, make1_str("cursor for select"), $7), $8, $9, $10, $11), $12, $13, $14);
this->next = NULL;
for (ptr = cur; ptr != NULL; ptr = ptr->next)
{
if (strcmp(this->name, ptr->name) == 0)
{
/* re-definition */
free(ptr->command);
ptr->command = this->command;
break;
}
}
if (ptr == NULL)
{
/* initial definition */
this->next = cur;
cur = this;
}
$$ = make5_str(make1_str("/* declare cursor \""), $2, make1_str("\" statement has been moved to location of open cursor \""), strdup($2), make1_str("\" statement. */"));
} }
; ;
...@@ -2361,6 +2381,15 @@ SelectStmt: SELECT opt_unique res_target_list2 ...@@ -2361,6 +2381,15 @@ SelectStmt: SELECT opt_unique res_target_list2
} }
; ;
SubSelect: SELECT opt_unique res_target_list2
from_clause where_clause
group_clause having_clause
union_clause
{
$$ =cat4_str(cat5_str(make1_str("select"), $2, $3, $4, $5), $6, $7, $8);
}
;
union_clause: UNION opt_union select_list union_clause: UNION opt_union select_list
{ {
$$ = cat3_str(make1_str("union"), $2, $3); $$ = cat3_str(make1_str("union"), $2, $3);
...@@ -2369,15 +2398,15 @@ union_clause: UNION opt_union select_list ...@@ -2369,15 +2398,15 @@ union_clause: UNION opt_union select_list
{ $$ = make1_str(""); } { $$ = make1_str(""); }
; ;
select_list: select_list UNION opt_union SubSelect select_list: select_list UNION opt_union SubUnion
{ {
$$ = cat4_str($1, make1_str("union"), $3, $4); $$ = cat4_str($1, make1_str("union"), $3, $4);
} }
| SubSelect | SubUnion
{ $$ = $1; } { $$ = $1; }
; ;
SubSelect: SELECT opt_unique res_target_list2 SubUnion: SELECT opt_unique res_target_list2
from_clause where_clause from_clause where_clause
group_clause having_clause group_clause having_clause
{ {
...@@ -2477,9 +2506,6 @@ groupby: ColId ...@@ -2477,9 +2506,6 @@ groupby: ColId
having_clause: HAVING a_expr having_clause: HAVING a_expr
{ {
#if FALSE
yyerror("HAVING clause not yet implemented");
#endif
$$ = cat2_str(make1_str("having"), $2); $$ = cat2_str(make1_str("having"), $2);
} }
| /*EMPTY*/ { $$ = make1_str(""); } | /*EMPTY*/ { $$ = make1_str(""); }
...@@ -3637,9 +3663,9 @@ AexprConst: Iconst ...@@ -3637,9 +3663,9 @@ AexprConst: Iconst
{ {
$$ = $1; $$ = $1;
} }
| FCONST | Fconst
{ {
$$ = make_name(); $$ = $1;
} }
| Sconst | Sconst
{ {
...@@ -3667,11 +3693,8 @@ ParamNo: PARAM ...@@ -3667,11 +3693,8 @@ ParamNo: PARAM
} }
; ;
NumConst: Iconst { $$ = $1; }
| FCONST { $$ = make_name(); }
;
Iconst: ICONST { $$ = make_name();}; Iconst: ICONST { $$ = make_name();};
Fconst: FCONST { $$ = make_name();};
Sconst: SCONST { Sconst: SCONST {
$$ = (char *)mm_alloc(strlen($1) + 3); $$ = (char *)mm_alloc(strlen($1) + 3);
$$[0]='\''; $$[0]='\'';
...@@ -3711,6 +3734,7 @@ ColId: ident { $$ = $1; } ...@@ -3711,6 +3734,7 @@ ColId: ident { $$ = $1; }
| DELIMITERS { $$ = make1_str("delimiters"); } | DELIMITERS { $$ = make1_str("delimiters"); }
| DOUBLE { $$ = make1_str("double"); } | DOUBLE { $$ = make1_str("double"); }
| EACH { $$ = make1_str("each"); } | EACH { $$ = make1_str("each"); }
| ENCODING { $$ = make1_str("encoding"); }
| FUNCTION { $$ = make1_str("function"); } | FUNCTION { $$ = make1_str("function"); }
| INCREMENT { $$ = make1_str("increment"); } | INCREMENT { $$ = make1_str("increment"); }
| INDEX { $$ = make1_str("index"); } | INDEX { $$ = make1_str("index"); }
...@@ -4197,22 +4221,7 @@ execstring: cvariable | ...@@ -4197,22 +4221,7 @@ execstring: cvariable |
* open is an open cursor, at the moment this has to be removed * open is an open cursor, at the moment this has to be removed
*/ */
ECPGOpen: SQL_OPEN name open_opts { ECPGOpen: SQL_OPEN name open_opts {
struct cursor *ptr; $$ = make3_str(make1_str("\""), $2, make1_str("\""));
for (ptr = cur; ptr != NULL; ptr=ptr->next)
{
if (strcmp(ptr->name, $2) == 0)
{
$$ = ptr->command;
break;
}
}
if (ptr == NULL)
{
sprintf(errortext, "unknown cursor %s opened", $2);
yyerror(errortext);
}
}; };
open_opts: /* empty */ { $$ = make1_str(""); } open_opts: /* empty */ { $$ = make1_str(""); }
...@@ -4633,7 +4642,7 @@ c_thing: c_anything | ';' { $$ = make1_str(";"); } ...@@ -4633,7 +4642,7 @@ c_thing: c_anything | ';' { $$ = make1_str(";"); }
c_anything: IDENT { $$ = $1; } c_anything: IDENT { $$ = $1; }
| CSTRING { $$ = make3_str(make1_str("\""), $1, make1_str("\"")); } | CSTRING { $$ = make3_str(make1_str("\""), $1, make1_str("\"")); }
| Iconst { $$ = $1; } | Iconst { $$ = $1; }
| FCONST { $$ = make_name(); } | Fconst { $$ = $1; }
| '*' { $$ = make1_str("*"); } | '*' { $$ = make1_str("*"); }
| S_AUTO { $$ = make1_str("auto"); } | S_AUTO { $$ = make1_str("auto"); }
| S_BOOL { $$ = make1_str("bool"); } | S_BOOL { $$ = make1_str("bool"); }
...@@ -4662,13 +4671,13 @@ c_anything: IDENT { $$ = $1; } ...@@ -4662,13 +4671,13 @@ c_anything: IDENT { $$ = $1; }
do_anything: IDENT { $$ = $1; } do_anything: IDENT { $$ = $1; }
| CSTRING { $$ = make3_str(make1_str("\""), $1, make1_str("\""));} | CSTRING { $$ = make3_str(make1_str("\""), $1, make1_str("\""));}
| Iconst { $$ = $1; } | Iconst { $$ = $1; }
| FCONST { $$ = make_name(); } | Fconst { $$ = $1; }
| ',' { $$ = make1_str(","); } | ',' { $$ = make1_str(","); }
var_anything: IDENT { $$ = $1; } var_anything: IDENT { $$ = $1; }
| CSTRING { $$ = make3_str(make1_str("\""), $1, make1_str("\"")); } | CSTRING { $$ = make3_str(make1_str("\""), $1, make1_str("\"")); }
| Iconst { $$ = $1; } | Iconst { $$ = $1; }
| FCONST { $$ = make_name(); } | Fconst { $$ = $1; }
| '{' c_line '}' { $$ = make3_str(make1_str("{"), $2, make1_str("}")); } | '{' c_line '}' { $$ = make3_str(make1_str("{"), $2, make1_str("}")); }
blockstart : '{' { blockstart : '{' {
...@@ -4685,6 +4694,6 @@ blockend : '}' { ...@@ -4685,6 +4694,6 @@ blockend : '}' {
void yyerror(char * error) void yyerror(char * error)
{ {
fprintf(stderr, "%s in line %d of file %s\n", error, yylineno, input_filename); fprintf(stderr, "%s:%d: %s\n", input_filename, yylineno, error);
exit(PARSE_ERROR); exit(PARSE_ERROR);
} }
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