github-actions[bot] commented on code in PR #67154: URL: https://github.com/apache/doris/pull/67154#discussion_r3877735883
########## regression-test/suites/nereids_function_p0/scalar_function/nereids_scalar_fn_map_decimal_precision.groovy: ########## @@ -0,0 +1,271 @@ +// 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. + +// The key and the value of a MAP are independent decimal slots. The default +// decimal v3 precision promotion must keep their precision/scale independent +// instead of merging them into one type, otherwise widening the scale of a big +// integral key silently converts it to NULL (e.g. in map_keys) and UNNEST(MAP)/ +// explode_map may fail the type check. +suite("nereids_scalar_fn_map_decimal_precision") { + sql "set enable_decimal256 = true;" + + // 1. map_keys must keep the big integral key instead of turning it into NULL + order_qt_map_keys_decimal256 """ + SELECT + CAST(MAP( + CAST('9999999999999999999999999999999999999999999999999999999999999999999999999999' AS DECIMAL(76,0)), + CAST('0.125000000000000000' AS DECIMAL(76,18)) + ) AS STRING) AS source_map, + CAST(MAP_KEYS(MAP( + CAST('9999999999999999999999999999999999999999999999999999999999999999999999999999' AS DECIMAL(76,0)), + CAST('0.125000000000000000' AS DECIMAL(76,18)) + )) AS STRING) AS actual_keys, + CAST(ARRAY(CAST('9999999999999999999999999999999999999999999999999999999999999999999999999999' AS DECIMAL(76,0))) AS STRING) AS expected_keys; + """ + + // 2. UNNEST(MAP) must pass the type check and return independent key/value + order_qt_unnest_map_decimal256 """ + SELECT key_out, value_out + FROM UNNEST(MAP( + CAST('1.2500' AS DECIMAL(16,4)), + CAST('2.125000000000000000' AS DECIMAL(76,18)) + )) AS expanded(key_out, value_out); + """ + + // 3. explode_map keeps independent key/value decimals + order_qt_explode_map_decimal256 """ + SELECT k, v + FROM (SELECT 1) x + LATERAL VIEW EXPLODE_MAP(MAP( + CAST('1.2500' AS DECIMAL(16,4)), + CAST('2.125000000000000000' AS DECIMAL(76,18)) + )) t AS k, v; + """ + + // 4. map_contains_key can find the big integral key + order_qt_map_contains_key_decimal256 """ + SELECT MAP_CONTAINS_KEY(MAP( + CAST('9999999999999999999999999999999999999999999999999999999999999999999999999999' AS DECIMAL(76,0)), + CAST('0.125000000000000000' AS DECIMAL(76,18)) + ), CAST('9999999999999999999999999999999999999999999999999999999999999999999999999999' AS DECIMAL(76,0))) AS ck; + """ + + // 5. map_values keeps the value + order_qt_map_values_decimal256 """ + SELECT CAST(MAP_VALUES(MAP( + CAST('9999999999999999999999999999999999999999999999999999999999999999999999999999' AS DECIMAL(76,0)), + CAST('0.125000000000000000' AS DECIMAL(76,18)) + )) AS STRING) AS actual_values; + """ + + // 6. map_entries keeps independent key/value decimals + order_qt_map_entries_decimal256 """ + SELECT CAST(MAP_ENTRIES(MAP( + CAST('9999999999999999999999999999999999999999999999999999999999999999999999999999' AS DECIMAL(76,0)), + CAST('0.125000000000000000' AS DECIMAL(76,18)) + )) AS STRING) AS entries; + """ + + // 7. element_at over a map with independent key/value decimals + order_qt_element_at_decimal256 """ + SELECT ELEMENT_AT(MAP( + CAST('1.2500' AS DECIMAL(16,4)), + CAST('2.125000000000000000' AS DECIMAL(76,18)) + ), CAST('1.2500' AS DECIMAL(16,4))) AS value; + """ + + // 8. element_at / map_contains_key with a wider lookup on a Decimal32 key column. + // The lookup slot follows the MAP key type, so both must be promoted to one type + // (across the DECIMAL32 -> DECIMAL64 storage-width boundary) instead of being + // widened independently, otherwise the BE compares columns of different concrete + // decimal classes. + sql "drop table if exists fn_test_map_decimal_precision" + sql """ + create table fn_test_map_decimal_precision ( + id int null, + m map<decimal(9,2), decimal(5,2)> null + ) engine=olap + distributed by hash(id) buckets 1 + properties('replication_num' = '1') + """ + sql """ + insert into fn_test_map_decimal_precision values + (1, map(cast('1234567.89' as decimal(9,2)), cast('12.34' as decimal(5,2)))), + (2, map(cast('1.23' as decimal(9,2)), cast('0.01' as decimal(5,2)))); + """ + order_qt_element_at_wider_lookup """ + select id, element_at(m, cast('1234567.890' as decimal(10,3))) + from fn_test_map_decimal_precision order by id + """ + order_qt_map_contains_key_wider_lookup """ + select id, map_contains_key(m, cast('1234567.890' as decimal(10,3))) + from fn_test_map_decimal_precision order by id + """ + // a NULL lookup must fall back to the MAP key group instead of the wider type of + // an unrelated MAP leaf + order_qt_element_at_null_lookup """ + select id, element_at(m, null) + from fn_test_map_decimal_precision order by id + """ + + // 9. field declares varArgs(DECIMALV3, DECIMALV3): its fixed first operand and the + // repeated tail are one comparison type and must keep one promoted type + order_qt_field_decimal """ + select field(cast('1.20' as decimal(3,2)), cast('1.200' as decimal(4,3)), + cast('2.000' as decimal(4,3))) + """ + + // 10. nonconstant nested containers: the item of an ARRAY nested in a MAP value + // keeps its own precision/scale instead of being merged with the key into the wider + // type, otherwise map_values() discards the low-order fractional digits + sql "drop table if exists fn_test_map_nested_decimal" + sql """ + create table fn_test_map_nested_decimal ( + id int null, + m map<decimal(38,0), array<decimal(38,18)>> null + ) engine=olap + distributed by hash(id) buckets 1 + properties('replication_num' = '1') + """ + sql """ + insert into fn_test_map_nested_decimal values + (1, map(cast('12345678901234567890123456789012345678' as decimal(38,0)), + array(cast('0.123456789012345678' as decimal(38,18))))); + """ + order_qt_map_values_nested_array """ + select cast(map_values(m) as string) as v from fn_test_map_nested_decimal order by id + """ + order_qt_map_keys_nested_array """ + select cast(map_keys(m) as string) as k from fn_test_map_nested_decimal order by id + """ + + // 11. nonconstant nested MAP: the key/value of a MAP nested in a MAP value keep + // their own precision/scale instead of being merged with the outer MAP leaves + sql "drop table if exists fn_test_nested_map_decimal" + sql """ + create table fn_test_nested_map_decimal ( + id int null, + m map<decimal(38,0), map<decimal(9,2), decimal(5,2)>> null + ) engine=olap + distributed by hash(id) buckets 1 + properties('replication_num' = '1') + """ + sql """ + insert into fn_test_nested_map_decimal values + (1, map(cast('12345678901234567890123456789012345678' as decimal(38,0)), + map(cast('1234567.89' as decimal(9,2)), cast('12.34' as decimal(5,2))))); + """ + order_qt_map_values_nested_map """ + select cast(map_values(m) as string) as v from fn_test_nested_map_decimal order by id + """ + order_qt_map_keys_nested_map """ + select cast(map_keys(m) as string) as k from fn_test_nested_map_decimal order by id + """ + + // 12. basic decimal v3 precision promotion (single slot) is not affected + order_qt_basic_decimal256 """ + SELECT ABS(CAST('123.456' AS DECIMAL(10,3))) AS abs_v, + ROUND(CAST('123.456' AS DECIMAL(10,3)), 2) AS round_v; + """ + + // 13. struct(...) fields are independent type variables: the default decimal v3 + // precision promotion must not merge them (e.g. widening the scale of a DECIMAL(76,0) + // field would truncate the decimals of an ARRAY<DECIMAL(76,18)> field) + order_qt_struct_independent_fields """ + SELECT CAST(STRUCT( + CAST('9999999999999999999999999999999999999999999999999999999999999999999999999999' AS DECIMAL(76,0)), + ARRAY(CAST('0.125000000000000000' AS DECIMAL(76,18))) + ) AS STRING) AS s; + """ + + // 14. nonconstant map_contains_value / map_contains_entry: the probe (Follow(0)) and + // the MAP value (Any(0)) are one logical group. When the probe and the independent key + // resolve to the same type (DECIMAL(10,3)), the probe must still be linked to the value + // group by the original Any/Follow index, otherwise the value regresses to DECIMAL(9,2) + // and the BE compares a Decimal32 value array with a Decimal64 probe. + sql "drop table if exists fn_test_map_contains_collision_decimal" + sql """ + create table fn_test_map_contains_collision_decimal ( + id int null, + m map<decimal(10,3), decimal(9,2)> null, + x decimal(10,3) null, + k decimal(10,3) null, + v decimal(9,2) null + ) engine=olap + distributed by hash(id) buckets 1 + properties('replication_num' = '1') + """ + sql """ + insert into fn_test_map_contains_collision_decimal values + (1, map(cast('1234567.890' as decimal(10,3)), cast('12.34' as decimal(9,2))), + cast('1234567.890' as decimal(10,3)), + cast('1234567.890' as decimal(10,3)), cast('12.34' as decimal(9,2))), + (2, map(cast('1.230' as decimal(10,3)), cast('0.01' as decimal(9,2))), + cast('9.999' as decimal(10,3)), + cast('9.999' as decimal(10,3)), cast('0.02' as decimal(9,2))); + """ + order_qt_map_contains_value_collision """ + select id, map_contains_value(m, x) as r from fn_test_map_contains_collision_decimal order by id + """ + order_qt_map_contains_entry_collision """ + select id, map_contains_entry(m, k, v) as r from fn_test_map_contains_collision_decimal order by id + """ + + // 15. array_pushfront(ARRAY<Any(0)>, Any(0)) with ARRAY-of-MAP and MAP inputs: the + // container Any identity must be propagated into the descendant-relative MAP keys so + // both slots stay one compatible MAP type instead of regressing to incompatible types. + sql "drop table if exists fn_test_arr_push_map_decimal" + sql """ + create table fn_test_arr_push_map_decimal ( + id int null, + arr array<map<decimal(10,3), decimal(5,2)>> null, + m map<decimal(9,2), decimal(9,2)> null + ) engine=olap + distributed by hash(id) buckets 1 + properties('replication_num' = '1') + """ + sql """ + insert into fn_test_arr_push_map_decimal values + (1, array(map(cast('1234567.890' as decimal(10,3)), cast('12.345' as decimal(5,2)))), + map(cast('12.34' as decimal(9,2)), cast('1.23' as decimal(9,2)))); + """ + order_qt_array_pushfront_map_container """ + select id, array_pushfront(arr, m) as r from fn_test_arr_push_map_decimal order by id + """ + + // 16. array_contains(ARRAY<Any(0)>, Any(0)): the ARRAY item and the probe are one + // logical group, so a wider ARRAY<DECIMAL(27,9)> with a DECIMAL(9,3) probe must keep + // both at DECIMAL(27,9) instead of regressing only the probe to Decimal32. + sql "drop table if exists fn_test_arr_contains_decimal" + sql """ + create table fn_test_arr_contains_decimal ( + id int null, + arr array<decimal(27,9)> null, + probe decimal(9,3) null + ) engine=olap + distributed by hash(id) buckets 1 + properties('replication_num' = '1') + """ + sql """ + insert into fn_test_arr_contains_decimal values + (1, array(cast('123456789012345678.123456789' as decimal(27,9))), cast('123456.789' as decimal(9,3))), + (2, array(cast('123456789012345678.123456789' as decimal(27,9))), cast('123456789012345678.123' as decimal(27,3))); Review Comment: [P2] Make the cross-width fixture representable The `probe` column is `DECIMAL(9,3)`, so it can hold only six integral digits, but row 2 inserts `123456789012345678.123` (eighteen integral digits). That narrowing either fails or produces NULL, so the checked `false` does not exercise the intended Decimal32/Decimal128 comparison. Row 1 can catch a concrete-class dispatch failure, but it is deliberately unequal to the ARRAY element, so this suite still has no positive result proving equality after exact precision/scale promotion. Please keep both stored probes representable and make at least one `ARRAY<DECIMAL(27,9)>` element numerically equal to its `DECIMAL(9,3)` probe (for example `123456.789000000` versus `123456.789`), with a separate representable negative row if desired. -- 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]
