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]

Reply via email to