diff options
Diffstat (limited to 'src/include')
| -rw-r--r-- | src/include/access/amapi.h | 2 | ||||
| -rw-r--r-- | src/include/access/genam.h | 3 | ||||
| -rw-r--r-- | src/include/access/nbtree.h | 79 | ||||
| -rw-r--r-- | src/include/utils/selfuncs.h | 3 |
4 files changed, 65 insertions, 22 deletions
diff --git a/src/include/access/amapi.h b/src/include/access/amapi.h index 2c6c307efcf..00300dd720e 100644 --- a/src/include/access/amapi.h +++ b/src/include/access/amapi.h @@ -194,7 +194,7 @@ typedef void (*amrestrpos_function) (IndexScanDesc scan); */ /* estimate size of parallel scan descriptor */ -typedef Size (*amestimateparallelscan_function) (void); +typedef Size (*amestimateparallelscan_function) (int nkeys, int norderbys); /* prepare for parallel index scan */ typedef void (*aminitparallelscan_function) (void *target); diff --git a/src/include/access/genam.h b/src/include/access/genam.h index 8026c2b36dd..fdcfbe8db74 100644 --- a/src/include/access/genam.h +++ b/src/include/access/genam.h @@ -165,7 +165,8 @@ extern void index_rescan(IndexScanDesc scan, extern void index_endscan(IndexScanDesc scan); extern void index_markpos(IndexScanDesc scan); extern void index_restrpos(IndexScanDesc scan); -extern Size index_parallelscan_estimate(Relation indexRelation, Snapshot snapshot); +extern Size index_parallelscan_estimate(Relation indexRelation, + int nkeys, int norderbys, Snapshot snapshot); extern void index_parallelscan_initialize(Relation heapRelation, Relation indexRelation, Snapshot snapshot, ParallelIndexScanDesc target); diff --git a/src/include/access/nbtree.h b/src/include/access/nbtree.h index 6eb162052e9..b9053219a69 100644 --- a/src/include/access/nbtree.h +++ b/src/include/access/nbtree.h @@ -960,12 +960,21 @@ typedef struct BTScanPosData * moreLeft and moreRight track whether we think there may be matching * index entries to the left and right of the current page, respectively. * We can clear the appropriate one of these flags when _bt_checkkeys() - * returns continuescan = false. + * sets BTReadPageState.continuescan = false. */ bool moreLeft; bool moreRight; /* + * Direction of the scan at the time that _bt_readpage was called. + * + * Used by btrestrpos to "restore" the scan's array keys by resetting each + * array to its first element's value (first in this scan direction). This + * avoids the need to directly track the array keys in btmarkpos. + */ + ScanDirection dir; + + /* * If we are doing an index-only scan, nextTupleOffset is the first free * location in the associated tuple storage workspace. */ @@ -1022,9 +1031,8 @@ typedef BTScanPosData *BTScanPos; /* We need one of these for each equality-type SK_SEARCHARRAY scan key */ typedef struct BTArrayKeyInfo { - int scan_key; /* index of associated key in arrayKeyData */ + int scan_key; /* index of associated key in keyData */ int cur_elem; /* index of current element in elem_values */ - int mark_elem; /* index of marked element in elem_values */ int num_elems; /* number of elems in current array value */ Datum *elem_values; /* array of num_elems Datums */ } BTArrayKeyInfo; @@ -1037,14 +1045,11 @@ typedef struct BTScanOpaqueData ScanKey keyData; /* array of preprocessed scan keys */ /* workspace for SK_SEARCHARRAY support */ - ScanKey arrayKeyData; /* modified copy of scan->keyData */ - bool arraysStarted; /* Started array keys, but have yet to "reach - * past the end" of all arrays? */ - int numArrayKeys; /* number of equality-type array keys (-1 if - * there are any unsatisfiable array keys) */ - int arrayKeyCount; /* count indicating number of array scan keys - * processed */ + int numArrayKeys; /* number of equality-type array keys */ + bool needPrimScan; /* New prim scan to continue in current dir? */ + bool scanBehind; /* Last array advancement matched -inf attr? */ BTArrayKeyInfo *arrayKeys; /* info about each equality-type array key */ + FmgrInfo *orderProcs; /* ORDER procs for required equality keys */ MemoryContext arrayContext; /* scan-lifespan context for array data */ /* info about killed items if any (killedItems is NULL if never used) */ @@ -1076,6 +1081,42 @@ typedef struct BTScanOpaqueData typedef BTScanOpaqueData *BTScanOpaque; /* + * _bt_readpage state used across _bt_checkkeys calls for a page + */ +typedef struct BTReadPageState +{ + /* Input parameters, set by _bt_readpage for _bt_checkkeys */ + ScanDirection dir; /* current scan direction */ + OffsetNumber minoff; /* Lowest non-pivot tuple's offset */ + OffsetNumber maxoff; /* Highest non-pivot tuple's offset */ + IndexTuple finaltup; /* Needed by scans with array keys */ + BlockNumber prev_scan_page; /* previous _bt_parallel_release block */ + Page page; /* Page being read */ + + /* Per-tuple input parameters, set by _bt_readpage for _bt_checkkeys */ + OffsetNumber offnum; /* current tuple's page offset number */ + + /* Output parameter, set by _bt_checkkeys for _bt_readpage */ + OffsetNumber skip; /* Array keys "look ahead" skip offnum */ + bool continuescan; /* Terminate ongoing (primitive) index scan? */ + + /* + * Input and output parameters, set and unset by both _bt_readpage and + * _bt_checkkeys to manage precheck optimizations + */ + bool prechecked; /* precheck set continuescan to 'true'? */ + bool firstmatch; /* at least one match so far? */ + + /* + * Private _bt_checkkeys state used to manage "look ahead" optimization + * (only used during scans with array keys) + */ + int16 rechecks; + int16 targetdistance; + +} BTReadPageState; + +/* * We use some private sk_flags bits in preprocessed scan keys. We're allowed * to use bits 16-31 (see skey.h). The uppermost bits are copied from the * index's indoption[] array entry for the index attribute. @@ -1128,7 +1169,7 @@ extern bool btinsert(Relation rel, Datum *values, bool *isnull, bool indexUnchanged, struct IndexInfo *indexInfo); extern IndexScanDesc btbeginscan(Relation rel, int nkeys, int norderbys); -extern Size btestimateparallelscan(void); +extern Size btestimateparallelscan(int nkeys, int norderbys); extern void btinitparallelscan(void *target); extern bool btgettuple(IndexScanDesc scan, ScanDirection dir); extern int64 btgetbitmap(IndexScanDesc scan, TIDBitmap *tbm); @@ -1149,10 +1190,12 @@ extern bool btcanreturn(Relation index, int attno); /* * prototypes for internal functions in nbtree.c */ -extern bool _bt_parallel_seize(IndexScanDesc scan, BlockNumber *pageno); +extern bool _bt_parallel_seize(IndexScanDesc scan, BlockNumber *pageno, + bool first); extern void _bt_parallel_release(IndexScanDesc scan, BlockNumber scan_page); extern void _bt_parallel_done(IndexScanDesc scan); -extern void _bt_parallel_advance_array_keys(IndexScanDesc scan); +extern void _bt_parallel_primscan_schedule(IndexScanDesc scan, + BlockNumber prev_scan_page); /* * prototypes for functions in nbtdedup.c @@ -1243,15 +1286,11 @@ extern Buffer _bt_get_endpoint(Relation rel, uint32 level, bool rightmost); */ extern BTScanInsert _bt_mkscankey(Relation rel, IndexTuple itup); extern void _bt_freestack(BTStack stack); -extern void _bt_preprocess_array_keys(IndexScanDesc scan); +extern bool _bt_start_prim_scan(IndexScanDesc scan, ScanDirection dir); extern void _bt_start_array_keys(IndexScanDesc scan, ScanDirection dir); -extern bool _bt_advance_array_keys(IndexScanDesc scan, ScanDirection dir); -extern void _bt_mark_array_keys(IndexScanDesc scan); -extern void _bt_restore_array_keys(IndexScanDesc scan); extern void _bt_preprocess_keys(IndexScanDesc scan); -extern bool _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple, - int tupnatts, ScanDirection dir, bool *continuescan, - bool requiredMatchedByPrecheck, bool haveFirstMatch); +extern bool _bt_checkkeys(IndexScanDesc scan, BTReadPageState *pstate, bool arrayKeys, + IndexTuple tuple, int tupnatts); extern void _bt_killitems(IndexScanDesc scan); extern BTCycleId _bt_vacuum_cycleid(Relation rel); extern BTCycleId _bt_start_vacuum(Relation rel); diff --git a/src/include/utils/selfuncs.h b/src/include/utils/selfuncs.h index 2fa4c4fc1b0..f2563ad1cb3 100644 --- a/src/include/utils/selfuncs.h +++ b/src/include/utils/selfuncs.h @@ -117,6 +117,9 @@ typedef struct VariableStatData * Callers should initialize all fields of GenericCosts to zero. In addition, * they can set numIndexTuples to some positive value if they have a better * than default way of estimating the number of leaf index tuples visited. + * Similarly, they can set num_sa_scans to some value >= 1 for an index AM + * that doesn't necessarily perform exactly one primitive index scan per + * distinct combination of ScalarArrayOp array elements. */ typedef struct { |
