summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2019-12-17 17:44:28 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2019-12-17 17:44:28 -0500
commit275a8ac4f75ccfa73e0baa7c71ad59f4fe89367c (patch)
tree7c27fc1c120ae996ee7557545bfa9ee144acea6d
parent65cb25e4fb5025ee6dcbcee0c15602f556945f8d (diff)
Fix error reporting for index expressions of prohibited types.
If CheckAttributeType() threw an error about the datatype of an index expression column, it would report an empty column name, which is pretty unhelpful and certainly not the intended behavior. I (tgl) evidently broke this in commit cfc5008a5, by not noticing that the column's attname was used above where I'd placed the assignment of it. In HEAD and v12, this is trivially fixable by moving up the assignment of attname. Before v12 the code is a bit more messy; to avoid doing substantial refactoring, I took the lazy way out and just put in two copies of the assignment code. Report and patch by Amit Langote. Back-patch to all supported branches. Discussion: https://postgr.es/m/CA+HiwqFA+BGyBFimjiYXXMa2Hc3fcL0+OJOyzUNjhU4NCa_XXw@mail.gmail.com
-rw-r--r--src/backend/catalog/index.c24
-rw-r--r--src/test/regress/expected/create_index.out37
-rw-r--r--src/test/regress/sql/create_index.sql12
3 files changed, 65 insertions, 8 deletions
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 535b29d4e70..9386485db23 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -350,6 +350,14 @@ ConstructTupleDescriptor(Relation heapRelation,
memcpy(to, from, ATTRIBUTE_FIXED_PART_SIZE);
/*
+ * Set the attribute name as specified by caller.
+ */
+ if (colnames_item == NULL) /* shouldn't happen */
+ elog(ERROR, "too few entries in colnames list");
+ namestrcpy(&to->attname, (const char *) lfirst(colnames_item));
+ colnames_item = lnext(colnames_item);
+
+ /*
* Fix the stuff that should not be the same as the underlying
* attr
*/
@@ -370,6 +378,14 @@ ConstructTupleDescriptor(Relation heapRelation,
MemSet(to, 0, ATTRIBUTE_FIXED_PART_SIZE);
+ /*
+ * Set the attribute name as specified by caller.
+ */
+ if (colnames_item == NULL) /* shouldn't happen */
+ elog(ERROR, "too few entries in colnames list");
+ namestrcpy(&to->attname, (const char *) lfirst(colnames_item));
+ colnames_item = lnext(colnames_item);
+
if (indexpr_item == NULL) /* shouldn't happen */
elog(ERROR, "too few entries in indexprs list");
indexkey = (Node *) lfirst(indexpr_item);
@@ -423,14 +439,6 @@ ConstructTupleDescriptor(Relation heapRelation,
to->attrelid = InvalidOid;
/*
- * Set the attribute name as specified by caller.
- */
- if (colnames_item == NULL) /* shouldn't happen */
- elog(ERROR, "too few entries in colnames list");
- namestrcpy(&to->attname, (const char *) lfirst(colnames_item));
- colnames_item = lnext(colnames_item);
-
- /*
* Check the opclass and index AM to see if either provides a keytype
* (overriding the attribute type). Opclass takes precedence.
*/
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 5bb3ea8baba..1db29f81e46 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2384,6 +2384,23 @@ ERROR: duplicate key value violates unique constraint "func_index_index"
DETAIL: Key (textcat(f1, f2))=(ABCDEF) already exists.
-- but this shouldn't:
INSERT INTO func_index_heap VALUES('QWERTY');
+-- while we're here, see that the metadata looks sane
+\d func_index_heap
+Table "public.func_index_heap"
+ Column | Type | Modifiers
+--------+------+-----------
+ f1 | text |
+ f2 | text |
+Indexes:
+ "func_index_index" UNIQUE, btree (textcat(f1, f2))
+
+\d func_index_index
+ Index "public.func_index_index"
+ Column | Type | Definition
+---------+------+-----------------
+ textcat | text | textcat(f1, f2)
+unique, btree, for table "public.func_index_heap"
+
--
-- Same test, expressional index
--
@@ -2399,6 +2416,26 @@ ERROR: duplicate key value violates unique constraint "func_index_index"
DETAIL: Key ((f1 || f2))=(ABCDEF) already exists.
-- but this shouldn't:
INSERT INTO func_index_heap VALUES('QWERTY');
+-- while we're here, see that the metadata looks sane
+\d func_index_heap
+Table "public.func_index_heap"
+ Column | Type | Modifiers
+--------+------+-----------
+ f1 | text |
+ f2 | text |
+Indexes:
+ "func_index_index" UNIQUE, btree ((f1 || f2))
+
+\d func_index_index
+Index "public.func_index_index"
+ Column | Type | Definition
+--------+------+------------
+ expr | text | (f1 || f2)
+unique, btree, for table "public.func_index_heap"
+
+-- this should fail because of unsafe column type (anonymous record)
+create index on func_index_heap ((f1 || f2), (row(f1, f2)));
+ERROR: column "row" has pseudo-type record
--
-- Also try building functional, expressional, and partial indexes on
-- tables that already contain data.
diff --git a/src/test/regress/sql/create_index.sql b/src/test/regress/sql/create_index.sql
index 60780fb9145..74bb3665965 100644
--- a/src/test/regress/sql/create_index.sql
+++ b/src/test/regress/sql/create_index.sql
@@ -715,6 +715,10 @@ INSERT INTO func_index_heap VALUES('ABCD', 'EF');
-- but this shouldn't:
INSERT INTO func_index_heap VALUES('QWERTY');
+-- while we're here, see that the metadata looks sane
+\d func_index_heap
+\d func_index_index
+
--
-- Same test, expressional index
@@ -731,6 +735,14 @@ INSERT INTO func_index_heap VALUES('ABCD', 'EF');
-- but this shouldn't:
INSERT INTO func_index_heap VALUES('QWERTY');
+-- while we're here, see that the metadata looks sane
+\d func_index_heap
+\d func_index_index
+
+-- this should fail because of unsafe column type (anonymous record)
+create index on func_index_heap ((f1 || f2), (row(f1, f2)));
+
+
--
-- Also try building functional, expressional, and partial indexes on
-- tables that already contain data.