blob: 1723711271d6c27b03c4477683e26c12d5762ccc [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.catalog;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeField;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexUtil;
import org.apache.calcite.sql.SqlIdentifier;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.type.ObjectSqlType;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql2rel.InitializerExpressionFactory;
import org.apache.calcite.sql2rel.NullInitializerExpressionFactory;
import org.apache.calcite.util.ImmutableIntList;
import org.apache.calcite.util.Litmus;
import org.apache.calcite.util.Util;
import com.google.common.collect.ImmutableList;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
/**
* Simple catalog reader for testing.
*/
public class MockCatalogReaderSimple extends MockCatalogReader {
private final ObjectSqlType addressType;
/**
* Creates a MockCatalogReader.
*
* <p>Caller must then call {@link #init} to populate with data.</p>
*
* @param typeFactory Type factory
* @param caseSensitive case sensitivity
*/
public MockCatalogReaderSimple(RelDataTypeFactory typeFactory,
boolean caseSensitive) {
super(typeFactory, caseSensitive);
addressType = new Fixture(typeFactory).addressType;
}
@Override public RelDataType getNamedType(SqlIdentifier typeName) {
if (typeName.equalsDeep(addressType.getSqlIdentifier(), Litmus.IGNORE)) {
return addressType;
} else {
return super.getNamedType(typeName);
}
}
@Override public MockCatalogReader init() {
final Fixture fixture = new Fixture(typeFactory);
// Register "SALES" schema.
MockSchema salesSchema = new MockSchema("SALES");
registerSchema(salesSchema);
// Register "EMP" table with customer InitializerExpressionFactory
// to check whether newDefaultValue method called or not.
final InitializerExpressionFactory countingInitializerExpressionFactory =
new CountingFactory(ImmutableList.of("DEPTNO"));
registerType(
ImmutableList.of(salesSchema.getCatalogName(), salesSchema.getName(),
"customBigInt"),
typeFactory -> typeFactory.createSqlType(SqlTypeName.BIGINT));
// Register "EMP" table.
final MockTable empTable =
MockTable.create(this, salesSchema, "EMP", false, 14, null,
countingInitializerExpressionFactory, false);
empTable.addColumn("EMPNO", fixture.intType, true);
empTable.addColumn("ENAME", fixture.varchar20Type);
empTable.addColumn("JOB", fixture.varchar10Type);
empTable.addColumn("MGR", fixture.intTypeNull);
empTable.addColumn("HIREDATE", fixture.timestampType);
empTable.addColumn("SAL", fixture.intType);
empTable.addColumn("COMM", fixture.intType);
empTable.addColumn("DEPTNO", fixture.intType);
empTable.addColumn("SLACKER", fixture.booleanType);
registerTable(empTable);
// Register "EMPNULLABLES" table with nullable columns.
final MockTable empNullablesTable =
MockTable.create(this, salesSchema, "EMPNULLABLES", false, 14);
empNullablesTable.addColumn("EMPNO", fixture.intType, true);
empNullablesTable.addColumn("ENAME", fixture.varchar20TypeNull);
empNullablesTable.addColumn("JOB", fixture.varchar10TypeNull);
empNullablesTable.addColumn("MGR", fixture.intTypeNull);
empNullablesTable.addColumn("HIREDATE", fixture.timestampTypeNull);
empNullablesTable.addColumn("SAL", fixture.intTypeNull);
empNullablesTable.addColumn("COMM", fixture.intTypeNull);
empNullablesTable.addColumn("DEPTNO", fixture.intTypeNull);
empNullablesTable.addColumn("SLACKER", fixture.booleanTypeNull);
registerTable(empNullablesTable);
// Register "EMPDEFAULTS" table with default values for some columns.
final MockTable empDefaultsTable =
MockTable.create(this, salesSchema, "EMPDEFAULTS", false, 14, null,
new EmpInitializerExpressionFactory(), false);
empDefaultsTable.addColumn("EMPNO", fixture.intType, true);
empDefaultsTable.addColumn("ENAME", fixture.varchar20Type);
empDefaultsTable.addColumn("JOB", fixture.varchar10TypeNull);
empDefaultsTable.addColumn("MGR", fixture.intTypeNull);
empDefaultsTable.addColumn("HIREDATE", fixture.timestampTypeNull);
empDefaultsTable.addColumn("SAL", fixture.intTypeNull);
empDefaultsTable.addColumn("COMM", fixture.intTypeNull);
empDefaultsTable.addColumn("DEPTNO", fixture.intTypeNull);
empDefaultsTable.addColumn("SLACKER", fixture.booleanTypeNull);
registerTable(empDefaultsTable);
// Register "EMP_B" table. As "EMP", birth with a "BIRTHDATE" column.
final MockTable empBTable =
MockTable.create(this, salesSchema, "EMP_B", false, 14);
empBTable.addColumn("EMPNO", fixture.intType, true);
empBTable.addColumn("ENAME", fixture.varchar20Type);
empBTable.addColumn("JOB", fixture.varchar10Type);
empBTable.addColumn("MGR", fixture.intTypeNull);
empBTable.addColumn("HIREDATE", fixture.timestampType);
empBTable.addColumn("SAL", fixture.intType);
empBTable.addColumn("COMM", fixture.intType);
empBTable.addColumn("DEPTNO", fixture.intType);
empBTable.addColumn("SLACKER", fixture.booleanType);
empBTable.addColumn("BIRTHDATE", fixture.dateType);
registerTable(empBTable);
// Register "DEPT" table.
MockTable deptTable = MockTable.create(this, salesSchema, "DEPT", false, 4);
deptTable.addColumn("DEPTNO", fixture.intType, true);
deptTable.addColumn("NAME", fixture.varchar10Type);
registerTable(deptTable);
// Register "DEPT_NESTED" table.
MockTable deptNestedTable =
MockTable.create(this, salesSchema, "DEPT_NESTED", false, 4);
deptNestedTable.addColumn("DEPTNO", fixture.intType, true);
deptNestedTable.addColumn("NAME", fixture.varchar10Type);
deptNestedTable.addColumn("SKILL", fixture.skillRecordType);
deptNestedTable.addColumn("EMPLOYEES", fixture.empListType);
registerTable(deptNestedTable);
// Register "DEPT_NESTED_EXPANDED" table.
MockTable deptNestedExpandedTable =
MockTable.create(this, salesSchema, "DEPT_NESTED_EXPANDED", false, 4);
deptNestedExpandedTable.addColumn("DEPTNO", fixture.intType, true);
deptNestedExpandedTable.addColumn("NAME", fixture.varchar10Type);
deptNestedExpandedTable.addColumn("EMPLOYEES", fixture.empListType);
deptNestedExpandedTable.addColumn("ADMINS", fixture.varchar5ArrayType);
deptNestedExpandedTable.addColumn("OFFICES", fixture.rectilinearPeekCoordMultisetType);
registerTable(deptNestedExpandedTable);
// Register "BONUS" table.
MockTable bonusTable =
MockTable.create(this, salesSchema, "BONUS", false, 0);
bonusTable.addColumn("ENAME", fixture.varchar20Type);
bonusTable.addColumn("JOB", fixture.varchar10Type);
bonusTable.addColumn("SAL", fixture.intType);
bonusTable.addColumn("COMM", fixture.intType);
registerTable(bonusTable);
// Register "SALGRADE" table.
MockTable salgradeTable =
MockTable.create(this, salesSchema, "SALGRADE", false, 5);
salgradeTable.addColumn("GRADE", fixture.intType, true);
salgradeTable.addColumn("LOSAL", fixture.intType);
salgradeTable.addColumn("HISAL", fixture.intType);
registerTable(salgradeTable);
// Register "EMP_ADDRESS" table
MockTable contactAddressTable =
MockTable.create(this, salesSchema, "EMP_ADDRESS", false, 26);
contactAddressTable.addColumn("EMPNO", fixture.intType, true);
contactAddressTable.addColumn("HOME_ADDRESS", addressType);
contactAddressTable.addColumn("MAILING_ADDRESS", addressType);
registerTable(contactAddressTable);
// Register "CUSTOMER" schema.
MockSchema customerSchema = new MockSchema("CUSTOMER");
registerSchema(customerSchema);
// Register "CONTACT" table.
MockTable contactTable = MockTable.create(this, customerSchema, "CONTACT",
false, 1000);
contactTable.addColumn("CONTACTNO", fixture.intType);
contactTable.addColumn("FNAME", fixture.varchar10Type);
contactTable.addColumn("LNAME", fixture.varchar10Type);
contactTable.addColumn("EMAIL", fixture.varchar20Type);
contactTable.addColumn("COORD", fixture.rectilinearCoordType);
registerTable(contactTable);
// Register "CONTACT_PEEK" table. The
MockTable contactPeekTable =
MockTable.create(this, customerSchema, "CONTACT_PEEK", false, 1000);
contactPeekTable.addColumn("CONTACTNO", fixture.intType);
contactPeekTable.addColumn("FNAME", fixture.varchar10Type);
contactPeekTable.addColumn("LNAME", fixture.varchar10Type);
contactPeekTable.addColumn("EMAIL", fixture.varchar20Type);
contactPeekTable.addColumn("COORD", fixture.rectilinearPeekCoordType);
contactPeekTable.addColumn("COORD_NE", fixture.rectilinearPeekNoExpandCoordType);
registerTable(contactPeekTable);
// Register "ACCOUNT" table.
MockTable accountTable = MockTable.create(this, customerSchema, "ACCOUNT",
false, 457);
accountTable.addColumn("ACCTNO", fixture.intType);
accountTable.addColumn("TYPE", fixture.varchar20Type);
accountTable.addColumn("BALANCE", fixture.intType);
registerTable(accountTable);
// Register "ORDERS" stream.
MockTable ordersStream = MockTable.create(this, salesSchema, "ORDERS",
true, Double.POSITIVE_INFINITY);
ordersStream.addColumn("ROWTIME", fixture.timestampType);
ordersStream.addMonotonic("ROWTIME");
ordersStream.addColumn("PRODUCTID", fixture.intType);
ordersStream.addColumn("ORDERID", fixture.intType);
registerTable(ordersStream);
// Register "SHIPMENTS" stream.
// "ROWTIME" is not column 0, just to mix things up.
MockTable shipmentsStream = MockTable.create(this, salesSchema, "SHIPMENTS",
true, Double.POSITIVE_INFINITY);
shipmentsStream.addColumn("ORDERID", fixture.intType);
shipmentsStream.addColumn("ROWTIME", fixture.timestampType);
shipmentsStream.addMonotonic("ROWTIME");
registerTable(shipmentsStream);
// Register "PRODUCTS" table.
MockTable productsTable = MockTable.create(this, salesSchema, "PRODUCTS",
false, 200D);
productsTable.addColumn("PRODUCTID", fixture.intType);
productsTable.addColumn("NAME", fixture.varchar20Type);
productsTable.addColumn("SUPPLIERID", fixture.intType);
registerTable(productsTable);
// Register "PRODUCTS_TEMPORAL" table.
MockTable productsTemporalTable =
MockTable.create(this, salesSchema, "PRODUCTS_TEMPORAL", false, 200D,
null, NullInitializerExpressionFactory.INSTANCE, true);
productsTemporalTable.addColumn("PRODUCTID", fixture.intType);
productsTemporalTable.addColumn("NAME", fixture.varchar20Type);
productsTemporalTable.addColumn("SUPPLIERID", fixture.intType);
productsTemporalTable.addColumn("SYS_START", fixture.timestampType);
productsTemporalTable.addColumn("SYS_END", fixture.timestampType);
registerTable(productsTemporalTable);
// Register "SUPPLIERS" table.
MockTable suppliersTable = MockTable.create(this, salesSchema, "SUPPLIERS",
false, 10D);
suppliersTable.addColumn("SUPPLIERID", fixture.intType);
suppliersTable.addColumn("NAME", fixture.varchar20Type);
suppliersTable.addColumn("CITY", fixture.intType);
registerTable(suppliersTable);
// Register "EMP_20" and "EMPNULLABLES_20 views.
// Same columns as "EMP" amd "EMPNULLABLES",
// but "DEPTNO" not visible and set to 20 by default
// and "SAL" is visible but must be greater than 1000,
// which is the equivalent of:
// SELECT EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, SLACKER
// FROM EMP
// WHERE DEPTNO = 20 AND SAL > 1000
final ImmutableIntList m0 = ImmutableIntList.of(0, 1, 2, 3, 4, 5, 6, 8);
MockTable emp20View =
new MockViewTable(this, salesSchema.getCatalogName(), salesSchema.getName(),
"EMP_20", false, 600, empTable, m0, null,
NullInitializerExpressionFactory.INSTANCE) {
public RexNode getConstraint(RexBuilder rexBuilder,
RelDataType tableRowType) {
final RelDataTypeField deptnoField =
tableRowType.getFieldList().get(7);
final RelDataTypeField salField =
tableRowType.getFieldList().get(5);
final List<RexNode> nodes = Arrays.asList(
rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
rexBuilder.makeInputRef(deptnoField.getType(),
deptnoField.getIndex()),
rexBuilder.makeExactLiteral(BigDecimal.valueOf(20L),
deptnoField.getType())),
rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN,
rexBuilder.makeInputRef(salField.getType(),
salField.getIndex()),
rexBuilder.makeExactLiteral(BigDecimal.valueOf(1000L),
salField.getType())));
return RexUtil.composeConjunction(rexBuilder, nodes);
}
};
salesSchema.addTable(Util.last(emp20View.getQualifiedName()));
emp20View.addColumn("EMPNO", fixture.intType);
emp20View.addColumn("ENAME", fixture.varchar20Type);
emp20View.addColumn("JOB", fixture.varchar10Type);
emp20View.addColumn("MGR", fixture.intTypeNull);
emp20View.addColumn("HIREDATE", fixture.timestampType);
emp20View.addColumn("SAL", fixture.intType);
emp20View.addColumn("COMM", fixture.intType);
emp20View.addColumn("SLACKER", fixture.booleanType);
registerTable(emp20View);
MockTable empNullables20View =
new MockViewTable(this, salesSchema.getCatalogName(), salesSchema.getName(),
"EMPNULLABLES_20", false, 600, empNullablesTable, m0, null,
NullInitializerExpressionFactory.INSTANCE) {
public RexNode getConstraint(RexBuilder rexBuilder,
RelDataType tableRowType) {
final RelDataTypeField deptnoField =
tableRowType.getFieldList().get(7);
final RelDataTypeField salField =
tableRowType.getFieldList().get(5);
final List<RexNode> nodes = Arrays.asList(
rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
rexBuilder.makeInputRef(deptnoField.getType(),
deptnoField.getIndex()),
rexBuilder.makeExactLiteral(BigDecimal.valueOf(20L),
deptnoField.getType())),
rexBuilder.makeCall(SqlStdOperatorTable.GREATER_THAN,
rexBuilder.makeInputRef(salField.getType(),
salField.getIndex()),
rexBuilder.makeExactLiteral(BigDecimal.valueOf(1000L),
salField.getType())));
return RexUtil.composeConjunction(rexBuilder, nodes);
}
};
salesSchema.addTable(Util.last(empNullables20View.getQualifiedName()));
empNullables20View.addColumn("EMPNO", fixture.intType);
empNullables20View.addColumn("ENAME", fixture.varchar20TypeNull);
empNullables20View.addColumn("JOB", fixture.varchar10TypeNull);
empNullables20View.addColumn("MGR", fixture.intTypeNull);
empNullables20View.addColumn("HIREDATE", fixture.timestampTypeNull);
empNullables20View.addColumn("SAL", fixture.intTypeNull);
empNullables20View.addColumn("COMM", fixture.intTypeNull);
empNullables20View.addColumn("SLACKER", fixture.booleanTypeNull);
registerTable(empNullables20View);
MockSchema structTypeSchema = new MockSchema("STRUCT");
registerSchema(structTypeSchema);
final List<CompoundNameColumn> columns = Arrays.asList(
new CompoundNameColumn("", "K0", fixture.varchar20Type),
new CompoundNameColumn("", "C1", fixture.varchar20Type),
new CompoundNameColumn("F1", "A0", fixture.intType),
new CompoundNameColumn("F2", "A0", fixture.booleanType),
new CompoundNameColumn("F0", "C0", fixture.intType),
new CompoundNameColumn("F1", "C0", fixture.intTypeNull),
new CompoundNameColumn("F0", "C1", fixture.intType),
new CompoundNameColumn("F1", "C2", fixture.intType),
new CompoundNameColumn("F2", "C3", fixture.intType));
final CompoundNameColumnResolver structTypeTableResolver =
new CompoundNameColumnResolver(columns, "F0");
final MockTable structTypeTable =
MockTable.create(this, structTypeSchema, "T", false, 100,
structTypeTableResolver);
for (CompoundNameColumn column : columns) {
structTypeTable.addColumn(column.getName(), column.type);
}
registerTable(structTypeTable);
final List<CompoundNameColumn> columnsNullable = Arrays.asList(
new CompoundNameColumn("", "K0", fixture.varchar20TypeNull),
new CompoundNameColumn("", "C1", fixture.varchar20TypeNull),
new CompoundNameColumn("F1", "A0", fixture.intTypeNull),
new CompoundNameColumn("F2", "A0", fixture.booleanTypeNull),
new CompoundNameColumn("F0", "C0", fixture.intTypeNull),
new CompoundNameColumn("F1", "C0", fixture.intTypeNull),
new CompoundNameColumn("F0", "C1", fixture.intTypeNull),
new CompoundNameColumn("F1", "C2", fixture.intType),
new CompoundNameColumn("F2", "C3", fixture.intTypeNull));
final MockTable structNullableTypeTable =
MockTable.create(this, structTypeSchema, "T_NULLABLES", false, 100,
structTypeTableResolver);
for (CompoundNameColumn column : columnsNullable) {
structNullableTypeTable.addColumn(column.getName(), column.type);
}
registerTable(structNullableTypeTable);
// Register "STRUCT.T_10" view.
// Same columns as "STRUCT.T",
// but "F0.C0" is set to 10 by default,
// which is the equivalent of:
// SELECT *
// FROM T
// WHERE F0.C0 = 10
// This table uses MockViewTable which does not populate the constrained columns with default
// values on INSERT.
final ImmutableIntList m1 = ImmutableIntList.of(0, 1, 2, 3, 4, 5, 6, 7, 8);
MockTable struct10View =
new MockViewTable(this, structTypeSchema.getCatalogName(),
structTypeSchema.getName(), "T_10", false, 20, structTypeTable,
m1, structTypeTableResolver,
NullInitializerExpressionFactory.INSTANCE) {
@Override public RexNode getConstraint(RexBuilder rexBuilder,
RelDataType tableRowType) {
final RelDataTypeField c0Field =
tableRowType.getFieldList().get(4);
return rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
rexBuilder.makeInputRef(c0Field.getType(),
c0Field.getIndex()),
rexBuilder.makeExactLiteral(BigDecimal.valueOf(10L),
c0Field.getType()));
}
};
structTypeSchema.addTable(Util.last(struct10View.getQualifiedName()));
for (CompoundNameColumn column : columns) {
struct10View.addColumn(column.getName(), column.type);
}
registerTable(struct10View);
registerTablesWithRollUp(salesSchema, fixture);
return this;
}
}