diff --git a/.gitignore b/.gitignore index 473b78c30..1695c70b7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -/.gitee/ -/.vscode/ -/.idea/ +/.gitee/ +/.vscode/ +/.idea/ diff --git a/src/bin/gs_guc/cluster_guc.conf b/src/bin/gs_guc/cluster_guc.conf index 4a3289cb0..c5309738b 100755 --- a/src/bin/gs_guc/cluster_guc.conf +++ b/src/bin/gs_guc/cluster_guc.conf @@ -794,5 +794,6 @@ datanode_heartbeat_interval|int|1000,60000|ms|The value is best configured less cost_weight_index|real|1e-10,1e+10|NULL|NULL| default_limit_rows|real|-100,1.79769e+308|NULL|NULL| enable_auto_explain|bool|0,0|NULL|NULL| +enable_custom_parser|bool|0,0|NULL|NULL| auto_explain_level|enum|off,log,notice|NULL|NULL| [end] diff --git a/src/common/backend/utils/init/miscinit.cpp b/src/common/backend/utils/init/miscinit.cpp index fa26cb2a6..50c2e9d7c 100644 --- a/src/common/backend/utils/init/miscinit.cpp +++ b/src/common/backend/utils/init/miscinit.cpp @@ -445,6 +445,33 @@ const char* show_nodegroup_mode(void) return "unknown"; } } + +#endif + +#ifndef ENABLE_MULTIPLE_NODES +const int GetCustomParserId() +{ + int id = 0; + switch (u_sess->attr.attr_sql.sql_compatibility) { + case A_FORMAT: + id = DB_CMPT_A; + break; + case B_FORMAT: + id = DB_CMPT_B; + break; + case C_FORMAT: + id = DB_CMPT_C; + break; + case PG_FORMAT: + id = DB_CMPT_PG; + break; + default: + ereport(WARNING, (errmsg("Unknown sql compatibility: %d", u_sess->attr.attr_sql.sql_compatibility))); + return -1; + } + Assert(id >= 0 && id < DB_CMPT_MAX); + return id; +} #endif /* diff --git a/src/common/backend/utils/misc/guc.cpp b/src/common/backend/utils/misc/guc.cpp index 29d1a1278..8498b24f5 100644 --- a/src/common/backend/utils/misc/guc.cpp +++ b/src/common/backend/utils/misc/guc.cpp @@ -3285,6 +3285,16 @@ static void InitConfigureNamesBool() NULL, NULL, NULL}, + {{"enable_custom_parser", + PGC_USERSET, + UNGROUPED, + gettext_noop("Enables custom parser"), + NULL}, + &u_sess->attr.attr_sql.enable_custom_parser, + false, + NULL, + NULL, + NULL}, #endif {{"enable_partition_opfusion", PGC_USERSET, QUERY_TUNING_METHOD, diff --git a/src/common/pl/plpgsql/src/pl_comp.cpp b/src/common/pl/plpgsql/src/pl_comp.cpp index dc8be5a46..4cafd3e65 100644 --- a/src/common/pl/plpgsql/src/pl_comp.cpp +++ b/src/common/pl/plpgsql/src/pl_comp.cpp @@ -98,6 +98,20 @@ static bool plpgsql_check_updel_colocate( static bool plpgsql_check_opexpr_colocate( Query* query, List* qry_part_attr_num, List* trig_part_attr_num, PLpgSQL_function* func, List* opexpr_list); +typedef int (*plsql_parser)(void); +static inline plsql_parser PlsqlParser(){ + int (*plsql_parser_hook)(void) = plpgsql_yyparse; +#ifndef ENABLE_MULTIPLE_NODES + if (u_sess->attr.attr_sql.enable_custom_parser) { + int id = GetCustomParserId(); + if (id >= 0 && g_instance.plsql_parser_hook[id] != NULL) { + plsql_parser_hook = (int(*)(void))g_instance.plsql_parser_hook[id]; + } + } +#endif + return plsql_parser_hook; +} + /* ---------- * plpgsql_compile Make an execution tree for a PL/pgSQL function. * @@ -778,7 +792,7 @@ static PLpgSQL_function* do_compile(FunctionCallInfo fcinfo, HeapTuple proc_tup, /* * Now parse the function's text */ - parse_rc = plpgsql_yyparse(); + parse_rc = (*PlsqlParser())(); if (parse_rc != 0) { ereport(ERROR, (errmodule(MOD_PLSQL), @@ -963,7 +977,7 @@ PLpgSQL_function* plpgsql_compile_inline(char* proc_source) /* * Now parse the function's text */ - parse_rc = plpgsql_yyparse(); + parse_rc = (*PlsqlParser())(); if (parse_rc != 0) { ereport(ERROR, (errmodule(MOD_PLSQL), errcode(ERRCODE_UNRECOGNIZED_NODE_TYPE), errmsg("Syntax parsing error, plpgsql parser returned %d", parse_rc))); @@ -3293,4 +3307,3 @@ static bool plpgsql_check_insert_colocate( } return true; } - diff --git a/src/gausskernel/process/tcop/postgres.cpp b/src/gausskernel/process/tcop/postgres.cpp index 1151c3ecc..40ac2cadf 100644 --- a/src/gausskernel/process/tcop/postgres.cpp +++ b/src/gausskernel/process/tcop/postgres.cpp @@ -771,6 +771,7 @@ void client_read_ended(void) } } + /* * Do raw parsing (only). * @@ -796,7 +797,16 @@ List* pg_parse_query(const char* query_string, List** query_string_locationlist) PGSTAT_START_TIME_RECORD(); - raw_parsetree_list = raw_parser(query_string, query_string_locationlist); + List* (*parser_hook)(const char*, List**) = raw_parser; +#ifndef ENABLE_MULTIPLE_NODES + if (u_sess->attr.attr_sql.enable_custom_parser) { + int id = GetCustomParserId(); + if (id >= 0 && g_instance.raw_parser_hook[id] != NULL) { + parser_hook = (List* (*)(const char*, List**))g_instance.raw_parser_hook[id]; + } + } +#endif + raw_parsetree_list = parser_hook(query_string, query_string_locationlist); PGSTAT_END_TIME_RECORD(PARSE_TIME); diff --git a/src/gausskernel/process/tcop/utility.cpp b/src/gausskernel/process/tcop/utility.cpp index 4a4f13ef0..f2c9fe7a9 100644 --- a/src/gausskernel/process/tcop/utility.cpp +++ b/src/gausskernel/process/tcop/utility.cpp @@ -9455,7 +9455,9 @@ bool DropExtensionIsSupported(const char* query_string) #ifndef ENABLE_MULTIPLE_NODES if (strstr(lower_string, "drop") && (strstr(lower_string, "postgis") || strstr(lower_string, "packages") || strstr(lower_string, "mysql_fdw") || strstr(lower_string, "oracle_fdw") || - strstr(lower_string, "postgres_fdw") || strstr(lower_string, "dblink"))) { + strstr(lower_string, "postgres_fdw") || strstr(lower_string, "dblink") || + strstr(lower_string, "db_b_parser") || strstr(lower_string, "db_a_parser") || + strstr(lower_string, "db_c_parser") || strstr(lower_string, "db_pg_parser"))) { #else if (strstr(lower_string, "drop") && (strstr(lower_string, "postgis") || strstr(lower_string, "packages"))) { #endif diff --git a/src/include/knl/knl_guc/knl_session_attr_sql.h b/src/include/knl/knl_guc/knl_session_attr_sql.h index 731e5a850..71037bd0d 100644 --- a/src/include/knl/knl_guc/knl_session_attr_sql.h +++ b/src/include/knl/knl_guc/knl_session_attr_sql.h @@ -211,6 +211,9 @@ typedef struct knl_session_attr_sql { /* hypo index */ bool enable_hypo_index; bool hypopg_is_explain; +#ifndef ENABLE_MULTIPLE_NODES + bool enable_custom_parser; +#endif } knl_session_attr_sql; #endif /* SRC_INCLUDE_KNL_KNL_SESSION_ATTR_SQL */ diff --git a/src/include/knl/knl_instance.h b/src/include/knl/knl_instance.h index 8d8a32ac2..67eacca24 100644 --- a/src/include/knl/knl_instance.h +++ b/src/include/knl/knl_instance.h @@ -70,6 +70,9 @@ const int NUM_PERCENTILE_COUNT = 2; const int INIT_NUMA_ALLOC_COUNT = 32; const int HOTKEY_ABANDON_LENGTH = 100; const int MAX_GLOBAL_CACHEMEM_NUM = 128; +#ifndef ENABLE_MULTIPLE_NODES +const int DB_CMPT_MAX = 4; +#endif enum knl_virtual_role { VUNKNOWN = 0, @@ -868,6 +871,11 @@ typedef struct knl_instance_context { struct HTAB* ngroup_hash_table; knl_g_hypo_context hypo_cxt; knl_sigbus_context sigbus_cxt; + +#ifndef ENABLE_MULTIPLE_NODES + void *raw_parser_hook[DB_CMPT_MAX]; + void *plsql_parser_hook[DB_CMPT_MAX]; +#endif } knl_instance_context; extern long random(); diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index d37304209..ad912113b 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -286,6 +286,10 @@ extern bool exist_logic_cluster(); #ifdef ENABLE_MULTIPLE_NODES extern const char* show_nodegroup_mode(void); #endif + +#ifndef ENABLE_MULTIPLE_NODES +extern const int GetCustomParserId(); +#endif extern const char* show_lcgroup_name(); extern Oid get_pgxc_logic_groupoid(Oid roleid); extern Oid get_pgxc_logic_groupoid(const char* groupname);