v0.patch.txt
application/octet-stream
Filename: v0.patch.txt
Type: application/octet-stream
Part: 0
diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c
index 2268cc27..bb3f2e63 100644
--- a/src/backend/access/heap/heapam_handler.c
+++ b/src/backend/access/heap/heapam_handler.c
@@ -1200,7 +1200,8 @@ heapam_index_build_range_scan(Relation heapRelation,
econtext->ecxt_scantuple = slot;
/* Set up execution state for predicate, if any. */
- predicate = ExecPrepareQual(indexInfo->ii_Predicate, estate);
+ predicate = ExecPrepareQual((List *)expand_generated_columns((Node *)indexInfo->ii_Predicate, heapRelation, InvalidOid),
+ estate);
/*
* Prepare for scan of the base relation. In a normal index build, we use
@@ -1758,7 +1759,8 @@ heapam_index_validate_scan(Relation heapRelation,
econtext->ecxt_scantuple = slot;
/* Set up execution state for predicate, if any. */
- predicate = ExecPrepareQual(indexInfo->ii_Predicate, estate);
+ predicate = ExecPrepareQual((List *)expand_generated_columns((Node *)indexInfo->ii_Predicate, heapRelation, InvalidOid),
+ estate);
/*
* Prepare for scan of the base relation. We need just those tuples
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9407c357..8c0fbfd8 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -81,6 +81,7 @@
#include "utils/snapmgr.h"
#include "utils/syscache.h"
#include "utils/tuplesort.h"
+#include "rewrite/rewriteHandler.h"
/* Potentially set by pg_upgrade_support functions */
Oid binary_upgrade_next_index_pg_class_oid = InvalidOid;
@@ -3029,6 +3030,7 @@ index_build(Relation heapRelation,
Oid save_userid;
int save_sec_context;
int save_nestlevel;
+ List *save_ii_Predicate = NIL;
/*
* sanity checks
@@ -3093,6 +3095,9 @@ index_build(Relation heapRelation,
pgstat_progress_update_multi_param(6, progress_index, progress_vals);
}
+ save_ii_Predicate = indexInfo->ii_Predicate;
+ indexInfo->ii_Predicate = (List *)expand_generated_columns((Node *)indexInfo->ii_Predicate,
+ heapRelation, InvalidOid);
/*
* Call the access method's build procedure
*/
@@ -3100,6 +3105,8 @@ index_build(Relation heapRelation,
indexInfo);
Assert(stats);
+ indexInfo->ii_Predicate = save_ii_Predicate;
+
/*
* If this is an unlogged index, we may need to write out an init fork for
* it -- but we must first check whether one already exists. If, for
@@ -3246,7 +3253,8 @@ IndexCheckExclusion(Relation heapRelation,
econtext->ecxt_scantuple = slot;
/* Set up execution state for predicate, if any. */
- predicate = ExecPrepareQual(indexInfo->ii_Predicate, estate);
+ predicate = ExecPrepareQual((List *)expand_generated_columns((Node *)indexInfo->ii_Predicate, heapRelation, InvalidOid),
+ estate);
/*
* Scan all live tuples in the base relation.
@@ -4309,3 +4317,38 @@ RestoreReindexState(const void *reindexstate)
/* Note the worker has its own transaction nesting level */
reindexingNestLevel = GetCurrentTransactionNestLevel();
}
+
+
+Node *
+expand_generated_columns(Node *node, Relation relation, Oid relid)
+{
+ /*expand_VGC_context context;
+ TupleDesc tupdesc;*/
+ bool opened_relation = false;
+
+ if (node == NULL || (relation == NULL && relid == InvalidOid))
+ return node;
+
+ if (relation == NULL)
+ {
+ relation = table_open(relid, NoLock);
+ opened_relation = true;
+ }
+
+ node = expand_generated_columns_in_expr(node, relation, 1);
+
+ /*tupdesc = RelationGetDescr(relation);
+
+ if ((tupdesc->constr && tupdesc->constr->has_generated_virtual))
+ {
+ context.relation = relation;
+ context.tupdesc = tupdesc;
+
+ node = expand_VGC_impl(node, &context);
+ }*/
+
+ if (opened_relation)
+ table_close(relation, NoLock);
+
+ return node;
+}
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index f66e80b7..69ba3c37 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -926,7 +926,8 @@ compute_index_stats(Relation onerel, double totalrows,
econtext->ecxt_scantuple = slot;
/* Set up execution state for predicate. */
- predicate = ExecPrepareQual(indexInfo->ii_Predicate, estate);
+ predicate = ExecPrepareQual((List *)expand_generated_columns((Node *)indexInfo->ii_Predicate, onerel, InvalidOid),
+ estate);
/* Compute and save index expression values */
exprvals = (Datum *) palloc(numrows * attr_cnt * sizeof(Datum));
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 9ab74c8d..f7cb7c70 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -1123,6 +1123,7 @@ DefineIndex(ParseState *pstate,
errmsg("index creation on system columns is not supported")));
+ /*
if (attno > 0 &&
TupleDescAttr(RelationGetDescr(rel), attno - 1)->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL)
ereport(ERROR,
@@ -1132,6 +1133,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"));
+ */
}
/*
@@ -1140,16 +1142,23 @@ DefineIndex(ParseState *pstate,
*/
if (indexInfo->ii_Expressions || indexInfo->ii_Predicate)
{
- Bitmapset *indexattrs = NULL;
+ Bitmapset *indexattrsExpr = NULL;
+ Bitmapset *indexattrsPred = NULL;
int j;
- pull_varattnos((Node *) indexInfo->ii_Expressions, 1, &indexattrs);
- pull_varattnos((Node *) indexInfo->ii_Predicate, 1, &indexattrs);
+ pull_varattnos((Node *) indexInfo->ii_Expressions, 1, &indexattrsExpr);
+ pull_varattnos((Node *) indexInfo->ii_Predicate, 1, &indexattrsPred);
for (int i = FirstLowInvalidHeapAttributeNumber + 1; i < 0; i++)
{
if (bms_is_member(i - FirstLowInvalidHeapAttributeNumber,
- indexattrs))
+ indexattrsExpr))
+ ereport(ERROR,
+ (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+ errmsg("index creation on system columns is not supported")));
+
+ if (bms_is_member(i - FirstLowInvalidHeapAttributeNumber,
+ indexattrsPred))
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("index creation on system columns is not supported")));
@@ -1161,7 +1170,7 @@ DefineIndex(ParseState *pstate,
* RelationGetIndexExpressions() and RelationGetIndexPredicate().
*/
j = -1;
- while ((j = bms_next_member(indexattrs, j)) >= 0)
+ while ((j = bms_next_member(indexattrsExpr, j)) >= 0)
{
AttrNumber attno = j + FirstLowInvalidHeapAttributeNumber;
diff --git a/src/backend/executor/execExprInterp.c b/src/backend/executor/execExprInterp.c
index 0634af96..5ebbb3ef 100644
--- a/src/backend/executor/execExprInterp.c
+++ b/src/backend/executor/execExprInterp.c
@@ -2416,8 +2416,8 @@ CheckVarSlotCompatibility(TupleTableSlot *slot, int attnum, Oid vartype)
attr = TupleDescAttr(slot_tupdesc, attnum - 1);
/* Internal error: somebody forgot to expand it. */
- if (attr->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL)
- elog(ERROR, "unexpected virtual generated column reference");
+ /*if (attr->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL)
+ elog(ERROR, "unexpected virtual generated column reference"); */
if (attr->attisdropped)
ereport(ERROR,
diff --git a/src/backend/executor/execIndexing.c b/src/backend/executor/execIndexing.c
index eb383812..3a865b19 100644
--- a/src/backend/executor/execIndexing.c
+++ b/src/backend/executor/execIndexing.c
@@ -388,7 +388,8 @@ ExecInsertIndexTuples(ResultRelInfo *resultRelInfo,
predicate = indexInfo->ii_PredicateState;
if (predicate == NULL)
{
- predicate = ExecPrepareQual(indexInfo->ii_Predicate, estate);
+ predicate = ExecPrepareQual((List *)expand_generated_columns((Node *)indexInfo->ii_Predicate, heapRelation, InvalidOid),
+ estate);
indexInfo->ii_PredicateState = predicate;
}
@@ -624,7 +625,8 @@ ExecCheckIndexConstraints(ResultRelInfo *resultRelInfo, TupleTableSlot *slot,
predicate = indexInfo->ii_PredicateState;
if (predicate == NULL)
{
- predicate = ExecPrepareQual(indexInfo->ii_Predicate, estate);
+ predicate = ExecPrepareQual((List *)expand_generated_columns((Node *)indexInfo->ii_Predicate, heapRelation, InvalidOid),
+ estate);
indexInfo->ii_PredicateState = predicate;
}
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 3f5d4fa3..007e892f 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -35,6 +35,7 @@
#include "optimizer/restrictinfo.h"
#include "utils/lsyscache.h"
#include "utils/selfuncs.h"
+#include "catalog/index.h"
/* XXX see PartCollMatchesExprColl */
@@ -1094,6 +1095,7 @@ build_paths_for_OR(PlannerInfo *root, RelOptInfo *rel,
List *result = NIL;
List *all_clauses = NIL; /* not computed till needed */
ListCell *lc;
+ Oid heapRelId = InvalidOid;
foreach(lc, rel->indexlist)
{
@@ -1127,14 +1129,18 @@ build_paths_for_OR(PlannerInfo *root, RelOptInfo *rel,
}
else
{
+ heapRelId = (root->simple_rte_array[index->rel->relid])->relid;
+
/* Form all_clauses if not done already */
if (all_clauses == NIL)
all_clauses = list_concat_copy(clauses, other_clauses);
- if (!predicate_implied_by(index->indpred, all_clauses, false))
+ if (!predicate_implied_by((List *)expand_generated_columns((Node *)index->indpred, NULL, heapRelId),
+ all_clauses, false))
continue; /* can't use it at all */
- if (!predicate_implied_by(index->indpred, other_clauses, false))
+ if (!predicate_implied_by((List *)expand_generated_columns((Node *)index->indpred, NULL, heapRelId),
+ other_clauses, false))
useful_predicate = true;
}
}
@@ -3944,6 +3950,7 @@ check_index_predicates(PlannerInfo *root, RelOptInfo *rel)
bool is_target_rel;
Relids otherrels;
ListCell *lc;
+ Oid heapRelId = InvalidOid;
/* Indexes are available only on base or "other" member relations. */
Assert(IS_SIMPLE_REL(rel));
@@ -4041,9 +4048,10 @@ check_index_predicates(PlannerInfo *root, RelOptInfo *rel)
if (index->indpred == NIL)
continue; /* ignore non-partial indexes here */
+ heapRelId = (root->simple_rte_array[index->rel->relid])->relid;
if (!index->predOK) /* don't repeat work if already proven OK */
- index->predOK = predicate_implied_by(index->indpred, clauselist,
- false);
+ index->predOK = predicate_implied_by((List *)expand_generated_columns((Node *)index->indpred, NULL, heapRelId),
+ clauselist, false);
/* If rel is an update target, leave indrestrictinfo as set above */
if (is_target_rel)
@@ -4068,7 +4076,8 @@ check_index_predicates(PlannerInfo *root, RelOptInfo *rel)
/* predicate_implied_by() assumes first arg is immutable */
if (contain_mutable_functions((Node *) rinfo->clause) ||
!predicate_implied_by(list_make1(rinfo->clause),
- index->indpred, false))
+ (List *)expand_generated_columns((Node *)index->indpred, NULL, heapRelId),
+ false))
index->indrestrictinfo = lappend(index->indrestrictinfo, rinfo);
}
}
diff --git a/src/include/catalog/index.h b/src/include/catalog/index.h
index 9aee8226..015ec674 100644
--- a/src/include/catalog/index.h
+++ b/src/include/catalog/index.h
@@ -16,6 +16,9 @@
#include "catalog/objectaddress.h"
#include "nodes/execnodes.h"
+/*#include "rewrite/rewriteManip.h"
+
+#include "nodes/nodeFuncs.h"*/
/*
@@ -59,6 +62,12 @@ typedef struct ValidateIndexState
tups_inserted;
} ValidateIndexState;
+typedef struct expand_VGC_context
+{
+ Relation relation; /* the relation of the virtual generated column */
+ TupleDesc tupdesc;
+} expand_VGC_context;
+
extern void index_check_primary_key(Relation heapRel,
const IndexInfo *indexInfo,
bool is_alter_table,
@@ -223,4 +232,35 @@ itemptr_decode(ItemPointer itemptr, int64 encoded)
ItemPointerSet(itemptr, block, offset);
}
+/*
+static Node *
+expand_VGC_impl(Node *node, expand_VGC_context *context)
+{
+ if (node == NULL)
+ {
+
+ }
+ else if (IsA(node, Var))
+ {
+ int varattno = ((Var *)node)->varattno;
+
+ Form_pg_attribute attr = TupleDescAttr(context->tupdesc, varattno - 1);
+ if (attr->attgenerated == ATTRIBUTE_GENERATED_VIRTUAL)
+ {
+ node = build_generation_expression(context->relation,
+ varattno);
+ ChangeVarNodes(node, 1, 1, 0);
+ }
+ else
+ node = copyObject(node);
+ }
+ else
+ node = expression_tree_mutator(node, expand_VGC_impl, context);
+
+ return node;
+}
+*/
+
+extern Node *expand_generated_columns(Node *node, Relation relation, Oid relid);
+
#endif /* INDEX_H */