未验证 提交 f0597006 编写于 作者: X Xiangwei Wei 提交者: GitHub

[IOTDB-1396] Restructure logical query operator (#3267)

* antlr grammar for arithmetic operators and nested operators

* expressions for complex operations in select clauses

* new SelectOperator

* rename

* refactor Planner and LogicalGenerator

* refactor Planner and LogicalGenerator

* add comments for todos

* refactor concatSelect() in ConcatPathOptimizer

* refactor removeWildcards() in ConcatPathOptimizer and fix build errors

* fix antlr

* fix aggregation tests

* fix checkAggregation

* fix IoTDBUDFManagementIT

* fix udf tests

* fix some as tests

* fix aggregation * query tests

* fix RemoveNotOptimizer for where not contain query

* fix align by device tests

* fix tests for align by device with as clauses

* fix index related tests

* fix queryNonexistentSeries

* remove a dependency in pom.xml

* fix ClusterPhysicalGenerator

* fix aggregation with alias tests

* fix last query with alias tests & remove ts alias

* Restructure query operator

* Reimplement logical checker

* add check for last query

* Fix sonar codesmells

* Delete select and from operatortype

* Delete root operator

* implement base construct method

* modify access control

* Remove the Inheritance Relationship of FilterOperator

* Modify some detail

* fix conflict

* remove filter from operator type

* Fix codesmells

* remove group by level clause component
Co-authored-by: NSteveYurongSu <steveyurongsu@outlook.com>
上级 dc3fc32c
......@@ -23,10 +23,9 @@ import org.apache.iotdb.cluster.common.TestUtils;
import org.apache.iotdb.db.exception.metadata.IllegalPathException;
import org.apache.iotdb.db.exception.query.QueryProcessException;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.constant.SQLConstant;
import org.apache.iotdb.db.qp.logical.crud.FromOperator;
import org.apache.iotdb.db.qp.logical.crud.FromComponent;
import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
import org.apache.iotdb.db.qp.logical.crud.SelectOperator;
import org.apache.iotdb.db.qp.logical.crud.SelectComponent;
import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
import org.apache.iotdb.db.query.expression.ResultColumn;
import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
......@@ -53,20 +52,19 @@ public class ClusterPhysicalGeneratorTest extends BaseQueryTest {
@Test
public void test() throws QueryProcessException, IllegalPathException {
QueryOperator operator = new QueryOperator(SQLConstant.TOK_QUERY);
QueryOperator operator = new QueryOperator();
SelectOperator selectOperator =
new SelectOperator(SQLConstant.TOK_SELECT, ZoneId.systemDefault());
SelectComponent selectComponent = new SelectComponent(ZoneId.systemDefault());
List<ResultColumn> resultColumns = new ArrayList<>();
for (PartialPath partialPath : pathList) {
resultColumns.add(new ResultColumn(new TimeSeriesOperand(partialPath)));
}
selectOperator.setResultColumns(resultColumns);
FromOperator fromOperator = new FromOperator(SQLConstant.TOK_FROM);
fromOperator.addPrefixTablePath(new PartialPath(TestUtils.getTestSg(0)));
selectComponent.setResultColumns(resultColumns);
FromComponent fromComponent = new FromComponent();
fromComponent.addPrefixTablePath(new PartialPath(TestUtils.getTestSg(0)));
operator.setSelectOperator(selectOperator);
operator.setFromOperator(fromOperator);
operator.setSelectComponent(selectComponent);
operator.setFromComponent(fromComponent);
RawDataQueryPlan plan =
(RawDataQueryPlan) physicalGenerator.transformToPhysicalPlan(operator, 1024);
......
......@@ -124,8 +124,6 @@ public class AuthorityChecker {
case DROP_INDEX:
return PrivilegeType.DELETE_TIMESERIES.ordinal();
case QUERY:
case SELECT:
case FILTER:
case GROUPBYTIME:
case QUERY_INDEX:
case AGGREGATION:
......
......@@ -19,7 +19,8 @@
package org.apache.iotdb.db.exception.query;
import org.apache.iotdb.db.exception.IoTDBException;
import org.apache.iotdb.db.qp.constant.SQLConstant;
import org.apache.iotdb.db.qp.constant.FilterConstant;
import org.apache.iotdb.db.qp.constant.FilterConstant.FilterType;
import org.apache.iotdb.rpc.TSStatusCode;
/** This exception is thrown while meeting error in optimizing logical operator. */
......@@ -31,11 +32,11 @@ public class LogicalOptimizeException extends LogicalOperatorException {
super(message, TSStatusCode.LOGICAL_OPTIMIZE_ERROR.getStatusCode());
}
public LogicalOptimizeException(String filterOperator, int tokenInt) {
public LogicalOptimizeException(String filterOperator, FilterType filterType) {
super(
String.format(
"Unknown token in [%s]: [%s], [%s].",
filterOperator, tokenInt, SQLConstant.tokenNames.get(tokenInt)),
filterOperator, filterType, FilterConstant.filterNames.get(filterType)),
TSStatusCode.LOGICAL_OPTIMIZE_ERROR.getStatusCode());
}
......
......@@ -26,6 +26,7 @@ import org.apache.iotdb.db.exception.query.QueryProcessException;
import org.apache.iotdb.db.qp.logical.Operator;
import org.apache.iotdb.db.qp.logical.crud.FilterOperator;
import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
import org.apache.iotdb.db.qp.logical.crud.WhereComponent;
import org.apache.iotdb.db.qp.physical.PhysicalPlan;
import org.apache.iotdb.db.qp.strategy.LogicalChecker;
import org.apache.iotdb.db.qp.strategy.LogicalGenerator;
......@@ -115,14 +116,15 @@ public class Planner {
throws LogicalOperatorException, PathNumOverLimitException {
root = (QueryOperator) new ConcatPathOptimizer().transform(root, fetchSize);
FilterOperator filter = root.getFilterOperator();
if (filter == null) {
WhereComponent whereComponent = root.getWhereComponent();
if (whereComponent == null) {
return root;
}
FilterOperator filter = whereComponent.getFilterOperator();
filter = new RemoveNotOptimizer().optimize(filter);
filter = new DnfFilterOptimizer().optimize(filter);
filter = new MergeSingleFilterOptimizer().optimize(filter);
root.setFilterOperator(filter);
whereComponent.setFilterOperator(filter);
return root;
}
......
/*
* 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.qp.constant;
import org.apache.iotdb.db.qp.sql.SqlBaseLexer;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
public class FilterConstant {
public static final Map<Integer, FilterType> lexerToFilterType = new HashMap<>();
public static final Map<FilterType, String> filterSymbol = new EnumMap<>(FilterType.class);
public static final Map<FilterType, String> filterNames = new EnumMap<>(FilterType.class);
public static final Map<FilterType, FilterType> filterReverseWords =
new EnumMap<>(FilterType.class);
public enum FilterType {
KW_AND,
KW_OR,
KW_NOT,
EQUAL,
NOTEQUAL,
LESSTHANOREQUALTO,
LESSTHAN,
GREATERTHANOREQUALTO,
GREATERTHAN,
IN
}
static {
lexerToFilterType.put(SqlBaseLexer.OPERATOR_EQ, FilterType.EQUAL);
lexerToFilterType.put(SqlBaseLexer.OPERATOR_NEQ, FilterType.NOTEQUAL);
lexerToFilterType.put(SqlBaseLexer.OPERATOR_LTE, FilterType.LESSTHANOREQUALTO);
lexerToFilterType.put(SqlBaseLexer.OPERATOR_LT, FilterType.LESSTHAN);
lexerToFilterType.put(SqlBaseLexer.OPERATOR_GTE, FilterType.GREATERTHANOREQUALTO);
lexerToFilterType.put(SqlBaseLexer.OPERATOR_GT, FilterType.GREATERTHAN);
lexerToFilterType.put(SqlBaseLexer.OPERATOR_IN, FilterType.IN);
}
static {
filterSymbol.put(FilterType.KW_AND, "&");
filterSymbol.put(FilterType.KW_OR, "|");
filterSymbol.put(FilterType.KW_NOT, "!");
filterSymbol.put(FilterType.EQUAL, "=");
filterSymbol.put(FilterType.NOTEQUAL, "<>");
filterSymbol.put(FilterType.LESSTHANOREQUALTO, "<=");
filterSymbol.put(FilterType.LESSTHAN, "<");
filterSymbol.put(FilterType.GREATERTHANOREQUALTO, ">=");
filterSymbol.put(FilterType.GREATERTHAN, ">");
}
static {
filterNames.put(FilterType.KW_AND, "and");
filterNames.put(FilterType.KW_OR, "or");
filterNames.put(FilterType.KW_NOT, "not");
filterNames.put(FilterType.EQUAL, "equal");
filterNames.put(FilterType.NOTEQUAL, "not_equal");
filterNames.put(FilterType.LESSTHANOREQUALTO, "lessthan_or_equalto");
filterNames.put(FilterType.LESSTHAN, "lessthan");
filterNames.put(FilterType.GREATERTHANOREQUALTO, "greaterthan_or_equalto");
filterNames.put(FilterType.GREATERTHAN, "greaterthan");
filterNames.put(FilterType.IN, "in");
}
static {
filterReverseWords.put(FilterType.KW_AND, FilterType.KW_OR);
filterReverseWords.put(FilterType.KW_OR, FilterType.KW_AND);
filterReverseWords.put(FilterType.EQUAL, FilterType.NOTEQUAL);
filterReverseWords.put(FilterType.NOTEQUAL, FilterType.EQUAL);
filterReverseWords.put(FilterType.LESSTHAN, FilterType.GREATERTHANOREQUALTO);
filterReverseWords.put(FilterType.GREATERTHANOREQUALTO, FilterType.LESSTHAN);
filterReverseWords.put(FilterType.LESSTHANOREQUALTO, FilterType.GREATERTHAN);
filterReverseWords.put(FilterType.GREATERTHAN, FilterType.LESSTHANOREQUALTO);
}
}
......@@ -19,7 +19,6 @@
package org.apache.iotdb.db.qp.constant;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.sql.SqlBaseLexer;
import java.util.Arrays;
import java.util.HashMap;
......@@ -35,8 +34,8 @@ public class SQLConstant {
// forbidding instantiation
}
private static final String[] SINGLE_ROOT_ARRAY = new String[1];
private static final String[] SINGLE_TIME_ARRAY = new String[1];
private static final String[] SINGLE_ROOT_ARRAY = {"root"};
private static final String[] SINGLE_TIME_ARRAY = {"time"};
public static final PartialPath TIME_PATH = new PartialPath(SINGLE_TIME_ARRAY);
public static final String ALIGNBY_DEVICE_COLUMN_NAME = "Device";
public static final String RESERVED_TIME = "time";
......@@ -88,20 +87,6 @@ public class SQLConstant {
SUM,
AVG));
public static final int KW_AND = 1;
public static final int KW_OR = 2;
public static final int KW_NOT = 3;
public static final int EQUAL = SqlBaseLexer.OPERATOR_EQ;
public static final int NOTEQUAL = SqlBaseLexer.OPERATOR_NEQ;
public static final int LESSTHANOREQUALTO = SqlBaseLexer.OPERATOR_LTE;
public static final int LESSTHAN = SqlBaseLexer.OPERATOR_LT;
public static final int GREATERTHANOREQUALTO = SqlBaseLexer.OPERATOR_GTE;
public static final int GREATERTHAN = SqlBaseLexer.OPERATOR_GT;
public static final int IN = SqlBaseLexer.OPERATOR_IN;
public static final int TOK_SELECT = 21;
public static final int TOK_FROM = 22;
public static final int TOK_WHERE = 23;
public static final int TOK_INSERT = 24;
public static final int TOK_DELETE = 25;
......@@ -188,12 +173,9 @@ public class SQLConstant {
public static final int TOK_TRIGGER_START = 102;
public static final int TOK_TRIGGER_STOP = 103;
public static final int TOK_SHOW_TRIGGERS = 104;
public static final int TOK_LOCK_INFO = 105;
public static final Map<Integer, String> tokenSymbol = new HashMap<>();
public static final Map<Integer, String> tokenNames = new HashMap<>();
public static final Map<Integer, Integer> reverseWords = new HashMap<>();
public static String[] getSingleRootArray() {
return SINGLE_ROOT_ARRAY;
......@@ -204,33 +186,6 @@ public class SQLConstant {
}
static {
SINGLE_ROOT_ARRAY[0] = ROOT;
SINGLE_TIME_ARRAY[0] = RESERVED_TIME;
tokenSymbol.put(KW_AND, "&");
tokenSymbol.put(KW_OR, "|");
tokenSymbol.put(KW_NOT, "!");
tokenSymbol.put(EQUAL, "=");
tokenSymbol.put(NOTEQUAL, "<>");
tokenSymbol.put(LESSTHANOREQUALTO, "<=");
tokenSymbol.put(LESSTHAN, "<");
tokenSymbol.put(GREATERTHANOREQUALTO, ">=");
tokenSymbol.put(GREATERTHAN, ">");
}
static {
tokenNames.put(KW_AND, "and");
tokenNames.put(KW_OR, "or");
tokenNames.put(KW_NOT, "not");
tokenNames.put(EQUAL, "equal");
tokenNames.put(NOTEQUAL, "not_equal");
tokenNames.put(LESSTHANOREQUALTO, "lessthan_or_equalto");
tokenNames.put(LESSTHAN, "lessthan");
tokenNames.put(GREATERTHANOREQUALTO, "greaterthan_or_equalto");
tokenNames.put(GREATERTHAN, "greaterthan");
tokenNames.put(IN, "in");
tokenNames.put(TOK_SELECT, "TOK_SELECT");
tokenNames.put(TOK_FROM, "TOK_FROM");
tokenNames.put(TOK_WHERE, "TOK_WHERE");
tokenNames.put(TOK_INSERT, "TOK_INSERT");
tokenNames.put(TOK_DELETE, "TOK_DELETE");
......@@ -286,17 +241,6 @@ public class SQLConstant {
tokenNames.put(TOK_SHOW_TRIGGERS, "TOK_SHOW_TRIGGERS");
}
static {
reverseWords.put(KW_AND, KW_OR);
reverseWords.put(KW_OR, KW_AND);
reverseWords.put(EQUAL, NOTEQUAL);
reverseWords.put(NOTEQUAL, EQUAL);
reverseWords.put(LESSTHAN, GREATERTHANOREQUALTO);
reverseWords.put(GREATERTHANOREQUALTO, LESSTHAN);
reverseWords.put(LESSTHANOREQUALTO, GREATERTHAN);
reverseWords.put(GREATERTHAN, LESSTHANOREQUALTO);
}
public static boolean isReservedPath(PartialPath pathStr) {
return pathStr.equals(TIME_PATH);
}
......
......@@ -25,8 +25,6 @@ public abstract class Operator {
// operator type in int format
protected int tokenIntType;
// operator type in String format
protected String tokenName;
// flag of "explain"
protected boolean isDebug;
......@@ -34,7 +32,6 @@ public abstract class Operator {
protected Operator(int tokenIntType) {
this.tokenIntType = tokenIntType;
this.tokenName = SQLConstant.tokenNames.get(tokenIntType);
this.isDebug = false;
}
......@@ -50,10 +47,6 @@ public abstract class Operator {
return tokenIntType;
}
public String getTokenName() {
return tokenName;
}
public void setOperatorType(OperatorType operatorType) {
this.operatorType = operatorType;
}
......@@ -68,25 +61,19 @@ public abstract class Operator {
@Override
public String toString() {
return tokenName;
return SQLConstant.tokenNames.get(tokenIntType);
}
/** If you want to add new OperatorType, you must add it in the last. */
public enum OperatorType {
FILTER,
GROUPBYTIME,
SELECT,
NULL,
INSERT,
BATCHINSERT,
DELETE,
BASIC_FUNC,
IN,
QUERY,
AGGREGATION,
AUTHOR,
FROM,
FUNC,
LOADDATA,
METADATA,
FILL,
......
/*
* 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.qp.logical.crud;
import org.apache.iotdb.db.exception.query.LogicalOperatorException;
import org.apache.iotdb.db.query.expression.Expression;
import org.apache.iotdb.db.query.expression.ResultColumn;
import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
public class AggregationQueryOperator extends QueryOperator {
public static final String ERROR_MESSAGE1 =
"Common queries and aggregated queries are not allowed to appear at the same time";
public AggregationQueryOperator() {
super();
}
public AggregationQueryOperator(QueryOperator queryOperator) {
super(queryOperator);
}
@Override
public void check() throws LogicalOperatorException {
super.check();
if (!isAlignByTime()) {
throw new LogicalOperatorException("AGGREGATION doesn't support disable align clause.");
}
for (ResultColumn resultColumn : selectComponent.getResultColumns()) {
Expression expression = resultColumn.getExpression();
if (expression instanceof TimeSeriesOperand) {
throw new LogicalOperatorException(ERROR_MESSAGE1);
}
}
}
}
......@@ -22,8 +22,8 @@ import org.apache.iotdb.db.exception.metadata.MetadataException;
import org.apache.iotdb.db.exception.query.LogicalOperatorException;
import org.apache.iotdb.db.exception.runtime.SQLParserException;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.constant.SQLConstant;
import org.apache.iotdb.db.qp.logical.Operator;
import org.apache.iotdb.db.qp.constant.FilterConstant;
import org.apache.iotdb.db.qp.constant.FilterConstant.FilterType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.read.expression.IUnaryExpression;
import org.apache.iotdb.tsfile.utils.Binary;
......@@ -46,16 +46,15 @@ public class BasicFunctionOperator extends FunctionOperator {
/**
* BasicFunctionOperator Constructor.
*
* @param tokenIntType token in Int Type
* @param filterType filter Type
* @param path path
* @param value value
* @throws LogicalOperatorException Logical Operator Exception
*/
public BasicFunctionOperator(int tokenIntType, PartialPath path, String value)
public BasicFunctionOperator(FilterType filterType, PartialPath path, String value)
throws SQLParserException {
super(tokenIntType);
operatorType = Operator.OperatorType.BASIC_FUNC;
funcToken = BasicOperatorType.getBasicOpBySymbol(tokenIntType);
super(filterType);
funcToken = BasicOperatorType.getBasicOpBySymbol(filterType);
this.singlePath = path;
this.value = value;
isLeaf = true;
......@@ -68,9 +67,9 @@ public class BasicFunctionOperator extends FunctionOperator {
@Override
public void reverseFunc() {
int intType = SQLConstant.reverseWords.get(tokenIntType);
setTokenIntType(intType);
funcToken = BasicOperatorType.getBasicOpBySymbol(intType);
FilterType filterType = FilterConstant.filterReverseWords.get(this.filterType);
setFilterType(filterType);
funcToken = BasicOperatorType.getBasicOpBySymbol(filterType);
}
@Override
......@@ -122,7 +121,7 @@ public class BasicFunctionOperator extends FunctionOperator {
for (int i = 0; i < spaceNum; i++) {
sc.addTail(" ");
}
sc.addTail(singlePath.getFullPath(), this.tokenSymbol, value, ", single\n");
sc.addTail(singlePath.getFullPath(), getFilterSymbol(), value, ", single\n");
return sc.toString();
}
......@@ -132,12 +131,11 @@ public class BasicFunctionOperator extends FunctionOperator {
try {
ret =
new BasicFunctionOperator(
this.tokenIntType, new PartialPath(singlePath.getNodes().clone()), value);
this.filterType, new PartialPath(singlePath.getNodes().clone()), value);
} catch (SQLParserException e) {
logger.error("error copy:", e);
return null;
}
ret.tokenSymbol = tokenSymbol;
ret.isLeaf = isLeaf;
ret.isSingle = isSingle;
ret.pathSet = pathSet;
......@@ -146,7 +144,7 @@ public class BasicFunctionOperator extends FunctionOperator {
@Override
public String toString() {
return "[" + singlePath.getFullPath() + tokenSymbol + value + "]";
return "[" + singlePath.getFullPath() + getFilterSymbol() + value + "]";
}
@Override
......
......@@ -20,7 +20,8 @@ package org.apache.iotdb.db.qp.logical.crud;
import org.apache.iotdb.db.exception.query.LogicalOperatorException;
import org.apache.iotdb.db.exception.runtime.SQLParserException;
import org.apache.iotdb.db.qp.constant.SQLConstant;
import org.apache.iotdb.db.qp.constant.FilterConstant;
import org.apache.iotdb.db.qp.constant.FilterConstant.FilterType;
import org.apache.iotdb.tsfile.read.common.Path;
import org.apache.iotdb.tsfile.read.expression.IUnaryExpression;
import org.apache.iotdb.tsfile.read.expression.impl.GlobalTimeExpression;
......@@ -157,27 +158,28 @@ public enum BasicOperatorType {
/**
* BasicOperatorType Constructor.
*
* @param tokenIntType token in Int Type
* @param filterType token in Int Type
* @return basic operator type
* @throws LogicalOperatorException Logical Operator Exception
*/
public static BasicOperatorType getBasicOpBySymbol(int tokenIntType) throws SQLParserException {
switch (tokenIntType) {
case SQLConstant.EQUAL:
public static BasicOperatorType getBasicOpBySymbol(FilterType filterType)
throws SQLParserException {
switch (filterType) {
case EQUAL:
return EQ;
case SQLConstant.LESSTHANOREQUALTO:
case LESSTHANOREQUALTO:
return LTEQ;
case SQLConstant.LESSTHAN:
case LESSTHAN:
return LT;
case SQLConstant.GREATERTHANOREQUALTO:
case GREATERTHANOREQUALTO:
return GTEQ;
case SQLConstant.GREATERTHAN:
case GREATERTHAN:
return GT;
case SQLConstant.NOTEQUAL:
case NOTEQUAL:
return NOTEQUAL;
default:
throw new SQLParserException(
"unsupported type:{}" + SQLConstant.tokenNames.get(tokenIntType));
"unsupported type:{}" + FilterConstant.filterNames.get(filterType));
}
}
......
/*
* 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.qp.logical.crud;
import org.apache.iotdb.db.query.executor.fill.IFill;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import java.util.Map;
public class FillClauseComponent extends SpecialClauseComponent {
private Map<TSDataType, IFill> fillTypes;
public FillClauseComponent() {}
public Map<TSDataType, IFill> getFillTypes() {
return fillTypes;
}
public void setFillTypes(Map<TSDataType, IFill> fillTypes) {
this.fillTypes = fillTypes;
}
}
/*
* 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.qp.logical.crud;
import org.apache.iotdb.db.exception.query.LogicalOperatorException;
import org.apache.iotdb.db.qp.constant.FilterConstant.FilterType;
public class FillQueryOperator extends QueryOperator {
@Override
public void check() throws LogicalOperatorException {
super.check();
if (!isAlignByTime()) {
throw new LogicalOperatorException("FILL doesn't support disable align clause.");
}
FilterOperator filterOperator = whereComponent.getFilterOperator();
if (!filterOperator.isLeaf() || filterOperator.getFilterType() != FilterType.EQUAL) {
throw new LogicalOperatorException("Only \"=\" can be used in fill function");
}
}
}
......@@ -22,8 +22,8 @@ import org.apache.iotdb.db.exception.metadata.MetadataException;
import org.apache.iotdb.db.exception.query.LogicalOperatorException;
import org.apache.iotdb.db.exception.query.QueryProcessException;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.constant.SQLConstant;
import org.apache.iotdb.db.qp.logical.Operator;
import org.apache.iotdb.db.qp.constant.FilterConstant;
import org.apache.iotdb.db.qp.constant.FilterConstant.FilterType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.read.expression.IExpression;
import org.apache.iotdb.tsfile.read.expression.IUnaryExpression;
......@@ -37,23 +37,19 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.apache.iotdb.db.qp.constant.SQLConstant.KW_AND;
import static org.apache.iotdb.db.qp.constant.SQLConstant.KW_OR;
/**
* This class is for filter operator and implements {@link Operator} . It may consist of more than
* two child FilterOperators, but if it's not a leaf operator, the relation is the same among all of
* its children (AND or OR), which is identified by tokenType.
* This class is for filter in where clause. It may consist of more than two child FilterOperators,
* but if it's not a leaf operator, the relation is the same among all of its children (AND or OR),
* which is identified by tokenType.
*/
public class FilterOperator extends Operator implements Comparable<FilterOperator> {
public class FilterOperator implements Comparable<FilterOperator> {
// it is the symbol of token. e.g. AND is & and OR is |
String tokenSymbol;
protected FilterType filterType;
private List<FilterOperator> childOperators;
private List<FilterOperator> childOperators = new ArrayList<>();
// leaf filter operator means it doesn't have left and right child filterOperator. Leaf filter
// should set FunctionOperator.
protected boolean isLeaf;
protected boolean isLeaf = false;
// isSingle being true means all recursive children of this filter belong to one seriesPath.
boolean isSingle = false;
// if isSingle = false, singlePath must be null
......@@ -61,29 +57,31 @@ public class FilterOperator extends Operator implements Comparable<FilterOperato
// all paths involved in this filter
Set<PartialPath> pathSet;
public FilterOperator(int tokenType) {
super(tokenType);
operatorType = OperatorType.FILTER;
childOperators = new ArrayList<>();
this.tokenIntType = tokenType;
isLeaf = false;
tokenSymbol = SQLConstant.tokenSymbol.get(tokenType);
public FilterOperator() {}
public FilterOperator(FilterType filterType) {
this.filterType = filterType;
}
public FilterOperator(int tokenType, boolean isSingle) {
this(tokenType);
public FilterOperator(FilterType filterType, boolean isSingle) {
this.filterType = filterType;
this.isSingle = isSingle;
}
@Override
public int getTokenIntType() {
return tokenIntType;
public FilterType getFilterType() {
return filterType;
}
public void setFilterType(FilterType filterType) {
this.filterType = filterType;
}
public String getFilterName() {
return FilterConstant.filterNames.get(filterType);
}
public void setTokenIntType(int intType) {
this.tokenIntType = intType;
this.tokenName = SQLConstant.tokenNames.get(tokenIntType);
this.tokenSymbol = SQLConstant.tokenSymbol.get(tokenIntType);
public String getFilterSymbol() {
return FilterConstant.filterSymbol.get(filterType);
}
public List<FilterOperator> getChildren() {
......@@ -139,13 +137,13 @@ public class FilterOperator extends Operator implements Comparable<FilterOperato
} else {
if (childOperators.isEmpty()) {
throw new LogicalOperatorException(
String.valueOf(tokenIntType), "this filter is not leaf, but it's empty");
String.valueOf(filterType), "this filter is not leaf, but it's empty");
}
IExpression retFilter = childOperators.get(0).transformToExpression(pathTSDataTypeHashMap);
IExpression currentFilter;
for (int i = 1; i < childOperators.size(); i++) {
currentFilter = childOperators.get(i).transformToExpression(pathTSDataTypeHashMap);
switch (tokenIntType) {
switch (filterType) {
case KW_AND:
retFilter = BinaryExpression.and(retFilter, currentFilter);
break;
......@@ -154,8 +152,7 @@ public class FilterOperator extends Operator implements Comparable<FilterOperato
break;
default:
throw new LogicalOperatorException(
String.valueOf(tokenIntType),
"Maybe it means " + SQLConstant.tokenNames.get(tokenIntType));
String.valueOf(filterType), "Maybe it means " + getFilterName());
}
}
return retFilter;
......@@ -175,7 +172,7 @@ public class FilterOperator extends Operator implements Comparable<FilterOperato
throws LogicalOperatorException, MetadataException {
if (childOperators.isEmpty()) {
throw new LogicalOperatorException(
String.valueOf(tokenIntType),
String.valueOf(filterType),
"TransformToSingleFilter: this filter is not a leaf, but it's empty.");
}
Pair<IUnaryExpression, String> currentPair =
......@@ -193,7 +190,7 @@ public class FilterOperator extends Operator implements Comparable<FilterOperato
+ ", another is: "
+ currentPair.right);
}
switch (tokenIntType) {
switch (filterType) {
case KW_AND:
retFilter.setFilter(
FilterFactory.and(retFilter.getFilter(), currentPair.left.getFilter()));
......@@ -204,8 +201,7 @@ public class FilterOperator extends Operator implements Comparable<FilterOperato
break;
default:
throw new LogicalOperatorException(
String.valueOf(tokenIntType),
"Maybe it means " + SQLConstant.tokenNames.get(tokenIntType));
String.valueOf(filterType), "Maybe it means " + getFilterName());
}
}
return new Pair<>(retFilter, path);
......@@ -233,13 +229,13 @@ public class FilterOperator extends Operator implements Comparable<FilterOperato
}
// if child is leaf, will execute BasicFunctionOperator.equals()
FilterOperator operator = (FilterOperator) fil;
return this.tokenIntType == operator.tokenIntType
return this.filterType == operator.filterType
&& this.getChildren().equals(operator.getChildren());
}
@Override
public int hashCode() {
return tokenSymbol.hashCode();
return getFilterSymbol().hashCode();
}
public boolean isLeaf() {
......@@ -259,7 +255,7 @@ public class FilterOperator extends Operator implements Comparable<FilterOperato
for (int i = 0; i < spaceNum; i++) {
sc.addTail(" ");
}
sc.addTail(this.tokenName);
sc.addTail(getFilterName());
if (isSingle) {
sc.addTail("[single:", getSinglePath().getFullPath(), "]");
}
......@@ -273,7 +269,7 @@ public class FilterOperator extends Operator implements Comparable<FilterOperato
@Override
public String toString() {
StringContainer sc = new StringContainer();
sc.addTail("[", this.tokenName);
sc.addTail("[", FilterConstant.filterNames.get(filterType));
if (isSingle) {
sc.addTail("[single:", getSinglePath().getFullPath(), "]");
}
......@@ -286,8 +282,7 @@ public class FilterOperator extends Operator implements Comparable<FilterOperato
}
public FilterOperator copy() {
FilterOperator ret = new FilterOperator(this.tokenIntType);
ret.tokenSymbol = tokenSymbol;
FilterOperator ret = new FilterOperator(this.filterType);
ret.isLeaf = isLeaf;
ret.isSingle = isSingle;
if (singlePath != null) {
......
......@@ -16,24 +16,20 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.iotdb.db.qp.logical.crud;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.logical.Operator;
import java.util.ArrayList;
import java.util.List;
/** this class maintains information of {@code FROM} clause. */
public class FromOperator extends Operator {
public class FromComponent {
private List<PartialPath> prefixList;
private List<PartialPath> prefixList = new ArrayList<>();
public FromOperator(int tokenIntType) {
super(tokenIntType);
operatorType = OperatorType.FROM;
prefixList = new ArrayList<>();
}
public FromComponent() {}
public void addPrefixTablePath(PartialPath prefixPath) {
prefixList.add(prefixPath);
......
......@@ -18,6 +18,8 @@
*/
package org.apache.iotdb.db.qp.logical.crud;
import org.apache.iotdb.db.qp.constant.FilterConstant.FilterType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -30,9 +32,8 @@ public class FunctionOperator extends FilterOperator {
private static final Logger logger = LoggerFactory.getLogger(FunctionOperator.class);
public FunctionOperator(int tokenIntType) {
super(tokenIntType);
operatorType = OperatorType.FUNC;
public FunctionOperator(FilterType filterType) {
super(filterType);
}
/** reverse func. */
......
/*
* 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.qp.logical.crud;
public class GroupByClauseComponent extends SpecialClauseComponent {
private long startTime;
private long endTime;
// time interval
private long unit;
// sliding step
private long slidingStep;
private boolean isIntervalByMonth = false;
private boolean isSlidingStepByMonth = false;
// if it is left close and right open interval
private boolean leftCRightO;
public GroupByClauseComponent() {}
public boolean isLeftCRightO() {
return leftCRightO;
}
public void setLeftCRightO(boolean leftCRightO) {
this.leftCRightO = leftCRightO;
}
public long getUnit() {
return unit;
}
public void setUnit(long unit) {
this.unit = unit;
}
public long getStartTime() {
return startTime;
}
public void setStartTime(long startTime) {
this.startTime = startTime;
}
public long getEndTime() {
return endTime;
}
public void setEndTime(long endTime) {
this.endTime = endTime;
}
public long getSlidingStep() {
return slidingStep;
}
public void setSlidingStep(long slidingStep) {
this.slidingStep = slidingStep;
}
public boolean isSlidingStepByMonth() {
return isSlidingStepByMonth;
}
public void setSlidingStepByMonth(boolean isSlidingStepByMonth) {
this.isSlidingStepByMonth = isSlidingStepByMonth;
}
public boolean isIntervalByMonth() {
return isIntervalByMonth;
}
public void setIntervalByMonth(boolean isIntervalByMonth) {
this.isIntervalByMonth = isIntervalByMonth;
}
}
/*
* 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.qp.logical.crud;
import org.apache.iotdb.db.query.executor.fill.IFill;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import java.util.Map;
public class GroupByFillClauseComponent extends GroupByClauseComponent {
private Map<TSDataType, IFill> fillTypes;
public GroupByFillClauseComponent() {}
public Map<TSDataType, IFill> getFillTypes() {
return fillTypes;
}
public void setFillTypes(Map<TSDataType, IFill> fillTypes) {
this.fillTypes = fillTypes;
}
}
/*
* 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.qp.logical.crud;
public class GroupByFillQueryOperator extends GroupByQueryOperator {}
/*
* 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.qp.logical.crud;
public class GroupByQueryOperator extends AggregationQueryOperator {}
......@@ -21,7 +21,7 @@ package org.apache.iotdb.db.qp.logical.crud;
import org.apache.iotdb.db.exception.metadata.MetadataException;
import org.apache.iotdb.db.exception.query.LogicalOperatorException;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.logical.Operator;
import org.apache.iotdb.db.qp.constant.FilterConstant.FilterType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.read.common.Path;
import org.apache.iotdb.tsfile.read.expression.IUnaryExpression;
......@@ -51,13 +51,12 @@ public class InOperator extends FunctionOperator {
/**
* In Operator Constructor.
*
* @param tokenIntType token in Int Type
* @param filterType filter Type
* @param path path
* @param values values
*/
public InOperator(int tokenIntType, PartialPath path, boolean not, Set<String> values) {
super(tokenIntType);
operatorType = Operator.OperatorType.IN;
public InOperator(FilterType filterType, PartialPath path, boolean not, Set<String> values) {
super(filterType);
this.singlePath = path;
this.values = values;
this.not = not;
......@@ -146,7 +145,7 @@ public class InOperator extends FunctionOperator {
for (int i = 0; i < spaceNum; i++) {
sc.addTail(" ");
}
sc.addTail(singlePath.getFullPath(), this.tokenSymbol, not, values, ", single\n");
sc.addTail(singlePath.getFullPath(), getFilterSymbol(), not, values, ", single\n");
return sc.toString();
}
......@@ -154,11 +153,10 @@ public class InOperator extends FunctionOperator {
public InOperator copy() {
InOperator ret =
new InOperator(
this.tokenIntType,
this.filterType,
new PartialPath(singlePath.getNodes().clone()),
not,
new HashSet<>(values));
ret.tokenSymbol = tokenSymbol;
ret.isLeaf = isLeaf;
ret.isSingle = isSingle;
ret.pathSet = pathSet;
......@@ -169,7 +167,7 @@ public class InOperator extends FunctionOperator {
public String toString() {
List<String> valuesList = new ArrayList<>(values);
Collections.sort(valuesList);
return "[" + singlePath.getFullPath() + tokenSymbol + not + valuesList + "]";
return "[" + singlePath.getFullPath() + getFilterSymbol() + not + valuesList + "]";
}
@Override
......
/*
* 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.qp.logical.crud;
import org.apache.iotdb.db.exception.query.LogicalOperatorException;
import org.apache.iotdb.db.query.expression.Expression;
import org.apache.iotdb.db.query.expression.ResultColumn;
import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
public class LastQueryOperator extends QueryOperator {
public LastQueryOperator() {}
public LastQueryOperator(QueryOperator queryOperator) {
super(queryOperator);
}
@Override
public void check() throws LogicalOperatorException {
super.check();
if (isAlignByDevice()) {
throw new LogicalOperatorException("Last query doesn't support align by device.");
}
for (ResultColumn resultColumn : selectComponent.getResultColumns()) {
Expression expression = resultColumn.getExpression();
if (!(expression instanceof TimeSeriesOperand)) {
throw new LogicalOperatorException("Last queries can only be applied on raw time series.");
}
}
}
}
......@@ -18,87 +18,69 @@
*/
package org.apache.iotdb.db.qp.logical.crud;
import org.apache.iotdb.db.exception.query.LogicalOperatorException;
import org.apache.iotdb.db.index.common.IndexType;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.constant.SQLConstant;
import org.apache.iotdb.db.qp.logical.Operator;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.query.executor.fill.IFill;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import java.util.Map;
public class QueryOperator extends RootOperator {
public class QueryOperator extends Operator {
private SelectOperator selectOperator;
private FromOperator fromOperator;
private FilterOperator filterOperator;
protected SelectComponent selectComponent;
protected FromComponent fromComponent;
protected WhereComponent whereComponent;
protected SpecialClauseComponent specialClauseComponent;
private long startTime;
private long endTime;
// time interval
private long unit;
// sliding step
private long slidingStep;
private boolean isGroupByTime = false;
private boolean isIntervalByMonth = false;
private boolean isSlidingStepByMonth = false;
// if it is left close and right open interval
private boolean leftCRightO;
protected Map<String, Object> props;
protected IndexType indexType;
private Map<TSDataType, IFill> fillTypes;
private boolean isFill = false;
private boolean isGroupByLevel = false;
private int level = -1;
private int rowLimit = 0;
private int rowOffset = 0;
private int seriesLimit = 0;
private int seriesOffset = 0;
private boolean isAlignByDevice = false;
private boolean isAlignByTime = true;
private String column;
private boolean ascending = true;
private Map<String, Object> props;
private IndexType indexType;
public QueryOperator() {
super(SQLConstant.TOK_QUERY);
operatorType = Operator.OperatorType.QUERY;
}
// if true, we don't need the row whose any column is null
private boolean withoutAnyNull;
public QueryOperator(QueryOperator queryOperator) {
this();
this.selectComponent = queryOperator.getSelectComponent();
this.fromComponent = queryOperator.getFromComponent();
this.whereComponent = queryOperator.getWhereComponent();
this.specialClauseComponent = queryOperator.getSpecialClauseComponent();
this.props = queryOperator.getProps();
this.indexType = queryOperator.getIndexType();
}
// if true, we don't need the row whose all columns are null
private boolean withoutAllNull;
public SelectComponent getSelectComponent() {
return selectComponent;
}
public QueryOperator(int tokenIntType) {
super(tokenIntType);
operatorType = Operator.OperatorType.QUERY;
public void setSelectComponent(SelectComponent selectComponent) {
this.selectComponent = selectComponent;
}
public SelectOperator getSelectOperator() {
return selectOperator;
public FromComponent getFromComponent() {
return fromComponent;
}
public void setSelectOperator(SelectOperator selectOperator) {
this.selectOperator = selectOperator;
public void setFromComponent(FromComponent fromComponent) {
this.fromComponent = fromComponent;
}
public FromOperator getFromOperator() {
return fromOperator;
public WhereComponent getWhereComponent() {
return whereComponent;
}
public void setFromOperator(FromOperator fromOperator) {
this.fromOperator = fromOperator;
public void setWhereComponent(WhereComponent whereComponent) {
this.whereComponent = whereComponent;
}
public FilterOperator getFilterOperator() {
return filterOperator;
public void setSpecialClauseComponent(SpecialClauseComponent specialClauseComponent) {
this.specialClauseComponent = specialClauseComponent;
}
public void setFilterOperator(FilterOperator filterOperator) {
this.filterOperator = filterOperator;
public SpecialClauseComponent getSpecialClauseComponent() {
return specialClauseComponent;
}
public Map<String, Object> getProps() {
......@@ -117,199 +99,42 @@ public class QueryOperator extends RootOperator {
this.indexType = indexType;
}
public boolean isFill() {
return isFill;
}
public void setFill(boolean fill) {
isFill = fill;
}
public Map<TSDataType, IFill> getFillTypes() {
return fillTypes;
}
public void setFillTypes(Map<TSDataType, IFill> fillTypes) {
this.fillTypes = fillTypes;
}
public boolean isGroupByLevel() {
return isGroupByLevel;
}
public void setGroupByLevel(boolean isGroupBy) {
this.isGroupByLevel = isGroupBy;
}
public boolean isLeftCRightO() {
return leftCRightO;
}
public void setLeftCRightO(boolean leftCRightO) {
this.leftCRightO = leftCRightO;
}
public int getRowLimit() {
return rowLimit;
}
public void setRowLimit(int rowLimit) {
this.rowLimit = rowLimit;
}
public int getRowOffset() {
return rowOffset;
}
public void setRowOffset(int rowOffset) {
this.rowOffset = rowOffset;
}
public boolean hasLimit() {
return rowLimit > 0;
}
public int getSeriesLimit() {
return seriesLimit;
}
public void setSeriesLimit(int seriesLimit) {
this.seriesLimit = seriesLimit;
}
public int getSeriesOffset() {
return seriesOffset;
}
public void setSeriesOffset(int seriesOffset) {
this.seriesOffset = seriesOffset;
}
public boolean hasSlimit() {
return seriesLimit > 0;
}
public long getUnit() {
return unit;
}
public void setUnit(long unit) {
this.unit = unit;
}
public long getStartTime() {
return startTime;
}
public void setStartTime(long startTime) {
this.startTime = startTime;
}
public long getEndTime() {
return endTime;
}
public void setEndTime(long endTime) {
this.endTime = endTime;
}
public long getSlidingStep() {
return slidingStep;
}
public void setSlidingStep(long slidingStep) {
this.slidingStep = slidingStep;
}
public boolean isAlignByDevice() {
return isAlignByDevice;
}
public void setAlignByDevice(boolean isAlignByDevice) {
this.isAlignByDevice = isAlignByDevice;
}
public boolean isAlignByTime() {
return isAlignByTime;
}
public void setAlignByTime(boolean isAlignByTime) {
this.isAlignByTime = isAlignByTime;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public boolean isGroupByTime() {
return isGroupByTime;
}
public void setGroupByTime(boolean groupByTime) {
isGroupByTime = groupByTime;
}
public boolean isSlidingStepByMonth() {
return isSlidingStepByMonth;
}
public void setSlidingStepByMonth(boolean isSlidingStepByMonth) {
this.isSlidingStepByMonth = isSlidingStepByMonth;
}
public boolean isIntervalByMonth() {
return isIntervalByMonth;
}
public void setIntervalByMonth(boolean isIntervalByMonth) {
this.isIntervalByMonth = isIntervalByMonth;
}
public String getColumn() {
return column;
}
public void setColumn(String column) {
this.column = column;
}
public boolean isAscending() {
return ascending;
}
public void setAscending(boolean ascending) {
this.ascending = ascending;
}
public boolean isLastQuery() {
return selectOperator.isLastQuery();
}
public boolean hasAggregationFunction() {
return selectOperator.hasAggregationFunction();
return selectComponent.hasAggregationFunction();
}
public boolean hasTimeSeriesGeneratingFunction() {
return selectOperator.hasTimeSeriesGeneratingFunction();
}
public boolean isWithoutAnyNull() {
return withoutAnyNull;
return selectComponent.hasTimeSeriesGeneratingFunction();
}
public void setWithoutAnyNull(boolean withoutAnyNull) {
this.withoutAnyNull = withoutAnyNull;
public boolean isAlignByDevice() {
return specialClauseComponent != null && specialClauseComponent.isAlignByDevice();
}
public boolean isWithoutAllNull() {
return withoutAllNull;
public boolean isAlignByTime() {
return specialClauseComponent == null || specialClauseComponent.isAlignByTime();
}
public void setWithoutAllNull(boolean withoutAllNull) {
this.withoutAllNull = withoutAllNull;
public boolean isGroupByLevel() {
return specialClauseComponent != null && specialClauseComponent.getLevel() != -1;
}
public void check() throws LogicalOperatorException {
if (isAlignByDevice()) {
if (selectComponent.hasTimeSeriesGeneratingFunction()) {
throw new LogicalOperatorException(
"ALIGN BY DEVICE clause is not supported in UDF queries.");
}
for (PartialPath path : selectComponent.getPaths()) {
String device = path.getDevice();
if (!device.isEmpty()) {
throw new LogicalOperatorException(
"The paths of the SELECT clause can only be single level. In other words, "
+ "the paths of the SELECT clause can only be measurements or STAR, without DOT."
+ " For more details please refer to the SQL document.");
}
}
}
}
}
......@@ -16,10 +16,10 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.iotdb.db.qp.logical.crud;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.logical.Operator;
import org.apache.iotdb.db.query.expression.Expression;
import org.apache.iotdb.db.query.expression.ResultColumn;
import org.apache.iotdb.db.query.expression.unary.FunctionExpression;
......@@ -30,11 +30,10 @@ import java.util.ArrayList;
import java.util.List;
/** this class maintains information from select clause. */
public final class SelectOperator extends Operator {
public final class SelectComponent {
private final ZoneId zoneId;
private boolean isLastQuery = false;
private boolean hasAggregationFunction = false;
private boolean hasTimeSeriesGeneratingFunction = false;
......@@ -44,9 +43,7 @@ public final class SelectOperator extends Operator {
private List<String> aggregationFunctionsCache;
/** init with tokenIntType, default operatorType is <code>OperatorType.SELECT</code>. */
public SelectOperator(int tokenIntType, ZoneId zoneId) {
super(tokenIntType);
operatorType = OperatorType.SELECT;
public SelectComponent(ZoneId zoneId) {
this.zoneId = zoneId;
}
......@@ -54,14 +51,6 @@ public final class SelectOperator extends Operator {
return zoneId;
}
public void markAsLastQuery() {
isLastQuery = true;
}
public boolean isLastQuery() {
return isLastQuery;
}
public boolean hasAggregationFunction() {
return hasAggregationFunction;
}
......
/*
* 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.qp.logical.crud;
public class SpecialClauseComponent {
protected int rowLimit = 0;
protected int rowOffset = 0;
protected int seriesLimit = 0;
protected int seriesOffset = 0;
protected boolean ascending = true;
// if true, we don't need the row whose any column is null
protected boolean withoutAnyNull;
// if true, we don't need the row whose all columns are null
protected boolean withoutAllNull;
protected int level = -1;
protected boolean isAlignByDevice = false;
protected boolean isAlignByTime = true;
public SpecialClauseComponent() {}
public int getRowLimit() {
return rowLimit;
}
public void setRowLimit(int rowLimit) {
this.rowLimit = rowLimit;
}
public int getRowOffset() {
return rowOffset;
}
public void setRowOffset(int rowOffset) {
this.rowOffset = rowOffset;
}
public boolean hasLimit() {
return rowLimit > 0;
}
public int getSeriesLimit() {
return seriesLimit;
}
public void setSeriesLimit(int seriesLimit) {
this.seriesLimit = seriesLimit;
}
public int getSeriesOffset() {
return seriesOffset;
}
public void setSeriesOffset(int seriesOffset) {
this.seriesOffset = seriesOffset;
}
public boolean hasSlimit() {
return seriesLimit > 0;
}
public boolean isAscending() {
return ascending;
}
public void setAscending(boolean ascending) {
this.ascending = ascending;
}
public boolean isWithoutAnyNull() {
return withoutAnyNull;
}
public void setWithoutAnyNull(boolean withoutAnyNull) {
this.withoutAnyNull = withoutAnyNull;
}
public boolean isWithoutAllNull() {
return withoutAllNull;
}
public void setWithoutAllNull(boolean withoutAllNull) {
this.withoutAllNull = withoutAllNull;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public boolean isAlignByDevice() {
return isAlignByDevice;
}
public void setAlignByDevice(boolean isAlignByDevice) {
this.isAlignByDevice = isAlignByDevice;
}
public boolean isAlignByTime() {
return isAlignByTime;
}
public void setAlignByTime(boolean isAlignByTime) {
this.isAlignByTime = isAlignByTime;
}
}
......@@ -16,15 +16,16 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.iotdb.db.qp.logical;
/**
* RootOperator indicates the operator that could be executed as a entire command. RootOperator
* consists of SFWOperator, like INSERT/UPDATE/DELETE, and other Operators.
*/
public abstract class RootOperator extends Operator {
package org.apache.iotdb.db.qp.logical.crud;
public class UDFQueryOperator extends QueryOperator {
public UDFQueryOperator() {
super();
}
public RootOperator(int tokenIntType) {
super(tokenIntType);
public UDFQueryOperator(QueryOperator queryOperator) {
super(queryOperator);
}
}
/*
* 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.qp.logical.crud;
public class WhereComponent {
private FilterOperator filterOperator;
public WhereComponent() {}
public WhereComponent(FilterOperator filterOperator) {
this.filterOperator = filterOperator;
}
public FilterOperator getFilterOperator() {
return filterOperator;
}
public void setFilterOperator(FilterOperator filterOperator) {
this.filterOperator = filterOperator;
}
}
......@@ -20,11 +20,11 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
import java.util.Map;
public class AlterTimeSeriesOperator extends RootOperator {
public class AlterTimeSeriesOperator extends Operator {
private PartialPath path;
......
......@@ -19,12 +19,12 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
/**
* this class maintains information in Author statement, including CREATE, DROP, GRANT and REVOKE.
*/
public class AuthorOperator extends RootOperator {
public class AuthorOperator extends Operator {
private final AuthorType authorType;
private String userName;
......
......@@ -18,9 +18,9 @@
*/
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
public class ClearCacheOperator extends RootOperator {
public class ClearCacheOperator extends Operator {
public ClearCacheOperator(int tokenIntType) {
super(tokenIntType);
......
......@@ -19,9 +19,9 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
public class CreateFunctionOperator extends RootOperator {
public class CreateFunctionOperator extends Operator {
private boolean isTemporary;
private String udfName;
......
......@@ -19,9 +19,9 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
public class CreateSnapshotOperator extends RootOperator {
public class CreateSnapshotOperator extends Operator {
public CreateSnapshotOperator(int tokenIntType) {
super(tokenIntType);
......
......@@ -19,14 +19,14 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
import java.util.Map;
public class CreateTimeSeriesOperator extends RootOperator {
public class CreateTimeSeriesOperator extends Operator {
private PartialPath path;
private String alias;
......
......@@ -21,12 +21,12 @@ package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.engine.trigger.executor.TriggerEvent;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
import java.util.HashMap;
import java.util.Map;
public class CreateTriggerOperator extends RootOperator {
public class CreateTriggerOperator extends Operator {
private String triggerName;
private TriggerEvent event;
......
......@@ -19,11 +19,11 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.qp.constant.SQLConstant;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
import java.util.List;
public class DataAuthOperator extends RootOperator {
public class DataAuthOperator extends Operator {
private final List<String> users;
......
......@@ -20,11 +20,11 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
import java.util.Set;
public class DeletePartitionOperator extends RootOperator {
public class DeletePartitionOperator extends Operator {
private PartialPath storageGroupName;
private Set<Long> partitionIds;
......
......@@ -19,11 +19,11 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
import java.util.List;
public class DeleteStorageGroupOperator extends RootOperator {
public class DeleteStorageGroupOperator extends Operator {
private List<PartialPath> deletePathList;
......
......@@ -19,12 +19,12 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
import java.util.List;
/** this class deletes whole data and metadata of the timeseries. */
public class DeleteTimeSeriesOperator extends RootOperator {
public class DeleteTimeSeriesOperator extends Operator {
private List<PartialPath> deletePathList;
......
......@@ -19,9 +19,9 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
public class DropFunctionOperator extends RootOperator {
public class DropFunctionOperator extends Operator {
private String udfName;
......
......@@ -19,9 +19,9 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
public class DropTriggerOperator extends RootOperator {
public class DropTriggerOperator extends Operator {
private String triggerName;
......
......@@ -19,11 +19,11 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
import java.util.List;
public class FlushOperator extends RootOperator {
public class FlushOperator extends Operator {
public List<PartialPath> getStorageGroupList() {
return storageGroupList;
......
......@@ -18,9 +18,9 @@
*/
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
public class KillQueryOperator extends RootOperator {
public class KillQueryOperator extends Operator {
long queryId = -1;
public KillQueryOperator(int tokenIntType) {
......
......@@ -20,9 +20,9 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.qp.constant.SQLConstant;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
public class LoadConfigurationOperator extends RootOperator {
public class LoadConfigurationOperator extends Operator {
LoadConfigurationOperatorType loadConfigurationOperatorType;
......
......@@ -18,12 +18,12 @@
*/
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
/**
* this class maintains information in Author statement, including CREATE, DROP, GRANT and REVOKE.
*/
public class LoadDataOperator extends RootOperator {
public class LoadDataOperator extends Operator {
private final String inputFilePath;
private final String measureType;
......
......@@ -19,11 +19,11 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.qp.constant.SQLConstant;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
import java.io.File;
public class LoadFilesOperator extends RootOperator {
public class LoadFilesOperator extends Operator {
private File file;
private boolean autoCreateSchema;
......
......@@ -18,9 +18,9 @@
*/
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
public class MergeOperator extends RootOperator {
public class MergeOperator extends Operator {
public MergeOperator(int tokenIntType) {
super(tokenIntType);
......
......@@ -19,11 +19,11 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.qp.constant.SQLConstant;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
import java.io.File;
public class MoveFileOperator extends RootOperator {
public class MoveFileOperator extends Operator {
private File file;
private File targetDir;
......
......@@ -19,11 +19,11 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.qp.constant.SQLConstant;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
import java.io.File;
public class RemoveFileOperator extends RootOperator {
public class RemoveFileOperator extends Operator {
private File file;
......
......@@ -19,9 +19,9 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
public class SetStorageGroupOperator extends RootOperator {
public class SetStorageGroupOperator extends Operator {
private PartialPath path;
......
......@@ -21,9 +21,9 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
public class SetTTLOperator extends RootOperator {
public class SetTTLOperator extends Operator {
private PartialPath storageGroup;
private long dataTTL;
......
......@@ -19,9 +19,9 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
public class ShowMergeStatusOperator extends RootOperator {
public class ShowMergeStatusOperator extends Operator {
public ShowMergeStatusOperator(int tokenIntType) {
super(tokenIntType);
......
......@@ -19,9 +19,9 @@
*/
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
public class ShowOperator extends RootOperator {
public class ShowOperator extends Operator {
public ShowOperator(int tokenIntType) {
this(tokenIntType, OperatorType.SHOW);
......
......@@ -19,9 +19,9 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
public class StartTriggerOperator extends RootOperator {
public class StartTriggerOperator extends Operator {
private String triggerName;
......
......@@ -19,9 +19,9 @@
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
public class StopTriggerOperator extends RootOperator {
public class StopTriggerOperator extends Operator {
private String triggerName;
......
......@@ -18,9 +18,9 @@
*/
package org.apache.iotdb.db.qp.logical.sys;
import org.apache.iotdb.db.qp.logical.RootOperator;
import org.apache.iotdb.db.qp.logical.Operator;
public class TracingOperator extends RootOperator {
public class TracingOperator extends Operator {
private boolean isTracingOn;
......
......@@ -103,14 +103,6 @@ public class AggregationPlan extends RawDataQueryPlan {
return levelAggPaths;
}
@Override
public void setAlignByTime(boolean align) throws QueryProcessException {
if (!align) {
throw new QueryProcessException(
getOperatorType().name() + " doesn't support disable align clause.");
}
}
@Override
public String getColumnForReaderFromPath(PartialPath path, int pathIndex) {
return resultColumns.get(pathIndex).getResultColumnName();
......
......@@ -18,7 +18,6 @@
*/
package org.apache.iotdb.db.qp.physical.crud;
import org.apache.iotdb.db.exception.query.QueryProcessException;
import org.apache.iotdb.db.qp.logical.Operator;
import org.apache.iotdb.db.query.executor.fill.IFill;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
......@@ -51,14 +50,6 @@ public class FillQueryPlan extends RawDataQueryPlan {
this.fillType = fillType;
}
@Override
public void setAlignByTime(boolean align) throws QueryProcessException {
if (!align) {
throw new QueryProcessException(
getOperatorType().name() + " doesn't support disable align clause.");
}
}
@Override
public boolean isRawQuery() {
return false;
......
......@@ -22,8 +22,6 @@ import org.apache.iotdb.db.qp.logical.Operator;
public class GroupByTimePlan extends AggregationPlan {
public static final String LACK_FUNC_ERROR_MESSAGE =
"Lack aggregation function in group by query";
// [startTime, endTime)
private long startTime;
private long endTime;
......
......@@ -20,7 +20,6 @@ package org.apache.iotdb.db.qp.physical.crud;
import org.apache.iotdb.db.exception.metadata.IllegalPathException;
import org.apache.iotdb.db.exception.metadata.MetadataException;
import org.apache.iotdb.db.exception.query.QueryProcessException;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.logical.Operator;
import org.apache.iotdb.db.qp.physical.PhysicalPlan;
......@@ -109,7 +108,7 @@ public abstract class QueryPlan extends PhysicalPlan {
return alignByTime;
}
public void setAlignByTime(boolean align) throws QueryProcessException {
public void setAlignByTime(boolean align) {
alignByTime = align;
}
......
......@@ -20,89 +20,17 @@
package org.apache.iotdb.db.qp.strategy;
import org.apache.iotdb.db.exception.query.LogicalOperatorException;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.logical.Operator;
import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
import org.apache.iotdb.db.qp.logical.crud.SelectOperator;
import org.apache.iotdb.db.query.expression.Expression;
import org.apache.iotdb.db.query.expression.ResultColumn;
import org.apache.iotdb.db.query.expression.unary.TimeSeriesOperand;
public class LogicalChecker {
/**
* TODO: make check() an abstract method and call check() in this method or outside the
* LogicalChecker.
*/
private LogicalChecker() {}
/** To check whether illegal component exists in specific operator. */
public static void check(Operator operator) throws LogicalOperatorException {
if (operator instanceof QueryOperator) {
checkQueryOperator((QueryOperator) operator);
((QueryOperator) operator).check();
}
}
private static void checkQueryOperator(QueryOperator queryOperator)
throws LogicalOperatorException {
checkSelectOperator(queryOperator);
}
private static void checkSelectOperator(QueryOperator queryOperator)
throws LogicalOperatorException {
checkLast(queryOperator);
checkAggregation(queryOperator);
checkAlignByDevice(queryOperator);
}
private static void checkLast(QueryOperator queryOperator) throws LogicalOperatorException {
SelectOperator selectOperator = queryOperator.getSelectOperator();
if (!selectOperator.isLastQuery()) {
return;
}
for (ResultColumn resultColumn : selectOperator.getResultColumns()) {
Expression expression = resultColumn.getExpression();
if (!(expression instanceof TimeSeriesOperand)) {
throw new LogicalOperatorException("Last queries can only be applied on raw time series.");
}
}
}
private static void checkAggregation(QueryOperator queryOperator)
throws LogicalOperatorException {
SelectOperator selectOperator = queryOperator.getSelectOperator();
if (!selectOperator.hasAggregationFunction()) {
return;
}
for (ResultColumn resultColumn : selectOperator.getResultColumns()) {
Expression expression = resultColumn.getExpression();
if (expression instanceof TimeSeriesOperand) {
throw new LogicalOperatorException(
"Common queries and aggregated queries are not allowed to appear at the same time");
}
}
}
private static void checkAlignByDevice(QueryOperator queryOperator)
throws LogicalOperatorException {
if (!queryOperator.isAlignByDevice()) {
return;
}
SelectOperator selectOperator = queryOperator.getSelectOperator();
if (selectOperator.hasTimeSeriesGeneratingFunction()) {
throw new LogicalOperatorException("ALIGN BY DEVICE clause is not supported in UDF queries.");
}
for (PartialPath path : selectOperator.getPaths()) {
String device = path.getDevice();
if (!device.isEmpty()) {
throw new LogicalOperatorException(
"The paths of the SELECT clause can only be single level. In other words, "
+ "the paths of the SELECT clause can only be measurements or STAR, without DOT."
+ " For more details please refer to the SQL document.");
}
}
}
private LogicalChecker() {}
}
......@@ -20,13 +20,15 @@ package org.apache.iotdb.db.qp.strategy;
import org.apache.iotdb.db.exception.metadata.IllegalPathException;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.constant.SQLConstant;
import org.apache.iotdb.db.qp.constant.FilterConstant.FilterType;
import org.apache.iotdb.db.qp.logical.Operator;
import org.apache.iotdb.db.qp.logical.crud.BasicFunctionOperator;
import org.apache.iotdb.db.qp.logical.crud.FilterOperator;
import org.apache.iotdb.db.qp.logical.crud.FromOperator;
import org.apache.iotdb.db.qp.logical.crud.FromComponent;
import org.apache.iotdb.db.qp.logical.crud.LastQueryOperator;
import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
import org.apache.iotdb.db.qp.logical.crud.SelectOperator;
import org.apache.iotdb.db.qp.logical.crud.SelectComponent;
import org.apache.iotdb.db.qp.logical.crud.WhereComponent;
import org.apache.iotdb.db.qp.sql.IoTDBSqlVisitor;
import org.apache.iotdb.db.qp.sql.SqlBaseLexer;
import org.apache.iotdb.db.qp.sql.SqlBaseParser;
......@@ -85,9 +87,9 @@ public class LogicalGenerator {
public static Operator generate(TSRawDataQueryReq rawDataQueryReq, ZoneId zoneId)
throws IllegalPathException {
// construct query operator and set its global time filter
QueryOperator queryOp = new QueryOperator(SQLConstant.TOK_QUERY);
FromOperator fromOp = new FromOperator(SQLConstant.TOK_FROM);
SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_SELECT, zoneId);
QueryOperator queryOp = new QueryOperator();
FromComponent fromOp = new FromComponent();
SelectComponent selectOp = new SelectComponent(zoneId);
// iterate the path list and add it to from operator
for (String p : rawDataQueryReq.getPaths()) {
......@@ -96,11 +98,11 @@ public class LogicalGenerator {
}
selectOp.addResultColumn(new ResultColumn(new TimeSeriesOperand(new PartialPath(""))));
queryOp.setSelectOperator(selectOp);
queryOp.setFromOperator(fromOp);
queryOp.setSelectComponent(selectOp);
queryOp.setFromComponent(fromOp);
// set time filter operator
FilterOperator filterOp = new FilterOperator(SQLConstant.KW_AND);
FilterOperator filterOp = new FilterOperator(FilterType.KW_AND);
PartialPath timePath = new PartialPath(TIME);
filterOp.setSinglePath(timePath);
Set<PartialPath> pathSet = new HashSet<>();
......@@ -110,16 +112,16 @@ public class LogicalGenerator {
BasicFunctionOperator left =
new BasicFunctionOperator(
SQLConstant.GREATERTHANOREQUALTO,
FilterType.GREATERTHANOREQUALTO,
timePath,
Long.toString(rawDataQueryReq.getStartTime()));
BasicFunctionOperator right =
new BasicFunctionOperator(
SQLConstant.LESSTHAN, timePath, Long.toString(rawDataQueryReq.getEndTime()));
FilterType.LESSTHAN, timePath, Long.toString(rawDataQueryReq.getEndTime()));
filterOp.addChildOperator(left);
filterOp.addChildOperator(right);
queryOp.setFilterOperator(filterOp);
queryOp.setWhereComponent(new WhereComponent(filterOp));
return queryOp;
}
......@@ -127,27 +129,26 @@ public class LogicalGenerator {
public static Operator generate(TSLastDataQueryReq req, ZoneId zoneId)
throws IllegalPathException {
// construct query operator and set its global time filter
SelectOperator selectOp = new SelectOperator(SQLConstant.TOK_SELECT, zoneId);
FromOperator fromOp = new FromOperator(SQLConstant.TOK_FROM);
QueryOperator queryOp = new QueryOperator(SQLConstant.TOK_QUERY);
LastQueryOperator queryOp = new LastQueryOperator();
FromComponent fromOp = new FromComponent();
SelectComponent selectOp = new SelectComponent(zoneId);
selectOp.addResultColumn(new ResultColumn(new TimeSeriesOperand(new PartialPath(""))));
selectOp.markAsLastQuery();
for (String p : req.getPaths()) {
PartialPath path = new PartialPath(p);
fromOp.addPrefixTablePath(path);
}
queryOp.setSelectOperator(selectOp);
queryOp.setFromOperator(fromOp);
queryOp.setSelectComponent(selectOp);
queryOp.setFromComponent(fromOp);
PartialPath timePath = new PartialPath(TIME);
BasicFunctionOperator basicFunctionOperator =
new BasicFunctionOperator(
SQLConstant.GREATERTHANOREQUALTO, timePath, Long.toString(req.getTime()));
queryOp.setFilterOperator(basicFunctionOperator);
FilterType.GREATERTHANOREQUALTO, timePath, Long.toString(req.getTime()));
queryOp.setWhereComponent(new WhereComponent(basicFunctionOperator));
return queryOp;
}
......
......@@ -30,9 +30,18 @@ import org.apache.iotdb.db.qp.logical.Operator;
import org.apache.iotdb.db.qp.logical.Operator.OperatorType;
import org.apache.iotdb.db.qp.logical.crud.BasicFunctionOperator;
import org.apache.iotdb.db.qp.logical.crud.DeleteDataOperator;
import org.apache.iotdb.db.qp.logical.crud.FillClauseComponent;
import org.apache.iotdb.db.qp.logical.crud.FillQueryOperator;
import org.apache.iotdb.db.qp.logical.crud.FilterOperator;
import org.apache.iotdb.db.qp.logical.crud.GroupByClauseComponent;
import org.apache.iotdb.db.qp.logical.crud.GroupByFillClauseComponent;
import org.apache.iotdb.db.qp.logical.crud.GroupByFillQueryOperator;
import org.apache.iotdb.db.qp.logical.crud.GroupByQueryOperator;
import org.apache.iotdb.db.qp.logical.crud.InsertOperator;
import org.apache.iotdb.db.qp.logical.crud.LastQueryOperator;
import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
import org.apache.iotdb.db.qp.logical.crud.SpecialClauseComponent;
import org.apache.iotdb.db.qp.logical.crud.WhereComponent;
import org.apache.iotdb.db.qp.logical.sys.AlterTimeSeriesOperator;
import org.apache.iotdb.db.qp.logical.sys.AuthorOperator;
import org.apache.iotdb.db.qp.logical.sys.CountOperator;
......@@ -476,41 +485,45 @@ public class PhysicalGenerator {
throw new QueryProcessException(
"User-defined and built-in hybrid aggregation is not supported.");
}
if (queryOperator.isGroupByTime() && queryOperator.isFill()) {
if (queryOperator instanceof GroupByFillQueryOperator) {
queryPlan = new GroupByTimeFillPlan();
} else if (queryOperator.isGroupByTime()) {
} else if (queryOperator instanceof GroupByQueryOperator) {
queryPlan = new GroupByTimePlan();
} else {
queryPlan = new AggregationPlan();
}
queryPlan.setPaths(queryOperator.getSelectOperator().getPaths());
queryPlan.setAggregations(queryOperator.getSelectOperator().getAggregationFunctions());
queryPlan.setPaths(queryOperator.getSelectComponent().getPaths());
queryPlan.setAggregations(queryOperator.getSelectComponent().getAggregationFunctions());
if (queryOperator.isGroupByTime()) {
if (queryOperator instanceof GroupByQueryOperator) {
GroupByTimePlan groupByTimePlan = (GroupByTimePlan) queryPlan;
groupByTimePlan.setInterval(queryOperator.getUnit());
groupByTimePlan.setIntervalByMonth(queryOperator.isIntervalByMonth());
groupByTimePlan.setSlidingStep(queryOperator.getSlidingStep());
groupByTimePlan.setSlidingStepByMonth(queryOperator.isSlidingStepByMonth());
groupByTimePlan.setLeftCRightO(queryOperator.isLeftCRightO());
if (!queryOperator.isLeftCRightO()) {
groupByTimePlan.setStartTime(queryOperator.getStartTime() + 1);
groupByTimePlan.setEndTime(queryOperator.getEndTime() + 1);
GroupByClauseComponent groupByClauseComponent =
(GroupByClauseComponent) queryOperator.getSpecialClauseComponent();
groupByTimePlan.setInterval(groupByClauseComponent.getUnit());
groupByTimePlan.setIntervalByMonth(groupByClauseComponent.isIntervalByMonth());
groupByTimePlan.setSlidingStep(groupByClauseComponent.getSlidingStep());
groupByTimePlan.setSlidingStepByMonth(groupByClauseComponent.isSlidingStepByMonth());
groupByTimePlan.setLeftCRightO(groupByClauseComponent.isLeftCRightO());
if (!groupByClauseComponent.isLeftCRightO()) {
groupByTimePlan.setStartTime(groupByClauseComponent.getStartTime() + 1);
groupByTimePlan.setEndTime(groupByClauseComponent.getEndTime() + 1);
} else {
groupByTimePlan.setStartTime(queryOperator.getStartTime());
groupByTimePlan.setEndTime(queryOperator.getEndTime());
groupByTimePlan.setStartTime(groupByClauseComponent.getStartTime());
groupByTimePlan.setEndTime(groupByClauseComponent.getEndTime());
}
}
if (queryOperator.isFill()) {
((GroupByTimeFillPlan) queryPlan).setFillType(queryOperator.getFillTypes());
if (queryOperator instanceof GroupByFillQueryOperator) {
GroupByFillClauseComponent groupByFillClauseComponent =
(GroupByFillClauseComponent) queryOperator.getSpecialClauseComponent();
((GroupByTimeFillPlan) queryPlan).setFillType(groupByFillClauseComponent.getFillTypes());
for (String aggregation : queryPlan.getAggregations()) {
if (!SQLConstant.LAST_VALUE.equals(aggregation)) {
throw new QueryProcessException("Group By Fill only support last_value function");
}
}
} else if (queryOperator.isGroupByLevel()) {
queryPlan.setLevel(queryOperator.getLevel());
queryPlan.setLevel(queryOperator.getSpecialClauseComponent().getLevel());
try {
if (!verifyAllAggregationDataTypesEqual(queryOperator)) {
throw new QueryProcessException("Aggregate among unmatched data types");
......@@ -528,17 +541,19 @@ public class PhysicalGenerator {
@Override
public QueryPlan transform(QueryOperator queryOperator) throws QueryProcessException {
FillQueryOperator fillQueryOperator = (FillQueryOperator) queryOperator;
if (queryOperator.hasTimeSeriesGeneratingFunction()) {
throw new QueryProcessException("Fill functions are not supported in UDF queries.");
}
FillQueryPlan queryPlan = new FillQueryPlan();
FilterOperator timeFilter = queryOperator.getFilterOperator();
FilterOperator timeFilter = fillQueryOperator.getWhereComponent().getFilterOperator();
if (!timeFilter.isSingle()) {
throw new QueryProcessException("Slice query must select a single time point");
}
long time = Long.parseLong(((BasicFunctionOperator) timeFilter).getValue());
queryPlan.setQueryTime(time);
queryPlan.setFillType(queryOperator.getFillTypes());
queryPlan.setFillType(
((FillClauseComponent) fillQueryOperator.getSpecialClauseComponent()).getFillTypes());
return queryPlan;
}
}
......@@ -549,24 +564,25 @@ public class PhysicalGenerator {
if (queryOperator.hasAggregationFunction()) {
queryPlan = new AggPhysicalPlanRule().transform(queryOperator);
} else if (queryOperator.isFill()) {
} else if (queryOperator instanceof FillQueryOperator) {
queryPlan = new FillPhysicalPlanRule().transform(queryOperator);
} else if (queryOperator.isLastQuery()) {
} else if (queryOperator instanceof LastQueryOperator) {
queryPlan = new LastQueryPlan();
} else if (queryOperator.getIndexType() != null) {
queryPlan = new QueryIndexPlan();
} else if (queryOperator.hasTimeSeriesGeneratingFunction()) {
queryPlan = new UDTFPlan(queryOperator.getSelectOperator().getZoneId());
queryPlan = new UDTFPlan(queryOperator.getSelectComponent().getZoneId());
((UDTFPlan) queryPlan)
.constructUdfExecutors(queryOperator.getSelectOperator().getResultColumns());
.constructUdfExecutors(queryOperator.getSelectComponent().getResultColumns());
} else {
queryPlan = new RawDataQueryPlan();
}
if (queryOperator.isAlignByDevice()) {
if (queryOperator.getSpecialClauseComponent() != null
&& queryOperator.getSpecialClauseComponent().isAlignByDevice()) {
queryPlan = getAlignQueryPlan(queryOperator, queryPlan);
} else {
queryPlan.setPaths(queryOperator.getSelectOperator().getPaths());
queryPlan.setPaths(queryOperator.getSelectComponent().getPaths());
// Last query result set will not be affected by alignment
if (queryPlan instanceof LastQueryPlan && !queryOperator.isAlignByTime()) {
throw new QueryProcessException("Disable align cannot be applied to LAST query.");
......@@ -574,9 +590,10 @@ public class PhysicalGenerator {
queryPlan.setAlignByTime(queryOperator.isAlignByTime());
// transform filter operator to expression
FilterOperator filterOperator = queryOperator.getFilterOperator();
WhereComponent whereComponent = queryOperator.getWhereComponent();
if (filterOperator != null) {
if (whereComponent != null) {
FilterOperator filterOperator = whereComponent.getFilterOperator();
List<PartialPath> filterPaths = new ArrayList<>(filterOperator.getPathSet());
try {
List<TSDataType> seriesTypes = getSeriesTypes(filterPaths);
......@@ -593,9 +610,6 @@ public class PhysicalGenerator {
}
}
queryPlan.setWithoutAllNull(queryOperator.isWithoutAllNull());
queryPlan.setWithoutAnyNull(queryOperator.isWithoutAnyNull());
if (queryOperator.getIndexType() != null) {
if (queryPlan instanceof QueryIndexPlan) {
((QueryIndexPlan) queryPlan).setIndexType(queryOperator.getIndexType());
......@@ -604,7 +618,7 @@ public class PhysicalGenerator {
return queryPlan;
}
queryPlan.setResultColumns(queryOperator.getSelectOperator().getResultColumns());
queryPlan.setResultColumns(queryOperator.getSelectComponent().getResultColumns());
try {
List<PartialPath> paths = queryPlan.getPaths();
......@@ -616,9 +630,14 @@ public class PhysicalGenerator {
throw new QueryProcessException(e);
}
queryPlan.setRowLimit(queryOperator.getRowLimit());
queryPlan.setRowOffset(queryOperator.getRowOffset());
queryPlan.setAscending(queryOperator.isAscending());
if (queryOperator.getSpecialClauseComponent() != null) {
SpecialClauseComponent specialClauseComponent = queryOperator.getSpecialClauseComponent();
queryPlan.setWithoutAllNull(specialClauseComponent.isWithoutAllNull());
queryPlan.setWithoutAnyNull(specialClauseComponent.isWithoutAnyNull());
queryPlan.setRowLimit(specialClauseComponent.getRowLimit());
queryPlan.setRowOffset(specialClauseComponent.getRowOffset());
queryPlan.setAscending(specialClauseComponent.isAscending());
}
return queryPlan;
}
......@@ -639,11 +658,11 @@ public class PhysicalGenerator {
alignByDevicePlan.setAggregationPlan((AggregationPlan) queryPlan);
}
List<PartialPath> prefixPaths = queryOperator.getFromOperator().getPrefixPaths();
List<PartialPath> prefixPaths = queryOperator.getFromComponent().getPrefixPaths();
// remove stars in fromPaths and get deviceId with deduplication
List<PartialPath> devices = this.removeStarsInDeviceWithUnique(prefixPaths);
List<ResultColumn> resultColumns = queryOperator.getSelectOperator().getResultColumns();
List<String> originAggregations = queryOperator.getSelectOperator().getAggregationFunctions();
List<ResultColumn> resultColumns = queryOperator.getSelectComponent().getResultColumns();
List<String> originAggregations = queryOperator.getSelectComponent().getAggregationFunctions();
// to record result measurement columns
List<String> measurements = new ArrayList<>();
......@@ -776,9 +795,9 @@ public class PhysicalGenerator {
}
// slimit trim on the measurementColumnList
if (queryOperator.hasSlimit()) {
int seriesSlimit = queryOperator.getSeriesLimit();
int seriesOffset = queryOperator.getSeriesOffset();
if (queryOperator.getSpecialClauseComponent().hasSlimit()) {
int seriesSlimit = queryOperator.getSpecialClauseComponent().getSeriesLimit();
int seriesOffset = queryOperator.getSpecialClauseComponent().getSeriesOffset();
measurements = slimitTrimColumn(measurements, seriesSlimit, seriesOffset);
}
......@@ -792,9 +811,10 @@ public class PhysicalGenerator {
alignByDevicePlan.setPaths(paths);
// get deviceToFilterMap
FilterOperator filterOperator = queryOperator.getFilterOperator();
if (filterOperator != null) {
alignByDevicePlan.setDeviceToFilterMap(concatFilterByDevice(devices, filterOperator));
WhereComponent whereComponent = queryOperator.getWhereComponent();
if (whereComponent != null) {
alignByDevicePlan.setDeviceToFilterMap(
concatFilterByDevice(devices, whereComponent.getFilterOperator()));
}
queryPlan = alignByDevicePlan;
......@@ -895,12 +915,12 @@ public class PhysicalGenerator {
private static boolean verifyAllAggregationDataTypesEqual(QueryOperator queryOperator)
throws MetadataException {
List<String> aggregations = queryOperator.getSelectOperator().getAggregationFunctions();
List<String> aggregations = queryOperator.getSelectComponent().getAggregationFunctions();
if (aggregations.isEmpty()) {
return true;
}
List<PartialPath> paths = queryOperator.getSelectOperator().getPaths();
List<PartialPath> paths = queryOperator.getSelectComponent().getPaths();
List<TSDataType> dataTypes = SchemaUtils.getSeriesTypesByPaths(paths);
String aggType = aggregations.get(0);
switch (aggType) {
......
......@@ -23,14 +23,16 @@ import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
import org.apache.iotdb.db.exception.query.PathNumOverLimitException;
import org.apache.iotdb.db.exception.runtime.SQLParserException;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.constant.FilterConstant.FilterType;
import org.apache.iotdb.db.qp.constant.SQLConstant;
import org.apache.iotdb.db.qp.logical.Operator;
import org.apache.iotdb.db.qp.logical.crud.BasicFunctionOperator;
import org.apache.iotdb.db.qp.logical.crud.FilterOperator;
import org.apache.iotdb.db.qp.logical.crud.FromOperator;
import org.apache.iotdb.db.qp.logical.crud.FromComponent;
import org.apache.iotdb.db.qp.logical.crud.FunctionOperator;
import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
import org.apache.iotdb.db.qp.logical.crud.SelectOperator;
import org.apache.iotdb.db.qp.logical.crud.SelectComponent;
import org.apache.iotdb.db.qp.logical.crud.WhereComponent;
import org.apache.iotdb.db.qp.utils.WildcardsRemover;
import org.apache.iotdb.db.query.expression.ResultColumn;
import org.apache.iotdb.db.service.IoTDB;
......@@ -71,13 +73,13 @@ public class ConcatPathOptimizer implements ILogicalOptimizer {
return false;
}
SelectOperator select = queryOperator.getSelectOperator();
SelectComponent select = queryOperator.getSelectComponent();
if (select == null || select.getResultColumns().isEmpty()) {
LOGGER.warn(WARNING_NO_SUFFIX_PATHS);
return false;
}
FromOperator from = queryOperator.getFromOperator();
FromComponent from = queryOperator.getFromComponent();
if (from == null || from.getPrefixPaths().isEmpty()) {
LOGGER.warn(WARNING_NO_PREFIX_PATHS);
return false;
......@@ -87,12 +89,12 @@ public class ConcatPathOptimizer implements ILogicalOptimizer {
}
private void concatSelect(QueryOperator queryOperator) throws LogicalOptimizeException {
List<PartialPath> prefixPaths = queryOperator.getFromOperator().getPrefixPaths();
List<PartialPath> prefixPaths = queryOperator.getFromComponent().getPrefixPaths();
List<ResultColumn> resultColumns = new ArrayList<>();
for (ResultColumn suffixColumn : queryOperator.getSelectOperator().getResultColumns()) {
for (ResultColumn suffixColumn : queryOperator.getSelectComponent().getResultColumns()) {
suffixColumn.concat(prefixPaths, resultColumns);
}
queryOperator.getSelectOperator().setResultColumns(resultColumns);
queryOperator.getSelectComponent().setResultColumns(resultColumns);
}
private void removeWildcardsInSelectPaths(QueryOperator queryOperator, int fetchSize)
......@@ -103,28 +105,30 @@ public class ConcatPathOptimizer implements ILogicalOptimizer {
WildcardsRemover wildcardsRemover = new WildcardsRemover(queryOperator, fetchSize);
List<ResultColumn> resultColumns = new ArrayList<>();
for (ResultColumn resultColumn : queryOperator.getSelectOperator().getResultColumns()) {
for (ResultColumn resultColumn : queryOperator.getSelectComponent().getResultColumns()) {
resultColumn.removeWildcards(wildcardsRemover, resultColumns);
if (wildcardsRemover.checkIfPathNumberIsOverLimit(resultColumns)) {
break;
}
}
wildcardsRemover.checkIfSoffsetIsExceeded(resultColumns);
queryOperator.getSelectOperator().setResultColumns(resultColumns);
queryOperator.getSelectComponent().setResultColumns(resultColumns);
}
private void concatFilterAndRemoveWildcards(QueryOperator queryOperator)
throws LogicalOptimizeException {
FilterOperator filter = queryOperator.getFilterOperator();
if (filter == null) {
WhereComponent whereComponent = queryOperator.getWhereComponent();
if (whereComponent == null) {
return;
}
Set<PartialPath> filterPaths = new HashSet<>();
queryOperator.setFilterOperator(
whereComponent.setFilterOperator(
concatFilterAndRemoveWildcards(
queryOperator.getFromOperator().getPrefixPaths(), filter, filterPaths));
queryOperator.getFilterOperator().setPathSet(filterPaths);
queryOperator.getFromComponent().getPrefixPaths(),
whereComponent.getFilterOperator(),
filterPaths));
whereComponent.getFilterOperator().setPathSet(filterPaths);
}
private FilterOperator concatFilterAndRemoveWildcards(
......@@ -167,18 +171,18 @@ public class ConcatPathOptimizer implements ILogicalOptimizer {
private FilterOperator constructBinaryFilterTreeWithAnd(
List<PartialPath> noStarPaths, FilterOperator operator) throws LogicalOptimizeException {
FilterOperator filterBinaryTree = new FilterOperator(SQLConstant.KW_AND);
FilterOperator filterBinaryTree = new FilterOperator(FilterType.KW_AND);
FilterOperator currentNode = filterBinaryTree;
for (int i = 0; i < noStarPaths.size(); i++) {
if (i > 0 && i < noStarPaths.size() - 1) {
FilterOperator newInnerNode = new FilterOperator(SQLConstant.KW_AND);
FilterOperator newInnerNode = new FilterOperator(FilterType.KW_AND);
currentNode.addChildOperator(newInnerNode);
currentNode = newInnerNode;
}
try {
currentNode.addChildOperator(
new BasicFunctionOperator(
operator.getTokenIntType(),
operator.getFilterType(),
noStarPaths.get(i),
((BasicFunctionOperator) operator).getValue()));
} catch (SQLParserException e) {
......
......@@ -19,14 +19,12 @@
package org.apache.iotdb.db.qp.strategy.optimizer;
import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
import org.apache.iotdb.db.qp.constant.FilterConstant.FilterType;
import org.apache.iotdb.db.qp.logical.crud.FilterOperator;
import java.util.ArrayList;
import java.util.List;
import static org.apache.iotdb.db.qp.constant.SQLConstant.KW_AND;
import static org.apache.iotdb.db.qp.constant.SQLConstant.KW_OR;
public class DnfFilterOptimizer implements IFilterOptimizer {
/**
......@@ -61,28 +59,28 @@ public class DnfFilterOptimizer implements IFilterOptimizer {
List<FilterOperator> childOperators = filter.getChildren();
if (childOperators.size() != 2) {
throw new LogicalOptimizeException(
"node :" + filter.getTokenName() + " has " + childOperators.size() + " children");
"node :" + filter.getFilterName() + " has " + childOperators.size() + " children");
}
FilterOperator left = getDnf(childOperators.get(0));
FilterOperator right = getDnf(childOperators.get(1));
List<FilterOperator> newChildrenList = new ArrayList<>();
switch (filter.getTokenIntType()) {
switch (filter.getFilterType()) {
case KW_OR:
addChildOpInOr(left, newChildrenList);
addChildOpInOr(right, newChildrenList);
break;
case KW_AND:
if (left.getTokenIntType() != KW_OR && right.getTokenIntType() != KW_OR) {
if (left.getFilterType() != FilterType.KW_OR && right.getFilterType() != FilterType.KW_OR) {
addChildOpInAnd(left, newChildrenList);
addChildOpInAnd(right, newChildrenList);
} else {
dealWithLeftAndRightAndChildren(getAndChild(left), getAndChild(right), newChildrenList);
filter.setTokenIntType(KW_OR);
filter.setFilterType(FilterType.KW_OR);
}
break;
default:
throw new LogicalOptimizeException(
"get DNF failed, this tokenType is:" + filter.getTokenIntType());
"get DNF failed, this tokenType is:" + filter.getFilterType());
}
filter.setChildren(newChildrenList);
return filter;
......@@ -104,7 +102,7 @@ public class DnfFilterOptimizer implements IFilterOptimizer {
List<FilterOperator> retChildrenList = new ArrayList<>();
addChildOpInAnd(operator1, retChildrenList);
addChildOpInAnd(operator2, retChildrenList);
FilterOperator ret = new FilterOperator(KW_AND, false);
FilterOperator ret = new FilterOperator(FilterType.KW_AND, false);
ret.setChildren(retChildrenList);
return ret;
}
......@@ -118,7 +116,7 @@ public class DnfFilterOptimizer implements IFilterOptimizer {
* @return children operator
*/
private List<FilterOperator> getAndChild(FilterOperator child) {
if (child.getTokenIntType() == KW_OR) {
if (child.getFilterType() == FilterType.KW_OR) {
return child.getChildren();
} else {
// other token type means leaf node or and
......@@ -140,7 +138,7 @@ public class DnfFilterOptimizer implements IFilterOptimizer {
throws LogicalOptimizeException {
if (operator.isLeaf()) {
newChildrenList.add(operator);
} else if (operator.getTokenIntType() == KW_AND) {
} else if (operator.getFilterType() == FilterType.KW_AND) {
newChildrenList.addAll(operator.getChildren());
} else {
throw new LogicalOptimizeException(
......@@ -156,7 +154,7 @@ public class DnfFilterOptimizer implements IFilterOptimizer {
* @param newChildrenList new children list
*/
private void addChildOpInOr(FilterOperator operator, List<FilterOperator> newChildrenList) {
if (operator.isLeaf() || operator.getTokenIntType() == KW_AND) {
if (operator.isLeaf() || operator.getFilterType() == FilterType.KW_AND) {
newChildrenList.add(operator);
} else {
newChildrenList.addAll(operator.getChildren());
......
......@@ -124,7 +124,7 @@ public class MergeSingleFilterOptimizer implements IFilterOptimizer {
childPath = tempPath;
} else {
// add a new inner node
FilterOperator newFilter = new FilterOperator(filter.getTokenIntType(), true);
FilterOperator newFilter = new FilterOperator(filter.getFilterType(), true);
newFilter.setSinglePath(childPath);
newFilter.setChildren(tempExtrNode);
ret.add(newFilter);
......@@ -140,7 +140,7 @@ public class MergeSingleFilterOptimizer implements IFilterOptimizer {
ret.add(tempExtrNode.get(0));
} else {
// add a new inner node
FilterOperator newFil = new FilterOperator(filter.getTokenIntType(), true);
FilterOperator newFil = new FilterOperator(filter.getFilterType(), true);
newFil.setSinglePath(childPath);
newFil.setChildren(tempExtrNode);
ret.add(newFil);
......
......@@ -21,17 +21,14 @@ package org.apache.iotdb.db.qp.strategy.optimizer;
import org.apache.iotdb.db.exception.query.LogicalOperatorException;
import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.constant.SQLConstant;
import org.apache.iotdb.db.qp.constant.FilterConstant;
import org.apache.iotdb.db.qp.constant.FilterConstant.FilterType;
import org.apache.iotdb.db.qp.logical.crud.FilterOperator;
import org.apache.iotdb.db.qp.logical.crud.FunctionOperator;
import java.util.List;
import java.util.Set;
import static org.apache.iotdb.db.qp.constant.SQLConstant.KW_AND;
import static org.apache.iotdb.db.qp.constant.SQLConstant.KW_NOT;
import static org.apache.iotdb.db.qp.constant.SQLConstant.KW_OR;
public class RemoveNotOptimizer implements IFilterOptimizer {
/**
......@@ -53,8 +50,8 @@ public class RemoveNotOptimizer implements IFilterOptimizer {
if (filter.isLeaf()) {
return filter;
}
int tokenInt = filter.getTokenIntType();
switch (tokenInt) {
FilterType filterType = filter.getFilterType();
switch (filterType) {
case KW_AND:
case KW_OR:
// replace children in-place for efficiency
......@@ -73,7 +70,7 @@ public class RemoveNotOptimizer implements IFilterOptimizer {
}
return reverseFilter(filter.getChildren().get(0));
default:
throw new LogicalOptimizeException("removeNot", tokenInt);
throw new LogicalOptimizeException("removeNot", filterType);
}
}
......@@ -85,23 +82,23 @@ public class RemoveNotOptimizer implements IFilterOptimizer {
* @throws LogicalOptimizeException exception in reverse filter
*/
private FilterOperator reverseFilter(FilterOperator filter) throws LogicalOperatorException {
int tokenInt = filter.getTokenIntType();
FilterType filterType = filter.getFilterType();
if (filter.isLeaf()) {
((FunctionOperator) filter).reverseFunc();
return filter;
}
switch (tokenInt) {
switch (filterType) {
case KW_AND:
case KW_OR:
List<FilterOperator> children = filter.getChildren();
children.set(0, reverseFilter(children.get(0)));
children.set(1, reverseFilter(children.get(1)));
filter.setTokenIntType(SQLConstant.reverseWords.get(tokenInt));
filter.setFilterType(FilterConstant.filterReverseWords.get(filterType));
return filter;
case KW_NOT:
return removeNot(filter.getChildren().get(0));
default:
throw new LogicalOptimizeException("reverseFilter", tokenInt);
throw new LogicalOptimizeException("reverseFilter", filterType);
}
}
}
......@@ -23,6 +23,7 @@ import org.apache.iotdb.db.exception.metadata.MetadataException;
import org.apache.iotdb.db.exception.query.LogicalOptimizeException;
import org.apache.iotdb.db.exception.query.PathNumOverLimitException;
import org.apache.iotdb.db.metadata.PartialPath;
import org.apache.iotdb.db.qp.logical.crud.LastQueryOperator;
import org.apache.iotdb.db.qp.logical.crud.QueryOperator;
import org.apache.iotdb.db.qp.strategy.optimizer.ConcatPathOptimizer;
import org.apache.iotdb.db.query.control.QueryResourceManager;
......@@ -39,13 +40,13 @@ import java.util.List;
public class WildcardsRemover {
private final int maxDeduplicatedPathNum;
private final int soffset;
private int soffset = 0;
private int currentOffset;
private int currentLimit;
private int currentOffset = 0;
private int currentLimit = Integer.MAX_VALUE;
/** Records the path number that the MManager totally returned. */
private int consumed;
private int consumed = 0;
public WildcardsRemover(QueryOperator queryOperator, int fetchSize) {
// Dataset of last query actually has only three columns, so we shouldn't limit the path num
......@@ -53,24 +54,21 @@ public class WildcardsRemover {
// To avoid overflowing because logicalOptimize function may do maxDeduplicatedPathNum + 1, we
// set it to Integer.MAX_VALUE - 1
maxDeduplicatedPathNum =
queryOperator.isLastQuery()
queryOperator instanceof LastQueryOperator
? Integer.MAX_VALUE - 1
: QueryResourceManager.getInstance().getMaxDeduplicatedPathNum(fetchSize);
soffset = queryOperator.getSeriesOffset();
currentOffset = soffset;
if (queryOperator.getSpecialClauseComponent() != null) {
soffset = queryOperator.getSpecialClauseComponent().getSeriesOffset();
currentOffset = soffset;
final int slimit = queryOperator.getSeriesLimit();
currentLimit =
slimit == 0 || maxDeduplicatedPathNum < slimit ? maxDeduplicatedPathNum + 1 : slimit;
consumed = 0;
final int slimit = queryOperator.getSpecialClauseComponent().getSeriesLimit();
currentLimit =
slimit == 0 || maxDeduplicatedPathNum < slimit ? maxDeduplicatedPathNum + 1 : slimit;
}
}
public WildcardsRemover() {
maxDeduplicatedPathNum = Integer.MAX_VALUE - 1;
soffset = 0;
currentLimit = maxDeduplicatedPathNum + 1;
consumed = 0;
}
public List<PartialPath> removeWildcardFrom(PartialPath path) throws LogicalOptimizeException {
......
......@@ -21,7 +21,7 @@ package org.apache.iotdb.db.integration;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
import org.apache.iotdb.db.engine.compaction.CompactionStrategy;
import org.apache.iotdb.db.qp.physical.crud.GroupByTimePlan;
import org.apache.iotdb.db.qp.logical.crud.AggregationQueryOperator;
import org.apache.iotdb.db.utils.EnvironmentUtils;
import org.apache.iotdb.jdbc.Config;
......@@ -946,7 +946,7 @@ public class IOTDBGroupByIT {
fail("No expected exception thrown");
} catch (Exception e) {
Assert.assertTrue(e.getMessage().contains(GroupByTimePlan.LACK_FUNC_ERROR_MESSAGE));
Assert.assertTrue(e.getMessage().contains(AggregationQueryOperator.ERROR_MESSAGE1));
}
}
......
......@@ -351,12 +351,11 @@ public class IoTDBDisableAlignIT {
DriverManager.getConnection(
Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
Statement statement = connection.createStatement()) {
boolean hasResultSet =
statement.execute(
"select * from root.vehicle where time = 3 Fill(int32[previous, 5ms]) disable align");
statement.execute(
"select * from root.vehicle where time = 3 Fill(int32[previous, 5ms]) disable align");
fail("No exception thrown.");
} catch (Exception e) {
Assert.assertTrue(e.getMessage().contains("FILL doesn't support disable align clause."));
Assert.assertTrue(e.getMessage().contains("doesn't support disable align clause."));
}
}
......@@ -367,13 +366,10 @@ public class IoTDBDisableAlignIT {
DriverManager.getConnection(
Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
Statement statement = connection.createStatement()) {
boolean hasResultSet =
statement.execute(
"select count(*) from root.vehicle GROUP BY ([2,50),20ms) disable align");
statement.execute("select count(*) from root.vehicle GROUP BY ([2,50),20ms) disable align");
fail("No exception thrown.");
} catch (Exception e) {
Assert.assertTrue(
e.getMessage().contains("GROUPBYTIME doesn't support disable align clause."));
Assert.assertTrue(e.getMessage().contains("doesn't support disable align clause."));
}
}
......@@ -384,11 +380,10 @@ public class IoTDBDisableAlignIT {
DriverManager.getConnection(
Config.IOTDB_URL_PREFIX + "127.0.0.1:6667/", "root", "root");
Statement statement = connection.createStatement()) {
boolean hasResultSet = statement.execute("select count(*) from root disable align");
statement.execute("select count(*) from root disable align");
fail("No exception thrown.");
} catch (Exception e) {
Assert.assertTrue(
e.getMessage().contains("AGGREGATION doesn't support disable align clause."));
Assert.assertTrue(e.getMessage().contains("doesn't support disable align clause."));
}
}
......
......@@ -19,7 +19,7 @@
package org.apache.iotdb.db.integration;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
import org.apache.iotdb.db.qp.physical.crud.GroupByTimePlan;
import org.apache.iotdb.db.qp.logical.crud.AggregationQueryOperator;
import org.apache.iotdb.db.utils.EnvironmentUtils;
import org.apache.iotdb.jdbc.Config;
import org.apache.iotdb.jdbc.IoTDBSQLException;
......@@ -526,7 +526,7 @@ public class IoTDBGroupByFillIT {
hasResultSet =
statement.execute(
"select last_value(temperature) from root.ln.wf01.wt01 "
+ "GROUP BY ([2, 48), 5ms) FILL(int32[previousUntilLast])order by time desc");
+ "GROUP BY ([2, 48), 5ms) FILL(int32[previousUntilLast]) order by time desc");
assertTrue(hasResultSet);
try (ResultSet resultSet = statement.getResultSet()) {
......@@ -804,7 +804,7 @@ public class IoTDBGroupByFillIT {
fail("No expected exception thrown");
} catch (Exception e) {
Assert.assertTrue(e.getMessage().contains(GroupByTimePlan.LACK_FUNC_ERROR_MESSAGE));
Assert.assertTrue(e.getMessage().contains(AggregationQueryOperator.ERROR_MESSAGE1));
}
}
......
......@@ -20,7 +20,7 @@ package org.apache.iotdb.db.integration.aggregation;
import org.apache.iotdb.db.constant.TestConstant;
import org.apache.iotdb.db.qp.Planner;
import org.apache.iotdb.db.qp.physical.crud.GroupByTimePlan;
import org.apache.iotdb.db.qp.logical.crud.AggregationQueryOperator;
import org.apache.iotdb.db.utils.EnvironmentUtils;
import org.apache.iotdb.jdbc.Config;
......@@ -339,7 +339,7 @@ public class IoTDBAggregationByLevelIT {
fail("No expected exception thrown");
} catch (Exception e) {
Assert.assertTrue(e.getMessage().contains(GroupByTimePlan.LACK_FUNC_ERROR_MESSAGE));
Assert.assertTrue(e.getMessage().contains(AggregationQueryOperator.ERROR_MESSAGE1));
}
}
......
......@@ -108,9 +108,12 @@ public class IndexLogicalPlanTest {
Assert.assertEquals(OperatorType.QUERY, queryOperator.getType());
Assert.assertEquals(
"Glu",
queryOperator.getSelectOperator().getResultColumns().get(0).getExpression().toString());
queryOperator.getSelectComponent().getResultColumns().get(0).getExpression().toString());
Assert.assertEquals(
"root.Ery.*", queryOperator.getFromOperator().getPrefixPaths().get(0).getFullPath());
"Glu",
queryOperator.getSelectComponent().getResultColumns().get(0).getExpression().toString());
Assert.assertEquals(
"root.Ery.*", queryOperator.getFromComponent().getPrefixPaths().get(0).getFullPath());
Assert.assertEquals(IndexType.RTREE_PAA, queryOperator.getIndexType());
Assert.assertEquals(2, queryOperator.getProps().size());
Assert.assertEquals(2, (int) queryOperator.getProps().get(TOP_K));
......@@ -132,9 +135,12 @@ public class IndexLogicalPlanTest {
Assert.assertEquals(OperatorType.QUERY, queryOperator.getType());
Assert.assertEquals(
"Speed",
queryOperator.getSelectOperator().getResultColumns().get(0).getExpression().toString());
queryOperator.getSelectComponent().getResultColumns().get(0).getExpression().toString());
Assert.assertEquals(
"Speed",
queryOperator.getSelectComponent().getResultColumns().get(0).getExpression().toString());
Assert.assertEquals(
"root.Wind.AZQ02", queryOperator.getFromOperator().getPrefixPaths().get(0).getFullPath());
"root.Wind.AZQ02", queryOperator.getFromComponent().getPrefixPaths().get(0).getFullPath());
Assert.assertEquals(IndexType.ELB_INDEX, queryOperator.getIndexType());
Assert.assertEquals(2, queryOperator.getProps().size());
Assert.assertEquals("[1.0, 2.0, 1.0]", queryOperator.getProps().get(THRESHOLD).toString());
......
......@@ -43,79 +43,77 @@ public class LogicalPlanSmallTest {
@Test
public void testLimit() {
String sqlStr = "select * from root.vehicle.d1 limit 10";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
QueryOperator operator =
(QueryOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
Assert.assertEquals(QueryOperator.class, operator.getClass());
Assert.assertEquals(10, ((QueryOperator) operator).getRowLimit());
Assert.assertEquals(0, ((QueryOperator) operator).getRowOffset());
Assert.assertEquals(0, ((QueryOperator) operator).getSeriesLimit());
Assert.assertEquals(0, ((QueryOperator) operator).getSeriesOffset());
Assert.assertEquals(10, operator.getSpecialClauseComponent().getRowLimit());
Assert.assertEquals(0, operator.getSpecialClauseComponent().getRowOffset());
Assert.assertEquals(0, operator.getSpecialClauseComponent().getSeriesLimit());
Assert.assertEquals(0, operator.getSpecialClauseComponent().getSeriesOffset());
}
@Test
public void testOffset() {
String sqlStr = "select * from root.vehicle.d1 limit 10 offset 20";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
QueryOperator operator =
(QueryOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
Assert.assertEquals(QueryOperator.class, operator.getClass());
Assert.assertEquals(10, ((QueryOperator) operator).getRowLimit());
Assert.assertEquals(20, ((QueryOperator) operator).getRowOffset());
Assert.assertEquals(0, ((QueryOperator) operator).getSeriesLimit());
Assert.assertEquals(0, ((QueryOperator) operator).getSeriesOffset());
Assert.assertEquals(10, operator.getSpecialClauseComponent().getRowLimit());
Assert.assertEquals(20, operator.getSpecialClauseComponent().getRowOffset());
Assert.assertEquals(0, operator.getSpecialClauseComponent().getSeriesLimit());
Assert.assertEquals(0, operator.getSpecialClauseComponent().getSeriesOffset());
}
@Test
public void testSlimit() {
String sqlStr = "select * from root.vehicle.d1 limit 10 slimit 1";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
QueryOperator operator =
(QueryOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
Assert.assertEquals(QueryOperator.class, operator.getClass());
Assert.assertEquals(10, ((QueryOperator) operator).getRowLimit());
Assert.assertEquals(0, ((QueryOperator) operator).getRowOffset());
Assert.assertEquals(1, ((QueryOperator) operator).getSeriesLimit());
Assert.assertEquals(0, ((QueryOperator) operator).getSeriesOffset());
Assert.assertEquals(10, operator.getSpecialClauseComponent().getRowLimit());
Assert.assertEquals(0, operator.getSpecialClauseComponent().getRowOffset());
Assert.assertEquals(1, operator.getSpecialClauseComponent().getSeriesLimit());
Assert.assertEquals(0, operator.getSpecialClauseComponent().getSeriesOffset());
}
@Test
public void testSOffset() {
String sqlStr =
"select * from root.vehicle.d1 where s1 < 20 and time <= now() limit 50 slimit 10 soffset 100";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
QueryOperator operator =
(QueryOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
Assert.assertEquals(QueryOperator.class, operator.getClass());
Assert.assertEquals(50, ((QueryOperator) operator).getRowLimit());
Assert.assertEquals(0, ((QueryOperator) operator).getRowOffset());
Assert.assertEquals(10, ((QueryOperator) operator).getSeriesLimit());
Assert.assertEquals(100, ((QueryOperator) operator).getSeriesOffset());
Assert.assertEquals(50, operator.getSpecialClauseComponent().getRowLimit());
Assert.assertEquals(0, operator.getSpecialClauseComponent().getRowOffset());
Assert.assertEquals(10, operator.getSpecialClauseComponent().getSeriesLimit());
Assert.assertEquals(100, operator.getSpecialClauseComponent().getSeriesOffset());
}
@Test
public void testSOffsetTimestamp() {
String sqlStr =
"select * from root.vehicle.d1 where s1 < 20 and timestamp <= now() limit 50 slimit 10 soffset 100";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
QueryOperator operator =
(QueryOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
Assert.assertEquals(QueryOperator.class, operator.getClass());
Assert.assertEquals(50, ((QueryOperator) operator).getRowLimit());
Assert.assertEquals(0, ((QueryOperator) operator).getRowOffset());
Assert.assertEquals(10, ((QueryOperator) operator).getSeriesLimit());
Assert.assertEquals(100, ((QueryOperator) operator).getSeriesOffset());
Assert.assertEquals(50, operator.getSpecialClauseComponent().getRowLimit());
Assert.assertEquals(0, operator.getSpecialClauseComponent().getRowOffset());
Assert.assertEquals(10, operator.getSpecialClauseComponent().getSeriesLimit());
Assert.assertEquals(100, operator.getSpecialClauseComponent().getSeriesOffset());
}
@Test(expected = SQLParserException.class)
public void testLimitOutOfRange() {
String sqlStr =
"select * from root.vehicle.d1 where s1 < 20 and time <= now() limit 1111111111111111111111";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
// expected to throw SQLParserException: Out of range. LIMIT <N>: N should be Int32.
}
@Test(expected = SQLParserException.class)
public void testLimitNotPositive() {
String sqlStr = "select * from root.vehicle.d1 where s1 < 20 and time <= now() limit 0";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
// expected to throw SQLParserException: LIMIT <N>: N should be greater than 0.
}
......@@ -124,8 +122,7 @@ public class LogicalPlanSmallTest {
String sqlStr =
"select * from root.vehicle.d1 where s1 < 20 and time <= now() "
+ "limit 1 offset 1111111111111111111111";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
// expected to throw SQLParserException: Out of range. OFFSET <OFFSETValue>: OFFSETValue should
// be Int32.
}
......@@ -134,8 +131,7 @@ public class LogicalPlanSmallTest {
public void testOffsetNotPositive() {
String sqlStr =
"select * from root.vehicle.d1 where s1 < 20 and time <= now() limit 1 offset -1";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
// expected to throw SQLParserException: OFFSET <OFFSETValue>: OFFSETValue should >= 0.
}
......@@ -143,16 +139,14 @@ public class LogicalPlanSmallTest {
public void testSlimitOutOfRange() {
String sqlStr =
"select * from root.vehicle.d1 where s1 < 20 and time <= now() slimit 1111111111111111111111";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
// expected to throw SQLParserException: Out of range. SLIMIT <SN>: SN should be Int32.
}
@Test(expected = SQLParserException.class)
public void testSlimitNotPositive() {
String sqlStr = "select * from root.vehicle.d1 where s1 < 20 and time <= now() slimit 0";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
// expected to throw SQLParserException: SLIMIT <SN>: SN should be greater than 0.
}
......@@ -161,8 +155,7 @@ public class LogicalPlanSmallTest {
String sqlStr =
"select * from root.vehicle.d1 where s1 < 20 and time <= now() "
+ "slimit 1 soffset 1111111111111111111111";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
// expected to throw SQLParserException: Out of range. SOFFSET <SOFFSETValue>: SOFFSETValue
// should be Int32.
}
......@@ -171,18 +164,18 @@ public class LogicalPlanSmallTest {
public void testSoffsetNotPositive() {
String sqlStr =
"select * from root.vehicle.d1 where s1 < 20 and time <= now() slimit 1 soffset 1";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
Assert.assertEquals(1, ((QueryOperator) operator).getSeriesOffset());
Assert.assertEquals(1, ((QueryOperator) operator).getSeriesLimit());
QueryOperator operator =
(QueryOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
Assert.assertEquals(1, operator.getSpecialClauseComponent().getSeriesOffset());
Assert.assertEquals(1, operator.getSpecialClauseComponent().getSeriesLimit());
}
@Test(expected = LogicalOptimizeException.class)
public void testSoffsetExceedColumnNum() throws QueryProcessException {
String sqlStr =
"select s1 from root.vehicle.d1 where s1 < 20 and time <= now() slimit 2 soffset 1";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
QueryOperator operator =
(QueryOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
IoTDB.metaManager.init();
ConcatPathOptimizer concatPathOptimizer = new ConcatPathOptimizer();
concatPathOptimizer.transform(operator, 1000);
......@@ -194,52 +187,50 @@ public class LogicalPlanSmallTest {
@Test
public void testDeleteStorageGroup() throws IllegalPathException {
String sqlStr = "delete storage group root.vehicle.d1";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
DeleteStorageGroupOperator operator =
(DeleteStorageGroupOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
Assert.assertEquals(DeleteStorageGroupOperator.class, operator.getClass());
PartialPath path = new PartialPath("root.vehicle.d1");
Assert.assertEquals(path, ((DeleteStorageGroupOperator) operator).getDeletePathList().get(0));
Assert.assertEquals(path, operator.getDeletePathList().get(0));
}
@Test
public void testDisableAlign() {
String sqlStr = "select * from root.vehicle disable align";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
QueryOperator operator =
(QueryOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
Assert.assertEquals(QueryOperator.class, operator.getClass());
Assert.assertFalse(((QueryOperator) operator).isAlignByTime());
Assert.assertFalse(operator.isAlignByTime());
}
@Test
public void testNotDisableAlign() {
String sqlStr = "select * from root.vehicle";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
QueryOperator operator =
(QueryOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
Assert.assertEquals(QueryOperator.class, operator.getClass());
Assert.assertTrue(((QueryOperator) operator).isAlignByTime());
Assert.assertTrue(operator.isAlignByTime());
}
@Test(expected = ParseCancellationException.class)
public void testDisableAlignConflictAlignByDevice() {
String sqlStr = "select * from root.vehicle disable align align by device";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
LogicalGenerator.generate(sqlStr, ZoneId.systemDefault());
}
@Test
public void testChineseCharacter() throws IllegalPathException {
String sqlStr1 = "set storage group to root.一级";
RootOperator operator =
(RootOperator) LogicalGenerator.generate(sqlStr1, ZoneId.systemDefault());
Operator operator = LogicalGenerator.generate(sqlStr1, ZoneId.systemDefault());
Assert.assertEquals(SetStorageGroupOperator.class, operator.getClass());
Assert.assertEquals(new PartialPath("root.一级"), ((SetStorageGroupOperator) operator).getPath());
String sqlStr2 = "select * from root.一级.设备1 limit 10 offset 20";
operator = (RootOperator) LogicalGenerator.generate(sqlStr2, ZoneId.systemDefault());
operator = LogicalGenerator.generate(sqlStr2, ZoneId.systemDefault());
Assert.assertEquals(QueryOperator.class, operator.getClass());
ArrayList<PartialPath> paths = new ArrayList<>();
paths.add(new PartialPath("*"));
Assert.assertEquals(paths, ((QueryOperator) operator).getSelectOperator().getPaths());
Assert.assertEquals(paths, ((QueryOperator) operator).getSelectComponent().getPaths());
}
@Test
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册