diff options
author | Pavan Deolasee | 2017-06-14 06:14:42 +0000 |
---|---|---|
committer | Pavan Deolasee | 2017-06-14 06:14:42 +0000 |
commit | d7e28951c4ade00832113449e15b9d1eef6995e3 (patch) | |
tree | 4b6cf554c78940eb854b819bd0d27a60d1dfdaaa | |
parent | ded31cde6e9e89e4712bef8518b2b7f36a7d3ded (diff) |
Revert "Handle multi-command queries correctly inside SQL as well as plpgsql functions."
This reverts commit 9ddddcb8d51fd640f59401ea9bc335d08bf5a23c. This commit uses
the facilities created by 455ff923454e78d80b77639a381db9b05c776577, which
itself has been now reverted.
-rw-r--r-- | src/backend/commands/extension.c | 14 | ||||
-rw-r--r-- | src/backend/executor/functions.c | 26 | ||||
-rw-r--r-- | src/backend/executor/spi.c | 36 | ||||
-rw-r--r-- | src/test/regress/expected/xc_misc.out | 75 | ||||
-rw-r--r-- | src/test/regress/sql/xc_misc.sql | 31 |
5 files changed, 37 insertions, 145 deletions
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c index fa79e71955..80c352ed0c 100644 --- a/src/backend/commands/extension.c +++ b/src/backend/commands/extension.c @@ -696,14 +696,13 @@ static void execute_sql_string(const char *sql, const char *filename) { List *raw_parsetree_list; - List *querysource_list; DestReceiver *dest; - ListCell *lc1, *lc3; + ListCell *lc1; /* * Parse the SQL string into a list of raw parse trees. */ - raw_parsetree_list = pg_parse_query_get_source(sql, &querysource_list); + raw_parsetree_list = pg_parse_query(sql); /* All output from SELECTs goes to the bit bucket */ dest = CreateDestReceiver(DestNone); @@ -713,10 +712,9 @@ execute_sql_string(const char *sql, const char *filename) * parsetree. We must fully execute each query before beginning parse * analysis on the next one, since there may be interdependencies. */ - forboth(lc1, raw_parsetree_list, lc3, querysource_list) + foreach(lc1, raw_parsetree_list) { RawStmt *parsetree = lfirst_node(RawStmt, lc1); - char *querysource = (char *) lfirst(lc3); List *stmt_list; ListCell *lc2; @@ -724,7 +722,7 @@ execute_sql_string(const char *sql, const char *filename) CommandCounterIncrement(); stmt_list = pg_analyze_and_rewrite(parsetree, - querysource, + sql, NULL, 0, NULL); @@ -743,7 +741,7 @@ execute_sql_string(const char *sql, const char *filename) QueryDesc *qdesc; qdesc = CreateQueryDesc(stmt, - querysource, + sql, GetActiveSnapshot(), NULL, dest, NULL, NULL, 0); @@ -762,7 +760,7 @@ execute_sql_string(const char *sql, const char *filename) errmsg("transaction control statements are not allowed within an extension script"))); ProcessUtility(stmt, - querysource, + sql, PROCESS_UTILITY_QUERY, NULL, NULL, diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 3f40fa65ef..f1a71e26c8 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -72,7 +72,6 @@ typedef struct execution_state bool lazyEval; /* true if should fetch one row at a time */ PlannedStmt *stmt; /* plan for this query */ QueryDesc *qd; /* null unless status == RUN */ - char *src; /* source query resulting in this state */ } execution_state; @@ -157,7 +156,6 @@ static Node *sql_fn_make_param(SQLFunctionParseInfoPtr pinfo, static Node *sql_fn_resolve_param_name(SQLFunctionParseInfoPtr pinfo, const char *paramname, int location); static List *init_execution_state(List *queryTree_list, - List *querySource_list, SQLFunctionCachePtr fcache, bool lazyEvalOK); static void init_sql_fcache(FmgrInfo *finfo, Oid collation, bool lazyEvalOK); @@ -476,21 +474,19 @@ sql_fn_resolve_param_name(SQLFunctionParseInfoPtr pinfo, */ static List * init_execution_state(List *queryTree_list, - List *querySource_list, SQLFunctionCachePtr fcache, bool lazyEvalOK) { List *eslist = NIL; execution_state *lasttages = NULL; - ListCell *lc1, *lc3; + ListCell *lc1; - forboth(lc1, queryTree_list, lc3, querySource_list) + foreach(lc1, queryTree_list) { List *qtlist = lfirst_node(List, lc1); - char *querysource = (char *) lfirst(lc3); execution_state *firstes = NULL; execution_state *preves = NULL; - ListCell *lc2, *lc4; + ListCell *lc2; foreach(lc2, qtlist) { @@ -575,7 +571,6 @@ init_execution_state(List *queryTree_list, newes->lazyEval = false; /* might change below */ newes->stmt = stmt; newes->qd = NULL; - newes->src = pstrdup(querysource); if (queryTree->canSetTag) lasttages = newes; @@ -627,10 +622,9 @@ init_sql_fcache(FmgrInfo *finfo, Oid collation, bool lazyEvalOK) Form_pg_proc procedureStruct; SQLFunctionCachePtr fcache; List *raw_parsetree_list; - List *querysource_list; List *queryTree_list; List *flat_query_list; - ListCell *lc, *lc2; + ListCell *lc; Datum tmp; bool isNull; @@ -729,18 +723,17 @@ init_sql_fcache(FmgrInfo *finfo, Oid collation, bool lazyEvalOK) * but we'll not worry about it until the module is rewritten to use * plancache.c. */ - raw_parsetree_list = pg_parse_query_get_source(fcache->src, &querysource_list); + raw_parsetree_list = pg_parse_query(fcache->src); queryTree_list = NIL; flat_query_list = NIL; - forboth(lc, raw_parsetree_list, lc2, querysource_list) + foreach(lc, raw_parsetree_list) { RawStmt *parsetree = lfirst_node(RawStmt, lc); - char *querysource = (char *) lfirst(lc2); List *queryTree_sublist; queryTree_sublist = pg_analyze_and_rewrite_params(parsetree, - querysource, + fcache->src, (ParserSetupHook) sql_fn_parser_setup, fcache->pinfo, NULL); @@ -792,7 +785,6 @@ init_sql_fcache(FmgrInfo *finfo, Oid collation, bool lazyEvalOK) /* Finally, plan the queries */ fcache->func_state = init_execution_state(queryTree_list, - querysource_list, fcache, lazyEvalOK); @@ -836,7 +828,7 @@ postquel_start(execution_state *es, SQLFunctionCachePtr fcache) dest = None_Receiver; es->qd = CreateQueryDesc(es->stmt, - es->src, + fcache->src, GetActiveSnapshot(), InvalidSnapshot, dest, @@ -876,7 +868,7 @@ postquel_getnext(execution_state *es, SQLFunctionCachePtr fcache) if (es->qd->operation == CMD_UTILITY) { ProcessUtility(es->qd->plannedstmt, - es->src, + fcache->src, PROCESS_UTILITY_QUERY, es->qd->params, es->qd->queryEnv, diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index ac0870c22d..a9ce846540 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -51,7 +51,6 @@ static Portal SPI_cursor_open_internal(const char *name, SPIPlanPtr plan, #ifdef PGXC static void _SPI_pgxc_prepare_plan(const char *src, List *src_parsetree, - List *query_source, SPIPlanPtr plan); #endif static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan); @@ -341,8 +340,7 @@ SPI_execute_direct(const char *remote_sql, char *nodename) plan.cursor_options = 0; /* Now pass the ExecDirectStmt parsetree node */ - _SPI_pgxc_prepare_plan(execdirect.data, list_make1(stmt), - list_make1(execdirect.data), &plan); + _SPI_pgxc_prepare_plan(execdirect.data, list_make1(stmt), &plan); res = _SPI_execute_plan(&plan, NULL, InvalidSnapshot, InvalidSnapshot, false, true, 0); @@ -1802,7 +1800,7 @@ static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan) { #ifdef PGXC - _SPI_pgxc_prepare_plan(src, NULL, NULL, plan); + _SPI_pgxc_prepare_plan(src, NULL, plan); } /* @@ -1812,14 +1810,12 @@ _SPI_prepare_plan(const char *src, SPIPlanPtr plan) * transparent to the user. */ static void -_SPI_pgxc_prepare_plan(const char *src, List *src_parsetree, - List *query_source, SPIPlanPtr plan) +_SPI_pgxc_prepare_plan(const char *src, List *src_parsetree, SPIPlanPtr plan) { #endif List *raw_parsetree_list; - List *querysource_list; List *plancache_list; - ListCell *list_item, *list_item2; + ListCell *list_item; ErrorContextCallback spierrcontext; /* @@ -1836,23 +1832,19 @@ _SPI_pgxc_prepare_plan(const char *src, List *src_parsetree, #ifdef PGXC /* Parse it only if there isn't an already parsed tree passed */ if (src_parsetree) - { raw_parsetree_list = src_parsetree; - querysource_list = query_source; - } else #endif - raw_parsetree_list = pg_parse_query_get_source(src, &querysource_list); + raw_parsetree_list = pg_parse_query(src); /* * Do parse analysis and rule rewrite for each raw parsetree, storing the * results into unsaved plancache entries. */ plancache_list = NIL; - forboth(list_item, raw_parsetree_list, list_item2, querysource_list) + foreach(list_item, raw_parsetree_list) { RawStmt *parsetree = lfirst_node(RawStmt, list_item); - char *querysource = (char *) lfirst (list_item2); List *stmt_list; CachedPlanSource *plansource; @@ -1861,7 +1853,7 @@ _SPI_pgxc_prepare_plan(const char *src, List *src_parsetree, * needs to see the unmodified raw parse tree. */ plansource = CreateCachedPlan(parsetree, - querysource, + src, #ifdef PGXC NULL, #endif @@ -1875,7 +1867,7 @@ _SPI_pgxc_prepare_plan(const char *src, List *src_parsetree, { Assert(plan->nargs == 0); stmt_list = pg_analyze_and_rewrite_params(parsetree, - querysource, + src, plan->parserSetup, plan->parserSetupArg, _SPI_current->queryEnv); @@ -1883,7 +1875,7 @@ _SPI_pgxc_prepare_plan(const char *src, List *src_parsetree, else { stmt_list = pg_analyze_and_rewrite(parsetree, - querysource, + src, plan->argtypes, plan->nargs, _SPI_current->queryEnv); @@ -1935,9 +1927,8 @@ static void _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan) { List *raw_parsetree_list; - List *querysource_list; List *plancache_list; - ListCell *list_item, *list_item2; + ListCell *list_item; ErrorContextCallback spierrcontext; /* @@ -1951,22 +1942,21 @@ _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan) /* * Parse the request string into a list of raw parse trees. */ - raw_parsetree_list = pg_parse_query_get_source(src, &querysource_list); + raw_parsetree_list = pg_parse_query(src); /* * Construct plancache entries, but don't do parse analysis yet. */ plancache_list = NIL; - forboth(list_item, raw_parsetree_list, list_item2, querysource_list) + foreach(list_item, raw_parsetree_list) { RawStmt *parsetree = lfirst_node(RawStmt, list_item); - char *querysource = (char *) lfirst (list_item2); CachedPlanSource *plansource; plansource = CreateOneShotCachedPlan(parsetree, - querysource, + src, CreateCommandTag(parsetree->stmt)); plancache_list = lappend(plancache_list, plansource); diff --git a/src/test/regress/expected/xc_misc.out b/src/test/regress/expected/xc_misc.out index b378aa495e..75d207cccb 100644 --- a/src/test/regress/expected/xc_misc.out +++ b/src/test/regress/expected/xc_misc.out @@ -51,79 +51,14 @@ drop table t1_misc; create table my_tab1 (a int); insert into my_tab1 values(1); create function f1 () returns setof my_tab1 as $$ create table my_tab2 (a int); select * from my_tab1; $$ language sql; -select f1(); - f1 ------ - (1) -(1 row) - -drop function f1(); --- fail since my_tab4 does not exist -create function f1 () returns setof my_tab2 as $$ create table my_tab3 (a int); select * from my_tab4; $$ language sql; -ERROR: relation "my_tab4" does not exist -LINE 1: ...as $$ create table my_tab3 (a int); select * from my_tab4; $... - ^ SET check_function_bodies = false; --- should be created since check_function_bodies is false -create function f1 () returns setof my_tab2 as $$ create table my_tab3 (a int); select * from my_tab4; $$ language sql; --- execution would fail though +create function f1 () returns setof my_tab1 as $$ create table my_tab2 (a int); select * from my_tab1; $$ language sql; +ERROR: function "f1" already exists with same argument types select f1(); -ERROR: relation "my_tab4" does not exist -LINE 1: create table my_tab3 (a int); select * from my_tab4; - ^ -QUERY: create table my_tab3 (a int); select * from my_tab4; -CONTEXT: SQL function "f1" during startup -drop function f1(); +ERROR: Unexpected response from Datanode +CONTEXT: SQL function "f1" statement 1 SET check_function_bodies = true; --- check handling of multi-command statements in plpgsql block -do -$$ -declare -begin - execute 'create table my_tab6(a int); create table my_tab7(a int)'; -end -$$ language plpgsql; --- check handling of multi-command statements in sql function -create or replace function f2() returns void as $$ create table my_tab8(a int); create table my_tab9(a int); $$ language sql; -select f2(); - f2 ----- - -(1 row) - -\d+ my_tab6 - Table "public.my_tab6" - Column | Type | Modifiers | Storage | Stats target | Description ---------+---------+-----------+---------+--------------+------------- - a | integer | | plain | | -Distribute By: HASH(a) -Location Nodes: ALL DATANODES - -\d+ my_tab7 - Table "public.my_tab7" - Column | Type | Modifiers | Storage | Stats target | Description ---------+---------+-----------+---------+--------------+------------- - a | integer | | plain | | -Distribute By: HASH(a) -Location Nodes: ALL DATANODES - -\d+ my_tab8 - Table "public.my_tab8" - Column | Type | Modifiers | Storage | Stats target | Description ---------+---------+-----------+---------+--------------+------------- - a | integer | | plain | | -Distribute By: HASH(a) -Location Nodes: ALL DATANODES - -\d+ my_tab9 - Table "public.my_tab9" - Column | Type | Modifiers | Storage | Stats target | Description ---------+---------+-----------+---------+--------------+------------- - a | integer | | plain | | -Distribute By: HASH(a) -Location Nodes: ALL DATANODES - -drop table my_tab6, my_tab7, my_tab8, my_tab9; +drop function f1(); -- Test pl-pgsql functions containing utility statements CREATE OR REPLACE FUNCTION test_fun_2() RETURNS SETOF my_tab1 AS ' DECLARE diff --git a/src/test/regress/sql/xc_misc.sql b/src/test/regress/sql/xc_misc.sql index 5b5057a440..30db55a1a3 100644 --- a/src/test/regress/sql/xc_misc.sql +++ b/src/test/regress/sql/xc_misc.sql @@ -44,39 +44,16 @@ create table my_tab1 (a int); insert into my_tab1 values(1); create function f1 () returns setof my_tab1 as $$ create table my_tab2 (a int); select * from my_tab1; $$ language sql; -select f1(); -drop function f1(); --- fail since my_tab4 does not exist -create function f1 () returns setof my_tab2 as $$ create table my_tab3 (a int); select * from my_tab4; $$ language sql; SET check_function_bodies = false; --- should be created since check_function_bodies is false -create function f1 () returns setof my_tab2 as $$ create table my_tab3 (a int); select * from my_tab4; $$ language sql; --- execution would fail though -select f1(); -drop function f1(); - -SET check_function_bodies = true; --- check handling of multi-command statements in plpgsql block -do -$$ -declare -begin - execute 'create table my_tab6(a int); create table my_tab7(a int)'; -end -$$ language plpgsql; +create function f1 () returns setof my_tab1 as $$ create table my_tab2 (a int); select * from my_tab1; $$ language sql; --- check handling of multi-command statements in sql function -create or replace function f2() returns void as $$ create table my_tab8(a int); create table my_tab9(a int); $$ language sql; -select f2(); +select f1(); -\d+ my_tab6 -\d+ my_tab7 -\d+ my_tab8 -\d+ my_tab9 +SET check_function_bodies = true; -drop table my_tab6, my_tab7, my_tab8, my_tab9; +drop function f1(); -- Test pl-pgsql functions containing utility statements |