Revert "Handle multi-command queries correctly inside SQL as well as plpgsql functions."
authorPavan Deolasee <[email protected]>
Wed, 14 Jun 2017 06:14:42 +0000 (11:44 +0530)
committerPavan Deolasee <[email protected]>
Wed, 14 Jun 2017 06:14:42 +0000 (11:44 +0530)
This reverts commit 9ddddcb8d51fd640f59401ea9bc335d08bf5a23c.  This commit uses
the facilities created by 455ff923454e78d80b77639a381db9b05c776577, which
itself has been now reverted.

src/backend/commands/extension.c
src/backend/executor/functions.c
src/backend/executor/spi.c
src/test/regress/expected/xc_misc.out
src/test/regress/sql/xc_misc.sql

index fa79e719553b91f5a53ee18f2fd123d5450597c3..80c352ed0cf05ff2e9b968b9f161a4f38ad97187 100644 (file)
@@ -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,
index 3f40fa65ef50241cd1b08c5e81e904645185e598..f1a71e26c8eec3fcdfbe17163290ea4c5bb3ec12 100644 (file)
@@ -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,
index ac0870c22d62f14a5456beaf69cd8b5cac25dfb2..a9ce846540aa03c87a0382678f989894156e82ee 100644 (file)
@@ -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);
index b378aa495ee8ee515f6a6771d7319f5edbb1db79..75d207cccb906840e544e4429c970b1af2c465b4 100644 (file)
@@ -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
index 5b5057a440d57a1950db1ff7c1183d59aac37b75..30db55a1a31451e6c2f89f3618d99e1fcd78230d 100644 (file)
@@ -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