/* * 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_beginscan_internal --- common code for index_beginscan variants */ static IndexScanDesc index_beginscan_internal(Relation indexRelation, int nkeys, int norderbys, Snapshot snapshot, ParallelIndexScanDesc pscan, bool temp_snap) { IndexScanDesc scan; RELATION_CHECKS; CHECK_REL_PROCEDURE(ambeginscan); if (!(indexRelation->rd_amroutine->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 = indexRelation->rd_amroutine->ambeginscan(indexRelation, nkeys, norderbys); /* Initialize information for parallel scan. */ scan->parallel_scan = pscan; scan->xs_temp_snap = temp_snap; return scan; }
/* * ConditionalLockRelation * * As above, but only lock if we can get the lock without blocking. * Returns TRUE iff the lock was acquired. * * NOTE: we do not currently need conditional versions of all the * LockXXX routines in this file, but they could easily be added if needed. */ bool ConditionalLockRelation(Relation relation, LOCKMODE lockmode) { LOCKTAG tag; MemSet(&tag, 0, sizeof(tag)); tag.relId = relation->rd_lockInfo.lockRelId.relId; tag.dbId = relation->rd_lockInfo.lockRelId.dbId; tag.objId.blkno = InvalidBlockNumber; if (!LockAcquire(LockTableId, &tag, GetCurrentTransactionId(), lockmode, true)) return false; /* * Check to see if the relcache entry has been invalidated while we * were waiting to lock it. If so, rebuild it, or ereport() trying. * Increment the refcount to ensure that RelationFlushRelation will * rebuild it and not just delete it. */ RelationIncrementReferenceCount(relation); AcceptInvalidationMessages(); RelationDecrementReferenceCount(relation); return true; }
/* * 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 - 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; }
/** *begin scanning of a parquet relation */ ParquetScanDesc parquet_beginscan( Relation relation, Snapshot parquetMetaDataSnapshot, TupleDesc relationTupleDesc, bool *proj) { ParquetScanDesc scan; AppendOnlyEntry *aoEntry; AppendOnlyStorageAttributes *attr; /* * increment relation ref count while scanning relation * * This is just to make really sure the relcache entry won't go away while * the scan has a pointer to it. Caller should be holding the rel open * anyway, so this is redundant in all normal scenarios... */ RelationIncrementReferenceCount(relation); /* allocate scan descriptor */ scan = (ParquetScanDescData *)palloc0(sizeof(ParquetScanDescData)); /* * Get the pg_appendonly information for this table */ aoEntry = GetAppendOnlyEntry(RelationGetRelid(relation), parquetMetaDataSnapshot); scan->aoEntry = aoEntry; Assert(aoEntry->majorversion == 1 && aoEntry->minorversion == 0); #ifdef FAULT_INJECTOR FaultInjector_InjectFaultIfSet( FailQeWhenBeginParquetScan, DDLNotSpecified, "", // databaseName ""); // tableName #endif /* * initialize the scan descriptor */ scan->pqs_filenamepath_maxlen = AOSegmentFilePathNameLen(relation) + 1; scan->pqs_filenamepath = (char*)palloc0(scan->pqs_filenamepath_maxlen); scan->pqs_rd = relation; scan->parquetScanInitContext = CurrentMemoryContext; /* * Fill in Parquet Storage layer attributes. */ attr = &scan->storageAttributes; /* * These attributes describe the AppendOnly format to be scanned. */ if (aoEntry->compresstype == NULL || pg_strcasecmp(aoEntry->compresstype, "none") == 0) attr->compress = false; else attr->compress = true; if (aoEntry->compresstype != NULL) attr->compressType = aoEntry->compresstype; else attr->compressType = "none"; attr->compressLevel = aoEntry->compresslevel; attr->checksum = aoEntry->checksum; attr->safeFSWriteSize = aoEntry->safefswritesize; attr->splitsize = aoEntry->splitsize; attr->version = aoEntry->version; AORelationVersion_CheckValid(attr->version); scan->proj = proj; scan->pqs_tupDesc = (relationTupleDesc == NULL) ? RelationGetDescr(relation) : relationTupleDesc; scan->hawqAttrToParquetColChunks = (int*)palloc0(scan->pqs_tupDesc->natts * sizeof(int)); initscan(scan); return scan ; }