summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavan Deolasee2017-06-14 06:14:42 +0000
committerPavan Deolasee2017-06-14 06:14:42 +0000
commitd7e28951c4ade00832113449e15b9d1eef6995e3 (patch)
tree4b6cf554c78940eb854b819bd0d27a60d1dfdaaa
parentded31cde6e9e89e4712bef8518b2b7f36a7d3ded (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.c14
-rw-r--r--src/backend/executor/functions.c26
-rw-r--r--src/backend/executor/spi.c36
-rw-r--r--src/test/regress/expected/xc_misc.out75
-rw-r--r--src/test/regress/sql/xc_misc.sql31
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