diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/util/DisplayNameUtils.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/util/DisplayNameUtils.java index 8e0db07a1880..5377f0807253 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/util/DisplayNameUtils.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/analytics/util/DisplayNameUtils.java @@ -145,7 +145,8 @@ public static String getDisplayName( private static String extractJsonValue( SqlBuilder sqlBuilder, String tablePrefix, String originColumn, String path) { - String jsonExtracted = sqlBuilder.jsonExtract(tablePrefix, originColumn, path); + String json = tablePrefix + "." + originColumn; + String jsonExtracted = sqlBuilder.jsonExtract(json, path); return sqlBuilder.trim(jsonExtracted); } diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/db/sql/ClickHouseSqlBuilder.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/db/sql/ClickHouseSqlBuilder.java index 8498baaaeac3..42938d1403d8 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/db/sql/ClickHouseSqlBuilder.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/db/sql/ClickHouseSqlBuilder.java @@ -218,19 +218,14 @@ public String coalesce(String expression, String defaultValue) { } @Override - public String jsonExtract(String column, String property) { - return String.format("JSONExtractString(%s, '%s')", column, property); + public String jsonExtract(String json, String property) { + return String.format("JSONExtractString(%s, '%s')", json, property); } @Override - public String jsonExtract(String tablePrefix, String column, String jsonPath) { - return String.format("JSONExtractString(%s.%s, '%s')", tablePrefix, column, jsonPath); - } - - @Override - public String jsonExtractNested(String column, String... jsonPath) { - String path = String.join(".", jsonPath); - return String.format("JSONExtractString(%s, '%s')", column, path); + public String jsonExtractNested(String json, String... expression) { + String path = String.join(".", expression); + return String.format("JSONExtractString(%s, '%s')", json, path); } // Statements diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/db/sql/DorisSqlBuilder.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/db/sql/DorisSqlBuilder.java index f7c9be3bd772..920ca25d1e8e 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/db/sql/DorisSqlBuilder.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/db/sql/DorisSqlBuilder.java @@ -221,19 +221,13 @@ public String coalesce(String expression, String defaultValue) { } @Override - public String jsonExtract(String column, String property) { - return String.format("json_unquote(json_extract(%s, '$.%s'))", column, property); + public String jsonExtract(String json, String property) { + return String.format("json_unquote(json_extract(%s, '$.%s'))", json, property); } @Override - public String jsonExtract(String tablePrefix, String column, String jsonPath) { - return String.format( - "json_unquote(json_extract(%s.%s, '$.%s'))", tablePrefix, column, jsonPath); - } - - @Override - public String jsonExtractNested(String column, String... jsonPath) { - String path = "$." + String.join(".", jsonPath); + public String jsonExtractNested(String column, String... expression) { + String path = "$." + String.join(".", expression); return String.format("json_unquote(json_extract(%s, '%s'))", column, path); } diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/db/sql/PostgreSqlBuilder.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/db/sql/PostgreSqlBuilder.java index ff25c349061f..aebd74100e11 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/db/sql/PostgreSqlBuilder.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/db/sql/PostgreSqlBuilder.java @@ -241,17 +241,12 @@ public String coalesce(String expression, String defaultValue) { @Override public String jsonExtract(String column, String property) { - return column + " ->> '" + property + "'"; + return String.format("%s ->> '%s'", column, property); } @Override - public String jsonExtract(String tablePrefix, String column, String jsonPath) { - return String.format("%s.%s ->> '%s'", tablePrefix, column, jsonPath); - } - - @Override - public String jsonExtractNested(String column, String... jsonPath) { - return String.format("%s #>> '{%s}'", column, String.join(", ", jsonPath)); + public String jsonExtractNested(String column, String... expression) { + return String.format("%s #>> '{%s}'", column, String.join(", ", expression)); } // Statements diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/db/sql/SqlBuilder.java b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/db/sql/SqlBuilder.java index 06d3da9070e7..8655372ff807 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/db/sql/SqlBuilder.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/main/java/org/hisp/dhis/db/sql/SqlBuilder.java @@ -246,16 +246,16 @@ public interface SqlBuilder { /** * Creates a SQL concatenation function that combines multiple columns or expressions. * - * @param columns the column names or expressions to concatenate - * @return the SQL function for concatenation + * @param columns the column names or expressions to concatenate. + * @return the SQL function for concatenation. */ String concat(String... columns); /** * Creates a SQL trim function that removes leading and trailing spaces from an expression. * - * @param expression the expression to trim - * @return the SQL function for trimming + * @param expression the expression to trim. + * @return the SQL function for trimming. */ String trim(String expression); @@ -263,40 +263,29 @@ public interface SqlBuilder { * Creates a SQL COALESCE function that returns the first non-null expression from the provided * expressions. If the first expression is null, it returns the default expression. * - * @param expression the expression to check for null - * @param defaultValue the value to return if the first expression is null - * @return the SQL function for coalescing + * @param expression the expression to check for null. + * @param defaultValue the value to return if the first expression is null. + * @return the SQL function for coalescing. */ String coalesce(String expression, String defaultValue); /** * Extracts a value from a JSON column using a specified property path. * - * @param column the JSON column name to extract from - * @param property the JSON property path to extract - * @return the SQL function for JSON value extraction + * @param json the JSON column name or value to extract from. + * @param property the JSON property path to extract. + * @return the SQL function for JSON value extraction. */ - String jsonExtract(String column, String property); - - /** - * Extracts a value from a JSON column using a specified JSON path expression, with support for - * table prefix qualification. - * - * @param tablePrefix the prefix/alias of the table containing the JSON column - * @param column the JSON column name to extract from - * @param jsonPath the JSON path expression to extract the value - * @return the SQL function for JSON value extraction - */ - String jsonExtract(String tablePrefix, String column, String jsonPath); + String jsonExtract(String json, String property); /** * Extracts a nested value from a JSON column. * - * @param column the name of the JSON column from which to extract the value. - * @param jsonPath the hierarchical path to the nested value, represented as a sequence of keys. + * @param json the JSON column name or value to extract from. + * @param expression the hierarchical path expression to the nested value. * @return a SQL expression to extract the specified nested value from the JSON column. */ - String jsonExtractNested(String column, String... jsonPath); + String jsonExtractNested(String json, String... expression); // Statements diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/table/JdbcTrackedEntityAnalyticsTableManagerTest.java b/dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/table/JdbcTrackedEntityAnalyticsTableManagerTest.java index b0377a320e30..5a7eefacbaf4 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/table/JdbcTrackedEntityAnalyticsTableManagerTest.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/analytics/table/JdbcTrackedEntityAnalyticsTableManagerTest.java @@ -109,7 +109,6 @@ void verifyNonConfidentialTeasAreSkipped() { when(sqlBuilder.qualifyTable(anyString())) .thenAnswer(inv -> SqlUtils.quote(inv.getArgument(0))); - when(sqlBuilder.jsonExtract(anyString(), anyString(), anyString())).thenReturn("jsonExtract"); when(sqlBuilder.jsonExtract(anyString(), anyString())).thenReturn("jsonExtract"); when(sqlBuilder.coalesce(anyString(), anyString())) diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/db/sql/ClickHouseSqlBuilderTest.java b/dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/db/sql/ClickHouseSqlBuilderTest.java index 5ef2e447e8ce..5087172105e4 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/db/sql/ClickHouseSqlBuilderTest.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/db/sql/ClickHouseSqlBuilderTest.java @@ -214,6 +214,12 @@ void testRegexpMatch() { assertEquals("match(id, '[a-z]\\w+\\d{3}')", sqlBuilder.regexpMatch("id", "'[a-z]\\w+\\d{3}'")); } + @Test + void testJsonExtract() { + assertEquals( + "JSONExtractString(value, 'D7m8vpzxHDJ')", sqlBuilder.jsonExtract("value", "D7m8vpzxHDJ")); + } + @Test void testJsonExtractNested() { assertEquals( diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/db/sql/DorisSqlBuilderTest.java b/dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/db/sql/DorisSqlBuilderTest.java index 36080486cea0..ad372141c9bc 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/db/sql/DorisSqlBuilderTest.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/db/sql/DorisSqlBuilderTest.java @@ -197,6 +197,13 @@ void testRegexpMatch() { assertEquals("id regexp '[a-z]\\w+\\d{3}'", sqlBuilder.regexpMatch("id", "'[a-z]\\w+\\d{3}'")); } + @Test + void testJsonExtract() { + assertEquals( + "json_unquote(json_extract(value, '$.D7m8vpzxHDJ'))", + sqlBuilder.jsonExtract("value", "D7m8vpzxHDJ")); + } + @Test void testJsonExtractNested() { assertEquals( diff --git a/dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/db/sql/PostgreSqlBuilderTest.java b/dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/db/sql/PostgreSqlBuilderTest.java index 56252070828b..2d621ae766e4 100644 --- a/dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/db/sql/PostgreSqlBuilderTest.java +++ b/dhis-2/dhis-services/dhis-service-analytics/src/test/java/org/hisp/dhis/db/sql/PostgreSqlBuilderTest.java @@ -225,6 +225,11 @@ void testRegexpMatch() { assertEquals("id ~* '[a-z]\\w+\\d{3}'", sqlBuilder.regexpMatch("id", "'[a-z]\\w+\\d{3}'")); } + @Test + void testJsonExtract() { + assertEquals("value ->> 'D7m8vpzxHDJ'", sqlBuilder.jsonExtract("value", "D7m8vpzxHDJ")); + } + @Test void testJsonExtractNested() { assertEquals(