Skip to content

Commit

Permalink
Update Postgres Filter Type Expression Parser to make it extendible t…
Browse files Browse the repository at this point in the history
…o non-identifier type LHS (#120)

* Update Postgres Filter Type Expression Parser to make it extendible to non-identifier type LHS
  • Loading branch information
suresh-prakash authored Aug 24, 2022
1 parent ccc8cf9 commit a82ecf4
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -57,6 +63,7 @@ public String visit(final RelationalExpression expression) {

return PostgresUtils.parseNonCompositeFilter(
fieldToPgColumn.getTransformedField(),
parsedLhsExpression,
fieldToPgColumn.getPgColumn(),
operator.toString(),
value,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 = " = ";
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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":
Expand All @@ -244,8 +257,7 @@ public static String parseNonCompositeFilter(
paramsBuilder.addObjectParam(value);
}
}
String filters = filterString.toString();
return filters;
return filterString.toString();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand All @@ -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(),
Expand All @@ -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(),
Expand All @@ -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(),
Expand All @@ -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(),
Expand All @@ -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(),
Expand All @@ -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(),
Expand All @@ -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(),
Expand Down

0 comments on commit a82ecf4

Please sign in to comment.