This is an automated email from the ASF dual-hosted git repository.
zhangstar333 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 838e31146f0 [improve](fold) support complex type for constant folding
(#32867)
838e31146f0 is described below
commit 838e31146f095cc53d4b38a8ec7e078cbc7b226c
Author: zhangstar333 <[email protected]>
AuthorDate: Thu Apr 11 23:40:50 2024 +0800
[improve](fold) support complex type for constant folding (#32867)
---
be/src/runtime/fold_constant_executor.cpp | 61 ++--
.../java/org/apache/doris/catalog/ScalarType.java | 4 +
.../java/org/apache/doris/analysis/CastExpr.java | 5 +
.../java/org/apache/doris/analysis/MapLiteral.java | 2 +-
.../expression/rules/FoldConstantRuleOnBE.java | 406 ++++++++++++++++++---
.../trees/expressions/literal/MapLiteral.java | 5 +-
.../trees/expressions/literal/StructLiteral.java | 5 +-
.../apache/doris/rewrite/FoldConstantsRule.java | 1 +
.../org/apache/doris/analysis/MapLiteralTest.java | 12 +-
.../apache/doris/analysis/StructLiteralTest.java | 4 +-
.../nereids/trees/expressions/LiteralTest.java | 265 ++++++++++++++
gensrc/thrift/PaloInternalService.thrift | 1 +
.../push_filter_inside_join.groovy | 1 +
.../filter_push_down/push_filter_through.groovy | 1 +
14 files changed, 696 insertions(+), 77 deletions(-)
diff --git a/be/src/runtime/fold_constant_executor.cpp
b/be/src/runtime/fold_constant_executor.cpp
index 69fe217da78..5ba384baf84 100644
--- a/be/src/runtime/fold_constant_executor.cpp
+++ b/be/src/runtime/fold_constant_executor.cpp
@@ -48,19 +48,20 @@
#include "util/runtime_profile.h"
#include "util/uid_util.h"
#include "vec/columns/column.h"
+#include "vec/columns/column_array.h"
#include "vec/columns/column_vector.h"
#include "vec/columns/columns_number.h"
#include "vec/common/string_ref.h"
#include "vec/core/block.h"
#include "vec/core/column_with_type_and_name.h"
+#include "vec/core/field.h"
+#include "vec/core/types.h"
+#include "vec/data_types/data_type_array.h"
#include "vec/data_types/data_type_number.h"
#include "vec/exprs/vexpr.h"
#include "vec/exprs/vexpr_context.h"
#include "vec/runtime/vdatetime_value.h"
-using std::string;
-using std::map;
-
namespace doris {
static std::unordered_set<PrimitiveType> PRIMITIVE_TYPE_SET {
@@ -72,7 +73,7 @@ static std::unordered_set<PrimitiveType> PRIMITIVE_TYPE_SET {
Status FoldConstantExecutor::fold_constant_vexpr(const TFoldConstantParams&
params,
PConstantExprResult*
response) {
const auto& expr_map = params.expr_map;
- auto expr_result_map = response->mutable_expr_result_map();
+ auto* expr_result_map = response->mutable_expr_result_map();
TQueryGlobals query_globals = params.query_globals;
_query_id = params.query_id;
@@ -107,31 +108,45 @@ Status FoldConstantExecutor::fold_constant_vexpr(const
TFoldConstantParams& para
string result;
const auto& column_ptr =
tmp_block.get_by_position(result_column).column;
const auto& column_type =
tmp_block.get_by_position(result_column).type;
- if (column_ptr->is_null_at(0)) {
- expr_result.set_success(false);
- } else {
+ // 4 from fe: Config.be_exec_version maybe need remove after next
version, now in 2.1
+ if (_runtime_state->be_exec_version() >= 4 &&
params.__isset.is_nereids &&
+ params.is_nereids) {
+ auto* p_type_desc = expr_result.mutable_type_desc();
+ auto* p_values = expr_result.mutable_result_content();
+ res_type.to_protobuf(p_type_desc);
+ auto datatype_serde = column_type->get_serde();
+ RETURN_IF_ERROR(datatype_serde->write_column_to_pb(
+ *column_ptr->convert_to_full_column_if_const(),
*p_values, 0, 1));
expr_result.set_success(true);
- StringRef string_ref;
- auto type = ctx->root()->type().type;
- //eg: strcut, array, map VARIANT... will not impl get_data_at,
so could use column->to_string()
- if (PRIMITIVE_TYPE_SET.contains(type)) {
- string_ref = column_ptr->get_data_at(0);
+ // after refactor, this field is useless, but it's required
+ expr_result.set_content("ERROR");
+ expr_result.mutable_type()->set_type(t_type);
+ pexpr_result_map.mutable_map()->insert({n.first, expr_result});
+ } else {
+ if (column_ptr->is_null_at(0)) {
+ expr_result.set_success(false);
+ } else {
+ expr_result.set_success(true);
+ StringRef string_ref;
+ auto type = ctx->root()->type().type;
+ //eg: strcut, array, map VARIANT... will not impl
get_data_at, so could use column->to_string()
+ if (PRIMITIVE_TYPE_SET.contains(type)) {
+ string_ref = column_ptr->get_data_at(0);
+ }
+ RETURN_IF_ERROR(_get_result((void*)string_ref.data,
string_ref.size,
+ ctx->root()->type(),
column_ptr, column_type,
+ result));
}
- RETURN_IF_ERROR(_get_result((void*)string_ref.data,
string_ref.size,
- ctx->root()->type(), column_ptr,
column_type, result));
+ expr_result.set_content(std::move(result));
+ expr_result.mutable_type()->set_type(t_type);
+ expr_result.mutable_type()->set_scale(res_type.scale);
+ expr_result.mutable_type()->set_precision(res_type.precision);
+ expr_result.mutable_type()->set_len(res_type.len);
+ pexpr_result_map.mutable_map()->insert({n.first, expr_result});
}
-
- expr_result.set_content(std::move(result));
- expr_result.mutable_type()->set_type(t_type);
- expr_result.mutable_type()->set_scale(res_type.scale);
- expr_result.mutable_type()->set_precision(res_type.precision);
- expr_result.mutable_type()->set_len(res_type.len);
- pexpr_result_map.mutable_map()->insert({n.first, expr_result});
}
expr_result_map->insert({m.first, pexpr_result_map});
}
- //TODO: will be delete the debug log after find problem of timeout.
- LOG(INFO) << "finish fold_query_id: " << query_id_string();
return Status::OK();
}
diff --git
a/fe/fe-common/src/main/java/org/apache/doris/catalog/ScalarType.java
b/fe/fe-common/src/main/java/org/apache/doris/catalog/ScalarType.java
index 83072ad97f5..67346fc2160 100644
--- a/fe/fe-common/src/main/java/org/apache/doris/catalog/ScalarType.java
+++ b/fe/fe-common/src/main/java/org/apache/doris/catalog/ScalarType.java
@@ -216,6 +216,10 @@ public class ScalarType extends Type {
return DEFAULT_DECIMALV2;
case LARGEINT:
return LARGEINT;
+ case IPV4:
+ return IPV4;
+ case IPV6:
+ return IPV6;
case ALL:
return ALL;
default:
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java
b/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java
index f069c1cd695..d2437fbd95c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/CastExpr.java
@@ -132,6 +132,11 @@ public class CastExpr extends Expr {
if (type.isDecimalV2() && e.type.isDecimalV2()) {
getChild(0).setType(type);
}
+ // as the targetType have struct field name, if use the default
name will be
+ // like col1,col2, col3... in struct, and the filed name is import
in BE.
+ if (type.isStructType() && e.type.isStructType()) {
+ getChild(0).setType(type);
+ }
analysisDone();
return;
}
diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/MapLiteral.java
b/fe/fe-core/src/main/java/org/apache/doris/analysis/MapLiteral.java
index e55519101cf..633478f3f84 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/analysis/MapLiteral.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/MapLiteral.java
@@ -188,7 +188,7 @@ public class MapLiteral extends LiteralExpr {
// map key type do not support complex type
throw new UnsupportedOperationException("Unsupport key type
for MAP: " + children.get(i).getType());
}
- list.add(children.get(i).getStringValueForArray()
+ list.add(getStringLiteralForComplexType(children.get(i))
+ ":" + getStringLiteralForComplexType(children.get(i +
1)));
}
return "{" + StringUtils.join(list, ", ") + "}";
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnBE.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnBE.java
index 09e9bbe0b91..ac9d7c4427b 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnBE.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/expression/rules/FoldConstantRuleOnBE.java
@@ -22,7 +22,9 @@ import org.apache.doris.analysis.ExprId;
import org.apache.doris.catalog.Env;
import org.apache.doris.catalog.PrimitiveType;
import org.apache.doris.catalog.ScalarType;
+import org.apache.doris.common.Config;
import org.apache.doris.common.IdGenerator;
+import org.apache.doris.common.Pair;
import org.apache.doris.common.UserException;
import org.apache.doris.common.util.DebugUtil;
import org.apache.doris.common.util.TimeUtils;
@@ -33,18 +35,44 @@ import
org.apache.doris.nereids.rules.expression.ExpressionPatternRuleFactory;
import org.apache.doris.nereids.trees.expressions.Alias;
import org.apache.doris.nereids.trees.expressions.Cast;
import org.apache.doris.nereids.trees.expressions.Expression;
+import
org.apache.doris.nereids.trees.expressions.functions.generator.TableGeneratingFunction;
import org.apache.doris.nereids.trees.expressions.functions.scalar.Sleep;
+import org.apache.doris.nereids.trees.expressions.functions.scalar.Tokenize;
+import org.apache.doris.nereids.trees.expressions.literal.ArrayLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.BigIntLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.DateTimeV2Literal;
+import org.apache.doris.nereids.trees.expressions.literal.DateV2Literal;
+import org.apache.doris.nereids.trees.expressions.literal.DecimalLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.DecimalV3Literal;
+import org.apache.doris.nereids.trees.expressions.literal.DoubleLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.FloatLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.IPv4Literal;
+import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.JsonLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.LargeIntLiteral;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
+import org.apache.doris.nereids.trees.expressions.literal.MapLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
import org.apache.doris.nereids.trees.expressions.literal.NumericLiteral;
-import org.apache.doris.nereids.types.CharType;
+import org.apache.doris.nereids.trees.expressions.literal.SmallIntLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.StructLiteral;
+import org.apache.doris.nereids.trees.expressions.literal.TinyIntLiteral;
+import org.apache.doris.nereids.types.ArrayType;
import org.apache.doris.nereids.types.DataType;
import org.apache.doris.nereids.types.DateTimeV2Type;
-import org.apache.doris.nereids.types.DecimalV2Type;
import org.apache.doris.nereids.types.DecimalV3Type;
-import org.apache.doris.nereids.types.VarcharType;
+import org.apache.doris.nereids.types.MapType;
+import org.apache.doris.nereids.types.StructField;
+import org.apache.doris.nereids.types.StructType;
import org.apache.doris.proto.InternalService;
import org.apache.doris.proto.InternalService.PConstantExprResult;
import org.apache.doris.proto.Types.PScalarType;
+import org.apache.doris.proto.Types.PStructField;
+import org.apache.doris.proto.Types.PTypeDesc;
+import org.apache.doris.proto.Types.PTypeNode;
+import org.apache.doris.proto.Types.PValues;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.rpc.BackendServiceProxy;
import org.apache.doris.system.Backend;
@@ -55,12 +83,18 @@ import org.apache.doris.thrift.TPrimitiveType;
import org.apache.doris.thrift.TQueryGlobals;
import org.apache.doris.thrift.TQueryOptions;
-import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
+import com.google.common.net.InetAddresses;
+import com.google.protobuf.ByteString;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.net.Inet4Address;
+import java.time.DateTimeException;
+import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
@@ -68,7 +102,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.Objects;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
@@ -84,8 +117,8 @@ public class FoldConstantRuleOnBE implements
ExpressionPatternRuleFactory {
public List<ExpressionPatternMatcher<? extends Expression>> buildRules() {
return ImmutableList.of(
root(Expression.class)
- .whenCtx(FoldConstantRuleOnBE::isEnableFoldByBe)
- .thenApply(FoldConstantRuleOnBE::foldByBE)
+ .whenCtx(FoldConstantRuleOnBE::isEnableFoldByBe)
+ .thenApply(FoldConstantRuleOnBE::foldByBE)
);
}
@@ -156,12 +189,23 @@ public class FoldConstantRuleOnBE implements
ExpressionPatternRuleFactory {
return;
}
// eg: avg_state(1) return is agg function serialize data
- if (expr.getDataType().isAggStateType()) {
+ // and some type can't find a literal to represent.
+ // time type: need add a time literal in nereids
+ // IPv6 type: need get a library to output the compressed address
format
+ if (expr.getDataType().isAggStateType() ||
expr.getDataType().isObjectType()
+ || expr.getDataType().isVariantType() ||
expr.getDataType().isTimeLikeType()
+ || expr.getDataType().isIPv6Type()) {
return;
}
- if (skipSleepFunction(expr)) {
+ if (skipSleepFunction(expr) || (expr instanceof
TableGeneratingFunction)) {
return;
}
+ // Tokenize function want check the second child literal must be
string type
+ // and properties format, it's a little special,
+ // maybe check in checkLegalityBeforeTypeCoercion function?
+ if (expr instanceof Tokenize) {
+ expr.checkLegalityAfterRewrite();
+ }
String id = idGenerator.getNextId().toString();
constMap.put(id, expr);
Expr staleExpr;
@@ -219,14 +263,14 @@ public class FoldConstantRuleOnBE implements
ExpressionPatternRuleFactory {
TQueryOptions tQueryOptions = new TQueryOptions();
tQueryOptions.setRepeatMaxNum(context.getSessionVariable().repeatMaxNum);
+ tQueryOptions.setBeExecVersion(Config.be_exec_version);
TFoldConstantParams tParams = new TFoldConstantParams(paramMap,
queryGlobals);
tParams.setVecExec(true);
tParams.setQueryOptions(tQueryOptions);
tParams.setQueryId(context.queryId());
+ tParams.setIsNereids(true);
- // TODO: will be delete the debug log after find problem of
timeout.
- LOG.info("fold query {} ", DebugUtil.printId(context.queryId()));
Future<PConstantExprResult> future =
BackendServiceProxy.getInstance().foldConstantExpr(brpcAddress,
tParams);
PConstantExprResult result = future.get(5, TimeUnit.SECONDS);
@@ -234,42 +278,18 @@ public class FoldConstantRuleOnBE implements
ExpressionPatternRuleFactory {
if (result.getStatus().getStatusCode() == 0) {
for (Entry<String, InternalService.PExprResultMap> e :
result.getExprResultMapMap().entrySet()) {
for (Entry<String, InternalService.PExprResult> e1 :
e.getValue().getMapMap().entrySet()) {
- PScalarType pScalarType = e1.getValue().getType();
- TPrimitiveType tPrimitiveType =
TPrimitiveType.findByValue(pScalarType.getType());
- PrimitiveType primitiveType =
PrimitiveType.fromThrift(Objects.requireNonNull(tPrimitiveType));
Expression ret;
if (e1.getValue().getSuccess()) {
- DataType type;
- if (PrimitiveType.ARRAY == primitiveType
- || PrimitiveType.MAP == primitiveType
- || PrimitiveType.STRUCT == primitiveType
- || PrimitiveType.AGG_STATE ==
primitiveType) {
+ PTypeDesc pTypeDesc = e1.getValue().getTypeDesc();
+ DataType type =
convertToNereidsType(pTypeDesc.getTypesList(), 0).key();
+ PValues resultContent =
e1.getValue().getResultContent();
+ List<Literal> resultExpression =
getResultExpression(type, resultContent);
+ if (resultExpression.isEmpty()) {
ret = constMap.get(e1.getKey());
+ LOG.debug("Be constant folding convert {} to
{} failed query_id: {}", e1.getKey(), ret,
+ DebugUtil.printId(context.queryId()));
} else {
- if (primitiveType == PrimitiveType.CHAR) {
-
Preconditions.checkState(pScalarType.hasLen(),
- "be return char type without len");
- type =
CharType.createCharType(pScalarType.getLen());
- } else if (primitiveType ==
PrimitiveType.VARCHAR) {
-
Preconditions.checkState(pScalarType.hasLen(),
- "be return varchar type without
len");
- type =
VarcharType.createVarcharType(pScalarType.getLen());
- } else if (primitiveType ==
PrimitiveType.DECIMALV2) {
- type = DecimalV2Type.createDecimalV2Type(
- pScalarType.getPrecision(),
pScalarType.getScale());
- } else if (primitiveType ==
PrimitiveType.DATETIMEV2) {
- type =
DateTimeV2Type.of(pScalarType.getScale());
- } else if (primitiveType ==
PrimitiveType.DECIMAL32
- || primitiveType ==
PrimitiveType.DECIMAL64
- || primitiveType ==
PrimitiveType.DECIMAL128
- || primitiveType ==
PrimitiveType.DECIMAL256) {
- type =
DecimalV3Type.createDecimalV3TypeLooseCheck(
- pScalarType.getPrecision(),
pScalarType.getScale());
- } else {
- type =
DataType.fromCatalogType(ScalarType.createType(
-
PrimitiveType.fromThrift(tPrimitiveType)));
- }
- ret =
Literal.of(e1.getValue().getContent()).castTo(type);
+ ret = resultExpression.get(0);
}
} else {
ret = constMap.get(e1.getKey());
@@ -291,4 +311,304 @@ public class FoldConstantRuleOnBE implements
ExpressionPatternRuleFactory {
}
return resultMap;
}
+
+ /**
+ * convert PValues which from BE to Expression of nereids
+ */
+ public static List<Literal> getResultExpression(DataType type, PValues
resultContent) {
+ List<Literal> res = new ArrayList<>();
+ if (type.isNullType()) {
+ int num = resultContent.getNullMapCount();
+ for (int i = 0; i < num; ++i) {
+ Literal literal = new NullLiteral(type);
+ res.add(literal);
+ }
+ } else if (type.isBooleanType()) {
+ int num = resultContent.getUint32ValueCount();
+ for (int i = 0; i < num; ++i) {
+ Literal literal =
BooleanLiteral.of(resultContent.getUint32Value(i) == 1);
+ res.add(literal);
+ }
+ } else if (type.isTinyIntType()) {
+ int num = resultContent.getInt32ValueCount();
+ for (int i = 0; i < num; ++i) {
+ Literal literal = new TinyIntLiteral((byte)
resultContent.getInt32Value(i));
+ res.add(literal);
+ }
+ } else if (type.isSmallIntType()) {
+ int num = resultContent.getInt32ValueCount();
+ for (int i = 0; i < num; ++i) {
+ Literal literal = new SmallIntLiteral((short)
resultContent.getInt32Value(i));
+ res.add(literal);
+ }
+ } else if (type.isIntegerType()) {
+ int num = resultContent.getInt32ValueCount();
+ for (int i = 0; i < num; ++i) {
+ Literal literal = new
IntegerLiteral(resultContent.getInt32Value(i));
+ res.add(literal);
+ }
+ } else if (type.isBigIntType()) {
+ int num = resultContent.getInt64ValueCount();
+ for (int i = 0; i < num; ++i) {
+ Literal literal = new
BigIntLiteral(resultContent.getInt64Value(i));
+ res.add(literal);
+ }
+ } else if (type.isLargeIntType()) {
+ int num = resultContent.getBytesValueCount();
+ for (int i = 0; i < num; ++i) {
+ ByteString bytesValue = resultContent.getBytesValue(i);
+ byte[] bytes = convertByteOrder(bytesValue.toByteArray());
+ BigInteger convertedBigInteger = new BigInteger(bytes);
+ Literal literal = new LargeIntLiteral(convertedBigInteger);
+ res.add(literal);
+ }
+ } else if (type.isFloatType()) {
+ int num = resultContent.getFloatValueCount();
+ for (int i = 0; i < num; ++i) {
+ float value = resultContent.getFloatValue(i);
+ Literal literal = null;
+ if (Float.isNaN(value)) {
+ literal = new NullLiteral(type);
+ } else {
+ literal = new FloatLiteral(value);
+ }
+ res.add(literal);
+ }
+ } else if (type.isDoubleType()) {
+ int num = resultContent.getDoubleValueCount();
+ for (int i = 0; i < num; ++i) {
+ double value = resultContent.getDoubleValue(i);
+ Literal literal = null;
+ if (Double.isNaN(value)) {
+ literal = new NullLiteral(type);
+ } else {
+ literal = new DoubleLiteral(value);
+ }
+ res.add(literal);
+ }
+ } else if (type.isDecimalV2Type()) {
+ int num = resultContent.getBytesValueCount();
+ for (int i = 0; i < num; ++i) {
+ ByteString bytesValue = resultContent.getBytesValue(i);
+ byte[] bytes = convertByteOrder(bytesValue.toByteArray());
+ BigInteger value = new BigInteger(bytes);
+ BigDecimal bigDecimal = new BigDecimal(value, 9); // decimalv2
scale always 9
+ Literal literal = new DecimalLiteral(bigDecimal);
+ res.add(literal);
+ }
+ } else if (type.isDecimalV3Type()) {
+ int num = resultContent.getBytesValueCount();
+ DecimalV3Type decimalV3Type = (DecimalV3Type) type;
+ for (int i = 0; i < num; ++i) {
+ ByteString bytesValue = resultContent.getBytesValue(i);
+ byte[] bytes = convertByteOrder(bytesValue.toByteArray());
+ BigInteger value = new BigInteger(bytes);
+ BigDecimal bigDecimal = new BigDecimal(value,
decimalV3Type.getScale());
+ Literal literal = new DecimalV3Literal(decimalV3Type,
bigDecimal);
+ res.add(literal);
+ }
+ } else if (type.isDateTimeV2Type()) {
+ int num = resultContent.getUint64ValueCount();
+ for (int i = 0; i < num; ++i) {
+ long uint64Value = resultContent.getUint64Value(i);
+ LocalDateTime dateTimeV2 =
convertToJavaDateTimeV2(uint64Value);
+ Literal literal = new DateTimeV2Literal((DateTimeV2Type) type,
dateTimeV2.getYear(),
+ dateTimeV2.getMonthValue(),
dateTimeV2.getDayOfMonth(), dateTimeV2.getHour(),
+ dateTimeV2.getMinute(), dateTimeV2.getSecond(),
dateTimeV2.getNano() / 1000);
+ res.add(literal);
+ }
+ } else if (type.isDateV2Type()) {
+ int num = resultContent.getUint32ValueCount();
+ for (int i = 0; i < num; ++i) {
+ int uint32Value = resultContent.getUint32Value(i);
+ LocalDate localDate = convertToJavaDateV2(uint32Value);
+ DateV2Literal dateV2Literal = new
DateV2Literal(localDate.getYear(), localDate.getMonthValue(),
+ localDate.getDayOfMonth());
+ res.add(dateV2Literal);
+ }
+ } else if (type.isIPv4Type()) {
+ int num = resultContent.getUint32ValueCount();
+ for (int i = 0; i < num; ++i) {
+ Inet4Address inet4Address =
InetAddresses.fromInteger(resultContent.getUint32Value(i));
+ IPv4Literal iPv4Literal = new
IPv4Literal(inet4Address.getHostAddress());
+ res.add(iPv4Literal);
+ }
+ } else if (type.isJsonType()) {
+ int num = resultContent.getStringValueCount();
+ for (int i = 0; i < num; ++i) {
+ String stringValue = resultContent.getStringValue(i);
+ // maybe need handle NULL_IN_CSV_FOR_ORDINARY_TYPE = "\\N";
+ JsonLiteral jsonLiteral = new JsonLiteral(stringValue);
+ res.add(jsonLiteral);
+ }
+ } else if (type.isStringLikeType()) {
+ int num = resultContent.getStringValueCount();
+ for (int i = 0; i < num; ++i) {
+ Literal literal = new
StringLiteral(resultContent.getStringValue(i));
+ res.add(literal);
+ }
+ } else if (type.isArrayType()) {
+ ArrayType arrayType = (ArrayType) type;
+ int childCount = resultContent.getChildElementCount();
+ List<Literal> allLiterals = new ArrayList<>();
+ for (int i = 0; i < childCount; ++i) {
+ allLiterals.addAll(getResultExpression(arrayType.getItemType(),
+ resultContent.getChildElement(i)));
+ }
+ int offsetCount = resultContent.getChildOffsetCount();
+ if (offsetCount == 1) {
+ ArrayLiteral arrayLiteral = new ArrayLiteral(allLiterals,
arrayType);
+ res.add(arrayLiteral);
+ } else {
+ for (int i = 0; i < offsetCount; ++i) {
+ List<Literal> childLiteral = new ArrayList<>();
+ int startOffset = (int) ((i == 0) ? 0 :
resultContent.getChildOffset(i - 1));
+ int endOffset = (int) resultContent.getChildOffset(i);
+ for (int off = startOffset; off < endOffset; ++off) {
+ childLiteral.add(allLiterals.get(off));
+ }
+ ArrayLiteral arrayLiteral = new ArrayLiteral(childLiteral,
arrayType);
+ res.add(arrayLiteral);
+ }
+ }
+ } else if (type.isMapType()) {
+ MapType mapType = (MapType) type;
+ int childCount = resultContent.getChildElementCount();
+ List<Literal> allKeys = new ArrayList<>();
+ List<Literal> allValues = new ArrayList<>();
+ for (int i = 0; i < childCount; i = i + 2) {
+ allKeys.addAll(getResultExpression(mapType.getKeyType(),
+ resultContent.getChildElement(i)));
+ allValues.addAll(getResultExpression(mapType.getValueType(),
+ resultContent.getChildElement(i + 1)));
+ }
+ int offsetCount = resultContent.getChildOffsetCount();
+ if (offsetCount == 1) {
+ MapLiteral mapLiteral = new MapLiteral(allKeys, allValues,
mapType);
+ res.add(mapLiteral);
+ } else {
+ for (int i = 0; i < offsetCount; ++i) {
+ List<Literal> keyLiteral = new ArrayList<>();
+ List<Literal> valueLiteral = new ArrayList<>();
+ int startOffset = (int) ((i == 0) ? 0 :
resultContent.getChildOffset(i - 1));
+ int endOffset = (int) resultContent.getChildOffset(i);
+ for (int off = startOffset; off < endOffset; ++off) {
+ keyLiteral.add(allKeys.get(off));
+ valueLiteral.add(allValues.get(off));
+ }
+ MapLiteral mapLiteral = new MapLiteral(keyLiteral,
valueLiteral, mapType);
+ res.add(mapLiteral);
+ }
+ }
+ } else if (type.isStructType()) {
+ StructType structType = (StructType) type;
+ int childCount = resultContent.getChildElementCount();
+ List<List<Literal>> allFields = new ArrayList<>();
+ for (int i = 0; i < childCount; ++i) {
+
allFields.add(getResultExpression(structType.getFields().get(i).getDataType(),
+ resultContent.getChildElement(i)));
+ }
+ for (int i = 0; i < allFields.get(0).size(); ++i) {
+ List<Literal> fields = new ArrayList<>();
+ for (int child = 0; child < childCount; ++child) {
+ fields.add(allFields.get(child).get(i));
+ }
+ StructLiteral structLiteral = new StructLiteral(fields,
structType);
+ res.add(structLiteral);
+ }
+ } else {
+ LOG.warn("the type: {} is not support, should implement it",
type.toString());
+ }
+ if (resultContent.hasHasNull()) {
+ for (int i = 0; i < resultContent.getNullMapCount(); ++i) {
+ if (resultContent.getNullMap(i)) {
+ res.set(i, new NullLiteral(type));
+ }
+ }
+ }
+ return res;
+ }
+
+ private static Pair<DataType, Integer>
convertToNereidsType(List<PTypeNode> typeNodes, int start) {
+ PScalarType pScalarType = typeNodes.get(start).getScalarType();
+ boolean containsNull = typeNodes.get(start).getContainsNull();
+ TPrimitiveType tPrimitiveType =
TPrimitiveType.findByValue(pScalarType.getType());
+ DataType type;
+ int parsedNodes;
+ if (tPrimitiveType == TPrimitiveType.ARRAY) {
+ Pair<DataType, Integer> itemType = convertToNereidsType(typeNodes,
start + 1);
+ type = ArrayType.of(itemType.key(), containsNull);
+ parsedNodes = 1 + itemType.value();
+ } else if (tPrimitiveType == TPrimitiveType.MAP) {
+ Pair<DataType, Integer> keyType = convertToNereidsType(typeNodes,
start + 1);
+ Pair<DataType, Integer> valueType =
convertToNereidsType(typeNodes, start + 1 + keyType.value());
+ type = MapType.of(keyType.key(), valueType.key());
+ parsedNodes = 1 + keyType.value() + valueType.value();
+ } else if (tPrimitiveType == TPrimitiveType.STRUCT) {
+ parsedNodes = 1;
+ ArrayList<StructField> fields = new ArrayList<>();
+ for (int i = 0; i < typeNodes.get(start).getStructFieldsCount();
++i) {
+ Pair<DataType, Integer> fieldType =
convertToNereidsType(typeNodes, start + parsedNodes);
+ PStructField structField =
typeNodes.get(start).getStructFields(i);
+ fields.add(new StructField(structField.getName(),
fieldType.key(),
+ structField.getContainsNull(),
+ structField.getComment() == null ? "" :
structField.getComment()));
+ parsedNodes += fieldType.value();
+ }
+ type = new StructType(fields);
+ } else if (tPrimitiveType == TPrimitiveType.DECIMALV2) {
+ type =
DataType.fromCatalogType(ScalarType.createDecimalType(PrimitiveType.fromThrift(tPrimitiveType),
+ pScalarType.getPrecision(), pScalarType.getScale()));
+ parsedNodes = 1;
+ } else {
+ type =
DataType.fromCatalogType(ScalarType.createType(PrimitiveType.fromThrift(tPrimitiveType),
+ pScalarType.getLen(), pScalarType.getPrecision(),
pScalarType.getScale()));
+ parsedNodes = 1;
+ }
+ return Pair.of(type, parsedNodes);
+ }
+
+ private static LocalDateTime convertToJavaDateTimeV2(long time) {
+ int year = (int) (time >> 46);
+ int yearMonth = (int) (time >> 42);
+ int yearMonthDay = (int) (time >> 37);
+
+ int month = (yearMonth & 0XF);
+ int day = (yearMonthDay & 0X1F);
+
+ int hour = (int) ((time >> 32) & 0X1F);
+ int minute = (int) ((time >> 26) & 0X3F);
+ int second = (int) ((time >> 20) & 0X3F);
+ int microsecond = (int) (time & 0XFFFFF);
+
+ try {
+ return LocalDateTime.of(year, month, day, hour, minute, second,
microsecond * 1000);
+ } catch (DateTimeException e) {
+ return null;
+ }
+ }
+
+ private static LocalDate convertToJavaDateV2(int date) {
+ int year = date >> 9;
+ int month = (date >> 5) & 0XF;
+ int day = date & 0X1F;
+ try {
+ return LocalDate.of(year, month, day);
+ } catch (DateTimeException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Change the order of the bytes, Because JVM is Big-Endian , x86 is
Little-Endian.
+ */
+ private static byte[] convertByteOrder(byte[] bytes) {
+ int length = bytes.length;
+ for (int i = 0; i < length / 2; ++i) {
+ byte temp = bytes[i];
+ bytes[i] = bytes[length - 1 - i];
+ bytes[length - 1 - i] = temp;
+ }
+ return bytes;
+ }
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/MapLiteral.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/MapLiteral.java
index 7dab827509b..c57bd3a0487 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/MapLiteral.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/MapLiteral.java
@@ -48,7 +48,10 @@ public class MapLiteral extends Literal {
this(keys, values, computeDataType(keys, values));
}
- private MapLiteral(List<Literal> keys, List<Literal> values, DataType
dataType) {
+ /**
+ * create MAP Literal with keys, values and datatype
+ */
+ public MapLiteral(List<Literal> keys, List<Literal> values, DataType
dataType) {
super(dataType);
this.keys = ImmutableList.copyOf(Objects.requireNonNull(keys, "keys
should not be null"));
this.values = ImmutableList.copyOf(Objects.requireNonNull(values,
"values should not be null"));
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StructLiteral.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StructLiteral.java
index 2fd2186f496..3a46f1f5b83 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StructLiteral.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/expressions/literal/StructLiteral.java
@@ -49,7 +49,10 @@ public class StructLiteral extends Literal {
this(fields, computeDataType(fields));
}
- private StructLiteral(List<Literal> fields, DataType dataType) {
+ /**
+ * create Struct Literal with fields and datatype
+ */
+ public StructLiteral(List<Literal> fields, DataType dataType) {
super(dataType);
this.fields = ImmutableList.copyOf(Objects.requireNonNull(fields,
"fields should not be null"));
Preconditions.checkArgument(dataType instanceof StructType,
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/rewrite/FoldConstantsRule.java
b/fe/fe-core/src/main/java/org/apache/doris/rewrite/FoldConstantsRule.java
index 3ef20a5651d..dd37c2fc7b1 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/rewrite/FoldConstantsRule.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/rewrite/FoldConstantsRule.java
@@ -384,6 +384,7 @@ public class FoldConstantsRule implements ExprRewriteRule {
tParams.setVecExec(true);
tParams.setQueryOptions(tQueryOptions);
tParams.setQueryId(context.queryId());
+ tParams.setIsNereids(false);
Future<InternalService.PConstantExprResult> future
=
BackendServiceProxy.getInstance().foldConstantExpr(brpcAddress, tParams);
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/analysis/MapLiteralTest.java
b/fe/fe-core/src/test/java/org/apache/doris/analysis/MapLiteralTest.java
index 700c54253e4..61e77dbc907 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/analysis/MapLiteralTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/MapLiteralTest.java
@@ -116,26 +116,26 @@ public class MapLiteralTest {
@Test
public void testGetStringInFe() throws AnalysisException {
MapLiteral mapLiteral1 = new MapLiteral(intLiteral1, floatLiteral);
- Assert.assertEquals("{\"1\":2.15}", mapLiteral1.getStringValueInFe());
+ Assert.assertEquals("{1:2.15}", mapLiteral1.getStringValueInFe());
MapLiteral mapLiteral11 = new MapLiteral(intLiteral1, floatLiteral1);
- Assert.assertEquals("{\"1\":\"11:22:33\"}",
mapLiteral11.getStringValueInFe());
+ Assert.assertEquals("{1:\"11:22:33\"}",
mapLiteral11.getStringValueInFe());
MapLiteral mapLiteral2 = new MapLiteral(boolLiteral, stringLiteral);
- Assert.assertEquals("{\"1\":\"shortstring\"}",
mapLiteral2.getStringValueInFe());
+ Assert.assertEquals("{1:\"shortstring\"}",
mapLiteral2.getStringValueInFe());
MapLiteral mapLiteral3 = new MapLiteral(largeIntLiteral, dateLiteral);
- Assert.assertEquals("{\"1000000000000000000000\":\"2022-10-10\"}",
mapLiteral3.getStringValueInFe());
+ Assert.assertEquals("{1000000000000000000000:\"2022-10-10\"}",
mapLiteral3.getStringValueInFe());
MapLiteral mapLiteral4 = new MapLiteral(floatLiteral1, nullLiteral);
Assert.assertEquals("{\"11:22:33\":null}",
mapLiteral4.getStringValueInFe());
MapLiteral mapLiteral5 = new MapLiteral(datetimeLiteral, dateLiteral);
Assert.assertEquals("{\"2022-10-10 12:10:10\":\"2022-10-10\"}",
mapLiteral5.getStringValueInFe());
MapLiteral mapLiteral6 = new MapLiteral(decimalLiteral1,
decimalLiteral2);
- Assert.assertEquals("{\"1.0\":2}", mapLiteral6.getStringValueInFe());
+ Assert.assertEquals("{1.0:2}", mapLiteral6.getStringValueInFe());
MapLiteral mapLiteral7 = new MapLiteral();
Assert.assertEquals("{}", mapLiteral7.getStringValueInFe());
MapLiteral mapLiteral8 = new MapLiteral(nullLiteral, intLiteral1);
Assert.assertEquals("{null:1}", mapLiteral8.getStringValueInFe());
MapLiteral mapLiteral9 = new MapLiteral(intLiteral1, nullLiteral);
- Assert.assertEquals("{\"1\":null}", mapLiteral9.getStringValueInFe());
+ Assert.assertEquals("{1:null}", mapLiteral9.getStringValueInFe());
MapLiteral mapLiteral10 = new MapLiteral(intLiteral1, arrayLiteral);
Assert.assertEquals("{\"1\":[\"1\", \"2.15\"]}",
mapLiteral10.getStringValueForArray());
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/analysis/StructLiteralTest.java
b/fe/fe-core/src/test/java/org/apache/doris/analysis/StructLiteralTest.java
index b7f2577ad63..c48ad5d5785 100644
--- a/fe/fe-core/src/test/java/org/apache/doris/analysis/StructLiteralTest.java
+++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/StructLiteralTest.java
@@ -86,9 +86,9 @@ public class StructLiteralTest {
stringLiteral, largeIntLiteral, decimalLiteral1,
decimalLiteral2, dateLiteral, datetimeLiteral);
Assert.assertEquals("{\"col1\": 1, \"col2\": 2.15, \"col3\":
\"11:22:33\", \"col4\": 1, \"col5\": "
+ "\"shortstring\", \"col6\": 1000000000000000000000,
\"col7\": 1.0, \"col8\": 2, \"col9\": \"2022-10-10\", \"col10\": \"2022-10-10
12:10:10\"}",
- structLiteral1.getStringValueInFe());
+ structLiteral1.getStringValueInFe());
StructLiteral structLiteral2 = new StructLiteral(arrayLiteral,
mapLiteral, structLiteral);
- Assert.assertEquals("{\"col1\": [1.0, 2.15], \"col2\": {\"1\":2.15},
\"col3\": "
+ Assert.assertEquals("{\"col1\": [1.0, 2.15], \"col2\": {1:2.15},
\"col3\": "
+ "{\"col1\": 1, \"col2\": 2.15, \"col3\": 1.0,
\"col4\": \"2022-10-10\"}}",
structLiteral2.getStringValueInFe());
StructLiteral structLiteral3 = new StructLiteral();
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/LiteralTest.java
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/LiteralTest.java
index 842846bbd1b..fcb64ff0bfa 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/LiteralTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/nereids/trees/expressions/LiteralTest.java
@@ -17,15 +17,29 @@
package org.apache.doris.nereids.trees.expressions;
+import org.apache.doris.nereids.trees.expressions.literal.ArrayLiteral;
import org.apache.doris.nereids.trees.expressions.literal.BooleanLiteral;
import org.apache.doris.nereids.trees.expressions.literal.IntegerLiteral;
import org.apache.doris.nereids.trees.expressions.literal.Literal;
import org.apache.doris.nereids.trees.expressions.literal.NullLiteral;
import org.apache.doris.nereids.trees.expressions.literal.StringLiteral;
+import org.apache.doris.nereids.types.ArrayType;
+import org.apache.doris.nereids.types.DataType;
+import org.apache.doris.nereids.types.IntegerType;
+import org.apache.doris.nereids.types.StringType;
+import org.apache.doris.nereids.types.StructField;
+import org.apache.doris.nereids.types.StructType;
+import org.apache.doris.proto.Types.PGenericType;
+import org.apache.doris.proto.Types.PGenericType.TypeId;
+import org.apache.doris.proto.Types.PValues;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
class LiteralTest {
@Test
@@ -42,4 +56,255 @@ class LiteralTest {
Assertions.assertTrue(Literal.of(1) instanceof IntegerLiteral);
Assertions.assertTrue(Literal.of(false) instanceof BooleanLiteral);
}
+
+ @Test
+ public void testGetResultExpressionArrayInt() {
+ int num = 10;
+ Integer[] elementsArray = new Integer[num];
+ for (int i = 0; i < elementsArray.length; ++i) {
+ elementsArray[i] = i;
+ }
+ DataType arrayType = ArrayType.of(IntegerType.INSTANCE, true);
+ PGenericType.Builder childTypeBuilder = PGenericType.newBuilder();
+ childTypeBuilder.setId(TypeId.INT32);
+ PGenericType.Builder typeBuilder = PGenericType.newBuilder();
+ typeBuilder.setId(TypeId.LIST);
+
+ PValues.Builder childBuilder = PValues.newBuilder();
+ PValues.Builder resultContentBuilder = PValues.newBuilder();
+ for (int value : elementsArray) {
+ childBuilder.addInt32Value(value);
+ }
+ childBuilder.setType(childTypeBuilder.build());
+ PValues childValues = childBuilder.build();
+ resultContentBuilder.setType(typeBuilder.build());
+ resultContentBuilder.addChildElement(childValues);
+ resultContentBuilder.addChildOffset(10);
+ PValues resultContent = resultContentBuilder.build();
+ List<Literal> resultExpression
+ =
org.apache.doris.nereids.rules.expression.rules.FoldConstantRuleOnBE.getResultExpression(arrayType,
+ resultContent);
+ Assertions.assertTrue(resultExpression.get(0).isLiteral());
+ }
+
+ @Test
+ public void testGetResultExpressionArrayArrayInt() {
+ int num = 10;
+ Integer[] elementsArray = new Integer[num];
+ for (int i = 0; i < elementsArray.length; ++i) {
+ elementsArray[i] = i;
+ }
+ DataType nestedArrayType = ArrayType.of(IntegerType.INSTANCE, true);
+ DataType outArrayType = ArrayType.of(nestedArrayType, true);
+ PGenericType.Builder childTypeBuilder = PGenericType.newBuilder();
+ childTypeBuilder.setId(TypeId.INT32);
+ PGenericType.Builder typeBuilder = PGenericType.newBuilder();
+ typeBuilder.setId(TypeId.LIST);
+ PGenericType.Builder outTypeBuilder = PGenericType.newBuilder();
+ outTypeBuilder.setId(TypeId.LIST);
+
+ PValues.Builder childBuilder = PValues.newBuilder();
+ PValues.Builder nestedContentBuilder = PValues.newBuilder();
+ PValues.Builder outContentBuilder = PValues.newBuilder();
+ for (int value : elementsArray) {
+ childBuilder.addInt32Value(value);
+ }
+ childBuilder.setType(childTypeBuilder.build());
+ PValues childValues = childBuilder.build();
+ nestedContentBuilder.setType(typeBuilder.build());
+ nestedContentBuilder.addChildElement(childValues);
+ nestedContentBuilder.addChildOffset(10);
+ PValues nestedResultContent = nestedContentBuilder.build();
+ outContentBuilder.setType(outTypeBuilder.build());
+ outContentBuilder.addChildElement(nestedResultContent);
+ outContentBuilder.addChildOffset(1);
+ PValues resultContent = outContentBuilder.build();
+ List<Literal> resultExpression
+ =
org.apache.doris.nereids.rules.expression.rules.FoldConstantRuleOnBE.getResultExpression(outArrayType,
+ resultContent);
+ // [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]
+ Assertions.assertTrue(resultExpression.get(0) instanceof ArrayLiteral);
+ System.out.println(resultExpression.get(0).toString());
+ }
+
+ @Test
+ public void testGetResultExpressionArrayArrayInt2() {
+ int num = 10;
+ Integer[] elementsArray = new Integer[num];
+ for (int i = 0; i < elementsArray.length; ++i) {
+ elementsArray[i] = i;
+ }
+ DataType nestedArrayType = ArrayType.of(IntegerType.INSTANCE, true);
+ DataType outArrayType = ArrayType.of(nestedArrayType, true);
+ PGenericType.Builder childTypeBuilder = PGenericType.newBuilder();
+ childTypeBuilder.setId(TypeId.INT32);
+ PGenericType.Builder typeBuilder = PGenericType.newBuilder();
+ typeBuilder.setId(TypeId.LIST);
+ PGenericType.Builder outTypeBuilder = PGenericType.newBuilder();
+ outTypeBuilder.setId(TypeId.LIST);
+
+ PValues.Builder childBuilder1 = PValues.newBuilder();
+ PValues.Builder childBuilder2 = PValues.newBuilder();
+ PValues.Builder nestedContentBuilder = PValues.newBuilder();
+ PValues.Builder outContentBuilder = PValues.newBuilder();
+ for (int i = 0; i < elementsArray.length; i = i + 2) {
+ childBuilder1.addInt32Value(elementsArray[i]);
+ childBuilder2.addInt32Value(elementsArray[i + 1]);
+ }
+ childBuilder1.setType(childTypeBuilder.build());
+ childBuilder2.setType(childTypeBuilder.build());
+ PValues childValues1 = childBuilder1.build();
+ PValues childValues2 = childBuilder2.build();
+ nestedContentBuilder.setType(typeBuilder.build());
+ nestedContentBuilder.addChildElement(childValues1);
+ nestedContentBuilder.addChildElement(childValues2);
+ nestedContentBuilder.addChildOffset(5);
+ nestedContentBuilder.addChildOffset(10);
+ PValues nestedResultContent = nestedContentBuilder.build();
+ outContentBuilder.setType(outTypeBuilder.build());
+ outContentBuilder.addChildElement(nestedResultContent);
+ outContentBuilder.addChildOffset(2);
+ PValues resultContent = outContentBuilder.build();
+ List<Literal> resultExpression
+ =
org.apache.doris.nereids.rules.expression.rules.FoldConstantRuleOnBE.getResultExpression(outArrayType,
+ resultContent);
+ // [[0, 2, 4, 6, 8], [1, 3, 5, 7, 9]]
+ Assertions.assertTrue(resultExpression.get(0) instanceof ArrayLiteral);
+ System.out.println(resultExpression.get(0).toString());
+ }
+
+ @Test
+ public void testGetResultExpressionArrayNull() {
+ int num = 10;
+ Integer[] elementsArray = new Integer[num];
+ Boolean[] nullMap = new Boolean[num];
+ for (int i = 0; i < elementsArray.length; ++i) {
+ elementsArray[i] = i;
+ nullMap[i] = (i % 2 == 1);
+ }
+ DataType arrayType = ArrayType.of(IntegerType.INSTANCE, true);
+ PGenericType.Builder childTypeBuilder = PGenericType.newBuilder();
+ childTypeBuilder.setId(TypeId.INT32);
+ PGenericType.Builder typeBuilder = PGenericType.newBuilder();
+ typeBuilder.setId(TypeId.LIST);
+
+ PValues.Builder childBuilder = PValues.newBuilder();
+ PValues.Builder resultContentBuilder = PValues.newBuilder();
+ for (int value : elementsArray) {
+ childBuilder.addInt32Value(value);
+ }
+ childBuilder.setType(childTypeBuilder.build());
+ childBuilder.setHasNull(true);
+ childBuilder.addAllNullMap(Arrays.asList(nullMap));
+ PValues childValues = childBuilder.build();
+ resultContentBuilder.setType(typeBuilder.build());
+ resultContentBuilder.addChildElement(childValues);
+ resultContentBuilder.addChildOffset(10);
+ PValues resultContent = resultContentBuilder.build();
+ List<Literal> resultExpression
+ =
org.apache.doris.nereids.rules.expression.rules.FoldConstantRuleOnBE.getResultExpression(arrayType,
+ resultContent);
+ // [0, NULL, 2, NULL, 4, NULL, 6, NULL, 8, NULL]
+ Assertions.assertTrue(resultExpression.get(0).isLiteral());
+ System.out.println(resultExpression.get(0).toString());
+ }
+
+ @Test
+ public void testGetResultExpressionStruct() {
+ int num = 10;
+ Integer[] elementsArray = new Integer[num];
+ for (int i = 0; i < elementsArray.length; ++i) {
+ elementsArray[i] = i;
+ }
+ List<StructField> typeFields = new ArrayList<>();
+ typeFields.add(new StructField("col1", IntegerType.INSTANCE, true,
"comment1"));
+ typeFields.add(new StructField("col2", StringType.INSTANCE, true,
"comment1"));
+
+ DataType structType = new StructType(typeFields);
+ PGenericType.Builder childTypeBuilder1 = PGenericType.newBuilder();
+ childTypeBuilder1.setId(TypeId.INT32);
+ PGenericType.Builder childTypeBuilder2 = PGenericType.newBuilder();
+ childTypeBuilder2.setId(TypeId.STRING);
+ PGenericType.Builder typeBuilder = PGenericType.newBuilder();
+ typeBuilder.setId(TypeId.STRUCT);
+
+ PValues.Builder childBuilder1 = PValues.newBuilder();
+ PValues.Builder childBuilder2 = PValues.newBuilder();
+ PValues.Builder resultContentBuilder = PValues.newBuilder();
+ for (int i = 0; i < elementsArray.length; i = i + 2) {
+ childBuilder1.addInt32Value(elementsArray[i]);
+ childBuilder2.addStringValue("str" + (i + 1));
+ }
+ childBuilder1.setType(childTypeBuilder1.build());
+ childBuilder2.setType(childTypeBuilder2.build());
+ PValues childValues1 = childBuilder1.build();
+ PValues childValues2 = childBuilder2.build();
+
+ resultContentBuilder.setType(typeBuilder.build());
+ resultContentBuilder.addChildElement(childValues1);
+ resultContentBuilder.addChildElement(childValues2);
+ PValues resultContent = resultContentBuilder.build();
+ List<Literal> resultExpression
+ =
org.apache.doris.nereids.rules.expression.rules.FoldConstantRuleOnBE.getResultExpression(structType,
+ resultContent);
+ Assertions.assertTrue(resultExpression.get(0).isLiteral());
+ // STRUCT('col1':0,'col2':'str1')
+ System.out.println(resultExpression.get(0).toString());
+ }
+
+ @Test
+ public void testGetResultExpressionStructArray() {
+ int num = 10;
+ Integer[] elementsArray = new Integer[num];
+ for (int i = 0; i < elementsArray.length; ++i) {
+ elementsArray[i] = i;
+ }
+ List<StructField> typeFields = new ArrayList<>();
+ typeFields.add(new StructField("col1",
ArrayType.of(IntegerType.INSTANCE), true, "comment1"));
+ typeFields.add(new StructField("col2",
ArrayType.of(StringType.INSTANCE), true, "comment1"));
+
+ DataType structType = new StructType(typeFields);
+ PGenericType.Builder childTypeBuilder1 = PGenericType.newBuilder();
+ childTypeBuilder1.setId(TypeId.INT32);
+ PGenericType.Builder childTypeBuilder2 = PGenericType.newBuilder();
+ childTypeBuilder2.setId(TypeId.STRING);
+ PGenericType.Builder childTypeBuilder3 = PGenericType.newBuilder();
+ childTypeBuilder3.setId(TypeId.LIST);
+ PGenericType.Builder typeBuilder = PGenericType.newBuilder();
+ typeBuilder.setId(TypeId.STRUCT);
+
+ PValues.Builder childBuilder1 = PValues.newBuilder();
+ PValues.Builder childBuilder2 = PValues.newBuilder();
+ PValues.Builder arrayChildBuilder1 = PValues.newBuilder();
+ PValues.Builder arrayChildBuilder2 = PValues.newBuilder();
+ PValues.Builder resultContentBuilder = PValues.newBuilder();
+ for (int i = 0; i < elementsArray.length; i = i + 2) {
+ childBuilder1.addInt32Value(elementsArray[i]);
+ childBuilder2.addStringValue("str" + (i + 1));
+ }
+ childBuilder1.setType(childTypeBuilder1.build());
+ childBuilder2.setType(childTypeBuilder2.build());
+ arrayChildBuilder1.setType(childTypeBuilder3.build());
+ arrayChildBuilder2.setType(childTypeBuilder3.build());
+
+ PValues childValues1 = childBuilder1.build();
+ PValues childValues2 = childBuilder2.build();
+ arrayChildBuilder1.addChildElement(childValues1);
+ arrayChildBuilder1.addChildOffset(5);
+ arrayChildBuilder2.addChildElement(childValues2);
+ arrayChildBuilder2.addChildOffset(5);
+ PValues arrayChildValues1 = arrayChildBuilder1.build();
+ PValues arrayChildValues2 = arrayChildBuilder2.build();
+
+ resultContentBuilder.setType(typeBuilder.build());
+ resultContentBuilder.addChildElement(arrayChildValues1);
+ resultContentBuilder.addChildElement(arrayChildValues2);
+ PValues resultContent = resultContentBuilder.build();
+ List<Literal> resultExpression
+ =
org.apache.doris.nereids.rules.expression.rules.FoldConstantRuleOnBE.getResultExpression(structType,
+ resultContent);
+ Assertions.assertTrue(resultExpression.get(0).isLiteral());
+ // STRUCT('col1':[0, 2, 4, 6, 8],'col2':['str1', 'str3', 'str5',
'str7', 'str9'])
+ System.out.println(resultExpression.get(0).toString());
+ }
}
diff --git a/gensrc/thrift/PaloInternalService.thrift
b/gensrc/thrift/PaloInternalService.thrift
index 97bd7f5552e..b71ddfa21a3 100644
--- a/gensrc/thrift/PaloInternalService.thrift
+++ b/gensrc/thrift/PaloInternalService.thrift
@@ -548,6 +548,7 @@ struct TFoldConstantParams {
3: optional bool vec_exec
4: optional TQueryOptions query_options
5: optional Types.TUniqueId query_id
+ 6: optional bool is_nereids
}
// TransmitData
diff --git
a/regression-test/suites/nereids_rules_p0/filter_push_down/push_filter_inside_join.groovy
b/regression-test/suites/nereids_rules_p0/filter_push_down/push_filter_inside_join.groovy
index 97fdc1c0b4f..cd8ed1a25a0 100644
---
a/regression-test/suites/nereids_rules_p0/filter_push_down/push_filter_inside_join.groovy
+++
b/regression-test/suites/nereids_rules_p0/filter_push_down/push_filter_inside_join.groovy
@@ -23,6 +23,7 @@ suite("push_filter_inside_join") {
sql "SET ignore_shape_nodes='PhysicalDistribute,PhysicalProject'"
sql "SET disable_join_reorder=true"
sql 'set be_number_for_test=3'
+ sql "set enable_fold_constant_by_be=false"//plan shape will be different
// Push down > condition to cross join
qt_pushdown_cross_join"""
diff --git
a/regression-test/suites/nereids_rules_p0/filter_push_down/push_filter_through.groovy
b/regression-test/suites/nereids_rules_p0/filter_push_down/push_filter_through.groovy
index 16c06b8edd9..d084d3240da 100644
---
a/regression-test/suites/nereids_rules_p0/filter_push_down/push_filter_through.groovy
+++
b/regression-test/suites/nereids_rules_p0/filter_push_down/push_filter_through.groovy
@@ -24,6 +24,7 @@ suite("push_filter_through") {
sql 'set be_number_for_test=3'
sql "SET ignore_shape_nodes='PhysicalDistribute, PhysicalProject'"
sql "set enable_fold_nondeterministic_fn=false"
+ sql "set enable_fold_constant_by_be=false"//plan shape will be different
// push filter through alias
qt_filter_project_alias"""
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]