Skip to content

Commit

Permalink
add function strcmp
Browse files Browse the repository at this point in the history
  • Loading branch information
xiedeyantu committed Apr 5, 2024
1 parent 7137749 commit 2ffd131
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 0 deletions.
1 change: 1 addition & 0 deletions be/src/vec/functions/function_string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1131,6 +1131,7 @@ void register_function_string(SimpleFunctionFactory& factory) {
factory.register_function<FunctionMaskPartial<false>>();
factory.register_function<FunctionSubReplace<SubReplaceThreeImpl>>();
factory.register_function<FunctionSubReplace<SubReplaceFourImpl>>();
factory.register_function<FunctionStrcmp>();

/// @TEMPORARY: for be_exec_version=3
factory.register_alternative_function<FunctionSubstringOld<Substr3ImplOld>>();
Expand Down
56 changes: 56 additions & 0 deletions be/src/vec/functions/function_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,62 @@ struct SubstringUtil {
}
};

class FunctionStrcmp : public IFunction {
public:
static constexpr auto name = "strcmp";

static FunctionPtr create() { return std::make_shared<FunctionStrcmp>(); }

String get_name() const override { return name; }

size_t get_number_of_arguments() const override { return 2; }

DataTypePtr get_return_type_impl(const DataTypes& arguments) const override {
return std::make_shared<DataTypeInt16>();
}

Status execute_impl(FunctionContext* context, Block& block, const ColumnNumbers& arguments,
size_t result, size_t input_rows_count) const override {
const auto& arg0_column =
assert_cast<const ColumnString&>(*block.get_by_position(arguments[0]).column);
const auto& arg1_column =
assert_cast<const ColumnString&>(*block.get_by_position(arguments[1]).column);

auto result_column = ColumnInt16::create(input_rows_count);
auto& result_data = result_column->get_data();
auto null_column = ColumnUInt8::create(input_rows_count);
auto& null_map = null_column->get_data();

for (int row = 0; row < input_rows_count; row++) {
null_map[row] = false;
if (arg0_column.is_nullable() || arg1_column.is_nullable()) {
null_map[row] = true;
continue;
}

auto arg0 = arg0_column.get_data_at(row).to_string();
auto arg1 = arg1_column.get_data_at(row).to_string();

Int16* result_cell = &result_data[row];
*result_cell = strcmp(arg0.c_str(), arg1.c_str());
}

block.replace_by_position(
result, ColumnNullable::create(std::move(result_column), std::move(null_column)));
return Status::OK();
}

static int strcmp(const char* arg0, const char* arg1) {
int ret = std::strcmp(arg0, arg1);
if (ret < 0) {
return -1;
} else if (ret > 0) {
return 1;
}
return 0;
}
};

struct SubstringUtilOld {
static constexpr auto name = "substring";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,7 @@
import org.apache.doris.nereids.trees.expressions.functions.scalar.StrLeft;
import org.apache.doris.nereids.trees.expressions.functions.scalar.StrRight;
import org.apache.doris.nereids.trees.expressions.functions.scalar.StrToDate;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Strcmp;
import org.apache.doris.nereids.trees.expressions.functions.scalar.StructElement;
import org.apache.doris.nereids.trees.expressions.functions.scalar.SubBitmap;
import org.apache.doris.nereids.trees.expressions.functions.scalar.SubReplace;
Expand Down Expand Up @@ -628,6 +629,7 @@ public class BuiltinScalarFunctions implements FunctionHelper {
scalar(InnerProduct.class, "inner_product"),
scalar(Instr.class, "instr"),
scalar(InttoUuid.class, "int_to_uuid"),
scalar(Strcmp.class, "strcmp"),
scalar(Ipv4NumToString.class, "ipv4_num_to_string", "inet_ntoa"),
scalar(Ipv4StringToNum.class, "ipv4_string_to_num"),
scalar(Ipv4StringToNumOrDefault.class, "ipv4_string_to_num_or_default"),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// 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.BinaryExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.SmallIntType;
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 'strcmp'.
*/
public class Strcmp extends ScalarFunction
implements BinaryExpression, ExplicitlyCastableSignature, PropagateNullable {

public static final List<FunctionSignature> SIGNATURES = ImmutableList.of(
FunctionSignature.ret(SmallIntType.INSTANCE).args(VarcharType.SYSTEM_DEFAULT, VarcharType.SYSTEM_DEFAULT),
FunctionSignature.ret(SmallIntType.INSTANCE).args(StringType.INSTANCE, StringType.INSTANCE));

/**
* constructor with 2 argument.
*/
public Strcmp(Expression arg0, Expression arg1) {
super("strcmp", arg0, arg1);
}

/**
* withChildren.
*/
@Override
public Strcmp withChildren(List<Expression> children) {
Preconditions.checkArgument(children.size() == 2);
return new Strcmp(children.get(0), children.get(1));
}

@Override
public List<FunctionSignature> getSignatures() {
return SIGNATURES;
}

@Override
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
return visitor.visitStrcmp(this, context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,7 @@
import org.apache.doris.nereids.trees.expressions.functions.scalar.StrLeft;
import org.apache.doris.nereids.trees.expressions.functions.scalar.StrRight;
import org.apache.doris.nereids.trees.expressions.functions.scalar.StrToDate;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Strcmp;
import org.apache.doris.nereids.trees.expressions.functions.scalar.StructElement;
import org.apache.doris.nereids.trees.expressions.functions.scalar.SubBitmap;
import org.apache.doris.nereids.trees.expressions.functions.scalar.SubReplace;
Expand Down Expand Up @@ -2011,6 +2012,10 @@ default R visitInttoUuid(InttoUuid inttoUuid, C context) {
return visitScalarFunction(inttoUuid, context);
}

default R visitStrcmp(Strcmp strcmp, C context) {
return visitScalarFunction(strcmp, context);
}

default R visitVersion(Version version, C context) {
return visitScalarFunction(version, context);
}
Expand Down
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,20 @@ suite("test_string_function", "arrow_flight_sql") {
qt_sql "select substring_index(\"prefix_string\", \"_\", null);"
qt_sql "select substring_index(\"prefix_string\", \"__\", -1);"

qt_sql_func_strcmp "select strcmp('test', 'test1');"
qt_sql_func_strcmp "select strcmp('test1', 'test');"
qt_sql_func_strcmp "select strcmp('test', 'test');"
qt_sql_func_strcmp "select strcmp('', '');"
qt_sql_func_strcmp "select strcmp(null, 'test');"
qt_sql_func_strcmp "select strcmp('test', null);"
qt_sql_func_strcmp "select strcmp(\"test\", \"test1\");"
qt_sql_func_strcmp "select strcmp(\"test1\", \"test\");"
qt_sql_func_strcmp "select strcmp(\"test\", \"test\");"
qt_sql_func_strcmp "select strcmp(\"\", \"\");"
qt_sql_func_strcmp "select strcmp(null, \"test\");"
qt_sql_func_strcmp "select strcmp(\"test\", null);"
qt_sql_func_strcmp "select strcmp(null, null);"

sql 'set enable_nereids_planner=true'
sql 'set enable_fallback_to_original_planner=false'

Expand Down

0 comments on commit 2ffd131

Please sign in to comment.