This is an automated email from the ASF dual-hosted git repository.

zstan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ignite.git


The following commit(s) were added to refs/heads/master by this push:
     new 41be30aa666 IGNITE-27836 Fix documentation for QuerySqlTableFunction 
(#12743)
41be30aa666 is described below

commit 41be30aa666599e856b4975fabcabf37dcb21f93
Author: Evgeniy Stanilovskiy <[email protected]>
AuthorDate: Fri Feb 20 15:27:15 2026 +0300

    IGNITE-27836 Fix documentation for QuerySqlTableFunction (#12743)
---
 .../java/org/apache/ignite/snippets/SqlAPI.java    | 14 +++++-
 .../UserDefinedFunctionsIntegrationTest.java       | 53 ++++++++++++++++++----
 .../query/calcite/jdbc/JdbcQueryTest.java          | 37 ++++++++++++++-
 .../query/annotations/QuerySqlTableFunction.java   |  2 +-
 4 files changed, 93 insertions(+), 13 deletions(-)

diff --git 
a/docs/_docs/code-snippets/java/src/main/java/org/apache/ignite/snippets/SqlAPI.java
 
b/docs/_docs/code-snippets/java/src/main/java/org/apache/ignite/snippets/SqlAPI.java
index 9de660bf2db..eff7d037676 100644
--- 
a/docs/_docs/code-snippets/java/src/main/java/org/apache/ignite/snippets/SqlAPI.java
+++ 
b/docs/_docs/code-snippets/java/src/main/java/org/apache/ignite/snippets/SqlAPI.java
@@ -174,6 +174,14 @@ public class SqlAPI {
                 new Object[] {i * 10, "empty"}
             );
         }
+
+        @QuerySqlTableFunction(alias = "TABLE_FUNC_WITH_ARRAY", columnTypes = 
{String.class}, columnNames = {"RES_COL"})
+        public static Iterable<Object[]> table_function_with_arr(List<Object> 
array) {
+            return array.stream()
+                .map(Object::toString)
+                .map(str -> new Object[]{str})
+                .collect(Collectors.toList());
+        }
     }
     // end::sql-table-function-example[]
 
@@ -202,7 +210,11 @@ public class SqlAPI {
 
         IgniteCache cache = ignite.createCache(cfg);
 
-        SqlFieldsQuery query = new SqlFieldsQuery("SELECT STR_COL FROM 
TABLE_FUNCTION(10) WHERE INT_COL > 50");
+        SqlFieldsQuery query = new SqlFieldsQuery("SELECT STR_COL FROM 
TABLE(TABLE_FUNCTION(10)) WHERE INT_COL > 50");
+
+        cache.query(query).getAll();
+
+        query = new SqlFieldsQuery("SELECT RES_COL FROM 
TABLE(TABLE_FUNC_WITH_ARRAY(?))").setArgs(List.of("row1", "row2"));
 
         cache.query(query).getAll();
         // end::sql-table-function-config-query[]
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/UserDefinedFunctionsIntegrationTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/UserDefinedFunctionsIntegrationTest.java
index 41aef299596..278b3bac52f 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/UserDefinedFunctionsIntegrationTest.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/UserDefinedFunctionsIntegrationTest.java
@@ -21,6 +21,7 @@ import java.sql.Timestamp;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
+import java.util.stream.Collectors;
 import org.apache.calcite.schema.SchemaPlus;
 import org.apache.calcite.sql.validate.SqlValidatorException;
 import org.apache.ignite.IgniteCache;
@@ -92,7 +93,6 @@ public class UserDefinedFunctionsIntegrationTest extends 
AbstractBasicIntegratio
         assertEquals(1, schema.getFunctions("SAMESIGN").size());
     }
 
-
     /** */
     @Test
     public void testSystemFunctionOverriding() throws Exception {
@@ -105,18 +105,25 @@ public class UserDefinedFunctionsIntegrationTest extends 
AbstractBasicIntegratio
 
         // 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 * from table(SYSTEM_RANGE(1, 
2))").returns(1L).returns(2L).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);
+        assertQuery("SELECT UNIX_SECONDS(TIMESTAMP '2021-01-01 
00:00:00')").returns(1609459200L).check();
+        assertQuery("SELECT * FROM TABLE(SYSTEM_RANGE(1, 
2))").returns(1L).returns(2L).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 * from table(\"OWN_SCHEMA\".SYSTEM_RANGE(1, 
2))").returns(100L).check();
-        assertQuery("select \"OWN_SCHEMA\".TYPEOF('ABC')").returns(1).check();
-        assertQuery("select \"OWN_SCHEMA\".PLUS(?, ?)").withParams(1, 
2).returns(100).check();
+        assertQuery("SELECT \"OWN_SCHEMA\".UNIX_SECONDS(TIMESTAMP '2021-01-01 
00:00:00')").returns(1).check();
+        assertQuery("SELECT * FROM TABLE(\"OWN_SCHEMA\".SYSTEM_RANGE(1, 
2))").returns(100L).check();
+        assertQuery("SELECT \"OWN_SCHEMA\".TYPEOF('ABC')").returns(1).check();
+        assertQuery("SELECT \"OWN_SCHEMA\".PLUS(?, ?)").withParams(1, 
2).returns(100).check();
+
+        assertQuery("SELECT * FROM 
TABLE(\"OWN_SCHEMA\".STR_ARRAY_CONSUME_TABLE(?)) as 
t").withParams(List.of("row1", "row2"))
+            .returns("row1").returns( "row2").check();
+        assertQuery("SELECT * FROM 
TABLE(\"OWN_SCHEMA\".OBJ_ARRAY_CONSUME_TABLE(?)) as t").withParams(List.of(new 
CustomClass(), "row2"))
+            .returns("CustomClass.toString").returns( "row2").check();
+        assertThrows("SELECT * FROM 
TABLE(\"OWN_SCHEMA\".STR_ARRAY_CONSUME_TABLE(?)) as t", 
IgniteSQLException.class,
+            "An error occurred while query executing", List.of(new 
CustomClass(), "row2"));
 
         LogListener logChecker0 = LogListener.matches("Unable to add 
user-defined SQL function 'upper'")
             .andMatches("Unable to add user-defined SQL function 
'unix_seconds'")
@@ -713,6 +720,24 @@ public class UserDefinedFunctionsIntegrationTest extends 
AbstractBasicIntegratio
         public static int plus(int x, int y) {
             return 100;
         }
+
+        /** Table function with String array as input. */
+        @QuerySqlTableFunction(alias = "STR_ARRAY_CONSUME_TABLE", columnTypes 
= {String.class}, columnNames = {"RESULT"})
+        public static Iterable<Object[]> strArrConsumeTable(List<String> 
array) {
+            return array.stream()
+                .map(Object::toString)
+                .map(str -> new Object[]{str})
+                .collect(Collectors.toList());
+        }
+
+        /** Table function with Object array as input. */
+        @QuerySqlTableFunction(alias = "OBJ_ARRAY_CONSUME_TABLE", columnTypes 
= {String.class}, columnNames = {"RESULT"})
+        public static Iterable<Object[]> objArrConsumeTable(List<Object> 
array) {
+            return array.stream()
+                .map(Object::toString)
+                .map(str -> new Object[]{str})
+                .collect(Collectors.toList());
+        }
     }
 
     /** */
@@ -726,4 +751,12 @@ public class UserDefinedFunctionsIntegrationTest extends 
AbstractBasicIntegratio
                 .getAll().get(0).get(0);
         }
     }
+
+    /** */
+    private static class CustomClass {
+        /** */
+        @Override public String toString() {
+            return "CustomClass.toString";
+        }
+    }
 }
diff --git 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/jdbc/JdbcQueryTest.java
 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/jdbc/JdbcQueryTest.java
index cd457f62a38..c7d39bfa208 100644
--- 
a/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/jdbc/JdbcQueryTest.java
+++ 
b/modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/jdbc/JdbcQueryTest.java
@@ -40,7 +40,9 @@ import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
+import org.apache.ignite.cache.query.annotations.QuerySqlTableFunction;
 import org.apache.ignite.calcite.CalciteQueryEngineConfiguration;
+import org.apache.ignite.configuration.CacheConfiguration;
 import org.apache.ignite.configuration.IgniteConfiguration;
 import org.apache.ignite.configuration.SqlConfiguration;
 import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
@@ -69,8 +71,14 @@ public class JdbcQueryTest extends GridCommonAbstractTest {
 
     /** {@inheritDoc} */
     @Override protected IgniteConfiguration getConfiguration(String 
igniteInstanceName) throws Exception {
+        CacheConfiguration<Object, Object> ccfg = new 
CacheConfiguration<>("TEST_CACHE_OWN")
+            .setSqlSchema("OWN_SCHEMA")
+            .setSqlFunctionClasses(FunctionsLibrary.class);
+
         return super.getConfiguration(igniteInstanceName).setSqlConfiguration(
-            new SqlConfiguration().setQueryEnginesConfiguration(new 
CalciteQueryEngineConfiguration()));
+            new SqlConfiguration()
+                .setQueryEnginesConfiguration(new 
CalciteQueryEngineConfiguration()))
+                .setCacheConfiguration(ccfg);
     }
 
     /** {@inheritDoc} */
@@ -113,6 +121,21 @@ public class JdbcQueryTest extends GridCommonAbstractTest {
         stopAllGrids();
     }
 
+    /** Test user defined table through jdbc. */
+    @Test
+    public void testUdt() throws Exception {
+        try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM 
TABLE(\"OWN_SCHEMA\".STR_ARRAY_CONSUME_TABLE(?))")) {
+            ps.setObject(1, List.of("row1", "row2"));
+            ResultSet rs = ps.executeQuery();
+
+            assertTrue(rs.next());
+            assertEquals("row1", rs.getString(1));
+
+            assertTrue(rs.next());
+            assertEquals("row2", rs.getString(1));
+        }
+    }
+
     /**
      * @throws SQLException If failed.
      */
@@ -490,4 +513,16 @@ public class JdbcQueryTest extends GridCommonAbstractTest {
             return Objects.hash(id, name, val);
         }
     }
+
+    /** User defined functions. */
+    public static class FunctionsLibrary {
+        /** Function consume String array and output it row by row. */
+        @QuerySqlTableFunction(alias = "STR_ARRAY_CONSUME_TABLE", columnTypes 
= {String.class}, columnNames = {"RESULT"})
+        public static Iterable<Object[]> strArrConsumeTable(List<String> 
array) {
+            return array.stream()
+                .map(Object::toString)
+                .map(str -> new Object[]{str})
+                .collect(Collectors.toList());
+        }
+    }
 }
diff --git 
a/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlTableFunction.java
 
b/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlTableFunction.java
index 7c41bf954ef..bceae02916c 100644
--- 
a/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlTableFunction.java
+++ 
b/modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlTableFunction.java
@@ -45,7 +45,7 @@ import 
org.apache.ignite.resources.SessionContextProviderResource;
  *     cacheCfg.setSqlFunctionClasses(MyTableFunctions.class);
  *
  *     // And use in queries.
- *     cache.query(new SqlFieldsQuery("select S_VAL from MY_TABLE(1, 5.0f, 
"ext") where F_VAL is not null"));
+ *     cache.query(new SqlFieldsQuery("select S_VAL from TABLE(MY_TABLE(1, 
5.0f, "ext")) where F_VAL is not null"));
  * </pre>
  * <p>
  * Table function must return an {@code Iterable} as a row set. Each row can 
be represented by an {@code Object[]} or

Reply via email to