public inbox for [email protected]
help / color / mirror / Atom feed[PATCH 06/10] Pass all keys to BRIN consistent function at once
30+ messages / 7 participants
[nested] [flat]
* [PATCH 06/10] Pass all keys to BRIN consistent function at once
@ 2019-06-09 20:04 Tomas Vondra <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Tomas Vondra @ 2019-06-09 20:04 UTC (permalink / raw)
---
src/backend/access/brin/brin.c | 125 ++++++++++++-----
src/backend/access/brin/brin_inclusion.c | 164 +++++++++++++++--------
src/backend/access/brin/brin_minmax.c | 116 +++++++++++-----
src/backend/access/brin/brin_validate.c | 4 +-
src/include/catalog/pg_proc.dat | 4 +-
5 files changed, 292 insertions(+), 121 deletions(-)
diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c
index 63f2d7990c..31d09bc88e 100644
--- a/src/backend/access/brin/brin.c
+++ b/src/backend/access/brin/brin.c
@@ -383,6 +383,9 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
BrinMemTuple *dtup;
BrinTuple *btup = NULL;
Size btupsz = 0;
+ ScanKey **keys;
+ int *nkeys;
+ int keyno;
opaque = (BrinOpaque *) scan->opaque;
bdesc = opaque->bo_bdesc;
@@ -404,6 +407,53 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
*/
consistentFn = palloc0(sizeof(FmgrInfo) * bdesc->bd_tupdesc->natts);
+ /*
+ * Make room for per-attribute lists of scan keys that we'll pass to the
+ * consistent support procedure.
+ */
+ keys = palloc0(sizeof(ScanKey *) * bdesc->bd_tupdesc->natts);
+ nkeys = palloc0(sizeof(int) * bdesc->bd_tupdesc->natts);
+
+ /*
+ * Preprocess the scan keys - split them into per-attribute arrays.
+ */
+ for (keyno = 0; keyno < scan->numberOfKeys; keyno++)
+ {
+ ScanKey key = &scan->keyData[keyno];
+ AttrNumber keyattno = key->sk_attno;
+
+ /*
+ * The collation of the scan key must match the collation
+ * used in the index column (but only if the search is not
+ * IS NULL/ IS NOT NULL). Otherwise we shouldn't be using
+ * this index ...
+ */
+ Assert((key->sk_flags & SK_ISNULL) ||
+ (key->sk_collation ==
+ TupleDescAttr(bdesc->bd_tupdesc,
+ keyattno - 1)->attcollation));
+
+ /* First time we see this index attribute, so init as needed. */
+ if (!keys[keyattno-1])
+ {
+ FmgrInfo *tmp;
+
+ keys[keyattno-1] = palloc0(sizeof(ScanKey) * scan->numberOfKeys);
+
+ /* First time this column, so look up consistent function */
+ Assert(consistentFn[keyattno - 1].fn_oid == InvalidOid);
+
+ tmp = index_getprocinfo(idxRel, keyattno,
+ BRIN_PROCNUM_CONSISTENT);
+ fmgr_info_copy(&consistentFn[keyattno - 1], tmp,
+ CurrentMemoryContext);
+ }
+
+ /* Add key to the per-attribute array. */
+ keys[keyattno - 1][nkeys[keyattno - 1]] = key;
+ nkeys[keyattno - 1]++;
+ }
+
/* allocate an initial in-memory tuple, out of the per-range memcxt */
dtup = brin_new_memtuple(bdesc);
@@ -464,7 +514,7 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
}
else
{
- int keyno;
+ int attno;
/*
* Compare scan keys with summary values stored for the range.
@@ -474,34 +524,19 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
* no keys.
*/
addrange = true;
- for (keyno = 0; keyno < scan->numberOfKeys; keyno++)
+ for (attno = 1; attno <= bdesc->bd_tupdesc->natts; attno++)
{
- ScanKey key = &scan->keyData[keyno];
- AttrNumber keyattno = key->sk_attno;
- BrinValues *bval = &dtup->bt_columns[keyattno - 1];
+ BrinValues *bval;
Datum add;
- /*
- * The collation of the scan key must match the collation
- * used in the index column (but only if the search is not
- * IS NULL/ IS NOT NULL). Otherwise we shouldn't be using
- * this index ...
- */
- Assert((key->sk_flags & SK_ISNULL) ||
- (key->sk_collation ==
- TupleDescAttr(bdesc->bd_tupdesc,
- keyattno - 1)->attcollation));
+ /* skip attributes without any san keys */
+ if (!nkeys[attno - 1])
+ continue;
- /* First time this column? look up consistent function */
- if (consistentFn[keyattno - 1].fn_oid == InvalidOid)
- {
- FmgrInfo *tmp;
+ bval = &dtup->bt_columns[attno - 1];
- tmp = index_getprocinfo(idxRel, keyattno,
- BRIN_PROCNUM_CONSISTENT);
- fmgr_info_copy(&consistentFn[keyattno - 1], tmp,
- CurrentMemoryContext);
- }
+ Assert((nkeys[attno - 1] > 0) &&
+ (nkeys[attno - 1] <= scan->numberOfKeys));
/*
* Check whether the scan key is consistent with the page
@@ -513,12 +548,42 @@ bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm)
* the range as a whole, so break out of the loop as soon
* as a false return value is obtained.
*/
- add = FunctionCall3Coll(&consistentFn[keyattno - 1],
- key->sk_collation,
- PointerGetDatum(bdesc),
- PointerGetDatum(bval),
- PointerGetDatum(key));
- addrange = DatumGetBool(add);
+ if (consistentFn[attno - 1].fn_nargs >= 4)
+ {
+ Oid collation;
+
+ /*
+ * Collation from the first key (has to be the same for
+ * all keys for the same attribue).
+ */
+ collation = keys[attno - 1][0]->sk_collation;
+
+ /* Check all keys at once */
+ add = FunctionCall4Coll(&consistentFn[attno - 1],
+ collation,
+ PointerGetDatum(bdesc),
+ PointerGetDatum(bval),
+ PointerGetDatum(keys[attno - 1]),
+ Int32GetDatum(nkeys[attno - 1]));
+ addrange = DatumGetBool(add);
+ }
+ else
+ {
+ /* Check keys one by one */
+ int keyno;
+
+ for (keyno = 0; keyno < nkeys[attno - 1]; keyno++)
+ {
+ add = FunctionCall3Coll(&consistentFn[attno - 1],
+ keys[attno - 1][keyno]->sk_collation,
+ PointerGetDatum(bdesc),
+ PointerGetDatum(bval),
+ PointerGetDatum(keys[attno - 1][keyno]));
+ addrange = DatumGetBool(add);
+ if (!addrange)
+ break;
+ }
+ }
if (!addrange)
break;
diff --git a/src/backend/access/brin/brin_inclusion.c b/src/backend/access/brin/brin_inclusion.c
index 86788024ef..f9c2918031 100644
--- a/src/backend/access/brin/brin_inclusion.c
+++ b/src/backend/access/brin/brin_inclusion.c
@@ -85,6 +85,8 @@ static FmgrInfo *inclusion_get_procinfo(BrinDesc *bdesc, uint16 attno,
uint16 procnum);
static FmgrInfo *inclusion_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno,
Oid subtype, uint16 strategynum);
+static bool inclusion_consistent_key(BrinDesc *bdesc, BrinValues *column,
+ ScanKey key, Oid colloid);
/*
@@ -252,53 +254,103 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS)
{
BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0);
BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1);
- ScanKey key = (ScanKey) PG_GETARG_POINTER(2);
- Oid colloid = PG_GET_COLLATION(),
- subtype;
- Datum unionval;
- AttrNumber attno;
- Datum query;
- FmgrInfo *finfo;
- Datum result;
-
- Assert(key->sk_attno == column->bv_attno);
+ ScanKey *keys = (ScanKey *) PG_GETARG_POINTER(2);
+ int nkeys = PG_GETARG_INT32(3);
+ Oid colloid = PG_GET_COLLATION();
+ int keyno;
+ bool matches;
+ bool regular_keys = false;
- /* Handle IS NULL/IS NOT NULL tests. */
- if (key->sk_flags & SK_ISNULL)
+ /*
+ * First check if there are any IS NULL scan keys, and if we're
+ * violating them. In that case we can terminate early, without
+ * inspecting the ranges.
+ */
+ for (keyno = 0; keyno < nkeys; keyno++)
{
- if (key->sk_flags & SK_SEARCHNULL)
+ ScanKey key = keys[keyno];
+
+ Assert(key->sk_attno == column->bv_attno);
+
+ /* handle IS NULL/IS NOT NULL tests */
+ if (key->sk_flags & SK_ISNULL)
{
- if (column->bv_allnulls || column->bv_hasnulls)
- PG_RETURN_BOOL(true);
+ if (key->sk_flags & SK_SEARCHNULL)
+ {
+ if (column->bv_allnulls || column->bv_hasnulls)
+ continue; /* this key is fine, continue */
+
+ PG_RETURN_BOOL(false);
+ }
+
+ /*
+ * For IS NOT NULL, we can only skip ranges that are known to have
+ * only nulls.
+ */
+ if (key->sk_flags & SK_SEARCHNOTNULL)
+ {
+ if (column->bv_allnulls)
+ PG_RETURN_BOOL(false);
+
+ continue;
+ }
+
+ /*
+ * Neither IS NULL nor IS NOT NULL was used; assume all indexable
+ * operators are strict and return false.
+ */
PG_RETURN_BOOL(false);
}
-
- /*
- * For IS NOT NULL, we can only skip ranges that are known to have
- * only nulls.
- */
- if (key->sk_flags & SK_SEARCHNOTNULL)
- PG_RETURN_BOOL(!column->bv_allnulls);
-
- /*
- * Neither IS NULL nor IS NOT NULL was used; assume all indexable
- * operators are strict and return false.
- */
- PG_RETURN_BOOL(false);
+ else
+ /* note we have regular (non-NULL) scan keys */
+ regular_keys = true;
}
- /* If it is all nulls, it cannot possibly be consistent. */
- if (column->bv_allnulls)
+ /*
+ * If the page range is all nulls, it cannot possibly be consistent if
+ * there are some regular scan keys.
+ */
+ if (column->bv_allnulls && regular_keys)
PG_RETURN_BOOL(false);
+ /* If there are no regular keys, the page range is considered consistent. */
+ if (!regular_keys)
+ PG_RETURN_BOOL(true);
+
/* It has to be checked, if it contains elements that are not mergeable. */
if (DatumGetBool(column->bv_values[INCLUSION_UNMERGEABLE]))
PG_RETURN_BOOL(true);
- attno = key->sk_attno;
- subtype = key->sk_subtype;
- query = key->sk_argument;
- unionval = column->bv_values[INCLUSION_UNION];
+ matches = true;
+
+ for (keyno = 0; keyno < nkeys; keyno++)
+ {
+ ScanKey key = keys[keyno];
+
+ /* ignore IS NULL/IS NOT NULL tests handled above */
+ if (key->sk_flags & SK_ISNULL)
+ continue;
+
+ matches = inclusion_consistent_key(bdesc, column, key, colloid);
+
+ if (!matches)
+ break;
+ }
+
+ PG_RETURN_BOOL(matches);
+}
+
+static bool
+inclusion_consistent_key(BrinDesc *bdesc, BrinValues *column, ScanKey key,
+ Oid colloid)
+{
+ FmgrInfo *finfo;
+ AttrNumber attno = key->sk_attno;
+ Oid subtype = key->sk_subtype;
+ Datum query = key->sk_argument;
+ Datum unionval = column->bv_values[INCLUSION_UNION];
+ Datum result;
+
switch (key->sk_strategy)
{
/*
@@ -318,49 +370,49 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS)
finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
RTOverRightStrategyNumber);
result = FunctionCall2Coll(finfo, colloid, unionval, query);
- PG_RETURN_BOOL(!DatumGetBool(result));
+ return !DatumGetBool(result);
case RTOverLeftStrategyNumber:
finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
RTRightStrategyNumber);
result = FunctionCall2Coll(finfo, colloid, unionval, query);
- PG_RETURN_BOOL(!DatumGetBool(result));
+ return !DatumGetBool(result);
case RTOverRightStrategyNumber:
finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
RTLeftStrategyNumber);
result = FunctionCall2Coll(finfo, colloid, unionval, query);
- PG_RETURN_BOOL(!DatumGetBool(result));
+ return !DatumGetBool(result);
case RTRightStrategyNumber:
finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
RTOverLeftStrategyNumber);
result = FunctionCall2Coll(finfo, colloid, unionval, query);
- PG_RETURN_BOOL(!DatumGetBool(result));
+ return !DatumGetBool(result);
case RTBelowStrategyNumber:
finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
RTOverAboveStrategyNumber);
result = FunctionCall2Coll(finfo, colloid, unionval, query);
- PG_RETURN_BOOL(!DatumGetBool(result));
+ return !DatumGetBool(result);
case RTOverBelowStrategyNumber:
finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
RTAboveStrategyNumber);
result = FunctionCall2Coll(finfo, colloid, unionval, query);
- PG_RETURN_BOOL(!DatumGetBool(result));
+ return !DatumGetBool(result);
case RTOverAboveStrategyNumber:
finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
RTBelowStrategyNumber);
result = FunctionCall2Coll(finfo, colloid, unionval, query);
- PG_RETURN_BOOL(!DatumGetBool(result));
+ return !DatumGetBool(result);
case RTAboveStrategyNumber:
finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
RTOverBelowStrategyNumber);
result = FunctionCall2Coll(finfo, colloid, unionval, query);
- PG_RETURN_BOOL(!DatumGetBool(result));
+ return !DatumGetBool(result);
/*
* Overlap and contains strategies
@@ -379,7 +431,7 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS)
finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
key->sk_strategy);
result = FunctionCall2Coll(finfo, colloid, unionval, query);
- PG_RETURN_DATUM(result);
+ return DatumGetBool(result);
/*
* Contained by strategies
@@ -400,9 +452,9 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS)
RTOverlapStrategyNumber);
result = FunctionCall2Coll(finfo, colloid, unionval, query);
if (DatumGetBool(result))
- PG_RETURN_BOOL(true);
+ return true;
- PG_RETURN_DATUM(column->bv_values[INCLUSION_CONTAINS_EMPTY]);
+ return DatumGetBool(column->bv_values[INCLUSION_CONTAINS_EMPTY]);
/*
* Adjacent strategy
@@ -419,12 +471,12 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS)
RTOverlapStrategyNumber);
result = FunctionCall2Coll(finfo, colloid, unionval, query);
if (DatumGetBool(result))
- PG_RETURN_BOOL(true);
+ return true;
finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
- RTAdjacentStrategyNumber);
+ RTAdjacentStrategyNumber);
result = FunctionCall2Coll(finfo, colloid, unionval, query);
- PG_RETURN_DATUM(result);
+ return DatumGetBool(result);
/*
* Basic comparison strategies
@@ -454,9 +506,9 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS)
RTRightStrategyNumber);
result = FunctionCall2Coll(finfo, colloid, unionval, query);
if (!DatumGetBool(result))
- PG_RETURN_BOOL(true);
+ return true;
- PG_RETURN_DATUM(column->bv_values[INCLUSION_CONTAINS_EMPTY]);
+ return DatumGetBool(column->bv_values[INCLUSION_CONTAINS_EMPTY]);
case RTSameStrategyNumber:
case RTEqualStrategyNumber:
@@ -464,30 +516,30 @@ brin_inclusion_consistent(PG_FUNCTION_ARGS)
RTContainsStrategyNumber);
result = FunctionCall2Coll(finfo, colloid, unionval, query);
if (DatumGetBool(result))
- PG_RETURN_BOOL(true);
+ return true;
- PG_RETURN_DATUM(column->bv_values[INCLUSION_CONTAINS_EMPTY]);
+ return DatumGetBool(column->bv_values[INCLUSION_CONTAINS_EMPTY]);
case RTGreaterEqualStrategyNumber:
finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
RTLeftStrategyNumber);
result = FunctionCall2Coll(finfo, colloid, unionval, query);
if (!DatumGetBool(result))
- PG_RETURN_BOOL(true);
+ return true;
- PG_RETURN_DATUM(column->bv_values[INCLUSION_CONTAINS_EMPTY]);
+ return DatumGetBool(column->bv_values[INCLUSION_CONTAINS_EMPTY]);
case RTGreaterStrategyNumber:
/* no need to check for empty elements */
finfo = inclusion_get_strategy_procinfo(bdesc, attno, subtype,
RTLeftStrategyNumber);
result = FunctionCall2Coll(finfo, colloid, unionval, query);
- PG_RETURN_BOOL(!DatumGetBool(result));
+ return !DatumGetBool(result);
default:
/* shouldn't happen */
elog(ERROR, "invalid strategy number %d", key->sk_strategy);
- PG_RETURN_BOOL(false);
+ return false;
}
}
diff --git a/src/backend/access/brin/brin_minmax.c b/src/backend/access/brin/brin_minmax.c
index ad0d18ed39..2266fef2f9 100644
--- a/src/backend/access/brin/brin_minmax.c
+++ b/src/backend/access/brin/brin_minmax.c
@@ -31,6 +31,8 @@ typedef struct MinmaxOpaque
static FmgrInfo *minmax_get_strategy_procinfo(BrinDesc *bdesc, uint16 attno,
Oid subtype, uint16 strategynum);
+static bool minmax_consistent_key(BrinDesc *bdesc, BrinValues *column,
+ ScanKey key, Oid colloid);
Datum
@@ -147,47 +149,99 @@ brin_minmax_consistent(PG_FUNCTION_ARGS)
{
BrinDesc *bdesc = (BrinDesc *) PG_GETARG_POINTER(0);
BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1);
- ScanKey key = (ScanKey) PG_GETARG_POINTER(2);
- Oid colloid = PG_GET_COLLATION(),
- subtype;
- AttrNumber attno;
- Datum value;
+ ScanKey *keys = (ScanKey *) PG_GETARG_POINTER(2);
+ int nkeys = PG_GETARG_INT32(3);
+ Oid colloid = PG_GET_COLLATION();
Datum matches;
- FmgrInfo *finfo;
+ int keyno;
+ bool regular_keys = false;
- Assert(key->sk_attno == column->bv_attno);
-
- /* handle IS NULL/IS NOT NULL tests */
- if (key->sk_flags & SK_ISNULL)
+ /*
+ * First check if there are any IS NULL scan keys, and if we're
+ * violating them. In that case we can terminate early, without
+ * inspecting the ranges.
+ */
+ for (keyno = 0; keyno < nkeys; keyno++)
{
- if (key->sk_flags & SK_SEARCHNULL)
+ ScanKey key = keys[keyno];
+
+ Assert(key->sk_attno == column->bv_attno);
+
+ /* handle IS NULL/IS NOT NULL tests */
+ if (key->sk_flags & SK_ISNULL)
{
- if (column->bv_allnulls || column->bv_hasnulls)
- PG_RETURN_BOOL(true);
+ if (key->sk_flags & SK_SEARCHNULL)
+ {
+ if (column->bv_allnulls || column->bv_hasnulls)
+ continue; /* this key is fine, continue */
+
+ PG_RETURN_BOOL(false);
+ }
+
+ /*
+ * For IS NOT NULL, we can only skip ranges that are known to have
+ * only nulls.
+ */
+ if (key->sk_flags & SK_SEARCHNOTNULL)
+ {
+ if (column->bv_allnulls)
+ PG_RETURN_BOOL(false);
+
+ continue;
+ }
+
+ /*
+ * Neither IS NULL nor IS NOT NULL was used; assume all indexable
+ * operators are strict and return false.
+ */
PG_RETURN_BOOL(false);
}
+ else
+ /* note we have regular (non-NULL) scan keys */
+ regular_keys = true;
+ }
- /*
- * For IS NOT NULL, we can only skip ranges that are known to have
- * only nulls.
- */
- if (key->sk_flags & SK_SEARCHNOTNULL)
- PG_RETURN_BOOL(!column->bv_allnulls);
-
- /*
- * Neither IS NULL nor IS NOT NULL was used; assume all indexable
- * operators are strict and return false.
- */
+ /*
+ * If the page range is all nulls, it cannot possibly be consistent if
+ * there are some regular scan keys.
+ */
+ if (column->bv_allnulls && regular_keys)
PG_RETURN_BOOL(false);
+
+ /* If there are no regular keys, the page range is considered consistent. */
+ if (!regular_keys)
+ PG_RETURN_BOOL(true);
+
+ matches = true;
+
+ for (keyno = 0; keyno < nkeys; keyno++)
+ {
+ ScanKey key = keys[keyno];
+
+ /* ignore IS NULL/IS NOT NULL tests handled above */
+ if (key->sk_flags & SK_ISNULL)
+ continue;
+
+ matches = minmax_consistent_key(bdesc, column, key, colloid);
+
+ /* found non-matching key */
+ if (!matches)
+ break;
}
- /* if the range is all empty, it cannot possibly be consistent */
- if (column->bv_allnulls)
- PG_RETURN_BOOL(false);
+ PG_RETURN_DATUM(matches);
+}
+
+static bool
+minmax_consistent_key(BrinDesc *bdesc, BrinValues *column, ScanKey key,
+ Oid colloid)
+{
+ FmgrInfo *finfo;
+ AttrNumber attno = key->sk_attno;
+ Oid subtype = key->sk_subtype;
+ Datum value = key->sk_argument;
+ Datum matches;
- attno = key->sk_attno;
- subtype = key->sk_subtype;
- value = key->sk_argument;
switch (key->sk_strategy)
{
case BTLessStrategyNumber:
@@ -230,7 +284,7 @@ brin_minmax_consistent(PG_FUNCTION_ARGS)
break;
}
- PG_RETURN_DATUM(matches);
+ return DatumGetBool(matches);
}
/*
diff --git a/src/backend/access/brin/brin_validate.c b/src/backend/access/brin/brin_validate.c
index 4222a1781f..257096c615 100644
--- a/src/backend/access/brin/brin_validate.c
+++ b/src/backend/access/brin/brin_validate.c
@@ -98,8 +98,8 @@ brinvalidate(Oid opclassoid)
break;
case BRIN_PROCNUM_CONSISTENT:
ok = check_amproc_signature(procform->amproc, BOOLOID, true,
- 3, 4, INTERNALOID, INTERNALOID,
- INTERNALOID, INTERNALOID);
+ 3, 5, INTERNALOID, INTERNALOID,
+ INTERNALOID, INT4OID, INTERNALOID);
break;
case BRIN_PROCNUM_UNION:
ok = check_amproc_signature(procform->amproc, BOOLOID, true,
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index bc3d08caec..3fb4073367 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -7891,7 +7891,7 @@
prosrc => 'brin_minmax_add_value' },
{ oid => '3385', descr => 'BRIN minmax support',
proname => 'brin_minmax_consistent', prorettype => 'bool',
- proargtypes => 'internal internal internal internal',
+ proargtypes => 'internal internal internal int4 internal',
prosrc => 'brin_minmax_consistent' },
{ oid => '3386', descr => 'BRIN minmax support',
proname => 'brin_minmax_union', prorettype => 'bool',
@@ -7907,7 +7907,7 @@
prosrc => 'brin_inclusion_add_value' },
{ oid => '4107', descr => 'BRIN inclusion support',
proname => 'brin_inclusion_consistent', prorettype => 'bool',
- proargtypes => 'internal internal internal internal',
+ proargtypes => 'internal internal internal int4 internal',
prosrc => 'brin_inclusion_consistent' },
{ oid => '4108', descr => 'BRIN inclusion support',
proname => 'brin_inclusion_union', prorettype => 'bool',
--
2.20.1
--54rc27wh4iahvygf
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename="0007-Move-IS-NOT-NULL-checks-to-bringetbitmap-20190611.patch"
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v12 5/5] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 183 +++++++++------------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 83 insertions(+), 104 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 08d44a1999..4586942960 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- int options, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, int options,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2625,8 +2625,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params->options, CurrentMemoryContext);
}
else
@@ -2961,12 +2961,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_partitions(List *inhoids, int options, List **heaprels)
+leaf_partitions(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -2998,7 +2997,6 @@ leaf_partitions(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3010,13 +3008,11 @@ leaf_partitions(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3070,7 +3066,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_partitions(inhoids, params->options, &heaprels);
+ partitions = leaf_partitions(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3083,7 +3079,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_partitions(partindexes, params->options, &heaprels);
+ partindexes = leaf_partitions(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3092,10 +3088,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3110,7 +3105,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params->options, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params->options, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3262,7 +3257,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3315,14 +3309,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3335,7 +3321,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3386,14 +3372,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3434,70 +3412,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3521,10 +3435,8 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
return false;
}
- Assert(heapRelationIds != NIL);
-
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params->options, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params->options, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3566,9 +3478,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds, int options,
+ReindexIndexesConcurrently(List *indexIds, int options,
MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3586,6 +3499,72 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds, int options,
};
int64 progress_vals[4];
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 4a03ab2abb..fc6afab58a 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--MfFXiAuoTsnnDAfZ--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* [PATCH v13 06/18] More refactoring
@ 2020-11-01 19:46 Justin Pryzby <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Justin Pryzby @ 2020-11-01 19:46 UTC (permalink / raw)
---
src/backend/commands/indexcmds.c | 201 ++++++++++-----------
src/test/regress/expected/create_index.out | 4 +-
2 files changed, 93 insertions(+), 112 deletions(-)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index f5fea14ff4..5c5596cd28 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -102,8 +102,8 @@ static void ReindexMultipleInternal(List *relids,
ReindexParams *params);
static bool ReindexRelationConcurrently(Oid relationOid,
ReindexParams *params);
-static List *ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context);
+static List *ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context);
static void update_relispartition(Oid relationId, bool newval);
static inline void set_indexsafe_procflags(void);
@@ -2652,8 +2652,8 @@ ReindexIndex(RangeVar *indexRelation, ReindexParams *params, bool isTopLevel)
.indexId = indOid,
/* other fields set later */
};
+
ReindexIndexesConcurrently(list_make1(&idxinfo),
- list_make1_oid(IndexGetRelation(indOid, false)),
params, CurrentMemoryContext);
}
else
@@ -3023,12 +3023,11 @@ reindex_error_callback(void *arg)
/*
- * Given a list of index oids, return a list of leaf partitions by removing
- * any intermediate parents. heaprels is populated with the corresponding
- * tables.
+ * Given a list of index oids, return a new list of leaf partitions by
+ * excluding any intermediate parents.
*/
static List *
-leaf_indexes(List *inhoids, int options, List **heaprels)
+leaf_indexes(List *inhoids, int options)
{
List *partitions = NIL;
ListCell *lc;
@@ -3060,7 +3059,6 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
/* Save partition OID in current MemoryContext */
partitions = lappend_oid(partitions, partoid);
- *heaprels = lappend_oid(*heaprels, tableoid);
}
return partitions;
@@ -3072,13 +3070,11 @@ leaf_indexes(List *inhoids, int options, List **heaprels)
*
* Reindex a set of partitions, per the partitioned index or table given
* by the caller.
- * XXX: should be further refactored with logic from ReindexRelationConcurrently
*/
static void
ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
{
- List *partitions = NIL,
- *heaprels = NIL;
+ List *partitions = NIL;
char relkind = get_rel_relkind(relid);
char *relname = get_rel_name(relid);
char *relnamespace = get_namespace_name(get_rel_namespace(relid));
@@ -3132,7 +3128,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
if (relkind == RELKIND_PARTITIONED_INDEX)
{
old_context = MemoryContextSwitchTo(reindex_context);
- partitions = leaf_indexes(inhoids, params->options, &heaprels);
+ partitions = leaf_indexes(inhoids, params->options);
MemoryContextSwitchTo(old_context);
} else {
/* Loop over parent tables */
@@ -3145,7 +3141,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
parttable = table_open(partoid, ShareLock);
old_context = MemoryContextSwitchTo(reindex_context);
partindexes = RelationGetIndexList(parttable);
- partindexes = leaf_indexes(partindexes, params->options, &heaprels);
+ partindexes = leaf_indexes(partindexes, params->options);
partitions = list_concat(partitions, partindexes);
MemoryContextSwitchTo(old_context);
@@ -3154,10 +3150,9 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
}
if ((params->options & REINDEXOPT_CONCURRENTLY) != 0 &&
- relkind == RELKIND_PARTITIONED_INDEX &&
get_rel_persistence(relid) != RELPERSISTENCE_TEMP)
{
- List *idxinfos = NIL;
+ List *idxinfos = NIL;
ReindexIndexInfo *idxinfo;
old_context = MemoryContextSwitchTo(reindex_context);
@@ -3172,7 +3167,7 @@ ReindexPartitions(Oid relid, ReindexParams *params, bool isTopLevel)
MemoryContextSwitchTo(old_context);
/* Process all indexes in a single loop */
- ReindexIndexesConcurrently(idxinfos, heaprels, params, reindex_context);
+ ReindexIndexesConcurrently(idxinfos, params, reindex_context);
} else {
/*
* Process each partition listed in a separate transaction. Note that
@@ -3342,7 +3337,6 @@ ReindexMultipleInternal(List *relids, ReindexParams *params)
static bool
ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
{
- List *heapRelationIds = NIL;
List *indexIds = NIL;
List *newIndexIds = NIL;
ListCell *lc,
@@ -3395,14 +3389,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
*/
Relation heapRelation;
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, relationOid);
-
- MemoryContextSwitchTo(oldcontext);
-
if (IsCatalogRelationOid(relationOid))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -3415,7 +3401,7 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
ShareUpdateExclusiveLock);
/* leave if relation does not exist */
if (!heapRelation)
- break;
+ break; // XXX: lremove
}
else
heapRelation = table_open(relationOid,
@@ -3473,14 +3459,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
Relation toastRelation = table_open(toastOid,
ShareUpdateExclusiveLock);
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track this relation for session locks */
- heapRelationIds = lappend_oid(heapRelationIds, toastOid);
-
- MemoryContextSwitchTo(oldcontext);
-
foreach(lc2, RelationGetIndexList(toastRelation))
{
Oid cellOid = lfirst_oid(lc2);
@@ -3521,78 +3499,6 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
break;
}
case RELKIND_INDEX:
- {
- Oid heapId = IndexGetRelation(relationOid,
- (params->options & REINDEXOPT_MISSING_OK) != 0);
- Relation heapRelation;
- ReindexIndexInfo *idx;
-
- /* if relation is missing, leave */
- if (!OidIsValid(heapId))
- break;
-
- if (IsCatalogRelationOid(heapId))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex system catalogs concurrently")));
-
- /*
- * Don't allow reindex for an invalid index on TOAST table, as
- * if rebuilt it would not be possible to drop it. Match
- * error message in reindex_index().
- */
- if (IsToastNamespace(get_rel_namespace(relationOid)) &&
- !get_index_isvalid(relationOid))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot reindex invalid index on TOAST table")));
-
- /*
- * Check if parent relation can be locked and if it exists,
- * this needs to be done at this stage as the list of indexes
- * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
- * should not be used once all the session locks are taken.
- */
- if ((params->options & REINDEXOPT_MISSING_OK) != 0)
- {
- heapRelation = try_table_open(heapId,
- ShareUpdateExclusiveLock);
- /* leave if relation does not exist */
- if (!heapRelation)
- break;
- }
- else
- heapRelation = table_open(heapId,
- ShareUpdateExclusiveLock);
-
- if (OidIsValid(params->tablespaceOid) &&
- IsSystemRelation(heapRelation))
- ereport(ERROR,
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
- errmsg("cannot move system relation \"%s\"",
- get_rel_name(relationOid))));
-
- table_close(heapRelation, NoLock);
-
- /* Save the list of relation OIDs in private context */
- oldcontext = MemoryContextSwitchTo(private_context);
-
- /* Track the heap relation of this index for session locks */
- heapRelationIds = list_make1_oid(heapId);
-
- /*
- * Save the list of relation OIDs in private context. Note
- * that invalid indexes are allowed here.
- */
- idx = palloc(sizeof(ReindexIndexInfo));
- idx->indexId = relationOid;
- indexIds = lappend(indexIds, idx);
- /* other fields set later */
-
- MemoryContextSwitchTo(oldcontext);
- break;
- }
-
case RELKIND_PARTITIONED_TABLE:
case RELKIND_PARTITIONED_INDEX:
default:
@@ -3623,10 +3529,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
errmsg("cannot move non-shared relation to tablespace \"%s\"",
get_tablespace_name(params->tablespaceOid))));
- Assert(heapRelationIds != NIL);
+ // Assert(heapRelationIds != NIL);
/* Do the work */
- newIndexIds = ReindexIndexesConcurrently(indexIds, heapRelationIds, params, private_context);
+ newIndexIds = ReindexIndexesConcurrently(indexIds, params, private_context);
/* Log what we did */
if ((params->options & REINDEXOPT_VERBOSE) != 0)
@@ -3668,9 +3574,10 @@ ReindexRelationConcurrently(Oid relationOid, ReindexParams *params)
* This is called by ReindexRelationConcurrently and
*/
static List *
-ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
- ReindexParams *params, MemoryContext private_context)
+ReindexIndexesConcurrently(List *indexIds, ReindexParams *params,
+ MemoryContext private_context)
{
+ List *heapRelationIds = NIL;
List *newIndexIds = NIL;
List *relationLocks = NIL;
List *lockTags = NIL;
@@ -3688,6 +3595,80 @@ ReindexIndexesConcurrently(List *indexIds, List *heapRelationIds,
};
int64 progress_vals[4];
+ /* It's not a shared catalog, so refuse to move it to shared tablespace */
+ if (params->tablespaceOid == GLOBALTABLESPACE_OID && false)
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move non-shared relation to tablespace \"%s\"",
+ get_tablespace_name(params->tablespaceOid))));
+
+ foreach(lc, indexIds)
+ {
+ ReindexIndexInfo *idx = lfirst(lc);
+ Oid indexrelid = idx->indexId;
+ Oid heapId = IndexGetRelation(indexrelid,
+ (params->options & REINDEXOPT_MISSING_OK) != 0);
+ Relation heapRelation;
+
+ /* if relation is missing, leave */
+ if (!OidIsValid(heapId))
+ break; // XXX: ldelete?
+
+ if (IsCatalogRelationOid(heapId))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex system catalogs concurrently")));
+
+ /*
+ * Don't allow reindex for an invalid index on TOAST table, as
+ * if rebuilt it would not be possible to drop it. Match
+ * error message in reindex_index().
+ */
+ if (IsToastNamespace(get_rel_namespace(indexrelid)) &&
+ !get_index_isvalid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot reindex invalid index on TOAST table")));
+
+ if (OidIsValid(params->tablespaceOid) &&
+ IsCatalogRelationOid(indexrelid))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("cannot move system relation \"%s\"",
+ get_rel_name(indexrelid))));
+
+ /*
+ * Check if parent relation can be locked and if it exists,
+ * this needs to be done at this stage as the list of indexes
+ * to rebuild is not complete yet, and REINDEXOPT_MISSING_OK
+ * should not be used once all the session locks are taken.
+ */
+ if ((params->options & REINDEXOPT_MISSING_OK) != 0)
+ {
+ heapRelation = try_table_open(heapId,
+ ShareUpdateExclusiveLock);
+ /* leave if relation does not exist */
+ if (!heapRelation)
+ break; // ldelete
+ }
+ else
+ heapRelation = table_open(heapId,
+ ShareUpdateExclusiveLock);
+ table_close(heapRelation, NoLock);
+
+ /* Save the list of relation OIDs in private context */
+ oldcontext = MemoryContextSwitchTo(private_context);
+
+ /* Track the heap relation of this index for session locks */
+ heapRelationIds = lappend_oid(heapRelationIds, heapId);
+ // heapRelationIds = list_make1_oid(heapId);
+
+ /* Note that invalid indexes are allowed here. */
+
+ MemoryContextSwitchTo(oldcontext);
+ // break;
+ }
+
/*-----
* Now we have all the indexes we want to process in indexIds.
*
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 6f41adf736..830fdddf24 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2470,12 +2470,12 @@ COMMIT;
REINDEX TABLE CONCURRENTLY pg_class; -- no catalog relation
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_class_oid_index; -- no catalog index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
-- These are the toast table and index of pg_authid.
REINDEX TABLE CONCURRENTLY pg_toast.pg_toast_1260; -- no catalog toast table
ERROR: cannot reindex system catalogs concurrently
REINDEX INDEX CONCURRENTLY pg_toast.pg_toast_1260_index; -- no catalog toast index
-ERROR: concurrent index creation on system catalog tables is not supported
+ERROR: cannot reindex system catalogs concurrently
REINDEX SYSTEM CONCURRENTLY postgres; -- not allowed for SYSTEM
ERROR: cannot reindex system catalogs concurrently
-- Warns about catalog relations
--
2.17.0
--QTprm0S8XgL7H0Dt--
^ permalink raw reply [nested|flat] 30+ messages in thread
* A new strategy for pull-up correlated ANY_SUBLINK
@ 2022-11-02 03:02 Andy Fan <[email protected]>
0 siblings, 2 replies; 30+ messages in thread
From: Andy Fan @ 2022-11-02 03:02 UTC (permalink / raw)
To: pgsql-hackers
In the past we pull-up the ANY-sublink with 2 steps, the first step is to
pull up the sublink as a subquery, and the next step is to pull up the
subquery if it is allowed. The benefits of this method are obvious,
pulling up the subquery has more requirements, even if we can just finish
the first step, we still get huge benefits. However the bad stuff happens
if varlevelsup = 1 involves, things fail at step 1.
convert_ANY_sublink_to_join ...
if (contain_vars_of_level((Node *) subselect, 1))
return NULL;
In this patch we distinguish the above case and try to pull-up it within
one step if it is helpful, It looks to me that what we need to do is just
transform it to EXIST-SUBLINK.
The only change is transforming the format of SUBLINK, so outer-join /
pull-up as semi-join is unrelated, so the correctness should not be an
issue.
I can help with the following query very much.
master:
explain (costs off, analyze) select * from tenk1 t1
where hundred in (select hundred from tenk2 t2
where t2.odd = t1.odd
and even in (select even from tenk1 t3
where t3.fivethous = t2.fivethous))
and even > 0;
QUERY PLAN
------------------------------------------------------------------------------------
Seq Scan on tenk1 t1 (actual time=0.023..234.955 rows=10000 loops=1)
Filter: ((even > 0) AND (SubPlan 2))
SubPlan 2
-> Seq Scan on tenk2 t2 (actual time=0.023..0.023 rows=1 loops=10000)
Filter: ((odd = t1.odd) AND (SubPlan 1))
Rows Removed by Filter: 94
SubPlan 1
-> Seq Scan on tenk1 t3 (actual time=0.011..0.011 rows=1
loops=10000)
Filter: (fivethous = t2.fivethous)
Rows Removed by Filter: 94
Planning Time: 0.169 ms
Execution Time: 235.488 ms
(12 rows)
patched:
explain (costs off, analyze) select * from tenk1 t1
where hundred in (select hundred from tenk2 t2
where t2.odd = t1.odd
and even in (select even from tenk1 t3
where t3.fivethous = t2.fivethous))
and even > 0;
QUERY PLAN
--------------------------------------------------------------------------------------------------
Hash Join (actual time=13.102..17.676 rows=10000 loops=1)
Hash Cond: ((t1.odd = t2.odd) AND (t1.hundred = t2.hundred))
-> Seq Scan on tenk1 t1 (actual time=0.014..1.702 rows=10000 loops=1)
Filter: (even > 0)
-> Hash (actual time=13.080..13.082 rows=100 loops=1)
Buckets: 1024 Batches: 1 Memory Usage: 12kB
-> HashAggregate (actual time=13.041..13.060 rows=100 loops=1)
Group Key: t2.odd, t2.hundred
Batches: 1 Memory Usage: 73kB
-> Hash Join (actual time=8.044..11.296 rows=10000 loops=1)
Hash Cond: ((t3.fivethous = t2.fivethous) AND (t3.even
= t2.even))
-> HashAggregate (actual time=4.054..4.804 rows=5000
loops=1)
Group Key: t3.fivethous, t3.even
Batches: 1 Memory Usage: 465kB
-> Seq Scan on tenk1 t3 (actual
time=0.002..0.862 rows=10000 loops=1)
-> Hash (actual time=3.962..3.962 rows=10000 loops=1)
Buckets: 16384 Batches: 1 Memory Usage: 597kB
-> Seq Scan on tenk2 t2 (actual
time=0.004..2.289 rows=10000 loops=1)
Planning Time: 0.426 ms
Execution Time: 18.129 ms
(20 rows)
The execution time is 33ms (patched) VS 235ms (master).
The planning time is 0.426ms (patched) VS 0.169ms (master).
I think the extra planning time comes from the search space increasing a
lot and that's where the better plan comes.
I used below queries to measure how much effort we made but got nothing:
run twice in 1 session and just count the second planning time.
explain (costs off, analyze) select * from tenk1 t1
where
(hundred, odd) in (select hundred, odd from tenk2 t2
where (even, fivethous) in
(select even, fivethous from tenk1 t3));
psql regression -f 1.sql | grep 'Planning Time' | tail -1
master:
Planning Time: 0.430 ms
Planning Time: 0.551 ms
Planning Time: 0.316 ms
Planning Time: 0.342 ms
Planning Time: 0.390 ms
patched:
Planning Time: 0.405 ms
Planning Time: 0.406 ms
Planning Time: 0.433 ms
Planning Time: 0.371 ms
Planning Time: 0.425 ms
I think this can show us the extra planning effort is pretty low.
This topic has been raised many times, at least at [1] [2]. and even MySQL
can support some simple but common cases. I think we can do something
helpful as well. Any feedback is welcome.
[1] https://www.postgresql.org/message-id/3691.1342650974%40sss.pgh.pa.us
[2]
https://www.postgresql.org/message-id/[email protected]...
--
Best Regards
Andy Fan
Attachments:
[application/octet-stream] v1-0001-Pull-up-the-direct-correlated-ANY_SUBLINK-like-EX.patch (21.2K, ../../CAKU4AWoZksNZ4VR-fLTdwmiR91WU8qViDBNQKNwY=7iyo+uV0w@mail.gmail.com/3-v1-0001-Pull-up-the-direct-correlated-ANY_SUBLINK-like-EX.patch)
download | inline diff:
From 0ad661728b89725ca28d9bf242c3e5f96a6423fb Mon Sep 17 00:00:00 2001
From: Andy Fan <[email protected]>
Date: Wed, 2 Nov 2022 09:27:21 +0800
Subject: [PATCH v1] Pull-up the direct-correlated ANY_SUBLINK like
EXISTS_SUBLINK
In the past we pull-up the ANY-sublink with 2 steps, the first step is to
pull up the sublink as a subquery, and the next step is to pull up the
subquery if it is allowed. The benefits of this method are obvious,
pulling up the subquery has more requirements, even if we can just finish
the first step, we still get huge benefits. However the bad stuff happens
if varlevelsup = 1 involves, things failed at step 1.
In this patch we distinguish the above case and transform it to
EXIST-SUBLINK with the essential checks, then the pull-up can be done
within 1 step.
---
src/backend/optimizer/prep/prepjointree.c | 291 ++++++++++++++++++++++
src/backend/utils/misc/guc_tables.c | 12 +
src/test/regress/expected/join.out | 35 +--
src/test/regress/expected/subselect.out | 121 +++++++++
src/test/regress/expected/sysviews.out | 3 +-
src/test/regress/sql/subselect.sql | 61 +++++
6 files changed, 505 insertions(+), 18 deletions(-)
diff --git a/src/backend/optimizer/prep/prepjointree.c b/src/backend/optimizer/prep/prepjointree.c
index 41c7066d90a..a8470be1c20 100644
--- a/src/backend/optimizer/prep/prepjointree.c
+++ b/src/backend/optimizer/prep/prepjointree.c
@@ -130,6 +130,7 @@ static void substitute_phv_relids(Node *node,
static void fix_append_rel_relids(List *append_rel_list, int varno,
Relids subrelids);
static Node *find_jointree_node_for_rel(Node *jtnode, int relid);
+static void transform_IN_sublink_to_EXIST_recurse(PlannerInfo *root, Node *jtnode);
/*
@@ -256,6 +257,291 @@ replace_empty_jointree(Query *parse)
parse->jointree->fromlist = list_make1(rtr);
}
+
+/*
+ * sublink_should_be_transformed
+ *
+ * Check if the sublink is a simple IN sublink.
+ */
+static bool
+sublink_should_be_transformed(PlannerInfo *root, SubLink *sublink)
+{
+ const char * operName;
+ Query *subselect = (Query *) sublink->subselect;
+ Node *whereClause;
+
+ if (sublink->subLinkType != ANY_SUBLINK || list_length(sublink->operName) != 1)
+ return false;
+
+ operName = linitial_node(String, sublink->operName)->sval;
+
+ if (strcmp(operName, "=") != 0)
+ return false;
+
+ if (!contain_vars_of_level((Node *) subselect, 1))
+ /* The existing framework can handle it well, so no action needed. */
+ return false;
+
+ if (list_length(subselect->rtable) == 0)
+ /* Get rid of this special cases for safety. */
+ return false;
+
+ /*
+ * The below checks are similar with the checks in convert_EXISTS_sublink_to_join
+ * so that that the new EXISTS-Sublink can be pull-up later.
+ */
+ if (subselect->cteList)
+ return false;
+
+ /* See simplify_EXISTS_query */
+
+ if (subselect->commandType != CMD_SELECT ||
+ subselect->setOperations ||
+ subselect->hasAggs ||
+ subselect->groupingSets ||
+ subselect->hasWindowFuncs ||
+ subselect->hasTargetSRFs ||
+ subselect->hasModifyingCTE ||
+ subselect->havingQual ||
+ subselect->limitOffset ||
+ subselect->rowMarks)
+ return false;
+
+ if (subselect->limitCount)
+ {
+ /*
+ * The LIMIT clause has not yet been through eval_const_expressions,
+ * so we have to apply that here. It might seem like this is a waste
+ * of cycles, since the only case plausibly worth worrying about is
+ * "LIMIT 1" ... but what we'll actually see is "LIMIT int8(1::int4)",
+ * so we have to fold constants or we're not going to recognize it.
+ */
+ Node *node = eval_const_expressions(root, subselect->limitCount);
+ Const *limit;
+
+ /* Might as well update the query if we simplified the clause. */
+
+ /* XXX: we do have the modification, but it is not harmful. */
+ subselect->limitCount = node;
+
+ if (!IsA(node, Const))
+ return false;
+
+ limit = (Const *) node;
+ Assert(limit->consttype == INT8OID);
+ if (!limit->constisnull && DatumGetInt64(limit->constvalue) <= 0)
+ return false;
+ }
+
+ whereClause = subselect->jointree->quals;
+ subselect->jointree->quals = NULL;
+
+ if (contain_vars_of_level((Node *) subselect, 1) ||
+ !contain_vars_of_level(whereClause, 1) ||
+ contain_volatile_functions(whereClause))
+ {
+ subselect->jointree->quals = whereClause;
+ return false;
+ }
+
+ /* Restore the whereClause. */
+ subselect->jointree->quals = whereClause;
+
+ /*
+ * No need to check the avaiable_rels like convert_EXISTS_sublink_to_join
+ * since here we just transform the sublinks type, no SEMIJOIN related.
+ */
+ return true;
+}
+
+/*
+ * replace_param_sublink_node
+ *
+ * Replace the PARAM_SUBLINK in src with target.
+ */
+static Node *
+replace_param_sublink_node(Node *src, Node *target)
+{
+
+ if (IsA(src, Param))
+ return target;
+
+ switch (nodeTag(src))
+ {
+ case T_RelabelType:
+ {
+ RelabelType *rtype = castNode(RelabelType, src);
+ rtype->arg = (Expr *)target;
+ break;
+ }
+ case T_FuncExpr:
+ {
+ FuncExpr *fexpr = castNode(FuncExpr, src);
+ Assert(list_length(fexpr->args));
+ Assert(linitial_node(Param, fexpr->args)->paramkind == PARAM_SUBLINK);
+ linitial(fexpr->args) = target;
+ break;
+ }
+ default:
+ {
+ Assert(false);
+ elog(ERROR, "Unexpected node type: %d", nodeTag(src));
+ }
+ }
+
+ /* src is in-placed updated. */
+ return src;
+
+}
+
+/*
+ * transform_IN_sublink_to_EXIST_qual_recurse
+ *
+ * Transform IN-SUBLINK with level-1 var to EXISTS-SUBLINK recursly.
+ */
+static Node *
+transform_IN_sublink_to_EXIST_qual_recurse(PlannerInfo *root, Node *node)
+{
+ if (node == NULL)
+ return NULL;
+
+ if (IsA(node, SubLink))
+ {
+ SubLink *sublink = (SubLink *) node;
+ Query *subselect = (Query *)sublink->subselect;
+ FromExpr *sub_fromexpr;
+
+ Assert(IsA(subselect, Query));
+
+ if (!sublink_should_be_transformed(root, sublink))
+ {
+ /* We still need to transform the subselect->jointree. */
+ transform_IN_sublink_to_EXIST_recurse(root, (Node *) subselect->jointree);
+ return node;
+ }
+
+ /*
+ * Make up the push-downed node from sublink->testexpr, the testexpr
+ * will be set to NULL later, so in-place update would be OK.
+ */
+ IncrementVarSublevelsUp(sublink->testexpr, 1, 0);
+
+ if (is_andclause(sublink->testexpr))
+ {
+ BoolExpr *and_expr = castNode(BoolExpr, sublink->testexpr);
+ ListCell *l1, *l2;
+ forboth(l1, and_expr->args, l2, subselect->targetList)
+ {
+ OpExpr *opexpr = lfirst_node(OpExpr, l1);
+ TargetEntry *tle = lfirst_node(TargetEntry, l2);
+ lsecond(opexpr->args) = replace_param_sublink_node(lsecond(opexpr->args),
+ (Node *) tle->expr);
+ }
+ }
+ else
+ {
+ OpExpr *opexpr = (OpExpr *) sublink->testexpr;
+ TargetEntry *tle = linitial_node(TargetEntry, subselect->targetList);
+ Assert(IsA(sublink->testexpr, OpExpr));
+ lsecond(opexpr->args) = replace_param_sublink_node(lsecond(opexpr->args),
+ (Node *) tle->expr);
+ }
+
+ /* Push down the transformed testexpr into subselect */
+ sub_fromexpr = subselect->jointree;
+ if (sub_fromexpr->quals == NULL)
+ sub_fromexpr->quals = sublink->testexpr;
+ else
+ sub_fromexpr->quals = make_and_qual(sub_fromexpr->quals,
+ (Node *) sublink->testexpr);
+
+ /*
+ * Turn the IN-Sublink to exist-SUBLINK for the parent query.
+ * sublink->subselect has already been modified.
+ */
+ sublink->subLinkType = EXISTS_SUBLINK;
+ sublink->operName = NIL;
+ sublink->testexpr = NULL;
+
+ /* Now transform the FromExpr in the subselect->jointree. */
+ transform_IN_sublink_to_EXIST_recurse(root, (Node *)sub_fromexpr);
+ return node;
+ }
+
+ if (is_andclause(node))
+ {
+ List *newclauses = NIL;
+ ListCell *l;
+ foreach(l, ((BoolExpr *) node)->args)
+ {
+ Node *oldclause = (Node *) lfirst(l);
+ Node *newclause;
+
+ newclause = transform_IN_sublink_to_EXIST_qual_recurse(root, oldclause);
+ newclauses = lappend(newclauses, newclause);
+ }
+
+ if (newclauses == NIL)
+ return NULL;
+ else if (list_length(newclauses) == 1)
+ return (Node *) linitial(newclauses);
+ else
+ return (Node *) make_andclause(newclauses);
+ }
+ else if (is_notclause(node))
+ {
+ /*
+ * NOT-IN can't be converted into NOT-exists.
+ */
+ return node;
+ }
+
+ return node;
+}
+
+/*
+ * transform_IN_sublink_to_EXIST_recurse
+ *
+ * Transform IN sublink to EXIST sublink if it benefits for sublink
+ * pull-ups.
+ */
+extern bool enable_geqo;
+static void
+transform_IN_sublink_to_EXIST_recurse(PlannerInfo *root, Node *jtnode)
+{
+ if (!enable_geqo)
+ return;
+
+ if (jtnode == NULL || IsA(jtnode, RangeTblRef))
+ {
+ return;
+ }
+ else if (IsA(jtnode, FromExpr))
+ {
+ FromExpr *f = (FromExpr *) jtnode;
+ ListCell *l;
+ foreach(l, f->fromlist)
+ {
+ transform_IN_sublink_to_EXIST_recurse(root, lfirst(l));
+ }
+ f->quals = transform_IN_sublink_to_EXIST_qual_recurse(root, f->quals);
+ }
+ else if (IsA(jtnode, JoinExpr))
+ {
+ JoinExpr *j = (JoinExpr *) jtnode;
+ transform_IN_sublink_to_EXIST_recurse(root, j->larg);
+ transform_IN_sublink_to_EXIST_recurse(root, j->rarg);
+
+ j->quals = transform_IN_sublink_to_EXIST_qual_recurse(root, j->quals);
+ }
+ else
+ {
+ elog(ERROR, "unrecognized node type: %d",
+ (int) nodeTag(jtnode));
+ }
+}
+
+
/*
* pull_up_sublinks
* Attempt to pull up ANY and EXISTS SubLinks to be treated as
@@ -284,12 +570,17 @@ replace_empty_jointree(Query *parse)
* to be AND/OR-flat either. That means we need to recursively search through
* explicit AND clauses. We stop as soon as we hit a non-AND item.
*/
+extern bool enable_in_exists_transfrom;
void
pull_up_sublinks(PlannerInfo *root)
{
Node *jtnode;
Relids relids;
+ if (enable_in_exists_transfrom)
+ transform_IN_sublink_to_EXIST_recurse(root,
+ (Node *)root->parse->jointree);
+
/* Begin recursion through the jointree */
jtnode = pull_up_sublinks_jointree_recurse(root,
(Node *) root->parse->jointree,
diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c
index 05ab087934c..c6c7d874a3b 100644
--- a/src/backend/utils/misc/guc_tables.c
+++ b/src/backend/utils/misc/guc_tables.c
@@ -763,8 +763,20 @@ StaticAssertDecl(lengthof(config_type_names) == (PGC_ENUM + 1),
* variable_is_guc_list_quote() in src/bin/pg_dump/dumputils.c.
*/
+bool enable_in_exists_transfrom = false;
+
struct config_bool ConfigureNamesBool[] =
{
+ {
+ {"enable_in_exists_transfrom", PGC_USERSET, QUERY_TUNING_METHOD,
+ gettext_noop("Enables the transform from in to exists."),
+ NULL,
+ GUC_EXPLAIN
+ },
+ &enable_in_exists_transfrom,
+ true,
+ NULL, NULL, NULL
+ },
{
{"enable_seqscan", PGC_USERSET, QUERY_TUNING_METHOD,
gettext_noop("Enables the planner's use of sequential-scan plans."),
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index 08334761ae6..6d5ccb7de2f 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -5983,8 +5983,8 @@ lateral (select * from int8_tbl t1,
where q2 = (select greatest(t1.q1,t2.q2))
and (select v.id=0)) offset 0) ss2) ss
where t1.q1 = ss.q2) ss0;
- QUERY PLAN
------------------------------------------------------------------
+ QUERY PLAN
+---------------------------------------------------------------------
Nested Loop
Output: "*VALUES*".column1, t1.q1, t1.q2, ss2.q1, ss2.q2
-> Seq Scan on public.int8_tbl t1
@@ -5996,23 +5996,24 @@ lateral (select * from int8_tbl t1,
-> Subquery Scan on ss2
Output: ss2.q1, ss2.q2
Filter: (t1.q1 = ss2.q2)
- -> Seq Scan on public.int8_tbl t2
+ -> Result
Output: t2.q1, t2.q2
- Filter: (SubPlan 3)
- SubPlan 3
+ One-Time Filter: $3
+ InitPlan 2 (returns $3)
-> Result
- Output: t3.q2
- One-Time Filter: $4
- InitPlan 1 (returns $2)
- -> Result
- Output: GREATEST($0, t2.q2)
- InitPlan 2 (returns $4)
- -> Result
- Output: ($3 = 0)
- -> Seq Scan on public.int8_tbl t3
- Output: t3.q1, t3.q2
- Filter: (t3.q2 = $2)
-(27 rows)
+ Output: ($2 = 0)
+ -> Nested Loop Semi Join
+ Output: t2.q1, t2.q2
+ Join Filter: (t2.q1 = t3.q2)
+ -> Seq Scan on public.int8_tbl t2
+ Output: t2.q1, t2.q2
+ Filter: ((SubPlan 1) = t2.q1)
+ SubPlan 1
+ -> Result
+ Output: GREATEST($0, t2.q2)
+ -> Seq Scan on public.int8_tbl t3
+ Output: t3.q1, t3.q2
+(28 rows)
select * from (values (0), (1)) v(id),
lateral (select * from int8_tbl t1,
diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out
index 63d26d44fc3..5e0ce397233 100644
--- a/src/test/regress/expected/subselect.out
+++ b/src/test/regress/expected/subselect.out
@@ -1926,3 +1926,124 @@ select * from x for update;
Output: subselect_tbl.f1, subselect_tbl.f2, subselect_tbl.f3
(2 rows)
+-- Test transform the level-1 in-sublink to existing sublink.
+create temp table temp_t1 (a int, b int, c int) on commit delete rows;
+create temp table temp_t2 (a int, b int, c int) on commit delete rows;
+create temp table temp_t3 (a int, b int, c int) on commit delete rows;
+create temp table temp_t4 (a int, b int, c int, d int) on commit delete rows;
+begin;
+insert into temp_t1 values (1, 1, 1), (2, 2, null), (3, null, null);
+insert into temp_t2 values (1, 1, 1), (2, 2, null), (3, null, null);
+insert into temp_t3 values (1, 1, 1), (2, 2, null), (3, null, null);
+insert into temp_t4 values (1, 1, 1, 1), (2, 2, null, null), (3, null, null, null);
+analyze temp_t1;
+analyze temp_t2;
+analyze temp_t3;
+-- one-elem in subquery
+select * from temp_t1 t1 where a in (select a from temp_t2 t2 where t2.b > t1.b);
+ a | b | c
+---+---+---
+(0 rows)
+
+explain (costs off)
+select * from temp_t1 t1 where a in (select a from temp_t2 t2 where t2.b > t1.b);
+ QUERY PLAN
+------------------------------------
+ Hash Semi Join
+ Hash Cond: (t1.a = t2.a)
+ Join Filter: (t2.b > t1.b)
+ -> Seq Scan on temp_t1 t1
+ -> Hash
+ -> Seq Scan on temp_t2 t2
+(6 rows)
+
+-- two-elem in subquery
+select * from temp_t1 t1 where (a, b) in (select a, b from temp_t2 t2 where t2.c = t1.c);
+ a | b | c
+---+---+---
+ 1 | 1 | 1
+(1 row)
+
+explain (costs off)
+select * from temp_t1 t1 where (a, b) in (select a, b from temp_t2 t2 where t2.c = t1.c);
+ QUERY PLAN
+------------------------------------------------------------------
+ Hash Semi Join
+ Hash Cond: ((t1.c = t2.c) AND (t1.a = t2.a) AND (t1.b = t2.b))
+ -> Seq Scan on temp_t1 t1
+ -> Hash
+ -> Seq Scan on temp_t2 t2
+(5 rows)
+
+-- sublink in sublink
+select * from temp_t1 t1
+where (a, b) in (select a, b from temp_t2 t2
+ where t2.c < t1.c
+ and t2.c in (select c from temp_t3 t3 where t3.b = t2.b));
+ a | b | c
+---+---+---
+(0 rows)
+
+explain (costs off)
+select * from temp_t1 t1
+where (a, b) in (select a, b from temp_t2 t2
+ where t2.c < t1.c
+ and t2.c in (select c from temp_t3 t3 where t3.b = t2.b));
+ QUERY PLAN
+--------------------------------------------------------------------
+ Nested Loop Semi Join
+ Join Filter: ((t2.c < t1.c) AND (t1.b = t3.b) AND (t1.a = t2.a))
+ -> Seq Scan on temp_t1 t1
+ -> Materialize
+ -> Hash Semi Join
+ Hash Cond: ((t2.b = t3.b) AND (t2.c = t3.c))
+ -> Seq Scan on temp_t2 t2
+ -> Hash
+ -> Seq Scan on temp_t3 t3
+(9 rows)
+
+-- sublink in not-in sublinks. not in will not be transformed but the in-clause
+-- in the subselect should be transformed.
+explain (costs off)
+select * from temp_t1 t1
+where (a, b) not in (select a, b from temp_t2 t2
+ where t2.c < t1.c
+ and t1.c in (SELECT c from temp_t3 t3 where t3.b = t2.b ))
+and c > 3;
+ QUERY PLAN
+-------------------------------------------
+ Seq Scan on temp_t1 t1
+ Filter: ((c > 3) AND (NOT (SubPlan 1)))
+ SubPlan 1
+ -> Nested Loop Semi Join
+ Join Filter: (t2.b = t3.b)
+ -> Seq Scan on temp_t2 t2
+ Filter: (c < t1.c)
+ -> Seq Scan on temp_t3 t3
+ Filter: (t1.c = c)
+(9 rows)
+
+-- The clause in the ON-clause should be transformed.
+explain (costs off)
+select * from temp_t1 t1, (temp_t2 t2 join temp_t4 t4
+ on t2.a in (select a from temp_t3 t3 where t4.b = t3.b)) v
+where t1.a = v.d;
+ QUERY PLAN
+------------------------------------------------------
+ Nested Loop
+ Join Filter: (t3.a = t2.a)
+ -> Hash Join
+ Hash Cond: (t4.d = t1.a)
+ -> Hash Join
+ Hash Cond: (t4.b = t3.b)
+ -> Seq Scan on temp_t4 t4
+ -> Hash
+ -> HashAggregate
+ Group Key: t3.b, t3.a
+ -> Seq Scan on temp_t3 t3
+ -> Hash
+ -> Seq Scan on temp_t1 t1
+ -> Seq Scan on temp_t2 t2
+(14 rows)
+
+commit;
diff --git a/src/test/regress/expected/sysviews.out b/src/test/regress/expected/sysviews.out
index 579b861d84f..c897429531c 100644
--- a/src/test/regress/expected/sysviews.out
+++ b/src/test/regress/expected/sysviews.out
@@ -116,6 +116,7 @@ select name, setting from pg_settings where name like 'enable%';
enable_gathermerge | on
enable_hashagg | on
enable_hashjoin | on
+ enable_in_exists_transfrom | on
enable_incremental_sort | on
enable_indexonlyscan | on
enable_indexscan | on
@@ -131,7 +132,7 @@ select name, setting from pg_settings where name like 'enable%';
enable_seqscan | on
enable_sort | on
enable_tidscan | on
-(20 rows)
+(21 rows)
-- Test that the pg_timezone_names and pg_timezone_abbrevs views are
-- more-or-less working. We can't test their contents in any great detail
diff --git a/src/test/regress/sql/subselect.sql b/src/test/regress/sql/subselect.sql
index 40276708c99..83ad18cf9b1 100644
--- a/src/test/regress/sql/subselect.sql
+++ b/src/test/regress/sql/subselect.sql
@@ -968,3 +968,64 @@ select * from (with x as (select 2 as y) select * from x) ss;
explain (verbose, costs off)
with x as (select * from subselect_tbl)
select * from x for update;
+
+
+-- Test transform the level-1 in-sublink to existing sublink.
+create temp table temp_t1 (a int, b int, c int) on commit delete rows;
+create temp table temp_t2 (a int, b int, c int) on commit delete rows;
+create temp table temp_t3 (a int, b int, c int) on commit delete rows;
+create temp table temp_t4 (a int, b int, c int, d int) on commit delete rows;
+
+begin;
+insert into temp_t1 values (1, 1, 1), (2, 2, null), (3, null, null);
+insert into temp_t2 values (1, 1, 1), (2, 2, null), (3, null, null);
+insert into temp_t3 values (1, 1, 1), (2, 2, null), (3, null, null);
+insert into temp_t4 values (1, 1, 1, 1), (2, 2, null, null), (3, null, null, null);
+
+analyze temp_t1;
+analyze temp_t2;
+analyze temp_t3;
+
+-- one-elem in subquery
+select * from temp_t1 t1 where a in (select a from temp_t2 t2 where t2.b > t1.b);
+explain (costs off)
+select * from temp_t1 t1 where a in (select a from temp_t2 t2 where t2.b > t1.b);
+
+-- two-elem in subquery
+select * from temp_t1 t1 where (a, b) in (select a, b from temp_t2 t2 where t2.c = t1.c);
+explain (costs off)
+select * from temp_t1 t1 where (a, b) in (select a, b from temp_t2 t2 where t2.c = t1.c);
+
+-- sublink in sublink
+select * from temp_t1 t1
+where (a, b) in (select a, b from temp_t2 t2
+ where t2.c < t1.c
+ and t2.c in (select c from temp_t3 t3 where t3.b = t2.b));
+explain (costs off)
+select * from temp_t1 t1
+where (a, b) in (select a, b from temp_t2 t2
+ where t2.c < t1.c
+ and t2.c in (select c from temp_t3 t3 where t3.b = t2.b));
+
+
+-- sublink in not-in sublinks. not in will not be transformed but the in-clause
+-- in the subselect should be transformed.
+explain (costs off)
+select * from temp_t1 t1
+where (a, b) not in (select a, b from temp_t2 t2
+ where t2.c < t1.c
+ and t1.c in (SELECT c from temp_t3 t3 where t3.b = t2.b ))
+and c > 3;
+
+
+-- The clause in the ON-clause should be transformed.
+explain (costs off)
+select * from temp_t1 t1, (temp_t2 t2 join temp_t4 t4
+ on t2.a in (select a from temp_t3 t3 where t4.b = t3.b)) v
+where t1.a = v.d;
+
+commit;
+
+
+
+
--
2.21.0
^ permalink raw reply [nested|flat] 30+ messages in thread
* Re: A new strategy for pull-up correlated ANY_SUBLINK
@ 2022-11-02 03:42 Andrey Lepikhov <[email protected]>
parent: Andy Fan <[email protected]>
1 sibling, 1 reply; 30+ messages in thread
From: Andrey Lepikhov @ 2022-11-02 03:42 UTC (permalink / raw)
To: Andy Fan <[email protected]>; pgsql-hackers
On 2/11/2022 09:02, Andy Fan wrote:
> In the past we pull-up the ANY-sublink with 2 steps, the first step is to
> pull up the sublink as a subquery, and the next step is to pull up the
> subquery if it is allowed. The benefits of this method are obvious,
> pulling up the subquery has more requirements, even if we can just finish
> the first step, we still get huge benefits. However the bad stuff happens
> if varlevelsup = 1 involves, things fail at step 1.
>
> convert_ANY_sublink_to_join ...
>
> if (contain_vars_of_level((Node *) subselect, 1))
> return NULL;
>
> In this patch we distinguish the above case and try to pull-up it within
> one step if it is helpful, It looks to me that what we need to do is just
> transform it to EXIST-SUBLINK.
Maybe code [1] would be useful for your purposes/tests.
We implemented flattening of correlated subqueries for simple N-J case,
but found out that in some cases the flattening isn't obvious the best
solution - we haven't info about cardinality/cost estimations and can do
worse.
I guess, for more complex flattening procedure (with aggregate function
in a targetlist of correlated subquery) situation can be even worse.
Maybe your idea has such corner cases too ?
[1]
https://www.postgresql.org/message-id/flat/CALNJ-vTa5VgvV1NPRHnypdnbx-fhDu7vWp73EkMUbZRpNHTYQQ%40mai...
--
regards,
Andrey Lepikhov
Postgres Professional
^ permalink raw reply [nested|flat] 30+ messages in thread
* Re: A new strategy for pull-up correlated ANY_SUBLINK
@ 2022-11-02 05:34 Andy Fan <[email protected]>
parent: Andrey Lepikhov <[email protected]>
0 siblings, 0 replies; 30+ messages in thread
From: Andy Fan @ 2022-11-02 05:34 UTC (permalink / raw)
To: Andrey Lepikhov <[email protected]>; +Cc: pgsql-hackers
Hi Andrey:
> > In this patch we distinguish the above case and try to pull-up it within
> > one step if it is helpful, It looks to me that what we need to do is just
> > transform it to EXIST-SUBLINK.
> Maybe code [1] would be useful for your purposes/tests.
>
Looks like we are resolving the same problem, IIUC, great that more
people are interested in it!
We implemented flattening of correlated subqueries for simple N-J case,
I went through the code, and it looks like you tried to do the pull-up by
yourself, which would have many troubles to think about. but I just
transformed
it into EXIST sublink after I distinguish it as the case I can improve.
> The only change is transforming the format of SUBLINK, so outer-join /
> pull-up as semi-join is unrelated, so the correctness should not be an
> issue.
That is just a difference, no matter which one is better.
but found out that in some cases the flattening isn't obvious the best
> solution - we haven't info about cardinality/cost estimations and can do
> worse.
I guess, for more complex flattening procedure (with aggregate function
> in a targetlist of correlated subquery) situation can be even worse.
> Maybe your idea has such corner cases too ?
>
In my case, since aggregate function can't be handled by
covert_EXISTS_sublink_to_join, so it is not the target I want to optimize in
this patch. More testing/review on my method would be pretty appreciated.
but I'm not insisting on my method at all. Link [2] might be useful as
well.
[2]
https://www.postgresql.org/message-id/CAKU4AWpi9oztiomUQt4JCxXEr6EaQ2thY-7JYDm6c9he0A7oCA%40mail.gma...
--
Best Regards
Andy Fan
^ permalink raw reply [nested|flat] 30+ messages in thread
* Re: A new strategy for pull-up correlated ANY_SUBLINK
@ 2022-11-12 22:45 Tom Lane <[email protected]>
parent: Andy Fan <[email protected]>
1 sibling, 2 replies; 30+ messages in thread
From: Tom Lane @ 2022-11-12 22:45 UTC (permalink / raw)
To: Andy Fan <[email protected]>; +Cc: pgsql-hackers
Andy Fan <[email protected]> writes:
> In the past we pull-up the ANY-sublink with 2 steps, the first step is to
> pull up the sublink as a subquery, and the next step is to pull up the
> subquery if it is allowed. The benefits of this method are obvious,
> pulling up the subquery has more requirements, even if we can just finish
> the first step, we still get huge benefits. However the bad stuff happens
> if varlevelsup = 1 involves, things fail at step 1.
> convert_ANY_sublink_to_join ...
> if (contain_vars_of_level((Node *) subselect, 1))
> return NULL;
> In this patch we distinguish the above case and try to pull-up it within
> one step if it is helpful, It looks to me that what we need to do is just
> transform it to EXIST-SUBLINK.
This patch seems awfully messy to me. The fact that you're having to
duplicate stuff done elsewhere suggests at the least that you've not
plugged the code into the best place.
Looking again at that contain_vars_of_level restriction, I think the
reason for it was just to avoid making a FROM subquery that has outer
references, and the reason we needed to avoid that was merely that we
didn't have LATERAL at the time. So I experimented with the attached.
It seems to work, in that we don't get wrong answers from any of the
small number of places that are affected. (I wonder though whether
those test cases still test what they were intended to, particularly
the postgres_fdw one. We might have to try to hack them some more
to not get affected by this optimization.) Could do with more test
cases, no doubt.
One thing I'm not at all clear about is whether we need to restrict
the optimization so that it doesn't occur if the subquery contains
outer references falling outside available_rels. I think that that
case is covered by is_simple_subquery() deciding later to not pull up
the subquery based on LATERAL restrictions, but maybe that misses
something.
I'm also wondering whether the similar restriction in
convert_EXISTS_sublink_to_join could be removed similarly.
In this light it was a mistake for convert_EXISTS_sublink_to_join
to manage the pullup itself rather than doing it in the two-step
fashion that convert_ANY_sublink_to_join does it.
regards, tom lane
Attachments:
[text/x-diff] v2-0001-use-LATERAL-for-ANY_SUBLINK.patch (6.9K, ../../[email protected]/2-v2-0001-use-LATERAL-for-ANY_SUBLINK.patch)
download | inline diff:
diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out
index 558e94b845..c07280d836 100644
--- a/contrib/postgres_fdw/expected/postgres_fdw.out
+++ b/contrib/postgres_fdw/expected/postgres_fdw.out
@@ -11377,19 +11377,19 @@ CREATE FOREIGN TABLE foreign_tbl2 () INHERITS (foreign_tbl)
SERVER loopback OPTIONS (table_name 'base_tbl');
EXPLAIN (VERBOSE, COSTS OFF)
SELECT a FROM base_tbl WHERE a IN (SELECT a FROM foreign_tbl);
- QUERY PLAN
------------------------------------------------------------------------------
- Seq Scan on public.base_tbl
+ QUERY PLAN
+---------------------------------------------------------------------------
+ Nested Loop Semi Join
Output: base_tbl.a
- Filter: (SubPlan 1)
- SubPlan 1
- -> Result
- Output: base_tbl.a
- -> Append
- -> Async Foreign Scan on public.foreign_tbl foreign_tbl_1
- Remote SQL: SELECT NULL FROM public.base_tbl
- -> Async Foreign Scan on public.foreign_tbl2 foreign_tbl_2
- Remote SQL: SELECT NULL FROM public.base_tbl
+ -> Seq Scan on public.base_tbl
+ Output: base_tbl.a, base_tbl.b
+ Filter: (base_tbl.a IS NOT NULL)
+ -> Materialize
+ -> Append
+ -> Async Foreign Scan on public.foreign_tbl foreign_tbl_1
+ Remote SQL: SELECT NULL FROM public.base_tbl
+ -> Async Foreign Scan on public.foreign_tbl2 foreign_tbl_2
+ Remote SQL: SELECT NULL FROM public.base_tbl
(11 rows)
SELECT a FROM base_tbl WHERE a IN (SELECT a FROM foreign_tbl);
diff --git a/src/backend/optimizer/plan/subselect.c b/src/backend/optimizer/plan/subselect.c
index 92e3338584..3d4645a154 100644
--- a/src/backend/optimizer/plan/subselect.c
+++ b/src/backend/optimizer/plan/subselect.c
@@ -1271,6 +1271,7 @@ convert_ANY_sublink_to_join(PlannerInfo *root, SubLink *sublink,
JoinExpr *result;
Query *parse = root->parse;
Query *subselect = (Query *) sublink->subselect;
+ bool has_level_1_vars;
Relids upper_varnos;
int rtindex;
ParseNamespaceItem *nsitem;
@@ -1283,11 +1284,10 @@ convert_ANY_sublink_to_join(PlannerInfo *root, SubLink *sublink,
Assert(sublink->subLinkType == ANY_SUBLINK);
/*
- * The sub-select must not refer to any Vars of the parent query. (Vars of
- * higher levels should be okay, though.)
+ * If the sub-select refers to any Vars of the parent query, we have to
+ * treat it as LATERAL. (Vars of higher levels don't matter here.)
*/
- if (contain_vars_of_level((Node *) subselect, 1))
- return NULL;
+ has_level_1_vars = contain_vars_of_level((Node *) subselect, 1);
/*
* The test expression must contain some Vars of the parent query, else
@@ -1324,7 +1324,7 @@ convert_ANY_sublink_to_join(PlannerInfo *root, SubLink *sublink,
nsitem = addRangeTableEntryForSubquery(pstate,
subselect,
makeAlias("ANY_subquery", NIL),
- false,
+ has_level_1_vars,
false);
rte = nsitem->p_rte;
parse->rtable = lappend(parse->rtable, rte);
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index 9358371072..cdaedb92b2 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -4657,17 +4657,17 @@ explain (costs off)
select a.unique1, b.unique2
from onek a left join onek b on a.unique1 = b.unique2
where b.unique2 = any (select q1 from int8_tbl c where c.q1 < b.unique1);
- QUERY PLAN
-----------------------------------------------------------
- Hash Join
- Hash Cond: (b.unique2 = a.unique1)
- -> Seq Scan on onek b
- Filter: (SubPlan 1)
- SubPlan 1
- -> Seq Scan on int8_tbl c
- Filter: (q1 < b.unique1)
- -> Hash
- -> Index Only Scan using onek_unique1 on onek a
+ QUERY PLAN
+----------------------------------------------------
+ Nested Loop
+ -> Hash Semi Join
+ Hash Cond: (b.unique2 = c.q1)
+ Join Filter: (c.q1 < b.unique1)
+ -> Seq Scan on onek b
+ -> Hash
+ -> Seq Scan on int8_tbl c
+ -> Index Only Scan using onek_unique1 on onek a
+ Index Cond: (unique1 = b.unique2)
(9 rows)
select a.unique1, b.unique2
@@ -6074,8 +6074,8 @@ lateral (select * from int8_tbl t1,
where q2 = (select greatest(t1.q1,t2.q2))
and (select v.id=0)) offset 0) ss2) ss
where t1.q1 = ss.q2) ss0;
- QUERY PLAN
------------------------------------------------------------------
+ QUERY PLAN
+---------------------------------------------------------------------
Nested Loop
Output: "*VALUES*".column1, t1.q1, t1.q2, ss2.q1, ss2.q2
-> Seq Scan on public.int8_tbl t1
@@ -6087,23 +6087,24 @@ lateral (select * from int8_tbl t1,
-> Subquery Scan on ss2
Output: ss2.q1, ss2.q2
Filter: (t1.q1 = ss2.q2)
- -> Seq Scan on public.int8_tbl t2
+ -> Result
Output: t2.q1, t2.q2
- Filter: (SubPlan 3)
- SubPlan 3
+ One-Time Filter: $3
+ InitPlan 2 (returns $3)
-> Result
- Output: t3.q2
- One-Time Filter: $4
- InitPlan 1 (returns $2)
- -> Result
- Output: GREATEST($0, t2.q2)
- InitPlan 2 (returns $4)
- -> Result
- Output: ($3 = 0)
- -> Seq Scan on public.int8_tbl t3
- Output: t3.q1, t3.q2
- Filter: (t3.q2 = $2)
-(27 rows)
+ Output: ($2 = 0)
+ -> Nested Loop Semi Join
+ Output: t2.q1, t2.q2
+ Join Filter: (t2.q1 = t3.q2)
+ -> Seq Scan on public.int8_tbl t2
+ Output: t2.q1, t2.q2
+ Filter: ((SubPlan 1) = t2.q1)
+ SubPlan 1
+ -> Result
+ Output: GREATEST($0, t2.q2)
+ -> Seq Scan on public.int8_tbl t3
+ Output: t3.q1, t3.q2
+(28 rows)
select * from (values (0), (1)) v(id),
lateral (select * from int8_tbl t1,
^ permalink raw reply [nested|flat] 30+ messages in thread
* Re: A new strategy for pull-up correlated ANY_SUBLINK
@ 2022-11-15 01:02 Richard Guo <[email protected]>
parent: Tom Lane <[email protected]>
1 sibling, 0 replies; 30+ messages in thread
From: Richard Guo @ 2022-11-15 01:02 UTC (permalink / raw)
To: Tom Lane <[email protected]>; +Cc: Andy Fan <[email protected]>; pgsql-hackers
On Sun, Nov 13, 2022 at 6:45 AM Tom Lane <[email protected]> wrote:
> Looking again at that contain_vars_of_level restriction, I think the
> reason for it was just to avoid making a FROM subquery that has outer
> references, and the reason we needed to avoid that was merely that we
> didn't have LATERAL at the time. So I experimented with the attached.
> It seems to work, in that we don't get wrong answers from any of the
> small number of places that are affected. (I wonder though whether
> those test cases still test what they were intended to, particularly
> the postgres_fdw one. We might have to try to hack them some more
> to not get affected by this optimization.) Could do with more test
> cases, no doubt.
Hmm, it seems there were discussions about this change before, such as
in [1].
> One thing I'm not at all clear about is whether we need to restrict
> the optimization so that it doesn't occur if the subquery contains
> outer references falling outside available_rels. I think that that
> case is covered by is_simple_subquery() deciding later to not pull up
> the subquery based on LATERAL restrictions, but maybe that misses
> something.
I think we need to do this, otherwise we'd encounter the problem
described in [2]. In short, the problem is that the constraints imposed
by LATERAL references may make us fail to find any legal join order. As
an example, consider
explain select * from A where exists
(select * from B where A.i in (select C.i from C where C.j = B.j));
ERROR: failed to build any 3-way joins
[1]
https://www.postgresql.org/message-id/flat/CAN_9JTx7N%2BCxEQLnu_uHxx%2BEscSgxLLuNgaZT6Sjvdpt7toy3w%4...
[2]
https://www.postgresql.org/message-id/[email protected]...
Thanks
Richard
^ permalink raw reply [nested|flat] 30+ messages in thread
* Re: A new strategy for pull-up correlated ANY_SUBLINK
@ 2024-01-26 12:46 vignesh C <[email protected]>
parent: Tom Lane <[email protected]>
1 sibling, 0 replies; 30+ messages in thread
From: vignesh C @ 2024-01-26 12:46 UTC (permalink / raw)
To: Alena Rybakina <[email protected]>; +Cc: Andy Fan <[email protected]>; pgsql-hackers; Tom Lane <[email protected]>; Richard Guo <[email protected]>; Andrey Lepikhov <[email protected]>
On Fri, 13 Oct 2023 at 14:09, Alena Rybakina <[email protected]> wrote:
>
> On 13.10.2023 10:04, Andy Fan wrote:
>>
>> It seems to me that the expressions "=" and "IN" are equivalent here due to the fact that the aggregated subquery returns only one value, and the result with the "IN" operation can be considered as the intersection of elements on the left and right. In this query, we have some kind of set on the left, among which there will be found or not only one element on the right.
>
>
> Yes, they are equivalent at the final result, but there are some
> differences at the execution level. the '=' case will be transformed
> to a Subplan whose subPlanType is EXPR_SUBLINK, so if there
> is more than 1 rows is returned in the subplan, error will be raised.
>
> select * from tenk1 where
> ten = (select ten from tenk1 i where i.two = tenk1.two );
>
> ERROR: more than one row returned by a subquery used as an expression
>
> However the IN case would not.
> select * from tenk1 where
> ten = (select ten from tenk1 i where i.two = tenk1.two ) is OK.
>
>
> I think the test case you added is not related to this feature. the
> difference is there even without the patch. so I kept the code
> you changed, but not for the test case.
>
> Yes, I understand and agree with you that we should delete the last queries, except to one.
>
> The query below have a different result compared to master, and it is correct.
>
>
> Without your patch:
>
> explain (costs off)
> +SELECT * FROM tenk1 A LEFT JOIN tenk2 B
> ON B.hundred in (SELECT min(c.hundred) FROM tenk2 C WHERE c.odd = b.odd);
> QUERY PLAN
> -----------------------------------------------------------------------------
> Nested Loop Left Join
> -> Seq Scan on tenk1 a
> -> Materialize
> -> Seq Scan on tenk2 b
> Filter: (SubPlan 2)
> SubPlan 2
> -> Result
> InitPlan 1 (returns $1)
> -> Limit
> -> Index Scan using tenk2_hundred on tenk2 c
> Index Cond: (hundred IS NOT NULL)
> Filter: (odd = b.odd)
> (12 rows)
>
>
> After your patch:
>
> postgres=# explain (costs off)
> SELECT * FROM tenk1 A LEFT JOIN tenk2 B
> ON B.hundred in (SELECT min(c.hundred) FROM tenk2 C WHERE c.odd = b.odd);
>
> QUERY PLAN
> --------------------------------------------------------------
> Nested Loop Left Join
> -> Seq Scan on tenk1 a
> -> Materialize
> -> Nested Loop
> -> Seq Scan on tenk2 b
> -> Subquery Scan on "ANY_subquery"
> Filter: (b.hundred = "ANY_subquery".min)
> -> Aggregate
> -> Seq Scan on tenk2 c
> Filter: (odd = b.odd)
> (10 rows)
>
>
>>> I took the liberty of adding this to your patch and added myself as reviewer, if you don't mind.
>>
>> Sure, the patch after your modification looks better than the original.
>> I'm not sure how the test case around "because of got one row" is
>> relevant to the current changes. After we reach to some agreement
>> on the above discussion, I think v4 is good for committer to review!
>>
>>
>> Thank you!) I am ready to discuss it.
>
>
> Actually I meant to discuss the "Unfortunately, I found a request..", looks
> we have reached an agreement there:)
>
> Yes, we have)
Hi Andy Fan,
If the changes of Alena are ok, can you merge the changes and post an
updated version so that CFBot can apply the patch and verify the
changes. As currently CFBot is trying to apply only Alena's changes
and failing with the following at [1]:
=== Applying patches on top of PostgreSQL commit ID
fba2112b1569fd001a9e54dfdd73fd3cb8f16140 ===
=== applying patch ./pull-up.diff
patching file src/test/regress/expected/subselect.out
Hunk #1 succeeded at 1926 with fuzz 2 (offset -102 lines).
patching file src/test/regress/sql/subselect.sql
Hunk #1 FAILED at 1000.
1 out of 1 hunk FAILED -- saving rejects to file
src/test/regress/sql/subselect.sql.rej
[1] - http://cfbot.cputube.org/patch_46_4268.log
Regards,
Vignesh
^ permalink raw reply [nested|flat] 30+ messages in thread
end of thread, other threads:[~2024-01-26 12:46 UTC | newest]
Thread overview: 30+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2019-06-09 20:04 [PATCH 06/10] Pass all keys to BRIN consistent function at once Tomas Vondra <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v12 5/5] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2020-11-01 19:46 [PATCH v13 06/18] More refactoring Justin Pryzby <[email protected]>
2022-11-02 03:02 A new strategy for pull-up correlated ANY_SUBLINK Andy Fan <[email protected]>
2022-11-02 03:42 ` Re: A new strategy for pull-up correlated ANY_SUBLINK Andrey Lepikhov <[email protected]>
2022-11-02 05:34 ` Re: A new strategy for pull-up correlated ANY_SUBLINK Andy Fan <[email protected]>
2022-11-12 22:45 ` Re: A new strategy for pull-up correlated ANY_SUBLINK Tom Lane <[email protected]>
2022-11-15 01:02 ` Re: A new strategy for pull-up correlated ANY_SUBLINK Richard Guo <[email protected]>
2024-01-26 12:46 ` Re: A new strategy for pull-up correlated ANY_SUBLINK vignesh C <[email protected]>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox