ignite-gg9499 - minor
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/63ec158e Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/63ec158e Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/63ec158e Branch: refs/heads/sprint-1 Commit: 63ec158e8dcfa9294c0727b8b778c87477416e10 Parents: 20566ff Author: S.Vladykin <svlady...@gridgain.com> Authored: Tue Jan 20 23:54:59 2015 +0300 Committer: S.Vladykin <svlady...@gridgain.com> Committed: Tue Jan 20 23:54:59 2015 +0300 ---------------------------------------------------------------------- .../query/h2/sql/GridSqlAggregateFunction.java | 4 +- .../query/h2/sql/GridSqlFunction.java | 40 +++++++--- .../query/h2/sql/GridSqlFunctionType.java | 58 +++++++++----- .../query/h2/sql/GridSqlQueryParser.java | 2 +- .../query/h2/sql/GridSqlQuerySplitter.java | 82 ++++++++++++-------- .../cache/GridCacheCrossCacheQuerySelfTest.java | 5 +- 6 files changed, 121 insertions(+), 70 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/63ec158e/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlAggregateFunction.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlAggregateFunction.java b/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlAggregateFunction.java index c48644d..c9aeee9 100644 --- a/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlAggregateFunction.java +++ b/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlAggregateFunction.java @@ -19,8 +19,8 @@ import static org.gridgain.grid.kernal.processors.query.h2.sql.GridSqlFunctionTy public class GridSqlAggregateFunction extends GridSqlFunction { /** */ private static final GridSqlFunctionType[] TYPE_INDEX = new GridSqlFunctionType[]{ - COUNT_ALL, COUNT, GROUP_CONCAT, SUM, MIN, MAX, AVG, STDDEV_POP, STDDEV_SAMP, VAR_POP, VAR_SAMP, BOOL_OR, - BOOL_AND, SELECTIVITY, HISTOGRAM, + COUNT_ALL, COUNT, GROUP_CONCAT, SUM, MIN, MAX, AVG, +// STDDEV_POP, STDDEV_SAMP, VAR_POP, VAR_SAMP, BOOL_OR, BOOL_AND, SELECTIVITY, HISTOGRAM, }; /** */ http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/63ec158e/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlFunction.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlFunction.java b/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlFunction.java index 0b6b73d..c9f6802 100644 --- a/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlFunction.java +++ b/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlFunction.java @@ -15,6 +15,8 @@ import org.h2.value.*; import java.util.*; +import static org.gridgain.grid.kernal.processors.query.h2.sql.GridSqlFunctionType.*; + /** * Function. */ @@ -43,33 +45,46 @@ public class GridSqlFunction extends GridSqlElement { * @param type Function type. */ public GridSqlFunction(GridSqlFunctionType type) { - name = type.functionName(); + this(type, type.functionName()); + } - this.type = type; + /** + * @param type Type. + * @param name Name. + */ + private GridSqlFunction(GridSqlFunctionType type, String name) { + if (name == null) + throw new NullPointerException(); - if (type == GridSqlFunctionType.CONVERT) - throw new UnsupportedOperationException(); + if (type == null) + type = UNKNOWN_FUNCTION; + + this.name = name; + this.type = type; } /** * @param name Name. */ public GridSqlFunction(String name) { - this(TYPE_MAP.get(name)); + this(TYPE_MAP.get(name), name); } /** * @param castType Type for {@link GridSqlFunctionType#CAST} function. + * @return {@code this}. */ - public void setCastType(String castType) { + public GridSqlFunction setCastType(String castType) { this.castType = castType; + + return this; } /** {@inheritDoc} */ @Override public String getSQL() { StatementBuilder buff = new StatementBuilder(name); - if (type == GridSqlFunctionType.CASE) { + if (type == CASE) { if (!children.isEmpty()) buff.append(" ").append(child().getSQL()); @@ -85,16 +100,17 @@ public class GridSqlFunction extends GridSqlElement { buff.append('('); - if (type == GridSqlFunctionType.CAST) { + if (type == CAST) { assert !F.isEmpty(castType) : castType; assert children().size() == 1; buff.append(child().getSQL()).append(" AS ").append(castType); } - else if (type == GridSqlFunctionType.CONVERT) { - throw new UnsupportedOperationException("CONVERT"); -// buff.append(args[0].getSQL()).append(','). -// append(new Column(null, dataType, precision, scale, displaySize).getCreateSQL()); + else if (type == CONVERT) { + assert !F.isEmpty(castType) : castType; + assert children().size() == 1; + + buff.append(child().getSQL()).append(',').append(castType); } else if (type == GridSqlFunctionType.EXTRACT) { ValueString v = (ValueString)((GridSqlConst)child(0)).value(); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/63ec158e/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlFunctionType.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlFunctionType.java b/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlFunctionType.java index e9aa8c9..be4d90d 100644 --- a/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlFunctionType.java +++ b/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlFunctionType.java @@ -15,42 +15,58 @@ import org.h2.expression.*; * Full list of available functions see at {@link Function} */ public enum GridSqlFunctionType { - ABS(1), CEIL(1), FLOOR(1), COS(1), PI(0), POWER(2), RAND(-1), ROUND(1), - CASE(-1), CAST(1), CONVERT(1), EXTRACT(2), - DAY_OF_MONTH(1), DAY_OF_WEEK(1), DAY_OF_YEAR(1), - // Aggregate functions. - COUNT_ALL("COUNT(*)", 0), COUNT(1), GROUP_CONCAT(1), SUM(1), MIN(1), MAX(1), AVG(1), STDDEV_POP(1), STDDEV_SAMP(1), - VAR_POP(1), VAR_SAMP(1), BOOL_OR(1), BOOL_AND(1), SELECTIVITY(1), HISTOGRAM(1); + /** */ + COUNT_ALL("COUNT(*)"), /** */ - private final String name; + COUNT, + + /** */ + SUM, + + /** */ + MIN, /** */ - private final int argCnt; + MAX, + + /** */ + AVG, + + /** */ + GROUP_CONCAT, + + // Functions with special handling. + /** */ + CASE, + + /** */ + CAST, + + /** */ + CONVERT, + + /** */ + EXTRACT, + + /** Constant for all other functions. */ + UNKNOWN_FUNCTION; + + /** */ + private final String name; /** - * @param argCnt Count. */ - GridSqlFunctionType(int argCnt) { + GridSqlFunctionType() { name = name(); - this.argCnt = argCnt; } /** * @param name Name. - * @param argCnt Count. */ - GridSqlFunctionType(String name, int argCnt) { + GridSqlFunctionType(String name) { this.name = name; - this.argCnt = argCnt; - } - - /** - * @return Argument count. - */ - public int argumentCount() { - return argCnt; } /** http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/63ec158e/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlQueryParser.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlQueryParser.java b/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlQueryParser.java index cbfca7a..5c7c762 100644 --- a/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlQueryParser.java +++ b/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlQueryParser.java @@ -410,7 +410,7 @@ public class GridSqlQueryParser { for (Expression arg : f.getArgs()) res.addChild(parseExpression(arg)); - if (f.getFunctionType() == Function.CAST) + if (f.getFunctionType() == Function.CAST || f.getFunctionType() == Function.CONVERT) res.setCastType(new Column(null, f.getType(), f.getPrecision(), f.getScale(), f.getDisplaySize()) .getCreateSQL()); http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/63ec158e/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlQuerySplitter.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlQuerySplitter.java b/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlQuerySplitter.java index 1a48540..4251451 100644 --- a/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlQuerySplitter.java +++ b/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlQuerySplitter.java @@ -122,66 +122,76 @@ public class GridSqlQuerySplitter { if (el instanceof GridSqlAggregateFunction) { GridSqlAggregateFunction agg = (GridSqlAggregateFunction)el; + GridSqlElement mapAgg, rdcAgg; + + String mapAggAlias = columnName(idx); + switch (agg.type()) { - case AVG: // Split AVG(x) into distributed SUM( AVG(x)*COUNT(x) )/SUM( COUNT(x) ). + case AVG: // SUM( AVG(x)*COUNT(x) )/SUM( COUNT(x) ). //-- COUNT(x) map - GridSqlElement cntMap = aggregate(agg.distinct(), COUNT).addChild(agg.child()); // Add function argument. + GridSqlElement cntMapAgg = aggregate(agg.distinct(), COUNT).addChild(agg.child()); // Add generated alias to COUNT(x). // Using size as index since COUNT will be added as the last select element to the map query. - cntMap = alias(columnName(mapSelect.size()), cntMap); + String cntMapAggAlias = columnName(mapSelect.size()); - mapSelect.add(cntMap); + cntMapAgg = alias(cntMapAggAlias, cntMapAgg); - //-- AVG(x) map - GridSqlElement avgMap = aggregate(agg.distinct(), AVG).addChild(agg.child()); // Add function argument. + mapSelect.add(cntMapAgg); - // Add generated alias to AVG(x). - avgMap = alias(columnName(idx), avgMap); - - mapSelect.set(idx, avgMap); + //-- AVG(x) map + mapAgg = aggregate(agg.distinct(), AVG).addChild(agg.child()); // Add function argument. //-- SUM( AVG(x)*COUNT(x) )/SUM( COUNT(x) ) reduce GridSqlElement sumUpRdc = aggregate(false, SUM).addChild( op(GridSqlOperationType.MULTIPLY, - column(((GridSqlAlias)avgMap).alias()), - column(((GridSqlAlias)cntMap).alias()))); + column(mapAggAlias), + column(cntMapAggAlias))); - GridSqlElement sumDownRdc = aggregate(false, SUM).addChild( - column(((GridSqlAlias)cntMap).alias())); + GridSqlElement sumDownRdc = aggregate(false, SUM).addChild(column(cntMapAggAlias)); - GridSqlElement rdc = op(GridSqlOperationType.DIVIDE, sumUpRdc, sumDownRdc); - - if (alias != null) // Add initial alias if it was set. - rdc = alias(alias.alias(), rdc); - - rdcSelect[idx] = rdc; + rdcAgg = op(GridSqlOperationType.DIVIDE, sumUpRdc, sumDownRdc); break; - case SUM: - case MAX: - case MIN: - GridSqlElement map = aggregate(agg.distinct(), agg.type()).addChild(agg.child()); + case SUM: // SUM( SUM(x) ) + case MAX: // MAX( MAX(x) ) + case MIN: // MIN( MIN(x) ) + mapAgg = aggregate(agg.distinct(), agg.type()).addChild(agg.child()); - map = alias(columnName(idx), map); + rdcAgg = aggregate(agg.distinct(), agg.type()).addChild(column(mapAggAlias)); - mapSelect.set(idx, map); + break; - rdc = aggregate(agg.distinct(), agg.type()).addChild(column(((GridSqlAlias)map).alias())); + case COUNT_ALL: // CAST(SUM( COUNT(*) ) AS BIGINT) + case COUNT: // CAST(SUM( COUNT(x) ) AS BIGINT) + mapAgg = aggregate(agg.distinct(), agg.type()); - if (alias != null) // Add initial alias if it was set. - rdc = alias(alias.alias(), rdc); + if (agg.type() == COUNT) + mapAgg.addChild(agg.child()); - rdcSelect[idx] = rdc; + rdcAgg = aggregate(false, SUM).addChild(column(mapAggAlias)); + + rdcAgg = function(CAST).setCastType("BIGINT").addChild(rdcAgg); break; - case COUNT_ALL: - case COUNT: default: throw new IgniteException("Unsupported aggregate: " + agg.type()); } + + assert !(mapAgg instanceof GridSqlAlias); + + // Add generated alias to map aggregate. + mapAgg = alias(mapAggAlias, mapAgg); + + if (alias != null) // Add initial alias if it was set. + rdcAgg = alias(alias.alias(), rdcAgg); + + // Set map and reduce aggregates to their places in selects. + mapSelect.set(idx, mapAgg); + + rdcSelect[idx] = rdcAgg; } else { if (alias == null) { // Generate alias if none. @@ -230,4 +240,12 @@ public class GridSqlQuerySplitter { private static GridSqlOperation op(GridSqlOperationType type, GridSqlElement left, GridSqlElement right) { return new GridSqlOperation(type, left, right); } + + /** + * @param type Type. + * @return Function. + */ + private static GridSqlFunction function(GridSqlFunctionType type) { + return new GridSqlFunction(type); + } } http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/63ec158e/modules/indexing/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheCrossCacheQuerySelfTest.java ---------------------------------------------------------------------- diff --git a/modules/indexing/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheCrossCacheQuerySelfTest.java b/modules/indexing/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheCrossCacheQuerySelfTest.java index 0933bf4..ffa1c4f 100644 --- a/modules/indexing/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheCrossCacheQuerySelfTest.java +++ b/modules/indexing/src/test/java/org/gridgain/grid/kernal/processors/cache/GridCacheCrossCacheQuerySelfTest.java @@ -155,10 +155,11 @@ public class GridCacheCrossCacheQuerySelfTest extends GridCommonAbstractTest { assertFalse(set1.isEmpty()); assertEquals(set0, set1); - X.println("___ AVG MIN MAX SUM"); + X.println("___ AVG MIN MAX SUM COUNT(*) COUNT(x)"); for (List<?> o : qx.executeTwoStepQuery("partitioned", - "select p.name, avg(f.price), min(f.price), max(f.price), sum(f.price) " + + "select p.name, avg(f.price), min(f.price), max(f.price), sum(f.price), count(*), " + + "count(nullif(f.price, 5)) " + "from FactPurchase f, \"replicated\".DimProduct p " + "where p.id = f.productId " + "group by f.productId, p.name").get()) {