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


##########
fe/fe-core/src/test/java/org/apache/doris/nereids/rules/analysis/BindExpressionTest.java:
##########
@@ -295,6 +305,67 @@ void testRowLevelMergeOutputIsCoercedByPosition() {
         Assertions.assertTrue(exception.getMessage().contains("not aligned"), 
exception.getMessage());
     }
 
+    @Test
+    void testDeleteOnlyMergeDoesNotValidateNestedSpatialDataWrites() {
+        for (DataType spatial : ImmutableList.of(new GeometryType("OGC:CRS84"),
+                new GeographyType("OGC:CRS84", "spherical"))) {
+            ArrayType array = ArrayType.of(spatial);
+            LogicalOneRowRelation input = new LogicalOneRowRelation(new 
RelationId(1), ImmutableList.of(
+                    new Alias(new NullLiteral(array), "shapes")));
+            LogicalProject<?> source = new LogicalProject<>(ImmutableList.of(
+                    new Alias(new TinyIntLiteral((byte) 1), 
MergeOperation.OPERATION_COLUMN),
+                    new Alias(new StringLiteral("row"), 
Column.ICEBERG_ROWID_COL),
+                    new Alias(input.getOutput().get(0), "shapes")), input);
+            List<Column> columns = ImmutableList.of(new Column("shapes", 
array.toCatalogDataType()));
+            for (boolean writesDataFiles : new boolean[] {false, true}) {
+                LogicalExternalRowLevelMergeSink<?> sink = new 
LogicalExternalRowLevelMergeSink<>(
+                        Mockito.mock(ExternalDatabase.class), 
Mockito.mock(ExternalTable.class),
+                        "schema-1", columns, ImmutableList.of(), 
writesDataFiles, true,
+                        Optional.empty(), Optional.empty(), source);
+                if (writesDataFiles) {
+                    AnalysisException exception = 
Assertions.assertThrows(AnalysisException.class,

Review Comment:
   [P2] Update the MERGE assertion for supported nested spatial writes
   
   The `writesDataFiles=true` case uses exactly matching source/target 
ARRAY<GEOMETRY/GEOGRAPHY> metadata, which this head now supports. Binding 
passes the Variant-only check, performs same-type output coercion, and 
`validateMergeSpatialTypes` recursively accepts the matching spatial leaf; the 
former `Nested spatial columns` production diagnostic is gone. Consequently 
this new test expects an AnalysisException that the binder no longer raises. 
Assert successful binding for both matching cases, and use a kind/CRS/algorithm 
mismatch for a negative data-write case while retaining the delete-only 
control. This is separate from the earlier production delete-only MERGE finding.



##########
fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/agg/MultiDistinctCount.java:
##########
@@ -64,6 +64,18 @@ protected MultiDistinctCount(AggregateFunctionParams 
functionParams) {
         super(functionParams);
     }
 
+    @Override
+    public void checkLegalityBeforeTypeCoercion() {
+        if (getArgumentType(0).isSpatialType()) {

Review Comment:
   [P2] Reject nested spatial arguments to MULTI_DISTINCT_COUNT
   
   `isSpatialType()` misses ARRAY<GEOMETRY/GEOGRAPHY>. For the regression's two 
equivalent POINT(1 2) rows with opposite WKB byte orders, `SELECT 
multi_distinct_count(array(geom)) FROM geometry_values WHERE id IN (101,102)` 
passes this guard. This explicit aggregate has `distinct=false` and no grouping 
key, so the recursive COUNT DISTINCT/group-key checks do not run. BE's 
implemented TYPE_ARRAY uniq specialization hashes through ColumnArray -> 
ColumnSpatial's raw WKB, counting the encodings separately rather than 
rejecting unsupported spatial DISTINCT. This is distinct from the previous 
scalar missing-factory and later MAP/list DISTINCT-lowering findings: this 
ARRAY specialization executes successfully. Use a recursive spatial-type check 
here and after rewrite, and cover nested arrays for both spatial kinds.



##########
be/src/core/data_type/data_type_spatial.cpp:
##########
@@ -0,0 +1,220 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "core/data_type/data_type_spatial.h"
+
+#include <algorithm>
+#include <cctype>
+#include <cstring>
+#include <string_view>
+
+#include "agent/be_exec_version_manager.h"
+#include "common/exception.h"
+#include "core/assert_cast.h"
+#include "core/column/column_const.h"
+#include "core/data_type/data_type.h"
+#include "core/data_type_serde/data_type_varbinary_serde.h"
+#include "core/field.h"
+#include "core/string_view.h"
+#include "exprs/function/geo/wkb_parse.h"
+#include "gen_cpp/data.pb.h"
+
+namespace doris {
+
+namespace {
+
+std::string normalize_spatial_crs(std::string crs) {
+    // Imported ogc:crs84 has default semantics; leave custom CRS/property 
references unchanged.
+    constexpr std::string_view default_crs = "OGC:CRS84";
+    if (std::ranges::equal(crs, default_crs, [](unsigned char left, unsigned 
char right) {
+            return std::tolower(left) == std::tolower(right);
+        })) {
+        return std::string(default_crs);
+    }
+    return crs;
+}
+
+std::string normalize_spatial_algorithm(PrimitiveType type, std::string 
algorithm) {
+    if (type == TYPE_GEOGRAPHY && algorithm.empty()) {
+        return "spherical";
+    }
+    std::ranges::transform(algorithm, algorithm.begin(),
+                           [](unsigned char c) { return 
static_cast<char>(std::tolower(c)); });
+    return algorithm;
+}
+
+class SpatialParquetSerDe final : public 
DataTypeVarbinarySerDeBase<ColumnSpatial> {
+public:
+    SpatialParquetSerDe(int nesting_level, bool geographic)
+            : DataTypeVarbinarySerDeBase<ColumnSpatial>(nesting_level), 
_geographic(geographic) {}
+
+    Status read_column_from_parquet(IColumn& column, ParquetDecodeSource& 
source,
+                                    const ParquetDecodeContext& context, 
size_t num_values,
+                                    ParquetMaterializationState& state) const 
override {
+        const auto start = column.size();
+        
RETURN_IF_ERROR(DataTypeVarbinarySerDeBase<ColumnSpatial>::read_column_from_parquet(

Review Comment:
   [P2] Add spatial columns to native nullable-selection batching
   
   This new leaf SerDe is reached through FileScannerV2's nullable-selection 
fallback: `visit_nullable_expandable_column` in native/column_chunk_reader.cpp 
supports ColumnVarbinary but omits ColumnSpatial, so 
`supports_fused_nullable_selection` returns false. For a filtered 
materialization range alternating Point/NULL, `decode_selected_values<true>` 
enters the decoder and this SerDe separately for every retained CONTENT run. 
The binary-carrier path instead batches compact non-NULL values and expands 
NULLs within each materialized page fragment. Large filtered ranges with many 
one-value runs therefore lose native batching. Add ownership-safe in-place 
StringView expansion and register ColumnSpatial in this dispatcher; merely 
adding the visitor entry is insufficient because ColumnSpatial lacks the 
mutable expansion interface. Cover filtered plain/dictionary inputs with 
alternating NULLs and verify that the fused path avoids 
HybridSelectionNullFallbackBatches.



-- 
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