This is an automated email from the ASF dual-hosted git repository.
lihaopeng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 3d13dbefeb7 [Enhancement] Support some compress functions (#47307)
3d13dbefeb7 is described below
commit 3d13dbefeb74c6be7be3bc509c696320823526df
Author: lzyy2024 <[email protected]>
AuthorDate: Fri Feb 7 10:26:22 2025 +0800
[Enhancement] Support some compress functions (#47307)
Added the compress and uncompressed functions similar to mysql
---
be/src/vec/functions/function_compress.cpp | 209 +++++++++++++++++++++
be/src/vec/functions/simple_function_factory.h | 2 +
.../doris/catalog/BuiltinScalarFunctions.java | 6 +-
.../expressions/functions/scalar/Compress.java | 69 +++++++
.../expressions/functions/scalar/Uncompress.java | 69 +++++++
.../expressions/visitor/ScalarFunctionVisitor.java | 10 +
.../string_functions/test_compress_uncompress.out | Bin 0 -> 741 bytes
.../test_compress_uncompress.groovy | 139 ++++++++++++++
8 files changed, 503 insertions(+), 1 deletion(-)
diff --git a/be/src/vec/functions/function_compress.cpp
b/be/src/vec/functions/function_compress.cpp
new file mode 100644
index 00000000000..4c175a5fd44
--- /dev/null
+++ b/be/src/vec/functions/function_compress.cpp
@@ -0,0 +1,209 @@
+// 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 <glog/logging.h>
+
+#include <array>
+#include <cctype>
+#include <cstddef>
+#include <cstring>
+#include <functional>
+#include <memory>
+#include <string>
+#include <utility>
+
+#include "common/status.h"
+#include "util/block_compression.h"
+#include "util/faststring.h"
+#include "vec/aggregate_functions/aggregate_function.h"
+#include "vec/columns/column.h"
+#include "vec/columns/column_nullable.h"
+#include "vec/columns/column_string.h"
+#include "vec/columns/column_vector.h"
+#include "vec/columns/columns_number.h"
+#include "vec/common/assert_cast.h"
+#include "vec/core/block.h"
+#include "vec/core/column_numbers.h"
+#include "vec/core/column_with_type_and_name.h"
+#include "vec/core/types.h"
+#include "vec/data_types/data_type.h"
+#include "vec/data_types/data_type_nullable.h"
+#include "vec/data_types/data_type_number.h"
+#include "vec/data_types/data_type_string.h"
+#include "vec/functions/function.h"
+#include "vec/functions/simple_function_factory.h"
+
+namespace doris {
+class FunctionContext;
+} // namespace doris
+
+namespace doris::vectorized {
+
+class FunctionCompress : public IFunction {
+public:
+ static constexpr auto name = "compress";
+ static FunctionPtr create() { return std::make_shared<FunctionCompress>();
}
+
+ String get_name() const override { return name; }
+
+ size_t get_number_of_arguments() const override { return 1; }
+
+ DataTypePtr get_return_type_impl(const DataTypes& arguments) const
override {
+ return std::make_shared<DataTypeString>();
+ }
+
+ Status execute_impl(FunctionContext* context, Block& block, const
ColumnNumbers& arguments,
+ uint32_t result, size_t input_rows_count) const
override {
+ // Get the compression algorithm object
+ BlockCompressionCodec* compression_codec;
+
RETURN_IF_ERROR(get_block_compression_codec(segment_v2::CompressionTypePB::ZLIB,
+ &compression_codec));
+
+ const auto& arg_column =
+ assert_cast<const
ColumnString&>(*block.get_by_position(arguments[0]).column);
+ auto result_column = ColumnString::create();
+
+ auto& arg_data = arg_column.get_chars();
+ auto& arg_offset = arg_column.get_offsets();
+ const char* arg_begin = reinterpret_cast<const char*>(arg_data.data());
+
+ auto& col_data = result_column->get_chars();
+ auto& col_offset = result_column->get_offsets();
+ col_offset.resize(input_rows_count);
+
+ faststring compressed_str;
+ Slice data;
+
+ // When the original string is large, the result is roughly this value
+ size_t total = arg_offset[input_rows_count - 1];
+ col_data.reserve(total / 1000);
+
+ for (size_t row = 0; row < input_rows_count; row++) {
+ uint32_t length = arg_offset[row] - arg_offset[row - 1];
+ data = Slice(arg_begin + arg_offset[row - 1], length);
+
+ size_t idx = col_data.size();
+ if (!length) { // data is ''
+ col_offset[row] = col_offset[row - 1];
+ continue;
+ }
+
+ // Z_MEM_ERROR and Z_BUF_ERROR are already handled in compress,
making sure st is always Z_OK
+ auto st = compression_codec->compress(data, &compressed_str);
+ col_data.resize(col_data.size() + 4 + compressed_str.size());
+
+ std::memcpy(col_data.data() + idx, &length, sizeof(length));
+ idx += 4;
+
+ // The length of compress_str is not known in advance, so it
cannot be compressed directly into col_data
+ unsigned char* src = compressed_str.data();
+ for (size_t i = 0; i < compressed_str.size(); idx++, i++, src++) {
+ col_data[idx] = *src;
+ }
+ col_offset[row] = col_offset[row - 1] + 10 + compressed_str.size();
+ }
+
+ block.replace_by_position(result, std::move(result_column));
+ return Status::OK();
+ }
+};
+
+class FunctionUncompress : public IFunction {
+public:
+ static constexpr auto name = "uncompress";
+ static FunctionPtr create() { return
std::make_shared<FunctionUncompress>(); }
+
+ String get_name() const override { return name; }
+
+ size_t get_number_of_arguments() const override { return 1; }
+
+ DataTypePtr get_return_type_impl(const DataTypes& arguments) const
override {
+ return make_nullable(std::make_shared<DataTypeString>());
+ }
+
+ Status execute_impl(FunctionContext* context, Block& block, const
ColumnNumbers& arguments,
+ uint32_t result, size_t input_rows_count) const
override {
+ // Get the compression algorithm object
+ BlockCompressionCodec* compression_codec;
+
RETURN_IF_ERROR(get_block_compression_codec(segment_v2::CompressionTypePB::ZLIB,
+ &compression_codec));
+
+ const auto& arg_column =
+ assert_cast<const
ColumnString&>(*block.get_by_position(arguments[0]).column);
+
+ auto& arg_data = arg_column.get_chars();
+ auto& arg_offset = arg_column.get_offsets();
+ const char* arg_begin = reinterpret_cast<const char*>(arg_data.data());
+
+ auto result_column = ColumnString::create();
+ auto& col_data = result_column->get_chars();
+ auto& col_offset = result_column->get_offsets();
+ col_offset.resize(input_rows_count);
+
+ auto null_column = ColumnUInt8::create(input_rows_count);
+ auto& null_map = null_column->get_data();
+
+ std::string uncompressed;
+ Slice data;
+ Slice uncompressed_slice;
+
+ size_t total = arg_offset[input_rows_count - 1];
+ col_data.reserve(total * 1000);
+
+ for (size_t row = 0; row < input_rows_count; row++) {
+ null_map[row] = false;
+ data = Slice(arg_begin + arg_offset[row - 1], arg_offset[row] -
arg_offset[row - 1]);
+ size_t data_length = arg_offset[row] - arg_offset[row - 1];
+
+ if (data_length == 0) { // The original data is ''
+ col_offset[row] = col_offset[row - 1];
+ continue;
+ }
+
+ union {
+ char bytes[4];
+ uint32_t value;
+ } length;
+ std::memcpy(length.bytes, data.data, 4);
+
+ size_t idx = col_data.size();
+ col_data.resize(col_data.size() + length.value);
+ uncompressed_slice = Slice(col_data.data() + idx, length.value);
+
+ Slice compressed_data(data.data + 4, data.size - 4);
+ auto st = compression_codec->decompress(compressed_data,
&uncompressed_slice);
+
+ if (!st.ok()) { // is not a
legal compressed string
+ col_data.resize(col_data.size() - length.value); // remove
compressed_data
+ col_offset[row] = col_offset[row - 1];
+ null_map[row] = true;
+ continue;
+ }
+ col_offset[row] = col_offset[row - 1] + length.value;
+ }
+
+ block.replace_by_position(
+ result, ColumnNullable::create(std::move(result_column),
std::move(null_column)));
+ return Status::OK();
+ }
+};
+
+void register_function_compress(SimpleFunctionFactory& factory) {
+ factory.register_function<FunctionCompress>();
+ factory.register_function<FunctionUncompress>();
+}
+
+} // namespace doris::vectorized
diff --git a/be/src/vec/functions/simple_function_factory.h
b/be/src/vec/functions/simple_function_factory.h
index 98f2917d163..46eca0cb419 100644
--- a/be/src/vec/functions/simple_function_factory.h
+++ b/be/src/vec/functions/simple_function_factory.h
@@ -110,6 +110,7 @@ void register_function_ip(SimpleFunctionFactory& factory);
void register_function_multi_match(SimpleFunctionFactory& factory);
void register_function_split_by_regexp(SimpleFunctionFactory& factory);
void register_function_assert_true(SimpleFunctionFactory& factory);
+void register_function_compress(SimpleFunctionFactory& factory);
void register_function_bit_test(SimpleFunctionFactory& factory);
class SimpleFunctionFactory {
@@ -301,6 +302,7 @@ public:
register_function_split_by_regexp(instance);
register_function_assert_true(instance);
register_function_bit_test(instance);
+ register_function_compress(instance);
});
return instance;
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
index c3c344436ee..e482b419ac5 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/catalog/BuiltinScalarFunctions.java
@@ -120,6 +120,7 @@ import
org.apache.doris.nereids.trees.expressions.functions.scalar.Ceil;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Char;
import
org.apache.doris.nereids.trees.expressions.functions.scalar.CharacterLength;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Coalesce;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.Compress;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Concat;
import org.apache.doris.nereids.trees.expressions.functions.scalar.ConcatWs;
import
org.apache.doris.nereids.trees.expressions.functions.scalar.ConnectionId;
@@ -451,6 +452,7 @@ import
org.apache.doris.nereids.trees.expressions.functions.scalar.Translate;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Trim;
import org.apache.doris.nereids.trees.expressions.functions.scalar.TrimIn;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Truncate;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.Uncompress;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Unhex;
import
org.apache.doris.nereids.trees.expressions.functions.scalar.UnixTimestamp;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Upper;
@@ -978,7 +980,9 @@ public class BuiltinScalarFunctions implements
FunctionHelper {
scalar(YearsSub.class, "years_sub"),
scalar(MultiMatch.class, "multi_match"),
scalar(SessionUser.class, "session_user"),
- scalar(LastQueryId.class, "last_query_id"));
+ scalar(LastQueryId.class, "last_query_id"),
+ scalar(Compress.class, "compress"),
+ scalar(Uncompress.class, "uncompress"));
public static final BuiltinScalarFunctions INSTANCE = new
BuiltinScalarFunctions();
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Compress.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Compress.java
new file mode 100644
index 00000000000..9422d72bca7
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Compress.java
@@ -0,0 +1,69 @@
+// 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.
+
+package org.apache.doris.nereids.trees.expressions.functions.scalar;
+
+import org.apache.doris.catalog.FunctionSignature;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
+import org.apache.doris.nereids.trees.expressions.functions.PropagateNullable;
+import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.StringType;
+import org.apache.doris.nereids.types.VarcharType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/**
+ * ScalarFunction 'compress'.
+ */
+public class Compress extends ScalarFunction
+ implements UnaryExpression, ExplicitlyCastableSignature,
PropagateNullable {
+
+ public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(VarcharType.SYSTEM_DEFAULT),
+
FunctionSignature.ret(StringType.INSTANCE).args(StringType.INSTANCE));
+
+ /**
+ * constructor with 1 argument.
+ */
+ public Compress(Expression arg) {
+ super("compress", arg);
+ }
+
+ /**
+ * withChildren.
+ */
+ @Override
+ public Compress withChildren(List<Expression> children) {
+ Preconditions.checkArgument(children.size() == 1);
+ return new Compress(children.get(0));
+ }
+
+ @Override
+ public List<FunctionSignature> getSignatures() {
+ return SIGNATURES;
+ }
+
+ @Override
+ public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitCompress(this, context);
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Uncompress.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Uncompress.java
new file mode 100644
index 00000000000..8726963f486
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/functions/scalar/Uncompress.java
@@ -0,0 +1,69 @@
+// 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.
+
+package org.apache.doris.nereids.trees.expressions.functions.scalar;
+
+import org.apache.doris.catalog.FunctionSignature;
+import org.apache.doris.nereids.trees.expressions.Expression;
+import org.apache.doris.nereids.trees.expressions.functions.AlwaysNullable;
+import
org.apache.doris.nereids.trees.expressions.functions.ExplicitlyCastableSignature;
+import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
+import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
+import org.apache.doris.nereids.types.StringType;
+import org.apache.doris.nereids.types.VarcharType;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+
+import java.util.List;
+
+/**
+ * ScalarFunction 'uncompress'.
+ */
+public class Uncompress extends ScalarFunction
+ implements UnaryExpression, ExplicitlyCastableSignature,
AlwaysNullable {
+
+ public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
+
FunctionSignature.ret(VarcharType.SYSTEM_DEFAULT).args(VarcharType.SYSTEM_DEFAULT),
+
FunctionSignature.ret(StringType.INSTANCE).args(StringType.INSTANCE));
+
+ /**
+ * constructor with 1 argument.
+ */
+ public Uncompress(Expression arg) {
+ super("uncompress", arg);
+ }
+
+ /**
+ * withChildren.
+ */
+ @Override
+ public Uncompress withChildren(List<Expression> children) {
+ Preconditions.checkArgument(children.size() == 1);
+ return new Uncompress(children.get(0));
+ }
+
+ @Override
+ public List<FunctionSignature> getSignatures() {
+ return SIGNATURES;
+ }
+
+ @Override
+ public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
+ return visitor.visitUncompress(this, context);
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
index 5a57688302e..4346fb71591 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/visitor/ScalarFunctionVisitor.java
@@ -127,6 +127,7 @@ import
org.apache.doris.nereids.trees.expressions.functions.scalar.Ceil;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Char;
import
org.apache.doris.nereids.trees.expressions.functions.scalar.CharacterLength;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Coalesce;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.Compress;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Concat;
import org.apache.doris.nereids.trees.expressions.functions.scalar.ConcatWs;
import
org.apache.doris.nereids.trees.expressions.functions.scalar.ConnectionId;
@@ -448,6 +449,7 @@ import
org.apache.doris.nereids.trees.expressions.functions.scalar.Translate;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Trim;
import org.apache.doris.nereids.trees.expressions.functions.scalar.TrimIn;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Truncate;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.Uncompress;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Unhex;
import
org.apache.doris.nereids.trees.expressions.functions.scalar.UnixTimestamp;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Upper;
@@ -2338,4 +2340,12 @@ public interface ScalarFunctionVisitor<R, C> {
default R visitLastQueryId(LastQueryId queryId, C context) {
return visitScalarFunction(queryId, context);
}
+
+ default R visitCompress(Compress compress, C context) {
+ return visitScalarFunction(compress, context);
+ }
+
+ default R visitUncompress(Uncompress uncompress, C context) {
+ return visitScalarFunction(uncompress, context);
+ }
}
diff --git
a/regression-test/data/query_p0/sql_functions/string_functions/test_compress_uncompress.out
b/regression-test/data/query_p0/sql_functions/string_functions/test_compress_uncompress.out
new file mode 100644
index 00000000000..be60951c955
Binary files /dev/null and
b/regression-test/data/query_p0/sql_functions/string_functions/test_compress_uncompress.out
differ
diff --git
a/regression-test/suites/query_p0/sql_functions/string_functions/test_compress_uncompress.groovy
b/regression-test/suites/query_p0/sql_functions/string_functions/test_compress_uncompress.groovy
new file mode 100644
index 00000000000..9c4df7b1ec9
--- /dev/null
+++
b/regression-test/suites/query_p0/sql_functions/string_functions/test_compress_uncompress.groovy
@@ -0,0 +1,139 @@
+// 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.
+
+suite("test_compress_uncompress") {
+ // Drop the existing table
+ sql "DROP TABLE IF EXISTS test_compression"
+
+ // Create the test table
+ sql """
+ CREATE TABLE test_compression (
+ k0 INT, -- Primary key
+ text_col STRING, -- String column for input data
+ binary_col STRING -- Binary column for compressed data
+ )
+ DISTRIBUTED BY HASH(k0)
+ PROPERTIES (
+ "replication_num" = "1"
+ );
+ """
+
+ // Insert test data with various cases
+ sql """
+ INSERT INTO test_compression VALUES
+ (1, 'Hello, world!', COMPRESS('Hello, world!')), -- Plain string
+ (2, 'Doris测试中文字符', COMPRESS('Doris测试中文字符')), -- Chinese characters
+ (3, NULL, NULL), -- Null values
+ (4, '', COMPRESS('')), -- Empty string
+ (5, NULL, 'invalid_compressed_data'), -- Invalid
binary data
+ (6, REPEAT('a', 50), COMPRESS(REPEAT('a', 50))); -- Short
repeated string
+ """
+
+ // Test 1: Verify that UNCOMPRESS can correctly restore the original data
+ order_qt_restore_original_data """
+ SELECT
+ k0,
+ UNCOMPRESS(binary_col) AS decompressed_data
+ FROM test_compression
+ WHERE binary_col IS NOT NULL
+ ORDER BY k0;
+ """
+
+ // Test 2: Verify that UNCOMPRESS returns NULL for NULL input
+ order_qt_uncompress_null_input """
+ SELECT
+ k0,
+ UNCOMPRESS(binary_col) AS decompressed_data
+ FROM test_compression
+ WHERE binary_col IS NULL
+ ORDER BY k0;
+ """
+
+ // Test 3: Verify that UNCOMPRESS handles invalid binary data gracefully
+ order_qt_uncompress_invalid_data """
+ SELECT
+ k0,
+ UNCOMPRESS(binary_col) AS decompressed_data
+ FROM test_compression
+ WHERE k0 = 5
+ ORDER BY k0;
+ """
+
+ // Test 4: Verify that COMPRESS and UNCOMPRESS work correctly with empty
strings
+ order_qt_compress_empty_string """
+ SELECT
+ k0,
+ UNCOMPRESS(binary_col) AS decompressed_data
+ FROM test_compression
+ WHERE k0 = 4
+ ORDER BY k0;
+ """
+
+ // Test 5: Verify that COMPRESS and UNCOMPRESS work correctly with
repeated strings
+ order_qt_compress_repeated_string """
+ SELECT
+ k0,
+ UNCOMPRESS(binary_col) AS decompressed_data
+ FROM test_compression
+ WHERE k0 = 6
+ ORDER BY k0;
+ """
+
+ // Additional tests using SELECT UNCOMPRESS(COMPRESS()) directly
+
+ // Test 6: Verify that COMPRESS and UNCOMPRESS work with a single
character string
+ order_qt_compress_single_char """
+ SELECT
+ UNCOMPRESS(COMPRESS('x')) AS decompressed_data
+ LIMIT 1;
+ """
+
+ // Test 7: Verify that COMPRESS handles NULL text values correctly
+ order_qt_compress_null_text """
+ SELECT
+ UNCOMPRESS(COMPRESS(NULL)) AS decompressed_data
+ LIMIT 1;
+ """
+
+ // Test 8: Verify that COMPRESS and UNCOMPRESS work with long repeated
strings
+ order_qt_compress_large_repeated_string """
+ SELECT
+ UNCOMPRESS(COMPRESS(REPEAT('a', 100))) AS decompressed_data
+ LIMIT 1;
+ """
+
+ // Test 9: Verify that COMPRESS and UNCOMPRESS work with an empty string
+ order_qt_compress_empty_string_direct """
+ SELECT
+ UNCOMPRESS(COMPRESS('')) AS decompressed_data
+ LIMIT 1;
+ """
+
+ // Test 10: Verify that COMPRESS and UNCOMPRESS work with the string
'Hello, world!'
+ order_qt_compress_string_direct """
+ SELECT
+ UNCOMPRESS(COMPRESS('Hello, world!')) AS decompressed_data
+ LIMIT 1;
+ """
+
+ // Test 11: Verify that COMPRESS and UNCOMPRESS work with a numeric value
+ order_qt_compress_numeric_direct """
+ SELECT
+ UNCOMPRESS(COMPRESS('12345')) AS decompressed_data
+ LIMIT 1;
+ """
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]