1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-08 11:42:09 +03:00

Fix handling of expressions and predicates in REINDEX CONCURRENTLY

When copying the definition of an index rebuilt concurrently for the new
entry, the index information was taken directly from the old index using
the relation cache.  In this case, predicates and expressions have
some post-processing to prepare things for the planner, which loses some
information including the collations added in any of them.

This inconsistency can cause issues when attempting for example a table
rewrite, and makes the new indexes rebuilt concurrently inconsistent
with the old entries.

In order to fix the problem, fetch expressions and predicates directly
from the catalog of the old entry, and fill in IndexInfo for the new
index with that.  This makes the process more consistent with
DefineIndex(), and the code is refactored with the addition of a routine
to create an IndexInfo node.

Reported-by: Manuel Rigger
Author: Michael Paquier
Discussion: https://postgr.es/m/CA+u7OA5Hp0ra235F3czPom_FyAd-3+XwSJmX95r1+sRPOJc9VQ@mail.gmail.com
Backpatch-through: 12
This commit is contained in:
Michael Paquier
2019-07-29 09:58:49 +09:00
parent a2a777d011
commit 7cce159349
6 changed files with 236 additions and 41 deletions

View File

@ -1,8 +1,8 @@
/*-------------------------------------------------------------------------
*
* makefuncs.c
* creator functions for primitive nodes. The functions here are for
* the most frequently created nodes.
* creator functions for various nodes. The functions here are for the
* most frequently created nodes.
*
* Portions Copyright (c) 1996-2019, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
@ -733,6 +733,54 @@ make_ands_implicit(Expr *clause)
return list_make1(clause);
}
/*
* makeIndexInfo
* create an IndexInfo node
*/
IndexInfo *
makeIndexInfo(int numattrs, int numkeyattrs, Oid amoid, List *expressions,
List *predicates, bool unique, bool isready, bool concurrent)
{
IndexInfo *n = makeNode(IndexInfo);
n->ii_NumIndexAttrs = numattrs;
n->ii_NumIndexKeyAttrs = numkeyattrs;
Assert(n->ii_NumIndexKeyAttrs != 0);
Assert(n->ii_NumIndexKeyAttrs <= n->ii_NumIndexAttrs);
n->ii_Unique = unique;
n->ii_ReadyForInserts = isready;
n->ii_Concurrent = concurrent;
/* expressions */
n->ii_Expressions = expressions;
n->ii_ExpressionsState = NIL;
/* predicates */
n->ii_Predicate = predicates;
n->ii_PredicateState = NULL;
/* exclusion constraints */
n->ii_ExclusionOps = NULL;
n->ii_ExclusionProcs = NULL;
n->ii_ExclusionStrats = NULL;
/* speculative inserts */
n->ii_UniqueOps = NULL;
n->ii_UniqueProcs = NULL;
n->ii_UniqueStrats = NULL;
/* initialize index-build state to default */
n->ii_BrokenHotChain = false;
n->ii_ParallelWorkers = 0;
/* set up for possible use by index AM */
n->ii_Am = amoid;
n->ii_AmCache = NULL;
n->ii_Context = CurrentMemoryContext;
return n;
}
/*
* makeGroupingSet
*