use of org.apache.calcite.schema.TableMacro in project calcite by apache.
the class ModelHandler method addFunctions.
/**
* Creates and validates a {@link ScalarFunctionImpl}, and adds it to a
* schema. If {@code methodName} is "*", may add more than one function.
*
* @param schema Schema to add to
* @param functionName Name of function; null to derived from method name
* @param path Path to look for functions
* @param className Class to inspect for methods that may be user-defined
* functions
* @param methodName Method name;
* null means use the class as a UDF;
* "*" means add all methods
* @param upCase Whether to convert method names to upper case, so that they
* can be called without using quotes
*/
public static void addFunctions(SchemaPlus schema, String functionName, List<String> path, String className, String methodName, boolean upCase) {
final Class<?> clazz;
try {
clazz = Class.forName(className);
} catch (ClassNotFoundException e) {
throw new RuntimeException("UDF class '" + className + "' not found");
}
final TableFunction tableFunction = TableFunctionImpl.create(clazz, Util.first(methodName, "eval"));
if (tableFunction != null) {
schema.add(functionName, tableFunction);
return;
}
// Must look for TableMacro before ScalarFunction. Both have an "eval"
// method.
final TableMacro macro = TableMacroImpl.create(clazz);
if (macro != null) {
schema.add(functionName, macro);
return;
}
if (methodName != null && methodName.equals("*")) {
for (Map.Entry<String, ScalarFunction> entry : ScalarFunctionImpl.createAll(clazz).entries()) {
String name = entry.getKey();
if (upCase) {
name = name.toUpperCase(Locale.ROOT);
}
schema.add(name, entry.getValue());
}
return;
} else {
final ScalarFunction function = ScalarFunctionImpl.create(clazz, Util.first(methodName, "eval"));
if (function != null) {
final String name;
if (functionName != null) {
name = functionName;
} else if (upCase) {
name = methodName.toUpperCase(Locale.ROOT);
} else {
name = methodName;
}
schema.add(name, function);
return;
}
}
if (methodName == null) {
final AggregateFunction aggFunction = AggregateFunctionImpl.create(clazz);
if (aggFunction != null) {
schema.add(functionName, aggFunction);
return;
}
}
throw new RuntimeException("Not a valid function class: " + clazz + ". Scalar functions and table macros have an 'eval' method; " + "aggregate functions have 'init' and 'add' methods, and optionally " + "'initAdd', 'merge' and 'result' methods.");
}
use of org.apache.calcite.schema.TableMacro in project calcite by apache.
the class SimpleCalciteSchema method addImplicitTablesBasedOnNullaryFunctionsToBuilder.
protected void addImplicitTablesBasedOnNullaryFunctionsToBuilder(ImmutableSortedMap.Builder<String, Table> builder) {
ImmutableSortedMap<String, Table> explicitTables = builder.build();
for (String s : schema.getFunctionNames()) {
// explicit table wins.
if (explicitTables.containsKey(s)) {
continue;
}
for (Function function : schema.getFunctions(s)) {
if (function instanceof TableMacro && function.getParameters().isEmpty()) {
final Table table = ((TableMacro) function).apply(ImmutableList.of());
builder.put(s, table);
}
}
}
}
use of org.apache.calcite.schema.TableMacro in project calcite by apache.
the class JdbcTest method testSchemaCaching.
@Test
public void testSchemaCaching() throws Exception {
final Connection connection = CalciteAssert.that(CalciteAssert.Config.JDBC_FOODMART).connect();
final CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class);
final SchemaPlus rootSchema = calciteConnection.getRootSchema();
// create schema "/a"
final Map<String, Schema> aSubSchemaMap = new HashMap<>();
final SchemaPlus aSchema = rootSchema.add("a", new AbstractSchema() {
@Override
protected Map<String, Schema> getSubSchemaMap() {
return aSubSchemaMap;
}
});
aSchema.setCacheEnabled(true);
assertThat(aSchema.getSubSchemaNames().size(), is(0));
// first call, to populate the cache
assertThat(aSchema.getSubSchemaNames().size(), is(0));
// create schema "/a/b1". Appears only when we disable caching.
aSubSchemaMap.put("b1", new AbstractSchema());
assertThat(aSchema.getSubSchemaNames().size(), is(0));
assertThat(aSchema.getSubSchema("b1"), nullValue());
aSchema.setCacheEnabled(false);
assertThat(aSchema.getSubSchemaNames().size(), is(1));
assertThat(aSchema.getSubSchema("b1"), notNullValue());
// create schema "/a/b2". Appears immediately, because caching is disabled.
aSubSchemaMap.put("b2", new AbstractSchema());
assertThat(aSchema.getSubSchemaNames().size(), is(2));
// an explicit sub-schema appears immediately, even if caching is enabled
aSchema.setCacheEnabled(true);
assertThat(aSchema.getSubSchemaNames().size(), is(2));
// explicit
aSchema.add("b3", new AbstractSchema());
// implicit
aSubSchemaMap.put("b4", new AbstractSchema());
assertThat(aSchema.getSubSchemaNames().size(), is(3));
aSchema.setCacheEnabled(false);
assertThat(aSchema.getSubSchemaNames().size(), is(4));
for (String name : aSchema.getSubSchemaNames()) {
assertThat(aSchema.getSubSchema(name), notNullValue());
}
// create schema "/a2"
final Map<String, Schema> a2SubSchemaMap = new HashMap<>();
final SchemaPlus a2Schema = rootSchema.add("a", new AbstractSchema() {
@Override
protected Map<String, Schema> getSubSchemaMap() {
return a2SubSchemaMap;
}
});
a2Schema.setCacheEnabled(true);
assertThat(a2Schema.getSubSchemaNames().size(), is(0));
// create schema "/a2/b3". Change not visible since caching is enabled.
a2SubSchemaMap.put("b3", new AbstractSchema());
assertThat(a2Schema.getSubSchemaNames().size(), is(0));
Thread.sleep(1);
assertThat(a2Schema.getSubSchemaNames().size(), is(0));
// Change visible after we turn off caching.
a2Schema.setCacheEnabled(false);
assertThat(a2Schema.getSubSchemaNames().size(), is(1));
a2SubSchemaMap.put("b4", new AbstractSchema());
assertThat(a2Schema.getSubSchemaNames().size(), is(2));
for (String name : aSchema.getSubSchemaNames()) {
assertThat(aSchema.getSubSchema(name), notNullValue());
}
// add tables and retrieve with various case sensitivities
final TableInRootSchemaTest.SimpleTable table = new TableInRootSchemaTest.SimpleTable();
a2Schema.add("table1", table);
a2Schema.add("TABLE1", table);
a2Schema.add("tabLe1", table);
a2Schema.add("tabLe2", table);
assertThat(a2Schema.getTableNames().size(), equalTo(4));
final CalciteSchema a2CalciteSchema = CalciteSchema.from(a2Schema);
assertThat(a2CalciteSchema.getTable("table1", true), notNullValue());
assertThat(a2CalciteSchema.getTable("table1", false), notNullValue());
assertThat(a2CalciteSchema.getTable("taBle1", true), nullValue());
assertThat(a2CalciteSchema.getTable("taBle1", false), notNullValue());
final TableMacro function = ViewTable.viewMacro(a2Schema, "values 1", null, null, null);
Util.discard(function);
connection.close();
}
use of org.apache.calcite.schema.TableMacro in project calcite by apache.
the class CalciteSchema method getTablesBasedOnNullaryFunctions.
/**
* Returns tables derived from explicit and implicit functions
* that take zero parameters.
*/
public final NavigableMap<String, Table> getTablesBasedOnNullaryFunctions() {
ImmutableSortedMap.Builder<String, Table> builder = new ImmutableSortedMap.Builder<>(NameSet.COMPARATOR);
for (Map.Entry<String, FunctionEntry> entry : nullaryFunctionMap.map().entrySet()) {
final Function function = entry.getValue().getFunction();
if (function instanceof TableMacro) {
assert function.getParameters().isEmpty();
final Table table = ((TableMacro) function).apply(ImmutableList.of());
builder.put(entry.getKey(), table);
}
}
// add tables derived from implicit functions
addImplicitTablesBasedOnNullaryFunctionsToBuilder(builder);
return Compatible.INSTANCE.navigableMap(builder.build());
}
use of org.apache.calcite.schema.TableMacro in project calcite by apache.
the class CachingCalciteSchema method addImplicitTablesBasedOnNullaryFunctionsToBuilder.
protected void addImplicitTablesBasedOnNullaryFunctionsToBuilder(ImmutableSortedMap.Builder<String, Table> builder) {
ImmutableSortedMap<String, Table> explicitTables = builder.build();
final long now = System.currentTimeMillis();
final NameSet set = implicitFunctionCache.get(now);
for (String s : set.iterable()) {
// explicit table wins.
if (explicitTables.containsKey(s)) {
continue;
}
for (Function function : schema.getFunctions(s)) {
if (function instanceof TableMacro && function.getParameters().isEmpty()) {
final Table table = ((TableMacro) function).apply(ImmutableList.of());
builder.put(s, table);
}
}
}
}
Aggregations