diff --git a/document-store/src/main/java/org/hypertrace/core/documentstore/postgres/PostgresQueryParser.java b/document-store/src/main/java/org/hypertrace/core/documentstore/postgres/PostgresQueryParser.java index 2f318240..16d2e619 100644 --- a/document-store/src/main/java/org/hypertrace/core/documentstore/postgres/PostgresQueryParser.java +++ b/document-store/src/main/java/org/hypertrace/core/documentstore/postgres/PostgresQueryParser.java @@ -31,7 +31,7 @@ static String parseFilter(Filter filter, Builder paramsBuilder) { if (filter.isComposite()) { return parseCompositeFilter(filter, paramsBuilder); } else { - return PostgresUtils.parseNonCompositeFilter( + return PostgresUtils.parseNonCompositeFilterWithCasting( filter.getFieldName(), PostgresUtils.DOCUMENT_COLUMN, filter.getOp().toString(), diff --git a/document-store/src/main/java/org/hypertrace/core/documentstore/postgres/query/v1/vistors/PostgresFilterTypeExpressionVisitor.java b/document-store/src/main/java/org/hypertrace/core/documentstore/postgres/query/v1/vistors/PostgresFilterTypeExpressionVisitor.java index fd7d2a1e..9f11e410 100644 --- a/document-store/src/main/java/org/hypertrace/core/documentstore/postgres/query/v1/vistors/PostgresFilterTypeExpressionVisitor.java +++ b/document-store/src/main/java/org/hypertrace/core/documentstore/postgres/query/v1/vistors/PostgresFilterTypeExpressionVisitor.java @@ -1,5 +1,7 @@ package org.hypertrace.core.documentstore.postgres.query.v1.vistors; +import static org.hypertrace.core.documentstore.postgres.utils.PostgresUtils.getType; + import java.util.Optional; import java.util.stream.Collector; import java.util.stream.Collectors; @@ -43,11 +45,15 @@ public String visit(final RelationalExpression expression) { SelectTypeExpression rhs = expression.getRhs(); // Only an identifier LHS and a constant RHS is supported as of now. - PostgresSelectTypeExpressionVisitor lhsVisitor = new PostgresIdentifierExpressionVisitor(); PostgresSelectTypeExpressionVisitor rhsVisitor = new PostgresConstantExpressionVisitor(); - - String fieldName = lhs.accept(lhsVisitor); Object value = rhs.accept(rhsVisitor); + PostgresIdentifierExpressionVisitor identifierVisitor = + new PostgresIdentifierExpressionVisitor(); + PostgresSelectTypeExpressionVisitor lhsVisitor = + new PostgresDataAccessorIdentifierExpressionVisitor(postgresQueryParser, getType(value)); + + final String fieldName = lhs.accept(identifierVisitor); + final String parsedLhsExpression = lhs.accept(lhsVisitor); FieldToPgColumn fieldToPgColumn = postgresQueryParser.getToPgColumnTransformer().transform(fieldName); @@ -57,6 +63,7 @@ public String visit(final RelationalExpression expression) { return PostgresUtils.parseNonCompositeFilter( fieldToPgColumn.getTransformedField(), + parsedLhsExpression, fieldToPgColumn.getPgColumn(), operator.toString(), value, diff --git a/document-store/src/main/java/org/hypertrace/core/documentstore/postgres/utils/PostgresUtils.java b/document-store/src/main/java/org/hypertrace/core/documentstore/postgres/utils/PostgresUtils.java index 27e60123..19913187 100644 --- a/document-store/src/main/java/org/hypertrace/core/documentstore/postgres/utils/PostgresUtils.java +++ b/document-store/src/main/java/org/hypertrace/core/documentstore/postgres/utils/PostgresUtils.java @@ -145,12 +145,25 @@ private static String prepareParameterizedStringForList( return "(" + collect + ")"; } - public static String parseNonCompositeFilter( + public static String parseNonCompositeFilterWithCasting( String fieldName, String columnName, String op, Object value, Builder paramsBuilder) { - String fullFieldName = prepareCast(prepareFieldDataAccessorExpr(fieldName, columnName), value); - StringBuilder filterString = new StringBuilder(fullFieldName); + String parsedExpression = + prepareCast(prepareFieldDataAccessorExpr(fieldName, columnName), value); + return parseNonCompositeFilter( + fieldName, parsedExpression, columnName, op, value, paramsBuilder); + } + + @SuppressWarnings("unchecked") + public static String parseNonCompositeFilter( + String fieldName, + String parsedExpression, + String columnName, + String op, + Object value, + Builder paramsBuilder) { + StringBuilder filterString = new StringBuilder(parsedExpression); String sqlOperator; - Boolean isMultiValued = false; + boolean isMultiValued = false; switch (op) { case "EQ": sqlOperator = " = "; @@ -182,8 +195,8 @@ public static String parseNonCompositeFilter( // https://github.com/hypertrace/document-store/pull/20#discussion_r547101520Other // so, we need - "document->key IS NULL OR document->key->> NOT IN (v1, v2)" StringBuilder notInFilterString = prepareFieldAccessorExpr(fieldName, columnName); - if (notInFilterString != null && !OUTER_COLUMNS.contains(fieldName)) { - filterString = notInFilterString.append(" IS NULL OR ").append(fullFieldName); + if (!OUTER_COLUMNS.contains(fieldName)) { + filterString = notInFilterString.append(" IS NULL OR ").append(parsedExpression); } sqlOperator = " NOT IN "; isMultiValued = true; @@ -201,7 +214,7 @@ public static String parseNonCompositeFilter( value = null; // For fields inside jsonb StringBuilder notExists = prepareFieldAccessorExpr(fieldName, columnName); - if (notExists != null && !OUTER_COLUMNS.contains(fieldName)) { + if (!OUTER_COLUMNS.contains(fieldName)) { filterString = notExists; } break; @@ -210,7 +223,7 @@ public static String parseNonCompositeFilter( value = null; // For fields inside jsonb StringBuilder exists = prepareFieldAccessorExpr(fieldName, columnName); - if (exists != null && !OUTER_COLUMNS.contains(fieldName)) { + if (!OUTER_COLUMNS.contains(fieldName)) { filterString = exists; } break; @@ -225,8 +238,8 @@ public static String parseNonCompositeFilter( // "document->key IS NULL OR document->key->> != value" StringBuilder notEquals = prepareFieldAccessorExpr(fieldName, columnName); // For fields inside jsonb - if (notEquals != null && !OUTER_COLUMNS.contains(fieldName)) { - filterString = notEquals.append(" IS NULL OR ").append(fullFieldName); + if (!OUTER_COLUMNS.contains(fieldName)) { + filterString = notEquals.append(" IS NULL OR ").append(parsedExpression); } break; case "CONTAINS": @@ -244,8 +257,7 @@ public static String parseNonCompositeFilter( paramsBuilder.addObjectParam(value); } } - String filters = filterString.toString(); - return filters; + return filterString.toString(); } /** diff --git a/document-store/src/test/java/org/hypertrace/core/documentstore/postgres/PostgresQueryParserTest.java b/document-store/src/test/java/org/hypertrace/core/documentstore/postgres/PostgresQueryParserTest.java index d2490fc3..5dca2e5a 100644 --- a/document-store/src/test/java/org/hypertrace/core/documentstore/postgres/PostgresQueryParserTest.java +++ b/document-store/src/test/java/org/hypertrace/core/documentstore/postgres/PostgresQueryParserTest.java @@ -21,7 +21,7 @@ void testParseNonCompositeFilter() { { Filter filter = new Filter(Filter.Op.EQ, ID, "val1"); String query = - PostgresUtils.parseNonCompositeFilter( + PostgresUtils.parseNonCompositeFilterWithCasting( filter.getFieldName(), PostgresUtils.DOCUMENT_COLUMN, filter.getOp().toString(), @@ -33,7 +33,7 @@ void testParseNonCompositeFilter() { { Filter filter = new Filter(Filter.Op.NEQ, ID, "val1"); String query = - PostgresUtils.parseNonCompositeFilter( + PostgresUtils.parseNonCompositeFilterWithCasting( filter.getFieldName(), PostgresUtils.DOCUMENT_COLUMN, filter.getOp().toString(), @@ -45,7 +45,7 @@ void testParseNonCompositeFilter() { { Filter filter = new Filter(Filter.Op.GT, ID, 5); String query = - PostgresUtils.parseNonCompositeFilter( + PostgresUtils.parseNonCompositeFilterWithCasting( filter.getFieldName(), PostgresUtils.DOCUMENT_COLUMN, filter.getOp().toString(), @@ -57,7 +57,7 @@ void testParseNonCompositeFilter() { { Filter filter = new Filter(Filter.Op.GTE, ID, 5); String query = - PostgresUtils.parseNonCompositeFilter( + PostgresUtils.parseNonCompositeFilterWithCasting( filter.getFieldName(), PostgresUtils.DOCUMENT_COLUMN, filter.getOp().toString(), @@ -69,7 +69,7 @@ void testParseNonCompositeFilter() { { Filter filter = new Filter(Filter.Op.LT, ID, 5); String query = - PostgresUtils.parseNonCompositeFilter( + PostgresUtils.parseNonCompositeFilterWithCasting( filter.getFieldName(), PostgresUtils.DOCUMENT_COLUMN, filter.getOp().toString(), @@ -81,7 +81,7 @@ void testParseNonCompositeFilter() { { Filter filter = new Filter(Filter.Op.LTE, ID, 5); String query = - PostgresUtils.parseNonCompositeFilter( + PostgresUtils.parseNonCompositeFilterWithCasting( filter.getFieldName(), PostgresUtils.DOCUMENT_COLUMN, filter.getOp().toString(), @@ -93,7 +93,7 @@ void testParseNonCompositeFilter() { { Filter filter = new Filter(Filter.Op.LIKE, ID, "abc"); String query = - PostgresUtils.parseNonCompositeFilter( + PostgresUtils.parseNonCompositeFilterWithCasting( filter.getFieldName(), PostgresUtils.DOCUMENT_COLUMN, filter.getOp().toString(), @@ -105,7 +105,7 @@ void testParseNonCompositeFilter() { { Filter filter = new Filter(Filter.Op.IN, ID, List.of("abc", "xyz")); String query = - PostgresUtils.parseNonCompositeFilter( + PostgresUtils.parseNonCompositeFilterWithCasting( filter.getFieldName(), PostgresUtils.DOCUMENT_COLUMN, filter.getOp().toString(),