Skip to content

Commit

Permalink
[dingo-expr, dingo-calcite, dingo-driver] Added env(timezone) in expr. (
Browse files Browse the repository at this point in the history
  • Loading branch information
lasyard authored Oct 11, 2022
1 parent ece3d19 commit 01cd577
Show file tree
Hide file tree
Showing 44 changed files with 527 additions and 230 deletions.
21 changes: 15 additions & 6 deletions dingo-calcite/src/main/java/io/dingodb/calcite/DingoParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import io.dingodb.calcite.rule.DingoRules;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.calcite.config.CalciteConnectionConfig;
import org.apache.calcite.config.CalciteConnectionConfigImpl;
import org.apache.calcite.config.CalciteConnectionProperty;
import org.apache.calcite.config.Lex;
Expand Down Expand Up @@ -61,6 +62,7 @@
import java.util.Objects;
import java.util.Properties;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

// Each sql parsing requires a new instance.
@Slf4j
Expand Down Expand Up @@ -91,8 +93,12 @@ public boolean allowNiladicParentheses() {
private final CalciteCatalogReader catalogReader;

public DingoParser(@Nonnull DingoParserContext context) {
this(context, null);
}

public DingoParser(@Nonnull DingoParserContext context, @Nullable CalciteConnectionConfig config) {
this.context = context;
planner = new VolcanoPlanner();
planner = new VolcanoPlanner(context);
// Very important, it defines the RelNode convention. Logical nodes have `Convention.NONE`.
planner.addRelTraitDef(ConventionTraitDef.INSTANCE);
// Defines the "order-by" traits.
Expand All @@ -107,15 +113,18 @@ public DingoParser(@Nonnull DingoParserContext context) {
)
));

Properties properties = new Properties();
properties.setProperty(CalciteConnectionProperty.CASE_SENSITIVE.camelName(),
String.valueOf(PARSER_CONFIG.caseSensitive()));

if (config == null) {
config = new CalciteConnectionConfigImpl(new Properties());
}
config = ((CalciteConnectionConfigImpl) config).set(
CalciteConnectionProperty.CASE_SENSITIVE,
String.valueOf(PARSER_CONFIG.caseSensitive())
);
catalogReader = new CalciteCatalogReader(
context.getRootSchema(),
Collections.singletonList(context.getDefaultSchemaName()),
context.getTypeFactory(),
new CalciteConnectionConfigImpl(properties)
config
);

// CatalogReader is also serving as SqlOperatorTable.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,37 @@
import lombok.Getter;
import org.apache.calcite.adapter.java.JavaTypeFactory;
import org.apache.calcite.jdbc.CalciteSchema;
import org.apache.calcite.plan.Context;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelProtoDataType;
import org.apache.calcite.schema.impl.ScalarFunctionImpl;
import org.apache.calcite.sql.type.SqlTypeName;
import org.checkerframework.checker.nullness.qual.Nullable;

import java.util.Properties;
import java.util.TimeZone;
import javax.annotation.Nonnull;


// These are static for every sql parsing.
public final class DingoParserContext {
public final class DingoParserContext implements Context {
@Getter
private final CalciteSchema rootSchema;
@Getter
private final String defaultSchemaName;
@Getter
private final TimeZone timeZone;

public DingoParserContext(@Nonnull String defaultSchemaName) {
this(defaultSchemaName, null);
}

public DingoParserContext(@Nonnull String defaultSchemaName, @Nullable Properties options) {
this.defaultSchemaName = defaultSchemaName;

String timeZoneId = options != null ? options.getProperty("timeZone") : null;
timeZone = timeZoneId != null ? TimeZone.getTimeZone(timeZoneId) : TimeZone.getDefault();

rootSchema = CalciteSchema.createRootSchema(
true,
false,
Expand All @@ -61,4 +75,12 @@ public JavaTypeFactory getTypeFactory() {
public CalciteSchema getDefaultSchema() {
return rootSchema.getSubSchema(defaultSchemaName, true);
}

@Override
public <C> @Nullable C unwrap(@Nonnull Class<C> clazz) {
if (clazz.isInstance(timeZone)) {
return clazz.cast(timeZone);
}
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,13 @@
package io.dingodb.calcite.rule;

import io.dingodb.calcite.rel.LogicalDingoValues;
import io.dingodb.calcite.visitor.RexConverter;
import io.dingodb.calcite.utils.CalcValueUtils;
import io.dingodb.common.type.DingoType;
import io.dingodb.common.type.DingoTypeFactory;
import io.dingodb.common.util.ArrayUtils;
import io.dingodb.expr.parser.exception.DingoExprCompileException;
import io.dingodb.expr.parser.exception.ElementNotExists;
import io.dingodb.expr.runtime.EvalEnv;
import io.dingodb.expr.runtime.TypeCode;
import io.dingodb.expr.runtime.exception.FailGetEvaluator;
import org.apache.calcite.plan.RelOptRuleCall;
Expand Down Expand Up @@ -50,15 +51,17 @@ public void onMatch(@Nonnull RelOptRuleCall call) {
List<Object[]> tuples = new LinkedList<>();
if (join.getJoinType() == JoinRelType.INNER) {
DingoType type = DingoTypeFactory.fromRelDataType(join.getRowType());
EvalEnv env = CalcValueUtils.getEnv(call);
try {
for (Object[] v0 : value0.getTuples()) {
for (Object[] v1 : value1.getTuples()) {
Object[] newTuple = ArrayUtils.concat(v0, v1);
Object v = RexConverter.calcValue(
Object v = CalcValueUtils.calcValue(
join.getCondition(),
DingoTypeFactory.scalar(TypeCode.BOOL, false),
newTuple,
type
type,
env
);
if (v != null && (boolean) v) {
tuples.add(newTuple);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
package io.dingodb.calcite.rule;

import io.dingodb.calcite.rel.LogicalDingoValues;
import io.dingodb.calcite.visitor.RexConverter;
import io.dingodb.calcite.utils.CalcValueUtils;
import io.dingodb.common.type.DingoType;
import io.dingodb.common.type.DingoTypeFactory;
import io.dingodb.expr.parser.exception.DingoExprCompileException;
import io.dingodb.expr.parser.exception.ElementNotExists;
import io.dingodb.expr.runtime.EvalEnv;
import io.dingodb.expr.runtime.TypeCode;
import io.dingodb.expr.runtime.exception.FailGetEvaluator;
import org.apache.calcite.plan.RelOptRuleCall;
Expand Down Expand Up @@ -50,9 +51,10 @@ private static void matchProject(
DingoType tupleType = DingoTypeFactory.fromRelDataType(values.getRowType());
DingoType rowType = DingoTypeFactory.fromRelDataType(project.getRowType());
List<Object[]> tuples = new LinkedList<>();
EvalEnv env = CalcValueUtils.getEnv(call);
try {
for (Object[] tuple : values.getTuples()) {
tuples.add(RexConverter.calcValues(project.getProjects(), rowType, tuple, tupleType));
tuples.add(CalcValueUtils.calcValues(project.getProjects(), rowType, tuple, tupleType, env));
}
} catch (ElementNotExists e) { // Means it is not a constant.
return;
Expand All @@ -75,13 +77,15 @@ private static void matchFilter(
LogicalDingoValues values = call.rel(1);
DingoType tupleType = DingoTypeFactory.fromRelDataType(values.getRowType());
List<Object[]> tuples = new LinkedList<>();
EvalEnv env = CalcValueUtils.getEnv(call);
try {
for (Object[] tuple : values.getTuples()) {
Object v = RexConverter.calcValue(
Object v = CalcValueUtils.calcValue(
filter.getCondition(),
DingoTypeFactory.scalar(TypeCode.BOOL, false),
tuple,
tupleType
tupleType,
env
);
if (v != null && (boolean) v) {
tuples.add(tuple);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
/*
* Copyright 2021 DataCanvas
*
* Licensed 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 io.dingodb.calcite.utils;

import io.dingodb.calcite.visitor.RexConverter;
import io.dingodb.common.type.DingoType;
import io.dingodb.common.type.converter.ExprConverter;
import io.dingodb.exec.expr.SqlExprCompileContext;
import io.dingodb.exec.expr.SqlExprEvalContext;
import io.dingodb.expr.parser.Expr;
import io.dingodb.expr.parser.exception.DingoExprCompileException;
import io.dingodb.expr.runtime.EvalEnv;
import io.dingodb.expr.runtime.exception.FailGetEvaluator;
import org.apache.calcite.plan.RelOptRuleCall;
import org.apache.calcite.rex.RexNode;

import java.util.List;
import java.util.TimeZone;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public final class CalcValueUtils {
private CalcValueUtils() {
}

@Nullable
public static Object calcValue(
RexNode rexNode,
@Nonnull DingoType targetType,
Object[] tuple,
DingoType tupleType,
@Nullable EvalEnv env
) throws DingoExprCompileException, FailGetEvaluator {
Expr expr = RexConverter.convert(rexNode);
SqlExprEvalContext etx = new SqlExprEvalContext(env);
etx.setTuple(tuple);
return targetType.convertFrom(
expr.compileIn(new SqlExprCompileContext(tupleType, null, env)).eval(etx),
ExprConverter.INSTANCE
);
}

@Nonnull
public static Object[] calcValues(
@Nonnull List<RexNode> rexNodeList,
@Nonnull DingoType targetType,
Object[] tuple,
DingoType tupleType,
@Nullable EvalEnv env
) throws DingoExprCompileException, FailGetEvaluator {
int size = rexNodeList.size();
Object[] result = new Object[size];
for (int i = 0; i < size; ++i) {
result[i] = calcValue(rexNodeList.get(i), targetType.getChild(i), tuple, tupleType, env);
}
return result;
}

@Nonnull
public static EvalEnv getEnv(@Nonnull RelOptRuleCall call) {
EvalEnv env = new EvalEnv();
env.setTimeZone(call.getPlanner().getContext().unwrap(TimeZone.class));
return env;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
import io.dingodb.calcite.rel.DingoTableScan;
import io.dingodb.calcite.rel.DingoUnion;
import io.dingodb.calcite.rel.DingoValues;
import io.dingodb.calcite.utils.SqlExprUtils;
import io.dingodb.calcite.utils.RexLiteralUtils;
import io.dingodb.calcite.utils.SqlExprUtils;
import io.dingodb.common.CommonId;
import io.dingodb.common.Location;
import io.dingodb.common.hash.HashStrategy;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,9 @@
package io.dingodb.calcite.visitor;

import io.dingodb.calcite.utils.RexLiteralUtils;
import io.dingodb.common.type.DingoType;
import io.dingodb.common.type.converter.ExprConverter;
import io.dingodb.exec.expr.SqlExprCompileContext;
import io.dingodb.exec.expr.SqlExprEvalContext;
import io.dingodb.expr.parser.DingoExprParser;
import io.dingodb.expr.parser.Expr;
import io.dingodb.expr.parser.exception.DingoExprCompileException;
import io.dingodb.expr.parser.exception.UndefinedFunctionName;
import io.dingodb.expr.parser.op.FunFactory;
import io.dingodb.expr.parser.op.IndexOp;
Expand Down Expand Up @@ -54,7 +50,6 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public final class RexConverter extends RexVisitorImpl<Expr> {
private static final RexConverter INSTANCE = new RexConverter();
Expand All @@ -67,35 +62,6 @@ private RexConverter() {
super(true);
}

@Nullable
public static Object calcValue(
RexNode rexNode,
@Nonnull DingoType targetType,
Object[] tuple,
DingoType tupleType
) throws DingoExprCompileException, FailGetEvaluator {
Expr expr = convert(rexNode);
return targetType.convertFrom(
expr.compileIn(new SqlExprCompileContext(tupleType)).eval(new SqlExprEvalContext(tuple)),
ExprConverter.INSTANCE
);
}

@Nonnull
public static Object[] calcValues(
@Nonnull List<RexNode> rexNodeList,
@Nonnull DingoType targetType,
Object[] tuple,
DingoType tupleType
) throws DingoExprCompileException, FailGetEvaluator {
int size = rexNodeList.size();
Object[] result = new Object[size];
for (int i = 0; i < size; ++i) {
result[i] = calcValue(rexNodeList.get(i), targetType.getChild(i), tuple, tupleType);
}
return result;
}

private static int typeCodeOf(@Nonnull RelDataType type) {
return TypeCode.codeOf(type.getSqlTypeName().getName());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ public Object convert(@Nonnull Object[] value, DingoType elementType) {
throw NEVER_CONVERT_BACK;
}

@Override
public Integer convertIntegerFrom(@Nonnull Object value) {
// Values transferred from remote client are Longs.
if (value instanceof Long) {
return ((Long) value).intValue();
}
return super.convertIntegerFrom(value);
}

/**
* Convert from an integer of days to a {@link Date}. See {@link org.apache.calcite.avatica.remote.TypedValue}.
*
Expand Down
Loading

0 comments on commit 01cd577

Please sign in to comment.