diff --git a/doc/changes/changelog.md b/doc/changes/changelog.md index 3a9335b..b9d17d2 100644 --- a/doc/changes/changelog.md +++ b/doc/changes/changelog.md @@ -1,5 +1,6 @@ # Changes +* [0.6.20](changes_0.6.20.md) * [0.6.19](changes_0.6.19.md) * [0.6.18](changes_0.6.18.md) * [0.6.17](changes_0.6.17.md) diff --git a/doc/changes/changes_0.6.20.md b/doc/changes/changes_0.6.20.md new file mode 100644 index 0000000..42b191f --- /dev/null +++ b/doc/changes/changes_0.6.20.md @@ -0,0 +1,14 @@ +# Udf Debugging Java 0.6.20, released 2026-07-16 + +Code name: Code Coverage > 80% + +## Summary + +In this release we fixed Sonar findings and raised the code coverage ot over 80%. + +We added an integration test for `PushDownTesting`. + +## Features + +* Fixed Sonar findings and raised test coverage. (PR #86) + diff --git a/pk_generated_parent.pom b/pk_generated_parent.pom index dff9fa9..d776ad2 100644 --- a/pk_generated_parent.pom +++ b/pk_generated_parent.pom @@ -3,7 +3,7 @@ 4.0.0 com.exasol udf-debugging-java-generated-parent - 0.6.19 + 0.6.20 pom UTF-8 diff --git a/pom.xml b/pom.xml index b88de7a..685740a 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 udf-debugging-java - 0.6.19 + 0.6.20 udf-debugging-java Utilities for debugging, profiling and code coverage measure for UDFs. https://github.com/exasol/udf-debugging-java/ @@ -147,7 +147,7 @@ udf-debugging-java-generated-parent com.exasol - 0.6.19 + 0.6.20 pk_generated_parent.pom diff --git a/src/main/java/com/exasol/udfdebugging/PushDownTesting.java b/src/main/java/com/exasol/udfdebugging/PushDownTesting.java index f09f147..724b132 100644 --- a/src/main/java/com/exasol/udfdebugging/PushDownTesting.java +++ b/src/main/java/com/exasol/udfdebugging/PushDownTesting.java @@ -21,9 +21,10 @@ private PushDownTesting() { * @return generated push down query * @throws SQLException if execution fails */ + @SuppressWarnings("java:S2077") // Constructed SQL only used in tests. public static String getPushDownSql(final Statement statement, final String query) throws SQLException { try (final ResultSet pushDownSqlResult = statement - .executeQuery("SELECT PUSHDOWN_SQL FROM (EXPLAIN VIRTUAL " + query + ");")) { + .executeQuery("SELECT PUSHDOWN_SQL FROM (EXPLAIN VIRTUAL " + query + ")")) { pushDownSqlResult.next(); return pushDownSqlResult.getString("PUSHDOWN_SQL"); } @@ -37,10 +38,11 @@ public static String getPushDownSql(final Statement statement, final String quer * @return selection (where clause) * @throws SQLException if SQL statement fails */ + @SuppressWarnings("java:S2077") // Constructed SQL only used in tests. public static String getSelectionThatIsSentToTheAdapter(final Statement statement, final String query) throws SQLException { try (final ResultSet pushDownSqlResult = statement - .executeQuery("SELECT PUSHDOWN_JSON FROM (EXPLAIN VIRTUAL " + query + ");")) { + .executeQuery("SELECT PUSHDOWN_JSON FROM (EXPLAIN VIRTUAL " + query + ")")) { pushDownSqlResult.next(); final String pushdownJson = pushDownSqlResult.getString("PUSHDOWN_JSON"); try (final JsonReader reader = Json.createReader(new StringReader(pushdownJson))) { diff --git a/src/test/java/com/exasol/udfdebugging/PushDownTestingIT.java b/src/test/java/com/exasol/udfdebugging/PushDownTestingIT.java new file mode 100644 index 0000000..834c65c --- /dev/null +++ b/src/test/java/com/exasol/udfdebugging/PushDownTestingIT.java @@ -0,0 +1,69 @@ +package com.exasol.udfdebugging; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.sql.SQLException; +import java.sql.Statement; + +import org.junit.jupiter.api.Test; + +import com.exasol.udfdebugging.modules.TestSetup; + +class PushDownTestingIT { + private static final String VS_SCHEMA = "VS_SCHEMA"; + private static final String VS_ADAPTER = VS_SCHEMA + ".VS_ADAPTER"; + private static final String VIRTUAL_SCHEMA_NAME = "TEST_VS"; + private static final String TABLE_NAME = "THE_TABLE"; + + private static String loadAdapterScriptContent() { + try (InputStream adapterScriptStream = PushDownTestingIT.class.getClassLoader() + .getResourceAsStream("virtual_schema_stub.lua")) { + if (adapterScriptStream == null) { + throw new AssertionError("Failed to find adapter script resource on the classpath."); + } + return new String(adapterScriptStream.readAllBytes(), StandardCharsets.UTF_8); + } catch (IOException exception) { + throw new AssertionError("Failed to read adapter script resource.", exception); + } + } + + + @Test + void testGetPushDownSqlFromExplainVirtual() throws SQLException { + try ( + final TestSetup testSetup = new TestSetup(); + final Statement statement = testSetup.getConnection().createStatement() + ) { + createVirtualSchema(statement); + final String pushDownSql = PushDownTesting.getPushDownSql(statement, + "SELECT THE_VALUE FROM " + VIRTUAL_SCHEMA_NAME + "." + TABLE_NAME); + assertThat(pushDownSql, equalTo("SELECT 'Hello VS!'")); + } + } + + @Test + void testGetSelectionThatIsSentToTheAdapter() throws SQLException { + try ( + final TestSetup testSetup = new TestSetup(); + final Statement statement = testSetup.getConnection().createStatement() + ) { + createVirtualSchema(statement); + final String pushDownSql = PushDownTesting.getSelectionThatIsSentToTheAdapter(statement, + "SELECT THE_VALUE FROM " + VIRTUAL_SCHEMA_NAME + "." + TABLE_NAME + + " WHERE THE_VALUE = 'something'"); + assertThat(pushDownSql, equalTo(TABLE_NAME +".THE_VALUE='something'")); + } + } + + private void createVirtualSchema(final Statement statement) throws SQLException { + statement.execute("DROP SCHEMA IF EXISTS " + VS_SCHEMA + "CASCADE"); + statement.execute("CREATE SCHEMA " + VS_SCHEMA); + statement.execute("CREATE TABLE ORIGIN_TABLE(THE_VALUE CHAR(9))"); + statement.execute("CREATE LUA ADAPTER SCRIPT " + VS_ADAPTER + " AS\n" + loadAdapterScriptContent() + "\n/"); + statement.execute("CREATE VIRTUAL SCHEMA " + VIRTUAL_SCHEMA_NAME + " USING " + VS_ADAPTER); + } +} diff --git a/src/test/resources/virtual_schema_stub.lua b/src/test/resources/virtual_schema_stub.lua new file mode 100644 index 0000000..5d62432 --- /dev/null +++ b/src/test/resources/virtual_schema_stub.lua @@ -0,0 +1,61 @@ +-- A minimal Lua virtual schema that allows testing VS interaction. +local cjson = require("cjson"); + +function report_schema() + return { + schemaMetadata = { + tables = { + { + name = "THE_TABLE", + columns = { + { + name = "THE_VALUE", + dataType = { + type = "CHAR", + size = 9 + } + } + } + } + } + } + } +end + +function report_capabilities() + return { + capabilities = { "SELECTLIST_PROJECTION", "FILTER_EXPRESSIONS", "FN_PRED_EQUAL", "LITERAL_STRING" } + } +end + +function pushdown(request) + if (request.filter == nil) then + return { + type = "select", + sql = "SELECT 'Hello VS!'" + } + else + return { + type = "select", + sql = "SELECT 'Hello VS!' FROM VS_SCHEMA.ORIGIN_TABLE WHERE THE_VALUE = 'something'" + } + end +end + +function adapter_call(request_as_json) + local request = cjson.decode(request_as_json) + local response; + if request.type == "createVirtualSchema" or request.type == "refresh" then + response = report_schema() + elseif request.type == "dropVirtualSchema" or request.type == "setProperties" then + response = {} + elseif request.type == "getCapabilities" then + response = report_capabilities() + elseif request.type == "pushdown" then + response = pushdown(request.pushdownRequest) + else + error("Unsupported adapter request: " .. (request.type or "'nil'")) + end + response.type = request.type + return cjson.encode(response) +end \ No newline at end of file