diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index f869e159d6..bbe0dee8c6 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -41,6 +41,8 @@ /* GUC parameters */ bool Transform_null_equals = false; +/* Hook for plugins to get control in transformExprRecurse() */ +parse_expr_hook_type parse_expr_hook = NULL; static Node *transformExprRecurse(ParseState *pstate, Node *expr); static Node *transformParamRef(ParseState *pstate, ParamRef *pref); @@ -307,9 +309,14 @@ transformExprRecurse(ParseState *pstate, Node *expr) } default: - /* should not reach here */ - elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr)); - result = NULL; /* keep compiler quiet */ + if (parse_expr_hook) + result = (*parse_expr_hook) (pstate, expr); + else + { + /* should not reach here */ + elog(ERROR, "unrecognized node type: %d", (int) nodeTag(expr)); + result = NULL; /* keep compiler quiet */ + } break; } diff --git a/src/backend/parser/parser.c b/src/backend/parser/parser.c index 875de7ba28..0dabbcecc5 100644 --- a/src/backend/parser/parser.c +++ b/src/backend/parser/parser.c @@ -26,6 +26,9 @@ #include "parser/parser.h" #include "parser/scansup.h" +/* Hook for plugins to get control in raw_parser() */ +parser_hook_type parser_hook = NULL; + static bool check_uescapechar(unsigned char escape); static char *str_udeescape(const char *str, char escape, int position, core_yyscan_t yyscanner); @@ -40,6 +43,18 @@ static char *str_udeescape(const char *str, char escape, */ List * raw_parser(const char *str, RawParseMode mode) +{ + List *result; + + if (parser_hook) + result = (*parser_hook) (str, mode); + else + result = standard_raw_parser(str, mode); + return result; +} + +List * +standard_raw_parser(const char *str, RawParseMode mode) { core_yyscan_t yyscanner; base_yy_extra_type yyextra; diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 05bb698cf4..6a69599db6 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -3101,7 +3101,9 @@ CreateCommandTag(Node *parsetree) } } break; - + case T_ExtensibleNode: + tag = CMDTAG_EXTENDED_COMMAND; + break; default: elog(WARNING, "unrecognized node type: %d", (int) nodeTag(parsetree)); diff --git a/src/include/parser/parse_expr.h b/src/include/parser/parse_expr.h index 8ac4a0a369..6465a8d03e 100644 --- a/src/include/parser/parse_expr.h +++ b/src/include/parser/parse_expr.h @@ -15,6 +15,10 @@ #include "parser/parse_node.h" +/* Hook for plugins to get control in transformExprRecurse() */ +typedef Node *(*parse_expr_hook_type) (ParseState *pstate, Node *expr); +extern PGDLLIMPORT parse_expr_hook_type parse_expr_hook; + /* GUC parameters */ extern bool Transform_null_equals; diff --git a/src/include/parser/parser.h b/src/include/parser/parser.h index 853b0f1606..8b1b915410 100644 --- a/src/include/parser/parser.h +++ b/src/include/parser/parser.h @@ -57,9 +57,13 @@ extern int backslash_quote; extern bool escape_string_warning; extern PGDLLIMPORT bool standard_conforming_strings; +/* Hook for plugins to get control in raw_parser() */ +typedef List *(*parser_hook_type) (const char *str, RawParseMode mode);; +extern PGDLLIMPORT parser_hook_type parser_hook; /* Primary entry point for the raw parsing functions */ extern List *raw_parser(const char *str, RawParseMode mode); +extern List *standard_raw_parser(const char *str, RawParseMode mode); /* Utility functions exported by gram.y (perhaps these should be elsewhere) */ extern List *SystemFuncName(char *name); diff --git a/src/include/tcop/cmdtaglist.h b/src/include/tcop/cmdtaglist.h index 9ba24d4ca9..c0d3427db5 100644 --- a/src/include/tcop/cmdtaglist.h +++ b/src/include/tcop/cmdtaglist.h @@ -178,6 +178,7 @@ PG_CMDTAG(CMDTAG_DROP_USER_MAPPING, "DROP USER MAPPING", true, false, false) PG_CMDTAG(CMDTAG_DROP_VIEW, "DROP VIEW", true, false, false) PG_CMDTAG(CMDTAG_EXECUTE, "EXECUTE", false, false, false) PG_CMDTAG(CMDTAG_EXPLAIN, "EXPLAIN", false, false, false) +PG_CMDTAG(CMDTAG_EXTENDED_COMMAND, "EXTENDED COMMAND", false, false, false) PG_CMDTAG(CMDTAG_FETCH, "FETCH", false, false, true) PG_CMDTAG(CMDTAG_GRANT, "GRANT", true, false, false) PG_CMDTAG(CMDTAG_GRANT_ROLE, "GRANT ROLE", false, false, false)