mirror of
https://github.com/postgres/postgres.git
synced 2025-06-27 23:21:58 +03:00
Reindent table partitioning code.
We've accumulated quite a bit of stuff with which pgindent is not quite happy in this code; clean it up to provide a less-annoying base for future pgindent runs.
This commit is contained in:
@ -1780,12 +1780,12 @@ heap_drop_with_catalog(Oid relid)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If the relation is a partition, we must grab exclusive lock on its
|
* If the relation is a partition, we must grab exclusive lock on its
|
||||||
* parent because we need to update its partition descriptor. We must
|
* parent because we need to update its partition descriptor. We must take
|
||||||
* take a table lock strong enough to prevent all queries on the parent
|
* a table lock strong enough to prevent all queries on the parent from
|
||||||
* from proceeding until we commit and send out a shared-cache-inval
|
* proceeding until we commit and send out a shared-cache-inval notice
|
||||||
* notice that will make them update their partition descriptor.
|
* that will make them update their partition descriptor. Sometimes, doing
|
||||||
* Sometimes, doing this is cycles spent uselessly, especially if the
|
* this is cycles spent uselessly, especially if the parent will be
|
||||||
* parent will be dropped as part of the same command anyway.
|
* dropped as part of the same command anyway.
|
||||||
*/
|
*/
|
||||||
if (rel->rd_rel->relispartition)
|
if (rel->rd_rel->relispartition)
|
||||||
{
|
{
|
||||||
@ -2084,8 +2084,8 @@ StoreRelCheck(Relation rel, char *ccname, Node *expr,
|
|||||||
rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
|
rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
|
(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
|
||||||
errmsg("cannot add NO INHERIT constraint to partitioned table \"%s\"",
|
errmsg("cannot add NO INHERIT constraint to partitioned table \"%s\"",
|
||||||
RelationGetRelationName(rel))));
|
RelationGetRelationName(rel))));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create the Check Constraint
|
* Create the Check Constraint
|
||||||
@ -3113,8 +3113,8 @@ StorePartitionKey(Relation rel,
|
|||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
Datum values[Natts_pg_partitioned_table];
|
Datum values[Natts_pg_partitioned_table];
|
||||||
bool nulls[Natts_pg_partitioned_table];
|
bool nulls[Natts_pg_partitioned_table];
|
||||||
ObjectAddress myself;
|
ObjectAddress myself;
|
||||||
ObjectAddress referenced;
|
ObjectAddress referenced;
|
||||||
|
|
||||||
Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
|
Assert(rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE);
|
||||||
|
|
||||||
@ -3129,7 +3129,7 @@ StorePartitionKey(Relation rel,
|
|||||||
/* Convert the expressions (if any) to a text datum */
|
/* Convert the expressions (if any) to a text datum */
|
||||||
if (partexprs)
|
if (partexprs)
|
||||||
{
|
{
|
||||||
char *exprString;
|
char *exprString;
|
||||||
|
|
||||||
exprString = nodeToString(partexprs);
|
exprString = nodeToString(partexprs);
|
||||||
partexprDatum = CStringGetTextDatum(exprString);
|
partexprDatum = CStringGetTextDatum(exprString);
|
||||||
@ -3149,7 +3149,7 @@ StorePartitionKey(Relation rel,
|
|||||||
values[Anum_pg_partitioned_table_partrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel));
|
values[Anum_pg_partitioned_table_partrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel));
|
||||||
values[Anum_pg_partitioned_table_partstrat - 1] = CharGetDatum(strategy);
|
values[Anum_pg_partitioned_table_partstrat - 1] = CharGetDatum(strategy);
|
||||||
values[Anum_pg_partitioned_table_partnatts - 1] = Int16GetDatum(partnatts);
|
values[Anum_pg_partitioned_table_partnatts - 1] = Int16GetDatum(partnatts);
|
||||||
values[Anum_pg_partitioned_table_partattrs - 1] = PointerGetDatum(partattrs_vec);
|
values[Anum_pg_partitioned_table_partattrs - 1] = PointerGetDatum(partattrs_vec);
|
||||||
values[Anum_pg_partitioned_table_partclass - 1] = PointerGetDatum(partopclass_vec);
|
values[Anum_pg_partitioned_table_partclass - 1] = PointerGetDatum(partopclass_vec);
|
||||||
values[Anum_pg_partitioned_table_partcollation - 1] = PointerGetDatum(partcollation_vec);
|
values[Anum_pg_partitioned_table_partcollation - 1] = PointerGetDatum(partcollation_vec);
|
||||||
values[Anum_pg_partitioned_table_partexprs - 1] = partexprDatum;
|
values[Anum_pg_partitioned_table_partexprs - 1] = partexprDatum;
|
||||||
@ -3185,8 +3185,8 @@ StorePartitionKey(Relation rel,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Anything mentioned in the expressions. We must ignore the column
|
* Anything mentioned in the expressions. We must ignore the column
|
||||||
* references, which will depend on the table itself; there is no
|
* references, which will depend on the table itself; there is no separate
|
||||||
* separate partition key object.
|
* partition key object.
|
||||||
*/
|
*/
|
||||||
if (partexprs)
|
if (partexprs)
|
||||||
recordDependencyOnSingleRelExpr(&myself,
|
recordDependencyOnSingleRelExpr(&myself,
|
||||||
@ -3204,7 +3204,7 @@ StorePartitionKey(Relation rel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RemovePartitionKeyByRelId
|
* RemovePartitionKeyByRelId
|
||||||
* Remove pg_partitioned_table entry for a relation
|
* Remove pg_partitioned_table entry for a relation
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
@ -3240,9 +3240,9 @@ StorePartitionBound(Relation rel, Relation parent, Node *bound)
|
|||||||
Relation classRel;
|
Relation classRel;
|
||||||
HeapTuple tuple,
|
HeapTuple tuple,
|
||||||
newtuple;
|
newtuple;
|
||||||
Datum new_val[Natts_pg_class];
|
Datum new_val[Natts_pg_class];
|
||||||
bool new_null[Natts_pg_class],
|
bool new_null[Natts_pg_class],
|
||||||
new_repl[Natts_pg_class];
|
new_repl[Natts_pg_class];
|
||||||
|
|
||||||
/* Update pg_class tuple */
|
/* Update pg_class tuple */
|
||||||
classRel = heap_open(RelationRelationId, RowExclusiveLock);
|
classRel = heap_open(RelationRelationId, RowExclusiveLock);
|
||||||
@ -3254,8 +3254,8 @@ StorePartitionBound(Relation rel, Relation parent, Node *bound)
|
|||||||
|
|
||||||
#ifdef USE_ASSERT_CHECKING
|
#ifdef USE_ASSERT_CHECKING
|
||||||
{
|
{
|
||||||
Form_pg_class classForm;
|
Form_pg_class classForm;
|
||||||
bool isnull;
|
bool isnull;
|
||||||
|
|
||||||
classForm = (Form_pg_class) GETSTRUCT(tuple);
|
classForm = (Form_pg_class) GETSTRUCT(tuple);
|
||||||
Assert(!classForm->relispartition);
|
Assert(!classForm->relispartition);
|
||||||
|
@ -1069,7 +1069,7 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode,
|
|||||||
Relation partrel = lfirst(lc1);
|
Relation partrel = lfirst(lc1);
|
||||||
Relation parent = lfirst(lc2);
|
Relation parent = lfirst(lc2);
|
||||||
PartitionKey partkey = RelationGetPartitionKey(partrel);
|
PartitionKey partkey = RelationGetPartitionKey(partrel);
|
||||||
TupleDesc tupdesc = RelationGetDescr(partrel);
|
TupleDesc tupdesc = RelationGetDescr(partrel);
|
||||||
PartitionDesc partdesc = RelationGetPartitionDesc(partrel);
|
PartitionDesc partdesc = RelationGetPartitionDesc(partrel);
|
||||||
int j,
|
int j,
|
||||||
m;
|
m;
|
||||||
@ -1082,17 +1082,17 @@ RelationGetPartitionDispatchInfo(Relation rel, int lockmode,
|
|||||||
if (parent != NULL)
|
if (parent != NULL)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* For every partitioned table other than root, we must store
|
* For every partitioned table other than root, we must store a
|
||||||
* a tuple table slot initialized with its tuple descriptor and
|
* tuple table slot initialized with its tuple descriptor and a
|
||||||
* a tuple conversion map to convert a tuple from its parent's
|
* tuple conversion map to convert a tuple from its parent's
|
||||||
* rowtype to its own. That is to make sure that we are looking
|
* rowtype to its own. That is to make sure that we are looking at
|
||||||
* at the correct row using the correct tuple descriptor when
|
* the correct row using the correct tuple descriptor when
|
||||||
* computing its partition key for tuple routing.
|
* computing its partition key for tuple routing.
|
||||||
*/
|
*/
|
||||||
pd[i]->tupslot = MakeSingleTupleTableSlot(tupdesc);
|
pd[i]->tupslot = MakeSingleTupleTableSlot(tupdesc);
|
||||||
pd[i]->tupmap = convert_tuples_by_name(RelationGetDescr(parent),
|
pd[i]->tupmap = convert_tuples_by_name(RelationGetDescr(parent),
|
||||||
tupdesc,
|
tupdesc,
|
||||||
gettext_noop("could not convert row type"));
|
gettext_noop("could not convert row type"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1574,10 +1574,10 @@ generate_partition_qual(Relation rel)
|
|||||||
result = my_qual;
|
result = my_qual;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Change Vars to have partition's attnos instead of the parent's.
|
* Change Vars to have partition's attnos instead of the parent's. We do
|
||||||
* We do this after we concatenate the parent's quals, because
|
* this after we concatenate the parent's quals, because we want every Var
|
||||||
* we want every Var in it to bear this relation's attnos.
|
* in it to bear this relation's attnos. It's safe to assume varno = 1
|
||||||
* It's safe to assume varno = 1 here.
|
* here.
|
||||||
*/
|
*/
|
||||||
result = map_partition_varattnos(result, 1, rel, parent);
|
result = map_partition_varattnos(result, 1, rel, parent);
|
||||||
|
|
||||||
|
@ -163,10 +163,9 @@ typedef struct CopyStateData
|
|||||||
List *range_table;
|
List *range_table;
|
||||||
|
|
||||||
PartitionDispatch *partition_dispatch_info;
|
PartitionDispatch *partition_dispatch_info;
|
||||||
int num_dispatch; /* Number of entries in the above array */
|
int num_dispatch; /* Number of entries in the above array */
|
||||||
int num_partitions; /* Number of members in the following
|
int num_partitions; /* Number of members in the following arrays */
|
||||||
* arrays */
|
ResultRelInfo *partitions; /* Per partition result relation */
|
||||||
ResultRelInfo *partitions; /* Per partition result relation */
|
|
||||||
TupleConversionMap **partition_tupconv_maps;
|
TupleConversionMap **partition_tupconv_maps;
|
||||||
TupleTableSlot *partition_tuple_slot;
|
TupleTableSlot *partition_tuple_slot;
|
||||||
|
|
||||||
@ -1416,12 +1415,12 @@ BeginCopy(ParseState *pstate,
|
|||||||
/* Initialize state for CopyFrom tuple routing. */
|
/* Initialize state for CopyFrom tuple routing. */
|
||||||
if (is_from && rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
|
if (is_from && rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
|
||||||
{
|
{
|
||||||
PartitionDispatch *partition_dispatch_info;
|
PartitionDispatch *partition_dispatch_info;
|
||||||
ResultRelInfo *partitions;
|
ResultRelInfo *partitions;
|
||||||
TupleConversionMap **partition_tupconv_maps;
|
TupleConversionMap **partition_tupconv_maps;
|
||||||
TupleTableSlot *partition_tuple_slot;
|
TupleTableSlot *partition_tuple_slot;
|
||||||
int num_parted,
|
int num_parted,
|
||||||
num_partitions;
|
num_partitions;
|
||||||
|
|
||||||
ExecSetupPartitionTupleRouting(rel,
|
ExecSetupPartitionTupleRouting(rel,
|
||||||
&partition_dispatch_info,
|
&partition_dispatch_info,
|
||||||
@ -2499,7 +2498,7 @@ CopyFrom(CopyState cstate)
|
|||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
TupleTableSlot *slot,
|
TupleTableSlot *slot,
|
||||||
*oldslot;
|
*oldslot;
|
||||||
bool skip_tuple;
|
bool skip_tuple;
|
||||||
Oid loaded_oid = InvalidOid;
|
Oid loaded_oid = InvalidOid;
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
|
|||||||
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
|
||||||
errmsg("\"%s\" is a partitioned table",
|
errmsg("\"%s\" is a partitioned table",
|
||||||
RelationGetRelationName(rel)),
|
RelationGetRelationName(rel)),
|
||||||
errdetail("Partitioned tables cannot have ROW triggers.")));
|
errdetail("Partitioned tables cannot have ROW triggers.")));
|
||||||
}
|
}
|
||||||
else if (rel->rd_rel->relkind == RELKIND_VIEW)
|
else if (rel->rd_rel->relkind == RELKIND_VIEW)
|
||||||
{
|
{
|
||||||
|
@ -1222,7 +1222,7 @@ InitResultRelInfo(ResultRelInfo *resultRelInfo,
|
|||||||
Relation partition_root,
|
Relation partition_root,
|
||||||
int instrument_options)
|
int instrument_options)
|
||||||
{
|
{
|
||||||
List *partition_check = NIL;
|
List *partition_check = NIL;
|
||||||
|
|
||||||
MemSet(resultRelInfo, 0, sizeof(ResultRelInfo));
|
MemSet(resultRelInfo, 0, sizeof(ResultRelInfo));
|
||||||
resultRelInfo->type = T_ResultRelInfo;
|
resultRelInfo->type = T_ResultRelInfo;
|
||||||
@ -1754,10 +1754,10 @@ ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot,
|
|||||||
*/
|
*/
|
||||||
if (resultRelInfo->ri_PartitionCheckExpr == NULL)
|
if (resultRelInfo->ri_PartitionCheckExpr == NULL)
|
||||||
{
|
{
|
||||||
List *qual = resultRelInfo->ri_PartitionCheck;
|
List *qual = resultRelInfo->ri_PartitionCheck;
|
||||||
|
|
||||||
resultRelInfo->ri_PartitionCheckExpr = (List *)
|
resultRelInfo->ri_PartitionCheckExpr = (List *)
|
||||||
ExecPrepareExpr((Expr *) qual, estate);
|
ExecPrepareExpr((Expr *) qual, estate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1837,7 +1837,7 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
|
|||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_NOT_NULL_VIOLATION),
|
(errcode(ERRCODE_NOT_NULL_VIOLATION),
|
||||||
errmsg("null value in column \"%s\" violates not-null constraint",
|
errmsg("null value in column \"%s\" violates not-null constraint",
|
||||||
NameStr(orig_tupdesc->attrs[attrChk - 1]->attname)),
|
NameStr(orig_tupdesc->attrs[attrChk - 1]->attname)),
|
||||||
val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
|
val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
|
||||||
errtablecol(orig_rel, attrChk)));
|
errtablecol(orig_rel, attrChk)));
|
||||||
}
|
}
|
||||||
@ -1900,9 +1900,9 @@ ExecConstraints(ResultRelInfo *resultRelInfo,
|
|||||||
64);
|
64);
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_CHECK_VIOLATION),
|
(errcode(ERRCODE_CHECK_VIOLATION),
|
||||||
errmsg("new row for relation \"%s\" violates partition constraint",
|
errmsg("new row for relation \"%s\" violates partition constraint",
|
||||||
RelationGetRelationName(orig_rel)),
|
RelationGetRelationName(orig_rel)),
|
||||||
val_desc ? errdetail("Failing row contains %s.", val_desc) : 0));
|
val_desc ? errdetail("Failing row contains %s.", val_desc) : 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3118,7 +3118,7 @@ ExecSetupPartitionTupleRouting(Relation rel,
|
|||||||
*partitions = (ResultRelInfo *) palloc(*num_partitions *
|
*partitions = (ResultRelInfo *) palloc(*num_partitions *
|
||||||
sizeof(ResultRelInfo));
|
sizeof(ResultRelInfo));
|
||||||
*tup_conv_maps = (TupleConversionMap **) palloc0(*num_partitions *
|
*tup_conv_maps = (TupleConversionMap **) palloc0(*num_partitions *
|
||||||
sizeof(TupleConversionMap *));
|
sizeof(TupleConversionMap *));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize an empty slot that will be used to manipulate tuples of any
|
* Initialize an empty slot that will be used to manipulate tuples of any
|
||||||
@ -3157,7 +3157,7 @@ ExecSetupPartitionTupleRouting(Relation rel,
|
|||||||
|
|
||||||
InitResultRelInfo(leaf_part_rri,
|
InitResultRelInfo(leaf_part_rri,
|
||||||
partrel,
|
partrel,
|
||||||
1, /* dummy */
|
1, /* dummy */
|
||||||
rel,
|
rel,
|
||||||
0);
|
0);
|
||||||
|
|
||||||
@ -3190,8 +3190,8 @@ int
|
|||||||
ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd,
|
ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd,
|
||||||
TupleTableSlot *slot, EState *estate)
|
TupleTableSlot *slot, EState *estate)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
Oid failed_at;
|
Oid failed_at;
|
||||||
ExprContext *econtext = GetPerTupleExprContext(estate);
|
ExprContext *econtext = GetPerTupleExprContext(estate);
|
||||||
|
|
||||||
econtext->ecxt_scantuple = slot;
|
econtext->ecxt_scantuple = slot;
|
||||||
@ -3218,7 +3218,7 @@ ExecFindPartition(ResultRelInfo *resultRelInfo, PartitionDispatch *pd,
|
|||||||
(errcode(ERRCODE_CHECK_VIOLATION),
|
(errcode(ERRCODE_CHECK_VIOLATION),
|
||||||
errmsg("no partition of relation \"%s\" found for row",
|
errmsg("no partition of relation \"%s\" found for row",
|
||||||
get_rel_name(failed_at)),
|
get_rel_name(failed_at)),
|
||||||
val_desc ? errdetail("Failing row contains %s.", val_desc) : 0));
|
val_desc ? errdetail("Failing row contains %s.", val_desc) : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -263,7 +263,7 @@ ExecInsert(ModifyTableState *mtstate,
|
|||||||
Oid newId;
|
Oid newId;
|
||||||
List *recheckIndexes = NIL;
|
List *recheckIndexes = NIL;
|
||||||
TupleTableSlot *oldslot = slot,
|
TupleTableSlot *oldslot = slot,
|
||||||
*result = NULL;
|
*result = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* get the heap tuple out of the tuple table slot, making sure we have a
|
* get the heap tuple out of the tuple table slot, making sure we have a
|
||||||
@ -279,19 +279,19 @@ ExecInsert(ModifyTableState *mtstate,
|
|||||||
/* Determine the partition to heap_insert the tuple into */
|
/* Determine the partition to heap_insert the tuple into */
|
||||||
if (mtstate->mt_partition_dispatch_info)
|
if (mtstate->mt_partition_dispatch_info)
|
||||||
{
|
{
|
||||||
int leaf_part_index;
|
int leaf_part_index;
|
||||||
TupleConversionMap *map;
|
TupleConversionMap *map;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Away we go ... If we end up not finding a partition after all,
|
* Away we go ... If we end up not finding a partition after all,
|
||||||
* ExecFindPartition() does not return and errors out instead.
|
* ExecFindPartition() does not return and errors out instead.
|
||||||
* Otherwise, the returned value is to be used as an index into
|
* Otherwise, the returned value is to be used as an index into arrays
|
||||||
* arrays mt_partitions[] and mt_partition_tupconv_maps[] that
|
* mt_partitions[] and mt_partition_tupconv_maps[] that will get us
|
||||||
* will get us the ResultRelInfo and TupleConversionMap for the
|
* the ResultRelInfo and TupleConversionMap for the partition,
|
||||||
* partition, respectively.
|
* respectively.
|
||||||
*/
|
*/
|
||||||
leaf_part_index = ExecFindPartition(resultRelInfo,
|
leaf_part_index = ExecFindPartition(resultRelInfo,
|
||||||
mtstate->mt_partition_dispatch_info,
|
mtstate->mt_partition_dispatch_info,
|
||||||
slot,
|
slot,
|
||||||
estate);
|
estate);
|
||||||
Assert(leaf_part_index >= 0 &&
|
Assert(leaf_part_index >= 0 &&
|
||||||
@ -308,7 +308,7 @@ ExecInsert(ModifyTableState *mtstate,
|
|||||||
if (resultRelInfo->ri_FdwRoutine)
|
if (resultRelInfo->ri_FdwRoutine)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||||
errmsg("cannot route inserted tuples to a foreign table")));
|
errmsg("cannot route inserted tuples to a foreign table")));
|
||||||
|
|
||||||
/* For ExecInsertIndexTuples() to work on the partition's indexes */
|
/* For ExecInsertIndexTuples() to work on the partition's indexes */
|
||||||
estate->es_result_relation_info = resultRelInfo;
|
estate->es_result_relation_info = resultRelInfo;
|
||||||
@ -320,14 +320,14 @@ ExecInsert(ModifyTableState *mtstate,
|
|||||||
map = mtstate->mt_partition_tupconv_maps[leaf_part_index];
|
map = mtstate->mt_partition_tupconv_maps[leaf_part_index];
|
||||||
if (map)
|
if (map)
|
||||||
{
|
{
|
||||||
Relation partrel = resultRelInfo->ri_RelationDesc;
|
Relation partrel = resultRelInfo->ri_RelationDesc;
|
||||||
|
|
||||||
tuple = do_convert_tuple(tuple, map);
|
tuple = do_convert_tuple(tuple, map);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We must use the partition's tuple descriptor from this
|
* We must use the partition's tuple descriptor from this point
|
||||||
* point on, until we're finished dealing with the partition.
|
* on, until we're finished dealing with the partition. Use the
|
||||||
* Use the dedicated slot for that.
|
* dedicated slot for that.
|
||||||
*/
|
*/
|
||||||
slot = mtstate->mt_partition_tuple_slot;
|
slot = mtstate->mt_partition_tuple_slot;
|
||||||
Assert(slot != NULL);
|
Assert(slot != NULL);
|
||||||
@ -1730,12 +1730,12 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
|
|||||||
if (operation == CMD_INSERT &&
|
if (operation == CMD_INSERT &&
|
||||||
rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
|
rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
|
||||||
{
|
{
|
||||||
PartitionDispatch *partition_dispatch_info;
|
PartitionDispatch *partition_dispatch_info;
|
||||||
ResultRelInfo *partitions;
|
ResultRelInfo *partitions;
|
||||||
TupleConversionMap **partition_tupconv_maps;
|
TupleConversionMap **partition_tupconv_maps;
|
||||||
TupleTableSlot *partition_tuple_slot;
|
TupleTableSlot *partition_tuple_slot;
|
||||||
int num_parted,
|
int num_parted,
|
||||||
num_partitions;
|
num_partitions;
|
||||||
|
|
||||||
ExecSetupPartitionTupleRouting(rel,
|
ExecSetupPartitionTupleRouting(rel,
|
||||||
&partition_dispatch_info,
|
&partition_dispatch_info,
|
||||||
@ -1784,7 +1784,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
|
|||||||
{
|
{
|
||||||
TupleTableSlot *slot;
|
TupleTableSlot *slot;
|
||||||
ExprContext *econtext;
|
ExprContext *econtext;
|
||||||
List *returningList;
|
List *returningList;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize result tuple slot and assign its rowtype using the first
|
* Initialize result tuple slot and assign its rowtype using the first
|
||||||
@ -1821,9 +1821,9 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
|
|||||||
/*
|
/*
|
||||||
* Build a projection for each leaf partition rel. Note that we
|
* Build a projection for each leaf partition rel. Note that we
|
||||||
* didn't build the returningList for each partition within the
|
* didn't build the returningList for each partition within the
|
||||||
* planner, but simple translation of the varattnos for each
|
* planner, but simple translation of the varattnos for each partition
|
||||||
* partition will suffice. This only occurs for the INSERT case;
|
* will suffice. This only occurs for the INSERT case; UPDATE/DELETE
|
||||||
* UPDATE/DELETE are handled above.
|
* are handled above.
|
||||||
*/
|
*/
|
||||||
resultRelInfo = mtstate->mt_partitions;
|
resultRelInfo = mtstate->mt_partitions;
|
||||||
returningList = linitial(node->returningLists);
|
returningList = linitial(node->returningLists);
|
||||||
@ -2095,7 +2095,8 @@ ExecEndModifyTable(ModifyTableState *node)
|
|||||||
resultRelInfo);
|
resultRelInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close all the partitioned tables, leaf partitions, and their indices
|
/*
|
||||||
|
* Close all the partitioned tables, leaf partitions, and their indices
|
||||||
*
|
*
|
||||||
* Remember node->mt_partition_dispatch_info[0] corresponds to the root
|
* Remember node->mt_partition_dispatch_info[0] corresponds to the root
|
||||||
* partitioned table, which we must not try to close, because it is the
|
* partitioned table, which we must not try to close, because it is the
|
||||||
|
@ -1431,7 +1431,7 @@ pg_get_partkeydef(PG_FUNCTION_ARGS)
|
|||||||
Oid relid = PG_GETARG_OID(0);
|
Oid relid = PG_GETARG_OID(0);
|
||||||
|
|
||||||
PG_RETURN_TEXT_P(string_to_text(pg_get_partkeydef_worker(relid,
|
PG_RETURN_TEXT_P(string_to_text(pg_get_partkeydef_worker(relid,
|
||||||
PRETTYFLAG_INDENT)));
|
PRETTYFLAG_INDENT)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1440,7 +1440,7 @@ pg_get_partkeydef(PG_FUNCTION_ARGS)
|
|||||||
static char *
|
static char *
|
||||||
pg_get_partkeydef_worker(Oid relid, int prettyFlags)
|
pg_get_partkeydef_worker(Oid relid, int prettyFlags)
|
||||||
{
|
{
|
||||||
Form_pg_partitioned_table form;
|
Form_pg_partitioned_table form;
|
||||||
HeapTuple tuple;
|
HeapTuple tuple;
|
||||||
oidvector *partclass;
|
oidvector *partclass;
|
||||||
oidvector *partcollation;
|
oidvector *partcollation;
|
||||||
@ -1476,8 +1476,8 @@ pg_get_partkeydef_worker(Oid relid, int prettyFlags)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the expressions, if any. (NOTE: we do not use the relcache
|
* Get the expressions, if any. (NOTE: we do not use the relcache
|
||||||
* versions of the expressions, because we want to display non-const-folded
|
* versions of the expressions, because we want to display
|
||||||
* expressions.)
|
* non-const-folded expressions.)
|
||||||
*/
|
*/
|
||||||
if (!heap_attisnull(tuple, Anum_pg_partitioned_table_partexprs))
|
if (!heap_attisnull(tuple, Anum_pg_partitioned_table_partexprs))
|
||||||
{
|
{
|
||||||
@ -1486,14 +1486,14 @@ pg_get_partkeydef_worker(Oid relid, int prettyFlags)
|
|||||||
char *exprsString;
|
char *exprsString;
|
||||||
|
|
||||||
exprsDatum = SysCacheGetAttr(PARTRELID, tuple,
|
exprsDatum = SysCacheGetAttr(PARTRELID, tuple,
|
||||||
Anum_pg_partitioned_table_partexprs, &isnull);
|
Anum_pg_partitioned_table_partexprs, &isnull);
|
||||||
Assert(!isnull);
|
Assert(!isnull);
|
||||||
exprsString = TextDatumGetCString(exprsDatum);
|
exprsString = TextDatumGetCString(exprsDatum);
|
||||||
partexprs = (List *) stringToNode(exprsString);
|
partexprs = (List *) stringToNode(exprsString);
|
||||||
|
|
||||||
if (!IsA(partexprs, List))
|
if (!IsA(partexprs, List))
|
||||||
elog(ERROR, "unexpected node type found in partexprs: %d",
|
elog(ERROR, "unexpected node type found in partexprs: %d",
|
||||||
(int) nodeTag(partexprs));
|
(int) nodeTag(partexprs));
|
||||||
|
|
||||||
pfree(exprsString);
|
pfree(exprsString);
|
||||||
}
|
}
|
||||||
@ -1515,7 +1515,7 @@ pg_get_partkeydef_worker(Oid relid, int prettyFlags)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
elog(ERROR, "unexpected partition strategy: %d",
|
elog(ERROR, "unexpected partition strategy: %d",
|
||||||
(int) form->partstrat);
|
(int) form->partstrat);
|
||||||
}
|
}
|
||||||
|
|
||||||
appendStringInfo(&buf, " (");
|
appendStringInfo(&buf, " (");
|
||||||
@ -8454,8 +8454,8 @@ get_rule_expr(Node *node, deparse_context *context,
|
|||||||
case T_PartitionBoundSpec:
|
case T_PartitionBoundSpec:
|
||||||
{
|
{
|
||||||
PartitionBoundSpec *spec = (PartitionBoundSpec *) node;
|
PartitionBoundSpec *spec = (PartitionBoundSpec *) node;
|
||||||
ListCell *cell;
|
ListCell *cell;
|
||||||
char *sep;
|
char *sep;
|
||||||
|
|
||||||
switch (spec->strategy)
|
switch (spec->strategy)
|
||||||
{
|
{
|
||||||
@ -8465,9 +8465,9 @@ get_rule_expr(Node *node, deparse_context *context,
|
|||||||
appendStringInfoString(buf, "FOR VALUES");
|
appendStringInfoString(buf, "FOR VALUES");
|
||||||
appendStringInfoString(buf, " IN (");
|
appendStringInfoString(buf, " IN (");
|
||||||
sep = "";
|
sep = "";
|
||||||
foreach (cell, spec->listdatums)
|
foreach(cell, spec->listdatums)
|
||||||
{
|
{
|
||||||
Const *val = lfirst(cell);
|
Const *val = lfirst(cell);
|
||||||
|
|
||||||
appendStringInfoString(buf, sep);
|
appendStringInfoString(buf, sep);
|
||||||
get_const_expr(val, context, -1);
|
get_const_expr(val, context, -1);
|
||||||
@ -8487,10 +8487,10 @@ get_rule_expr(Node *node, deparse_context *context,
|
|||||||
appendStringInfoString(buf, " FROM");
|
appendStringInfoString(buf, " FROM");
|
||||||
appendStringInfoString(buf, " (");
|
appendStringInfoString(buf, " (");
|
||||||
sep = "";
|
sep = "";
|
||||||
foreach (cell, spec->lowerdatums)
|
foreach(cell, spec->lowerdatums)
|
||||||
{
|
{
|
||||||
PartitionRangeDatum *datum = lfirst(cell);
|
PartitionRangeDatum *datum = lfirst(cell);
|
||||||
Const *val;
|
Const *val;
|
||||||
|
|
||||||
appendStringInfoString(buf, sep);
|
appendStringInfoString(buf, sep);
|
||||||
if (datum->infinite)
|
if (datum->infinite)
|
||||||
@ -8507,10 +8507,10 @@ get_rule_expr(Node *node, deparse_context *context,
|
|||||||
appendStringInfoString(buf, " TO");
|
appendStringInfoString(buf, " TO");
|
||||||
appendStringInfoString(buf, " (");
|
appendStringInfoString(buf, " (");
|
||||||
sep = "";
|
sep = "";
|
||||||
foreach (cell, spec->upperdatums)
|
foreach(cell, spec->upperdatums)
|
||||||
{
|
{
|
||||||
PartitionRangeDatum *datum = lfirst(cell);
|
PartitionRangeDatum *datum = lfirst(cell);
|
||||||
Const *val;
|
Const *val;
|
||||||
|
|
||||||
appendStringInfoString(buf, sep);
|
appendStringInfoString(buf, sep);
|
||||||
if (datum->infinite)
|
if (datum->infinite)
|
||||||
|
@ -136,12 +136,12 @@ extern void CheckAttributeType(const char *attname,
|
|||||||
|
|
||||||
/* pg_partitioned_table catalog manipulation functions */
|
/* pg_partitioned_table catalog manipulation functions */
|
||||||
extern void StorePartitionKey(Relation rel,
|
extern void StorePartitionKey(Relation rel,
|
||||||
char strategy,
|
char strategy,
|
||||||
int16 partnatts,
|
int16 partnatts,
|
||||||
AttrNumber *partattrs,
|
AttrNumber *partattrs,
|
||||||
List *partexprs,
|
List *partexprs,
|
||||||
Oid *partopclass,
|
Oid *partopclass,
|
||||||
Oid *partcollation);
|
Oid *partcollation);
|
||||||
extern void RemovePartitionKeyByRelId(Oid relid);
|
extern void RemovePartitionKeyByRelId(Oid relid);
|
||||||
extern void StorePartitionBound(Relation rel, Relation parent, Node *bound);
|
extern void StorePartitionBound(Relation rel, Relation parent, Node *bound);
|
||||||
|
|
||||||
|
@ -323,7 +323,7 @@ DECLARE_UNIQUE_INDEX(pg_replication_origin_roname_index, 6002, on pg_replication
|
|||||||
#define ReplicationOriginNameIndex 6002
|
#define ReplicationOriginNameIndex 6002
|
||||||
|
|
||||||
DECLARE_UNIQUE_INDEX(pg_partitioned_table_partrelid_index, 3351, on pg_partitioned_table using btree(partrelid oid_ops));
|
DECLARE_UNIQUE_INDEX(pg_partitioned_table_partrelid_index, 3351, on pg_partitioned_table using btree(partrelid oid_ops));
|
||||||
#define PartitionedRelidIndexId 3351
|
#define PartitionedRelidIndexId 3351
|
||||||
|
|
||||||
DECLARE_UNIQUE_INDEX(pg_publication_oid_index, 6110, on pg_publication using btree(oid oid_ops));
|
DECLARE_UNIQUE_INDEX(pg_publication_oid_index, 6110, on pg_publication using btree(oid oid_ops));
|
||||||
#define PublicationObjectIndexId 6110
|
#define PublicationObjectIndexId 6110
|
||||||
|
@ -32,9 +32,9 @@ typedef struct PartitionBoundInfoData *PartitionBoundInfo;
|
|||||||
*/
|
*/
|
||||||
typedef struct PartitionDescData
|
typedef struct PartitionDescData
|
||||||
{
|
{
|
||||||
int nparts; /* Number of partitions */
|
int nparts; /* Number of partitions */
|
||||||
Oid *oids; /* OIDs of partitions */
|
Oid *oids; /* OIDs of partitions */
|
||||||
PartitionBoundInfo boundinfo; /* collection of partition bounds */
|
PartitionBoundInfo boundinfo; /* collection of partition bounds */
|
||||||
} PartitionDescData;
|
} PartitionDescData;
|
||||||
|
|
||||||
typedef struct PartitionDescData *PartitionDesc;
|
typedef struct PartitionDescData *PartitionDesc;
|
||||||
@ -59,13 +59,13 @@ typedef struct PartitionDescData *PartitionDesc;
|
|||||||
*/
|
*/
|
||||||
typedef struct PartitionDispatchData
|
typedef struct PartitionDispatchData
|
||||||
{
|
{
|
||||||
Relation reldesc;
|
Relation reldesc;
|
||||||
PartitionKey key;
|
PartitionKey key;
|
||||||
List *keystate; /* list of ExprState */
|
List *keystate; /* list of ExprState */
|
||||||
PartitionDesc partdesc;
|
PartitionDesc partdesc;
|
||||||
TupleTableSlot *tupslot;
|
TupleTableSlot *tupslot;
|
||||||
TupleConversionMap *tupmap;
|
TupleConversionMap *tupmap;
|
||||||
int *indexes;
|
int *indexes;
|
||||||
} PartitionDispatchData;
|
} PartitionDispatchData;
|
||||||
|
|
||||||
typedef struct PartitionDispatchData *PartitionDispatch;
|
typedef struct PartitionDispatchData *PartitionDispatch;
|
||||||
@ -75,7 +75,7 @@ extern bool partition_bounds_equal(PartitionKey key,
|
|||||||
PartitionBoundInfo p1, PartitionBoundInfo p2);
|
PartitionBoundInfo p1, PartitionBoundInfo p2);
|
||||||
|
|
||||||
extern void check_new_partition_bound(char *relname, Relation parent, Node *bound);
|
extern void check_new_partition_bound(char *relname, Relation parent, Node *bound);
|
||||||
extern Oid get_partition_parent(Oid relid);
|
extern Oid get_partition_parent(Oid relid);
|
||||||
extern List *get_qual_from_partbound(Relation rel, Relation parent, Node *bound);
|
extern List *get_qual_from_partbound(Relation rel, Relation parent, Node *bound);
|
||||||
extern List *map_partition_varattnos(List *expr, int target_varno,
|
extern List *map_partition_varattnos(List *expr, int target_varno,
|
||||||
Relation partrel, Relation parent);
|
Relation partrel, Relation parent);
|
||||||
@ -86,7 +86,7 @@ extern PartitionDispatch *RelationGetPartitionDispatchInfo(Relation rel,
|
|||||||
int lockmode, int *num_parted,
|
int lockmode, int *num_parted,
|
||||||
List **leaf_part_oids);
|
List **leaf_part_oids);
|
||||||
extern int get_partition_for_tuple(PartitionDispatch *pd,
|
extern int get_partition_for_tuple(PartitionDispatch *pd,
|
||||||
TupleTableSlot *slot,
|
TupleTableSlot *slot,
|
||||||
EState *estate,
|
EState *estate,
|
||||||
Oid *failed_at);
|
Oid *failed_at);
|
||||||
#endif /* PARTITION_H */
|
#endif /* PARTITION_H */
|
||||||
|
@ -70,7 +70,7 @@ CATALOG(pg_class,1259) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83) BKI_SCHEMA_MACRO
|
|||||||
* not */
|
* not */
|
||||||
bool relispopulated; /* matview currently holds query results */
|
bool relispopulated; /* matview currently holds query results */
|
||||||
char relreplident; /* see REPLICA_IDENTITY_xxx constants */
|
char relreplident; /* see REPLICA_IDENTITY_xxx constants */
|
||||||
bool relispartition; /* is relation a partition? */
|
bool relispartition; /* is relation a partition? */
|
||||||
TransactionId relfrozenxid; /* all Xids < this are frozen in this rel */
|
TransactionId relfrozenxid; /* all Xids < this are frozen in this rel */
|
||||||
TransactionId relminmxid; /* all multixacts in this rel are >= this.
|
TransactionId relminmxid; /* all multixacts in this rel are >= this.
|
||||||
* this is really a MultiXactId */
|
* this is really a MultiXactId */
|
||||||
|
@ -1982,7 +1982,7 @@ DATA(insert OID = 1642 ( pg_get_userbyid PGNSP PGUID 12 1 0 0 0 f f f f t f
|
|||||||
DESCR("role name by OID (with fallback)");
|
DESCR("role name by OID (with fallback)");
|
||||||
DATA(insert OID = 1643 ( pg_get_indexdef PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 25 "26" _null_ _null_ _null_ _null_ _null_ pg_get_indexdef _null_ _null_ _null_ ));
|
DATA(insert OID = 1643 ( pg_get_indexdef PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 25 "26" _null_ _null_ _null_ _null_ _null_ pg_get_indexdef _null_ _null_ _null_ ));
|
||||||
DESCR("index description");
|
DESCR("index description");
|
||||||
DATA(insert OID = 3352 ( pg_get_partkeydef PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 25 "26" _null_ _null_ _null_ _null_ _null_ pg_get_partkeydef _null_ _null_ _null_ ));
|
DATA(insert OID = 3352 ( pg_get_partkeydef PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 25 "26" _null_ _null_ _null_ _null_ _null_ pg_get_partkeydef _null_ _null_ _null_ ));
|
||||||
DESCR("partition key description");
|
DESCR("partition key description");
|
||||||
DATA(insert OID = 1662 ( pg_get_triggerdef PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 25 "26" _null_ _null_ _null_ _null_ _null_ pg_get_triggerdef _null_ _null_ _null_ ));
|
DATA(insert OID = 1662 ( pg_get_triggerdef PGNSP PGUID 12 1 0 0 0 f f f f t f s s 1 0 25 "26" _null_ _null_ _null_ _null_ _null_ pg_get_triggerdef _null_ _null_ _null_ ));
|
||||||
DESCR("trigger description");
|
DESCR("trigger description");
|
||||||
|
@ -42,7 +42,7 @@ extern bool CheckIndexCompatible(Oid oldId,
|
|||||||
List *attributeList,
|
List *attributeList,
|
||||||
List *exclusionOpNames);
|
List *exclusionOpNames);
|
||||||
extern Oid GetDefaultOpClass(Oid type_id, Oid am_id);
|
extern Oid GetDefaultOpClass(Oid type_id, Oid am_id);
|
||||||
extern Oid ResolveOpClass(List *opclass, Oid attrType,
|
extern Oid ResolveOpClass(List *opclass, Oid attrType,
|
||||||
char *accessMethodName, Oid accessMethodId);
|
char *accessMethodName, Oid accessMethodId);
|
||||||
|
|
||||||
/* commands/functioncmds.c */
|
/* commands/functioncmds.c */
|
||||||
|
@ -715,11 +715,11 @@ typedef struct XmlSerialize
|
|||||||
typedef struct PartitionElem
|
typedef struct PartitionElem
|
||||||
{
|
{
|
||||||
NodeTag type;
|
NodeTag type;
|
||||||
char *name; /* name of column to partition on, or NULL */
|
char *name; /* name of column to partition on, or NULL */
|
||||||
Node *expr; /* expression to partition on, or NULL */
|
Node *expr; /* expression to partition on, or NULL */
|
||||||
List *collation; /* name of collation; NIL = default */
|
List *collation; /* name of collation; NIL = default */
|
||||||
List *opclass; /* name of desired opclass; NIL = default */
|
List *opclass; /* name of desired opclass; NIL = default */
|
||||||
int location; /* token location, or -1 if unknown */
|
int location; /* token location, or -1 if unknown */
|
||||||
} PartitionElem;
|
} PartitionElem;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -728,9 +728,9 @@ typedef struct PartitionElem
|
|||||||
typedef struct PartitionSpec
|
typedef struct PartitionSpec
|
||||||
{
|
{
|
||||||
NodeTag type;
|
NodeTag type;
|
||||||
char *strategy; /* partitioning strategy ('list' or 'range') */
|
char *strategy; /* partitioning strategy ('list' or 'range') */
|
||||||
List *partParams; /* List of PartitionElems */
|
List *partParams; /* List of PartitionElems */
|
||||||
int location; /* token location, or -1 if unknown */
|
int location; /* token location, or -1 if unknown */
|
||||||
} PartitionSpec;
|
} PartitionSpec;
|
||||||
|
|
||||||
#define PARTITION_STRATEGY_LIST 'l'
|
#define PARTITION_STRATEGY_LIST 'l'
|
||||||
@ -749,8 +749,8 @@ typedef struct PartitionBoundSpec
|
|||||||
List *listdatums;
|
List *listdatums;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Range partition lower and upper bounds; each member of the lists
|
* Range partition lower and upper bounds; each member of the lists is a
|
||||||
* is a PartitionRangeDatum (see below).
|
* PartitionRangeDatum (see below).
|
||||||
*/
|
*/
|
||||||
List *lowerdatums;
|
List *lowerdatums;
|
||||||
List *upperdatums;
|
List *upperdatums;
|
||||||
|
@ -124,11 +124,11 @@ typedef struct RelationData
|
|||||||
List *rd_fkeylist; /* list of ForeignKeyCacheInfo (see below) */
|
List *rd_fkeylist; /* list of ForeignKeyCacheInfo (see below) */
|
||||||
bool rd_fkeyvalid; /* true if list has been computed */
|
bool rd_fkeyvalid; /* true if list has been computed */
|
||||||
|
|
||||||
MemoryContext rd_partkeycxt; /* private memory cxt for the below */
|
MemoryContext rd_partkeycxt; /* private memory cxt for the below */
|
||||||
struct PartitionKeyData *rd_partkey; /* partition key, or NULL */
|
struct PartitionKeyData *rd_partkey; /* partition key, or NULL */
|
||||||
MemoryContext rd_pdcxt; /* private context for partdesc */
|
MemoryContext rd_pdcxt; /* private context for partdesc */
|
||||||
struct PartitionDescData *rd_partdesc; /* partitions, or NULL */
|
struct PartitionDescData *rd_partdesc; /* partitions, or NULL */
|
||||||
List *rd_partcheck; /* partition CHECK quals */
|
List *rd_partcheck; /* partition CHECK quals */
|
||||||
|
|
||||||
/* data managed by RelationGetIndexList: */
|
/* data managed by RelationGetIndexList: */
|
||||||
List *rd_indexlist; /* list of OIDs of indexes on relation */
|
List *rd_indexlist; /* list of OIDs of indexes on relation */
|
||||||
|
Reference in New Issue
Block a user