48#include "utils/fmgroids.h"
64#define RI_MAX_NUMKEYS INDEX_MAX_KEYS
66#define RI_INIT_CONSTRAINTHASHSIZE 64
67#define RI_INIT_QUERYHASHSIZE (RI_INIT_CONSTRAINTHASHSIZE * 4)
69#define RI_KEYS_ALL_NULL 0
70#define RI_KEYS_SOME_NULL 1
71#define RI_KEYS_NONE_NULL 2
75#define RI_PLAN_CHECK_LOOKUPPK 1
76#define RI_PLAN_CHECK_LOOKUPPK_FROM_PK 2
77#define RI_PLAN_LAST_ON_PK RI_PLAN_CHECK_LOOKUPPK_FROM_PK
79#define RI_PLAN_CASCADE_ONDELETE 3
80#define RI_PLAN_CASCADE_ONUPDATE 4
81#define RI_PLAN_NO_ACTION 5
83#define RI_PLAN_RESTRICT 6
84#define RI_PLAN_SETNULL_ONDELETE 7
85#define RI_PLAN_SETNULL_ONUPDATE 8
86#define RI_PLAN_SETDEFAULT_ONDELETE 9
87#define RI_PLAN_SETDEFAULT_ONUPDATE 10
89#define MAX_QUOTED_NAME_LEN (NAMEDATALEN*2+3)
90#define MAX_QUOTED_REL_NAME_LEN (MAX_QUOTED_NAME_LEN*2)
92#define RIAttName(rel, attnum) NameStr(*attnumAttName(rel, attnum))
93#define RIAttType(rel, attnum) attnumTypeId(rel, attnum)
94#define RIAttCollation(rel, attnum) attnumCollationId(rel, attnum)
96#define RI_TRIGTYPE_INSERT 1
97#define RI_TRIGTYPE_UPDATE 2
98#define RI_TRIGTYPE_DELETE 3
214#define RI_FASTPATH_BATCH_SIZE 64
292 int32 constr_queryno);
348 Datum *vals,
char *nulls);
411 switch (
riinfo->confmatchtype)
421 errmsg(
"insert or update on table \"%s\" violates foreign key constraint \"%s\"",
424 errdetail(
"MATCH FULL does not allow mixing of null and nonnull key values."),
556 "SELECT 1 FROM (SELECT %s AS r FROM %s%s x",
589 riinfo->agged_period_contained_by_oper,
726 "SELECT 1 FROM (SELECT %s AS r FROM %s%s x",
758 riinfo->agged_period_contained_by_oper,
998 riinfo->period_intersect_oper,
1031 riinfo->agged_period_contained_by_oper,
1390 elog(
ERROR,
"invalid tgkind passed to ri_set");
1421 if (
riinfo->ndelsetcols != 0)
1433 elog(
ERROR,
"invalid tgkind passed to ri_set");
1601 switch (
riinfo->confmatchtype)
1747 ((pk_rel->
rd_rel->relrowsecurity &&
1750 (
fk_rel->rd_rel->relrowsecurity &&
1788 " FROM %s%s fk LEFT OUTER JOIN %s%s pk ON",
1826 "%sfk.%s IS NOT NULL",
1828 switch (
riinfo->confmatchtype)
1873 elog(
ERROR,
"SPI_prepare returned %s for %s",
1929 errmsg(
"insert or update on table \"%s\" violates foreign key constraint \"%s\"",
1932 errdetail(
"MATCH FULL does not allow mixing of null and nonnull key values."),
2023 " FROM %s%s fk JOIN %s pk ON",
2065 "%sfk.%s IS NOT NULL",
2067 switch (
riinfo->confmatchtype)
2112 elog(
ERROR,
"SPI_prepare returned %s for %s",
2160 slot, tupdesc, 0,
false,
true);
2193 *buffer++ = *
name++;
2208 buffer +=
strlen(buffer);
2262 elog(
ERROR,
"cache lookup failed for collation %u", collation);
2291 int32 constr_queryno)
2312 key->constr_id =
riinfo->constraint_root_id;
2314 key->constr_id =
riinfo->constraint_id;
2315 key->constr_queryno = constr_queryno;
2329 errmsg(
"function \"%s\" was not called by trigger manager",
funcname)));
2381 errmsg(
"no pg_constraint entry for trigger \"%s\" on table \"%s\"",
2383 errhint(
"Remove this referential integrity trigger and its mates, then do ALTER TABLE ADD CONSTRAINT.")));
2393 elog(
ERROR,
"wrong pg_constraint entry for trigger \"%s\" on table \"%s\"",
2400 elog(
ERROR,
"wrong pg_constraint entry for trigger \"%s\" on table \"%s\"",
2407 elog(
ERROR,
"unrecognized confmatchtype: %d",
2413 errmsg(
"MATCH PARTIAL not yet implemented")));
2455 elog(
ERROR,
"constraint %u is not a foreign key constraint",
2461 riinfo->constraint_root_id =
2497 &
riinfo->period_contained_by_oper,
2498 &
riinfo->agged_period_contained_by_oper,
2499 &
riinfo->period_intersect_oper);
2504 riinfo->pk_is_partitioned =
2580 valid_link, iter.
cur);
2587 if (hashvalue == 0 ||
2588 riinfo->oidHashValue == hashvalue ||
2589 riinfo->rootHashValue == hashvalue)
2614 int save_sec_context;
2666 int save_sec_context;
2760 false,
false, limit);
2772 errmsg(
"referential integrity query on \"%s\" from constraint \"%s\" on \"%s\" gave unexpected result",
2776 errhint(
"This is most likely due to a rule having rewritten the query.")));
2914 elog(
ERROR,
"RI fast-path batch unexpectedly full");
2944 if (
fpentry->batch_count == 0)
3006 fk_rel, snapshot, scandesc);
3009 fk_rel, snapshot, scandesc);
3058 for (
int i = 0;
i <
fpentry->batch_count;
i++)
3307 errmsg(
"could not serialize access due to concurrent delete")));
3314 errmsg(
"could not serialize access due to concurrent update")));
3335 elog(
ERROR,
"attempted to lock invisible tuple");
3354 if (
riinfo->pk_is_partitioned)
3417 bool matched =
true;
3426 for (
int i = 0;
i < nkeys;
i++)
3435 skey->sk_argument)))
3563 Datum *vals,
char *nulls)
3565 const int16 *attnums;
3569 attnums =
riinfo->pk_attnums;
3571 attnums =
riinfo->fk_attnums;
3576 nulls[
i] = isnull ?
'n' :
' ';
3598 const int16 *attnums;
3610 attnums =
riinfo->fk_attnums;
3612 if (tupdesc ==
NULL)
3613 tupdesc =
fk_rel->rd_att;
3617 attnums =
riinfo->pk_attnums;
3619 if (tupdesc ==
NULL)
3620 tupdesc = pk_rel->
rd_att;
3703 errmsg(
"removing partition \"%s\" violates foreign key constraint \"%s\"",
3706 errdetail(
"Key (%s)=(%s) is still referenced from table \"%s\".",
3713 errmsg(
"insert or update on table \"%s\" violates foreign key constraint \"%s\"",
3717 errdetail(
"Key (%s)=(%s) is not present in table \"%s\".",
3720 errdetail(
"Key is not present in table \"%s\".",
3726 errmsg(
"update or delete on table \"%s\" violates RESTRICT setting of foreign key constraint \"%s\" on table \"%s\"",
3731 errdetail(
"Key (%s)=(%s) is referenced from table \"%s\".",
3734 errdetail(
"Key is referenced from table \"%s\".",
3740 errmsg(
"update or delete on table \"%s\" violates foreign key constraint \"%s\" on table \"%s\"",
3745 errdetail(
"Key (%s)=(%s) is still referenced from table \"%s\".",
3748 errdetail(
"Key is still referenced from table \"%s\".",
3766 const int16 *attnums;
3771 attnums =
riinfo->pk_attnums;
3773 attnums =
riinfo->fk_attnums;
3927 const int16 *attnums;
3930 attnums =
riinfo->pk_attnums;
3932 attnums =
riinfo->fk_attnums;
3980 eq_opr =
riinfo->period_contained_by_oper;
3982 eq_opr =
riinfo->ff_eq_oprs[
i];
4075 key.eq_opr = eq_opr;
4076 key.typeid =
typeid;
4081 entry->
valid =
false;
4137 elog(
ERROR,
"no conversion function from %s to %s",
4147 entry->
valid =
true;
4311 elog(
WARNING,
"RI fast-path cache not flushed at end of transaction");
4400 "RI fast path flush temporary context",
4411 entry->flushing =
false;
4412 entry->batch_count = 0;
Datum idx(PG_FUNCTION_ARGS)
bool has_bypassrls_privilege(Oid roleid)
void aclcheck_error(AclResult aclerr, ObjectType objtype, const char *objectname)
AclResult pg_attribute_aclcheck(Oid table_oid, AttrNumber attnum, Oid roleid, AclMode mode)
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
bool object_ownercheck(Oid classid, Oid objectid, Oid roleid)
AclResult pg_class_aclcheck(Oid table_oid, Oid roleid, AclMode mode)
ArrayType * construct_array(Datum *elems, int nelems, Oid elmtype, int elmlen, bool elmbyval, char elmalign)
Bitmapset * bms_add_member(Bitmapset *a, int x)
static Datum values[MAXATTR]
#define Assert(condition)
#define OidIsValid(objectId)
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
bool datum_image_eq(Datum value1, Datum value2, bool typByVal, int typLen)
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
HTAB * hash_create(const char *tabname, int64 nelem, const HASHCTL *info, int flags)
void hash_destroy(HTAB *hashp)
void * hash_seq_search(HASH_SEQ_STATUS *status)
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
int errcode(int sqlerrcode)
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define ereport(elevel,...)
bool ExecCheckPermissions(List *rangeTable, List *rteperminfos, bool ereport_on_violation)
TupleTableSlot * MakeSingleTupleTableSlot(TupleDesc tupdesc, const TupleTableSlotOps *tts_ops)
const TupleTableSlotOps TTSOpsVirtual
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
TupleTableSlot * ExecStoreVirtualTuple(TupleTableSlot *slot)
const TupleTableSlotOps TTSOpsHeapTuple
TupleTableSlot * ExecStoreHeapTuple(HeapTuple tuple, TupleTableSlot *slot, bool shouldFree)
#define palloc_object(type)
Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation, Datum arg1, Datum arg2)
char * OidOutputFunctionCall(Oid functionId, Datum val)
void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo, MemoryContext mcxt)
void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo, MemoryContext destcxt)
#define FunctionCall3(flinfo, arg1, arg2, arg3)
int NewGUCNestLevel(void)
void AtEOXact_GUC(bool isCommit, int nestLevel)
int set_config_option(const char *name, const char *value, GucContext context, GucSource source, GucAction action, bool changeVal, int elevel, bool is_reload)
void heap_deform_tuple(HeapTuple tuple, TupleDesc tupleDesc, Datum *values, bool *isnull)
#define HeapTupleIsValid(tuple)
static void * GETSTRUCT(const HeapTupleData *tuple)
#define dclist_container(type, membername, ptr)
static void dclist_push_tail(dclist_head *head, dlist_node *node)
static uint32 dclist_count(const dclist_head *head)
static void dclist_delete_from(dclist_head *head, dlist_node *node)
#define dclist_foreach_modify(iter, lhead)
IndexInfo * BuildIndexInfo(Relation index)
void FormIndexDatum(IndexInfo *indexInfo, TupleTableSlot *slot, EState *estate, Datum *values, bool *isnull)
bool index_getnext_slot(IndexScanDesc scan, ScanDirection direction, TupleTableSlot *slot)
IndexScanDesc index_beginscan(Relation heapRelation, Relation indexRelation, Snapshot snapshot, IndexScanInstrumentation *instrument, int nkeys, int norderbys, uint32 flags)
void index_close(Relation relation, LOCKMODE lockmode)
void index_endscan(IndexScanDesc scan)
Relation index_open(Oid relationId, LOCKMODE lockmode)
void index_rescan(IndexScanDesc scan, ScanKey keys, int nkeys, ScanKey orderbys, int norderbys)
void CacheRegisterSyscacheCallback(SysCacheIdentifier cacheid, SyscacheCallbackFunction func, Datum arg)
List * lappend(List *list, void *datum)
void get_op_opfamily_properties(Oid opno, Oid opfamily, bool ordering_op, int *strategy, Oid *lefttype, Oid *righttype)
void getTypeOutputInfo(Oid type, Oid *typOutput, bool *typIsVarlena)
void get_typlenbyvalalign(Oid typid, int16 *typlen, bool *typbyval, char *typalign)
char get_rel_relkind(Oid relid)
RegProcedure get_opcode(Oid opno)
Oid get_index_column_opclass(Oid index_oid, int attno)
Oid getBaseType(Oid typid)
char * get_namespace_name(Oid nspid)
void op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
void MemoryContextReset(MemoryContext context)
MemoryContext TopTransactionContext
void pfree(void *pointer)
MemoryContext TopMemoryContext
MemoryContext CurrentMemoryContext
void MemoryContextDelete(MemoryContext context)
#define AllocSetContextCreate
#define ALLOCSET_SMALL_SIZES
#define SECURITY_NOFORCE_RLS
#define SECURITY_LOCAL_USERID_CHANGE
void GetUserIdAndSecContext(Oid *userid, int *sec_context)
void SetUserIdAndSecContext(Oid userid, int sec_context)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
CoercionPathType find_coercion_pathway(Oid targetTypeId, Oid sourceTypeId, CoercionContext ccontext, Oid *funcid)
bool IsBinaryCoercible(Oid srctype, Oid targettype)
@ COERCION_PATH_RELABELTYPE
#define FKCONSTR_MATCH_SIMPLE
#define FKCONSTR_MATCH_PARTIAL
#define FKCONSTR_MATCH_FULL
FormData_pg_attribute * Form_pg_attribute
END_CATALOG_STRUCT typedef FormData_pg_collation * Form_pg_collation
void FindFKPeriodOpers(Oid opclass, Oid *containedbyoperoid, Oid *aggedcontainedbyoperoid, Oid *intersectoperoid)
void DeconstructFkConstraintRow(HeapTuple tuple, int *numfks, AttrNumber *conkey, AttrNumber *confkey, Oid *pf_eq_oprs, Oid *pp_eq_oprs, Oid *ff_eq_oprs, int *num_fk_del_set_cols, AttrNumber *fk_del_set_cols)
END_CATALOG_STRUCT typedef FormData_pg_constraint * Form_pg_constraint
static int list_length(const List *l)
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define ERRCODE_T_R_SERIALIZATION_FAILURE
static bool DatumGetBool(Datum X)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
static Datum Int32GetDatum(int32 X)
#define PointerGetDatum(X)
#define RelationGetForm(relation)
#define RelationGetRelid(relation)
#define RelationGetDescr(relation)
#define RelationGetRelationName(relation)
#define RelationGetNamespace(relation)
int errtableconstraint(Relation rel, const char *conname)
static void ri_FastPathEndBatch(void *arg)
static bool recheck_matched_pk_tuple(Relation idxrel, ScanKeyData *skeys, int nkeys, TupleTableSlot *new_slot)
static Datum ri_set(TriggerData *trigdata, bool is_set_null, int tgkind)
static bool ri_PerformCheck(const RI_ConstraintInfo *riinfo, RI_QueryKey *qkey, SPIPlanPtr qplan, Relation fk_rel, Relation pk_rel, TupleTableSlot *oldslot, TupleTableSlot *newslot, bool is_restrict, bool detectNewRows, int expect_OK)
#define RI_TRIGTYPE_INSERT
static Datum RI_FKey_check(TriggerData *trigdata)
#define RI_PLAN_SETNULL_ONUPDATE
#define RI_PLAN_CASCADE_ONUPDATE
#define RI_TRIGTYPE_DELETE
static SPIPlanPtr ri_PlanCheck(const char *querystr, int nargs, const Oid *argtypes, RI_QueryKey *qkey, Relation fk_rel, Relation pk_rel)
Datum RI_FKey_setnull_del(PG_FUNCTION_ARGS)
static bool ri_fastpath_callback_registered
static pg_noreturn void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, int queryno, bool is_restrict, bool partgone)
static void ri_HashPreparedPlan(RI_QueryKey *key, SPIPlanPtr plan)
static void quoteOneName(char *buffer, const char *name)
bool RI_FKey_pk_upd_check_required(Trigger *trigger, Relation pk_rel, TupleTableSlot *oldslot, TupleTableSlot *newslot)
#define RI_PLAN_LAST_ON_PK
#define RIAttType(rel, attnum)
static void ri_GenerateQualCollation(StringInfo buf, Oid collation)
Datum RI_FKey_cascade_del(PG_FUNCTION_ARGS)
#define RI_KEYS_SOME_NULL
Datum RI_FKey_check_upd(PG_FUNCTION_ARGS)
static HTAB * ri_query_cache
#define MAX_QUOTED_REL_NAME_LEN
Datum RI_FKey_restrict_upd(PG_FUNCTION_ARGS)
static int ri_FastPathFlushLoop(RI_FastPathEntry *fpentry, TupleTableSlot *fk_slot, const RI_ConstraintInfo *riinfo, Relation fk_rel, Snapshot snapshot, IndexScanDesc scandesc)
static Datum ri_restrict(TriggerData *trigdata, bool is_no_action)
Datum RI_FKey_restrict_del(PG_FUNCTION_ARGS)
Datum RI_FKey_noaction_del(PG_FUNCTION_ARGS)
static void ri_FastPathCheck(RI_ConstraintInfo *riinfo, Relation fk_rel, TupleTableSlot *newslot)
static void quoteRelationName(char *buffer, Relation rel)
static void ri_FastPathBatchAdd(RI_ConstraintInfo *riinfo, Relation fk_rel, TupleTableSlot *newslot)
static int ri_NullCheck(TupleDesc tupDesc, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk)
static void ri_GenerateQual(StringInfo buf, const char *sep, const char *leftop, Oid leftoptype, Oid opoid, const char *rightop, Oid rightoptype)
static void build_index_scankeys(const RI_ConstraintInfo *riinfo, Relation idx_rel, Datum *pk_vals, char *pk_nulls, ScanKey skeys)
static bool ri_LockPKTuple(Relation pk_rel, TupleTableSlot *slot, Snapshot snap, bool *concurrently_updated)
static bool ri_KeysEqual(Relation rel, TupleTableSlot *oldslot, TupleTableSlot *newslot, const RI_ConstraintInfo *riinfo, bool rel_is_pk)
static HTAB * ri_fastpath_cache
static RI_CompareHashEntry * ri_HashCompareOp(Oid eq_opr, Oid typeid)
#define RI_PLAN_CHECK_LOOKUPPK_FROM_PK
#define RIAttCollation(rel, attnum)
static dclist_head ri_constraint_cache_valid_list
static Oid get_ri_constraint_root(Oid constrOid)
Datum RI_FKey_check_ins(PG_FUNCTION_ARGS)
static HTAB * ri_compare_cache
static void ri_populate_fastpath_metadata(RI_ConstraintInfo *riinfo, Relation fk_rel, Relation idx_rel)
#define RI_KEYS_NONE_NULL
#define RI_FASTPATH_BATCH_SIZE
#define RI_INIT_QUERYHASHSIZE
static void ri_FastPathBatchFlush(RI_FastPathEntry *fpentry, Relation fk_rel, RI_ConstraintInfo *riinfo)
static bool ri_FastPathProbeOne(Relation pk_rel, Relation idx_rel, IndexScanDesc scandesc, TupleTableSlot *slot, Snapshot snapshot, const RI_ConstraintInfo *riinfo, ScanKeyData *skey, int nkeys)
void AtEOXact_RI(bool isCommit)
static void ri_BuildQueryKey(RI_QueryKey *key, const RI_ConstraintInfo *riinfo, int32 constr_queryno)
#define RI_PLAN_CASCADE_ONDELETE
Datum RI_FKey_setnull_upd(PG_FUNCTION_ARGS)
static RI_ConstraintInfo * ri_FetchConstraintInfo(Trigger *trigger, Relation trig_rel, bool rel_is_pk)
#define RI_PLAN_SETDEFAULT_ONDELETE
Datum RI_FKey_setdefault_del(PG_FUNCTION_ARGS)
#define RI_PLAN_SETDEFAULT_ONUPDATE
#define RI_PLAN_CHECK_LOOKUPPK
static bool ri_CompareWithCast(Oid eq_opr, Oid typeid, Oid collid, Datum lhs, Datum rhs)
static int ri_FastPathFlushArray(RI_FastPathEntry *fpentry, TupleTableSlot *fk_slot, const RI_ConstraintInfo *riinfo, Relation fk_rel, Snapshot snapshot, IndexScanDesc scandesc)
#define RI_PLAN_SETNULL_ONDELETE
#define RI_INIT_CONSTRAINTHASHSIZE
static void ri_CheckPermissions(Relation query_rel)
bool RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
static RI_FastPathEntry * ri_FastPathGetEntry(const RI_ConstraintInfo *riinfo, Relation fk_rel)
static bool ri_Check_Pk_Match(Relation pk_rel, Relation fk_rel, TupleTableSlot *oldslot, const RI_ConstraintInfo *riinfo)
void RI_PartitionRemove_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
static void ri_FastPathTeardown(void)
#define MAX_QUOTED_NAME_LEN
static void ri_CheckTrigger(FunctionCallInfo fcinfo, const char *funcname, int tgkind)
static bool ri_fastpath_is_applicable(const RI_ConstraintInfo *riinfo)
#define RI_TRIGTYPE_UPDATE
static bool ri_fastpath_flushing
bool RI_FKey_fk_upd_check_required(Trigger *trigger, Relation fk_rel, TupleTableSlot *oldslot, TupleTableSlot *newslot)
int RI_FKey_trigger_type(Oid tgfoid)
Datum RI_FKey_cascade_upd(PG_FUNCTION_ARGS)
Datum RI_FKey_noaction_upd(PG_FUNCTION_ARGS)
static void ri_InitHashTables(void)
static void InvalidateConstraintCacheCallBack(Datum arg, SysCacheIdentifier cacheid, uint32 hashvalue)
static void ri_ExtractValues(Relation rel, TupleTableSlot *slot, const RI_ConstraintInfo *riinfo, bool rel_is_pk, Datum *vals, char *nulls)
static RI_ConstraintInfo * ri_LoadConstraintInfo(Oid constraintOid)
#define RIAttName(rel, attnum)
static HTAB * ri_constraint_cache
static SPIPlanPtr ri_FetchPreparedPlan(RI_QueryKey *key)
Datum RI_FKey_setdefault_upd(PG_FUNCTION_ARGS)
#define RI_PLAN_NO_ACTION
int check_enable_rls(Oid relid, Oid checkAsUser, bool noError)
char * pg_get_partconstrdef_string(Oid partitionId, char *aliasname)
void generate_operator_clause(StringInfo buf, const char *leftop, Oid leftoptype, Oid opoid, const char *rightop, Oid rightoptype)
void ScanKeyEntryInitialize(ScanKey entry, int flags, AttrNumber attributeNumber, StrategyNumber strategy, Oid subtype, Oid collation, RegProcedure procedure, Datum argument)
Snapshot GetTransactionSnapshot(void)
Snapshot GetLatestSnapshot(void)
void UnregisterSnapshot(Snapshot snapshot)
Snapshot RegisterSnapshot(Snapshot snapshot)
bool SPI_plan_is_valid(SPIPlanPtr plan)
int SPI_freeplan(SPIPlanPtr plan)
const char * SPI_result_code_string(int code)
SPITupleTable * SPI_tuptable
int SPI_execute_snapshot(SPIPlanPtr plan, const Datum *Values, const char *Nulls, Snapshot snapshot, Snapshot crosscheck_snapshot, bool read_only, bool fire_triggers, long tcount)
int SPI_keepplan(SPIPlanPtr plan)
SPIPlanPtr SPI_prepare(const char *src, int nargs, const Oid *argtypes)
void appendStringInfo(StringInfo str, const char *fmt,...)
void appendBinaryStringInfo(StringInfo str, const void *data, int datalen)
void appendStringInfoString(StringInfo str, const char *s)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
int16 pk_attnums[RI_MAX_NUMKEYS]
Oid agged_period_contained_by_oper
int16 fk_attnums[RI_MAX_NUMKEYS]
Oid pp_eq_oprs[RI_MAX_NUMKEYS]
Oid pf_eq_oprs[RI_MAX_NUMKEYS]
Oid period_contained_by_oper
int16 confdelsetcols[RI_MAX_NUMKEYS]
Oid period_intersect_oper
Oid ff_eq_oprs[RI_MAX_NUMKEYS]
HeapTuple batch[RI_FASTPATH_BATCH_SIZE]
const struct IndexAmRoutine * rd_indam
TupleTableSlot * tg_trigslot
TupleTableSlot * tg_newslot
#define FirstLowInvalidHeapAttributeNumber
void ReleaseSysCache(HeapTuple tuple)
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
#define GetSysCacheHashValue1(cacheId, key1)
void table_close(Relation relation, LOCKMODE lockmode)
Relation table_open(Oid relationId, LOCKMODE lockmode)
TupleTableSlot * table_slot_create(Relation relation, List **reglist)
static TM_Result table_tuple_lock(Relation rel, ItemPointer tid, Snapshot snapshot, TupleTableSlot *slot, CommandId cid, LockTupleMode mode, LockWaitPolicy wait_policy, uint8 flags, TM_FailureData *tmfd)
#define TUPLE_LOCK_FLAG_FIND_LAST_VERSION
static bool table_tuple_satisfies_snapshot(Relation rel, TupleTableSlot *slot, Snapshot snapshot)
#define TUPLE_LOCK_FLAG_LOCK_UPDATE_IN_PROGRESS
void RegisterAfterTriggerBatchCallback(AfterTriggerBatchCallback callback, void *arg)
bool AfterTriggerIsActive(void)
#define TRIGGER_FIRED_BY_DELETE(event)
#define CALLED_AS_TRIGGER(fcinfo)
#define TRIGGER_FIRED_FOR_ROW(event)
#define TRIGGER_FIRED_AFTER(event)
#define TRIGGER_FIRED_BY_INSERT(event)
#define TRIGGER_FIRED_BY_UPDATE(event)
static FormData_pg_attribute * TupleDescAttr(TupleDesc tupdesc, int i)
static CompactAttribute * TupleDescCompactAttr(TupleDesc tupdesc, int i)
static HeapTuple ExecCopySlotHeapTuple(TupleTableSlot *slot)
static Datum slot_getattr(TupleTableSlot *slot, int attnum, bool *isnull)
static bool slot_is_current_xact_tuple(TupleTableSlot *slot)
static bool slot_attisnull(TupleTableSlot *slot, int attnum)
int GetCurrentTransactionNestLevel(void)
void CommandCounterIncrement(void)
CommandId GetCurrentCommandId(bool used)
#define IsolationUsesXactSnapshot()