github-actions[bot] commented on code in PR #65548:
URL: https://github.com/apache/doris/pull/65548#discussion_r3576573151


##########
be/src/format_v2/table_reader.h:
##########
@@ -1433,16 +1433,15 @@ class TableReader {
         request->columns.clear();
         if (agg_type == TPushAggOp::type::COUNT) {
             // COUNT pushdown historically meant COUNT(*) and therefore 
carried no columns. For
-            // complex COUNT(col), materializing the full MAP/LIST/STRUCT 
value only to test the
-            // top-level NULL bit can be extremely expensive. When the scan 
projects exactly one
-            // directly-mapped complex column, pass that file column to the 
reader so formats such
-            // as Parquet can count the column shape from metadata/levels 
without decoding payload
-            // values like MAP value strings. Other COUNT cases stay on the 
existing row-count path
-            // to avoid changing count(*) semantics.
+            // COUNT(col), Nereids retains exactly the counted slot in the 
file scan. Pass that
+            // single direct mapping for both scalar and complex columns: 
besides allowing nullable
+            // complex values to be counted from levels, it lets the file 
reader validate logical
+            // types before returning footer row counts. For example, a 
required TIME_MILLIS leaf
+            // has the same count as COUNT(*), but it must still fail as an 
unsupported requested
+            // column rather than silently returning the row-group count.
             if (_data_reader.column_mapper->mappings().size() == 1) {
                 const auto& mapping = 
_data_reader.column_mapper->mappings()[0];
                 if (mapping.file_local_id.has_value() && mapping.file_type != 
nullptr &&
-                    
is_complex_type(remove_nullable(mapping.file_type)->get_primitive_type()) &&

Review Comment:
   This still needs to preserve the COUNT(*) vs COUNT(col) distinction. 
`TPushAggOp::COUNT` is used for both shapes, and the only signal here is the 
post-pruning scan mapping. For a real `COUNT(*)`, column pruning can leave one 
arbitrary physical column under the scan (`pruneOutput()` picks a minimum 
column, then `newProjectIfNotPruned()` wraps it with a literal/empty project), 
so this branch turns an empty row-count request into `COUNT(that_column)`. File 
readers such as Parquet/ORC then count only non-null values for a nullable 
placeholder column, or reject an unsupported placeholder leaf, even though 
COUNT(*) should return the selected row count without observing any column 
nullability/logical type. Please pass a count column only when FE/BE knows the 
aggregate argument was `COUNT(col)` and the mapping is semantically countable; 
true COUNT(*) requests should keep `request.columns` empty.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to