Skip to content

Suggested support "sum(case when expression then 1 else 0 end) " case! #77

@maxid

Description

@maxid

Suggested support "sum(case when expression then 1 else 0 end) " case!
new file: CaseClauseProcessor.java

    // new file:  CaseClauseProcessor.java
...

/**
 * case when then else end => $cond support
 *
 * @author maxid
 * @since 2024/8/20 18:00
 */
public class CaseClauseProcessor implements ClauseProcessor {
    ...
}

modify QueryConverter.java

    // modify QueryConverter.java
    private void parseFunctionForAggregation(final Function function, final Document document,
                                             final List<String> groupBys, final Alias alias,
                                             MongoDBQueryHolder mongoHolder) throws ConvertParseException {
        String op = function.getName().toLowerCase();
        String aggField = SqlUtils.generateAggField(function, alias).getValue();
        switch (op) {
            case "count":
                document.put(aggField, new Document("$sum", 1));
                break;
            case "sum":
            case "min":
            case "max":
            case "avg":
                Expression expression = function.getParameters().getExpressions().get(0);
                if (expression instanceof CaseExpression) {
                    createFunction(op, aggField, document, parseCaseExpression(expression, mongoHolder));
                } else {
                    createFunction(op, aggField, document, "$" + SqlUtils.getFieldFromFunction(function));
                }
                break;
            default:
                throw new ConvertParseException("could not understand function:" + function.getName());
        }
    }

    private void createFunction(final String functionName, final String aggField,
                                final Document document, final Object value) {
        document.put(aggField, new Document("$" + functionName, value));
    }

    private void createFunction(final String functionName, final String aggField, final Document document, Document value) {
        document.put(aggField, new Document("$" + functionName, value));
    }

    private Document parseCaseExpression(Expression expression, MongoDBQueryHolder mongoHolder) throws ConvertParseException {
        Document value = new Document();
        Document cond = new Document();
        CaseExpression caseExpression = (CaseExpression) expression;
        CaseClauseProcessor processor = new CaseClauseProcessor(defaultFieldType, fieldNameToFieldTypeMapping, mongoHolder.isRequiresMultistepAggregation());
        WhenClause whenExpression = caseExpression.getWhenClauses().get(0);
        processor.parseExpression(cond, whenExpression.getWhenExpression(), null);
        Object thenValue = getActualValue(whenExpression.getThenExpression(), mongoHolder);
        if (thenValue instanceof String) {
            thenValue = String.format("$%s", thenValue);
        }
        Object elseValue = getActualValue(caseExpression.getElseExpression(), mongoHolder);
        if (elseValue instanceof String) {
            elseValue = String.format("$%s", elseValue);
        }
        value.put("$cond", Lists.newArrayList(cond, thenValue, elseValue));
        return value;
    }

    private static Object getActualValue(final Expression expression) {
        if (expression instanceof StringValue) {
            return ((StringValue) expression).getValue();
        } else if (expression instanceof LongValue) {
            return ((LongValue) expression).getValue();
        } else if (expression instanceof DoubleValue) {
            return ((DoubleValue) expression).getValue();
        } else if (expression instanceof Column) {
            return SqlUtils.getStringValue(expression);
        }
        return expression.toString();
    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions