@@ -1298,82 +1298,95 @@ columnar_scan_plan_create(PlannerInfo *root, RelOptInfo *rel, CustomPath *path,
12981298
12991299 sort_options = list_make4 (sort_col_idx , sort_ops , sort_collations , sort_nulls );
13001300
1301- /*
1302- * Build a sort node for the compressed batches. The sort function is
1303- * derived from the sort function of the pathkeys, except that it refers
1304- * to the min and max metadata columns of the batches. We have already
1305- * verified that the pathkeys match the compression order_by, so this
1306- * mapping is possible.
1307- */
1308- AttrNumber * sortColIdx = palloc (sizeof (AttrNumber ) * numsortkeys );
1309- Oid * sortOperators = palloc (sizeof (Oid ) * numsortkeys );
1310- Oid * collations = palloc (sizeof (Oid ) * numsortkeys );
1311- bool * nullsFirst = palloc (sizeof (bool ) * numsortkeys );
1312- for (int i = 0 ; i < numsortkeys ; i ++ )
1301+ /* We can utilize compressed sort for batch sorted merge over unordered chunks: do not need
1302+ * to add extra Sort node */
1303+ if (dcpath -> required_compressed_pathkeys &&
1304+ pathkeys_contained_in (dcpath -> required_compressed_pathkeys , compressed_path -> pathkeys ))
1305+ {
1306+ decompress_plan -> custom_plans = custom_plans ;
1307+ }
1308+ else
13131309 {
1314- Oid sortop = list_nth_oid (sort_ops , i );
1315-
1316- /* Find the operator in pg_amop --- failure shouldn't happen */
1317- Oid opfamily , opcintype ;
1318- CompareType strategy ;
1319- if (!get_ordering_op_properties (list_nth_oid (sort_ops , i ),
1320- & opfamily ,
1321- & opcintype ,
1322- & strategy ))
1323- {
1324- elog (ERROR , "operator %u is not a valid ordering operator" , sortOperators [i ]);
1325- }
1326-
13271310 /*
1328- * This way to determine the matching metadata column works, because
1329- * we have already verified that the pathkeys match the compression
1330- * orderby.
1311+ * Build a sort node for the compressed batches. The sort function is
1312+ * derived from the sort function of the pathkeys, except that it refers
1313+ * to the min and max metadata columns of the batches. We have already
1314+ * verified that the pathkeys match the compression order_by, so this
1315+ * mapping is possible.
13311316 */
1332- Assert (strategy == BTLessStrategyNumber || strategy == BTGreaterStrategyNumber );
1333- char * lower_name ;
1334- char * upper_name ;
1335- orderby_sparse_metadata_names (dcpath -> info -> settings , i + 1 , & lower_name , & upper_name );
1336- char * meta_col_name = strategy == BTLessStrategyNumber ? lower_name : upper_name ;
1317+ AttrNumber * sortColIdx = palloc (sizeof (AttrNumber ) * numsortkeys );
1318+ Oid * sortOperators = palloc (sizeof (Oid ) * numsortkeys );
1319+ Oid * collations = palloc (sizeof (Oid ) * numsortkeys );
1320+ bool * nullsFirst = palloc (sizeof (bool ) * numsortkeys );
1321+ for (int i = 0 ; i < numsortkeys ; i ++ )
1322+ {
1323+ Oid sortop = list_nth_oid (sort_ops , i );
1324+
1325+ /* Find the operator in pg_amop --- failure shouldn't happen */
1326+ Oid opfamily , opcintype ;
1327+ CompareType strategy ;
1328+ if (!get_ordering_op_properties (list_nth_oid (sort_ops , i ),
1329+ & opfamily ,
1330+ & opcintype ,
1331+ & strategy ))
1332+ {
1333+ elog (ERROR , "operator %u is not a valid ordering operator" , sortOperators [i ]);
1334+ }
13371335
1338- AttrNumber attr_position =
1339- get_attnum (dcpath -> info -> compressed_rte -> relid , meta_col_name );
1336+ /*
1337+ * This way to determine the matching metadata column works, because
1338+ * we have already verified that the pathkeys match the compression
1339+ * orderby.
1340+ */
1341+ Assert (strategy == BTLessStrategyNumber || strategy == BTGreaterStrategyNumber );
1342+ char * lower_name ;
1343+ char * upper_name ;
1344+ orderby_sparse_metadata_names (dcpath -> info -> settings ,
1345+ i + 1 ,
1346+ & lower_name ,
1347+ & upper_name );
1348+ char * meta_col_name = strategy == BTLessStrategyNumber ? lower_name : upper_name ;
1349+
1350+ AttrNumber attr_position =
1351+ get_attnum (dcpath -> info -> compressed_rte -> relid , meta_col_name );
1352+
1353+ if (attr_position == InvalidAttrNumber )
1354+ {
1355+ elog (ERROR , "couldn't find metadata column \"%s\"" , meta_col_name );
1356+ }
13401357
1341- if (attr_position == InvalidAttrNumber )
1342- {
1343- elog (ERROR , "couldn't find metadata column \"%s\"" , meta_col_name );
1344- }
1358+ /*
1359+ * If the compressed target list is not based on the layout of
1360+ * the uncompressed chunk (see comment for physical_tlist above),
1361+ * adjust the position of the attribute.
1362+ */
1363+ if (target_list_compressed_is_physical )
1364+ {
1365+ sortColIdx [i ] = attr_position ;
1366+ }
1367+ else
1368+ {
1369+ sortColIdx [i ] =
1370+ find_attr_pos_in_tlist (compressed_scan -> plan .targetlist , attr_position );
1371+ }
13451372
1346- /*
1347- * If the compressed target list is not based on the layout of
1348- * the uncompressed chunk (see comment for physical_tlist above),
1349- * adjust the position of the attribute.
1350- */
1351- if (target_list_compressed_is_physical )
1352- {
1353- sortColIdx [i ] = attr_position ;
1373+ sortOperators [i ] = sortop ;
1374+ collations [i ] = list_nth_oid (sort_collations , i );
1375+ nullsFirst [i ] = list_nth_oid (sort_nulls , i );
13541376 }
1355- else
1356- {
1357- sortColIdx [i ] =
1358- find_attr_pos_in_tlist (compressed_scan -> plan .targetlist , attr_position );
1359- }
1360-
1361- sortOperators [i ] = sortop ;
1362- collations [i ] = list_nth_oid (sort_collations , i );
1363- nullsFirst [i ] = list_nth_oid (sort_nulls , i );
1364- }
13651377
1366- /* Now build the compressed batches sort node */
1367- Sort * sort = ts_make_sort ((Plan * ) compressed_scan ,
1368- numsortkeys ,
1369- sortColIdx ,
1370- sortOperators ,
1371- collations ,
1372- nullsFirst );
1378+ /* Now build the compressed batches sort node */
1379+ Sort * sort = ts_make_sort ((Plan * ) compressed_scan ,
1380+ numsortkeys ,
1381+ sortColIdx ,
1382+ sortOperators ,
1383+ collations ,
1384+ nullsFirst );
13731385
1374- ts_label_sort_with_costsize (root , sort , /* limit_tuples = */ -1.0 );
1386+ ts_label_sort_with_costsize (root , sort , /* limit_tuples = */ -1.0 );
13751387
1376- decompress_plan -> custom_plans = list_make1 (sort );
1388+ decompress_plan -> custom_plans = list_make1 (sort );
1389+ }
13771390 }
13781391 else
13791392 {
0 commit comments