From: Julien Rouhaud Date: Wed, 21 Apr 2021 22:47:18 +0800 Subject: [PATCH v3 1/4] Add a parser_hook hook. This does nothing but allow third-party plugins to implement a different syntax, and fallback on the core parser if they don't implement a superset of the supported core syntax. --- src/backend/tcop/postgres.c | 16 ++++++++++++++-- src/include/tcop/tcopprot.h | 5 +++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 8cea10c901..e941b59b85 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -99,6 +99,9 @@ int log_statement = LOGSTMT_NONE; /* GUC variable for maximum stack depth (measured in kilobytes) */ int max_stack_depth = 100; +/* Hook for plugins to get control in pg_parse_query() */ +parser_hook_type parser_hook = NULL; + /* wait N seconds to allow attach from a debugger */ int PostAuthDelay = 0; @@ -589,18 +592,27 @@ ProcessClientWriteInterrupt(bool blocked) * database tables. So, we rely on the raw parser to determine whether * we've seen a COMMIT or ABORT command; when we are in abort state, other * commands are not processed any further than the raw parse stage. + * + * To support loadable plugins that monitor the parsing or implements SQL + * syntactic sugar we provide a hook variable that lets a plugin get control + * before and after the standard parsing process. If the plugin only implement + * a subset of postgres supported syntax, it's its duty to call raw_parser (or + * the previous hook if any) for the statements it doesn't understand. */ List * pg_parse_query(const char *query_string) { - List *raw_parsetree_list; + List *raw_parsetree_list = NIL; TRACE_POSTGRESQL_QUERY_PARSE_START(query_string); if (log_parser_stats) ResetUsage(); - raw_parsetree_list = raw_parser(query_string, RAW_PARSE_DEFAULT); + if (parser_hook) + raw_parsetree_list = (*parser_hook) (query_string, RAW_PARSE_DEFAULT); + else + raw_parsetree_list = raw_parser(query_string, RAW_PARSE_DEFAULT); if (log_parser_stats) ShowUsage("PARSER STATISTICS"); diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h index 968345404e..131dc2b22e 100644 --- a/src/include/tcop/tcopprot.h +++ b/src/include/tcop/tcopprot.h @@ -17,6 +17,7 @@ #include "nodes/params.h" #include "nodes/parsenodes.h" #include "nodes/plannodes.h" +#include "parser/parser.h" #include "storage/procsignal.h" #include "utils/guc.h" #include "utils/queryenvironment.h" @@ -43,6 +44,10 @@ typedef enum extern PGDLLIMPORT int log_statement; +/* Hook for plugins to get control in pg_parse_query() */ +typedef List *(*parser_hook_type) (const char *str, RawParseMode mode); +extern PGDLLIMPORT parser_hook_type parser_hook; + extern List *pg_parse_query(const char *query_string); extern List *pg_rewrite_query(Query *query); extern List *pg_analyze_and_rewrite(RawStmt *parsetree, -- 2.31.1 --v6yspzozp6k6x4hy Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v3-0002-Add-a-sqlol-parser.patch"