#endif
#define STRUCT_DEPTH 128
+#define EMPTY make1_str("")
/*
* Variables containing simple states.
int struct_level = 0;
char errortext[128];
static char *connection = NULL;
-static int QueryIsRule = 0, ForUpdateNotAllowed = 0;
+static int QueryIsRule = 0, ForUpdateNotAllowed = 0, FoundInto = 0;
static struct this_type actual_type[STRUCT_DEPTH];
static char *actual_storage[STRUCT_DEPTH];
%type <str> target_list target_el update_target_list
%type <str> update_target_el opt_id relation_name database_name
%type <str> access_method attr_name class index_name name func_name
-%type <str> file_name AexprConst ParamNo TypeId
+%type <str> file_name AexprConst ParamNo TypeId com_expr
%type <str> in_expr_nodes a_expr b_expr TruncateStmt CommentStmt
%type <str> opt_indirection expr_list extract_list extract_arg
%type <str> position_list substr_list substr_from
%type <str> opt_collate Datetime datetime opt_timezone opt_interval
%type <str> numeric a_expr_or_null row_expr row_descriptor row_list
%type <str> SelectStmt SubSelect result OptTemp OptTempType OptTempScope
-%type <str> opt_table opt_union opt_unique sort_clause sortby_list
+%type <str> opt_table opt_all opt_unique sort_clause sortby_list
%type <str> sortby OptUseOp opt_inh_star relation_name_list name_list
%type <str> group_clause having_clause from_clause
-%type <str> table_list join_outer where_clause relation_expr row_op sub_type
+%type <str> table_list join_outer where_clause relation_expr sub_type
%type <str> opt_column_list insert_rest InsertStmt OptimizableStmt
%type <str> columnList DeleteStmt LockStmt UpdateStmt CursorStmt
%type <str> NotifyStmt columnElem copy_dirn UnlistenStmt
%type <str> index_opt_unique IndexStmt set_opt func_return def_rest
%type <str> func_args_list func_args opt_with ProcedureStmt def_arg
%type <str> def_elem def_list definition def_name def_type DefineStmt
-%type <str> opt_instead event event_object RuleActionList,
+%type <str> opt_instead event event_object RuleActionList opt_using
%type <str> RuleActionStmtOrEmpty RuleActionMulti join_list func_as
%type <str> RuleStmt opt_column opt_name oper_argtypes
%type <str> MathOp RemoveFuncStmt aggr_argtype for_update_clause
%type <str> constraints_set_list constraints_set_namelist comment_fn
%type <str> constraints_set_mode comment_type comment_cl comment_ag
-%type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen opt_using
-%type <str> indicator ECPGExecute ecpg_expr ECPGPrepare
+%type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen
+%type <str> indicator ECPGExecute ECPGPrepare ecpg_using
%type <str> storage_clause opt_initializer c_anything blockstart
%type <str> blockend variable_list variable c_thing c_term
%type <str> opt_pointer cvariable ECPGDisconnect dis_name
;
user_passwd_clause: WITH PASSWORD UserId { $$ = cat2_str(make1_str("with password") , $3); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
user_createdb_clause: CREATEDB
{
$$ = make1_str("nocreatedb");
}
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
user_createuser_clause: CREATEUSER
;
user_group_clause: IN GROUP user_group_list { $$ = cat2_str(make1_str("in group"), $3); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
user_valid_clause: VALID UNTIL Sconst { $$ = cat2_str(make1_str("valid until"), $3); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
/*****************************************************************************
;
opt_binary: BINARY { $$ = make1_str("binary"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
opt_with_copy: WITH OIDS { $$ = make1_str("with oids"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
/*
* the default copy delimiter is tab but the user can configure it
*/
-copy_delimiter: USING DELIMITERS Sconst { $$ = cat2_str(make1_str("using delimiters"), $3); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+copy_delimiter: opt_using DELIMITERS Sconst { $$ = cat3_str($1, make1_str("delimiters"), $3); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-
+opt_using: USING { $$ = make1_str("using"); }
+ | /* EMPTY */ { $$ = EMPTY; }
/*****************************************************************************
*
OptTempType: TEMP { $$ = make1_str("temp"); }
| TEMPORARY { $$ = make1_str("temporary"); }
- | /* EMPTY */ { $$ = make1_str(""); }
+ | /* EMPTY */ { $$ = EMPTY; }
;
OptTempScope: GLOBAL
{
$$ = $1;
}
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
OptTableElement: columnDef { $$ = $1; }
;
ColQualifier: ColQualList { $$ = $1; }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
ColQualList: ColQualList ColConstraint { $$ = cat2_str($1,$2); }
}
| /*EMPTY*/
{
- $$ = make1_str("");
+ $$ = EMPTY;
}
;
{ $$ = $1; }
;
-/* DEFAULT NULL is already the default for Postgres.
+/*
+ * DEFAULT NULL is already the default for Postgres.
* Bue define it here and carry it forward into the system
* to make it explicit.
* - thomas 1998-09-13
+ *
* WITH NULL and NULL are not SQL92-standard syntax elements,
* so leave them out. Use DEFAULT NULL to explicitly indicate
* that a column may have that value. WITH NULL leads to
* shift/reduce conflicts with WITH TIME ZONE anyway.
* - thomas 1999-01-08
+ *
* DEFAULT expression must be b_expr not a_expr to prevent shift/reduce
* conflict on NOT (since NOT might start a subsequent NOT NULL constraint,
* or be part of a_expr NOT LIKE or similar constructs).
| REFERENCES ColId opt_column_list key_match key_actions
{
fprintf(stderr, "CREATE TABLE/FOREIGN KEY clause ignored; not yet implemented");
- $$ = make1_str("");
+ $$ = EMPTY;
}
;
key_match: MATCH FULL { $$ = make1_str("match full"); }
| MATCH PARTIAL { $$ = make1_str("match partial"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
key_actions: key_action key_action { $$ = cat2_str($1, $2); }
| key_action { $$ = $1; }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
key_action: ON DELETE key_reference { $$ = cat2_str(make1_str("on delete"), $3); }
;
OptInherit: INHERITS '(' relation_name_list ')' { $$ = make3_str(make1_str("inherits ("), $3, make1_str(")")); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-CreateAsStmt: CREATE OptTemp TABLE relation_name OptCreateAs AS SubSelect
+/*
+ * Note: CREATE TABLE ... AS SELECT ... is just another spelling for
+ * SELECT ... INTO.
+ */
+
+CreateAsStmt: CREATE OptTemp TABLE relation_name OptCreateAs AS SelectStmt
{
+ if (FoundInto == 1)
+ yyerror("CREATE TABLE/AS SELECT may not specify INTO");
+
$$ = cat5_str(cat3_str(make1_str("create"), $2, make1_str("table")), $4, $5, make1_str("as"), $7);
}
;
OptCreateAs: '(' CreateAsList ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
CreateAsList: CreateAsList ',' CreateAsElement { $$ = cat3_str($1, make1_str(","), $3); }
OptSeqList: OptSeqList OptSeqElem
{ $$ = cat2_str($1, $2); }
- | { $$ = make1_str(""); }
+ | { $$ = EMPTY; }
;
OptSeqElem: CACHE IntegerOnly
;
PLangTrusted: TRUSTED { $$ = make1_str("trusted"); }
- | { $$ = make1_str(""); }
+ | { $$ = EMPTY; }
DropPLangStmt: DROP PROCEDURAL LANGUAGE Sconst
{
;
TriggerForOpt: EACH { $$ = make1_str("each"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
TriggerForType: ROW { $$ = make1_str("row"); }
| TriggerFuncArgs ',' TriggerFuncArg
{ $$ = cat3_str($1, make1_str(","), $3); }
| /*EMPTY*/
- { $$ = make1_str(""); }
+ { $$ = EMPTY; }
;
TriggerFuncArg: Iconst
OptConstrFromTable: /* Empty */
{
- $$ = make1_str("");
+ $$ = EMPTY;
}
| FROM relation_name
{
OptConstrTrigDeferrable: /* Empty */
{
- $$ = make1_str("");
+ $$ = EMPTY;
}
| DEFERRABLE
{
OptConstrTrigInitdeferred: /* Empty */
{
- $$ = make1_str("");
+ $$ = EMPTY;
}
| INITIALLY DEFERRED
{
def_name: PROCEDURE { $$ = make1_str("procedure"); }
| JOIN { $$ = make1_str("join"); }
| ColId { $$ = $1; }
- | MathOp { $$ = $1; }
- | Op { $$ = $1; }
+ | all_Op { $$ = $1; }
;
definition: '(' def_list ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
fprintf(stderr, "FETCH/ABSOLUTE not supported, using RELATIVE");
$$ = make1_str("absolute");
}
- | /*EMPTY*/ { $$ = make1_str(""); /* default */ }
+ | /*EMPTY*/ { $$ = EMPTY; /* default */ }
;
fetch_how_many: Iconst { $$ = $1; }
| ALL { $$ = make1_str("all"); }
| NEXT { $$ = make1_str("next"); }
| PRIOR { $$ = make1_str("prior"); }
- | /*EMPTY*/ { $$ = make1_str(""); /*default*/ }
+ | /*EMPTY*/ { $$ = EMPTY; /*default*/ }
;
opt_portal_name: IN name { $$ = cat2_str(make1_str("in"), $2); }
| FROM name { $$ = cat2_str(make1_str("from"), $2); }
/* | name { $$ = cat2_str(make1_str("in"), $1); */
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
/*****************************************************************************
;
index_opt_unique: UNIQUE { $$ = make1_str("unique"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
access_method_clause: USING access_method { $$ = cat2_str(make1_str("using"), $2); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
index_params: index_list { $$ = $1; }
opt_type: ':' Typename { $$ = cat2_str(make1_str(":"), $2); }
| FOR Typename { $$ = cat2_str(make1_str("for"), $2); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
/* opt_class "WITH class" conflicts with preceeding opt_type
*/
opt_class: class { $$ = $1; }
| USING class { $$ = cat2_str(make1_str("using"), $2); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
/*****************************************************************************
}
opt_with: WITH definition { $$ = cat2_str(make1_str("with"), $2); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
func_args: '(' func_args_list ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
;
set_opt: SETOF { $$ = make1_str("setof"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
}
;
-all_Op: Op | MathOp;
-
-MathOp: '+' { $$ = make1_str("+"); }
- | '-' { $$ = make1_str("-"); }
- | '*' { $$ = make1_str("*"); }
- | '%' { $$ = make1_str("%"); }
- | '^' { $$ = make1_str("^"); }
- | '|' { $$ = make1_str("|"); }
- | '/' { $$ = make1_str("/"); }
- | '<' { $$ = make1_str("<"); }
- | '>' { $$ = make1_str(">"); }
- | '=' { $$ = make1_str("="); }
- ;
-
oper_argtypes: name
{
yyerror("parser: argument type missing (use NONE for unary operators)");
;
opt_name: name { $$ = $1; }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
opt_column: COLUMN { $$ = make1_str("colmunn"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
| NotifyStmt
;
RuleActionStmtOrEmpty: RuleActionStmt { $$ = $1; }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
event_object: relation_name '.' attr_name
;
opt_instead: INSTEAD { $$ = make1_str("instead"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
;
opt_database1: LOCATION '=' location { $$ = cat2_str(make1_str("location ="), $3); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
opt_database2: ENCODING '=' encoding { $$ = cat2_str(make1_str("encoding ="), $3); }
location: Sconst { $$ = $1; }
| DEFAULT { $$ = make1_str("default"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
encoding: Sconst { $$ = $1; }
| DEFAULT { $$ = make1_str("default"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
/*****************************************************************************
;
opt_verbose: VERBOSE { $$ = make1_str("verbose"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
opt_analyze: ANALYZE { $$ = make1_str("analyse"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
opt_va_list: '(' va_list ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
va_list: name
;
opt_column_list: '(' columnList ')' { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
columnList:
;
opt_lock: IN lock_type MODE { $$ = cat3_str(make1_str("in"), $2, make1_str("mode")); }
- | /*EMPTY*/ { $$ = make1_str("");}
+ | /*EMPTY*/ { $$ = EMPTY;}
;
lock_type: SHARE ROW EXCLUSIVE { $$ = make1_str("share row exclusive"); }
}
;
-opt_cursor: BINARY { $$ = make1_str("binary"); }
- | INSENSITIVE { $$ = make1_str("insensitive"); }
- | SCROLL { $$ = make1_str("scroll"); }
+opt_cursor: BINARY { $$ = make1_str("binary"); }
+ | INSENSITIVE { $$ = make1_str("insensitive"); }
+ | SCROLL { $$ = make1_str("scroll"); }
| INSENSITIVE SCROLL { $$ = make1_str("insensitive scroll"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
/*****************************************************************************
*/
select_clause: '(' select_clause ')'
{
- $$ = make3_str(make1_str("("), $2, make1_str(")"));
+ $$ = make3_str(make1_str("("), $2, make1_str(")"));
}
| SubSelect
{
- $$ = $1;
+ FoundInto = 0;
+ $$ = $1;
}
| select_clause EXCEPT select_clause
{
$$ = cat3_str($1, make1_str("except"), $3);
ForUpdateNotAllowed = 1;
}
- | select_clause UNION opt_union select_clause
+ | select_clause UNION opt_all select_clause
{
$$ = cat4_str($1, make1_str("union"), $3, $4);
ForUpdateNotAllowed = 1;
}
- | select_clause INTERSECT opt_union select_clause
+ | select_clause INTERSECT opt_all select_clause
{
$$ = cat3_str($1, make1_str("intersect"), $3);
ForUpdateNotAllowed = 1;
}
;
-result: INTO OptTemp opt_table relation_name { $$= cat4_str(make1_str("into"), $2, $3, $4); }
- | INTO into_list { $$ = make1_str(""); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+result: INTO OptTemp opt_table relation_name { FoundInto = 1;
+ $$= cat4_str(make1_str("into"), $2, $3, $4);
+ }
+ | INTO into_list { $$ = EMPTY; }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
opt_table: TABLE { $$ = make1_str("table"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-opt_union: ALL { $$ = make1_str("all"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+opt_all: ALL { $$ = make1_str("all"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
opt_unique: DISTINCT { $$ = make1_str("distinct"); }
| DISTINCT ON ColId { $$ = cat2_str(make1_str("distinct on"), $3); }
| ALL { $$ = make1_str("all"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
sort_clause: ORDER BY sortby_list { $$ = cat2_str(make1_str("order by"), $3); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
sortby_list: sortby { $$ = $1; }
}
;
-OptUseOp: USING Op { $$ = cat2_str(make1_str("using"), $2); }
- | USING '<' { $$ = make1_str("using <"); }
- | USING '>' { $$ = make1_str("using >"); }
+OptUseOp: USING all_Op { $$ = cat2_str(make1_str("using"), $2); }
| ASC { $$ = make1_str("asc"); }
| DESC { $$ = make1_str("desc"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
opt_select_limit: LIMIT select_limit_value ',' select_offset_value
| OFFSET select_offset_value
{ $$ = cat2_str(make1_str("offset"), $2); }
| /* EMPTY */
- { $$ = make1_str(""); }
+ { $$ = EMPTY; }
;
select_limit_value: Iconst { $$ = $1; }
* cases for these.
*/
opt_inh_star: '*' { $$ = make1_str("*"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
relation_name_list: name_list { $$ = $1; };
;
group_clause: GROUP BY expr_list { $$ = cat2_str(make1_str("group by"), $3); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
having_clause: HAVING a_expr
{
$$ = cat2_str(make1_str("having"), $2);
}
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
for_update_clause: FOR UPDATE update_list
}
| /* EMPTY */
{
- $$ = make1_str("");
+ $$ = EMPTY;
}
;
update_list: OF va_list
}
| /* EMPTY */
{
- $$ = make1_str("");
+ $$ = EMPTY;
}
;
}
| /* EMPTY */
{
- $$ = make1_str("");
+ $$ = EMPTY;
}
}
| /* EMPTY */
{
- $$ = make1_str("");
+ $$ = EMPTY;
}
join_outer: OUTER_P { $$ = make1_str("outer"); }
- | /*EMPTY*/ { $$ = make1_str(""); /* no qualifiers */ }
+ | /*EMPTY*/ { $$ = EMPTY; /* no qualifiers */ }
;
/* JOIN qualification clauses
;
where_clause: WHERE a_expr { $$ = cat2_str(make1_str("where"), $2); }
- | /*EMPTY*/ { $$ = make1_str(""); /* no qualifiers */ }
+ | /*EMPTY*/ { $$ = EMPTY; /* no qualifiers */ }
;
relation_expr: relation_name
{
$$.index1 = -1;
$$.index2 = -1;
- $$.str= make1_str("");
+ $$.str= EMPTY;
}
;
}
| /*EMPTY*/
{
- $$ = make1_str("");
+ $$ = EMPTY;
}
;
}
| /*EMPTY*/
{
- $$ = make1_str("");
+ $$ = EMPTY;
}
;
}
| /*EMPTY*/
{
- $$ = make1_str("");
+ $$ = EMPTY;
}
;
;
opt_varying: VARYING { $$ = make1_str("varying"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
opt_charset: CHARACTER SET ColId { $$ = cat2_str(make1_str("character set"), $3); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
opt_collate: COLLATE ColId { $$ = cat2_str(make1_str("collate"), $2); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
Datetime: datetime
;
opt_timezone: WITH TIME ZONE { $$ = make1_str("with time zone"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
opt_interval: datetime { $$ = $1; }
| HOUR_P TO MINUTE_P { $$ = make1_str("hour to minute"); }
| MINUTE_P TO SECOND_P { $$ = make1_str("minute to second"); }
| HOUR_P TO SECOND_P { $$ = make1_str("hour to second"); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
/*****************************************************************************
*
- * expression grammar, still needs some cleanup
+ * expression grammar
*
*****************************************************************************/
/* Expressions using row descriptors
* Define row_descriptor to allow yacc to break the reduce/reduce conflict
* with singleton expressions.
- * Eliminated lots of code by defining row_op and sub_type clauses.
- * However, can not consolidate EXPR_LINK case with others subselects
- * due to shift/reduce conflict with the non-subselect clause (the parser
- * would have to look ahead more than one token to resolve the conflict).
- * - thomas 1998-05-09
*/
row_expr: '(' row_descriptor ')' IN '(' SubSelect ')'
{
{
$$ = make5_str(make1_str("("), $2, make1_str(") not in ("), $7, make1_str(")"));
}
- | '(' row_descriptor ')' row_op sub_type '(' SubSelect ')'
+ | '(' row_descriptor ')' all_Op sub_type '(' SubSelect ')'
{
$$ = make4_str(make5_str(make1_str("("), $2, make1_str(")"), $4, $5), make1_str("("), $7, make1_str(")"));
}
- | '(' row_descriptor ')' row_op '(' SubSelect ')'
+ | '(' row_descriptor ')' all_Op '(' SubSelect ')'
{
$$ = make3_str(make5_str(make1_str("("), $2, make1_str(")"), $4, make1_str("(")), $6, make1_str(")"));
}
- | '(' row_descriptor ')' row_op '(' row_descriptor ')'
+ | '(' row_descriptor ')' all_Op '(' row_descriptor ')'
{
$$ = cat3_str(make3_str(make1_str("("), $2, make1_str(")")), $4, make3_str(make1_str("("), $6, make1_str(")")));
}
}
;
-row_op: Op { $$ = $1; }
- | '<' { $$ = "<"; }
- | '=' { $$ = "="; }
- | '>' { $$ = ">"; }
- | '+' { $$ = "+"; }
- | '-' { $$ = "-"; }
- | '*' { $$ = "*"; }
- | '%' { $$ = "%"; }
- | '/' { $$ = "/"; }
- | '^' { $$ = "^"; }
- | '|' { $$ = "|"; }
- ;
-
sub_type: ANY { $$ = make1_str("ANY"); }
| ALL { $$ = make1_str("ALL"); }
;
}
;
+all_Op: Op | MathOp;
+
+MathOp: '+' { $$ = make1_str("+"); }
+ | '-' { $$ = make1_str("-"); }
+ | '*' { $$ = make1_str("*"); }
+ | '%' { $$ = make1_str("%"); }
+ | '^' { $$ = make1_str("^"); }
+ | '|' { $$ = make1_str("|"); }
+ | '/' { $$ = make1_str("/"); }
+ | '<' { $$ = make1_str("<"); }
+ | '>' { $$ = make1_str(">"); }
+ | '=' { $$ = make1_str("="); }
+ ;
+
/* General expressions
* This is the heart of the expression syntax.
- * Note that the BETWEEN clause looks similar to a boolean expression
- * and so we must define b_expr which is almost the same as a_expr
- * but without the boolean expressions.
- * All operations/expressions are allowed in a BETWEEN clause
- * if surrounded by parens.
+ *
+ * We have two expression types: a_expr is the unrestricted kind, and
+ * b_expr is a subset that must be used in some places to avoid shift/reduce
+ * conflicts. For example, we can't do BETWEEN as "BETWEEN a_expr AND a_expr"
+ * because that use of AND conflicts with AND as a boolean operator. So,
+ * b_expr is used in BETWEEN and we remove boolean keywords from b_expr.
+ *
+ * Note that '(' a_expr ')' is a b_expr, so an unrestricted expression can
+ * always be used by surrounding it with parens.
+ *
+ * com_expr is all the productions that are common to a_expr and b_expr;
+ * it's factored out just to eliminate redundant coding.
*/
-a_expr: attr
- {
- $$ = $1;
- }
- | row_expr
- { $$ = $1; }
- | AexprConst
- { $$ = $1; }
- | ColId opt_indirection
- {
- $$ = cat2_str($1, $2);
- }
+a_expr: com_expr
+ { $$ = $1; }
+ | a_expr TYPECAST Typename
+ { $$ = cat3_str($1, make1_str("::"), $3); }
+ /*
+ * These operators must be called out explicitly in order to make use
+ * of yacc/bison's automatic operator-precedence handling. All other
+ * operator names are handled by the generic productions using "Op",
+ * below; and all those operators will have the same precedence.
+ *
+ * If you add more explicitly-known operators, be sure to add them
+ * also to b_expr and to the MathOp list above.
+ */
| '-' a_expr %prec UMINUS
{ $$ = cat2_str(make1_str("-"), $2); }
| '%' a_expr
{ $$ = cat3_str($1, make1_str(">"), $3); }
| a_expr '=' NULL_P
{ $$ = cat2_str($1, make1_str("= NULL")); }
+ /* We allow this for standards-broken SQL products, like MS stuff */
| NULL_P '=' a_expr
{ $$ = cat2_str(make1_str("= NULL"), $3); }
| a_expr '=' a_expr
{ $$ = cat3_str($1, make1_str("="), $3); }
- | a_expr TYPECAST Typename
- {
- $$ = cat3_str($1, make1_str("::"), $3);
- }
- | CAST '(' a_expr AS Typename ')'
- {
- $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")")));
- }
- | '(' a_expr_or_null ')'
- { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
| a_expr Op a_expr
- { $$ = cat3_str($1, $2, $3); }
- | a_expr LIKE a_expr
- { $$ = cat3_str($1, make1_str("like"), $3); }
- | a_expr NOT LIKE a_expr
- { $$ = cat3_str($1, make1_str("not like"), $4); }
+ { $$ = cat3_str($1, make1_str("="), $3); }
| Op a_expr
{ $$ = cat2_str($1, $2); }
| a_expr Op
{ $$ = cat2_str($1, $2); }
- | func_name '(' '*' ')'
- {
- $$ = cat2_str($1, make1_str("(*)"));
- }
- | func_name '(' ')'
- {
- $$ = cat2_str($1, make1_str("()"));
- }
- | func_name '(' expr_list ')'
- {
- $$ = make4_str($1, make1_str("("), $3, make1_str(")"));
- }
- | CURRENT_DATE
- {
- $$ = make1_str("current_date");
- }
- | CURRENT_TIME
- {
- $$ = make1_str("current_time");
- }
- | CURRENT_TIME '(' Iconst ')'
- {
- if (atol($3) != 0)
- fprintf(stderr,"CURRENT_TIME(%s) precision not implemented; zero used instead", $3);
- $$ = make1_str("current_time");
- }
- | CURRENT_TIMESTAMP
- {
- $$ = make1_str("current_timestamp");
- }
- | CURRENT_TIMESTAMP '(' Iconst ')'
- {
- if (atol($3) != 0)
- fprintf(stderr,"CURRENT_TIMESTAMP(%s) precision not implemented; zero used instead",$3);
- $$ = make1_str("current_timestamp");
- }
- | CURRENT_USER
- {
- $$ = make1_str("current_user");
- }
- | USER
- {
- $$ = make1_str("user");
- }
- | EXISTS '(' SubSelect ')'
- {
- $$ = make3_str(make1_str("exists("), $3, make1_str(")"));
- }
- | EXTRACT '(' extract_list ')'
- {
- $$ = make3_str(make1_str("extract("), $3, make1_str(")"));
- }
- | POSITION '(' position_list ')'
- {
- $$ = make3_str(make1_str("position("), $3, make1_str(")"));
- }
- | SUBSTRING '(' substr_list ')'
- {
- $$ = make3_str(make1_str("substring("), $3, make1_str(")"));
- }
- /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
- | TRIM '(' BOTH trim_list ')'
- {
- $$ = make3_str(make1_str("trim(both"), $4, make1_str(")"));
- }
- | TRIM '(' LEADING trim_list ')'
- {
- $$ = make3_str(make1_str("trim(leading"), $4, make1_str(")"));
- }
- | TRIM '(' TRAILING trim_list ')'
- {
- $$ = make3_str(make1_str("trim(trailing"), $4, make1_str(")"));
- }
- | TRIM '(' trim_list ')'
- {
- $$ = make3_str(make1_str("trim("), $3, make1_str(")"));
- }
+ | a_expr AND a_expr
+ { $$ = cat3_str($1, make1_str("and"), $3); }
+ | a_expr OR a_expr
+ { $$ = cat3_str($1, make1_str("or"), $3); }
+ | NOT a_expr
+ { $$ = cat2_str(make1_str("not"), $2); }
+ | a_expr LIKE a_expr
+ { $$ = cat3_str($1, make1_str("like"), $3); }
+ | a_expr NOT LIKE a_expr
+ { $$ = cat3_str($1, make1_str("not like"), $4); }
| a_expr ISNULL
{ $$ = cat2_str($1, make1_str("isnull")); }
| a_expr IS NULL_P
* - thomas 1997-12-22
*/
| a_expr IS TRUE_P
- {
{ $$ = cat2_str($1, make1_str("is true")); }
- }
| a_expr IS NOT FALSE_P
- {
{ $$ = cat2_str($1, make1_str("is not false")); }
- }
| a_expr IS FALSE_P
- {
{ $$ = cat2_str($1, make1_str("is false")); }
- }
| a_expr IS NOT TRUE_P
- {
{ $$ = cat2_str($1, make1_str("is not true")); }
- }
| a_expr BETWEEN b_expr AND b_expr
{
$$ = cat5_str($1, make1_str("between"), $3, make1_str("and"), $5);
{
$$ = make4_str($1, make1_str(" not in ("), $5, make1_str(")"));
}
- | a_expr Op '(' SubSelect ')'
- {
- $$ = cat3_str($1, $2, make3_str(make1_str("("), $4, make1_str(")")));
- }
- | a_expr '+' '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("+("), $4, make1_str(")"));
- }
- | a_expr '-' '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("-("), $4, make1_str(")"));
- }
- | a_expr '*' '(' SubSelect ')'
+ | a_expr all_Op sub_type '(' SubSelect ')'
{
- $$ = make4_str($1, make1_str("*("), $4, make1_str(")"));
+ $$ = cat4_str($1, $2, $3, make3_str(make1_str("("), $5, make1_str(")")));
}
- | a_expr '/' '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("/("), $4, make1_str(")"));
- }
- | a_expr '%' '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("%("), $4, make1_str(")"));
- }
- | a_expr '^' '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("^("), $4, make1_str(")"));
- }
- | a_expr '|' '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("|("), $4, make1_str(")"));
- }
- | a_expr '<' '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("<("), $4, make1_str(")"));
- }
- | a_expr '>' '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str(">("), $4, make1_str(")"));
- }
- | a_expr '=' '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("=("), $4, make1_str(")"));
- }
- | a_expr Op ANY '(' SubSelect ')'
- {
- $$ = cat3_str($1, $2, make3_str(make1_str("any("), $5, make1_str(")")));
- }
- | a_expr '+' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("+ any("), $5, make1_str(")"));
- }
- | a_expr '-' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("- any("), $5, make1_str(")"));
- }
- | a_expr '*' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("* any("), $5, make1_str(")"));
- }
- | a_expr '/' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("/ any("), $5, make1_str(")"));
- }
- | a_expr '%' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("% any("), $5, make1_str(")"));
- }
- | a_expr '^' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("^ any("), $5, make1_str(")"));
- }
- | a_expr '|' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("| any("), $5, make1_str(")"));
- }
- | a_expr '<' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("< any("), $5, make1_str(")"));
- }
- | a_expr '>' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("> any("), $5, make1_str(")"));
- }
- | a_expr '=' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("= any("), $5, make1_str(")"));
- }
- | a_expr Op ALL '(' SubSelect ')'
- {
- $$ = cat3_str($1, $2, make3_str(make1_str("all ("), $5, make1_str(")")));
- }
- | a_expr '+' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("+ all("), $5, make1_str(")"));
- }
- | a_expr '-' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("- all("), $5, make1_str(")"));
- }
- | a_expr '*' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("* all("), $5, make1_str(")"));
- }
- | a_expr '/' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("/ all("), $5, make1_str(")"));
- }
- | a_expr '%' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("% all("), $5, make1_str(")"));
- }
- | a_expr '^' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("^ all("), $5, make1_str(")"));
- }
- | a_expr '|' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("| all("), $5, make1_str(")"));
- }
- | a_expr '<' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("< all("), $5, make1_str(")"));
- }
- | a_expr '>' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("> all("), $5, make1_str(")"));
- }
- | a_expr '=' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("= all("), $5, make1_str(")"));
- }
- | a_expr AND a_expr
- { $$ = cat3_str($1, make1_str("and"), $3); }
- | a_expr OR a_expr
- { $$ = cat3_str($1, make1_str("or"), $3); }
- | NOT a_expr
- { $$ = cat2_str(make1_str("not"), $2); }
- | case_expr
+ | row_expr
{ $$ = $1; }
| cinputvariable
{ $$ = make1_str("?"); }
;
/* Restricted expressions
+ *
* b_expr is a subset of the complete expression syntax
- * defined by a_expr. b_expr is used in BETWEEN clauses
- * to eliminate parser ambiguities stemming from the AND keyword.
+ *
+ * Presently, AND, NOT, IS, IN, and NULL are the a_expr keywords that would
+ * cause trouble in the places where b_expr is used. For simplicity, we
+ * just eliminate all the boolean-keyword-operator productions from b_expr.
*/
-b_expr: attr
+b_expr: com_expr
{
- $$ = $1
+ $$ = $1;
}
- | AexprConst
- { $$ = $1; }
- | ColId opt_indirection
+ | b_expr TYPECAST Typename
{
- $$ = cat2_str($1, $2);
+ $$ = cat3_str($1, make1_str("::"), $3);
}
| '-' b_expr %prec UMINUS
{ $$ = cat2_str(make1_str("-"), $2); }
{ $$ = cat2_str(make1_str("%"), $2); }
| '^' b_expr
{ $$ = cat2_str(make1_str("^"), $2); }
-/* not possible in embedded sql | ':' b_expr
- { $$ = cat2_str(make1_str(":"), $2); }
+ | '|' b_expr
+ { $$ = cat2_str(make1_str("|"), $2); }
+/* not possible in embedded sql | ':' b_expr
+ { $$ = cat2_str(make1_str(":"), $2); }
*/
| ';' b_expr
- { $$ = cat2_str(make1_str(";"), $2); }
- | '|' b_expr
- { $$ = cat2_str(make1_str("|"), $2); }
+ { $$ = cat2_str(make1_str(";"), $2); }
| b_expr '%'
{ $$ = cat2_str($1, make1_str("%")); }
| b_expr '^'
{ $$ = cat3_str($1, make1_str("^"), $3); }
| b_expr '|' b_expr
{ $$ = cat3_str($1, make1_str("|"), $3); }
- | b_expr TYPECAST Typename
- {
- $$ = cat3_str($1, make1_str("::"), $3);
- }
- | CAST '(' b_expr AS Typename ')'
- {
- $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")")));
- }
- | '(' a_expr ')'
- { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
+ | b_expr '<' b_expr
+ { $$ = cat3_str($1, make1_str("<"), $3); }
+ | b_expr '>' b_expr
+ { $$ = cat3_str($1, make1_str(">"), $3); }
+ | b_expr '=' b_expr
+ { $$ = cat3_str($1, make1_str("="), $3); }
| b_expr Op b_expr
- { $$ = cat3_str($1, $2, $3); }
+ { $$ = cat3_str($1, make1_str("="), $3); }
| Op b_expr
{ $$ = cat2_str($1, $2); }
| b_expr Op
{ $$ = cat2_str($1, $2); }
+ | civariableonly
+ { $$ = $1; }
+ ;
+
+/*
+ * Productions that can be used in both a_expr and b_expr.
+ *
+ * Note: productions that refer recursively to a_expr or b_expr mostly
+ * cannot appear here. However, it's OK to refer to a_exprs that occur
+ * inside parentheses, such as function arguments; that cannot introduce
+ * ambiguity to the b_expr syntax.
+ */
+com_expr: attr
+ { $$ = $1; }
+ | ColId opt_indirection
+ { $$ = cat2_str($1, $2); }
+ | AexprConst
+ { $$ = $1; }
+ | '(' a_expr_or_null ')'
+ { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
+ | CAST '(' a_expr AS Typename ')'
+ { $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")"))); }
+ | case_expr
+ { $$ = $1; }
| func_name '(' ')'
- {
- $$ = cat2_str($1, make1_str("()"));
- }
+ { $$ = cat2_str($1, make1_str("()")); }
| func_name '(' expr_list ')'
- {
- $$ = make4_str($1, make1_str("("), $3, make1_str(")"));
- }
+ { $$ = make4_str($1, make1_str("("), $3, make1_str(")")); }
+ | func_name '(' '*' ')'
+ { $$ = cat2_str($1, make1_str("(*)")); }
| CURRENT_DATE
- {
- $$ = make1_str("current_date");
- }
+ { $$ = make1_str("current_date"); }
| CURRENT_TIME
- {
- $$ = make1_str("current_time");
- }
+ { $$ = make1_str("current_time"); }
| CURRENT_TIME '(' Iconst ')'
{
- if ($3 != 0)
+ if (atol($3) != 0)
fprintf(stderr,"CURRENT_TIME(%s) precision not implemented; zero used instead", $3);
$$ = make1_str("current_time");
}
| CURRENT_TIMESTAMP
- {
- $$ = make1_str("current_timestamp");
- }
+ { $$ = make1_str("current_timestamp"); }
| CURRENT_TIMESTAMP '(' Iconst ')'
{
if (atol($3) != 0)
$$ = make1_str("current_timestamp");
}
| CURRENT_USER
- {
- $$ = make1_str("current_user");
- }
+ { $$ = make1_str("current_user"); }
| USER
- {
- $$ = make1_str("user");
- }
+ { $$ = make1_str("user"); }
+ | EXTRACT '(' extract_list ')'
+ { $$ = make3_str(make1_str("extract("), $3, make1_str(")")); }
| POSITION '(' position_list ')'
- {
- $$ = make3_str(make1_str("position ("), $3, make1_str(")"));
- }
+ { $$ = make3_str(make1_str("position("), $3, make1_str(")")); }
| SUBSTRING '(' substr_list ')'
- {
- $$ = make3_str(make1_str("substring ("), $3, make1_str(")"));
- }
+ { $$ = make3_str(make1_str("substring("), $3, make1_str(")")); }
/* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
| TRIM '(' BOTH trim_list ')'
- {
- $$ = make3_str(make1_str("trim(both"), $4, make1_str(")"));
- }
+ { $$ = make3_str(make1_str("trim(both"), $4, make1_str(")")); }
| TRIM '(' LEADING trim_list ')'
- {
- $$ = make3_str(make1_str("trim(leading"), $4, make1_str(")"));
- }
+ { $$ = make3_str(make1_str("trim(leading"), $4, make1_str(")")); }
| TRIM '(' TRAILING trim_list ')'
- {
- $$ = make3_str(make1_str("trim(trailing"), $4, make1_str(")"));
- }
+ { $$ = make3_str(make1_str("trim(trailing"), $4, make1_str(")")); }
| TRIM '(' trim_list ')'
- {
- $$ = make3_str(make1_str("trim("), $3, make1_str(")"));
- }
- | civariableonly
- { $$ = $1; }
+ { $$ = make3_str(make1_str("trim("), $3, make1_str(")")); }
+ | '(' SubSelect ')'
+ { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
+ | EXISTS '(' SubSelect ')'
+ { $$ = make3_str(make1_str("exists("), $3, make1_str(")")); }
;
-
-opt_indirection: '[' ecpg_expr ']' opt_indirection
+/*
+ * This used to use ecpg_expr, but since there is no shift/reduce conflict
+ * anymore, we can remove ecpg_expr. - MM
+ */
+opt_indirection: '[' a_expr ']' opt_indirection
{
$$ = cat4_str(make1_str("["), $2, make1_str("]"), $4);
}
- | '[' ecpg_expr ':' ecpg_expr ']' opt_indirection
+ | '[' a_expr ':' a_expr ']' opt_indirection
{
$$ = cat2_str(cat5_str(make1_str("["), $2, make1_str(":"), $4, make1_str("]")), $6);
}
| /* EMPTY */
- { $$ = make1_str(""); }
+ { $$ = EMPTY; }
;
expr_list: a_expr_or_null
$$ = cat3_str($1, make1_str("from"), $3);
}
| /* EMPTY */
- { $$ = make1_str(""); }
+ { $$ = EMPTY; }
| cinputvariable
{ $$ = make1_str("?"); }
;
position_list: b_expr IN b_expr
{ $$ = cat3_str($1, make1_str("in"), $3); }
| /* EMPTY */
- { $$ = make1_str(""); }
+ { $$ = EMPTY; }
;
substr_list: expr_list substr_from substr_for
$$ = cat3_str($1, $2, $3);
}
| /* EMPTY */
- { $$ = make1_str(""); }
+ { $$ = EMPTY; }
;
substr_from: FROM expr_list
{ $$ = cat2_str(make1_str("from"), $2); }
| /* EMPTY */
{
- $$ = make1_str("");
+ $$ = EMPTY;
}
;
substr_for: FOR expr_list
{ $$ = cat2_str(make1_str("for"), $2); }
| /* EMPTY */
- { $$ = make1_str(""); }
+ { $$ = EMPTY; }
;
trim_list: a_expr FROM expr_list
;
case_default: ELSE a_expr_or_null { $$ = cat2_str(make1_str("else"), $2); }
- | /*EMPTY*/ { $$ = make1_str(""); }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
case_arg: a_expr {
$$ = $1;
}
| /*EMPTY*/
- { $$ = make1_str(""); }
+ { $$ = EMPTY; }
;
attr: relation_name '.' attrs opt_indirection
}
opt_server: server { $$ = $1; }
- | /* empty */ { $$ = make1_str(""); }
+ | /* empty */ { $$ = EMPTY; }
server_name: ColId { $$ = $1; }
| ColId '.' server_name { $$ = make3_str($1, make1_str("."), $3); }
opt_port: ':' Iconst { $$ = make2_str(make1_str(":"), $2); }
- | /* empty */ { $$ = make1_str(""); }
+ | /* empty */ { $$ = EMPTY; }
opt_connection_name: AS connection_target { $$ = $2; }
| /* empty */ { $$ = make1_str("NULL"); }
$$ = make2_str(make1_str("?"), $2);
}
- | /* empty */ { $$ = make1_str(""); }
+ | /* empty */ { $$ = EMPTY; }
/*
* Declare a prepared cursor. The syntax is different from the standard
variable_declarations: /* empty */
{
- $$ = make1_str("");
+ $$ = EMPTY;
}
| declaration variable_declarations
{
| S_CONST { $$ = make1_str("const"); }
| S_REGISTER { $$ = make1_str("register"); }
| S_AUTO { $$ = make1_str("auto"); }
- | /* empty */ { $$ = make1_str(""); }
+ | /* empty */ { $$ = EMPTY; }
type: simple_type
{
| varchar_type
{
$$.type_enum = ECPGt_varchar;
- $$.type_str = make1_str("");
+ $$.type_str = EMPTY;
$$.type_dimension = -1;
$$.type_index = -1;
}
/* this is for typedef'ed types */
struct typedefs *this = get_typedef($1);
- $$.type_str = (this->type->type_enum == ECPGt_varchar) ? make1_str("") : mm_strdup(this->name);
+ $$.type_str = (this->type->type_enum == ECPGt_varchar) ? EMPTY : mm_strdup(this->name);
$$.type_enum = this->type->type_enum;
$$.type_dimension = this->type->type_dimension;
$$.type_index = this->type->type_index;
$$ = cat2_str(make1_str("union"), $2);
}
-opt_symbol: /* empty */ { $$ = make1_str(""); }
+opt_symbol: /* empty */ { $$ = EMPTY; }
| symbol { $$ = $1; }
simple_type: S_SHORT { $$ = ECPGt_short; }
free($2);
}
-opt_initializer: /* empty */ { $$ = make1_str(""); }
+opt_initializer: /* empty */ { $$ = EMPTY; }
| '=' c_term { $$ = make2_str(make1_str("="), $2); }
-opt_pointer: /* empty */ { $$ = make1_str(""); }
+opt_pointer: /* empty */ { $$ = EMPTY; }
| '*' { $$ = make1_str("*"); }
/*
sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $2);
add_variable(&argsinsert, thisquery, &no_indicator);
- } opt_using
+ } ecpg_using
{
$$ = make1_str("?");
}
/*
* open is an open cursor, at the moment this has to be removed
*/
-ECPGOpen: SQL_OPEN name opt_using {
+ECPGOpen: SQL_OPEN name ecpg_using {
$$ = $2;
};
-opt_using: /* empty */ { $$ = make1_str(""); }
+ecpg_using: /* empty */ { $$ = EMPTY; }
| USING variablelist {
/* yyerror ("open cursor with variables not implemented yet"); */
- $$ = make1_str("");
+ $$ = EMPTY;
}
variablelist: cinputvariable | cinputvariable ',' variablelist
on_off: ON { $$ = make1_str("on"); }
| SQL_OFF { $$ = make1_str("off"); }
-to_equal: TO | "=";
+to_equal: TO | '=';
/*
* set the actual connection, this needs a differnet handling as the other
{
$$.index1 = -1;
$$.index2 = -1;
- $$.str= make1_str("");
+ $$.str= EMPTY;
}
;
opt_reference: SQL_REFERENCE { $$ = make1_str("reference"); }
- | /* empty */ { $$ = make1_str(""); }
+ | /* empty */ { $$ = EMPTY; }
ctype: CHAR
{
sql_variable_declarations: /* empty */
{
- $$ = make1_str("");
+ $$ = EMPTY;
}
| sql_declaration sql_variable_declarations
{
}
/* some other stuff for ecpg */
-ecpg_expr: attr
- {
- $$ = $1;
- }
- | row_expr
- { $$ = $1; }
- | AexprConst
- { $$ = $1; }
- | ColId opt_indirection
- {
- $$ = cat2_str($1, $2);
- }
+/*
+ * no longer used
+ecpg_expr: com_expr
+ { $$ = $1; }
+ | a_expr TYPECAST Typename
+ { $$ = cat3_str($1, make1_str("::"), $3); }
| '-' ecpg_expr %prec UMINUS
{ $$ = cat2_str(make1_str("-"), $2); }
| '%' ecpg_expr
{ $$ = cat2_str(make1_str("%"), $2); }
| '^' ecpg_expr
{ $$ = cat2_str(make1_str("^"), $2); }
- | ';' ecpg_expr
- { $$ = cat2_str(make1_str(";"), $2); }
| '|' ecpg_expr
- { $$ = cat2_str(make1_str("|"), $2); }
+ { $$ = cat2_str(make1_str("|"), $2); }
+ | ';' a_expr
+ { $$ = cat2_str(make1_str(";"), $2); }
| a_expr '%'
{ $$ = cat2_str($1, make1_str("%")); }
| a_expr '^'
| a_expr '>' ecpg_expr
{ $$ = cat3_str($1, make1_str(">"), $3); }
| a_expr '=' NULL_P
- { $$ = cat2_str($1, make1_str("= NULL")); }
- | NULL_P '=' a_expr
- { $$ = cat2_str(make1_str("= NULL"), $3); }
+ { $$ = cat2_str($1, make1_str("= NULL")); }
+ | NULL_P '=' ecpg_expr
+ { $$ = cat2_str(make1_str("= NULL"), $3); }
| a_expr '=' ecpg_expr
{ $$ = cat3_str($1, make1_str("="), $3); }
- | a_expr TYPECAST Typename
- {
- $$ = cat3_str($1, make1_str("::"), $3);
- }
- | CAST '(' a_expr AS Typename ')'
- {
- $$ = cat3_str(make2_str(make1_str("cast("), $3), make1_str("as"), make2_str($5, make1_str(")")));
- }
- | '(' a_expr_or_null ')'
- { $$ = make3_str(make1_str("("), $2, make1_str(")")); }
| a_expr Op ecpg_expr
- { $$ = cat3_str($1, $2, $3); }
- | a_expr LIKE ecpg_expr
- { $$ = cat3_str($1, make1_str("like"), $3); }
- | a_expr NOT LIKE ecpg_expr
- { $$ = cat3_str($1, make1_str("not like"), $4); }
+ { $$ = cat3_str($1, make1_str("="), $3); }
| Op ecpg_expr
{ $$ = cat2_str($1, $2); }
| a_expr Op
{ $$ = cat2_str($1, $2); }
- | func_name '(' '*' ')'
- {
- $$ = cat2_str($1, make1_str("(*)"));
- }
- | func_name '(' ')'
- {
- $$ = cat2_str($1, make1_str("()"));
- }
- | func_name '(' expr_list ')'
- {
- $$ = make4_str($1, make1_str("("), $3, make1_str(")"));
- }
- | CURRENT_DATE
- {
- $$ = make1_str("current_date");
- }
- | CURRENT_TIME
- {
- $$ = make1_str("current_time");
- }
- | CURRENT_TIME '(' Iconst ')'
- {
- if (atol($3) != 0)
- fprintf(stderr,"CURRENT_TIME(%s) precision not implemented; zero used instead", $3);
- $$ = make1_str("current_time");
- }
- | CURRENT_TIMESTAMP
- {
- $$ = make1_str("current_timestamp");
- }
- | CURRENT_TIMESTAMP '(' Iconst ')'
- {
- if (atol($3) != 0)
- fprintf(stderr,"CURRENT_TIMESTAMP(%s) precision not implemented; zero used instead",$3);
- $$ = make1_str("current_timestamp");
- }
- | CURRENT_USER
- {
- $$ = make1_str("current_user");
- }
- | USER
- {
- $$ = make1_str("user");
- }
- | EXISTS '(' SubSelect ')'
- {
- $$ = make3_str(make1_str("exists("), $3, make1_str(")"));
- }
- | EXTRACT '(' extract_list ')'
- {
- $$ = make3_str(make1_str("extract("), $3, make1_str(")"));
- }
- | POSITION '(' position_list ')'
- {
- $$ = make3_str(make1_str("position("), $3, make1_str(")"));
- }
- | SUBSTRING '(' substr_list ')'
- {
- $$ = make3_str(make1_str("substring("), $3, make1_str(")"));
- }
- /* various trim expressions are defined in SQL92 - thomas 1997-07-19 */
- | TRIM '(' BOTH trim_list ')'
- {
- $$ = make3_str(make1_str("trim(both"), $4, make1_str(")"));
- }
- | TRIM '(' LEADING trim_list ')'
- {
- $$ = make3_str(make1_str("trim(leading"), $4, make1_str(")"));
- }
- | TRIM '(' TRAILING trim_list ')'
- {
- $$ = make3_str(make1_str("trim(trailing"), $4, make1_str(")"));
- }
- | TRIM '(' trim_list ')'
- {
- $$ = make3_str(make1_str("trim("), $3, make1_str(")"));
- }
+ | a_expr AND ecpg_expr
+ { $$ = cat3_str($1, make1_str("and"), $3); }
+ | a_expr OR ecpg_expr
+ { $$ = cat3_str($1, make1_str("or"), $3); }
+ | NOT ecpg_expr
+ { $$ = cat2_str(make1_str("not"), $2); }
+ | a_expr LIKE ecpg_expr
+ { $$ = cat3_str($1, make1_str("like"), $3); }
+ | a_expr NOT LIKE ecpg_expr
+ { $$ = cat3_str($1, make1_str("not like"), $4); }
| a_expr ISNULL
{ $$ = cat2_str($1, make1_str("isnull")); }
| a_expr IS NULL_P
{ $$ = cat2_str($1, make1_str("notnull")); }
| a_expr IS NOT NULL_P
{ $$ = cat2_str($1, make1_str("is not null")); }
- /* IS TRUE, IS FALSE, etc used to be function calls
- * but let's make them expressions to allow the optimizer
- * a chance to eliminate them if a_expr is a constant string.
- * - thomas 1997-12-22
- */
| a_expr IS TRUE_P
- {
{ $$ = cat2_str($1, make1_str("is true")); }
- }
| a_expr IS NOT FALSE_P
- {
{ $$ = cat2_str($1, make1_str("is not false")); }
- }
| a_expr IS FALSE_P
- {
{ $$ = cat2_str($1, make1_str("is false")); }
- }
| a_expr IS NOT TRUE_P
- {
{ $$ = cat2_str($1, make1_str("is not true")); }
- }
| a_expr BETWEEN b_expr AND b_expr
{
$$ = cat5_str($1, make1_str("between"), $3, make1_str("and"), $5);
{
$$ = make4_str($1, make1_str(" not in ("), $5, make1_str(")"));
}
- | a_expr Op '(' SubSelect ')'
- {
- $$ = cat3_str($1, $2, make3_str(make1_str("("), $4, make1_str(")")));
- }
- | a_expr '+' '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("+("), $4, make1_str(")"));
- }
- | a_expr '-' '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("-("), $4, make1_str(")"));
- }
- | a_expr '*' '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("*("), $4, make1_str(")"));
- }
- | a_expr '/' '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("/("), $4, make1_str(")"));
- }
- | a_expr '%' '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("%("), $4, make1_str(")"));
- }
- | a_expr '^' '(' SubSelect ')'
+ | a_expr all_Op sub_type '(' SubSelect ')'
{
- $$ = make4_str($1, make1_str("^("), $4, make1_str(")"));
+ $$ = cat4_str($1, $2, $3, make3_str(make1_str("("), $5, make1_str(")")));
}
- | a_expr '|' '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("|("), $4, make1_str(")"));
- }
- | a_expr '<' '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("<("), $4, make1_str(")"));
- }
- | a_expr '>' '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str(">("), $4, make1_str(")"));
- }
- | a_expr '=' '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("=("), $4, make1_str(")"));
- }
- | a_expr Op ANY '(' SubSelect ')'
- {
- $$ = cat3_str($1, $2, make3_str(make1_str("any ("), $5, make1_str(")")));
- }
- | a_expr '+' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("+ any("), $5, make1_str(")"));
- }
- | a_expr '-' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("- any("), $5, make1_str(")"));
- }
- | a_expr '*' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("* any("), $5, make1_str(")"));
- }
- | a_expr '/' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("/ any("), $5, make1_str(")"));
- }
- | a_expr '%' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("% any("), $5, make1_str(")"));
- }
- | a_expr '^' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("^ any("), $5, make1_str(")"));
- }
- | a_expr '|' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("| any("), $5, make1_str(")"));
- }
- | a_expr '<' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("< any("), $5, make1_str(")"));
- }
- | a_expr '>' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("> any("), $5, make1_str(")"));
- }
- | a_expr '=' ANY '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("= any("), $5, make1_str(")"));
- }
- | a_expr Op ALL '(' SubSelect ')'
- {
- $$ = cat3_str($1, $2, make3_str(make1_str("all ("), $5, make1_str(")")));
- }
- | a_expr '+' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("+ all("), $5, make1_str(")"));
- }
- | a_expr '-' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("- all("), $5, make1_str(")"));
- }
- | a_expr '*' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("* all("), $5, make1_str(")"));
- }
- | a_expr '/' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("/ all("), $5, make1_str(")"));
- }
- | a_expr '%' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("% all("), $5, make1_str(")"));
- }
- | a_expr '^' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("^ all("), $5, make1_str(")"));
- }
- | a_expr '|' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("| all("), $5, make1_str(")"));
- }
- | a_expr '<' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("< all("), $5, make1_str(")"));
- }
- | a_expr '>' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("> all("), $5, make1_str(")"));
- }
- | a_expr '=' ALL '(' SubSelect ')'
- {
- $$ = make4_str($1, make1_str("=all("), $5, make1_str(")"));
- }
- | a_expr AND ecpg_expr
- { $$ = cat3_str($1, make1_str("and"), $3); }
- | a_expr OR ecpg_expr
- { $$ = cat3_str($1, make1_str("or"), $3); }
- | NOT ecpg_expr
- { $$ = cat2_str(make1_str("not"), $2); }
- | case_expr
+ | row_expr
{ $$ = $1; }
| civariableonly
{ $$ = $1; }
;
+*/
into_list : coutputvariable | into_list ',' coutputvariable;
ecpgstart: SQL_START { reset_variables();}
-c_args: /* empty */ { $$ = make1_str(""); }
+c_args: /* empty */ { $$ = EMPTY; }
| c_list { $$ = $1; }
coutputvariable : cvariable indicator {