blob: 5683def94af1a79abaaac50941286262d1202bc6 [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.plan.RelOptPredicateList;
import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.metadata.BuiltInMetadata;
import org.apache.calcite.rel.metadata.MetadataDef;
import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexInputRef;
import org.apache.calcite.schema.TableMacro;
import org.apache.calcite.schema.TranslatableTable;
import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.SqlOperator;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql.util.SqlOperatorTables;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/** Adds some extra tables to the mock catalog. These increase the time and
* complexity of initializing the catalog (because they contain views whose
* SQL needs to be parsed) and so are not used for all tests. */
public class MockCatalogReaderExtended extends MockCatalogReaderSimple {
/**
* Creates a MockCatalogReader.
*
* <p>Caller must then call {@link #init} to populate with data.</p>
*
* @param typeFactory Type factory
* @param caseSensitive case sensitivity
*/
public MockCatalogReaderExtended(RelDataTypeFactory typeFactory,
boolean caseSensitive) {
super(typeFactory, caseSensitive);
}
@Override public MockCatalogReader init() {
super.init();
MockSchema salesSchema = new MockSchema("SALES");
// Same as "EMP_20" except it uses ModifiableViewTable which populates
// constrained columns with default values on INSERT and has a single constraint on DEPTNO.
List<String> empModifiableViewNames = ImmutableList.of(
salesSchema.getCatalogName(), salesSchema.getName(), "EMP_MODIFIABLEVIEW");
TableMacro empModifiableViewMacro = MockModifiableViewRelOptTable.viewMacro(rootSchema,
"select EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, SLACKER from EMPDEFAULTS"
+ " where DEPTNO = 20", empModifiableViewNames.subList(0, 2),
ImmutableList.of(empModifiableViewNames.get(2)), true);
TranslatableTable empModifiableView = empModifiableViewMacro.apply(ImmutableList.of());
MockModifiableViewRelOptTable mockEmpViewTable = MockModifiableViewRelOptTable.create(
(MockModifiableViewRelOptTable.MockModifiableViewTable) empModifiableView, this,
empModifiableViewNames.get(0), empModifiableViewNames.get(1),
empModifiableViewNames.get(2), false, 20, null);
registerTable(mockEmpViewTable);
// Same as "EMP_MODIFIABLEVIEW" except that all columns are in the view, columns are reordered,
// and there is an `extra` extended column.
List<String> empModifiableViewNames2 = ImmutableList.of(
salesSchema.getCatalogName(), salesSchema.getName(), "EMP_MODIFIABLEVIEW2");
TableMacro empModifiableViewMacro2 = MockModifiableViewRelOptTable.viewMacro(rootSchema,
"select ENAME, EMPNO, JOB, DEPTNO, SLACKER, SAL, EXTRA, HIREDATE, MGR, COMM"
+ " from EMPDEFAULTS extend (EXTRA boolean)"
+ " where DEPTNO = 20", empModifiableViewNames2.subList(0, 2),
ImmutableList.of(empModifiableViewNames.get(2)), true);
TranslatableTable empModifiableView2 = empModifiableViewMacro2.apply(ImmutableList.of());
MockModifiableViewRelOptTable mockEmpViewTable2 = MockModifiableViewRelOptTable.create(
(MockModifiableViewRelOptTable.MockModifiableViewTable) empModifiableView2, this,
empModifiableViewNames2.get(0), empModifiableViewNames2.get(1),
empModifiableViewNames2.get(2), false, 20, null);
registerTable(mockEmpViewTable2);
// Same as "EMP_MODIFIABLEVIEW" except that comm is not in the view.
List<String> empModifiableViewNames3 = ImmutableList.of(
salesSchema.getCatalogName(), salesSchema.getName(), "EMP_MODIFIABLEVIEW3");
TableMacro empModifiableViewMacro3 = MockModifiableViewRelOptTable.viewMacro(rootSchema,
"select EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, SLACKER from EMPDEFAULTS"
+ " where DEPTNO = 20", empModifiableViewNames3.subList(0, 2),
ImmutableList.of(empModifiableViewNames3.get(2)), true);
TranslatableTable empModifiableView3 = empModifiableViewMacro3.apply(ImmutableList.of());
MockModifiableViewRelOptTable mockEmpViewTable3 = MockModifiableViewRelOptTable.create(
(MockModifiableViewRelOptTable.MockModifiableViewTable) empModifiableView3, this,
empModifiableViewNames3.get(0), empModifiableViewNames3.get(1),
empModifiableViewNames3.get(2), false, 20, null);
registerTable(mockEmpViewTable3);
MockSchema structTypeSchema = new MockSchema("STRUCT");
registerSchema(structTypeSchema);
final Fixture f = new Fixture(typeFactory);
final List<CompoundNameColumn> columnsExtended = Arrays.asList(
new CompoundNameColumn("", "K0", f.varchar20TypeNull),
new CompoundNameColumn("", "C1", f.varchar20TypeNull),
new CompoundNameColumn("F0", "C0", f.intType),
new CompoundNameColumn("F1", "C1", f.intTypeNull));
final List<CompoundNameColumn> extendedColumns =
new ArrayList<>(columnsExtended);
extendedColumns.add(new CompoundNameColumn("F2", "C2", f.varchar20Type));
final CompoundNameColumnResolver structExtendedTableResolver =
new CompoundNameColumnResolver(extendedColumns, "F0");
final MockTable structExtendedTypeTable =
MockTable.create(this, structTypeSchema, "T_EXTEND", false, 100,
structExtendedTableResolver);
for (CompoundNameColumn column : columnsExtended) {
structExtendedTypeTable.addColumn(column.getName(), column.type);
}
registerTable(structExtendedTypeTable);
// Defines a table with
// schema(A int, B bigint, C varchar(10), D as a + 1 stored, E as b * 3 virtual).
MockSchema virtualColumnsSchema = new MockSchema("VIRTUALCOLUMNS");
registerSchema(virtualColumnsSchema);
final MockTable virtualColumnsTable1 =
MockTable.create(this, virtualColumnsSchema, "VC_T1", false, 100,
null, new VirtualColumnsExpressionFactory(), true);
virtualColumnsTable1.addColumn("A", f.intTypeNull);
virtualColumnsTable1.addColumn("B", f.bigintType);
virtualColumnsTable1.addColumn("C", f.varchar10Type);
virtualColumnsTable1.addColumn("D", f.intTypeNull);
// Column E has the same type as column A because it's a virtual column
// with expression that references column A.
virtualColumnsTable1.addColumn("E", f.intTypeNull);
// Same schema with VC_T1 but with different table name.
final MockTable virtualColumnsTable2 =
MockTable.create(this, virtualColumnsSchema, "VC_T2", false, 100,
null, new VirtualColumnsExpressionFactory(), false);
virtualColumnsTable2.addColumn("A", f.intTypeNull);
virtualColumnsTable2.addColumn("B", f.bigintType);
virtualColumnsTable2.addColumn("C", f.varchar10Type);
virtualColumnsTable2.addColumn("D", f.intTypeNull);
virtualColumnsTable2.addColumn("E", f.bigintType);
registerTable(virtualColumnsTable1);
registerTable(virtualColumnsTable2);
// Register table with complex data type rows.
MockSchema complexTypeColumnsSchema = new MockSchema("COMPLEXTYPES");
registerSchema(complexTypeColumnsSchema);
final MockTable complexTypeColumnsTable =
MockTable.create(this, complexTypeColumnsSchema, "CTC_T1",
false, 100);
complexTypeColumnsTable.addColumn("A", f.recordType1);
complexTypeColumnsTable.addColumn("B", f.recordType2);
complexTypeColumnsTable.addColumn("C", f.recordType3);
complexTypeColumnsTable.addColumn("D", f.recordType4);
complexTypeColumnsTable.addColumn("E", f.recordType5);
complexTypeColumnsTable.addColumn("intArrayType", f.intArrayType);
complexTypeColumnsTable.addColumn("varchar5ArrayType", f.varchar5ArrayType);
complexTypeColumnsTable.addColumn("intArrayArrayType", f.intArrayArrayType);
complexTypeColumnsTable.addColumn("varchar5ArrayArrayType", f.varchar5ArrayArrayType);
complexTypeColumnsTable.addColumn("intMultisetType", f.intMultisetType);
complexTypeColumnsTable.addColumn("varchar5MultisetType", f.varchar5MultisetType);
complexTypeColumnsTable.addColumn("intMultisetArrayType", f.intMultisetArrayType);
complexTypeColumnsTable.addColumn("varchar5MultisetArrayType",
f.varchar5MultisetArrayType);
complexTypeColumnsTable.addColumn("intArrayMultisetType", f.intArrayMultisetType);
complexTypeColumnsTable.addColumn("rowArrayMultisetType", f.rowArrayMultisetType);
registerTable(complexTypeColumnsTable);
MockSchema nullableRowsSchema = new MockSchema("NULLABLEROWS");
registerSchema(nullableRowsSchema);
final MockTable nullableRowsTable =
MockTable.create(this, nullableRowsSchema, "NR_T1", false, 100);
RelDataType bigIntNotNull = typeFactory.createSqlType(SqlTypeName.BIGINT);
RelDataType nullableRecordType =
typeFactory.builder()
.nullableRecord(true)
.add("NOT_NULL_FIELD", bigIntNotNull)
.add("NULLABLE_FIELD", bigIntNotNull).nullable(true)
.build();
nullableRowsTable.addColumn("ROW_COLUMN", nullableRecordType, false);
nullableRowsTable.addColumn(
"ROW_COLUMN_ARRAY",
typeFactory.createArrayType(nullableRecordType, -1),
true);
registerTable(nullableRowsTable);
MockSchema geoSchema = new MockSchema("GEO");
registerSchema(geoSchema);
final MockTable restaurantTable =
MockTable.create(this, geoSchema, "RESTAURANTS", false, 100);
restaurantTable.addColumn("NAME", f.varchar20Type, true);
restaurantTable.addColumn("LATITUDE", f.intType);
restaurantTable.addColumn("LONGITUDE", f.intType);
restaurantTable.addColumn("CUISINE", f.varchar10Type);
restaurantTable.addColumn("HILBERT", f.bigintType);
restaurantTable.addMonotonic("HILBERT");
restaurantTable.addWrap(
new BuiltInMetadata.AllPredicates.Handler() {
public RelOptPredicateList getAllPredicates(RelNode r,
RelMetadataQuery mq) {
// Return the predicate:
// r.hilbert = hilbert(r.longitude, r.latitude)
//
// (Yes, x = longitude, y = latitude. Same as ST_MakePoint.)
final RexBuilder rexBuilder = r.getCluster().getRexBuilder();
final RexInputRef refLatitude = rexBuilder.makeInputRef(r, 1);
final RexInputRef refLongitude = rexBuilder.makeInputRef(r, 2);
final RexInputRef refHilbert = rexBuilder.makeInputRef(r, 4);
return RelOptPredicateList.of(rexBuilder,
ImmutableList.of(
rexBuilder.makeCall(SqlStdOperatorTable.EQUALS,
refHilbert,
rexBuilder.makeCall(hilbertOp(),
refLongitude, refLatitude))));
}
SqlOperator hilbertOp() {
for (SqlOperator op
: SqlOperatorTables.spatialInstance().getOperatorList()) {
if (op.getKind() == SqlKind.HILBERT
&& op.getOperandCountRange().isValidCount(2)) {
return op;
}
}
throw new AssertionError();
}
public MetadataDef<BuiltInMetadata.AllPredicates> getDef() {
return BuiltInMetadata.AllPredicates.DEF;
}
});
registerTable(restaurantTable);
return this;
}
}