Skip to content

Commit 028e3da

Browse files
committed
Fix pg_get_indexdef()'s behavior for included index columns.
The multi-argument form of pg_get_indexdef() failed to print anything when asked to print a single index column that is an included column rather than a key column. This seems an unintentional result of someone having tried to take a short-cut and use the attrsOnly flag for two different purposes. To fix, split said flag into two flags, attrsOnly which suppresses non-attribute info, and keysOnly which suppresses included columns. Add a test case using psql's \d command, which relies on that function. (It's mighty tempting at this point to replace pg_get_indexdef_worker's mess of boolean flag arguments with a single bitmask-of-flags argument, which would allow making the call sites much more self-documenting. But I refrained for the moment.) Discussion: https://postgr.es/m/21724.1531943735@sss.pgh.pa.us
1 parent 1573995 commit 028e3da

File tree

3 files changed

+38
-18
lines changed

3 files changed

+38
-18
lines changed

src/backend/utils/adt/ruleutils.c

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,8 @@ static void decompile_column_index_array(Datum column_index_array, Oid relId,
320320
static char *pg_get_ruledef_worker(Oid ruleoid, int prettyFlags);
321321
static char *pg_get_indexdef_worker(Oid indexrelid, int colno,
322322
const Oid *excludeOps,
323-
bool attrsOnly, bool showTblSpc, bool inherits,
323+
bool attrsOnly, bool keysOnly,
324+
bool showTblSpc, bool inherits,
324325
int prettyFlags, bool missing_ok);
325326
static char *pg_get_statisticsobj_worker(Oid statextid, bool missing_ok);
326327
static char *pg_get_partkeydef_worker(Oid relid, int prettyFlags,
@@ -1097,7 +1098,9 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
10971098

10981099
prettyFlags = PRETTYFLAG_INDENT;
10991100

1100-
res = pg_get_indexdef_worker(indexrelid, 0, NULL, false, false, false,
1101+
res = pg_get_indexdef_worker(indexrelid, 0, NULL,
1102+
false, false,
1103+
false, false,
11011104
prettyFlags, true);
11021105

11031106
if (res == NULL)
@@ -1117,8 +1120,10 @@ pg_get_indexdef_ext(PG_FUNCTION_ARGS)
11171120

11181121
prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) : PRETTYFLAG_INDENT;
11191122

1120-
res = pg_get_indexdef_worker(indexrelid, colno, NULL, colno != 0, false,
1121-
false, prettyFlags, true);
1123+
res = pg_get_indexdef_worker(indexrelid, colno, NULL,
1124+
colno != 0, false,
1125+
false, false,
1126+
prettyFlags, true);
11221127

11231128
if (res == NULL)
11241129
PG_RETURN_NULL();
@@ -1134,18 +1139,23 @@ pg_get_indexdef_ext(PG_FUNCTION_ARGS)
11341139
char *
11351140
pg_get_indexdef_string(Oid indexrelid)
11361141
{
1137-
return pg_get_indexdef_worker(indexrelid, 0, NULL, false, true, true, 0, false);
1142+
return pg_get_indexdef_worker(indexrelid, 0, NULL,
1143+
false, false,
1144+
true, true,
1145+
0, false);
11381146
}
11391147

1140-
/* Internal version that just reports the column definitions */
1148+
/* Internal version that just reports the key-column definitions */
11411149
char *
11421150
pg_get_indexdef_columns(Oid indexrelid, bool pretty)
11431151
{
11441152
int prettyFlags;
11451153

11461154
prettyFlags = pretty ? (PRETTYFLAG_PAREN | PRETTYFLAG_INDENT | PRETTYFLAG_SCHEMA) : PRETTYFLAG_INDENT;
11471155

1148-
return pg_get_indexdef_worker(indexrelid, 0, NULL, true, false, false,
1156+
return pg_get_indexdef_worker(indexrelid, 0, NULL,
1157+
true, true,
1158+
false, false,
11491159
prettyFlags, false);
11501160
}
11511161

@@ -1158,7 +1168,8 @@ pg_get_indexdef_columns(Oid indexrelid, bool pretty)
11581168
static char *
11591169
pg_get_indexdef_worker(Oid indexrelid, int colno,
11601170
const Oid *excludeOps,
1161-
bool attrsOnly, bool showTblSpc, bool inherits,
1171+
bool attrsOnly, bool keysOnly,
1172+
bool showTblSpc, bool inherits,
11621173
int prettyFlags, bool missing_ok)
11631174
{
11641175
/* might want a separate isConstraint parameter later */
@@ -1297,15 +1308,13 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
12971308
Oid keycolcollation;
12981309

12991310
/*
1300-
* attrsOnly flag is used for building unique-constraint and
1301-
* exclusion-constraint error messages. Included attrs are meaningless
1302-
* there, so do not include them in the message.
1311+
* Ignore non-key attributes if told to.
13031312
*/
1304-
if (attrsOnly && keyno >= idxrec->indnkeyatts)
1313+
if (keysOnly && keyno >= idxrec->indnkeyatts)
13051314
break;
13061315

1307-
/* Report the INCLUDED attributes, if any. */
1308-
if ((!attrsOnly) && keyno == idxrec->indnkeyatts)
1316+
/* Otherwise, print INCLUDE to divide key and non-key attrs. */
1317+
if (!colno && keyno == idxrec->indnkeyatts)
13091318
{
13101319
appendStringInfoString(&buf, ") INCLUDE (");
13111320
sep = "";
@@ -1352,13 +1361,12 @@ pg_get_indexdef_worker(Oid indexrelid, int colno,
13521361
keycolcollation = exprCollation(indexkey);
13531362
}
13541363

1355-
if (!attrsOnly && (!colno || colno == keyno + 1))
1364+
/* Print additional decoration for (selected) key columns */
1365+
if (!attrsOnly && keyno < idxrec->indnkeyatts &&
1366+
(!colno || colno == keyno + 1))
13561367
{
13571368
Oid indcoll;
13581369

1359-
if (keyno >= idxrec->indnkeyatts)
1360-
continue;
1361-
13621370
/* Add collation, if not default for column */
13631371
indcoll = indcollation->values[keyno];
13641372
if (OidIsValid(indcoll) && indcoll != keycolcollation)
@@ -2197,6 +2205,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
21972205
false,
21982206
false,
21992207
false,
2208+
false,
22002209
prettyFlags,
22012210
false));
22022211
break;

src/test/regress/expected/index_including.out

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,16 @@ WHERE i.indrelid = 'tbl_include_reg'::regclass ORDER BY c.relname;
1919
CREATE INDEX tbl_include_reg_idx ON public.tbl_include_reg USING btree (c1, c2) INCLUDE (c3, c4)
2020
(2 rows)
2121

22+
\d tbl_include_reg_idx
23+
Index "public.tbl_include_reg_idx"
24+
Column | Type | Definition
25+
--------+---------+------------
26+
c1 | integer | c1
27+
c2 | integer | c2
28+
c3 | integer | c3
29+
c4 | box | c4
30+
btree, for table "public.tbl_include_reg"
31+
2232
-- Unique index and unique constraint
2333
CREATE TABLE tbl_include_unique1 (c1 int, c2 int, c3 int, c4 box);
2434
INSERT INTO tbl_include_unique1 SELECT x, 2*x, 3*x, box('4,4,4,4') FROM generate_series(1,10) AS x;

src/test/regress/sql/index_including.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ CREATE INDEX ON tbl_include_reg (c1, c2) INCLUDE (c1, c3);
1414
SELECT pg_get_indexdef(i.indexrelid)
1515
FROM pg_index i JOIN pg_class c ON i.indexrelid = c.oid
1616
WHERE i.indrelid = 'tbl_include_reg'::regclass ORDER BY c.relname;
17+
\d tbl_include_reg_idx
1718

1819
-- Unique index and unique constraint
1920
CREATE TABLE tbl_include_unique1 (c1 int, c2 int, c3 int, c4 box);

0 commit comments

Comments
 (0)