ecpg now accepts array elements as arguments.

This commit is contained in:
Michael Meskes 2003-05-23 15:19:36 +00:00
parent 450d7e276e
commit d258fb91cf
4 changed files with 623 additions and 434 deletions

View File

@ -1436,6 +1436,11 @@ Tue May 20 11:47:00 CEST 2003
Thu May 22 09:33:54 CEST 2003
- ecpg now recognizes named struct/union usage.
Fri May 23 11:46:15 CEST 2003
- Synced parser and keyword table.
- ecpg now accepts array elements as input variables.
- Set ecpg version to 2.12.0.
- Set ecpg library to 3.4.2.
- Set pgtypes library to 1.0.0

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.57 2003/05/16 04:59:22 momjian Exp $
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/keywords.c,v 1.58 2003/05/23 15:19:34 meskes Exp $
*
*-------------------------------------------------------------------------
*/
@ -41,6 +41,7 @@ static ScanKeyword ScanKeywords[] = {
{"analyze", ANALYZE},
{"and", AND},
{"any", ANY},
{"array", ARRAY},
{"as", AS},
{"asc", ASC},
{"assertion", ASSERTION},
@ -126,6 +127,7 @@ static ScanKeyword ScanKeywords[] = {
{"extract", EXTRACT},
{"false", FALSE_P},
{"fetch", FETCH},
{"first", FIRST_P},
{"float", FLOAT_P},
{"for", FOR},
{"force", FORCE},
@ -141,6 +143,7 @@ static ScanKeyword ScanKeywords[] = {
{"group", GROUP_P},
{"handler", HANDLER},
{"having", HAVING},
{"hold", HOLD},
{"hour", HOUR_P},
{"ilike", ILIKE},
{"immediate", IMMEDIATE},
@ -170,6 +173,7 @@ static ScanKeyword ScanKeywords[] = {
{"key", KEY},
{"lancompiler", LANCOMPILER},
{"language", LANGUAGE},
{"last", LAST_P},
{"leading", LEADING},
{"left", LEFT},
{"level", LEVEL},
@ -241,6 +245,7 @@ static ScanKeyword ScanKeywords[] = {
{"rename", RENAME},
{"replace", REPLACE},
{"reset", RESET},
{"restart", RESTART},
{"restrict", RESTRICT},
{"returns", RETURNS},
{"revoke", REVOKE},

View File

@ -1,4 +1,4 @@
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.221 2003/05/22 17:09:00 meskes Exp $ */
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.222 2003/05/23 15:19:34 meskes Exp $ */
/* Copyright comment */
%{
@ -32,6 +32,19 @@ struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
struct ECPGtype ecpg_query = {ECPGt_char_variable, 0L, NULL, {NULL}};
static struct inf_compat_col
{
char *name;
char *indirection;
struct inf_compat_col *next;
} *informix_col;
static struct inf_compat_val
{
char *val;
struct inf_compat_val *next;
} *informix_val;
/*
* Handle parsing errors and warnings
*/
@ -135,6 +148,41 @@ make_name(void)
return(name);
}
static char *
create_questionmarks(char *name, bool array)
{
struct variable *p = find_variable(name);
int count;
char *result = EMPTY;
/* In case we have a struct, we have to print as many "?" as there are attributes in the struct
* An array is only allowed together with an element argument
* This is essantially only used for inserts, but using a struct as input parameter is an error anywhere else
* so we don't have to worry here. */
if (p->type->type == ECPGt_struct || (array && p->type->type == ECPGt_array && p->type->u.element->type == ECPGt_struct))
{
struct ECPGstruct_member *m;
if (p->type->type == ECPGt_struct)
m = p->type->u.members;
else
m = p->type->u.element->u.members;
for (count = 0; m != NULL; m=m->next, count++);
}
else
count = 1;
for (; count > 0; count --)
result = cat2_str(result, make_str("? , "));
/* removed the trailing " ," */
result[strlen(result)-3] = '\0';
return(result);
}
%}
%union {
@ -178,7 +226,7 @@ make_name(void)
/* ordinary key words in alphabetical order */
%token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD AFTER
AGGREGATE ALL ALTER ANALYSE ANALYZE AND ANY AS ASC
AGGREGATE ALL ALTER ANALYSE ANALYZE AND ANY ARRAY AS ASC
ASSERTION ASSIGNMENT AT AUTHORIZATION
BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT
@ -197,11 +245,11 @@ make_name(void)
EACH ELSE ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUSIVE
EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
FALSE_P FETCH FLOAT_P FOR FORCE FOREIGN FORWARD FREEZE FROM
FALSE_P FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD FREEZE FROM
FULL FUNCTION
GET GLOBAL GRANT GROUP_P
HANDLER HAVING HOUR_P
HANDLER HAVING HOLD HOUR_P
ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCREMENT INDEX INHERITS
INITIALLY INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P
@ -211,7 +259,7 @@ make_name(void)
KEY
LANCOMPILER LANGUAGE LEADING LEFT LEVEL LIKE LIMIT LISTEN
LANCOMPILER LANGUAGE LAST_P LEADING LEFT LEVEL LIKE LIMIT LISTEN
LOAD LOCAL LOCATION LOCK_P
MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
@ -227,7 +275,7 @@ make_name(void)
PRECISION PRESERVE PREPARE PRIMARY PRIOR PRIVILEGES PROCEDURAL PROCEDURE
READ REAL RECHECK REFERENCES REINDEX RELATIVE_P RENAME REPLACE
RESET RESTRICT RETURNS REVOKE RIGHT ROLLBACK ROW ROWS RULE
RESET RESTART RESTRICT RETURNS REVOKE RIGHT ROLLBACK ROW ROWS RULE
SCHEMA SCROLL SECOND_P SECURITY SELECT SEQUENCE SERIALIZABLE
SESSION SESSION_USER SET SETOF SHARE SHOW SIMILAR SIMPLE SMALLINT SOME
@ -239,7 +287,7 @@ make_name(void)
UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL UPDATE USAGE
USER USING
VACUUM VALID VALUE VALUES VARCHAR VARYING VERBOSE VERSION VIEW VOLATILE
VACUUM VALID VALUES VARCHAR VARYING VERBOSE VERSION VIEW VOLATILE
WHEN WHERE WITH WITHOUT WORK WRITE
YEAR_P
ZONE
@ -293,7 +341,7 @@ make_name(void)
%type <str> TableConstraint OptTableElementList Xconst opt_transaction
%type <str> ConstraintElem key_actions ColQualList type_name
%type <str> target_list target_el update_target_list alias_clause
%type <str> update_target_el opt_id qualified_name database_name
%type <str> update_target_el qualified_name database_name
%type <str> access_method attr_name index_name name func_name
%type <str> file_name AexprConst c_expr ConstTypename var_list
%type <str> a_expr b_expr TruncateStmt CommentStmt OnCommitOption opt_by
@ -302,18 +350,18 @@ make_name(void)
%type <str> trim_list in_expr substr_for attrs TableFuncElement
%type <str> Typename SimpleTypename Numeric opt_float opt_numeric
%type <str> opt_decimal Character character opt_varying opt_charset
%type <str> opt_collate opt_timezone opt_interval table_ref
%type <str> row_descriptor ConstDatetime AlterDomainStmt
%type <str> opt_collate opt_timezone opt_interval table_ref fetch_direction
%type <str> row_descriptor ConstDatetime AlterDomainStmt AlterSeqStmt
%type <str> SelectStmt into_clause OptTemp ConstraintAttributeSpec
%type <str> opt_table opt_all sort_clause sortby_list ConstraintAttr
%type <str> sortby OptUseOp qualified_name_list name_list ColId_or_Sconst
%type <str> group_clause having_clause from_clause opt_distinct
%type <str> group_clause having_clause from_clause opt_distinct opt_hold
%type <str> join_outer where_clause relation_expr sub_type opt_arg
%type <str> opt_column_list insert_rest InsertStmt OptimizableStmt
%type <str> columnList DeleteStmt LockStmt UpdateStmt CursorStmt
%type <str> opt_column_list insert_rest InsertStmt
%type <str> columnList DeleteStmt LockStmt UpdateStmt DeclareCursorStmt
%type <str> NotifyStmt columnElem UnlistenStmt TableElement rowdefinition
%type <str> copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
%type <str> FetchStmt direction fetch_how_many from_in CreateOpClassStmt
%type <str> FetchStmt from_in CreateOpClassStmt
%type <str> ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose
%type <str> opt_full func_arg OptWithOids opt_freeze opt_ecpg_into
%type <str> analyze_keyword opt_name_list ExplainStmt index_params
@ -335,22 +383,22 @@ make_name(void)
%type <str> DropTrigStmt TriggerOneEvent TriggerEvents RuleActionStmt
%type <str> TriggerActionTime CreateTrigStmt DropPLangStmt DropCastStmt
%type <str> CreatePLangStmt TriggerFuncArgs TriggerFuncArg simple_select
%type <str> ViewStmt LoadStmt CreatedbStmt createdb_opt_item
%type <str> ViewStmt LoadStmt CreatedbStmt createdb_opt_item ExplainableStmt
%type <str> createdb_opt_list opt_encoding OptInherit opt_equal
%type <str> AlterUserSetStmt privilege_list privilege privilege_target
%type <str> opt_grant_grant_option opt_revoke_grant_option
%type <str> opt_grant_grant_option opt_revoke_grant_option cursor_options
%type <str> transaction_mode_list_or_empty transaction_mode_list
%type <str> function_with_argtypes_list function_with_argtypes
%type <str> DropdbStmt ClusterStmt grantee RevokeStmt Bit DropOpClassStmt
%type <str> GrantStmt privileges PosAllConst constraints_set_list
%type <str> opt_cursor ConstraintsSetStmt AllConst CreateDomainStmt
%type <str> ConstraintsSetStmt AllConst CreateDomainStmt
%type <str> case_expr when_clause_list case_default case_arg when_clause
%type <str> select_clause opt_select_limit select_limit_value opt_recheck
%type <str> ConstraintTimeSpec AlterDatabaseSetStmt DropAssertStmt
%type <str> select_offset_value ReindexStmt join_type opt_boolean
%type <str> join_qual update_list joined_table opclass_item
%type <str> opt_lock lock_type OptGroupList OptGroupElem
%type <str> OptConstrFromTable OptTempTableName StringConst
%type <str> join_qual update_list joined_table opclass_item fetch_count
%type <str> opt_lock lock_type OptGroupList OptGroupElem array_expr_list
%type <str> OptConstrFromTable OptTempTableName StringConst array_expr
%type <str> constraints_set_mode comment_type opt_empty_parentheses
%type <str> CreateGroupStmt AlterGroupStmt DropGroupStmt key_delete
%type <str> opt_force key_update CreateSchemaStmt PosIntStringConst
@ -391,8 +439,8 @@ make_name(void)
%type <str> ECPGGetDescriptorHeader ECPGColLabel single_var_declaration
%type <str> reserved_keyword unreserved_keyword ecpg_interval
%type <str> col_name_keyword func_name_keyword precision opt_scale
%type <str> ECPGTypeName variablelist ECPGColLabelCommon
%type <str> s_struct_union_symbol
%type <str> ECPGTypeName variablelist ECPGColLabelCommon c_variable
%type <str> s_struct_union_symbol inf_val_list inf_col_list
%type <descriptor> ECPGGetDescriptor
@ -433,8 +481,8 @@ opt_at: AT connection_target
{
connection = $2;
/*
* if we have a variable as connection
* target, remove it from the variable
* Do we have a variable as connection target?
* Remove the variable from the variable
* list or else it will be used twice
*/
if (argsinsert != NULL)
@ -444,44 +492,54 @@ opt_at: AT connection_target
stmt: AlterDatabaseSetStmt { output_statement($1, 0, connection); }
| AlterDomainStmt { output_statement($1, 0, connection); }
| AlterGroupStmt { output_statement($1, 0, connection); }
| AlterSeqStmt { output_statement($1, 0, connection); }
| AlterTableStmt { output_statement($1, 0, connection); }
| AlterUserStmt { output_statement($1, 0, connection); }
| AlterUserSetStmt { output_statement($1, 0, connection); }
| AlterUserStmt { output_statement($1, 0, connection); }
| AnalyzeStmt { output_statement($1, 0, connection); }
| CheckPointStmt { output_statement($1, 0, connection); }
| ClosePortalStmt { output_statement($1, 0, connection); }
| ClusterStmt { output_statement($1, 0, connection); }
| CommentStmt { output_statement($1, 0, connection); }
| ConstraintsSetStmt { output_statement($1, 0, connection); }
| CopyStmt { output_statement($1, 0, connection); }
| CreateStmt { output_statement($1, 0, connection); }
| CreateAsStmt { output_statement($1, 0, connection); }
| CreateAssertStmt { output_statement($1, 0, connection); }
| CreateCastStmt { output_statement($1, 0, connection); }
| CreateConversionStmt { output_statement($1, 0, connection); }
| CreateDomainStmt { output_statement($1, 0, connection); }
| CreateFunctionStmt { output_statement($1, 0, connection); }
| CreateSchemaStmt { output_statement($1, 0, connection); }
| CreateGroupStmt { output_statement($1, 0, connection); }
| CreateSeqStmt { output_statement($1, 0, connection); }
| CreatePLangStmt { output_statement($1, 0, connection); }
| CreateAssertStmt { output_statement($1, 0, connection); }
| CreateOpClassStmt { output_statement($1, 0, connection); }
| CreateSchemaStmt { output_statement($1, 0, connection); }
| CreateSeqStmt { output_statement($1, 0, connection); }
| CreateStmt { output_statement($1, 0, connection); }
| CreateTrigStmt { output_statement($1, 0, connection); }
| CreateUserStmt { output_statement($1, 0, connection); }
| ClusterStmt { output_statement($1, 0, connection); }
| CreatedbStmt { output_statement($1, 0, connection); }
/*| DeallocateStmt { output_statement($1, 0, connection); }*/
| DeclareCursorStmt { output_simple_statement($1); }
| DefineStmt { output_statement($1, 0, connection); }
| DropStmt { output_statement($1, 0, connection); }
| TruncateStmt { output_statement($1, 0, connection); }
| DeleteStmt { output_statement($1, 0, connection); }
| DropAssertStmt { output_statement($1, 0, connection); }
| DropCastStmt { output_statement($1, 0, connection); }
| DropGroupStmt { output_statement($1, 0, connection); }
| DropOpClassStmt { output_statement($1, 0, connection); }
| DropPLangStmt { output_statement($1, 0, connection); }
| DropAssertStmt { output_statement($1, 0, connection); }
| DropTrigStmt { output_statement($1, 0, connection); }
| DropRuleStmt { output_statement($1, 0, connection); }
| DropStmt { output_statement($1, 0, connection); }
| DropTrigStmt { output_statement($1, 0, connection); }
| DropUserStmt { output_statement($1, 0, connection); }
| ExplainStmt { output_statement($1, 0, connection); }/* | ExecuteStmt { output_statement($1, 0, connection); }*/
| DropdbStmt { output_statement($1, 0, connection); }
| ExplainStmt { output_statement($1, 0, connection); }
/* | ExecuteStmt { output_statement($1, 0, connection); }*/
| FetchStmt { output_statement($1, 1, connection); }
| GrantStmt { output_statement($1, 0, connection); }
| IndexStmt { output_statement($1, 0, connection); }
| InsertStmt { output_statement($1, 0, connection); }
| ListenStmt { output_statement($1, 0, connection); }
| UnlistenStmt { output_statement($1, 0, connection); }
| LoadStmt { output_statement($1, 0, connection); }
| LockStmt { output_statement($1, 0, connection); }
| NotifyStmt { output_statement($1, 0, connection); }
/* | PrepareStmt { output_statement($1, 0, connection); }*/
@ -491,32 +549,22 @@ stmt: AlterDatabaseSetStmt { output_statement($1, 0, connection); }
| RemoveFuncStmt { output_statement($1, 0, connection); }
| RenameStmt { output_statement($1, 0, connection); }
| RevokeStmt { output_statement($1, 0, connection); }
| OptimizableStmt
{
if (strncmp($1, "/* " , sizeof("/* ")-1) == 0)
output_simple_statement($1);
else
output_statement($1, 1, connection);
}
| RuleStmt { output_statement($1, 0, connection); }
| SelectStmt { output_statement($1, 0, connection); }
| TransactionStmt
{
fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1);
whenever_action(2);
free($1);
}
| ViewStmt { output_statement($1, 0, connection); }
| LoadStmt { output_statement($1, 0, connection); }
| CreatedbStmt { output_statement($1, 0, connection); }
| DropdbStmt { output_statement($1, 0, connection); }
| TruncateStmt { output_statement($1, 0, connection); }
| UnlistenStmt { output_statement($1, 0, connection); }
| UpdateStmt { output_statement($1, 0, connection); }
| VacuumStmt { output_statement($1, 0, connection); }
| AnalyzeStmt { output_statement($1, 0, connection); }
| VariableSetStmt { output_statement($1, 0, connection); }
| VariableShowStmt { output_statement($1, 0, connection); }
| VariableResetStmt { output_statement($1, 0, connection); }
| ConstraintsSetStmt { output_statement($1, 0, connection); }
| CheckPointStmt { output_statement($1, 0, connection); }
| CreateConversionStmt { output_statement($1, 0, connection); }
| ViewStmt { output_statement($1, 0, connection); }
| ECPGAllocateDescr
{
fprintf(yyout,"ECPGallocate_desc(__LINE__, %s);",$1);
@ -1010,6 +1058,9 @@ AlterTableStmt:
/* ALTER TABLE <name> OWNER TO UserId */
| ALTER TABLE qualified_name OWNER TO UserId
{ $$ = cat_str(4, make_str("alter table"), $3, make_str("owner to"), $6); }
/* ALTER TABLE <name> CLUSTER ON <indexname> */
| ALTER TABLE qualified_name CLUSTER ON name
{ $$ = cat_str(4, make_str("alter table"), $3, make_str("cluster on"), $6); }
;
alter_column_default:
@ -1025,15 +1076,11 @@ opt_drop_behavior: CASCADE { $$ = make_str("cascade"); }
/*****************************************************************************
*
* QUERY :
* close <optname>
* close <portalname>
*
*****************************************************************************/
ClosePortalStmt: CLOSE opt_id { $$ = cat2_str(make_str("close"), $2); }
;
opt_id: ColId { $$ = $1; }
| /*EMPTY*/ { $$ = NULL; }
ClosePortalStmt: CLOSE name { $$ = cat2_str(make_str("close"), $2); }
;
/*****************************************************************************
@ -1121,16 +1168,8 @@ OptTemp: TEMPORARY { $$ = make_str("temporary"); }
| TEMP { $$ = make_str("temp"); }
| LOCAL TEMPORARY { $$ = make_str("local temporary"); }
| LOCAL TEMP { $$ = make_str("local temp"); }
| GLOBAL TEMPORARY
{
mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported CREATE TABLE / GLOBAL TEMPORARY will be passed to backend");
$$ = make_str("global temporary");
}
| GLOBAL TEMP
{
mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported CREATE TABLE / GLOBAL TEMP will be passed to backend");
$$ = make_str("global temp");
}
| GLOBAL TEMPORARY { $$ = make_str("global temporary"); }
| GLOBAL TEMP { $$ = make_str("global temp"); }
| /*EMPTY*/ { $$ = EMPTY; }
;
@ -1343,6 +1382,7 @@ CreateAsElement: ColId { $$ = $1; }
*
* QUERY :
* CREATE SEQUENCE seqname
* ALTER SEQUENCE seqname
*
*****************************************************************************/
@ -1350,6 +1390,10 @@ CreateSeqStmt: CREATE OptTemp SEQUENCE qualified_name OptSeqList
{ $$ = cat_str(4, make_str("create sequence"), $2, $4, $5); }
;
AlterSeqStmt: ALTER SEQUENCE qualified_name OptSeqList
{ $$ = cat_str(3,make_str("alter sequence"), $3, $4); }
;
OptSeqList: OptSeqList OptSeqElem { $$ = cat2_str($1, $2); }
| /*EMPTY*/ { $$ = EMPTY; }
;
@ -1372,6 +1416,8 @@ OptSeqElem: CACHE NumConst
{ $$ = make_str("no minvalue"); }
| START opt_with NumConst
{ $$ = cat_str(3, make_str("start"), $2, $3); }
| RESTART opt_with NumConst
{ $$ = cat_str(3, make_str("restart"), $2, $3); }
;
opt_by: BY { $$ = make_str("by"); }
@ -1662,48 +1708,38 @@ TruncateStmt: TRUNCATE opt_table qualified_name
/*****************************************************************************
*
* QUERY:
* fetch/move [forward | backward] [ # | all ] [ in <portalname> ]
* fetch [ forward | backward | absolute | relative ]
* [ # | all | next | prior ] [ [ in | from ] <portalname> ]
* fetch/move
*
*****************************************************************************/
FetchStmt: FETCH direction fetch_how_many from_in name ecpg_into
{ $$ = cat_str(5, make_str("fetch"), $2, $3, $4, $5); }
| FETCH fetch_how_many from_in name ecpg_into
FetchStmt: FETCH fetch_direction from_in name ecpg_into
{ $$ = cat_str(4, make_str("fetch"), $2, $3, $4); }
| FETCH direction from_in name ecpg_into
{ $$ = cat_str(4, make_str("fetch"), $2, $3, $4); }
| FETCH from_in name ecpg_into
{ $$ = cat_str(3, make_str("fetch"), $2, $3); }
| FETCH name ecpg_into
{ $$ = cat2_str(make_str("fetch"), $2); }
| MOVE direction fetch_how_many from_in name
{ $$ = cat_str(5, make_str("move"), $2, $3, $4, $5); }
| MOVE fetch_how_many from_in name
| MOVE fetch_direction from_in name
{ $$ = cat_str(4, make_str("move"), $2, $3, $4); }
| MOVE direction from_in name
{ $$ = cat_str(4, make_str("move"), $2, $3, $4); }
| MOVE from_in name
{ $$ = cat_str(3, make_str("move"), $2, $3); }
| MOVE name
{ $$ = cat2_str(make_str("move"), $2); }
;
direction: FORWARD { $$ = make_str("forward"); }
| BACKWARD { $$ = make_str("backward"); }
| RELATIVE_P { $$ = make_str("relative"); }
| ABSOLUTE_P
{
mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported FETCH/ABSOLUTE will be passed to backend, backend will use RELATIVE");
$$ = make_str("absolute");
}
;
fetch_how_many: IntConst { $$ = $1; }
| ALL { $$ = make_str("all"); }
fetch_direction: /* EMPTY */ { $$ = EMPTY; }
| NEXT { $$ = make_str("next"); }
| PRIOR { $$ = make_str("prior"); }
| FIRST_P { $$ = make_str("first"); }
| LAST_P { $$ = make_str("last"); }
| ABSOLUTE_P fetch_count { $$ = cat2_str(make_str("absolute"), $2); }
| RELATIVE_P fetch_count { $$ = cat2_str(make_str("relative"), $2); }
| fetch_count { $$ = $1; }
| ALL { $$ = make_str("all"); }
| FORWARD { $$ = make_str("forward"); }
| FORWARD fetch_count { $$ = cat2_str(make_str("forward"), $2); }
| FORWARD ALL { $$ = make_str("forward all"); }
| BACKWARD { $$ = make_str("backward"); }
| BACKWARD fetch_count { $$ = cat2_str(make_str("backward"), $2); }
| BACKWARD ALL { $$ = make_str("backward all"); }
;
fetch_count: IntConst { $$ = $1; }
;
from_in: IN_P { $$ = make_str("in"); }
@ -2419,12 +2455,18 @@ opt_name_list: '(' name_list ')'
*
*****************************************************************************/
ExplainStmt: EXPLAIN opt_analyze opt_verbose OptimizableStmt
ExplainStmt: EXPLAIN opt_analyze opt_verbose ExplainableStmt
{ $$ = cat_str(4, make_str("explain"), $2, $3, $4); }
/* | EXPLAIN opt_analyze opt_verbose ExecuteStmt
{ $$ = cat_str(4, make_str("explain"), $2, $3, $4); }*/
;
ExplainableStmt:
SelectStmt
| InsertStmt
| UpdateStmt
| DeleteStmt
| DeclareCursorStmt
/* | ExecuteStmt */
;
opt_analyze:
analyze_keyword { $$ = $1; }
| /* EMPTY */ { $$ = EMPTY; }
@ -2434,10 +2476,17 @@ opt_analyze:
conflicts with ecpg
PrepareStmt: PREPARE name prep_type_clause AS OptimizableStmt
PrepareStmt: PREPARE name prep_type_clause AS PreparableStmt
{ $$ = cat_str(5, make_str("prepare"), $2, $3, make_str("as"), $5); }
;
PreparableStmt:
SelectStmt
| InsertStmt
| UpdateStmt
| DeleteStmt
;
prep_type_clause: '(' prep_type_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
| /* EMPTY * / { $$ = EMPTY; }
;
@ -2459,25 +2508,6 @@ DeallocateStmt: DEALLOCATE name { $$ = cat2_str(make_str("deallocate"), $2); }
;
*/
/*****************************************************************************
* *
* Optimizable Stmts: *
* *
* one of the five queries processed by the planner *
* *
* [ultimately] produces query-trees as specified *
* in the query-spec document in ~postgres/ref *
* *
*****************************************************************************/
OptimizableStmt: SelectStmt
| CursorStmt
| UpdateStmt
| InsertStmt
| DeleteStmt
;
/*****************************************************************************
*
* QUERY:
@ -2564,7 +2594,7 @@ UpdateStmt: UPDATE relation_expr
* CURSOR STATEMENTS
*
*****************************************************************************/
CursorStmt: DECLARE name opt_cursor CURSOR FOR SelectStmt
DeclareCursorStmt: DECLARE name cursor_options CURSOR opt_hold FOR SelectStmt
{
struct cursor *ptr, *this;
@ -2584,7 +2614,7 @@ CursorStmt: DECLARE name opt_cursor CURSOR FOR SelectStmt
this->next = cur;
this->name = $2;
this->connection = connection;
this->command = cat_str(5, make_str("declare"), mm_strdup($2), $3, make_str("cursor for"), $6);
this->command = cat_str(7, make_str("declare"), mm_strdup($2), $3, make_str("cursor"), $5, make_str("for"), $7);
this->argsinsert = argsinsert;
this->argsresult = argsresult;
argsinsert = argsresult = NULL;
@ -2595,11 +2625,16 @@ CursorStmt: DECLARE name opt_cursor CURSOR FOR SelectStmt
}
;
opt_cursor: BINARY { $$ = make_str("binary"); }
| INSENSITIVE { $$ = make_str("insensitive"); }
| SCROLL { $$ = make_str("scroll"); }
| INSENSITIVE SCROLL { $$ = make_str("insensitive scroll"); }
| /*EMPTY*/ { $$ = EMPTY; }
cursor_options: /* EMPTY */ { $$ = EMPTY; }
| cursor_options BINARY { $$ = cat2_str($1, make_str("binary")); }
| cursor_options INSENSITIVE { $$ = cat2_str($1, make_str("insensitive")); }
| cursor_options SCROLL { $$ = cat2_str($1, make_str("scroll")); }
| cursor_options NO SCROLL { $$ = cat2_str($1, make_str("no scroll")); }
;
opt_hold: /* EMPTY */ { $$ = EMPTY; }
| WITH HOLD { $$ = make_str("with hold"); }
| WITHOUT HOLD { $$ = make_str("without hold"); }
;
/*****************************************************************************
@ -2672,15 +2707,9 @@ OptTempTableName: TEMPORARY opt_table qualified_name
| LOCAL TEMP opt_table qualified_name
{ $$ = cat_str(3, make_str("local temp"), $3, $4); }
| GLOBAL TEMPORARY opt_table qualified_name
{
mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported CREATE TABLE / GLOBAL TEMPORARY will be passed to backend");
$$ = cat_str(3, make_str("global temporary"), $3, $4);
}
{ $$ = cat_str(3, make_str("global temporary"), $3, $4); }
| GLOBAL TEMP opt_table qualified_name
{
mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported CREATE TABLE / GLOBAL TEMP will be passed to backend");
$$ = cat_str(3, make_str("global temp"), $3, $4);
}
{ $$ = cat_str(3, make_str("global temp"), $3, $4); }
| TABLE qualified_name
{ $$ = cat2_str(make_str("table"), $2); }
| qualified_name
@ -2952,6 +2981,10 @@ Typename: SimpleTypename opt_array_bounds
{ $$ = cat2_str($1, $2.str); }
| SETOF SimpleTypename opt_array_bounds
{ $$ = cat_str(3, make_str("setof"), $2, $3); }
| SimpleTypename ARRAY '[' PosIntConst ']'
{ $$ = cat_str(4, $1, make_str("array ["), $4, make_str("]")); }
| SETOF SimpleTypename ARRAY '[' PosIntConst ']'
{ $$ = cat_str(5, make_str("setof"), $2, make_str("array ["), $5, make_str("]")); }
;
@ -3461,10 +3494,10 @@ c_expr: columnref
{ $$ = $1; }
| PARAM attrs opt_indirection
{ $$ = cat_str(3, make_str("param"), $2, $3); }
| '(' a_expr ')'
{ $$ = cat_str(3, make_str("("), $2, make_str(")")); }
| '(' a_expr ')' attrs opt_indirection
{ $$ = cat_str(5, make_str("("), $2, make_str(")"), $4, $5); }
| '(' a_expr ')' opt_indirection
{ $$ = cat_str(4, make_str("("), $2, make_str(")"), $4); }
| case_expr
{ $$ = $1; }
| func_name '(' ')'
@ -3522,8 +3555,10 @@ c_expr: columnref
{ $$ = $1; }
| EXISTS select_with_parens
{ $$ = cat2_str(make_str("exists"), $2); }
| VALUE
{ $$ = make_str("value"); }
| ARRAY select_with_parens
{ $$ = cat2_str(make_str("array"), $2); }
| ARRAY array_expr
{ $$ = cat2_str(make_str("array"), $2); }
;
/*
* This used to use ecpg_expr, but since there is no shift/reduce conflict
@ -3555,6 +3590,14 @@ type_list: type_list ',' Typename
{ $$ = $1; }
;
array_expr_list: array_expr { $$ = $1; }
| array_expr_list ',' array_expr { $$ = cat_str(3, $1, make_str(","), $3); }
;
array_expr: '[' expr_list ']' { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
| '[' array_expr_list ']' { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
;
/* Allow delimited string SCONST in extract_arg as an SQL extension.
* - thomas 2001-04-12
*/
@ -3714,12 +3757,74 @@ target_el: a_expr AS ColLabel
/* Target list as found in UPDATE table SET ... */
update_target_list: update_target_list ',' update_target_el
{ $$ = cat_str(3, $1, make_str(","),$3); }
| '(' inf_col_list ')' '=' '(' inf_val_list ')'
{
struct inf_compat_col *ptrc;
struct inf_compat_val *ptrv;
char *cols = make_str( "(" );
char *vals = make_str( "(" );
for (ptrc = informix_col, ptrv = informix_val; ptrc != NULL && ptrv != NULL; ptrc = ptrc->next, ptrv = ptrv->next)
{
if ( ptrc->next != NULL )
{
cols = cat_str(4, cols, ptrc->name, ptrc->indirection, make_str(",") );
}
else
{
cols = cat_str(4, cols, ptrc->name, ptrc->indirection, make_str(")") );
}
if (ptrv->next != NULL )
vals = cat_str(3, vals, ptrv->val, make_str("," ) );
else
vals = cat_str( 3, vals, ptrv->val, make_str(")") );
}
$$ = cat_str( 3, cols, make_str("="), vals );
}
| update_target_el
{ $$ = $1; }
| '*'
{ $$ = make_str("*"); }
;
inf_col_list: ColId opt_indirection
{
struct inf_compat_col *ptr = mm_alloc(sizeof(struct inf_compat_col));
ptr->name = $1;
ptr->indirection = $2;
ptr->next = NULL;
informix_col = ptr;
}
| ColId opt_indirection ',' inf_col_list
{
struct inf_compat_col *ptr = mm_alloc(sizeof(struct inf_compat_col));
ptr->name = $1;
ptr->indirection = $2;
ptr->next = informix_col;
informix_col = ptr;
}
;
inf_val_list: a_expr
{
struct inf_compat_val *ptr = mm_alloc(sizeof(struct inf_compat_val));
ptr->val = $1;
ptr->next = NULL;
informix_val = ptr;
}
| a_expr ',' inf_val_list
{
struct inf_compat_val *ptr = mm_alloc(sizeof(struct inf_compat_val));
ptr->val = $1;
ptr->next = informix_val;
informix_val = ptr;
}
;
update_target_el: ColId opt_indirection '=' a_expr
{ $$ = cat_str(4, $1, $2, make_str("="), $4); }
;
@ -3807,7 +3912,7 @@ AexprConst: PosAllConst
| NULL_P
{ $$ = make_str("null"); }
| civarind
{ $$ = make_str("?"); }
{ $$ = $1; }
;
Iconst: ICONST { $$ = make_name();};
@ -3826,7 +3931,7 @@ Sconst: SCONST
;
PosIntConst: Iconst { $$ = $1; }
| civar { $$ = make_str("?"); }
| civar { $$ = $1; }
;
IntConst: PosIntConst { $$ = $1; }
@ -3834,19 +3939,19 @@ IntConst: PosIntConst { $$ = $1; }
;
StringConst: Sconst { $$ = $1; }
| civar { $$ = make_str("?"); }
| civar { $$ = $1; }
;
PosIntStringConst: Iconst { $$ = $1; }
| Sconst { $$ = $1; }
| civar { $$ = make_str("?"); }
| civar { $$ = $1; }
;
NumConst: Fconst { $$ = $1; }
| Iconst { $$ = $1; }
| '-' Fconst { $$ = cat2_str(make_str("-"), $2); }
| '-' Iconst { $$ = cat2_str(make_str("-"), $2); }
| civar { $$ = make_str("?"); }
| civar { $$ = $1; }
;
AllConst: Sconst { $$ = $1; }
@ -3858,7 +3963,7 @@ PosAllConst: Sconst { $$ = $1; }
| Iconst { $$ = $1; }
| Bconst { $$ = $1; }
| Xconst { $$ = $1; }
| civar { $$ = make_str("?"); }
| civar { $$ = $1; }
;
UserId: ColId { $$ = $1;};
@ -3936,9 +4041,10 @@ connection_target: database_name opt_server opt_port
}
| StringConst
{
printf("MM: %s\n", $1);
if ($1[0] == '\"')
$$ = $1;
else if (strcmp($1, "?") == 0) /* variable */
else if (strcmp($1, " ?") == 0) /* variable */
{
enum ECPGttype type = argsinsert->variable->type->type;
@ -4094,7 +4200,7 @@ opt_options: Op ColId
* Declare a prepared cursor. The syntax is different from the standard
* declare statement, so we create a new rule.
*/
ECPGCursorStmt: DECLARE name opt_cursor CURSOR FOR ident
ECPGCursorStmt: DECLARE name cursor_options CURSOR opt_hold FOR ident
{
struct cursor *ptr, *this;
struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
@ -4115,14 +4221,14 @@ ECPGCursorStmt: DECLARE name opt_cursor CURSOR FOR ident
this->next = cur;
this->name = $2;
this->connection = connection;
this->command = cat_str(4, make_str("declare"), mm_strdup($2), $3, make_str("cursor for ?"));
this->command = cat_str(6, make_str("declare"), mm_strdup($2), $3, make_str("cursor"), $5, make_str("for ?"));
this->argsresult = NULL;
thisquery->type = &ecpg_query;
thisquery->brace_level = 0;
thisquery->next = NULL;
thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($6));
sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $6);
thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($7));
sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $7);
this->argsinsert = NULL;
add_variable(&(this->argsinsert), thisquery, NULL, &no_indicator, NULL);
@ -5004,9 +5110,9 @@ opt_ecpg_into: /*EMPTY*/ { $$ = EMPTY; }
| ecpg_into { $$ = $1; }
;
variable: civarind | civar
;
variablelist: variable | variable ',' variablelist;
c_variable: civarind | civar;
variablelist: c_variable | c_variable ',' variablelist;
/*
* As long as the prepare statement is not supported by the backend, we will
@ -5523,11 +5629,13 @@ unreserved_keyword:
| EXECUTE { $$ = make_str("execute"); }
| EXPLAIN { $$ = make_str("explain"); }
| FETCH { $$ = make_str("fetch"); }
| FIRST_P { $$ = make_str("first"); }
| FORCE { $$ = make_str("force"); }
| FORWARD { $$ = make_str("forward"); }
| FUNCTION { $$ = make_str("function"); }
| GLOBAL { $$ = make_str("global"); }
| HANDLER { $$ = make_str("handler"); }
| HOLD { $$ = make_str("hold"); }
| HOUR_P { $$ = make_str("hour"); }
| IMMEDIATE { $$ = make_str("immediate"); }
| IMMUTABLE { $$ = make_str("immutable"); }
@ -5536,6 +5644,7 @@ unreserved_keyword:
| INDEX { $$ = make_str("index"); }
| INHERITS { $$ = make_str("inherits"); }
| INOUT { $$ = make_str("inout"); }
| INPUT_P { $$ = make_str("input"); }
| INSENSITIVE { $$ = make_str("insensitive"); }
| INSERT { $$ = make_str("insert"); }
| INSTEAD { $$ = make_str("instead"); }
@ -5543,6 +5652,7 @@ unreserved_keyword:
| KEY { $$ = make_str("key"); }
| LANCOMPILER { $$ = make_str("lancompiler"); }
| LANGUAGE { $$ = make_str("language"); }
| LAST_P { $$ = make_str("last"); }
| LEVEL { $$ = make_str("level"); }
| LISTEN { $$ = make_str("listen"); }
| LOAD { $$ = make_str("load"); }
@ -5588,6 +5698,7 @@ unreserved_keyword:
| RENAME { $$ = make_str("rename"); }
| REPLACE { $$ = make_str("replace"); }
| RESET { $$ = make_str("reset"); }
| RESTART { $$ = make_str("restart"); }
| RESTRICT { $$ = make_str("restrict"); }
| RETURNS { $$ = make_str("returns"); }
| REVOKE { $$ = make_str("revoke"); }
@ -5597,9 +5708,9 @@ unreserved_keyword:
| SCHEMA { $$ = make_str("schema"); }
| SCROLL { $$ = make_str("scroll"); }
| SECOND_P { $$ = make_str("second"); }
| SESSION { $$ = make_str("session"); }
| SEQUENCE { $$ = make_str("sequence"); }
| SERIALIZABLE { $$ = make_str("serializable"); }
| SESSION { $$ = make_str("session"); }
| SET { $$ = make_str("set"); }
| SHARE { $$ = make_str("share"); }
| SHOW { $$ = make_str("show"); }
@ -5611,6 +5722,7 @@ unreserved_keyword:
| STDIN { $$ = make_str("stdin"); }
| STDOUT { $$ = make_str("stdout"); }
| STORAGE { $$ = make_str("storage"); }
| STRICT_P { $$ = make_str("strict"); }
| SYSID { $$ = make_str("sysid"); }
| TEMP { $$ = make_str("temp"); }
| TEMPLATE { $$ = make_str("template"); }
@ -5635,8 +5747,8 @@ unreserved_keyword:
| VIEW { $$ = make_str("view"); }
| WITH { $$ = make_str("with"); }
| WITHOUT { $$ = make_str("without"); }
| WRITE { $$ = make_str("write"); }
| WORK { $$ = make_str("work"); }
| WRITE { $$ = make_str("write"); }
| YEAR_P { $$ = make_str("year"); }
| ZONE { $$ = make_str("zone"); }
;
@ -5733,6 +5845,7 @@ reserved_keyword:
| ANALYZE { $$ = make_str("analyze"); }
| AND { $$ = make_str("and"); }
| ANY { $$ = make_str("any"); }
| ARRAY { $$ = make_str("array"); }
| AS { $$ = make_str("as"); }
| ASC { $$ = make_str("asc"); }
| BOTH { $$ = make_str("both"); }
@ -5808,8 +5921,16 @@ c_args: /*EMPTY*/ { $$ = EMPTY; }
| c_list { $$ = $1; }
;
coutputvariable: CVARIABLE indicator
coutputvariable: CVARIABLE '[' Iresult ']' indicator '[' Iresult ']'
{ add_variable(&argsresult, find_variable($1), $3, find_variable($5), $7); }
| CVARIABLE indicator '[' Iresult ']'
{ add_variable(&argsresult, find_variable($1), NULL, find_variable($2), $4); }
| CVARIABLE '[' Iresult ']' indicator
{ add_variable(&argsresult, find_variable($1), $3, find_variable($5), NULL); }
| CVARIABLE indicator
{ add_variable(&argsresult, find_variable($1), NULL, find_variable($2), NULL); }
| CVARIABLE '[' Iresult ']'
{ add_variable(&argsresult, find_variable($1), $3, &no_indicator, NULL); }
| CVARIABLE
{ add_variable(&argsresult, find_variable($1), NULL, &no_indicator, NULL); }
;
@ -5817,17 +5938,13 @@ coutputvariable: CVARIABLE indicator
civarind: CVARIABLE '[' Iresult ']' indicator '[' Iresult ']'
{
if (find_variable($5)->type->type == ECPGt_array)
mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
add_variable(&argsinsert, find_variable($1), $3, find_variable($5), $7);
$$ = create_questionmarks($1, true);
}
| CVARIABLE indicator '[' Iresult ']'
{
if (find_variable($2)->type->type == ECPGt_array)
mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
add_variable(&argsinsert, find_variable($1), NULL, find_variable($2), $4);
$$ = create_questionmarks($1, false);
}
| CVARIABLE '[' Iresult ']' indicator
{
@ -5835,6 +5952,7 @@ civarind: CVARIABLE '[' Iresult ']' indicator '[' Iresult ']'
mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
add_variable(&argsinsert, find_variable($1), $3, find_variable($5), NULL);
$$ = create_questionmarks($1, true);
}
| CVARIABLE indicator
{
@ -5842,18 +5960,19 @@ civarind: CVARIABLE '[' Iresult ']' indicator '[' Iresult ']'
mmerror(PARSE_ERROR, ET_ERROR, "arrays of indicators are not allowed on input");
add_variable(&argsinsert, find_variable($1), NULL, find_variable($2), NULL);
$$ = create_questionmarks($1, false);
}
;
civar: CVARIABLE '[' Iresult ']'
{
add_variable(&argsinsert, find_variable($1), $3, &no_indicator, NULL);
$$ = cat_str(4, $1, make_str("["), $3, make_str("]"));
add_variable(&argsinsert, find_variable($1), mm_strdup($3), &no_indicator, NULL);
$$ = create_questionmarks($1, true);
}
| CVARIABLE
{
add_variable(&argsinsert, find_variable($1), NULL, &no_indicator, NULL);
$$ = $1;
$$ = create_questionmarks($1, false);
}
;

View File

@ -233,21 +233,81 @@ ECPGdump_a_type(FILE *o, const char *name, struct ECPGtype * type,
break;
case ECPGt_struct:
case ECPGt_union:
ECPGdump_a_struct(o, name, ind_name, type->size, type->u.element, (ind_type->type == ECPGt_NO_INDICATOR) ? ind_type : ind_type->u.element, NULL, prefix, ind_prefix);
/* If var_array_element is not equal * NULL, we have to use the * <var_array_element>th entry and not * the whole array */ if (var_array_element == NULL)
ECPGdump_a_struct(o, name, ind_name, type->size,
type->u.element,
(ind_type->type == ECPGt_NO_INDICATOR) ? ind_type : ind_type->u.element,
NULL, prefix, ind_prefix);
else
{
char *array_element = (char *)mm_alloc(strlen(name) + strlen(var_array_element) + sizeof("[]\0")), *ind_array_element;
sprintf(array_element, "%s[%s]", name, var_array_element);
if (ind_type->type != ECPGt_NO_INDICATOR)
{
ind_array_element = (char *)mm_alloc(strlen(ind_name) + strlen(ind_array_element) + sizeof("+\0"));
sprintf(ind_array_element, "%s[%s]", ind_name, ind_array_element);
ECPGdump_a_struct(o, array_element, ind_array_element, make_str("1"),
type->u.element, ind_type->u.element,
NULL, prefix, ind_prefix);
free(ind_array_element);
}
else
ECPGdump_a_struct(o, array_element, ind_name, make_str("1"),
type->u.element, ind_type,
NULL, prefix, ind_prefix);
free (array_element);
}
break;
default:
if (!IS_SIMPLE_TYPE(type->u.element->type))
yyerror("Internal error: unknown datatype, please inform pgsql-bugs@postgresql.org");
ECPGdump_a_simple(o, name, type->u.element->type,
/* If var_array_element is not equal
* NULL, we have to use the
* <var_array_element>th entry and not
* the whole array */
if (var_array_element == NULL)
ECPGdump_a_simple(o, name,
type->u.element->type,
type->u.element->size, type->size, NULL, prefix);
else
{
char *array_element = (char *)mm_alloc(strlen(name) + strlen(var_array_element) + sizeof("+\0"));
sprintf(array_element, "%s+%s", name, var_array_element);
ECPGdump_a_simple(o, array_element,
type->u.element->type,
type->u.element->size, make_str("1"), NULL, prefix);
free(array_element);
}
if (ind_type != NULL)
{
if (ind_type->type == ECPGt_NO_INDICATOR)
ECPGdump_a_simple(o, ind_name, ind_type->type, ind_type->size, make_str("-1"), NULL, ind_prefix);
else
{
if (ind_array_element == NULL)
ECPGdump_a_simple(o, ind_name, ind_type->u.element->type,
ind_type->u.element->size, ind_type->size, NULL, prefix);
else
{
char *array_element = (char *)mm_alloc(strlen(ind_name) + strlen(ind_array_element) + sizeof("+\0"));
sprintf(array_element, "%s+%s", ind_name, ind_array_element);
ECPGdump_a_simple(o, array_element,
ind_type->u.element->type,
ind_type->u.element->size,
make_str("1"), NULL, prefix);
free(array_element);
}
}
}
}
break;