Skip to content

Commit 41be30a

Browse files
authored
IGNITE-27836 Fix documentation for QuerySqlTableFunction (#12743)
1 parent bebb4d8 commit 41be30a

File tree

4 files changed

+93
-13
lines changed

4 files changed

+93
-13
lines changed

docs/_docs/code-snippets/java/src/main/java/org/apache/ignite/snippets/SqlAPI.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,14 @@ public static Iterable<Object[]> table_function(int i) {
174174
new Object[] {i * 10, "empty"}
175175
);
176176
}
177+
178+
@QuerySqlTableFunction(alias = "TABLE_FUNC_WITH_ARRAY", columnTypes = {String.class}, columnNames = {"RES_COL"})
179+
public static Iterable<Object[]> table_function_with_arr(List<Object> array) {
180+
return array.stream()
181+
.map(Object::toString)
182+
.map(str -> new Object[]{str})
183+
.collect(Collectors.toList());
184+
}
177185
}
178186
// end::sql-table-function-example[]
179187

@@ -202,7 +210,11 @@ IgniteCache testSqlTableFunction(Ignite ignite) {
202210

203211
IgniteCache cache = ignite.createCache(cfg);
204212

205-
SqlFieldsQuery query = new SqlFieldsQuery("SELECT STR_COL FROM TABLE_FUNCTION(10) WHERE INT_COL > 50");
213+
SqlFieldsQuery query = new SqlFieldsQuery("SELECT STR_COL FROM TABLE(TABLE_FUNCTION(10)) WHERE INT_COL > 50");
214+
215+
cache.query(query).getAll();
216+
217+
query = new SqlFieldsQuery("SELECT RES_COL FROM TABLE(TABLE_FUNC_WITH_ARRAY(?))").setArgs(List.of("row1", "row2"));
206218

207219
cache.query(query).getAll();
208220
// end::sql-table-function-config-query[]

modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/integration/UserDefinedFunctionsIntegrationTest.java

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.util.Arrays;
2222
import java.util.Collection;
2323
import java.util.List;
24+
import java.util.stream.Collectors;
2425
import org.apache.calcite.schema.SchemaPlus;
2526
import org.apache.calcite.sql.validate.SqlValidatorException;
2627
import org.apache.ignite.IgniteCache;
@@ -92,7 +93,6 @@ public void testSameSignatureNotRegistered() throws Exception {
9293
assertEquals(1, schema.getFunctions("SAMESIGN").size());
9394
}
9495

95-
9696
/** */
9797
@Test
9898
public void testSystemFunctionOverriding() throws Exception {
@@ -105,18 +105,25 @@ public void testSystemFunctionOverriding() throws Exception {
105105

106106
// Make sure that the new functions didn't affect schema 'PUBLIC'.
107107
assertQuery("SELECT UPPER(?)").withParams("abc").returns("ABC").check();
108-
assertQuery("select UNIX_SECONDS(TIMESTAMP '2021-01-01 00:00:00')").returns(1609459200L).check();
109-
assertQuery("select * from table(SYSTEM_RANGE(1, 2))").returns(1L).returns(2L).check();
110-
assertQuery("select TYPEOF(?)").withParams(1L).returns("BIGINT").check();
111-
assertQuery("select ? + ?").withParams(1, 2).returns(3).check();
112-
assertThrows("select PLUS(?, ?)", SqlValidatorException.class, "No match found for function signature", 1, 2);
108+
assertQuery("SELECT UNIX_SECONDS(TIMESTAMP '2021-01-01 00:00:00')").returns(1609459200L).check();
109+
assertQuery("SELECT * FROM TABLE(SYSTEM_RANGE(1, 2))").returns(1L).returns(2L).check();
110+
assertQuery("SELECT TYPEOF(?)").withParams(1L).returns("BIGINT").check();
111+
assertQuery("SELECT ? + ?").withParams(1, 2).returns(3).check();
112+
assertThrows("SELECT PLUS(?, ?)", SqlValidatorException.class, "No match found for function signature", 1, 2);
113113

114114
// Ensure that new functions are successfully created in a custom schema.
115115
assertQuery("SELECT \"OWN_SCHEMA\".UPPER(?)").withParams("abc").returns(3).check();
116-
assertQuery("select \"OWN_SCHEMA\".UNIX_SECONDS(TIMESTAMP '2021-01-01 00:00:00')").returns(1).check();
117-
assertQuery("select * from table(\"OWN_SCHEMA\".SYSTEM_RANGE(1, 2))").returns(100L).check();
118-
assertQuery("select \"OWN_SCHEMA\".TYPEOF('ABC')").returns(1).check();
119-
assertQuery("select \"OWN_SCHEMA\".PLUS(?, ?)").withParams(1, 2).returns(100).check();
116+
assertQuery("SELECT \"OWN_SCHEMA\".UNIX_SECONDS(TIMESTAMP '2021-01-01 00:00:00')").returns(1).check();
117+
assertQuery("SELECT * FROM TABLE(\"OWN_SCHEMA\".SYSTEM_RANGE(1, 2))").returns(100L).check();
118+
assertQuery("SELECT \"OWN_SCHEMA\".TYPEOF('ABC')").returns(1).check();
119+
assertQuery("SELECT \"OWN_SCHEMA\".PLUS(?, ?)").withParams(1, 2).returns(100).check();
120+
121+
assertQuery("SELECT * FROM TABLE(\"OWN_SCHEMA\".STR_ARRAY_CONSUME_TABLE(?)) as t").withParams(List.of("row1", "row2"))
122+
.returns("row1").returns( "row2").check();
123+
assertQuery("SELECT * FROM TABLE(\"OWN_SCHEMA\".OBJ_ARRAY_CONSUME_TABLE(?)) as t").withParams(List.of(new CustomClass(), "row2"))
124+
.returns("CustomClass.toString").returns( "row2").check();
125+
assertThrows("SELECT * FROM TABLE(\"OWN_SCHEMA\".STR_ARRAY_CONSUME_TABLE(?)) as t", IgniteSQLException.class,
126+
"An error occurred while query executing", List.of(new CustomClass(), "row2"));
120127

121128
LogListener logChecker0 = LogListener.matches("Unable to add user-defined SQL function 'upper'")
122129
.andMatches("Unable to add user-defined SQL function 'unix_seconds'")
@@ -713,6 +720,24 @@ public static int typeof(Object o) {
713720
public static int plus(int x, int y) {
714721
return 100;
715722
}
723+
724+
/** Table function with String array as input. */
725+
@QuerySqlTableFunction(alias = "STR_ARRAY_CONSUME_TABLE", columnTypes = {String.class}, columnNames = {"RESULT"})
726+
public static Iterable<Object[]> strArrConsumeTable(List<String> array) {
727+
return array.stream()
728+
.map(Object::toString)
729+
.map(str -> new Object[]{str})
730+
.collect(Collectors.toList());
731+
}
732+
733+
/** Table function with Object array as input. */
734+
@QuerySqlTableFunction(alias = "OBJ_ARRAY_CONSUME_TABLE", columnTypes = {String.class}, columnNames = {"RESULT"})
735+
public static Iterable<Object[]> objArrConsumeTable(List<Object> array) {
736+
return array.stream()
737+
.map(Object::toString)
738+
.map(str -> new Object[]{str})
739+
.collect(Collectors.toList());
740+
}
716741
}
717742

718743
/** */
@@ -726,4 +751,12 @@ public static double salary(String ignite, int key) {
726751
.getAll().get(0).get(0);
727752
}
728753
}
754+
755+
/** */
756+
private static class CustomClass {
757+
/** */
758+
@Override public String toString() {
759+
return "CustomClass.toString";
760+
}
761+
}
729762
}

modules/calcite/src/test/java/org/apache/ignite/internal/processors/query/calcite/jdbc/JdbcQueryTest.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@
4040
import java.util.concurrent.TimeUnit;
4141
import java.util.stream.Collectors;
4242
import java.util.stream.Stream;
43+
import org.apache.ignite.cache.query.annotations.QuerySqlTableFunction;
4344
import org.apache.ignite.calcite.CalciteQueryEngineConfiguration;
45+
import org.apache.ignite.configuration.CacheConfiguration;
4446
import org.apache.ignite.configuration.IgniteConfiguration;
4547
import org.apache.ignite.configuration.SqlConfiguration;
4648
import org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion;
@@ -69,8 +71,14 @@ public class JdbcQueryTest extends GridCommonAbstractTest {
6971

7072
/** {@inheritDoc} */
7173
@Override protected IgniteConfiguration getConfiguration(String igniteInstanceName) throws Exception {
74+
CacheConfiguration<Object, Object> ccfg = new CacheConfiguration<>("TEST_CACHE_OWN")
75+
.setSqlSchema("OWN_SCHEMA")
76+
.setSqlFunctionClasses(FunctionsLibrary.class);
77+
7278
return super.getConfiguration(igniteInstanceName).setSqlConfiguration(
73-
new SqlConfiguration().setQueryEnginesConfiguration(new CalciteQueryEngineConfiguration()));
79+
new SqlConfiguration()
80+
.setQueryEnginesConfiguration(new CalciteQueryEngineConfiguration()))
81+
.setCacheConfiguration(ccfg);
7482
}
7583

7684
/** {@inheritDoc} */
@@ -113,6 +121,21 @@ private void connect(String url) throws Exception {
113121
stopAllGrids();
114122
}
115123

124+
/** Test user defined table through jdbc. */
125+
@Test
126+
public void testUdt() throws Exception {
127+
try (PreparedStatement ps = conn.prepareStatement("SELECT * FROM TABLE(\"OWN_SCHEMA\".STR_ARRAY_CONSUME_TABLE(?))")) {
128+
ps.setObject(1, List.of("row1", "row2"));
129+
ResultSet rs = ps.executeQuery();
130+
131+
assertTrue(rs.next());
132+
assertEquals("row1", rs.getString(1));
133+
134+
assertTrue(rs.next());
135+
assertEquals("row2", rs.getString(1));
136+
}
137+
}
138+
116139
/**
117140
* @throws SQLException If failed.
118141
*/
@@ -490,4 +513,16 @@ public ObjectToStore(int id, String name, double val) {
490513
return Objects.hash(id, name, val);
491514
}
492515
}
516+
517+
/** User defined functions. */
518+
public static class FunctionsLibrary {
519+
/** Function consume String array and output it row by row. */
520+
@QuerySqlTableFunction(alias = "STR_ARRAY_CONSUME_TABLE", columnTypes = {String.class}, columnNames = {"RESULT"})
521+
public static Iterable<Object[]> strArrConsumeTable(List<String> array) {
522+
return array.stream()
523+
.map(Object::toString)
524+
.map(str -> new Object[]{str})
525+
.collect(Collectors.toList());
526+
}
527+
}
493528
}

modules/core/src/main/java/org/apache/ignite/cache/query/annotations/QuerySqlTableFunction.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
* cacheCfg.setSqlFunctionClasses(MyTableFunctions.class);
4646
*
4747
* // And use in queries.
48-
* cache.query(new SqlFieldsQuery("select S_VAL from MY_TABLE(1, 5.0f, "ext") where F_VAL is not null"));
48+
* cache.query(new SqlFieldsQuery("select S_VAL from TABLE(MY_TABLE(1, 5.0f, "ext")) where F_VAL is not null"));
4949
* </pre>
5050
* <p>
5151
* Table function must return an {@code Iterable} as a row set. Each row can be represented by an {@code Object[]} or

0 commit comments

Comments
 (0)