blob: 26db5c6b097855e6aa7fc73a5aa94ce8a2c93e64 [file] [log] [blame]
/*
* 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.calcite.test;
import org.apache.calcite.DataContexts;
import org.apache.calcite.jdbc.JavaTypeFactoryImpl;
import org.apache.calcite.plan.RelOptPredicateList;
import org.apache.calcite.plan.RexImplicationChecker;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeSystem;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexExecutorImpl;
import org.apache.calcite.rex.RexInputRef;
import org.apache.calcite.rex.RexLiteral;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexSimplify;
import org.apache.calcite.sql.SqlCollation;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.tools.Frameworks;
import org.apache.calcite.util.DateString;
import org.apache.calcite.util.NlsString;
import org.apache.calcite.util.TimeString;
import org.apache.calcite.util.TimestampString;
import java.math.BigDecimal;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Fixtures for verifying {@link RexImplicationChecker}.
*/
public interface RexImplicationCheckerFixtures {
/** Contains all the nourishment a test case could possibly need.
*
* <p>We put the data in here, rather than as fields in the test case, so that
* the data can be garbage-collected as soon as the test has executed.
*/
@SuppressWarnings("WeakerAccess")
class Fixture {
public final RelDataTypeFactory typeFactory;
public final RexBuilder rexBuilder;
public final RelDataType boolRelDataType;
public final RelDataType intRelDataType;
public final RelDataType decRelDataType;
public final RelDataType longRelDataType;
public final RelDataType shortDataType;
public final RelDataType byteDataType;
public final RelDataType floatDataType;
public final RelDataType charDataType;
public final RelDataType dateDataType;
public final RelDataType timestampDataType;
public final RelDataType timeDataType;
public final RelDataType stringDataType;
public final RexNode bl; // a field of Java type "Boolean"
public final RexNode i; // a field of Java type "Integer"
public final RexNode dec; // a field of Java type "Double"
public final RexNode lg; // a field of Java type "Long"
public final RexNode sh; // a field of Java type "Short"
public final RexNode by; // a field of Java type "Byte"
public final RexNode fl; // a field of Java type "Float" (not a SQL FLOAT)
public final RexNode d; // a field of Java type "Date"
public final RexNode ch; // a field of Java type "Character"
public final RexNode ts; // a field of Java type "Timestamp"
public final RexNode t; // a field of Java type "Time"
public final RexNode str; // a field of Java type "String"
public final RexImplicationChecker checker;
public final RelDataType rowType;
public final RexExecutorImpl executor;
public final RexSimplify simplify;
public Fixture() {
typeFactory = new JavaTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
rexBuilder = new RexBuilder(typeFactory);
boolRelDataType = typeFactory.createJavaType(Boolean.class);
intRelDataType = typeFactory.createJavaType(Integer.class);
decRelDataType = typeFactory.createJavaType(Double.class);
longRelDataType = typeFactory.createJavaType(Long.class);
shortDataType = typeFactory.createJavaType(Short.class);
byteDataType = typeFactory.createJavaType(Byte.class);
floatDataType = typeFactory.createJavaType(Float.class);
charDataType = typeFactory.createJavaType(Character.class);
dateDataType = typeFactory.createJavaType(Date.class);
timestampDataType = typeFactory.createJavaType(Timestamp.class);
timeDataType = typeFactory.createJavaType(Time.class);
stringDataType = typeFactory.createJavaType(String.class);
bl = ref(0, this.boolRelDataType);
i = ref(1, intRelDataType);
dec = ref(2, decRelDataType);
lg = ref(3, longRelDataType);
sh = ref(4, shortDataType);
by = ref(5, byteDataType);
fl = ref(6, floatDataType);
ch = ref(7, charDataType);
d = ref(8, dateDataType);
ts = ref(9, timestampDataType);
t = ref(10, timeDataType);
str = ref(11, stringDataType);
rowType = typeFactory.builder()
.add("bool", this.boolRelDataType)
.add("int", intRelDataType)
.add("dec", decRelDataType)
.add("long", longRelDataType)
.add("short", shortDataType)
.add("byte", byteDataType)
.add("float", floatDataType)
.add("char", charDataType)
.add("date", dateDataType)
.add("timestamp", timestampDataType)
.add("time", timeDataType)
.add("string", stringDataType)
.build();
executor = Frameworks.withPrepare(
(cluster, relOptSchema, rootSchema, statement) ->
new RexExecutorImpl(
DataContexts.of(statement.getConnection(), rootSchema)));
simplify =
new RexSimplify(rexBuilder, RelOptPredicateList.EMPTY, executor)
.withParanoid(true);
checker = new RexImplicationChecker(rexBuilder, executor, rowType);
}
public RexInputRef ref(int i, RelDataType type) {
return new RexInputRef(i,
typeFactory.createTypeWithNullability(type, true));
}
public RexLiteral literal(int i) {
return rexBuilder.makeExactLiteral(new BigDecimal(i));
}
public RexNode gt(RexNode node1, RexNode node2) {
return rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN, node1, node2);
}
public RexNode ge(RexNode node1, RexNode node2) {
return rexBuilder.makeCall(
SqlStdOperatorTable.GREATER_THAN_OR_EQUAL, node1, node2);
}
public RexNode eq(RexNode node1, RexNode node2) {
return rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, node1, node2);
}
public RexNode ne(RexNode node1, RexNode node2) {
return rexBuilder.makeCall(SqlStdOperatorTable.NOT_EQUALS, node1, node2);
}
public RexNode lt(RexNode node1, RexNode node2) {
return rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN, node1, node2);
}
public RexNode le(RexNode node1, RexNode node2) {
return rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN_OR_EQUAL, node1,
node2);
}
public RexNode notNull(RexNode node1) {
return rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL, node1);
}
public RexNode isNull(RexNode node2) {
return rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, node2);
}
public RexNode and(RexNode... nodes) {
return rexBuilder.makeCall(SqlStdOperatorTable.AND, nodes);
}
public RexNode or(RexNode... nodes) {
return rexBuilder.makeCall(SqlStdOperatorTable.OR, nodes);
}
public RexNode longLiteral(long value) {
return rexBuilder.makeLiteral(value, longRelDataType, true);
}
public RexNode shortLiteral(short value) {
return rexBuilder.makeLiteral(value, shortDataType, true);
}
public RexLiteral floatLiteral(double value) {
return rexBuilder.makeApproxLiteral(new BigDecimal(value));
}
public RexLiteral charLiteral(String z) {
return rexBuilder.makeCharLiteral(
new NlsString(z, null, SqlCollation.COERCIBLE));
}
public RexNode dateLiteral(DateString d) {
return rexBuilder.makeDateLiteral(d);
}
public RexNode timestampLiteral(TimestampString ts) {
return rexBuilder.makeTimestampLiteral(ts,
timestampDataType.getPrecision());
}
public RexNode timestampLocalTzLiteral(TimestampString ts) {
return rexBuilder.makeTimestampWithLocalTimeZoneLiteral(ts,
timestampDataType.getPrecision());
}
public RexNode timeLiteral(TimeString t) {
return rexBuilder.makeTimeLiteral(t, timeDataType.getPrecision());
}
public RexNode cast(RelDataType type, RexNode exp) {
return rexBuilder.makeCast(type, exp, true);
}
void checkImplies(RexNode node1, RexNode node2) {
assertTrue(checker.implies(node1, node2),
() -> node1 + " does not imply " + node2 + " when it should");
}
void checkNotImplies(RexNode node1, RexNode node2) {
assertFalse(checker.implies(node1, node2),
() -> node1 + " does implies " + node2 + " when it should not");
}
}
}