/* * index_beginscan_internal --- common code for index_beginscan variants */ static IndexScanDesc index_beginscan_internal(Relation indexRelation, int nkeys, int norderbys, Snapshot snapshot) { IndexScanDesc scan; FmgrInfo *procedure; RELATION_CHECKS; GET_REL_PROCEDURE(ambeginscan); if (!(indexRelation->rd_am->ampredlocks)) PredicateLockRelation(indexRelation, snapshot); /* * We hold a reference count to the relcache entry throughout the scan. */ RelationIncrementReferenceCount(indexRelation); /* * Tell the AM to open a scan. */ scan = (IndexScanDesc) DatumGetPointer(FunctionCall3(procedure, PointerGetDatum(indexRelation), Int32GetDatum(nkeys), Int32GetDatum(norderbys))); return scan; }
/* ---------------- * index_insert - insert an index tuple into a relation * ---------------- */ InsertIndexResult index_insert(Relation indexRelation, Datum *datums, char *nulls, ItemPointer heap_t_ctid, Relation heapRelation, bool check_uniqueness) { RegProcedure procedure; InsertIndexResult specificResult; RELATION_CHECKS; GET_REL_PROCEDURE(insert, aminsert); /* * have the am's insert proc do all the work. */ specificResult = (InsertIndexResult) DatumGetPointer(OidFunctionCall6(procedure, PointerGetDatum(indexRelation), PointerGetDatum(datums), PointerGetDatum(nulls), PointerGetDatum(heap_t_ctid), PointerGetDatum(heapRelation), BoolGetDatum(check_uniqueness))); /* must be pfree'ed */ return specificResult; }
/* ---------------- * index_insert - insert an index tuple into a relation * ---------------- */ bool index_insert(Relation indexRelation, Datum *values, bool *isnull, ItemPointer heap_t_ctid, Relation heapRelation, IndexUniqueCheck checkUnique) { FmgrInfo *procedure; RELATION_CHECKS; GET_REL_PROCEDURE(aminsert); if (!(indexRelation->rd_am->ampredlocks)) CheckForSerializableConflictIn(indexRelation, (HeapTuple) NULL, InvalidBuffer); /* * have the am's insert proc do all the work. */ return DatumGetBool(FunctionCall6(procedure, PointerGetDatum(indexRelation), PointerGetDatum(values), PointerGetDatum(isnull), PointerGetDatum(heap_t_ctid), PointerGetDatum(heapRelation), Int32GetDatum((int32) checkUnique))); }
/* * index_beginscan_internal --- common code for index_beginscan variants */ static IndexScanDesc index_beginscan_internal(Relation indexRelation, int nkeys, ScanKey key) { IndexScanDesc scan; FmgrInfo *procedure; RELATION_CHECKS; GET_REL_PROCEDURE(ambeginscan); /* * We hold a reference count to the relcache entry throughout the scan. */ RelationIncrementReferenceCount(indexRelation); /* * Tell the AM to open a scan. */ scan = (IndexScanDesc) DatumGetPointer(FunctionCall3(procedure, PointerGetDatum(indexRelation), Int32GetDatum(nkeys), PointerGetDatum(key))); return scan; }
/* * __index_beginscan --- common code for index_beginscan variants */ static struct index_scan* __index_beginscan( struct relation* indexRelation, int nkeys, int norderbys, struct snap *snapshot) { struct index_scan *scan; struct fmgr_info *procedure; RELATION_CHECKS; GET_REL_PROCEDURE(ambeginscan); if (!(indexRelation->rd_am->ampredlocks)) predlock_rel(indexRelation, snapshot); /* * We hold a reference count to the relcache entry throughout the scan. */ rel_incr_refcnt(indexRelation); /* * Tell the AM to open a scan. */ scan = (struct index_scan*) D_TO_PTR(FC3( procedure, PTR_TO_D(indexRelation), INT32_TO_D(nkeys), INT32_TO_D(norderbys))); return scan; }
/* ---------------- * index_insert - insert an index tuple into a relation * ---------------- */ bool index_insert( struct relation* indexRelation, datum_t* values, bool* isnull, struct item_ptr* heap_t_ctid, struct relation* heapRelation, enum index_unique_check checkUnique) { struct fmgr_info *procedure; RELATION_CHECKS; GET_REL_PROCEDURE(aminsert); if (!(indexRelation->rd_am->ampredlocks)) check_ser_conflict_in(indexRelation, (struct heap_tuple*) NULL, INVALID_BUF); /* * have the am's insert proc do all the work. */ return D_TO_BOOL(FC6( procedure, PTR_TO_D(indexRelation), PTR_TO_D(values), PTR_TO_D(isnull), PTR_TO_D(heap_t_ctid), PTR_TO_D(heapRelation), INT32_TO_D((int32) checkUnique))); }
/* ---------------- * index_cost_estimator * * Fetch the amcostestimate procedure OID for an index. * * We could combine fetching and calling the procedure, * as index_insert does for example; but that would require * importing a bunch of planner/optimizer stuff into this file. * ---------------- */ RegProcedure index_cost_estimator(Relation indexRelation) { RegProcedure procedure; RELATION_CHECKS; GET_REL_PROCEDURE(cost_estimator, amcostestimate); return procedure; }
/* ---------------- * index_beginscan - start a scan of an index * * Note: heapRelation may be NULL if there is no intention of calling * index_getnext on this scan; index_getnext_indexitem will not use the * heapRelation link (nor the snapshot). However, the caller had better * be holding some kind of lock on the heap relation in any case, to ensure * no one deletes it (or the index) out from under us. * ---------------- */ IndexScanDesc index_beginscan(Relation heapRelation, Relation indexRelation, Snapshot snapshot, int nkeys, ScanKey key) { IndexScanDesc scan; RegProcedure procedure; RELATION_CHECKS; GET_REL_PROCEDURE(beginscan, ambeginscan); RelationIncrementReferenceCount(indexRelation); /* * Acquire AccessShareLock for the duration of the scan * * Note: we could get an SI inval message here and consequently have to * rebuild the relcache entry. The refcount increment above ensures * that we will rebuild it and not just flush it... */ LockRelation(indexRelation, AccessShareLock); /* * Tell the AM to open a scan. */ scan = (IndexScanDesc) DatumGetPointer(OidFunctionCall3(procedure, PointerGetDatum(indexRelation), Int32GetDatum(nkeys), PointerGetDatum(key))); /* * Save additional parameters into the scandesc. Everything else was * set up by RelationGetIndexScan. */ scan->heapRelation = heapRelation; scan->xs_snapshot = snapshot; /* * We want to look up the amgettuple procedure just once per scan, not * once per index_getnext call. So do it here and save the fmgr info * result in the scan descriptor. */ GET_SCAN_PROCEDURE(beginscan, amgettuple); fmgr_info(procedure, &scan->fn_getnext); return scan; }
/* ---------------- * index_can_return - does index support index-only scans? * ---------------- */ bool index_can_return(Relation indexRelation) { FmgrInfo *procedure; RELATION_CHECKS; /* amcanreturn is optional; assume FALSE if not provided by AM */ if (!RegProcedureIsValid(indexRelation->rd_am->amcanreturn)) return false; GET_REL_PROCEDURE(amcanreturn); return DatumGetBool(FunctionCall1(procedure, PointerGetDatum(indexRelation))); }
/* ---------------- * index_vacuum_cleanup - do post-deletion cleanup of an index * * return value is an optional palloc'd struct of statistics * ---------------- */ IndexBulkDeleteResult * index_vacuum_cleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats) { Relation indexRelation = info->index; FmgrInfo *procedure; IndexBulkDeleteResult *result; RELATION_CHECKS; GET_REL_PROCEDURE(amvacuumcleanup); result = (IndexBulkDeleteResult *) DatumGetPointer(FunctionCall2(procedure, PointerGetDatum(info), PointerGetDatum(stats))); return result; }
/* ---------------- * index_vacuum_cleanup - do post-deletion cleanup of an index * * return value is an optional palloc'd struct of statistics * ---------------- */ struct index_bulk_delete_result* index_vacuum_cleanup( struct index_vacuum_info *info, struct index_bulk_delete_result *stats) { struct relation *indexRelation = info->index; struct fmgr_info *procedure; struct index_bulk_delete_result *result; RELATION_CHECKS; GET_REL_PROCEDURE(amvacuumcleanup); result = (struct index_bulk_delete_result*) D_TO_PTR(FC2( procedure, PTR_TO_D(info), PTR_TO_D(stats))); return result; }
/* ---------------- * index_bulk_delete - do mass deletion of index entries * * callback routine tells whether a given main-heap tuple is * to be deleted * * return value is an optional palloc'd struct of statistics * ---------------- */ IndexBulkDeleteResult * index_bulk_delete(Relation indexRelation, IndexBulkDeleteCallback callback, void *callback_state) { RegProcedure procedure; IndexBulkDeleteResult *result; RELATION_CHECKS; GET_REL_PROCEDURE(bulk_delete, ambulkdelete); result = (IndexBulkDeleteResult *) DatumGetPointer(OidFunctionCall3(procedure, PointerGetDatum(indexRelation), PointerGetDatum((Pointer) callback), PointerGetDatum(callback_state))); return result; }
/* ---------------- * index_bulk_delete - do mass deletion of index entries * * callback routine tells whether a given main-heap tuple is * to be deleted * * return value is an optional palloc'd struct of statistics * ---------------- */ IndexBulkDeleteResult * index_bulk_delete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats, IndexBulkDeleteCallback callback, void *callback_state) { Relation indexRelation = info->index; FmgrInfo *procedure; IndexBulkDeleteResult *result; RELATION_CHECKS; GET_REL_PROCEDURE(ambulkdelete); result = (IndexBulkDeleteResult *) DatumGetPointer(FunctionCall4(procedure, PointerGetDatum(info), PointerGetDatum(stats), PointerGetDatum((Pointer) callback), PointerGetDatum(callback_state))); return result; }
/* ---------------- * index_bulk_delete - do mass deletion of index entries * * callback routine tells whether a given main-heap tuple is * to be deleted * * return value is an optional palloc'd struct of statistics * ---------------- */ struct index_bulk_delete_result* index_bulk_delete( struct index_vacuum_info* info, struct index_bulk_delete_result* stats, index_bulk_delete_cb_f* callback, void *callback_state) { struct relation* indexRelation = info->index; struct fmgr_info* procedure; struct index_bulk_delete_result *result; RELATION_CHECKS; GET_REL_PROCEDURE(ambulkdelete); result = (struct index_bulk_delete_result*) D_TO_PTR(FC4( procedure, PTR_TO_D(info), PTR_TO_D(stats), PTR_TO_D((pointer_p) callback), PTR_TO_D(callback_state))); return result; }
/* ---------------- * index_insert - insert an index tuple into a relation * ---------------- */ bool index_insert(Relation indexRelation, Datum *values, bool *isnull, ItemPointer heap_t_ctid, Relation heapRelation, bool check_uniqueness) { MIRROREDLOCK_BUFMGR_VERIFY_NO_LOCK_LEAK_DECLARE; FmgrInfo *procedure; bool result; MIRROREDLOCK_BUFMGR_VERIFY_NO_LOCK_LEAK_ENTER; RELATION_CHECKS; GET_REL_PROCEDURE(aminsert); // Fetch gp_persistent_relation_node information that will be added to XLOG record. RelationFetchGpRelationNodeForXLog(indexRelation); /* * have the am's insert proc do all the work. */ result = DatumGetBool(FunctionCall6(procedure, PointerGetDatum(indexRelation), PointerGetDatum(values), PointerGetDatum(isnull), PointerGetDatum(heap_t_ctid), PointerGetDatum(heapRelation), BoolGetDatum(check_uniqueness))); MIRROREDLOCK_BUFMGR_VERIFY_NO_LOCK_LEAK_EXIT; return result; }
/* ---------------- * index_insert - insert an index tuple into a relation * ---------------- */ bool index_insert(Relation indexRelation, Datum *values, bool *isnull, ItemPointer heap_t_ctid, Relation heapRelation, IndexUniqueCheck checkUnique) { FmgrInfo *procedure; RELATION_CHECKS; GET_REL_PROCEDURE(aminsert); /* * have the am's insert proc do all the work. */ return DatumGetBool(FunctionCall6(procedure, PointerGetDatum(indexRelation), PointerGetDatum(values), PointerGetDatum(isnull), PointerGetDatum(heap_t_ctid), PointerGetDatum(heapRelation), Int32GetDatum((int32) checkUnique))); }
/* ---------------- * index_vacuum_cleanup - do post-deletion cleanup of an index * * return value is an optional palloc'd struct of statistics * ---------------- */ IndexBulkDeleteResult * index_vacuum_cleanup(Relation indexRelation, IndexVacuumCleanupInfo *info, IndexBulkDeleteResult *stats) { RegProcedure procedure; IndexBulkDeleteResult *result; RELATION_CHECKS; /* It's okay for an index AM not to have a vacuumcleanup procedure */ if (!RegProcedureIsValid(indexRelation->rd_am->amvacuumcleanup)) return stats; GET_REL_PROCEDURE(vacuum_cleanup, amvacuumcleanup); result = (IndexBulkDeleteResult *) DatumGetPointer(OidFunctionCall3(procedure, PointerGetDatum(indexRelation), PointerGetDatum((Pointer) info), PointerGetDatum((Pointer) stats))); return result; }