@@ -890,6 +890,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
890890 ScanKeyData notnullkeys [INDEX_MAX_KEYS ];
891891 int keysz = 0 ;
892892 StrategyNumber strat_total ;
893+ BlockNumber blkno = InvalidBlockNumber ,
894+ lastcurrblkno ;
893895
894896 Assert (!BTScanPosIsValid (so -> currPos ));
895897
@@ -905,64 +907,42 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
905907 */
906908 if (!so -> qual_ok )
907909 {
910+ Assert (!so -> needPrimScan );
908911 _bt_parallel_done (scan );
909912 return false;
910913 }
911914
912915 /*
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.
921918 */
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;
926922
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 );
929930
931+ if (blkno != InvalidBlockNumber )
932+ {
930933 /*
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).
937936 */
938- if (so -> numArrayKeys && !so -> needPrimScan )
939- _bt_start_array_keys (scan , dir );
940-
937+ Assert (scan -> parallel_scan != NULL );
938+ Assert (!so -> needPrimScan );
941939 Assert (blkno != P_NONE );
942- if (blkno != InvalidBlockNumber )
943- {
944- Assert (!so -> needPrimScan );
945940
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;
952943
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;
966946 }
967947
968948 /*
@@ -1090,7 +1070,12 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
10901070 break ;
10911071 startKeys [keysz ++ ] = chosen ;
10921072
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+ */
10941079 strat_total = chosen -> sk_strategy ;
10951080 if (strat_total == BTGreaterStrategyNumber ||
10961081 strat_total == BTLessStrategyNumber )
@@ -1190,6 +1175,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
11901175 Assert (subkey -> sk_flags & SK_ROW_MEMBER );
11911176 if (subkey -> sk_flags & SK_ISNULL )
11921177 {
1178+ Assert (!so -> needPrimScan );
11931179 _bt_parallel_done (scan );
11941180 return false;
11951181 }
@@ -1408,6 +1394,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
14081394
14091395 if (!BufferIsValid (so -> currPos .buf ))
14101396 {
1397+ Assert (!so -> needPrimScan );
14111398 _bt_parallel_done (scan );
14121399 return false;
14131400 }
@@ -2553,6 +2540,7 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
25532540 OffsetNumber start ;
25542541
25552542 Assert (!BTScanPosIsValid (so -> currPos ));
2543+ Assert (!so -> needPrimScan );
25562544
25572545 /*
25582546 * Scan down to the leftmost or rightmost leaf page. This is a simplified
0 commit comments