You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by se...@apache.org on 2015/04/08 13:38:17 UTC
[02/16] incubator-ignite git commit: # IGNITE-624 Make
GridSqlQueryParser able to parse SQL query with UNION expression. Created
class GridSqlUnion.
# IGNITE-624 Make GridSqlQueryParser able to parse SQL query with UNION expression. Created class GridSqlUnion.
Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/98de490f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/98de490f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/98de490f
Branch: refs/heads/ignite-sprint-3
Commit: 98de490fbb4bb671ee28da5f9ad7d0911cf9b190
Parents: b297a4c
Author: sevdokimov <se...@jetbrains.com>
Authored: Tue Mar 31 23:26:34 2015 +0300
Committer: sevdokimov <se...@jetbrains.com>
Committed: Tue Mar 31 23:26:34 2015 +0300
----------------------------------------------------------------------
.../processors/query/h2/sql/GridSqlQuery.java | 221 +----------------
.../query/h2/sql/GridSqlQueryParser.java | 62 ++++-
.../query/h2/sql/GridSqlQuerySplitter.java | 53 ++--
.../processors/query/h2/sql/GridSqlSelect.java | 243 +++++++++++++++++++
.../processors/query/h2/sql/GridSqlUnion.java | 162 +++++++++++++
.../query/h2/sql/GridQueryParsingTest.java | 18 +-
6 files changed, 515 insertions(+), 244 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/98de490f/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQuery.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQuery.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQuery.java
index da71bcb..db1dcbf 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQuery.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQuery.java
@@ -17,49 +17,29 @@
package org.apache.ignite.internal.processors.query.h2.sql;
-import org.h2.util.*;
-
import java.util.*;
/**
* Select query.
*/
-public class GridSqlQuery implements Cloneable {
- /** */
- private boolean distinct;
-
- /** */
- private List<GridSqlElement> allExprs;
-
- /** */
- private List<GridSqlElement> select = new ArrayList<>();
-
+public abstract class GridSqlQuery implements Cloneable {
/** */
- private List<GridSqlElement> groups = new ArrayList<>();
+ protected boolean distinct;
/** */
- private int[] grpCols;
+ protected List<GridSqlElement> allExprs;
/** */
- private GridSqlElement from;
+ protected List<GridSqlElement> select = new ArrayList<>();
/** */
- private GridSqlElement where;
+ protected Map<GridSqlElement,GridSqlSortColumn> sort = new LinkedHashMap<>();
/** */
- private GridSqlElement having;
+ protected GridSqlElement offset;
/** */
- private int havingCol = -1;
-
- /** */
- private Map<GridSqlElement,GridSqlSortColumn> sort = new LinkedHashMap<>();
-
- /** */
- private GridSqlElement offset;
-
- /** */
- private GridSqlElement limit;
+ protected GridSqlElement limit;
/**
* @return Offset.
@@ -106,78 +86,7 @@ public class GridSqlQuery implements Cloneable {
/**
* @return Generate sql.
*/
- public String getSQL() {
- StatementBuilder buff = new StatementBuilder("SELECT");
-
- if (distinct)
- buff.append(" DISTINCT");
-
- for (GridSqlElement expression : select) {
- buff.appendExceptFirst(",");
- buff.append('\n');
- buff.append(StringUtils.indent(expression.getSQL(), 4, false));
- }
-
- buff.append("\nFROM ").append(from.getSQL());
-
- if (where != null)
- buff.append("\nWHERE ").append(StringUtils.unEnclose(where.getSQL()));
-
- if (!groups.isEmpty()) {
- buff.append("\nGROUP BY ");
-
- buff.resetCount();
-
- for (GridSqlElement expression : groups) {
- buff.appendExceptFirst(", ");
-
- if (expression instanceof GridSqlAlias)
- buff.append(StringUtils.unEnclose((expression.child().getSQL())));
- else
- buff.append(StringUtils.unEnclose(expression.getSQL()));
- }
- }
-
- if (having != null)
- buff.append("\nHAVING ").append(StringUtils.unEnclose(having.getSQL()));
-
- if (!sort.isEmpty()) {
- buff.append("\nORDER BY ");
-
- buff.resetCount();
-
- for (Map.Entry<GridSqlElement,GridSqlSortColumn> entry : sort.entrySet()) {
- buff.appendExceptFirst(", ");
-
- GridSqlElement expression = entry.getKey();
-
- int idx = select.indexOf(expression);
-
- if (idx >= 0)
- buff.append(idx + 1);
- else
- buff.append('=').append(StringUtils.unEnclose(expression.getSQL()));
-
- GridSqlSortColumn type = entry.getValue();
-
- if (!type.asc())
- buff.append(" DESC");
-
- if (type.nullsFirst())
- buff.append(" NULLS FIRST");
- else if (type.nullsLast())
- buff.append(" NULLS LAST");
- }
- }
-
- if (limit != null)
- buff.append(" LIMIT ").append(StringUtils.unEnclose(limit.getSQL()));
-
- if (offset != null)
- buff.append(" OFFSET ").append(StringUtils.unEnclose(offset.getSQL()));
-
- return buff.toString();
- }
+ public abstract String getSQL();
/**
* @param expression Expression.
@@ -221,119 +130,6 @@ public class GridSqlQuery implements Cloneable {
}
/**
- * @return Expressions.
- */
- public List<GridSqlElement> groups() {
- return groups;
- }
-
- /**
- *
- */
- public void clearGroups() {
- groups = new ArrayList<>();
- grpCols = null;
- }
-
- /**
- * @param expression Expression.
- */
- public void addGroupExpression(GridSqlElement expression) {
- if (expression == null)
- throw new NullPointerException();
-
- groups.add(expression);
- }
-
- /**
- * @return Group columns.
- */
- public int[] groupColumns() {
- return grpCols;
- }
-
- /**
- * @param grpCols Group columns.
- */
- public void groupColumns(int[] grpCols) {
- this.grpCols = grpCols;
- }
-
- /**
- * @return Tables.
- */
- public GridSqlElement from() {
- return from;
- }
-
- /**
- * @param from From element.
- * @return {@code this}.
- */
- public GridSqlQuery from(GridSqlElement from) {
- this.from = from;
-
- return this;
- }
-
- /**
- * @return Where.
- */
- public GridSqlElement where() {
- return where;
- }
-
- /**
- * @param where New where.
- */
- public void where(GridSqlElement where) {
- this.where = where;
- }
-
- /**
- * @param condition Adds new WHERE condition using AND operator.
- * @return {@code this}.
- */
- public GridSqlQuery whereAnd(GridSqlElement condition) {
- if (condition == null)
- throw new NullPointerException();
-
- GridSqlElement old = where();
-
- where(old == null ? condition : new GridSqlOperation(GridSqlOperationType.AND, old, condition));
-
- return this;
- }
-
- /**
- * @return Having.
- */
- public GridSqlElement having() {
- return having;
- }
-
- /**
- * @param having New having.
- */
- public void having(GridSqlElement having) {
- this.having = having;
- }
-
- /**
- * @param col Index of HAVING column.
- */
- public void havingColumn(int col) {
- this.havingCol = col;
- }
-
- /**
- * @return Index of HAVING column.
- */
- public int havingColumn() {
- return havingCol;
- }
-
- /**
* @return Sort.
*/
public Map<GridSqlElement,GridSqlSortColumn> sort() {
@@ -362,7 +158,6 @@ public class GridSqlQuery implements Cloneable {
GridSqlQuery res = (GridSqlQuery)super.clone();
res.select = new ArrayList<>(select);
- res.groups = new ArrayList<>(groups);
res.sort = new LinkedHashMap<>(sort);
res.allExprs = null;
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/98de490f/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
index d3cd038..fb341c1 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQueryParser.java
@@ -22,6 +22,7 @@ import org.h2.command.*;
import org.h2.command.dml.*;
import org.h2.engine.*;
import org.h2.expression.*;
+import org.h2.expression.Parameter;
import org.h2.jdbc.*;
import org.h2.result.*;
import org.h2.table.*;
@@ -154,6 +155,9 @@ public class GridSqlQueryParser {
private static final Getter<JdbcPreparedStatement,Command> COMMAND = getter(JdbcPreparedStatement.class, "command");
/** */
+ private static final Getter<SelectUnion, SortOrder> UNION_SORT = getter(SelectUnion.class, "sort");
+
+ /** */
private static volatile Getter<Command,Prepared> prepared;
/** */
@@ -171,14 +175,14 @@ public class GridSqlQueryParser {
if (p == null) {
Class<? extends Command> cls = cmd.getClass();
- assert cls.getSimpleName().equals("CommandContainer");
+ assert "CommandContainer".equals(cls.getSimpleName());
prepared = p = getter(cls, "prepared");
}
- Prepared select = p.get(cmd);
+ Prepared statement = p.get(cmd);
- return new GridSqlQueryParser().parse((Select)select);
+ return new GridSqlQueryParser().parse((Query)statement);
}
/**
@@ -199,9 +203,8 @@ public class GridSqlQueryParser {
res = new GridSqlSubquery(parse((Select)qry));
}
- else if (tbl instanceof FunctionTable) {
+ else if (tbl instanceof FunctionTable)
res = parseExpression(FUNC_EXPR.get((FunctionTable)tbl));
- }
else if (tbl instanceof RangeTable) {
res = new GridSqlFunction(GridSqlFunctionType.SYSTEM_RANGE);
@@ -225,13 +228,13 @@ public class GridSqlQueryParser {
/**
* @param select Select.
*/
- public GridSqlQuery parse(Select select) {
- GridSqlQuery res = (GridSqlQuery)h2ObjToGridObj.get(select);
+ public GridSqlSelect parse(Select select) {
+ GridSqlSelect res = (GridSqlSelect)h2ObjToGridObj.get(select);
if (res != null)
return res;
- res = new GridSqlQuery();
+ res = new GridSqlSelect();
h2ObjToGridObj.put(select, res);
@@ -314,6 +317,45 @@ public class GridSqlQueryParser {
}
/**
+ * @param qry Select.
+ */
+ public GridSqlQuery parse(Query qry) {
+ if (qry instanceof Select)
+ return parse((Select)qry);
+
+ if (qry instanceof SelectUnion)
+ return parse((SelectUnion)qry);
+
+ throw new UnsupportedOperationException("Unknown query type: " + qry);
+ }
+
+ /**
+ * @param union Select.
+ */
+ public GridSqlUnion parse(SelectUnion union) {
+ GridSqlUnion res = (GridSqlUnion)h2ObjToGridObj.get(union);
+
+ if (res != null)
+ return res;
+
+ res = new GridSqlUnion();
+
+ res.right(parse(union.getRight()));
+ res.left(parse(union.getLeft()));
+
+ res.unionType(union.getUnionType());
+
+ res.limit(parseExpression(union.getLimit()));
+ res.offset(parseExpression(union.getOffset()));
+
+ assert UNION_SORT.get(union) == null; // todo IGNITE-624
+
+ h2ObjToGridObj.put(union, res);
+
+ return res;
+ }
+
+ /**
* @param expression Expression.
*/
private GridSqlElement parseExpression(@Nullable Expression expression) {
@@ -495,8 +537,8 @@ public class GridSqlQueryParser {
return res;
}
- if (expression instanceof org.h2.expression.Parameter)
- return new GridSqlParameter(((org.h2.expression.Parameter)expression).getIndex());
+ if (expression instanceof Parameter)
+ return new GridSqlParameter(((Parameter)expression).getIndex());
if (expression instanceof Aggregate) {
GridSqlAggregateFunction res = new GridSqlAggregateFunction(DISTINCT.get((Aggregate)expression),
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/98de490f/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQuerySplitter.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQuerySplitter.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQuerySplitter.java
index 6c32e13..e98169c 100644
--- a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQuerySplitter.java
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlQuerySplitter.java
@@ -21,6 +21,7 @@ import org.apache.ignite.*;
import org.apache.ignite.internal.processors.cache.query.*;
import org.h2.jdbc.*;
import org.h2.value.*;
+import org.jetbrains.annotations.*;
import java.util.*;
@@ -66,14 +67,19 @@ public class GridSqlQuerySplitter {
GridSqlQuery srcQry = GridSqlQueryParser.parse(stmt);
+ if (!(srcQry instanceof GridSqlSelect))
+ throw new UnsupportedOperationException(); // todo IGNITE-624 Support UNION,
+
+ GridSqlSelect srcSelect = (GridSqlSelect)srcQry;
+
final String mergeTable = TABLE_FUNC_NAME + "()"; // table(0); TODO
- GridSqlQuery mapQry = srcQry.clone();
- GridSqlQuery rdcQry = new GridSqlQuery().from(new GridSqlFunction("PUBLIC", TABLE_FUNC_NAME)); // table(mergeTable)); TODO
+ GridSqlSelect mapQry = srcSelect.clone();
+ GridSqlSelect rdcQry = new GridSqlSelect().from(new GridSqlFunction("PUBLIC", TABLE_FUNC_NAME)); // table(mergeTable)); TODO
// Split all select expressions into map-reduce parts.
- List<GridSqlElement> mapExps = new ArrayList<>(srcQry.allExpressions());
- GridSqlElement[] rdcExps = new GridSqlElement[srcQry.select().size()];
+ List<GridSqlElement> mapExps = new ArrayList<>(srcSelect.allExpressions());
+ GridSqlElement[] rdcExps = new GridSqlElement[srcSelect.select().size()];
Set<String> colNames = new HashSet<>();
@@ -90,43 +96,43 @@ public class GridSqlQuerySplitter {
rdcQry.addSelectExpression(rdcExp);
// -- GROUP BY
- if (!srcQry.groups().isEmpty()) {
+ if (!srcSelect.groups().isEmpty()) {
mapQry.clearGroups();
- for (int col : srcQry.groupColumns())
+ for (int col : srcSelect.groupColumns())
mapQry.addGroupExpression(column(((GridSqlAlias)mapExps.get(col)).alias()));
- for (int col : srcQry.groupColumns())
+ for (int col : srcSelect.groupColumns())
rdcQry.addGroupExpression(column(((GridSqlAlias)mapExps.get(col)).alias()));
}
// -- HAVING
- if (srcQry.having() != null) {
+ if (srcSelect.having() != null) {
// TODO Find aggregate functions in HAVING clause.
- rdcQry.whereAnd(column(columnName(srcQry.havingColumn())));
+ rdcQry.whereAnd(column(columnName(srcSelect.havingColumn())));
mapQry.having(null);
}
// -- ORDER BY
- if (!srcQry.sort().isEmpty()) {
- for (GridSqlSortColumn sortCol : srcQry.sort().values())
+ if (!srcSelect.sort().isEmpty()) {
+ for (GridSqlSortColumn sortCol : srcSelect.sort().values())
rdcQry.addSort(column(((GridSqlAlias)mapExps.get(sortCol.column())).alias()), sortCol);
}
// -- LIMIT
- if (srcQry.limit() != null)
- rdcQry.limit(srcQry.limit());
+ if (srcSelect.limit() != null)
+ rdcQry.limit(srcSelect.limit());
// -- OFFSET
- if (srcQry.offset() != null) {
+ if (srcSelect.offset() != null) {
mapQry.offset(null);
- rdcQry.offset(srcQry.offset());
+ rdcQry.offset(srcSelect.offset());
}
// -- DISTINCT
- if (srcQry.distinct()) {
+ if (srcSelect.distinct()) {
mapQry.distinct(false);
rdcQry.distinct(true);
}
@@ -148,6 +154,19 @@ public class GridSqlQuerySplitter {
* @return Extracted parameters list.
*/
private static List<Object> findParams(GridSqlQuery qry, Object[] params, ArrayList<Object> target) {
+ if (qry instanceof GridSqlSelect)
+ return findParams((GridSqlSelect)qry, params, target);
+
+ throw new UnsupportedOperationException(); // todo IGNITE-624
+ }
+
+ /**
+ * @param qry Select.
+ * @param params Parameters.
+ * @param target Extracted parameters.
+ * @return Extracted parameters list.
+ */
+ private static List<Object> findParams(GridSqlSelect qry, Object[] params, ArrayList<Object> target) {
if (params.length == 0)
return target;
@@ -176,7 +195,7 @@ public class GridSqlQuerySplitter {
* @param params Parameters.
* @param target Extracted parameters.
*/
- private static void findParams(GridSqlElement el, Object[] params, ArrayList<Object> target) {
+ private static void findParams(@Nullable GridSqlElement el, Object[] params, ArrayList<Object> target) {
if (el == null)
return;
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/98de490f/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlSelect.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlSelect.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlSelect.java
new file mode 100644
index 0000000..272f8b4
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlSelect.java
@@ -0,0 +1,243 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.query.h2.sql;
+
+import org.h2.util.*;
+
+import java.util.*;
+
+/**
+ *
+ */
+public class GridSqlSelect extends GridSqlQuery {
+ /** */
+ private List<GridSqlElement> groups = new ArrayList<>();
+
+ /** */
+ private int[] grpCols;
+
+ /** */
+ private GridSqlElement from;
+
+ /** */
+ private GridSqlElement where;
+
+ /** */
+ private GridSqlElement having;
+
+ /** */
+ private int havingCol = -1;
+
+ /** {@inheritDoc} */
+ @Override public String getSQL() {
+ StatementBuilder buff = new StatementBuilder("SELECT");
+
+ if (distinct)
+ buff.append(" DISTINCT");
+
+ for (GridSqlElement expression : select) {
+ buff.appendExceptFirst(",");
+ buff.append('\n');
+ buff.append(StringUtils.indent(expression.getSQL(), 4, false));
+ }
+
+ buff.append("\nFROM ").append(from.getSQL());
+
+ if (where != null)
+ buff.append("\nWHERE ").append(StringUtils.unEnclose(where.getSQL()));
+
+ if (!groups.isEmpty()) {
+ buff.append("\nGROUP BY ");
+
+ buff.resetCount();
+
+ for (GridSqlElement expression : groups) {
+ buff.appendExceptFirst(", ");
+
+ if (expression instanceof GridSqlAlias)
+ buff.append(StringUtils.unEnclose((expression.child().getSQL())));
+ else
+ buff.append(StringUtils.unEnclose(expression.getSQL()));
+ }
+ }
+
+ if (having != null)
+ buff.append("\nHAVING ").append(StringUtils.unEnclose(having.getSQL()));
+
+ if (!sort.isEmpty()) {
+ buff.append("\nORDER BY ");
+
+ buff.resetCount();
+
+ for (Map.Entry<GridSqlElement,GridSqlSortColumn> entry : sort.entrySet()) {
+ buff.appendExceptFirst(", ");
+
+ GridSqlElement expression = entry.getKey();
+
+ int idx = select.indexOf(expression);
+
+ if (idx >= 0)
+ buff.append(idx + 1);
+ else
+ buff.append('=').append(StringUtils.unEnclose(expression.getSQL()));
+
+ GridSqlSortColumn type = entry.getValue();
+
+ if (!type.asc())
+ buff.append(" DESC");
+
+ if (type.nullsFirst())
+ buff.append(" NULLS FIRST");
+ else if (type.nullsLast())
+ buff.append(" NULLS LAST");
+ }
+ }
+
+ if (limit != null)
+ buff.append(" LIMIT ").append(StringUtils.unEnclose(limit.getSQL()));
+
+ if (offset != null)
+ buff.append(" OFFSET ").append(StringUtils.unEnclose(offset.getSQL()));
+
+ return buff.toString();
+ }
+
+ /**
+ * @return Expressions.
+ */
+ public List<GridSqlElement> groups() {
+ return groups;
+ }
+
+ /**
+ *
+ */
+ public void clearGroups() {
+ groups = new ArrayList<>();
+ grpCols = null;
+ }
+
+ /**
+ * @param expression Expression.
+ */
+ public void addGroupExpression(GridSqlElement expression) {
+ if (expression == null)
+ throw new NullPointerException();
+
+ groups.add(expression);
+ }
+
+ /**
+ * @return Group columns.
+ */
+ public int[] groupColumns() {
+ return grpCols;
+ }
+
+ /**
+ * @param grpCols Group columns.
+ */
+ public void groupColumns(int[] grpCols) {
+ this.grpCols = grpCols;
+ }
+
+ /**
+ * @return Tables.
+ */
+ public GridSqlElement from() {
+ return from;
+ }
+
+ /**
+ * @param from From element.
+ * @return {@code this}.
+ */
+ public GridSqlSelect from(GridSqlElement from) {
+ this.from = from;
+
+ return this;
+ }
+
+ /**
+ * @return Where.
+ */
+ public GridSqlElement where() {
+ return where;
+ }
+
+ /**
+ * @param where New where.
+ */
+ public void where(GridSqlElement where) {
+ this.where = where;
+ }
+
+ /**
+ * @param cond Adds new WHERE condition using AND operator.
+ * @return {@code this}.
+ */
+ public GridSqlSelect whereAnd(GridSqlElement cond) {
+ if (cond == null)
+ throw new NullPointerException();
+
+ GridSqlElement old = where();
+
+ where(old == null ? cond : new GridSqlOperation(GridSqlOperationType.AND, old, cond));
+
+ return this;
+ }
+
+ /**
+ * @return Having.
+ */
+ public GridSqlElement having() {
+ return having;
+ }
+
+ /**
+ * @param having New having.
+ */
+ public void having(GridSqlElement having) {
+ this.having = having;
+ }
+
+ /**
+ * @param col Index of HAVING column.
+ */
+ public void havingColumn(int col) {
+ havingCol = col;
+ }
+
+ /**
+ * @return Index of HAVING column.
+ */
+ public int havingColumn() {
+ return havingCol;
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings({"CloneCallsConstructors", "CloneDoesntDeclareCloneNotSupportedException"})
+ @Override public GridSqlSelect clone() {
+ GridSqlSelect res = (GridSqlSelect)super.clone();
+
+ res.groups = new ArrayList<>(groups);
+ res.grpCols = grpCols == null ? null : grpCols.clone();
+
+ return res;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/98de490f/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlUnion.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlUnion.java b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlUnion.java
new file mode 100644
index 0000000..1eae1ef
--- /dev/null
+++ b/modules/indexing/src/main/java/org/apache/ignite/internal/processors/query/h2/sql/GridSqlUnion.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ignite.internal.processors.query.h2.sql;
+
+import org.h2.command.dml.*;
+import org.h2.message.*;
+import org.h2.util.*;
+
+import javax.cache.*;
+import java.util.*;
+
+/**
+ *
+ */
+public class GridSqlUnion extends GridSqlQuery {
+ /** */
+ private int unionType;
+
+ /** */
+ private GridSqlQuery right;
+
+ /** */
+ private GridSqlQuery left;
+
+ /** {@inheritDoc} */
+ @Override public String getSQL() {
+ StringBuilder buff = new StringBuilder();
+
+ buff.append('(').append(left.getSQL()).append(')');
+
+ switch (unionType) {
+ case SelectUnion.UNION_ALL:
+ buff.append("\nUNION ALL\n");
+ break;
+
+ case SelectUnion.UNION:
+ buff.append("\nUNION\n");
+ break;
+
+ case SelectUnion.INTERSECT:
+ buff.append("\nINTERSECT\n");
+ break;
+
+ case SelectUnion.EXCEPT:
+ buff.append("\nEXCEPT\n");
+ break;
+
+ default:
+ throw new CacheException("type=" + unionType);
+ }
+
+ buff.append('(').append(right.getSQL()).append(')');
+
+ if (!sort.isEmpty()) {
+ buff.append("\nORDER BY ");
+
+ boolean first = true;
+
+ for (Map.Entry<GridSqlElement, GridSqlSortColumn> entry : sort.entrySet()) {
+ if (first)
+ first = false;
+ else
+ buff.append(", ");
+
+ GridSqlElement expression = entry.getKey();
+
+ int idx = select.indexOf(expression);
+
+ if (idx >= 0)
+ buff.append(idx + 1);
+ else
+ buff.append('=').append(StringUtils.unEnclose(expression.getSQL()));
+
+ GridSqlSortColumn type = entry.getValue();
+
+ if (!type.asc())
+ buff.append(" DESC");
+
+ if (type.nullsFirst())
+ buff.append(" NULLS FIRST");
+ else if (type.nullsLast())
+ buff.append(" NULLS LAST");
+ }
+ }
+
+ if (limit != null)
+ buff.append(" LIMIT ").append(StringUtils.unEnclose(limit.getSQL()));
+
+ if (offset != null)
+ buff.append(" OFFSET ").append(StringUtils.unEnclose(offset.getSQL()));
+
+ return buff.toString();
+ }
+
+ /** {@inheritDoc} */
+ @SuppressWarnings({"CloneCallsConstructors", "CloneDoesntDeclareCloneNotSupportedException"})
+ @Override public GridSqlUnion clone() {
+ GridSqlUnion res = (GridSqlUnion)super.clone();
+
+ res.right = right.clone();
+ res.left = left.clone();
+
+ return res;
+ }
+
+ /**
+ * @return Union type.
+ */
+ public int unionType() {
+ return unionType;
+ }
+
+ /**
+ * @param unionType New union type.
+ */
+ public void unionType(int unionType) {
+ this.unionType = unionType;
+ }
+
+ /**
+ * @return Right.
+ */
+ public GridSqlQuery right() {
+ return right;
+ }
+
+ /**
+ * @param right New right.
+ */
+ public void right(GridSqlQuery right) {
+ this.right = right;
+ }
+
+ /**
+ * @return Left.
+ */
+ public GridSqlQuery left() {
+ return left;
+ }
+
+ /**
+ * @param left New left.
+ */
+ public void left(GridSqlQuery left) {
+ this.left = left;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/98de490f/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
----------------------------------------------------------------------
diff --git a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
index db8e8bd..3eead22 100644
--- a/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
+++ b/modules/indexing/src/test/java/org/apache/ignite/internal/processors/query/h2/sql/GridQueryParsingTest.java
@@ -197,13 +197,23 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
checkQuery("select addr.street from Person p, (select a.street from Address a where a.street is not null) addr");
checkQuery("select p.name n from \"\".Person p order by p.old + 10");
+
+ checkQuery("select count(*) as a from Person union select count(*) as a from Address");
+ checkQuery("select old, count(*) as a from Person group by old union select 1, count(*) as a from Address");
+ checkQuery("select name from Person MINUS select street from Address");
+ checkQuery("select name from Person EXCEPT select street from Address");
+ checkQuery("select name from Person INTERSECT select street from Address");
+ checkQuery("select name from Person UNION select street from Address limit 5");
+ checkQuery("select name from Person UNION select street from Address limit ?");
+ checkQuery("select name from Person UNION select street from Address limit ? offset ?");
+ checkQuery("(select name from Person limit 4) UNION (select street from Address limit 1) limit ? offset ?");
}
/**
*
*/
public void testExample1() throws Exception {
- Select select = parse("select p.name n, max(p.old) maxOld, min(p.old) minOld from Person p group by p.name having maxOld > 10 and min(p.old) < 1");
+ Query select = parse("select p.name n, max(p.old) maxOld, min(p.old) minOld from Person p group by p.name having maxOld > 10 and min(p.old) < 1");
GridSqlQueryParser ses = new GridSqlQueryParser();
@@ -217,7 +227,7 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
*
*/
private JdbcConnection connection() throws Exception {
- GridKernalContext ctx = ((IgniteKernal)ignite).context();
+ GridKernalContext ctx = ((IgniteEx)ignite).context();
GridQueryProcessor qryProcessor = ctx.query();
@@ -266,8 +276,8 @@ public class GridQueryParsingTest extends GridCommonAbstractTest {
String res;
- if (prepared instanceof Select)
- res = ses.parse((Select) prepared).getSQL();
+ if (prepared instanceof Query)
+ res = ses.parse((Query) prepared).getSQL();
else
throw new UnsupportedOperationException();