@@ -890,6 +890,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
890
890
ScanKeyData notnullkeys [INDEX_MAX_KEYS ];
891
891
int keysz = 0 ;
892
892
StrategyNumber strat_total ;
893
+ BlockNumber blkno = InvalidBlockNumber ,
894
+ lastcurrblkno ;
893
895
894
896
Assert (!BTScanPosIsValid (so -> currPos ));
895
897
@@ -905,64 +907,42 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
905
907
*/
906
908
if (!so -> qual_ok )
907
909
{
910
+ Assert (!so -> needPrimScan );
908
911
_bt_parallel_done (scan );
909
912
return false;
910
913
}
911
914
912
915
/*
913
- * For parallel scans, get the starting page from shared state. If the
914
- * scan has not started, proceed to find out first leaf page in the usual
915
- * way while keeping other participating processes waiting. If the scan
916
- * has already begun, use the page number from the shared structure.
917
- *
918
- * When a parallel scan has another primitive index scan scheduled, a
919
- * parallel worker will seize the scan for that purpose now. This is
920
- * similar to the case where the top-level scan hasn't started.
916
+ * If this is a parallel scan, we must seize the scan. _bt_readfirstpage
917
+ * will likely release the parallel scan later on.
921
918
*/
922
- if (scan -> parallel_scan != NULL )
923
- {
924
- BlockNumber blkno ,
925
- lastcurrblkno ;
919
+ if (scan -> parallel_scan != NULL &&
920
+ !_bt_parallel_seize (scan , & blkno , & lastcurrblkno , true))
921
+ return false;
926
922
927
- if (!_bt_parallel_seize (scan , & blkno , & lastcurrblkno , true))
928
- return false;
923
+ /*
924
+ * Initialize the scan's arrays (if any) for the current scan direction
925
+ * (except when they were already set to later values as part of
926
+ * scheduling the primitive index scan that is now underway)
927
+ */
928
+ if (so -> numArrayKeys && !so -> needPrimScan )
929
+ _bt_start_array_keys (scan , dir );
929
930
931
+ if (blkno != InvalidBlockNumber )
932
+ {
930
933
/*
931
- * Successfully seized the scan, which _bt_readfirstpage or possibly
932
- * _bt_readnextpage will release (unless the scan ends right away, in
933
- * which case we'll call _bt_parallel_done directly).
934
- *
935
- * Initialize arrays (when _bt_parallel_seize didn't already set up
936
- * the next primitive index scan).
934
+ * We anticipated calling _bt_search, but another worker bet us to it.
935
+ * _bt_readnextpage releases the scan for us (not _bt_readfirstpage).
937
936
*/
938
- if (so -> numArrayKeys && !so -> needPrimScan )
939
- _bt_start_array_keys (scan , dir );
940
-
937
+ Assert (scan -> parallel_scan != NULL );
938
+ Assert (!so -> needPrimScan );
941
939
Assert (blkno != P_NONE );
942
- if (blkno != InvalidBlockNumber )
943
- {
944
- Assert (!so -> needPrimScan );
945
940
946
- /*
947
- * We anticipated starting another primitive scan, but some other
948
- * worker bet us to it
949
- */
950
- if (!_bt_readnextpage (scan , blkno , lastcurrblkno , dir , true))
951
- return false;
941
+ if (!_bt_readnextpage (scan , blkno , lastcurrblkno , dir , true))
942
+ return false;
952
943
953
- _bt_returnitem (scan , so );
954
- return true;
955
- }
956
- }
957
- else if (so -> numArrayKeys && !so -> needPrimScan )
958
- {
959
- /*
960
- * First _bt_first call (for current btrescan) without parallelism.
961
- *
962
- * Initialize arrays, and the corresponding scan keys that were just
963
- * output by _bt_preprocess_keys.
964
- */
965
- _bt_start_array_keys (scan , dir );
944
+ _bt_returnitem (scan , so );
945
+ return true;
966
946
}
967
947
968
948
/*
@@ -1090,7 +1070,12 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
1090
1070
break ;
1091
1071
startKeys [keysz ++ ] = chosen ;
1092
1072
1093
- /* Quit if we have stored a > or < key */
1073
+ /*
1074
+ * We can only consider adding more boundary keys when the one
1075
+ * that we just chose to add uses either the = or >= strategy
1076
+ * (during backwards scans we can only do so when the key that
1077
+ * we just added to startKeys[] uses the = or <= strategy)
1078
+ */
1094
1079
strat_total = chosen -> sk_strategy ;
1095
1080
if (strat_total == BTGreaterStrategyNumber ||
1096
1081
strat_total == BTLessStrategyNumber )
@@ -1190,6 +1175,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
1190
1175
Assert (subkey -> sk_flags & SK_ROW_MEMBER );
1191
1176
if (subkey -> sk_flags & SK_ISNULL )
1192
1177
{
1178
+ Assert (!so -> needPrimScan );
1193
1179
_bt_parallel_done (scan );
1194
1180
return false;
1195
1181
}
@@ -1408,6 +1394,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
1408
1394
1409
1395
if (!BufferIsValid (so -> currPos .buf ))
1410
1396
{
1397
+ Assert (!so -> needPrimScan );
1411
1398
_bt_parallel_done (scan );
1412
1399
return false;
1413
1400
}
@@ -2553,6 +2540,7 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
2553
2540
OffsetNumber start ;
2554
2541
2555
2542
Assert (!BTScanPosIsValid (so -> currPos ));
2543
+ Assert (!so -> needPrimScan );
2556
2544
2557
2545
/*
2558
2546
* Scan down to the leftmost or rightmost leaf page. This is a simplified
0 commit comments