-/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/Attic/preproc.y,v 1.230 2003/06/11 06:39:12 meskes Exp $ */
+/* $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/preproc.y,v 1.314 2005/12/27 04:00:08 momjian Exp $ */
/* Copyright comment */
%{
*/
int struct_level = 0;
int braces_open; /* brace level counter */
-char errortext[128];
+int ecpg_informix_var = 0;
char *connection = NULL;
char *input_filename = NULL;
static int QueryIsRule = 0, FoundInto = 0;
static int initializer = 0;
static struct this_type actual_type[STRUCT_DEPTH];
-static char *actual_storage[STRUCT_DEPTH];
static char *actual_startline[STRUCT_DEPTH];
/* temporarily store struct members while creating the data structure */
* Handle parsing errors and warnings
*/
void
-mmerror(int error_code, enum errortype type, char * error)
+mmerror(int error_code, enum errortype type, char * error, ...)
{
+ va_list ap;
+
+ fprintf(stderr, "%s:%d: ", input_filename, yylineno);
+
+ switch(type)
+ {
+ case ET_WARNING:
+ fprintf(stderr, "WARNING: ");
+ break;
+ case ET_ERROR:
+ case ET_FATAL:
+ fprintf(stderr, "ERROR: ");
+ break;
+ }
+
+ va_start(ap, error);
+ vfprintf(stderr, error, ap);
+ va_end(ap);
+
+ fprintf(stderr, "\n");
+
switch(type)
{
case ET_WARNING:
- fprintf(stderr, "%s:%d: WARNING: %s\n", input_filename, yylineno, error);
break;
case ET_ERROR:
- fprintf(stderr, "%s:%d: ERROR: %s\n", input_filename, yylineno, error);
ret_value = error_code;
break;
case ET_FATAL:
- fprintf(stderr, "%s:%d: ERROR: %s\n", input_filename, yylineno, error);
exit(error_code);
}
}
return(res_str);
}
+/* and the rest */
static char *
make_name(void)
{
return(result);
}
+static char *
+adjust_informix(struct arguments *list)
+{
+ /* Informix accepts DECLARE with variables that are out of scope when OPEN is called.
+ * for instance you can declare variables in a function, and then subsequently use them
+ * {
+ * declare_vars();
+ * exec sql ... which uses vars declared in the above function
+ *
+ * This breaks standard and leads to some very dangerous programming.
+ * Since they do, we have to work around and accept their syntax as well.
+ * But we will do so ONLY in Informix mode.
+ * We have to change the variables to our own struct and just store the pointer instead of the variable
+ */
+
+ struct arguments *ptr;
+ char *result = make_str("");
+
+ for (ptr = list; ptr != NULL; ptr = ptr->next)
+ {
+ char temp[20]; /* this should be sufficient unless you have 8 byte integers */
+ char *original_var;
+
+ /* change variable name to "ECPG_informix_get_var(<counter>)" */
+ original_var = ptr->variable->name;
+ sprintf(temp, "%d))", ecpg_informix_var);
+
+ if ((ptr->variable->type->type != ECPGt_varchar && ptr->variable->type->type != ECPGt_char && ptr->variable->type->type != ECPGt_unsigned_char) && atoi(ptr->variable->type->size) > 1)
+ {
+ ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ECPGtype_name(ptr->variable->type->u.element->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type, make_str("1")), ptr->variable->type->size), 0);
+ sprintf(temp, "%d, (", ecpg_informix_var++);
+ }
+ else if ((ptr->variable->type->type == ECPGt_varchar || ptr->variable->type->type == ECPGt_char || ptr->variable->type->type == ECPGt_unsigned_char) && atoi(ptr->variable->type->size) > 1)
+ {
+ ptr->variable = new_variable(cat_str(4, make_str("("), mm_strdup(ECPGtype_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size), 0);
+ sprintf(temp, "%d, (", ecpg_informix_var++);
+ }
+ else
+ {
+ ptr->variable = new_variable(cat_str(4, make_str("*("), mm_strdup(ECPGtype_name(ptr->variable->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size), 0);
+ sprintf(temp, "%d, &(", ecpg_informix_var++);
+ }
+
+ /* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */
+ result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n"));
+
+ /* now the indicator if there is one */
+ if (ptr->indicator->type->type != ECPGt_NO_INDICATOR)
+ {
+ /* change variable name to "ECPG_informix_get_var(<counter>)" */
+ original_var = ptr->indicator->name;
+ sprintf(temp, "%d))", ecpg_informix_var);
+
+ /* create call to "ECPG_informix_set_var(<counter>, <pointer>. <linen number>)" */
+ if (atoi(ptr->indicator->type->size) > 1)
+ {
+ ptr->indicator = new_variable(cat_str(4, make_str("("), mm_strdup(ECPGtype_name(ptr->indicator->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size), 0);
+ sprintf(temp, "%d, (", ecpg_informix_var++);
+ }
+ else
+ {
+ ptr->indicator = new_variable(cat_str(4, make_str("*("), mm_strdup(ECPGtype_name(ptr->indicator->type->type)), make_str(" *)(ECPG_informix_get_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size), 0);
+ sprintf(temp, "%d, &(", ecpg_informix_var++);
+ }
+ result = cat_str(5, result, make_str("ECPG_informix_set_var("), mm_strdup(temp), mm_strdup(original_var), make_str("), __LINE__);\n"));
+ }
+ }
+
+ return result;
+}
+
+static struct cursor *
+add_additional_variables(char *name, bool insert)
+{
+ struct cursor *ptr;
+ struct arguments *p;
+
+ for (ptr = cur; ptr != NULL; ptr=ptr->next)
+ {
+ if (strcmp(ptr->name, name) == 0)
+ break;
+ }
+
+ if (ptr == NULL)
+ {
+ mmerror(PARSE_ERROR, ET_ERROR, "trying to access an undeclared cursor %s\n", name);
+ return NULL;
+ }
+ if (insert)
+ {
+ /* add all those input variables that were given earlier
+ * note that we have to append here but have to keep the existing order */
+ for (p = ptr->argsinsert; p; p = p->next)
+ add_variable_to_tail(&argsinsert, p->variable, p->indicator);
+ }
+
+ /* add all those output variables that were given earlier */
+ for (p = ptr->argsresult; p; p = p->next)
+ add_variable_to_tail(&argsresult, p->variable, p->indicator);
+
+ return ptr;
+}
%}
%union {
/* special embedded SQL token */
%token SQL_ALLOCATE SQL_AUTOCOMMIT SQL_BOOL SQL_BREAK
- SQL_CALL SQL_CARDINALITY SQL_CONNECT SQL_CONNECTION
+ SQL_CALL SQL_CARDINALITY SQL_CONNECT
SQL_CONTINUE SQL_COUNT SQL_CURRENT SQL_DATA
SQL_DATETIME_INTERVAL_CODE
SQL_DATETIME_INTERVAL_PRECISION SQL_DESCRIBE
SQL_FREE SQL_GO SQL_GOTO SQL_IDENTIFIED
SQL_INDICATOR SQL_KEY_MEMBER SQL_LENGTH
SQL_LONG SQL_NAME SQL_NULLABLE SQL_OCTET_LENGTH
- SQL_OPEN SQL_OUTPUT SQL_RELEASE SQL_REFERENCE
+ SQL_OPEN SQL_OUTPUT SQL_REFERENCE
SQL_RETURNED_LENGTH SQL_RETURNED_OCTET_LENGTH SQL_SCALE
SQL_SECTION SQL_SHORT SQL_SIGNED SQL_SQL SQL_SQLERROR
SQL_SQLPRINT SQL_SQLWARNING SQL_START SQL_STOP
%token TYPECAST
/* ordinary key words in alphabetical order */
-%token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD AFTER
- AGGREGATE ALL ALTER ANALYSE ANALYZE AND ANY ARRAY AS ASC
- ASSERTION ASSIGNMENT AT AUTHORIZATION
+%token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER
+ AGGREGATE ALL ALSO ALTER ANALYSE ANALYZE AND ANY ARRAY AS ASC
+ ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION
BACKWARD BEFORE BEGIN_P BETWEEN BIGINT BINARY BIT
BOOLEAN_P BOTH BY
CACHE CALLED CASCADE CASE CAST CHAIN CHAR_P
CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
- COMMITTED CONSTRAINT CONSTRAINTS CONVERSION_P CONVERT COPY
- CREATE CREATEDB CREATEUSER CROSS CURRENT_DATE CURRENT_TIME
+ COMMITTED CONNECTION CONSTRAINT CONSTRAINTS CONVERSION_P CONVERT COPY CREATE CREATEDB
+ CREATEROLE CREATEUSER CROSS CSV CURRENT_DATE CURRENT_ROLE CURRENT_TIME
CURRENT_TIMESTAMP CURRENT_USER CURSOR CYCLE
- DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT
+ DATABASE DAY_P DEALLOCATE DEC DECIMAL_P DECLARE DEFAULT DEFAULTS
DEFERRABLE DEFERRED DEFINER DELETE_P DELIMITER DELIMITERS
- DESC DISTINCT DO DOMAIN_P DOUBLE_P DROP
- EACH ELSE ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUSIVE
+ DESC DISABLE_P DISTINCT DO DOMAIN_P DOUBLE_P DROP
+
+ EACH ELSE ENABLE_P ENCODING ENCRYPTED END_P ESCAPE EXCEPT EXCLUSIVE EXCLUDING
EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT
FALSE_P FETCH FIRST_P FLOAT_P FOR FORCE FOREIGN FORWARD FREEZE FROM
FULL FUNCTION
- GET GLOBAL GRANT GROUP_P
- HANDLER HAVING HOLD HOUR_P
+ GET GLOBAL GRANT GRANTED GREATEST GROUP_P
+
+ HANDLER HAVING HEADER_P HOLD HOUR_P
- ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCREMENT INDEX INHERITS
- INITIALLY INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P
- INTEGER INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION
+ ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT
+ INDEX INHERIT INHERITS INITIALLY INNER_P INOUT INPUT_P
+ INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
+ INTERVAL INTO INVOKER IS ISNULL ISOLATION
JOIN
KEY
- LANCOMPILER LANGUAGE LAST_P LEADING LEFT LEVEL LIKE LIMIT LISTEN
- LOAD LOCAL LOCATION LOCK_P
+ LANCOMPILER LANGUAGE LARGE_P LAST_P LEADING LEAST LEFT LEVEL
+ LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION
+ LOCK_P LOGIN_P
MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE
NAMES NATIONAL NATURAL NCHAR NEW NEXT NO NOCREATEDB
- NOCREATEUSER NONE NOT NOTHING NOTIFY NOTNULL NULL_P NULLIF
- NUMERIC
+ NOCREATEROLE NOCREATEUSER NOINHERIT NOLOGIN_P NONE NOSUPERUSER
+ NOT NOTHING NOTIFY NOTNULL NOWAIT NULL_P NULLIF NUMERIC
- OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR ORDER
+ OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR ORDER
OUT_P OUTER_P OVERLAPS OVERLAY OWNER
- PARTIAL PASSWORD PATH_P PENDANT PLACING POSITION
- PRECISION PRESERVE PREPARE PRIMARY PRIOR PRIVILEGES PROCEDURAL PROCEDURE
+ PARTIAL PASSWORD PLACING POSITION
+ PRECISION PRESERVE PREPARE PREPARED PRIMARY
+ PRIOR PRIVILEGES PROCEDURAL PROCEDURE
- READ REAL RECHECK REFERENCES REINDEX RELATIVE_P RENAME REPLACE
- RESET RESTART RESTRICT RETURNS REVOKE RIGHT ROLLBACK ROW ROWS RULE
+ QUOTE
- SCHEMA SCROLL SECOND_P SECURITY SELECT SEQUENCE SERIALIZABLE
- SESSION SESSION_USER SET SETOF SHARE SHOW SIMILAR SIMPLE SMALLINT SOME
- STABLE START STATEMENT STATISTICS STDIN STDOUT STORAGE STRICT_P
- SUBSTRING SYSID
+ READ REAL RECHECK REFERENCES REINDEX RELATIVE_P RELEASE RENAME
+ REPEATABLE REPLACE RESET RESTART RESTRICT RETURNS REVOKE RIGHT
+ ROLE ROLLBACK ROW ROWS RULE
- TABLE TEMP TEMPLATE TEMPORARY THEN TIME TIMESTAMP TO TOAST
+ SAVEPOINT SCHEMA SCROLL SECOND_P SECURITY SELECT SEQUENCE
+ SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
+ SHOW SIMILAR SIMPLE SMALLINT SOME STABLE START STATEMENT
+ STATISTICS STDIN STDOUT STORAGE STRICT_P SUBSTRING SUPERUSER_P SYMMETRIC
+ SYSID SYSTEM_P
+
+ TABLE TABLESPACE TEMP TEMPLATE TEMPORARY THEN TIME TIMESTAMP TO TOAST
TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P TRUNCATE TRUSTED TYPE_P
- UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL UPDATE USAGE
- USER USING
+
+ UNCOMMITTED UNENCRYPTED UNION UNIQUE UNKNOWN UNLISTEN UNTIL
+ UPDATE USER USING
- VACUUM VALID VALUES VARCHAR VARYING VERBOSE VERSION VIEW VOLATILE
+ VACUUM VALID VALIDATOR VALUES VARCHAR VARYING VERBOSE VIEW VOLATILE
WHEN WHERE WITH WITHOUT WORK WRITE
YEAR_P
ZONE
*/
%token UNIONJOIN
-/* Special keywords, not in the query language - see the "lex" file */
+/* Special token types, not actually keywords - see the "lex" file */
%token <str> IDENT SCONST Op CSTRING CVARIABLE CPP_LINE IP BCONST XCONST
%token <ival> ICONST PARAM
%token <dval> FCONST
%left '.'
%left JOIN UNIONJOIN CROSS LEFT FULL RIGHT INNER_P NATURAL
-%type <str> Iconst Fconst Sconst TransactionStmt CreateStmt UserId
+%type <str> Iconst Fconst Sconst TransactionStmt CreateStmt RoleId
%type <str> CreateAsElement OptCreateAs CreateAsList CreateAsStmt
%type <str> comment_text ConstraintDeferrabilitySpec TableElementList
%type <str> key_match ColLabel SpecialRuleRelation ColId columnDef
%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 qualified_name database_name
+%type <str> update_target_el qualified_name database_name alter_using
%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
%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 fetch_direction
-%type <str> row_descriptor ConstDatetime AlterDomainStmt AlterSeqStmt
+%type <str> opt_timezone opt_interval table_ref fetch_direction
+%type <str> ConstDatetime AlterDomainStmt AlterSeqStmt alter_rel_cmds
%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> sortby qualified_name_list name_list ColId_or_Sconst
%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
-%type <str> columnList DeleteStmt LockStmt UpdateStmt DeclareCursorStmt
+%type <str> join_outer where_clause relation_expr sub_type arg_class
+%type <str> opt_column_list insert_rest InsertStmt WithOidsAs param_name
+%type <str> columnList DeleteStmt UpdateStmt DeclareCursorStmt
%type <str> NotifyStmt columnElem UnlistenStmt TableElement rowdefinition
%type <str> copy_delimiter ListenStmt CopyStmt copy_file_name opt_binary
-%type <str> FetchStmt from_in CreateOpClassStmt
+%type <str> FetchStmt from_in CreateOpClassStmt like_including_defaults
%type <str> ClosePortalStmt DropStmt VacuumStmt AnalyzeStmt opt_verbose
-%type <str> opt_full func_arg OptWithOids opt_freeze
+%type <str> opt_full func_arg OptWithOids opt_freeze alter_table_cmd
%type <str> analyze_keyword opt_name_list ExplainStmt index_params
-%type <str> index_elem opt_class access_method_clause
+%type <str> index_elem opt_class access_method_clause alter_table_cmds
%type <str> index_opt_unique IndexStmt func_return ConstInterval
%type <str> func_args_list func_args opt_with def_arg overlay_placing
%type <str> def_elem def_list definition DefineStmt select_with_parens
%type <str> opt_instead event RuleActionList opt_using CreateAssertStmt
%type <str> RuleActionStmtOrEmpty RuleActionMulti func_as reindex_type
-%type <str> RuleStmt opt_column opt_name oper_argtypes NumConst
-%type <str> MathOp RemoveFuncStmt aggr_argtype for_update_clause
+%type <str> RuleStmt opt_column oper_argtypes NumConst var_name
+%type <str> MathOp RemoveFuncStmt aggr_argtype ECPGunreserved_con
%type <str> RemoveAggrStmt opt_procedural select_no_parens CreateCastStmt
-%type <str> RemoveOperStmt RenameStmt all_Op opt_Trusted opt_lancompiler
+%type <str> RemoveOperStmt RenameStmt all_Op opt_trusted opt_lancompiler
%type <str> VariableSetStmt var_value zone_value VariableShowStmt
%type <str> VariableResetStmt AlterTableStmt from_list overlay_list
-%type <str> user_list OptUserList OptUserElem relation_name
+%type <str> relation_name OptTableSpace LockStmt opt_lock
%type <str> CreateUserStmt AlterUserStmt CreateSeqStmt OptSeqList
%type <str> OptSeqElem TriggerForSpec TriggerForOpt TriggerForType
%type <str> DropTrigStmt TriggerOneEvent TriggerEvents RuleActionStmt
%type <str> CreatePLangStmt TriggerFuncArgs TriggerFuncArg simple_select
%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 cursor_options
+%type <str> privilege_list privilege privilege_target
+%type <str> opt_grant_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> function_with_argtypes_list function_with_argtypes IntConstVar
%type <str> DropdbStmt ClusterStmt grantee RevokeStmt Bit DropOpClassStmt
%type <str> GrantStmt privileges PosAllConst constraints_set_list
-%type <str> ConstraintsSetStmt AllConst CreateDomainStmt
+%type <str> ConstraintsSetStmt AllConst CreateDomainStmt opt_nowait
%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 fetch_count
-%type <str> opt_lock lock_type OptGroupList OptGroupElem array_expr_list
+%type <str> join_qual joined_table opclass_item
+%type <str> lock_type array_expr_list
%type <str> OptConstrFromTable OptTempTableName StringConst array_expr
-%type <str> constraints_set_mode comment_type opt_empty_parentheses
+%type <str> constraints_set_mode comment_type
%type <str> CreateGroupStmt AlterGroupStmt DropGroupStmt key_delete
%type <str> opt_force key_update CreateSchemaStmt PosIntStringConst
%type <str> IntConst PosIntConst grantee_list func_type opt_or_replace
-%type <str> select_limit opt_for_update_clause CheckPointStmt
+%type <str> select_limit CheckPointStmt ECPGColId
%type <str> OptSchemaName OptSchemaEltList schema_stmt opt_drop_behavior
%type <str> handler_name any_name_list any_name opt_as insert_column_list
-%type <str> columnref dotted_name function_name insert_target_el
+%type <str> columnref function_name insert_target_el AllConstVar
%type <str> insert_target_list insert_column_item DropRuleStmt
-%type <str> createfunc_opt_item set_rest var_list_or_default
+%type <str> createfunc_opt_item set_rest var_list_or_default alter_rel_cmd
%type <str> CreateFunctionStmt createfunc_opt_list func_table
%type <str> DropUserStmt copy_from copy_opt_list copy_opt_item
%type <str> opt_oids TableLikeClause key_action opt_definition
-%type <str> cast_context row r_expr qual_Op qual_all_Op opt_default
+%type <str> cast_context row qual_Op qual_all_Op opt_default
%type <str> CreateConversionStmt any_operator opclass_item_list
%type <str> iso_level type_list CharacterWithLength ConstCharacter
%type <str> CharacterWithoutLength BitWithLength BitWithoutLength
%type <str> ConstBit GenericType TableFuncElementList opt_analyze
-%type <str> opt_sort_clause transaction_access_mode
-
+%type <str> opt_sort_clause subquery_Op transaction_mode_item
%type <str> ECPGWhenever ECPGConnect connection_target ECPGOpen
%type <str> indicator ECPGExecute ECPGPrepare ecpg_using ecpg_into
%type <str> storage_declaration storage_clause opt_initializer c_anything
%type <str> variable_list variable c_thing c_term ECPGKeywords_vanames
%type <str> opt_pointer ECPGDisconnect dis_name storage_modifier
-%type <str> ECPGRelease execstring server_name ECPGVarDeclaration
+%type <str> execstring server_name ECPGVarDeclaration func_expr
%type <str> connection_object opt_server opt_port c_stuff c_stuff_item
%type <str> user_name opt_user char_variable ora_user ident opt_reference
%type <str> var_type_declarations quoted_ident_stringvar ECPGKeywords_rest
%type <str> db_prefix server opt_options opt_connection_name c_list
-%type <str> ECPGSetConnection ECPGTypedef c_args ECPGKeywords
+%type <str> ECPGSetConnection ECPGTypedef c_args ECPGKeywords ECPGCKeywords
%type <str> enum_type civar civarind ECPGCursorStmt ECPGDeallocate
%type <str> ECPGFree ECPGDeclare ECPGVar opt_at enum_definition
%type <str> struct_union_type s_struct_union vt_declarations execute_rest
%type <str> ECPGGetDescriptorHeader ECPGColLabel single_var_declaration
%type <str> reserved_keyword unreserved_keyword ecpg_interval opt_ecpg_using
%type <str> col_name_keyword func_name_keyword precision opt_scale
-%type <str> ECPGTypeName using_list ECPGColLabelCommon
+%type <str> ECPGTypeName using_list ECPGColLabelCommon UsingConst
%type <str> inf_val_list inf_col_list using_descriptor into_descriptor
-%type <str> ecpg_into_using
+%type <str> prepared_name struct_union_type_with_symbol OptConsTableSpace
+%type <str> ECPGunreserved ECPGunreserved_interval cvariable
+%type <str> AlterOwnerStmt OptTableSpaceOwner CreateTableSpaceStmt
+%type <str> DropTableSpaceStmt indirection indirection_el ECPGSetDescriptorHeader
+%type <str> AlterDatabaseStmt CreateRoleStmt OptRoleList AlterRoleStmt AlterRoleSetStmt
+%type <str> DropRoleStmt add_drop opt_validator common_func_opt_item
+%type <str> opt_grant_admin_option AlterFunctionStmt alterfunc_opt_list opt_restrict
+%type <str> AlterObjectSchemaStmt alterdb_opt_list for_locking_clause opt_for_locking_clause
+%type <str> locked_rels_list opt_granted_by RevokeRoleStmt alterdb_opt_item using_clause
+%type <str> GrantRoleStmt opt_asymmetric
%type <struct_union> s_struct_union_symbol
-%type <descriptor> ECPGGetDescriptor
+%type <descriptor> ECPGGetDescriptor ECPGSetDescriptor
%type <type_enum> simple_type signed_type unsigned_type
%type <dtype_enum> descriptor_item desc_header_item
-%type <type> var_type common_type single_vt_type
-%type <type> struct_union_type_with_symbol
+%type <type> var_type
%type <action> action
| c_thing { fprintf(yyout, "%s", $1); free($1); }
| CPP_LINE { fprintf(yyout, "%s", $1); free($1); }
| '{' { braces_open++; fputs("{", yyout); }
- | '}' { remove_variables(braces_open--); fputs("}", yyout); }
+ | '}' { remove_typedefs(braces_open); remove_variables(braces_open--); fputs("}", yyout); }
;
opt_at: AT connection_target
argsinsert = NULL;
};
-stmt: AlterDatabaseSetStmt { output_statement($1, 0, connection); }
+stmt: AlterDatabaseStmt { output_statement($1, 0, connection); }
+ | AlterDatabaseSetStmt { output_statement($1, 0, connection); }
| AlterDomainStmt { output_statement($1, 0, connection); }
+ | AlterFunctionStmt { output_statement($1, 0, connection); }
| AlterGroupStmt { output_statement($1, 0, connection); }
+ | AlterObjectSchemaStmt { output_statement($1, 0, connection); }
+ | AlterOwnerStmt { output_statement($1, 0, connection); }
| AlterSeqStmt { output_statement($1, 0, connection); }
| AlterTableStmt { output_statement($1, 0, connection); }
- | AlterUserSetStmt { output_statement($1, 0, connection); }
+ | AlterRoleSetStmt { output_statement($1, 0, connection); }
+ | AlterRoleStmt { 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); }
+ | ClosePortalStmt
+ {
+ if (INFORMIX_MODE)
+ {
+ /* Informix also has a CLOSE DATABASE command that
+ essantially works like a DISCONNECT CURRENT
+ as far as I know. */
+ if (pg_strcasecmp($1+strlen("close "), "database") == 0)
+ {
+ if (connection)
+ mmerror(PARSE_ERROR, ET_ERROR, "no at option for close database statement.\n");
+
+ fprintf(yyout, "{ ECPGdisconnect(__LINE__, \"CURRENT\");");
+ whenever_action(2);
+ free($1);
+ }
+ else
+ output_statement($1, 0, connection);
+ }
+ else
+ output_statement($1, 0, connection);
+ }
| ClusterStmt { output_statement($1, 0, connection); }
| CommentStmt { output_statement($1, 0, connection); }
| ConstraintsSetStmt { output_statement($1, 0, connection); }
| CreateGroupStmt { output_statement($1, 0, connection); }
| CreatePLangStmt { output_statement($1, 0, connection); }
| CreateOpClassStmt { output_statement($1, 0, connection); }
+ | CreateRoleStmt { output_statement($1, 0, connection); }
| CreateSchemaStmt { output_statement($1, 0, connection); }
| CreateSeqStmt { output_statement($1, 0, connection); }
| CreateStmt { output_statement($1, 0, connection); }
+ | CreateTableSpaceStmt { output_statement($1, 0, connection); }
| CreateTrigStmt { output_statement($1, 0, connection); }
| CreateUserStmt { 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); }
- | DeleteStmt { output_statement($1, 0, connection); }
+ | DeleteStmt { output_statement($1, 1, 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); }
+ | DropRoleStmt { output_statement($1, 0, connection); }
| DropRuleStmt { output_statement($1, 0, connection); }
| DropStmt { output_statement($1, 0, connection); }
+ | DropTableSpaceStmt { output_statement($1, 0, connection); }
| DropTrigStmt { output_statement($1, 0, connection); }
| DropUserStmt { output_statement($1, 0, connection); }
| DropdbStmt { output_statement($1, 0, connection); }
/* | ExecuteStmt { output_statement($1, 0, connection); }*/
| FetchStmt { output_statement($1, 1, connection); }
| GrantStmt { output_statement($1, 0, connection); }
+ | GrantRoleStmt { output_statement($1, 0, connection); }
| IndexStmt { output_statement($1, 0, connection); }
- | InsertStmt { output_statement($1, 0, connection); }
+ | InsertStmt { output_statement($1, 1, connection); }
| ListenStmt { output_statement($1, 0, connection); }
| LoadStmt { output_statement($1, 0, connection); }
| LockStmt { output_statement($1, 0, connection); }
| RemoveFuncStmt { output_statement($1, 0, connection); }
| RenameStmt { output_statement($1, 0, connection); }
| RevokeStmt { output_statement($1, 0, connection); }
+ | RevokeRoleStmt { output_statement($1, 0, connection); }
| RuleStmt { output_statement($1, 0, connection); }
- | SelectStmt { output_statement($1, 0, connection); }
+ | SelectStmt { output_statement($1, 1, connection); }
| TransactionStmt
{
fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1);
}
| TruncateStmt { output_statement($1, 0, connection); }
| UnlistenStmt { output_statement($1, 0, connection); }
- | UpdateStmt { output_statement($1, 0, connection); }
+ | UpdateStmt { output_statement($1, 1, connection); }
| VacuumStmt { output_statement($1, 0, connection); }
| VariableSetStmt { output_statement($1, 0, connection); }
| VariableShowStmt { output_statement($1, 0, connection); }
if (connection)
mmerror(PARSE_ERROR, ET_ERROR, "no at option for connect statement.\n");
- if (compat == ECPG_COMPAT_INFORMIX)
- fprintf(yyout, "{ ECPGconnect_informix(__LINE__, %s, %d); ", $1, autocommit);
- else
- fprintf(yyout, "{ ECPGconnect(__LINE__, %s, %d); ", $1, autocommit);
+ fprintf(yyout, "{ ECPGconnect(__LINE__, %d, %s, %d); ", compat, $1, autocommit);
reset_variables();
whenever_action(2);
free($1);
| ECPGDeallocate
{
if (connection)
- mmerror(PARSE_ERROR, ET_ERROR, "no at option for connect statement.\n");
-
- fputc('{', yyout);
- fputs($1, yyout);
+ mmerror(PARSE_ERROR, ET_ERROR, "no at option for deallocate statement.\n");
+ fprintf(yyout, "{ ECPGdeallocate(__LINE__, %d, %s);", compat, $1);
whenever_action(2);
free($1);
}
| ECPGDeallocateDescr
{
+ if (connection)
+ mmerror(PARSE_ERROR, ET_ERROR, "no at option for deallocate statement.\n");
fprintf(yyout,"ECPGdeallocate_desc(__LINE__, %s);",$1);
whenever_action(0);
free($1);
}
| ECPGFree
{
- fprintf(yyout, "{ ECPGdeallocate(__LINE__, \"%s\");", $1);
+ fprintf(yyout, "{ ECPGdeallocate(__LINE__, %d, \"%s\");", compat, $1);
whenever_action(2);
free($1);
| ECPGOpen
{
struct cursor *ptr;
- struct arguments *p;
-
- for (ptr = cur; ptr != NULL; ptr=ptr->next)
- {
- if (strcmp(ptr->name, $1) == 0)
- break;
- }
-
- if (ptr == NULL)
- {
- snprintf(errortext, sizeof(errortext), "trying to open undeclared cursor %s\n", $1);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
- else
- {
- /* merge variables given in prepare statement with those given here */
- for (p = ptr->argsinsert; p; p = p->next)
- append_variable(&argsinsert, p->variable, p->indicator);
-
- for (p = ptr->argsresult; p; p = p->next)
- add_variable(&argsresult, p->variable, p->indicator);
+ if ((ptr = add_additional_variables($1, true)) != NULL)
output_statement(mm_strdup(ptr->command), 0, ptr->connection ? mm_strdup(ptr->connection) : NULL);
- }
+ ptr->opened = true;
}
| ECPGPrepare
{
whenever_action(2);
free($1);
}
- | ECPGRelease { /* output already done */ }
+ /* | ECPGRelease { / * output already done * / } */
| ECPGSetAutocommit
{
fprintf(yyout, "{ ECPGsetcommit(__LINE__, \"%s\", %s);", $1, connection ? connection : "NULL");
whenever_action(2);
free($1);
}
+ | ECPGSetDescriptor
+ {
+ lookup_descriptor($1.name, connection);
+ output_set_descr($1.name, $1.str);
+ free($1.name);
+ free($1.str);
+ }
+ | ECPGSetDescriptorHeader
+ {
+ lookup_descriptor($1, connection);
+ output_set_descr_header($1);
+ free($1);
+ }
| ECPGTypedef
{
if (connection)
/*****************************************************************************
*
- * Create a new Postgres DBMS user
+ * Create a new Postgres DBMS role
*
*
*****************************************************************************/
-CreateUserStmt: CREATE USER UserId opt_with OptUserList
- { $$ = cat_str(4, make_str("create user"), $3, make_str("with"), $5); }
+CreateRoleStmt: CREATE ROLE RoleId opt_with OptRoleList
+ { $$ = cat_str(4, make_str("create role"), $3, make_str("with"), $5); }
;
opt_with: WITH { $$ = make_str("with"); }
| /*EMPTY*/ { $$ = EMPTY; }
;
+/*
+ * Options for CREATE ROLE and ALTER ROLE (also used by CREATE/ALTER USER
+ * for backwards compatibility). Note: the only option required by SQL99
+ * is "WITH ADMIN name".
+ */
+OptRoleList:
+ PASSWORD Sconst { $$ = cat2_str(make_str("password"), $2); }
+ | ENCRYPTED PASSWORD Sconst { $$ = cat2_str(make_str("encrypted password"), $3); }
+ | UNENCRYPTED PASSWORD Sconst { $$ = cat2_str(make_str("unencrypted password"), $3); }
+ | SUPERUSER_P { $$ = make_str("superuser"); }
+ | NOSUPERUSER { $$ = make_str("nosuperuser"); }
+ | INHERIT { $$ = make_str("inherit"); }
+ | NOINHERIT { $$ = make_str("noinherit"); }
+ | CREATEDB { $$ = make_str("createdb"); }
+ | NOCREATEDB { $$ = make_str("nocreatedb"); }
+ | CREATEROLE { $$ = make_str("createrole"); }
+ | NOCREATEROLE { $$ = make_str("nocreaterole"); }
+ | LOGIN_P { $$ = make_str("login"); }
+ | NOLOGIN_P { $$ = make_str("nologin"); }
+ | CONNECTION LIMIT IntConst { $$ = cat2_str(make_str("connection limit"), $3); }
+ | VALID UNTIL Sconst { $$ = cat2_str(make_str("valid until"), $3); }
+ | USER name_list { $$ = cat2_str(make_str("user"), $2); }
+ | SYSID PosIntConst { $$ = cat2_str(make_str("sysid"), $2); }
+ | ADMIN name_list { $$ = cat2_str(make_str("admin"), $2); }
+ | ROLE name_list { $$ = cat2_str(make_str("role"), $2); }
+ | IN_P ROLE name_list { $$ = cat2_str(make_str("in role"), $3); }
+ | IN_P GROUP_P name_list { $$ = cat2_str(make_str("in group"), $3); }
+ ;
/*****************************************************************************
*
- * Alter a postgresql DBMS user
+ * Create a new Postgres DBMS user (role with implied login ability)
+ *
+ *****************************************************************************/
+
+CreateUserStmt:
+ CREATE USER RoleId opt_with OptRoleList
+ {
+ $$ = cat_str(4, make_str("create user"), $3, $4, $5);
+ }
+ ;
+
+
+/*****************************************************************************
+ *
+ * Alter a postgresql DBMS role
*
*
*****************************************************************************/
-AlterUserStmt: ALTER USER UserId OptUserList
- { $$ = cat_str(3, make_str("alter user"), $3, $4); }
- | ALTER USER UserId WITH OptUserList
- { $$ = cat_str(4, make_str("alter user"), $3, make_str("with"), $5); }
+AlterRoleStmt: ALTER ROLE RoleId opt_with OptRoleList
+ { $$ = cat_str(4, make_str("alter role"), $3, $4, $5); }
+ ;
+
+AlterRoleSetStmt: ALTER ROLE RoleId SET set_rest
+ { $$ = cat_str(4, make_str("alter role"), $3, make_str("set"), $5); }
+ | ALTER ROLE RoleId VariableResetStmt
+ { $$ = cat_str(3, make_str("alter role"), $3, $4); }
;
-AlterUserSetStmt: ALTER USER UserId SET set_rest
+/*****************************************************************************
+ *
+ * Alter a postgresql DBMS user
+ *
+ *****************************************************************************/
+
+AlterUserStmt: ALTER USER RoleId opt_with OptRoleList
+ { $$ = cat_str(4, make_str("alter user"), $3, $4, $5); };
+
+AlterRoleSetStmt: ALTER USER RoleId SET set_rest
{ $$ = cat_str(4, make_str("alter user"), $3, make_str("set"), $5); }
- | ALTER USER UserId VariableResetStmt
+ | ALTER USER RoleId VariableResetStmt
{ $$ = cat_str(3, make_str("alter user"), $3, $4); }
;
+/*****************************************************************************
+ *
+ * Drop a postgresql DBMS role
+ *
+ *
+ *****************************************************************************/
+DropRoleStmt: DROP ROLE name_list
+ { $$ = cat2_str(make_str("drop role"), $3);}
+ ;
+
/*****************************************************************************
*
* Drop a postgresql DBMS user
*
*
*****************************************************************************/
-DropUserStmt: DROP USER user_list
+DropUserStmt: DROP USER name_list
{ $$ = cat2_str(make_str("drop user"), $3);}
;
-/*
- * Options for CREATE USER and ALTER USER
- */
-
-OptUserList: OptUserList OptUserElem { $$ = cat2_str($1, $2); }
- | /* EMPTY */ { $$ = EMPTY; }
- ;
-
-OptUserElem: PASSWORD Sconst
- { $$ = cat2_str(make_str("password"), $2); }
- | SYSID PosIntConst
- { $$ = cat2_str(make_str("sysid"), $2); }
- | CREATEDB
- { $$ = make_str("createdb"); }
- | NOCREATEDB
- { $$ = make_str("nocreatedb"); }
- | CREATEUSER
- { $$ = make_str("createuser"); }
- | NOCREATEUSER
- { $$ = make_str("nocreateuser"); }
- | IN_P GROUP_P user_list
- { $$ = cat2_str(make_str("in group"), $3); }
- | VALID UNTIL Sconst
- { $$ = cat2_str(make_str("valid until"), $3); }
- ;
-
-user_list: user_list ',' UserId
- { $$ = cat_str(3, $1, make_str(","), $3); }
- | UserId
- { $$ = $1; }
- ;
/*****************************************************************************
*
*
*
****************************************************************************/
-CreateGroupStmt: CREATE GROUP_P UserId OptGroupList
- { $$ = cat_str(3, make_str("create group"), $3, $4); }
- | CREATE GROUP_P UserId WITH OptGroupList
- { $$ = cat_str(4, make_str("create group"), $3, make_str("with"), $5); }
- ;
-
-/*
- * Options for CREATE GROUP
- */
-OptGroupList: OptGroupList OptGroupElem { $$ = cat2_str($1, $2); }
- | /* EMPTY */ { $$ = EMPTY; }
+CreateGroupStmt: CREATE GROUP_P RoleId opt_with OptRoleList
+ { $$ = cat_str(4, make_str("create group"), $3, $4, $5); }
;
-OptGroupElem: USER user_list
- { $$ = cat2_str(make_str("user"), $2); }
- | SYSID PosIntConst
- { $$ = cat2_str(make_str("sysid"), $2); }
- ;
-
-
/*****************************************************************************
*
* Alter a postgresql group
*
*
*****************************************************************************/
-AlterGroupStmt: ALTER GROUP_P UserId ADD USER user_list
- { $$ = cat_str(4, make_str("alter group"), $3, make_str("add user"), $6); }
- | ALTER GROUP_P UserId DROP USER user_list
- { $$ = cat_str(4, make_str("alter group"), $3, make_str("drop user"), $6); }
+AlterGroupStmt: ALTER GROUP_P RoleId add_drop USER name_list
+ { $$ = cat_str(5, make_str("alter group"), $3, $4, make_str("user"), $6); }
;
+add_drop: ADD_P { $$ = make_str("add"); }
+ | DROP { $$ = make_str("drop"); }
+ ;
+
/*****************************************************************************
*
* Drop a postgresql group
*
*
*****************************************************************************/
-DropGroupStmt: DROP GROUP_P UserId
+DropGroupStmt: DROP GROUP_P name_list
{ $$ = cat2_str(make_str("drop group"), $3); }
;
*
*****************************************************************************/
-CreateSchemaStmt: CREATE SCHEMA UserId OptSchemaName AUTHORIZATION UserId OptSchemaEltList
- { $$ = cat_str(6, make_str("create scheme"), $3, $4, make_str("authorization"), $6, $7); }
+CreateSchemaStmt: CREATE SCHEMA OptSchemaName AUTHORIZATION RoleId OptSchemaEltList
+ { $$ = cat_str(5, make_str("create schema"), $3, make_str("authorization"), $5, $6); }
| CREATE SCHEMA ColId OptSchemaEltList
- { $$ = cat_str(3, make_str("create scheme"), $3, $4); }
+ { $$ = cat_str(3, make_str("create schema"), $3, $4); }
;
OptSchemaName: ColId { $$ = $1; }
* statement (in addition to by themselves).
*/
schema_stmt: CreateStmt { $$ = $1; }
+ | IndexStmt { $$ = $1; }
+ | CreateSeqStmt { $$ = $1; }
+ | CreateTrigStmt { $$ = $1; }
| GrantStmt { $$ = $1; }
| ViewStmt { $$ = $1; }
;
{ $$ = cat2_str(make_str("set session"), $3 ); }
;
-set_rest: ColId TO var_list_or_default
+set_rest: var_name TO var_list_or_default
{ $$ = cat_str(3, $1, make_str("to"), $3); }
- | ColId "=" var_list_or_default
+ | var_name "=" var_list_or_default
{ $$ = cat_str(3, $1, make_str("="), $3); }
| TIME ZONE zone_value
{ $$ = cat2_str(make_str("time zone"), $3); }
{ $$ = cat2_str(make_str("session characteristics as transaction"), $5); }
| NAMES opt_encoding
{ $$ = cat2_str(make_str("names"), $2); }
+ | ROLE ColId_or_Sconst
+ { $$ = cat2_str(make_str("role"), $2); }
| SESSION AUTHORIZATION ColId_or_Sconst
{ $$ = cat2_str(make_str("session authorization"), $3); }
| SESSION AUTHORIZATION DEFAULT
{ $$ = make_str("session authorization default"); }
;
+var_name: ECPGColId { $$ = $1; }
+ | var_name '.' ColId { $$ = cat_str(3, $1, make_str("."), $3); }
+ ;
+
+
var_list_or_default: var_list
{ $$ = $1; }
| DEFAULT
{ $$ = cat_str(3, $1, make_str(","), $3); }
;
-iso_level: READ COMMITTED { $$ = make_str("read committed"); }
+iso_level: READ UNCOMMITTED { $$ = make_str("read uncommitted"); }
+ | READ COMMITTED { $$ = make_str("read committed"); }
+ | REPEATABLE READ { $$ = make_str("repeatable read"); }
| SERIALIZABLE { $$ = make_str("serializable"); }
;
| StringConst { $$ = $1; }
;
-VariableShowStmt: SHOW ColId
+VariableShowStmt: SHOW var_name
{ $$ = cat2_str(make_str("show"), $2); }
| SHOW TIME ZONE
{ $$ = make_str("show time zone"); }
{ $$ = make_str("show all"); }
;
-VariableResetStmt: RESET ColId
+VariableResetStmt: RESET var_name
{ $$ = cat2_str(make_str("reset"), $2); }
| RESET TIME ZONE
{ $$ = make_str("reset time zone"); }
/*****************************************************************************
*
- * ALTER TABLE variations
+ * ALTER [ TABLE | INDEX ] variations
*
*****************************************************************************/
AlterTableStmt:
-/* ALTER TABLE <relation> ADD [COLUMN] <coldef> */
- ALTER TABLE relation_expr ADD opt_column columnDef
- { $$ = cat_str(5, make_str("alter table"), $3, make_str("add"), $5, $6); }
+ ALTER TABLE relation_expr alter_table_cmds
+ { $$ = cat_str(3, make_str("alter table"), $3, $4); }
+ | ALTER INDEX relation_expr alter_rel_cmds
+ { $$ = cat_str(3, make_str("alter table"), $3, $4); }
+ ;
+
+/* Subcommands that are for ALTER TABLE only */
+alter_table_cmds:
+ alter_table_cmd { $$ = $1; }
+ | alter_table_cmds ',' alter_table_cmd { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
+
+alter_table_cmd:
+ ADD_P opt_column columnDef
+/* ALTER TABLE <relation> ADD_P [COLUMN] <coldef> */
+ { $$ = cat_str(3, make_str("add"), $2, $3); }
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> {SET DEFAULT <expr>|DROP DEFAULT} */
- | ALTER TABLE relation_expr ALTER opt_column ColId alter_column_default
- { $$ = cat_str(6, make_str("alter table"), $3, make_str("alter"), $5, $6, $7); }
+ | ALTER opt_column ColId alter_column_default
+ { $$ = cat_str(4, make_str("alter"), $2, $3, $4); }
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> DROP NOT NULL */
- | ALTER TABLE relation_expr ALTER opt_column ColId DROP NOT NULL_P
- { $$ = cat_str(6, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("drop not null")); }
+ | ALTER opt_column ColId DROP NOT NULL_P
+ { $$ = cat_str(4, make_str("alter"), $2, $3, make_str("drop not null")); }
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET NOT NULL */
- | ALTER TABLE relation_expr ALTER opt_column ColId SET NOT NULL_P
- { $$ = cat_str(6, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("set not null")); }
+ | ALTER opt_column ColId SET NOT NULL_P
+ { $$ = cat_str(4, make_str("alter"), $2, $3, make_str("set not null")); }
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STATISTICS <IntegerOnly> */
- | ALTER TABLE relation_expr ALTER opt_column ColId SET STATISTICS PosIntConst
- { $$ = cat_str(7, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("set statistics"), $9); }
+ | ALTER opt_column ColId SET STATISTICS PosIntConst
+ { $$ = cat_str(5, make_str("alter"), $2, $3, make_str("set statistics"), $6); }
/* ALTER TABLE <relation> ALTER [COLUMN] <colname> SET STORAGE <storagemode> */
- | ALTER TABLE relation_expr ALTER opt_column ColId SET STORAGE ColId
- { $$ = cat_str(7, make_str("alter table"), $3, make_str("alter"), $5, $6, make_str("set storage"), $9); }
+ | ALTER opt_column ColId SET STORAGE ColId
+ { $$ = cat_str(5, make_str("alter"), $2, $3, make_str("set storage"), $6); }
/* ALTER TABLE <relation> DROP [COLUMN] <colname> {RESTRICT|CASCADE} */
- | ALTER TABLE relation_expr DROP opt_column ColId opt_drop_behavior
- { $$ = cat_str(6, make_str("alter table"), $3, make_str("drop"), $5, $6, $7); }
-/* ALTER TABLE <relation> ADD CONSTRAINT ... */
- | ALTER TABLE relation_expr ADD TableConstraint
- { $$ = cat_str(4, make_str("alter table"), $3, make_str("add"), $5); }
+ | DROP opt_column ColId opt_drop_behavior
+ { $$ = cat_str(4, make_str("drop"), $2, $3, $4); }
+/* ALTER TABLE <relation> ALTER [COLUMN] <colname> TYPE <typename> [ USING <expression> ] */
+ | ALTER opt_column ColId TYPE_P Typename alter_using
+ { $$ = cat_str(6, make_str("alter"), $2, $3, make_str("type"), $5, $6); }
+/* ALTER TABLE <relation> ADD_P CONSTRAINT ... */
+ | ADD_P TableConstraint
+ { $$ = cat_str(2, make_str("add"), $2); }
/* ALTER TABLE <relation> DROP CONSTRAINT ... */
- | ALTER TABLE relation_expr DROP CONSTRAINT name opt_drop_behavior
- { $$ = cat_str(5, make_str("alter table"), $3, make_str("drop constraint"), $6, $7); }
+ | DROP CONSTRAINT name opt_drop_behavior
+ { $$ = cat_str(3, make_str("drop constraint"), $3, $4); }
/* ALTER TABLE <relation> SET WITHOUT OIDS */
- | ALTER TABLE relation_expr SET WITHOUT OIDS
- { $$ = cat_str(3, make_str("alter table"), $3, make_str("set without oids")); }
+ | SET WITHOUT OIDS
+ { $$ = make_str("set without oids"); }
/* ALTER TABLE <name> CREATE TOAST TABLE */
- | ALTER TABLE qualified_name CREATE TOAST TABLE
- { $$ = cat_str(3, make_str("alter table"), $3, make_str("create toast table")); }
-/* 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); }
+ | CREATE TOAST TABLE
+ { $$ = make_str("create toast table"); }
/* 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); }
+ | CLUSTER ON name
+ { $$ = cat_str(2, make_str("cluster on"), $3); }
+/* ALTER TABLE <name> SET WITHOUT CLUSTER */
+ | SET WITHOUT CLUSTER
+ { $$ = make_str("set without cluster"); }
+/* ALTER TABLE <name> ENABLE TRIGGER <trig> */
+ | ENABLE_P TRIGGER name
+ { $$ = cat2_str(make_str("enable trigger"), $3); }
+/* ALTER TABLE <name> ENABLE TRIGGER ALL */
+ | ENABLE_P TRIGGER ALL
+ { $$ = make_str("enable trigger all"); }
+/* ALTER TABLE <name> ENABLE TRIGGER USER */
+ | ENABLE_P TRIGGER USER
+ { $$ = make_str("enable trigger user"); }
+/* ALTER TABLE <name> DISABLE TRIGGER <trig> */
+ | DISABLE_P TRIGGER name
+ { $$ = cat2_str(make_str("disable trigger"), $3); }
+/* ALTER TABLE <name> DISABLE TRIGGER ALL */
+ | DISABLE_P TRIGGER ALL
+ { $$ = make_str("disable trigger all"); }
+/* ALTER TABLE <name> DISABLE TRIGGER USER */
+ | DISABLE_P TRIGGER USER
+ { $$ = make_str("disable trigger user"); }
+ ;
+
+alter_rel_cmds: alter_rel_cmd { $$ = $1; }
+ | alter_rel_cmds ',' alter_rel_cmd { $$ = cat_str(3, $1, make_str(","), $3); }
+ ;
+
+/* Subcommands that are for ALTER TABLE or ALTER INDEX */
+alter_rel_cmd:
+ /* ALTER [TABLE|INDEX] <name> OWNER TO RoleId */
+ OWNER TO RoleId
+ { $$ = cat_str(2, make_str("owner to"), $3); }
+ /* ALTER [TABLE|INDEX] <name> SET TABLESPACE <tablespacename> */
+ | SET TABLESPACE name
+ { $$ = cat_str(2, make_str("set tablespace"), $3); }
;
alter_column_default:
| /* EMPTY */ { $$ = EMPTY; }
;
+alter_using: USING a_expr { $$ = cat2_str(make_str("using"), $2); }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
+
/*****************************************************************************
*
* QUERY :
*
*****************************************************************************/
-ClosePortalStmt: CLOSE name { $$ = cat2_str(make_str("close"), $2); }
+ClosePortalStmt: CLOSE name
+ {
+ $$ = cat2_str(make_str("close"), $2);
+ }
;
/*****************************************************************************
{ $$ = cat_str(3, make_str("delimiter"), $2, $3); }
| NULL_P opt_as StringConst
{ $$ = cat_str(3, make_str("null"), $2, $3); }
+ | CSV { $$ = make_str("csv"); }
+ | HEADER_P { $$ = make_str("header"); }
+ | QUOTE opt_as Sconst
+ { $$ = cat_str(3, make_str("quote"), $2, $3); }
+ | ESCAPE opt_as Sconst
+ { $$ = cat_str(3, make_str("escape"), $2, $3); }
+ | FORCE QUOTE columnList
+ { $$ = cat2_str(make_str("force quote"), $3); }
+ | FORCE NOT NULL_P columnList
+ { $$ = cat2_str(make_str("force not null"), $4); }
+
;
opt_binary: BINARY { $$ = make_str("binary"); }
*****************************************************************************/
CreateStmt: CREATE OptTemp TABLE qualified_name '(' OptTableElementList ')'
- OptInherit OptWithOids OnCommitOption
- { $$ = cat_str(10, make_str("create"), $2, make_str("table"), $4, make_str("("), $6, make_str(")"), $8, $9, $10); }
+ OptInherit OptWithOids OnCommitOption OptTableSpace
+ { $$ = cat_str(11, make_str("create"), $2, make_str("table"), $4, make_str("("), $6, make_str(")"), $8, $9, $10, $11); }
| CREATE OptTemp TABLE qualified_name OF qualified_name
- '(' OptTableElementList ')' OptWithOids OnCommitOption
- { $$ = cat_str(11, make_str("create"), $2, make_str("table"), $4, make_str("of"), $6, make_str("("), $8, make_str(")"), $10, $11); }
+ '(' OptTableElementList ')' OptWithOids OnCommitOption OptTableSpace
+ { $$ = cat_str(12, make_str("create"), $2, make_str("table"), $4, make_str("of"), $6, make_str("("), $8, make_str(")"), $10, $11, $12); }
;
/*
| TableConstraint { $$ = $1; }
;
-columnDef: ColId Typename ColQualList opt_collate
+columnDef: ColId Typename ColQualList
{
- if (strlen($4) > 0)
- {
- snprintf(errortext, sizeof(errortext), "Currently unsupported CREATE TABLE / COLLATE %s will be passed to backend", $4);
- mmerror(PARSE_ERROR, ET_WARNING, errortext);
- }
- $$ = cat_str(4, $1, $2, $3, $4);
+ $$ = cat_str(3, $1, $2, $3);
}
;
{ $$ = make_str("not null"); }
| NULL_P
{ $$ = make_str("null"); }
- | UNIQUE
- { $$ = make_str("unique"); }
- | PRIMARY KEY
- { $$ = make_str("primary key"); }
+ | UNIQUE OptConsTableSpace
+ { $$ = cat2_str(make_str("unique"), $2); }
+ | PRIMARY KEY OptConsTableSpace
+ { $$ = cat2_str(make_str("primary key"), $3); }
| CHECK '(' a_expr ')'
{ $$ = cat_str(3, make_str("check ("), $3, make_str(")")); }
| DEFAULT b_expr
| INITIALLY IMMEDIATE { $$ = make_str("initially immediate"); }
;
-TableLikeClause: LIKE any_name
- {
- mmerror(PARSE_ERROR, ET_ERROR, "LIKE in table definitions not yet supported");
- $$ = cat2_str(make_str("like"), $2);
- }
+TableLikeClause: LIKE qualified_name like_including_defaults
+ {
+ $$ = cat_str(3, make_str("like"), $2, $3);
+ }
;
+like_including_defaults:
+ INCLUDING DEFAULTS { $$ = make_str("including defaults"); }
+ | EXCLUDING DEFAULTS { $$ = make_str("excluding defaults"); }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
+
/* ConstraintElem specifies constraint syntax which is not embedded into
* a column definition. ColConstraintElem specifies the embedded form.
* - thomas 1997-12-03
ConstraintElem: CHECK '(' a_expr ')'
{ $$ = cat_str(3, make_str("check("), $3, make_str(")")); }
- | UNIQUE '(' columnList ')'
- { $$ = cat_str(3, make_str("unique("), $3, make_str(")")); }
- | PRIMARY KEY '(' columnList ')'
- { $$ = cat_str(3, make_str("primary key("), $4, make_str(")")); }
+ | UNIQUE '(' columnList ')' OptConsTableSpace
+ { $$ = cat_str(4, make_str("unique("), $3, make_str(")"), $5); }
+ | PRIMARY KEY '(' columnList ')' OptConsTableSpace
+ { $$ = cat_str(4, make_str("primary key("), $4, make_str(")"), $6); }
| FOREIGN KEY '(' columnList ')' REFERENCES qualified_name opt_column_list
key_match key_actions ConstraintAttributeSpec
{ $$ = cat_str(8, make_str("foreign key("), $4, make_str(") references"), $7, $8, $9, $10, $11); }
| /*EMPTY*/ { $$ = EMPTY; }
;
+OptTableSpace: TABLESPACE name { $$ = cat2_str(make_str("tablespace"), $2); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
+OptConsTableSpace: USING INDEX TABLESPACE name { $$ = cat2_str(make_str("using index tablespace"), $4); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
+
/*
* Note: CREATE TABLE ... AS SELECT ... is just another spelling for
* SELECT ... INTO.
*/
-CreateAsStmt: CREATE OptTemp TABLE qualified_name OptCreateAs AS
+CreateAsStmt: CREATE OptTemp TABLE qualified_name OptCreateAs WithOidsAs
{ FoundInto = 0; }
SelectStmt
{
if (FoundInto == 1)
mmerror(PARSE_ERROR, ET_ERROR, "CREATE TABLE / AS SELECT may not specify INTO");
- $$ = cat_str(7, make_str("create"), $2, make_str("table"), $4, $5, make_str("as"), $8);
+ $$ = cat_str(7, make_str("create"), $2, make_str("table"), $4, $5, $6, $8);
}
;
+/*
+ * To avoid a shift/reduce conflict in CreateAsStmt, we need to
+ * include the 'AS' terminal in the parsing of WITH/WITHOUT
+ * OIDS. Unfortunately that means this production is effectively a
+ * duplicate of OptWithOids.
+ */
+WithOidsAs:
+ WITH OIDS AS { $$ = make_str("with oids as"); }
+ | WITHOUT OIDS AS { $$ = make_str("without oids as"); }
+ | AS { $$ = make_str("as"); }
+ ;
+
+
OptCreateAs: '(' CreateAsList ')'
{ $$ = cat_str(3, make_str("("), $2, make_str(")")); }
| /*EMPTY*/
*****************************************************************************/
CreateSeqStmt: CREATE OptTemp SEQUENCE qualified_name OptSeqList
- { $$ = cat_str(4, make_str("create sequence"), $2, $4, $5); }
+ { $$ = cat_str(5, make_str("create"), $2, make_str("sequence"), $4, $5); }
;
AlterSeqStmt: ALTER SEQUENCE qualified_name OptSeqList
*
*****************************************************************************/
-CreatePLangStmt: CREATE opt_Trusted opt_procedural LANGUAGE ColId_or_Sconst
- HANDLER handler_name opt_lancompiler
- { $$ = cat_str(8, make_str("create"), $2, $3, make_str("language"), $5, make_str("handler"), $7, $8); }
+CreatePLangStmt: CREATE opt_trusted opt_procedural LANGUAGE ColId_or_Sconst
+ { $$ = cat_str(5, make_str("create"), $2, $3, make_str("language"), $5); }
+ | CREATE opt_trusted opt_procedural LANGUAGE ColId_or_Sconst
+ HANDLER handler_name opt_validator opt_lancompiler
+ { $$ = cat_str(9, make_str("create"), $2, $3, make_str("language"), $5, make_str("handler"), $7, $8, $9); }
;
-opt_Trusted: TRUSTED { $$ = make_str("trusted"); }
+opt_trusted: TRUSTED { $$ = make_str("trusted"); }
| /*EMPTY*/ { $$ = EMPTY; }
;
/* This ought to be just func_name, but that causes reduce/reduce conflicts
* (CREATE LANGUAGE is the only place where func_name isn't followed by '(').
- * Work around by using name and dotted_name separately.
+ * Work around by using simple names instead.
*/
-handler_name: name
- { $$ = $1; }
- | dotted_name
- { $$ = $1; /* XXX changing soon */ }
+handler_name: name { $$ = $1; }
+ | name attrs { $$ = cat2_str($1, $2); }
;
+opt_validator: VALIDATOR handler_name
+ { $$ = cat2_str(make_str("validator"), $2); }
+ | /*EMPTY*/
+ { $$ = ""; }
+ ;
opt_lancompiler: LANCOMPILER StringConst
{ $$ = cat2_str(make_str("lancompiler"), $2); }
| /*EMPTY*/
| /*EMPTY*/ { $$ = EMPTY; }
;
+/*****************************************************************************
+ *
+ * QUERY:
+ * CREATE TABLESPACE tablespace LOCATION '/path/to/tablespace/'
+ *
+ *****************************************************************************/
+
+CreateTableSpaceStmt: CREATE TABLESPACE name OptTableSpaceOwner LOCATION Sconst
+ { $$ = cat_str(5,make_str("create tablespace"), $3, $4, make_str("location"), $6); }
+ ;
+
+OptTableSpaceOwner: OWNER name { $$ = cat2_str(make_str("owner"), $2); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
+
+/*****************************************************************************
+ *
+ * QUERY :
+ * DROP TABLESPACE <tablespace>
+ *
+ * No need for drop behaviour as we cannot implement dependencies for
+ * objects in other databases; we can only support RESTRICT.
+ *
+ ****************************************************************************/
+
+
+DropTableSpaceStmt: DROP TABLESPACE name { $$ = cat2_str(make_str("drop tablespace"), $3); };
+
+
/*****************************************************************************
*
* QUERIES :
;
/* Note: any simple identifier will be returned as a type name! */
-def_arg: func_return { $$ = $1; }
- | qual_all_Op { $$ = $1; }
- | AllConst { $$ = $1; }
+def_arg: func_type { $$ = $1; }
+ | qual_all_Op { $$ = $1; }
+ | AllConst { $$ = $1; }
;
CreateOpClassStmt: CREATE OPERATOR CLASS any_name opt_default FOR TYPE_P Typename
{ $$ = cat_str(4, make_str("drop"), $2, $3, $4); }
;
-drop_type: TABLE { $$ = make_str("table"); }
+drop_type: TABLE { $$ = make_str("table"); }
| SEQUENCE { $$ = make_str("sequence"); }
| VIEW { $$ = make_str("view"); }
| INDEX { $$ = make_str("index"); }
{ $$ = cat_str(3, $1, make_str(","), $3); }
;
-any_name: ColId
- { $$ = $1; }
- | dotted_name
- { $$ = $1; }
- ;
+any_name: ColId { $$ = $1; }
+ | ColId attrs { $$ = cat2_str($1, $2); }
+ ;
+
+attrs: '.' attr_name { $$ = cat2_str(make_str("."), $2); }
+ | attrs '.' attr_name { $$ = cat_str(3, $1, make_str("."), $3); }
+ ;
+
/*****************************************************************************
*
* QUERY:
- * truncate table relname
+ * truncate table relname1, relname2, ....
*
*****************************************************************************/
-TruncateStmt: TRUNCATE opt_table qualified_name
+TruncateStmt: TRUNCATE opt_table qualified_name_list
{ $$ = cat_str(3, make_str("truncate table"), $2, $3); }
;
*
*****************************************************************************/
-FetchStmt: FETCH fetch_direction from_in name ecpg_into_using
- { $$ = cat_str(4, make_str("fetch"), $2, $3, $4); }
- | FETCH name ecpg_into_using
- { $$ = cat2_str(make_str("fetch"), $2); }
+/* This is different from the backend as we try to be compatible with many other
+ * embedded SQL implementations. So we accept their syntax as well and
+ * translate it to the PGSQL syntax. */
+
+FetchStmt: FETCH fetch_direction from_in name ecpg_into
+ {
+ add_additional_variables($4, false);
+ $$ = cat_str(4, make_str("fetch"), $2, $3, $4);
+ }
+ | FETCH fetch_direction name ecpg_into
+ {
+ add_additional_variables($3, false);
+ $$ = cat_str(4, make_str("fetch"), $2, make_str("from"), $3);
+ }
+ | FETCH from_in name ecpg_into
+ {
+ add_additional_variables($3, false);
+ $$ = cat_str(3, make_str("fetch"), $2, $3);
+ }
+ | FETCH name ecpg_into
+ {
+ add_additional_variables($2, false);
+ $$ = cat2_str(make_str("fetch"), $2);
+ }
+ | FETCH fetch_direction from_in name
+ {
+ add_additional_variables($4, false);
+ $$ = cat_str(4, make_str("fetch"), $2, $3, $4);
+ }
+ | FETCH fetch_direction name
+ {
+ add_additional_variables($3, false);
+ $$ = cat_str(4, make_str("fetch"), $2, make_str("from"), $3);
+ }
+ | FETCH from_in name
+ {
+ add_additional_variables($3, false);
+ $$ = cat_str(3, make_str("fetch"), $2, $3);
+ }
+ | FETCH name
+ {
+ add_additional_variables($2, false);
+ $$ = cat2_str(make_str("fetch"), $2);
+ }
| MOVE fetch_direction from_in name
{ $$ = cat_str(4, make_str("move"), $2, $3, $4); }
| MOVE name
{ $$ = cat2_str(make_str("move"), $2); }
;
-fetch_direction: /* EMPTY */ { $$ = EMPTY; }
- | NEXT { $$ = make_str("next"); }
+fetch_direction: 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; }
+ | ABSOLUTE_P IntConst { $$ = cat2_str(make_str("absolute"), $2); }
+ | RELATIVE_P IntConst { $$ = cat2_str(make_str("relative"), $2); }
+ | IntConst { $$ = $1; }
| ALL { $$ = make_str("all"); }
| FORWARD { $$ = make_str("forward"); }
- | FORWARD fetch_count { $$ = cat2_str(make_str("forward"), $2); }
+ | FORWARD IntConst { $$ = 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 IntConst { $$ = cat2_str(make_str("backward"), $2); }
| BACKWARD ALL { $$ = make_str("backward all"); }
;
-fetch_count: IntConst { $$ = $1; }
- ;
-
from_in: IN_P { $$ = make_str("in"); }
- | FROM { $$ = make_str("from"); }
+ | FROM { $$ = make_str("from"); }
;
-/*****************************************************************************
- *
- * The COMMENT ON statement can take different forms based upon the type of
- * the object associated with the comment. The form of the statement is:
- *
- * COMMENT ON [ [ DATABASE | DOMAIN | INDEX | SEQUENCE | TABLE | TYPE | VIEW ]
- * <objname> | AGGREGATE <aggname> (<aggtype>) | FUNCTION
- * <funcname> (arg1, arg2, ...) | OPERATOR <op>
- * (leftoperand_typ rightoperand_typ) | TRIGGER <triggername> ON
- * <relname> | RULE <rulename> ON <relname> ] IS 'text'
- *
- *****************************************************************************/
CommentStmt: COMMENT ON comment_type name IS comment_text
{ $$ = cat_str(5, make_str("comment on"), $3, $4, make_str("is"), $6); }
| COMMENT ON AGGREGATE func_name '(' aggr_argtype ')' IS comment_text
{ $$ = cat_str(6, make_str("comment on rule"), $4, make_str("on"), $6, make_str("is"), $8); }
| COMMENT ON RULE name IS comment_text
{ $$ = cat_str(4, make_str("comment on rule"), $4, make_str("is"), $6); }
+ | COMMENT ON OPERATOR CLASS any_name USING access_method IS comment_text
+ { $$ = cat_str(6, make_str("comment on operator class"), $5, make_str("using"), $7, make_str("is"), $9); }
+ | COMMENT ON LARGE_P OBJECT_P NumConst IS comment_text
+ { $$ = cat_str(4, make_str("comment on large object"), $5, make_str("is"), $7); }
+ | COMMENT ON CAST '(' Typename AS Typename ')' IS comment_text
+ { $$ = cat_str(6, make_str("comment on cast ("), $5, make_str("as"), $7, make_str(") is"), $10); }
+ | COMMENT ON opt_procedural LANGUAGE any_name IS comment_text
+ { $$ = cat_str(6, make_str("comment on"), $3, make_str("language"), $5, make_str("is"), $7); }
;
comment_type: COLUMN { $$ = make_str("column"); }
| DOMAIN_P { $$ = make_str("domain"); }
| TYPE_P { $$ = make_str("type"); }
| VIEW { $$ = make_str("view"); }
+ | CONVERSION_P { $$ = make_str("conversion"); }
;
comment_text: StringConst { $$ = $1; }
{ $$ = cat_str(7, make_str("grant"), $2, make_str("on"), $4, make_str("to"), $6, $7); }
;
-RevokeStmt: REVOKE opt_revoke_grant_option privileges ON privilege_target FROM grantee_list opt_drop_behavior
+RevokeStmt: REVOKE privileges ON privilege_target FROM grantee_list opt_drop_behavior
+ {
+ $$ = cat_str(7, make_str("revoke"), $2, make_str("on"), $4, make_str("from"), $6, $7);
+ }
+ | REVOKE GRANT OPTION FOR privileges ON privilege_target FROM grantee_list opt_drop_behavior
{
- $$ = cat_str(9, make_str("revoke"), $2, $3, make_str("on"), $5, make_str("from"), $7, $8);
+ $$ = cat_str(7, make_str("revoke grant option for"), $5, make_str("on"), $7, make_str("from"), $9, $10);
}
;
;
privilege: SELECT { $$ = make_str("select"); }
- | INSERT { $$ = make_str("insert"); }
- | UPDATE { $$ = make_str("update"); }
- | DELETE_P { $$ = make_str("delete"); }
- | RULE { $$ = make_str("rule"); }
| REFERENCES { $$ = make_str("references"); }
- | TRIGGER { $$ = make_str("trigger"); }
- | EXECUTE { $$ = make_str("execute"); }
- | USAGE { $$ = make_str("usage"); }
- | CREATE { $$ = make_str("create"); }
- | TEMPORARY { $$ = make_str("temporary"); }
- | TEMP { $$ = make_str("temp"); }
+ | CREATE { $$ = make_str("create"); }
+ | ColId { $$ = $1; }
;
privilege_target: qualified_name_list
{ $$ = cat2_str(make_str("language") , $2); }
| SCHEMA name_list
{ $$ = cat2_str(make_str("schema") , $2); }
+ | TABLESPACE name_list
+ { $$ = cat2_str(make_str("tablespace") , $2); }
;
grantee_list: grantee
{ $$ = cat_str(3, $1, make_str(","), $3); }
;
-grantee: ColId { $$ = $1; }
- | GROUP_P ColId { $$ = cat2_str(make_str("group"), $2); }
+grantee: RoleId { $$ = $1; }
+ | GROUP_P RoleId { $$ = cat2_str(make_str("group"), $2); }
;
opt_grant_grant_option: WITH GRANT OPTION
| /*EMPTY*/ { $$ = EMPTY; }
;
-opt_revoke_grant_option: GRANT OPTION FOR
- {
- mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported REVOKE/GRANT OPTION FOR will be passed to backend");
- $$ = make_str("with grant option");
- }
- | /*EMPTY*/ { $$ = EMPTY; }
- ;
-
function_with_argtypes_list: function_with_argtypes
{ $$ = $1; }
| function_with_argtypes_list ',' function_with_argtypes
function_with_argtypes: func_name func_args { $$ = cat2_str($1, $2); };
+/*****************************************************************************
+ *
+ * GRANT and REVOKE ROLE statements
+ *
+ *****************************************************************************/
+
+GrantRoleStmt:
+ GRANT privilege_list TO name_list opt_grant_admin_option opt_granted_by
+ { $$ = cat_str(6, make_str("grant"), $2, make_str("to"), $4, $5, $6); }
+ ;
+
+RevokeRoleStmt:
+ REVOKE privilege_list FROM name_list opt_granted_by opt_drop_behavior
+ { $$ = cat_str(6, make_str("revoke"), $2, make_str("from"), $4, $5, $6); }
+ ;
+
+opt_grant_admin_option: WITH ADMIN OPTION { $$ = make_str("with admin option"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
+
+opt_granted_by: GRANTED BY RoleId { $$ = cat2_str(make_str("granted by"), $3); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
+
/*****************************************************************************
*
* QUERY:
* create index <indexname> on <relname>
* [ using <access> ] "(" ( <col> | using <opclass> ] )+ ")"
- * [ where <predicate> ]
+ * [ tablespace <tablespacename> ] [ where <predicate> ]
*
*****************************************************************************/
IndexStmt: CREATE index_opt_unique INDEX index_name ON qualified_name
- access_method_clause '(' index_params ')' where_clause
- { $$ = cat_str(11, make_str("create"), $2, make_str("index"), $4, make_str("on"), $6, $7, make_str("("), $9, make_str(")"), $11); }
+ access_method_clause '(' index_params ')' OptTableSpace where_clause
+ { $$ = cat_str(12, make_str("create"), $2, make_str("index"), $4, make_str("on"), $6, $7, make_str("("), $9, make_str(")"), $11, $12); }
;
index_opt_unique: UNIQUE { $$ = make_str("unique"); }
;
index_params: index_elem { $$ = $1; }
- | index_params ',' index_elem { $$ = $1; }
+ | index_params ',' index_elem { $$ = cat_str(3, $1, make_str(","), $3); }
;
-index_elem: attr_name opt_class
+index_elem: ColId opt_class
+ { $$ = cat2_str($1, $2); }
+ | func_expr opt_class
{ $$ = cat2_str($1, $2); }
- | func_name '(' expr_list ')' opt_class
- { $$ = cat_str(5, $1, make_str("("), $3, ")", $5); }
| '(' a_expr ')' opt_class
{ $$ = cat_str(4, make_str("("), $2, make_str(")"), $4); }
;
CreateFunctionStmt: CREATE opt_or_replace FUNCTION func_name func_args
RETURNS func_return createfunc_opt_list opt_definition
{ $$ = cat_str(8, make_str("create"), $2, make_str("function"), $4, $5, make_str("returns"), $7, $8); }
+ | CREATE opt_or_replace FUNCTION func_name func_args
+ createfunc_opt_list opt_definition
+ { $$ = cat_str(6, make_str("create"), $2, make_str("function"), $4, $5, $6, $7); }
;
opt_or_replace: OR REPLACE { $$ = make_str("or replace"); }
{ $$ = cat_str(3, $1, make_str(","), $3); }
;
-func_arg: opt_arg func_type
- {
- /* We can catch over-specified arguments here if we want to,
- * but for now better to silently swallow typmod, etc.
- * - thomas 2000-03-22
- */
- $$ = cat2_str($1, $2);
- }
- | func_type { $$ = $1; }
+func_arg: arg_class param_name func_type { $$ = cat_str(3, $1, $2, $3); }
+ | param_name arg_class func_type { $$ = cat_str(3, $1, $2, $3); }
+ | param_name func_type { $$ = cat2_str($1, $2); }
+ | arg_class func_type { $$ = cat2_str($1, $2); }
+ | func_type { $$ = $1; }
;
-opt_arg: IN_P { $$ = make_str("in"); }
- | OUT_P
- {
- mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported CREATE FUNCTION/OUT will be passed to backend");
-
- $$ = make_str("out");
- }
- | INOUT
- {
- mmerror(PARSE_ERROR, ET_WARNING, "Currently unsupported CREATE FUNCTION/INOUT will be passed to backend");
-
- $$ = make_str("inout");
- }
- ;
+arg_class: IN_P { $$ = make_str("in"); }
+ | OUT_P { $$ = make_str("out"); }
+ | INOUT { $$ = make_str("inout"); }
+ | IN_P OUT_P { $$ = make_str("in out"); }
+ ;
func_as: StringConst
{ $$ = $1; }
{ $$ = cat_str(3, $1, make_str(","), $3); }
;
+param_name: function_name { $$ = $1; };
+
func_return: func_type
{
/* We can catch over-specified arguments here if we want to,
{ $$ = cat2_str($1, $2); }
;
-createfunc_opt_item: AS func_as
- { $$ = cat2_str(make_str("as"), $2); }
- | LANGUAGE ColId_or_Sconst
- { $$ = cat2_str(make_str("language"), $2); }
+common_func_opt_item:
+ CALLED ON NULL_P INPUT_P
+ { $$ = make_str("called on null input"); }
+ | RETURNS NULL_P ON NULL_P INPUT_P
+ { $$ = make_str("returns null on null input"); }
+ | STRICT_P
+ { $$ = make_str("strict"); }
| IMMUTABLE
{ $$ = make_str("immutable"); }
| STABLE
{ $$ = make_str("stable"); }
| VOLATILE
{ $$ = make_str("volatile"); }
- | CALLED ON NULL_P INPUT_P
- { $$ = make_str("called on null input"); }
- | RETURNS NULL_P ON NULL_P INPUT_P
- { $$ = make_str("returns null on null input"); }
- | STRICT_P
- { $$ = make_str("strict"); }
| EXTERNAL SECURITY DEFINER
{ $$ = make_str("external security definer"); }
| EXTERNAL SECURITY INVOKER
| SECURITY INVOKER
{ $$ = make_str("security invoker"); }
;
+createfunc_opt_item: AS func_as
+ { $$ = cat2_str(make_str("as"), $2); }
+ | LANGUAGE ColId_or_Sconst
+ { $$ = cat2_str(make_str("language"), $2); }
+ | common_func_opt_item
+ { $$ = $1; }
+ ;
opt_definition: WITH definition { $$ = cat2_str(make_str("with"), $2); }
| /*EMPTY*/ { $$ = EMPTY; }
;
+AlterFunctionStmt:
+ ALTER FUNCTION function_with_argtypes alterfunc_opt_list opt_restrict
+ { $$ = cat_str(4, make_str("alter function"), $3, $4, $5); }
+ ;
+
+alterfunc_opt_list: common_func_opt_item { $$ = $1; }
+ | alterfunc_opt_list common_func_opt_item { $$ = cat2_str($1, $2);}
+ ;
+
+opt_restrict: RESTRICT { $$ = make_str("restrict"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
+
/*****************************************************************************
*
* QUERY:
*****************************************************************************/
ReindexStmt: REINDEX reindex_type qualified_name opt_force
{ $$ = cat_str(4, make_str("reindex"), $2, $3, $4); }
+ | REINDEX SYSTEM_P name opt_force
+ { $$ = cat_str(3, make_str("reindex system"), $3, $4); }
| REINDEX DATABASE name opt_force
{ $$ = cat_str(3, make_str("reindex database"), $3, $4); }
;
*
*****************************************************************************/
-RenameStmt: ALTER TABLE relation_expr RENAME opt_column opt_name TO name
+RenameStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' RENAME TO name
+ { $$ = cat_str(6, make_str("alter aggregate"), $3, make_str("("), $5, make_str(") rename to"), $9); }
+ | ALTER CONVERSION_P any_name RENAME TO name
+ { $$ = cat_str(4, make_str("alter conversion"), $3, make_str("rename to"), $6); }
+ | ALTER DATABASE database_name RENAME TO database_name
+ { $$ = cat_str(4, make_str("alter database"), $3, make_str("rename to"), $6); }
+ | ALTER FUNCTION func_name func_args RENAME TO name
+ { $$ = cat_str(5, make_str("alter function"), $3, $4, make_str("rename to"), $7); }
+ | ALTER GROUP_P RoleId RENAME TO RoleId
+ { $$ = cat_str(4, make_str("alter group"), $3, make_str("rename to"), $6); }
+ | ALTER LANGUAGE name RENAME TO name
+ { $$ = cat_str(4, make_str("alter language"), $3, make_str("rename to"), $6); }
+ | ALTER OPERATOR CLASS any_name USING access_method RENAME TO name
+ { $$ = cat_str(6, make_str("alter operator class"), $4, make_str("using"), $6, make_str("rename to"), $9); }
+ | ALTER SCHEMA name RENAME TO name
+ { $$ = cat_str(4, make_str("alter schema"), $3, make_str("rename to"), $6); }
+ | ALTER TABLE relation_expr RENAME TO name
+ { $$ = cat_str(4, make_str("alter table"), $3, make_str("rename to"), $6); }
+ | ALTER INDEX relation_expr RENAME TO name
+ { $$ = cat_str(4, make_str("alter index"), $3, make_str("rename to"), $6); }
+ | ALTER TABLE relation_expr RENAME opt_column name TO name
{ $$ = cat_str(7, make_str("alter table"), $3, make_str("rename"), $5, $6, make_str("to"), $8); }
| ALTER TRIGGER name ON relation_expr RENAME TO name
{ $$ = cat_str(6, make_str("alter trigger"), $3, make_str("on"), $5, make_str("rename to"), $8); }
+ | ALTER USER RoleId RENAME TO RoleId
+ { $$ = cat_str(4, make_str("alter user"), $3, make_str("rename to"), $6); }
+ | ALTER TABLESPACE name RENAME TO name
+ { $$ = cat_str(4, make_str("alter tablespace"), $3, make_str("rename to"), $6); }
;
-opt_name: name { $$ = $1; }
+opt_column: COLUMN { $$ = make_str("column"); }
| /*EMPTY*/ { $$ = EMPTY; }
;
-opt_column: COLUMN { $$ = make_str("column"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+/*****************************************************************************
+ *
+ * ALTER THING name SET SCHEMA name
+ *
+ *****************************************************************************/
+
+AlterObjectSchemaStmt:
+ ALTER AGGREGATE func_name '(' aggr_argtype ')' SET SCHEMA name
+ { $$ = cat_str(6, make_str("alter aggregate"), $3, make_str("("), $5, make_str(") set schema"), $9); }
+ | ALTER DOMAIN_P any_name SET SCHEMA name
+ { $$ = cat_str(4, make_str("alter domain"), $3, make_str("set schema"), $6); }
+ | ALTER FUNCTION func_name func_args SET SCHEMA name
+ { $$ = cat_str(5, make_str("alter function"), $3, $4, make_str("set schema"), $7); }
+ | ALTER SEQUENCE relation_expr SET SCHEMA name
+ { $$ = cat_str(4, make_str("alter sequence"), $3, make_str("set schema"), $6); }
+ | ALTER TABLE relation_expr SET SCHEMA name
+ { $$ = cat_str(4, make_str("alter sequence"), $3, make_str("set schema"), $6); }
+ | ALTER TYPE_P any_name SET SCHEMA name
+ { $$ = cat_str(4, make_str("alter type"), $3, make_str("set schema"), $6); }
+ ;
+
+/*****************************************************************************
+ *
+ * ALTER THING name OWNER TO newname
+ *
+ *****************************************************************************/
+
+AlterOwnerStmt: ALTER AGGREGATE func_name '(' aggr_argtype ')' OWNER TO RoleId
+ { $$ = cat_str(6, make_str("alter aggregate"), $3, make_str("("), $5, make_str(") owner to"), $9); }
+ | ALTER CONVERSION_P any_name OWNER TO RoleId
+ { $$ = cat_str(4, make_str("alter conversion"), $3, make_str("owner to"), $6); }
+ | ALTER DATABASE database_name OWNER TO RoleId
+ { $$ = cat_str(4, make_str("alter database"), $3, make_str("owner to"), $6); }
+ | ALTER DOMAIN_P database_name OWNER TO RoleId
+ { $$ = cat_str(4, make_str("alter domain"), $3, make_str("owner to"), $6); }
+ | ALTER FUNCTION func_name func_args OWNER TO RoleId
+ { $$ = cat_str(5, make_str("alter function"), $3, $4, make_str("owner to"), $7); }
+ | ALTER OPERATOR any_operator '(' oper_argtypes ')' OWNER TO RoleId
+ { $$ = cat_str(6, make_str("alter operator"), $3, make_str("("), $5, make_str(") owner to"), $9); }
+ | ALTER OPERATOR CLASS any_name USING access_method OWNER TO RoleId
+ { $$ = cat_str(6, make_str("alter operator class"), $4, make_str("using"), $6, make_str("owner to"), $9); }
+ | ALTER SCHEMA name OWNER TO RoleId
+ { $$ = cat_str(4, make_str("alter schema"), $3, make_str("owner to"), $6); }
+ | ALTER TYPE_P any_name OWNER TO RoleId
+ { $$ = cat_str(4, make_str("alter type"), $3, make_str("owner to"), $6); }
+ | ALTER TABLESPACE name OWNER TO RoleId
+ { $$ = cat_str(4, make_str("alter tablespace"), $3, make_str("owner to"), $6); }
;
;
opt_instead: INSTEAD { $$ = make_str("instead"); }
+ | ALSO { $$ = make_str("also"); }
| /*EMPTY*/ { $$ = EMPTY; }
;
* (also older versions END / ABORT)
*
*****************************************************************************/
-TransactionStmt: ABORT_P opt_transaction { $$ = make_str("rollback"); }
- | BEGIN_P opt_transaction { $$ = make_str("begin transaction"); }
- | START TRANSACTION transaction_mode_list_or_empty { $$ = cat2_str(make_str("start transaction"), $3); }
- | COMMIT opt_transaction { $$ = make_str("commit"); }
- | END_P opt_transaction { $$ = make_str("commit"); }
- | ROLLBACK opt_transaction { $$ = make_str("rollback"); }
+TransactionStmt: ABORT_P opt_transaction { $$ = make_str("rollback"); }
+ | BEGIN_P opt_transaction transaction_mode_list_or_empty { $$ = cat2_str(make_str("begin transaction"), $3); }
+ | START TRANSACTION transaction_mode_list_or_empty { $$ = cat2_str(make_str("start transaction"), $3); }
+ | COMMIT opt_transaction { $$ = make_str("commit"); }
+ | END_P opt_transaction { $$ = make_str("commit"); }
+ | ROLLBACK opt_transaction { $$ = make_str("rollback"); }
+ | SAVEPOINT ColId { $$ = cat2_str(make_str("savepoint"), $2); }
+ | RELEASE SAVEPOINT ColId { $$ = cat2_str(make_str("release savepoint"), $3); }
+ | RELEASE ColId { $$ = cat2_str(make_str("release"), $2); }
+ | ROLLBACK opt_transaction TO SAVEPOINT ColId { $$ = cat_str(4, make_str("rollback"), $2, make_str("to savepoint"), $5); }
+ | ROLLBACK opt_transaction TO ColId { $$ = cat_str(4, make_str("rollback"), $2, make_str("to"), $4); }
+ | PREPARE TRANSACTION StringConst { $$ = cat2_str(make_str("prepare transaction"), $3); }
+ | COMMIT PREPARED StringConst { $$ = cat2_str(make_str("commit prepared"), $3); }
+ | ROLLBACK PREPARED StringConst { $$ = cat2_str(make_str("rollback prepared"), $3); }
;
opt_transaction: WORK { $$ = EMPTY; }
| /*EMPTY*/ { $$ = EMPTY; }
;
-transaction_mode_list:
+transaction_mode_item:
ISOLATION LEVEL iso_level
{ $$ = cat2_str(make_str("isolation level"), $3); }
- | transaction_access_mode
- { $$ = $1; }
- | ISOLATION LEVEL iso_level transaction_access_mode
- { $$ = cat_str(3, make_str("isolation level"), $3, $4); }
- | transaction_access_mode ISOLATION LEVEL iso_level
- { $$ = cat_str(3, $1, make_str("isolation level"), $4); }
+ | READ ONLY { $$ = make_str("read only"); }
+ | READ WRITE { $$ = make_str("read write"); }
+ ;
+
+transaction_mode_list:
+ transaction_mode_item { $$ = $1; }
+ | transaction_mode_list ',' transaction_mode_item { $$ = cat_str(3, $1, make_str(","), $3); }
+ | transaction_mode_list transaction_mode_item { $$ = cat_str(3, $1, make_str(" "), $2); }
;
transaction_mode_list_or_empty:
| /* EMPTY */ { $$ = EMPTY; }
;
-transaction_access_mode:
- READ ONLY { $$ = make_str("read only"); }
- | READ WRITE { $$ = make_str("read write"); }
- ;
-
/*****************************************************************************
*
- * QUERY:
- * define view <viewname> '('target-list ')' [where <quals> ]
+ * QUERY:
+ * CREATE [ OR REPLACE ] [ TEMP ] VIEW <viewname> '('target-list ')' AS <query>
*
*****************************************************************************/
-ViewStmt: CREATE opt_or_replace VIEW qualified_name opt_column_list AS SelectStmt
+ViewStmt: CREATE OptTemp VIEW qualified_name opt_column_list AS SelectStmt
{ $$ = cat_str(7, make_str("create"), $2, make_str("view"), $4, $5, make_str("as"), $7); }
+ | CREATE OR REPLACE OptTemp VIEW qualified_name opt_column_list AS SelectStmt
+ { $$ = cat_str(7, make_str("create or replace"), $4, make_str("view"), $6, $7, make_str("as"), $9); }
;
{ $$ = cat2_str($1, $2); }
;
-createdb_opt_item: LOCATION opt_equal StringConst
+createdb_opt_item: TABLESPACE opt_equal name
+ { $$ = cat_str(3,make_str("tablespace"), $2, $3); }
+ | TABLESPACE opt_equal DEFAULT
+ { $$ = cat_str(3, make_str("tablespace"), $2, make_str("default")); }
+ | LOCATION opt_equal StringConst
{ $$ = cat_str(3,make_str("location"), $2, $3); }
| LOCATION opt_equal DEFAULT
{ $$ = cat_str(3, make_str("location"), $2, make_str("default")); }
{ $$ = cat_str(3, make_str("encoding"), $2, $3); }
| ENCODING opt_equal DEFAULT
{ $$ = cat_str(3, make_str("encoding"), $2, make_str("default")); }
+ | CONNECTION LIMIT opt_equal PosIntConst
+ { $$ = cat_str(3, make_str("connection limit"), $3, $4); }
| OWNER opt_equal name
{ $$ = cat_str(3, make_str("owner"), $2, $3); }
| OWNER opt_equal DEFAULT
*
*****************************************************************************/
+AlterDatabaseStmt: ALTER DATABASE database_name opt_with alterdb_opt_list
+ { $$ = cat_str(4, make_str("alter database"), $3, $4, $5); }
+ ;
+
AlterDatabaseSetStmt: ALTER DATABASE database_name SET set_rest
{ $$ = cat_str(4, make_str("alter database"), $3, make_str("set"), $5); }
| ALTER DATABASE database_name VariableResetStmt
{ $$ = cat_str(3, make_str("alter database"), $3, $4); }
;
+alterdb_opt_list:
+ alterdb_opt_list alterdb_opt_item { $$ = cat2_str($1, $2);}
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
+
+alterdb_opt_item:
+ CONNECTION LIMIT opt_equal PosIntConst { $$ = cat_str(3, make_str("connection limit"), $3, $4); }
+ ;
+
/*****************************************************************************
*
* DROP DATABASE
*
*****************************************************************************/
-CreateDomainStmt: CREATE DOMAIN_P any_name opt_as Typename ColQualList opt_collate
+CreateDomainStmt: CREATE DOMAIN_P any_name opt_as Typename ColQualList
{
- $$ = cat_str(6, make_str("create domain"), $3, $4, $5, $6, $7);
+ $$ = cat_str(5, make_str("create domain"), $3, $4, $5, $6);
}
;
{ $$ = cat_str(3, make_str("alter domain"), $3, make_str("drop not null")); }
| ALTER DOMAIN_P any_name SET NOT NULL_P
{ $$ = cat_str(3, make_str("alter domain"), $3, make_str("set not null")); }
- | ALTER DOMAIN_P any_name ADD TableConstraint
+ | ALTER DOMAIN_P any_name ADD_P TableConstraint
{ $$ = cat_str(4, make_str("alter domain"), $3, make_str("add"), $5); }
| ALTER DOMAIN_P any_name DROP CONSTRAINT name opt_drop_behavior
{ $$ = cat_str(5, make_str("alter domain"), $3, make_str("drop constraint"), $6, $7); }
- | ALTER DOMAIN_P any_name OWNER TO UserId
- { $$ = cat_str(4, make_str("alter domain"), $3, make_str("owner to"), $6); }
;
opt_as: AS {$$ = make_str("as"); }
| prep_type_list ',' Typename { $$ = cat_str(3, $1, make_str(","), $3); }
;
-ExecuteStmt: EXECUTE name execute_param_clause into_clause
- { $$ = cat_str(4, make_str("execute"), $2, $3, $4); }
+ExecuteStmt: EXECUTE name execute_param_clause
+ { $$ = cat_str(3, make_str("execute"), $2, $3); }
+ | CREATE OptTemp TABLE qualified_name OptCreateAs AS EXECUTE name execute_param_clause
+ { $$ = cat_str(8, make_str("create"), $2, make_str("table"), $4, $5, make_str("as execute"), $8, $9); }
+
;
execute_param_clause: '(' expr_list ')' { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
*
*****************************************************************************/
-DeleteStmt: DELETE_P FROM relation_expr where_clause
- { $$ = cat_str(3, make_str("delete from"), $3, $4); }
+DeleteStmt: DELETE_P FROM relation_expr using_clause where_clause
+ { $$ = cat_str(4, make_str("delete from"), $3, $4, $5); }
+ ;
+
+using_clause: USING from_list { cat2_str(make_str("using"), $2); }
+ | /* EMPTY */ { $$ = EMPTY; }
;
-LockStmt: LOCK_P opt_table qualified_name_list opt_lock
- { $$ = cat_str(4, make_str("lock"), $2, $3, $4); }
+LockStmt: LOCK_P opt_table qualified_name_list opt_lock opt_nowait
+ { $$ = cat_str(5, make_str("lock"), $2, $3, $4, $5); }
;
opt_lock: IN_P lock_type MODE
| ACCESS EXCLUSIVE { $$ = make_str("access exclusive"); }
;
+opt_nowait: NOWAIT { $$ = make_str("nowait"); }
+ | /* EMPTY */ { $$ = EMPTY; }
+ ;
+
/*****************************************************************************
*
* QUERY:
for (ptr = cur; ptr != NULL; ptr = ptr->next)
{
if (strcmp($2, ptr->name) == 0)
- {
- /* re-definition is a bug */
- snprintf(errortext, sizeof(errortext), "cursor %s already defined", $2);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
+ /* re-definition is a bug */
+ mmerror(PARSE_ERROR, ET_ERROR, "cursor %s already defined", $2);
}
this = (struct cursor *) mm_alloc(sizeof(struct cursor));
this->next = cur;
this->name = $2;
this->connection = connection;
+ this->opened = false;
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;
-
cur = this;
- $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
+ if (INFORMIX_MODE)
+ $$ = cat_str(5, adjust_informix(this->argsinsert), adjust_informix(this->argsresult), make_str("/*"), mm_strdup(this->command), make_str("*/"));
+ else
+ $$ = cat_str(3, make_str("/*"), mm_strdup(this->command), make_str("*/"));
}
;
| cursor_options NO SCROLL { $$ = cat2_str($1, make_str("no scroll")); }
;
-opt_hold: /* EMPTY */ { $$ = EMPTY; }
+opt_hold: /* EMPTY */ { if (compat == ECPG_COMPAT_INFORMIX_SE && autocommit == true)
+ $$ = make_str("with hold");
+ else
+ $$ = EMPTY; }
| WITH HOLD { $$ = make_str("with hold"); }
| WITHOUT HOLD { $$ = make_str("without hold"); }
;
{ $$ = $1; }
| select_clause sort_clause
{ $$ = cat2_str($1, $2); }
- | select_clause opt_sort_clause for_update_clause opt_select_limit
+ | select_clause opt_sort_clause for_locking_clause opt_select_limit
{ $$ = cat_str(4, $1, $2, $3, $4); }
- | select_clause opt_sort_clause select_limit opt_for_update_clause
+ | select_clause opt_sort_clause select_limit opt_for_locking_clause
{ $$ = cat_str(4, $1, $2, $3, $4); }
;
FoundInto = 1;
$$= cat2_str(make_str("into"), $2);
}
- | ecpg_into_using { $$ = EMPTY; }
+ | ecpg_into { $$ = EMPTY; }
| /*EMPTY*/ { $$ = EMPTY; }
;
| sortby_list ',' sortby { $$ = cat_str(3, $1, make_str(","), $3); }
;
-sortby: a_expr OptUseOp
- { $$ = cat2_str($1, $2); }
- ;
-
-OptUseOp: USING all_Op { $$ = cat2_str(make_str("using"), $2); }
- | ASC { $$ = make_str("asc"); }
- | DESC { $$ = make_str("desc"); }
- | /*EMPTY*/ { $$ = EMPTY; }
+sortby: a_expr USING qual_all_Op
+ { $$ = cat_str(3, $1, make_str("using"), $3); }
+ | a_expr ASC
+ { $$ = cat2_str($1, make_str("asc")); }
+ | a_expr DESC
+ { $$ = cat2_str($1, make_str("desc")); }
+ | a_expr
+ { $$ = $1; }
;
select_limit: LIMIT select_limit_value OFFSET select_offset_value
| /*EMPTY*/ { $$ = EMPTY; }
;
-select_limit_value: PosIntConst
- {
- if (atoi($1) < 0)
- mmerror(PARSE_ERROR, ET_ERROR, "LIMIT must not be negative");
- $$ = $1;
- }
- | ALL { $$ = make_str("all"); }
- | PARAM { $$ = make_name(); }
+select_limit_value: a_expr { $$ = $1; }
+ | ALL { $$ = make_str("all"); }
;
-select_offset_value: PosIntConst
- {
- if (atoi($1) < 0)
- mmerror(PARSE_ERROR, ET_ERROR, "OFFSET must not be negative");
- $$ = $1;
- }
- | PARAM { $$ = make_name(); }
+select_offset_value: a_expr { $$ = $1; }
;
/*
{ $$ = EMPTY; }
;
-for_update_clause: FOR UPDATE update_list
- { $$ = make_str("for update"); }
+for_locking_clause: FOR UPDATE locked_rels_list opt_nowait
+ { $$ = cat_str(3, make_str("for update"), $3, $4); }
+ | FOR SHARE locked_rels_list opt_nowait
+ { $$ = cat_str(3, make_str("for share"), $3, $4); }
| FOR READ ONLY
{ $$ = make_str("for read only"); }
;
-opt_for_update_clause: for_update_clause { $$ = $1; }
- | /* EMPTY */ { $$ = EMPTY; }
+opt_for_locking_clause: for_locking_clause { $$ = $1; }
+ | /* EMPTY */ { $$ = EMPTY; }
;
-update_list: OF name_list { $$ = cat2_str(make_str("of"), $2); }
+locked_rels_list:
+ OF name_list { $$ = cat2_str(make_str("of"), $2); }
| /* EMPTY */ { $$ = EMPTY; }
;
| func_table AS '(' TableFuncElementList ')'
{ $$=cat_str(4, $1, make_str("as ("), $4, make_str(")")); }
| func_table AS ColId '(' TableFuncElementList ')'
- { $$=cat_str(6, $1, make_str("as"), $3, make_str("("), $5, make_str(")")); }
+ { $$=cat_str(6, $1, make_str("as"), $3, make_str("("), $5, make_str(")"));}
| func_table ColId '(' TableFuncElementList ')'
{ $$=cat_str(5, $1, $2, make_str("("), $4, make_str(")")); }
| select_with_parens
{ /* inheritance query */ $$ = cat_str(3, make_str("only ("), $3, make_str(")")); }
;
-func_table: func_name '(' ')'
- { $$ = cat2_str($1, make_str("()")); }
- | func_name '(' expr_list ')'
- { $$ = cat_str(4, $1, make_str("("), $3, make_str(")")); }
+func_table: func_expr { $$ = $1; }
;
where_clause: WHERE a_expr { $$ = cat2_str(make_str("where"), $2); }
TableFuncElementList: TableFuncElement
{ $$ = $1; }
| TableFuncElementList ',' TableFuncElement
- { $$ = cat_str(3, $1, ',', $3); }
+ { $$ = cat_str(3, $1, make_str(","), $3); }
;
TableFuncElement: ColId Typename { $$ = cat2_str($1, $2); }
{ $$ = EMPTY; }
;
-opt_collate: COLLATE ColId
- { $$ = cat2_str(make_str("collate"), $2); }
- | /*EMPTY*/
- { $$ = EMPTY; }
- ;
-
ConstDatetime: TIMESTAMP '(' PosIntConst ')' opt_timezone
{ $$ = cat_str(4, make_str("timestamp("), $3, make_str(")"), $5); }
| TIMESTAMP opt_timezone
* expression grammar
*
*****************************************************************************/
-
-/* Expressions using row descriptors
- * Define row_descriptor to allow yacc to break the reduce/reduce conflict
- * with singleton expressions.
- */
-r_expr: row IN_P select_with_parens
- { $$ = cat_str(3, $1, make_str("in"), $3); }
- | row NOT IN_P select_with_parens
- { $$ = cat_str(3, $1, make_str("not in"), $4); }
- | row qual_all_Op sub_type select_with_parens %prec Op
- { $$ = cat_str(4, $1, $2, $3, $4); }
- | row qual_all_Op select_with_parens %prec Op
- { $$ = cat_str(3, $1, $2, $3); }
- | row qual_all_Op row %prec Op
- { $$ = cat_str(3, $1, $2, $3); }
- | row IS NULL_P
- { $$ = cat2_str($1, make_str("is null")); }
- | row IS NOT NULL_P
- { $$ = cat2_str($1, make_str("is not null")); }
- | row OVERLAPS row
- { $$ = cat_str(3, $1, make_str("overlaps"), $3); }
- | row IS DISTINCT FROM row %prec IS
- { $$ = cat_str(3, $1, make_str("is distinct from"), $5); }
- ;
-
-row: ROW '(' row_descriptor ')'
- { $$ = cat_str(3, make_str("row ("), $3, make_str(")")); }
- | ROW '(' a_expr ')'
- { $$ = cat_str(3, make_str("row ("), $3, make_str(")")); }
- | ROW '(' ')'
- { $$ = make_str("row()"); }
- | '(' row_descriptor ')'
- { $$ = cat_str(3, make_str("("), $2, make_str(")")); }
- ;
-
-row_descriptor: expr_list ',' a_expr
- { $$ = cat_str(3, $1, make_str(","), $3); }
- ;
-
-sub_type: ANY { $$ = make_str("ANY"); }
- | SOME { $$ = make_str("SOME"); }
- | ALL { $$ = make_str("ALL"); }
- ;
-
-all_Op: Op { $$ = $1; }
- | MathOp { $$ = $1; }
- ;
-
-MathOp: '+' { $$ = make_str("+"); }
- | '-' { $$ = make_str("-"); }
- | '*' { $$ = make_str("*"); }
- | '%' { $$ = make_str("%"); }
- | '^' { $$ = make_str("^"); }
- | '/' { $$ = make_str("/"); }
- | '<' { $$ = make_str("<"); }
- | '>' { $$ = make_str(">"); }
- | '=' { $$ = make_str("="); }
- ;
-
-qual_Op: Op { $$ = $1; }
- | OPERATOR '(' any_operator ')' { $$ = cat_str(3, make_str("operator ("), $3, make_str(")")); }
- ;
-
-qual_all_Op: all_Op { $$ = $1; }
- | OPERATOR '(' any_operator ')' { $$ = cat_str(3, make_str("operator ("), $3, make_str(")")); }
- ;
-
+
/* General expressions
* This is the heart of the expression syntax.
*
{ $$ = $1; }
| a_expr TYPECAST Typename
{ $$ = cat_str(3, $1, make_str("::"), $3); }
- | a_expr AT TIME ZONE c_expr
+ | a_expr AT TIME ZONE a_expr
{ $$ = cat_str(3, $1, make_str("at time zone"), $5); }
/*
* These operators must be called out explicitly in order to make use
{ $$ = cat2_str(make_str("+"), $2); }
| '-' a_expr %prec UMINUS
{ $$ = cat2_str(make_str("-"), $2); }
- | '%' a_expr
- { $$ = cat2_str(make_str("%"), $2); }
- | '^' a_expr
- { $$ = cat2_str(make_str("^"), $2); }
- | a_expr '%'
- { $$ = cat2_str($1, make_str("%")); }
- | a_expr '^'
- { $$ = cat2_str($1, make_str("^")); }
| a_expr '+' a_expr
{ $$ = cat_str(3, $1, make_str("+"), $3); }
| a_expr '-' a_expr
{ $$ = cat_str(4, $1, make_str("is of ("), $5, make_str(")")); }
| a_expr IS NOT OF '(' type_list ')' %prec IS
{ $$ = cat_str(4, $1, make_str("is not of ("), $6, make_str(")")); }
- | a_expr BETWEEN b_expr AND b_expr %prec BETWEEN
- { $$ = cat_str(5, $1, make_str("between"), $3, make_str("and"), $5); }
- | a_expr NOT BETWEEN b_expr AND b_expr %prec BETWEEN
- { $$ = cat_str(5, $1, make_str("not between"), $4, make_str("and"), $6); }
+ | a_expr BETWEEN opt_asymmetric b_expr AND b_expr %prec BETWEEN
+ { $$ = cat_str(6, $1, make_str("between"), $3, $4, make_str("and"), $6); }
+ | a_expr NOT BETWEEN opt_asymmetric b_expr AND b_expr %prec BETWEEN
+ { $$ = cat_str(6, $1, make_str("not between"), $4, $5, make_str("and"), $7); }
+ | a_expr BETWEEN SYMMETRIC b_expr AND b_expr %prec BETWEEN
+ { $$ = cat_str(5, $1, make_str("between symmetric"), $4, make_str("and"), $6); }
+ | a_expr NOT BETWEEN SYMMETRIC b_expr AND b_expr %prec BETWEEN
+ { $$ = cat_str(5, $1, make_str("not between symmetric"), $5, make_str("and"), $7); }
| a_expr IN_P in_expr
{ $$ = cat_str(3, $1, make_str("in"), $3); }
| a_expr NOT IN_P in_expr
{ $$ = cat_str(3, $1, make_str("not in"), $4); }
- | a_expr qual_all_Op sub_type select_with_parens %prec Op
+ | a_expr subquery_Op sub_type select_with_parens %prec Op
{ $$ = cat_str(4, $1, $2, $3, $4); }
+ | a_expr subquery_Op sub_type '(' a_expr ')' %prec Op
+ { $$ = cat_str(6, $1, $2, $3, make_str("("), $5, make_str(")")); }
| UNIQUE select_with_parens %prec Op
{ $$ = cat2_str(make_str("unique"), $2); }
- | r_expr
- { $$ = $1; }
;
/* Restricted expressions
{ $$ = cat_str(3, $1, make_str("::"), $3); }
| '-' b_expr %prec UMINUS
{ $$ = cat2_str(make_str("-"), $2); }
- | '%' b_expr
- { $$ = cat2_str(make_str("%"), $2); }
- | '^' b_expr
- { $$ = cat2_str(make_str("^"), $2); }
- | b_expr '%'
- { $$ = cat2_str($1, make_str("%")); }
- | b_expr '^'
- { $$ = cat2_str($1, make_str("^")); }
| b_expr '+' b_expr
{ $$ = cat_str(3, $1, make_str("+"), $3); }
| b_expr '-' b_expr
{ $$ = $1; }
| AexprConst
{ $$ = $1; }
- | PARAM attrs opt_indirection
- { $$ = cat_str(3, make_str("param"), $2, $3); }
- | '(' a_expr ')' attrs opt_indirection
- { $$ = cat_str(5, make_str("("), $2, make_str(")"), $4, $5); }
+ | PARAM opt_indirection
+ { $$ = cat2_str(make_str("param"), $2); }
| '(' a_expr ')' opt_indirection
{ $$ = cat_str(4, make_str("("), $2, make_str(")"), $4); }
| case_expr
{ $$ = $1; }
- | func_name '(' ')'
+ | func_expr
+ { $$ = $1; }
+ | select_with_parens %prec UMINUS
+ { $$ = $1; }
+ | EXISTS select_with_parens
+ { $$ = cat2_str(make_str("exists"), $2); }
+ | ARRAY select_with_parens
+ { $$ = cat2_str(make_str("array"), $2); }
+ | ARRAY array_expr
+ { $$ = cat2_str(make_str("array"), $2); }
+ | row
+ { $$ = $1; }
+ ;
+
+/*
+ * func_expr is split out from c_expr just so that we have a classification
+ * for "everything that is a function call or looks like one". This isn't
+ * very important, but it saves us having to document which variants are
+ * legal in the backwards-compatible functional-index syntax for CREATE INDEX.
+ * (Note that many of the special SQL functions wouldn't actually make any
+ * sense as functional index entries, but we ignore that consideration here.)
+ */
+func_expr: func_name '(' ')'
{ $$ = cat2_str($1, make_str("()")); }
| func_name '(' expr_list ')'
{ $$ = cat_str(4, $1, make_str("("), $3, make_str(")")); }
{ $$ = cat2_str($1, make_str("(*)")); }
| CURRENT_DATE
{ $$ = make_str("current_date"); }
- | CURRENT_TIME opt_empty_parentheses
- { $$ = cat2_str(make_str("current_time"), $2); }
- | CURRENT_TIME '(' PosIntConst ')'
+ | CURRENT_TIME
{ $$ = make_str("current_time"); }
- | CURRENT_TIMESTAMP opt_empty_parentheses
- { $$ = cat2_str(make_str("current_timestamp"), $2); }
- | CURRENT_TIMESTAMP '(' PosIntConst ')'
+ | CURRENT_TIME '(' PosIntConst ')'
+ { $$ = cat_str(3, make_str("current_time ("), $3, make_str(")")); }
+ | CURRENT_TIMESTAMP
{ $$ = make_str("current_timestamp"); }
- | CURRENT_USER opt_empty_parentheses
- { $$ = cat2_str(make_str("current_user"), $2); }
- | SESSION_USER opt_empty_parentheses
- { $$ = cat2_str(make_str("session_user"), $2); }
- | USER opt_empty_parentheses
- { $$ = cat2_str(make_str("user"), $2); }
+ | CURRENT_TIMESTAMP '(' PosIntConst ')'
+ { $$ = cat_str(3, make_str("current_timestamp ("), $3, make_str(")")); }
+ | LOCALTIME
+ { $$ = make_str("localtime"); }
+ | LOCALTIME '(' PosIntConst ')'
+ { $$ = cat_str(3, make_str("localtime ("), $3, make_str(")")); }
+ | LOCALTIMESTAMP
+ { $$ = make_str("local_timestamp"); }
+ | LOCALTIMESTAMP '(' PosIntConst ')'
+ { $$ = cat_str(3, make_str("locale_timestamp ("), $3, make_str(")")); }
+ | CURRENT_ROLE
+ { $$ = make_str("current_role"); }
+ | CURRENT_USER
+ { $$ = make_str("current_user"); }
+ | SESSION_USER
+ { $$ = make_str("session_user"); }
+ | USER
+ { $$ = make_str("user"); }
| CAST '(' a_expr AS Typename ')'
{ $$ = cat_str(5, make_str("cast("), $3, make_str("as"), $5, make_str(")")); }
| EXTRACT '(' extract_list ')'
{ $$ = cat_str(5, make_str("convert("), $3, make_str("using"), $5, make_str(")"));}
| CONVERT '(' expr_list ')'
{ $$ = cat_str(3, make_str("convert("), $3, make_str(")")); }
- | select_with_parens %prec UMINUS
- { $$ = $1; }
- | EXISTS select_with_parens
- { $$ = cat2_str(make_str("exists"), $2); }
- | ARRAY select_with_parens
- { $$ = cat2_str(make_str("array"), $2); }
- | ARRAY array_expr
- { $$ = cat2_str(make_str("array"), $2); }
+ | NULLIF '(' a_expr ',' a_expr ')'
+ { $$ = cat_str(5, make_str("nullif("), $3, make_str(","), $5, make_str(")")); }
+ | COALESCE '(' expr_list ')'
+ { $$ = cat_str(3, make_str("coalesce("), $3, make_str(")")); }
+ | GREATEST '(' expr_list ')'
+ { $$ = cat_str(3, make_str("greatest("), $3, make_str(")")); }
+ | LEAST '(' expr_list ')'
+ { $$ = cat_str(3, make_str("least("), $3, make_str(")")); }
;
-/*
- * 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
- { $$ = cat_str(4, make_str("["), $2, make_str("]"), $4); }
- | '[' a_expr ':' a_expr ']' opt_indirection
- { $$ = cat_str(6, make_str("["), $2, make_str(":"), $4, make_str("]"), $6); }
- | /* EMPTY */
- { $$ = EMPTY; }
+
+
+row: ROW '(' expr_list ')'
+ { $$ = cat_str(3, make_str("row ("), $3, make_str(")")); }
+ | ROW '(' ')'
+ { $$ = make_str("row()"); }
+ | '(' expr_list ',' a_expr ')'
+ { $$ = cat_str(5, make_str("("), $2, make_str(","), $4, make_str(")")); }
+ ;
+
+sub_type: ANY { $$ = make_str("ANY"); }
+ | SOME { $$ = make_str("SOME"); }
+ | ALL { $$ = make_str("ALL"); }
+ ;
+
+all_Op: Op { $$ = $1; }
+ | MathOp { $$ = $1; }
+ ;
+
+MathOp: '+' { $$ = make_str("+"); }
+ | '-' { $$ = make_str("-"); }
+ | '*' { $$ = make_str("*"); }
+ | '%' { $$ = make_str("%"); }
+ | '^' { $$ = make_str("^"); }
+ | '/' { $$ = make_str("/"); }
+ | '<' { $$ = make_str("<"); }
+ | '>' { $$ = make_str(">"); }
+ | '=' { $$ = make_str("="); }
+ ;
+
+qual_Op: Op { $$ = $1; }
+ | OPERATOR '(' any_operator ')' { $$ = cat_str(3, make_str("operator ("), $3, make_str(")")); }
+ ;
+
+qual_all_Op: all_Op { $$ = $1; }
+ | OPERATOR '(' any_operator ')' { $$ = cat_str(3, make_str("operator ("), $3, make_str(")")); }
+ ;
+
+subquery_Op: all_Op { $$ = $1; }
+ | OPERATOR '(' any_operator ')' { $$ = cat_str(3, make_str("operator ("), $3, make_str(")")); }
+ | LIKE { $$ = make_str("like"); }
+ | NOT LIKE { $$ = make_str("not like"); }
+ | ILIKE { $$ = make_str("ilike"); }
+ | NOT ILIKE { $$ = make_str("not ilike"); }
;
expr_list: a_expr
/* Case clause
* Define SQL92-style case clause.
- * Allow all four forms described in the standard:
- * - Full specification
- * CASE WHEN a = b THEN c ... ELSE d END
- * - Implicit argument
- * CASE a WHEN b THEN c ... ELSE d END
- * - Conditional NULL
- * NULLIF(x,y)
- * same as CASE WHEN x = y THEN NULL ELSE x END
- * - Conditional substitution from list, use first non-null argument
- * COALESCE(a,b,...)
- * same as CASE WHEN a IS NOT NULL THEN a WHEN b IS NOT NULL THEN b ... END
- * - thomas 1998-11-09
*/
case_expr: CASE case_arg when_clause_list case_default END_P
{ $$ = cat_str(5, make_str("case"), $2, $3, $4, make_str("end")); }
- | NULLIF '(' a_expr ',' a_expr ')'
- { $$ = cat_str(5, make_str("nullif("), $3, make_str(","), $5, make_str(")")); }
- | COALESCE '(' expr_list ')'
- { $$ = cat_str(3, make_str("coalesce("), $3, make_str(")")); }
;
when_clause_list: when_clause_list when_clause
;
case_arg: a_expr { $$ = $1; }
- | /*EMPTY*/ { $$ = EMPTY; }
+ | /*EMPTY*/ { $$ = EMPTY; }
;
-columnref: relation_name opt_indirection
- { $$ = cat2_str($1, $2); }
- | dotted_name opt_indirection
- { $$ = cat2_str($1, $2); }
+columnref: relation_name { $$ = $1; }
+ | relation_name indirection { $$ = cat2_str($1, $2); }
;
-dotted_name: relation_name attrs
- { $$ = cat2_str($1, $2); }
- ;
+indirection_el:
+ '.' attr_name { $$ = cat2_str(make_str("."), $2); }
+ | '.' '*' { $$ = make_str(".*"); }
+ | '[' a_expr ']' { $$ = cat_str(3, make_str("["), $2, make_str("]")); }
+ | '[' a_expr ':' a_expr ']' { $$ = cat_str(5, make_str("["), $2, make_str(":"), $4, make_str("]")); }
+ ;
-attrs: '.' attr_name
- { $$ = cat2_str(make_str("."), $2); }
- | '.' '*'
- { $$ = make_str(".*"); }
- | '.' attr_name attrs
- { $$ = cat_str(3, make_str("."), $2, $3); }
- ;
+indirection: indirection_el { $$ = $1; }
+ | indirection indirection_el { $$ = cat2_str($1, $2); }
+ ;
-opt_empty_parentheses: '(' ')' { $$ = make_str("()"); }
- | /*EMPTY*/ { $$ = EMPTY; }
- ;
+opt_indirection:
+ /*EMPTY*/ { $$ = EMPTY; }
+ | opt_indirection indirection_el { $$ = cat2_str($1, $2);}
+ ;
+opt_asymmetric: ASYMMETRIC { $$ = make_str("asymmetric"); }
+ | /*EMPTY*/ { $$ = EMPTY; }
+ ;
/*****************************************************************************
*
- * target lists
+ * target lists for SELECT, UPDATE, INSERT
*
*****************************************************************************/
-/* Target lists as found in SELECT ... and INSERT VALUES ( ... ) */
target_list: target_list ',' target_el
{ $$ = cat_str(3, $1, make_str(","), $3); }
| target_el
update_target_el: ColId opt_indirection '=' a_expr
{ $$ = cat_str(4, $1, $2, make_str("="), $4); }
+ | ColId opt_indirection '=' DEFAULT
+ { $$ = cat_str(3, $1, $2, make_str("= default")); }
;
insert_target_list: insert_target_list ',' insert_target_el
{ $$ = $1; }
;
-insert_target_el: target_el { $$ = $1; }
- | DEFAULT { $$ = make_str("default"); }
+insert_target_el: a_expr { $$ = $1; }
+ | DEFAULT { $$ = make_str("default"); }
;
qualified_name: relation_name
{ $$ = $1; }
- | dotted_name
- { $$ = $1; }
+ | relation_name indirection
+ { $$ = cat2_str($1, $2); }
;
name_list: name
name: ColId { $$ = $1; };
database_name: ColId { $$ = $1; };
access_method: ColId { $$ = $1; };
-attr_name: ColId { $$ = $1; };
+attr_name: ColLabel { $$ = $1; };
index_name: ColId { $$ = $1; };
file_name: StringConst { $$ = $1; };
-/* func_name will soon return a List ... but not yet */
-/*
-func_name: function_name
- { $$ = makeList1(makeString($1)); }
- | dotted_name
- { $$ = $1; }
- ;
-*/
func_name: function_name
{ $$ = $1; }
- | dotted_name
- { $$ = $1; }
+ | relation_name indirection
+ { $$ = cat2_str($1, $2); }
;
{ $$ = cat_str(3, $1, $2, $3); }
| ConstInterval '(' PosIntConst ')' StringConst opt_interval
{ $$ = cat_str(6, $1, make_str("("), $3, make_str(")"), $5, $6); }
- | PARAM opt_indirection
- { $$ = cat2_str(make_str("param"), $2); }
| TRUE_P
{ $$ = make_str("true"); }
| FALSE_P
{
$$ = (char *)mm_alloc(strlen($1) + 3);
$$[0]='\'';
- strcpy($$+1, $1);
+ strcpy($$+1, $1);
$$[strlen($1)+2]='\0';
$$[strlen($1)+1]='\'';
free($1);
| '-' PosIntConst { $$ = cat2_str(make_str("-"), $2); }
;
+IntConstVar: Iconst
+ {
+ char *length = mm_alloc(32);
+
+ sprintf(length, "%d", (int) strlen($1));
+ new_variable($1, ECPGmake_simple_type(ECPGt_const, length), 0);
+ $$ = $1;
+ }
+ | cvariable { $$ = $1; }
+ ;
+
+AllConstVar: Fconst
+ {
+ char *length = mm_alloc(32);
+
+ sprintf(length, "%d", (int) strlen($1));
+ new_variable($1, ECPGmake_simple_type(ECPGt_const, length), 0);
+ $$ = $1;
+ }
+ | IntConstVar { $$ = $1; }
+ | '-' Fconst
+ {
+ char *length = mm_alloc(32);
+ char *var = cat2_str(make_str("-"), $2);
+
+ sprintf(length, "%d", (int) strlen(var));
+ new_variable(var, ECPGmake_simple_type(ECPGt_const, length), 0);
+ $$ = var;
+ }
+ | '-' Iconst
+ {
+ char *length = mm_alloc(32);
+ char *var = cat2_str(make_str("-"), $2);
+
+ sprintf(length, "%d", (int) strlen(var));
+ new_variable(var, ECPGmake_simple_type(ECPGt_const, length), 0);
+ $$ = var;
+ }
+ | Sconst
+ {
+ char *length = mm_alloc(32);
+ char *var = $1 + 1;
+
+ var[strlen(var) - 1] = '\0';
+ sprintf(length, "%d", (int) strlen(var));
+ new_variable(var, ECPGmake_simple_type(ECPGt_const, length), 0);
+ $$ = var;
+ }
+ ;
+
StringConst: Sconst { $$ = $1; }
| civar { $$ = $1; }
;
| civar { $$ = $1; }
;
-UserId: ColId { $$ = $1;};
+RoleId: ColId { $$ = $1;};
SpecialRuleRelation: OLD
{
{
/* old style: dbname[@server][:port] */
if (strlen($2) > 0 && *($2) != '@')
- {
- snprintf(errortext, sizeof(errortext),
- "Expected '@', found '%s'", $2);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
+ mmerror(PARSE_ERROR, ET_ERROR, "Expected '@', found '%s'", $2);
$$ = make3_str(make_str("\""), make3_str($1, $2, $3), make_str("\""));
}
{
/* new style: <tcp|unix>:postgresql://server[:port][/dbname] */
if (strncmp($1, "unix:postgresql", strlen("unix:postgresql")) != 0 && strncmp($1, "tcp:postgresql", strlen("tcp:postgresql")) != 0)
- {
- snprintf(errortext, sizeof(errortext), "only protocols 'tcp' and 'unix' and database type 'postgresql' are supported");
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
+ mmerror(PARSE_ERROR, ET_ERROR, "only protocols 'tcp' and 'unix' and database type 'postgresql' are supported");
if (strncmp($3, "//", strlen("//")) != 0)
- {
- snprintf(errortext, sizeof(errortext), "Expected '://', found '%s'", $3);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
+ mmerror(PARSE_ERROR, ET_ERROR, "Expected '://', found '%s'", $3);
if (strncmp($1, "unix", strlen("unix")) == 0 &&
strncmp($3 + strlen("//"), "localhost", strlen("localhost")) != 0 &&
strncmp($3 + strlen("//"), "127.0.0.1", strlen("127.0.0.1")) != 0)
- {
- snprintf(errortext, sizeof(errortext), "unix domain sockets only work on 'localhost' but not on '%9.9s'", $3 + strlen("//"));
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
+ mmerror(PARSE_ERROR, ET_ERROR, "unix domain sockets only work on 'localhost' but not on '%9.9s'", $3 + strlen("//"));
$$ = make3_str(make3_str(make_str("\""), $1, make_str(":")), $3, make3_str(make3_str($4, make_str("/"), $6), $7, make_str("\"")));
}
- | StringConst
+ | Sconst
{
if ($1[0] == '\"')
$$ = $1;
- else if (strcmp($1, " ?") == 0) /* variable */
- {
- enum ECPGttype type = argsinsert->variable->type->type;
-
- /* if array see what's inside */
- if (type == ECPGt_array)
- type = argsinsert->variable->type->u.element->type;
-
- /* handle varchars */
- if (type == ECPGt_varchar)
- $$ = make2_str(mm_strdup(argsinsert->variable->name), make_str(".arr"));
- else
- $$ = mm_strdup(argsinsert->variable->name);
- }
else
$$ = make3_str(make_str("\""), $1, make_str("\""));
}
+ | char_variable
+ {
+ $$ = $1;
+ }
;
-db_prefix: ident CVARIABLE
+db_prefix: ident cvariable
{
if (strcmp($2, "postgresql") != 0 && strcmp($2, "postgres") != 0)
- {
- snprintf(errortext, sizeof(errortext), "Expected 'postgresql', found '%s'", $2);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
+ mmerror(PARSE_ERROR, ET_ERROR, "Expected 'postgresql', found '%s'", $2);
if (strcmp($1, "tcp") != 0 && strcmp($1, "unix") != 0)
- {
- snprintf(errortext, sizeof(errortext), "Illegal connection type %s", $1);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
+ mmerror(PARSE_ERROR, ET_ERROR, "Illegal connection type %s", $1);
$$ = make3_str($1, make_str(":"), $2);
}
server: Op server_name
{
if (strcmp($1, "@") != 0 && strcmp($1, "//") != 0)
- {
- snprintf(errortext, sizeof(errortext), "Expected '@' or '://', found '%s'", $1);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
+ mmerror(PARSE_ERROR, ET_ERROR, "Expected '@' or '://', found '%s'", $1);
$$ = make2_str($1, $2);
}
{ $$ = cat_str(3, $1, make_str(","), $3); }
;
-user_name: UserId
+user_name: RoleId
{
if ($1[0] == '\"')
$$ = $1;
{
if ($1[0] == '\"')
$$ = $1;
- else if (strcmp($1, "?") == 0) /* variable */
+ else if (strcmp($1, " ?") == 0) /* variable */
{
enum ECPGttype type = argsinsert->variable->type->type;
}
;
-char_variable: CVARIABLE
+char_variable: cvariable
{
- /* check if we have a char variable */
+ /* check if we have a string variable */
struct variable *p = find_variable($1);
enum ECPGttype type = p->type->type;
- /* if array see what's inside */
- if (type == ECPGt_array)
- type = p->type->u.element->type;
-
- switch (type)
- {
- case ECPGt_char:
- case ECPGt_unsigned_char:
- $$ = $1;
- break;
- case ECPGt_varchar:
- $$ = make2_str($1, make_str(".arr"));
- break;
- default:
+ /* If we have just one character this is not a string */
+ if (atol(p->type->size) == 1)
mmerror(PARSE_ERROR, ET_ERROR, "invalid datatype");
- break;
+ else
+ {
+ /* if array see what's inside */
+ if (type == ECPGt_array)
+ type = p->type->u.element->type;
+
+ switch (type)
+ {
+ case ECPGt_char:
+ case ECPGt_unsigned_char:
+ $$ = $1;
+ break;
+ case ECPGt_varchar:
+ $$ = make2_str($1, make_str(".arr"));
+ break;
+ default:
+ mmerror(PARSE_ERROR, ET_ERROR, "invalid datatype");
+ break;
+ }
}
}
;
mmerror(PARSE_ERROR, ET_ERROR, "incomplete statement");
if (strcmp($1, "?") != 0)
- {
- snprintf(errortext, sizeof(errortext), "unrecognised token '%s'", $1);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
+ mmerror(PARSE_ERROR, ET_ERROR, "unrecognised token '%s'", $1);
$$ = make2_str(make_str("?"), $2);
}
* Declare a prepared cursor. The syntax is different from the standard
* declare statement, so we create a new rule.
*/
-ECPGCursorStmt: DECLARE name cursor_options CURSOR opt_hold FOR ident
+ECPGCursorStmt: DECLARE name cursor_options CURSOR opt_hold FOR prepared_name
{
struct cursor *ptr, *this;
struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
for (ptr = cur; ptr != NULL; ptr = ptr->next)
{
if (strcmp($2, ptr->name) == 0)
- {
- /* re-definition is a bug */
- snprintf(errortext, sizeof(errortext), "cursor %s already defined", $2);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
+ /* re-definition is a bug */
+ mmerror(PARSE_ERROR, ET_ERROR, "cursor %s already defined", $2);
}
this = (struct cursor *) mm_alloc(sizeof(struct cursor));
thisquery->type = &ecpg_query;
thisquery->brace_level = 0;
thisquery->next = NULL;
- thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($7));
- sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $7);
+ 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, &no_indicator);
+ add_variable_to_head(&(this->argsinsert), thisquery, &no_indicator);
cur = this;
* the exec sql deallocate prepare command to deallocate a previously
* prepared statement
*/
-ECPGDeallocate: DEALLOCATE PREPARE ident
- { $$ = cat_str(3, make_str("ECPGdeallocate(__LINE__, \""), $3, make_str("\");")); }
- | DEALLOCATE ident
- { $$ = cat_str(2, make_str("ECPGdeallocate(__LINE__, \""), $2, make_str("\");")); }
+ECPGDeallocate: DEALLOCATE PREPARE prepared_name
+ { $$ = $3; }
+ | DEALLOCATE prepared_name
+ { $$ = $2; }
;
/*
;
single_var_declaration: storage_declaration
- single_vt_type
+ var_type
{
actual_type[struct_level].type_enum = $2.type_enum;
actual_type[struct_level].type_dimension = $2.type_dimension;
actual_type[struct_level].type_index = $2.type_index;
actual_type[struct_level].type_sizeof = $2.type_sizeof;
+
+ actual_startline[struct_level] = hashline_number();
}
variable_list ';'
{
$$ = cat_str(5, actual_startline[struct_level], $1, $2.type_str, $4, make_str(";\n"));
}
- | single_vt_type
+ | var_type
{
actual_type[struct_level].type_enum = $1.type_enum;
actual_type[struct_level].type_dimension = $1.type_dimension;
actual_type[struct_level].type_index = $1.type_index;
actual_type[struct_level].type_sizeof = $1.type_sizeof;
- actual_storage[struct_level] = EMPTY;
actual_startline[struct_level] = hashline_number();
}
}
| struct_union_type_with_symbol ';'
{
- /* this is essantially a typedef but needs the keyword struct/union as well */
- struct typedefs *ptr, *this;
-
- for (ptr = types; ptr != NULL; ptr = ptr->next)
- {
- if (strcmp($1.type_str, ptr->name) == 0)
- {
- /* re-definition is a bug */
- snprintf(errortext, sizeof(errortext), "Type %s already defined", $1.type_str);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
- }
-
- this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
-
- /* initial definition */
- this->next = types;
- this->name = $1.type_str;
- this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
- this->type->type_enum = $1.type_enum;
- this->type->type_str = mm_strdup($1.type_str);
- this->type->type_dimension = make_str("-1"); /* dimension of array */
- this->type->type_index = make_str("-1"); /* length of string */
- this->type->type_sizeof = ECPGstruct_sizeof;
- this->struct_member_list = struct_member_list[struct_level];
-
- types = this;
- $$ = cat2_str($1.type_sizeof, make_str(";"));
+ $$ = cat2_str($1, make_str(";"));
}
;
| MONTH_P TO MONTH_P { $$ = make_str("month to month"); }
;
-single_vt_type: common_type
- | DOUBLE_P
- {
- $$.type_enum = ECPGt_double;
- $$.type_str = make_str("double");
- $$.type_dimension = make_str("-1");
- $$.type_index = make_str("-1");
- $$.type_sizeof = NULL;
- }
- | ECPGColLabelCommon ecpg_interval
- {
- if (strlen($2) != 0 && strcmp ($1, "datetime") != 0 && strcmp ($1, "interval") != 0)
- mmerror (PARSE_ERROR, ET_ERROR, "Interval specification not allowed here ");
-
- /*
- * Check for type names that the SQL grammar treats as
- * unreserved keywords
- */
- if (strcmp($1, "varchar") == 0)
- {
- $$.type_enum = ECPGt_varchar;
- $$.type_str = EMPTY;
- $$.type_dimension = make_str("-1");
- $$.type_index = make_str("-1");
- $$.type_sizeof = NULL;
- }
- else if (strcmp($1, "float") == 0)
- {
- $$.type_enum = ECPGt_float;
- $$.type_str = make_str("float");
- $$.type_dimension = make_str("-1");
- $$.type_index = make_str("-1");
- $$.type_sizeof = NULL;
- }
- else if (strcmp($1, "numeric") == 0)
- {
- $$.type_enum = ECPGt_numeric;
- $$.type_str = EMPTY;
- $$.type_dimension = make_str("-1");
- $$.type_index = make_str("-1");
- $$.type_sizeof = NULL;
- }
- else if (strcmp($1, "decimal") == 0)
- {
- $$.type_enum = ECPGt_numeric;
- $$.type_str = EMPTY;
- $$.type_dimension = make_str("-1");
- $$.type_index = make_str("-1");
- $$.type_sizeof = NULL;
- }
- else if (strcmp($1, "date") == 0)
- {
- $$.type_enum = ECPGt_date;
- $$.type_str = make_str("Date");
- $$.type_dimension = make_str("-1");
- $$.type_index = make_str("-1");
- $$.type_sizeof = NULL;
- }
- else if (strcmp($1, "timestamp") == 0)
- {
- $$.type_enum = ECPGt_timestamp;
- $$.type_str = make_str("Timestamp");
- $$.type_dimension = make_str("-1");
- $$.type_index = make_str("-1");
- $$.type_sizeof = NULL;
- }
- else if (strcmp($1, "datetime") == 0)
- {
- $$.type_enum = ECPGt_timestamp;
- $$.type_str = make_str("Timestamp");
- $$.type_dimension = make_str("-1");
- $$.type_index = make_str("-1");
- $$.type_sizeof = NULL;
- }
- else if (strcmp($1, "interval") == 0)
- {
- $$.type_enum = ECPGt_interval;
- $$.type_str = EMPTY;
- $$.type_dimension = make_str("-1");
- $$.type_index = make_str("-1");
- $$.type_sizeof = NULL;
- }
- else
- {
- /* this is for typedef'ed types */
- struct typedefs *this = get_typedef($1);
-
- $$.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;
- $$.type_sizeof = this->type->type_sizeof;
- struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
- }
- }
- | s_struct_union_symbol
- {
- /* this is for named structs/unions */
- char *name;
- struct typedefs *this;
- bool forward = (forward_name != NULL && strcmp($1.symbol, forward_name) == 0 && strcmp($1.su, "struct") == 0);
-
- name = cat2_str($1.su, $1.symbol);
- /* Do we have a forward definition? */
- if (!forward)
- {
- /* No */
-
- this = get_typedef(name);
- $$.type_str = mm_strdup(this->name);
- $$.type_enum = this->type->type_enum;
- $$.type_dimension = this->type->type_dimension;
- $$.type_index = this->type->type_index;
- $$.type_sizeof = this->type->type_sizeof;
- struct_member_list[struct_level] = ECPGstruct_member_dup(this->struct_member_list);
- free(name);
- }
- else
- {
- $$.type_str = name;
- $$.type_enum = ECPGt_long;
- $$.type_dimension = make_str("-1");
- $$.type_index = make_str("-1");
- $$.type_sizeof = make_str("");
- struct_member_list[struct_level] = NULL;
- }
- }
- ;
-
/*
* variable declaration inside exec sql declare block
*/
var_type_declarations: /*EMPTY*/ { $$ = EMPTY; }
| vt_declarations { $$ = $1; }
+ | CPP_LINE { $$ = $1; }
;
vt_declarations: var_declaration { $$ = $1; }
| type_declaration { $$ = $1; }
| vt_declarations var_declaration { $$ = cat2_str($1, $2); }
| vt_declarations type_declaration { $$ = cat2_str($1, $2); }
+ | vt_declarations CPP_LINE { $$ = cat2_str($1, $2); }
;
variable_declarations: var_declaration { $$ = $1; }
for (ptr = types; ptr != NULL; ptr = ptr->next)
{
if (strcmp($5, ptr->name) == 0)
- {
/* re-definition is a bug */
- snprintf(errortext, sizeof(errortext), "Type %s already defined", $5);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
+ mmerror(PARSE_ERROR, ET_ERROR, "Type %s already defined", $5);
}
-
- adjust_array($3.type_enum, &dimension, &length, $3.type_dimension, $3.type_index, *$4?1:0);
+ adjust_array($3.type_enum, &dimension, &length, $3.type_dimension, $3.type_index, *$4?1:0, true);
this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
/* initial definition */
this->next = types;
this->name = $5;
+ this->brace_level = braces_open;
this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
this->type->type_enum = $3.type_enum;
this->type->type_str = mm_strdup($5);
this->type->type_index = length; /* length of string */
this->type->type_sizeof = ECPGstruct_sizeof;
this->struct_member_list = ($3.type_enum == ECPGt_struct || $3.type_enum == ECPGt_union) ?
- struct_member_list[struct_level] : NULL;
+ ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL;
if ($3.type_enum != ECPGt_varchar &&
$3.type_enum != ECPGt_char &&
$3.type_enum != ECPGt_unsigned_char &&
atoi(this->type->type_index) >= 0)
- mmerror(PARSE_ERROR, ET_ERROR, "No multi-dimensional array support for simple data types");
+ mmerror(PARSE_ERROR, ET_ERROR, "No multidimensional array support for simple data types");
types = this;
}
actual_type[struct_level].type_dimension = $2.type_dimension;
actual_type[struct_level].type_index = $2.type_index;
actual_type[struct_level].type_sizeof = $2.type_sizeof;
+
+ actual_startline[struct_level] = hashline_number();
}
variable_list ';'
{
actual_type[struct_level].type_dimension = $1.type_dimension;
actual_type[struct_level].type_index = $1.type_index;
actual_type[struct_level].type_sizeof = $1.type_sizeof;
- actual_storage[struct_level] = EMPTY;
actual_startline[struct_level] = hashline_number();
}
}
| struct_union_type_with_symbol ';'
{
- /* this is essantially a typedef but needs the keyword struct/union as well */
- struct typedefs *ptr, *this;
-
- for (ptr = types; ptr != NULL; ptr = ptr->next)
- {
- if (strcmp($1.type_str, ptr->name) == 0)
- {
- /* re-definition is a bug */
- snprintf(errortext, sizeof(errortext), "Type %s already defined", $1.type_str);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
- }
-
- this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
-
- /* initial definition */
- this->next = types;
- this->name = $1.type_str;
- this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
- this->type->type_enum = $1.type_enum;
- this->type->type_str = mm_strdup($1.type_str);
- this->type->type_dimension = make_str("-1"); /* dimension of array */
- this->type->type_index = make_str("-1"); /* length of string */
- this->type->type_sizeof = ECPGstruct_sizeof;
- this->struct_member_list = struct_member_list[struct_level];
-
- types = this;
- $$ = cat2_str($1.type_sizeof, make_str(";"));
+ $$ = cat2_str($1, make_str(";"));
}
;
storage_declaration: storage_clause storage_modifier
{
- actual_storage[struct_level] = cat2_str(mm_strdup($1), mm_strdup($2));
- actual_startline[struct_level] = hashline_number();
+ $$ = cat2_str ($1, $2);
}
| storage_clause
{
- actual_storage[struct_level] = mm_strdup($1);
- actual_startline[struct_level] = hashline_number();
+ $$ = $1;
}
| storage_modifier
{
- actual_storage[struct_level] = mm_strdup($1);
- actual_startline[struct_level] = hashline_number();
+ $$ = $1;
}
;
| S_VOLATILE { $$ = make_str("volatile"); }
;
-common_type: simple_type
+var_type: simple_type
{
$$.type_enum = $1;
$$.type_str = mm_strdup(ECPGtype_name($1));
}
| ECPGColLabelCommon '(' precision opt_scale ')'
{
- if (strcmp($1, "numeric") != 0 && strcmp($1, "decimal") != 0)
+ if (strcmp($1, "numeric") == 0)
+ {
+ $$.type_enum = ECPGt_numeric;
+ $$.type_str = make_str("numeric");
+ }
+ else if (strcmp($1, "decimal") == 0)
+ {
+ $$.type_enum = ECPGt_decimal;
+ $$.type_str = make_str("decimal");
+ }
+ else
+ {
mmerror(PARSE_ERROR, ET_ERROR, "Only numeric/decimal have precision/scale argument");
+ $$.type_enum = ECPGt_numeric;
+ $$.type_str = make_str("numeric");
+ }
- $$.type_enum = ECPGt_numeric;
- $$.type_str = EMPTY;
$$.type_dimension = make_str("-1");
$$.type_index = make_str("-1");
$$.type_sizeof = NULL;
}
- ;
-
-var_type: common_type
- | ECPGColLabel ecpg_interval
+ | ECPGColLabelCommon ecpg_interval
{
if (strlen($2) != 0 && strcmp ($1, "datetime") != 0 && strcmp ($1, "interval") != 0)
mmerror (PARSE_ERROR, ET_ERROR, "Interval specification not allowed here ");
else if (strcmp($1, "numeric") == 0)
{
$$.type_enum = ECPGt_numeric;
- $$.type_str = EMPTY;
+ $$.type_str = make_str("numeric");
$$.type_dimension = make_str("-1");
$$.type_index = make_str("-1");
$$.type_sizeof = NULL;
}
else if (strcmp($1, "decimal") == 0)
{
- $$.type_enum = ECPGt_numeric;
- $$.type_str = EMPTY;
+ $$.type_enum = ECPGt_decimal;
+ $$.type_str = make_str("decimal");
$$.type_dimension = make_str("-1");
$$.type_index = make_str("-1");
$$.type_sizeof = NULL;
else if (strcmp($1, "date") == 0)
{
$$.type_enum = ECPGt_date;
- $$.type_str = make_str("Date");
+ $$.type_str = make_str("date");
$$.type_dimension = make_str("-1");
$$.type_index = make_str("-1");
$$.type_sizeof = NULL;
else if (strcmp($1, "timestamp") == 0)
{
$$.type_enum = ECPGt_timestamp;
- $$.type_str = make_str("Timestamp");
+ $$.type_str = make_str("timestamp");
$$.type_dimension = make_str("-1");
$$.type_index = make_str("-1");
$$.type_sizeof = NULL;
else if (strcmp($1, "interval") == 0)
{
$$.type_enum = ECPGt_interval;
- $$.type_str = EMPTY;
+ $$.type_str = make_str("interval");
$$.type_dimension = make_str("-1");
$$.type_index = make_str("-1");
$$.type_sizeof = NULL;
else if (strcmp($1, "datetime") == 0)
{
$$.type_enum = ECPGt_timestamp;
- $$.type_str = make_str("Timestamp");
+ $$.type_str = make_str("timestamp");
$$.type_dimension = make_str("-1");
$$.type_index = make_str("-1");
$$.type_sizeof = NULL;
}
'{' variable_declarations '}'
{
+ struct typedefs *ptr, *this;
+ struct this_type su_type;
+
ECPGfree_struct_member(struct_member_list[struct_level]);
struct_member_list[struct_level] = NULL;
- free(actual_storage[struct_level--]);
+ struct_level--;
if (strncmp($1.su, "struct", sizeof("struct")-1) == 0)
- $$.type_enum = ECPGt_struct;
+ su_type.type_enum = ECPGt_struct;
else
- $$.type_enum = ECPGt_union;
- $$.type_str = cat2_str($1.su, $1.symbol);
- $$.type_sizeof = cat_str(4, mm_strdup($$.type_str), make_str("{"), $4, make_str("}"));
+ su_type.type_enum = ECPGt_union;
+ su_type.type_str = cat2_str($1.su, $1.symbol);
free(forward_name);
forward_name = NULL;
+
+ /* This is essantially a typedef but needs the keyword struct/union as well.
+ * So we create the typedef for each struct definition with symbol */
+ for (ptr = types; ptr != NULL; ptr = ptr->next)
+ {
+ if (strcmp(su_type.type_str, ptr->name) == 0)
+ /* re-definition is a bug */
+ mmerror(PARSE_ERROR, ET_ERROR, "Type %s already defined", su_type.type_str);
+ }
+
+ this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
+
+ /* initial definition */
+ this->next = types;
+ this->name = mm_strdup(su_type.type_str);
+ this->brace_level = braces_open;
+ this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
+ this->type->type_enum = su_type.type_enum;
+ this->type->type_str = mm_strdup(su_type.type_str);
+ this->type->type_dimension = make_str("-1"); /* dimension of array */
+ this->type->type_index = make_str("-1"); /* length of string */
+ this->type->type_sizeof = ECPGstruct_sizeof;
+ this->struct_member_list = struct_member_list[struct_level];
+
+ types = this;
+ $$ = cat_str(4, su_type.type_str, make_str("{"), $4, make_str("}"));
}
;
-struct_union_type: struct_union_type_with_symbol { $$ = $1.type_sizeof; }
+struct_union_type: struct_union_type_with_symbol { $$ = $1; }
| s_struct_union
{
struct_member_list[struct_level++] = NULL;
{
ECPGfree_struct_member(struct_member_list[struct_level]);
struct_member_list[struct_level] = NULL;
- free(actual_storage[struct_level--]);
+ struct_level--;
$$ = cat_str(4, $1, make_str("{"), $4, make_str("}"));
}
;
}
| SQL_BOOL { $$ = ECPGt_bool; }
| CHAR_P { $$ = ECPGt_char; }
+ | DOUBLE_P { $$ = ECPGt_double; }
;
opt_signed: SQL_SIGNED
{ $$ = cat_str(3, $1, make_str(","), $3); }
;
-variable: opt_pointer ECPGColLabelCommon opt_array_bounds opt_initializer
+variable: opt_pointer ECPGColLabel opt_array_bounds opt_initializer
{
struct ECPGtype * type;
char *dimension = $3.index1; /* dimension of array */
char *length = $3.index2; /* length of string */
char dim[14L];
- adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1));
+ adjust_array(actual_type[struct_level].type_enum, &dimension, &length, actual_type[struct_level].type_dimension, actual_type[struct_level].type_index, strlen($1), false);
switch (actual_type[struct_level].type_enum)
{
*dim = '\0';
else
sprintf(dim, "[%s]", dimension);
- if (strcmp(length, "0") == 0)
+ /* cannot check for atoi <= 0 because a defined constant will yield 0 here as well */
+ if (atoi(length) < 0 || strcmp(length, "0") == 0)
mmerror(PARSE_ERROR, ET_ERROR, "pointer to varchar are not implemented");
if (strcmp(dimension, "0") == 0)
- $$ = cat_str(7, mm_strdup(actual_storage[struct_level]), make2_str(make_str(" struct varchar_"), mm_strdup($2)), make_str(" { int len; char arr["), mm_strdup(length), make_str("]; } *"), mm_strdup($2), $4);
+ $$ = cat_str(6, make2_str(make_str(" struct varchar_"), mm_strdup($2)), make_str(" { int len; char arr["), mm_strdup(length), make_str("]; } *"), mm_strdup($2), $4);
else
- $$ = cat_str(8, mm_strdup(actual_storage[struct_level]), make2_str(make_str(" struct varchar_"), mm_strdup($2)), make_str(" { int len; char arr["), mm_strdup(length), make_str("]; } "), mm_strdup($2), mm_strdup(dim), $4);
+ $$ = cat_str(7, make2_str(make_str(" struct varchar_"), mm_strdup($2)), make_str(" { int len; char arr["), mm_strdup(length), make_str("]; } "), mm_strdup($2), mm_strdup(dim), $4);
break;
case ECPGt_char:
$$ = cat_str(4, $1, mm_strdup($2), $3.str, $4);
break;
- case ECPGt_numeric:
- if (atoi(dimension) < 0)
- type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
- else
- type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
-
- if (atoi(dimension) < 0)
- $$ = cat_str(4, mm_strdup(actual_storage[struct_level]), make_str("Numeric"), mm_strdup($2), $4);
- else
- $$ = cat_str(5, mm_strdup(actual_storage[struct_level]), make_str("Numeric"), mm_strdup($2), mm_strdup(dim), $4);
- break;
-
- case ECPGt_interval:
- if (atoi(dimension) < 0)
- type = ECPGmake_simple_type(actual_type[struct_level].type_enum, length);
- else
- type = ECPGmake_array_type(ECPGmake_simple_type(actual_type[struct_level].type_enum, length), dimension);
-
- if (atoi(dimension) < 0)
- $$ = cat_str(4, mm_strdup(actual_storage[struct_level]), make_str("Interval"), mm_strdup($2), $4);
- else
- $$ = cat_str(5, mm_strdup(actual_storage[struct_level]), make_str("Interval"), mm_strdup($2), mm_strdup(dim), $4);
- break;
-
default:
if (atoi(dimension) < 0)
type = ECPGmake_simple_type(actual_type[struct_level].type_enum, make_str("1"));
;
/*
- * As long as the prepare statement is not supported by the backend, we will
- * try to simulate it here so we get dynamic SQL
+ * We try to simulate the correct DECLARE syntax here so we get dynamic SQL
*/
ECPGDeclare: DECLARE STATEMENT ident
{
thisquery->next = NULL;
thisquery->name = $3;
- add_variable(&argsinsert, thisquery, &no_indicator);
+ add_variable_to_head(&argsinsert, thisquery, &no_indicator);
$$ = make_str("?");
}
- | EXECUTE name
+ | EXECUTE prepared_name
{
struct variable *thisquery = (struct variable *)mm_alloc(sizeof(struct variable));
thisquery->type = &ecpg_query;
thisquery->brace_level = 0;
thisquery->next = NULL;
- thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement(\"\")") + strlen($2));
- sprintf(thisquery->name, "ECPGprepared_statement(\"%s\")", $2);
+ thisquery->name = (char *) mm_alloc(sizeof("ECPGprepared_statement()") + strlen($2));
+ sprintf(thisquery->name, "ECPGprepared_statement(%s)", $2);
- add_variable(&argsinsert, thisquery, &no_indicator);
+ add_variable_to_head(&argsinsert, thisquery, &no_indicator);
}
execute_rest
{
{ $$ = make3_str(make_str("\""), $1, make_str("\"")); }
;
+prepared_name: name { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
+ | char_variable { $$ = $1; }
+ ;
+
/*
* the exec sql free command to deallocate a previously
* prepared statement
;
ecpg_using: USING using_list { $$ = EMPTY; }
+ | using_descriptor { $$ = $1; }
;
using_descriptor: USING opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
{
- add_variable(&argsresult, descriptor_variable($4,0), &no_indicator);
+ add_variable_to_head(&argsinsert, descriptor_variable($4,0), &no_indicator);
$$ = EMPTY;
}
;
into_descriptor: INTO opt_sql SQL_DESCRIPTOR quoted_ident_stringvar
{
- add_variable(&argsresult, descriptor_variable($4,0), &no_indicator);
+ add_variable_to_head(&argsresult, descriptor_variable($4,1), &no_indicator);
$$ = EMPTY;
}
;
opt_sql: /*EMPTY*/ | SQL_SQL;
-ecpg_into_using: ecpg_into { $$ = EMPTY; }
- | using_descriptor { $$ = $1; }
- ;
-
ecpg_into: INTO into_list { $$ = EMPTY; }
| into_descriptor { $$ = $1; }
;
-using_list: civar | civar ',' using_list;
+using_list: UsingConst | UsingConst ',' using_list;
+
+UsingConst: AllConst
+ {
+ if ($1[1] != '?') /* found a constant */
+ {
+ char *length = mm_alloc(32);
+
+ sprintf(length, "%d", (int) strlen($1));
+ add_variable_to_head(&argsinsert, new_variable($1, ECPGmake_simple_type(ECPGt_const, length), 0), &no_indicator);
+ }
+ }
+ | civarind { $$ = EMPTY; }
+ ;
/*
* As long as the prepare statement is not supported by the backend, we will
*
* It is supported now but not usable yet by ecpg.
*/
-ECPGPrepare: PREPARE name FROM execstring
- { $$ = cat2_str(make3_str(make_str("\""), $2, make_str("\",")), $4); }
+ECPGPrepare: PREPARE prepared_name FROM execstring
+ { $$ = cat_str(3, $2, make_str(","), $4); }
;
/*
* We accept descibe but do nothing with it so far.
/*
* dynamic SQL: descriptor based access
- * written by Christof Petig <christof.petig@wtal.de>
+ * originall written by Christof Petig <christof.petig@wtal.de>
+ * and Peter Eisentraut <peter.eisentraut@credativ.de>
+ */
+
+/*
+ * allocate a descriptor
*/
+ECPGAllocateDescr: SQL_ALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
+ {
+ add_descriptor($3,connection);
+ $$ = $3;
+ };
+
/*
* deallocate a descriptor
*/
;
/*
- * allocate a descriptor
+ * manipulate a descriptor header
*/
-ECPGAllocateDescr: SQL_ALLOCATE SQL_DESCRIPTOR quoted_ident_stringvar
- {
- add_descriptor($3,connection);
- $$ = $3;
- };
-/*
- * read from descriptor
- */
+ECPGGetDescriptorHeader: GET SQL_DESCRIPTOR quoted_ident_stringvar ECPGGetDescHeaderItems
+ { $$ = $3; }
+ ;
+
+ECPGGetDescHeaderItems: ECPGGetDescHeaderItem
+ | ECPGGetDescHeaderItems ',' ECPGGetDescHeaderItem
+ ;
-ECPGGetDescHeaderItem: CVARIABLE '=' desc_header_item
+ECPGGetDescHeaderItem: cvariable '=' desc_header_item
{ push_assignment($1, $3); }
;
-desc_header_item: SQL_COUNT { $$ = ECPGd_count; }
+
+ECPGSetDescriptorHeader: SET SQL_DESCRIPTOR quoted_ident_stringvar ECPGSetDescHeaderItems
+ { $$ = $3; }
;
-ECPGGetDescItem: CVARIABLE '=' descriptor_item { push_assignment($1, $3); };
+ECPGSetDescHeaderItems: ECPGSetDescHeaderItem
+ | ECPGSetDescHeaderItems ',' ECPGSetDescHeaderItem
+ ;
-descriptor_item: SQL_CARDINALITY { $$ = ECPGd_cardinality; }
- | SQL_DATA { $$ = ECPGd_data; }
- | SQL_DATETIME_INTERVAL_CODE { $$ = ECPGd_di_code; }
- | SQL_DATETIME_INTERVAL_PRECISION { $$ = ECPGd_di_precision; }
- | SQL_INDICATOR { $$ = ECPGd_indicator; }
- | SQL_KEY_MEMBER { $$ = ECPGd_key_member; }
- | SQL_LENGTH { $$ = ECPGd_length; }
- | SQL_NAME { $$ = ECPGd_name; }
- | SQL_NULLABLE { $$ = ECPGd_nullable; }
- | SQL_OCTET_LENGTH { $$ = ECPGd_octet; }
- | PRECISION { $$ = ECPGd_precision; }
- | SQL_RETURNED_LENGTH { $$ = ECPGd_length; }
- | SQL_RETURNED_OCTET_LENGTH { $$ = ECPGd_ret_octet; }
- | SQL_SCALE { $$ = ECPGd_scale; }
- | TYPE_P { $$ = ECPGd_type; }
+ECPGSetDescHeaderItem: desc_header_item '=' IntConstVar
+ {
+ push_assignment($3, $1);
+ }
;
-ECPGGetDescHeaderItems: ECPGGetDescHeaderItem
- | ECPGGetDescHeaderItems ',' ECPGGetDescHeaderItem
+
+desc_header_item: SQL_COUNT { $$ = ECPGd_count; }
+ ;
+
+/*
+ * manipulate a descriptor
+ */
+
+ECPGGetDescriptor: GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE IntConstVar ECPGGetDescItems
+ { $$.str = $5; $$.name = $3; }
;
ECPGGetDescItems: ECPGGetDescItem
| ECPGGetDescItems ',' ECPGGetDescItem
;
-ECPGGetDescriptorHeader: GET SQL_DESCRIPTOR quoted_ident_stringvar
- ECPGGetDescHeaderItems
- { $$ = $3; }
- ;
+ECPGGetDescItem: cvariable '=' descriptor_item { push_assignment($1, $3); };
-ECPGGetDescriptor: GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE CVARIABLE ECPGGetDescItems
- { $$.str = $5; $$.name = $3; }
- | GET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE Iconst ECPGGetDescItems
+
+ECPGSetDescriptor: SET SQL_DESCRIPTOR quoted_ident_stringvar SQL_VALUE IntConstVar ECPGSetDescItems
{ $$.str = $5; $$.name = $3; }
;
+ECPGSetDescItems: ECPGSetDescItem
+ | ECPGSetDescItems ',' ECPGSetDescItem
+ ;
+
+ECPGSetDescItem: descriptor_item '=' AllConstVar
+ {
+ push_assignment($3, $1);
+ }
+ ;
+
+
+descriptor_item: SQL_CARDINALITY { $$ = ECPGd_cardinality; }
+ | SQL_DATA { $$ = ECPGd_data; }
+ | SQL_DATETIME_INTERVAL_CODE { $$ = ECPGd_di_code; }
+ | SQL_DATETIME_INTERVAL_PRECISION { $$ = ECPGd_di_precision; }
+ | SQL_INDICATOR { $$ = ECPGd_indicator; }
+ | SQL_KEY_MEMBER { $$ = ECPGd_key_member; }
+ | SQL_LENGTH { $$ = ECPGd_length; }
+ | SQL_NAME { $$ = ECPGd_name; }
+ | SQL_NULLABLE { $$ = ECPGd_nullable; }
+ | SQL_OCTET_LENGTH { $$ = ECPGd_octet; }
+ | PRECISION { $$ = ECPGd_precision; }
+ | SQL_RETURNED_LENGTH { $$ = ECPGd_length; }
+ | SQL_RETURNED_OCTET_LENGTH { $$ = ECPGd_ret_octet; }
+ | SQL_SCALE { $$ = ECPGd_scale; }
+ | TYPE_P { $$ = ECPGd_type; }
+ ;
+
+
/*
* for compatibility with ORACLE we will also allow the keyword RELEASE
* after a transaction statement to disconnect from the database.
*/
-ECPGRelease: TransactionStmt SQL_RELEASE
+/* We cannot do that anymore since it causes shift/reduce conflicts. 2004-09-27 Michael Meskes
+ECPGRelease: TransactionStmt RELEASE
{
if (strcmp($1, "begin") == 0)
mmerror(PARSE_ERROR, ET_ERROR, "RELEASE does not make sense when beginning a transaction");
free($1);
}
;
+*/
/*
* set/reset the automatic transaction mode, this needs a differnet handling
* set the actual connection, this needs a differnet handling as the other
* set commands
*/
-ECPGSetConnection: SET SQL_CONNECTION TO connection_object { $$ = $4; }
- | SET SQL_CONNECTION '=' connection_object { $$ = $4; }
- | SET SQL_CONNECTION connection_object { $$ = $3; }
+ECPGSetConnection: SET CONNECTION TO connection_object { $$ = $4; }
+ | SET CONNECTION '=' connection_object { $$ = $4; }
+ | SET CONNECTION connection_object { $$ = $3; }
;
/*
/* an initializer specified */
initializer = 0;
}
- ColLabel IS var_type opt_array_bounds opt_reference
+ ECPGColLabelCommon IS var_type opt_array_bounds opt_reference
{
/* add entry to list */
struct typedefs *ptr, *this;
for (ptr = types; ptr != NULL; ptr = ptr->next)
{
if (strcmp($3, ptr->name) == 0)
- {
/* re-definition is a bug */
- snprintf(errortext, sizeof(errortext), "Type %s already defined", $3);
- mmerror(PARSE_ERROR, ET_ERROR, errortext);
- }
+ mmerror(PARSE_ERROR, ET_ERROR, "Type %s already defined", $3);
}
- adjust_array($5.type_enum, &dimension, &length, $5.type_dimension, $5.type_index, *$7?1:0);
+ adjust_array($5.type_enum, &dimension, &length, $5.type_dimension, $5.type_index, *$7?1:0, false);
this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
/* initial definition */
this->next = types;
this->name = $3;
+ this->brace_level = braces_open;
this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
this->type->type_enum = $5.type_enum;
this->type->type_str = mm_strdup($3);
this->type->type_index = length; /* length of string */
this->type->type_sizeof = ECPGstruct_sizeof;
this->struct_member_list = ($5.type_enum == ECPGt_struct || $5.type_enum == ECPGt_union) ?
- struct_member_list[struct_level] : NULL;
+ ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL;
if ($5.type_enum != ECPGt_varchar &&
$5.type_enum != ECPGt_char &&
$5.type_enum != ECPGt_unsigned_char &&
atoi(this->type->type_index) >= 0)
- mmerror(PARSE_ERROR, ET_ERROR, "No multi-dimensional array support for simple data types");
+ mmerror(PARSE_ERROR, ET_ERROR, "No multidimensional array support for simple data types");
types = this;
}
mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in EXEC SQL VAR command");
else
{
- adjust_array($5.type_enum, &dimension, &length, $5.type_dimension, $5.type_index, *$7?1:0);
+ adjust_array($5.type_enum, &dimension, &length, $5.type_dimension, $5.type_index, *$7?1:0, false);
switch ($5.type_enum)
{
default:
if (atoi(length) >= 0)
- mmerror(PARSE_ERROR, ET_ERROR, "No multi-dimensional array support for simple data types");
+ mmerror(PARSE_ERROR, ET_ERROR, "No multidimensional array support for simple data types");
if (atoi(dimension) < 0)
type = ECPGmake_simple_type($5.type_enum, make_str("1"));
| SQL_NAME { $$ = make_str("name"); }
| SQL_NULLABLE { $$ = make_str("nullable"); }
| SQL_OCTET_LENGTH { $$ = make_str("octet_length"); }
- | SQL_RELEASE { $$ = make_str("release"); }
| SQL_RETURNED_LENGTH { $$ = make_str("returned_length"); }
| SQL_RETURNED_OCTET_LENGTH { $$ = make_str("returned_octet_length"); }
| SQL_SCALE { $$ = make_str("scale"); }
| SQL_SQLPRINT { $$ = make_str("sqlprint"); }
| SQL_SQLWARNING { $$ = make_str("sqlwarning"); }
| SQL_STOP { $$ = make_str("stop"); }
+ | SQL_VALUE { $$ = make_str("value"); }
;
ECPGKeywords_rest: SQL_CONNECT { $$ = make_str("connect"); }
* is chosen in part to make keywords acceptable as names wherever possible.
*/
+ECPGColId:ident { $$ = $1; }
+ | ECPGunreserved_interval { $$ = $1; }
+ | ECPGunreserved_con { $$ = $1; }
+ | col_name_keyword { $$ = $1; }
+ | ECPGKeywords { $$ = $1; }
+ | ECPGCKeywords { $$ = $1; }
+ | CHAR_P { $$ = make_str("char"); }
+ ;
/* Column identifier --- names that can be column, table, etc names.
*/
ColId: ident { $$ = $1; }
| unreserved_keyword { $$ = $1; }
| col_name_keyword { $$ = $1; }
| ECPGKeywords { $$ = $1; }
+ | ECPGCKeywords { $$ = $1; }
| CHAR_P { $$ = make_str("char"); }
;
| unreserved_keyword { $$ = $1; }
| ECPGKeywords { $$ = $1; }
| ECPGTypeName { $$ = $1; }
+ | ECPGCKeywords { $$ = $1; }
;
/* Function identifier --- names that can be function names.
| unreserved_keyword { $$ = $1; }
| func_name_keyword { $$ = $1; }
| ECPGKeywords { $$ = $1; }
+ | ECPGCKeywords { $$ = $1; }
;
/* Column label --- allowed labels in "AS" clauses.
| INPUT_P { $$ = make_str("input"); }
| INT_P { $$ = make_str("int"); }
| UNION { $$ = make_str("union"); }
+ | TO { $$ = make_str("to"); }
+ | ECPGCKeywords { $$ = $1; }
+ | ECPGunreserved_interval { $$ = $1; }
;
ECPGColLabelCommon: ident { $$ = $1; }
;
ECPGColLabel: ECPGColLabelCommon { $$ = $1; }
- | unreserved_keyword { $$ = $1; }
| reserved_keyword { $$ = $1; }
+ | ECPGunreserved { $$ = $1; }
| ECPGKeywords_rest { $$ = $1; }
;
+ECPGCKeywords: S_AUTO { $$ = make_str("auto"); }
+ | S_CONST { $$ = make_str("const"); }
+ | S_EXTERN { $$ = make_str("extern"); }
+ | S_REGISTER { $$ = make_str("register"); }
+ | S_STATIC { $$ = make_str("static"); }
+ | S_TYPEDEF { $$ = make_str("typedef"); }
+ | S_VOLATILE { $$ = make_str("volatile"); }
+ ;
+
/*
* Keyword classification lists. Generally, every keyword present in
* the Postgres grammar should appear in exactly one of these lists.
/* "Unreserved" keywords --- available for use as any kind of name.
*/
-unreserved_keyword:
- ABORT_P { $$ = make_str("abort"); }
+/* The following symbols must be excluded from ECPGColLabel and directly included into ColLabel
+ to enable C variables to get names from ECPGColLabel:
+ DAY_P, HOUR_P, MINUTE_P, MONTH_P, SECOND_P, YEAR_P
+ */
+unreserved_keyword: ECPGunreserved_interval | ECPGunreserved;
+
+ECPGunreserved_interval: DAY_P { $$ = make_str("day"); }
+ | HOUR_P { $$ = make_str("hour"); }
+ | MINUTE_P { $$ = make_str("minute"); }
+ | MONTH_P { $$ = make_str("month"); }
+ | SECOND_P { $$ = make_str("second"); }
+ | YEAR_P { $$ = make_str("year"); }
+ ;
+
+/* The following symbol must be excluded from var_name but still included in ColId
+ to enable ecpg special postgresql variables with this name:
+ CONNECTION
+ */
+ECPGunreserved: ECPGunreserved_con { $$ = $1; }
+ | CONNECTION { $$ = make_str("connection"); }
+ ;
+
+ECPGunreserved_con: ABORT_P { $$ = make_str("abort"); }
| ABSOLUTE_P { $$ = make_str("absolute"); }
| ACCESS { $$ = make_str("access"); }
| ACTION { $$ = make_str("action"); }
- | ADD { $$ = make_str("add"); }
+ | ADD_P { $$ = make_str("add"); }
+ | ADMIN { $$ = make_str("admin"); }
| AFTER { $$ = make_str("after"); }
| AGGREGATE { $$ = make_str("aggregate"); }
+ | ALSO { $$ = make_str("also"); }
| ALTER { $$ = make_str("alter"); }
| ASSERTION { $$ = make_str("assertion"); }
| ASSIGNMENT { $$ = make_str("assignment"); }
| COMMENT { $$ = make_str("comment"); }
| COMMIT { $$ = make_str("commit"); }
| COMMITTED { $$ = make_str("committed"); }
+/* | CONNECTION { $$ = make_str("connection"); }*/
| CONSTRAINTS { $$ = make_str("constraints"); }
| CONVERSION_P { $$ = make_str("conversion"); }
| COPY { $$ = make_str("copy"); }
| CREATEDB { $$ = make_str("createdb"); }
+ | CREATEROLE { $$ = make_str("createrole"); }
| CREATEUSER { $$ = make_str("createuser"); }
+ | CSV { $$ = make_str("csv"); }
| CURSOR { $$ = make_str("cursor"); }
| CYCLE { $$ = make_str("cycle"); }
| DATABASE { $$ = make_str("database"); }
- | DAY_P { $$ = make_str("day"); }
+/* | DAY_P { $$ = make_str("day"); }*/
| DEALLOCATE { $$ = make_str("deallocate"); }
| DECLARE { $$ = make_str("declare"); }
+ | DEFAULTS { $$ = make_str("defaults"); }
| DEFERRED { $$ = make_str("deferred"); }
| DELETE_P { $$ = make_str("delete"); }
| DELIMITER { $$ = make_str("delimiter"); }
| DELIMITERS { $$ = make_str("delimiters"); }
+ | DISABLE_P { $$ = make_str("disable"); }
| DOMAIN_P { $$ = make_str("domain"); }
| DOUBLE_P { $$ = make_str("double"); }
| DROP { $$ = make_str("drop"); }
| EACH { $$ = make_str("each"); }
+ | ENABLE_P { $$ = make_str("ensable"); }
| ENCODING { $$ = make_str("encoding"); }
| ENCRYPTED { $$ = make_str("encrypted"); }
| ESCAPE { $$ = make_str("escape"); }
+ | EXCLUDING { $$ = make_str("excluding"); }
| EXCLUSIVE { $$ = make_str("exclusive"); }
| EXECUTE { $$ = make_str("execute"); }
| EXPLAIN { $$ = make_str("explain"); }
| FORWARD { $$ = make_str("forward"); }
| FUNCTION { $$ = make_str("function"); }
| GLOBAL { $$ = make_str("global"); }
+ | GRANTED { $$ = make_str("granted"); }
| HANDLER { $$ = make_str("handler"); }
+ | HEADER_P { $$ = make_str("header"); }
| HOLD { $$ = make_str("hold"); }
- | HOUR_P { $$ = make_str("hour"); }
+/* | HOUR_P { $$ = make_str("hour"); }*/
| IMMEDIATE { $$ = make_str("immediate"); }
| IMMUTABLE { $$ = make_str("immutable"); }
| IMPLICIT_P { $$ = make_str("implicit"); }
+ | INCLUDING { $$ = make_str("including"); }
| INCREMENT { $$ = make_str("increment"); }
| INDEX { $$ = make_str("index"); }
+ | INHERIT { $$ = make_str("inherit"); }
| INHERITS { $$ = make_str("inherits"); }
- | INOUT { $$ = make_str("inout"); }
| INSENSITIVE { $$ = make_str("insensitive"); }
| INSERT { $$ = make_str("insert"); }
| INSTEAD { $$ = make_str("instead"); }
| KEY { $$ = make_str("key"); }
| LANCOMPILER { $$ = make_str("lancompiler"); }
| LANGUAGE { $$ = make_str("language"); }
+ | LARGE_P { $$ = make_str("large"); }
| LAST_P { $$ = make_str("last"); }
| LEVEL { $$ = make_str("level"); }
| LISTEN { $$ = make_str("listen"); }
| LOCAL { $$ = make_str("local"); }
| LOCATION { $$ = make_str("location"); }
| LOCK_P { $$ = make_str("lock"); }
+ | LOGIN_P { $$ = make_str("login"); }
| MATCH { $$ = make_str("match"); }
| MAXVALUE { $$ = make_str("maxvalue"); }
- | MINUTE_P { $$ = make_str("minute"); }
+/* | MINUTE_P { $$ = make_str("minute"); }*/
| MINVALUE { $$ = make_str("minvalue"); }
| MODE { $$ = make_str("mode"); }
- | MONTH_P { $$ = make_str("month"); }
+/* | MONTH_P { $$ = make_str("month"); }*/
| MOVE { $$ = make_str("move"); }
| NAMES { $$ = make_str("names"); }
- | NATIONAL { $$ = make_str("national"); }
| NEXT { $$ = make_str("next"); }
| NO { $$ = make_str("no"); }
| NOCREATEDB { $$ = make_str("nocreatedb"); }
+ | NOCREATEROLE { $$ = make_str("nocreaterole"); }
| NOCREATEUSER { $$ = make_str("nocreateuser"); }
+ | NOINHERIT { $$ = make_str("noinherit"); }
+ | NOLOGIN_P { $$ = make_str("nologin"); }
+ | NOSUPERUSER { $$ = make_str("nosuperuser"); }
| NOTHING { $$ = make_str("nothing"); }
| NOTIFY { $$ = make_str("notify"); }
+ | NOWAIT { $$ = make_str("nowait"); }
+ | OBJECT_P { $$ = make_str("object"); }
| OF { $$ = make_str("of"); }
| OIDS { $$ = make_str("oids"); }
| OPERATOR { $$ = make_str("operator"); }
| OPTION { $$ = make_str("option"); }
- | OUT_P { $$ = make_str("out"); }
| OWNER { $$ = make_str("owner"); }
| PARTIAL { $$ = make_str("partial"); }
| PASSWORD { $$ = make_str("password"); }
- | PATH_P { $$ = make_str("path"); }
- | PENDANT { $$ = make_str("pendant"); }
- | PRECISION { $$ = make_str("precision"); }
| PREPARE { $$ = make_str("prepare"); }
+ | PREPARED { $$ = make_str("prepared"); }
| PRESERVE { $$ = make_str("preserver"); }
| PRIOR { $$ = make_str("prior"); }
| PRIVILEGES { $$ = make_str("privileges"); }
| PROCEDURAL { $$ = make_str("procedural"); }
| PROCEDURE { $$ = make_str("procedure"); }
+ | QUOTE { $$ = make_str("quote"); }
| READ { $$ = make_str("read"); }
| RECHECK { $$ = make_str("recheck"); }
| REINDEX { $$ = make_str("reindex"); }
| RELATIVE_P { $$ = make_str("relative"); }
+ | RELEASE { $$ = make_str("release"); }
| RENAME { $$ = make_str("rename"); }
+ | REPEATABLE { $$ = make_str("repeatable"); }
| REPLACE { $$ = make_str("replace"); }
| RESET { $$ = make_str("reset"); }
| RESTART { $$ = make_str("restart"); }
| RESTRICT { $$ = make_str("restrict"); }
| RETURNS { $$ = make_str("returns"); }
| REVOKE { $$ = make_str("revoke"); }
+ | ROLE { $$ = make_str("role"); }
| ROLLBACK { $$ = make_str("rollback"); }
| ROWS { $$ = make_str("rows"); }
| RULE { $$ = make_str("rule"); }
+ | SAVEPOINT { $$ = make_str("savepoint"); }
| SCHEMA { $$ = make_str("schema"); }
| SCROLL { $$ = make_str("scroll"); }
- | SECOND_P { $$ = make_str("second"); }
+/* | SECOND_P { $$ = make_str("second"); }*/
| SEQUENCE { $$ = make_str("sequence"); }
| SERIALIZABLE { $$ = make_str("serializable"); }
| SESSION { $$ = make_str("session"); }
| STDIN { $$ = make_str("stdin"); }
| STDOUT { $$ = make_str("stdout"); }
| STORAGE { $$ = make_str("storage"); }
+ | SUPERUSER_P { $$ = make_str("superuser"); }
| STRICT_P { $$ = make_str("strict"); }
+ | SYSTEM_P { $$ = make_str("system"); }
| SYSID { $$ = make_str("sysid"); }
+ | TABLESPACE { $$ = make_str("tablespace"); }
| TEMP { $$ = make_str("temp"); }
| TEMPLATE { $$ = make_str("template"); }
| TEMPORARY { $$ = make_str("temporary"); }
| TRUNCATE { $$ = make_str("truncate"); }
| TRUSTED { $$ = make_str("trusted"); }
| TYPE_P { $$ = make_str("type"); }
+ | UNCOMMITTED { $$ = make_str("uncommitted"); }
| UNENCRYPTED { $$ = make_str("unencrypted"); }
| UNKNOWN { $$ = make_str("unknown"); }
| UNLISTEN { $$ = make_str("unlisten"); }
| UNTIL { $$ = make_str("until"); }
| UPDATE { $$ = make_str("update"); }
- | USAGE { $$ = make_str("usage"); }
| VACUUM { $$ = make_str("vacuum"); }
| VALID { $$ = make_str("valid"); }
| VALUES { $$ = make_str("values"); }
| VARYING { $$ = make_str("varying"); }
- | VERSION { $$ = make_str("version"); }
| VIEW { $$ = make_str("view"); }
| WITH { $$ = make_str("with"); }
| WITHOUT { $$ = make_str("without"); }
| WORK { $$ = make_str("work"); }
| WRITE { $$ = make_str("write"); }
- | YEAR_P { $$ = make_str("year"); }
+/* | YEAR_P { $$ = make_str("year"); }*/
| ZONE { $$ = make_str("zone"); }
;
| EXISTS { $$ = make_str("exists"); }
| EXTRACT { $$ = make_str("extract"); }
| FLOAT_P { $$ = make_str("float"); }
+ | GREATEST { $$ = make_str("greatest"); }
+ | INOUT { $$ = make_str("inout"); }
/* INT must be excluded from ECPGColLabel because of conflict
| INT_P { $$ = make_str("int"); }
*/
| INTEGER { $$ = make_str("integer"); }
| INTERVAL { $$ = make_str("interval"); }
+ | LEAST { $$ = make_str("least"); }
+ | NATIONAL { $$ = make_str("national"); }
| NCHAR { $$ = make_str("nchar"); }
| NONE { $$ = make_str("none"); }
| NULLIF { $$ = make_str("nullif"); }
| NUMERIC { $$ = make_str("numeric"); }
+ | OUT_P { $$ = make_str("out"); }
+ | OVERLAY { $$ = make_str("overlay"); }
| POSITION { $$ = make_str("position"); }
+ | PRECISION { $$ = make_str("precision"); }
| REAL { $$ = make_str("real"); }
| ROW { $$ = make_str("row"); }
| SETOF { $$ = make_str("setof"); }
| FREEZE { $$ = make_str("freeze"); }
| FULL { $$ = make_str("full"); }
| ILIKE { $$ = make_str("ilike"); }
- | IN_P { $$ = make_str("in"); }
| INNER_P { $$ = make_str("inner"); }
| IS { $$ = make_str("is"); }
| ISNULL { $$ = make_str("isnull"); }
| ARRAY { $$ = make_str("array"); }
| AS { $$ = make_str("as"); }
| ASC { $$ = make_str("asc"); }
+ | ASYMMETRIC { $$ = make_str("asymmetric"); }
| BOTH { $$ = make_str("both"); }
| CASE { $$ = make_str("case"); }
| CAST { $$ = make_str("cast"); }
| CURRENT_DATE { $$ = make_str("current_date"); }
| CURRENT_TIME { $$ = make_str("current_time"); }
| CURRENT_TIMESTAMP { $$ = make_str("current_timestamp"); }
+ | CURRENT_ROLE { $$ = make_str("current_role"); }
| CURRENT_USER { $$ = make_str("current_user"); }
| DEFAULT { $$ = make_str("default"); }
| DEFERRABLE { $$ = make_str("deferrable"); }
| GRANT { $$ = make_str("grant"); }
| GROUP_P { $$ = make_str("group"); }
| HAVING { $$ = make_str("having"); }
+ | IN_P { $$ = make_str("in"); }
| INITIALLY { $$ = make_str("initially"); }
| INTERSECT { $$ = make_str("intersect"); }
| INTO { $$ = make_str("into"); }
| SELECT { $$ = make_str("select"); }
| SESSION_USER { $$ = make_str("session_user"); }
| SOME { $$ = make_str("some"); }
+ | SYMMETRIC { $$ = make_str("symmetric"); }
| TABLE { $$ = make_str("table"); }
| THEN { $$ = make_str("then"); }
+/* TO must be excluded from ECPGColLabel because of a conflict in variable name parsing
| TO { $$ = make_str("to"); }
+ */
| TRAILING { $$ = make_str("trailing"); }
| TRUE_P { $$ = make_str("true"); }
/* UNION must be excluded from ECPGColLabel because of conflict with s_union
| c_list { $$ = $1; }
;
-coutputvariable: CVARIABLE indicator
- { add_variable(&argsresult, find_variable($1), find_variable($2)); }
- | CVARIABLE
- { add_variable(&argsresult, find_variable($1), &no_indicator); }
+coutputvariable: cvariable indicator
+ { add_variable_to_head(&argsresult, find_variable($1), find_variable($2)); }
+ | cvariable
+ { add_variable_to_head(&argsresult, find_variable($1), &no_indicator); }
;
-civarind: CVARIABLE indicator
+civarind: cvariable indicator
{
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), find_variable($2));
+ add_variable_to_head(&argsinsert, find_variable($1), find_variable($2));
$$ = create_questionmarks($1, false);
}
;
-civar: CVARIABLE
+civar: cvariable
{
- add_variable(&argsinsert, find_variable($1), &no_indicator);
+ add_variable_to_head(&argsinsert, find_variable($1), &no_indicator);
$$ = create_questionmarks($1, false);
}
;
-indicator: CVARIABLE { check_indicator((find_variable($1))->type); $$ = $1; }
- | SQL_INDICATOR CVARIABLE { check_indicator((find_variable($2))->type); $$ = $2; }
+indicator: cvariable { check_indicator((find_variable($1))->type); $$ = $1; }
+ | SQL_INDICATOR cvariable { check_indicator((find_variable($2))->type); $$ = $2; }
| SQL_INDICATOR name { check_indicator((find_variable($2))->type); $$ = $2; }
;
-ident: IDENT { $$ = $1; }
- | CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
+cvariable: CVARIABLE
+ {
+ /* As long as multidimensional arrays are not implemented we have to check for those here */
+ char *ptr = $1;
+ int brace_open=0, brace = false;
+
+ for (; *ptr; ptr++)
+ {
+ switch (*ptr)
+ {
+ case '[': if (brace)
+ {
+ mmerror(PARSE_ERROR, ET_FATAL, "No multidimensional array support for simple data types");
+ }
+ brace_open++;
+ break;
+ case ']': brace_open--;
+ if (brace_open == 0) brace = true;
+ break;
+ case '\t':
+ case ' ': break;
+ default: if (brace_open == 0) brace = false;
+ break;
+ }
+ }
+
+ $$ = $1;
+ }
+ ;
+ident: IDENT { $$ = $1; }
+ | CSTRING { $$ = make3_str(make_str("\""), $1, make_str("\"")); }
;
quoted_ident_stringvar: name
| S_STATIC { $$ = make_str("static"); }
| S_SUB { $$ = make_str("-="); }
| S_TYPEDEF { $$ = make_str("typedef"); }
+ | S_VOLATILE { $$ = make_str("volatile"); }
| SQL_BOOL { $$ = make_str("bool"); }
| SQL_ENUM { $$ = make_str("enum"); }
| HOUR_P { $$ = make_str("hour"); }
| YEAR_P { $$ = make_str("year"); }
| CHAR_P { $$ = make_str("char"); }
| FLOAT_P { $$ = make_str("float"); }
+ | TO { $$ = make_str("to"); }
| UNION { $$ = make_str("union"); }
| VARCHAR { $$ = make_str("varchar"); }
| '[' { $$ = make_str("["); }