69 bool include_noinherit,
71 bool include_partition);
140 if (!(relation->
rd_rel->relkind == RELKIND_FOREIGN_TABLE ||
141 relation->
rd_rel->relkind == RELKIND_PARTITIONED_TABLE))
143 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
144 errmsg(
"cannot open relation \"%s\"",
152 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
153 errmsg(
"cannot access temporary or unlogged relations during recovery")));
160 rel->attr_needed = (
Relids *)
162 rel->attr_widths = (
int32 *)
174 if (!inhparent || relation->
rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
180 if (attr->attnotnull)
190 Assert(!attr->attisdropped);
215 if ((inhparent && relation->
rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
219 hasindex = relation->
rd_rel->relhasindex;
237 lmode =
root->simple_rte_array[varno]->rellockmode;
239 foreach(l, indexoidlist)
263 if (!
index->indisvalid)
274 if (
index->indcheckxmin &&
278 root->glob->transientPlan =
true;
292 info->indexkeys = (
int *)
palloc(
sizeof(
int) * ncolumns);
293 info->indexcollations = (
Oid *)
palloc(
sizeof(
Oid) * nkeycolumns);
294 info->opfamily = (
Oid *)
palloc(
sizeof(
Oid) * nkeycolumns);
295 info->opcintype = (
Oid *)
palloc(
sizeof(
Oid) * nkeycolumns);
296 info->canreturn = (
bool *)
palloc(
sizeof(
bool) * ncolumns);
298 for (
i = 0;
i < ncolumns;
i++)
300 info->indexkeys[
i] =
index->indkey.values[
i];
304 for (
i = 0;
i < nkeycolumns;
i++)
317 if (indexRelation->
rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
320 amroutine = indexRelation->
rd_indam;
340 if (info->
relam == BTREE_AM_OID)
348 info->sortopfamily = info->opfamily;
349 info->reverse_sort = (
bool *)
palloc(
sizeof(
bool) * nkeycolumns);
350 info->nulls_first = (
bool *)
palloc(
sizeof(
bool) * nkeycolumns);
352 for (
i = 0;
i < nkeycolumns;
i++)
356 info->reverse_sort[
i] = (opt & INDOPTION_DESC) != 0;
357 info->nulls_first[
i] = (opt & INDOPTION_NULLS_FIRST) != 0;
377 info->sortopfamily = (
Oid *)
palloc(
sizeof(
Oid) * nkeycolumns);
378 info->reverse_sort = (
bool *)
palloc(
sizeof(
bool) * nkeycolumns);
379 info->nulls_first = (
bool *)
palloc(
sizeof(
bool) * nkeycolumns);
381 for (
i = 0;
i < nkeycolumns;
i++)
389 info->reverse_sort[
i] = (opt & INDOPTION_DESC) != 0;
390 info->nulls_first[
i] = (opt & INDOPTION_NULLS_FIRST) != 0;
401 btopcintype == info->opcintype[
i] &&
405 info->sortopfamily[
i] = btopfamily;
410 info->sortopfamily = NULL;
411 info->reverse_sort = NULL;
412 info->nulls_first = NULL;
419 info->sortopfamily = NULL;
420 info->reverse_sort = NULL;
421 info->nulls_first = NULL;
436 info->sortopfamily = NULL;
437 info->reverse_sort = NULL;
438 info->nulls_first = NULL;
449 if (info->indexprs && varno != 1)
451 if (info->
indpred && varno != 1)
471 if (indexRelation->
rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
518 indexinfos =
lcons(info, indexinfos);
529 if (relation->
rd_rel->relkind == RELKIND_FOREIGN_TABLE)
538 (
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
539 errmsg(
"access to non-system foreign table is restricted")));
548 rel->fdwroutine = NULL;
564 if (inhparent && relation->
rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
575 (*get_relation_info_hook) (
root, relationObjectId, inhparent, rel);
633 foreach(lc, cachedfkeys)
658 if (rti == rel->
relid)
666 memcpy(info->conkey, cachedfk->conkey,
sizeof(info->conkey));
667 memcpy(info->confkey, cachedfk->confkey,
sizeof(info->confkey));
668 memcpy(info->conpfeqop, cachedfk->conpfeqop,
sizeof(info->conpfeqop));
738 varno =
root->parse->resultRelation;
766 (
errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
767 errmsg(
"whole row unique index inference specifications are not supported")));
783 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
784 errmsg(
"constraint in ON CONFLICT clause has no associated index")));
793 foreach(l, indexList)
812 idxRel =
index_open(indexoid, rte->rellockmode);
815 if (!idxForm->indisvalid)
829 if (indexOidFromConstraint == idxForm->indexrelid)
833 (
errcode(ERRCODE_WRONG_OBJECT_TYPE),
834 errmsg(
"ON CONFLICT DO UPDATE not supported with exclusion constraints")));
836 results =
lappend_oid(results, idxForm->indexrelid);
842 else if (indexOidFromConstraint !=
InvalidOid)
853 if (!idxForm->indisunique)
860 if (idxForm->indisexclusion)
865 for (natt = 0; natt < idxForm->indnkeyatts; natt++)
867 int attno = idxRel->
rd_index->indkey.values[natt];
875 if (!
bms_equal(indexedAttrs, inferAttrs))
880 if (idxExprs && varno != 1)
934 if (predExprs && varno != 1)
940 results =
lappend_oid(results, idxForm->indexrelid);
950 (
errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
951 errmsg(
"there is no unique or exclusion constraint matching the ON CONFLICT specification")));
1008 for (natt = 1; natt <= idxRel->
rd_att->
natts; natt++)
1013 int attno = idxRel->
rd_index->indkey.values[natt - 1];
1019 (inferopfamily != opfamily || inferopcinputtype != opcinputtype))
1035 if (((
Var *) elem->
expr)->varattno == attno)
1038 else if (attno == 0)
1040 Node *nattExpr =
list_nth(idxExprs, (natt - 1) - nplain);
1067 BlockNumber *pages,
double *tuples,
double *allvisfrac)
1075 if (RELKIND_HAS_TABLE_AM(rel->
rd_rel->relkind))
1080 else if (rel->
rd_rel->relkind == RELKIND_INDEX)
1102 reltuples = (
double) rel->
rd_rel->reltuples;
1118 if (reltuples >= 0 && relpages > 0)
1119 density = reltuples / (double) relpages;
1147 *tuples = rint(density * (
double) curpages);
1155 if (relallvisible == 0 || curpages <= 0)
1157 else if ((
double) relallvisible >= curpages)
1160 *allvisfrac = (double) relallvisible / curpages;
1170 *pages = rel->
rd_rel->relpages;
1171 *tuples = rel->
rd_rel->reltuples;
1193 int64 tuple_width = 0;
1201 if (att->attisdropped)
1205 if (attr_widths != NULL && attr_widths[
i] > 0)
1207 tuple_width += attr_widths[
i];
1213 if (item_width <= 0)
1218 if (attr_widths != NULL)
1219 attr_widths[
i] = item_width;
1220 tuple_width += item_width;
1275 bool include_noinherit,
1276 bool include_notnull,
1277 bool include_partition)
1295 for (
i = 0;
i < num_check;
i++)
1342 for (
i = 1;
i <= natts;
i++)
1346 if (att->attnotnull && !att->attisdropped)
1363 ntest->argisrow =
false;
1365 result =
lappend(result, ntest);
1374 if (include_partition && relation->
rd_rel->relispartition)
1394 Oid statOid,
bool inh,
1413 info->
inherit = dataForm->stxdinherit;
1415 info->
kind = STATS_EXT_NDISTINCT;
1417 info->
exprs = exprs;
1419 *stainfos =
lappend(*stainfos, info);
1427 info->
inherit = dataForm->stxdinherit;
1429 info->
kind = STATS_EXT_DEPENDENCIES;
1431 info->
exprs = exprs;
1433 *stainfos =
lappend(*stainfos, info);
1441 info->
inherit = dataForm->stxdinherit;
1443 info->
kind = STATS_EXT_MCV;
1445 info->
exprs = exprs;
1447 *stainfos =
lappend(*stainfos, info);
1455 info->
inherit = dataForm->stxdinherit;
1457 info->
kind = STATS_EXT_EXPRESSIONS;
1459 info->
exprs = exprs;
1461 *stainfos =
lappend(*stainfos, info);
1485 foreach(l, statoidlist)
1496 elog(
ERROR,
"cache lookup failed for statistics object %u", statOid);
1504 for (
i = 0;
i < staForm->stxkeys.dim1;
i++)
1522 Anum_pg_statistic_ext_stxexprs, &isnull);
1585 bool include_noinherit;
1586 bool include_notnull;
1587 bool include_partition =
false;
1588 List *safe_restrictions;
1589 List *constraint_pred;
1590 List *safe_constraints;
1618 if (clause &&
IsA(clause,
Const) &&
1619 (((
Const *) clause)->constisnull ||
1655 include_partition =
true;
1667 safe_restrictions =
NIL;
1673 safe_restrictions =
lappend(safe_restrictions, rinfo->
clause);
1695 include_noinherit = !rte->
inh;
1704 include_notnull = (!rte->
inh || rte->relkind == RELKIND_PARTITIONED_TABLE);
1721 safe_constraints =
NIL;
1722 foreach(lc, constraint_pred)
1727 safe_constraints =
lappend(safe_constraints, pred);
1792 for (attrno = 1; attrno <= numattrs; attrno++)
1797 if (att_tup->attisdropped || att_tup->atthasmissing)
1808 att_tup->attcollation,
1874 elog(
ERROR,
"unsupported RTE kind %d in build_physical_tlist",
1902 for (
i = 0;
i <
index->ncolumns;
i++)
1904 int indexkey =
index->indexkeys[
i];
1921 att_tup->attcollation,
1927 if (indexpr_item == NULL)
1928 elog(
ERROR,
"wrong number of index expressions");
1930 indexpr_item =
lnext(
index->indexprs, indexpr_item);
1939 if (indexpr_item != NULL)
1940 elog(
ERROR,
"wrong number of index expressions");
1978 if (result < 0.0 || result > 1.0)
1979 elog(
ERROR,
"invalid restriction selectivity: %f", result);
2019 if (result < 0.0 || result > 1.0)
2020 elog(
ERROR,
"invalid join selectivity: %f", result);
2058 req.
type = T_SupportRequestSelectivity;
2074 if (sresult != &req)
2105 elog(
ERROR,
"cache lookup failed for function %u", funcid);
2113 req.
type = T_SupportRequestCost;
2126 if (sresult == &req)
2166 elog(
ERROR,
"cache lookup failed for function %u", funcid);
2169 Assert(procform->proretset);
2176 req.
type = T_SupportRequestRows;
2187 if (sresult == &req)
2196 result = procform->prorows;
2232 if (
index->unique &&
2233 index->nkeycolumns == 1 &&
2234 index->indexkeys[0] == attno &&
2253 bool result =
false;
2284 elog(
ERROR,
"unrecognized CmdType: %d", (
int) event);
2303 bool result =
false;
2338 constr = tupdesc->
constr;
2364 return dependentCols;
2381 if (
root->glob->partition_directory == NULL)
2383 root->glob->partition_directory =
2390 Assert(partdesc != NULL && rel->part_scheme != NULL);
2417 foreach(lc,
root->part_schemes)
2419 part_scheme =
lfirst(lc);
2428 sizeof(
Oid) * partnatts) != 0 ||
2430 sizeof(
Oid) * partnatts) != 0 ||
2432 sizeof(
Oid) * partnatts) != 0)
2440 sizeof(
int16) * partnatts) == 0);
2442 sizeof(
bool) * partnatts) == 0);
2451 #ifdef USE_ASSERT_CHECKING
2473 sizeof(
Oid) * partnatts);
2477 sizeof(
Oid) * partnatts);
2481 sizeof(
Oid) * partnatts);
2485 sizeof(
int16) * partnatts);
2489 sizeof(
bool) * partnatts);
2493 for (
i = 0;
i < partnatts;
i++)
2529 for (cnt = 0; cnt < partnatts; cnt++)
2547 elog(
ERROR,
"wrong number of partition key expressions");
2559 rel->partexprs = partexprs;
2567 rel->nullable_partexprs = (
List **)
palloc0(
sizeof(
List *) * partnatts);
2596 if (rel->
relid != 1)
#define InvalidAttrNumber
bool bms_equal(const Bitmapset *a, const Bitmapset *b)
void bms_free(Bitmapset *a)
Bitmapset * bms_add_member(Bitmapset *a, int x)
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
Bitmapset * bms_copy(const Bitmapset *a)
#define RelationGetNumberOfBlocks(reln)
#define SizeOfPageHeaderData
#define TextDatumGetCString(d)
#define Assert(condition)
#define OidIsValid(objectId)
bool IsSystemRelation(Relation relation)
bool contain_mutable_functions(Node *clause)
Node * eval_const_expressions(PlannerInfo *root, Node *node)
@ CONSTRAINT_EXCLUSION_OFF
@ CONSTRAINT_EXCLUSION_PARTITION
@ CONSTRAINT_EXCLUSION_ON
int32 clamp_width_est(int64 tuple_width)
int errcode(int sqlerrcode)
int errmsg(const char *fmt,...)
#define ereport(elevel,...)
bool equal(const void *a, const void *b)
bool statext_is_kind_built(HeapTuple htup, char type)
Datum OidFunctionCall5Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4, Datum arg5)
Datum OidFunctionCall4Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2, Datum arg3, Datum arg4)
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
#define OidFunctionCall1(functionId, arg1)
FdwRoutine * GetFdwRoutineForRelation(Relation relation, bool makecopy)
Oid GetForeignServerIdByRelId(Oid relid)
const FormData_pg_attribute * SystemAttributeDefinition(AttrNumber attno)
#define HeapTupleIsValid(tuple)
#define SizeofHeapTupleHeader
#define HeapTupleHeaderGetXmin(tup)
void index_close(Relation relation, LOCKMODE lockmode)
bool index_can_return(Relation indexRelation, int attno)
Relation index_open(Oid relationId, LOCKMODE lockmode)
if(TABLE==NULL||TABLE_index==NULL)
struct ItemIdData ItemIdData
List * lappend(List *list, void *datum)
List * lappend_oid(List *list, Oid datum)
void list_free(List *list)
List * list_concat(List *list1, const List *list2)
bool list_member(const List *list, const void *datum)
List * lcons(void *datum, List *list)
List * list_difference(const List *list1, const List *list2)
RegProcedure get_oprrest(Oid opno)
Oid get_constraint_index(Oid conoid)
Oid get_opclass_input_type(Oid opclass)
Oid get_opclass_family(Oid opclass)
RegProcedure get_func_support(Oid funcid)
int32 get_attavgwidth(Oid relid, AttrNumber attnum)
RegProcedure get_oprjoin(Oid opno)
Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, int16 strategy)
bool get_ordering_op_properties(Oid opno, Oid *opfamily, Oid *opcintype, int16 *strategy)
int32 get_typavgwidth(Oid typid, int32 typmod)
Var * makeVarFromTargetEntry(int varno, TargetEntry *tle)
List * make_ands_implicit(Expr *clause)
TargetEntry * makeTargetEntry(Expr *expr, AttrNumber resno, char *resname, bool resjunk)
Var * makeVar(int varno, AttrNumber varattno, Oid vartype, int32 vartypmod, Oid varcollid, Index varlevelsup)
void pfree(void *pointer)
void * palloc0(Size size)
MemoryContext CurrentMemoryContext
void fix_opfuncids(Node *node)
#define IsA(nodeptr, _type_)
void expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up, int location, bool include_dropped, List **colnames, List **colvars)
#define rt_fetch(rangetable_index, rangetable)
List * RelationGetPartitionQual(Relation rel)
PartitionKey RelationGetPartitionKey(Relation rel)
PartitionDirectory CreatePartitionDirectory(MemoryContext mcxt, bool omit_detached)
PartitionDesc PartitionDirectoryLookup(PartitionDirectory pdir, Relation rel)
#define IS_SIMPLE_REL(rel)
#define planner_rt_fetch(rti, root)
struct PartitionSchemeData * PartitionScheme
@ RELOPT_OTHER_MEMBER_REL
#define AMFLAG_HAS_TID_RANGE
FormData_pg_attribute * Form_pg_attribute
int errdetail_relkind_not_supported(char relkind)
FormData_pg_index * Form_pg_index
static int list_length(const List *l)
static ListCell * list_head(const List *l)
static void * list_nth(const List *list, int n)
static ListCell * lnext(const List *l, const ListCell *c)
FormData_pg_proc * Form_pg_proc
FormData_pg_statistic_ext * Form_pg_statistic_ext
FormData_pg_statistic_ext_data * Form_pg_statistic_ext_data
void estimate_rel_size(Relation rel, int32 *attr_widths, BlockNumber *pages, double *tuples, double *allvisfrac)
Bitmapset * get_dependent_generated_columns(PlannerInfo *root, Index rti, Bitmapset *target_cols)
int32 get_rel_data_width(Relation rel, int32 *attr_widths)
bool has_stored_generated_columns(PlannerInfo *root, Index rti)
static void get_relation_foreign_keys(PlannerInfo *root, RelOptInfo *rel, Relation relation, bool inhparent)
bool relation_excluded_by_constraints(PlannerInfo *root, RelOptInfo *rel, RangeTblEntry *rte)
double get_function_rows(PlannerInfo *root, Oid funcid, Node *node)
bool has_row_triggers(PlannerInfo *root, Index rti, CmdType event)
static List * get_relation_constraints(PlannerInfo *root, Oid relationObjectId, RelOptInfo *rel, bool include_noinherit, bool include_notnull, bool include_partition)
void add_function_cost(PlannerInfo *root, Oid funcid, Node *node, QualCost *cost)
List * build_physical_tlist(PlannerInfo *root, RelOptInfo *rel)
get_relation_info_hook_type get_relation_info_hook
List * infer_arbiter_indexes(PlannerInfo *root)
static void get_relation_statistics_worker(List **stainfos, RelOptInfo *rel, Oid statOid, bool inh, Bitmapset *keys, List *exprs)
Selectivity restriction_selectivity(PlannerInfo *root, Oid operatorid, List *args, Oid inputcollid, int varRelid)
int32 get_relation_data_width(Oid relid, int32 *attr_widths)
static void set_baserel_partition_constraint(Relation relation, RelOptInfo *rel)
static List * build_index_tlist(PlannerInfo *root, IndexOptInfo *index, Relation heapRelation)
static bool infer_collation_opclass_match(InferenceElem *elem, Relation idxRel, List *idxExprs)
static List * get_relation_statistics(RelOptInfo *rel, Relation relation)
static void set_relation_partition_info(PlannerInfo *root, RelOptInfo *rel, Relation relation)
bool has_unique_index(RelOptInfo *rel, AttrNumber attno)
static PartitionScheme find_partition_scheme(PlannerInfo *root, Relation relation)
static void set_baserel_partition_key_exprs(Relation relation, RelOptInfo *rel)
Selectivity join_selectivity(PlannerInfo *root, Oid operatorid, List *args, Oid inputcollid, JoinType jointype, SpecialJoinInfo *sjinfo)
Selectivity function_selectivity(PlannerInfo *root, Oid funcid, List *args, Oid inputcollid, bool is_join, int varRelid, JoinType jointype, SpecialJoinInfo *sjinfo)
void get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, RelOptInfo *rel)
void(* get_relation_info_hook_type)(PlannerInfo *root, Oid relationObjectId, bool inhparent, RelOptInfo *rel)
Expr * expression_planner(Expr *expr)
int restrict_nonsystem_relation_kind
static bool DatumGetBool(Datum X)
static Datum PointerGetDatum(const void *X)
static Datum Int16GetDatum(int16 X)
static Datum BoolGetDatum(bool X)
static float8 DatumGetFloat8(Datum X)
static Datum ObjectIdGetDatum(Oid X)
static Pointer DatumGetPointer(Datum X)
static Datum Int32GetDatum(int32 X)
bool predicate_refuted_by(List *predicate_list, List *clause_list, bool weak)
bool predicate_implied_by(List *predicate_list, List *clause_list, bool weak)
Expr * canonicalize_qual(Expr *qual, bool is_check)
void * stringToNode(const char *str)
#define RelationGetForm(relation)
#define RelationGetRelid(relation)
#define RelationGetParallelWorkers(relation, defaultpw)
#define RelationGetDescr(relation)
#define RelationGetNumberOfAttributes(relation)
#define RelationGetRelationName(relation)
#define RelationIsPermanent(relation)
List * RelationGetIndexList(Relation relation)
List * RelationGetIndexPredicate(Relation relation)
List * RelationGetStatExtList(Relation relation)
List * RelationGetFKeyList(Relation relation)
bytea ** RelationGetIndexAttOptions(Relation relation, bool copy)
List * RelationGetIndexExpressions(Relation relation)
void ChangeVarNodes(Node *node, int rt_index, int new_index, int sublevels_up)
TransactionId TransactionXmin
#define BTLessStrategyNumber
struct EquivalenceClass * eclass[INDEX_MAX_KEYS]
List * rinfos[INDEX_MAX_KEYS]
struct EquivalenceMember * fk_eclass_member[INDEX_MAX_KEYS]
amrestrpos_function amrestrpos
amcostestimate_function amcostestimate
amgettuple_function amgettuple
amgetbitmap_function amgetbitmap
ammarkpos_function ammarkpos
amgettreeheight_function amgettreeheight
void(* amcostestimate)(struct PlannerInfo *, struct IndexPath *, double, Cost *, Cost *, Selectivity *, double *, double *) pg_node_attr(read_write_ignore)
NullTestType nulltesttype
PartitionBoundInfo boundinfo
PartitionStrategy strategy
struct FmgrInfo * partsupfunc
Bitmapset * notnullattnums
const struct TableAmRoutine * rd_tableam
struct IndexAmRoutine * rd_indam
struct HeapTupleData * rd_indextuple
struct PlannerInfo * root
struct PlannerInfo * root
struct PlannerInfo * root
struct SpecialJoinInfo * sjinfo
bool(* scan_getnextslot_tidrange)(TableScanDesc scan, ScanDirection direction, TupleTableSlot *slot)
bool(* scan_bitmap_next_block)(TableScanDesc scan, BlockNumber *blockno, bool *recheck, uint64 *lossy_pages, uint64 *exact_pages)
void(* scan_set_tidrange)(TableScanDesc scan, ItemPointer mintid, ItemPointer maxtid)
bool trig_delete_before_row
bool trig_update_after_row
bool trig_insert_after_row
bool trig_update_before_row
bool trig_delete_after_row
bool trig_insert_before_row
bool has_generated_stored
#define FirstLowInvalidHeapAttributeNumber
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Datum SysCacheGetAttr(int cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
HeapTuple SearchSysCache2(int cacheId, Datum key1, Datum key2)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
static void table_relation_estimate_size(Relation rel, int32 *attr_widths, BlockNumber *pages, double *tuples, double *allvisfrac)
#define RESTRICT_RELKIND_FOREIGN_TABLE
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
#define FirstNormalObjectId
#define TupleDescAttr(tupdesc, i)
void pull_varattnos(Node *node, Index varno, Bitmapset **varattnos)
bool RecoveryInProgress(void)