This is an automated email from the ASF dual-hosted git repository. morningman pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-doris.git
The following commit(s) were added to refs/heads/master by this push: new 5ade21b [Load] Support load true or false as boolean value (#3898) 5ade21b is described below commit 5ade21b55d773b4160dfc0070f14bdc31a44981f Author: yangzhg <780531...@qq.com> AuthorDate: Thu Jul 2 13:58:24 2020 +0800 [Load] Support load true or false as boolean value (#3898) Fixes #3831 After this PR insert into: `1/"1" -> 1, 0/"0"->0, true/"true"->1, false/"false" -> 0, "10"->null, "xxxx" -> null` load: `1/true -> 1, 0/false -> 0` other -> null --- be/src/exprs/cast_functions.cpp | 20 ++++++++++++++++++++ be/src/exprs/cast_functions.h | 2 +- be/src/olap/delete_handler.cpp | 2 ++ be/src/olap/utils.cpp | 10 ++++++++++ be/src/olap/utils.h | 2 ++ .../java/org/apache/doris/analysis/BoolLiteral.java | 4 ++-- .../java/org/apache/doris/analysis/CastExpr.java | 4 ---- .../java/org/apache/doris/load/DeleteHandler.java | 10 ++++++++++ 8 files changed, 47 insertions(+), 7 deletions(-) diff --git a/be/src/exprs/cast_functions.cpp b/be/src/exprs/cast_functions.cpp index 9c89f52..115eb42 100644 --- a/be/src/exprs/cast_functions.cpp +++ b/be/src/exprs/cast_functions.cpp @@ -229,6 +229,26 @@ StringVal CastFunctions::cast_to_string_val(FunctionContext* ctx, const StringVa return sv; } +BooleanVal CastFunctions::cast_to_boolean_val(FunctionContext* ctx, const StringVal& val) { + if (val.is_null) { + return BooleanVal::null(); + } + StringParser::ParseResult result; + BooleanVal ret; + IntVal int_val = cast_to_int_val(ctx, val); + if (!int_val.is_null && int_val.val == 0) { + ret.val = false; + } else if (!int_val.is_null && int_val.val == 1) { + ret.val = true; + } else { + ret.val = StringParser::string_to_bool(reinterpret_cast<char*>(val.ptr), val.len, &result); + if (UNLIKELY(result != StringParser::PARSE_SUCCESS)) { + return BooleanVal::null(); + } + } + return ret; +} + #if 0 StringVal CastFunctions::CastToChar(FunctionContext* ctx, const StringVal& val) { if (val.is_null) return StringVal::null(); diff --git a/be/src/exprs/cast_functions.h b/be/src/exprs/cast_functions.h index 8a3b612..26eb130 100644 --- a/be/src/exprs/cast_functions.h +++ b/be/src/exprs/cast_functions.h @@ -33,7 +33,7 @@ public: static BooleanVal cast_to_boolean_val(FunctionContext* context, const LargeIntVal& val); static BooleanVal cast_to_boolean_val(FunctionContext* context, const FloatVal& val); static BooleanVal cast_to_boolean_val(FunctionContext* context, const DoubleVal& val); - // static BooleanVal cast_to_boolean_val(FunctionContext* context, const StringVal& val); + static BooleanVal cast_to_boolean_val(FunctionContext* context, const StringVal& val); static BooleanVal cast_to_boolean_val(FunctionContext* context, const DateTimeVal& val); static TinyIntVal cast_to_tiny_int_val(FunctionContext* context, const BooleanVal& val); diff --git a/be/src/olap/delete_handler.cpp b/be/src/olap/delete_handler.cpp index 3435dc3..369db7a 100644 --- a/be/src/olap/delete_handler.cpp +++ b/be/src/olap/delete_handler.cpp @@ -155,6 +155,8 @@ OLAPStatus DeleteConditionHandler::check_condition_valid( } } else if (field_type == OLAP_FIELD_TYPE_DATE || field_type == OLAP_FIELD_TYPE_DATETIME) { valid_condition = valid_datetime(value_str); + } else if (field_type == OLAP_FIELD_TYPE_BOOL) { + valid_condition = valid_bool(value_str); } else { OLAP_LOG_WARNING("unknown field type. [type=%d]", field_type); } diff --git a/be/src/olap/utils.cpp b/be/src/olap/utils.cpp index 93a61e3..f34108f 100644 --- a/be/src/olap/utils.cpp +++ b/be/src/olap/utils.cpp @@ -51,6 +51,7 @@ #include "olap/olap_define.h" #include "util/errno.h" #include "util/mutex.h" +#include "util/string_parser.hpp" using std::string; using std::set; @@ -1264,6 +1265,15 @@ bool valid_datetime(const string &value_str) { } } +bool valid_bool(const std::string& value_str) { + if (value_str == "0" || value_str == "1") { + return true; + } + StringParser::ParseResult result; + StringParser::string_to_bool(value_str.c_str(), value_str.length(), &result); + return result == StringParser::PARSE_SUCCESS; +} + void write_log_info(char *buf, size_t buf_len, const char *fmt, ...) { va_list args; va_start(args, fmt); diff --git a/be/src/olap/utils.h b/be/src/olap/utils.h index 09cbf8c..feba526 100644 --- a/be/src/olap/utils.h +++ b/be/src/olap/utils.h @@ -321,6 +321,8 @@ bool valid_decimal(const std::string& value_str, const uint32_t precision, const // 粗略检查date或者datetime类型是否正确 bool valid_datetime(const std::string& value_str); +bool valid_bool(const std::string& value_str); + #define OLAP_LOG_WRITE(level, fmt, arg...) \ do { \ char buf[10240] = {0}; \ diff --git a/fe/src/main/java/org/apache/doris/analysis/BoolLiteral.java b/fe/src/main/java/org/apache/doris/analysis/BoolLiteral.java index 6e22b75..ea493c3 100644 --- a/fe/src/main/java/org/apache/doris/analysis/BoolLiteral.java +++ b/fe/src/main/java/org/apache/doris/analysis/BoolLiteral.java @@ -40,9 +40,9 @@ public class BoolLiteral extends LiteralExpr { public BoolLiteral(String value) throws AnalysisException { this.type = Type.BOOLEAN; - if (value.toLowerCase().equals("true")) { + if (value.trim().toLowerCase().equals("true") || value.trim().equals("1")) { this.value = true; - } else if (value.toLowerCase().equals("false")) { + } else if (value.trim().toLowerCase().equals("false") || value.trim().equals("0")) { this.value = false; } else { throw new AnalysisException("Invalid BOOLEAN literal: " + value); diff --git a/fe/src/main/java/org/apache/doris/analysis/CastExpr.java b/fe/src/main/java/org/apache/doris/analysis/CastExpr.java index f8b4177..bcf65c0 100644 --- a/fe/src/main/java/org/apache/doris/analysis/CastExpr.java +++ b/fe/src/main/java/org/apache/doris/analysis/CastExpr.java @@ -99,10 +99,6 @@ public class CastExpr extends Expr { if (toType.isNull()) { continue; } - // Disable casting from string to boolean - if (fromType.isStringType() && toType.isBoolean()) { - continue; - } // Disable casting from boolean to decimal or datetime or date if (fromType.isBoolean() && (toType.equals(Type.DECIMAL) || toType.equals(Type.DECIMALV2) || diff --git a/fe/src/main/java/org/apache/doris/load/DeleteHandler.java b/fe/src/main/java/org/apache/doris/load/DeleteHandler.java index bba013a..c12813a 100644 --- a/fe/src/main/java/org/apache/doris/load/DeleteHandler.java +++ b/fe/src/main/java/org/apache/doris/load/DeleteHandler.java @@ -33,6 +33,7 @@ import org.apache.doris.catalog.MaterializedIndexMeta; import org.apache.doris.catalog.OlapTable; import org.apache.doris.catalog.Partition; import org.apache.doris.catalog.PartitionType; +import org.apache.doris.catalog.PrimitiveType; import org.apache.doris.catalog.Replica; import org.apache.doris.catalog.Table; import org.apache.doris.catalog.Tablet; @@ -493,7 +494,16 @@ public class DeleteHandler implements Writable { String value = null; try { BinaryPredicate binaryPredicate = (BinaryPredicate) condition; + // if a bool cond passed to be, be's zone_map cannot handle bool correctly, + // change it to a tinyint type here; value = ((LiteralExpr) binaryPredicate.getChild(1)).getStringValue(); + if (column.getDataType() == PrimitiveType.BOOLEAN ) { + if (value.toLowerCase().equals("true")) { + binaryPredicate.setChild(1, LiteralExpr.create("1", Type.TINYINT)); + } else if (value.toLowerCase().equals("false")) { + binaryPredicate.setChild(1, LiteralExpr.create("0", Type.TINYINT)); + } + } LiteralExpr.create(value, Type.fromPrimitiveType(column.getDataType())); } catch (AnalysisException e) { // ErrorReport.reportDdlException(ErrorCode.ERR_INVALID_VALUE, value); --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org