alex-plekhanov commented on code in PR #11851:
URL: https://github.com/apache/ignite/pull/11851#discussion_r1944955669
##########
modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/UserDefinedFunctionsIntegrationTest.java:
##########
@@ -61,6 +67,64 @@ public class UserDefinedFunctionsIntegrationTest extends
AbstractBasicIntegratio
return cfg;
}
+ /** */
+ @Test
+ public void testSystemFunctionOverriding() throws Exception {
+ // To a custom schema.
+ client.getOrCreateCache(new CacheConfiguration<Integer,
Employer>("TEST_CACHE_OWN")
+ .setSqlSchema("OWN_SCHEMA")
+ .setSqlFunctionClasses(OverrideSystemFunctionLibrary.class)
+ .setQueryEntities(F.asList(new QueryEntity(Integer.class,
Employer.class).setTableName("emp_own")))
+ );
+
+ // Make sure that the new functions didn't affect schema 'PUBLIC'.
+ assertQuery("SELECT
UPPER(?)").withParams("abc").returns("ABC").check();
+ assertQuery("select UNIX_SECONDS(TIMESTAMP '2021-01-01
00:00:00')").returns(1609459200L).check();
+ assertQuery("select
TYPEOF(?)").withParams(1L).returns("BIGINT").check();
+ assertQuery("select ? + ?").withParams(1, 2).returns(3).check();
+ assertThrows("select PLUS(?, ?)", SqlValidatorException.class, "No
match found for function signature", 1, 2);
+
+ // Ensure that new functions are successfully created in a custom
schema.
+ assertQuery("SELECT
\"OWN_SCHEMA\".UPPER(?)").withParams("abc").returns(3).check();
+ assertQuery("select \"OWN_SCHEMA\".UNIX_SECONDS(TIMESTAMP '2021-01-01
00:00:00')").returns(1).check();
+ assertQuery("select \"OWN_SCHEMA\".TYPEOF('ABC')").returns(1).check();
+ assertQuery("select \"OWN_SCHEMA\".PLUS(?, ?)").withParams(1,
2).returns(100).check();
+
+ LogListener logChecker0 = LogListener.matches("Unable to add
user-defined SQL function 'upper'")
+ .andMatches("Unable to add user-defined SQL function
'unix_seconds'")
+ .andMatches("Unable to add user-defined SQL function 'typeof'")
+ .andMatches("Unable to add user-defined SQL function
'plus'").times(0)
+ .build();
+
+ listeningLog.registerListener(logChecker0);
+
+ // Try to add the functions into the default schema.
+ client.getOrCreateCache(new CacheConfiguration<Integer,
Employer>("TEST_CACHE_PUB")
+ .setSqlFunctionClasses(OverrideSystemFunctionLibrary.class)
+ .setSqlSchema(QueryUtils.DFLT_SCHEMA)
+ .setQueryEntities(F.asList(new QueryEntity(Integer.class,
Employer.class).setTableName("emp_pub"))));
+
+ assertTrue(logChecker0.check(getTestTimeout()));
+
+ // Make sure that the standard functions work once again.
+ assertQuery("SELECT
UPPER(?)").withParams("abc").returns("ABC").check();
+ assertQuery("select UNIX_SECONDS(TIMESTAMP '2021-01-01
00:00:00')").returns(1609459200L).check();
+ assertQuery("select
TYPEOF(?)").withParams(1L).returns("BIGINT").check();
+
+ // Make sure that operator + works and new function 'PLUS' also
regustered in the default schema.
Review Comment:
Typo `regustered`
##########
modules/calcite/src/main/java/org/apache/ignite/internal/processors/query/calcite/schema/SchemaHolderImpl.java:
##########
@@ -371,13 +377,29 @@ private static Object
affinityIdentity(CacheConfiguration<?, ?> ccfg) {
Class<?>[] colTypes,
String[] colNames
) {
+ if (!checkNewUserDefinedFunction(schemaName, name))
+ return;
+
IgniteSchema schema = igniteSchemas.computeIfAbsent(schemaName,
IgniteSchema::new);
schema.addFunction(name.toUpperCase(),
IgniteTableFunction.create(method, colTypes, colNames));
rebuild();
}
+ /** */
+ private boolean checkNewUserDefinedFunction(String schName, String
funName) {
+ if (F.eq(schName, QueryUtils.DFLT_SCHEMA)
+ && RexImpTable.INSTANCE.hasOperator(op -> op instanceof
SqlFunction && op.getName().equalsIgnoreCase(funName))) {
Review Comment:
RexImpTable - it's not a catalog of all system functions, it's implementor
table. Some functions are absent in RexImpTable (convertlet can transform some
function to another, for example, there is no DECODE or NVL.. in RexImpTable).
Right place to find system functions - is operator table (see
frameworkCfg.getOperatorTable().lookupOperatorOverloads())
##########
modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/UserDefinedFunctionsIntegrationTest.java:
##########
@@ -61,6 +67,64 @@ public class UserDefinedFunctionsIntegrationTest extends
AbstractBasicIntegratio
return cfg;
}
+ /** */
+ @Test
+ public void testSystemFunctionOverriding() throws Exception {
+ // To a custom schema.
+ client.getOrCreateCache(new CacheConfiguration<Integer,
Employer>("TEST_CACHE_OWN")
+ .setSqlSchema("OWN_SCHEMA")
+ .setSqlFunctionClasses(OverrideSystemFunctionLibrary.class)
+ .setQueryEntities(F.asList(new QueryEntity(Integer.class,
Employer.class).setTableName("emp_own")))
+ );
+
+ // Make sure that the new functions didn't affect schema 'PUBLIC'.
+ assertQuery("SELECT
UPPER(?)").withParams("abc").returns("ABC").check();
Review Comment:
Let's check also system_range table function
##########
modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/UserDefinedFunctionsIntegrationTest.java:
##########
@@ -61,6 +67,64 @@ public class UserDefinedFunctionsIntegrationTest extends
AbstractBasicIntegratio
return cfg;
}
+ /** */
+ @Test
+ public void testSystemFunctionOverriding() throws Exception {
+ // To a custom schema.
+ client.getOrCreateCache(new CacheConfiguration<Integer,
Employer>("TEST_CACHE_OWN")
+ .setSqlSchema("OWN_SCHEMA")
+ .setSqlFunctionClasses(OverrideSystemFunctionLibrary.class)
+ .setQueryEntities(F.asList(new QueryEntity(Integer.class,
Employer.class).setTableName("emp_own")))
+ );
+
+ // Make sure that the new functions didn't affect schema 'PUBLIC'.
+ assertQuery("SELECT
UPPER(?)").withParams("abc").returns("ABC").check();
+ assertQuery("select UNIX_SECONDS(TIMESTAMP '2021-01-01
00:00:00')").returns(1609459200L).check();
+ assertQuery("select
TYPEOF(?)").withParams(1L).returns("BIGINT").check();
+ assertQuery("select ? + ?").withParams(1, 2).returns(3).check();
+ assertThrows("select PLUS(?, ?)", SqlValidatorException.class, "No
match found for function signature", 1, 2);
+
+ // Ensure that new functions are successfully created in a custom
schema.
+ assertQuery("SELECT
\"OWN_SCHEMA\".UPPER(?)").withParams("abc").returns(3).check();
+ assertQuery("select \"OWN_SCHEMA\".UNIX_SECONDS(TIMESTAMP '2021-01-01
00:00:00')").returns(1).check();
+ assertQuery("select \"OWN_SCHEMA\".TYPEOF('ABC')").returns(1).check();
+ assertQuery("select \"OWN_SCHEMA\".PLUS(?, ?)").withParams(1,
2).returns(100).check();
+
+ LogListener logChecker0 = LogListener.matches("Unable to add
user-defined SQL function 'upper'")
+ .andMatches("Unable to add user-defined SQL function
'unix_seconds'")
+ .andMatches("Unable to add user-defined SQL function 'typeof'")
+ .andMatches("Unable to add user-defined SQL function
'plus'").times(0)
+ .build();
+
+ listeningLog.registerListener(logChecker0);
+
+ // Try to add the functions into the default schema.
+ client.getOrCreateCache(new CacheConfiguration<Integer,
Employer>("TEST_CACHE_PUB")
+ .setSqlFunctionClasses(OverrideSystemFunctionLibrary.class)
+ .setSqlSchema(QueryUtils.DFLT_SCHEMA)
+ .setQueryEntities(F.asList(new QueryEntity(Integer.class,
Employer.class).setTableName("emp_pub"))));
+
+ assertTrue(logChecker0.check(getTestTimeout()));
+
+ // Make sure that the standard functions work once again.
+ assertQuery("SELECT
UPPER(?)").withParams("abc").returns("ABC").check();
+ assertQuery("select UNIX_SECONDS(TIMESTAMP '2021-01-01
00:00:00')").returns(1609459200L).check();
+ assertQuery("select
TYPEOF(?)").withParams(1L).returns("BIGINT").check();
+
+ // Make sure that operator + works and new function 'PLUS' also
regustered in the default schema.
+ assertQuery("select ? + ?").withParams(1, 2).returns(3).check();
+ assertQuery("select PLUS(?, ?)").withParams(1, 2).returns(100);
+
+ CalciteQueryProcessor qryProc =
Commons.lookupComponent(client.context(), CalciteQueryProcessor.class);
+ Map<String, IgniteSchema> schemas =
GridTestUtils.getFieldValue(qryProc, "schemaHolder", "igniteSchemas");
+ IgniteSchema dfltSchema = schemas.get(QueryUtils.DFLT_SCHEMA);
Review Comment:
Why not use public API?
queryProcessor(ignite).schemaHolder().schema(QueryUtils.DFLT_SCHEMA)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]