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 <[email protected]>
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: [email protected]
For additional commands, e-mail: [email protected]