v1.patch.txt
application/octet-stream
Filename: v1.patch.txt
Type: application/octet-stream
Part: 1
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 9ab74c8d..63540cfb 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -594,6 +594,7 @@ DefineIndex(ParseState *pstate,
Oid root_save_userid;
int root_save_sec_context;
int root_save_nestlevel;
+ Node *whereClause = NULL;
root_save_nestlevel = NewGUCNestLevel();
@@ -905,8 +906,11 @@ DefineIndex(ParseState *pstate,
/*
* Validate predicate, if given
*/
- if (stmt->whereClause)
- CheckPredicate((Expr *) stmt->whereClause);
+ if (stmt->whereClause){
+ /* Expand virtual generated columns in expressions */
+ whereClause = ExpandVirtualGeneratedColumns(copyObject(stmt->whereClause), rel, InvalidOid);
+ CheckPredicate((Expr *) whereClause);
+ }
/*
* Parse AM-specific options, convert to text array form, validate.
@@ -925,7 +929,7 @@ DefineIndex(ParseState *pstate,
numberOfKeyAttributes,
accessMethodId,
NIL, /* expressions, NIL for now */
- make_ands_implicit((Expr *) stmt->whereClause),
+ make_ands_implicit((Expr *) whereClause),
stmt->unique,
stmt->nulls_not_distinct,
!concurrent,
@@ -948,6 +952,11 @@ DefineIndex(ParseState *pstate,
root_save_userid, root_save_sec_context,
&root_save_nestlevel);
+ /* Expand virtual generated columns in expressions */
+ if (indexInfo->ii_Expressions)
+ indexInfo->ii_Expressions =
+ (List *)ExpandVirtualGeneratedColumns((Node *)indexInfo->ii_Expressions, rel, InvalidOid);
+
/*
* Extra checks when creating a PRIMARY KEY index.
*/
@@ -1122,8 +1131,8 @@ DefineIndex(ParseState *pstate,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("index creation on system columns is not supported")));
-
- if (attno > 0 &&
+ /* allow virtual generated columns in include(...)*/
+ if (attno > 0 && i < numberOfKeyAttributes &&
TupleDescAttr(RelationGetDescr(rel), attno - 1)->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL)
ereport(ERROR,
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -1135,13 +1144,12 @@ DefineIndex(ParseState *pstate,
}
/*
- * Also check for system and generated columns used in expressions or
- * predicates.
+ * Also check for system columns used in expressions or predicates.
*/
if (indexInfo->ii_Expressions || indexInfo->ii_Predicate)
{
Bitmapset *indexattrs = NULL;
- int j;
+ /*int j;*/
pull_varattnos((Node *) indexInfo->ii_Expressions, 1, &indexattrs);
pull_varattnos((Node *) indexInfo->ii_Predicate, 1, &indexattrs);
@@ -1160,7 +1168,7 @@ DefineIndex(ParseState *pstate,
* could be supported, but it needs support in
* RelationGetIndexExpressions() and RelationGetIndexPredicate().
*/
- j = -1;
+ /*j = -1;
while ((j = bms_next_member(indexattrs, j)) >= 0)
{
AttrNumber attno = j + FirstLowInvalidHeapAttributeNumber;
@@ -1172,7 +1180,7 @@ DefineIndex(ParseState *pstate,
stmt->isconstraint ?
errmsg("unique constraints on virtual generated columns are not supported") :
errmsg("indexes on virtual generated columns are not supported")));
- }
+ }*/
}
/* Is index safe for others to ignore? See set_indexsafe_procflags() */
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 0572ab42..7b531628 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -91,6 +91,7 @@
#include "utils/resowner.h"
#include "utils/snapmgr.h"
#include "utils/syscache.h"
+#include "rewrite/rewriteHandler.h"
#define RELCACHE_INIT_FILEMAGIC 0x573266 /* version ID value */
@@ -5102,6 +5103,8 @@ RelationGetIndexExpressions(Relation relation)
bool isnull;
char *exprsString;
MemoryContext oldcxt;
+ Datum heapRelidDatum;
+ Oid heapRelid;
/* Quick exit if we already computed the result. */
if (relation->rd_indexprs)
@@ -5138,6 +5141,15 @@ RelationGetIndexExpressions(Relation relation)
/* May as well fix opfuncids too */
fix_opfuncids((Node *) result);
+ heapRelidDatum = heap_getattr(relation->rd_indextuple,
+ Anum_pg_index_indrelid,
+ GetPgIndexDescriptor(),
+ &isnull);
+ Assert(!isnull);
+ heapRelid = DatumGetObjectId(heapRelidDatum);
+
+ result = (List *)ExpandVirtualGeneratedColumns((Node *) result, NULL, heapRelid);
+
/* Now save a copy of the completed tree in the relcache entry. */
oldcxt = MemoryContextSwitchTo(relation->rd_indexcxt);
relation->rd_indexprs = copyObject(result);
@@ -5215,6 +5227,8 @@ RelationGetIndexPredicate(Relation relation)
bool isnull;
char *predString;
MemoryContext oldcxt;
+ Datum heapRelidDatum;
+ Oid heapRelid;
/* Quick exit if we already computed the result. */
if (relation->rd_indpred)
@@ -5258,6 +5272,15 @@ RelationGetIndexPredicate(Relation relation)
/* May as well fix opfuncids too */
fix_opfuncids((Node *) result);
+ heapRelidDatum = heap_getattr(relation->rd_indextuple,
+ Anum_pg_index_indrelid,
+ GetPgIndexDescriptor(),
+ &isnull);
+ Assert(!isnull);
+ heapRelid = DatumGetObjectId(heapRelidDatum);
+
+ result = (List *)ExpandVirtualGeneratedColumns((Node *) result, NULL, heapRelid);
+
/* Now save a copy of the completed tree in the relcache entry. */
oldcxt = MemoryContextSwitchTo(relation->rd_indexcxt);
relation->rd_indpred = copyObject(result);
@@ -7019,3 +7042,46 @@ ResOwnerReleaseRelation(Datum res)
RelationCloseCleanup((Relation) DatumGetPointer(res));
}
+
+Node *
+ExpandVirtualGeneratedColumns(Node *node, Relation heapRelation, Oid heapRelId)
+{
+ bool opened_relation = false;
+ TupleDesc tupdesc;
+
+ if (node == NULL || (heapRelation == NULL && heapRelId == InvalidOid))
+ return node;
+
+ if (heapRelation == NULL)
+ {
+ heapRelation = table_open(heapRelId, NoLock);
+ opened_relation = true;
+ }
+
+ tupdesc = RelationGetDescr(heapRelation);
+ if ((tupdesc->constr && tupdesc->constr->has_generated_virtual))
+ {
+ int j;
+ Bitmapset *indexattrs = NULL;
+
+ pull_varattnos(node, 1, &indexattrs);
+
+ j = -1;
+ while ((j = bms_next_member(indexattrs, j)) >= 0)
+ {
+ AttrNumber attno = j + FirstLowInvalidHeapAttributeNumber;
+
+ if (attno > 0 &&
+ TupleDescAttr(tupdesc, attno - 1)->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL)
+ {
+ node = expand_generated_columns_in_expr(node, heapRelation, 1);
+ break;
+ }
+ }
+ }
+
+ if (opened_relation)
+ table_close(heapRelation, NoLock);
+
+ return node;
+}
diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h
index 89c27aa1..07e70273 100644
--- a/src/include/utils/relcache.h
+++ b/src/include/utils/relcache.h
@@ -161,4 +161,6 @@ extern PGDLLIMPORT bool criticalRelcachesBuilt;
/* should be used only by relcache.c and postinit.c */
extern PGDLLIMPORT bool criticalSharedRelcachesBuilt;
+extern Node *ExpandVirtualGeneratedColumns(Node *node, Relation heapRelation, Oid heapRelId);
+
#endif /* RELCACHE_H */