PQ_INCLUDE=-I$(SRCDIR)/interfaces/libpq
SO_MAJOR_VERSION=2
-SO_MINOR_VERSION=5
+SO_MINOR_VERSION=6
PORTNAME=@PORTNAME@
#include
#include
-extern int no_auto_trans;
+/* variables visible to the programs */
+int no_auto_trans;
+
+static struct sqlca sqlca_init =
+{
+ {'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '},
+ sizeof(struct sqlca),
+ 0,
+ { 0, {0}},
+ {'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '},
+ {0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0}
+};
+
+struct sqlca sqlca =
+{
+ {'S', 'Q', 'L', 'C', 'A', ' ', ' ', ' '},
+ sizeof(struct sqlca),
+ 0,
+ { 0, {0}},
+ {'N', 'O', 'T', ' ', 'S', 'E', 'T', ' '},
+ {0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0},
+ {0, 0, 0, 0, 0, 0, 0, 0}
+};
static struct connection
{
sqlca.sqlerrm.sqlerrml = strlen(sqlca.sqlerrm.sqlerrmc);
}
-/* This function returns a newly malloced string that has the ' and \
- in the argument quoted with \.
- */
-static
-char *
-quote_postgres(char *arg)
-{
- char *res = (char *) malloc(2 * strlen(arg) + 1);
- int i,
- ri;
-
- if (!res)
- return(res);
-
- for (i = 0, ri = 0; arg[i]; i++, ri++)
- {
- switch (arg[i])
- {
- case '\'':
- case '\\':
- res[ri++] = '\\';
- default:
- ;
- }
-
- res[ri] = arg[i];
- }
- res[ri] = '\0';
-
- return res;
-}
-
-
static void
ECPGfinish(struct connection *act)
{
ECPGlog("ECPGfinish: called an extra time.\n");
}
+static char *ecpg_alloc(long size, int lineno)
+{
+ char *new = (char *) malloc(size);
+
+ if (!new)
+ {
+ ECPGfinish(actual_connection);
+ ECPGlog("out of memory\n");
+ register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
+ return NULL;
+ }
+
+ memset(new, '\0', size);
+ return(new);
+}
+
+/* This function returns a newly malloced string that has the ' and \
+ in the argument quoted with \.
+ */
+static
+char *
+quote_postgres(char *arg, int lineno)
+{
+ char *res = (char *) ecpg_alloc(2 * strlen(arg) + 1, lineno);
+ int i,
+ ri;
+
+ if (!res)
+ return(res);
+
+ for (i = 0, ri = 0; arg[i]; i++, ri++)
+ {
+ switch (arg[i])
+ {
+ case '\'':
+ case '\\':
+ res[ri++] = '\\';
+ default:
+ ;
+ }
+
+ res[ri] = arg[i];
+ }
+ res[ri] = '\0';
+
+ return res;
+}
+
/* create a list of variables */
static bool
create_statement(int lineno, struct statement **stmt, char *query, va_list ap)
struct variable **list = &((*stmt)->inlist);
enum ECPGttype type;
- *stmt = calloc(sizeof(struct statement), 1);
-
- if (!*stmt)
- {
- ECPGfinish(actual_connection);
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
- return false;
- }
+ if (!(*stmt = (struct statement *) ecpg_alloc(sizeof(struct statement), lineno)))
+ return false;
(*stmt)->command = query;
(*stmt)->lineno = lineno;
{
struct variable *var, *ptr;
- var = malloc(sizeof(struct variable));
- if (!var)
- {
- ECPGfinish(actual_connection);
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
+ if (!(var = (struct variable *) ecpg_alloc(sizeof(struct variable), lineno)))
return false;
- }
var->type = type;
var->value = va_arg(ap, void *);
PGnotify *notify;
struct variable *var;
- memset((char *) &sqlca, 0, sizeof (sqlca));
-
+ memcpy((char *)&sqlca, (char *)&sqlca_init, sizeof(sqlca));
+
copiedquery = strdup(stmt->command);
/*
int slen = (var->varcharsize == 0) ? strlen((char *) var->value) : var->varcharsize;
char * tmp;
- newcopy = (char *) malloc(slen + 1);
- if (!newcopy)
- {
- ECPGfinish(actual_connection);
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
+ if (!(newcopy = ecpg_alloc(slen + 1, stmt->lineno)))
return false;
- }
strncpy(newcopy, (char *) var->value, slen);
newcopy[slen] = '\0';
- mallocedval = (char *) malloc(2 * strlen(newcopy) + 3);
- if (!mallocedval)
- {
- ECPGfinish(actual_connection);
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
+ if (!(mallocedval = (char *) ecpg_alloc(2 * strlen(newcopy) + 3, stmt->lineno)))
return false;
- }
strcpy(mallocedval, "'");
- tmp = quote_postgres(newcopy);
+ tmp = quote_postgres(newcopy, stmt->lineno);
if (!tmp)
- {
- ECPGfinish(actual_connection);
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
return false;
- }
strcat(mallocedval, tmp);
strcat(mallocedval, "'");
(struct ECPGgeneric_varchar *) (var->value);
char *tmp;
- newcopy = (char *) malloc(variable->len + 1);
- if (!newcopy)
- {
- ECPGfinish(actual_connection);
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
+ if (!(newcopy = (char *) ecpg_alloc(variable->len + 1, stmt->lineno)))
return false;
- }
strncpy(newcopy, variable->arr, variable->len);
newcopy[variable->len] = '\0';
- mallocedval = (char *) malloc(2 * strlen(newcopy) + 3);
- if (!mallocedval)
- {
- ECPGfinish(actual_connection);
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
+ if (!(mallocedval = (char *) ecpg_alloc(2 * strlen(newcopy) + 3, stmt->lineno)))
return false;
- }
strcpy(mallocedval, "'");
- tmp = quote_postgres(newcopy);
+ tmp = quote_postgres(newcopy, stmt->lineno);
if (!tmp)
- {
- ECPGfinish(actual_connection);
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
return false;
- }
strcat(mallocedval, tmp);
strcat(mallocedval, "'");
* Now tobeinserted points to an area that is to be inserted at
* the first %s
*/
- newcopy = (char *) malloc(strlen(copiedquery)
- + strlen(tobeinserted)
- + 1);
- if (!newcopy)
- {
- ECPGfinish(actual_connection);
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", stmt->lineno);
+ if (!(newcopy = (char *) ecpg_alloc(strlen(copiedquery) + strlen(tobeinserted) + 1, stmt->lineno)))
return false;
- }
strcpy(newcopy, copiedquery);
if ((p = strstr(newcopy, ";;")) == NULL)
if (create_statement(lineno, &stmt, query, args) == false)
return(false);
va_end(args);
-
+
+ /* are we connected? */
+ if (actual_connection == NULL || actual_connection->connection == NULL)
+ {
+ ECPGlog("ECPGdo: not connected\n");
+ register_error(ECPG_NOT_CONN, "Not connected in line %d", lineno);
+ return false;
+ }
+
return(ECPGexecute(stmt));
}
bool
ECPGconnect(int lineno, const char *dbname, const char *user, const char *passwd, const char * connection_name)
{
- struct connection *this = malloc(sizeof(struct connection));
+ struct connection *this = (struct connection *) ecpg_alloc(sizeof(struct connection), lineno);
if (!this)
- {
- ECPGlog("out of memory\n");
- register_error(ECPG_OUT_OF_MEMORY, "out of memory in line %d", lineno);
return false;
- }
if (dbname == NULL && connection_name == NULL)
connection_name = "DEFAULT";
{
ECPGfinish(this);
ECPGlog("connect: could not open database %s %s%s in line %d\n", dbname ? dbname : "NULL", user ? "for user ": "", user ? user : "", lineno);
-
register_error(ECPG_CONNECT, "connect: could not open database %s.", dbname ? dbname : "NULL");
return false;
}
include $(SRCDIR)/Makefile.global
MAJOR_VERSION=2
-MINOR_VERSION=3
-PATCHLEVEL=5
+MINOR_VERSION=4
+PATCHLEVEL=1
CFLAGS+=-I../include -DMAJOR_VERSION=$(MAJOR_VERSION) \
-DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL) \
#include "extern.h"
struct _include_path *include_paths;
-static int no_auto_trans = 0;
+int no_auto_trans = 0;
struct cursor *cur = NULL;
static void
else
{
struct cursor *ptr;
+ struct _defines *defptr;
/* remove old cursor definitions if any are still there */
- for (ptr = cur; ptr != NULL; ptr=ptr->next)
+ for (ptr = cur; ptr != NULL;)
{
+ struct cursor *this = ptr;
struct arguments *l1, *l2;
free(ptr->command);
l2 = l1->next;
free(l1);
}
+ ptr = ptr->next;
+ free(this);
}
+
+ /* remove old defines as well */
+ for (defptr = defines; defptr != NULL;)
+ {
+ struct _defines *this = defptr;
+ free(defptr->new);
+ free(defptr->old);
+ defptr = defptr->next;
+ free(this);
+ }
+
/* initialize lex */
lex_init();
/* 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 \n#include \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 \n#include \n\n", MAJOR_VERSION, MINOR_VERSION, PATCHLEVEL);
/* and parse the source */
yyparse();
/* variables */
-extern int braces_open;
+extern int braces_open, no_auto_trans;
extern char *yytext;
extern int yylineno,
yyleng;
extern struct cursor *cur;
+struct _defines { char *old;
+ char *new;
+ struct _defines *next;
+ };
+
+extern struct _defines *defines;
+
/* This is a linked list of the variable names and types. */
struct variable
{
struct _yy_buffer * next;
} *yy_buffer = NULL;
+struct _defines *defines = NULL;
+static char *old;
+
%}
%option yylineno
-%s C SQL incl
+%s C SQL incl def def_ident
/* OK, here is a short description of lex/flex rules behavior.
* The longest pattern which matches an input string is always chosen.
* For equal-length patterns, the first occurring in the rules list is chosen.
/* some stuff needed for ecpg */
ccomment "//".*\n
exec [eE][xX][eE][cC]
+define [dD][eE][fF][iI][nN][eE]
include [iI][nN][cC][lL][uU][dD][eE]
sql [sS][qQ][lL]
{typecast} { return TYPECAST; }
-
{self}/{space}*-[\.0-9] {
BEGIN(xm);
return (yytext[0]);
yylval.ival = atoi((char*)&yytext[1]);
return (PARAM);
}
-
{identifier}/{space}*-{number} {
int i;
ScanKeyword *keyword;
}
else
{
- yylval.str = strdup((char*)yytext);
- return (IDENT);
+ struct _defines *ptr;
+
+ for (ptr = defines; ptr; ptr = ptr->next)
+ {
+ if (strcmp(yytext, ptr->old) == 0)
+ {
+ struct _yy_buffer *yb;
+
+ yb = mm_alloc(sizeof(struct _yy_buffer));
+
+ yb->buffer = YY_CURRENT_BUFFER;
+ yb->lineno = yylineno;
+ yb->filename = strdup(input_filename);
+ yb->next = yy_buffer;
+
+ yy_buffer = yb;
+
+ yy_scan_string(ptr->new);
+ break;
+ }
+ }
+ if (ptr == NULL)
+ {
+ yylval.str = strdup((char*)yytext);
+ return (IDENT);
+ }
}
}
}
-{integer}/{space}*-{number} {
+{integer}/{space}*-{number} {
char* endptr;
BEGIN(xm);
}
return (ICONST);
}
-{real}/{space}*-{number} {
+{real}/{space}*-{number} {
char* endptr;
BEGIN(xm);
yyerror("ERROR: Bad float8 input");
return (FCONST);
}
-{integer} {
+{integer} {
char* endptr;
errno = 0;
}
return (ICONST);
}
-{real} {
+{real} {
char* endptr;
errno = 0;
yyerror("ERROR: Bad float input");
return (FCONST);
}
+{integer}/{space}*-{number} {
+ char* endptr;
+ BEGIN(xm);
+ errno = 0;
+ yylval.ival = strtol((char *)yytext,&endptr,10);
+ if (*endptr != '\0' || errno == ERANGE)
+ {
+ errno = 0;
+ yylval.dval = strtod(((char *)yytext),&endptr);
+ if (*endptr != '\0' || errno == ERANGE)
+ yyerror("ERROR: Bad integer input");
+ yyerror("WARNING: Integer input is out of range; promoted to float");
+ return (FCONST);
+ }
+ return (ICONST);
+ }
+{integer} {
+ char* endptr;
+
+ errno = 0;
+ yylval.ival = strtol((char *)yytext,&endptr,10);
+ if (*endptr != '\0' || errno == ERANGE)
+ {
+ errno = 0;
+ yylval.dval = strtod(((char *)yytext),&endptr);
+ if (*endptr != '\0' || errno == ERANGE)
+ yyerror("ERROR: Bad integer input");
+ yyerror("WARNING: Integer input is out of range; promoted to float");
+ return (FCONST);
+ }
+ return (ICONST);
+ }
:{identifier}(("->"|\.){identifier})* {
yylval.str = strdup((char*)yytext+1);
return(CVARIABLE);
}
else
{
- yylval.str = strdup((char*)yytext);
- return (IDENT);
+ struct _defines *ptr;
+
+ for (ptr = defines; ptr; ptr = ptr->next)
+ {
+ if (strcmp(yytext, ptr->old) == 0)
+ {
+ struct _yy_buffer *yb;
+
+ yb = mm_alloc(sizeof(struct _yy_buffer));
+
+ yb->buffer = YY_CURRENT_BUFFER;
+ yb->lineno = yylineno;
+ yb->filename = strdup(input_filename);
+ yb->next = yy_buffer;
+
+ yy_buffer = yb;
+
+ yy_scan_string(ptr->new);
+ break;
+ }
+ }
+ if (ptr == NULL)
+ {
+ yylval.str = strdup((char*)yytext);
+ return (IDENT);
+ }
}
}
}
{space} { /* ignore */ }
";" { BEGIN C; return SQL_SEMI; }
{other} { return (yytext[0]); }
-
{exec}{space}{sql} { BEGIN SQL; return SQL_START; }
{ccomment} { /* ignore */ }
{cppline} {
}
else
{
- yylval.str = strdup((char*)yytext);
- return (IDENT);
+ struct _defines *ptr;
+
+ for (ptr = defines; ptr; ptr = ptr->next)
+ {
+ if (strcmp(yytext, ptr->old) == 0)
+ {
+ struct _yy_buffer *yb;
+
+ yb = mm_alloc(sizeof(struct _yy_buffer));
+
+ yb->buffer = YY_CURRENT_BUFFER;
+ yb->lineno = yylineno;
+ yb->filename = strdup(input_filename);
+ yb->next = yy_buffer;
+
+ yy_buffer = yb;
+
+ yy_scan_string(ptr->new);
+ break;
+ }
+ }
+ if (ptr == NULL)
+ {
+ yylval.str = strdup((char*)yytext);
+ return (IDENT);
+ }
}
}
";" { return(';'); }
\] { return(']'); }
\= { return('='); }
{other} { return (S_ANYTHING); }
+{exec}{space}{sql}{space}{define} {BEGIN(def_ident);}
+{space} {}
+{identifier} {
+ old = strdup(yytext);
+ BEGIN(def);
+ llen = 0;
+ *literal = '\0';
+ }
+{space} /* eat the whitespace */
+";" {
+ struct _defines *ptr, *this;
+
+ for (ptr = defines; ptr != NULL; ptr = ptr->next)
+ {
+ if (strcmp(old, ptr->old) == 0)
+ {
+ free(ptr->new);
+ ptr->new = strdup(scanstr(literal));
+ }
+ }
+ if (ptr == NULL)
+ {
+ this = (struct _defines *) mm_alloc(sizeof(struct _defines));
+
+ /* initial definition */
+ this->old = old;
+ this->new = strdup(scanstr(literal));
+ this->next = defines;
+ defines = this;
+ }
+
+ BEGIN(C);
+ }
+[^";"] {
+ if ((llen+yyleng) > (MAX_PARSE_BUFFER - 1))
+ yyerror("ERROR: define statement parse buffer exceeded");
+ memcpy(literal+llen, yytext, yyleng+1);
+ llen += yyleng;
+ }
{exec}{space}{sql}{space}{include} { BEGIN(incl); }
{space} /* eat the whitespace */
[^ \t\n]+ { /* got the include file name */
%type ColId default_expr ColQualifier columnDef ColQualList
%type ColConstraint ColConstraintElem default_list NumericOnly FloatOnly
%type OptTableElementList OptTableElement TableConstraint
-%type ConstraintElem key_actions constraint_list TypeId
+%type ConstraintElem key_actions constraint_list
%type res_target_list res_target_el res_target_list2
%type res_target_el2 opt_id relation_name database_name
%type access_method attr_name class index_name name func_name
%type SelectStmt union_clause select_list SubSelect result
%type opt_table opt_union opt_unique sort_clause sortby_list
%type sortby OptUseOp opt_inh_star relation_name_list name_list
-%type group_clause groupby_list groupby having_clause from_clause
+%type group_clause having_clause from_clause c_list
%type from_list from_val join_expr join_outer join_spec join_list
%type join_using where_clause relation_expr row_op sub_type
%type opt_column_list insert_rest InsertStmt OptimizableStmt
%type columnList DeleteStmt LockStmt UpdateStmt CursorStmt
-%type NotifyStmt columnElem copy_dirn SubUnion
+%type NotifyStmt columnElem copy_dirn SubUnion c_expr
%type copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
%type opt_with_copy FetchStmt opt_direction fetch_how_many opt_portal_name
%type ClosePortalStmt DestroyStmt VacuumStmt opt_verbose
%type def_elem def_list definition def_name def_type DefineStmt
%type opt_instead event event_object OptStmtMulti OptStmtBlock
%type OptStmtList RuleStmt opt_column opt_name oper_argtypes
-%type MathOp RemoveOperStmt RemoveFuncStmt aggr_argtype
+%type MathOp RemoveFuncStmt aggr_argtype
%type RemoveAggrStmt remove_type RemoveStmt ExtendStmt RecipeStmt
%type RemoveOperStmt RenameStmt all_Op user_valid_clause
%type VariableSetStmt var_value zone_value VariableShowStmt
%type user_createuser_clause user_group_list user_group_clause
%type CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList
%type OptSeqElem TriggerForSpec TriggerForOpt TriggerForType
-%type TriggerFuncArgs DropTrigStmt TriggerOneEvent TriggerEvents
+%type DropTrigStmt TriggerOneEvent TriggerEvents
%type TriggerActionTime CreateTrigStmt DropPLangStmt PLangTrusted
%type CreatePLangStmt IntegerOnly TriggerFuncArgs TriggerFuncArg
%type ViewStmt LoadStmt CreatedbStmt opt_database1 opt_database2 location
%type GrantStmt privileges operation_commalist operation
%type ECPGWhenever ECPGConnect connection_target ECPGOpen open_opts
-%type indicator ECPGExecute c_expr variable_list dotext
+%type indicator ECPGExecute ecpg_expr dotext
%type storage_clause opt_initializer vartext c_anything blockstart
%type blockend variable_list variable var_anything do_anything
%type opt_pointer cvariable ECPGDisconnect dis_name
| VariableShowStmt { output_statement($1, 0); }
| VariableResetStmt { output_statement($1, 0); }
| ECPGConnect {
+ fprintf(yyout, "no_auto_trans = %d;\n", no_auto_trans);
fprintf(yyout, "ECPGconnect(__LINE__, %s);", $1);
whenever_action(0);
free($1);
{ $$ = cat3_str($1, $2, $3); }
| constraint_expr LIKE constraint_expr
{ $$ = cat3_str($1, make1_str("like"), $3); }
+ | constraint_expr NOT LIKE constraint_expr
+ { $$ = cat3_str($1, make1_str("not like"), $4); }
| constraint_expr AND constraint_expr
{ $$ = cat3_str($1, make1_str("and"), $3); }
| constraint_expr OR constraint_expr
{ $$ = cat2_str($1, make1_str("is not true")); }
| constraint_expr IS NOT FALSE_P
{ $$ = cat2_str($1, make1_str("is not false")); }
- ;
+ | constraint_expr IN '(' c_list ')'
+ { $$ = cat4_str($1, make1_str("in ("), $4, make1_str(")")); }
+ | constraint_expr NOT IN '(' c_list ')'
+ { $$ = cat4_str($1, make1_str("not in ("), $5, make1_str(")")); }
+ | constraint_expr BETWEEN c_expr AND c_expr
+ { $$ = cat5_str($1, make1_str("between"), $3, make1_str("and"), $5); }
+ | constraint_expr NOT BETWEEN c_expr AND c_expr
+ { $$ = cat5_str($1, make1_str("not between"), $4, make1_str("and"), $6); }
+ ;
+c_list: c_list ',' c_expr
+ {
+ $$ = make3_str($1, make1_str(", "), $3);
+ }
+ | c_expr
+ {
+ $$ = $1;
+ }
+
+c_expr: AexprConst
+ {
+ $$ = $1;
+ }
key_match: MATCH FULL { $$ = make1_str("match full"); }
| MATCH PARTIAL { $$ = make1_str("match partial"); }
OptStmtList: NOTHING { $$ = make1_str("nothing"); }
| OptimizableStmt { $$ = $1; }
| '[' OptStmtBlock ']' { $$ = cat3_str(make1_str("["), $2, make1_str("]")); }
+ | '(' OptStmtBlock ')' { $$ = cat3_str(make1_str("("), $2, make1_str(")")); }
;
OptStmtBlock: OptStmtMulti
| sortby_list ',' sortby { $$ = cat3_str($1, make1_str(","), $3); }
;
-sortby: ColId OptUseOp
- {
- $$ = cat2_str($1, $2);
- }
- | ColId '.' ColId OptUseOp
+sortby: a_expr OptUseOp
{
- $$ = cat2_str(make3_str($1, make1_str("."), $3), $4);
- }
- | Iconst OptUseOp
- {
- $$ = cat2_str($1, $2);
- }
+ $$ = cat2_str($1, $2);
+ }
;
OptUseOp: USING Op { $$ = cat2_str(make1_str("using"), $2); }
{ $$ = cat3_str($1, make1_str(","), $3); }
;
-group_clause: GROUP BY groupby_list { $$ = cat2_str(make1_str("groub by"), $3); }
+group_clause: GROUP BY expr_list { $$ = cat2_str(make1_str("groub by"), $3); }
| /*EMPTY*/ { $$ = make1_str(""); }
;
-groupby_list: groupby { $$ = $1; }
- | groupby_list ',' groupby { $$ = cat3_str($1, make1_str(","), $3); }
- ;
-
-groupby: ColId
- {
- $$ = $1;
- }
- | ColId '.' ColId
- {
- $$ = make3_str($1, make1_str(","), $3);
- }
- | Iconst
- {
- $$ = $1;
- }
- ;
-
having_clause: HAVING a_expr
{
$$ = cat2_str(make1_str("having"), $2);
{ $$ = make1_str(";;"); }
;
-opt_indirection: '[' c_expr ']' opt_indirection
+opt_indirection: '[' ecpg_expr ']' opt_indirection
{
$$ = cat4_str(make1_str("["), $2, make1_str("]"), $4);
}
- | '[' c_expr ':' c_expr ']' opt_indirection
+ | '[' ecpg_expr ':' ecpg_expr ']' opt_indirection
{
$$ = cat2_str(cat5_str(make1_str("["), $2, make1_str(":"), $4, make1_str("]")), $6);
}
/* some other stuff for ecpg */
-c_expr: attr opt_indirection
+ecpg_expr: attr opt_indirection
{
$$ = cat2_str($1, $2);
}
{
$$ = $1;
}
- | '-' c_expr %prec UMINUS
+ | '-' ecpg_expr %prec UMINUS
{ $$ = cat2_str(make1_str("-"), $2); }
- | a_expr '+' c_expr
+ | a_expr '+' ecpg_expr
{ $$ = cat3_str($1, make1_str("+"), $3); }
- | a_expr '-' c_expr
+ | a_expr '-' ecpg_expr
{ $$ = cat3_str($1, make1_str("-"), $3); }
- | a_expr '/' c_expr
+ | a_expr '/' ecpg_expr
{ $$ = cat3_str($1, make1_str("/"), $3); }
- | a_expr '*' c_expr
+ | a_expr '*' ecpg_expr
{ $$ = cat3_str($1, make1_str("*"), $3); }
- | a_expr '<' c_expr
+ | a_expr '<' ecpg_expr
{ $$ = cat3_str($1, make1_str("<"), $3); }
- | a_expr '>' c_expr
+ | a_expr '>' ecpg_expr
{ $$ = cat3_str($1, make1_str(">"), $3); }
- | a_expr '=' c_expr
+ | a_expr '=' ecpg_expr
{ $$ = cat3_str($1, make1_str("="), $3); }
- /* | ':' c_expr
+ /* | ':' ecpg_expr
{ $$ = cat2_str(make1_str(":"), $2); }*/
- | ';' c_expr
+ | ';' ecpg_expr
{ $$ = cat2_str(make1_str(";"), $2); }
- | '|' c_expr
+ | '|' ecpg_expr
{ $$ = cat2_str(make1_str("|"), $2); }
| a_expr TYPECAST Typename
{
}
| '(' a_expr_or_null ')'
{ $$ = make3_str(make1_str("("), $2, make1_str(")")); }
- | a_expr Op c_expr
+ | a_expr Op ecpg_expr
{ $$ = cat3_str($1, $2, $3); }
- | a_expr LIKE c_expr
+ | a_expr LIKE ecpg_expr
{ $$ = cat3_str($1, make1_str("like"), $3); }
- | a_expr NOT LIKE c_expr
+ | a_expr NOT LIKE ecpg_expr
{ $$ = cat3_str($1, make1_str("not like"), $4); }
- | Op c_expr
+ | Op ecpg_expr
{ $$ = cat2_str($1, $2); }
| a_expr Op
{ $$ = cat2_str($1, $2); }
{
$$ = make4_str($1, make1_str("=all("), $5, make1_str(")"));
}
- | a_expr AND c_expr
+ | a_expr AND ecpg_expr
{ $$ = cat3_str($1, make1_str("and"), $3); }
- | a_expr OR c_expr
+ | a_expr OR ecpg_expr
{ $$ = cat3_str($1, make1_str("or"), $3); }
- | NOT c_expr
+ | NOT ecpg_expr
{ $$ = cat2_str(make1_str("not"), $2); }
| civariableonly
{ $$ = make1_str(";;"); }