This is an automated email from the ASF dual-hosted git repository. jackietien pushed a commit to branch ty/TableModelGrammar in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 7ffa882b6fcb0a14870e523bdad10a4e6b7900be Author: JackieTien97 <[email protected]> AuthorDate: Thu Apr 18 10:00:49 2024 +0800 partial ok --- .../iotdb/db/protocol/session/IClientSession.java | 34 +++++- .../iotdb/db/protocol/session/SessionManager.java | 3 +- .../iotdb/db/queryengine/common/SessionInfo.java | 37 +++++- .../queryengine/plan/analyze/PredicateUtils.java | 11 ++ .../plan/planner/LocalExecutionPlanner.java | 14 ++- .../plan/planner/TableOperatorGenerator.java | 135 +++++++++++++++------ .../plan/planner/plan/TableModelTimePredicate.java | 65 ++++++++++ .../plan/relational/planner/node/LimitNode.java | 4 + .../plan/relational/planner/node/OffsetNode.java | 4 + .../plan/relational/analyzer/AnalyzerTest.java | 5 +- 10 files changed, 265 insertions(+), 47 deletions(-) diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/session/IClientSession.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/session/IClientSession.java index ff3040a34ec..6ef98c4308a 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/session/IClientSession.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/session/IClientSession.java @@ -22,9 +22,13 @@ package org.apache.iotdb.db.protocol.session; import org.apache.iotdb.commons.conf.IoTDBConstant.ClientVersion; import org.apache.iotdb.service.rpc.thrift.TSConnectionInfo; import org.apache.iotdb.service.rpc.thrift.TSConnectionType; +import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils; import javax.annotation.Nullable; +import java.io.DataOutputStream; +import java.io.IOException; +import java.nio.ByteBuffer; import java.time.ZoneId; import java.util.Set; import java.util.TimeZone; @@ -159,7 +163,33 @@ public abstract class IClientSession { } public enum SqlDialect { - TREE, - TABLE + TREE((byte) 0), + TABLE((byte) 1); + + private final byte dialect; + + SqlDialect(byte dialect) { + this.dialect = dialect; + } + + public byte getDialect() { + return dialect; + } + + public void serialize(DataOutputStream stream) throws IOException { + ReadWriteIOUtils.write(dialect, stream); + } + + public static SqlDialect deserializeFrom(ByteBuffer buffer) { + byte b = ReadWriteIOUtils.readByte(buffer); + switch (b) { + case 0: + return TREE; + case 1: + return TABLE; + default: + throw new IllegalArgumentException(String.format("Unknown sql dialect: %s", b)); + } + } } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/session/SessionManager.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/session/SessionManager.java index a3f2c4358ce..6f13111731d 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/session/SessionManager.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/protocol/session/SessionManager.java @@ -378,7 +378,8 @@ public class SessionManager implements SessionManagerMBean { session.getUsername(), session.getZoneId(), session.getClientVersion(), - session.getDatabaseName()); + session.getDatabaseName(), + session.getSqlDialect()); } @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/SessionInfo.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/SessionInfo.java index 958d39abafa..2cc9aed732a 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/SessionInfo.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/SessionInfo.java @@ -20,7 +20,7 @@ package org.apache.iotdb.db.queryengine.common; import org.apache.iotdb.commons.conf.IoTDBConstant.ClientVersion; -import org.apache.iotdb.commons.utils.TestOnly; +import org.apache.iotdb.db.protocol.session.IClientSession; import org.apache.iotdb.db.queryengine.plan.relational.security.Identity; import org.apache.iotdb.tsfile.utils.ReadWriteIOUtils; @@ -40,6 +40,8 @@ public class SessionInfo { @Nullable private final String databaseName; + private final IClientSession.SqlDialect sqlDialect; + private ClientVersion version = ClientVersion.V_1_0; public SessionInfo(long sessionId, String userName, ZoneId zoneId) { @@ -47,12 +49,16 @@ public class SessionInfo { this.userName = userName; this.zoneId = zoneId; this.databaseName = null; + this.sqlDialect = IClientSession.SqlDialect.TREE; } - @TestOnly public SessionInfo( - long sessionId, String userName, ZoneId zoneId, @Nullable String databaseName) { - this(sessionId, userName, zoneId, ClientVersion.V_1_0, databaseName); + long sessionId, + String userName, + ZoneId zoneId, + @Nullable String databaseName, + IClientSession.SqlDialect sqlDialect) { + this(sessionId, userName, zoneId, ClientVersion.V_1_0, databaseName, sqlDialect); } public SessionInfo( @@ -60,12 +66,14 @@ public class SessionInfo { String userName, ZoneId zoneId, ClientVersion version, - @Nullable String databaseName) { + @Nullable String databaseName, + IClientSession.SqlDialect sqlDialect) { this.sessionId = sessionId; this.userName = userName; this.zoneId = zoneId; this.version = version; this.databaseName = databaseName; + this.sqlDialect = sqlDialect; } public long getSessionId() { @@ -92,16 +100,33 @@ public class SessionInfo { return Optional.ofNullable(databaseName); } + public IClientSession.SqlDialect getSqlDialect() { + return sqlDialect; + } + public static SessionInfo deserializeFrom(ByteBuffer buffer) { long sessionId = ReadWriteIOUtils.readLong(buffer); String userName = ReadWriteIOUtils.readString(buffer); ZoneId zoneId = ZoneId.of(Objects.requireNonNull(ReadWriteIOUtils.readString(buffer))); - return new SessionInfo(sessionId, userName, zoneId); + boolean hasDatabaseName = ReadWriteIOUtils.readBool(buffer); + String databaseName = null; + if (hasDatabaseName) { + databaseName = ReadWriteIOUtils.readString(buffer); + } + IClientSession.SqlDialect sqlDialect1 = IClientSession.SqlDialect.deserializeFrom(buffer); + return new SessionInfo(sessionId, userName, zoneId, databaseName, sqlDialect1); } public void serialize(DataOutputStream stream) throws IOException { ReadWriteIOUtils.write(sessionId, stream); ReadWriteIOUtils.write(userName, stream); ReadWriteIOUtils.write(zoneId.getId(), stream); + if (databaseName == null) { + ReadWriteIOUtils.write((byte) 0, stream); + } else { + ReadWriteIOUtils.write((byte) 1, stream); + ReadWriteIOUtils.write(databaseName, stream); + } + sqlDialect.serialize(stream); } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/PredicateUtils.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/PredicateUtils.java index dc2d8653b2c..872f80217f9 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/PredicateUtils.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/PredicateUtils.java @@ -279,6 +279,17 @@ public class PredicateUtils { return predicate.accept(new ConvertPredicateToTimeFilterVisitor(), null); } + public static Filter convertPredicateToTimeFilter( + org.apache.iotdb.db.relational.sql.tree.Expression predicate) { + if (predicate == null) { + return null; + } + return predicate.accept( + new org.apache.iotdb.db.queryengine.plan.relational.analyzer.predicate + .ConvertPredicateToTimeFilterVisitor(), + null); + } + public static Filter convertPredicateToFilter( Expression predicate, List<String> allMeasurements, diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LocalExecutionPlanner.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LocalExecutionPlanner.java index 6acd4e1b716..2894ac2b432 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LocalExecutionPlanner.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/LocalExecutionPlanner.java @@ -21,6 +21,7 @@ package org.apache.iotdb.db.queryengine.plan.planner; import org.apache.iotdb.commons.path.PartialPath; import org.apache.iotdb.db.conf.IoTDBConfig; import org.apache.iotdb.db.conf.IoTDBDescriptor; +import org.apache.iotdb.db.protocol.session.IClientSession; import org.apache.iotdb.db.queryengine.exception.MemoryNotEnoughException; import org.apache.iotdb.db.queryengine.execution.driver.DataDriverContext; import org.apache.iotdb.db.queryengine.execution.fragment.DataNodeQueryContext; @@ -80,7 +81,18 @@ public class LocalExecutionPlanner { // Generate pipelines, return the last pipeline data structure // TODO Replace operator with operatorFactory to build multiple driver for one pipeline - Operator root = plan.accept(new OperatorTreeGenerator(), context); + Operator root; + IClientSession.SqlDialect sqlDialect = instanceContext.getSessionInfo().getSqlDialect(); + switch (sqlDialect) { + case TREE: + root = plan.accept(new OperatorTreeGenerator(), context); + break; + case TABLE: + root = plan.accept(new TableOperatorGenerator(), context); + break; + default: + throw new IllegalArgumentException(String.format("Unknown sql dialect: %s", sqlDialect)); + } // check whether current free memory is enough to execute current query long estimatedMemorySize = checkMemory(root, instanceContext.getStateMachine()); diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java index 273e949b37f..bd699c18b5e 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/TableOperatorGenerator.java @@ -24,10 +24,13 @@ import org.apache.iotdb.db.queryengine.execution.driver.DataDriverContext; import org.apache.iotdb.db.queryengine.execution.operator.Operator; import org.apache.iotdb.db.queryengine.execution.operator.OperatorContext; import org.apache.iotdb.db.queryengine.execution.operator.process.FilterAndProjectOperator; +import org.apache.iotdb.db.queryengine.execution.operator.process.LimitOperator; +import org.apache.iotdb.db.queryengine.execution.operator.process.OffsetOperator; import org.apache.iotdb.db.queryengine.execution.operator.source.AlignedSeriesScanOperator; import org.apache.iotdb.db.queryengine.execution.operator.source.relational.TableScanOperator; import org.apache.iotdb.db.queryengine.execution.relational.ColumnTransformerBuilder; import org.apache.iotdb.db.queryengine.plan.analyze.PredicateUtils; +import org.apache.iotdb.db.queryengine.plan.analyze.TypeProvider; import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNode; import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanNodeId; import org.apache.iotdb.db.queryengine.plan.planner.plan.node.PlanVisitor; @@ -63,6 +66,8 @@ import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; import static java.util.Objects.requireNonNull; import static org.apache.iotdb.db.queryengine.execution.operator.source.relational.TableScanOperator.constructAlignedPath; @@ -170,8 +175,8 @@ public class TableOperatorGenerator extends PlanVisitor<Operator, LocalExecution if (!predicateCanPushIntoScan) { - return constructFilterOperator( - pushDownPredicate, + return constructFilterAndProjectOperator( + Optional.of(pushDownPredicate), tableScanOperator, node.getOutputSymbols().stream() .map(Symbol::toSymbolReference) @@ -221,11 +226,24 @@ public class TableOperatorGenerator extends PlanVisitor<Operator, LocalExecution @Override public Operator visitFilter(FilterNode node, LocalExecutionPlanContext context) { - return super.visitFilter(node, context); + TypeProvider typeProvider = context.getTypeProvider(); + Optional<Expression> predicate = Optional.of(node.getPredicate()); + Operator inputOperator = node.getChild().accept(this, context); + List<TSDataType> inputDataTypes = getInputColumnTypes(node, typeProvider); + Map<Symbol, List<InputLocation>> inputLocations = makeLayout(node.getChildren()); + + return constructFilterAndProjectOperator( + predicate, + inputOperator, + node.getOutputSymbols().stream().map(Symbol::toSymbolReference).toArray(Expression[]::new), + inputDataTypes, + inputLocations, + node.getPlanNodeId(), + context); } - private Operator constructFilterOperator( - Expression predicate, + private Operator constructFilterAndProjectOperator( + Optional<Expression> predicate, Operator inputOperator, Expression[] projectExpressions, List<TSDataType> inputDataTypes, @@ -238,36 +256,41 @@ public class TableOperatorGenerator extends PlanVisitor<Operator, LocalExecution // records LeafColumnTransformer of filter List<LeafColumnTransformer> filterLeafColumnTransformerList = new ArrayList<>(); - // records common ColumnTransformer between filter and project expressions - List<ColumnTransformer> commonTransformerList = new ArrayList<>(); - - // records LeafColumnTransformer of project expressions - List<LeafColumnTransformer> projectLeafColumnTransformerList = new ArrayList<>(); - // records subexpression -> ColumnTransformer for filter Map<Expression, ColumnTransformer> filterExpressionColumnTransformerMap = new HashMap<>(); ColumnTransformerBuilder visitor = new ColumnTransformerBuilder(); - ColumnTransformerBuilder.Context filterColumnTransformerContext = - new ColumnTransformerBuilder.Context( - context.getDriverContext().getFragmentInstanceContext().getSessionInfo(), - filterLeafColumnTransformerList, - inputLocations, - filterExpressionColumnTransformerMap, - ImmutableMap.of(), - ImmutableList.of(), - ImmutableList.of(), - 0, - context.getTypeProvider()); - ColumnTransformer filterOutputTransformer = - visitor.process(predicate, filterColumnTransformerContext); + predicate + .map( + p -> { + ColumnTransformerBuilder.Context filterColumnTransformerContext = + new ColumnTransformerBuilder.Context( + context.getDriverContext().getFragmentInstanceContext().getSessionInfo(), + filterLeafColumnTransformerList, + inputLocations, + filterExpressionColumnTransformerMap, + ImmutableMap.of(), + ImmutableList.of(), + ImmutableList.of(), + 0, + context.getTypeProvider()); + + return visitor.process(p, filterColumnTransformerContext); + }) + .orElse(null); + + // records LeafColumnTransformer of project expressions + List<LeafColumnTransformer> projectLeafColumnTransformerList = new ArrayList<>(); List<ColumnTransformer> projectOutputTransformerList = new ArrayList<>(); Map<Expression, ColumnTransformer> projectExpressionColumnTransformerMap = new HashMap<>(); + // records common ColumnTransformer between filter and project expressions + List<ColumnTransformer> commonTransformerList = new ArrayList<>(); + ColumnTransformerBuilder.Context projectColumnTransformerContext = new ColumnTransformerBuilder.Context( context.getDriverContext().getFragmentInstanceContext().getSessionInfo(), @@ -304,33 +327,73 @@ public class TableOperatorGenerator extends PlanVisitor<Operator, LocalExecution projectLeafColumnTransformerList, projectOutputTransformerList, false, - true); + predicate.isPresent()); } @Override public Operator visitProject(ProjectNode node, LocalExecutionPlanContext context) { + TypeProvider typeProvider = context.getTypeProvider(); + Optional<Expression> predicate; + Operator inputOperator; + List<TSDataType> inputDataTypes; + Map<Symbol, List<InputLocation>> inputLocations; if (node.getChild() instanceof FilterNode) { FilterNode filterNode = (FilterNode) node.getChild(); - return constructFilterOperator( - filterNode.getPredicate(), - filterNode.getChild().accept(this, context), - node.getAssignments().getExpressions().toArray(new Expression[0]), - tableScanOperator.getResultDataTypes(), - makeLayout(Collections.singletonList(filterNode.getChild())), - node.getPlanNodeId(), - context); + predicate = Optional.of(filterNode.getPredicate()); + inputOperator = filterNode.getChild().accept(this, context); + inputDataTypes = getInputColumnTypes(filterNode, typeProvider); + inputLocations = makeLayout(filterNode.getChildren()); + } else { + predicate = Optional.empty(); + inputOperator = node.getChild().accept(this, context); + inputDataTypes = getInputColumnTypes(node, typeProvider); + inputLocations = makeLayout(node.getChildren()); } - return super.visitProject(node, context); + + return constructFilterAndProjectOperator( + predicate, + inputOperator, + node.getAssignments().getExpressions().toArray(new Expression[0]), + inputDataTypes, + inputLocations, + node.getPlanNodeId(), + context); + } + + private List<TSDataType> getInputColumnTypes(PlanNode node, TypeProvider typeProvider) { + return node.getChildren().stream() + .map(PlanNode::getOutputSymbols) + .flatMap(List::stream) + .map(s -> getTSDataType(typeProvider.get(s))) + .collect(Collectors.toList()); } @Override public Operator visitLimit(LimitNode node, LocalExecutionPlanContext context) { - return super.visitLimit(node, context); + Operator child = node.getChild().accept(this, context); + OperatorContext operatorContext = + context + .getDriverContext() + .addOperatorContext( + context.getNextOperatorId(), + node.getPlanNodeId(), + LimitOperator.class.getSimpleName()); + + return new LimitOperator(operatorContext, node.getCount(), child); } @Override public Operator visitOffset(OffsetNode node, LocalExecutionPlanContext context) { - return super.visitOffset(node, context); + Operator child = node.getChild().accept(this, context); + OperatorContext operatorContext = + context + .getDriverContext() + .addOperatorContext( + context.getNextOperatorId(), + node.getPlanNodeId(), + OffsetOperator.class.getSimpleName()); + + return new OffsetOperator(operatorContext, node.getCount(), child); } @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/TableModelTimePredicate.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/TableModelTimePredicate.java new file mode 100644 index 00000000000..5a19fb08a71 --- /dev/null +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/planner/plan/TableModelTimePredicate.java @@ -0,0 +1,65 @@ +/* + * 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.iotdb.db.queryengine.plan.planner.plan; + +import org.apache.iotdb.db.queryengine.plan.analyze.PredicateUtils; +import org.apache.iotdb.db.relational.sql.tree.Expression; +import org.apache.iotdb.tsfile.read.filter.basic.Filter; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.Objects; + +public class TableModelTimePredicate implements TimePredicate { + + private final Expression timePredicate; + + public TableModelTimePredicate(Expression timePredicate) { + this.timePredicate = timePredicate; + } + + @Override + public void serialize(DataOutputStream stream) throws IOException { + throw new UnsupportedEncodingException(); + } + + @Override + public Filter convertPredicateToTimeFilter() { + return PredicateUtils.convertPredicateToTimeFilter(timePredicate); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + TableModelTimePredicate that = (TableModelTimePredicate) o; + return Objects.equals(timePredicate, that.timePredicate); + } + + @Override + public int hashCode() { + return Objects.hash(timePredicate); + } +} diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/LimitNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/LimitNode.java index 17481074932..dbc82fcb5b9 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/LimitNode.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/LimitNode.java @@ -46,4 +46,8 @@ public class LimitNode extends SingleChildProcessNode { public List<Symbol> getOutputSymbols() { return child.getOutputSymbols(); } + + public long getCount() { + return count; + } } diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/OffsetNode.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/OffsetNode.java index 69ac2517e83..b1fa2db71ee 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/OffsetNode.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/planner/node/OffsetNode.java @@ -38,4 +38,8 @@ public class OffsetNode extends SingleChildProcessNode { public List<Symbol> getOutputSymbols() { return child.getOutputSymbols(); } + + public long getCount() { + return count; + } } diff --git a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java index 8bb2cecd3bc..583f1ec64ca 100644 --- a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java +++ b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/AnalyzerTest.java @@ -20,6 +20,7 @@ package org.apache.iotdb.db.queryengine.plan.relational.analyzer; import org.apache.iotdb.commons.exception.IoTDBException; +import org.apache.iotdb.db.protocol.session.IClientSession; import org.apache.iotdb.db.queryengine.common.MPPQueryContext; import org.apache.iotdb.db.queryengine.common.QueryId; import org.apache.iotdb.db.queryengine.common.SessionInfo; @@ -154,7 +155,9 @@ public class AnalyzerTest { private Analysis analyzeSQL(String sql, Metadata metadata) { try { Statement statement = sqlParser.createStatement(sql); - SessionInfo session = new SessionInfo(0, "test", ZoneId.systemDefault(), "testdb"); + SessionInfo session = + new SessionInfo( + 0, "test", ZoneId.systemDefault(), "testdb", IClientSession.SqlDialect.TABLE); StatementAnalyzerFactory statementAnalyzerFactory = new StatementAnalyzerFactory(metadata, sqlParser, nopAccessControl);
