Skip to content

Commit

Permalink
fix: Extract JSON from object for ClickHouse [DHIS2-18417] (#19499)
Browse files Browse the repository at this point in the history
  • Loading branch information
larshelge authored Dec 16, 2024
1 parent 55c3a60 commit ae7bf7b
Show file tree
Hide file tree
Showing 8 changed files with 37 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ private List<AnalyticsTableColumn> getColumnForDataElement(

DataType dataType = getColumnType(dataElement.getValueType(), isSpatialSupport());
String jsonExpression =
sqlBuilder.jsonExtractNested("eventdatavalues", dataElement.getUid(), "value");
sqlBuilder.jsonExtract("eventdatavalues", dataElement.getUid(), "value");
String columnExpression = getColumnExpression(dataElement.getValueType(), jsonExpression);
String dataFilterClause = getDataFilterClause(dataElement);
String selectExpression = getSelectExpression(dataElement, columnExpression);
Expand Down Expand Up @@ -576,7 +576,7 @@ private String getOrgUnitSelectSubquery(DataElement dataElement, String column)
(select ou.${column} from ${organisationunit} ou \
where ou.uid = ${columnExpression}) as ${alias}""";
String columnExpression =
sqlBuilder.jsonExtractNested("eventdatavalues", dataElement.getUid(), "value");
sqlBuilder.jsonExtract("eventdatavalues", dataElement.getUid(), "value");
String alias = quote(dataElement.getUid());

return replaceQualify(
Expand Down Expand Up @@ -706,11 +706,11 @@ private List<AnalyticsTableColumn> getColumnFromDataElementWithLegendSet(
* @return a data filter clause.
*/
private String getDataFilterClause(DataElement dataElement) {
String uid = dataElement.getUid();
ValueType valueType = dataElement.getValueType();

if (valueType.isNumeric() || valueType.isDate()) {
String jsonExpression = sqlBuilder.jsonExtractNested("eventdatavalues", uid, "value");
String jsonExpression =
sqlBuilder.jsonExtract("eventdatavalues", dataElement.getUid(), "value");
String regex = valueType.isNumeric() ? NUMERIC_REGEXP : DATE_REGEXP;

return " and " + sqlBuilder.regexpMatch(jsonExpression, regex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,9 +224,9 @@ public String jsonExtract(String json, String property) {
}

@Override
public String jsonExtractNested(String json, String... expression) {
String path = String.join(".", expression);
return String.format("JSONExtractString(%s, '%s')", json, path);
public String jsonExtract(String json, String key, String property) {
String path = String.format("JSONExtractRaw(%s, '%s')", json, key);
return String.format("JSONExtractString(%s, '%s')", path, property);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,9 +227,9 @@ public String jsonExtract(String json, String property) {
}

@Override
public String jsonExtractNested(String column, String... expression) {
String path = "$." + String.join(".", expression);
return String.format("json_unquote(json_extract(%s, '%s'))", column, path);
public String jsonExtract(String json, String key, String property) {
String path = "$." + String.join(".", key, property);
return String.format("json_unquote(json_extract(%s, '%s'))", json, path);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,9 @@ public String jsonExtract(String column, String property) {
}

@Override
public String jsonExtractNested(String column, String... expression) {
return String.format("%s #>> '{%s}'", column, String.join(", ", expression));
public String jsonExtract(String json, String key, String property) {
String path = String.join(", ", key, property);
return String.format("%s #>> '{%s}'", json, path);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -284,19 +284,20 @@ public interface SqlBuilder {
* Extracts a value from a JSON column using a specified property path.
*
* @param json the JSON column name or value to extract from.
* @param property the JSON property path to extract.
* @param property the JSON property to extract.
* @return the SQL function for JSON value extraction.
*/
String jsonExtract(String json, String property);

/**
* Extracts a nested value from a JSON column.
* Extracts a nested value from a JSON object.
*
* @param json the JSON column name or value to extract from.
* @param expression the hierarchical path expression to the nested value.
* @param json the JSON column name or object to extract from.
* @param key the object key.
* @param property the JSON property to extract.
* @return a SQL expression to extract the specified nested value from the JSON column.
*/
String jsonExtractNested(String json, String... expression);
String jsonExtract(String json, String key, String property);

/**
* Generates a SQL casting expression for the given column or expression.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,10 +231,13 @@ void testJsonExtract() {
}

@Test
void testJsonExtractNested() {
void testJsonExtractObject() {
assertEquals(
"JSONExtractString(eventdatavalues, 'D7m8vpzxHDJ.value')",
sqlBuilder.jsonExtractNested("eventdatavalues", "D7m8vpzxHDJ", "value"));
"JSONExtractString(JSONExtractRaw(ev.eventdatavalues, 'D7m8vpzxHDJ'), 'value')",
sqlBuilder.jsonExtract("ev.eventdatavalues", "D7m8vpzxHDJ", "value"));
assertEquals(
"JSONExtractString(JSONExtractRaw(ev.eventdatavalues, 'qrur9Dvnyt5'), 'value')",
sqlBuilder.jsonExtract("ev.eventdatavalues", "qrur9Dvnyt5", "value"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,10 +215,13 @@ void testJsonExtract() {
}

@Test
void testJsonExtractNested() {
void testJsonExtractObject() {
assertEquals(
"json_unquote(json_extract(eventdatavalues, '$.D7m8vpzxHDJ.value'))",
sqlBuilder.jsonExtractNested("eventdatavalues", "D7m8vpzxHDJ", "value"));
"json_unquote(json_extract(ev.eventdatavalues, '$.D7m8vpzxHDJ.value'))",
sqlBuilder.jsonExtract("ev.eventdatavalues", "D7m8vpzxHDJ", "value"));
assertEquals(
"json_unquote(json_extract(ev.eventdatavalues, '$.qrur9Dvnyt5.value'))",
sqlBuilder.jsonExtract("ev.eventdatavalues", "qrur9Dvnyt5", "value"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,13 @@ void testJsonExtract() {
}

@Test
void testJsonExtractNested() {
void testJsonExtractObject() {
assertEquals(
"eventdatavalues #>> '{D7m8vpzxHDJ, value}'",
sqlBuilder.jsonExtractNested("eventdatavalues", "D7m8vpzxHDJ", "value"));
"ev.eventdatavalues #>> '{D7m8vpzxHDJ, value}'",
sqlBuilder.jsonExtract("ev.eventdatavalues", "D7m8vpzxHDJ", "value"));
assertEquals(
"ev.eventdatavalues #>> '{qrur9Dvnyt5, value}'",
sqlBuilder.jsonExtract("ev.eventdatavalues", "qrur9Dvnyt5", "value"));
}

@Test
Expand Down

0 comments on commit ae7bf7b

Please sign in to comment.