com.hazelcast.org.apache.calcite.prepare.LixToRelTranslator Maven / Gradle / Ivy
/*
* 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 com.hazelcast.org.apache.calcite.prepare;
import com.hazelcast.org.apache.calcite.adapter.java.JavaTypeFactory;
import com.hazelcast.org.apache.calcite.linq4j.Queryable;
import com.hazelcast.org.apache.calcite.linq4j.tree.Blocks;
import com.hazelcast.org.apache.calcite.linq4j.tree.ConstantExpression;
import com.hazelcast.org.apache.calcite.linq4j.tree.Expression;
import com.hazelcast.org.apache.calcite.linq4j.tree.FunctionExpression;
import com.hazelcast.org.apache.calcite.linq4j.tree.MethodCallExpression;
import com.hazelcast.org.apache.calcite.linq4j.tree.NewExpression;
import com.hazelcast.org.apache.calcite.linq4j.tree.Types;
import com.hazelcast.org.apache.calcite.plan.RelOptCluster;
import com.hazelcast.org.apache.calcite.plan.RelOptTable;
import com.hazelcast.org.apache.calcite.plan.ViewExpanders;
import com.hazelcast.org.apache.calcite.rel.RelNode;
import com.hazelcast.org.apache.calcite.rel.logical.LogicalFilter;
import com.hazelcast.org.apache.calcite.rel.logical.LogicalProject;
import com.hazelcast.org.apache.calcite.rel.logical.LogicalTableScan;
import com.hazelcast.org.apache.calcite.rex.RexBuilder;
import com.hazelcast.org.apache.calcite.rex.RexNode;
import com.hazelcast.org.apache.calcite.util.BuiltInMethod;
import com.hazelcast.com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Translates a tree of linq4j {@link Queryable} nodes to a tree of
* {@link RelNode} planner nodes.
*
* @see QueryableRelBuilder
*/
class LixToRelTranslator {
final RelOptCluster cluster;
private final Prepare preparingStmt;
final JavaTypeFactory typeFactory;
LixToRelTranslator(RelOptCluster cluster, Prepare preparingStmt) {
this.cluster = cluster;
this.preparingStmt = preparingStmt;
this.typeFactory = (JavaTypeFactory) cluster.getTypeFactory();
}
RelOptTable.ToRelContext toRelContext() {
if (preparingStmt instanceof RelOptTable.ViewExpander) {
final RelOptTable.ViewExpander viewExpander =
(RelOptTable.ViewExpander) this.preparingStmt;
return ViewExpanders.toRelContext(viewExpander, cluster);
} else {
return ViewExpanders.simpleContext(cluster);
}
}
public RelNode translate(Queryable queryable) {
QueryableRelBuilder translatorQueryable =
new QueryableRelBuilder<>(this);
return translatorQueryable.toRel(queryable);
}
public RelNode translate(Expression expression) {
if (expression instanceof MethodCallExpression) {
final MethodCallExpression call = (MethodCallExpression) expression;
BuiltInMethod method = BuiltInMethod.MAP.get(call.method);
if (method == null) {
throw new UnsupportedOperationException(
"unknown method " + call.method);
}
RelNode input;
switch (method) {
case SELECT:
input = translate(call.targetExpression);
return LogicalProject.create(input,
ImmutableList.of(),
toRex(input, (FunctionExpression) call.expressions.get(0)),
(List) null);
case WHERE:
input = translate(call.targetExpression);
return LogicalFilter.create(input,
toRex((FunctionExpression) call.expressions.get(0), input));
case AS_QUERYABLE:
return LogicalTableScan.create(cluster,
RelOptTableImpl.create(null,
typeFactory.createJavaType(
Types.toClass(
Types.getElementType(call.targetExpression.getType()))),
ImmutableList.of(),
call.targetExpression),
ImmutableList.of());
case SCHEMA_GET_TABLE:
return LogicalTableScan.create(cluster,
RelOptTableImpl.create(null,
typeFactory.createJavaType((Class)
((ConstantExpression) call.expressions.get(1)).value),
ImmutableList.of(),
call.targetExpression),
ImmutableList.of());
default:
throw new UnsupportedOperationException(
"unknown method " + call.method);
}
}
throw new UnsupportedOperationException(
"unknown expression type " + expression.getNodeType());
}
private List toRex(
RelNode child, FunctionExpression expression) {
RexBuilder rexBuilder = cluster.getRexBuilder();
List list =
Collections.singletonList(
rexBuilder.makeRangeReference(child));
CalcitePrepareImpl.ScalarTranslator translator =
CalcitePrepareImpl.EmptyScalarTranslator
.empty(rexBuilder)
.bind(expression.parameterList, list);
final List rexList = new ArrayList<>();
final Expression simple = Blocks.simple(expression.body);
for (Expression expression1 : fieldExpressions(simple)) {
rexList.add(translator.toRex(expression1));
}
return rexList;
}
List fieldExpressions(Expression expression) {
if (expression instanceof NewExpression) {
// Note: We are assuming that the arguments to the constructor
// are the same order as the fields of the class.
return ((NewExpression) expression).arguments;
}
throw new RuntimeException(
"unsupported expression type " + expression);
}
List toRexList(
FunctionExpression expression,
RelNode... inputs) {
List list = new ArrayList<>();
RexBuilder rexBuilder = cluster.getRexBuilder();
for (RelNode input : inputs) {
list.add(rexBuilder.makeRangeReference(input));
}
return CalcitePrepareImpl.EmptyScalarTranslator.empty(rexBuilder)
.bind(expression.parameterList, list)
.toRexList(expression.body);
}
RexNode toRex(
FunctionExpression expression,
RelNode... inputs) {
List list = new ArrayList<>();
RexBuilder rexBuilder = cluster.getRexBuilder();
for (RelNode input : inputs) {
list.add(rexBuilder.makeRangeReference(input));
}
return CalcitePrepareImpl.EmptyScalarTranslator.empty(rexBuilder)
.bind(expression.parameterList, list)
.toRex(expression.body);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy