ignite-gg9499 - avg wip

Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/c85b7bea
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/c85b7bea
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/c85b7bea

Branch: refs/heads/ignite-gg9499
Commit: c85b7bea4e6a60247b4bd270314bab76cfa95c14
Parents: f941e41
Author: S.Vladykin <svlady...@gridgain.com>
Authored: Thu Jan 15 20:24:44 2015 +0300
Committer: S.Vladykin <svlady...@gridgain.com>
Committed: Thu Jan 15 20:24:44 2015 +0300

----------------------------------------------------------------------
 .../query/h2/sql/GridSqlAggregateFunction.java  |   7 +
 .../processors/query/h2/sql/GridSqlElement.java |   5 +-
 .../query/h2/sql/GridSqlQuerySplitter.java      | 151 +++++++++++++++++--
 3 files changed, 152 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/c85b7bea/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 a0daab0..c48644d 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
@@ -44,6 +44,13 @@ public class GridSqlAggregateFunction extends 
GridSqlFunction {
         this(distinct, TYPE_INDEX[typeId]);
     }
 
+    /**
+     * @return Distinct.
+     */
+    public boolean distinct() {
+        return distinct;
+    }
+
     /** {@inheritDoc} */
     @Override public String getSQL() {
         String text;

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/c85b7bea/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlElement.java
----------------------------------------------------------------------
diff --git 
a/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlElement.java
 
b/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlElement.java
index 3a3acbe..16c824b 100644
--- 
a/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlElement.java
+++ 
b/modules/indexing/src/main/java/org/gridgain/grid/kernal/processors/query/h2/sql/GridSqlElement.java
@@ -30,12 +30,15 @@ public abstract class GridSqlElement implements Cloneable {
 
     /**
      * @param expr Expr.
+     * @return {@code this}.
      */
-    public void addChild(GridSqlElement expr) {
+    public GridSqlElement addChild(GridSqlElement expr) {
         if (expr == null)
             throw new NullPointerException();
 
         children.add(expr);
+
+        return this;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/c85b7bea/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 c9815cc..deeeae0 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
@@ -9,11 +9,14 @@
 
 package org.gridgain.grid.kernal.processors.query.h2.sql;
 
+import org.apache.ignite.*;
 import org.gridgain.grid.kernal.processors.cache.query.*;
 
 import java.sql.*;
 import java.util.*;
 
+import static 
org.gridgain.grid.kernal.processors.query.h2.sql.GridSqlFunctionType.*;
+
 /**
  * Splits a single SQL query into two step map-reduce query.
  */
@@ -34,9 +37,9 @@ public class GridSqlQuerySplitter {
 
     /**
      * @param idx Index of column.
-     * @return Column alias.
+     * @return Generated by index column alias.
      */
-    private static String column(int idx) {
+    private static String columnAlias(int idx) {
         return COLUMN_PREFIX + idx;
     }
 
@@ -64,29 +67,34 @@ public class GridSqlQuerySplitter {
 
         mapQry.clearSelect();
 
+        List<GridSqlElement> mapExps = new 
ArrayList<>(srcQry.allExpressions());
+
+        GridSqlElement[] rdcExps = new GridSqlElement[srcQry.select().size()];
+
+        for (int i = 0, len = mapExps.size(); i < len; i++)
+            splitSelectExpression(mapExps, rdcExps, i);
+
         List<GridSqlAlias> aliases = new 
ArrayList<>(srcQry.allExpressions().size());
 
         int idx = 0;
 
-        for (GridSqlElement exp : srcQry.allExpressions()) { // Add all 
expressions to select clause.
+        for (GridSqlElement exp : mapExps) { // Add all expressions to select 
clause.
             if (exp instanceof GridSqlColumn)
-                exp = new GridSqlAlias(((GridSqlColumn)exp).columnName(), exp);
+                exp = alias(((GridSqlColumn)exp).columnName(), exp);
             else if (!(exp instanceof GridSqlAlias))
-                exp = new GridSqlAlias(column(idx), exp);
+                exp = alias(columnAlias(idx), exp);
 
             aliases.add((GridSqlAlias)exp);
 
             mapQry.addSelectExpression(exp);
 
             idx++;
-
-            assert aliases.size() == idx;
         }
 
         mapQry.clearGroups();
 
         for (int col : srcQry.groupColumns())
-            mapQry.addGroupExpression(new GridSqlColumn(null, null, 
aliases.get(col).alias()));
+            mapQry.addGroupExpression(column(aliases.get(col).alias()));
 
         mapQry.clearSort(); // TODO sort support
 
@@ -94,12 +102,12 @@ public class GridSqlQuerySplitter {
         GridSqlSelect rdcQry = new GridSqlSelect();
 
         for (int i = 0; i < srcQry.select().size(); i++)
-            rdcQry.addSelectExpression(new GridSqlColumn(null, null, 
aliases.get(i).alias()));
+            rdcQry.addSelectExpression(column(aliases.get(i).alias()));
 
         rdcQry.from(new GridSqlTable(null, table(0)));
 
         for (int col : srcQry.groupColumns())
-            rdcQry.addGroupExpression(new GridSqlColumn(null, null, 
aliases.get(col).alias()));
+            rdcQry.addGroupExpression(column(aliases.get(col).alias()));
 
         GridCacheTwoStepQuery res = new GridCacheTwoStepQuery(rdcQry.getSQL());
 
@@ -107,4 +115,127 @@ public class GridSqlQuerySplitter {
 
         return res;
     }
+
+    /**
+     * @param exp Expression.
+     * @param idx Index in select.
+     * @return Natural or generated alias.
+     */
+    private static String alias(GridSqlElement exp, int idx) {
+        if (exp instanceof GridSqlColumn)
+            return ((GridSqlColumn)exp).columnName();
+
+        if (exp instanceof GridSqlAlias)
+            return ((GridSqlAlias)exp).alias();
+
+        return columnAlias(idx);
+    }
+
+    /**
+     * @param mapSelect Selects for map query.
+     * @param rdcSelect Selects for reduce query.
+     * @param idx Index.
+     */
+    private static void splitSelectExpression(List<GridSqlElement> mapSelect, 
GridSqlElement[] rdcSelect, int idx) {
+        assert idx < rdcSelect.length;
+
+        GridSqlElement el = mapSelect.get(idx);
+
+        GridSqlAlias alias = null;
+
+        if (el instanceof GridSqlAlias) { // Unwrap from alias.
+            alias = (GridSqlAlias)el;
+            el = alias.child();
+        }
+
+        if (el instanceof GridSqlAggregateFunction) {
+            GridSqlAggregateFunction agg = (GridSqlAggregateFunction)el;
+
+            switch (agg.type()) {
+                case AVG: // Split AVG(x) into distributed SUM( 
AVG(x)*COUNT(x) )/SUM( COUNT(x) ).
+                    //-- COUNT(x) map
+                    GridSqlElement cntMap = aggregate(agg.distinct(), 
COUNT).addChild(agg.child()); // Add function argument.
+
+                    // 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(columnAlias(mapSelect.size()), cntMap);
+
+                    mapSelect.add(cntMap);
+
+                    //-- AVG(x) map
+                    GridSqlElement avgMap = aggregate(agg.distinct(), 
AVG).addChild(agg.child()); // Add function argument.
+
+                    // Add generated alias to AVG(x).
+                    avgMap = alias(columnAlias(idx), avgMap);
+
+                    mapSelect.set(idx, avgMap);
+
+                    //-- 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())));
+
+                    GridSqlElement sumDownRdc = aggregate(false, SUM).addChild(
+                        column(((GridSqlAlias)cntMap).alias()));
+
+                    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;
+
+                    break;
+
+                case COUNT_ALL:
+                case COUNT:
+                case MAX:
+                case MIN:
+                case SUM:
+                case GROUP_CONCAT:
+                default:
+                    throw new IgniteException("Unsupported aggregate: " + 
agg.type());
+            }
+        }
+        else if (alias == null) {
+
+        }
+    }
+
+    /**
+     * @param distinct Distinct.
+     * @param type Type.
+     * @return Aggregate function.
+     */
+    private static GridSqlAggregateFunction aggregate(boolean distinct, 
GridSqlFunctionType type) {
+        return new GridSqlAggregateFunction(distinct, type);
+    }
+
+    /**
+     * @param name Column name.
+     * @return Column.
+     */
+    private static GridSqlColumn column(String name) {
+        return new GridSqlColumn(null, name, name);
+    }
+
+    /**
+     * @param alias Alias.
+     * @param child Child.
+     * @return Alias.
+     */
+    private static GridSqlAlias alias(String alias, GridSqlElement child) {
+        return new GridSqlAlias(alias, child);
+    }
+
+    /**
+     * @param type Type.
+     * @param left Left expression.
+     * @param right Right expression.
+     * @return Binary operator.
+     */
+    private static GridSqlOperation op(GridSqlOperationType type, 
GridSqlElement left, GridSqlElement right) {
+        return new GridSqlOperation(type, left, right);
+    }
 }

Reply via email to