From d1bf82658be1b6ec9c65f6377ed72691b5ee77f3 Mon Sep 17 00:00:00 2001 From: Kang Date: Fri, 17 Feb 2023 14:54:48 +0800 Subject: [PATCH 01/13] map functions: map, map_size, map_contains_key/value, map_keys/values --- be/src/vec/CMakeLists.txt | 1 + be/src/vec/columns/column_map.h | 7 +- be/src/vec/functions/function_map.cpp | 340 ++++++++++++++++++ .../vec/functions/simple_function_factory.h | 2 + .../doris/analysis/FunctionCallExpr.java | 11 + gensrc/script/doris_builtins_functions.py | 13 +- 6 files changed, 368 insertions(+), 6 deletions(-) create mode 100644 be/src/vec/functions/function_map.cpp diff --git a/be/src/vec/CMakeLists.txt b/be/src/vec/CMakeLists.txt index aa9f875385b04c..4db743459c2f86 100644 --- a/be/src/vec/CMakeLists.txt +++ b/be/src/vec/CMakeLists.txt @@ -187,6 +187,7 @@ set(VEC_FILES functions/array/function_array_apply.cpp functions/array/function_array_concat.cpp functions/array/function_array_pushfront.cpp + functions/function_map.cpp exprs/table_function/vexplode_json_array.cpp functions/math.cpp functions/function_bitmap.cpp diff --git a/be/src/vec/columns/column_map.h b/be/src/vec/columns/column_map.h index f6f8ebec504373..e5c8ee8dc2a373 100644 --- a/be/src/vec/columns/column_map.h +++ b/be/src/vec/columns/column_map.h @@ -152,6 +152,10 @@ class ColumnMap final : public COWHelper { const IColumn& get_values() const { return *values_column; } IColumn& get_values() { return *values_column; } + size_t ALWAYS_INLINE size_at(ssize_t i) const { + return get_offsets()[i] - get_offsets()[i - 1]; + } + private: friend class COWHelper; @@ -160,9 +164,6 @@ class ColumnMap final : public COWHelper { WrappedPtr offsets_column; // offset size_t ALWAYS_INLINE offset_at(ssize_t i) const { return get_offsets()[i - 1]; } - size_t ALWAYS_INLINE size_at(ssize_t i) const { - return get_offsets()[i] - get_offsets()[i - 1]; - } ColumnMap(MutableColumnPtr&& keys, MutableColumnPtr&& values, MutableColumnPtr&& offsets); diff --git a/be/src/vec/functions/function_map.cpp b/be/src/vec/functions/function_map.cpp new file mode 100644 index 00000000000000..59d9ba3c695f5a --- /dev/null +++ b/be/src/vec/functions/function_map.cpp @@ -0,0 +1,340 @@ +// 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 "vec/columns/column_array.h" +#include "vec/columns/column_const.h" +#include "vec/columns/column_map.h" +#include "vec/data_types/get_least_supertype.h" +#include "vec/data_types/data_type.h" +#include "vec/data_types/data_type_array.h" +#include "vec/data_types/data_type_map.h" +#include "vec/data_types/data_type_number.h" +#include "vec/functions/array/function_array_index.h" +#include "vec/functions/function.h" +#include "vec/functions/function_helpers.h" +#include "vec/functions/simple_function_factory.h" + +namespace doris::vectorized { + +// construct a map +// map(key1, value2, key2, value2) -> {key1: value2, key2: value2} +class FunctionMap : public IFunction { +public: + static constexpr auto name = "map"; + static FunctionPtr create() { return std::make_shared(); } + + /// Get function name. + String get_name() const override { return name; } + + bool is_variadic() const override { return true; } + + bool use_default_implementation_for_nulls() const override { return false; } + + size_t get_number_of_arguments() const override { return 0; } + + DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { + DCHECK(arguments.size() % 2 == 0) + << "function: " << get_name() << ", arguments should not be even number"; + + DataTypes key_types; + DataTypes val_types; + for (size_t i = 0; i < arguments.size(); i += 2) { + key_types.push_back(arguments[i]); + val_types.push_back(arguments[i + 1]); + } + + DataTypePtr key_type; + DataTypePtr val_type; + get_least_supertype(key_types, &key_type); + get_least_supertype(val_types, &val_type); + + return std::make_shared(key_type, val_type); + } + + Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, + size_t result, size_t input_rows_count) override { + DCHECK(arguments.size() % 2 == 0) + << "function: " << get_name() << ", arguments should not be even number"; + + size_t num_element = arguments.size(); + + auto result_col = block.get_by_position(result).type->create_column(); + // auto result_col_map = static_cast(result_col.get()); + // auto col_map = typeid_cast(result_col.get()); + auto col_map = static_cast(result_col.get()); + auto col_map_keys = static_cast(&col_map->get_keys()); + auto col_map_vals = static_cast(&col_map->get_values()); + + // map keys array data and offsets + auto& result_col_map_keys_data = col_map_keys->get_data(); + auto& result_col_map_keys_offsets = col_map_keys->get_offsets(); + result_col_map_keys_data.reserve(input_rows_count * num_element / 2); + result_col_map_keys_offsets.resize(input_rows_count); + // map values array data and offsets + auto& result_col_map_vals_data = col_map_vals->get_data(); + auto& result_col_map_vals_offsets = col_map_vals->get_offsets(); + result_col_map_vals_data.reserve(input_rows_count * num_element / 2); + result_col_map_vals_offsets.resize(input_rows_count); + + // convert to nullable column + for (size_t i = 0; i < num_element; ++i) { + auto& col = block.get_by_position(arguments[i]).column; + col = col->convert_to_full_column_if_const(); + bool is_nullable = i % 2 == 0 ? + result_col_map_keys_data.is_nullable() : result_col_map_vals_data.is_nullable(); + if (is_nullable && !col->is_nullable()) { + col = ColumnNullable::create(col, ColumnUInt8::create(col->size(), 0)); + } + } + + // insert value into array + ColumnArray::Offset64 offset = 0; + for (size_t row = 0; row < input_rows_count; ++row) { + for (size_t i = 0; i < num_element; i += 2) { + result_col_map_keys_data.insert_from(*block.get_by_position(arguments[i]).column, row); + result_col_map_vals_data.insert_from(*block.get_by_position(arguments[i + 1]).column, row); + } + offset += num_element / 2; + result_col_map_keys_offsets[row] = offset; + result_col_map_vals_offsets[row] = offset; + } + block.replace_by_position(result, std::move(result_col)); + return Status::OK(); + } +}; + +class FunctionMapSize : public IFunction { +public: + static constexpr auto name = "size"; + static FunctionPtr create() { return std::make_shared(); } + + /// Get function name. + String get_name() const override { return name; } + + bool is_variadic() const override { return false; } + + size_t get_number_of_arguments() const override { return 1; } + + DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { + DCHECK(is_map(arguments[0])) + << "first argument for function: " << name << " should be DataTypeMap"; + return std::make_shared(); + } + + Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, + size_t result, size_t input_rows_count) override { + auto left_column = + block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); + const auto col_map = check_and_get_column(*left_column); + if (!col_map) { + return Status::RuntimeError("unsupported types for function {}({})", get_name(), + block.get_by_position(arguments[0]).type->get_name()); + } + + auto dst_column = ColumnInt64::create(input_rows_count); + auto& dst_data = dst_column->get_data(); + + for (size_t i = 0; i < col_map->size(); i++) { + dst_data[i] = col_map->size_at(i); + } + + block.replace_by_position(result, std::move(dst_column)); + return Status::OK(); + } +}; + +template +class FunctionMapContains : public IFunction { +public: + static constexpr auto name = is_key ? "map_contains_key" : "map_contains_value"; + static FunctionPtr create() { return std::make_shared(); } + + /// Get function name. + String get_name() const override { return name; } + + bool is_variadic() const override { return false; } + + size_t get_number_of_arguments() const override { return 2; } + + DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { + DCHECK(is_map(arguments[0])) + << "first argument for function: " << name << " should be DataTypeMap"; + + if (arguments[0]->is_nullable()) { + return make_nullable(std::make_shared>()); + } else { + return std::make_shared>(); + } + } + + Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, + size_t result, size_t input_rows_count) override { + // backup original argument 0 + auto orig_arg0 = block.get_by_position(arguments[0]); + auto left_column = + block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); + const auto col_map = check_and_get_column(*left_column); + if (!col_map) { + return Status::RuntimeError("unsupported types for function {}({})", get_name(), + block.get_by_position(arguments[0]).type->get_name()); + } + + const auto datatype_map = + static_cast(block.get_by_position(arguments[0]).type.get()); + if constexpr(is_key) { + block.get_by_position(arguments[0]) = { + col_map->get_keys_ptr(), + std::make_shared(datatype_map->get_key_type()), + block.get_by_position(arguments[0]).name + ".keys" + }; + } else { + block.get_by_position(arguments[0]) = { + col_map->get_values_ptr(), + std::make_shared(datatype_map->get_value_type()), + block.get_by_position(arguments[0]).name + ".values" + }; + } + + RETURN_IF_ERROR( + array_contains.execute_impl(context, block, arguments, result, input_rows_count)); + + // restore original argument 0 + block.get_by_position(arguments[0]) = orig_arg0; + return Status::OK(); + } + +private: + FunctionArrayIndex> array_contains; +}; + +// template +// class FunctionMapContainsLike : public IFunction { +// public: +// static constexpr auto name = is_key ? "map_contains_key_like" : "map_contains_value_like"; +// static FunctionPtr create() { return std::make_shared(); } + +// /// Get function name. +// String get_name() const override { return name; } + +// bool is_variadic() const override { return false; } + +// size_t get_number_of_arguments() const override { return 2; } + +// DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { +// DCHECK(is_map(arguments[0])) +// << "first argument for function: " << name << " should be DataTypeMap"; + +// if (arguments[0]->is_nullable()) { +// return make_nullable(std::make_shared>()); +// } else { +// return std::make_shared>(); +// } +// } + +// Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, +// size_t result, size_t input_rows_count) override { +// // backup original argument 0 +// auto orig_arg0 = block.get_by_position(arguments[0]); +// auto left_column = +// block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); +// const auto col_map = check_and_get_column(*left_column); +// if (!col_map) { +// return Status::RuntimeError("unsupported types for function {}({})", get_name(), +// block.get_by_position(arguments[0]).type->get_name()); +// } + +// const auto datatype_map = +// static_cast(block.get_by_position(arguments[0]).type.get()); +// if constexpr(is_key) { +// block.get_by_position(arguments[0]) = { +// col_map->get_keys_ptr(), +// std::make_shared(datatype_map->get_key_type()), +// block.get_by_position(arguments[0]).name + ".keys" +// }; +// } else { +// block.get_by_position(arguments[0]) = { +// col_map->get_values_ptr(), +// std::make_shared(datatype_map->get_value_type()), +// block.get_by_position(arguments[0]).name + ".values" +// }; +// } + +// RETURN_IF_ERROR( +// array_contains.execute_impl(context, block, arguments, result, input_rows_count)); + +// // restore original argument 0 +// block.get_by_position(arguments[0]) = orig_arg0; +// return Status::OK(); +// } +// }; + +template +class FunctionMapEntries : public IFunction { +public: + static constexpr auto name = is_key ? "map_keys" : "map_values"; + static FunctionPtr create() { return std::make_shared(); } + + /// Get function name. + String get_name() const override { return name; } + + bool is_variadic() const override { return false; } + + size_t get_number_of_arguments() const override { return 1; } + + DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { + DCHECK(is_map(arguments[0])) + << "first argument for function: " << name << " should be DataTypeMap"; + const auto datatype_map = + static_cast(arguments[0].get()); + if (is_key) { + return std::make_shared(datatype_map->get_key_type()); + } else { + return std::make_shared(datatype_map->get_value_type()); + } + } + + Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, + size_t result, size_t input_rows_count) override { + auto left_column = + block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); + const auto col_map = check_and_get_column(*left_column); + if (!col_map) { + return Status::RuntimeError("unsupported types for function {}({})", get_name(), + block.get_by_position(arguments[0]).type->get_name()); + } + + if constexpr(is_key) { + block.replace_by_position(result, col_map->get_keys_ptr()); + } else { + block.replace_by_position(result, col_map->get_values_ptr()); + } + + return Status::OK(); + } +}; + +void register_function_map(SimpleFunctionFactory& factory) { + factory.register_function(); + factory.register_function(); + factory.register_alias(FunctionMapSize::name, "map_size"); + factory.register_function>(); + factory.register_function>(); + factory.register_function>(); + factory.register_function>(); +} + +} // namespace doris::vectorized diff --git a/be/src/vec/functions/simple_function_factory.h b/be/src/vec/functions/simple_function_factory.h index 9ab060d11a5b7c..8a9213eae02bea 100644 --- a/be/src/vec/functions/simple_function_factory.h +++ b/be/src/vec/functions/simple_function_factory.h @@ -81,6 +81,7 @@ void register_function_convert_tz(SimpleFunctionFactory& factory); void register_function_least_greast(SimpleFunctionFactory& factory); void register_function_fake(SimpleFunctionFactory& factory); void register_function_array(SimpleFunctionFactory& factory); +void register_function_map(SimpleFunctionFactory& factory); void register_function_geo(SimpleFunctionFactory& factory); void register_function_multi_string_position(SimpleFunctionFactory& factory); void register_function_multi_string_search(SimpleFunctionFactory& factory); @@ -230,6 +231,7 @@ class SimpleFunctionFactory { register_function_regexp_extract(instance); register_function_hex_variadic(instance); register_function_array(instance); + register_function_map(instance); register_function_geo(instance); register_function_url(instance); register_function_multi_string_position(instance); diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java index 30b40088dbfbe2..87bb96ccb08923 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/FunctionCallExpr.java @@ -28,6 +28,7 @@ import org.apache.doris.catalog.Env; import org.apache.doris.catalog.Function; import org.apache.doris.catalog.FunctionSet; +import org.apache.doris.catalog.MapType; import org.apache.doris.catalog.ScalarFunction; import org.apache.doris.catalog.ScalarType; import org.apache.doris.catalog.Type; @@ -1396,6 +1397,12 @@ && collectChildReturnTypes()[0].isDecimalV3()) { for (int i = 0; i < argTypes.length - orderByElements.size(); ++i) { // For varargs, we must compare with the last type in callArgs.argTypes. int ix = Math.min(args.length - 1, i); + // map varargs special case map(key_type, value_type, ...) + if (i >= args.length && i >= 2 && args.length >= 2 + && fnName.getFunction().equalsIgnoreCase("map")) { + ix = i % 2 == 0 ? 0 : 1; + } + if ((fnName.getFunction().equalsIgnoreCase("money_format") || fnName.getFunction() .equalsIgnoreCase("histogram") || fnName.getFunction().equalsIgnoreCase("hist")) @@ -1515,6 +1522,10 @@ private void analyzeNestedFunction() { if (children.size() > 0) { this.type = new ArrayType(children.get(0).getType()); } + } else if (fnName.getFunction().equalsIgnoreCase("map")) { + if (children.size() > 1) { + this.type = new MapType(children.get(0).getType(), children.get(1).getType()); + } } else if (fnName.getFunction().equalsIgnoreCase("if")) { if (children.get(1).getType().isArrayType() && ( ((ArrayType) children.get(1).getType()).getItemType().isDecimalV3() diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index d0c82f3fc60773..21598fd7a14ce6 100644 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -64,6 +64,16 @@ [['bitnot'], 'BIGINT', ['BIGINT'], ''], [['bitnot'], 'LARGEINT', ['LARGEINT'], ''], + # map functions + [['map'], 'MAP', ['K', 'V', '...'], 'ALWAYS_NOT_NULLABLE', ['K', 'V']], + [['element_at', '%element_extract%'], 'V', ['MAP', 'K'], 'ALWAYS_NULLABLE', ['K', 'V']], + [['size', 'map_size'], 'BIGINT', ['MAP'], '', ['K', 'V']], + [['map_contains_key'], 'BOOLEAN', ['MAP', 'K'], '', ['K', 'V']], + [['map_contains_value'], 'BOOLEAN', ['MAP', 'V'], '', ['K', 'V']], + #[['map_contains_key_like'], 'BOOLEAN', ['MAP', 'K'], '', ['K', 'V']], + [['map_keys'], 'ARRAY', ['MAP'], '', ['K', 'V']], + [['map_values'], 'ARRAY', ['MAP'], '', ['K', 'V']], + # array functions [['array'], 'ARRAY', ['BOOLEAN', '...'], 'ALWAYS_NOT_NULLABLE'], [['array'], 'ARRAY', ['TINYINT', '...'], 'ALWAYS_NOT_NULLABLE'], @@ -103,9 +113,6 @@ [['element_at', '%element_extract%'], 'VARCHAR', ['ARRAY_VARCHAR', 'BIGINT'], 'ALWAYS_NULLABLE'], [['element_at', '%element_extract%'], 'STRING', ['ARRAY_STRING', 'BIGINT'], 'ALWAYS_NULLABLE'], - # map element - [['element_at', '%element_extract%'], 'V', ['MAP', 'K'], 'ALWAYS_NULLABLE', ['K', 'V']], - [['arrays_overlap'], 'BOOLEAN', ['ARRAY_BOOLEAN', 'ARRAY_BOOLEAN'], 'ALWAYS_NULLABLE'], [['arrays_overlap'], 'BOOLEAN', ['ARRAY_TINYINT', 'ARRAY_TINYINT'], 'ALWAYS_NULLABLE'], [['arrays_overlap'], 'BOOLEAN', ['ARRAY_SMALLINT', 'ARRAY_SMALLINT'], 'ALWAYS_NULLABLE'], From e7a912bd1b13cfff8a8c8246833d0a04097f3de2 Mon Sep 17 00:00:00 2001 From: Kang Date: Sat, 18 Feb 2023 10:05:35 +0800 Subject: [PATCH 02/13] add testcase for basic map functions --- .../test_map_load_and_function.out | 368 ++++++++++++++++++ .../test_map_load_and_function.groovy | 70 ++++ 2 files changed, 438 insertions(+) diff --git a/regression-test/data/load_p0/stream_load/test_map_load_and_function.out b/regression-test/data/load_p0/stream_load/test_map_load_and_function.out index 94ef70fdeaa5e6..8bb23bb4c4384f 100644 --- a/regression-test/data/load_p0/stream_load/test_map_load_and_function.out +++ b/regression-test/data/load_p0/stream_load/test_map_load_and_function.out @@ -49,3 +49,371 @@ -- !select_m5 -- 1 100 200 \N + +-- !select_map_contains_value101 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} true +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} true +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_value102 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} true +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} true +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} true +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_value103 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} true +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_value104 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} true +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_value105 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} true +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_value106 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} true +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_value107 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} true +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_value108 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} true +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_value109 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} true +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} true +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} true +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_value110 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} true +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_value111 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} true +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_value112 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} true +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_value113 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} true +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_value114 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} true +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} true +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} true +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_value115 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} true +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_value116 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_value117 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} \N +3 {'k1':31, 'k2':300} \N +4 {} \N +5 \N \N +6 {'k1':41, 'k2':400} \N +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +8 {} \N +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +10 {} \N +11 \N \N +12 {'k3':23, null:20, 'k4':null} \N +13 {'null':1} \N +15 {'':2, 'k2':0} \N +16 {null:null} \N +17 \N \N +18 {'k1':100, 'k2':130} \N + +-- !select_map_keys1 -- +['k11', 'k22'] + +-- !select_map_keys2 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} [' 11amory ', 'beat', ' clever '] +3 {'k1':31, 'k2':300} ['k1', 'k2'] +4 {} [] +5 \N \N +6 {'k1':41, 'k2':400} ['k1', 'k2'] +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} [' 33,amory ', ' bet ', ' cler '] +8 {} [] +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} [' 1,amy ', ' k2 ', ' k7 '] +10 {} [] +11 \N \N +12 {'k3':23, null:20, 'k4':null} ['k3', NULL, 'k4'] +13 {'null':1} ['null'] +15 {'':2, 'k2':0} ['', 'k2'] +16 {null:null} [NULL] +17 \N \N +18 {'k1':100, 'k2':130} ['k1', 'k2'] + +-- !select_map_values1 -- +[1000, 2000] + +-- !select_map_values2 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} [23, 20, 66] +3 {'k1':31, 'k2':300} [31, 300] +4 {} [] +5 \N \N +6 {'k1':41, 'k2':400} [41, 400] +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} [2, 20, 26] +8 {} [] +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} [2, 90, 33] +10 {} [] +11 \N \N +12 {'k3':23, null:20, 'k4':null} [23, 20, NULL] +13 {'null':1} [1] +15 {'':2, 'k2':0} [2, 0] +16 {null:null} [NULL] +17 \N \N +18 {'k1':100, 'k2':130} [100, 130] + diff --git a/regression-test/suites/load_p0/stream_load/test_map_load_and_function.groovy b/regression-test/suites/load_p0/stream_load/test_map_load_and_function.groovy index 38e4d295ca1a5a..0792dfff01e272 100644 --- a/regression-test/suites/load_p0/stream_load/test_map_load_and_function.groovy +++ b/regression-test/suites/load_p0/stream_load/test_map_load_and_function.groovy @@ -72,6 +72,76 @@ suite("test_map_load_and_function", "p0") { // map element_at qt_select_m "SELECT id, m['k2'] FROM ${testTable} ORDER BY id" + // check result + qt_select2 "SELECT * FROM ${testTable} ORDER BY id" + + // map construct + qt_select_map1 "SELECT map('k11', 1000, 'k22', 2000)" + + // map element_at + qt_select_element1 "SELECT map('k11', 1000, 'k22', 2000)['k11']" + qt_select_element2 "SELECT map('k11', 1000, 'k22', 2000)['k22']" + qt_select_element3 "SELECT map('k11', 1000, 'k22', 2000)['nokey']" + qt_select_element4 "SELECT map('k11', 1000, 'k22', 2000)['']" + // qt_select_element5 "SELECT map('k11', 1000, 'k22', 2000)[NULL]" + qt_select_element6 "SELECT id, m, m['k2'] FROM ${testTable} ORDER BY id" + + // map size + qt_select_map_size1 "SELECT size(map('k11', 1000, 'k22', 2000))" + qt_select_map_size2 "SELECT id, m, size(m), map_size(m) FROM ${testTable} ORDER BY id" + + // map_contains_key + qt_select_map_contains_key1 "SELECT map_contains_key(map('k11', 1000, 'k22', 2000), 'k11')" + qt_select_map_contains_key2 "SELECT map_contains_key(map('k11', 1000, 'k22', 2000), 'k22')" + qt_select_map_contains_key3 "SELECT map_contains_key(map('k11', 1000, 'k22', 2000), 'nokey')" + qt_select_map_contains_key4 "SELECT map_contains_key(map('k11', 1000, 'k22', 2000), '')" + qt_select_map_contains_key5 "SELECT map_contains_key(map('k11', 1000, 'k22', 2000), NULL)" + qt_select_map_contains_key101 "SELECT id, m, map_contains_key(m, 'k1') FROM ${testTable} ORDER BY id" + qt_select_map_contains_key102 "SELECT id, m, map_contains_key(m, 'k2') FROM ${testTable} ORDER BY id" + qt_select_map_contains_key103 "SELECT id, m, map_contains_key(m, ' 11amory ') FROM ${testTable} ORDER BY id" + qt_select_map_contains_key104 "SELECT id, m, map_contains_key(m, 'beat') FROM ${testTable} ORDER BY id" + qt_select_map_contains_key105 "SELECT id, m, map_contains_key(m, ' clever ') FROM ${testTable} ORDER BY id" + qt_select_map_contains_key106 "SELECT id, m, map_contains_key(m, ' 33,amory ') FROM ${testTable} ORDER BY id" + qt_select_map_contains_key107 "SELECT id, m, map_contains_key(m, ' bet ') FROM ${testTable} ORDER BY id" + qt_select_map_contains_key108 "SELECT id, m, map_contains_key(m, ' cler ') FROM ${testTable} ORDER BY id" + qt_select_map_contains_key109 "SELECT id, m, map_contains_key(m, ' 1,amy ') FROM ${testTable} ORDER BY id" + qt_select_map_contains_key110 "SELECT id, m, map_contains_key(m, ' k2 ') FROM ${testTable} ORDER BY id" + qt_select_map_contains_key111 "SELECT id, m, map_contains_key(m, 'null') FROM ${testTable} ORDER BY id" + qt_select_map_contains_key112 "SELECT id, m, map_contains_key(m, '') FROM ${testTable} ORDER BY id" + qt_select_map_contains_key113 "SELECT id, m, map_contains_key(m, NULL) FROM ${testTable} ORDER BY id" + qt_select_map_contains_key114 "SELECT id, m, map_contains_key(m, 'nokey') FROM ${testTable} ORDER BY id" + + // map_contains_value + qt_select_map_contains_value1 "SELECT map_contains_value(map('k11', 1000, 'k22', 2000), 1000)" + qt_select_map_contains_value2 "SELECT map_contains_value(map('k11', 1000, 'k22', 2000), 2000)" + qt_select_map_contains_value3 "SELECT map_contains_value(map('k11', 1000, 'k22', 2000), 100)" + qt_select_map_contains_value4 "SELECT map_contains_value(map('k11', 1000, 'k22', 2000), NULL)" + qt_select_map_contains_value101 "SELECT id, m, map_contains_value(m, 23) FROM ${testTable} ORDER BY id" + qt_select_map_contains_value102 "SELECT id, m, map_contains_value(m, 20) FROM ${testTable} ORDER BY id" + qt_select_map_contains_value103 "SELECT id, m, map_contains_value(m, 66) FROM ${testTable} ORDER BY id" + qt_select_map_contains_value104 "SELECT id, m, map_contains_value(m, 31) FROM ${testTable} ORDER BY id" + qt_select_map_contains_value105 "SELECT id, m, map_contains_value(m, 300) FROM ${testTable} ORDER BY id" + qt_select_map_contains_value106 "SELECT id, m, map_contains_value(m, 41) FROM ${testTable} ORDER BY id" + qt_select_map_contains_value107 "SELECT id, m, map_contains_value(m, 400) FROM ${testTable} ORDER BY id" + qt_select_map_contains_value108 "SELECT id, m, map_contains_value(m, 33) FROM ${testTable} ORDER BY id" + qt_select_map_contains_value109 "SELECT id, m, map_contains_value(m, 2) FROM ${testTable} ORDER BY id" + qt_select_map_contains_value110 "SELECT id, m, map_contains_value(m, 26) FROM ${testTable} ORDER BY id" + qt_select_map_contains_value111 "SELECT id, m, map_contains_value(m, 90) FROM ${testTable} ORDER BY id" + qt_select_map_contains_value112 "SELECT id, m, map_contains_value(m, 33) FROM ${testTable} ORDER BY id" + qt_select_map_contains_value113 "SELECT id, m, map_contains_value(m, 1) FROM ${testTable} ORDER BY id" + qt_select_map_contains_value114 "SELECT id, m, map_contains_value(m, 2) FROM ${testTable} ORDER BY id" + qt_select_map_contains_value115 "SELECT id, m, map_contains_value(m, 0) FROM ${testTable} ORDER BY id" + qt_select_map_contains_value116 "SELECT id, m, map_contains_value(m, -1) FROM ${testTable} ORDER BY id" + qt_select_map_contains_value117 "SELECT id, m, map_contains_value(m, NULL) FROM ${testTable} ORDER BY id" + + // map_keys + qt_select_map_keys1 "SELECT map_keys(map('k11', 1000, 'k22', 2000))" + qt_select_map_keys2 "SELECT id, m, map_keys(m) FROM ${testTable} ORDER BY id" + + // map_values + qt_select_map_values1 "SELECT map_values(map('k11', 1000, 'k22', 2000))" + qt_select_map_values2 "SELECT id, m, map_values(m) FROM ${testTable} ORDER BY id" + testTable = "tbl_test_map2" sql "DROP TABLE IF EXISTS ${testTable}" From bbf4a82d584ef0800b3a476515f69ffef9ffa023 Mon Sep 17 00:00:00 2001 From: Kang Date: Mon, 20 Feb 2023 09:54:17 +0800 Subject: [PATCH 03/13] fix function size confilt with array --- be/src/vec/functions/function_map.cpp | 3 +-- .../load_p0/stream_load/test_map_load_and_function.groovy | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/be/src/vec/functions/function_map.cpp b/be/src/vec/functions/function_map.cpp index 59d9ba3c695f5a..114a949f5df3d9 100644 --- a/be/src/vec/functions/function_map.cpp +++ b/be/src/vec/functions/function_map.cpp @@ -119,7 +119,7 @@ class FunctionMap : public IFunction { class FunctionMapSize : public IFunction { public: - static constexpr auto name = "size"; + static constexpr auto name = "map_size"; static FunctionPtr create() { return std::make_shared(); } /// Get function name. @@ -330,7 +330,6 @@ class FunctionMapEntries : public IFunction { void register_function_map(SimpleFunctionFactory& factory) { factory.register_function(); factory.register_function(); - factory.register_alias(FunctionMapSize::name, "map_size"); factory.register_function>(); factory.register_function>(); factory.register_function>(); diff --git a/regression-test/suites/load_p0/stream_load/test_map_load_and_function.groovy b/regression-test/suites/load_p0/stream_load/test_map_load_and_function.groovy index 0792dfff01e272..f32031101107bc 100644 --- a/regression-test/suites/load_p0/stream_load/test_map_load_and_function.groovy +++ b/regression-test/suites/load_p0/stream_load/test_map_load_and_function.groovy @@ -87,8 +87,8 @@ suite("test_map_load_and_function", "p0") { qt_select_element6 "SELECT id, m, m['k2'] FROM ${testTable} ORDER BY id" // map size - qt_select_map_size1 "SELECT size(map('k11', 1000, 'k22', 2000))" - qt_select_map_size2 "SELECT id, m, size(m), map_size(m) FROM ${testTable} ORDER BY id" + qt_select_map_size1 "SELECT map_size(map('k11', 1000, 'k22', 2000))" + qt_select_map_size2 "SELECT id, m, map_size(m) FROM ${testTable} ORDER BY id" // map_contains_key qt_select_map_contains_key1 "SELECT map_contains_key(map('k11', 1000, 'k22', 2000), 'k11')" From 71a8a4028dfa97fb74f694fa3138bcfccfd4499e Mon Sep 17 00:00:00 2001 From: Kang Date: Mon, 20 Feb 2023 10:09:55 +0800 Subject: [PATCH 04/13] clang format --- be/src/vec/functions/function_map.cpp | 55 +++++++++++++-------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/be/src/vec/functions/function_map.cpp b/be/src/vec/functions/function_map.cpp index 114a949f5df3d9..0fcbfc275abf31 100644 --- a/be/src/vec/functions/function_map.cpp +++ b/be/src/vec/functions/function_map.cpp @@ -18,11 +18,11 @@ #include "vec/columns/column_array.h" #include "vec/columns/column_const.h" #include "vec/columns/column_map.h" -#include "vec/data_types/get_least_supertype.h" #include "vec/data_types/data_type.h" #include "vec/data_types/data_type_array.h" #include "vec/data_types/data_type_map.h" #include "vec/data_types/data_type_number.h" +#include "vec/data_types/get_least_supertype.h" #include "vec/functions/array/function_array_index.h" #include "vec/functions/function.h" #include "vec/functions/function_helpers.h" @@ -61,7 +61,7 @@ class FunctionMap : public IFunction { DataTypePtr val_type; get_least_supertype(key_types, &key_type); get_least_supertype(val_types, &val_type); - + return std::make_shared(key_type, val_type); } @@ -94,8 +94,8 @@ class FunctionMap : public IFunction { for (size_t i = 0; i < num_element; ++i) { auto& col = block.get_by_position(arguments[i]).column; col = col->convert_to_full_column_if_const(); - bool is_nullable = i % 2 == 0 ? - result_col_map_keys_data.is_nullable() : result_col_map_vals_data.is_nullable(); + bool is_nullable = i % 2 == 0 ? result_col_map_keys_data.is_nullable() + : result_col_map_vals_data.is_nullable(); if (is_nullable && !col->is_nullable()) { col = ColumnNullable::create(col, ColumnUInt8::create(col->size(), 0)); } @@ -105,8 +105,10 @@ class FunctionMap : public IFunction { ColumnArray::Offset64 offset = 0; for (size_t row = 0; row < input_rows_count; ++row) { for (size_t i = 0; i < num_element; i += 2) { - result_col_map_keys_data.insert_from(*block.get_by_position(arguments[i]).column, row); - result_col_map_vals_data.insert_from(*block.get_by_position(arguments[i + 1]).column, row); + result_col_map_keys_data.insert_from(*block.get_by_position(arguments[i]).column, + row); + result_col_map_vals_data.insert_from( + *block.get_by_position(arguments[i + 1]).column, row); } offset += num_element / 2; result_col_map_keys_offsets[row] = offset; @@ -157,7 +159,7 @@ class FunctionMapSize : public IFunction { } }; -template +template class FunctionMapContains : public IFunction { public: static constexpr auto name = is_key ? "map_contains_key" : "map_contains_value"; @@ -173,7 +175,7 @@ class FunctionMapContains : public IFunction { DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { DCHECK(is_map(arguments[0])) << "first argument for function: " << name << " should be DataTypeMap"; - + if (arguments[0]->is_nullable()) { return make_nullable(std::make_shared>()); } else { @@ -193,25 +195,23 @@ class FunctionMapContains : public IFunction { block.get_by_position(arguments[0]).type->get_name()); } - const auto datatype_map = - static_cast(block.get_by_position(arguments[0]).type.get()); - if constexpr(is_key) { + const auto datatype_map = + static_cast(block.get_by_position(arguments[0]).type.get()); + if constexpr (is_key) { block.get_by_position(arguments[0]) = { - col_map->get_keys_ptr(), - std::make_shared(datatype_map->get_key_type()), - block.get_by_position(arguments[0]).name + ".keys" - }; + col_map->get_keys_ptr(), + std::make_shared(datatype_map->get_key_type()), + block.get_by_position(arguments[0]).name + ".keys"}; } else { block.get_by_position(arguments[0]) = { - col_map->get_values_ptr(), - std::make_shared(datatype_map->get_value_type()), - block.get_by_position(arguments[0]).name + ".values" - }; + col_map->get_values_ptr(), + std::make_shared(datatype_map->get_value_type()), + block.get_by_position(arguments[0]).name + ".values"}; } RETURN_IF_ERROR( - array_contains.execute_impl(context, block, arguments, result, input_rows_count)); - + array_contains.execute_impl(context, block, arguments, result, input_rows_count)); + // restore original argument 0 block.get_by_position(arguments[0]) = orig_arg0; return Status::OK(); @@ -237,7 +237,7 @@ class FunctionMapContains : public IFunction { // DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { // DCHECK(is_map(arguments[0])) // << "first argument for function: " << name << " should be DataTypeMap"; - + // if (arguments[0]->is_nullable()) { // return make_nullable(std::make_shared>()); // } else { @@ -257,7 +257,7 @@ class FunctionMapContains : public IFunction { // block.get_by_position(arguments[0]).type->get_name()); // } -// const auto datatype_map = +// const auto datatype_map = // static_cast(block.get_by_position(arguments[0]).type.get()); // if constexpr(is_key) { // block.get_by_position(arguments[0]) = { @@ -275,14 +275,14 @@ class FunctionMapContains : public IFunction { // RETURN_IF_ERROR( // array_contains.execute_impl(context, block, arguments, result, input_rows_count)); - + // // restore original argument 0 // block.get_by_position(arguments[0]) = orig_arg0; // return Status::OK(); // } // }; -template +template class FunctionMapEntries : public IFunction { public: static constexpr auto name = is_key ? "map_keys" : "map_values"; @@ -298,8 +298,7 @@ class FunctionMapEntries : public IFunction { DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { DCHECK(is_map(arguments[0])) << "first argument for function: " << name << " should be DataTypeMap"; - const auto datatype_map = - static_cast(arguments[0].get()); + const auto datatype_map = static_cast(arguments[0].get()); if (is_key) { return std::make_shared(datatype_map->get_key_type()); } else { @@ -317,7 +316,7 @@ class FunctionMapEntries : public IFunction { block.get_by_position(arguments[0]).type->get_name()); } - if constexpr(is_key) { + if constexpr (is_key) { block.replace_by_position(result, col_map->get_keys_ptr()); } else { block.replace_by_position(result, col_map->get_values_ptr()); From 080f98deacbc7a6acd5ff458463d898a26efb8e5 Mon Sep 17 00:00:00 2001 From: Kang Date: Thu, 9 Mar 2023 01:41:20 +0800 Subject: [PATCH 05/13] fix MapType ArrayType template for return type --- .../java/org/apache/doris/catalog/ArrayType.java | 10 +++++++--- .../java/org/apache/doris/catalog/MapType.java | 15 ++++++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/fe/fe-common/src/main/java/org/apache/doris/catalog/ArrayType.java b/fe/fe-common/src/main/java/org/apache/doris/catalog/ArrayType.java index a28f3c030236b1..938722528a19e2 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/catalog/ArrayType.java +++ b/fe/fe-common/src/main/java/org/apache/doris/catalog/ArrayType.java @@ -101,14 +101,18 @@ public boolean hasTemplateType() { @Override public Type specializeTemplateType(Type specificType, Map specializedTypeMap, boolean useSpecializedType) throws TypeException { - if (!(specificType instanceof ArrayType)) { + ArrayType specificArrayType = null; + if (specificType instanceof ArrayType) { + specificArrayType = (ArrayType) specificType; + } else if (!useSpecializedType) { throw new TypeException(specificType + " is not ArrayType"); } - ArrayType o = (ArrayType) specificType; Type newItemType = itemType; if (itemType.hasTemplateType()) { - newItemType = itemType.specializeTemplateType(o.itemType, specializedTypeMap, useSpecializedType); + newItemType = itemType.specializeTemplateType( + specificArrayType != null ? specificArrayType.itemType : specificType, + specializedTypeMap, useSpecializedType); } return new ArrayType(newItemType); diff --git a/fe/fe-common/src/main/java/org/apache/doris/catalog/MapType.java b/fe/fe-common/src/main/java/org/apache/doris/catalog/MapType.java index e72df777100691..a1000b90582eab 100644 --- a/fe/fe-common/src/main/java/org/apache/doris/catalog/MapType.java +++ b/fe/fe-common/src/main/java/org/apache/doris/catalog/MapType.java @@ -130,24 +130,29 @@ public boolean hasTemplateType() { @Override public Type specializeTemplateType(Type specificType, Map specializedTypeMap, boolean useSpecializedType) throws TypeException { - if (!(specificType instanceof MapType)) { + MapType specificMapType = null; + if (specificType instanceof MapType) { + specificMapType = (MapType) specificType; + } else if (!useSpecializedType) { throw new TypeException(specificType + " is not MapType"); } - MapType specificMapType = (MapType) specificType; Type newKeyType = keyType; if (keyType.hasTemplateType()) { newKeyType = keyType.specializeTemplateType( - specificMapType.keyType, specializedTypeMap, useSpecializedType); + specificMapType != null ? specificMapType.keyType : specificType, + specializedTypeMap, useSpecializedType); } Type newValueType = valueType; if (valueType.hasTemplateType()) { newValueType = valueType.specializeTemplateType( - specificMapType.valueType, specializedTypeMap, useSpecializedType); + specificMapType != null ? specificMapType.valueType : specificType, + specializedTypeMap, useSpecializedType); } Type newMapType = new MapType(newKeyType, newValueType); - if (Type.canCastTo(specificType, newMapType)) { + if (Type.canCastTo(specificType, newMapType) + || (useSpecializedType && !(specificType instanceof MapType))) { return newMapType; } else { throw new TypeException(specificType + " can not cast to specialize type " + newMapType); From 7eac81525d7e5dfb13162de6bcdff58e670d49f3 Mon Sep 17 00:00:00 2001 From: Kang Date: Thu, 9 Mar 2023 01:41:56 +0800 Subject: [PATCH 06/13] fix nullable for map functions --- be/src/vec/functions/function_map.cpp | 113 ++++++++++++++++++++------ 1 file changed, 86 insertions(+), 27 deletions(-) diff --git a/be/src/vec/functions/function_map.cpp b/be/src/vec/functions/function_map.cpp index 0fcbfc275abf31..37465049c2896e 100644 --- a/be/src/vec/functions/function_map.cpp +++ b/be/src/vec/functions/function_map.cpp @@ -21,6 +21,7 @@ #include "vec/data_types/data_type.h" #include "vec/data_types/data_type_array.h" #include "vec/data_types/data_type_map.h" +#include "vec/data_types/data_type_nullable.h" #include "vec/data_types/data_type_number.h" #include "vec/data_types/get_least_supertype.h" #include "vec/functions/array/function_array_index.h" @@ -132,7 +133,11 @@ class FunctionMapSize : public IFunction { size_t get_number_of_arguments() const override { return 1; } DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { - DCHECK(is_map(arguments[0])) + DataTypePtr datatype = arguments[0]; + if (datatype->is_nullable()) { + datatype = assert_cast(datatype.get())->get_nested_type(); + } + DCHECK(is_map(datatype)) << "first argument for function: " << name << " should be DataTypeMap"; return std::make_shared(); } @@ -141,8 +146,17 @@ class FunctionMapSize : public IFunction { size_t result, size_t input_rows_count) override { auto left_column = block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); - const auto col_map = check_and_get_column(*left_column); - if (!col_map) { + const ColumnMap* map_column = nullptr; + // const UInt8* map_null_map = nullptr; + if (left_column->is_nullable()) { + auto nullable_column = reinterpret_cast(left_column.get()); + map_column = + check_and_get_column(nullable_column->get_nested_column()); + // map_null_map = nullable_column->get_null_map_column().get_data().data(); + } else { + map_column = check_and_get_column(*left_column.get()); + } + if (!map_column) { return Status::RuntimeError("unsupported types for function {}({})", get_name(), block.get_by_position(arguments[0]).type->get_name()); } @@ -150,8 +164,8 @@ class FunctionMapSize : public IFunction { auto dst_column = ColumnInt64::create(input_rows_count); auto& dst_data = dst_column->get_data(); - for (size_t i = 0; i < col_map->size(); i++) { - dst_data[i] = col_map->size_at(i); + for (size_t i = 0; i < map_column->size(); i++) { + dst_data[i] = map_column->size_at(i); } block.replace_by_position(result, std::move(dst_column)); @@ -172,15 +186,18 @@ class FunctionMapContains : public IFunction { size_t get_number_of_arguments() const override { return 2; } - DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { - DCHECK(is_map(arguments[0])) - << "first argument for function: " << name << " should be DataTypeMap"; + bool use_default_implementation_for_nulls() const override { + return array_contains.use_default_implementation_for_nulls(); + } - if (arguments[0]->is_nullable()) { - return make_nullable(std::make_shared>()); - } else { - return std::make_shared>(); + DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { + DataTypePtr datatype = arguments[0]; + if (datatype->is_nullable()) { + datatype = assert_cast(datatype.get())->get_nested_type(); } + DCHECK(is_map(datatype)) + << "first argument for function: " << name << " should be DataTypeMap"; + return make_nullable(std::make_shared>()); } Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, @@ -189,24 +206,55 @@ class FunctionMapContains : public IFunction { auto orig_arg0 = block.get_by_position(arguments[0]); auto left_column = block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); - const auto col_map = check_and_get_column(*left_column); - if (!col_map) { + const ColumnMap* map_column = nullptr; + ColumnPtr nullmap_column = nullptr; + if (left_column->is_nullable()) { + auto nullable_column = reinterpret_cast(left_column.get()); + map_column = + check_and_get_column(nullable_column->get_nested_column()); + nullmap_column = nullable_column->get_null_map_column_ptr(); + } else { + map_column = check_and_get_column(*left_column.get()); + } + if (!map_column) { return Status::RuntimeError("unsupported types for function {}({})", get_name(), block.get_by_position(arguments[0]).type->get_name()); } + DataTypePtr datatype = block.get_by_position(arguments[0]).type; + if (datatype->is_nullable()) { + datatype = assert_cast(datatype.get())->get_nested_type(); + } const auto datatype_map = - static_cast(block.get_by_position(arguments[0]).type.get()); + static_cast(datatype.get()); if constexpr (is_key) { - block.get_by_position(arguments[0]) = { - col_map->get_keys_ptr(), - std::make_shared(datatype_map->get_key_type()), + const auto& array_column = map_column->get_keys_ptr(); + const auto datatype_array = std::make_shared(datatype_map->get_key_type()); + if (nullmap_column) { + block.get_by_position(arguments[0]) = { + ColumnNullable::create(array_column, nullmap_column), + make_nullable(datatype_array), + block.get_by_position(arguments[0]).name + ".keys"}; + } else { + block.get_by_position(arguments[0]) = { + array_column, + datatype_array, block.get_by_position(arguments[0]).name + ".keys"}; + } } else { - block.get_by_position(arguments[0]) = { - col_map->get_values_ptr(), - std::make_shared(datatype_map->get_value_type()), + const auto& array_column = map_column->get_values_ptr(); + const auto datatype_array = std::make_shared(datatype_map->get_value_type()); + if (nullmap_column) { + block.get_by_position(arguments[0]) = { + ColumnNullable::create(array_column, nullmap_column), + make_nullable(datatype_array), + block.get_by_position(arguments[0]).name + ".values"}; + } else { + block.get_by_position(arguments[0]) = { + array_column, + datatype_array, block.get_by_position(arguments[0]).name + ".values"}; + } } RETURN_IF_ERROR( @@ -296,9 +344,13 @@ class FunctionMapEntries : public IFunction { size_t get_number_of_arguments() const override { return 1; } DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { - DCHECK(is_map(arguments[0])) + DataTypePtr datatype = arguments[0]; + if (datatype->is_nullable()) { + datatype = assert_cast(datatype.get())->get_nested_type(); + } + DCHECK(is_map(datatype)) << "first argument for function: " << name << " should be DataTypeMap"; - const auto datatype_map = static_cast(arguments[0].get()); + const auto datatype_map = static_cast(datatype.get()); if (is_key) { return std::make_shared(datatype_map->get_key_type()); } else { @@ -310,16 +362,23 @@ class FunctionMapEntries : public IFunction { size_t result, size_t input_rows_count) override { auto left_column = block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); - const auto col_map = check_and_get_column(*left_column); - if (!col_map) { + const ColumnMap* map_column = nullptr; + if (left_column->is_nullable()) { + auto nullable_column = reinterpret_cast(left_column.get()); + map_column = + check_and_get_column(nullable_column->get_nested_column()); + } else { + map_column = check_and_get_column(*left_column.get()); + } + if (!map_column) { return Status::RuntimeError("unsupported types for function {}({})", get_name(), block.get_by_position(arguments[0]).type->get_name()); } if constexpr (is_key) { - block.replace_by_position(result, col_map->get_keys_ptr()); + block.replace_by_position(result, map_column->get_keys_ptr()); } else { - block.replace_by_position(result, col_map->get_values_ptr()); + block.replace_by_position(result, map_column->get_values_ptr()); } return Status::OK(); From df5ad8d598231a6c9b6c0dfcdbd26ee68716cff6 Mon Sep 17 00:00:00 2001 From: Kang Date: Thu, 9 Mar 2023 01:42:13 +0800 Subject: [PATCH 07/13] fix testcase --- gensrc/script/doris_builtins_functions.py | 4 +- .../test_map_load_and_function.out | 676 +++++++++++++++++- .../test_map_load_and_function.groovy | 21 +- 3 files changed, 674 insertions(+), 27 deletions(-) diff --git a/gensrc/script/doris_builtins_functions.py b/gensrc/script/doris_builtins_functions.py index 21598fd7a14ce6..b575dae5884970 100644 --- a/gensrc/script/doris_builtins_functions.py +++ b/gensrc/script/doris_builtins_functions.py @@ -68,8 +68,8 @@ [['map'], 'MAP', ['K', 'V', '...'], 'ALWAYS_NOT_NULLABLE', ['K', 'V']], [['element_at', '%element_extract%'], 'V', ['MAP', 'K'], 'ALWAYS_NULLABLE', ['K', 'V']], [['size', 'map_size'], 'BIGINT', ['MAP'], '', ['K', 'V']], - [['map_contains_key'], 'BOOLEAN', ['MAP', 'K'], '', ['K', 'V']], - [['map_contains_value'], 'BOOLEAN', ['MAP', 'V'], '', ['K', 'V']], + [['map_contains_key'], 'BOOLEAN', ['MAP', 'K'], 'ALWAYS_NULLABLE', ['K', 'V']], + [['map_contains_value'], 'BOOLEAN', ['MAP', 'V'], 'ALWAYS_NULLABLE', ['K', 'V']], #[['map_contains_key_like'], 'BOOLEAN', ['MAP', 'K'], '', ['K', 'V']], [['map_keys'], 'ARRAY', ['MAP'], '', ['K', 'V']], [['map_values'], 'ARRAY', ['MAP'], '', ['K', 'V']], diff --git a/regression-test/data/load_p0/stream_load/test_map_load_and_function.out b/regression-test/data/load_p0/stream_load/test_map_load_and_function.out index 8bb23bb4c4384f..1925f88e27f635 100644 --- a/regression-test/data/load_p0/stream_load/test_map_load_and_function.out +++ b/regression-test/data/load_p0/stream_load/test_map_load_and_function.out @@ -35,20 +35,635 @@ 17 \N 18 130 --- !select_m1 -- -1 100 200 \N +-- !select2 -- +1 \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} +3 {'k1':31, 'k2':300} +4 {} +5 \N +6 {'k1':41, 'k2':400} +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} +8 {} +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} +10 {} +11 \N +12 {'k3':23, null:20, 'k4':null} +13 {'null':1} +15 {'':2, 'k2':0} +16 {null:null} +17 \N +18 {'k1':100, 'k2':130} + +-- !select_map1 -- +{'k11':1000, 'k22':2000} + +-- !select_map2 -- +{1000:'k11', 2000:'k22'} + +-- !select_element1 -- +1000 + +-- !select_element2 -- +2000 + +-- !select_element3 -- +\N + +-- !select_element4 -- +\N + +-- !select_element5 -- +k11 + +-- !select_element6 -- +k22 + +-- !select_element7 -- +\N + +-- !select_element8 -- +\N + +-- !select_element101 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} \N +3 {'k1':31, 'k2':300} 31 +4 {} \N +5 \N \N +6 {'k1':41, 'k2':400} 41 +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +8 {} \N +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +10 {} \N +11 \N \N +12 {'k3':23, null:20, 'k4':null} \N +13 {'null':1} \N +15 {'':2, 'k2':0} \N +16 {null:null} \N +17 \N \N +18 {'k1':100, 'k2':130} 100 + +-- !select_element102 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} \N +3 {'k1':31, 'k2':300} 300 +4 {} \N +5 \N \N +6 {'k1':41, 'k2':400} 400 +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +8 {} \N +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +10 {} \N +11 \N \N +12 {'k3':23, null:20, 'k4':null} \N +13 {'null':1} \N +15 {'':2, 'k2':0} 0 +16 {null:null} \N +17 \N \N +18 {'k1':100, 'k2':130} 130 + +-- !select_element103 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} 23 +3 {'k1':31, 'k2':300} \N +4 {} \N +5 \N \N +6 {'k1':41, 'k2':400} \N +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +8 {} \N +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +10 {} \N +11 \N \N +12 {'k3':23, null:20, 'k4':null} \N +13 {'null':1} \N +15 {'':2, 'k2':0} \N +16 {null:null} \N +17 \N \N +18 {'k1':100, 'k2':130} \N + +-- !select_element104 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} 20 +3 {'k1':31, 'k2':300} \N +4 {} \N +5 \N \N +6 {'k1':41, 'k2':400} \N +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +8 {} \N +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +10 {} \N +11 \N \N +12 {'k3':23, null:20, 'k4':null} \N +13 {'null':1} \N +15 {'':2, 'k2':0} \N +16 {null:null} \N +17 \N \N +18 {'k1':100, 'k2':130} \N + +-- !select_element105 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} 66 +3 {'k1':31, 'k2':300} \N +4 {} \N +5 \N \N +6 {'k1':41, 'k2':400} \N +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +8 {} \N +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +10 {} \N +11 \N \N +12 {'k3':23, null:20, 'k4':null} \N +13 {'null':1} \N +15 {'':2, 'k2':0} \N +16 {null:null} \N +17 \N \N +18 {'k1':100, 'k2':130} \N + +-- !select_element106 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} \N +3 {'k1':31, 'k2':300} \N +4 {} \N +5 \N \N +6 {'k1':41, 'k2':400} \N +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} 2 +8 {} \N +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +10 {} \N +11 \N \N +12 {'k3':23, null:20, 'k4':null} \N +13 {'null':1} \N +15 {'':2, 'k2':0} \N +16 {null:null} \N +17 \N \N +18 {'k1':100, 'k2':130} \N + +-- !select_element107 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} \N +3 {'k1':31, 'k2':300} \N +4 {} \N +5 \N \N +6 {'k1':41, 'k2':400} \N +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} 20 +8 {} \N +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +10 {} \N +11 \N \N +12 {'k3':23, null:20, 'k4':null} \N +13 {'null':1} \N +15 {'':2, 'k2':0} \N +16 {null:null} \N +17 \N \N +18 {'k1':100, 'k2':130} \N + +-- !select_element108 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} \N +3 {'k1':31, 'k2':300} \N +4 {} \N +5 \N \N +6 {'k1':41, 'k2':400} \N +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} 26 +8 {} \N +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +10 {} \N +11 \N \N +12 {'k3':23, null:20, 'k4':null} \N +13 {'null':1} \N +15 {'':2, 'k2':0} \N +16 {null:null} \N +17 \N \N +18 {'k1':100, 'k2':130} \N + +-- !select_element109 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} \N +3 {'k1':31, 'k2':300} \N +4 {} \N +5 \N \N +6 {'k1':41, 'k2':400} \N +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +8 {} \N +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} 2 +10 {} \N +11 \N \N +12 {'k3':23, null:20, 'k4':null} \N +13 {'null':1} \N +15 {'':2, 'k2':0} \N +16 {null:null} \N +17 \N \N +18 {'k1':100, 'k2':130} \N + +-- !select_element110 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} \N +3 {'k1':31, 'k2':300} \N +4 {} \N +5 \N \N +6 {'k1':41, 'k2':400} \N +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +8 {} \N +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} 90 +10 {} \N +11 \N \N +12 {'k3':23, null:20, 'k4':null} \N +13 {'null':1} \N +15 {'':2, 'k2':0} \N +16 {null:null} \N +17 \N \N +18 {'k1':100, 'k2':130} \N + +-- !select_element111 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} \N +3 {'k1':31, 'k2':300} \N +4 {} \N +5 \N \N +6 {'k1':41, 'k2':400} \N +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +8 {} \N +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +10 {} \N +11 \N \N +12 {'k3':23, null:20, 'k4':null} \N +13 {'null':1} 1 +15 {'':2, 'k2':0} \N +16 {null:null} \N +17 \N \N +18 {'k1':100, 'k2':130} \N + +-- !select_element112 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} \N +3 {'k1':31, 'k2':300} \N +4 {} \N +5 \N \N +6 {'k1':41, 'k2':400} \N +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +8 {} \N +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +10 {} \N +11 \N \N +12 {'k3':23, null:20, 'k4':null} 20 +13 {'null':1} \N +15 {'':2, 'k2':0} 2 +16 {null:null} \N +17 \N \N +18 {'k1':100, 'k2':130} \N + +-- !select_element113 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} \N +3 {'k1':31, 'k2':300} \N +4 {} \N +5 \N \N +6 {'k1':41, 'k2':400} \N +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +8 {} \N +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +10 {} \N +11 \N \N +12 {'k3':23, null:20, 'k4':null} \N +13 {'null':1} \N +15 {'':2, 'k2':0} \N +16 {null:null} \N +17 \N \N +18 {'k1':100, 'k2':130} \N + +-- !select_element114 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} \N +3 {'k1':31, 'k2':300} \N +4 {} \N +5 \N \N +6 {'k1':41, 'k2':400} \N +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +8 {} \N +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +10 {} \N +11 \N \N +12 {'k3':23, null:20, 'k4':null} \N +13 {'null':1} \N +15 {'':2, 'k2':0} \N +16 {null:null} \N +17 \N \N +18 {'k1':100, 'k2':130} \N + +-- !select_map_size1 -- +2 + +-- !select_map_size2 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} 3 +3 {'k1':31, 'k2':300} 2 +4 {} 0 +5 \N \N +6 {'k1':41, 'k2':400} 2 +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} 3 +8 {} 0 +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} 3 +10 {} 0 +11 \N \N +12 {'k3':23, null:20, 'k4':null} 3 +13 {'null':1} 1 +15 {'':2, 'k2':0} 2 +16 {null:null} 1 +17 \N \N +18 {'k1':100, 'k2':130} 2 + +-- !select_map_contains_key1 -- +true + +-- !select_map_contains_key2 -- +true + +-- !select_map_contains_key3 -- +false + +-- !select_map_contains_key4 -- +false + +-- !select_map_contains_key5 -- +false + +-- !select_map_contains_key101 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} true +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} true +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} true + +-- !select_map_contains_key102 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} true +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} true +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} true +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} true + +-- !select_map_contains_key103 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} true +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false --- !select_m2 -- -1 k1 k2 \N +-- !select_map_contains_key104 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} true +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false --- !select_m3 -- -1 v1 v2 \N +-- !select_map_contains_key105 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} true +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false --- !select_m4 -- -1 10000 20000 \N +-- !select_map_contains_key106 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} true +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false --- !select_m5 -- -1 100 200 \N +-- !select_map_contains_key107 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} true +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_key108 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} true +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_key109 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} true +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_key110 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} true +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_key111 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} true +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_key112 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} true +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_key113 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} true +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} true +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_key114 -- +1 \N \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false +5 \N \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false +11 \N \N +12 {'k3':23, null:20, 'k4':null} false +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} false +17 \N \N +18 {'k1':100, 'k2':130} false + +-- !select_map_contains_value1 -- +true + +-- !select_map_contains_value2 -- +true + +-- !select_map_contains_value3 -- +false + +-- !select_map_contains_value4 -- +false -- !select_map_contains_value101 -- 1 \N \N @@ -356,22 +971,22 @@ -- !select_map_contains_value117 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} \N -3 {'k1':31, 'k2':300} \N -4 {} \N +2 {' 11amory ':23, 'beat':20, ' clever ':66} false +3 {'k1':31, 'k2':300} false +4 {} false 5 \N \N -6 {'k1':41, 'k2':400} \N -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N -8 {} \N -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N -10 {} \N +6 {'k1':41, 'k2':400} false +7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +8 {} false +9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} \N -13 {'null':1} \N -15 {'':2, 'k2':0} \N -16 {null:null} \N +12 {'k3':23, null:20, 'k4':null} true +13 {'null':1} false +15 {'':2, 'k2':0} false +16 {null:null} true 17 \N \N -18 {'k1':100, 'k2':130} \N +18 {'k1':100, 'k2':130} false -- !select_map_keys1 -- ['k11', 'k22'] @@ -417,3 +1032,18 @@ 17 \N \N 18 {'k1':100, 'k2':130} [100, 130] +-- !select_m1 -- +1 100 200 \N + +-- !select_m2 -- +1 k1 k2 \N + +-- !select_m3 -- +1 v1 v2 \N + +-- !select_m4 -- +1 10000 20000 \N + +-- !select_m5 -- +1 100 200 \N + diff --git a/regression-test/suites/load_p0/stream_load/test_map_load_and_function.groovy b/regression-test/suites/load_p0/stream_load/test_map_load_and_function.groovy index f32031101107bc..a328f61ec66bf1 100644 --- a/regression-test/suites/load_p0/stream_load/test_map_load_and_function.groovy +++ b/regression-test/suites/load_p0/stream_load/test_map_load_and_function.groovy @@ -77,14 +77,31 @@ suite("test_map_load_and_function", "p0") { // map construct qt_select_map1 "SELECT map('k11', 1000, 'k22', 2000)" + qt_select_map2 "SELECT map(1000, 'k11', 2000, 'k22')" // map element_at qt_select_element1 "SELECT map('k11', 1000, 'k22', 2000)['k11']" qt_select_element2 "SELECT map('k11', 1000, 'k22', 2000)['k22']" qt_select_element3 "SELECT map('k11', 1000, 'k22', 2000)['nokey']" qt_select_element4 "SELECT map('k11', 1000, 'k22', 2000)['']" - // qt_select_element5 "SELECT map('k11', 1000, 'k22', 2000)[NULL]" - qt_select_element6 "SELECT id, m, m['k2'] FROM ${testTable} ORDER BY id" + qt_select_element5 "SELECT map(1000, 'k11', 2000, 'k22')[1000]" + qt_select_element6 "SELECT map(1000, 'k11', 2000, 'k22')[2000]" + qt_select_element7 "SELECT map(1000, 'k11', 2000, 'k22')[3000]" + qt_select_element8 "SELECT map('k11', 1000, 'k22', 2000)[NULL]" + qt_select_element101 "SELECT id, m, m['k1'] FROM ${testTable} ORDER BY id" + qt_select_element102 "SELECT id, m, m['k2'] FROM ${testTable} ORDER BY id" + qt_select_element103 "SELECT id, m, m[' 11amory '] FROM ${testTable} ORDER BY id" + qt_select_element104 "SELECT id, m, m['beat'] FROM ${testTable} ORDER BY id" + qt_select_element105 "SELECT id, m, m[' clever '] FROM ${testTable} ORDER BY id" + qt_select_element106 "SELECT id, m, m[' 33,amory '] FROM ${testTable} ORDER BY id" + qt_select_element107 "SELECT id, m, m[' bet '] FROM ${testTable} ORDER BY id" + qt_select_element108 "SELECT id, m, m[' cler '] FROM ${testTable} ORDER BY id" + qt_select_element109 "SELECT id, m, m[' 1,amy '] FROM ${testTable} ORDER BY id" + qt_select_element110 "SELECT id, m, m[' k2 '] FROM ${testTable} ORDER BY id" + qt_select_element111 "SELECT id, m, m['null'] FROM ${testTable} ORDER BY id" + qt_select_element112 "SELECT id, m, m[''] FROM ${testTable} ORDER BY id" + qt_select_element113 "SELECT id, m, m[NULL] FROM ${testTable} ORDER BY id" + qt_select_element114 "SELECT id, m, m['nokey'] FROM ${testTable} ORDER BY id" // map size qt_select_map_size1 "SELECT map_size(map('k11', 1000, 'k22', 2000))" From 04dc556213d046c0405c8a5b52aef0bd87619757 Mon Sep 17 00:00:00 2001 From: Kang Date: Thu, 9 Mar 2023 01:43:09 +0800 Subject: [PATCH 08/13] format --- be/src/vec/functions/function_map.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/be/src/vec/functions/function_map.cpp b/be/src/vec/functions/function_map.cpp index 37465049c2896e..82f74a7ddf86cb 100644 --- a/be/src/vec/functions/function_map.cpp +++ b/be/src/vec/functions/function_map.cpp @@ -229,7 +229,8 @@ class FunctionMapContains : public IFunction { static_cast(datatype.get()); if constexpr (is_key) { const auto& array_column = map_column->get_keys_ptr(); - const auto datatype_array = std::make_shared(datatype_map->get_key_type()); + const auto datatype_array = + std::make_shared(datatype_map->get_key_type()); if (nullmap_column) { block.get_by_position(arguments[0]) = { ColumnNullable::create(array_column, nullmap_column), @@ -243,7 +244,8 @@ class FunctionMapContains : public IFunction { } } else { const auto& array_column = map_column->get_values_ptr(); - const auto datatype_array = std::make_shared(datatype_map->get_value_type()); + const auto datatype_array = + std::make_shared(datatype_map->get_value_type()); if (nullmap_column) { block.get_by_position(arguments[0]) = { ColumnNullable::create(array_column, nullmap_column), From 7a154159a6dec508ed0493c04dd65d457df798dc Mon Sep 17 00:00:00 2001 From: Kang Date: Thu, 9 Mar 2023 10:30:37 +0800 Subject: [PATCH 09/13] clang format --- be/src/vec/functions/function_map.cpp | 50 ++++++++++++--------------- 1 file changed, 22 insertions(+), 28 deletions(-) diff --git a/be/src/vec/functions/function_map.cpp b/be/src/vec/functions/function_map.cpp index 82f74a7ddf86cb..d5374fdddfa073 100644 --- a/be/src/vec/functions/function_map.cpp +++ b/be/src/vec/functions/function_map.cpp @@ -137,8 +137,8 @@ class FunctionMapSize : public IFunction { if (datatype->is_nullable()) { datatype = assert_cast(datatype.get())->get_nested_type(); } - DCHECK(is_map(datatype)) - << "first argument for function: " << name << " should be DataTypeMap"; + DCHECK(is_map(datatype)) << "first argument for function: " << name + << " should be DataTypeMap"; return std::make_shared(); } @@ -150,8 +150,7 @@ class FunctionMapSize : public IFunction { // const UInt8* map_null_map = nullptr; if (left_column->is_nullable()) { auto nullable_column = reinterpret_cast(left_column.get()); - map_column = - check_and_get_column(nullable_column->get_nested_column()); + map_column = check_and_get_column(nullable_column->get_nested_column()); // map_null_map = nullable_column->get_null_map_column().get_data().data(); } else { map_column = check_and_get_column(*left_column.get()); @@ -195,8 +194,8 @@ class FunctionMapContains : public IFunction { if (datatype->is_nullable()) { datatype = assert_cast(datatype.get())->get_nested_type(); } - DCHECK(is_map(datatype)) - << "first argument for function: " << name << " should be DataTypeMap"; + DCHECK(is_map(datatype)) << "first argument for function: " << name + << " should be DataTypeMap"; return make_nullable(std::make_shared>()); } @@ -210,8 +209,7 @@ class FunctionMapContains : public IFunction { ColumnPtr nullmap_column = nullptr; if (left_column->is_nullable()) { auto nullable_column = reinterpret_cast(left_column.get()); - map_column = - check_and_get_column(nullable_column->get_nested_column()); + map_column = check_and_get_column(nullable_column->get_nested_column()); nullmap_column = nullable_column->get_null_map_column_ptr(); } else { map_column = check_and_get_column(*left_column.get()); @@ -225,37 +223,34 @@ class FunctionMapContains : public IFunction { if (datatype->is_nullable()) { datatype = assert_cast(datatype.get())->get_nested_type(); } - const auto datatype_map = - static_cast(datatype.get()); + const auto datatype_map = static_cast(datatype.get()); if constexpr (is_key) { const auto& array_column = map_column->get_keys_ptr(); const auto datatype_array = - std::make_shared(datatype_map->get_key_type()); + std::make_shared(datatype_map->get_key_type()); if (nullmap_column) { block.get_by_position(arguments[0]) = { - ColumnNullable::create(array_column, nullmap_column), - make_nullable(datatype_array), - block.get_by_position(arguments[0]).name + ".keys"}; + ColumnNullable::create(array_column, nullmap_column), + make_nullable(datatype_array), + block.get_by_position(arguments[0]).name + ".keys"}; } else { block.get_by_position(arguments[0]) = { - array_column, - datatype_array, - block.get_by_position(arguments[0]).name + ".keys"}; + array_column, datatype_array, + block.get_by_position(arguments[0]).name + ".keys"}; } } else { const auto& array_column = map_column->get_values_ptr(); const auto datatype_array = - std::make_shared(datatype_map->get_value_type()); + std::make_shared(datatype_map->get_value_type()); if (nullmap_column) { block.get_by_position(arguments[0]) = { - ColumnNullable::create(array_column, nullmap_column), - make_nullable(datatype_array), - block.get_by_position(arguments[0]).name + ".values"}; + ColumnNullable::create(array_column, nullmap_column), + make_nullable(datatype_array), + block.get_by_position(arguments[0]).name + ".values"}; } else { block.get_by_position(arguments[0]) = { - array_column, - datatype_array, - block.get_by_position(arguments[0]).name + ".values"}; + array_column, datatype_array, + block.get_by_position(arguments[0]).name + ".values"}; } } @@ -350,8 +345,8 @@ class FunctionMapEntries : public IFunction { if (datatype->is_nullable()) { datatype = assert_cast(datatype.get())->get_nested_type(); } - DCHECK(is_map(datatype)) - << "first argument for function: " << name << " should be DataTypeMap"; + DCHECK(is_map(datatype)) << "first argument for function: " << name + << " should be DataTypeMap"; const auto datatype_map = static_cast(datatype.get()); if (is_key) { return std::make_shared(datatype_map->get_key_type()); @@ -367,8 +362,7 @@ class FunctionMapEntries : public IFunction { const ColumnMap* map_column = nullptr; if (left_column->is_nullable()) { auto nullable_column = reinterpret_cast(left_column.get()); - map_column = - check_and_get_column(nullable_column->get_nested_column()); + map_column = check_and_get_column(nullable_column->get_nested_column()); } else { map_column = check_and_get_column(*left_column.get()); } From d7ae4870526bdddbc49f2de2fc6e162acf9c7455 Mon Sep 17 00:00:00 2001 From: Kang Date: Thu, 9 Mar 2023 16:53:55 +0800 Subject: [PATCH 10/13] add get_keys_array_ptr get_values_array_ptr for ColumnMap --- be/src/vec/columns/column_map.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/be/src/vec/columns/column_map.h b/be/src/vec/columns/column_map.h index e5c8ee8dc2a373..befc99a05a3eaf 100644 --- a/be/src/vec/columns/column_map.h +++ b/be/src/vec/columns/column_map.h @@ -146,12 +146,26 @@ class ColumnMap final : public COWHelper { const IColumn& get_keys() const { return *keys_column; } IColumn& get_keys() { return *keys_column; } + const ColumnPtr get_keys_array_ptr() const { + return ColumnArray::create(keys_column, offsets_column); + } + ColumnPtr get_keys_array_ptr() { + return ColumnArray::create(keys_column, offsets_column); + } + const ColumnPtr& get_values_ptr() const { return values_column; } ColumnPtr& get_values_ptr() { return values_column; } const IColumn& get_values() const { return *values_column; } IColumn& get_values() { return *values_column; } + const ColumnPtr get_values_array_ptr() const { + return ColumnArray::create(values_column, offsets_column); + } + ColumnPtr get_values_array_ptr() { + return ColumnArray::create(values_column, offsets_column); + } + size_t ALWAYS_INLINE size_at(ssize_t i) const { return get_offsets()[i] - get_offsets()[i - 1]; } From 70c4c1a7a8feeb12a2ec7436d3301c92e79f1176 Mon Sep 17 00:00:00 2001 From: Kang Date: Thu, 9 Mar 2023 16:54:17 +0800 Subject: [PATCH 11/13] change impl of map functions for new ColumnMap --- .../functions/array/function_array_element.h | 3 +- be/src/vec/functions/function_map.cpp | 101 ++++-------------- 2 files changed, 21 insertions(+), 83 deletions(-) diff --git a/be/src/vec/functions/array/function_array_element.h b/be/src/vec/functions/array/function_array_element.h index 094802f886ed0f..9ecbca6471ecaa 100644 --- a/be/src/vec/functions/array/function_array_element.h +++ b/be/src/vec/functions/array/function_array_element.h @@ -235,7 +235,8 @@ class FunctionArrayElement : public IFunction { const auto& map_column = reinterpret_cast(*left_column); // create column array to find keys - auto key_arr = ColumnArray::create(map_column.get_keys_ptr(), map_column.get_offsets_ptr()); + auto key_arr = + ColumnArray::create(map_column.get_keys_ptr(), map_column.get_offsets_ptr()); auto val_arr = ColumnArray::create(map_column.get_values_ptr(), map_column.get_offsets_ptr()); diff --git a/be/src/vec/functions/function_map.cpp b/be/src/vec/functions/function_map.cpp index d5374fdddfa073..9cb5c5898d2af2 100644 --- a/be/src/vec/functions/function_map.cpp +++ b/be/src/vec/functions/function_map.cpp @@ -63,7 +63,7 @@ class FunctionMap : public IFunction { get_least_supertype(key_types, &key_type); get_least_supertype(val_types, &val_type); - return std::make_shared(key_type, val_type); + return std::make_shared(make_nullable(key_type), make_nullable(val_type)); } Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, @@ -74,22 +74,21 @@ class FunctionMap : public IFunction { size_t num_element = arguments.size(); auto result_col = block.get_by_position(result).type->create_column(); - // auto result_col_map = static_cast(result_col.get()); - // auto col_map = typeid_cast(result_col.get()); - auto col_map = static_cast(result_col.get()); - auto col_map_keys = static_cast(&col_map->get_keys()); - auto col_map_vals = static_cast(&col_map->get_values()); - - // map keys array data and offsets - auto& result_col_map_keys_data = col_map_keys->get_data(); - auto& result_col_map_keys_offsets = col_map_keys->get_offsets(); + auto map_column = typeid_cast(result_col.get()); + if (!map_column) { + return Status::RuntimeError("unsupported types for function {} return {}", get_name(), + block.get_by_position(result).type->get_name()); + } + + // map keys column + auto& result_col_map_keys_data = map_column->get_keys(); result_col_map_keys_data.reserve(input_rows_count * num_element / 2); - result_col_map_keys_offsets.resize(input_rows_count); - // map values array data and offsets - auto& result_col_map_vals_data = col_map_vals->get_data(); - auto& result_col_map_vals_offsets = col_map_vals->get_offsets(); + // map values column + auto& result_col_map_vals_data = map_column->get_values(); result_col_map_vals_data.reserve(input_rows_count * num_element / 2); - result_col_map_vals_offsets.resize(input_rows_count); + // map offsets column + auto& result_col_map_offsets = map_column->get_offsets(); + result_col_map_offsets.resize(input_rows_count); // convert to nullable column for (size_t i = 0; i < num_element; ++i) { @@ -112,8 +111,7 @@ class FunctionMap : public IFunction { *block.get_by_position(arguments[i + 1]).column, row); } offset += num_element / 2; - result_col_map_keys_offsets[row] = offset; - result_col_map_vals_offsets[row] = offset; + result_col_map_offsets[row] = offset; } block.replace_by_position(result, std::move(result_col)); return Status::OK(); @@ -225,7 +223,7 @@ class FunctionMapContains : public IFunction { } const auto datatype_map = static_cast(datatype.get()); if constexpr (is_key) { - const auto& array_column = map_column->get_keys_ptr(); + const auto& array_column = map_column->get_keys_array_ptr(); const auto datatype_array = std::make_shared(datatype_map->get_key_type()); if (nullmap_column) { @@ -239,7 +237,7 @@ class FunctionMapContains : public IFunction { block.get_by_position(arguments[0]).name + ".keys"}; } } else { - const auto& array_column = map_column->get_values_ptr(); + const auto& array_column = map_column->get_values_array_ptr(); const auto datatype_array = std::make_shared(datatype_map->get_value_type()); if (nullmap_column) { @@ -266,67 +264,6 @@ class FunctionMapContains : public IFunction { FunctionArrayIndex> array_contains; }; -// template -// class FunctionMapContainsLike : public IFunction { -// public: -// static constexpr auto name = is_key ? "map_contains_key_like" : "map_contains_value_like"; -// static FunctionPtr create() { return std::make_shared(); } - -// /// Get function name. -// String get_name() const override { return name; } - -// bool is_variadic() const override { return false; } - -// size_t get_number_of_arguments() const override { return 2; } - -// DataTypePtr get_return_type_impl(const DataTypes& arguments) const override { -// DCHECK(is_map(arguments[0])) -// << "first argument for function: " << name << " should be DataTypeMap"; - -// if (arguments[0]->is_nullable()) { -// return make_nullable(std::make_shared>()); -// } else { -// return std::make_shared>(); -// } -// } - -// Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments, -// size_t result, size_t input_rows_count) override { -// // backup original argument 0 -// auto orig_arg0 = block.get_by_position(arguments[0]); -// auto left_column = -// block.get_by_position(arguments[0]).column->convert_to_full_column_if_const(); -// const auto col_map = check_and_get_column(*left_column); -// if (!col_map) { -// return Status::RuntimeError("unsupported types for function {}({})", get_name(), -// block.get_by_position(arguments[0]).type->get_name()); -// } - -// const auto datatype_map = -// static_cast(block.get_by_position(arguments[0]).type.get()); -// if constexpr(is_key) { -// block.get_by_position(arguments[0]) = { -// col_map->get_keys_ptr(), -// std::make_shared(datatype_map->get_key_type()), -// block.get_by_position(arguments[0]).name + ".keys" -// }; -// } else { -// block.get_by_position(arguments[0]) = { -// col_map->get_values_ptr(), -// std::make_shared(datatype_map->get_value_type()), -// block.get_by_position(arguments[0]).name + ".values" -// }; -// } - -// RETURN_IF_ERROR( -// array_contains.execute_impl(context, block, arguments, result, input_rows_count)); - -// // restore original argument 0 -// block.get_by_position(arguments[0]) = orig_arg0; -// return Status::OK(); -// } -// }; - template class FunctionMapEntries : public IFunction { public: @@ -372,9 +309,9 @@ class FunctionMapEntries : public IFunction { } if constexpr (is_key) { - block.replace_by_position(result, map_column->get_keys_ptr()); + block.replace_by_position(result, map_column->get_keys_array_ptr()); } else { - block.replace_by_position(result, map_column->get_values_ptr()); + block.replace_by_position(result, map_column->get_values_array_ptr()); } return Status::OK(); From 01a334ee59e13c14fd9997d9a37e1f5fa45b1418 Mon Sep 17 00:00:00 2001 From: Kang Date: Thu, 9 Mar 2023 16:54:56 +0800 Subject: [PATCH 12/13] change test map result to_string ' to " --- .../test_map_load_and_function.out | 886 +++++++++--------- 1 file changed, 443 insertions(+), 443 deletions(-) diff --git a/regression-test/data/load_p0/stream_load/test_map_load_and_function.out b/regression-test/data/load_p0/stream_load/test_map_load_and_function.out index 1925f88e27f635..70f7d3c7d19b5b 100644 --- a/regression-test/data/load_p0/stream_load/test_map_load_and_function.out +++ b/regression-test/data/load_p0/stream_load/test_map_load_and_function.out @@ -37,28 +37,28 @@ -- !select2 -- 1 \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} -3 {'k1':31, 'k2':300} +2 {" 11amory ":23, "beat":20, " clever ":66} +3 {"k1":31, "k2":300} 4 {} 5 \N -6 {'k1':41, 'k2':400} -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} +6 {"k1":41, "k2":400} +7 {" 33,amory ":2, " bet ":20, " cler ":26} 8 {} -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} 10 {} 11 \N -12 {'k3':23, null:20, 'k4':null} -13 {'null':1} -15 {'':2, 'k2':0} +12 {"k3":23, null:20, "k4":null} +13 {"null":1} +15 {"":2, "k2":0} 16 {null:null} 17 \N -18 {'k1':100, 'k2':130} +18 {"k1":100, "k2":130} -- !select_map1 -- -{'k11':1000, 'k22':2000} +{"k11":1000, "k22":2000} -- !select_map2 -- -{1000:'k11', 2000:'k22'} +{1000:"k11", 2000:"k22"} -- !select_element1 -- 1000 @@ -86,291 +86,291 @@ k22 -- !select_element101 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} \N -3 {'k1':31, 'k2':300} 31 +2 {" 11amory ":23, "beat":20, " clever ":66} \N +3 {"k1":31, "k2":300} 31 4 {} \N 5 \N \N -6 {'k1':41, 'k2':400} 41 -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +6 {"k1":41, "k2":400} 41 +7 {" 33,amory ":2, " bet ":20, " cler ":26} \N 8 {} \N -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} \N 10 {} \N 11 \N \N -12 {'k3':23, null:20, 'k4':null} \N -13 {'null':1} \N -15 {'':2, 'k2':0} \N +12 {"k3":23, null:20, "k4":null} \N +13 {"null":1} \N +15 {"":2, "k2":0} \N 16 {null:null} \N 17 \N \N -18 {'k1':100, 'k2':130} 100 +18 {"k1":100, "k2":130} 100 -- !select_element102 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} \N -3 {'k1':31, 'k2':300} 300 +2 {" 11amory ":23, "beat":20, " clever ":66} \N +3 {"k1":31, "k2":300} 300 4 {} \N 5 \N \N -6 {'k1':41, 'k2':400} 400 -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +6 {"k1":41, "k2":400} 400 +7 {" 33,amory ":2, " bet ":20, " cler ":26} \N 8 {} \N -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} \N 10 {} \N 11 \N \N -12 {'k3':23, null:20, 'k4':null} \N -13 {'null':1} \N -15 {'':2, 'k2':0} 0 +12 {"k3":23, null:20, "k4":null} \N +13 {"null":1} \N +15 {"":2, "k2":0} 0 16 {null:null} \N 17 \N \N -18 {'k1':100, 'k2':130} 130 +18 {"k1":100, "k2":130} 130 -- !select_element103 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} 23 -3 {'k1':31, 'k2':300} \N +2 {" 11amory ":23, "beat":20, " clever ":66} 23 +3 {"k1":31, "k2":300} \N 4 {} \N 5 \N \N -6 {'k1':41, 'k2':400} \N -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +6 {"k1":41, "k2":400} \N +7 {" 33,amory ":2, " bet ":20, " cler ":26} \N 8 {} \N -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} \N 10 {} \N 11 \N \N -12 {'k3':23, null:20, 'k4':null} \N -13 {'null':1} \N -15 {'':2, 'k2':0} \N +12 {"k3":23, null:20, "k4":null} \N +13 {"null":1} \N +15 {"":2, "k2":0} \N 16 {null:null} \N 17 \N \N -18 {'k1':100, 'k2':130} \N +18 {"k1":100, "k2":130} \N -- !select_element104 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} 20 -3 {'k1':31, 'k2':300} \N +2 {" 11amory ":23, "beat":20, " clever ":66} 20 +3 {"k1":31, "k2":300} \N 4 {} \N 5 \N \N -6 {'k1':41, 'k2':400} \N -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +6 {"k1":41, "k2":400} \N +7 {" 33,amory ":2, " bet ":20, " cler ":26} \N 8 {} \N -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} \N 10 {} \N 11 \N \N -12 {'k3':23, null:20, 'k4':null} \N -13 {'null':1} \N -15 {'':2, 'k2':0} \N +12 {"k3":23, null:20, "k4":null} \N +13 {"null":1} \N +15 {"":2, "k2":0} \N 16 {null:null} \N 17 \N \N -18 {'k1':100, 'k2':130} \N +18 {"k1":100, "k2":130} \N -- !select_element105 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} 66 -3 {'k1':31, 'k2':300} \N +2 {" 11amory ":23, "beat":20, " clever ":66} 66 +3 {"k1":31, "k2":300} \N 4 {} \N 5 \N \N -6 {'k1':41, 'k2':400} \N -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +6 {"k1":41, "k2":400} \N +7 {" 33,amory ":2, " bet ":20, " cler ":26} \N 8 {} \N -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} \N 10 {} \N 11 \N \N -12 {'k3':23, null:20, 'k4':null} \N -13 {'null':1} \N -15 {'':2, 'k2':0} \N +12 {"k3":23, null:20, "k4":null} \N +13 {"null":1} \N +15 {"":2, "k2":0} \N 16 {null:null} \N 17 \N \N -18 {'k1':100, 'k2':130} \N +18 {"k1":100, "k2":130} \N -- !select_element106 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} \N -3 {'k1':31, 'k2':300} \N +2 {" 11amory ":23, "beat":20, " clever ":66} \N +3 {"k1":31, "k2":300} \N 4 {} \N 5 \N \N -6 {'k1':41, 'k2':400} \N -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} 2 +6 {"k1":41, "k2":400} \N +7 {" 33,amory ":2, " bet ":20, " cler ":26} 2 8 {} \N -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} \N 10 {} \N 11 \N \N -12 {'k3':23, null:20, 'k4':null} \N -13 {'null':1} \N -15 {'':2, 'k2':0} \N +12 {"k3":23, null:20, "k4":null} \N +13 {"null":1} \N +15 {"":2, "k2":0} \N 16 {null:null} \N 17 \N \N -18 {'k1':100, 'k2':130} \N +18 {"k1":100, "k2":130} \N -- !select_element107 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} \N -3 {'k1':31, 'k2':300} \N +2 {" 11amory ":23, "beat":20, " clever ":66} \N +3 {"k1":31, "k2":300} \N 4 {} \N 5 \N \N -6 {'k1':41, 'k2':400} \N -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} 20 +6 {"k1":41, "k2":400} \N +7 {" 33,amory ":2, " bet ":20, " cler ":26} 20 8 {} \N -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} \N 10 {} \N 11 \N \N -12 {'k3':23, null:20, 'k4':null} \N -13 {'null':1} \N -15 {'':2, 'k2':0} \N +12 {"k3":23, null:20, "k4":null} \N +13 {"null":1} \N +15 {"":2, "k2":0} \N 16 {null:null} \N 17 \N \N -18 {'k1':100, 'k2':130} \N +18 {"k1":100, "k2":130} \N -- !select_element108 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} \N -3 {'k1':31, 'k2':300} \N +2 {" 11amory ":23, "beat":20, " clever ":66} \N +3 {"k1":31, "k2":300} \N 4 {} \N 5 \N \N -6 {'k1':41, 'k2':400} \N -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} 26 +6 {"k1":41, "k2":400} \N +7 {" 33,amory ":2, " bet ":20, " cler ":26} 26 8 {} \N -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} \N 10 {} \N 11 \N \N -12 {'k3':23, null:20, 'k4':null} \N -13 {'null':1} \N -15 {'':2, 'k2':0} \N +12 {"k3":23, null:20, "k4":null} \N +13 {"null":1} \N +15 {"":2, "k2":0} \N 16 {null:null} \N 17 \N \N -18 {'k1':100, 'k2':130} \N +18 {"k1":100, "k2":130} \N -- !select_element109 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} \N -3 {'k1':31, 'k2':300} \N +2 {" 11amory ":23, "beat":20, " clever ":66} \N +3 {"k1":31, "k2":300} \N 4 {} \N 5 \N \N -6 {'k1':41, 'k2':400} \N -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +6 {"k1":41, "k2":400} \N +7 {" 33,amory ":2, " bet ":20, " cler ":26} \N 8 {} \N -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} 2 +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} 2 10 {} \N 11 \N \N -12 {'k3':23, null:20, 'k4':null} \N -13 {'null':1} \N -15 {'':2, 'k2':0} \N +12 {"k3":23, null:20, "k4":null} \N +13 {"null":1} \N +15 {"":2, "k2":0} \N 16 {null:null} \N 17 \N \N -18 {'k1':100, 'k2':130} \N +18 {"k1":100, "k2":130} \N -- !select_element110 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} \N -3 {'k1':31, 'k2':300} \N +2 {" 11amory ":23, "beat":20, " clever ":66} \N +3 {"k1":31, "k2":300} \N 4 {} \N 5 \N \N -6 {'k1':41, 'k2':400} \N -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +6 {"k1":41, "k2":400} \N +7 {" 33,amory ":2, " bet ":20, " cler ":26} \N 8 {} \N -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} 90 +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} 90 10 {} \N 11 \N \N -12 {'k3':23, null:20, 'k4':null} \N -13 {'null':1} \N -15 {'':2, 'k2':0} \N +12 {"k3":23, null:20, "k4":null} \N +13 {"null":1} \N +15 {"":2, "k2":0} \N 16 {null:null} \N 17 \N \N -18 {'k1':100, 'k2':130} \N +18 {"k1":100, "k2":130} \N -- !select_element111 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} \N -3 {'k1':31, 'k2':300} \N +2 {" 11amory ":23, "beat":20, " clever ":66} \N +3 {"k1":31, "k2":300} \N 4 {} \N 5 \N \N -6 {'k1':41, 'k2':400} \N -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +6 {"k1":41, "k2":400} \N +7 {" 33,amory ":2, " bet ":20, " cler ":26} \N 8 {} \N -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} \N 10 {} \N 11 \N \N -12 {'k3':23, null:20, 'k4':null} \N -13 {'null':1} 1 -15 {'':2, 'k2':0} \N +12 {"k3":23, null:20, "k4":null} \N +13 {"null":1} 1 +15 {"":2, "k2":0} \N 16 {null:null} \N 17 \N \N -18 {'k1':100, 'k2':130} \N +18 {"k1":100, "k2":130} \N -- !select_element112 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} \N -3 {'k1':31, 'k2':300} \N +2 {" 11amory ":23, "beat":20, " clever ":66} \N +3 {"k1":31, "k2":300} \N 4 {} \N 5 \N \N -6 {'k1':41, 'k2':400} \N -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +6 {"k1":41, "k2":400} \N +7 {" 33,amory ":2, " bet ":20, " cler ":26} \N 8 {} \N -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} \N 10 {} \N 11 \N \N -12 {'k3':23, null:20, 'k4':null} 20 -13 {'null':1} \N -15 {'':2, 'k2':0} 2 +12 {"k3":23, null:20, "k4":null} 20 +13 {"null":1} \N +15 {"":2, "k2":0} 2 16 {null:null} \N 17 \N \N -18 {'k1':100, 'k2':130} \N +18 {"k1":100, "k2":130} \N -- !select_element113 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} \N -3 {'k1':31, 'k2':300} \N +2 {" 11amory ":23, "beat":20, " clever ":66} \N +3 {"k1":31, "k2":300} \N 4 {} \N 5 \N \N -6 {'k1':41, 'k2':400} \N -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +6 {"k1":41, "k2":400} \N +7 {" 33,amory ":2, " bet ":20, " cler ":26} \N 8 {} \N -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} \N 10 {} \N 11 \N \N -12 {'k3':23, null:20, 'k4':null} \N -13 {'null':1} \N -15 {'':2, 'k2':0} \N +12 {"k3":23, null:20, "k4":null} \N +13 {"null":1} \N +15 {"":2, "k2":0} \N 16 {null:null} \N 17 \N \N -18 {'k1':100, 'k2':130} \N +18 {"k1":100, "k2":130} \N -- !select_element114 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} \N -3 {'k1':31, 'k2':300} \N +2 {" 11amory ":23, "beat":20, " clever ":66} \N +3 {"k1":31, "k2":300} \N 4 {} \N 5 \N \N -6 {'k1':41, 'k2':400} \N -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} \N +6 {"k1":41, "k2":400} \N +7 {" 33,amory ":2, " bet ":20, " cler ":26} \N 8 {} \N -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} \N +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} \N 10 {} \N 11 \N \N -12 {'k3':23, null:20, 'k4':null} \N -13 {'null':1} \N -15 {'':2, 'k2':0} \N +12 {"k3":23, null:20, "k4":null} \N +13 {"null":1} \N +15 {"":2, "k2":0} \N 16 {null:null} \N 17 \N \N -18 {'k1':100, 'k2':130} \N +18 {"k1":100, "k2":130} \N -- !select_map_size1 -- 2 -- !select_map_size2 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} 3 -3 {'k1':31, 'k2':300} 2 +2 {" 11amory ":23, "beat":20, " clever ":66} 3 +3 {"k1":31, "k2":300} 2 4 {} 0 5 \N \N -6 {'k1':41, 'k2':400} 2 -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} 3 +6 {"k1":41, "k2":400} 2 +7 {" 33,amory ":2, " bet ":20, " cler ":26} 3 8 {} 0 -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} 3 +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} 3 10 {} 0 11 \N \N -12 {'k3':23, null:20, 'k4':null} 3 -13 {'null':1} 1 -15 {'':2, 'k2':0} 2 +12 {"k3":23, null:20, "k4":null} 3 +13 {"null":1} 1 +15 {"":2, "k2":0} 2 16 {null:null} 1 17 \N \N -18 {'k1':100, 'k2':130} 2 +18 {"k1":100, "k2":130} 2 -- !select_map_contains_key1 -- true @@ -389,269 +389,269 @@ false -- !select_map_contains_key101 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} true +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} true 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} true -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} true +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} true +18 {"k1":100, "k2":130} true -- !select_map_contains_key102 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} true +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} true 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} true -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} true +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} true +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} true 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} true +18 {"k1":100, "k2":130} true -- !select_map_contains_key103 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} true -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} true +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_key104 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} true -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} true +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_key105 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} true -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} true +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_key106 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} true +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} true 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_key107 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} true +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} true 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_key108 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} true +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} true 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_key109 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} true +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} true 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_key110 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} true +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} true 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_key111 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} true -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} true +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_key112 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} true +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} true 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_key113 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} true -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} true +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} true 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_key114 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_value1 -- true @@ -667,370 +667,370 @@ false -- !select_map_contains_value101 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} true -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} true +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} true -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} true +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_value102 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} true -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} true +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} true +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} true 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} true -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} true +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_value103 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} true -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} true +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_value104 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} true +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} true 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_value105 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} true +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} true 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_value106 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} true -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} true +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_value107 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} true -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} true +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_value108 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} true +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} true 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_value109 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} true +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} true 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} true +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} true 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} true +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} true 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_value110 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} true +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} true 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_value111 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} true +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} true 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_value112 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} true +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} true 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_value113 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} true -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} true +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_value114 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} true +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} true 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} true +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} true 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} true +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} true 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_value115 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} true +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} true 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_value116 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} false -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} false +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} false 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_contains_value117 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} false -3 {'k1':31, 'k2':300} false +2 {" 11amory ":23, "beat":20, " clever ":66} false +3 {"k1":31, "k2":300} false 4 {} false 5 \N \N -6 {'k1':41, 'k2':400} false -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} false +6 {"k1":41, "k2":400} false +7 {" 33,amory ":2, " bet ":20, " cler ":26} false 8 {} false -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} false +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} false 10 {} false 11 \N \N -12 {'k3':23, null:20, 'k4':null} true -13 {'null':1} false -15 {'':2, 'k2':0} false +12 {"k3":23, null:20, "k4":null} true +13 {"null":1} false +15 {"":2, "k2":0} false 16 {null:null} true 17 \N \N -18 {'k1':100, 'k2':130} false +18 {"k1":100, "k2":130} false -- !select_map_keys1 -- ['k11', 'k22'] -- !select_map_keys2 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} [' 11amory ', 'beat', ' clever '] -3 {'k1':31, 'k2':300} ['k1', 'k2'] +2 {" 11amory ":23, "beat":20, " clever ":66} [' 11amory ', 'beat', ' clever '] +3 {"k1":31, "k2":300} ['k1', 'k2'] 4 {} [] 5 \N \N -6 {'k1':41, 'k2':400} ['k1', 'k2'] -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} [' 33,amory ', ' bet ', ' cler '] +6 {"k1":41, "k2":400} ['k1', 'k2'] +7 {" 33,amory ":2, " bet ":20, " cler ":26} [' 33,amory ', ' bet ', ' cler '] 8 {} [] -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} [' 1,amy ', ' k2 ', ' k7 '] +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} [' 1,amy ', ' k2 ', ' k7 '] 10 {} [] 11 \N \N -12 {'k3':23, null:20, 'k4':null} ['k3', NULL, 'k4'] -13 {'null':1} ['null'] -15 {'':2, 'k2':0} ['', 'k2'] +12 {"k3":23, null:20, "k4":null} ['k3', NULL, 'k4'] +13 {"null":1} ['null'] +15 {"":2, "k2":0} ['', 'k2'] 16 {null:null} [NULL] 17 \N \N -18 {'k1':100, 'k2':130} ['k1', 'k2'] +18 {"k1":100, "k2":130} ['k1', 'k2'] -- !select_map_values1 -- [1000, 2000] -- !select_map_values2 -- 1 \N \N -2 {' 11amory ':23, 'beat':20, ' clever ':66} [23, 20, 66] -3 {'k1':31, 'k2':300} [31, 300] +2 {" 11amory ":23, "beat":20, " clever ":66} [23, 20, 66] +3 {"k1":31, "k2":300} [31, 300] 4 {} [] 5 \N \N -6 {'k1':41, 'k2':400} [41, 400] -7 {' 33,amory ':2, ' bet ':20, ' cler ':26} [2, 20, 26] +6 {"k1":41, "k2":400} [41, 400] +7 {" 33,amory ":2, " bet ":20, " cler ":26} [2, 20, 26] 8 {} [] -9 {' 1,amy ':2, ' k2 ':90, ' k7 ':33} [2, 90, 33] +9 {" 1,amy ":2, " k2 ":90, " k7 ":33} [2, 90, 33] 10 {} [] 11 \N \N -12 {'k3':23, null:20, 'k4':null} [23, 20, NULL] -13 {'null':1} [1] -15 {'':2, 'k2':0} [2, 0] +12 {"k3":23, null:20, "k4":null} [23, 20, NULL] +13 {"null":1} [1] +15 {"":2, "k2":0} [2, 0] 16 {null:null} [NULL] 17 \N \N -18 {'k1':100, 'k2':130} [100, 130] +18 {"k1":100, "k2":130} [100, 130] -- !select_m1 -- 1 100 200 \N From 26c06efc4baba62ee03afcad55a897b81aea56af Mon Sep 17 00:00:00 2001 From: Kang Date: Thu, 9 Mar 2023 17:02:34 +0800 Subject: [PATCH 13/13] clang format --- be/src/vec/columns/column_map.h | 8 ++------ be/src/vec/functions/array/function_array_element.h | 3 +-- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/be/src/vec/columns/column_map.h b/be/src/vec/columns/column_map.h index befc99a05a3eaf..9d828a2794a559 100644 --- a/be/src/vec/columns/column_map.h +++ b/be/src/vec/columns/column_map.h @@ -149,9 +149,7 @@ class ColumnMap final : public COWHelper { const ColumnPtr get_keys_array_ptr() const { return ColumnArray::create(keys_column, offsets_column); } - ColumnPtr get_keys_array_ptr() { - return ColumnArray::create(keys_column, offsets_column); - } + ColumnPtr get_keys_array_ptr() { return ColumnArray::create(keys_column, offsets_column); } const ColumnPtr& get_values_ptr() const { return values_column; } ColumnPtr& get_values_ptr() { return values_column; } @@ -162,9 +160,7 @@ class ColumnMap final : public COWHelper { const ColumnPtr get_values_array_ptr() const { return ColumnArray::create(values_column, offsets_column); } - ColumnPtr get_values_array_ptr() { - return ColumnArray::create(values_column, offsets_column); - } + ColumnPtr get_values_array_ptr() { return ColumnArray::create(values_column, offsets_column); } size_t ALWAYS_INLINE size_at(ssize_t i) const { return get_offsets()[i] - get_offsets()[i - 1]; diff --git a/be/src/vec/functions/array/function_array_element.h b/be/src/vec/functions/array/function_array_element.h index 9ecbca6471ecaa..094802f886ed0f 100644 --- a/be/src/vec/functions/array/function_array_element.h +++ b/be/src/vec/functions/array/function_array_element.h @@ -235,8 +235,7 @@ class FunctionArrayElement : public IFunction { const auto& map_column = reinterpret_cast(*left_column); // create column array to find keys - auto key_arr = - ColumnArray::create(map_column.get_keys_ptr(), map_column.get_offsets_ptr()); + auto key_arr = ColumnArray::create(map_column.get_keys_ptr(), map_column.get_offsets_ptr()); auto val_arr = ColumnArray::create(map_column.get_values_ptr(), map_column.get_offsets_ptr());