From c026220a59c43ec86c8ea2c6bc8f89ca306a425d Mon Sep 17 00:00:00 2001 From: wuyuechuan Date: Tue, 21 Jul 2020 15:26:11 +0800 Subject: [PATCH 1/2] pg_stat_statements extension bug fix --- .../pg_stat_statements/pg_stat_statements.cpp | 35 ++++++++++--------- src/include/storage/lwlock.h | 2 +- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/contrib/pg_stat_statements/pg_stat_statements.cpp b/contrib/pg_stat_statements/pg_stat_statements.cpp index b70ca0aa8..15013089d 100755 --- a/contrib/pg_stat_statements/pg_stat_statements.cpp +++ b/contrib/pg_stat_statements/pg_stat_statements.cpp @@ -172,20 +172,20 @@ typedef struct pgssJumbleState { /*---- Local variables ----*/ /* Current nesting depth of ExecutorRun+ProcessUtility calls */ -static int nested_level = 0; +static THR_LOCAL int nested_level = 0; /* Saved hook values in case of unload */ -static shmem_startup_hook_type prev_shmem_startup_hook = NULL; -static post_parse_analyze_hook_type prev_post_parse_analyze_hook = NULL; -static ExecutorStart_hook_type prev_ExecutorStart = NULL; -static ExecutorRun_hook_type prev_ExecutorRun = NULL; -static ExecutorFinish_hook_type prev_ExecutorFinish = NULL; -static ExecutorEnd_hook_type prev_ExecutorEnd = NULL; -static ProcessUtility_hook_type prev_ProcessUtility = NULL; +static THR_LOCAL shmem_startup_hook_type prev_shmem_startup_hook = NULL; +static THR_LOCAL post_parse_analyze_hook_type prev_post_parse_analyze_hook = NULL; +static THR_LOCAL ExecutorStart_hook_type prev_ExecutorStart = NULL; +static THR_LOCAL ExecutorRun_hook_type prev_ExecutorRun = NULL; +static THR_LOCAL ExecutorFinish_hook_type prev_ExecutorFinish = NULL; +static THR_LOCAL ExecutorEnd_hook_type prev_ExecutorEnd = NULL; +static THR_LOCAL ProcessUtility_hook_type prev_ProcessUtility = NULL; /* Links to shared memory state */ -static pgssSharedState* pgss = NULL; -static HTAB* pgss_hash = NULL; +static THR_LOCAL pgssSharedState* pgss = NULL; +static THR_LOCAL HTAB* pgss_hash = NULL; /*---- GUC variables ----*/ @@ -210,8 +210,8 @@ static bool pgss_save; /* whether to save stats across shutdown */ void _PG_init(void); void _PG_fini(void); -Datum pg_stat_statements_reset(PG_FUNCTION_ARGS); -Datum pg_stat_statements(PG_FUNCTION_ARGS); +extern "C" Datum pg_stat_statements_reset(PG_FUNCTION_ARGS); +extern "C" Datum pg_stat_statements(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(pg_stat_statements_reset); PG_FUNCTION_INFO_V1(pg_stat_statements); @@ -260,7 +260,7 @@ void _PG_init(void) * module isn't active. The functions must protect themselves against * being called then, however.) */ - if (!process_shared_preload_libraries_in_progress) + if (!u_sess->misc_cxt.process_shared_preload_libraries_in_progress) return; /* @@ -389,7 +389,7 @@ static void pgss_shmem_startup(void) if (!found) { /* First time through ... */ - pgss->lock = LWLockAssign(); + pgss->lock = LWLockAssign(LWTRANCHE_BUFFER_CONTENT); pgss->query_size = g_instance.attr.attr_common.pgstat_track_activity_query_size; pgss->cur_median_usage = ASSUMED_MEDIAN_INIT; } @@ -456,7 +456,7 @@ static void pgss_shmem_startup(void) buffer_size = temp.query_len + 1; } - if (fread(buffer, 1, temp.query_len, file) != temp.query_len) + if (fread(buffer, 1, temp.query_len, file) != (size_t)temp.query_len) goto error; buffer[temp.query_len] = '\0'; @@ -536,7 +536,7 @@ static void pgss_shmem_shutdown(int code, Datum arg) while ((entry = (pgssEntry*)hash_seq_search(&hash_seq)) != NULL) { int len = entry->query_len; - if (fwrite(entry, offsetof(pgssEntry, mutex), 1, file) != 1 || fwrite(entry->query, 1, len, file) != len) + if (fwrite(entry, offsetof(pgssEntry, mutex), 1, file) != 1 || fwrite(entry->query, 1, len, file) != (size_t)len) goto error; } @@ -748,7 +748,8 @@ static void pgss_ProcessUtility(Node* parsetree, const char* queryString, ParamL BufferUsage bufusage_start, bufusage; uint32 queryId; - bufusage_start = u_sess->instr_cxt.pg_buffer_usage->INSTR_TIME_SET_CURRENT(start); + bufusage_start = *(u_sess->instr_cxt.pg_buffer_usage); + INSTR_TIME_SET_CURRENT(start); nested_level++; PG_TRY(); diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h index 8b34fd844..57923a3be 100755 --- a/src/include/storage/lwlock.h +++ b/src/include/storage/lwlock.h @@ -286,5 +286,5 @@ extern int LWLockTranchesAllocated; * to LWLocks. New code should instead use LWLock *. However, for the * convenience of third-party code, we include the following typedef. */ -// typedef LWLock *LWLockId; // Uncomment it later. Now should disable to find bugs +typedef LWLock *LWLockId; // Uncomment it later. Now should disable to find bugs #endif /* LWLOCK_H */ From 433ae75066d90f7d54bc2273400867b4565c33ad Mon Sep 17 00:00:00 2001 From: wuyuechuan Date: Thu, 6 Aug 2020 19:16:26 +0800 Subject: [PATCH 2/2] fixbug: procudure multi option error --- src/common/backend/parser/gram.y | 28 +++++++++++++++++-- src/test/regress/expected/create_function.out | 6 ++++ .../regress/expected/create_procedure.out | 8 ++++++ src/test/regress/parallel_schedule | 5 ++++ src/test/regress/sql/create_function.sql | 6 ++++ src/test/regress/sql/create_procedure.sql | 8 ++++++ 6 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 src/test/regress/expected/create_function.out create mode 100644 src/test/regress/expected/create_procedure.out create mode 100644 src/test/regress/sql/create_function.sql create mode 100644 src/test/regress/sql/create_procedure.sql diff --git a/src/common/backend/parser/gram.y b/src/common/backend/parser/gram.y index e94c320e7..d8e86397d 100755 --- a/src/common/backend/parser/gram.y +++ b/src/common/backend/parser/gram.y @@ -9009,8 +9009,32 @@ callfunc_args: func_arg_expr } ; CreateProcedureStmt: - CREATE opt_or_replace PROCEDURE func_name_opt_arg proc_args - opt_createproc_opt_list as_is {u_sess->parser_cxt.eaten_declare = false; u_sess->parser_cxt.eaten_begin = false;} subprogram_body + CREATE opt_or_replace PROCEDURE func_name_opt_arg proc_args + as_is {u_sess->parser_cxt.eaten_declare = false; u_sess->parser_cxt.eaten_begin = false;} subprogram_body + { + CreateFunctionStmt *n = makeNode(CreateFunctionStmt); + int count = get_outarg_num($5); + n->isOraStyle = true; + n->replace = $2; + n->funcname = $4; + n->parameters = $5; + n->returnType = NULL; + n->isProcedure = true; + if (0 == count) + { + n->returnType = makeTypeName("void"); + n->returnType->typmods = NULL; + n->returnType->arrayBounds = NULL; + } + n->options = list_make1(makeDefElem("as", + (Node *)list_make1(makeString($8)))); + n->options = lappend(n->options, makeDefElem("language", + (Node *)makeString("plpgsql"))); + n->withClause = NIL; + $$ = (Node *)n; + } + | CREATE opt_or_replace PROCEDURE func_name_opt_arg proc_args + createfunc_opt_list as_is {u_sess->parser_cxt.eaten_declare = false; u_sess->parser_cxt.eaten_begin = false;} subprogram_body { CreateFunctionStmt *n = makeNode(CreateFunctionStmt); int count = get_outarg_num($5); diff --git a/src/test/regress/expected/create_function.out b/src/test/regress/expected/create_function.out new file mode 100644 index 000000000..c776e9548 --- /dev/null +++ b/src/test/regress/expected/create_function.out @@ -0,0 +1,6 @@ +create function create_function_test(integer,integer) RETURNS integer +AS 'SELECT $1 + $2;' +LANGUAGE SQL +IMMUTABLE SHIPPABLE +RETURNS NULL ON NULL INPUT; +drop function create_function_test; \ No newline at end of file diff --git a/src/test/regress/expected/create_procedure.out b/src/test/regress/expected/create_procedure.out new file mode 100644 index 000000000..fabc749ab --- /dev/null +++ b/src/test/regress/expected/create_procedure.out @@ -0,0 +1,8 @@ +create procedure test_procedure_test(int,int) +SHIPPABLE IMMUTABLE +as +begin + select $1 + $2; +end; +/ +drop procedure test_procedure_test; \ No newline at end of file diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule index 10c1a0097..fbcec5ab4 100644 --- a/src/test/regress/parallel_schedule +++ b/src/test/regress/parallel_schedule @@ -577,3 +577,8 @@ test: gtt_function test: gtt_prepare test: gtt_parallel_1 gtt_parallel_2 test: gtt_clean + + +# procedure, Function Test +test: create_procedure +test: create_function diff --git a/src/test/regress/sql/create_function.sql b/src/test/regress/sql/create_function.sql new file mode 100644 index 000000000..c776e9548 --- /dev/null +++ b/src/test/regress/sql/create_function.sql @@ -0,0 +1,6 @@ +create function create_function_test(integer,integer) RETURNS integer +AS 'SELECT $1 + $2;' +LANGUAGE SQL +IMMUTABLE SHIPPABLE +RETURNS NULL ON NULL INPUT; +drop function create_function_test; \ No newline at end of file diff --git a/src/test/regress/sql/create_procedure.sql b/src/test/regress/sql/create_procedure.sql new file mode 100644 index 000000000..67ab2c93e --- /dev/null +++ b/src/test/regress/sql/create_procedure.sql @@ -0,0 +1,8 @@ +create procedure test_procedure_test(int,int) +SHIPPABLE IMMUTABLE +as +begin + select $1 + $2; +end; +/ +drop procedure test_procedure_test; \ No newline at end of file