stmtblock: stmtmulti {*((List**)parsetree) = $1; } ; /* the thrashing around here is to discard "empty" statements... */ stmtmulti: stmtmulti ';' stmt { if ($3 != (Node *)NULL) $$ = lappend($1, $3); else $$ = $1; } | stmtmulti ';' error ';' { $$ = $1; yyerrok; } | stmt { if ($1 != (Node *)NULL) $$ = makeList1($1); else $$ = NIL; } ; stmt: LoginStmt | LogoutStmt | EncryptStmt | DecryptStmt | CreateEncryptStmt | DropEncryptStmt | StartEncryptdb | NotifyStmt | ListenStmt | UnlistenStmt | TraceStmt | DisassembleStmt | CreatPolicyStmt | AlterPolicyStmt | DropPolicyStmt | AlterUserPolicyStmt | AlterTabPolicyStmt | AuditStmt | AlterCluStmt | ShutdownStmt | pl_sql_stmt | PrepareStmt | DeallocateStmt | RecompileStmt | EnableStmt | DropSessionStmt | AbortSessionStmt | LoadVocableStmt | CompileVocableStmt | GetLobStmt | AssistantStmt | ConnectPolicyStmt //why 2016-07-28 add | CreateContextStmt //++bysdc@20201003 | DropContextStmt //++bysdc@20201003 | /*empty*/ { $$ = (Node *)NULL; } ; pl_sql_stmt: CreProcedureStmt | PackDecl | PackBody | ClassDeclStmt | ClassBodyDefStmt | AnonyProcedure | sql_stmt ; sql_stmt: AlterSchemaStmt | BackupStmt | ImportStmt | CheckTabStmt | AlterTableStmt | AlterIndexStmt | AlterRoleStmt | AlterUserStmt | AlterspacStmt | OpenCursorStmt | CloseCursorStmt | CreateTabStmt | CreateAsStmt | CreateSchemaStmt | CreateRoleStmt | CreateSeqStmt | AlterSeqStmt | CreateTrigStmt | CreateUserStmt | ClusterStmt | AnalyzeStmt | DropTabStmt | DropViewStmt | DropSeqStmt | DropIdxStmt | DropSchemaStmt | DropspacStmt | DropProcedureStmt | DropPackStmt | DropTypeStmt | TruncateStmt | DropRoleStmt | DropTrigStmt | DropUserStmt | ExtendStmt | ExplainStmt | FetchStmt | GrantStmt | IndexStmt | LockStmt | ReindexStmt | RenameStmt | RevokeStmt | dml_stmt | CursorStmt | TransactionStmt | ViewStmt | LoadStmt | CreatedbStmt | CreatespacStmt | DropdbStmt | VacuumStmt | CreateLinkStmt | DropLinkStmt | CreateSynonymStmt | DropSynonymStmt | CreateMViewStmt | DropMViewStmt | CreateDirStmt | ShowDirStmt | ConstraintsSetStmt | CheckPointStmt | VariableSetStmt | VariableShowStmt | CallPrepareStmt | ExecuteStmt | CreateDomainStmt | AlterDomainStmt | DropDomainStmt | CommentStmt | FlashBackStmt /*why 2019-03-25 add*/ | CreateProfileStmt//++bysdc@20200415 | filter_where_clause//++bysdc@20201003 ; pl_stmt: VarAssign | IfElseStmt | LoopStmt | ForStmt | ForallStmt | ThrowStmt | CaseStmt | GotoStmt | BreakStmt | ContinueStmt | ReturnStmt | _NULL ';' { $$ = (Node*)makeNode(NullStmt); SetNodePos($$); } | sql_stmt ';' { $$ = $1; SetNodePos($$); } | StmtBlock | StmtBlock ';' { $$ = $1; } | error ';' { $$ = (Node*)makeNode(NullStmt); SetNodePos($$); yyerrok; } ; /* define or redefine package or procedure or function */ Cre_Rep: CREATE { $$ = 0; } | CREATE NOFORCE { $$ = 0; } | CREATE FORCE { $$ = 2; } | CREATE OR REPLACE { $$ = 1; } | CREATE OR REPLACE NOFORCE { $$ = 1; } | CREATE OR REPLACE FORCE { $$ = 3; } ; Is_As: IS{} | AS{} ; /* maintenace node online an offline */ AlterCluStmt: ALTER CLUSTER ADD NODE ICONST DESCRIBE Sconst { AlterCluStmt *p_stmt = makeNode(AlterCluStmt); p_stmt->action = 1; p_stmt->node_id = $5; p_stmt->describe = $7; $$ = (Node*)p_stmt; SetNodePos($$); } | ALTER CLUSTER ADD NODE ICONST DESCRIBE IDENT { AlterCluStmt *p_stmt = makeNode(AlterCluStmt); p_stmt->action = 1; p_stmt->node_id = $5; p_stmt->describe = $7; $$ = (Node*)p_stmt; SetNodePos($$); } | ALTER CLUSTER SET NODE ICONST OFFLINE { AlterCluStmt *p_stmt = makeNode(AlterCluStmt); p_stmt->action = 2; p_stmt->node_id = $5; $$ = (Node*)p_stmt; SetNodePos($$); } | ALTER CLUSTER DROP NODE ICONST { AlterCluStmt *p_stmt = makeNode(AlterCluStmt); p_stmt->action = 3; p_stmt->node_id = $5; $$ = (Node*)p_stmt; SetNodePos($$); } ; /* shutdown database */ ShutdownStmt: SHUTDOWN { ShutdownStmt *p_stmt = makeNode(ShutdownStmt); $$ = (Node*)p_stmt; } | SHUTDOWN RESTART { ShutdownStmt *p_stmt = makeNode(ShutdownStmt); p_stmt->b_restart = true; $$ = (Node*)p_stmt; } | SHUTDOWN IMMEDIATE { ShutdownStmt *p_stmt = makeNode(ShutdownStmt); p_stmt->b_immediate = true; $$ = (Node*)p_stmt; } | SHUTDOWN RESTART IMMEDIATE { ShutdownStmt *p_stmt = makeNode(ShutdownStmt); p_stmt->b_restart = true; p_stmt->b_immediate = true; $$ = (Node*)p_stmt; } ; /* ++bysdc@20201003 */ CreateContextStmt: Cre_Rep _CONTXT name_space USING name_space { CreateContextStmt *p_stmt = makeNode(CreateContextStmt); p_stmt->cre_mode = $1; p_stmt->ctx_name = $3; p_stmt->pack_name = $5; p_stmt->inited_mode = 0; p_stmt->accessed_mode = 0; $$ = (Node*)p_stmt; SetNodePos($$); } ; DropContextStmt: DROP _CONTXT name_space { DropStmt *p_stmt = makeNode(DropStmt); p_stmt->obj_name = $3; p_stmt->drop_type = DROP_CONTEXT; $$ = (Node*)p_stmt; SetNodePos($$); } ; //end /******************************************************************************* * * Package declare * *********************************************************************************/ PackDecl: Cre_Rep PACKAGE name_space opt_authid opt_comment Is_As PackSpecs _END { PackDecl *p_stmt = makeNode(PackDecl); p_stmt->cre_mode = $1; p_stmt->pack_name = $3; p_stmt->def_list = $7; p_stmt->auth_type = $4; p_stmt->comments = $5; $$ = (Node*)p_stmt; SetNodePos($$); } | Cre_Rep PACKAGE name_space opt_authid opt_comment Is_As PackSpecs _END name_space { PackDecl *p_stmt = makeNode(PackDecl); p_stmt->cre_mode = $1; p_stmt->pack_name = $3; p_stmt->def_list = $7; p_stmt->auth_type = $4; p_stmt->comments = $5; $$ = (Node*)p_stmt; SetNodePos($$); } ; PackSpecs: PackSpecItem { $$ = makeList1($1); } | PackSpecs PackSpecItem { if($2) $$ = lappend($1,$2); else $$ = $1; } ; PackSpecItem: VarDef ';' | ProcDecl ';' { $$ = $1; } ; pragmas: TokenId { $$ = makeList1($1); } | pragmas ',' TokenId { $$ = lappend($1,$3); } ; opt_comment: /*empty*/ { $$ = NULL; } | COMMENT SCONST { $$ = $2; } ; DropPackStmt: DROP PACKAGE name_space alter_behavior { DropStmt *p_stmt = makeNode(DropStmt); p_stmt->obj_name = $3; p_stmt->drop_type = DROP_PACKAGE; p_stmt->behavior = ($4==CASCADE? OP_CASCADE : OP_RESTRICT); $$ = (Node*)p_stmt; SetNodePos($$); } ; /************************************************************************ * * Package boby * *************************************************************************/ PackBody: Cre_Rep PACKAGE BODY name_space Is_As optVarDefList PackMemberProcs opt_pack_inits OptExceptionStmt _END opt_name_space { PackBody *p_stmt = makeNode(PackBody); p_stmt->cre_mode = $1; p_stmt->name = $4; p_stmt->member_var_list = $6; p_stmt->member_proc_list = $7; p_stmt->init_stmt_list = $8; p_stmt->exception_list = $9; if($11!=NULL && (astrlen($4)cre_mode = $1; p_stmt->udt_type = TYPE_OBJECT; p_stmt->udt_name = $3; p_stmt->def_list = $8; p_stmt->flags = $10; p_stmt->auth_type = $4; p_stmt->comments = $11; $$ = (Node*)p_stmt; SetNodePos($$); } | Cre_Rep TYPE name_space opt_authid UNDER name_space '(' member_decls ')' opt_class_flags opt_comment { UdtDecl *p_stmt = makeNode(UdtDecl); p_stmt->cre_mode = $1; p_stmt->udt_type = TYPE_OBJECT; p_stmt->udt_name = $3; p_stmt->super_name = $6; p_stmt->def_list = $8; p_stmt->flags = $10; p_stmt->auth_type = $4; p_stmt->comments = $11; $$ = (Node*)p_stmt; SetNodePos($$); } | Cre_Rep TYPE name_space opt_authid Is_As VARRAY '(' ICONST ')' OF TypeName opt_comment { UdtDecl *p_stmt = makeNode(UdtDecl); p_stmt->cre_mode = $1; p_stmt->udt_type = TYPE_VARRAY; p_stmt->udt_name = $3; p_stmt->varray_num = $8; p_stmt->base_type= $11; p_stmt->auth_type = $4; p_stmt->comments = $12; $$ = (Node*)p_stmt; SetNodePos($$); } | Cre_Rep TYPE name_space opt_authid Is_As TABLE OF TypeName opt_comment { UdtDecl *p_stmt = makeNode(UdtDecl); p_stmt->cre_mode = $1; p_stmt->udt_type = TYPE_TABLE; p_stmt->udt_name = $3; p_stmt->base_type = $8; p_stmt->auth_type = $4; p_stmt->comments = $9; $$ = (Node*)p_stmt; SetNodePos($$); } ; opt_authid: /**/ { $$ = 0; } | AUTHID DEFAULT { $$ = 0; } | AUTHID ColId { if(!astricmp($2,"CURRENT_USER")) $$ = 2; else if(!astricmp($2,"DEFINER")) $$ = 1; else add_parse_error(987); } | AUTHID USER { $$ = 2; } ; member_decls: member_decl { $$ = makeList1($1); } | member_decls ',' member_decl { $$ = lappend($1,$3); } ; member_decl: MemberVarDecl { $$ = $1; } | MemberFuncDecl { $$ = $1; } ; MemberVarDecl: ColId opt_constant TypeName opt_not_null { VarDef *p_item = makeNode(VarDef); p_item->var_name = $1; p_item->is_constant = $2; p_item->type_nam = (Typenam*)$3; p_item->not_null = $4; $$ = (Node*)p_item; SetNodePos($$); } | ColId opt_constant TypeName opt_not_null DEFAULT b_expr { VarDef *p_item = makeNode(VarDef); p_item->var_name = $1; p_item->is_constant = $2; p_item->type_nam = (Typenam*)$3; p_item->not_null = $4; p_item->def_val = $6; $$ = (Node*)p_item; SetNodePos($$); } | ColId opt_constant TypeName opt_not_null ASSIGN b_expr { VarDef *p_item = makeNode(VarDef); p_item->var_name = $1; p_item->is_constant = $2; p_item->type_nam = (Typenam*)$3; p_item->not_null = $4; p_item->def_val = $6; $$ = (Node*)p_item; SetNodePos($$); } ; MemberFuncDecl: CONSTRUCTOR ProcDecl { ((ProcDecl*)$2)->scope = 1; $$ = $2; SetNodePos($$); } | STATIC ProcDecl { ((ProcDecl*)$2)->scope = 2; $$ = $2; SetNodePos($$); } | MEMBER ProcDecl { ((ProcDecl*)$2)->scope = 4; $$ = $2; SetNodePos($$); } ; opt_class_flags: /**/ { $$ = 0; } | class_flags { $$ = $1; } ; class_flags: class_flag { $$ = $1; } | class_flags class_flag { $$ = $1 | $2; } ; class_flag: FINAL { $$ = 1; } | NOT FINAL { $$ = 0; } | INSTANTIABLE { $$ = 0; } | NOT INSTANTIABLE { $$ = 2; } ; /************************************************************************* * * UDT(User define Data type) body * **************************************************************************/ ClassBodyDefStmt: Cre_Rep TYPE BODY name_space Is_As MemberFuncDefs _END opt_name_space { UdtBody *p_stmt = makeNode(UdtBody); p_stmt->cre_mode = $1; p_stmt->udt_name = $4; p_stmt->member_procs = $6; $$ = (Node*)p_stmt; SetNodePos($$); } ; MemberFuncDefs: MemberFuncDef ';' { $$ = makeList1($1); } | MemberFuncDefs MemberFuncDef ';' { $$ = lappend($1,$2); } ; MemberFuncDef: CONSTRUCTOR ProcDef { ((ProcDef*)$2)->scope = 1; $$ = $2; SetNodePos($$); } | STATIC ProcDef { ((ProcDef*)$2)->scope = 2; $$ = $2; SetNodePos($$); } | MEMBER ProcDef { ((ProcDef*)$2)->scope = 4; $$ = $2; SetNodePos($$); } ; DropTypeStmt: DROP TYPE name_space alter_behavior { DropStmt *p_stmt = makeNode(DropStmt); p_stmt->obj_name = $3; p_stmt->drop_type = DROP_TYPE; p_stmt->behavior = ($4==CASCADE? OP_CASCADE : OP_RESTRICT); $$ = (Node*)p_stmt; SetNodePos($$); } ; /******************************************************************************* * Create Domain... ********************************************************************************/ CreateDomainStmt: CREATE opt_global _DOMAIN_ name_space opt_as TypeName opt_domain_constraints opt_comment { CreateDomainStmt *n = makeNode(CreateDomainStmt); n->is_global = $2; n->domain_name = $4; n->type_nam = (Typenam*)$6; n->constraints = $7; n->comment = $8; $$ = (Node *)n; SetNodePos($$); } ; opt_global: /*empty*/ { $$ = false; } | LOCAL { $$ = false; } | GLOBAL { $$ = true; } ; opt_as: /*empty*/ | AS{} | IS{} ; opt_domain_constraints: /*empty*/ { $$ = NIL; } | domain_constraints { $$ = $1; } ; domain_constraints: domain_constraint { $$ = makeList1($1); } | domain_constraints domain_constraint { $$ = lappend($1,$2); } ; domain_constraint: _NULL { ConstraintDef *n = makeNode(ConstraintDef); n->contype = CONSTR_NULL; n->enable = true; $$ = (Node *)n; SetNodePos($$); } | NOT _NULL { ConstraintDef *n = makeNode(ConstraintDef); n->contype = CONSTR_NOTNULL; n->enable = true; $$ = (Node *)n; SetNodePos($$); } | DEFAULT b_expr { ConstraintDef *n = makeNode(ConstraintDef); n->contype = CONSTR_DEFAULT; n->constr_name = (char*)NULL; if (exprIsNullConstant($2)) { n->raw_expr = (Node*)NULL; } else { n->raw_expr = $2; } n->cooked_expr = (char*)NULL; n->keys = (List*)NULL; n->enable = true; $$ = (Node *)n; SetNodePos($$); } | CHECK '(' bool_expr ')' { ConstraintDef *n = makeNode(ConstraintDef); n->contype = CONSTR_CHECK; n->constr_name = (char*)NULL; n->raw_expr = $3; n->cooked_expr = (char*)NULL; n->keys = (List*)NULL; n->enable = true; $$ = (Node *)n; SetNodePos($$); } | CONSTRAINT name CHECK '(' bool_expr ')' { ConstraintDef *n = makeNode(ConstraintDef); n->contype = CONSTR_CHECK; n->constr_name = (char*)$2; n->raw_expr = $5; n->cooked_expr = (char*)NULL; n->keys = (List*)NULL; n->enable = true; $$ = (Node *)n; SetNodePos($$); } ; /******************************************************************************* * Alter DOMAIN statement *******************************************************************************/ AlterDomainStmt: ALTER _DOMAIN_ name_space SET DEFAULT b_expr { AlterDomainStmt *n = makeNode(AlterDomainStmt); n->alter_type = ADD_DOMAIN_DEF_VAL; n->domain_name = $3; n->def_val = $6; $$ = (Node *)n; SetNodePos($$); } | ALTER _DOMAIN_ name_space DROP DEFAULT { AlterDomainStmt *n = makeNode(AlterDomainStmt); n->alter_type = DROP_DOMAIN_DEF_VAL; n->domain_name = $3; $$ = (Node *)n; SetNodePos($$); } | ALTER _DOMAIN_ name_space SET NOT _NULL { AlterDomainStmt *n = makeNode(AlterDomainStmt); n->alter_type = SET_DOMAIN_NOTNULL; n->domain_name = $3; $$ = (Node *)n; SetNodePos($$); } | ALTER _DOMAIN_ name_space SET _NULL { AlterDomainStmt *n = makeNode(AlterDomainStmt); n->alter_type = DROP_DOMAIN_NOTNULL; n->domain_name = $3; $$ = (Node *)n; SetNodePos($$); } | ALTER _DOMAIN_ name_space DROP NOT _NULL { AlterDomainStmt *n = makeNode(AlterDomainStmt); n->alter_type = DROP_DOMAIN_NOTNULL; n->domain_name = $3; $$ = (Node *)n; SetNodePos($$); } | ALTER _DOMAIN_ name_space ADD CHECK '(' bool_expr ')' alter_behavior { AlterDomainStmt *n = makeNode(AlterDomainStmt); ConstraintDef *cons = makeNode(ConstraintDef); n->constraint = (Node*)cons; n->alter_type = ADD_DOMAIN_CONSTRAINT; n->domain_name = $3; n->constraint_name = NULL; n->alter_behavier = $9; cons->contype = CONSTR_CHECK; cons->constr_name = (char*)NULL; cons->raw_expr = $7; cons->cooked_expr = (char*)NULL; cons->keys = (List*)NULL; cons->enable = true; $$ = (Node *)n; SetNodePos($$); } | ALTER _DOMAIN_ name_space ADD CONSTRAINT name CHECK '(' bool_expr ')' alter_behavior { AlterDomainStmt *n = makeNode(AlterDomainStmt); ConstraintDef *cons = makeNode(ConstraintDef); n->constraint = (Node*)cons; n->alter_type = ADD_DOMAIN_CONSTRAINT; n->domain_name = $3; n->constraint_name = $6; n->alter_behavier = $11; cons->contype = CONSTR_CHECK; cons->constr_name = (char*)$6; cons->raw_expr = $9; cons->cooked_expr = (char*)NULL; cons->keys = (List*)NULL; cons->enable = true; $$ = (Node *)n; SetNodePos($$); } | ALTER _DOMAIN_ name_space DROP CONSTRAINT name alter_behavior { AlterDomainStmt *n = makeNode(AlterDomainStmt); n->alter_type = DROP_DOMAIN_CONSTRAINT; n->domain_name = $3; n->constraint_name = $6; n->alter_behavier = $7; $$ = (Node *)n; SetNodePos($$); } | ALTER _DOMAIN_ name_space OWNER TO UserId { AlterDomainStmt *n = makeNode(AlterDomainStmt); n->alter_type = SET_DOMAIN_OWNER; n->domain_name = $3; n->new_owner = $6; } ; /******************************************************************************* * * Drop DOMAIN statement * *******************************************************************************/ DropDomainStmt: DROP _DOMAIN_ name_space alter_behavior { DropDomainStmt *n = makeNode(DropDomainStmt); n->domain_name = $3; n->drop_behavior = $4; $$ = (Node *)n; SetNodePos($$); } ; /******************************************************************************* * COMMENT statement *******************************************************************************/ CommentStmt: COMMENT ON obj_type name_space IS Sconst { CommentStmt *n = makeNode(CommentStmt); n->objtype = $3; n->objname = $4; n->comment = $6; $$ = (Node *)n; SetNodePos($$); } | COMMENT ON COLUMN name_space IS Sconst { CommentStmt *n = makeNode(CommentStmt); n->objtype = OBJ_TYPE_COL; n->objname = $4; n->comment = $6; $$ = (Node *)n; SetNodePos($$); } ; /******************************************************************************* * Create procedure statement *******************************************************************************/ CreProcedureStmt: Cre_Rep ProcDef { CreProcedureStmt *p_stmt = makeNode(CreProcedureStmt); p_stmt->cre_mode = $1; p_stmt->language = "PLSQL"; p_stmt->define = (ProcDef*)$2; $$ = (Node*)p_stmt; SetNodePos($$); } | ProcDef { CreProcedureStmt *p_stmt = makeNode(CreProcedureStmt); p_stmt->language = "PLSQL"; p_stmt->define = (ProcDef*)$1; $$ = (Node*)p_stmt; SetNodePos($$); } ; /******************************************************************************* * Procedure(Function) declaration *******************************************************************************/ ProcDecl: FUNCTION name_space func_args RETURN TypeName opt_authid opt_proc_flags { ProcDecl *p_decl =makeNode(ProcDecl); p_decl->func_name = $2; p_decl->fparam_list = $3; p_decl->ret_type = (Typenam*)$5; p_decl->auth_type = $6; $$ = (Node*)p_decl; SetNodePos($$); } | FUNCTION name_space func_args RETURN SELF AS RESULT opt_authid opt_proc_flags { ProcDecl *p_decl =makeNode(ProcDecl); p_decl->func_name = $2; p_decl->fparam_list = $3; p_decl->scope = 1; p_decl->ret_type = NULL; p_decl->auth_type = $8; $$ = (Node*)p_decl; SetNodePos($$); } | PROCEDURE name_space func_args opt_authid opt_proc_flags { ProcDecl *p_decl =makeNode(ProcDecl); p_decl->func_name = $2; p_decl->fparam_list = $3; p_decl->auth_type = $4; $$ = (Node*)p_decl; SetNodePos($$); } ; func_args: '(' func_args_list ')' { $$ = $2; } | '(' ')' { $$ = NIL; } | { $$ = NIL; } ; func_args_list: FuncArg { $$ = makeList1($1); } | func_args_list ',' FuncArg { $$ = lappend($1, $3); } ; FuncArg: ColLabel in_out TypeName { FuncArg *p_arg = makeNode(FuncArg); p_arg->name = $1; p_arg->in_out = $2; p_arg->type_nam = (Typenam*)$3; $$ = (Node*)p_arg; SetNodePos($$); } | ColLabel TypeName { FuncArg *p_arg = makeNode(FuncArg); p_arg->name = $1; p_arg->in_out = 1; p_arg->type_nam = (Typenam*)$2; $$ = (Node*)p_arg; SetNodePos($$); } | ColLabel in_out TypeName ASSIGN b_expr { FuncArg *p_arg = makeNode(FuncArg); p_arg->name = $1; p_arg->in_out = $2; p_arg->type_nam = (Typenam*)$3; p_arg->def_val = (A_Expr*)$5; $$ = (Node*)p_arg; SetNodePos($$); } | ColLabel TypeName ASSIGN b_expr { FuncArg *p_arg = makeNode(FuncArg); p_arg->name = $1; p_arg->in_out = 1; p_arg->type_nam = (Typenam*)$2; p_arg->def_val = (A_Expr*)$4; $$ = (Node*)p_arg; SetNodePos($$); } | ColLabel in_out TypeName DEFAULT b_expr { FuncArg *p_arg = makeNode(FuncArg); p_arg->name = $1; p_arg->in_out = $2; p_arg->type_nam = (Typenam*)$3; p_arg->def_val = (A_Expr*)$5; $$ = (Node*)p_arg; SetNodePos($$); } | ColLabel TypeName DEFAULT b_expr { FuncArg *p_arg = makeNode(FuncArg); p_arg->name = $1; p_arg->in_out = 1; p_arg->type_nam = (Typenam*)$2; p_arg->def_val = (A_Expr*)$4; $$ = (Node*)p_arg; SetNodePos($$); } ; in_out: _IN { $$ = 1; } | _OUT { $$ = 2; } | _IN _OUT { $$ = 3; } ; opt_proc_flags: /*empty*/ { $$ = 0; } | DETERMINISTIC { $$ = 1; } ; /******************************************************************************* * * procedure or function define * *******************************************************************************/ ProcDef: ProcDecl opt_comment Is_As LANGUAGE TokenId NAME ColId LIBRARY name_space opt_with_context PARAMETERS '(' oci_parameters ')' { ProcDef *p_def = makeNode(ProcDef); p_def->comments = $2; p_def->language = $5; p_def->func_name = ((ProcDecl*)$1)->func_name; p_def->fparam_list = ((ProcDecl*)$1)->fparam_list; p_def->ret_type = ((ProcDecl*)$1)->ret_type; p_def->auth_type = ((ProcDecl*)$1)->auth_type; p_def->native_name = $7; p_def->library = $9; p_def->with_context = $10; p_def->oci_parameter = $13; $$ = (Node*)p_def; SetNodePos($$); } | ProcDecl opt_comment Is_As LANGUAGE TokenId NAME ColId { ProcDef *p_def = makeNode(ProcDef); p_def->comments = $2; p_def->language = $5; p_def->func_name = ((ProcDecl*)$1)->func_name; p_def->fparam_list = ((ProcDecl*)$1)->fparam_list; p_def->ret_type = ((ProcDecl*)$1)->ret_type; p_def->auth_type = ((ProcDecl*)$1)->auth_type; p_def->native_name = $7; $$ = (Node*)p_def; SetNodePos($$); } | ProcDecl opt_comment Is_As optVarDefList StmtBlock opt_name_space { ProcDef *p_def = makeNode(ProcDef); p_def->func_name = ((ProcDecl*)$1)->func_name; p_def->comments = $2; if( $6!=NULL && (astrlen(p_def->func_name)func_name+astrlen(p_def->func_name)-astrlen($6),$6))) { SetParsePos(); add_parse_error(576,p_def->func_name,$6); } p_def->fparam_list = ((ProcDecl*)$1)->fparam_list; p_def->ret_type = ((ProcDecl*)$1)->ret_type; p_def->auth_type = ((ProcDecl*)$1)->auth_type; p_def->var_def_list = $4; p_def->stmt_list = ((StmtBlock*)$5)->stmt_list; p_def->sub_proc_list = ((StmtBlock*)$5)->sub_proc_list; p_def->exception_list = ((StmtBlock*)$5)->exception_list; ((StmtBlock*)$5)->exception_list = NIL; $$ = (Node*)p_def; SetNodePos($$); } ; opt_with_context: /*empty*/ { $$ = false; } | WITH _CONTXT { $$ = true; } ; oci_parameters: oci_parameter { $$ = makeList1($1); } | oci_parameters ',' oci_parameter { $$ = lappend($1,$3); } ; oci_parameter: _CONTXT { OciArg *p_arg = makeNode(OciArg); p_arg->name = "CONTXT"; p_arg->arg_type = OCI_CONTEXT; p_arg->type_nam = NULL; $$ = (Node*)p_arg; SetNodePos($$); } | ColLabel TypeName { OciArg *p_arg = makeNode(OciArg); p_arg->name = $1; p_arg->arg_type = OCI_PARAMETER; p_arg->type_nam = (Typenam*)$2; $$ = (Node*)p_arg; SetNodePos($$); } | ColLabel INDICATOR TypeName { OciArg *p_arg = makeNode(OciArg); p_arg->name = $1; p_arg->arg_type = OCI_INDICATOR; p_arg->type_nam = (Typenam*)$3; $$ = (Node*)p_arg; SetNodePos($$); } | ColLabel LENGTH TypeName { OciArg *p_arg = makeNode(OciArg); p_arg->name = $1; p_arg->arg_type = OCI_LENGTH; p_arg->type_nam = (Typenam*)$3; $$ = (Node*)p_arg; SetNodePos($$); } ; AnonyProcedure: DECLARE VarDefList StmtBlock { ProcDef *p_def = makeNode(ProcDef); p_def->var_def_list = $2; p_def->stmt_list = ((StmtBlock *)$3)->stmt_list; p_def->exception_list = ((StmtBlock *)$3)->exception_list; ((StmtBlock *)$3)->exception_list = NIL; $$ = (Node*)p_def; SetNodePos($$); } | DECLARE StmtBlock { ProcDef *p_def = makeNode(ProcDef); p_def->var_def_list = NIL; p_def->stmt_list = ((StmtBlock *)$2)->stmt_list; p_def->exception_list = ((StmtBlock *)$2)->exception_list; ((StmtBlock *)$2)->exception_list = NIL; $$ = (Node*)p_def; SetNodePos($$); } | StmtBlock { ProcDef *p_def = makeNode(ProcDef); p_def->stmt_list = ((StmtBlock *)$1)->stmt_list; p_def->exception_list = ((StmtBlock *)$1)->exception_list; ((StmtBlock *)$1)->exception_list = NIL; $$ = (Node*)p_def; SetNodePos($$); } ; /******************************************************************************* * * drop procedure or function * *******************************************************************************/ DropProcedureStmt: DROP PROCEDURE name_space alter_behavior { DropStmt *p_stmt = makeNode(DropStmt); p_stmt->obj_name = $3; p_stmt->drop_type = DROP_PROCEDURE; p_stmt->behavior = ($4==CASCADE? OP_CASCADE : OP_RESTRICT); $$ = (Node*)p_stmt; SetNodePos($$); } | DROP FUNCTION name_space alter_behavior { DropStmt *p_stmt = makeNode(DropStmt); p_stmt->obj_name = $3; p_stmt->drop_type = DROP_PROCEDURE; p_stmt->behavior = ($4==CASCADE? OP_CASCADE : OP_RESTRICT); $$ = (Node*)p_stmt; SetNodePos($$); } ; /************************************************************************************** * sql block ***************************************************************************************/ StmtBlock: _BEGIN pl_stmt_list OptExceptionStmt _END { StmtBlock *p_body = makeNode(StmtBlock); p_body->stmt_list = $2; p_body->exception_list = $3; $$ = (Node*)p_body; SetNodePos($$); } ; /* exception sql define */ OptExceptionStmt: /*empty*/ { $$ = NULL; } | EXCEPTION Exceptions { $$ = $2; } | EXCEPTION Exceptions FINALLY pl_stmt_list { Exception_Item *p_item = makeNode(Exception_Item); p_item->err_name = NULL; p_item->stmt_list = $4; $$ = lappend($2,p_item); } ; Exceptions: Exception_Item { $$ = makeList1($1); } | Exceptions Exception_Item { $$ = lappend($1,$2); } ; Exception_Item: WHEN ColId THEN pl_stmt_list { Exception_Item *p_item = makeNode(Exception_Item); p_item->err_name = $2; p_item->stmt_list = $4; $$ = (Node*)p_item; SetNodePos($$); } | WHEN ICONST THEN pl_stmt_list { Exception_Item *p_item = makeNode(Exception_Item); p_item->err_code = $2; p_item->stmt_list = $4; $$ = (Node*)p_item; SetNodePos($$); } ; /***************************************************************************** * * var define * ******************************************************************************/ optVarDefList: VarDefList { $$ = $1; } | DECLARE VarDefList { $$ = $2; } | /*empty*/ { $$ = NIL; } ; VarDefList: VarDef ';' { if($1) $$ = makeList1($1); else $$ = NIL; } | VarDefList VarDef ';' { if($1 && $2) $$ = lappend($1,$2); else if($1==NIL && $2==NULL) $$ = NIL; else if($1==NIL) $$ = makeList1($2); else if($2==NULL) $$ = $1; } ; /* exception num define */ ExceptionDef: TokenId EXCEPTION { ExceptionDef *p_stmt = makeNode(ExceptionDef); p_stmt->exception_name = $1; p_stmt->exception_no = -1; /*-1:define by compiler , used in current function*/ $$ = (Node*)p_stmt; SetNodePos($$); }; | TokenId EXCEPTION integer { ExceptionDef *p_stmt = makeNode(ExceptionDef); p_stmt->exception_name = $1; p_stmt->exception_no = ABS($3) ; //bywsy@20210121 feature170 $$ = (Node*)p_stmt; SetNodePos($$); }; /*define type*/ TypeDefStmt: TYPE_SUBTYPE ColId IS TypeName opt_not_null { TypeDef *p_node = makeNode(TypeDef); p_node->type_name = $2; p_node->base_type = (Typenam*)$4; p_node->not_null = $5; $$ = (Node*)p_node; SetNodePos($$); } ; TYPE_SUBTYPE: TYPE{} | SUBTYPE {}; /*define single var*/ VarDef: TokenId opt_constant TypeName opt_not_null { VarDef *p_item = makeNode(VarDef); p_item->var_name = $1; p_item->is_constant = $2; p_item->type_nam = (Typenam*)$3; p_item->not_null = $4; $$ = (Node*)p_item; SetNodePos($$); } | TokenId opt_constant TypeName opt_not_null DEFAULT b_expr { VarDef *p_item = makeNode(VarDef); p_item->var_name = $1; p_item->is_constant = $2; p_item->type_nam = (Typenam*)$3; p_item->not_null = $4; p_item->def_val = $6; $$ = (Node*)p_item; SetNodePos($$); } | TokenId opt_constant TypeName opt_not_null ASSIGN opt_default b_expr { VarDef *p_item = makeNode(VarDef); p_item->var_name = $1; p_item->is_constant = $2; p_item->type_nam = (Typenam*)$3; p_item->not_null = $4; p_item->def_val = $7; $$ = (Node*)p_item; SetNodePos($$); } | CursorDef | ExceptionDef | TypeDefStmt | PRAGMA EXCEPTION_INIT '(' TokenId ',' integer ')'//bywsy@202210128 feature170 add { Pragma *n = makeNode(Pragma); Exception_Item *p_item = makeNode(Exception_Item); p_item->err_name = $4; p_item->err_code = ABS($6); n->name = $2; n->args = makeList1(p_item); $$ = (Node*)n; SetNodePos($$); } | PRAGMA TokenId { Pragma *n = makeNode(Pragma); n->name = $2; $$ = (Node*)n; SetNodePos($$); } | PRAGMA TokenId '(' pragmas ')' { Pragma *n = makeNode(Pragma); n->name = $2; n->args = $4; $$ = (Node*)n; SetNodePos($$); } ; /*define cursor */ CursorDef: CURSOR name func_args Is_As SelectStmt parallel_opt opt_wait { CursorDef *p_def = makeNode(CursorDef); p_def->var_name = $2; p_def->args = $3; p_def->cur_type = CUR_INSENSITIVE; ((SelectStmt*)$5)->parallel = $6; ((SelectStmt*)$5)->wait_ms = $7; p_def->define = (SelectStmt*)$5; $$ = (Node*)p_def; SetNodePos($$); }; opt_constant: { $$ = false; } | CONSTANT { $$ = true; } ; opt_not_null: { $$ = false; } | NOT _NULL { $$ = true; } ; opt_default: | DEFAULT {} ; /********************************************************************** * PL SQL sets **********************************************************************/ pl_stmt_list: pl_stmt_line { $$ = makeList1($1); } | pl_stmt_list pl_stmt_line { $$ = lappend($1,$2); } ; /********************************************************************** * PL SQL line **********************************************************************/ pl_stmt_line: pl_stmt { $$ = $1; } | '<' '<' ColId '>' '>' pl_stmt { LabelStmt *p_label = makeNode(LabelStmt); p_label->label = $3; p_label->stmt = $6; $$ = (Node*)p_label; SetNodePos($$); } | ColId ':' pl_stmt { LabelStmt *p_label = makeNode(LabelStmt); p_label->label = $1; p_label->stmt = $3; $$ = (Node*)p_label; SetNodePos($$); } ; /********************************************************************** * assign sql ***********************************************************************/ VarAssign: ident ASSIGN b_expr ';' { VarAssign *p_assign = makeNode(VarAssign); p_assign->var = (Ident*)$1; p_assign->value = $3; $$ = (Node*)p_assign; SetNodePos($$); } | SET ident '=' b_expr ';' { VarAssign *p_assign = makeNode(VarAssign); p_assign->var = (Ident*)$2; p_assign->value = $4; $$ = (Node*)p_assign; SetNodePos($$); } ; IfElseStmt: IF bool_expr THEN pl_stmt_list ELSE pl_stmt_list EndIf ';' { IfElseStmt *p_if = makeNode(IfElseStmt); p_if->t_cond = $2; p_if->t_stmt_list = $4; p_if->elsif_list = NIL; p_if->f_stmt_list = $6; $$ = (Node*)p_if; SetNodePos($$); } | IF bool_expr THEN pl_stmt_list EndIf ';' { IfElseStmt *p_if = makeNode(IfElseStmt); p_if->t_cond = $2; p_if->t_stmt_list = $4; $$ = (Node*)p_if; SetNodePos($$); } | IF bool_expr THEN pl_stmt_list Else_list EndIf ';' { IfElseStmt *p_if = makeNode(IfElseStmt); p_if->t_cond = $2; p_if->t_stmt_list = $4; p_if->elsif_list = $5; $$ = (Node*)p_if; SetNodePos($$); } | IF bool_expr THEN pl_stmt_list Else_list ELSE pl_stmt_list EndIf ';' { IfElseStmt *p_if = makeNode(IfElseStmt); p_if->t_cond = $2; p_if->t_stmt_list = $4; p_if->elsif_list = $5; p_if->f_stmt_list = $7; $$ = (Node*)p_if; SetNodePos($$); } ; EndIf: _END IF {} | ENDIF {} |_END IF name_space {} | ENDIF name_space {} ; Else_list: ElsIfItem { $$ = makeList1($1); } | Else_list ElsIfItem { $$ = lappend($1,$2); } ; ElsIfItem: ELSIF bool_expr THEN pl_stmt_list { ElsIfItem *p_item = makeNode(ElsIfItem); p_item->cond = $2; p_item->stmt_list = $4; $$ = (Node*)p_item; SetNodePos($$); } ; LoopStmt: WHILE bool_expr LOOP pl_stmt_list EndLoop ';' { LoopStmt *p_loop = makeNode(LoopStmt); p_loop->cond = $2; p_loop->stmt_list = $4; $$ = (Node*)p_loop; SetNodePos($$); } | WHERE bool_expr LOOP pl_stmt_list EndLoop ';' { LoopStmt *p_loop = makeNode(LoopStmt); p_loop->cond = $2; p_loop->stmt_list = $4; $$ = (Node*)p_loop; SetNodePos($$); } | LOOP pl_stmt_list EndLoop ';' { LoopStmt *p_loop = makeNode(LoopStmt); p_loop->stmt_list = $2; $$ = (Node*)p_loop; SetNodePos($$); } ; EndLoop:_END LOOP {} | ENDLOOP {} | ENDLOOP name_space {} | _END LOOP name_space {} ; ForStmt: FOR ColId _IN b_expr TWO_DOT b_expr LOOP pl_stmt_list EndFor ';' { ForStmt *p_for = makeNode(ForStmt); p_for->var_name = $2; p_for->from_val = $4; p_for->to_val = $6; p_for->stmt_list = $8; $$ = (Node*)p_for; SetNodePos($$); } | FOR ColId _IN REVERSE b_expr TWO_DOT b_expr LOOP pl_stmt_list EndFor ';' { ForStmt *p_for = makeNode(ForStmt); p_for->var_name = $2; p_for->from_val = $5; p_for->to_val = $7; p_for->b_reverse = true; p_for->stmt_list = $9; $$ = (Node*)p_for; SetNodePos($$); } | FOR ColId _IN ident LOOP pl_stmt_list EndFor ';' { ForStmt *p_for = makeNode(ForStmt); Ident *p_ident = ((Ident*)$4); p_for->var_name = $2; p_for->b_use_cursor = true; if(p_ident->child) { if(p_ident->child->ident_t != IDENT_FUNC) { SetSrcPos(p_ident); add_parse_error(577); } p_for->cursor_paras = p_ident->child->args; } p_for->cursor_name = p_ident->name; p_for->stmt_list = $6; $$ = (Node*)p_for; SetNodePos($$); } | FOR ColId _IN select_with_parens LOOP pl_stmt_list EndFor ';' { ForStmt *p_for = makeNode(ForStmt); p_for->var_name = $2; p_for->sel_stmt = (SelectStmt*)$4; p_for->stmt_list = $6; $$ = (Node*)p_for; SetNodePos($$); } | FOR error LOOP pl_stmt_list EndFor ';' { ForStmt *p_for = makeNode(ForStmt); p_for->stmt_list = $4; $$ = (Node*)p_for; SetNodePos($$); } ; EndFor: _END FOR {} | ENDFOR {} | _END LOOP {} | ENDLOOP {} | _END FOR name_space {} | ENDFOR name_space {} | _END LOOP name_space {} | ENDLOOP name_space {} ; ForallStmt: FORALL ColId _IN b_expr TWO_DOT b_expr dml_stmt1 ';' { ForallStmt *p_stmt = makeNode(ForallStmt); p_stmt->var_name = $2; p_stmt->from_val = $4; p_stmt->to_val = $6; p_stmt->dml_stmt = $7; $$ = (Node*)p_stmt; SetNodePos($$); } | FORALL ColId _IN INDICES OF ident BETWEEN b_expr AND b_expr dml_stmt1 ';' { ForallStmt *p_stmt = makeNode(ForallStmt); p_stmt->var_name = $2; p_stmt->idx_ident = (Ident*)$6; p_stmt->from_val = $8; p_stmt->to_val = $10; p_stmt->dml_stmt = $11; $$ = (Node*)p_stmt; SetNodePos($$); } | FORALL ColId _IN INDICES OF ident dml_stmt1 ';' { ForallStmt *p_stmt = makeNode(ForallStmt); p_stmt->var_name = $2; p_stmt->idx_ident = (Ident*)$6; p_stmt->dml_stmt = $7; $$ = (Node*)p_stmt; SetNodePos($$); } | FORALL ColId _IN VALUES OF ident dml_stmt1 ';' { ForallStmt *p_stmt = makeNode(ForallStmt); p_stmt->var_name = $2; p_stmt->value_of = (Ident*)$6; p_stmt->dml_stmt = $7; $$ = (Node*)p_stmt; SetNodePos($$); } ; dml_stmt1: UpdateStmt | InsertStmt | DeleteStmt | ExecuteStmt ; ThrowStmt:THROW EXCEPTION ColId ';' { ThrowStmt *p_stmt = makeNode(ThrowStmt); p_stmt->exception_name = $3; $$ = (Node*)p_stmt; SetNodePos($$); } | THROW EXCEPTION ColId b_expr ';' { ThrowStmt *p_stmt = makeNode(ThrowStmt); p_stmt->exception_name = $3; p_stmt->msg_expr = $4; $$ = (Node*)p_stmt; SetNodePos($$); } | THROW ColId ';' { ThrowStmt *p_stmt = makeNode(ThrowStmt); p_stmt->exception_name= $2; $$ = (Node*)p_stmt; SetNodePos($$); } | THROW ColId b_expr ';' { ThrowStmt *p_stmt = makeNode(ThrowStmt); p_stmt->exception_name= $2; p_stmt->msg_expr = $3; $$ = (Node*)p_stmt; SetNodePos($$); } | RAISE EXCEPTION ColId ';' { ThrowStmt *p_stmt = makeNode(ThrowStmt); p_stmt->exception_name = $3; $$ = (Node*)p_stmt; SetNodePos($$); } | RAISE EXCEPTION ColId b_expr ';' { ThrowStmt *p_stmt = makeNode(ThrowStmt); p_stmt->exception_name = $3; p_stmt->msg_expr = $4; $$ = (Node*)p_stmt; SetNodePos($$); } | RAISE ColId ';' { ThrowStmt *p_stmt = makeNode(ThrowStmt); p_stmt->exception_name= $2; $$ = (Node*)p_stmt; SetNodePos($$); } | RAISE ColId b_expr ';' { ThrowStmt *p_stmt = makeNode(ThrowStmt); p_stmt->exception_name= $2; p_stmt->msg_expr = $3; $$ = (Node*)p_stmt; SetNodePos($$); } | RAISE ';' { ThrowStmt *p_stmt = makeNode(ThrowStmt); p_stmt->exception_name= NULL; $$ = (Node*)p_stmt; SetNodePos($$); } ; CaseStmt: CASE case_arg When_list EndCase ';' { CaseStmt *p_stmt = makeNode(CaseStmt); p_stmt->case_arg = $2; p_stmt->when_list = $3; $$ = (Node*)p_stmt; SetNodePos($$); } | CASE case_arg When_list ELSE pl_stmt_list EndCase ';' { CaseStmt *p_stmt = makeNode(CaseStmt); p_stmt->case_arg = $2; p_stmt->when_list = $3; p_stmt->def_stmt_list = $5; $$ = (Node*)p_stmt; SetNodePos($$); } ; EndCase:_END CASE {} | ENDCASE {} ; When_list: When_item { $$ = makeList1($1); } | When_list When_item { $$ = lappend($1,$2); } ; When_item: WHEN bool_expr THEN pl_stmt_list { When_item *p_item = makeNode(When_item); p_item->cond = $2; p_item->stmt_list = $4; $$ = (Node*)p_item; SetNodePos($$); } ; GotoStmt: GOTO ColId ';' { GotoStmt *p_goto = makeNode(GotoStmt); p_goto->label = $2; $$ = (Node*)p_goto; SetNodePos($$); }; BreakStmt: EXIT ';' { BreakStmt *p_stmt = makeNode(BreakStmt); $$ = (Node*)p_stmt; SetNodePos($$); } | EXIT ColId ';' { BreakStmt *p_stmt = makeNode(BreakStmt); p_stmt->label = $2; $$ = (Node*)p_stmt; SetNodePos($$); } | EXIT WHEN bool_expr ';' { BreakStmt *p_stmt = makeNode(BreakStmt); p_stmt->cond = $3; $$ = (Node*)p_stmt; SetNodePos($$); } | EXIT ColId WHEN bool_expr ';' { BreakStmt *p_stmt = makeNode(BreakStmt); p_stmt->label = $2; p_stmt->cond = $4; $$ = (Node*)p_stmt; SetNodePos($$); } | LEAVE ';' { BreakStmt *p_stmt = makeNode(BreakStmt); $$ = (Node*)p_stmt; SetNodePos($$); } | LEAVE ColId ';' { BreakStmt *p_stmt = makeNode(BreakStmt); p_stmt->label = $2; $$ = (Node*)p_stmt; SetNodePos($$); } | LEAVE WHEN bool_expr ';' { BreakStmt *p_stmt = makeNode(BreakStmt); p_stmt->cond = $3; $$ = (Node*)p_stmt; SetNodePos($$); } | LEAVE ColId WHEN bool_expr ';' { BreakStmt *p_stmt = makeNode(BreakStmt); p_stmt->label = $2; p_stmt->cond = $4; $$ = (Node*)p_stmt; SetNodePos($$); } ; ContinueStmt: CONTINUE ';' { ContinueStmt *p_stmt = makeNode(ContinueStmt); $$ = (Node*)p_stmt; SetNodePos($$); } | CONTINUE ColId ';' { ContinueStmt *p_stmt = makeNode(ContinueStmt); p_stmt->label = $2; $$ = (Node*)p_stmt; SetNodePos($$); }; ReturnStmt: RETURN ';' { ReturnStmt *p_stmt = makeNode(ReturnStmt); $$ = (Node*)p_stmt; SetNodePos($$); } | RETURN b_expr ';' // b_expr ';' { ReturnStmt *p_stmt = makeNode(ReturnStmt); p_stmt->p_val = $2; $$ = (Node*)p_stmt; SetNodePos($$); } ; CallPrepareStmt: '?' ColLabel { ExePrepareStmt *p_stmt = makeNode(ExePrepareStmt); p_stmt->name = $2; $$ = (Node*)p_stmt; SetNodePos($$); } | '?' ColLabel '(' expr_list ')' { ExePrepareStmt *p_stmt = makeNode(ExePrepareStmt); p_stmt->name = $2; p_stmt->params = $4; $$ = (Node*)p_stmt; SetNodePos($$); } | '?' ColLabel AS CURSOR name RETURN ICONST { ExePrepareStmt *p_stmt = makeNode(ExePrepareStmt); p_stmt->name = $2; p_stmt->cursor_name = $5; p_stmt->fetch_num = $7; $$ = (Node*)p_stmt; SetNodePos($$); } | '?' ColLabel AS CURSOR name { ExePrepareStmt *p_stmt = makeNode(ExePrepareStmt); p_stmt->name = $2; p_stmt->cursor_name = $5; p_stmt->fetch_num = 0x7fffffff;//default=MAX(INT) $$ = (Node*)p_stmt; SetNodePos($$); } ; ExecuteStmt: ident { ExecuteStmt *p_stmt = makeNode(ExecuteStmt); p_stmt->p_ident = (Ident*)$1; $$ = (Node*)p_stmt; SetNodePos($$); } | _CALL func_name { ExecuteStmt *p_stmt = makeNode(ExecuteStmt); Ident *p_ident = makeNode(Ident); p_ident->name = $2; p_stmt->p_ident = p_ident; p_stmt->limit_num = -1; $$ = (Node*)p_stmt; SetNodePos($$); } | EXECUTE func_name { ExecuteStmt *p_stmt = makeNode(ExecuteStmt); Ident *p_ident = makeNode(Ident); p_ident->name = $2; p_stmt->p_ident = p_ident; p_stmt->limit_num = -1; $$ = (Node*)p_stmt; SetNodePos($$); } | EXECUTE func_name '(' func_params ')' { ExecuteStmt *p_stmt = makeNode(ExecuteStmt); Ident *p_ident1 = makeNode(Ident); Ident *p_ident2 = makeNode(Ident); p_ident1->name = $2; p_ident2->args = $4; p_ident2->ident_t = IDENT_FUNC; set_ident_child(p_ident1,p_ident2); p_stmt->p_ident = p_ident1; p_stmt->limit_num = -1; $$ = (Node*)p_stmt; SetNodePos($$); } | _CALL func_name '(' func_params ')' { ExecuteStmt *p_stmt = makeNode(ExecuteStmt); Ident *p_ident1 = makeNode(Ident); Ident *p_ident2 = makeNode(Ident); p_ident1->name = $2; p_ident2->args = $4; p_ident2->ident_t = IDENT_FUNC; set_ident_child(p_ident1,p_ident2); p_stmt->p_ident = p_ident1; p_stmt->limit_num = -1; $$ = (Node*)p_stmt; SetNodePos($$); } | EXECUTE IMMEDIATE b_expr opt_using opt_return opt_into_list opt_limit { ExecuteStmt *p_stmt = makeNode(ExecuteStmt); p_stmt->sql_expr = $3; p_stmt->param_list = $4; p_stmt->is_bulk = $5; p_stmt->into_list = $6; p_stmt->limit_num = $7; $$ = (Node*)p_stmt; SetNodePos($$); } | _CALL IMMEDIATE b_expr opt_using opt_return opt_into_list opt_limit { ExecuteStmt *p_stmt = makeNode(ExecuteStmt); p_stmt->sql_expr = $3; p_stmt->param_list = $4; p_stmt->is_bulk = $5; p_stmt->into_list = $6; p_stmt->limit_num = $7; $$ = (Node*)p_stmt; SetNodePos($$); } ; opt_return: /*empty*/ { $$ = false; } | RETURNING { $$ = false; } | BULK COLLECT { $$ = true; } | RETURNING BULK COLLECT { $$ = true; } ; opt_limit: /*empty*/ { $$ = 0; } | LIMIT ICONST { $$ = $2; } ; opt_using: /*empty*/ { $$ = NIL; } | USING expr_list { $$ = $2; } ; ident_list: ident { $$ = makeList1($1); } | ident_list ',' ident { $$ = lappend($1,$3); } ; func_params: RParam { $$ = makeList1($1); } | func_params ',' RParam { if($1==NIL) { SetParsePos(); add_parse_error(578); } $$ = lappend($1,$3); } |/*empty*/ { $$ = NIL; } ; RParam: b_expr { $$ = $1; } | name '=' '>' b_expr { RParam *p_func_para = makeNode(RParam); p_func_para->param_name = $1; p_func_para->value = $4; $$ = (Node*)p_func_para; } ; /*disassemble sql*/ DisassembleStmt: DISASSEMBLE name_space { DisassembleStmt *p_stmt = makeNode(DisassembleStmt); p_stmt->name_space = $2; $$ = (Node*)p_stmt; } ; /*procedure or function debug sql*/ TraceStmt: TRACE SESSION ICONST { TraceStmt *p_stmt = makeNode(TraceStmt); p_stmt->cmd = TRACE_BIND; p_stmt->session_id = $3; $$ = (Node*)p_stmt; } | TRACE STEP { TraceStmt *p_stmt = makeNode(TraceStmt); p_stmt->cmd = TRACE_STEP; $$ = (Node*)p_stmt; } | TRACE NEXT { TraceStmt *p_stmt = makeNode(TraceStmt); p_stmt->cmd = TRACE_NEXT; $$ = (Node*)p_stmt; } | TRACE _OUT { TraceStmt *p_stmt = makeNode(TraceStmt); p_stmt->cmd = TRACE_OUT; $$ = (Node*)p_stmt; } | TRACE _OUT BREAK { TraceStmt *p_stmt = makeNode(TraceStmt); p_stmt->cmd = TRACE_OUT_BRK; $$ = (Node*)p_stmt; } | TRACE RUN { TraceStmt *p_stmt = makeNode(TraceStmt); p_stmt->cmd = TRACE_RUN; $$ = (Node*)p_stmt; } | TRACE RUN BREAK { TraceStmt *p_stmt = makeNode(TraceStmt); p_stmt->cmd = TRACE_RUN_BRK; $$ = (Node*)p_stmt; } | TRACE RUN TO ICONST OF name_space { TraceStmt *p_stmt = makeNode(TraceStmt); p_stmt->cmd = TRACE_RUN_TO; p_stmt->obj_name = $6; p_stmt->src_pos = $4<<16; $$ = (Node*)p_stmt; } | TRACE RUN TO ICONST ':' ICONST OF name_space { TraceStmt *p_stmt = makeNode(TraceStmt); p_stmt->cmd = TRACE_RUN_TO; p_stmt->obj_name = $8; p_stmt->src_pos = ($4<<16)+$6; $$ = (Node*)p_stmt; } | TRACE BREAK { TraceStmt *p_stmt = makeNode(TraceStmt); p_stmt->cmd = TRACE_BRK; $$ = (Node*)p_stmt; } | TRACE CONTINUE { TraceStmt *p_stmt = makeNode(TraceStmt); p_stmt->cmd = TRACE_CONTINUE; $$ = (Node*)p_stmt; } | TRACE STOP { TraceStmt *p_stmt = makeNode(TraceStmt); p_stmt->cmd = TRACE_STOP; $$ = (Node*)p_stmt; } | TRACE ADD BREAK ICONST OF name_space { TraceStmt *p_stmt = makeNode(TraceStmt); p_stmt->cmd = TRACE_ADD_BRK; p_stmt->obj_name = $6; p_stmt->src_pos = $4<<16; $$ = (Node*)p_stmt; } | TRACE ADD BREAK ICONST ':' ICONST OF name_space { TraceStmt *p_stmt = makeNode(TraceStmt); p_stmt->cmd = TRACE_ADD_BRK; p_stmt->obj_name = $8; p_stmt->src_pos = ($4<<16)+$6; $$ = (Node*)p_stmt; } | TRACE DROP BREAK ICONST OF name_space { TraceStmt *p_stmt = makeNode(TraceStmt); p_stmt->cmd = TRACE_DROP_BRK; p_stmt->obj_name = $6; p_stmt->src_pos = $4<<16; $$ = (Node*)p_stmt; } | TRACE DROP BREAK ICONST ':' ICONST OF name_space { TraceStmt *p_stmt = makeNode(TraceStmt); p_stmt->cmd = TRACE_DROP_BRK; p_stmt->obj_name = $8; p_stmt->src_pos = ($4<<16)+$6; $$ = (Node*)p_stmt; } | TRACE SET ident TO AexprConst { TraceStmt *p_stmt = makeNode(TraceStmt); p_stmt->cmd = TRACE_SET; p_stmt->var = (Ident*)$3; p_stmt->value = $5; $$ = (Node*)p_stmt; } /*get infomation of vars*/ | TRACE GET watch_list { TraceStmt *p_stmt = makeNode(TraceStmt); p_stmt->cmd = TRACE_GET; p_stmt->watch_list = $3; $$ = (Node*)p_stmt; } ; /*watch var list*/ watch_list: b_expr { $$ = makeList1($1); } |watch_list ',' b_expr { $$ = lappend($1,$3); } ; /********************************************************** *backup database or data *add opt_encryptor bysdc@20210310 feature-backup_encrypt ***********************************************************/ BackupStmt: EXPORT DATABASE opt_trans_range opt_encryptor parallel_opt { BackupStmt *p_stmt = makeNode(BackupStmt); p_stmt->backup_type = EXPORT_DB; p_stmt->min_trans_id = ((TransRange*)$3)->min_trans_id; p_stmt->max_trans_id = ((TransRange*)$3)->max_trans_id; p_stmt->encrypt_key = $4; p_stmt->parallel = $5; $$ = (Node*)p_stmt; } | EXPORT TABLE name_space opt_trans_range opt_encryptor parallel_opt { BackupStmt *p_stmt = makeNode(BackupStmt); p_stmt->backup_type = EXPORT_TABLE; p_stmt->name = $3; p_stmt->min_trans_id = ((TransRange*)$4)->min_trans_id; p_stmt->max_trans_id = ((TransRange*)$4)->max_trans_id; p_stmt->encrypt_key = $5; p_stmt->parallel = $6; $$ = (Node*)p_stmt; } /* add by sdc@20170527 */ | BACKUP SYSTEM opt_increment opt_path opt_online opt_encryptor parallel_opt { BackupStmt *p_stmt = makeNode(BackupStmt); p_stmt->backup_type = BACKUP_SYS; if($3) p_stmt->is_increment = $3; if($4) { p_stmt->is_append = ((BackupPath*)$4)->is_append; p_stmt->path = ((BackupPath*)$4)->path; } p_stmt->online = $5; p_stmt->encrypt_key = $6; if($7) p_stmt->parallel = $7; $$ = (Node*)p_stmt; } | BACKUP DATABASE opt_increment opt_path opt_encryptor parallel_opt { BackupStmt *p_stmt = makeNode(BackupStmt); p_stmt->backup_type = BACKUP_DB; if($3) p_stmt->is_increment = $3; p_stmt->is_append = ((BackupPath*)$4)->is_append; p_stmt->path = ((BackupPath*)$4)->path; p_stmt->encrypt_key = $5; p_stmt->parallel = $6; $$ = (Node*)p_stmt; } | BACKUP TABLE name_space opt_path opt_encryptor { BackupStmt *p_stmt = makeNode(BackupStmt); p_stmt->backup_type = BACKUP_TABLE; p_stmt->name = $3; p_stmt->is_append = ((BackupPath*)$4)->is_append; p_stmt->path = ((BackupPath*)$4)->path; p_stmt->encrypt_key = $5; $$ = (Node*)p_stmt; }/* end add by sdc@20170527 */ ; opt_trans_range: /*empty*/ { TransRange *p_range = New(TransRange); p_range->min_trans_id = 0; p_range->max_trans_id = 0xffffffffffffffffULL; $$ = p_range; } | TRANSACTION BETWEEN ICONST AND ICONST { TransRange *p_range = New(TransRange); p_range->min_trans_id = (TRANID)$3; p_range->max_trans_id = (TRANID)$5; $$ = p_range; } | TRANSACTION BETWEEN ICONST AND FCONST { TransRange *p_range = New(TransRange); p_range->min_trans_id = (TRANID)$3; p_range->max_trans_id = (TRANID)atoi8($5); $$ = p_range; } | TRANSACTION BETWEEN FCONST AND ICONST { TransRange *p_range = New(TransRange); p_range->min_trans_id = (TRANID)atoi8($3); p_range->max_trans_id = (TRANID)$5; $$ = p_range; } | TRANSACTION BETWEEN FCONST AND FCONST { TransRange *p_range = New(TransRange); p_range->min_trans_id = (TRANID)atoi8($3); p_range->max_trans_id = (TRANID)atoi8($5); $$ = p_range; } ; /* add by sdc@20170527 */ opt_increment: /* empty */ { $$ = false; } | ALL { $$ = false; } | INCREMENT { $$ = true; } ; opt_path: /* empty */ /* { BackupPath *p_path = New(BackupPath); p_path->is_append = false; p_path->path = NULL; $$ = (Node*)p_path; } | */ TO Sconst { BackupPath *p_path = New(BackupPath); p_path->is_append = false; p_path->path = dbs2utf($2); $$ = (Node*)p_path; } | APPEND TO Sconst { BackupPath *p_path = New(BackupPath); p_path->is_append = true; p_path->path = dbs2utf($3); $$ = (Node*)p_path; } ; /* end add by sdc@20170527 */ /********************************************************** *restore database or data ***********************************************************/ ImportStmt: IMPORT op_append_mode TABLE name_space opt_column_list FROM STREAM opt_reindex opt_import_mode parallel_opt { ImportStmt *p_stmt = makeNode(ImportStmt); p_stmt->restore_type = IMPORT_TABLE; p_stmt->append_mode = $2; p_stmt->b_reindex = $8; p_stmt->name = $4; p_stmt->import_mode = $9; p_stmt->parallel = $10; $$ = (Node*)p_stmt; } | IMPORT op_append_mode TABLE name_space opt_column_list FROM STREAM RECORDS DELIMITED BY terminated_chars FIELDS TERMINATED BY terminated_chars opt_reindex opt_import_mode parallel_opt { ImportStmt *p_stmt = makeNode(ImportStmt); p_stmt->restore_type = IMPORT_TABLE; p_stmt->append_mode = $2; p_stmt->b_reindex = $16; p_stmt->name = $4; p_stmt->row_separator = $11; p_stmt->field_separator = $15; p_stmt->import_mode = $17; p_stmt->parallel = $18; $$ = (Node*)p_stmt; } | IMPORT op_append_mode TABLE name_space opt_column_list FROM SelectStmt opt_reindex opt_import_mode parallel_opt { ImportStmt *p_stmt = makeNode(ImportStmt); p_stmt->restore_type = IMPORT_TABLE; p_stmt->append_mode = $2; p_stmt->b_reindex = $8; p_stmt->name = $4; p_stmt->col_list = $5; p_stmt->selectStmt = $7; p_stmt->import_mode = $9; p_stmt->parallel = $10; $$ = (Node*)p_stmt; } /* add by sdc@20170527 */ | RESTORE DATABASE name_space FROM Sconst opt_encryptor parallel_opt { ImportStmt *p_stmt = makeNode(ImportStmt); p_stmt->restore_type = RESTORE_DB; p_stmt->name = $3; p_stmt->path = dbs2utf($5); p_stmt->encrypt_key = $6; p_stmt->parallel = $7; $$ = (Node*)p_stmt; } | RESTORE TABLE name_space FROM Sconst opt_encryptor parallel_opt { ImportStmt *p_stmt = makeNode(ImportStmt); p_stmt->restore_type = RESTORE_TABLE; p_stmt->name = $3; p_stmt->path = dbs2utf($5); //p_stmt->append_mode = $2; p_stmt->encrypt_key = $6; p_stmt->parallel = $7; $$ = (Node*)p_stmt; } | RESTORE TABLE name_space RENAME TO name_space FROM Sconst opt_encryptor parallel_opt { ImportStmt *p_stmt = makeNode(ImportStmt); p_stmt->restore_type = RESTORE_TABLE; p_stmt->name = $3; p_stmt->rename = $6; p_stmt->path = dbs2utf($8); //p_stmt->append_mode = $2; p_stmt->encrypt_key = $9; p_stmt->parallel = $10; $$ = (Node*)p_stmt; } | RESTORE SYSTEM FROM Sconst opt_encryptor opt_until_time parallel_opt { ImportStmt *p_stmt = (ImportStmt*)$6; p_stmt->restore_type = RESTORE_SYS; p_stmt->name = NULL; p_stmt->path = dbs2utf($4); p_stmt->encrypt_key = $5; p_stmt->parallel = $7; $$ = (Node*)p_stmt; }/* end add by sdc@20170527 */ /*why 2019-01-03 add*/ |LOAD op_append_mode TABLE name_space FROM STREAM opt_reindex opt_import_mode parallel_opt2 { ImportStmt *p_stmt = makeNode(ImportStmt); p_stmt->restore_type = LOAD_TABLE; p_stmt->append_mode = $2; p_stmt->b_reindex = $7; p_stmt->name = $4; p_stmt->import_mode = $8; p_stmt->parallel = $9; $$ = (Node*)p_stmt; } |LOAD op_append_mode TABLE name_space FROM STREAM RECORDS DELIMITED BY terminated_chars FIELDS TERMINATED BY terminated_chars opt_reindex opt_import_mode parallel_opt2 { ImportStmt *p_stmt = makeNode(ImportStmt); p_stmt->restore_type = LOAD_TABLE; p_stmt->append_mode = $2; p_stmt->b_reindex = $15; p_stmt->name = $4; p_stmt->row_separator = $10; p_stmt->field_separator = $14; p_stmt->import_mode = $16; p_stmt->parallel = $17; $$ = (Node*)p_stmt; } //end ; terminated_chars: Sconst { $$ = $1; } | BITCONST { $$ = hex2str($1); } ; op_append_mode: /*empty*/ { $$ = 1; } | APPEND { $$ = 1; } | REPLACE { $$ = 2; } ; opt_reindex: /*empty*/ { $$ = false; } | WITH REINDEX { $$ = true; } ; opt_import_mode: /*empty*/ { $$ = 0; } | USE MODE ICONST { $$ = $3; } | USE MODE AUTO { $$ = 0; }; //why 2016-10-27 add mergebysdc@20180907 opt_encrypt:/*empty*/ { $$ = 0; } | ENCRYPT BY Sconst { $$ = dbs2utf($3); }; opt_cascade:/*empty*/ { $$ = false; } | CASCADE { $$ = true; } //end /* add by sdc@20170527 */ opt_encryptor: /* empty */ { $$ = NULL; } | ENCRYPTOR IS Sconst { $$ = dbs2utf($3); } ; opt_until_time: /* empty */ { ImportStmt *p_stmt = makeNode(ImportStmt); p_stmt->until_time = NULL; p_stmt->until_tranid = 0; $$ = (Node*)p_stmt; } | UNTIL CURRENT TIME { ImportStmt *p_stmt = makeNode(ImportStmt); p_stmt->until_time = "NOW"; p_stmt->until_tranid = 0; $$ = (Node*)p_stmt; } | UNTIL TIME Sconst { ImportStmt *p_stmt = makeNode(ImportStmt); p_stmt->until_time = dbs2utf($3); p_stmt->until_tranid = 0; $$ = (Node*)p_stmt; } | UNTIL TRANSACTION ICONST { ImportStmt *p_stmt = makeNode(ImportStmt); p_stmt->until_time = NULL; p_stmt->until_tranid = (TRANID)$3; $$ = (Node*)p_stmt; } | UNTIL TRANSACTION FCONST { ImportStmt *p_stmt = makeNode(ImportStmt); p_stmt->until_time = NULL; p_stmt->until_tranid = (TRANID)atoi8($3); $$ = (Node*)p_stmt; } ; /* end add by sdc@20170527 */ /********************************************************** *create encryptor ***********************************************************/ CreateEncryptStmt: CREATE ENCRYPTOR Sconst BY Sconst { CreateEncryptorStmt *p_stmt = makeNode( CreateEncryptorStmt); p_stmt->name = dbs2utf($3); p_stmt->password = dbs2utf($5); $$ = (Node*)p_stmt; } ; /*********************************************************** *define database or user or table encryt ************************************************************/ /* why 2016-10-27 mergebysdc@20180907 modify old: EncryptStmt: ENCRYPT ALL { EncryptStmt *p_stmt = makeNode(EncryptStmt); p_stmt->tab_list = makeList1((Node*)NULL); $$ = (Node*)p_stmt; } | ENCRYPT TABLE relation_name_list { EncryptStmt *p_stmt = makeNode(EncryptStmt); p_stmt->tab_list = $3; $$ = (Node*)p_stmt; } ; */ EncryptStmt: ENCRYPT DATABASE BY ICONST opt_cascade opt_force { if($4<2 || $4>255) add_parse_error(1170); EncryptStmt *p_stmt = makeNode(EncryptStmt); p_stmt->mode = 1; p_stmt->encry_id = $4; p_stmt->cascade = $5; p_stmt->b_force = $6; $$ = (Node*)p_stmt; } | ENCRYPT USER UserId BY ICONST opt_cascade opt_force { if($5<2 || $5>255) add_parse_error(1170); EncryptStmt *p_stmt = makeNode(EncryptStmt); p_stmt->mode = 2; p_stmt->name = $3; p_stmt->encry_id = $5; p_stmt->cascade = $6; p_stmt->b_force = $7; $$ = (Node*)p_stmt; }; | ENCRYPT TABLE name_space BY ICONST opt_force { if($5<2 || $5>255) add_parse_error(1170); EncryptStmt *p_stmt = makeNode(EncryptStmt); p_stmt->mode = 3; p_stmt->name = $3; p_stmt->encry_id = $5; p_stmt->b_force = $6; $$ = (Node*)p_stmt; } | ENCRYPT DATABASE BY Sconst opt_cascade opt_force { EncryptStmt *p_stmt = makeNode(EncryptStmt); p_stmt->mode = 1; p_stmt->encry_name = dbs2utf($4); p_stmt->cascade = $5; p_stmt->b_force = $6; $$ = (Node*)p_stmt; } | ENCRYPT USER UserId BY Sconst opt_cascade opt_force { EncryptStmt *p_stmt = makeNode(EncryptStmt); p_stmt->mode = 2; p_stmt->name = $3; p_stmt->encry_name = dbs2utf($5); p_stmt->cascade = $6; p_stmt->b_force = $7; $$ = (Node*)p_stmt; }; | ENCRYPT TABLE name_space BY Sconst opt_force { EncryptStmt *p_stmt = makeNode(EncryptStmt); p_stmt->mode = 3; p_stmt->name = $3; p_stmt->encry_name = dbs2utf($5); p_stmt->b_force = $6; $$ = (Node*)p_stmt; }; //end /************************************************************ *decrypt database or table ************************************************************/ DecryptStmt: DECRYPT ALL { DecryptStmt *p_stmt = makeNode(DecryptStmt); p_stmt->tab_list = makeList1((Node*)NULL); $$ = (Node*)p_stmt; } | DECRYPT TABLE relation_name_list { DecryptStmt *p_stmt = makeNode(DecryptStmt); p_stmt->tab_list = $3; $$ = (Node*)p_stmt; }; /*********************************************************** *alter encyptor ***********************************************************/ DropEncryptStmt : DROP ENCRYPTOR { $$ = (Node*)makeNode(DropEncryptorStmt); }; /*********************************************************** *enable encrypt database ***********************************************************/ StartEncryptdb :START DATABASE WITH PASSWORD Sconst { StartEncryptdbStmt *p_stmt = makeNode(StartEncryptdbStmt); p_stmt->password = dbs2utf($5); $$ = (Node*)p_stmt; } ; /***************************************************************************** * * Create a new DBMS user * *****************************************************************************/ CreateUserStmt: CREATE USER UserId opt_alias opt_priority user_passwd_clause user_role_clause user_valid_clause account_lock_clause password_expire_clause opt_trust_ip opt_user_quotas opt_encrypt { CreateUserStmt *n = makeNode(CreateUserStmt); n->user = $3; n->alias = $4; n->priority = $5; n->password = $6; n->roleElts = $7; n->validUntil = $8; n->lock_action = $9; n->expire = $10; n->trust_ip = $11; n->user_quotas = $12; n->encry_name = $13; $$ = (Node *)n; } ; opt_alias: /*empty*/ { $$ = NULL; } | LOGIN UserId { $$ = $2; } ; opt_priority: /*empty*/ { $$ = 0; } | PRIORITY ICONST { $$ = $2; } ; /*lock account*/ account_lock_clause: ACCOUNT _LOCK { $$ = 1; } | ACCOUNT UNLOCK { $$ = -1; } | /* empty*/ { $$ = 0; } ; /*define password expire */ password_expire_clause: PASSWORD EXPIRE { $$ = true; } | /*empty*/ { $$ = false; } ; /***************************************************************************** * * Alter a DBMS user * *****************************************************************************/ AlterUserStmt: ALTER USER UserId opt_alias opt_priority user_passwd_clause user_valid_clause account_lock_clause password_expire_clause opt_trust_ip opt_user_quotas { AlterUserStmt *n = makeNode(AlterUserStmt); n->user = $3; n->alias = $4; n->priority = $5; n->password = $6; n->validUntil = $7; n->lock_action = $8; n->expire = $9; n->trust_ip = $10; n->user_quotas = $11; $$ = (Node *)n; } | ALTER USER UserId RENAME TO UserId { AlterUserStmt *n = makeNode(AlterUserStmt); n->user = $3; n->new_name = $6; $$ = (Node *)n; } | ALTER USER UserId SET LOGIN UserId { AlterUserStmt *n = makeNode(AlterUserStmt); n->user = $3; n->alias = $6; $$ = (Node *)n; } ; user_passwd_clause: IDENTIFIED BY Sconst { $$ = dbs2utf($3); } | IDENTIFIED BY ColId { $$ = $3; } | /*EMPTY*/ { $$ = (char*)NULL} ; user_list: user_list ',' UserId { $$ = lappend($1, $3); } | UserId { $$ = makeList1($1); } ; user_role_clause: DEFAULT ROLE user_list { $$ = $3; } | /*EMPTY*/ { $$ = NIL; } ; user_valid_clause: VALID UNTIL SCONST { $$ = $3; } | /*EMPTY*/ { $$ = (char*)NULL; } ; opt_trust_ip: /*empty*/ { $$ = NULL; } | SCONST { $$ = $1; } ; opt_user_quotas: /*empty*/ { $$ = NIL;} | user_quotas { $$ = $1; } ; user_quotas: user_quota { $$ = makeList1($1); } | user_quotas user_quota { $$ = lappend($1,$2); } ; user_quota: QUOTA ICONST size_unit ON MEMORY { UserQuota *n = makeNode(UserQuota); n->quota_type = "MEMORY"; n->quota = $2*($3/1024); $$ = (Node*)n; } | QUOTA UNLIMITED ON MEMORY { UserQuota *n = makeNode(UserQuota); n->quota_type = "MEMORY"; n->quota = -1; $$ = (Node*)n; } | QUOTA ICONST size_unit ON TEMP TABLESPACE { UserQuota *n = makeNode(UserQuota); n->quota_type = "TEMP_SPACE"; n->quota = $2*($3/1024); $$ = (Node*)n; } | QUOTA UNLIMITED ON TEMP TABLESPACE { UserQuota *n = makeNode(UserQuota); n->quota_type = "TEMP_SPACE"; n->quota = -1; $$ = (Node*)n; } | QUOTA ICONST size_unit ON UNDO TABLESPACE { UserQuota *n = makeNode(UserQuota); n->quota_type = "UNDO_SPACE"; n->quota = $2*($3/1024); $$ = (Node*)n; } | QUOTA UNLIMITED ON UNDO TABLESPACE { UserQuota *n = makeNode(UserQuota); n->quota_type = "UNDO_SPACE"; n->quota = -1; $$ = (Node*)n; } | QUOTA ICONST ON CURSOR { UserQuota *n = makeNode(UserQuota); n->quota_type = "CURSOR"; n->quota = $2; $$ = (Node*)n; } | QUOTA UNLIMITED ON CURSOR { UserQuota *n = makeNode(UserQuota); n->quota_type = "CURSOR"; n->quota = -1; $$ = (Node*)n; } | QUOTA ICONST ON SESSION { UserQuota *n = makeNode(UserQuota); n->quota_type = "SESSION"; n->quota = $2; $$ = (Node*)n; } | QUOTA UNLIMITED ON SESSION { UserQuota *n = makeNode(UserQuota); n->quota_type = "SESSION"; n->quota = -1; $$ = (Node*)n; } | QUOTA ICONST ON IO { UserQuota *n = makeNode(UserQuota); n->quota_type = "IO"; n->quota = $2; $$ = (Node*)n; } | QUOTA UNLIMITED ON IO { UserQuota *n = makeNode(UserQuota); n->quota_type = "IO"; n->quota = -1; $$ = (Node*)n; } | QUOTA ICONST ON PROCEDURE { UserQuota *n = makeNode(UserQuota); n->quota_type = "PROC"; n->quota = $2; $$ = (Node*)n; } | QUOTA UNLIMITED ON PROCEDURE { UserQuota *n = makeNode(UserQuota); n->quota_type = "PROC"; n->quota = -1; $$ = (Node*)n; } | QUOTA ICONST size_unit ON TABLESPACE { UserQuota *n = makeNode(UserQuota); n->quota_type = "SPACE"; n->quota = $2*($3/1024); $$ = (Node*)n; } | QUOTA UNLIMITED ON TABLESPACE { UserQuota *n = makeNode(UserQuota); n->quota_type = "SPACE"; n->quota = -1; $$ = (Node*)n; } ; /***************************************************************************** * * Drop a DBMS user * * *****************************************************************************/ DropUserStmt: DROP USER UserId alter_behavior opt_keep_obj { DropStmt *n = makeNode(DropStmt); n->obj_name = $3; n->drop_type = DROP_USER; n->behavior = ($4==CASCADE? OP_CASCADE : OP_RESTRICT); n->keep_objs = $5; $$ = (Node *)n; SetNodePos($$); } ; opt_keep_obj: /*empty*/ { $$ = false; } | KEEP OBJECT { $$ = true; } ; /***************************************************************************** * * Create a group * * *****************************************************************************/ CreateRoleStmt: CREATE ROLE UserId { CreateRoleStmt *n = makeNode(CreateRoleStmt); n->name = $3; n->initUsers = NIL; $$ = (Node *)n; } | CREATE ROLE UserId INIT USER user_list { CreateRoleStmt *n = makeNode(CreateRoleStmt); n->name = $3; n->initUsers = $6; $$ = (Node *)n; } |CREATE ROLE UserId INITIALLY USER user_list { CreateRoleStmt *n = makeNode(CreateRoleStmt); n->name = $3; n->initUsers = $6; $$ = (Node *)n; } ; /***************************************************************************** * * Alter role * * *****************************************************************************/ AlterRoleStmt: GRANT ROLE UserId TO user_list { AlterRoleStmt *n = makeNode(AlterRoleStmt); n->name = $3; n->action = +1; n->listUsers = $5; $$ = (Node *)n; } | REVOKE ROLE UserId FROM user_list { AlterRoleStmt *n = makeNode(AlterRoleStmt); n->name = $3; n->action = -1; n->listUsers = $5; $$ = (Node *)n; } ; /***************************************************************************** * * Drop Role * *****************************************************************************/ DropRoleStmt: DROP ROLE UserId { DropStmt *n = makeNode(DropStmt); n->obj_name = $3; n->drop_type = DROP_ROLE; $$ = (Node *)n; SetNodePos($$); } ; /***************************************************************************** * * Manipulate a schema * * *****************************************************************************/ CreateSchemaStmt: CREATE SCHEMA ColId AUTHORIZATION UserId { CreateSchemaStmt *n = makeNode(CreateSchemaStmt); n->schema_name = $3; n->owner = $5; $$ = (Node *)n; } | CREATE SCHEMA ColId { CreateSchemaStmt *n = makeNode(CreateSchemaStmt); n->schema_name = $3; $$ = (Node *)n; } ; AlterSchemaStmt: ALTER SCHEMA name_space RENAME TO name { AlterSchemaStmt *n = makeNode(AlterSchemaStmt); n->schema_name = $3; n->new_name = $6; $$ = (Node*)n; } | ALTER SCHEMA ColId OWNER TO ColId { AlterSchemaStmt *stmt = makeNode(AlterSchemaStmt ); stmt->schema_name = $3; stmt->new_owner = $6; $$ = (Node*)stmt; } ; DropSchemaStmt: DROP SCHEMA ColId alter_behavior { DropStmt *n = makeNode(DropStmt); n->obj_name = $3; n->drop_type = DROP_SCHEMA; n->behavior = ($4==CASCADE? OP_CASCADE : OP_RESTRICT); $$ = (Node *)n; SetNodePos($$); } ; /***************************************************************************** * * Set internal variable * SET name TO 'var_value' * Include SQL92 syntax (thomas 1997-10-22): * SET TIME ZONE 'var_value' * *****************************************************************************/ VariableSetStmt: SET ColId TO var_value { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = $2; n->value = dbs2utf($4); $$ = (Node *) n; } | SET ColId TO ColId { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = $2; n->value = $4; $$ = (Node *) n; } | SET ColId ON { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = $2; n->value = "ON"; $$ = (Node *) n; } | SET ColId OFF { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = $2; n->value = "OFF"; $$ = (Node *) n; } | ALTER SESSION SET ColId '=' var_value { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = $4; n->value = $6; $$ = (Node *) n; } | ALTER SESSION SET ColId '=' ColId { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = $4; n->value = $6; $$ = (Node *) n; } | SET TIME ZONE zone_value { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = "TIMEZONE"; n->value = $4; $$ = (Node *) n; } | SET TRANSACTION ISOLATION LEVEL opt_level { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = "ISO_LEVEL"; n->value = $5; $$ = (Node *) n; } | SET TRANSACTION READ ONLY { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = "TRANS_READONLY"; n->value = "ON"; $$ = (Node *) n; } | SET TRANSACTION READ WRITE { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = "TRANS_READONLY"; n->value = "OFF"; $$ = (Node *) n; } | SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL opt_level { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = "SESSION_ISO_LEVEL"; n->value = $8; $$ = (Node *) n; } | SET SESSION TRANSACTION ISOLATION LEVEL opt_level { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = "SESSION_ISO_LEVEL"; n->value = $6; $$ = (Node *) n; } | SET SESSION AUTHORIZATION SCONST { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = "SESSION_USER"; n->value = $4; $$ = (Node *) n; } | SET SESSION AUTHORIZATION UserId { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = "SESSION_USER"; n->value = $4; $$ = (Node *) n; } | SET NAMES opt_encoding { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = "CLIENT_ENCODING"; n->value = $3; $$ = (Node *) n; } | SET AUTO COMMIT ON { VariableSetStmt *n = makeNode(VariableSetStmt); n->name ="AUTO_COMMIT"; n->value = "ON"; $$ = (Node *) n; } | SET AUTO COMMIT OFF { VariableSetStmt *n = makeNode(VariableSetStmt); n->name ="AUTO_COMMIT"; n->value = "OFF"; $$ = (Node *) n; } | SET ROLLBACK ALL ON { VariableSetStmt *n = makeNode(VariableSetStmt); n->name ="ROLLBACK_ALL"; n->value = "ON"; $$ = (Node *) n; } | SET ROLLBACK ALL OFF { VariableSetStmt *n = makeNode(VariableSetStmt); n->name ="ROLLBACK_ALL"; n->value = "OFF"; $$ = (Node *) n; } | SET CURRENT SCHEMA name { VariableSetStmt *n = makeNode(VariableSetStmt); n->name ="CURRENT_SCHEMA"; n->value = $4; $$ = (Node *) n; } | SET CURRENT SCHEMA DEFAULT { VariableSetStmt *n = makeNode(VariableSetStmt); n->name ="CURRENT_SCHEMA"; n->value = "DEFAULT"; $$ = (Node *) n; } | SET SCHEMA name { VariableSetStmt *n = makeNode(VariableSetStmt); n->name ="CURRENT_SCHEMA"; n->value = $3; $$ = (Node *) n; } | SET SCHEMA DEFAULT { VariableSetStmt *n = makeNode(VariableSetStmt); n->name ="CURRENT_SCHEMA"; n->value = "DEFAULT"; $$ = (Node *) n; } | SET SCHEMA Sconst { VariableSetStmt *n = makeNode(VariableSetStmt); n->name ="CURRENT_SCHEMA"; n->value = dbs2utf($3); $$ = (Node *) n; } | SET AUDIT ON { VariableSetStmt *n = makeNode(VariableSetStmt); n->name ="$ENABLE_AUDIT"; n->value = "ON"; $$ = (Node *) n; } | SET AUDIT OFF { VariableSetStmt *n = makeNode(VariableSetStmt); n->name ="$ENABLE_AUDIT"; n->value = "OFF"; $$ = (Node *) n; } | SET _NULL _NULL { VariableSetStmt *n = makeNode(VariableSetStmt); n->name ="EMPTY_STR_AS_NULL"; n->value = "OFF"; $$ = (Node *) n; } | SET _NULL SCONST { VariableSetStmt *n = makeNode(VariableSetStmt); n->name = "EMPTY_STR_AS_NULL"; n->value = "ON"; $$ = (Node *) n; } ; opt_level: READ ONLY { $$ = (char*)"0"; } //{ $$ = "Read Only; } | READ COMMITTED { $$ = (char*)"1"; } //{ $$ = "Read Committed"; } | _REPEATABLE READ { $$ = (char*)"2"; } //{ $$ = "Repeatable Read";} | SERIALIZABLE { $$ = (char*)"3"; } //{ $$ = "Serializable"; } ; var_value: opt_boolean { $$ = $1; } | SCONST { $$ = $1; } | ICONST { char buf[64]; sprintf(buf, "%d", $1); $$ = tstrdup(buf); } | '-' ICONST { char buf[64]; sprintf(buf, "%d", -($2)); $$ = tstrdup(buf); } | FCONST { $$ = $1; } | '-' FCONST { char * s = (char*)tmalloc(astrlen($2)+2); s[0] = '-'; strcpy(s + 1, $2); $$ = s; } | DEFAULT { $$ = (char*)"DEFAULT"; } ; opt_boolean: _TRUE { $$ = (char*)"TRUE"; } | _FALSE { $$ = (char*)"FALSE"; } | ON { $$ = (char*)"ON"; } | OFF { $$ = (char*)"OFF"; } ; zone_value: Sconst { $$ = dbs2utf($1); } | DEFAULT { $$ = (char*)NULL; } | LOCAL { $$ = (char*)NULL; } ; opt_encoding: Sconst { $$ = dbs2utf($1); } | DEFAULT { $$ = (char*)NULL; } | /*EMPTY*/ { $$ = (char*)NULL; } ; VariableShowStmt: SHOW ColId { VariableShowStmt *n = makeNode(VariableShowStmt); n->name = $2; $$ = (Node *) n; } | SHOW TIME ZONE { VariableShowStmt *n = makeNode(VariableShowStmt); n->name = "TIMEZONE"; $$ = (Node *) n; } | SHOW TRANSACTION ISOLATION LEVEL { VariableShowStmt *n = makeNode(VariableShowStmt); n->name = "ISO_LEVEL"; $$ = (Node *) n; } | SHOW AUTO COMMIT { VariableShowStmt *n = makeNode(VariableShowStmt); n->name ="AUTO_COMMIT"; $$ = (Node *) n; } | SHOW ROLLBACK ALL { VariableShowStmt *n = makeNode(VariableShowStmt); n->name ="ROLLBACK_ALL"; $$ = (Node *) n; } | SHOW CURRENT SCHEMA { VariableShowStmt *n = makeNode(VariableShowStmt); n->name ="CURRENT_SCHEMA"; $$ = (Node *) n; } ; ConstraintsSetStmt: SET CONSTRAINTS constraints_set_list constraints_set_mode { ConstraintsSetStmt *n = makeNode(ConstraintsSetStmt); n->constraints = $3; n->deferred = $4; $$ = (Node *) n; } ; constraints_set_list: ALL { $$ = NIL; } | constraints_set_namelist { $$ = $1; } ; constraints_set_namelist: IDENT { $$ = makeList1($1); } | constraints_set_namelist ',' IDENT { $$ = lappend($1, $3); } ; constraints_set_mode: DEFERRED { $$ = true; } | IMMEDIATE { $$ = false; } ; /* * Checkpoint statement */ CheckPointStmt: CHECKPOINT { CheckPointStmt *n = makeNode(CheckPointStmt); $$ = (Node *)n; } ; /* * recompile objects */ /*********************************************************************** * ALTER TABLE[ PROCEDUE|PACKAGE |TRIGGER |TYPE |VIEW] RECOMPILE ***********************************************************************/ RecompileStmt: ALTER TABLE name_space RECOMPILE { RecompileStmt *n = makeNode(RecompileStmt ); n->obj_type = OBJ_TYPE_TAB; n->obj_name = $3; $$ = (Node*)n; } | ALTER VIEW name_space RECOMPILE { RecompileStmt *n = makeNode(RecompileStmt ); n->obj_type = OBJ_TYPE_VIEW; n->obj_name = $3; $$ = (Node*)n; } | ALTER PROCEDURE name_space RECOMPILE { RecompileStmt *n = makeNode(RecompileStmt ); n->obj_type = OBJ_TYPE_PROC; n->obj_name = $3; $$ = (Node*)n; } | ALTER PACKAGE name_space RECOMPILE { RecompileStmt *n = makeNode(RecompileStmt ); n->obj_type = OBJ_TYPE_PACK; n->obj_name = $3; $$ = (Node*)n; } | ALTER TYPE name_space RECOMPILE { RecompileStmt *n = makeNode(RecompileStmt ); n->obj_type = OBJ_TYPE_UDT; n->obj_name = $3; $$ = (Node*)n; } | ALTER TRIGGER name_space RECOMPILE { RecompileStmt *n = makeNode(RecompileStmt ); n->obj_type = OBJ_TYPE_TRIG; n->obj_name = $3; $$ = (Node*)n; } ; /* * enable or disable an object (etc. TRIGGER) */ /*********************************************************************** * ALTER TRIGGER ... [ENABLE | DISABLE] ***********************************************************************/ EnableStmt: ALTER TRIGGER name_space enable_disable { EnableStmt *n = makeNode(EnableStmt ); n->obj_type = OBJ_TYPE_TRIG; n->obj_name = $3; n->enable = $4; $$ = (Node*)n; } ; /***************************************************************************** * * ALTER TABLE variations * *****************************************************************************/ //add opt_wait bysdc@20190508 AlterTableStmt: ALTER TABLE name_space add_columns alter_behavior opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = CHG_FIELDS; n->relname = $3; n->add_columns = $4; n->behavior = ($5==CASCADE? OP_CASCADE : OP_RESTRICT); n->wait_ms = $6;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space alter_columns alter_behavior opt_force opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = CHG_FIELDS; n->relname = $3; n->alter_columns = $4; n->behavior = ($5==CASCADE? OP_CASCADE : OP_RESTRICT); n->opt_force = $6; n->wait_ms = $7;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space drop_columns alter_behavior opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = CHG_FIELDS; n->relname = $3; n->drop_columns = $4; n->behavior = ($5==CASCADE? OP_CASCADE : OP_RESTRICT); n->wait_ms = $6;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space add_columns alter_columns alter_behavior opt_force opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = CHG_FIELDS; n->relname = $3; n->add_columns = $4; n->alter_columns = $5; n->behavior = ($6==CASCADE? OP_CASCADE : OP_RESTRICT); n->opt_force = $7; n->wait_ms = $8;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space add_columns drop_columns alter_behavior opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = CHG_FIELDS; n->relname = $3; n->add_columns = $4; n->drop_columns = $5; n->behavior = ($6==CASCADE? OP_CASCADE : OP_RESTRICT); n->wait_ms = $7;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space alter_columns drop_columns alter_behavior opt_force opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = CHG_FIELDS; n->relname = $3; n->alter_columns = $4; n->drop_columns = $5; n->behavior = ($6==CASCADE? OP_CASCADE : OP_RESTRICT); n->opt_force = $7; n->wait_ms = $8;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space add_columns alter_columns drop_columns alter_behavior opt_force opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = CHG_FIELDS; n->relname = $3; n->add_columns = $4; n->alter_columns = $5; n->drop_columns = $6; n->behavior = ($7==CASCADE? OP_CASCADE : OP_RESTRICT); n->opt_force = $8; n->wait_ms = $9;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space MODIFY CONSTRAINT ColId enable_disable opt_validate exceptions_opt cascade_opt keep_drop_opt opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = CHG_CONS; n->relname = $3; n->wait_ms = $12;//add opt_wait bysdc@20190508 $$ = (Node*)n; } | ALTER TABLE name_space ENABLE CONSTRAINT name_list opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = ENABLE_CONS; n->relname = $3; n->cons_name_list = $6; n->wait_ms = $7;//add opt_wait bysdc@20190508 $$ = (Node*)n; } | ALTER TABLE name_space DISABLE CONSTRAINT name_list opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = DISABLE_CONS; n->relname = $3; n->cons_name_list = $6; n->wait_ms = $7;//add opt_wait bysdc@20190508 $$ = (Node*)n; } | ALTER TABLE name_space DROP CONSTRAINT name_list keep_drop_opt alter_behavior opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = DROP_CONS; n->relname = $3; n->cons_name_list = $6; n->keep_idx = $7; n->behavior = ($8==CASCADE? OP_CASCADE : OP_RESTRICT); n->wait_ms = $9;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space OWNER TO UserId opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = CHG_OWNER; n->relname = $3; n->name = $6; n->wait_ms = $7;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space SET ONLINE opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = SET_ONLINE; n->relname = $3; n->wait_ms = $6;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space ENABLE operation_commalist opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = ENABLE_OP; n->relname = $3; n->acl_mask = $5; n->wait_ms = $6;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space DISABLE operation_commalist opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = DISABLE_OP; n->relname = $3; n->acl_mask = $5; n->wait_ms = $6;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space SET OFFLINE opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = SET_OFFLINE; n->relname = $3; n->wait_ms = $6;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space SET PARTITION ColId ONLINE opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = PART_ONLINE; n->relname = $3; n->parti_name= $6; n->wait_ms = $8;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space SET PARTITION ColId OFFLINE opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = PART_OFFLINE; n->relname = $3; n->parti_name = $6; n->wait_ms = $8;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space DROP PARTITION ColId opt_rebuild_idx opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = DROP_PART; n->relname = $3; n->parti_name = $6; n->rebuild_idx = $7; n->wait_ms = $8;//add opt_wait bysdc@20190508 $$ = (Node *)n; } //why 2016-11-03 add opt_rebuild_idx | ALTER TABLE name_space TRUNCATE PARTITION ColId opt_rebuild_idx opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = TRUNC_PART; n->relname = $3; n->parti_name = $6; n->rebuild_idx = $7; //why 2016-11-03 add n->wait_ms = $8;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space ADD PARTITION ColId VALUES '(' parti_values ')' opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = ADD_PART; n->relname = $3; n->parti_name = $6; n->parti_type = LIST_PARTITION; n->parti_vals = $9; n->wait_ms = $11;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space ADD PARTITION ColId VALUES LESS THAN '(' parti_values ')' opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = ADD_PART; n->relname = $3; n->parti_name = $6; n->parti_type = RANGE_PARTITION; n->parti_vals = $11; n->wait_ms = $13;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space REBUILD HEAP opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = REBLD_HEAP; n->relname = $3; n->wait_ms = $6;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space SET SLOW MODIFY ON opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = SET_SLOW_MODI; n->relname = $3; n->wait_ms = $8;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | ALTER TABLE name_space SET SLOW MODIFY OFF opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = CLR_SLOW_MODI; n->relname = $3; n->wait_ms = $8;//add opt_wait bysdc@20190508 $$ = (Node *)n; } /* ++bysdc@20201116 */ | ALTER TABLE name_space SET CACHE BY '(' name_list ')' opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = SET_CACHE_ON; n->relname = $3; n->cache_keys = $8; n->wait_ms = $10; $$ = (Node *)n; } | ALTER TABLE name_space SET CACHE OFF opt_wait { AlterTableStmt *n = makeNode(AlterTableStmt); n->action = SET_CACHE_OFF; n->relname = $3; n->wait_ms = $7; $$ = (Node *)n; } ; add_columns: ADD opt_column table_elements { $$ = $3; } | ADD opt_column '(' table_elements ')' { $$ = $4; } ; alter_columns: ALTER opt_column alt_columns { $$ = $3; } | ALTER opt_column '(' alt_columns ')' { $$ = $4; } ; drop_columns: DROP COLUMN name_list { $$ = $3; } ; enable_disable: { $$ = true; } | ENABLE { $$ = true; } | DISABLE { $$ = false; } ; opt_validate: { $$ = true; } | VALIDATE { $$ = true; } | NOVALIDATE { $$ = false; } ; exceptions_opt: { $$ = (char*)NULL; } | EXCEPTIONS INTO name_space { $$ = (char*)$3; } ; cascade_opt: { $$ = false; } | CASCADE { $$ = true; } ; keep_drop_opt: { $$ = false; } | KEEP INDEX { $$ = true; } | DROP INDEX { $$ = false; } ; opt_rebuild_idx: { $$ = false; } | REBUILD GLOBAL INDEX { $$ = true; } ; alt_columns: alter_column_item { $$ = makeList1($1); } | columnDef { $$ = makeList1($1); } | alt_columns ',' alter_column_item { $$ = lappend($1,$3); } | alt_columns ',' columnDef { $$ = lappend($1,$3); } ; alter_column_item: ColId SET DEFAULT b_expr { AlterColumn *p_alt = makeNode(AlterColumn); p_alt->col_name = $1; /* Treat SET DEFAULT NULL the same as DROP DEFAULT */ if (exprIsNullConstant($4)) p_alt->def_val = (Node*)NULL; else p_alt->def_val = $4; p_alt->alt_type = ADD_DEFAULT_VAL; $$ = (Node*)p_alt; } |ColId DROP DEFAULT { AlterColumn *p_alt = makeNode(AlterColumn); p_alt->col_name = $1; p_alt->alt_type = DROP_DEFAULT_VAL; $$ =(Node*) p_alt; } |ColId SET NOT _NULL { AlterColumn *p_alt = makeNode(AlterColumn); p_alt->col_name = $1; p_alt->alt_type = SET_NOT_NULL; $$ =(Node*) p_alt; } | ColId SET NOTNULL { AlterColumn *p_alt = makeNode(AlterColumn); p_alt->col_name = $1; p_alt->alt_type = SET_NOT_NULL; $$ =(Node*) p_alt; } | ColId SET _NULL { AlterColumn *p_alt = makeNode(AlterColumn); p_alt->col_name = $1; p_alt->alt_type = CLR_NOT_NULL; $$ =(Node*) p_alt; } | ColId DROP NOT _NULL { AlterColumn *p_alt = makeNode(AlterColumn); p_alt->col_name = $1; p_alt->alt_type = CLR_NOT_NULL; $$ =(Node*) p_alt; } | ColId DROP NOTNULL { AlterColumn *p_alt = makeNode(AlterColumn); p_alt->col_name = $1; p_alt->alt_type = CLR_NOT_NULL; $$ =(Node*) p_alt; } ; alter_behavior: /*empty*/ { $$ = RESTRICT;} | CASCADE { $$ = CASCADE; } | RESTRICT { $$ = RESTRICT;} ; /***************************************************************************** * * truncate table relname * *****************************************************************************/ //add opt_wait bysdc@20190508 TruncateStmt: TRUNCATE opt_table name_space opt_wait { TruncateStmt *n = makeNode(TruncateStmt); n->relName = $3; n->wait_ms = $4;//add opt_wait bysdc@20190508 $$ = (Node *)n; } ; /***************************************************************************** * * drop table relname {CASCADE|RESTRICT} * *****************************************************************************/ DropTabStmt:DROP TABLE opt_if_exists name_space alter_behavior { DropStmt *p_stmt = makeNode(DropStmt); p_stmt->if_exists = $3; p_stmt->obj_name = $4; p_stmt->behavior = ($5==CASCADE? OP_CASCADE : OP_RESTRICT); p_stmt->drop_type = DROP_TABLE; $$ = (Node*)p_stmt; SetNodePos($$); } ; opt_if_exists:/*empty*/ { $$ = false; } | IF EXISTS { $$ = true; } ; /***************************************************************************** * why 2019-03-25 add * flashback table relname * *****************************************************************************/ FlashBackStmt:FLASHBACK TABLE name_space TO BEFORE DROP { FlashBackStmt * p_stmt = makeNode(FlashBackStmt); p_stmt->action = 1; p_stmt->tab_name = $3; $$ = (Node*)p_stmt; SetNodePos($$); } |FLASHBACK TABLE name_space TO BEFORE DROP RENAME TO ColId { FlashBackStmt * p_stmt = makeNode(FlashBackStmt); p_stmt->action = 1; p_stmt->tab_name = $3; p_stmt->new_name = $9; $$ = (Node*)p_stmt; SetNodePos($$); } ; /***************************************************************************** * ++bysdc@20200415 * xugu profile support * *****************************************************************************/ CreateProfileStmt:CREATE PROFILE name_space LIMIT ProfileList { CreateProfileStmt * p_stmt = makeNode(CreateProfileStmt); p_stmt->profile_lists = $5; $$ = (Node*)p_stmt; } ; ProfileList:ProfileItem { $$ = makeList1($1); } | ProfileList ProfileItem { $$ = lappend($1,$2); } ; ProfileItem: SESSION_PER_USER ProfileValue { ProfileItem * p_stmt = makeNode(ProfileItem); p_stmt->profile_type = PROF_SESSION_PER_USER; p_stmt->value = $2; $$ = (Node*)p_stmt; } | CPU_PER_SESSION ProfileValue { ProfileItem * p_stmt = makeNode(ProfileItem); p_stmt->profile_type = PROF_CPU_PER_SESSION; p_stmt->value = $2; $$ = (Node*)p_stmt; } | CPU_PER_CALL ProfileValue { ProfileItem * p_stmt = makeNode(ProfileItem); p_stmt->profile_type = PROF_CPU_PER_CALL; p_stmt->value = $2; $$ = (Node*)p_stmt; } | MAX_CONNECT_TIME ProfileValue { ProfileItem * p_stmt = makeNode(ProfileItem); p_stmt->profile_type = PROF_MAX_CONNECT_TIME; p_stmt->value = $2; $$ = (Node*)p_stmt; } | MAX_IDLE_TIME ProfileValue { ProfileItem * p_stmt = makeNode(ProfileItem); p_stmt->profile_type = PROF_MAX_IDLE_TIME; p_stmt->value = $2; $$ = (Node*)p_stmt; } | READS_PER_SESSION ProfileValue { ProfileItem * p_stmt = makeNode(ProfileItem); p_stmt->profile_type = PROF_READS_PER_SESSION; p_stmt->value = $2; $$ = (Node*)p_stmt; } | READS_PER_CALL ProfileValue { ProfileItem * p_stmt = makeNode(ProfileItem); p_stmt->profile_type = PROF_READS_PER_CALL; p_stmt->value = $2; $$ = (Node*)p_stmt; } | TOTAL_RESOURCE_LIMIT ProfileValue { ProfileItem * p_stmt = makeNode(ProfileItem); p_stmt->profile_type = PROF_TOTAL_RESOURCE_LIMIT; p_stmt->value = $2; $$ = (Node*)p_stmt; } | PRIVATE_SGA ProfileValue { ProfileItem * p_stmt = makeNode(ProfileItem); p_stmt->profile_type = PROF_PRIVATE_SGA; p_stmt->value = $2; $$ = (Node*)p_stmt; } | MAX_STORE_NUM ProfileValue { ProfileItem * p_stmt = makeNode(ProfileItem); p_stmt->profile_type = PROF_MAX_STORE_NUM; p_stmt->value = $2; $$ = (Node*)p_stmt; } | CONNECT_NODES ProfileValue { ProfileItem * p_stmt = makeNode(ProfileItem); p_stmt->profile_type = PROF_CONNECT_NODES; p_stmt->value = $2; $$ = (Node*)p_stmt; } | STORE_NODES ProfileValue { ProfileItem * p_stmt = makeNode(ProfileItem); p_stmt->profile_type = PROF_STORE_NODES; p_stmt->value = $2; $$ = (Node*)p_stmt; } | TEMPSPACE_QUOTA ProfileValue { ProfileItem * p_stmt = makeNode(ProfileItem); p_stmt->profile_type = PROF_TEMPSPACE_QUOTA; p_stmt->value = $2; $$ = (Node*)p_stmt; } | CURSOR_QUOTA ProfileValue { ProfileItem * p_stmt = makeNode(ProfileItem); p_stmt->profile_type = PROF_CURSOR_QUOTA; p_stmt->value = $2; $$ = (Node*)p_stmt; } | FAILED_LOGIN_ATTEMPTS ProfileValue { ProfileItem * p_stmt = makeNode(ProfileItem); p_stmt->profile_type = PROF_FAILED_LOGIN_ATTEMPTS; p_stmt->value = $2; $$ = (Node*)p_stmt; } | PASSWORD_LIFE_PERIOD ProfileValue { ProfileItem * p_stmt = makeNode(ProfileItem); p_stmt->profile_type = PROF_PASSWORD_LIFE_PERIOD; p_stmt->value = $2; $$ = (Node*)p_stmt; } | PASSWORD_LOCK_TIME ProfileValue { ProfileItem * p_stmt = makeNode(ProfileItem); p_stmt->profile_type = PROF_PASSWORD_LOCK_TIME; p_stmt->value = $2; $$ = (Node*)p_stmt; } ; ProfileValue: ICONST { $$ = $1; } | DEFAULT { $$ = 0; } | UNLIMITED { $$ = -1; } ; /***************************************************************************** * * QUERY : * open * *****************************************************************************/ OpenCursorStmt: OPEN ColId { OpenCursorStmt *p_stmt = makeNode(OpenCursorStmt); p_stmt->cursor_name = $2; $$ = (Node*)p_stmt; SetNodePos($$); } | OPEN ColId '(' expr_list ')' { OpenCursorStmt *p_stmt = makeNode(OpenCursorStmt); p_stmt->cursor_name = $2; p_stmt->params = $4; $$ = (Node*)p_stmt; SetNodePos($$); } /*why 2015-11-18 modify (add opt_using)old: | OPEN ColId FOR b_expr { OpenCursorStmt *p_stmt = makeNode(OpenCursorStmt); p_stmt->cursor_name = $2; p_stmt->cursor_var = (A_Expr*)$4; $$ = (Node*)p_stmt; SetNodePos($$); } | OPEN ColId FOR select_no_parens { OpenCursorStmt *p_stmt = makeNode(OpenCursorStmt); p_stmt->cursor_name = $2; p_stmt->select_stmt = (SelectStmt*)$4; $$ = (Node*)p_stmt; SetNodePos($$); }*/ | OPEN ColId FOR b_expr opt_using { OpenCursorStmt *p_stmt = makeNode(OpenCursorStmt); p_stmt->cursor_name = $2; p_stmt->cursor_var = (A_Expr*)$4; p_stmt->params = $5; $$ = (Node*)p_stmt; SetNodePos($$); } | OPEN ColId FOR select_no_parens opt_using { OpenCursorStmt *p_stmt = makeNode(OpenCursorStmt); p_stmt->cursor_name = $2; p_stmt->select_stmt = (SelectStmt*)$4; p_stmt->params = $5; $$ = (Node*)p_stmt; SetNodePos($$); } ; /***************************************************************************** * * QUERY : * close * *****************************************************************************/ CloseCursorStmt: CLOSE { CloseCursorStmt *n = makeNode(CloseCursorStmt); n->cursor_name = NULL; $$ = (Node *)n; } | CLOSE ColId { CloseCursorStmt *n = makeNode(CloseCursorStmt); n->cursor_name = $2; $$ = (Node *)n; } ; CheckTabStmt: CHECK TABLE name_list { CheckTabStmt *p_stmt = makeNode(CheckTabStmt); p_stmt->names = $3; $$ = (Node*) p_stmt; } ; /***************************************************************************** * * QUERY : * CREATE relname * *****************************************************************************/ CreateTabStmt: CREATE OptTemp TABLE opt_if_not_exists name_space '(' table_elements ')' on_commit_del ena_trans_opt opt_phyical_props opt_partitioning_clause opt_subpartitioning_clause opt_constraint_props opt_store_props opt_comment opt_encrypt { CreateTabStmt *n = makeNode(CreateTabStmt); n->temp = $2; n->if_not_exists = $4; n->relname = $5; n->table_eles = $7; n->constraints = NIL; n->on_commit_del = $9; n->phy_prop = (PhysiProp*)$11; n->parti_prop = (PartiProp*)$12; n->subpa_prop = (PartiProp*)$13; n->cons_props = (List*)$14; n->store_prop = (StoreProp*)$15; n->comments = $16; n->parallel = 1; n->encry_name = $17; $$ = (Node *)n; } ; opt_if_not_exists: IF NOT EXISTS { $$ = true; } |/*empty*/ { $$ = false; } ; on_commit_del: { $$ = -1; } | ON COMMIT _DELETE ROWS { $$ = 1; } | ON COMMIT PRESERVE ROWS { $$ = 0; } ; opt_phyical_props: { $$ = (Node*)makeNode(PhysiProp); } | ORGANIZATION HEAP { $$ = (Node*)makeNode(PhysiProp); } | ORGANIZATION INDEX { PhysiProp *p_phy = makeNode(PhysiProp); p_phy->is_iot = true; $$ = (Node*)p_phy; } | ORGANIZATION INDEX '(' name_list ')' { PhysiProp *p_phy = makeNode(PhysiProp); p_phy->is_iot = true; p_phy->iot_idx_cols = $4; $$ = (Node*)p_phy; } | ORGANIZATION EXTERNAL '(' opt_file_type opt_default_dir LOCATION Sconst ')' { PhysiProp *p_phy = makeNode(PhysiProp); p_phy->file_type = $4; p_phy->default_dir = $5; p_phy->file_location = dbs2utf($7); p_phy->is_file = true; $$ = (Node*)p_phy; } | ORGANIZATION EXTERNAL '(' opt_file_type opt_default_dir ACCESS PARAMETERS '(' RECORDS DELIMITED BY terminated_chars FIELDS TERMINATED BY terminated_chars opt_badfile opt_discordfile opt_logfile opt_missing_field_value ')' LOCATION Sconst ')' { PhysiProp *p_phy = makeNode(PhysiProp); p_phy->file_type = $4; p_phy->default_dir = $5; p_phy->row_delimiter = $12; p_phy->col_delimiter = $16; p_phy->bad_file = $17; p_phy->discord_file = $18; p_phy->log_file = $19; p_phy->missing_value = $20; p_phy->file_location = $23; p_phy->is_file = true; $$ = (Node*)p_phy; } ; /*enable or disable transaction support*/ ena_trans_opt: /*empty*/ { $$ = 1; /*default decide by runtime*/ } | DISABLE TRANSACTION { $$ = 0; /*unsupport transaction*/ } | ENABLE TRANSACTION { $$ = 2; /*support transaction*/ } ; opt_file_type: { $$ = NULL; } | TYPE ColId { $$ = $2; } ; opt_default_dir: { $$ = NULL; } | DEFAULT _DIR ColId { $$ = $3; } | DEFAULT _DIR Sconst { $$ = dbs2utf($3); } ; opt_badfile: { $$ = NULL; } | BADFILE Sconst { $$ = dbs2utf($2); } ; opt_discordfile: { $$ = NULL; } | DISCORDFILE Sconst { $$ = dbs2utf($2); } ; opt_logfile: { $$ = NULL; } | LOGFILE Sconst { $$ = dbs2utf($2); } ; opt_missing_field_value: { $$ = NULL; } | MISSING FIELD VALUES ARE c_expr { $$ = $5; } ; opt_store_props: /*empty*/ { $$ = NULL; } | store_props { $$ = $1; } ; store_props: store_prop { $$ = $1; } | store_props store_prop { StoreProp *p_attr1 = (StoreProp*)$1; StoreProp *p_attr2 = (StoreProp*)$2; if(p_attr2) { if(p_attr2->pct_free>0) p_attr1->pct_free = p_attr2->pct_free; if(p_attr2->copy_num>0) p_attr1->copy_num = p_attr2->copy_num; if(p_attr2->hot_num>0) p_attr1->hot_num = p_attr2->hot_num; p_attr1->zone_ply = p_attr2->zone_ply;/*why 2019-06-13 add*/ p_attr1->flags |= p_attr2->flags; } $$ = (Node*)$1; } ; store_prop: PCTFREE ICONST { StoreProp *p_prop = makeNode(StoreProp); p_prop->pct_free = $2; if(p_prop->pct_free>99 || p_prop->pct_free<0) { SetParsePos(); add_parse_error(60); } $$ = (Node*)p_prop; } | PCTUSED ICONST { StoreProp *p_prop = makeNode(StoreProp); p_prop->pct_free = 100 - $2; if(p_prop->pct_free>99 || p_prop->pct_free<0) { SetParsePos(); add_parse_error(61); } $$ = (Node*)p_prop; } | HOTSPOT ICONST { StoreProp *p_prop = makeNode(StoreProp); p_prop->hot_num = $2; $$ = (Node*)p_prop; } | CACHE { StoreProp *p_prop = makeNode(StoreProp); p_prop->flags = ENABLE_CACHE; $$ = (Node*)p_prop; } | NOCACHE { StoreProp *p_prop = makeNode(StoreProp); p_prop->flags = DISABLE_CACHE; $$ = (Node*)p_prop; } | LOGGING { StoreProp *p_prop = makeNode(StoreProp); p_prop->flags = ENABLE_LOGGING; $$ = (Node*)p_prop; } | NOLOGGING { StoreProp *p_prop = makeNode(StoreProp); p_prop->flags = DISABLE_LOGGING; $$ = (Node*)p_prop; } | COMPRESS { $$ = NULL; } | NOCOMPRESS { $$ = NULL; } | INITRANS ICONST { $$ = NULL; } | MAXTRANS ICONST { $$ = NULL; } | COMPUTE STATISTICS { $$ = NULL; } | CACHE READS { StoreProp *p_prop = makeNode(StoreProp); p_prop->flags = CACHE_READ; $$ = (Node*)p_prop; } | COPY NUMBER ICONST { StoreProp *p_prop = makeNode(StoreProp); p_prop->copy_num = $3;; $$ = (Node*)p_prop; } | PCTVERSION ICONST { $$ = NULL; } /*why 2019-06-13 add storage zone*/ | ZONE BY ICONST { StoreProp *p_prop = makeNode(StoreProp); p_prop->zone_ply = $3; $$ = (Node*)p_prop; } | ZONE BY LOCAL { StoreProp *p_prop = makeNode(StoreProp); p_prop->zone_ply = -1; $$ = (Node*)p_prop; } /*end */ ; opt_partitioning_clause: { $$ = (Node*)NULL; } | PARTITION BY RANGE '(' name_list ')' opt_parti_interval PARTITIONS '(' range_parti_items ')' { PartiProp *p_par = makeNode(PartiProp); p_par->partition_type = RANGE_PARTITION; p_par->col_names = $5; p_par->interval = $7; p_par->partitions = $10; p_par->parti_num = length($10); $$ = (Node *)p_par; } | PARTITION BY LIST '(' name_list ')' PARTITIONS '(' list_parti_items ')' { PartiProp *p_par = makeNode(PartiProp); p_par->partition_type = LIST_PARTITION; p_par->col_names = $5; p_par->partitions = $9; p_par->parti_num = length($9); $$ = (Node*)p_par; } | PARTITION BY HASH '(' name_list ')' PARTITIONS ICONST { PartiProp *p_par = makeNode(PartiProp); p_par->partition_type = HASH_PARTITION; p_par->col_names = $5; p_par->parti_num = $8; $$ = (Node*)p_par; } | PARTITION BY HASH '(' name_list ')' PARTITIONS '(' name_list ')' { PartiProp *p_par = makeNode(PartiProp); p_par->partition_type = HASH_PARTITION; p_par->col_names = $5; p_par->parti_num = length($9); p_par->parti_names = $9; $$ = (Node*)p_par; } ; //why 2017-02-22 modify old: /* opt_parti_interval: { $$ = 0; } | INTERVAL ICONST _YEAR { $$ = $2 | 0x10000000; } | INTERVAL ICONST _MONTH { $$ = $2; } ; */ opt_parti_interval: /*empty*/ { $$ = 0; } | INTERVAL ICONST _YEAR { //++bysdc@20190214 for bug2967 if($2 >= 0x01000000 || $2 <= 0) { SetParsePos(); add_parse_error(1208); } $$ = $2 | 0x01000000; } | INTERVAL ICONST _MONTH { //++bysdc@20190214 for bug2967 if($2 >= 0x01000000 || $2 <= 0) { SetParsePos(); add_parse_error(1208); } $$ = $2 | 0x02000000; } | INTERVAL ICONST _DAY { //++bysdc@20190214 for bug2967 if($2 >= 0x01000000 || $2 <= 0) { SetParsePos(); add_parse_error(1208); } $$ = $2 | 0x03000000; } | INTERVAL ICONST _HOUR { //++bysdc@20190214 for bug2967 if($2 >= 0x01000000 || $2 <= 0) { SetParsePos(); add_parse_error(1208); } $$ = $2 | 0x04000000; } ; //end opt_subpartitioning_clause: { $$ = NULL; } | SUBPARTITION BY HASH '(' name_list ')' SUBPARTITIONS ICONST { PartiProp *p_par = makeNode(PartiProp); p_par->partition_type = HASH_PARTITION; p_par->col_names = $5; p_par->parti_num = $8; $$ = (Node*)p_par; } | SUBPARTITION BY HASH '(' name_list ')' SUBPARTITIONS '(' name_list ')' { PartiProp *p_par = makeNode(PartiProp); p_par->partition_type = HASH_PARTITION; p_par->col_names = $5; p_par->parti_num = length($9); p_par->parti_names = $9; $$ = (Node*)p_par; } | SUBPARTITION BY LIST '(' name_list ')' SUBPARTITIONS '(' list_parti_items ')' { PartiProp *p_par = makeNode(PartiProp); p_par->partition_type = LIST_PARTITION; p_par->col_names = $5; p_par->partitions = $9; p_par->parti_num = length($9); $$ = (Node*)p_par; } | SUBPARTITION BY RANGE '(' name_list ')' SUBPARTITIONS '(' range_parti_items ')' { PartiProp *p_par = makeNode(PartiProp); p_par->partition_type = RANGE_PARTITION; p_par->col_names = $5; p_par->partitions = $9; p_par->parti_num = length($9); $$ = (Node*)p_par; } ; range_parti_items: range_parti_item { $$ = makeList1($1); } | range_parti_items ',' range_parti_item { $$ = lappend($1,$3); } ; range_parti_item: '(' parti_values ')' { PartiItem *p_par = makeNode(PartiItem); p_par->values = $2; $$ = (Node*)p_par; } | '(' MAXVALUES ')' { PartiItem *p_par = makeNode(PartiItem); $$ = (Node*)p_par; } | ColId VALUES LESS THAN '(' parti_values ')' { PartiItem *p_par = makeNode(PartiItem); p_par->name = $1; p_par->values = $6; $$ = (Node*)p_par; } | ColId VALUES LESS THAN '(' MAXVALUES ')' { PartiItem *p_par = makeNode(PartiItem); p_par->name = $1; $$ = (Node*)p_par; } ; list_parti_items: list_parti_item { $$ = makeList1($1); } | list_parti_items ',' list_parti_item { $$ = lappend($1,$3); } ; list_parti_item: '(' parti_values ')' { PartiItem *p_par = makeNode(PartiItem); p_par->values = $2; $$ = (Node*)p_par; } | ColId VALUES '(' parti_values ')' { PartiItem *p_par = makeNode(PartiItem); p_par->name = $1; p_par->values = $4; $$ = (Node*)p_par; } | '(' OTHERVALUES ')' { PartiItem *p_par = makeNode(PartiItem); $$ = (Node*)p_par; } | ColId VALUES '(' OTHERVALUES ')' { PartiItem *p_par = makeNode(PartiItem); p_par->name = $1; $$ = (Node*)p_par; } ; parti_values: c_expr { $$ = makeList1($1); } | parti_values ',' c_expr { $$ = lappend($1,$3); } ; AssistantStmt: '@' '(' name_list ')' { $$ = (Node*)$3; } | LEXER TextPattern { $$ = $2; } //++bysdc@20200411 | HINT ALL_ROWS { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type= HINT_ALL_ROWS; $$ = (Node*)p_hn; } | HINT FIRST_ROWS { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type= HINT_FIRST_ROWS; $$ = (Node*)p_hn; } | HINT CHOOSE { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type= HINT_CHOOSE; $$ = (Node*)p_hn; } | HINT RULE { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type= HINT_RULE; $$ = (Node*)p_hn; } | HINT RESULT_CACHE { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type= HINT_RESULT_CACHE; $$ = (Node*)p_hn; } | HINT FULL '(' name_space ')' { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type = HINT_FULL; p_hn->tab_list = makeList1($4); $$ = (Node*)p_hn; } | HINT INDEX '(' name_space name ')' { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type= HINT_INDEX; p_hn->tab_list = makeList1($4); p_hn->idx_list = makeList1($5); $$ = (Node*)p_hn; } | HINT NOINDEX '(' name_space name ')' { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type= HINT_NOINDEX; p_hn->tab_list = makeList1($4); p_hn->idx_list = makeList1($5); $$ = (Node*)p_hn; } | HINT INDEX_JOIN { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type= HINT_INDEX_JOIN; $$ = (Node*)p_hn; } | HINT INDEX_ASC { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type= HINT_INDEX_ASC; $$ = (Node*)p_hn; } | HINT INDEX_DESC { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type= HINT_INDEX_DESC; $$ = (Node*)p_hn; } | HINT INDEX_FSS { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type= HINT_INDEX_FSS; $$ = (Node*)p_hn; } | HINT USE_HASH '(' name_space ',' name_space ')' { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type= HINT_USE_HASH; p_hn->tab_list = makeList2($4,$6); $$ = (Node*)p_hn; } | HINT CACHE { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type= HINT_CACHE; $$ = (Node*)p_hn; } | HINT NOCACHE { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type= HINT_NOCACHE; $$ = (Node*)p_hn; } | HINT PARALLEL { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type= HINT_PARALLEL; $$ = (Node*)p_hn; } | HINT APPEND { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type= HINT_APPEND; $$ = (Node*)p_hn; } | HINT NOAPPEND { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type= HINT_NOAPPEND; $$ = (Node*)p_hn; } | HINT ORDERD { HintNode *p_hn = makeNode(HintNode); p_hn->hint_type= HINT_ORDERD; $$ = (Node*)p_hn; } //end ; TextPattern: TextPattern '&' TextPattern { TextPattern *p_pattern = makeNode(TextPattern); p_pattern->l_pattern = $1; p_pattern->r_pattern = $3; p_pattern->pattern_ch = '&'; $$ = (Node*)p_pattern; } | TextPattern ',' TextPattern { TextPattern *p_pattern = makeNode(TextPattern); p_pattern->l_pattern = $1; p_pattern->r_pattern = $3; p_pattern->pattern_ch = '&'; $$ = (Node*)p_pattern; } | TextPattern '|' TextPattern { TextPattern *p_pattern = makeNode(TextPattern); p_pattern->l_pattern = $1; p_pattern->r_pattern = $3; p_pattern->pattern_ch = '|'; $$ = (Node*)p_pattern; } | TextPattern '^' TextPattern { TextPattern *p_pattern = makeNode(TextPattern); p_pattern->l_pattern = $1; p_pattern->r_pattern = $3; p_pattern->pattern_ch = '^'; $$ = (Node*)p_pattern; } | TextPattern '-' TextPattern { TextPattern *p_pattern = makeNode(TextPattern); p_pattern->l_pattern = $1; p_pattern->r_pattern = $3; p_pattern->pattern_ch = '^'; $$ = (Node*)p_pattern; } | '[' TextItem ']' { TextPattern *p_pattern = makeNode(TextPattern); p_pattern->l_pattern = (Node*)$2; p_pattern->pattern_ch = '['; $$ = (Node*)p_pattern; } | TextItem { TextPattern *p_pattern = makeNode(TextPattern); p_pattern->l_pattern = (Node*)$1; p_pattern->pattern_ch = 't'; $$ = (Node*)p_pattern; } | '(' TextPattern ')' { $$ = $2; } ; TextItem: Keywords | IDENT | FCONST | ICONST { $$ = (char*)tmalloc(12); i4toa($1,$$); } ; parallel_opt: { $$ = 1; /*no parallel*/ } | NOPARALLEL { $$ = 1; /*no parallel */ } | PARALLEL { $$ = -1; /*use default set */ } | PARALLEL ICONST { $$ = $2; } ; parallel_opt2: { $$ = 1; /*no parallel*/ } | NOPARALLEL { $$ = 1; /*no parallel*/ } | PARALLEL { $$ = -1; /*use default set */ } | PARALLEL ICONST { $$ = $2; } | PARALLEL ICONST ',' ICONST { $$ = $2 | $4<<16; } ; opt_constraint_props: { $$ = NIL; } | constraint_props { $$ = $1; } ; constraint_props: constraint_prop { $$ = makeList1($1); } | constraint_props constraint_prop { $$ = lappend($1,$2); } ; constraint_prop: which_constraint enable_disable opt_validate exceptions_opt cascade_opt { ConstProp *p_cons_prop = makeNode(ConstProp); p_cons_prop->cons_type = ((ConstraintObj*)$1)->cons_type; p_cons_prop->cons_name = ((ConstraintObj*)$1)->cons_name; p_cons_prop->col_names = ((ConstraintObj*)$1)->col_names; p_cons_prop->enable = $2; p_cons_prop->validate = $3; p_cons_prop->exception_table = $4; p_cons_prop->cascade = $5; $$ = (Node*)p_cons_prop; } ; which_constraint: UNIQUE '(' name_list ')' { ConstraintObj *p_obj = New(ConstraintObj); p_obj->cons_type = CONSTR_UNIQUE; p_obj->col_names = $3; $$ = (Node*)p_obj; } | PRIMARY KEY { ConstraintObj *p_obj = New(ConstraintObj); p_obj->cons_type = CONSTR_PRIMARY; $$ = (Node*)p_obj; } | CONSTRAINT ColId { ConstraintObj *p_obj = New(ConstraintObj); p_obj->cons_type = CONSTR_NON; p_obj->cons_name = $2; $$ = (Node*)p_obj; } ; /* * Redundancy here is needed to avoid shift/reduce conflicts, * since TEMP is not a reserved word. */ OptTemp: TEMPORARY { $$ = 1; } | TEMP { $$ = 1; } | LOCAL TEMPORARY { $$ = 1; } | LOCAL TEMP { $$ = 1; } | GLOBAL TEMPORARY { $$ = 2; } | GLOBAL TEMP { $$ = 2; } | /*EMPTY*/ { $$ = 0; } ; table_elements: table_elements ',' table_element { if ($3 != (Node*)NULL) $$ = lappend($1, $3); else $$ = $1; } | table_element { if ($1 != (Node*)NULL) $$ = makeList1($1); else $$ = NIL; } ; table_element: columnDef { $$ = $1; } | TableConstraint { $$ = $1; } ; columnDef: ColId TypeName opt_serial ColQualList opt_collate opt_comment { ColumnDef *n = makeNode(ColumnDef); n->colname = $1; n->type_name = (Typenam*)$2; if($3!=NULL) { n->is_sequence = true; n->p_serial_def = (SerialDef*)$3; } n->constraints = $4; if ($5 != (void*)NULL) { SetParsePos(); add_parse_error(214,$4); } n->comments = $6; $$ = (Node *)n; SetNodePos($$); } ; opt_serial: /*empty*/ { $$ = NULL; } | IDENTITY { SerialDef *p_def = makeNode(SerialDef); p_def->ini_val = (Value*)makeInteger(1); p_def->step_val =(Value*)makeInteger(1); $$ = (Node*)p_def; SetNodePos($$); } | IDENTITY '(' IntegerOnly ',' IntegerOnly ')' { SerialDef *p_def = makeNode(SerialDef); p_def->ini_val = (Value*)$3; p_def->step_val =(Value*) $5; $$ = (Node*)p_def; SetNodePos($$); } ; ColQualList: ColQualList ColConstraint { $$ = lappend($1, $2); } | /*EMPTY*/ { $$ = NIL; } ; ColConstraint: CONSTRAINT name ColConstraintElem { switch (nodeTag($3)) { case T_ConstraintDef: { ConstraintDef *n = (ConstraintDef *)$3; n->constr_name = $2; } break; case T_FkConstraint: { FkConstraint *n = (FkConstraint *)$3; n->constr_name = $2; } break; default: break; } $$ = $3; } | ColConstraintElem { $$ = $1; } | ConstraintAttr { $$ = $1; } ; /* DEFAULT NULL is already the default for . * But define it here and carry it forward into the system * to make it explicit. * - thomas 1998-09-13 * * WITH NULL and NULL are not SQL92-standard syntax elements, * so leave them out. Use DEFAULT NULL to explicitly indicate * that a column may have that value. WITH NULL leads to * shift/reduce conflicts with WITH TIME ZONE anyway. * - thomas 1999-01-08 * * DEFAULT expression must be b_expr not b_expr to prevent shift/reduce * conflict on NOT (since NOT might start a subsequent NOT NULL constraint, * or be part of b_expr NOT LIKE or similar constructs). */ ColConstraintElem: NOT _NULL enable_disable { ConstraintDef *n = makeNode(ConstraintDef); n->contype = CONSTR_NOTNULL; n->constr_name = (char*)NULL; n->raw_expr = (Node*)NULL; n->cooked_expr = (char*)NULL; n->keys = NIL; n->enable = $3; $$ = (Node *)n; SetNodePos($$); } | _NULL enable_disable { ConstraintDef *n = makeNode(ConstraintDef); n->contype = CONSTR_NULL; n->constr_name = (char*)NULL; n->raw_expr = (Node*)NULL; n->cooked_expr = (char*)NULL; n->keys = (List*)NULL; n->enable = $2; $$ = (Node *)n; SetNodePos($$); } | UNIQUE enable_disable { ConstraintDef *n = makeNode(ConstraintDef); n->contype = CONSTR_UNIQUE; n->constr_name = (char*)NULL; n->raw_expr = (Node*)NULL; n->cooked_expr = (char*)NULL; n->keys = (List*)NULL; n->enable = $2; $$ = (Node *)n; SetNodePos($$); } | PRIMARY KEY enable_disable { ConstraintDef *n = makeNode(ConstraintDef); n->contype = CONSTR_PRIMARY; n->constr_name = (char*)NULL; n->raw_expr = (Node*)NULL; n->cooked_expr = (char*)NULL; n->keys = (List*)NULL; n->enable = $3; $$ = (Node *)n; SetNodePos($$); } | CHECK '(' bool_expr ')' enable_disable { ConstraintDef *n = makeNode(ConstraintDef); n->contype = CONSTR_CHECK; n->constr_name = (char*)NULL; n->raw_expr = $3; n->cooked_expr = (char*)NULL; n->keys = (List*)NULL; n->enable = $5; $$ = (Node *)n; SetNodePos($$); } | DEFAULT b_expr enable_disable { ConstraintDef *n = makeNode(ConstraintDef); n->contype = CONSTR_DEFAULT; n->constr_name = (char*)NULL; if (exprIsNullConstant($2)) { /* DEFAULT NULL should be reported as empty expr */ n->raw_expr = (Node*)NULL; } else { n->raw_expr = $2; } n->cooked_expr = (char*)NULL; n->keys = (List*)NULL; n->enable = $3; $$ = (Node *)n; SetNodePos($$); } | REFERENCES name_space opt_column_list key_match key_actions enable_disable { FkConstraint *n = makeNode(FkConstraint); n->constr_name = (char*)NULL; n->pktable_name = $2; n->fk_attrs = NIL; n->pk_attrs = $3; n->match_type = $4; n->actions = $5; n->deferrable = false; n->initdeferred = false; n->enable = $6; $$ = (Node *)n; SetNodePos($$); } | FOREIGN KEY opt_fk_name REFERENCES name_space opt_column_list key_match key_actions enable_disable { FkConstraint *n = makeNode(FkConstraint); n->constr_name = $3; n->pktable_name = $5; n->fk_attrs = NIL; n->pk_attrs = $6; n->match_type = $7; n->actions = $8; n->deferrable = false; n->initdeferred = false; n->enable = $9; $$ = (Node *)n; SetNodePos($$); } ; /* * ConstraintAttr represents constraint attributes, which we parse as if * they were independent constraint clauses, in order to avoid shift/reduce * conflicts (since NOT might start either an independent NOT NULL clause * or an attribute). analyze.c is responsible for attaching the attribute * information to the preceding "REAL" constraint node, and for complaining * if attribute clauses appear in the wrong place or wrong combinations. * * See also ConstraintAttributeSpec, which can be used in places where * there is no parsing conflict. */ ConstraintAttr: DEFERRABLE { ConstraintDef *n = makeNode(ConstraintDef); n->contype = CONSTR_ATTR_DEFERRABLE; $$ = (Node *)n; } | NOT DEFERRABLE { ConstraintDef *n = makeNode(ConstraintDef); n->contype = CONSTR_ATTR_NOT_DEFERRABLE; $$ = (Node *)n; } | INITIALLY DEFERRED { ConstraintDef *n = makeNode(ConstraintDef); n->contype = CONSTR_ATTR_DEFERRED; $$ = (Node *)n; } | INITIALLY IMMEDIATE { ConstraintDef *n = makeNode(ConstraintDef); n->contype = CONSTR_ATTR_IMMEDIATE; $$ = (Node *)n; } ; /* ConstraintElem specifies constraint syntax which is not embedded into * a column definition. ColConstraintElem specifies the embedded form. * - thomas 1997-12-03 */ TableConstraint: CONSTRAINT name ConstraintElem { switch (nodeTag($3)) { case T_ConstraintDef: { ConstraintDef *n = (ConstraintDef *)$3; n->constr_name = $2; } break; case T_FkConstraint: { FkConstraint *n = (FkConstraint *)$3; n->constr_name = $2; } break; default: break; } $$ = $3; } | ConstraintElem { $$ = $1; } ; ConstraintElem: CHECK '(' bool_expr ')' enable_disable { ConstraintDef *n = makeNode(ConstraintDef); n->contype = CONSTR_CHECK; n->constr_name = (char*)NULL; n->raw_expr = $3; n->cooked_expr = (char*)NULL; n->enable = $5; $$ = (Node *)n; } | UNIQUE '(' columnList ')' enable_disable { ConstraintDef *n = makeNode(ConstraintDef); n->contype = CONSTR_UNIQUE; n->constr_name =(char*) NULL; n->raw_expr = (Node*)NULL; n->cooked_expr = (char*)NULL; n->keys = $3; n->enable = $5; $$ = (Node *)n; } | PRIMARY KEY '(' columnList ')' enable_disable { ConstraintDef *n = makeNode(ConstraintDef); n->contype = CONSTR_PRIMARY; n->constr_name = (char*)NULL; n->raw_expr = (Node*)NULL; n->cooked_expr = (char*)NULL; n->keys = $4; n->enable = $6; $$ = (Node *)n; } | FOREIGN KEY opt_fk_name '(' columnList ')' REFERENCES name_space opt_column_list key_match key_actions ConstraintAttributeSpec enable_disable { FkConstraint *n = makeNode(FkConstraint); n->constr_name = $3; n->pktable_name = $8; n->fk_attrs = $5; n->pk_attrs = $9; n->match_type = $10; n->actions = $11; n->deferrable = ($12 & 1) != 0; n->initdeferred = ($12 & 2) != 0; n->enable = $13; $$ = (Node *)n; } ; opt_fk_name: /*empty*/ { $$ = NULL; } | ColId { $$ = $1; } ; key_match: MATCH FULL { $$ = (char*)"FULL"; } | MATCH PARTIAL { $$ = (char*)"PARTIAL"; } | /*EMPTY*/ { $$ = (char*)"UNSPECIFIED"; } ; key_actions: key_delete { $$ = $1; } | key_update { $$ = $1; } | key_delete key_update { $$ = $1 | $2; } | key_update key_delete { $$ = $1 | $2; } | /*EMPTY*/ { $$ = (FKCONSTR_ON_KEY_NOACTION<is_public = true; // p_stmt->name = $5; // p_stmt->targ_db = dbs2utf($8); // p_stmt->user = $10; // p_stmt->password = $11; // $$ = (Node*)p_stmt; // } // | CREATE DATABASE LINK name CONNECT TO Sconst USER UserId user_passwd_clause // { // CreateLinkStmt *p_stmt = makeNode(CreateLinkStmt); // p_stmt->is_public = false; // p_stmt->name = $4; // p_stmt->targ_db = dbs2utf($7); /*target database uri*/ // p_stmt->user = $9; // p_stmt->password = $10; // $$ = (Node*)p_stmt; // } // ; CreateLinkStmt: Cre_Rep PUBLIC DATABASE LINK name CONNECT TO Sconst USER UserId user_passwd_clause { CreateLinkStmt *p_stmt = makeNode(CreateLinkStmt); p_stmt->is_public = true; p_stmt->name = $5; p_stmt->targ_db = dbs2utf($8); p_stmt->user = $10; p_stmt->password = $11; $$ = (Node*)p_stmt; } | Cre_Rep PUBLIC DATABASE LINK name FOR Sconst CONNECT TO Sconst USER UserId user_passwd_clause { CreateLinkStmt *p_stmt = makeNode(CreateLinkStmt); p_stmt->is_public = true; p_stmt->name = $5; p_stmt->db_type = $7; p_stmt->targ_db = dbs2utf($10); p_stmt->user = $12; p_stmt->password = $13; $$ = (Node*)p_stmt; } | CREATE DATABASE LINK name CONNECT TO Sconst USER UserId user_passwd_clause { CreateLinkStmt *p_stmt = makeNode(CreateLinkStmt); p_stmt->is_public = false; p_stmt->name = $4; p_stmt->targ_db = dbs2utf($7); /*target database uri*/ p_stmt->user = $9; p_stmt->password = $10; $$ = (Node*)p_stmt; } | CREATE DATABASE LINK name FOR Sconst CONNECT TO Sconst USER UserId user_passwd_clause { CreateLinkStmt *p_stmt = makeNode(CreateLinkStmt); p_stmt->is_public = false; p_stmt->name = $4; p_stmt->db_type = $6; p_stmt->targ_db = dbs2utf($9); /*target database uri*/ p_stmt->user = $11; p_stmt->password = $12; $$ = (Node*)p_stmt; }; DropLinkStmt: DROP DATABASE LINK name { DropStmt *p_stmt = makeNode(DropStmt); p_stmt->obj_name = $4; p_stmt->drop_type = DROP_DB_LINK; $$ = (Node*)p_stmt; SetNodePos($$); }; CreateSynonymStmt: Cre_Rep SYNONYM name_space FOR name_space { CreateSynonymStmt *p_stmt = makeNode(CreateSynonymStmt); p_stmt->cre_mode = $1; p_stmt->syn_name = $3; p_stmt->obj_name = $5; p_stmt->is_public = false; $$ = (Node*)p_stmt; } | Cre_Rep PUBLIC SYNONYM name_space FOR name_space { CreateSynonymStmt *p_stmt = makeNode(CreateSynonymStmt); p_stmt->cre_mode = $1; p_stmt->syn_name = $4; p_stmt->obj_name = $6; p_stmt->is_public = true; $$ = (Node*)p_stmt; } ; DropSynonymStmt: DROP SYNONYM name_space { DropStmt *p_stmt = makeNode(DropStmt); p_stmt->obj_name = $3; p_stmt->drop_type = DROP_SYNONYM; $$ = (Node*)p_stmt; SetNodePos($$); } | DROP PUBLIC SYNONYM name_space { DropStmt *p_stmt = makeNode(DropStmt); p_stmt->obj_name = $4; p_stmt->drop_type = DROP_PUB_SYN; $$ = (Node*)p_stmt; SetNodePos($$); } ; CreateMViewStmt: CREATE MATERIALIZED VIEW name_space opt_exist_tab opt_column_list opt_phyical_props opt_build_mode refresh_mode start_time period opt_rewrite AS SelectStmt opt_comment { CreateMViewStmt *p_stmt = makeNode(CreateMViewStmt); p_stmt->view_name = $4; p_stmt->tab_exist_mode = $5; p_stmt->aliases = $6; p_stmt->physical_props = (PhysiProp *)$7; p_stmt->build_mode = $8; p_stmt->refresh_mode = $9; p_stmt->start_t = $10; p_stmt->period = $11; p_stmt->rewrite_mode = $12; p_stmt->filter_stmt = (SelectStmt *)$14; p_stmt->comments = $15; SetNodePos($$); $$ = (Node*)p_stmt; } | CREATE SNAPSHOT name_space opt_exist_tab opt_column_list opt_phyical_props opt_build_mode refresh_mode start_time period opt_rewrite AS SelectStmt opt_comment { CreateMViewStmt *p_stmt = makeNode(CreateMViewStmt); p_stmt->view_name = $3; p_stmt->tab_exist_mode = $4; p_stmt->aliases = $5; p_stmt->physical_props = (PhysiProp *)$6; p_stmt->build_mode = $7; p_stmt->refresh_mode = $8; p_stmt->start_t = $9; p_stmt->period = $10; p_stmt->rewrite_mode = $11; p_stmt->filter_stmt = (SelectStmt *)$13; p_stmt->comments = $14; SetNodePos($$); $$ = (Node*)p_stmt; } ; DropMViewStmt: DROP MATERIALIZED VIEW name_space opt_keep_tab { DropStmt *n = makeNode(DropStmt); n->drop_type = DROP_MVIEW; n->obj_name = $4; n->keep_objs = $5; $$ = (Node*)n; SetNodePos($$); } | DROP SNAPSHOT name_space opt_keep_tab { DropStmt *n = makeNode(DropStmt); n->drop_type = DROP_MVIEW; n->obj_name = $3; n->keep_objs = $4; $$ = (Node*)n; SetNodePos($$); } ; opt_exist_tab:/*empty*/ { $$ = 0; } | ON PREBUILT TABLE { $$ = 1; } | ON PREBUILT TABLE WITHOUT REDUCED PRECISION { $$ = 1; } | ON PREBUILT TABLE WITH REDUCED PRECISION { $$ = 2; } ; opt_build_mode: /*empty*/ { $$ = 0; } | BUILD IMMEDIATE { $$ = 1; } | BUILD DEFERRED { $$ = 0; } ; refresh_mode: /*empty*/ { $$ = 0; } | REFRESH FORCE { $$ = 0; } | REFRESH FORCE ON DEMAND { $$ = 0; } | REFRESH FORCE ON COMMIT { $$ = 0x1; } | REFRESH FAST { $$ = 0x10; } | REFRESH FAST ON DEMAND { $$ = 0x10; } | REFRESH FAST ON COMMIT { $$ = 0x11; } | REFRESH COMPLETE { $$ = 0x20; } | REFRESH FORCE WITH PRIMARY KEY { $$ = 0; } | REFRESH FORCE ON DEMAND WITH PRIMARY KEY { $$ = 0; } | REFRESH FORCE ON COMMIT WITH PRIMARY KEY { $$ = 1; } | REFRESH FAST WITH PRIMARY KEY { $$ = 0x10; } | REFRESH FAST ON DEMAND WITH PRIMARY KEY { $$ = 0x10; } | REFRESH FAST ON COMMIT WITH PRIMARY KEY { $$ = 0x11; } | REFRESH COMPLETE WITH PRIMARY KEY { $$ = 0x20; } | REFRESH FORCE ON DEMAND WITH _ROWID { $$ = 0x100; } | REFRESH FORCE ON COMMIT WITH _ROWID { $$ = 0x101; } | REFRESH FAST WITH _ROWID { $$ = 0x110; } | REFRESH FAST ON DEMAND WITH _ROWID { $$ = 0x110; } | REFRESH FAST ON COMMIT WITH _ROWID { $$ = 0x111; } | REFRESH COMPLETE WITH _ROWID { $$ = 0x120; } ; start_time: /*empty*/ { $$ = (char*)"NOW"; } | START WITH Sconst { $$ = dbs2utf($3); } ; period: /*empty*/ { $$ = 0; } | PERIOD ICONST dt_unit { if($3 == DTUNIT_DAY) $$ = $2*3600*24; else if($3 == DTUNIT_HOUR) $$ = $2*3600; else if($3 == DTUNIT_MINUTE) $$ = $2*60; else $$ = $2; } ; opt_rewrite: /*empty*/ { $$ = 0; } | DISABLE QUERY REWRITE { $$ = 0; } | ENABLE QUERY REWRITE { $$ = 1; } | ENABLE GLOBAL QUERY REWRITE { $$ = 2; } ; opt_keep_tab: /*empty*/ { $$ = false; } | KEEP TABLE { $$ = true; } ; /* * Note: CREATE TABLE ... AS SELECT ... is just another spelling for * SELECT ... INTO. */ CreateAsStmt: CREATE OptTemp TABLE opt_if_not_exists name_space OptCreateAs AS SelectStmt { /* * When the SelectStmt is a set-operation tree, we must * stuff the INTO information into the leftmost component * Select, because that's where analyze.c will expect * to find it. Similarly, the output column names must * be attached to that Select's target list. */ SelectStmt *n = findLeftmostSelect((SelectStmt *) $8); if (n->into != (char*)NULL) { SetParsePos(); add_parse_error(215); } n->temp_type = $2; n->into = $5; n->aliasList = $6; //bywsy@20210302 bug3803 /*if ($6 != NIL) mapTargetColumns($6, n->targetList);*/ $$ = $8; } ; OptCreateAs: '(' CreateAsList ')' { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } ; CreateAsList: CreateAsList ',' CreateAsElement { $$ = lappend($1, $3); } | CreateAsElement { $$ = makeList1($1); } ; CreateAsElement: ColId { ColumnDef *n = makeNode(ColumnDef); n->colname = $1; n->type_name = (Typenam*)NULL; n->raw_default = (Node*)NULL; n->cooked_default = (char*)NULL; n->is_not_null = false; n->constraints = (List*)NULL; $$ = (Node *)n; } ; /***************************************************************************** * * QUERY : * CREATE SEQUENCE seqname * *****************************************************************************/ CreateSeqStmt: CREATE SEQUENCE name_space OptSeqList opt_comment { CreateSeqStmt *n = makeNode(CreateSeqStmt); n->seqname = $3; n->options = $4; n->comments = $5; $$ = (Node *)n; } ; AlterSeqStmt: ALTER SEQUENCE name_space OptSeqList { AlterSeqStmt *n = makeNode(AlterSeqStmt); n->seqname = $3; n->options = $4; $$ = (Node *)n; } ; OptSeqList: OptSeqList OptSeqElem { $$ = lappend($1, $2); } | { $$ = NIL; } ; OptSeqElem: CACHE IntegerOnly { $$ = (Node*)makeNode(DefElem); ((DefElem*)$$)->defname = "cache"; ((DefElem*)$$)->arg = (Node *)$2; } | NOCACHE { $$ = (Node*)makeNode(DefElem); ((DefElem*)$$)->defname = "nocache"; } | NOORDER { $$ = (Node*)makeNode(DefElem); ((DefElem*)$$)->defname = "noorder"; } | ORDER { $$ = (Node*)makeNode(DefElem); ((DefElem*)$$)->defname = "order"; } | NOCYCLE { $$ = (Node*)makeNode(DefElem); ((DefElem*)$$)->defname = "NOCYCLE"; } | CYCLE { $$ = (Node*)makeNode(DefElem); ((DefElem*)$$)->defname = "CYCLE"; ((DefElem*)$$)->arg = (Node *)NULL; } | NO CYCLE { $$ = (Node*)makeNode(DefElem); ((DefElem*)$$)->defname = "NOCYCLE"; ((DefElem*)$$)->arg = (Node *)NULL; } | INCREMENT BY IntegerOnly { $$ = (Node*)makeNode(DefElem); ((DefElem*)$$)->defname = "INCREMENT"; ((DefElem*)$$)->arg = (Node *)$3; } | MAXVALUE IntegerOnly { $$ = (Node*)makeNode(DefElem); ((DefElem*)$$)->defname = "MAXVALUE"; ((DefElem*)$$)->arg = (Node *)$2; } | MINVALUE IntegerOnly { $$ = (Node*)makeNode(DefElem); ((DefElem*)$$)->defname = "MINVALUE"; ((DefElem*)$$)->arg = (Node *)$2; } | START WITH IntegerOnly { $$ = (Node*)makeNode(DefElem); ((DefElem*)$$)->defname = "START"; ((DefElem*)$$)->arg = (Node *)$3; } ; IntegerOnly: ICONST { $$ = (Node*)makeInteger($1); } | '-' ICONST { $$ = (Node*)makeInteger($2); ((Value*)$$)->val.ival = - ((Value*)$$)->val.ival; } /*support int64*/ | FCONST { $$ = (Node*)makeNumeric($1); } | '-' FCONST { char * s = (char*)tmalloc(astrlen($2)+4); s[0] = '-'; strcpy(s + 1, $2); $$ = (Node*)makeNumeric(s); } ; DropSeqStmt: DROP SEQUENCE name_space alter_behavior { DropStmt *p_stmt = makeNode(DropStmt); p_stmt->obj_name = $3; p_stmt->drop_type = DROP_SEQUENCE; p_stmt->behavior = ($4==CASCADE? OP_CASCADE : OP_RESTRICT); $$ = (Node*)p_stmt; SetNodePos($$); } ; /***************************************************************************** * * QUERIES : * CREATE TRIGGER ... * DROP TRIGGER ... * *****************************************************************************/ CreateTrigStmt: Cre_Rep TRIGGER name_space TriggerActionTime TriggerEvents ON name_space OptTrggParamAlias TriggerForSpec { _curr_thd->parse_rule = true; } opt_trig_cond opt_comment opt_trig_var_def StmtBlock opt_name_space { CreateTrigStmt *n = makeNode(CreateTrigStmt); n->cre_mode = $1; n->language = "PLSQL"; n->trigname = $3; n->objname = $7; n->objtype = "TABLE_OR_VIEW"; n->trigger_time = $4; n->trigger_event = ((TrigEvent*)$5)->trigger_event; n->field_names = ((TrigEvent*)$5)->field_names; n->new_alias = ((TrggParamAlias*)$8)->new_alias; n->old_alias = ((TrggParamAlias*)$8)->old_alias; n->trigger_type = $9; n->trigger_cond = $11; n->comments = $12; n->var_def_list = $13; n->stmt_list = ((StmtBlock*)$14)->stmt_list; n->exception_list = ((StmtBlock*)$14)->exception_list; ((StmtBlock*)$14)->exception_list = NIL; if($15!=NULL && (astrlen(n->trigname)trigname+astrlen(n->trigname)-astrlen($15),$15))) { SetParsePos(); add_parse_error(579,n->trigname,$15); } $$ = (Node*)n; SetNodePos($$); } |Cre_Rep TRIGGER name_space AFTER LOGON ON DATABASE { _curr_thd->parse_rule = true; } opt_comment opt_trig_var_def StmtBlock opt_name_space { CreateTrigStmt *n = makeNode(CreateTrigStmt); n->cre_mode = $1; n->language = "PLSQL"; n->trigname = $3; n->objtype = "DATABASE"; n->trigger_time = T_AFTER; n->trigger_event = E_LOGON; n->comments = $9; n->var_def_list = $10; n->stmt_list = ((StmtBlock*)$11)->stmt_list; n->exception_list = ((StmtBlock*)$11)->exception_list; ((StmtBlock*)$11)->exception_list = NIL; if($12!=NULL && (astrlen(n->trigname)trigname+astrlen(n->trigname)-astrlen($12),$12))) { SetParsePos(); add_parse_error(579,n->trigname,$12); } $$ = (Node*)n; SetNodePos($$); } ; OptTrggParamAlias: /*empty*/ { TrggParamAlias *n = makeNode(TrggParamAlias); n->new_alias = NULL; n->old_alias = NULL; $$ = (Node*)n; } | REFERENCING NEW AS ColId { TrggParamAlias *n = makeNode(TrggParamAlias); n->new_alias = $4; n->old_alias = NULL; $$ = (Node*)n; } | REFERENCING OLD AS ColId { TrggParamAlias *n = makeNode(TrggParamAlias); n->new_alias = NULL; n->old_alias = $4; $$ = (Node*)n; } | REFERENCING NEW AS ColId OLD AS ColId { TrggParamAlias *n = makeNode(TrggParamAlias); n->new_alias = $4; n->old_alias = $7; $$ = (Node*)n; } | REFERENCING OLD AS ColId NEW AS ColId { TrggParamAlias *n = makeNode(TrggParamAlias); n->new_alias = $7; n->old_alias = $4; $$ = (Node*)n; } ; opt_trig_cond: /*empty*/ { $$ = NULL; } | WHEN bool_expr { $$ = $2; } ; opt_trig_var_def: /*empty*/ { $$ = NIL; } | DECLARE VarDefList { $$ = $2; } ; TriggerActionTime: BEFORE { $$ = T_BEFORE; } | AFTER { $$ = T_AFTER; } | INSTEAD OF { $$ = T_INSTEAD; } ; TriggerEvents: TriggerOneEvent { $$ = $1; } | TriggerEvents OR TriggerOneEvent { TrigEvent *trig_event1 = (TrigEvent*)$1; TrigEvent *trig_event2 = (TrigEvent*)$3; if((trig_event1->trigger_event & trig_event2->trigger_event) !=0) { SetParsePos(); add_parse_error(580); } trig_event1->trigger_event |= trig_event2->trigger_event; if(trig_event2->field_names) trig_event1->field_names = lconc(trig_event1->field_names,trig_event2->field_names); $$ = $1; } ; TriggerOneEvent: INSERT { TrigEvent *p_trig_event = makeNode(TrigEvent); p_trig_event->trigger_event = E_INSERT; $$ = (Node*)p_trig_event ; } | _DELETE { TrigEvent *p_trig_event = makeNode(TrigEvent); p_trig_event->trigger_event = E_DELETE; $$ = (Node*)p_trig_event ; } | UPDATE { TrigEvent *p_trig_event = makeNode(TrigEvent); p_trig_event->trigger_event = E_UPDATE; $$ = (Node*)p_trig_event ; } | UPDATE OF name_list { TrigEvent *p_trig_event = makeNode(TrigEvent); p_trig_event->trigger_event = E_UPDATE; p_trig_event->field_names = $3; $$ = (Node*)p_trig_event ; } | UPDATE OF '(' name_list ')' { TrigEvent *p_trig_event = makeNode(TrigEvent); p_trig_event->trigger_event = E_UPDATE; p_trig_event->field_names = $4; $$ = (Node*)p_trig_event ; } ; TriggerForSpec: /*empty*/ { $$ = TRIG_STATEMENT; } | FOR EACH ROW { $$ = TRIG_EACH_ROW; } | FOR STATEMENT { $$ = TRIG_STATEMENT; } ; ConstraintAttributeSpec: ConstraintDeferrabilitySpec { $$ = $1; } | ConstraintDeferrabilitySpec ConstraintTimeSpec { if ($1 == 0 && $2 != 0) { SetParsePos(); add_parse_error(146); } $$ = $1 | $2; } | ConstraintTimeSpec { if ($1 != 0) $$ = 3; else $$ = 0; } | ConstraintTimeSpec ConstraintDeferrabilitySpec { if ($2 == 0 && $1 != 0) { SetParsePos(); add_parse_error(146); } $$ = $1 | $2; } | /* Empty */ { $$ = 0; } ; ConstraintDeferrabilitySpec: NOT DEFERRABLE { $$ = 0; } | DEFERRABLE { $$ = 1; } ; ConstraintTimeSpec: INITIALLY IMMEDIATE { $$ = 0; } | INITIALLY DEFERRED { $$ = 2; } ; DropTrigStmt: DROP TRIGGER name_space { DropStmt *n = makeNode(DropStmt); n->obj_name = $3; n->drop_type = DROP_TRIGGER; $$ = (Node *) n; SetNodePos($$); } ; /***************************************************************************** * * QUERY: * fetch statement * *****************************************************************************/ FetchStmt: FETCH name opt_bulk opt_into_list opt_limit { FetchStmt *n = makeNode(FetchStmt); n->cursor_name = $2; n->is_bulk = $3; n->into_list = $4; n->limit_num = $5; $$ = (Node*)n; SetNodePos($$); } | FETCH integer FROM name { FetchStmt *n = makeNode(FetchStmt); n->fetch_num = $2; n->cursor_name = $4; $$ = (Node *)n; SetNodePos($$); } ; integer: ICONST {$$ = $1;} | '-' ICONST {$$ = -$2;}; /**************************************************************************** * Delete connect by session id ****************************************************************************/ DropSessionStmt:DROP SESSION ICONST { DropSessionStmt *n = makeNode(DropSessionStmt); n->session_id = $3; $$ = (Node*)n; SetNodePos($$); } | DROP SESSION ICONST IMMEDIATE { DropSessionStmt *n = makeNode(DropSessionStmt); n->session_id = $3; n->immediate = true; $$ = (Node*)n; SetNodePos($$); } ; /**************************************************************************** * Abort transaction of session ****************************************************************************/ AbortSessionStmt:_ABORT SESSION ICONST { AbortSessionStmt *n = makeNode(AbortSessionStmt); n->session_id = $3; $$ = (Node*)n; SetNodePos($$); } ; /***************************************************************************** * * QUERY: * GRANT [privileges] ON [relation_name_list] TO [ROLE] grantee * *****************************************************************************/ GrantStmt: GRANT privileges ON name_space TO grantee_list opt_with_grant { ChangeACLStmt *p_acl = makeNode(ChangeACLStmt); p_acl->is_grant = true; p_acl->acl_mask = $2; p_acl->obj_type = 0; p_acl->obj_name = $4; p_acl->user_list = $6; p_acl->can_regrant = $7; $$ = (Node*)p_acl; } | GRANT privileges ON TABLE name_space TO grantee_list opt_with_grant { ChangeACLStmt *p_acl = makeNode(ChangeACLStmt); p_acl->is_grant = true; p_acl->acl_mask = $2; p_acl->obj_type = OBJ_TYPE_TAB; p_acl->obj_name = $5; p_acl->user_list = $7; p_acl->can_regrant = $8; $$ = (Node*)p_acl; } | GRANT privileges ON VIEW name_space TO grantee_list opt_with_grant { ChangeACLStmt *p_acl = makeNode(ChangeACLStmt); p_acl->is_grant = true; p_acl->acl_mask = $2; p_acl->obj_type = OBJ_TYPE_VIEW; p_acl->obj_name = $5; p_acl->user_list = $7; p_acl->can_regrant = $8; $$ = (Node*)p_acl; } | GRANT privileges ON PROCEDURE name_space TO grantee_list opt_with_grant { ChangeACLStmt *p_acl = makeNode(ChangeACLStmt); p_acl->is_grant = true; p_acl->acl_mask = $2; p_acl->obj_type = OBJ_TYPE_PROC; p_acl->obj_name = $5; p_acl->user_list = $7; p_acl->can_regrant = $8; $$ = (Node*)p_acl; } | GRANT privileges ON SEQUENCE name_space TO grantee_list opt_with_grant { ChangeACLStmt *p_acl = makeNode(ChangeACLStmt); p_acl->is_grant = true; p_acl->acl_mask = $2; p_acl->obj_type = OBJ_TYPE_SEQ; p_acl->obj_name = $5; p_acl->user_list = $7; p_acl->can_regrant = $8; $$ = (Node*)p_acl; } | GRANT sys_privileges _IN SCHEMA name TO grantee_list opt_with_grant { ChangeACLStmt *p_acl = makeNode(ChangeACLStmt); p_acl->sys_privileges = $2; p_acl->is_grant = true; p_acl->schema_name = $5; p_acl->user_list = $7; p_acl->can_regrant = $8; $$ = (Node*)p_acl; } | GRANT sys_privileges TO grantee_list opt_with_grant { ChangeACLStmt *p_acl = makeNode(ChangeACLStmt); p_acl->sys_privileges = $2; p_acl->is_grant = true; p_acl->user_list = $4; p_acl->can_regrant = $5; $$ = (Node*)p_acl; } | GRANT operation_commalist '(' name_list ')' ON name_space TO grantee_list opt_with_grant { ChangeAttrACLStmt *p_acl = makeNode(ChangeAttrACLStmt); p_acl->is_grant = true; p_acl->acl_mask = $2; p_acl->attrNames = $4; p_acl->tab_name = $7; p_acl->user_list = $9; p_acl->can_regrant = $10; $$ = (Node *)p_acl; } ; | GRANT operation_commalist '(' name_list ')' ON TABLE name_space TO grantee_list opt_with_grant { ChangeAttrACLStmt *p_acl = makeNode(ChangeAttrACLStmt); p_acl->is_grant = true; p_acl->acl_mask = $2; p_acl->attrNames = $4; p_acl->tab_name = $8; p_acl->user_list = $10; p_acl->can_regrant = $11; $$ = (Node *)p_acl; } ; privileges: ALL PRIVILEGES { $$ = -1; } | ALL { $$ = -1; } | operation_commalist { $$ = $1; } ; operation_commalist: operation { $$ = $1; } | operation_commalist ',' operation { $$ = ($1 | $3); } ; operation: SELECT { $$ = ACL_READ; } | INSERT { $$ = ACL_INSERT; } | UPDATE { $$ = ACL_UPDATE; } | _DELETE { $$ = ACL_DELETE; } | EXECUTE { $$ = ACL_EXECUTE; } | REFERENCES { $$ = ACL_REF; } | ALTER { $$ = ACL_ALTER; } | DROP { $$ = ACL_DROP; } | INDEX { $$ = ACL_INDEX; } | TRIGGER { $$ = ACL_TRIG; } | VACUUM { $$ = ACL_VACUUM; } ; sys_privileges : sys_privilege { $$ = makeList1($1); } | sys_privileges ',' sys_privilege { $$ = lappend($1,$3); } ; /*database level privilege*/ sys_privilege: DBA { SysAuth *p_auth = makeNode(SysAuth); p_auth->acl_mask = ACL_DBA; $$ = (Node*)p_auth; } | SSO { SysAuth *p_auth = makeNode(SysAuth); p_auth->acl_mask = ACL_SSO; $$ = (Node*)p_auth; } | AUDITOR { SysAuth *p_auth = makeNode(SysAuth); p_auth->acl_mask = ACL_AUDITOR; $$ = (Node*)p_auth; } | BACKUP DATABASE { SysAuth *p_auth = makeNode(SysAuth); p_auth->acl_mask = ACL_BACKUP_ANY; $$ = (Node*)p_auth; } | BACKUP { SysAuth *p_auth = makeNode(SysAuth); p_auth->acl_mask = ACL_BACKUP_ANY; $$ = (Node*)p_auth; } | RESTORE { SysAuth *p_auth = makeNode(SysAuth); p_auth->acl_mask = ACL_RESTORE_ANY; $$ = (Node*)p_auth; } | RESTORE DATABASE { SysAuth *p_auth = makeNode(SysAuth); p_auth->acl_mask = ACL_RESTORE_ANY; $$ = (Node*)p_auth; } | TRACE { SysAuth *p_auth = makeNode(SysAuth); p_auth->acl_mask = ACL_TRACE; $$ = (Node*)p_auth; } | sys_operation obj_type { SysAuth *p_auth = makeNode(SysAuth); p_auth->acl_mask = $1; p_auth->obj_type = $2; $$ = (Node*)p_auth; } ; sys_operation: CREATE { $$ = ACL_CREATE; } | CREATE ANY { $$ = ACL_CRE_ANY; } | ALTER ANY { $$ = ACL_ALT_ANY; } | DROP ANY { $$ = ACL_DROP_ANY; } | SELECT ANY { $$ = ACL_READ_ANY; } | INSERT ANY { $$ = ACL_INSERT_ANY; } | UPDATE ANY { $$ = ACL_UPDATE_ANY; } | _DELETE ANY { $$ = ACL_DELETE_ANY; } | EXECUTE ANY { $$ = ACL_EXECUTE_ANY; } | REFERENCES ANY { $$ = ACL_REF_ANY; } | VACUUM ANY { $$ = ACL_VACUUM_ANY; } | ENCRYPT ANY { $$ = ACL_ENCRYPT_ANY; } ; obj_type: DATABASE { $$ = OBJ_TYPE_DB; } | SCHEMA { $$ = OBJ_TYPE_SCHEMA; } | TABLE { $$ = OBJ_TYPE_TAB; } | SEQUENCE { $$ = OBJ_TYPE_SEQ; } | INDEX { $$ = OBJ_TYPE_INDEX; } | VIEW { $$ = OBJ_TYPE_VIEW; } | PROCEDURE { $$ = OBJ_TYPE_PROC; } | PACKAGE { $$ = OBJ_TYPE_PACK; } | TRIGGER { $$ = OBJ_TYPE_TRIG; } | TABLESPACE { $$ = OBJ_TYPE_SPACE; } | UNDO SEGMENT { $$ = OBJ_TYPE_UNDO_SEG; } | DATABASE LINK { $$ = OBJ_TYPE_DBLINK; } | REPLICATION { $$ = OBJ_TYPE_REPLI; } | SNAPSHOT { $$ = OBJ_TYPE_SNAPSHOT; } | SYNONYM { $$ = OBJ_TYPE_SYNONYM; } | USER { $$ = OBJ_TYPE_USER; } | ROLE { $$ = OBJ_TYPE_ROLE; } | JOB { $$ = OBJ_TYPE_JOB; } | _DIR { $$ = OBJ_TYPE_DIR; } | OBJECT { $$ = OBJ_TYPE_UDT; } ; grantee_list: grantee { $$ = makeList1($1); } | grantee_list ',' grantee { $$ = lappend($1,$3); } ; grantee: ROLE UserId { UserNode *p_user = makeNode(UserNode); p_user->user_type = 'R'; p_user->user_name = $2; $$ = (Node*)p_user; } | UserId { UserNode *p_user = makeNode(UserNode); p_user->user_type = 'U'; p_user->user_name = $1; $$ = (Node*)p_user; } ; opt_with_grant: WITH GRANT OPTION { $$ = true; } | /*EMPTY*/ { $$ = false; } ; /***************************************************************************** * * QUERY: * REVOKE [privileges] ON [name_space] FROM [user] * *****************************************************************************/ RevokeStmt: REVOKE privileges ON name_space FROM grantee_list alter_behavior { /*revoke table level privilege*/ ChangeACLStmt *p_acl = makeNode(ChangeACLStmt); p_acl->is_grant = false; p_acl->obj_name = $4; p_acl->user_list = $6; p_acl->acl_mask = $2; p_acl->obj_type = 0; p_acl->is_cascade = ($7==CASCADE); $$ = (Node*)p_acl; } | REVOKE GRANT OPTION FOR privileges ON name_space FROM grantee_list alter_behavior { ChangeACLStmt *p_acl = makeNode(ChangeACLStmt); p_acl->is_grant = false; p_acl->obj_name = $7; p_acl->user_list = $9; p_acl->acl_mask = $5; p_acl->obj_type = 0; p_acl->can_regrant = true; p_acl->is_cascade = ($10==CASCADE); $$ = (Node*)p_acl; } | REVOKE privileges ON TABLE name_space FROM grantee_list alter_behavior { /*revoke table level privilege*/ ChangeACLStmt *p_acl = makeNode(ChangeACLStmt); p_acl->is_grant = false; p_acl->obj_name = $5; p_acl->user_list = $7; p_acl->acl_mask = $2; p_acl->obj_type = OBJ_TYPE_TAB; p_acl->is_cascade = ($8==CASCADE); $$ = (Node*)p_acl; } | REVOKE privileges ON VIEW name_space FROM grantee_list alter_behavior { /*revoke table level privilege*/ ChangeACLStmt *p_acl = makeNode(ChangeACLStmt); p_acl->is_grant = false; p_acl->obj_name = $5; p_acl->user_list = $7; p_acl->acl_mask = $2; p_acl->obj_type = OBJ_TYPE_VIEW; p_acl->is_cascade = ($8==CASCADE); $$ = (Node*)p_acl; } | REVOKE privileges ON PROCEDURE name_space FROM grantee_list alter_behavior { ChangeACLStmt *p_acl = makeNode(ChangeACLStmt); p_acl->is_grant = false; p_acl->acl_mask = $2; p_acl->obj_type = OBJ_TYPE_PROC; p_acl->obj_name = $5; p_acl->user_list = $7; p_acl->is_cascade = ($8==CASCADE); $$ = (Node*)p_acl; } | REVOKE privileges ON PACKAGE name_space FROM grantee_list alter_behavior { ChangeACLStmt *p_acl = makeNode(ChangeACLStmt); p_acl->is_grant = false; p_acl->acl_mask = $2; p_acl->obj_type = OBJ_TYPE_PACK; p_acl->obj_name = $5; p_acl->user_list = $7; p_acl->is_cascade = ($8==CASCADE); $$ = (Node*)p_acl; } | REVOKE privileges ON SEQUENCE name_space FROM grantee_list alter_behavior { ChangeACLStmt *p_acl = makeNode(ChangeACLStmt); p_acl->is_grant = false; p_acl->acl_mask = $2; p_acl->obj_type = OBJ_TYPE_SEQ; p_acl->obj_name = $5; p_acl->user_list = $7; p_acl->is_cascade = ($8==CASCADE); $$ = (Node*)p_acl; } | REVOKE GRANT OPTION FOR sys_privileges FROM grantee_list alter_behavior {/*revoke database level privilege*/ ChangeACLStmt *p_acl = makeNode(ChangeACLStmt); p_acl->is_grant = false; p_acl->sys_privileges = $5; p_acl->user_list = $7; p_acl->can_regrant = true; p_acl->is_cascade = ($8==CASCADE); $$ = (Node*)p_acl; } | REVOKE sys_privileges FROM grantee_list alter_behavior {/*revoke database level privilege*/ ChangeACLStmt *p_acl = makeNode(ChangeACLStmt); p_acl->is_grant = false; p_acl->sys_privileges = $2; p_acl->user_list = $4; p_acl->is_cascade = ($5==CASCADE); $$ = (Node*)p_acl; } | REVOKE sys_privileges _IN SCHEMA name FROM grantee_list alter_behavior { ChangeACLStmt *p_acl = makeNode(ChangeACLStmt); p_acl->sys_privileges = $2; p_acl->is_grant = false; p_acl->schema_name = $5; p_acl->user_list = $7; p_acl->is_cascade = ($8==CASCADE); $$ = (Node*)p_acl; } | REVOKE GRANT OPTION FOR sys_privileges _IN SCHEMA name FROM grantee_list alter_behavior { ChangeACLStmt *p_acl = makeNode(ChangeACLStmt); p_acl->sys_privileges = $5; p_acl->is_grant = false; p_acl->schema_name = $8; p_acl->user_list = $10; p_acl->can_regrant = true; p_acl->is_cascade = ($11==CASCADE); $$ = (Node*)p_acl; } | REVOKE operation_commalist '(' name_list ')' ON name_space FROM grantee_list alter_behavior {/*revoke columne level privilege*/ ChangeAttrACLStmt *p_acl = makeNode(ChangeAttrACLStmt); p_acl->is_grant = false; p_acl->acl_mask = $2; p_acl->attrNames = $4; p_acl->tab_name = $7; p_acl->user_list = $9; p_acl->is_cascade = ($10==CASCADE); $$ = (Node *)p_acl; } | REVOKE GRANT OPTION FOR operation_commalist '(' name_list ')' ON name_space FROM grantee_list alter_behavior {/*revoke column level privilege*/ ChangeAttrACLStmt *p_acl = makeNode(ChangeAttrACLStmt); p_acl->is_grant = false; p_acl->acl_mask = $5; p_acl->attrNames = $7; p_acl->tab_name = $10; p_acl->user_list = $12; p_acl->can_regrant = true; p_acl->is_cascade = ($13==CASCADE); $$ = (Node *)p_acl; } | REVOKE operation_commalist '(' name_list ')' ON TABLE name_space FROM grantee_list alter_behavior {/*revoke column level privilege*/ ChangeAttrACLStmt *p_acl = makeNode(ChangeAttrACLStmt); p_acl->is_grant = false; p_acl->acl_mask = $2; p_acl->attrNames = $4; p_acl->tab_name = $8; p_acl->user_list = $10; p_acl->is_cascade = ($11==CASCADE); $$ = (Node *)p_acl; } ; /***************************************************************************** * * QUERY: * create index on * usings "(" ( with )+ ")" [with * ] * * [where ] is not supported anymore ******************************************************************************/ //add opt_wait bysdc@20190508 IndexStmt: CREATE opt_unique INDEX index_name ON name_space '(' index_params ')' index_type_opt ftidx_opt opt_idx_parti opt_online parallel_opt2 opt_wait { IndexStmt *n = makeNode(IndexStmt); n->unique = $2; n->idxname = $4; n->relname = $6; n->index_elems = $8; n->idxtype = $10; if($11) { n->vocable_name = ((FullTxtIdxOpt*)$11)->vocable_name; n->word_len = ((FullTxtIdxOpt*)$11)->word_len; n->filter_name = ((FullTxtIdxOpt*)$11)->filter_name; n->lexer_name = ((FullTxtIdxOpt*)$11)->lexer_name; } n->opt_global = ((IdxPartiProp*)$12)->opt_global; n->parti_prop = ((IdxPartiProp*)$12)->parti_prop; n->subparti_prop = ((IdxPartiProp*)$12)->subparti_prop; n->online = $13; n->parallel = $14&0xffff; n->scan_parallel = $14>>16; n->wait_ms = $15;//add opt_wait bysdc@20190508 $$ = (Node *)n; } ; opt_unique: /*EMPTY*/{ $$ = false; } | UNIQUE { $$ = true; } ; index_type_opt: /*EMPTY*/ { $$ = (char*)"DEFAULT"; } | INDEXTYPE IS ColId { $$ = $3;} ; ftidx_opt: /*EMPTY*/ { $$ = NULL; } | full_index_opts { $$ = $1; } ; full_index_opts: full_index_opt_item { $$ = (Node*)$1; } | full_index_opts full_index_opt_item { FullTxtIdxOpt *p_opt1 = (FullTxtIdxOpt *)$1; FullTxtIdxOpt *p_opt2 = (FullTxtIdxOpt *)$2; if(p_opt2->vocable_name) p_opt1->vocable_name = p_opt2->vocable_name; if(p_opt2->word_len) p_opt1->word_len = p_opt2->word_len; if(p_opt2->filter_name) p_opt1->filter_name = p_opt2->filter_name; if(p_opt2->lexer_name) p_opt1->lexer_name = p_opt2->lexer_name; $$ = (Node*)p_opt1; } ; full_index_opt_item: /*specify vocable table*/ USING VOCABLE TABLE Sconst { FullTxtIdxOpt *p_opt = New(FullTxtIdxOpt); p_opt->vocable_name = dbs2utf($4); $$ = p_opt; } /* build word by chinese or mutibytes*/ | FOR EVERY ICONST VOCABLE { FullTxtIdxOpt *p_opt = New(FullTxtIdxOpt); p_opt->word_len = $3; $$ = p_opt; } /*specify filter*/ | USING FILTER Sconst { FullTxtIdxOpt *p_opt = New(FullTxtIdxOpt); p_opt->filter_name = dbs2utf($3); $$ = p_opt; } /*specify lexer*/ | USING LEXER Sconst { FullTxtIdxOpt *p_opt = New(FullTxtIdxOpt); p_opt->lexer_name = dbs2utf($3); $$ = p_opt; } ; index_params: index_params ',' index_elem { $$ = lappend($1, $3); } | index_elem { $$ = makeList1($1); } ; index_elem: ColId { $$ = (Node*)makeNode(IndexElem); ((IndexElem*)$$)->name = $1; ((IndexElem*)$$)->args = NIL; } | func_name '(' expr_list ')' { $$ = (Node*)makeNode(IndexElem); ((IndexElem*)$$)->name = $1; ((IndexElem*)$$)->args = $3; } | ColId DESC { $$ = (Node*)makeNode(IndexElem); ((IndexElem*)$$)->name = $1; ((IndexElem*)$$)->args = NIL; ((IndexElem*)$$)->order = 1; } | func_name '(' expr_list ')' DESC { $$ = (Node*)makeNode(IndexElem); ((IndexElem*)$$)->name = $1; ((IndexElem*)$$)->args = $3; ((IndexElem*)$$)->order = 1; } ; opt_online: /*empty*/ { $$ = false; } | ONLINE { $$ = true; } | OFFLINE { $$ = false; } ; opt_idx_parti: /*empty*/ { IdxPartiProp *p_prop = makeNode(IdxPartiProp); p_prop->opt_global = -1; $$ = (Node*)p_prop; } | LOCAL { IdxPartiProp *p_prop = makeNode(IdxPartiProp); p_prop->opt_global = 0; $$ = (Node*)p_prop; } | GLOBAL opt_partitioning_clause opt_subpartitioning_clause { IdxPartiProp *p_prop = makeNode(IdxPartiProp); p_prop->opt_global = 1; p_prop->parti_prop = (PartiProp*)$2; p_prop->subparti_prop = (PartiProp*)$3; $$ = (Node*)p_prop; } ; LoadVocableStmt: LOAD VOCABLE TABLE SCONST { LoadVocableStmt *p_stmt = makeNode(LoadVocableStmt); p_stmt->voc_tab_name = $4; $$ = (Node*)p_stmt; SetNodePos($$); }; CompileVocableStmt: RECOMPILE VOCABLE TABLE SCONST { CompileVocableStmt *p_stmt = makeNode(CompileVocableStmt); p_stmt->voc_tab_name = $4; $$ = (Node*)p_stmt; SetNodePos($$); } | RECOMPILE VOCABLE TABLE SCONST AUTO LOAD { CompileVocableStmt *p_stmt = makeNode(CompileVocableStmt); p_stmt->voc_tab_name = $4; p_stmt->auto_load = true; $$ = (Node*)p_stmt; SetNodePos($$); } ; GetLobStmt: GET LOB Sconst OFFSET ICONST LIMIT ICONST { GetLobStmt *p_stmt = makeNode(GetLobStmt); p_stmt->descriptor = $3; p_stmt->offset = $5; p_stmt->limit = $7; $$ = (Node*)p_stmt; SetNodePos($$); } ; /************************************************************************** * alter index add partition *bysdc@20210106 支持 slow modify opt_wait **************************************************************************/ AlterIndexStmt: ALTER INDEX name_space ADD PARTITION ColId VALUES '(' parti_values ')' opt_wait { AlterIndexStmt *n = makeNode(AlterIndexStmt); n->action = ADD_PART; n->idx_name = $3; n->parti_name = $6; n->parti_type = LIST_PARTITION; n->parti_vals = $9; n->wait_ms = $11; $$ = (Node *)n; } | ALTER INDEX name_space ADD PARTITION ColId VALUES LESS THAN '(' parti_values ')' opt_wait { AlterIndexStmt *n = makeNode(AlterIndexStmt); n->action = ADD_PART; n->idx_name = $3; n->parti_name = $6; n->parti_type = RANGE_PARTITION; n->parti_vals = $11; n->wait_ms = $13; $$ = (Node *)n; } | ALTER INDEX name_space SLOW MODIFY ON opt_wait { AlterIndexStmt *n = makeNode(AlterIndexStmt); n->action = SET_SLOW_MODI; n->idx_name = $3; n->wait_ms = $7; $$ = (Node *)n; } | ALTER INDEX name_space SLOW MODIFY OFF opt_wait { AlterIndexStmt *n = makeNode(AlterIndexStmt); n->action = CLR_SLOW_MODI; n->idx_name = $3; n->wait_ms = $7; $$ = (Node *)n; } ; DropIdxStmt: DROP INDEX name_space { DropStmt *p_stmt = makeNode(DropStmt); p_stmt->obj_name = $3; p_stmt->drop_type = DROP_INDEX; $$ = (Node*)p_stmt; SetNodePos($$); } ; /***************************************************************************** * * QUERY: * extend index [where ] * *****************************************************************************/ ExtendStmt: EXTEND INDEX index_name opt_where_clause { ExtendStmt *n = makeNode(ExtendStmt); n->idxname = $3; n->whereClause = $4; $$ = (Node *)n; } ; /***************************************************************************** * * QUERY: * * REINDEX type [FORCE] [ALL] * *****************************************************************************/ //add opt_wait bysdc@20190508 ReindexStmt: REINDEX name_space opt_force opt_fast opt_online parallel_opt2 opt_wait { ReindexStmt *n = makeNode(ReindexStmt); n->reindexType = 1; n->name = $2; n->force = $3; n->fast = $4; n->online = $5; n->parallel = $6&0xffff; n->scan_parallel = $6>>16; n->wait_ms = $7;//add opt_wait bysdc@20190508 $$ = (Node *)n; } | REINDEX name_space '.' '*' opt_force opt_fast opt_online parallel_opt2 opt_wait { ReindexStmt *n = makeNode(ReindexStmt); n->reindexType = 2; n->name = $2; n->force = $5; n->fast = $6; n->online = $7; n->parallel = $8&0xffff; n->scan_parallel = $8>>16; n->wait_ms = $9;//add opt_wait bysdc@20190508 $$ = (Node *)n; } /*why 2018-01-16 add index partition rebuild*/ | REINDEX name_space PARTITION name_space opt_force opt_fast opt_online parallel_opt2 opt_wait { ReindexStmt *n = makeNode(ReindexStmt); n->reindexType = 1; n->name = $2; n->pname = $4; //partition name n->force = $5; n->fast = $6; n->online = $7; n->parallel = $8&0xffff; n->scan_parallel = $8>>16; n->wait_ms = $9;//add opt_wait bysdc@20190508 $$ = (Node *)n; } ; opt_force: FORCE { $$ = true; } | /* EMPTY */ { $$ = false; } ; opt_fast: FAST { $$ = true; } | /* EMPTY */ { $$ = false; } ; /***************************************************************************** * * QUERY: * rename in [*] to * rename to * *****************************************************************************/ RenameStmt: ALTER TABLE name_space RENAME opt_column opt_name TO name alter_behavior { RenameStmt *n = makeNode(RenameStmt); n->relname = $3; n->column = $6; n->newname = $8; n->behavior = ($9==CASCADE? OP_CASCADE : OP_RESTRICT); $$ = (Node *)n; } ; opt_name: name { $$ = $1; } | /*EMPTY*/ { $$ = NULL; } ; opt_column: COLUMN { $$ = COLUMN; } | /*EMPTY*/ { $$ = 0; } ; /***************************************************************************** * * QUERY: * NOTIFY can appear both in rule bodies and * as a query-level command * *****************************************************************************/ NotifyStmt: NOTIFY name_space { NotifyStmt *n = makeNode(NotifyStmt); n->relname = $2; $$ = (Node *)n; } | NOTIFY name_space Sconst { NotifyStmt *n = makeNode(NotifyStmt); n->relname = $2; n->info = dbs2utf($3); $$ = (Node *)n; } ; ListenStmt: LISTEN name_space { ListenStmt *n = makeNode(ListenStmt); n->relname = $2; $$ = (Node *)n; } ; UnlistenStmt: UNLISTEN name_space { UnlistenStmt *n = makeNode(UnlistenStmt); n->relname = $2; $$ = (Node *)n; } | UNLISTEN '*' { UnlistenStmt *n = makeNode(UnlistenStmt); n->relname = "*"; $$ = (Node *)n; } ; /***************************************************************************** * * Transactions: * * BEGIN / COMMIT / ROLLBACK * (also older versions _END / ABORT) * *****************************************************************************/ TransactionStmt: _ABORT opt_trans { TransactionStmt *n = makeNode(TransactionStmt); n->command = OP_ROLLBACK; $$ = (Node *)n; } | _BEGIN opt_trans { TransactionStmt *n = makeNode(TransactionStmt); n->command = OP_BEGIN; $$ = (Node *)n; } | COMMIT opt_trans { TransactionStmt *n = makeNode(TransactionStmt); n->command = OP_COMMIT; $$ = (Node *)n; } | COMMIT opt_trans opt_chain { TransactionStmt *n = makeNode(TransactionStmt); n->command = OP_COMMIT; $$ = (Node *)n; } | ROLLBACK opt_trans { TransactionStmt *n = makeNode(TransactionStmt); n->command = OP_ROLLBACK; $$ = (Node *)n; } | ROLLBACK opt_trans opt_chain { TransactionStmt *n = makeNode(TransactionStmt); n->command = OP_ROLLBACK; $$ = (Node *)n; } |ROLLBACK TO ColId { TransactionStmt *n = makeNode(TransactionStmt); n->command = OP_ROLLBACK; n->label= $3; $$ = (Node *)n; } |ROLLBACK TO SAVEPOINT ColId { TransactionStmt *n = makeNode(TransactionStmt); n->command = OP_ROLLBACK; n->label = $4; $$ = (Node *)n; } | SAVEPOINT ColId { TransactionStmt *n = makeNode(TransactionStmt); n->command = OP_SAVEPOINT; n->label = $2; $$ = (Node *)n; } ; opt_trans: WORK {} | TRAN {} | TRANSACTION {} | /*EMPTY*/ ; opt_chain: AND NO CHAIN { $$ = false; } | AND CHAIN { /* SQL99 asks that conforming dbs reject AND CHAIN * if they don't support it. So we can't just ignore it. * - thomas 2000-08-06 */ SetParsePos(); add_parse_error(7); $$ = true; } ; /***************************************************************************** * * QUERY: * define view '('target-list ')' [where ] * *****************************************************************************/ ViewStmt: Cre_Rep VIEW name_space opt_column_list AS SelectStmt view_opt opt_comment { ViewStmt *n = makeNode(ViewStmt); n->cre_mode = $1; n->view_name = $3; n->aliases = $4; n->filter_stmt = (SelectStmt *) $6; n->option = $7; n->comments = $8; $$ = (Node *)n; SetNodePos($$); } | Cre_Rep VIEW name_space opt_column_list AS joined_table view_opt opt_comment { ViewStmt *n = makeNode(ViewStmt); SelectStmt *select_stmt = makeNode(SelectStmt); ResTarget *res_targ = makeNode(ResTarget); Attr *att = makeNode(Attr); att->relname = "*"; att->fields = NULL; res_targ->name = NULL; res_targ->val = (Node *)att; select_stmt->fromClause = makeList1($6); select_stmt->targetList = makeList1(res_targ); n->cre_mode = $1; n->view_name = $3; n->aliases = $4; n->filter_stmt = select_stmt; n->option = $7; n->comments = $8; $$ = (Node *)n; SetNodePos($$); } | Cre_Rep VIEW name_space opt_column_list AS '(' joined_table ')' alias_clause view_opt opt_comment { ViewStmt *n = makeNode(ViewStmt); SelectStmt *select_stmt = makeNode(SelectStmt); ResTarget *res_targ = makeNode(ResTarget); Attr *att = makeNode(Attr); att->relname = "*"; att->fields = NULL; res_targ->name = NULL; res_targ->val = (Node *)att; ((JoinNode*)$7)->alias = (Attr*) $9; select_stmt->fromClause = makeList1($7); select_stmt->targetList = makeList1(res_targ); n->cre_mode = $1; n->view_name = $3; n->aliases = $4; n->filter_stmt = select_stmt; n->option = $10; n->comments = $11; $$ = (Node *)n; SetNodePos($$); } ; view_opt: /*empty*/ { $$ = 0; } | WITH READ ONLY { $$ = 1; } | WITH CHECK OPTION { $$ = 2; } ; DropViewStmt:DROP VIEW name_space alter_behavior { DropStmt *p_stmt = makeNode(DropStmt); p_stmt->obj_name = $3; p_stmt->behavior = ($4==CASCADE? OP_CASCADE : OP_RESTRICT); p_stmt->drop_type = DROP_VIEW; $$ = (Node*)p_stmt; SetNodePos($$); } ; /***************************************************************************** * * QUERY: * load "filename" * *****************************************************************************/ LoadStmt: LOAD file_name { LoadStmt *n = makeNode(LoadStmt); n->filename = $2; $$ = (Node *)n; } ; /***************************************************************************** * why 2016-07-28 add * Connect Policy * ******************************************************************************/ opt_conn_policy:/*empty*/ { $$ = NULL; } |TO Sconst { $$ = dbs2utf($2); } ; //**bysdc@20190604 add [opt_on_node] merge[why 2019-09-05 modify] ConnectPolicyStmt: ALTER CONNECT POLICY ADD ENABLE Sconst LOGIN Sconst FROM Sconst opt_conn_policy opt_on_node { ConnectPolicyStmt *n = makeNode(ConnectPolicyStmt); n->action = 1; n->mode = 1; n->user = dbs2utf($6); n->db_name = dbs2utf($8); n->start_ip = dbs2utf($10); n->end_ip = $11; n->node_id = $12;//++bysdc@20190604 $$ = (Node*)n; } |ALTER CONNECT POLICY ADD DISABLE Sconst LOGIN Sconst FROM Sconst opt_conn_policy opt_on_node { ConnectPolicyStmt *n = makeNode(ConnectPolicyStmt); n->action = 1; n->mode = 2; n->user = dbs2utf($6); n->db_name = dbs2utf($8); n->start_ip = dbs2utf($10); n->end_ip = $11; n->node_id = $12;//++bysdc@20190604 $$ = (Node*)n; } |ALTER CONNECT POLICY DROP ENABLE Sconst LOGIN Sconst FROM Sconst opt_conn_policy opt_on_node { ConnectPolicyStmt *n = makeNode(ConnectPolicyStmt); n->action = 2; n->mode = 1; n->user = dbs2utf($6); n->db_name = dbs2utf($8); n->start_ip = dbs2utf($10); n->end_ip = $11; n->node_id = $12;//++bysdc@20190604 $$ = (Node*)n; } |ALTER CONNECT POLICY DROP DISABLE Sconst LOGIN Sconst FROM Sconst opt_conn_policy opt_on_node { ConnectPolicyStmt *n = makeNode(ConnectPolicyStmt); n->action = 2; n->mode = 2; n->user = dbs2utf($6); n->db_name = dbs2utf($8); n->start_ip = dbs2utf($10); n->end_ip = $11; n->node_id = $12;//++bysdc@20190604 $$ = (Node*)n; } |ALTER CONNECT POLICY DROP ALL ENABLE opt_on_node { ConnectPolicyStmt *n = makeNode(ConnectPolicyStmt); n->action = 2; n->mode = 1; n->all = true; n->node_id = $7;//++bysdc@20190604 $$ = (Node*)n; } |ALTER CONNECT POLICY DROP ALL ENABLE LOGIN Sconst opt_on_node { ConnectPolicyStmt *n = makeNode(ConnectPolicyStmt); n->action = 2; n->mode = 1; n->all = true; n->db_name = dbs2utf($8); n->node_id = $9;//++bysdc@20190604 $$ = (Node*)n; } |ALTER CONNECT POLICY DROP ALL ENABLE Sconst LOGIN Sconst opt_on_node { ConnectPolicyStmt *n = makeNode(ConnectPolicyStmt); n->action = 2; n->mode = 1; n->all = true; n->user = dbs2utf($7); n->db_name = dbs2utf($9); n->node_id = $10;//++bysdc@20190604 $$ = (Node*)n; } |ALTER CONNECT POLICY DROP ALL DISABLE opt_on_node { ConnectPolicyStmt *n = makeNode(ConnectPolicyStmt); n->action = 2; n->mode = 2; n->all = true; n->node_id = $7;//++bysdc@20190604 $$ = (Node*)n; } |ALTER CONNECT POLICY DROP ALL DISABLE LOGIN Sconst opt_on_node { ConnectPolicyStmt *n = makeNode(ConnectPolicyStmt); n->action = 2; n->mode = 2; n->all = true; n->db_name = dbs2utf($8); n->node_id = $9;//++bysdc@20190604 $$ = (Node*)n; } |ALTER CONNECT POLICY DROP ALL DISABLE Sconst LOGIN Sconst opt_on_node { ConnectPolicyStmt *n = makeNode(ConnectPolicyStmt); n->action = 2; n->mode = 2; n->all = true; n->user = dbs2utf($7); n->db_name = dbs2utf($9); n->node_id = $10;//++bysdc@20190604 $$ = (Node*)n; } |ALTER CONNECT POLICY DROP ALL opt_on_node { ConnectPolicyStmt *n = makeNode(ConnectPolicyStmt); n->action = 2; n->mode = 3; n->all = true; n->node_id = $6;//++bysdc@20190604 $$ = (Node*)n; } ; /***************************************************************************** * * LOGIN * * *****************************************************************************/ LoginStmt: USE ColId { LoginStmt *n = makeNode(LoginStmt); n->db_name = $2; $$ = (Node*)n; } | USE ColId PASSWORD '=' Sconst { LoginStmt *n = makeNode(LoginStmt); n->db_name = $2; n->password = dbs2utf($5); $$ = (Node*)n; } | USE ColId USER '=' UserId PASSWORD '=' Sconst { LoginStmt *n = makeNode(LoginStmt); n->db_name = $2; n->user = $5; n->password = dbs2utf($8); $$ = (Node*)n; } ; /***************************************************************************** * * LOGOUT * * *****************************************************************************/ LogoutStmt: LOGOUT DATABASE { $$ = (Node*)makeNode(LogoutStmt); }; /***************************************************************************** * CREATE DIR *****************************************************************************/ CreateDirStmt: CREATE _DIR Sconst opt_on_node { CreateDirStmt *n = makeNode(CreateDirStmt); n->dir = dbs2utf($3); n->node_id = $4; $$ = (Node*)n; }; ShowDirStmt: SHOW _DIR Sconst opt_on_node { ShowDirStmt *n = makeNode(ShowDirStmt); n->dir = dbs2utf($3); n->node_id = $4; $$ = (Node*)n; }; /***************************************************************************** * CREATE TABLESPACE *****************************************************************************/ CreatespacStmt: CREATE optSpaceType TABLESPACE space_name opt_on_node DATAFILE data_files { CreatespacStmt *p_space = makeNode(CreatespacStmt); p_space->space_type = (SpaceType)$2; p_space->spac_name = $4; p_space->node_id = $5; p_space->data_files = $7; $$ = (Node*)p_space; } ; optSpaceType: { $$ = DATA_SPACE; } | TEMP { $$ = TEMP_SPACE; } | TEMPORARY { $$ = TEMP_SPACE; } ; /*excute node option*/ opt_on_node: /* empty */ { $$ = 0; //default current node } | ON ALL NODE { $$ = -1; //all cluster alive nodes } | ON NODE ICONST { $$ = $3; } ; /*group files of data*/ data_files: data_file { $$ = makeList1($1); } | data_files ',' data_file { $$ = lappend($1,$3); } ; data_file: Sconst { TFile *p_file = New(TFile); p_file->path = dbs2utf($1); p_file->max_size = -1; p_file->ini_size = -1; p_file->step_size = -1; $$ = (Node*)p_file; } | Sconst autoextend_clause { TFile *p_file = (TFile*)$2; p_file->path = dbs2utf($1); $$ = (Node*)p_file; }; autoextend_clause: /* ++bysdc@20200122 for refactor-tablespace */ AUTO EXTEND OFF { TFile *p_f = New(TFile); p_f->ini_size = 0; p_f->max_size = 0; p_f->step_size = 0; $$ = (Node*)p_f; } //end | _SIZE_ ICONST size_unit AUTO EXTEND OFF { TFile *p_f = New(TFile); p_f->ini_size = ((int64)$2) * $3; p_f->max_size = p_f->ini_size; p_f->step_size = 0; $$ = (Node*)p_f; } | _SIZE_ ICONST size_unit MAXSIZE UNLIMITED { TFile *p_f = New(TFile); p_f->ini_size = ((int64)$2) *$3; p_f->max_size = -1; p_f->step_size = -1; $$ = (Node*)p_f; } | _SIZE_ ICONST size_unit MAXSIZE ICONST size_unit { TFile *p_f = New(TFile); p_f->ini_size = ((int64)$2) *$3; p_f->max_size = ((int64)$5) *$6; p_f->step_size = -1; $$ = (Node*)p_f; } | _SIZE_ ICONST size_unit NEXT ICONST size_unit MAXSIZE UNLIMITED { TFile *p_f = New(TFile); p_f->ini_size = ((int64)$2)*$3; p_f->step_size = ((int64)$5)*$6; p_f->max_size = -1; $$ = (Node*)p_f; } | _SIZE_ ICONST size_unit NEXT ICONST size_unit MAXSIZE ICONST size_unit { TFile *p_f = New(TFile); p_f->ini_size = ((int64)$2)*$3; p_f->step_size = ((int64)$5)*$6; p_f->max_size = ((int64)$8)*$9; $$ = (Node*)p_f; } /* ++bysdc@20200122 for refactor-tablespace */ | NEXT ICONST size_unit MAXSIZE ICONST size_unit { TFile *p_f = New(TFile); p_f->ini_size = 0; p_f->step_size = ((int64)$2)*$3; p_f->max_size = ((int64)$5)*$6; $$ = (Node*)p_f; } | MAXSIZE ICONST size_unit { TFile *p_f = New(TFile); p_f->ini_size = 0; p_f->max_size = ((int64)$2) *$3; p_f->step_size = -1; $$ = (Node*)p_f; } | NEXT ICONST size_unit { TFile *p_f = New(TFile); p_f->ini_size = 0; p_f->max_size = 0; p_f->step_size = ((int64)$2)*$3; $$ = (Node*)p_f; } //end ; size_unit: K { $$ = 1024; } | M { $$ = 1024*1024; } /* ++bysdc@20200122 for refactor-tablespace */ | G { $$ = 1024*1024*1024; } //end ; /***************************************************************************** * * DROP TABLESPACE * *****************************************************************************/ DropspacStmt: DROP TABLESPACE space_name { DropStmt *n = makeNode(DropStmt); n->obj_name = $3; n->drop_type = DROP_SPACE; $$ = (Node*)n; }; /***************************************************************************** * * Alter TABLESPACE * *****************************************************************************/ AlterspacStmt: ALTER TABLESPACE space_name opt_on_node ADD DATAFILE data_file { AlterspacStmt *p_stmt = makeNode(AlterspacStmt); p_stmt->spac_name = $3; p_stmt->node_id = $4; p_stmt->alt_type = '+'; p_stmt->data_file = (TFile*)$7; $$ = (Node *)p_stmt; } | ALTER TABLESPACE space_name opt_on_node ALTER DATAFILE data_file { AlterspacStmt *p_stmt = makeNode(AlterspacStmt); p_stmt->spac_name = $3; p_stmt->node_id = $4; p_stmt->alt_type = 'a'; p_stmt->data_file =(TFile*)$7; $$ = (Node *)p_stmt; } ; /***************************************************************************** * CREATE DATABASE *****************************************************************************/ CreatedbStmt: CREATE DATABASE database_name { CreatedbStmt *stmt = makeNode(CreatedbStmt); stmt->dbname = $3; $$ = (Node*)stmt; } | CreatedbStmt CHARACTER SET ColId { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->cset_name = $4; $$ = (Node*)stmt; } | CreatedbStmt CHARACTER SET Sconst { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->cset_name = dbs2utf($4); $$ = (Node*)stmt; } | CreatedbStmt TIME ZONE Sconst { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->time_zone = dbs2utf($4); $$ = (Node*)stmt; } | CreatedbStmt _MAX USER ICONST { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->max_user = $4; $$ = (Node*)stmt; } | CreatedbStmt _MAX CONNECT ICONST { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->max_dbc = $4; $$ = (Node*)stmt; } | CreatedbStmt _MAX _SIZE_ ICONST size_unit { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->max_size = ((int64)$4) *$5; $$ = (Node*)stmt; } | CreatedbStmt _MAX TABLE ICONST { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->max_tab = $4; $$ = (Node*)stmt; } | CreatedbStmt _MAX VIEW ICONST { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->max_view = $4; $$ = (Node*)stmt; } | CreatedbStmt _MAX SEQUENCE ICONST { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->max_seq = $4; $$ = (Node*)stmt; } | CreatedbStmt _MAX TRIGGER ICONST { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->max_trig = $4; $$ = (Node*)stmt; } | CreatedbStmt _MAX PROCEDURE ICONST { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->max_proc = $4; $$ = (Node*)stmt; } | CreatedbStmt _MAX PACKAGE ICONST { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->max_pack = $4; $$ = (Node*)stmt; } | CreatedbStmt _MAX TYPE ICONST { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->max_udt = $4; $$ = (Node*)stmt; } | CreatedbStmt _MAX JOB ICONST { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->max_job = $4; $$ = (Node*)stmt; } | CreatedbStmt ENABLE ENCRYPT { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->ena_encry = true; $$ = (Node*)stmt; } | CreatedbStmt DISABLE ENCRYPT { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->ena_encry = false; $$ = (Node*)stmt; } | CreatedbStmt ENABLE POLICY { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->ena_policy = true; $$ = (Node*)stmt; } | CreatedbStmt DISABLE POLICY { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->ena_policy = false; $$ = (Node*)stmt; } | CreatedbStmt ENABLE AUDIT { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->ena_audit = true; $$ = (Node*)stmt; } | CreatedbStmt DISABLE AUDIT { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->ena_audit = false; $$ = (Node*)stmt; } //why 2016-10-27 add mergebysdc@20180907 | CreatedbStmt ENCRYPT BY Sconst { CreatedbStmt *stmt = (CreatedbStmt*)$1; stmt->encry_name = dbs2utf($4); $$ = (Node*)stmt; } //end ; /***************************************************************************** * * DROP DATABASE * * *****************************************************************************/ DropdbStmt: DROP DATABASE database_name { DropStmt *n = makeNode(DropStmt); n->obj_name = $3; n->drop_type = DROP_DB; $$ = (Node *)n; } ; /***************************************************************************** * * QUERY: cluster on * *****************************************************************************/ ClusterStmt: ALTER TABLE name_space CLUSTER BY name_list { ClusterStmt *n = makeNode(ClusterStmt); n->relname = $3; n->col_names = $6; $$ = (Node*)n; SetNodePos($$); } ; AnalyzeStmt: ANALYZE TABLE name_space COMPUTE STATISTICS opt_analyze_for { AnalyzeStmt *p_stmt = makeNode(AnalyzeStmt); p_stmt->table_name = $3; AnalyzeOpt *opt = (AnalyzeOpt*)$6; p_stmt->ana_type = opt->ana_type; p_stmt->col_names = opt->col_names; $$ = (Node*)p_stmt; SetNodePos($$); }; opt_analyze_for: /*empty*/ { AnalyzeOpt *opt = New(AnalyzeOpt); opt->ana_type = 1; opt->col_names = NIL; $$ = opt; } | FOR ALL COLUMNS { AnalyzeOpt *opt = New(AnalyzeOpt); opt->ana_type = 1; opt->col_names = NIL; $$ = opt; } | FOR COLUMNS '(' name_list ')' { AnalyzeOpt *opt = New(AnalyzeOpt); opt->ana_type = 1; opt->col_names = $4; $$ = opt; } ; /***************************************************************************** * * QUERY: * vacuum * *****************************************************************************/ VacuumStmt: VACUUM opt_verbose opt_analyze { VacuumStmt *n = makeNode(VacuumStmt); n->verbose = $2; n->analyze = $3; n->tab_name = NULL; n->col_list = NIL; $$ = (Node *)n; SetNodePos($$); } | VACUUM opt_verbose opt_analyze name_space opt_va_list { VacuumStmt *n = makeNode(VacuumStmt); n->verbose = $2; n->analyze = $3; n->tab_name = $4; n->col_list = $5; if ( $5 != NIL && !$4 ) { SetParsePos(); add_parse_error(515); } $$ = (Node *)n; SetNodePos($$); } ; opt_verbose: VERBOSE { $$ = true; } | /*EMPTY*/ { $$ = false; } ; opt_analyze: ANALYZE { $$ = true; } | /*EMPTY*/ { $$ = false; } ; opt_va_list: '(' va_list ')' { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } ; va_list: name { $$ = makeList1($1); } | va_list ',' name { $$ = lappend($1, $3); } ; /***************************************************************************** * * QUERY: * EXPLAIN query * *****************************************************************************/ ExplainStmt: EXPLAIN opt_verbose dml_stmt { ExplainStmt *n = makeNode(ExplainStmt); n->verbose = $2; n->query = (Node*)$3; $$ = (Node *)n; } ; /***************************************************************************** * * * Optimizable Stmts: * * * * one of the five queries processed by the planner * * * * [ultimately] produces query-trees as specified * * in the query-spec document in ~postgres/ref * * * *****************************************************************************/ dml_stmt: SelectStmt parallel_opt opt_wait dml_opt { ((SelectStmt*)$1)->parallel = $2; ((SelectStmt*)$1)->wait_ms = $3; ((ParseNode*)$1)->dml_opt = $4; $$ = (Node*)$1; } | UpdateStmt parallel_opt opt_wait dml_opt { ((UpdateStmt*)$1)->parallel = $2; ((UpdateStmt*)$1)->wait_ms = $3; ((SelectStmt*)$1)->dml_opt = $4; ((ParseNode*)$1)->dml_opt = $4; $$ = (Node*)$1; } | InsertStmt parallel_opt opt_wait dml_opt { ((InsertStmt*)$1)->parallel = $2; ((InsertStmt*)$1)->wait_ms = $3; ((ParseNode*)$1)->dml_opt = $4; $$ = (Node*)$1; } | DeleteStmt parallel_opt opt_wait dml_opt { ((DeleteStmt*)$1)->parallel = $2; ((DeleteStmt*)$1)->wait_ms = $3; ((ParseNode*)$1)->dml_opt = $4; $$ = (Node*)$1; } /*++bysdc@20200910 for mergeinto*/ | MergeIntoStmt parallel_opt opt_wait dml_opt { ((MergeIntoStmt*)$1)->parallel = $2; ((MergeIntoStmt*)$1)->wait_ms = $3; ((ParseNode*)$1)->dml_opt = $4; $$ = (Node*)$1; } ; opt_wait: /*empty*/ { $$ = -2; } | NOWAIT { $$ = 0; } | WAIT { $$ = -1; } | WAIT ICONST { $$ = $2; } ; dml_opt: /*empty*/ { $$ = 0; } | WITH NO ROLLBACK { $$ = OPT_NO_UNDO; } | WITH NO UNDO { $$ = OPT_NO_UNDO; } | WITH NOT ROLLBACK { $$ = OPT_NO_UNDO; } | WITH NOT UNDO { $$ = OPT_NO_UNDO; } ; /*prepare sql for reuse until deallocate*/ PrepareStmt: PREPARE ColId AS sql_stmt //** dml_stmt >> sql_stmt bysdc@20201028 for ddl prepare compatable { PrepareStmt *p_prepare_stmt = makeNode(PrepareStmt); p_prepare_stmt->name = $2; p_prepare_stmt->p_stmt = $4; p_prepare_stmt->is_dml = true;//++bysdc@20201028 $$ = (Node*)p_prepare_stmt; } ; DeallocateStmt: DEALLOCATE ColId { DeallocateStmt *p_stmt = makeNode(DeallocateStmt); p_stmt->name = $2; $$ = (Node*)p_stmt; } ; /***************************************************************************** * QUERY: * INSERT STATEMENTS *****************************************************************************/ /* This rule used 'opt_column_list' between 'name_space' and 'insert_rest' * originally. When the second rule of 'insert_rest' was changed to use the * new 'SelectStmt' rule (for INTERSECT and EXCEPT) it produced a shift/reduce * conflict. So I just changed the rules 'InsertStmt' and 'insert_rest' to * accept the same statements without any shift/reduce conflicts */ InsertStmt: INSERT INTO relation_expr insert_rest { ((InsertStmt*)$4)->relation =(TabNode*) $3; $$ = (Node *) $4; } | INSERT INTO relation_expr insert_rest RETURNING target_list opt_bulk opt_into_list { ((InsertStmt*)$4)->relation =(TabNode*) $3; ((InsertStmt*)$4)->return_list = $6; ((InsertStmt*)$4)->is_bulk = $7; ((InsertStmt*)$4)->into_list = $8; $$ = (Node *) $4; } ; insert_rest: VALUES insert_values { $$ = (Node*)makeNode(InsertStmt); ((InsertStmt*)$$)->cols = NIL; ((InsertStmt*)$$)->values = $2; ((InsertStmt*)$$)->selectStmt = NULL; } | DEFAULT VALUES { $$ = (Node*)makeNode(InsertStmt); ((InsertStmt*)$$)->cols = NIL; ((InsertStmt*)$$)->selectStmt = NULL; } | SelectStmt { $$ = (Node*)makeNode(InsertStmt); ((InsertStmt*)$$)->cols = NIL; ((InsertStmt*)$$)->selectStmt = $1; } | '(' columnList ')' VALUES insert_values { $$ = (Node*)makeNode(InsertStmt); ((InsertStmt*)$$)->cols = $2; ((InsertStmt*)$$)->values = $5; ((InsertStmt*)$$)->selectStmt = NULL; } //++bysdc@20191128 | '(' columnList ')' VALUES insert_values select_no_parens { $$ = (Node*)makeNode(InsertStmt); ((InsertStmt*)$$)->cols = $2; ((InsertStmt*)$$)->values = $5; ((InsertStmt*)$$)->selectStmt = $6; } //end++bysdc@20191128 | '(' columnList ')' SelectStmt { $$ = (Node*)makeNode(InsertStmt); ((InsertStmt*)$$)->cols = $2; ((InsertStmt*)$$)->selectStmt = $4; } ; /*++bysdc@20200910 for mergeinto:*/ insert_merge: VALUES insert_values { $$ = (Node*)makeNode(InsertStmt); ((InsertStmt*)$$)->cols = NIL; ((InsertStmt*)$$)->values = $2; ((InsertStmt*)$$)->selectStmt = NULL; } | DEFAULT VALUES { $$ = (Node*)makeNode(InsertStmt); ((InsertStmt*)$$)->cols = NIL; ((InsertStmt*)$$)->selectStmt = NULL; } | '(' columnList2 ')' VALUES insert_values { $$ = (Node*)makeNode(InsertStmt); ((InsertStmt*)$$)->cols = $2; ((InsertStmt*)$$)->values = $5; ((InsertStmt*)$$)->selectStmt = NULL; } ; insert_values: '(' target_list ')' { $$ = makeList1($2); } | insert_values '(' target_list ')' { $$ = lappend($1,$3); } ; opt_column_list: '(' columnList ')' { $$ = $2; } | /*EMPTY*/ { $$ = NIL; } ; columnList: columnList ',' ColLabel { Ident *p_ident = makeNode(Ident); p_ident->name = $3; $$ = lappend($1, p_ident); } | ColLabel { Ident *p_ident = makeNode(Ident); p_ident->name = $1; $$ = makeList1(p_ident); } ; /*++bysdc@20200910 for mergeinto*/ columnList2: columnList2 ',' ident { $$ = lappend($1, $3); } | ident { $$ = makeList1($1); } ; opt_returning: /*empty*/ { $$ = NIL; } | RETURNING target_list { $$ = $2; } ; opt_bulk: /*empty*/ { $$ = false; } | BULK COLLECT { $$ = true; } ; opt_into_list: INTO ident_list { $$ = $2; } | /*empty*/ { $$ = NIL; } ; /***************************************************************************** * QUERY: * DELETE STATEMENTS * *****************************************************************************/ DeleteStmt: _DELETE del_targ_tab opt_from_clause opt_where_clause opt_returning opt_bulk opt_into_list { DeleteStmt *n = makeNode(DeleteStmt); n->relation = (TabNode*)$2; n->fromClause = $3; n->whereClause = $4; n->return_list = $5; n->into_list = $7; n->is_bulk = $6; $$ = (Node *)n; } | _DELETE del_targ_tab opt_from_clause WHERE CURRENT OF name opt_returning opt_bulk opt_into_list { DeleteStmt *n = makeNode(DeleteStmt); n->relation = (TabNode*)$2; n->fromClause = $3; n->whereClause = NULL; n->cursor_name = $7; n->return_list = $8; n->into_list = $10; n->is_bulk = $9; $$ = (Node *)n; } ; del_targ_tab: base_table_ref { $$ = $1; } | FROM base_table_ref { $$ = $2; } ; /***************************************************************************** * * QUERY: * LOCK STATEMENTS * *****************************************************************************/ LockStmt: _LOCK opt_table relation_name_list opt_lock opt_wait { LockStmt *n = makeNode(LockStmt); n->tab_name_list = $3; n->mode = $4; n->wait_ms = $5; $$ = (Node *)n; } ; opt_lock: _IN SHARE MODE { $$ = S_LOCK; } | _IN EXCLUSIVE MODE { $$ = X_LOCK; } | _IN ROW SHARE MODE { $$ = IS_LOCK; } | _IN ROW EXCLUSIVE MODE { $$ = IX_LOCK; } | /*EMPTY*/ { $$ = X_LOCK; } ; /***************************************************************************** * QUERY: * UpdateStmt (UPDATE) *****************************************************************************/ UpdateStmt: UPDATE base_table_refs SET update_target_list opt_from_clause opt_where_clause opt_returning opt_bulk opt_into_list { UpdateStmt *n = makeNode(UpdateStmt); n->targetTables = $2; n->targetList = $4; n->fromClause = $5; n->whereClause = $6; n->return_list = $7; n->is_bulk = $8; n->into_list = $9; $$ = (Node *)n; } | UPDATE base_table_refs SET update_target_list opt_from_clause WHERE CURRENT OF name opt_returning opt_bulk opt_into_list { UpdateStmt *n = makeNode(UpdateStmt); n->targetTables = $2; n->targetList = $4; n->fromClause = $5; n->cursor_name = $9; n->return_list = $10; n->is_bulk = $11; n->into_list = $12; $$ = (Node *)n; } //why 2015-11-27 add | UPDATE base_table_refs SET '(' update_target_list ')' '=' select_with_parens opt_where_clause opt_returning opt_bulk opt_into_list { UpdateStmt *n = makeNode(UpdateStmt); n->targetTables = $2; n->targetList = $5; n->selNode = $8; n->whereClause = $9; n->return_list = $10; n->is_bulk = $11; n->into_list = $12; $$ = (Node *)n; } ; /***************************************************************************** * MergeIntoStmt (MERGE INTO) ++bysdc@20200910 for mergeinto *****************************************************************************/ MergeIntoStmt:MERGE INTO base_table_ref USING table_ref ON '(' bool_expr ')' WHEN MATCHED THEN UPDATE SET update_target_list opt_where_clause opt_delete_where_clause WHEN NOT MATCHED THEN INSERT insert_merge opt_where_clause { MergeIntoStmt *n = makeNode(MergeIntoStmt); n->mergeType = 3; n->to_relation = (TabNode*) $3; //build select node JoinNode *jnode = makeNode(JoinNode); jnode->jointype = JOIN_RIGHT; jnode->isNatural = false; jnode->isMergeinto = true; jnode->larg = $3; jnode->rarg = $5; jnode->quals = $8; n->selectStmt = makeSelectStmt4JoinNode(jnode); //update clause UpdateStmt *u = makeNode(UpdateStmt); u->targetTables = makeList1($3); u->targetList = $15; n->updateStmt = u; //insert clause ((InsertStmt*)$23)->relation = (TabNode*) $3; n->insertStmt = $23;// n->updateWhereClause = $16; n->updateDeleteClause = $17; n->insertWhereClause = $24; $$ = (Node *)n; } | MERGE INTO base_table_ref USING table_ref ON '(' bool_expr ')' WHEN NOT MATCHED THEN INSERT insert_merge opt_where_clause WHEN MATCHED THEN UPDATE SET update_target_list opt_where_clause opt_delete_where_clause { MergeIntoStmt *n = makeNode(MergeIntoStmt); n->mergeType = 3; n->to_relation = (TabNode*) $3; // JoinNode *jnode = makeNode(JoinNode); jnode->jointype = JOIN_RIGHT; jnode->isNatural = false; jnode->isMergeinto = true; jnode->larg = $3; jnode->rarg = $5; jnode->quals = $8; n->selectStmt = makeSelectStmt4JoinNode(jnode); // UpdateStmt *u = makeNode(UpdateStmt); u->targetTables = makeList1($3); u->targetList = $22; n->updateStmt = u; // ((InsertStmt*)$15)->relation = (TabNode*) $3; n->insertStmt = $15; n->insertWhereClause = $16; n->updateWhereClause = $23; n->updateDeleteClause = $24; $$ = (Node *)n; } | MERGE INTO base_table_ref USING table_ref ON '(' bool_expr ')' WHEN MATCHED THEN UPDATE SET update_target_list opt_where_clause opt_delete_where_clause { MergeIntoStmt *n = makeNode(MergeIntoStmt); n->mergeType = 1; n->to_relation = (TabNode*) $3; // JoinNode *m = makeNode(JoinNode); m->jointype = JOIN_INNER; m->isNatural = false; m->isMergeinto = true; m->larg = $3; m->rarg = $5; m->quals = $8; n->selectStmt = makeSelectStmt4JoinNode(m); // UpdateStmt *u = makeNode(UpdateStmt); u->targetTables = makeList1($3); u->targetList = $15; n->updateStmt = u; n->updateWhereClause = $16; n->updateDeleteClause = $17; $$ = (Node *)n; } | MERGE INTO base_table_ref USING table_ref ON '(' bool_expr ')' WHEN NOT MATCHED THEN INSERT insert_merge opt_where_clause { MergeIntoStmt *n = makeNode(MergeIntoStmt); n->mergeType = 2; n->to_relation = (TabNode*) $3; // JoinNode *m = makeNode(JoinNode); m->jointype = JOIN_RIGHT; m->isNatural = false; m->isMergeinto = true; m->larg = $3; m->rarg = $5; m->quals = $8; n->selectStmt = makeSelectStmt4JoinNode(m); // ((InsertStmt*)$15)->relation = (TabNode*) $3; n->insertStmt = $15;// n->insertWhereClause = $16; $$ = (Node *)n; } ; opt_delete_where_clause: _DELETE WHERE bool_expr { $$ = $3; } | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ } ; /***************************************************************************** * * QUERY: * CURSOR STATEMENTS * *****************************************************************************/ CursorStmt: DECLARE ColId func_args CURSOR FOR SelectStmt parallel_opt opt_wait { CursorDef *p_def = makeNode(CursorDef); p_def->var_name = $2; p_def->args = $3; p_def->cur_type = CUR_INSENSITIVE; p_def->define = (SelectStmt*)$6; ((SelectStmt*)$6)->parallel = $7; ((SelectStmt*)$6)->wait_ms = $8; $$ = (Node*)p_def; SetNodePos($$); } | DECLARE ColId func_args CURSOR FOR ColId parallel_opt opt_wait { CursorDef *p_def = makeNode(CursorDef); p_def->var_name = $2; p_def->cur_type = CUR_INSENSITIVE; p_def->stmt_name = $6; $$ = (Node*)p_def; SetNodePos($$); } ; /***************************************************************************** * * QUERY: * SELECT STATEMENTS * *****************************************************************************/ /* A complete SELECT statement looks like this. * * The rule returns either a single SelectStmt node or a tree of them, * representing a set-operation tree. * * There is an ambiguity when a sub-SELECT is within an b_expr and there * are excess parentheses: do the parentheses belong to the sub-SELECT or * to the surrounding b_expr? We don't really care, but yacc wants to know. * To resolve the ambiguity, we are careful to define the grammar so that * the decision is staved off as long as possible: as long as we can keep * absorbing parentheses into the sub-SELECT, we will do so, and only when * it's no longer possible to do that will we decide that parens belong to * the expression. For example, in "SELECT (((SELECT 2)) + 3)" the extra * parentheses are treated as part of the sub-select. The necessity of doing * it that way is shown by "SELECT (((SELECT 2)) UNION SELECT 2)". Had we * parsed "((SELECT 2))" as an b_expr, it'd be too late to go back to the * SELECT viewpoint when we see the UNION. * * This approach is implemented by defining a nonterminal select_with_parens, * which represents a SELECT with at least one outer layer of parentheses, * and being careful to use select_with_parens, never '(' SelectStmt ')', * in the expression grammar. We will then have shift-reduce conflicts * which we can resolve in favor of always treating '(' nonterminal to something else. We use UMINUS * precedence for this, which is a fairly arbitrary choice. * * To be able to define select_with_parens itself without ambiguity, we need * a nonterminal select_no_parens that represents a SELECT structure with no * outermost parentheses. This is a little bit tedious, but it works. * * In non-expression contexts, we use SelectStmt which can represent a SELECT * with or without outer parentheses. */ SelectStmt: select_no_parens %prec UMINUS | select_with_parens %prec UMINUS | with_clauses select_no_parens { ((SelectStmt*)$2)->with_list = $1; $$ = $2; } ; with_clauses: WITH with_name AS select_with_parens { QryNode *n = makeNode(QryNode); ((QryNode*)n)->subquery = $4; ((QryNode*)n)->name =(Attr*) $2; $$ = makeList1(n); } | with_clauses ',' with_name AS select_with_parens { QryNode *n = makeNode(QryNode); ((QryNode*)n)->subquery = $5; ((QryNode*)n)->name =(Attr*) $3; $$ =lappend($$,n); } ; with_name: ColId '(' name_list ')' { $$ = (Node*)makeNode(Attr); ((Attr*)$$)->relname = $1; ((Attr*)$$)->fields = $3; } | ColId { $$ = (Node*)makeNode(Attr); ((Attr*)$$)->relname = $1; }; select_with_parens: '(' select_no_parens parallel_opt opt_wait ')' { $$ = $2; ((SelectStmt*)$2)->parallel = $3; ((SelectStmt*)$2)->wait_ms = $4; SetNodePos($$); } | '(' select_with_parens ')' { $$ = $2; SetNodePos($$); } //++bywsy@20210225 bug3561 | '(' with_clauses select_no_parens ')' { ((SelectStmt*)$3)->with_list = $2; $$ = $3; SetNodePos($$); } ; select_no_parens: simple_select { $$ = $1; } /* why 2015-12-17 modify old: | select_clause sort_clause opt_nulls_order opt_for_update_clause opt_select_limit { insertSelectOptions((SelectStmt *)$1,$2,$4,(Node*)nth(0,$5),(Node*)nth(1,$5)); ((SelectStmt*)$1)->nulls_first = $3; $$ = $1; SetNodePos($$); } */ | select_clause sort_clause opt_for_update_clause opt_select_limit { //why 2016-04-11 modify old:insertSelectOptions((SelectStmt *)$1,$2,$3,(Node*)nth(0,$4),(Node*)nth(1,$4)); insertSelectOptions((SelectStmt *)$1,$2,$3,((LimitExpr*)$4)->limitOffset,((LimitExpr*)$4)->limitCount,((LimitExpr*)$4)->is_comma); $$ = $1; SetNodePos($$); } | select_clause for_update_clause opt_select_limit { //why 2016-04-11 modify old:insertSelectOptions((SelectStmt *) $1,NIL,$2,(Node*)nth(0,$3),(Node*)nth(1,$3)); insertSelectOptions((SelectStmt *)$1,NIL,$2,((LimitExpr*)$3)->limitOffset,((LimitExpr*)$3)->limitCount,((LimitExpr*)$3)->is_comma); $$ = $1; SetNodePos($$); } | select_clause select_limit { //why 2016-04-11 modify old:insertSelectOptions((SelectStmt *)$1,NIL,NIL,(Node*)nth(0,$2),(Node*)nth(1,$2)); insertSelectOptions((SelectStmt *)$1,NIL,NIL,((LimitExpr*)$2)->limitOffset,((LimitExpr*)$2)->limitCount,((LimitExpr*)$2)->is_comma); $$ = $1; SetNodePos($$); } | select_clause FOR SNAPSHOT OF ICONST AFTER ICONST START AT ICONST opt_select_limit { ((SelectStmt*)$1)->for_snapshot = true; ((SelectStmt*)$1)->remote_db_id = $5; ((SelectStmt*)$1)->last_trans_id = $7; ((SelectStmt*)$1)->start_rowpos = $10; //why 2016-04-11 modify old:insertSelectOptions((SelectStmt *)$1,NIL,NIL,(Node*)nth(0,$11),(Node*)nth(1, $11)); insertSelectOptions((SelectStmt *)$1,NIL,NIL,((LimitExpr*)$11)->limitOffset,((LimitExpr*)$11)->limitCount,((LimitExpr*)$11)->is_comma); $$ = $1; SetNodePos($$); } ; select_clause: simple_select | select_with_parens ; /* * This rule parses SELECT statements that can appear within set operations, * including UNION, INTERSECT and EXCEPT. '(' and ')' can be used to specify * the ordering of the set operations. Without '(' and ')' we want the * operations to be ordered per the precedence specs at the head of this file. * * As with select_no_parens, simple_select cannot have outer parentheses, * but can have parenthesized subclauses. * * Note that sort clauses cannot be included at this level --- SQL92 requires * SELECT foo UNION SELECT bar ORDER BY baz * to be parsed as * (SELECT foo UNION SELECT bar) ORDER BY baz * not * SELECT foo UNION (SELECT bar ORDER BY baz) * Likewise FOR UPDATE and LIMIT. Therefore, those clauses are described * as part of the select_no_parens production, not simple_select. * This does not limit functionality, because you can reintroduce sort and * limit clauses inside parentheses. * * NOTE: only the leftmost component SelectStmt should have INTO. * However, this is not checked by the grammar; parse analysis must check it. */ simple_select:SELECT opt_hint opt_top opt_distinct target_list opt_bulk opt_into_list opt_from_clause opt_where_clause opt_connect_by opt_group_clause opt_having_clause { SelectStmt *n = makeNode(SelectStmt); n->hint_text = $2;//++bysdc@20200411 n->limitCount = $3; n->is_distinct = $4; n->targetList = $5; n->is_bulk = $6; n->intoList = $7; n->fromClause = $8; n->whereClause = $9; if($10!=NIL) { n->connect_by = ((ConnectBy*)$10)->connect_by; n->start_with = ((ConnectBy*)$10)->start_with; n->no_cycle = ((ConnectBy*)$10)->no_cycle; n->keep_clause = ((ConnectBy*)$10)->keep_clause; n->start_with_first = ((ConnectBy*)$10)->start_with_first;//fix bug3517 add lwb@20200830 } n->groupClause = $11; n->havingClause = $12; $$ = (Node *)n; SetNodePos($$); } | select_clause UNION opt_all opt_corresponding select_clause { $$ = makeSetOp(SETOP_UNION, $3, $1, $5,$4); SetNodePos($$); } | select_clause INTERSECT opt_all opt_corresponding select_clause { $$ = makeSetOp(SETOP_INTERSECT, $3, $1, $5,$4); SetNodePos($$); } | select_clause EXCEPT opt_all opt_corresponding select_clause { $$ = makeSetOp(SETOP_EXCEPT, $3, $1, $5,$4); SetNodePos($$); } | select_clause MINUS opt_all opt_corresponding select_clause { $$ = makeSetOp(SETOP_EXCEPT, $3, $1, $5,$4); SetNodePos($$); } ; opt_connect_by: /*empty*/ { $$ = NIL; } | connect_by { $$ = $1; } ; connect_by: CONNECT BY bool_expr START WITH bool_expr opt_keep_clause { ConnectBy *n = New(ConnectBy); n->connect_by = $3; n->start_with = $6; n->keep_clause = $7; n->start_with_first = false;//fix bug3517 add lwb@20200830 $$ = (void*)n; } | CONNECT BY NOCYCLE bool_expr START WITH bool_expr opt_keep_clause { ConnectBy *n = New(ConnectBy); n->connect_by = $4; n->start_with = $7; n->keep_clause = $8; n->no_cycle = true; n->start_with_first = false;//fix bug3517 add lwb@20200830 $$ = (void*)n; } | START WITH bool_expr CONNECT BY bool_expr opt_keep_clause { ConnectBy *n = New(ConnectBy); n->connect_by = $6; n->start_with = $3; n->keep_clause = $7; n->start_with_first = true;//fix bug3517 add lwb@20200830 $$ = (void*)n; } | START WITH bool_expr CONNECT BY NOCYCLE bool_expr opt_keep_clause { ConnectBy *n = New(ConnectBy); n->connect_by = $7; n->start_with = $3; n->keep_clause = $8; n->no_cycle = true; n->start_with_first = true;//fix bug3517 add lwb@20200830 $$ = (void*)n; } | CONNECT BY bool_expr opt_keep_clause { ConnectBy *n = New(ConnectBy); n->connect_by = $3; n->keep_clause = $4; n->start_with_first = false;//fix bug3517 add lwb@20200830 $$ = (void*)n; } | CONNECT BY NOCYCLE bool_expr opt_keep_clause { ConnectBy *n = New(ConnectBy); n->connect_by = $4; n->keep_clause = $5; n->no_cycle = true; n->start_with_first = false;//fix bug3517 add lwb@20200830 $$ = (void*)n; } ; opt_keep_clause: /*empty*/ { $$ = NULL; } | KEEP bool_expr { $$ = $2; } ; opt_corresponding: { $$ = NIL; } | CORRESPONDING { $$ = makeList1(NULL); } | CORRESPONDING BY name_list { $$ = $3; } ; opt_top: /*empty*/ { $$ = NULL; } | TOP ICONST { $$ = (Node*)makeInteger($2); } ; //++bysdc@20200411 opt_hint: /*empty*/ { $$ = NULL; } | _HINT_TEXT { $$ = $1; } ; opt_table: TABLE { $$ = true; } | /*EMPTY*/ { $$ = false; } ; opt_all: ALL { $$ = true; } | DISTINCT { $$ = true;} | /*EMPTY*/ { $$ = false; } ; /* We use (NIL) as a placeholder to indicate that all target expressions * should be placed in the DISTINCT list during parsetree analysis. */ opt_distinct: DISTINCT { $$ = true; } | ALL { $$ = false; } | /*EMPTY*/ { $$ = false; } ; sort_clause: ORDER BY sortby_list { $$ = $3; } | ORDER SIBLINGS BY sortby_list { Ident *p_ident = makeNode(Ident); p_ident->name = "CONNECT_BY_SIBLINGS"; SortBy *p_sort = makeNode(SortBy); p_sort->node = (Node*)p_ident; p_sort->useOp = (char*)"<"; List *l1 = makeList1(p_sort); $$ = lconc(l1,$4); } ; sortby_list: sortby { $$ = makeList1($1); } | sortby_list ',' sortby { $$ = lappend($1, $3); } ; // why 2015-12-17 modify compatible oracle /* sortby: b_expr OptUseOp { $$ = (Node*)makeNode(SortBy); ((SortBy*)$$)->node = $1; ((SortBy*)$$)->useOp = $2; } ; */ sortby: b_expr OptUseOp opt_nulls_order { $$ = (Node*)makeNode(SortBy); ((SortBy*)$$)->node = $1; ((SortBy*)$$)->useOp = $2; ((SortBy*)$$)->nulls_first = $3; } ; OptUseOp: USING ROp { $$ = $2; } | _ASC { $$ = (char*)"<"; } | DESC { $$ = (char*)">"; } | /*EMPTY*/ { $$ = (char*)"<"; } ; opt_nulls_order: NULLS FIRST {$$ = NULLS_FIRST;} | NULLS LAST {$$ = NULLS_LAST;} |/*empty*/ {$$ = NULLS_DEFAULT;} ; /*why 2016-04-11 modify old: select_limit: LIMIT select_offset_value ',' select_limit_value { $$ = makeList2($2, $4); } | LIMIT select_limit_value OFFSET select_offset_value { $$ = makeList2($4, $2); } | LIMIT select_limit_value { $$ = makeList2(NULL, $2); } */ select_limit: LIMIT select_offset_value ',' select_limit_value { LimitExpr *n = makeNode(LimitExpr); n->limitCount = $4; n->limitOffset = $2; n->is_comma = true; $$ = (Node*)n; } | LIMIT select_limit_value OFFSET select_offset_value { LimitExpr *n = makeNode(LimitExpr); n->limitCount = $2; n->limitOffset = $4; n->is_comma = false; $$ = (Node*)n; } | LIMIT select_limit_value { LimitExpr *n = makeNode(LimitExpr); n->limitCount = $2; n->is_comma = false; $$ = (Node*)n; } ; opt_select_limit: select_limit { $$ = $1; } | /* EMPTY */ { //why 2016-04-11 modify old:$$ = makeList2(NULL,NULL); $$ = (Node*)makeNode(LimitExpr); } ; select_limit_value: ICONST { if($1 <0) $1 = 0; $$ = (Node*)makeInteger($1); } | ALL { /* LIMIT ALL is represented as a NULL constant */ $$ = (Node*)makeInteger(0); } /*why 2016-04-11 add*/ |Param { $$ = $1; } | ':' ICONST { Ident *n = makeNode(Ident); n->param_no = $2; n->ident_t = IDENT_PARAM; $$ = (Node *)n; SetNodePos($$); } //end ; select_offset_value: ICONST { if ($1 < 0) $1 = 0; $$ = (Node*)makeInteger($1); } /*why 2016-04-11 add*/ |Param { $$ = $1; } | ':' ICONST { Ident *n = makeNode(Ident); n->param_no = $2; n->ident_t = IDENT_PARAM; $$ = (Node *)n; SetNodePos($$); } //end ; relation_name_list: name_space { $$ = makeList1($1); } | relation_name_list ',' name_space { $$ = lappend($1,$3); } ; name_list: name { $$ = makeList1($1); } | name_list ',' name { $$ = lappend($1, $3); } ; opt_group_clause: _GROUP BY group_items { $$ = $3; } | /*EMPTY*/{ $$ = NIL; } ; group_items: group_item { $$ = makeList1($1); } | group_items ',' group_item { $$ = lappend($1,$3); } ; group_item: b_expr { $$ = (Node*)$1; } | ROLLUP '(' group_items ')' { GroupingSet *grp_item = makeNode(GroupingSet); grp_item->grp_type = 1; grp_item->members = $3; $$ = (Node*)grp_item; } | CUBE '(' group_items ')' { GroupingSet *grp_item = makeNode(GroupingSet); grp_item->grp_type = 2; grp_item->members = $3; $$ = (Node*)grp_item; } | GROUPING SETS '(' group_items ')' { GroupingSet *grp_item = makeNode(GroupingSet); grp_item->grp_type = 3; grp_item->members = $4; $$ = (Node*)grp_item; } | '(' multi_group_item ')' { GroupingSet *grp_item = makeNode(GroupingSet); grp_item->grp_type = 4; grp_item->members = $2; $$ = (Node*)grp_item; } | '(' ')' { GroupingSet *grp_item = makeNode(GroupingSet); grp_item->grp_type = 4; grp_item->members = NIL; $$ = (Node*)grp_item; } ; multi_group_item: group_item ',' group_item { $$ = makeList2($1,$3); } | multi_group_item ',' group_item { $$ = lappend($1,$3); } ; opt_having_clause: HAVING bool_expr { $$ = $2; } | /*EMPTY*/ { $$ = NULL; } ; opt_for_update_clause: for_update_clause { $$ = $1; } | /* EMPTY */ { $$ = NULL; } ; for_update_clause: FOR UPDATE OF update_list { $$ = $4; } | FOR READ ONLY { $$ = NULL; } | FOR UPDATE { $$ = makeList1(NULL);} ; update_list: name_space { $$ = makeList1($1); } | update_list ',' name_space { $$ = lappend($1,$3); } ; /***************************************************************************** * * clauses common to all Optimizable Stmts: * opt_from_clause - allow list of both JOIN expressions and table names * opt_where_clause - qualifications for joins or restrictions * *****************************************************************************/ opt_from_clause: { $$ = NIL; } | FROM from_list { $$ = $2; } ; from_list: from_list ',' table_ref { $$ = lappend($1, $3); } | table_ref { $$ = makeList1($1); } ; /* ++bysdc@20200915 query by partition */ opt_parti_clip_clause: /*EMPTY*/ { $$ = NULL; } | PARTITION '(' name_list ')' { PartiClip *n = makeNode(PartiClip); ((PartiClip*)n)->parti_level = 0; ((PartiClip*)n)->parti_names =(List*) $3; $$ = (Node *) n; } | SUBPARTITION '(' name_list ')' { PartiClip *n = makeNode(PartiClip); ((PartiClip*)n)->parti_level = 1; ((PartiClip*)n)->parti_names =(List*) $3; $$ = (Node *) n; } /* * table_ref is where an alias clause can be attached. Note we cannot make * alias_clause have an empty production because that causes parse conflicts * between table_ref := '(' joined_table ')' alias_clause * and joined_table := '(' joined_table ')'. So, we must have the * redundant-looking productions here instead. */ base_table_refs: base_table_ref { $$ = makeList1($1); } | base_table_refs ','base_table_ref { $$ = lappend($1,$3); }; base_table_ref: relation_expr { $$ = (Node *) $1; } | relation_expr alias_clause { ((TabNode*)$1)->name =(Attr*) $2; $$ = (Node *) $1; }; table_ref: base_table_ref { $$ = $1; } | select_with_parens { QryNode *n = makeNode(QryNode); ((QryNode*)n)->subquery = $1; $$ = (Node *) n; } | select_with_parens alias_clause { QryNode *n = makeNode(QryNode); ((QryNode*)n)->subquery = $1; ((QryNode*)n)->name =(Attr*) $2; $$ = (Node *) n; } //why 2015-12-17 add | '(' relation_expr ')' { $$ = (Node *) $2; } | '(' relation_expr ')' alias_clause { ((TabNode*)$2)->name =(Attr*) $4; $$ = (Node *) $2; } //end | joined_table { $$ = (Node *) $1; } | '(' joined_table ')' alias_clause { ((JoinNode*)$2)->alias = (Attr*) $4; $$ = (Node *) $2; } | TABLE '(' c_expr ')' { $$ = (Node*)makeNode(TabNode); ((TabNode*)$$)->tab_expr = $3; SetNodePos($$); } | TABLE '(' c_expr ')' alias_clause { $$ = (Node*)makeNode(TabNode); ((TabNode*)$$)->tab_expr = $3; ((TabNode*)$$)->name = (Attr*)$5; SetNodePos($$); } ; /* * It may seem silly to separate joined_table from table_ref, but there is * method in SQL92's madness: if you don't do it this way you get reduce- * reduce conflicts, because it's not clear to the parser generator whether * to expect alias_clause after ')' or not. For the same reason we must * treat 'JOIN' and 'join_type JOIN' separately, rather than allowing * join_type to expand to empty; if we try it, the parser generator can't * figure out when to reduce an empty join_type right after table_ref. * * Note that a CROSS JOIN is the same as an unqualified * INNER JOIN, and an INNER JOIN/ON has the same shape * but a qualification expression to limit membership. * A NATURAL JOIN implicitly matches column names between * tables and the shape is determined by which columns are * in common. We'll collect columns during the later transformations. */ joined_table: '(' joined_table ')' { $$ = $2; } | table_ref CROSS JOIN table_ref { /* CROSS JOIN is same as unqualified inner join */ JoinNode *n = makeNode(JoinNode); n->jointype = JOIN_INNER; n->isNatural = false; n->larg = $1; n->rarg = $4; n->usings = NIL; n->quals = NULL; $$ = (Node*)n; } | table_ref UNIONJOIN table_ref { /* UNION JOIN is made into 1 token to avoid shift/reduce * conflict against regular UNION keyword. */ JoinNode *n = makeNode(JoinNode); n->jointype = JOIN_UNION; n->isNatural = false; n->larg = $1; n->rarg = $3; n->usings = NIL; n->quals = NULL; $$ = (Node*)n; } | table_ref join_type JOIN table_ref USING '(' name_list ')' { JoinNode *n = makeNode(JoinNode); n->jointype = (JType)$2; n->isNatural = false; n->larg = $1; n->rarg = $4; n->usings = (List*)$7; $$ = (Node*)n; } | table_ref join_type JOIN table_ref ON bool_expr { JoinNode *n = makeNode(JoinNode); n->jointype = (JType)$2; n->isNatural = false; n->larg = $1; n->rarg = $4; n->quals = $6; $$ = (Node*)n; } | table_ref JOIN table_ref USING '(' name_list ')' { /* letting join_type reduce to empty doesn't work */ JoinNode *n = makeNode(JoinNode); n->jointype = JOIN_INNER; n->isNatural = false; n->larg = $1; n->rarg = $3; n->usings = (List *)$6; $$ = (Node*)n; } | table_ref JOIN table_ref ON bool_expr { /* letting join_type reduce to empty doesn't work */ JoinNode *n = makeNode(JoinNode); n->jointype = JOIN_INNER; n->isNatural = false; n->larg = $1; n->rarg = $3; n->quals = $5; $$ = (Node*)n; } | table_ref NATURAL join_type JOIN table_ref { JoinNode *n = makeNode(JoinNode); n->jointype = (JType)$3; n->isNatural = true; n->larg = $1; n->rarg = $5; n->usings = NIL; /* figure out which columns later... */ n->quals = NULL; /* fill later */ $$ = (Node*)n; } | table_ref NATURAL JOIN table_ref { /* letting join_type reduce to empty doesn't work */ JoinNode *n = makeNode(JoinNode); n->jointype = JOIN_INNER; n->isNatural = true; n->larg = $1; n->rarg = $4; n->usings = NIL; /* figure out which columns later... */ n->quals = NULL; /* fill later */ $$ = (Node*)n; } ; alias_clause: AS ColId '(' name_list ')' { $$ = (Node*)makeNode(Attr); ((Attr*)$$)->relname = $2; ((Attr*)$$)->fields = $4; } | AS ColId { $$ = (Node*)makeNode(Attr); ((Attr*)$$)->relname = $2; } | ColId '(' name_list ')' { $$ = (Node*)makeNode(Attr); ((Attr*)$$)->relname = $1; ((Attr*)$$)->fields = $3; } | ColId { $$ = (Node*)makeNode(Attr); ((Attr*)$$)->relname = $1; } ; join_type: FULL join_outer { $$ = JOIN_FULL; } | LEFT join_outer { $$ = JOIN_LEFT; } | RIGHT join_outer { $$ = JOIN_RIGHT; } | _INNER { $$ = JOIN_INNER; } ; /* OUTER is just noise... */ join_outer: _OUTER { $$ = NULL; } | /*EMPTY*/ { $$ = NULL; } ; relation_expr: name_space opt_parti_clip_clause/* bysdc@20200915 */ { /* default inheritance */ $$ = (Node*)makeNode(TabNode); ((TabNode*)$$)->relname = $1; ((TabNode*)$$)->name = NULL; ((TabNode*)$$)->partiClip = $2;//bysdc@20200915 SetNodePos($$); } | name_space '@' name { /* default inheritance */ $$ = (Node*)makeNode(TabNode); ((TabNode*)$$)->relname = $1; ((TabNode*)$$)->name = NULL; ((TabNode*)$$)->link_name = $3; SetNodePos($$); } ; opt_where_clause: WHERE bool_expr { $$ = $2; } | /*EMPTY*/ { $$ = NULL; /* no qualifiers */ } ; filter_where_clause: WHERE bool_expr { $$ = $2; }; /***************************************************************************** * * Type syntax * SQL92 introduces a large amount of type-specific syntax. * Define individual clauses to handle these cases, and use * the generic case to handle regular type-extensible syntax. * - thomas 1997-10-10 * *****************************************************************************/ /* data type */ TypeName: STypename { $$ = $1; SetNodePos($$); } | TABLE OF STypename { Typenam *p_node = (Typenam*)makeNode(Typenam); p_node->type_id = TYPE_TABLE; p_node->memb_type = (Typenam*)$3; $$ = (Node*)p_node; SetNodePos($$); } | TABLE OF STypename INDEX BY STypename { Typenam *p_node = (Typenam*)makeNode(Typenam); p_node->type_id = TYPE_ITABLE; p_node->memb_type = (Typenam*)$3; p_node->idx_type = (Typenam*)$6; $$ = (Node*)p_node; SetNodePos($$); } | VARRAY '(' ICONST ')' OF STypename { Typenam *p_node = (Typenam*)makeNode(Typenam); p_node->type_id = TYPE_VARRAY; p_node->elem_num = $3; p_node->memb_type = (Typenam*)$6; $$ = (Node*)p_node; SetNodePos($$); } | VARYING ARRAY '(' ICONST ')' OF STypename { Typenam *p_node = (Typenam*)makeNode(Typenam); p_node->type_id = TYPE_VARRAY; p_node->elem_num = $4; p_node->memb_type = (Typenam*)$7; $$ = (Node*)p_node; SetNodePos($$); } ; col_defs: MemberVarDecl { $$ = makeList1($1); } | col_defs ',' MemberVarDecl { $$ = lappend($1,$3); } ; STypename: ConstTypename | GenericType | name_space '%' ROWTYPE { Typenam * p_node = (Typenam*)makeNode(Typenam); p_node->type_id = TYPE_ROWTYPE; p_node->type_name = $1; $$ = (Node*)p_node; SetNodePos($$); } | name_space '%' ROW TYPE { Typenam * p_node = (Typenam*)makeNode(Typenam); p_node->type_id = TYPE_ROWTYPE; p_node->type_name = $1; $$ = (Node*)p_node; SetNodePos($$); } | name_space '%' TYPE { Typenam * p_node = (Typenam*)makeNode(Typenam); p_node->type_id = TYPE_COLTYPE; p_node->type_name = $1; $$ = (Node*)p_node; SetNodePos($$); } | ROWTYPE OF name_space { Typenam * p_node = (Typenam*)makeNode(Typenam); p_node->type_id = TYPE_ROWTYPE; p_node->type_name = $3; $$ = (Node*)p_node; SetNodePos($$); } | ROW TYPE OF name_space { Typenam * p_node = (Typenam*)makeNode(Typenam); p_node->type_id = TYPE_ROWTYPE; p_node->type_name = $4; $$ = (Node*)p_node; SetNodePos($$); } | TYPE OF name_space { Typenam * p_node = (Typenam*)makeNode(Typenam); p_node->type_id = TYPE_COLTYPE; p_node->type_name = $3; $$ = (Node*)p_node; SetNodePos($$); } | REF CURSOR { Typenam * p_node = (Typenam*)makeNode(Typenam); p_node->type_id = TYPE_REFCUR; $$ = (Node*)p_node; SetNodePos($$); } | RECORD '('col_defs ')' { Typenam * p_node = makeNode(Typenam); p_node->type_id = TYPE_RECORD; p_node->col_defs = $3; $$ = (Node*)p_node; SetNodePos($$); } ; STypename1: ConstTypename1 | GenericType ; ConstTypename: Numeric | Bit | Character | ConstDatetime | _RAW_ { $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = "BINARY"; ((Typenam*)$$)->preci_scale = -1; } | _RAW_ '(' ICONST ')' { $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = "BINARY"; ((Typenam*)$$)->preci_scale = $3; } | BINARY { $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = "BINARY"; ((Typenam*)$$)->preci_scale = -1; } ; ConstTypename1: Numeric | Bit | Character | ConstDatetime1 | BINARY { $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = "BINARY"; ((Typenam*)$$)->preci_scale = -1; } ; GenericType: name_space { $$ = (Node*)makeNode(Typenam); if(!astricmp($1,"SYS_REFCURSOR")) ((Typenam*)$$)->type_id = TYPE_REFCUR; else { ((Typenam*)$$)->type_name = xlateSqlType($1); ((Typenam*)$$)->preci_scale = -1; } } ; /*SQL92 numeric data types * Check _FLOAT() precision limits assuming IEEE floating types. * Provide real _DECIMAL() and _NUMERIC() implementations now */ Numeric: _FLOAT opt_float { $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = "FLOAT"; ((Typenam*)$$)->preci_scale = -1; } | _DOUBLE { $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = "DOUBLE"; ((Typenam*)$$)->preci_scale = -1; } /* | _DOUBLE PRECISION { $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = "DOUBLE"; ((Typenam*)$$)->preci_scale = -1; }*/ | _DECIMAL opt_decimal { $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = "NUMERIC"; ((Typenam*)$$)->preci_scale = $2; } | DEC opt_decimal { $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = "NUMERIC"; ((Typenam*)$$)->preci_scale = $2; } | _NUMERIC opt_numeric { $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = "NUMERIC"; ((Typenam*)$$)->preci_scale = $2; } | NUMBER opt_decimal { $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = "NUMERIC"; ((Typenam*)$$)->preci_scale = $2; } ; opt_float: '(' ICONST ')' { if ($2 < 1) { SetParsePos(); add_parse_error(80); } else if ($2 <= 32) $$ = (char*)"FLOAT"; else if ($2 <= 128) $$ = (char*)"DOUBLE"; else { SetParsePos(); add_parse_error(81); } } | /*EMPTY*/ { $$ = (char*)"FLOAT"; } ; opt_numeric: '(' ICONST ',' ICONST ')' { if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION) { SetParsePos(); add_parse_error(82,$2, NUMERIC_MAX_PRECISION); } if ($4 < 0 || $4 > $2) { SetParsePos(); add_parse_error(83, $4,$2); } $$ = (($2 << 16) | $4); } | '(' ICONST ')' { if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION) { SetParsePos(); add_parse_error(82, $2, NUMERIC_MAX_PRECISION); } $$ = ($2 << 16); } | /*EMPTY*/ { $$ = ((NUMERIC_DEFAULT_PRECISION<<16)); } ; opt_decimal: '(' ICONST ',' ICONST ')' { if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION) { SetParsePos(); add_parse_error(84, $2, NUMERIC_MAX_PRECISION); } if ($4 < 0 || $4 > $2) { SetParsePos(); add_parse_error(85, $4,$2); } $$ = (($2 << 16) | $4); } | '(' ICONST ')' { if ($2 < 1 || $2 > NUMERIC_MAX_PRECISION) { SetParsePos(); add_parse_error(84, $2, NUMERIC_MAX_PRECISION); } $$ = ($2 << 16); } | '(' '*' ',' ICONST ')' { $$ = ((NUMERIC_DEFAULT_PRECISION<<16)|$4); } | '(' ICONST ',' '*' ')' { $$ = (($2<<16)|NUMERIC_DEFAULT_SCALE); } | '(' '*' ')' { $$ = ((NUMERIC_DEFAULT_PRECISION<<16)); } | '(' '*' ',' '*' ')' { $$ = ((NUMERIC_DEFAULT_PRECISION<<16)|NUMERIC_DEFAULT_SCALE); } | /*EMPTY*/ { $$ = ((NUMERIC_DEFAULT_PRECISION<<16)); } ; /* * SQL92 bit-field data types * The following implements BIT() and BIT VARYING(). */ Bit: BIT opt_varying opt_preci { Typenam *p_typenam = makeNode(Typenam); p_typenam->type_name = "BIT"; p_typenam->is_varying = $2; p_typenam->preci_scale = $3; $$ = (Node*)p_typenam; } ; /* * SQL92 character data types * The following implements CHAR() and VARCHAR(). */ Character: character opt_charset opt_preci { $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = "CHAR"; ((Typenam*)$$)->cset_name = $2; ((Typenam*)$$)->preci_scale = $3; ((Typenam*)$$)->is_varying = (astricmp($1,"CHAR")!=0); } ; character: CHARACTER opt_varying { $$ = $2 ? (char*)"VARCHAR": (char*)"CHAR";} | VARCHAR { $$ = (char*)"VARCHAR"; } | NVARCHAR { $$ = (char*)"VARCHAR"; } | VARCHAR2 { $$ = (char*)"VARCHAR"; } | NVARCHAR2 { $$ = (char*)"VARCHAR"; } | NCHAR opt_varying { $$ = $2 ? (char*)"VARCHAR": (char*)"CHAR"; } | NATIONAL CHARACTER opt_varying{ $$ = $3 ? (char*)"VARCHAR": (char*)"CHAR"; } ; opt_varying: VARYING { $$ = true; } | /*EMPTY*/ { $$ = false; } ; opt_preci: { $$ = -1;} | '(' ICONST ')' { if($2 < 1) { SetParsePos(); add_parse_error(88); } else if($2 > MAX_ATTR_SIZE) { SetParsePos(); add_parse_error(89,MAX_ATTR_SIZE); } $$ = $2; } ; opt_charset: CHARACTER SET ColId { $$ = $3; } | CHARACTER SET Sconst { $$ = dbs2utf($3);} | /*EMPTY*/ { $$ = NULL; } ; opt_collate: COLLATE ColId { $$ = $2; } | /*EMPTY*/ { $$ = NULL; } ; ConstDatetime: TIMESTAMP opt_sub_label opt_with_timez opt_auto_update { if($2>6) add_parse_error(971,"TIMESTAMP",6); if($2<0) $2 = 6; $$ = (Node*)makeNode(Typenam); if($3) ((Typenam*)$$)->type_name = "DATETIME WITH TIME ZONE"; else ((Typenam*)$$)->type_name = "DATETIME"; ((Typenam*)$$)->preci_scale = $2; ((Typenam*)$$)->is_timestamp = true; if($4) ((Typenam*)$$)->timestamp_type = 'u'; /*for update*/ else ((Typenam*)$$)->timestamp_type = 'i'; /*for insert*/ } | TIME opt_sub_label opt_with_timez { if($2>3) add_parse_error(971,"TIME",3); if($2<0) $2 = 3; $$ = (Node*)makeNode(Typenam); if($3) ((Typenam*)$$)->type_name = "TIME WITH TIME ZONE"; else ((Typenam*)$$)->type_name = "TIME"; ((Typenam*)$$)->preci_scale = $2; } | _DATE { $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = "DATE"; ((Typenam*)$$)->preci_scale = -1; } | DATETIME opt_sub_label opt_with_timez { if($2>6) add_parse_error(971,"DATETIME",6); if($2<0) $2 = 6; $$ = (Node*)makeNode(Typenam); if($3) ((Typenam*)$$)->type_name = "DATETIME WITH TIME ZONE"; else ((Typenam*)$$)->type_name = "DATETIME"; ((Typenam*)$$)->preci_scale = $2; } | INTERVAL opt_interval { $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = interval_names[(((uint)$2)>>28)-1]; ((Typenam*)$$)->preci_scale = ($2 & 0x0fffffff); } ; opt_auto_update: /*empty*/ { $$ = false; } | AUTO UPDATE { $$ = true; } ; ConstDatetime1: TIMESTAMP opt_sub_label { if($2>6) add_parse_error(971,"TIMESTAMP",6); if($2<0) $2 = 6; $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = "DATETIME"; ((Typenam*)$$)->preci_scale = $2; ((Typenam*)$$)->is_timestamp = true; ((Typenam*)$$)->timestamp_type = 'i'; } //why 2016-05-06 modify bug:1895 | TIME opt_sub_label { if($2>3) add_parse_error(971,"TIME",3); if($2<0) $2 = 3; $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = "TIME"; ((Typenam*)$$)->preci_scale = $2; } /* | TIME opt_sub_label opt_with_timez { if($2>3) add_parse_error(971,"TIME",3); if($2<0) $2 = 3; $$ = (Node*)makeNode(Typenam); if($3) ((Typenam*)$$)->type_name = "TIME WITH TIME ZONE"; else ((Typenam*)$$)->type_name = "TIME"; ((Typenam*)$$)->preci_scale = $2; } */ | _DATE { $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = "DATE"; ((Typenam*)$$)->preci_scale = -1; } //why 2016-05-06 modify bug:1895 old: /* | DATETIME opt_sub_label { if($2>6) add_parse_error(971,"DATETIME",6); if($2<0) $2 = 6; $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = "DATETIME"; ((Typenam*)$$)->preci_scale = $2; } */ | DATETIME opt_sub_label opt_with_timez { if($2>6) add_parse_error(971,"DATETIME",6); if($2<0) $2 = 6; $$ = (Node*)makeNode(Typenam); if($3) ((Typenam*)$$)->type_name = "DATETIME WITH TIME ZONE"; else ((Typenam*)$$)->type_name = "DATETIME"; ((Typenam*)$$)->preci_scale = $2; } | INTERVAL opt_interval { $$ = (Node*)makeNode(Typenam); ((Typenam*)$$)->type_name = interval_names[(((uint)$2)>>28)-1]; ((Typenam*)$$)->preci_scale = ($2 & 0x0fffffff); } ; dt_unit: _YEAR { $$ = DTUNIT_YEAR; } | _MONTH { $$ = DTUNIT_MONTH; } | _DAY { $$ = DTUNIT_DAY; } | _HOUR { $$ = DTUNIT_HOUR; } | _MINUTE { $$ = DTUNIT_MINUTE; } | _SECOND { $$ = DTUNIT_SECOND; } ; opt_with_timez: WITH TIME ZONE { $$ = true; } | WITHOUT TIME ZONE { $$ = false; } | /*EMPTY*/ { $$ = false; } ; opt_interval: _YEAR opt_sub_label { if($2>9) add_parse_error(970,"INTERVAL YEAR",9); if($2<0) $2 = 9; $$ = 0x10000000|($2<<16); } | _MONTH opt_sub_label { if($2>9) add_parse_error(970,"INTERVAL MONTH",9); if($2<0) $2 = 9; $$ = 0x20000000|($2<<16); } | _YEAR opt_sub_label TO _MONTH { if($2>8) add_parse_error(970,"INTERVAL YEAR",8); if($2<0) $2 = 8; $$ = 0x30000000|($2<<16); } | _DAY opt_sub_label { if($2>9) add_parse_error(970,"INTERVAL DAY",9); if($2<0) $2 = 9; $$ = 0x40000000|($2<<16); } | _HOUR opt_sub_label { if($2>9) add_parse_error(970,"INTERVAL HOUR",9); if($2<0) $2 = 9; $$ = 0x50000000|($2<<16); } | _MINUTE opt_sub_label { if($2>9) add_parse_error(970,"INTERVAL MINUTE",9); if($2<0) $2 = 9; $$ = 0x60000000|($2<<16); } | _SECOND opt_sub_label2 { if(($2>>16)>9) add_parse_error(970,"INTERVAL SECOND",9); if(($2&0x0ffff)>6) add_parse_error(971,"INTERVAL SECOND",6); $$ = 0x70000000|($2); } | _DAY opt_sub_label TO _HOUR { if($2>7) add_parse_error(970,"INTERVAL DAY TO HOUR",7); if($2<0) $2 = 7; $$ = 0x80000000|($2<<16); } | _DAY opt_sub_label TO _MINUTE { if($2>6) add_parse_error(970,"INTERVAL DAY TO MINUTE",6); if($2<0) $2 = 6; $$ = 0x90000000|($2<<16); } | _DAY opt_sub_label TO _SECOND opt_sub_label { if($2>6) add_parse_error(970,"INTERVAL DAY TO SECOND",7); if($2<0) $2 = 6; if($5>6) add_parse_error(971,"INTERVAL DAY TO SECOND",6); if($5<0) $5 = 6; $$ = 0xa0000000|($2<<16)|$5; } | _HOUR opt_sub_label TO _MINUTE { if($2>7) add_parse_error(970,"INTERVAL HOUR TO MINUTE",7); if($2<0) $2 = 7; $$ = 0xb0000000|($2<<16); } | _HOUR opt_sub_label TO _SECOND opt_sub_label { if($2>7) add_parse_error(970,"INTERVAL HOUR TO SECOND",7); if($2<0) $2 = 7; if($5>6) add_parse_error(971,"INTERVAL HOUR TO SECOND",6); if($5<0) $5 = 6; $$ = 0xc0000000|($2<<16)|$5; } | _MINUTE opt_sub_label TO _SECOND opt_sub_label { if($2>7) add_parse_error(970,"INTERVAL MINUTE TO SECOND",7); if($2<0) $2 = 7; if($5>6) add_parse_error(971,"INTERVAL MINUTE TO SECOND",6); if($5<0) $5 = 6; $$ = 0xd0000000|($2<<16)|$5; } ; opt_sub_label: { $$ = -1; } | '(' ICONST ')' { if($2>10) add_parse_error(961); $$ = $2; } ; opt_sub_label2: { $$ = 0x90006; } | '(' ICONST ')' { if($2>12) add_parse_error(961); $$ = ($2<<16)|0x6; } | '(' ICONST ',' ICONST ')' { if($2>12 || $4>9) add_parse_error(961); $$ = (($2<<16)|$4); } ; sub_type: ANY { $$ = ANY_SUBLINK; } | SOME { $$ = ANY_SUBLINK; } | ALL { $$ = ALL_SUBLINK; } ; opt_match_type: { $$ = 0; } | UNIQUE { $$ = 0x10000; } | UNIQUE PARTIAL { $$ = 0x10001; } | UNIQUE FULL { $$ = 0x10002; } | PARTIAL { $$ = 1; } | FULL { $$ = 2; } ; ROp: '<' { $$ = (char*)"<"; } | '>' { $$ = (char*)">"; } | '=' { $$ = (char*)"="; } | LE { $$ = (char*)"<=";} | GE { $$ = (char*)">=";} | NE { $$ = (char*)"<>";} ; GeomROp: CONTAINS {$$ = (char*)"CONTAINS";} | WITHIN { $$ = (char*)"WITHIN";} | TOUCHES { $$ = (char*)"TOUCHS";} | DISJOINT { $$ = (char*)"DISJOIN";} | OVERLAPS { $$ = (char*)"OVERLAPS";} | CROSSES { $$ = (char*)"CROSSES";} | INTERSECTS { $$ = (char*)"INTERSECTS";} | EQUALS { $$ = (char*)"EQUALS";} | BCONTAINS { $$ = (char*)"BCONTAINS";} | BWITHIN { $$ = (char*)"BWITHIN";} | BINTERSECTS { $$ = (char*)"BINTERSECTS";} | BOVERLAPS { $$ = (char*)"BOVERLAPS";} | ABOVE { $$ = (char*)"ABOVE";} | UNDER { $$ = (char*)"UNDER";} | LEFTOF { $$ = (char*)"LEFTOF";} | RIGHTOF { $$ = (char*)"RIGHTOF";} | LOVERLAPS { $$ = (char*)"LOVERLAPS";} | ROVERLAPS { $$ = (char*)"ROVERLAPS";} | AOVERLAPS { $$ = (char*)"AOVERLAPS";} | UOVERLAPS { $$ = (char*)"UOVERLAPS";} ; bool_expr: rela_expr { $$ = $1; SetNodePos($$); } | bool_expr1 { $$ = $1; SetNodePos($$); } | bool_expr AND bool_expr { $$ = makeA_Expr(OP_AND, NULL, $1, $3); SetNodePos($$); } | bool_expr OR bool_expr { $$ = makeA_Expr(OP_OR, NULL, $1, $3); SetNodePos($$); } | NOT bool_expr { $$ = makeA_Expr(OP_NOT, NULL, NULL, $2); SetNodePos($$); } | b_expr { $$ = $1; SetNodePos($$); } ; bool_expr1: '(' bool_expr AND bool_expr ')' { $$ = makeA_Expr(OP_AND, NULL, $2, $4); SetNodePos($$); } | '(' bool_expr OR bool_expr ')' { $$ = makeA_Expr(OP_OR, NULL, $2, $4); SetNodePos($$); } | '(' NOT bool_expr ')' { $$ = makeA_Expr(OP_NOT, NULL, NULL, $3); SetNodePos($$); } | '(' bool_expr1 ')' { $$ = $2; SetNodePos($$); } ; rela_expr: '(' rela_expr ')' { $$ = $2; SetNodePos($$); } | b_expr LIKE b_expr { $$ = makeA_Expr(OP, "LIKE", $1, $3); SetNodePos($$); } | b_expr _O_JOIN LIKE b_expr //why 2016-01-29 add { $$ = makeA_Expr(OP, "LIKE", $1, $4); ((A_Expr*)$$)->ora_join = JOIN_RIGHT; SetNodePos($$); } | b_expr LIKE b_expr ESCAPE SCONST { A_Const *n = makeNode(A_Const); n->val.type = T_String; n->val.val.str = $5; if( *(((char*)$5)+1)!=0) add_parse_error(962); $$ = makeA_Expr(OP, "LIKE", $1, $3); ((A_Expr*)$$)->tag = (Node*)n; SetNodePos($$); } | b_expr NOT LIKE b_expr { $$ = makeA_Expr(OP, "NOTLIKE", $1, $4); SetNodePos($$); } | b_expr NOT LIKE b_expr ESCAPE SCONST { A_Const *n = makeNode(A_Const); n->val.type = T_String; n->val.val.str = $6; if( *(((char*)$6)+1)!=0) add_parse_error(962); $$ = makeA_Expr(OP, "NOTLIKE", $1, $4); ((A_Expr*)$$)->tag = (Node*)n; SetNodePos($$); } | b_expr ILIKE b_expr { $$ = makeA_Expr(OP, "ILIKE", $1, $3); SetNodePos($$); } | b_expr ILIKE b_expr ESCAPE SCONST { A_Const *n = makeNode(A_Const); n->val.type = T_String; n->val.val.str = $5; if( *(((char*)$5)+1)!=0) add_parse_error(962); $$ = makeA_Expr(OP, "ILIKE", $1, $3); ((A_Expr*)$$)->tag = (Node*)n; SetNodePos($$); } | b_expr NOT ILIKE b_expr { $$ = makeA_Expr(OP, "NOTILIKE", $1, $4); SetNodePos($$); } | b_expr NOT ILIKE b_expr ESCAPE SCONST { A_Const *n = makeNode(A_Const); n->val.type = T_String; n->val.val.str = $6; if(*(((char*)$6)+1)!=0) add_parse_error(962); $$ = makeA_Expr(OP, "NOTILIKE", $1, $4); ((A_Expr*)$$)->tag = (Node*)n; SetNodePos($$); } | b_expr ISNULL { $$ = makeA_Expr(OP_ISNULL, NULL, $1, NULL); SetNodePos($$); } | b_expr IS _NULL { $$ = makeA_Expr(OP_ISNULL, NULL, $1, NULL); SetNodePos($$); } | b_expr NOTNULL { $$ = makeA_Expr(OP_NOTNULL, NULL, $1, NULL); SetNodePos($$); } | b_expr IS NOT _NULL { $$ = makeA_Expr(OP_NOTNULL, NULL, $1, NULL); SetNodePos($$); } | b_expr IS _TRUE { A_Const *n = makeNode(A_Const); n->val.type = T_Boolean; n->val.val.bval = TRUE; n->type_name = "BOOLEAN"; n->preci_scale = -1; $$ = makeA_Expr(OP, "=", $1,(Node *)n); SetNodePos($$); } | b_expr IS NOT _TRUE { A_Const *n = makeNode(A_Const); n->val.type = T_Boolean; n->val.val.bval = TRUE; n->type_name = "BOOLEAN"; n->preci_scale = -1; $$ = makeA_Expr(OP, "<>", $1,(Node *)n); SetNodePos($$); } | b_expr IS _FALSE { A_Const *n = makeNode(A_Const); n->val.type = T_Boolean; n->val.val.bval = FALSE; n->type_name = "BOOLEAN"; n->preci_scale = -1; $$ = makeA_Expr(OP, "=", $1,(Node *)n); SetNodePos($$); } | b_expr IS NOT _FALSE { A_Const *n = makeNode(A_Const); n->val.type = T_Boolean; n->val.val.bval = FALSE; n->type_name = "BOOLEAN"; n->preci_scale = -1; $$ = makeA_Expr(OP, "<>", $1,(Node *)n); SetNodePos($$); } /*why 2015-12-22 modify old: | b_expr BETWEEN b_expr AND b_expr %prec BETWEEN { $$ = makeA_Expr(OP_AND, NULL, makeA_Expr(OP, ">=", $1, $3), makeA_Expr(OP, "<=", $1, $5)); SetNodePos($$); } | b_expr NOT BETWEEN b_expr AND b_expr %prec BETWEEN { $$ = makeA_Expr(OP_OR, NULL, makeA_Expr(OP, "<", $1, $4), makeA_Expr(OP, ">", $1, $6)); SetNodePos($$); } */ | b_expr BETWEEN b_expr AND b_expr %prec BETWEEN { BetweenExpr * n = makeNode(BetweenExpr); n->is_not = false; n->expr = $1; n->low_expr = $3; n->high_expr = $5; $$ = (Node *)n; SetNodePos($$); } | b_expr NOT BETWEEN b_expr AND b_expr %prec BETWEEN { BetweenExpr * n = makeNode(BetweenExpr); //n->is_not = true;//update lwb@20200901 n->expr = $1; n->low_expr = $4; n->high_expr = $6; //$$ = (Node *)n; $$ = makeA_Expr(OP_NOT, NULL, NULL, (Node*)n); //update lwb@20200901,wrap BetweenExpr into OP_NOT SetNodePos($$); } /* select_with_parens reduce conflict with c_expr*/ | b_expr _IN select_with_parens { SubLink *n = makeNode(SubLink); n->sub_select = $3; n->left_exprs = makeList1($1); n->oper = "="; n->sublk_t = ANY_SUBLINK; $$ = (Node *)n; SetNodePos($$); } | b_expr _IN '(' expr_list ')' { if(length((List*)$4)<=1) $$ = makeA_Expr(OP, "=", $1, (Node*)lptr((List*)$4)); else { InExpr *p_in = makeNode(InExpr); p_in->left_expr = $1; p_in->val_list = (List*)$4; $$ = (Node*)p_in; } SetNodePos($$); } /* select_with_parens reduce conflict with c_expr*/ | b_expr NOT _IN select_with_parens { SubLink *n = makeNode(SubLink); n->sub_select = $4; n->left_exprs = makeList1($1); n->oper = "<>"; n->sublk_t = ALL_SUBLINK; $$ = (Node *)n; SetNodePos($$); } | b_expr NOT _IN '(' expr_list ')' { Node *n = NULL; if(length((List*)$5)==1) $$ = makeA_Expr(OP, "<>", $1, (Node*)lptr((List*)$5)); else { InExpr *p_in = makeNode(InExpr); //p_in->is_not_in = true;//update lwb@20200901 unuse is_not in wrap into notexpr p_in->left_expr = $1; p_in->val_list = (List*)$5; //$$ = (Node*)p_in; $$ = makeA_Expr(OP_NOT, NULL, NULL, (Node*)p_in); //update lwb@20200901 } SetNodePos($$); } | b_expr ROp sub_type select_with_parens %prec ROp { SubLink *n = makeNode(SubLink); n->left_exprs = makeList1($1); n->oper = $2; n->sublk_t = (SubLkT)$3; n->sub_select = $4; $$ = (Node *)n; SetNodePos($$); } | EXISTS select_with_parens { SubLink *n = makeNode(SubLink); n->left_exprs = NIL; n->oper = NULL; n->sublk_t = EXISTS_SUBLINK; n->sub_select = $2; $$ = (Node *)n; SetNodePos($$); } | UNIQUE select_with_parens { SubLink *n = makeNode(SubLink); n->left_exprs = NIL; n->oper = NULL; n->sublk_t = UNIQUE_SUBLINK; n->sub_select = $2; $$ = (Node *)n; SetNodePos($$); } | b_expr ROp b_expr { if(exprIsNullConstant($1) || exprIsNullConstant($3)) { A_Const *n = makeNode(A_Const); n->val.type = T_Boolean; n->val.val.bval = -1; n->type_name = "BOOLEAN"; n->preci_scale = -1; $$ = (Node*)n; } else if(!strcmp($2,">")) { if( exprIsGeoOp($1) && IsA($3,A_Const)) { if( getConstVal($3) > 0 ) { $$ = makeA_Expr(OP_NOT,NULL,NULL,$1); } else $$ = $1; } else if(exprIsGeoOp($3) && IsA($1,A_Const)) { if(getConstVal($1)==0) { $$ = makeA_Expr ( NOT, NULL, NULL, $3 ); } else $$ = $1; } else $$ = makeA_Expr(OP, $2, $1, $3); } else if(!strcmp($2,"=")) { if ( exprIsGeoOp($1) && IsA($3,A_Const)) { if ( getConstVal($3) == 0 ) { $$ = makeA_Expr(OP_NOT,NULL,NULL,$1); } else $$ = $1; } else if(exprIsGeoOp($3) && IsA($1,A_Const)) { if(getConstVal($1)==0) { $$ = makeA_Expr ( NOT, NULL, NULL, $3 ); } else $$ = $1; } else $$ = makeA_Expr(OP, "=", $1, $3); } else $$ = makeA_Expr(OP, $2, $1, $3); SetNodePos($$); } | b_expr GeomROp b_expr { $$ = makeA_Expr(OP, $2, $1, $3); SetNodePos($$); } | b_expr ROp b_expr _O_JOIN { $$ = makeA_Expr(OP,$2,$1,$3); ((A_Expr*)$$)->ora_join = JOIN_LEFT; SetNodePos($$); } | b_expr _O_JOIN ROp b_expr { $$ = makeA_Expr(OP,$3,$1,$4); ((A_Expr*)$$)->ora_join = JOIN_RIGHT; SetNodePos($$); } | '(' expr_vector ')' _IN select_with_parens { SubLink *n = makeNode(SubLink); n->left_exprs = $2; n->oper = "="; n->sublk_t = ANY_SUBLINK; n->sub_select = $5; $$ = (Node *)n; SetNodePos($$); } | '(' expr_vector ')' _IN '(' vector_values ')' { VInExpr *n = makeNode(VInExpr); n->left_exprs = $2; n->vector_values = $6; $$ = (Node*)n; SetNodePos($$); } | '(' expr_vector ')' NOT _IN select_with_parens { SubLink *n = makeNode(SubLink); n->left_exprs = $2; n->oper = "<>"; n->sublk_t = ALL_SUBLINK; n->sub_select = $6; $$ = (Node *)n; SetNodePos($$); } | '(' expr_vector ')' NOT _IN '(' vector_values ')' { VInExpr *n = makeNode(VInExpr); n->left_exprs = $2; n->is_not_in = true; n->vector_values = $7; $$ = (Node*)n; SetNodePos($$); } | '(' expr_vector ')' ROp sub_type select_with_parens { SubLink *n = makeNode(SubLink); n->left_exprs = $2; n->oper = $4; n->sublk_t = (SubLkT)$5; n->sub_select = $6; $$ = (Node *)n; SetNodePos($$); } | '(' expr_vector ')' ROp select_with_parens { SubLink *n = makeNode(SubLink); n->left_exprs = $2; n->oper = $4; n->sublk_t = MULTIEXPR_SUBLINK; n->sub_select = $5; $$ = (Node *)n; SetNodePos($$); } | '(' expr_vector ')' MATCH opt_match_type select_with_parens { SubLink *n = makeNode(SubLink); n->left_exprs = $2; n->oper = NULL; n->sublk_t = MATCH_SUBLINK; n->match_type = $5; n->sub_select = $6; $$ = (Node *)n; SetNodePos($$); } | '(' expr_vector ')' ROp '(' expr_list ')' { SetParsePos(); $$ = makeRowExpr($4, $2, $6); SetNodePos($$); } | '(' expr_vector ')' ISNULL { SetParsePos(); $$ = makeRowIsNull($2); SetNodePos($$); } | '(' expr_vector ')' IS _NULL { SetParsePos(); $$ = makeRowIsNull($2); SetNodePos($$); } | '(' expr_vector ')' IS NOT _NULL { SetParsePos(); $$ = makeRowNotNull($2); SetNodePos($$); } | '(' expr_vector ')' NOTNULL { SetParsePos(); $$ = makeRowNotNull($2); SetNodePos($$); } | '(' expr_vector ')' OVERLAPS '(' expr_vector ')' { Ident *n = makeNode(Ident); Ident *n1 = makeNode(Ident); List *largs = $2; List *rargs = $6; n1->ident_t = IDENT_FUNC; n->name = "OVERLAPS"; if (length(largs) == 1) largs = lappend(largs, $2); else if (length(largs) != 2) { SetParsePos(); add_parse_error(151); } if (length(rargs) == 1) rargs = lappend(rargs, $6); else if (length(rargs) != 2) { SetParsePos(); add_parse_error(152); } n1->args = lconc(largs, rargs); n1->agg_star = false; n1->agg_distinct = false; set_ident_child(n,n1); $$ = (Node *)n; SetNodePos($$); } ; expr_vector: b_expr ',' b_expr { $$ = makeList2($1,$3); } | expr_vector ',' b_expr { $$ = lappend($1,$3); } ; vector_values: '(' expr_vector ')' { $$ = makeList1($2); } | vector_values ',' '(' expr_vector ')' { $$ = lappend($1,$4); } ; b_expr: c_expr { $$ = $1; } | PRIOR c_expr { PriorExpr *n = makeNode(PriorExpr); n->bexpr = (Node*)$2; $$ = (Node*)n; } /* mzh | c_expr opt_interval { if(!IsA($1,A_Expr)) add_parse_error(90); else { Typenam *p_typenam = makeNode(Typenam); p_typenam->type_name = interval_names[(((uint)$2)>>28)-1]; p_typenam->preci_scale = ($2 & 0x0fffffff); $$ = makeTypeCast($1, p_typenam); SetNodePos($$); } } */ | c_expr TYPECAST STypename1 { $$ = makeTypeCast($1, (Typenam*) $3); SetNodePos($$); } |b_expr AT TIME ZONE c_expr { Ident *n = makeNode(Ident); Ident *n1 = makeNode(Ident); n->name = "TIMEZONE"; n1->args = makeList2($5, $1); n1->agg_star = false; n1->agg_distinct = false; n1->ident_t = IDENT_FUNC; set_ident_child(n,n1); $$ = (Node *)n; SetNodePos($$); } | b_expr '+' b_expr { $$ = makeA_Expr(OP, "+", $1, $3); SetNodePos($$); } | b_expr '-' b_expr { $$ = makeA_Expr(OP, "-", $1, $3); SetNodePos($$); } | b_expr '*' b_expr { $$ = makeA_Expr(OP, "*", $1, $3); SetNodePos($$); } | b_expr '/' b_expr { $$ = makeA_Expr(OP, "/", $1, $3); SetNodePos($$); } | b_expr '^' b_expr { $$ = makeA_Expr(OP, "^", $1, $3); SetNodePos($$); } | b_expr '|' b_expr { $$ = makeA_Expr(OP, "|", $1, $3); SetNodePos($$); } | b_expr Op b_expr { $$ = makeA_Expr(OP, $2, $1, $3); SetNodePos($$); } ; c_expr: '(' b_expr ')' { $$ = $2; } | CONTAINS '(' b_expr ','b_expr ')' { A_Expr *p_expr = (A_Expr*)makeA_Expr(OP,"CONTAINS",$3,$5); $$ = (Node*)p_expr; SetNodePos($$); } | CONTAINS '(' b_expr ','b_expr ',' AexprConst ')' { A_Expr *p_expr = (A_Expr*)makeA_Expr(OP,"CONTAINS",$3,$5); p_expr->tag = (Node*)$7; $$ = (Node*)p_expr; SetNodePos($$); } | GeomROp '(' b_expr ',' b_expr ')' { $$ = makeA_Expr(OP,$1,$3,$5); SetNodePos($$); } | Op c_expr { $$ = makeA_Expr(OP, $1, NULL, $2); SetNodePos($$); } | '+' c_expr { $$ = $2; SetNodePos($$); } | '-' c_expr { $$ = makeA_Expr(OP, "-", NULL, $2); SetNodePos($$); } | '~' c_expr { $$ = makeA_Expr(OP, "~", NULL, $2); SetNodePos($$); } | ident { $$ = (Node *) $1; SetNodePos($$); } | Param { $$ = (Node *) $1; SetNodePos($$); } | AexprConst { $$ = $1; } | CAST '(' b_expr AS STypename ')' { $$ = makeTypeCast($3, (Typenam*)$5); SetNodePos($$); } | case_expr { $$ = $1; } | USER { Ident *n = makeNode(Ident); n->name = "CURRENT_USER"; n->args = NIL; n->agg_star = false; n->agg_distinct = false; $$ = (Node *)n; SetNodePos($$); } | select_with_parens %prec UMINUS { SubLink *n = makeNode(SubLink); n->left_exprs = NIL; n->oper = NULL; n->sublk_t = EXPR_SUBLINK; n->sub_select = $1; $$ = (Node *)n; SetNodePos($$); } | LEAST '(' expr_list ')' { LeastExpr *n = makeNode(LeastExpr); n->args = $3; $$ = (Node*)n; SetNodePos($$); } | GREATEST '(' expr_list ')' { GreatestExpr *n = makeNode(GreatestExpr); n->args = $3; $$ = (Node*)n; SetNodePos($$); } | error { Ident *n = makeNode(Ident); n->name = "@Error@"; n->args = NIL; n->agg_star = false; n->agg_distinct = false; $$ = (Node *)n; SetNodePos($$); } | ident OVER '(' opt_win_parti opt_win_order opt_win_range ')' { WindowExpr *n = makeNode(WindowExpr); n->p_ident = $1; n->parti_list = $4; n->order_list = $5; if($6) { WindowExpr *n1 = (WindowExpr*)$6; n->range_type = n1->range_type; n->wind_lo_off = n1->wind_lo_off; n->wind_hi_off = n1->wind_hi_off; n->wind_lo_val = n1->wind_lo_val; n->wind_hi_val = n1->wind_hi_val; } $$ = (Node*)n; SetNodePos($$); } | ident '%' ROWCOUNT { IdentAttr *n = makeNode(IdentAttr); n->p_ident = (Ident*)$1; n->attr_name = "ROWCOUNT"; $$ = (Node*)n; SetNodePos($$); } | ident '%' FOUND { IdentAttr *n = makeNode(IdentAttr); n->p_ident = (Ident*)$1; n->attr_name = "FOUND"; $$ = (Node*)n; SetNodePos($$); } | ident '%' NOFOUND { IdentAttr *n = makeNode(IdentAttr); n->p_ident = (Ident*)$1; n->attr_name = "NOFOUND"; $$ = (Node*)n; SetNodePos($$); } | ident '%' NOTFOUND { IdentAttr *n = makeNode(IdentAttr); n->p_ident = (Ident*)$1; n->attr_name = "NOFOUND"; $$ = (Node*)n; SetNodePos($$); } | ident '%' ISOPEN { IdentAttr *n = makeNode(IdentAttr); n->p_ident = (Ident*)$1; n->attr_name = "ISOPEN"; $$ = (Node*)n; SetNodePos($$); } ; opt_win_parti: /*empty*/ { $$ = NIL; } | PARTITION BY expr_list { $$ = $3; } ; opt_win_order: /*empty*/ { $$ = NIL; } | ORDER BY sortby_list { $$ = $3; } ; opt_win_range: /*empty*/ { $$ = NULL; } | ROWS window_extent { WindowExpr *n = (WindowExpr *)$2; n->range_type |= FRAMEOPTION_ROWS; $$ = (Node*)n; SetNodePos($$); } | RANGE window_extent { WindowExpr *n = (WindowExpr *)$2; n->range_type |= FRAMEOPTION_RANGE; $$ = (Node*)n; SetNodePos($$); } ; window_extent:row_range { WindowExpr *n = (WindowExpr *)$1; if (n->range_type & FRAMEOPTION_START_UNBOUNDED_FOLLOWING) add_parse_error(1232); if (n->range_type & FRAMEOPTION_START_OFFSET_FOLLOWING) add_parse_error(1232); n->range_type |= FRAMEOPTION_END_CURRENT_ROW; $$ = (Node*)n; } | BETWEEN row_range AND row_range { WindowExpr *n1 = (WindowExpr *)$2; WindowExpr *n2 = (WindowExpr *)$4; int n1_type = n1->range_type; int n2_type = n2->range_type << 1; int n_type = n1_type | n2_type; if(n_type & FRAMEOPTION_START_UNBOUNDED_FOLLOWING) add_parse_error(1232); if(n_type & FRAMEOPTION_START_UNBOUNDED_FOLLOWING) add_parse_error(1232); if ((n_type & FRAMEOPTION_START_CURRENT_ROW) && (n_type & FRAMEOPTION_END_OFFSET_PRECEDING)) add_parse_error(1232); if ((n_type & FRAMEOPTION_START_OFFSET_FOLLOWING) && (n_type & (FRAMEOPTION_END_OFFSET_PRECEDING | FRAMEOPTION_END_CURRENT_ROW))) add_parse_error(1232); n1->wind_hi_off = n2->wind_lo_off; n1->wind_hi_val = n2->wind_lo_val; n1->range_type |= (n1_type | n2_type | FRAMEOPTION_BETWEEN); $$ = (Node*)n1; } ; row_range:UNBOUNDED PRECEDING { WindowExpr *n = makeNode(WindowExpr); n->range_type= FRAMEOPTION_START_UNBOUNDED_PRECEDING; n->wind_lo_off = (0-0x7fffffff); n->wind_hi_off = 0; n->wind_lo_val = NULL; n->wind_hi_val = NULL; $$ = (Node*)n; } | UNBOUNDED FOLLOWING { WindowExpr *n = makeNode(WindowExpr); n->range_type= FRAMEOPTION_START_UNBOUNDED_FOLLOWING; n->wind_lo_off = 0x7fffffff; n->wind_hi_off = 0; n->wind_lo_val = NULL; n->wind_hi_val = NULL; $$ = (Node*)n; } | CURRENT ROW { WindowExpr *n = makeNode(WindowExpr); n->range_type= FRAMEOPTION_START_CURRENT_ROW; n->wind_lo_off = 0; n->wind_hi_off = 0; n->wind_lo_val = NULL; n->wind_hi_val = NULL; $$ = (Node*)n; } | b_expr PRECEDING { WindowExpr *n = makeNode(WindowExpr); n->range_type= FRAMEOPTION_START_OFFSET_PRECEDING; n->wind_lo_off = ((A_Const *)$1)->val.val.ival; n->wind_hi_off = 0; n->wind_lo_val = $1; n->wind_hi_val = NULL; $$ = (Node*)n; } | b_expr FOLLOWING { WindowExpr *n = makeNode(WindowExpr); n->range_type= FRAMEOPTION_START_OFFSET_FOLLOWING; n->wind_lo_off = ((A_Const *)$1)->val.val.ival; n->wind_hi_off = 0; n->wind_lo_val = $1; n->wind_hi_val = $1; $$ = (Node*)n; } ; expr_list: b_expr { $$ = makeList1($1); } | expr_list ',' b_expr { $$ = lappend($1, $3); } | expr_list USING b_expr { $$ = lappend($1, $3); } ; /* position_list uses b_expr not b_expr to avoid conflict with general _IN */ position_list: b_expr _IN b_expr { $$ = makeList2($3, $1); } ; /* SUBSTRING() arguments * SQL9x defines a specific syntax for arguments to SUBSTRING(): * o substring(text from int for int) * o substring(text from int) get entire string from starting point "INTEGER" * o substring(text for int) get first "INTEGER" characters of string * We also want to implement generic substring functions which accept * the usual generic list of arguments. So we will accept both styles * here, and convert the SQL9x style to the generic list for further * processing. - thomas 2000-11-28 */ substr_list: b_expr FROM b_expr FOR b_expr { $$ = makeList3($1, $3, $5); } | b_expr FOR b_expr FROM b_expr { $$ = makeList3($1, $5, $3); } | b_expr FOR b_expr { A_Const *n = makeNode(A_Const); n->val.type = T_Integer; n->val.val.ival = 1; $$ = makeList3($1,(Node *)n, $3); } ; trim_list: b_expr FROM b_expr { $$ = makeList2($3, $1); } | FROM b_expr { $$ = makeList1($2); } ; /* 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: DECODE '(' case_arg ',' decode_list ')' { CaseExpr *c = makeNode(CaseExpr); c->arg = $3; c->args = $5; c->defresult = NULL; $$ = (Node *)c; SetNodePos($$); } | DECODE '(' case_arg ',' decode_list ',' b_expr')' { CaseExpr *c = makeNode(CaseExpr); c->arg = $3; c->args = $5; c->defresult = $7; $$ = (Node *)c; SetNodePos($$); } | CASE case_arg when_clause_list case_default _END { CaseExpr *c = makeNode(CaseExpr); c->arg = $2; c->args = $3; c->defresult = $4; $$ = (Node *)c; SetNodePos($$); } | NVL '(' b_expr ',' b_expr ')' { NvlExpr *n = makeNode(NvlExpr); n->expr = $3; n->null_result = $5; $$ = (Node *)n; SetNodePos($$); } | NVL2 '(' b_expr ',' b_expr ',' b_expr')' { NvlExpr *n = makeNode(NvlExpr); n->expr = $3; n->null_result = $7; n->notnull_result = $5; $$ = (Node *)n; SetNodePos($$); } | NULLIF '(' b_expr ',' b_expr ')' { CaseExpr *c = makeNode(CaseExpr); CaseWhen *w = makeNode(CaseWhen); A_Const *n = makeNode(A_Const); n->val.type = T_Null; w->result = (Node *)n; w->expr = makeA_Expr(OP, "=", $3, $5); c->args = makeList1(w); c->defresult = $3; $$ = (Node *)c; SetNodePos($$); } | COALESCE '(' expr_list ')' { CaseExpr *c = makeNode(CaseExpr); CaseWhen *w; foreach (l,$3) { w = makeNode(CaseWhen); w->expr = makeA_Expr(OP_NOTNULL, NULL, (Node*)lptr(l), NULL); w->result = (Node*)lptr(l); c->args = lappend(c->args, w); } $$ = (Node *)c; SetNodePos($$); } ; when_clause_list: when_clause_list when_clause { $$ = lappend($1, $2); } | when_clause { $$ = makeList1($1); } ; decode_list: b_expr ','b_expr { CaseWhen *w = makeNode(CaseWhen); w->expr = $1; w->result = $3; $$ = makeList1(w); } | decode_list ',' b_expr ',' b_expr { CaseWhen *w = makeNode(CaseWhen); w->expr = $3; w->result = $5; $$ = lappend($1,w); } ; when_clause: WHEN bool_expr THEN b_expr { CaseWhen *w = makeNode(CaseWhen); w->expr = $2; w->result = $4; $$ = (Node *)w; SetNodePos($$); } ; case_default: ELSE b_expr { $$ = $2; } | /*EMPTY*/ { $$ = NULL; } ; case_arg: b_expr { $$ = $1; } | /*EMPTY*/ { $$ = NULL; } ; /******************************************************************************** * * ident node * ********************************************************************************/ ident: ':' ColId { Ident *n = makeNode(Ident); n->name = $2; n->ident_t = IDENT_PARAM; $$ = (Node *)n; SetNodePos($$); } | ':' ICONST { Ident *n = makeNode(Ident); n->param_no = $2; n->ident_t = IDENT_PARAM; $$ = (Node *)n; SetNodePos($$); } | ColId { Ident *n = makeNode(Ident); n->name = $1; $$ = (Node *)n; SetNodePos($$); } | COLUMN { Ident *n = makeNode(Ident); n->name = "COLUMN"; $$ = (Node *)n; SetNodePos($$); } | SELF { Ident *n = makeNode(Ident); n->name = "SELF"; $$ = (Node *)n; SetNodePos($$); } | ISNULL { Ident *n = makeNode(Ident); n->name = "ISNULL"; $$ = (Node *)n; SetNodePos($$); } | NOTNULL { Ident *n = makeNode(Ident); n->name = "NOTNULL"; $$ = (Node *)n; SetNodePos($$); } | ident '.' ColLabel { Ident *n = makeNode(Ident); n->name = $3; set_ident_child((Ident*)$1,n); $$ = (Node *)$1; SetNodePos($$); } | ident '(' func_params ')' { Ident *n = makeNode(Ident); n->args = $3; n->agg_star = false; n->agg_distinct = false; n->ident_t = IDENT_FUNC; set_ident_child((Ident*)$1,n); $$ = (Node *)$1; SetNodePos($$); } | ident '(' ALL expr_list ')' { Ident *n = makeNode(Ident); n->args = $4; n->agg_star = false; n->agg_distinct = false; n->ident_t = IDENT_FUNC; set_ident_child((Ident*)$1,n); $$ = (Node *)$1; SetNodePos($$); } | ident '(' DISTINCT expr_list ')' { Ident *n = makeNode(Ident); n->args = $4; n->agg_star = false; n->agg_distinct = true; n->ident_t = IDENT_FUNC; set_ident_child((Ident*)$1,n); $$ = (Node *)$1; SetNodePos($$); } | ident '(' '*' ')' { A_Const *star; Ident *n = makeNode(Ident); star = makeNode(A_Const); star->val.type = T_Integer; star->val.val.ival = 1; n->args = makeList1(star); n->agg_star = true; n->agg_distinct = false; n->ident_t = IDENT_FUNC; set_ident_child((Ident*)$1,n); $$ = (Node *)$1; SetNodePos($$); } | EXTRACT '(' _YEAR FROM b_expr ')' { Ident *n = makeNode(Ident); Ident *n1 = makeNode(Ident); n->name = "EXTRACT_YEAR"; n1->args = makeList1($5); n1->agg_star = false; n1->agg_distinct = false; n1->ident_t = IDENT_FUNC; set_ident_child(n,n1); $$ = (Node *)n; SetNodePos($$); } | EXTRACT '(' _MONTH FROM b_expr ')' { Ident *n = makeNode(Ident); Ident *n1 = makeNode(Ident); n->name = "EXTRACT_MONTH"; n1->args = makeList1($5); n1->agg_star = false; n1->agg_distinct = false; n1->ident_t = IDENT_FUNC; set_ident_child(n,n1); $$ = (Node *)n; SetNodePos($$); } | EXTRACT '(' _DAY FROM b_expr ')' { Ident *n = makeNode(Ident); Ident *n1 = makeNode(Ident); n->name = "EXTRACT_DAY"; n1->args = makeList1($5); n1->agg_star = false; n1->agg_distinct = false; n1->ident_t = IDENT_FUNC; set_ident_child(n,n1); $$ = (Node *)n; SetNodePos($$); } | EXTRACT '(' _HOUR FROM b_expr ')' { Ident *n = makeNode(Ident); Ident *n1 = makeNode(Ident); n->name = "EXTRACT_HOUR"; n1->args = makeList1($5); n1->agg_star = false; n1->agg_distinct = false; n1->ident_t = IDENT_FUNC; set_ident_child(n,n1); $$ = (Node *)n; SetNodePos($$); } | EXTRACT '(' _MINUTE FROM b_expr ')' { Ident *n = makeNode(Ident); Ident *n1 = makeNode(Ident); n->name = "EXTRACT_MINUTE"; n1->args = makeList1($5); n1->agg_star = false; n1->agg_distinct = false; n1->ident_t = IDENT_FUNC; set_ident_child(n,n1); $$ = (Node *)n; SetNodePos($$); } | EXTRACT '(' _SECOND FROM b_expr ')' { Ident *n = makeNode(Ident); Ident *n1 = makeNode(Ident); n->name = "EXTRACT_SECOND"; n1->args = makeList1($5); n1->agg_star = false; n1->agg_distinct = false; n1->ident_t = IDENT_FUNC; set_ident_child(n,n1); $$ = (Node *)n; SetNodePos($$); } | ident '(' position_list ')' { Ident *n = (Ident*)$1; if(namecmp(n->name,"POSITION")) { SetParsePos(); add_parse_error(90); } Ident *n1 = makeNode(Ident); n->name = "POSITION"; n1->args = $3; n1->agg_star = false; n1->agg_distinct = false; n1->ident_t = IDENT_FUNC; set_ident_child(n,n1); $$ = (Node *)n; SetNodePos($$); } | ident '(' substr_list ')' { /* substring(A from B for C) is converted to * substring(A, B, C) - thomas 2000-11-28 */ Ident *n = (Ident*)$1; if(namecmp(n->name,"SUBSTRING") &&namecmp(n->name,"SUBSTR")) { SetParsePos(); add_parse_error(90); } Ident *n1 = makeNode(Ident); n->name = "SUBSTR"; n1->args = $3; n1->agg_star = false; n1->agg_distinct = false; n1->ident_t = IDENT_FUNC; set_ident_child(n,n1); $$ = (Node *)n; SetNodePos($$); } | ident '(' BOTH trim_list ')' { Ident *n = (Ident*)$1; if(namecmp(n->name,"TRIM")) { SetParsePos(); add_parse_error(90); } Ident *n1 = makeNode(Ident); n->name = "TRIM"; n1->args = $4; n1->agg_star = false; n1->agg_distinct = false; n1->ident_t = IDENT_FUNC; set_ident_child(n,n1); $$ = (Node *)n; SetNodePos($$); } | ident '(' LEADING trim_list ')' { Ident *n = (Ident*)$1; if(namecmp(n->name,"TRIM")) { SetParsePos(); add_parse_error(90); } Ident *n1 = makeNode(Ident); n->name = "LTRIM"; n1->args = $4; n1->agg_star = false; n1->agg_distinct = false; n1->ident_t = IDENT_FUNC; set_ident_child(n,n1); $$ = (Node *)n; SetNodePos($$); } | ident '(' TRAILING trim_list ')' { Ident *n = (Ident*)$1; if(namecmp(n->name,"TRIM")) { SetParsePos(); add_parse_error(90); } Ident *n1 = makeNode(Ident); n->name = "RTRIM"; n1->args = $4; n1->agg_star = false; n1->agg_distinct = false; n1->ident_t = IDENT_FUNC; set_ident_child(n,n1); $$ = (Node *)n; SetNodePos($$); } | ident '(' trim_list ')' { Ident *n = (Ident*)$1; if(namecmp(n->name,"TRIM")) { SetParsePos(); add_parse_error(90); } Ident *n1 = makeNode(Ident); n->name = "TRIM"; n1->args = $3; n1->agg_star = false; n1->agg_distinct = false; n1->ident_t = IDENT_FUNC; set_ident_child(n,n1); $$ = (Node *)n; SetNodePos($$); } ; /***************************************************************************** * * target lists * *****************************************************************************/ /* Target lists as found in SELECT ... and INSERT VALUES ( ... ) */ target_list: target_list ',' target_el { $$ = lappend($1, $3); } | target_el { $$ = makeList1($1); } ; /* AS is not optional because shift/red conflict with unary ops */ target_el: b_expr AS ColLabel { $$ = (Node*)makeNode(ResTarget); ((ResTarget*)$$)->name = $3; ((ResTarget*)$$)->val = (Node *)$1; SetNodePos($$); } | b_expr ColId { $$ = (Node*)makeNode(ResTarget); ((ResTarget*)$$)->name = $2; ((ResTarget*)$$)->val = (Node *)$1; SetNodePos($$); } | DEFAULT { $$ = (Node*)makeNode(ResTarget); ((ResTarget*)$$)->name = NULL; ((ResTarget*)$$)->val = NULL; SetNodePos($$); } | b_expr { $$ = (Node*)makeNode(ResTarget); ((ResTarget*)$$)->name = NULL; ((ResTarget*)$$)->val = (Node *)$1; SetNodePos($$); } | ident '.' '*' { Attr *att = makeNode(Attr); att->relname = ident2names((Ident*)$1); if(!att->relname) { SetParsePos(); add_parse_error(581); } att->fields = makeList1((char*)"*"); $$ = (Node*)makeNode(ResTarget); ((ResTarget*)$$)->name = NULL; ((ResTarget*)$$)->val = (Node *)att; SetNodePos($$); } | '*' { Attr *att = makeNode(Attr); att->relname = "*"; att->fields = NULL; $$ = (Node*)makeNode(ResTarget); ((ResTarget*)$$)->name = NULL; ((ResTarget*)$$)->val = (Node *)att; SetNodePos($$); } ; /* Target list as found in UPDATE table SET ... */ update_target_list: update_target_el { $$ = makeList1($1); } | update_target_list ',' update_target_el { $$ = lappend($1,$3); } ; update_target_el: ident '=' b_expr { UpdateTarget *n = makeNode(UpdateTarget); n->targ_var = $1; n->val = (Node *)$3; $$ = (Node*)n; SetNodePos($$); } | ident '=' DEFAULT { UpdateTarget *n = makeNode(UpdateTarget); n->targ_var = $1; n->val = NULL; $$ = (Node*)n; SetNodePos($$); } //why 2015-11-27 add | ident { UpdateTarget *n = makeNode(UpdateTarget); n->targ_var = $1; n->val = NULL; $$ = (Node*)n; SetNodePos($$); } ; func_name: name_space { $$ = $1; } | BETWEEN { $$ = (char*)"BETWEEN"; } | ILIKE { $$ = (char*)"ILIKE"; } | _IN { $$ = (char*)"IN"; } | IS { $$ = (char*)"IS"; } | ISNULL { $$ = (char*)"ISNULL"; } | LIKE { $$ = (char*)"LIKE"; } | NOTNULL { $$ = (char*)"NOTNULL"; } ; file_name: Sconst { $$ = dbs2utf($1); }; name: ColId { $$ = $1; }; database_name: TokenId { $$ = $1; }; space_name: TokenId { $$ = $1; }; index_name: TokenId { $$ = $1; }; name_space: TokenId { $$ = $1; //_curr_thd->parse_as_ident = false; } | SELF '.' ColId { char *p_str = (char*)tmalloc(astrlen($3)+8); strcpy(p_str,"SELF."); strcat(p_str,$3); //_curr_thd->parse_as_ident = false; $$ = p_str; } | name_space '.' ColId { char *p_str; SizeT name_len = astrlen($1)+astrlen($3)+4; if(name_len>MAX_NAME_LEN*3) add_parse_error(305,MAX_NAME_LEN*3); p_str = (char*)tmalloc(name_len); strcpy(p_str,$1); strcat(p_str,"."); strcat(p_str,$3); //_curr_thd->parse_as_ident = false; $$ = p_str; } ; AexprConst: ICONST { A_Const *n = makeNode(A_Const); n->val.type = T_Integer; n->val.val.ival = $1; $$ = (Node *)n; SetNodePos($$); } | FCONST { A_Const *n = makeNode(A_Const); n->val.type = T_Numeric; n->val.val.str = $1; $$ = (Node *)n; SetNodePos($$); } | multi_sconst { A_Const *n = makeNode(A_Const); n->val.type = T_String; n->val.val.str = $1; $$ = (Node *)n; SetNodePos($$); } | BITCONST { A_Const *n = makeNode(A_Const); n->val.type = T_BitString; n->val.val.str = $1; $$ = (Node *)n; SetNodePos($$); } | INTERVAL Sconst opt_interval { A_Const *n = makeNode(A_Const); n->val.type = T_String; n->val.val.str = $2; n->type_name = interval_names[(((uint)$3)>>28)-1]; n->preci_scale = ($3 & 0x0fffffff); $$ = (Node*)n; SetNodePos($$); } | INTERVAL '+' Sconst opt_interval { A_Const *n = makeNode(A_Const); n->val.type = T_String; n->val.val.str = $3; n->type_name = interval_names[(((uint)$4)>>28)-1]; n->preci_scale = ($4 & 0x0fffffff); $$ = (Node*)n; SetNodePos($$); } | INTERVAL '-' Sconst opt_interval { A_Const *n = makeNode(A_Const); char *val_str = (char*)tmalloc((SizeT)strlen($3)+4); char *p_str = $3; while(*p_str==' ') p_str++; if(*p_str=='+') { *p_str = '-'; n->val.type = T_String; n->val.val.str = $3; } else if(*p_str=='-') { *p_str = ' '; n->val.type = T_String; n->val.val.str = $3; } else { val_str[0]='-'; strcpy(val_str+1,$3); n->val.type = T_String; n->val.val.str = val_str; } n->type_name = interval_names[(((uint)$4)>>28)-1]; n->preci_scale = ($4 & 0x0fffffff); $$ = (Node*)n; SetNodePos($$); } | _TRUE { A_Const *n = makeNode(A_Const); n->val.type = T_Boolean; n->val.val.bval = true; n->type_name = "BOOLEAN"; n->preci_scale = -1; $$ = (Node *)n; SetNodePos($$); } | _FALSE { A_Const *n = makeNode(A_Const); n->val.type = T_Boolean; n->val.val.bval = false; n->type_name = "BOOLEAN"; n->preci_scale = -1; $$ = (Node *)n; SetNodePos($$); } | _NULL { A_Const *n = makeNode(A_Const); n->val.type = T_Null; $$ = (Node *)n; SetNodePos($$); } ; Param: '?' { Param *n = makeNode(Param); n->paramkind=0; n->paramid=0; n->paramname = NULL; $$ = (Node *)n; SetNodePos($$); } ; multi_sconst: Sconst { $$ = $1; } | multi_sconst Sconst { int len1,len2; char *mstr; len1 = astrlen($1); len2 = astrlen($2); mstr = (char*)tmalloc(len1+len2+2); MemCpy(mstr,$1,len1); MemCpy(mstr+len1,$2,len2); mstr[len1+len2]=0x0; $$ = mstr; } ; /***************************************************************************** * policies maintenance *******************************************************************************/ CreatPolicyStmt: CREATE POLICY name { CreatePolicyStmt *p_stmt = makeNode(CreatePolicyStmt); p_stmt->name = $3; $$ = (Node*)p_stmt; } | CREATE POLICY name PolicyMemsOfCre { CreatePolicyStmt *p_stmt = makeNode(CreatePolicyStmt); p_stmt->name = $3; p_stmt->members = $4; $$ = (Node*)p_stmt; } ; AlterPolicyStmt:ALTER POLICY name PolicyMembers { AlterPolicyStmt *p_stmt = makeNode(AlterPolicyStmt); p_stmt->name = $3; p_stmt->members = $4; $$ = (Node*)p_stmt; } ; PolicyMembers: PolicyMember { $$ = makeList1($1); } | PolicyMembers ',' PolicyMember { $$ = lappend($1,$3); } ; PolicyMemsOfCre: PolicyMemOfCre { $$ = makeList1($1); } | PolicyMemsOfCre ',' PolicyMemOfCre { $$ = lappend($1,$3); } ; PolicyMemOfCre: ADD LEVEL name AS ICONST { PolicyMember *n = makeNode(PolicyMember); n->action = 2; n->level_name = $3; n->level_val = $5; $$ = (Node*)n; } | ADD CATEGORY name { PolicyMember *n = makeNode(PolicyMember); n->action = 4; n->cate_name = $3; $$ = (Node*)n; } ; PolicyMember: RENAME TO name { PolicyMember *n = makeNode(PolicyMember); n->action = 1; n->new_name = $3; $$ = (Node*)n; } | ADD LEVEL name AS ICONST { PolicyMember *n = makeNode(PolicyMember); n->action = 2; n->level_name = $3; n->level_val = $5; $$ = (Node*)n; } | ALTER LEVEL name RENAME TO name { PolicyMember *n = makeNode(PolicyMember); n->action = 3; n->level_name = $3; n->new_level_name = $6; $$ = (Node*)n; } | ADD CATEGORY name { PolicyMember *n = makeNode(PolicyMember); n->action = 4; n->cate_name = $3; $$ = (Node*)n; } | ALTER CATEGORY name RENAME TO name { PolicyMember *n = makeNode(PolicyMember); n->action = 5; n->cate_name = $3; n->new_cate_name = $6; $$ = (Node*)n; } | DROP CATEGORY name { PolicyMember *n = makeNode(PolicyMember); n->action = 6; n->cate_name = $3; $$ = (Node*)n; } | DROP LEVEL name { PolicyMember *n = makeNode(PolicyMember); n->action = 7; n->level_name = $3; $$ = (Node*)n; } ; DropPolicyStmt: DROP POLICY name { DropStmt *p_stmt = makeNode(DropStmt); p_stmt->obj_name = $3; p_stmt->drop_type = DROP_POLICY; $$ = (Node*)p_stmt; } ; AlterUserPolicyStmt: ALTER USER POLICY name ADD name LEVEL name { AlterUserPolicyStmt *p_stmt = makeNode(AlterUserPolicyStmt); p_stmt->action = 1; p_stmt->user_name = $4; p_stmt->policy_name = $6; p_stmt->level_name = $8; $$ = (Node*)p_stmt; } | ALTER USER POLICY name ADD name LEVEL name CATEGORY name_list { AlterUserPolicyStmt *p_stmt = makeNode(AlterUserPolicyStmt); p_stmt->action = 1; p_stmt->user_name = $4; p_stmt->policy_name = $6; p_stmt->level_name = $8; p_stmt->categories = $10; $$ = (Node*)p_stmt; } | ALTER USER POLICY name ALTER name LEVEL name { AlterUserPolicyStmt *p_stmt = makeNode(AlterUserPolicyStmt); p_stmt->action = 2; p_stmt->user_name = $4; p_stmt->policy_name = $6; p_stmt->level_name = $8; $$ = (Node*)p_stmt; } | ALTER USER POLICY name ALTER name CATEGORY name_list { AlterUserPolicyStmt *p_stmt = makeNode(AlterUserPolicyStmt); p_stmt->action = 3; p_stmt->user_name = $4; p_stmt->policy_name = $6; p_stmt->categories= $8; $$ = (Node*)p_stmt; } | ALTER USER POLICY name DROP name { AlterUserPolicyStmt *p_stmt = makeNode(AlterUserPolicyStmt); p_stmt->action = 4; p_stmt->user_name = $4; p_stmt->policy_name = $6; $$ = (Node*)p_stmt; } ; AlterTabPolicyStmt: ALTER TABLE POLICY name_space ADD name COLUMN ColId opt_hide LABEL Sconst { AlterTabPolicyStmt *p_stmt = makeNode(AlterTabPolicyStmt); p_stmt->action = 1; p_stmt->tab_name = $4; p_stmt->policy_name = $6; p_stmt->col_name = $8; p_stmt->is_hide = $9; p_stmt->label = dbs2utf($11); $$ = (Node*)p_stmt; } | ALTER TABLE POLICY name_space ALTER ColId opt_hide { AlterTabPolicyStmt *p_stmt = makeNode(AlterTabPolicyStmt); p_stmt->action = 2; p_stmt->tab_name = $4; p_stmt->policy_name = $6; p_stmt->is_hide = $7; $$ = (Node*)p_stmt; } | ALTER TABLE POLICY name_space DROP name { AlterTabPolicyStmt *p_stmt = makeNode(AlterTabPolicyStmt); p_stmt->action = 3; p_stmt->tab_name = $4; p_stmt->policy_name = $6; $$ = (Node*)p_stmt; } ; opt_hide: /*empty*/ { $$ = false; } | HIDE { $$ = true; } | NOT HIDE { $$ = false; } ; /*enable or disable audit*/ AuditStmt: AUDIT GlobalAuditItems optAuditUser optAuditCond { AuditStmt *p_stmt = makeNode(AuditStmt); p_stmt->audit_type = 1; p_stmt->action = 1; p_stmt->audits = $2; p_stmt->users = $3; p_stmt->audit_cond = $4; $$ = (Node*)p_stmt; } | AUDIT LocalAuditItems optAuditUser optAuditCond { AuditStmt *p_stmt =(AuditStmt*) $2; p_stmt->audit_type = 2; p_stmt->action = 1; p_stmt->users = $3; p_stmt->audit_cond = $4; $$ = (Node*)p_stmt; } | NOAUDIT GlobalAuditItems optAuditUser optAuditCond { AuditStmt *p_stmt = makeNode(AuditStmt); p_stmt->audit_type = 1; p_stmt->action = 2; p_stmt->audits = $2; p_stmt->users = $3; p_stmt->audit_cond = $4; $$ = (Node*)p_stmt; } | NOAUDIT LocalAuditItems optAuditUser optAuditCond { AuditStmt *p_stmt =(AuditStmt*) $2; p_stmt->audit_type = 2; p_stmt->action = 2; p_stmt->users = $3; p_stmt->audit_cond = $4; $$ = (Node*)p_stmt; } ; GlobalAuditItems: GlobalAuditItem { $$ = $1; } | GlobalAuditItems ',' GlobalAuditItem { $$ = ($1) | ($3); } ; GlobalAuditItem: DATABASE { $$ = 0x1<audits = 0xffffffff; p_stmt->obj_name = $3; $$ = (Node*)p_stmt; } | ObjAuditItems ON name_space { AuditStmt *p_stmt =makeNode(AuditStmt); p_stmt->audits = $1; p_stmt->obj_name = $3; $$ = (Node*)p_stmt; } ; ObjAuditItems: ObjAuditItem { $$ = $1; } | ObjAuditItems ',' ObjAuditItem { $$ = (($1)|($3)); } ; ObjAuditItem: INSERT { $$ = 0x1<