This is an automated email from the ASF dual-hosted git repository. morrysnow 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 1a3b70bf4a [fix](Nereids) fix ctas bugs (#24267) 1a3b70bf4a is described below commit 1a3b70bf4a5dd5382b6c3b25f579958f1c60e0a5 Author: morrySnow <101034200+morrys...@users.noreply.github.com> AuthorDate: Wed Sep 13 09:17:57 2023 +0800 [fix](Nereids) fix ctas bugs (#24267) 1. ctas should support without distribution desc 2. ctas should support column name list 3. ctas should throw exception when excution failed 4. ctas should convert null type to tinyint 5. ctas should support type conversion 6. ctas should convert first column from string to varchar --- .../antlr4/org/apache/doris/nereids/DorisParser.g4 | 4 +- .../doris/nereids/parser/LogicalPlanBuilder.java | 13 ++- .../trees/plans/commands/CreateTableCommand.java | 28 +++-- .../plans/commands/info/ColumnDefinition.java | 9 ++ .../trees/plans/commands/info/CreateTableInfo.java | 3 +- .../commands/info/DistributionDescriptor.java | 12 ++- .../org/apache/doris/nereids/types/DataType.java | 115 ++++++++++++++------- .../org/apache/doris/nereids/parser/CTASTest.java | 72 +++++++++++++ .../es/test_es_query_nereids.groovy | 4 +- 9 files changed, 209 insertions(+), 51 deletions(-) diff --git a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 index 8cd5381d02..b19f6123ed 100644 --- a/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 +++ b/fe/fe-core/src/main/antlr4/org/apache/doris/nereids/DorisParser.g4 @@ -41,12 +41,12 @@ statement TO (user=userIdentify | ROLE roleName=identifier) USING LEFT_PAREN booleanExpression RIGHT_PAREN #createRowPolicy | CREATE TABLE (IF NOT EXISTS)? name=multipartIdentifier - ((LEFT_PAREN columnDefs indexDefs? RIGHT_PAREN) | (ctasCols=identifierList)?) + ((ctasCols=identifierList)? | (LEFT_PAREN columnDefs indexDefs? RIGHT_PAREN)) (ENGINE EQ engine=identifier)? ((AGGREGATE | UNIQUE | DUPLICATE) KEY keys=identifierList)? (COMMENT STRING_LITERAL)? (PARTITION BY (RANGE | LIST) partitionKeys=identifierList LEFT_PAREN partitions=partitionsDef RIGHT_PAREN)? - DISTRIBUTED BY (HASH hashKeys=identifierList | RANDOM) BUCKETS (INTEGER_VALUE | AUTO)? + (DISTRIBUTED BY (HASH hashKeys=identifierList | RANDOM) (BUCKETS INTEGER_VALUE | AUTO)?)? (ROLLUP LEFT_PAREN rollupDefs RIGHT_PAREN)? propertyClause? (AS query)? #createTable diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java index 9231e3094c..5a50c25523 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java @@ -25,6 +25,7 @@ import org.apache.doris.analysis.UserIdentity; import org.apache.doris.catalog.AggregateType; import org.apache.doris.catalog.KeysType; import org.apache.doris.common.Config; +import org.apache.doris.common.FeConstants; import org.apache.doris.common.Pair; import org.apache.doris.nereids.DorisParser; import org.apache.doris.nereids.DorisParser.AggClauseContext; @@ -1773,9 +1774,13 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> { keysType = KeysType.UNIQUE_KEYS; } String engineName = ctx.engine != null ? ctx.engine.getText().toLowerCase() : "olap"; - DistributionDescriptor desc = new DistributionDescriptor(ctx.HASH() != null, ctx.AUTO() != null, - Integer.parseInt(ctx.INTEGER_VALUE().getText()), - ctx.HASH() != null ? visitIdentifierList(ctx.hashKeys) : null); + boolean isHash = ctx.HASH() != null || ctx.RANDOM() == null; + int bucketNum = FeConstants.default_bucket_num; + if (isHash && ctx.INTEGER_VALUE() != null) { + bucketNum = Integer.parseInt(ctx.INTEGER_VALUE().getText()); + } + DistributionDescriptor desc = new DistributionDescriptor(isHash, ctx.AUTO() != null, + bucketNum, ctx.HASH() != null ? visitIdentifierList(ctx.hashKeys) : null); Map<String, String> properties = ctx.propertyClause() != null ? visitPropertyClause(ctx.propertyClause()) : null; String partitionType = null; @@ -2501,7 +2506,7 @@ public class LogicalPlanBuilder extends DorisParserBaseVisitor<Object> { String dataType = ctx.primitiveColType().type.getText().toLowerCase(Locale.ROOT); List<String> l = Lists.newArrayList(dataType); ctx.INTEGER_VALUE().stream().map(ParseTree::getText).forEach(l::add); - return DataType.convertPrimitiveFromStrings(l); + return DataType.convertPrimitiveFromStrings(l, ctx.primitiveColType().UNSIGNED() != null); }); } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateTableCommand.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateTableCommand.java index c9f3d03f8d..6f5cf65667 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateTableCommand.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/CreateTableCommand.java @@ -21,6 +21,7 @@ import org.apache.doris.analysis.CreateTableStmt; import org.apache.doris.analysis.DropTableStmt; import org.apache.doris.analysis.TableName; import org.apache.doris.catalog.Env; +import org.apache.doris.catalog.ScalarType; import org.apache.doris.common.ErrorCode; import org.apache.doris.nereids.NereidsPlanner; import org.apache.doris.nereids.analyzer.UnboundOlapTableSink; @@ -36,6 +37,10 @@ import org.apache.doris.nereids.trees.plans.commands.info.ColumnDefinition; import org.apache.doris.nereids.trees.plans.commands.info.CreateTableInfo; import org.apache.doris.nereids.trees.plans.logical.LogicalPlan; import org.apache.doris.nereids.trees.plans.visitor.PlanVisitor; +import org.apache.doris.nereids.types.DataType; +import org.apache.doris.nereids.types.DecimalV2Type; +import org.apache.doris.nereids.types.TinyIntType; +import org.apache.doris.nereids.types.VarcharType; import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.QueryState.MysqlStateType; import org.apache.doris.qe.StmtExecutor; @@ -91,11 +96,20 @@ public class CreateTableCommand extends Command implements ForwardWithSync { if (slots.size() != ctasCols.size()) { throw new AnalysisException("ctas column size is not equal to the query's"); } - List<ColumnDefinition> columnsOfQuery = slots.stream() - .map(s -> new ColumnDefinition(s.getName(), s.getDataType(), s.nullable())) - .collect(ImmutableList.toImmutableList()); - createTableInfo.validateCreateTableAsSelect(columnsOfQuery, ctx); - + ImmutableList.Builder<ColumnDefinition> columnsOfQuery = ImmutableList.builder(); + for (int i = 0; i < slots.size(); i++) { + Slot s = slots.get(i); + DataType dataType = s.getDataType().conversion(); + if (dataType.isNullType()) { + dataType = TinyIntType.INSTANCE; + } else if (dataType.isDecimalV2Type()) { + dataType = DecimalV2Type.SYSTEM_DEFAULT; + } else if (i == 0 && dataType.isStringType()) { + dataType = VarcharType.createVarcharType(ScalarType.MAX_VARCHAR_LENGTH); + } + columnsOfQuery.add(new ColumnDefinition(s.getName(), dataType, s.nullable())); + } + createTableInfo.validateCreateTableAsSelect(columnsOfQuery.build(), ctx); CreateTableStmt createTableStmt = createTableInfo.translateToLegacyStmt(); LOG.debug("Nereids start to execute the ctas command, query id: {}, tableName: {}", ctx.queryId(), createTableInfo.getTableName()); @@ -114,6 +128,7 @@ public class CreateTableCommand extends Command implements ForwardWithSync { } } catch (Exception e) { handleFallbackFailedCtas(ctx); + throw new AnalysisException("Failed to execute CTAS Reason: " + e.getMessage(), e); } } @@ -123,7 +138,8 @@ public class CreateTableCommand extends Command implements ForwardWithSync { new TableName(Env.getCurrentEnv().getCurrentCatalog().getName(), createTableInfo.getDbName(), createTableInfo.getTableName()), true)); } catch (Exception e) { - ctx.getState().setError(ErrorCode.ERR_UNKNOWN_ERROR, "Unexpected exception: " + e.getMessage()); + // TODO: refactor it with normal error process. + ctx.getState().setError(ErrorCode.ERR_UNKNOWN_ERROR, e.getMessage()); } } diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/ColumnDefinition.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/ColumnDefinition.java index d9227a4b43..02f36817f6 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/ColumnDefinition.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/ColumnDefinition.java @@ -17,6 +17,7 @@ package org.apache.doris.nereids.trees.plans.commands.info; +import org.apache.doris.analysis.ColumnDef; import org.apache.doris.catalog.AggregateType; import org.apache.doris.catalog.Column; import org.apache.doris.catalog.KeysType; @@ -179,6 +180,14 @@ public class ColumnDefinition { } else if (type.isArrayType() && !defaultValue.isPresent()) { defaultValue = Optional.of(DefaultValue.ARRAY_EMPTY_DEFAULT_VALUE); } + if (defaultValue.isPresent() && type.toCatalogDataType().isScalarType()) { + try { + ColumnDef.validateDefaultValue(type.toCatalogDataType(), + defaultValue.get().getValue(), defaultValue.get().getDefaultValueExprDef()); + } catch (Exception e) { + throw new AnalysisException(e.getMessage(), e); + } + } } /** diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableInfo.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableInfo.java index 4ae8590c17..f2469c70e6 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableInfo.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/CreateTableInfo.java @@ -202,7 +202,7 @@ public class CreateTableInfo { keyLength += catalogType.getIndexSize(); if (keys.size() >= FeConstants.shortkey_max_column_count || keyLength > FeConstants.shortkey_maxsize_bytes) { - if (keys.size() == 0 && type.isStringLikeType()) { + if (keys.isEmpty() && type.isStringLikeType()) { keys.add(column.getName()); } break; @@ -326,6 +326,7 @@ public class CreateTableInfo { } // analyze distribution descriptor + distribution.updateCols(columns.get(0).getName()); distribution.validate(columnMap, keysType); // analyze key set. diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/DistributionDescriptor.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/DistributionDescriptor.java index f8a3fb14db..397a3f09ae 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/DistributionDescriptor.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/DistributionDescriptor.java @@ -24,10 +24,13 @@ import org.apache.doris.catalog.AggregateType; import org.apache.doris.catalog.KeysType; import org.apache.doris.nereids.exceptions.AnalysisException; +import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import org.apache.commons.collections.CollectionUtils; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; /** @@ -37,7 +40,7 @@ public class DistributionDescriptor { private final boolean isHash; private final boolean isAutoBucket; private final int bucketNum; - private final List<String> cols; + private List<String> cols; public DistributionDescriptor(boolean isHash, boolean isAutoBucket, int bucketNum, List<String> cols) { this.isHash = isHash; @@ -50,6 +53,13 @@ public class DistributionDescriptor { return isHash; } + public void updateCols(String col) { + Objects.requireNonNull(col, "col should not be null"); + if (CollectionUtils.isEmpty(cols)) { + cols = Lists.newArrayList(col); + } + } + /** * analyze distribution descriptor */ diff --git a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DataType.java b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DataType.java index 71aa83102b..2b70aa7fc9 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DataType.java +++ b/fe/fe-core/src/main/java/org/apache/doris/nereids/types/DataType.java @@ -109,120 +109,163 @@ public abstract class DataType { * @param types data type in string representation * @return data type in Nereids */ - public static DataType convertPrimitiveFromStrings(List<String> types) { + public static DataType convertPrimitiveFromStrings(List<String> types, boolean unsigned) { String type = types.get(0).toLowerCase().trim(); + DataType dataType; switch (type) { case "boolean": - return BooleanType.INSTANCE; + dataType = BooleanType.INSTANCE; + break; case "tinyint": - return TinyIntType.INSTANCE; + dataType = TinyIntType.INSTANCE; + break; case "smallint": - return SmallIntType.INSTANCE; + dataType = SmallIntType.INSTANCE; + break; case "int": - return IntegerType.INSTANCE; + dataType = IntegerType.INSTANCE; + break; case "bigint": - return BigIntType.INSTANCE; + dataType = BigIntType.INSTANCE; + break; case "largeint": - return LargeIntType.INSTANCE; + dataType = LargeIntType.INSTANCE; + break; case "float": - return FloatType.INSTANCE; + dataType = FloatType.INSTANCE; + break; case "double": - return DoubleType.INSTANCE; + dataType = DoubleType.INSTANCE; + break; case "decimal": // NOTICE, maybe convert to decimalv3, so do not truc here. switch (types.size()) { case 1: - return DecimalV2Type.CATALOG_DEFAULT; + dataType = DecimalV2Type.CATALOG_DEFAULT; + break; case 2: - return DecimalV2Type.createDecimalV2TypeWithoutTruncate(Integer.parseInt(types.get(1)), - 0); + dataType = DecimalV2Type.createDecimalV2TypeWithoutTruncate( + Integer.parseInt(types.get(1)), 0); + break; case 3: - return DecimalV2Type.createDecimalV2TypeWithoutTruncate(Integer.parseInt(types.get(1)), - Integer.parseInt(types.get(2))); + dataType = DecimalV2Type.createDecimalV2TypeWithoutTruncate( + Integer.parseInt(types.get(1)), Integer.parseInt(types.get(2))); + break; default: throw new AnalysisException("Nereids do not support type: " + type); } + break; case "decimalv3": switch (types.size()) { case 1: - return DecimalV3Type.CATALOG_DEFAULT; + dataType = DecimalV3Type.CATALOG_DEFAULT; + break; case 2: - return DecimalV3Type.createDecimalV3Type(Integer.parseInt(types.get(1))); + dataType = DecimalV3Type.createDecimalV3Type(Integer.parseInt(types.get(1))); + break; case 3: - return DecimalV3Type.createDecimalV3Type( + dataType = DecimalV3Type.createDecimalV3Type( Integer.parseInt(types.get(1)), Integer.parseInt(types.get(2))); + break; default: throw new AnalysisException("Nereids do not support type: " + type); } + break; case "text": case "string": - return StringType.INSTANCE; + dataType = StringType.INSTANCE; + break; case "varchar": switch (types.size()) { case 1: - return VarcharType.SYSTEM_DEFAULT; + dataType = VarcharType.SYSTEM_DEFAULT; + break; case 2: if (types.get(1).equals("*")) { - return VarcharType.SYSTEM_DEFAULT; + dataType = VarcharType.SYSTEM_DEFAULT; } else { - return VarcharType.createVarcharType(Integer.parseInt(types.get(1))); + dataType = VarcharType.createVarcharType(Integer.parseInt(types.get(1))); } + break; default: throw new AnalysisException("Nereids do not support type: " + type); } + break; case "character": case "char": switch (types.size()) { case 1: - return CharType.SYSTEM_DEFAULT; + dataType = CharType.SYSTEM_DEFAULT; + break; case 2: if (types.get(1).equals("*")) { - return CharType.SYSTEM_DEFAULT; + dataType = CharType.SYSTEM_DEFAULT; } else { - return CharType.createCharType(Integer.parseInt(types.get(1))); + dataType = CharType.createCharType(Integer.parseInt(types.get(1))); } + break; default: throw new AnalysisException("Nereids do not support type: " + type); } + break; case "null": case "null_type": // ScalarType.NULL.toSql() return "null_type", so support it - return NullType.INSTANCE; + dataType = NullType.INSTANCE; + break; case "date": - return DateType.INSTANCE; + dataType = DateType.INSTANCE; + break; case "datev2": - return DateV2Type.INSTANCE; + dataType = DateV2Type.INSTANCE; + break; case "time": - return TimeType.INSTANCE; + dataType = TimeType.INSTANCE; + break; case "datetime": switch (types.size()) { case 1: - return DateTimeType.INSTANCE; + dataType = DateTimeType.INSTANCE; + break; case 2: - return DateTimeV2Type.of(Integer.parseInt(types.get(1))); + dataType = DateTimeV2Type.of(Integer.parseInt(types.get(1))); + break; default: throw new AnalysisException("Nereids do not support type: " + type); } + break; case "datetimev2": switch (types.size()) { case 1: - return DateTimeV2Type.SYSTEM_DEFAULT; + dataType = DateTimeV2Type.SYSTEM_DEFAULT; + break; case 2: - return DateTimeV2Type.of(Integer.parseInt(types.get(1))); + dataType = DateTimeV2Type.of(Integer.parseInt(types.get(1))); + break; default: throw new AnalysisException("Nereids do not support type: " + type); } + break; case "hll": - return HllType.INSTANCE; + dataType = HllType.INSTANCE; + break; case "bitmap": - return BitmapType.INSTANCE; + dataType = BitmapType.INSTANCE; + break; case "quantile_state": - return QuantileStateType.INSTANCE; + dataType = QuantileStateType.INSTANCE; + break; case "json": case "jsonb": - return JsonType.INSTANCE; + dataType = JsonType.INSTANCE; + break; default: throw new AnalysisException("Nereids do not support type: " + type); } + if (unsigned) { + return dataType.promotion(); + } else { + return dataType; + } } /** diff --git a/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/CTASTest.java b/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/CTASTest.java new file mode 100644 index 0000000000..909366cb1c --- /dev/null +++ b/fe/fe-core/src/test/java/org/apache/doris/nereids/parser/CTASTest.java @@ -0,0 +1,72 @@ +// 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.parser; + +import org.apache.doris.nereids.trees.plans.commands.CreateTableCommand; +import org.apache.doris.nereids.trees.plans.logical.LogicalPlan; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class CTASTest extends ParserTestBase { + + @Test + public void testSimpleCtas() { + NereidsParser nereidsParser = new NereidsParser(); + LogicalPlan logicalPlan; + String cteSql1 = "CREATE TABLE T14 AS SELECT * FROM T10 WHERE DT > DATE_FORMAT(NOW(), 'YYYYMMDD');"; + logicalPlan = nereidsParser.parseSingle(cteSql1); + Assertions.assertTrue(logicalPlan instanceof CreateTableCommand); + } + + @Test + public void testCtasWithProperties() { + NereidsParser nereidsParser = new NereidsParser(); + LogicalPlan logicalPlan; + String cteSql1 = "CREATE TABLE T14 PROPERTIES ('REPLICATION_NUM'='1') AS SELECT * FROM T10 WHERE DT > DATE_FORMAT(NOW(), 'YYYYMMDD');"; + logicalPlan = nereidsParser.parseSingle(cteSql1); + Assertions.assertTrue(logicalPlan instanceof CreateTableCommand); + } + + @Test + public void testCtasWithColumn() { + NereidsParser nereidsParser = new NereidsParser(); + LogicalPlan logicalPlan; + String cteSql1 = "CREATE TABLE T14(ID, AGE, DT) AS SELECT * FROM T10 WHERE DT > DATE_FORMAT(NOW(), 'YYYYMMDD');"; + logicalPlan = nereidsParser.parseSingle(cteSql1); + Assertions.assertTrue(logicalPlan instanceof CreateTableCommand); + } + + @Test + public void testCtasWithDistributed() { + NereidsParser nereidsParser = new NereidsParser(); + LogicalPlan logicalPlan; + String cteSql1 = "CREATE TABLE T14 DISTRIBUTED BY RANDOM AS SELECT * FROM T10 WHERE DT > DATE_FORMAT(NOW(), 'YYYYMMDD');"; + logicalPlan = nereidsParser.parseSingle(cteSql1); + Assertions.assertTrue(logicalPlan instanceof CreateTableCommand); + } + + @Test + public void testCtasWithbuckets() { + NereidsParser nereidsParser = new NereidsParser(); + LogicalPlan logicalPlan; + String cteSql1 = "CREATE TABLE T14 DISTRIBUTED BY HASH(ID) BUCKETS 10 AS SELECT * FROM T10 WHERE DT > DATE_FORMAT(NOW(), 'YYYYMMDD');"; + logicalPlan = nereidsParser.parseSingle(cteSql1); + Assertions.assertTrue(logicalPlan instanceof CreateTableCommand); + } +} diff --git a/regression-test/suites/external_table_p0/es/test_es_query_nereids.groovy b/regression-test/suites/external_table_p0/es/test_es_query_nereids.groovy index 011bd1df5e..a292701200 100644 --- a/regression-test/suites/external_table_p0/es/test_es_query_nereids.groovy +++ b/regression-test/suites/external_table_p0/es/test_es_query_nereids.groovy @@ -30,7 +30,6 @@ suite("test_es_query_nereids", "p0,external,es,external_docker,external_docker_e sql """drop table if exists test_v1_nereids;""" sql """drop table if exists test_v2_nereids;""" sql """set enable_nereids_planner=true;""" - sql """set enable_fallback_to_original_planner=false;""" // test old create-catalog syntax for compatibility sql """ @@ -134,6 +133,9 @@ suite("test_es_query_nereids", "p0,external,es,external_docker,external_docker_e "http_ssl_enabled"="false" ); """ + + sql """set enable_fallback_to_original_planner=false;""" + // TODO(ftw): should open these annotation when nereids support es external table // order_qt_sql51 """select * from test_v2_nereids where test2='text#1'""" --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org