From 2764c4db1ba4c32863823b83a5b66f9af6c9492c Mon Sep 17 00:00:00 2001 From: "houzj.fnst" <63178771+sherlockcpp@users.noreply.github.com> Date: Mon, 20 Jul 2020 13:53:27 +0800 Subject: [PATCH 1/5] Update pool_select_walker.c --- src/utils/pool_select_walker.c | 92 +++++++++++++++++++++++++++++++++--------- 1 file changed, 72 insertions(+), 20 deletions(-) diff --git a/src/utils/pool_select_walker.c b/src/utils/pool_select_walker.c index b9075b5..7a19117 100644 --- a/src/utils/pool_select_walker.c +++ b/src/utils/pool_select_walker.c @@ -339,20 +339,12 @@ function_call_walker(Node *node, void *context) if (length > 0) { - if (length == 1) /* no schema qualification? */ - { - fname = strVal(linitial(fcall->funcname)); - } - else - { - fname = strVal(lsecond(fcall->funcname)); /* with schema - * qualification */ - } + fname = make_function_name_from_funccall(fcall); ereport(DEBUG1, (errmsg("function call walker, function name: \"%s\"", fname))); - if (ctx->pg_terminate_backend_pid == 0 && strcmp("pg_terminate_backend", fname) == 0) + if (ctx->pg_terminate_backend_pid == 0 && strcmp("pg_terminate_backend", strVal(llast(fcall->funcname))) == 0) { if (list_length(fcall->args) == 1) { @@ -995,15 +987,7 @@ non_immutable_function_call_walker(Node *node, void *context) if (length > 0) { - if (length == 1) /* no schema qualification? */ - { - fname = strVal(linitial(fcall->funcname)); - } - else - { - fname = strVal(lsecond(fcall->funcname)); /* with schema - * qualification */ - } + fname = strVal(llast(fcall->funcname)); ereport(DEBUG1, (errmsg("non immutable function walker. checking function \"%s\"", fname))); @@ -1210,7 +1194,6 @@ select_table_walker(Node *node, void *context) } } - /* Skip Data-Modifying Statements in SELECT. */ else if (IsA(node, InsertStmt) || IsA(node, DeleteStmt) || IsA(node, UpdateStmt)) { return false; @@ -1255,6 +1238,75 @@ makeRangeVarFromNameList(List *names) } /* + * Extract function name from FuncCall. Make schema qualification name if + * necessary. The returned function name is in static area. So next + * call to this function will break previous result. + */ +char * +make_function_name_from_funccall(FuncCall *fcall) +{ + /* + * Function name. Max size is calculated as follows: schema + * name(POOL_NAMEDATALEN byte) + quotation marks for schmea name(2 byte) + + * period(1 byte) + function name (POOL_NAMEDATALEN byte) + quotation marks + * for function name(2 byte) + NULL(1 byte) + */ + static char funcname[POOL_NAMEDATALEN * 2 + 1 + 2 * 2 + 1]; + List *names; + + if(fcall == NULL) + { + ereport(WARNING, + (errmsg("FuncCall argument is NULL, while getting function name from FuncCall"))); + return ""; + } + + *funcname = '\0'; + names = fcall->funcname; + + switch (list_length(names)) + { + case 1: + strcat(funcname, "\""); + strncat(funcname, strVal(linitial(names)), POOL_NAMEDATALEN); + strcat(funcname, "\""); + break; + case 2: + strcat(funcname, "\""); + strncat(funcname, strVal(linitial(names)), POOL_NAMEDATALEN); + strcat(funcname, "\""); + + strcat(funcname, "."); + + strcat(funcname, "\""); + strncat(funcname, strVal(lsecond(names)), POOL_NAMEDATALEN); + strcat(funcname, "\""); + break; + case 3: + strcat(funcname, "\""); + strncat(funcname, strVal(lsecond(names)), POOL_NAMEDATALEN); + strcat(funcname, "\""); + + strcat(funcname, "."); + + strcat(funcname, "\""); + strncat(funcname, strVal(lthird(names)), POOL_NAMEDATALEN); + strcat(funcname, "\""); + + break; + default: + ereport(WARNING, + (errmsg("invalid function name, too many indirections, while getting function name from FuncCall"))); + break; + } + + ereport(DEBUG1, + (errmsg("make function name from funccall: funcname:\"%s\"", funcname))); + + return funcname; +} + +/* * Extract table name from RageVar. Make schema qualification name if * necessary. The returned table name is in static area. So next * call to this function will break previous result. -- 1.8.3.1