Ensure that typename is schema qualified while sending row description
authorPavan Deolasee <[email protected]>
Tue, 10 Jul 2018 09:10:56 +0000 (14:40 +0530)
committerPavan Deolasee <[email protected]>
Tue, 10 Jul 2018 09:14:15 +0000 (14:44 +0530)
A row description messages contains the type information for the attributes in
the column. But if the type does not exist in the search_path then the
coordinator fails to parse the typename back to the type. So the datanode must
send the schema name along with the type name.

Per report and test case by Hengbing Wang @ Microfun.

Added a new test file and a few test cases to cover this area.

src/backend/access/common/printtup.c
src/backend/catalog/namespace.c
src/backend/pgxc/pool/execRemote.c
src/test/regress/expected/xl_misc.out [new file with mode: 0644]
src/test/regress/parallel_schedule
src/test/regress/sql/xl_misc.sql [new file with mode: 0644]

index 31712da34bc5380bc9bd0abf2b920bd98d4b3fd1..18c7ee6369b7d55fb1bef3984787cc24fed2fed5 100644 (file)
@@ -217,8 +217,16 @@ SendRowDescriptionMessage(TupleDesc typeinfo, List *targetlist, int16 *formats)
                 */
                if (IsConnFromCoord())
                {
-                       char       *typename;
+                       char       *typename, *typeschema_name;
+                       Oid                     typeschema_oid;
+
                        typename = get_typename(atttypid);
+                       typeschema_oid = get_typ_namespace(atttypid);
+                       typeschema_name = isTempNamespace(typeschema_oid) ?
+                                                               "pg_temp" :
+                                                               get_namespace_name(typeschema_oid);
+
+                       pq_sendstring(&buf, typeschema_name);
                        pq_sendstring(&buf, typename);
                }
 #endif
index 8f5cceed6a6fa00ee2e8efa94e9358d6c51c9f02..73addcf3aaaec5227a17db56d0bedd7bb9bae33f 100644 (file)
@@ -29,6 +29,7 @@
 #endif
 #include "access/xlog.h"
 #include "catalog/dependency.h"
+#include "catalog/namespace.h"
 #include "catalog/objectaccess.h"
 #include "catalog/pg_authid.h"
 #include "catalog/pg_collation.h"
index 801923f314f0147cc5c745b55c618703330c04a6..1b0f72a3a7b932a52775adb33cb0e6f9961fdf53 100644 (file)
@@ -24,6 +24,7 @@
 #include "access/transam.h"
 #include "access/xact.h"
 #include "access/relscan.h"
+#include "catalog/namespace.h"
 #include "catalog/pg_type.h"
 #include "catalog/pgxc_node.h"
 #include "commands/prepare.h"
@@ -300,8 +301,10 @@ create_tuple_desc(char *msg_body, size_t len)
                AttrNumber      attnum;
                char            *attname;
                char            *typname;
+               char            *typschema;
                Oid             oidtypeid;
                int32           typemode, typmod;
+               List            *namelist = NIL;
 
                attnum = (AttrNumber) i;
 
@@ -309,8 +312,14 @@ create_tuple_desc(char *msg_body, size_t len)
                attname = msg_body;
                msg_body += strlen(attname) + 1;
 
+               /* type schema name */
+               typschema = msg_body;
+               namelist = lappend(namelist, makeString(typschema));
+               msg_body += strlen(typschema) + 1;
+
                /* type name */
                typname = msg_body;
+               namelist = lappend(namelist, makeString(typname));
                msg_body += strlen(typname) + 1;
 
                /* table OID, ignored */
@@ -334,7 +343,7 @@ create_tuple_desc(char *msg_body, size_t len)
                msg_body += 2;
 
                /* Get the OID type and mode type from typename */
-               parseTypeString(quote_identifier(typname), &oidtypeid, NULL, false);
+               parseTypeString(NameListToQuotedString(namelist), &oidtypeid, NULL, false);
 
                TupleDescInitEntry(result, attnum, attname, oidtypeid, typmod, 0);
        }
diff --git a/src/test/regress/expected/xl_misc.out b/src/test/regress/expected/xl_misc.out
new file mode 100644 (file)
index 0000000..6a13035
--- /dev/null
@@ -0,0 +1,164 @@
+-- try a special column name 
+create table xltest_type ("primary" integer, b integer);
+insert into xltest_type values(1, 11);
+insert into xltest_type values(2, 12);
+insert into xltest_type values(3, 13);
+select count(*) from xltest_type;
+ count 
+-------
+     3
+(1 row)
+
+set enable_fast_query_shipping to false;
+select count(*) from xltest_type;
+ count 
+-------
+     3
+(1 row)
+
+select * from xltest_type order by "primary";
+ primary | b  
+---------+----
+       1 | 11
+       2 | 12
+       3 | 13
+(3 rows)
+
+drop table xltest_type;
+-- repeat with a temp table
+set enable_fast_query_shipping to default;
+create temp table xltest_type ("primary" integer, b integer);
+insert into xltest_type values(1, 11);
+insert into xltest_type values(2, 12);
+insert into xltest_type values(3, 13);
+select count(*) from xltest_type;
+ count 
+-------
+     3
+(1 row)
+
+set enable_fast_query_shipping to false;
+select count(*) from xltest_type;
+ count 
+-------
+     3
+(1 row)
+
+select * from xltest_type order by "primary";
+ primary | b  
+---------+----
+       1 | 11
+       2 | 12
+       3 | 13
+(3 rows)
+
+drop table xltest_type;
+-- try a special table name
+set enable_fast_query_shipping to default;
+create table "XLTEST_type" ("primary" integer, b integer);
+-- fail
+insert into xltest_type values(1, 11);
+ERROR:  relation "xltest_type" does not exist
+LINE 1: insert into xltest_type values(1, 11);
+                    ^
+-- fail
+insert into XLTEST_type values(1, 11);
+ERROR:  relation "xltest_type" does not exist
+LINE 1: insert into XLTEST_type values(1, 11);
+                    ^
+-- ok
+insert into "XLTEST_type" values(1, 11);
+insert into "XLTEST_type" values(2, 12);
+insert into "XLTEST_type" values(3, 13);
+-- fail
+select count(*) from XLTEST_type;
+ERROR:  relation "xltest_type" does not exist
+LINE 1: select count(*) from XLTEST_type;
+                             ^
+-- ok
+select count(*) from "XLTEST_type";
+ count 
+-------
+     3
+(1 row)
+
+select array_agg(c.*) from "XLTEST_type" c where c.primary = 1;
+ array_agg  
+------------
+ {"(1,11)"}
+(1 row)
+
+set enable_fast_query_shipping to false;
+-- fail
+select count(*) from XLTEST_type;
+ERROR:  relation "xltest_type" does not exist
+LINE 1: select count(*) from XLTEST_type;
+                             ^
+-- ok
+select count(*) from "XLTEST_type";
+ count 
+-------
+     3
+(1 row)
+
+select array_agg(c.*) from "XLTEST_type" c where c.primary = 1;
+ array_agg  
+------------
+ {"(1,11)"}
+(1 row)
+
+-- fail
+drop table xltest_type;
+ERROR:  table "xltest_type" does not exist
+-- fail
+drop table XLTEST_type;
+ERROR:  table "xltest_type" does not exist
+-- fail
+drop table "XLTEST_TYPE";
+ERROR:  table "XLTEST_TYPE" does not exist
+-- ok
+drop table "XLTEST_type";
+-- try schema qualification for simple schema name
+set enable_fast_query_shipping to default;
+create schema xltypeschema;
+create table xltypeschema."XLTEST_type" ("primary" integer, b integer);
+insert into xltypeschema."XLTEST_type" values(1, 11);
+insert into xltypeschema."XLTEST_type" values(2, 12);
+insert into xltypeschema."XLTEST_type" values(3, 13);
+select array_agg(c.*) from "XLTEST_type" c where c.primary = 1;
+ERROR:  relation "XLTEST_type" does not exist
+LINE 1: select array_agg(c.*) from "XLTEST_type" c where c.primary =...
+                                   ^
+select array_agg(c.*) from xltypeschema."XLTEST_type" c where c.primary = 1;
+ array_agg  
+------------
+ {"(1,11)"}
+(1 row)
+
+drop table xltypeschema."XLTEST_type";
+-- try schema qualification for special schema name
+create schema "XL.Schema";
+create table "XL.Schema"."XLTEST_type" ("primary" integer, b integer);
+insert into "XL.Schema"."XLTEST_type" values(1, 11);
+insert into "XL.Schema"."XLTEST_type" values(2, 12);
+insert into "XL.Schema"."XLTEST_type" values(3, 13);
+select array_agg(c.*) from "XL.Schema"."XLTEST_type" c where c.primary = 1;
+ array_agg  
+------------
+ {"(1,11)"}
+(1 row)
+
+-- without schema, fail
+select array_agg(c.*) from "XLTEST_type" c;
+ERROR:  relation "XLTEST_type" does not exist
+LINE 1: select array_agg(c.*) from "XLTEST_type" c;
+                                   ^
+set search_path = "XL.Schema";
+-- should work
+select array_agg(c.*) from "XLTEST_type" c where c.primary = 1;
+ array_agg  
+------------
+ {"(1,11)"}
+(1 row)
+
+drop table "XL.Schema"."XLTEST_type";
index e1b20d9a3c576fbaa58977f9355bcb1b73d09e29..39841fbaf4fed68fbf0957d07a09600d84778a72 100644 (file)
@@ -139,4 +139,4 @@ test: xc_prepared_xacts
 test: xc_notrans_block
 
 # This runs XL specific tests
-test: xl_primary_key xl_foreign_key xl_distribution_column_types xl_alter_table xl_distribution_column_types_modulo xl_plan_pushdown xl_functions xl_limitations xl_user_defined_functions xl_join xl_distributed_xact xl_create_table
+test: xl_misc xl_primary_key xl_foreign_key xl_distribution_column_types xl_alter_table xl_distribution_column_types_modulo xl_plan_pushdown xl_functions xl_limitations xl_user_defined_functions xl_join xl_distributed_xact xl_create_table
diff --git a/src/test/regress/sql/xl_misc.sql b/src/test/regress/sql/xl_misc.sql
new file mode 100644 (file)
index 0000000..3ad64c5
--- /dev/null
@@ -0,0 +1,95 @@
+
+-- try a special column name 
+create table xltest_type ("primary" integer, b integer);
+insert into xltest_type values(1, 11);
+insert into xltest_type values(2, 12);
+insert into xltest_type values(3, 13);
+
+select count(*) from xltest_type;
+set enable_fast_query_shipping to false;
+select count(*) from xltest_type;
+select * from xltest_type order by "primary";
+
+drop table xltest_type;
+
+
+-- repeat with a temp table
+set enable_fast_query_shipping to default;
+create temp table xltest_type ("primary" integer, b integer);
+insert into xltest_type values(1, 11);
+insert into xltest_type values(2, 12);
+insert into xltest_type values(3, 13);
+
+select count(*) from xltest_type;
+set enable_fast_query_shipping to false;
+select count(*) from xltest_type;
+select * from xltest_type order by "primary";
+
+drop table xltest_type;
+
+
+-- try a special table name
+set enable_fast_query_shipping to default;
+create table "XLTEST_type" ("primary" integer, b integer);
+-- fail
+insert into xltest_type values(1, 11);
+-- fail
+insert into XLTEST_type values(1, 11);
+-- ok
+insert into "XLTEST_type" values(1, 11);
+insert into "XLTEST_type" values(2, 12);
+insert into "XLTEST_type" values(3, 13);
+
+-- fail
+select count(*) from XLTEST_type;
+-- ok
+select count(*) from "XLTEST_type";
+select array_agg(c.*) from "XLTEST_type" c where c.primary = 1;
+
+set enable_fast_query_shipping to false;
+-- fail
+select count(*) from XLTEST_type;
+-- ok
+select count(*) from "XLTEST_type";
+
+select array_agg(c.*) from "XLTEST_type" c where c.primary = 1;
+
+-- fail
+drop table xltest_type;
+-- fail
+drop table XLTEST_type;
+-- fail
+drop table "XLTEST_TYPE";
+-- ok
+drop table "XLTEST_type";
+
+-- try schema qualification for simple schema name
+set enable_fast_query_shipping to default;
+create schema xltypeschema;
+create table xltypeschema."XLTEST_type" ("primary" integer, b integer);
+insert into xltypeschema."XLTEST_type" values(1, 11);
+insert into xltypeschema."XLTEST_type" values(2, 12);
+insert into xltypeschema."XLTEST_type" values(3, 13);
+
+select array_agg(c.*) from "XLTEST_type" c where c.primary = 1;
+select array_agg(c.*) from xltypeschema."XLTEST_type" c where c.primary = 1;
+
+drop table xltypeschema."XLTEST_type";
+
+-- try schema qualification for special schema name
+create schema "XL.Schema";
+create table "XL.Schema"."XLTEST_type" ("primary" integer, b integer);
+insert into "XL.Schema"."XLTEST_type" values(1, 11);
+insert into "XL.Schema"."XLTEST_type" values(2, 12);
+insert into "XL.Schema"."XLTEST_type" values(3, 13);
+
+select array_agg(c.*) from "XL.Schema"."XLTEST_type" c where c.primary = 1;
+
+-- without schema, fail
+select array_agg(c.*) from "XLTEST_type" c;
+set search_path = "XL.Schema";
+-- should work
+select array_agg(c.*) from "XLTEST_type" c where c.primary = 1;
+
+drop table "XL.Schema"."XLTEST_type";
+