Skip to content

Commit

Permalink
Bug fix, count(distinct field) should transalte to cardinality aggreg…
Browse files Browse the repository at this point in the history
…ation (opendistro-for-elasticsearch#442)

(cherry picked from commit b3df480)
  • Loading branch information
penghuo committed May 2, 2020
1 parent fda5f6c commit 4c824de
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

package com.amazon.opendistroforelasticsearch.sql.query.maker;

import com.alibaba.druid.sql.ast.expr.SQLAggregateOption;
import com.amazon.opendistroforelasticsearch.sql.domain.Condition;
import com.amazon.opendistroforelasticsearch.sql.domain.Field;
import com.amazon.opendistroforelasticsearch.sql.domain.KVValue;
Expand Down Expand Up @@ -697,7 +698,7 @@ private RangeAggregationBuilder rangeBuilder(MethodField field) {
private ValuesSourceAggregationBuilder makeCountAgg(MethodField field) {

// Cardinality is approximate DISTINCT.
if ("DISTINCT".equals(field.getOption())) {
if (SQLAggregateOption.DISTINCT.equals(field.getOption())) {

if (field.getParams().size() == 1) {
return AggregationBuilders.cardinality(field.getAlias()).field(field.getParams().get(0).value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.expr.SQLAggregateExpr;
import com.alibaba.druid.sql.ast.expr.SQLAggregateOption;
import com.alibaba.druid.sql.ast.expr.SQLCastExpr;
import com.alibaba.druid.sql.ast.expr.SQLIdentifierExpr;
import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
Expand Down Expand Up @@ -259,8 +260,12 @@ public AggregationExpr(SQLAggregateExpr expr) {
public static String nameOfExpr(SQLExpr expr) {
String exprName = expr.toString().toLowerCase();
if (expr instanceof SQLAggregateExpr) {
exprName = String.format("%s(%s)", ((SQLAggregateExpr) expr).getMethodName(),
((SQLAggregateExpr) expr).getArguments().get(0));
SQLAggregateExpr aggExpr = (SQLAggregateExpr) expr;
SQLAggregateOption option = aggExpr.getOption();
exprName = option == null
? String.format("%s(%s)", aggExpr.getMethodName(), aggExpr.getArguments().get(0))
: String.format("%s(%s %s)", aggExpr.getMethodName(), option.name(),
aggExpr.getArguments().get(0));
} else if (expr instanceof SQLMethodInvokeExpr) {
exprName = String.format("%s(%s)", ((SQLMethodInvokeExpr) expr).getMethodName(),
nameOfExpr(((SQLMethodInvokeExpr) expr).getParameters().get(0)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@
import static com.amazon.opendistroforelasticsearch.sql.esintgtest.TestsConstants.TEST_INDEX_GAME_OF_THRONES;
import static com.amazon.opendistroforelasticsearch.sql.esintgtest.TestsConstants.TEST_INDEX_NESTED_TYPE;
import static com.amazon.opendistroforelasticsearch.sql.esintgtest.TestsConstants.TEST_INDEX_ONLINE;
import static com.amazon.opendistroforelasticsearch.sql.util.MatcherUtils.rows;
import static com.amazon.opendistroforelasticsearch.sql.util.MatcherUtils.schema;
import static com.amazon.opendistroforelasticsearch.sql.util.MatcherUtils.verifyDataRows;
import static com.amazon.opendistroforelasticsearch.sql.util.MatcherUtils.verifySchema;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
Expand All @@ -64,6 +68,14 @@ public void countTest() throws IOException {
Assert.assertThat(getIntAggregationValue(result, "COUNT(*)", "value"), equalTo(1000));
}

@Test
public void countDistinctTest() {
JSONObject response = executeJdbcRequest(String.format("SELECT COUNT(distinct gender) FROM %s", TEST_INDEX_ACCOUNT));

verifySchema(response, schema("COUNT(DISTINCT gender)", null, "integer"));
verifyDataRows(response, rows(2));
}

@Test
public void countWithDocsHintTest() throws Exception {

Expand Down Expand Up @@ -1238,4 +1250,8 @@ private double getDoubleAggregationValue(final JSONObject queryResult, final Str

return targetField.getDouble(subFieldName);
}

private JSONObject executeJdbcRequest(String query) {
return new JSONObject(executeQuery(query, "jdbc"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,20 @@ public void noGroupKeyInSelectShouldPass() {
columnNode("avg(age)", null, ExpressionFactory.ref("avg_0"))));
}

@Test
public void aggWithDistinctShouldPass() {
String sql = "SELECT count(distinct gender) FROM t GROUP BY age";
SQLAggregationParser parser = new SQLAggregationParser(new ColumnTypeProvider());
parser.parse(mYSqlSelectQueryBlock(sql));
List<SQLSelectItem> sqlSelectItems = parser.selectItemList();
List<ColumnNode> columnNodes = parser.getColumnNodes();

assertThat(sqlSelectItems, containsInAnyOrder(
agg("count", "gender", "count_0")));
assertThat(columnNodes, containsInAnyOrder(
columnNode("count(distinct gender)", null, ExpressionFactory.ref("count_0"))));
}

/**
* TermQueryExplainIT.testNestedSingleGroupBy
*/
Expand Down

0 comments on commit 4c824de

Please sign in to comment.