You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@phoenix.apache.org by ma...@apache.org on 2014/09/25 18:30:27 UTC
[1/2] PHOENIX-1168 Support non-correlated sub-queries in where clause
having a comparison operator with no modifier or a comparison operator
modified by ANY, SOME or ALL
Repository: phoenix
Updated Branches:
refs/heads/master ea5a797eb -> a0694b77c
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
index a74e0f1..d4c119b 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/BaseQueryPlan.java
@@ -150,7 +150,7 @@ public abstract class BaseQueryPlan implements QueryPlan {
return iterator(Collections.<SQLCloseable>emptyList());
}
- public final ResultIterator iterator(final List<SQLCloseable> dependencies) throws SQLException {
+ public final ResultIterator iterator(final List<? extends SQLCloseable> dependencies) throws SQLException {
if (context.getScanRanges() == ScanRanges.NOTHING) {
return ResultIterator.EMPTY_ITERATOR;
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java b/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java
index 6154c88..0d09f79 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/execute/HashJoinPlan.java
@@ -17,14 +17,14 @@
*/
package org.apache.phoenix.execute;
-import static java.util.Collections.emptyMap;
import static org.apache.phoenix.util.LogUtil.addCustomAnnotations;
import java.sql.ParameterMetaData;
import java.sql.SQLException;
-import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
@@ -36,6 +36,7 @@ import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.phoenix.cache.ServerCacheClient.ServerCache;
+import org.apache.phoenix.compile.ColumnProjector;
import org.apache.phoenix.compile.ExplainPlan;
import org.apache.phoenix.compile.FromCompiler;
import org.apache.phoenix.compile.GroupByCompiler.GroupBy;
@@ -45,12 +46,14 @@ import org.apache.phoenix.compile.RowProjector;
import org.apache.phoenix.compile.ScanRanges;
import org.apache.phoenix.compile.StatementContext;
import org.apache.phoenix.compile.WhereCompiler;
+import org.apache.phoenix.exception.SQLExceptionCode;
+import org.apache.phoenix.exception.SQLExceptionInfo;
import org.apache.phoenix.expression.AndExpression;
import org.apache.phoenix.expression.ComparisonExpression;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.InListExpression;
import org.apache.phoenix.expression.LiteralExpression;
-import org.apache.phoenix.hbase.index.util.ImmutableBytesPtr;
+import org.apache.phoenix.expression.RowValueConstructorExpression;
import org.apache.phoenix.iterate.ResultIterator;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.job.JobManager.JobCallable;
@@ -66,9 +69,11 @@ import org.apache.phoenix.query.ConnectionQueryServices;
import org.apache.phoenix.query.KeyRange;
import org.apache.phoenix.query.QueryServices;
import org.apache.phoenix.query.QueryServicesOptions;
+import org.apache.phoenix.schema.PArrayDataType;
import org.apache.phoenix.schema.PDataType;
import org.apache.phoenix.schema.PTable;
import org.apache.phoenix.schema.TableRef;
+import org.apache.phoenix.schema.tuple.Tuple;
import org.apache.phoenix.util.SQLCloseable;
import org.apache.phoenix.util.SQLCloseables;
@@ -80,29 +85,43 @@ public class HashJoinPlan implements QueryPlan {
private final FilterableStatement statement;
private final BaseQueryPlan plan;
private final HashJoinInfo joinInfo;
- private final List<Expression>[] hashExpressions;
- private final Expression[] keyRangeLhsExpressions;
- private final Expression[] keyRangeRhsExpressions;
- private final QueryPlan[] hashPlans;
- private final TupleProjector[] clientProjectors;
- private final boolean[] hasFilters;
+ private final SubPlan[] subPlans;
+ private final boolean recompileWhereClause;
private final boolean forceHashJoinRangeScan;
private final boolean forceHashJoinSkipScan;
-
- public HashJoinPlan(FilterableStatement statement,
- BaseQueryPlan plan, HashJoinInfo joinInfo,
- List<Expression>[] hashExpressions, Expression[] keyRangeLhsExpressions,
- Expression[] keyRangeRhsExpressions, QueryPlan[] hashPlans,
- TupleProjector[] clientProjectors, boolean[] hasFilters) {
+ private List<SQLCloseable> dependencies;
+ private HashCacheClient hashClient;
+ private int maxServerCacheTimeToLive;
+ private AtomicLong firstJobEndTime;
+ private Map<String, String> customAnnotations;
+ private List<Expression> keyRangeExpressions;
+
+ public static HashJoinPlan create(FilterableStatement statement,
+ QueryPlan plan, HashJoinInfo joinInfo, SubPlan[] subPlans) {
+ if (plan instanceof BaseQueryPlan)
+ return new HashJoinPlan(statement, (BaseQueryPlan) plan, joinInfo, subPlans, joinInfo == null);
+
+ assert (plan instanceof HashJoinPlan);
+ HashJoinPlan hashJoinPlan = (HashJoinPlan) plan;
+ assert hashJoinPlan.joinInfo == null;
+ SubPlan[] mergedSubPlans = new SubPlan[hashJoinPlan.subPlans.length + subPlans.length];
+ int i = 0;
+ for (SubPlan subPlan : hashJoinPlan.subPlans) {
+ mergedSubPlans[i++] = subPlan;
+ }
+ for (SubPlan subPlan : subPlans) {
+ mergedSubPlans[i++] = subPlan;
+ }
+ return new HashJoinPlan(statement, hashJoinPlan.plan, joinInfo, mergedSubPlans, true);
+ }
+
+ private HashJoinPlan(FilterableStatement statement,
+ BaseQueryPlan plan, HashJoinInfo joinInfo, SubPlan[] subPlans, boolean recompileWhereClause) {
this.statement = statement;
this.plan = plan;
this.joinInfo = joinInfo;
- this.hashExpressions = hashExpressions;
- this.keyRangeLhsExpressions = keyRangeLhsExpressions;
- this.keyRangeRhsExpressions = keyRangeRhsExpressions;
- this.hashPlans = hashPlans;
- this.clientProjectors = clientProjectors;
- this.hasFilters = hasFilters;
+ this.subPlans = subPlans;
+ this.recompileWhereClause = recompileWhereClause;
this.forceHashJoinRangeScan = plan.getStatement().getHint().hasHint(Hint.RANGE_SCAN_HASH_JOIN);
this.forceHashJoinSkipScan = plan.getStatement().getHint().hasHint(Hint.SKIP_SCAN_HASH_JOIN);
}
@@ -124,47 +143,27 @@ public class HashJoinPlan implements QueryPlan {
@Override
public ResultIterator iterator() throws SQLException {
- ImmutableBytesPtr[] joinIds = joinInfo.getJoinIds();
- assert (joinIds.length == hashExpressions.length && joinIds.length == hashPlans.length);
-
- final HashCacheClient hashClient = new HashCacheClient(plan.getContext().getConnection());
- Scan scan = plan.getContext().getScan();
- final ScanRanges ranges = plan.getContext().getScanRanges();
-
- int count = joinIds.length;
- final PhoenixConnection connection = getContext().getConnection();
- ConnectionQueryServices services = getContext().getConnection().getQueryServices();
+ int count = subPlans.length;
+ PhoenixConnection connection = getContext().getConnection();
+ ConnectionQueryServices services = connection.getQueryServices();
ExecutorService executor = services.getExecutor();
- List<Future<ServerCache>> futures = new ArrayList<Future<ServerCache>>(count);
- List<SQLCloseable> dependencies = new ArrayList<SQLCloseable>(count);
- List<Expression> keyRangeExpressions = new ArrayList<Expression>();
- @SuppressWarnings("unchecked")
- final List<ImmutableBytesWritable>[] keyRangeRhsValues = new List[count];
- final int maxServerCacheTimeToLive = services.getProps().getInt(QueryServices.MAX_SERVER_CACHE_TIME_TO_LIVE_MS_ATTRIB, QueryServicesOptions.DEFAULT_MAX_SERVER_CACHE_TIME_TO_LIVE_MS);
- final AtomicLong firstJobEndTime = new AtomicLong(0);
- SQLException firstException = null;
+ List<Future<Object>> futures = Lists.<Future<Object>>newArrayListWithExpectedSize(count);
+ dependencies = Lists.newArrayList();
+ if (joinInfo != null) {
+ hashClient = new HashCacheClient(plan.getContext().getConnection());
+ maxServerCacheTimeToLive = services.getProps().getInt(QueryServices.MAX_SERVER_CACHE_TIME_TO_LIVE_MS_ATTRIB, QueryServicesOptions.DEFAULT_MAX_SERVER_CACHE_TIME_TO_LIVE_MS);
+ firstJobEndTime = new AtomicLong(0);
+ customAnnotations = connection.getCustomTracingAnnotations();
+ keyRangeExpressions = new CopyOnWriteArrayList<Expression>();
+ }
+
for (int i = 0; i < count; i++) {
final int index = i;
- if (keyRangeRhsExpressions[index] != null) {
- keyRangeRhsValues[index] = new ArrayList<ImmutableBytesWritable>();
- }
- futures.add(executor.submit(new JobCallable<ServerCache>() {
+ futures.add(executor.submit(new JobCallable<Object>() {
@Override
- public ServerCache call() throws Exception {
- QueryPlan hashPlan = hashPlans[index];
- ServerCache cache = hashClient.addHashCache(ranges, hashPlan.iterator(),
- clientProjectors[index], hashPlan.getEstimatedSize(), hashExpressions[index], plan.getTableRef(), keyRangeRhsExpressions[index], keyRangeRhsValues[index]);
- long endTime = System.currentTimeMillis();
- boolean isSet = firstJobEndTime.compareAndSet(0, endTime);
- if (!isSet && (endTime - firstJobEndTime.get()) > maxServerCacheTimeToLive) {
- Map<String, String> customAnnotations = emptyMap();
- if (connection != null) {
- customAnnotations = connection.getCustomTracingAnnotations();
- }
- LOG.warn(addCustomAnnotations("Hash plan [" + index + "] execution seems too slow. Earlier hash cache(s) might have expired on servers.", customAnnotations));
- }
- return cache;
+ public Object call() throws Exception {
+ return subPlans[index].execute(HashJoinPlan.this);
}
@Override
@@ -173,21 +172,19 @@ public class HashJoinPlan implements QueryPlan {
}
}));
}
+
+ SQLException firstException = null;
for (int i = 0; i < count; i++) {
try {
- ServerCache cache = futures.get(i).get();
- joinIds[i].set(cache.getId());
- dependencies.add(cache);
- if (keyRangeRhsExpressions[i] != null) {
- keyRangeExpressions.add(createKeyRangeExpression(keyRangeLhsExpressions[i], keyRangeRhsExpressions[i], keyRangeRhsValues[i], plan.getContext().getTempPtr(), hasFilters[i]));
- }
+ Object result = futures.get(i).get();
+ subPlans[i].postProcess(result, this);
} catch (InterruptedException e) {
if (firstException == null) {
- firstException = new SQLException("Hash plan [" + i + "] execution interrupted.", e);
+ firstException = new SQLException("Sub plan [" + i + "] execution interrupted.", e);
}
} catch (ExecutionException e) {
if (firstException == null) {
- firstException = new SQLException("Encountered exception in hash plan [" + i + "] execution.",
+ firstException = new SQLException("Encountered exception in sub plan [" + i + "] execution.",
e.getCause());
}
}
@@ -196,16 +193,26 @@ public class HashJoinPlan implements QueryPlan {
SQLCloseables.closeAllQuietly(dependencies);
throw firstException;
}
-
- HashJoinInfo.serializeHashJoinIntoScan(scan, joinInfo);
- if (!keyRangeExpressions.isEmpty()) {
+
+ boolean hasKeyRangeExpressions = keyRangeExpressions != null && !keyRangeExpressions.isEmpty();
+ if (recompileWhereClause || hasKeyRangeExpressions) {
StatementContext context = plan.getContext();
PTable table = context.getCurrentTable().getTable();
ParseNode viewWhere = table.getViewStatement() == null ? null : new SQLParser(table.getViewStatement()).parseQuery().getWhere();
context.setResolver(FromCompiler.getResolverForQuery((SelectStatement) (plan.getStatement()), plan.getContext().getConnection()));
- WhereCompiler.compile(plan.getContext(), plan.getStatement(), viewWhere, keyRangeExpressions, true);
+ if (recompileWhereClause) {
+ WhereCompiler.compile(plan.getContext(), plan.getStatement(), viewWhere);
+ }
+ if (hasKeyRangeExpressions) {
+ WhereCompiler.compile(plan.getContext(), plan.getStatement(), viewWhere, keyRangeExpressions, true);
+ }
}
+ if (joinInfo != null) {
+ Scan scan = plan.getContext().getScan();
+ HashJoinInfo.serializeHashJoinIntoScan(scan, joinInfo);
+ }
+
return plan.iterator(dependencies);
}
@@ -260,40 +267,20 @@ public class HashJoinPlan implements QueryPlan {
@Override
public ExplainPlan getExplainPlan() throws SQLException {
- List<String> mainQuerySteps = plan.getExplainPlan().getPlanSteps();
- List<String> planSteps = Lists.newArrayList(mainQuerySteps);
- int count = hashPlans.length;
- planSteps.add(" PARALLEL EQUI-JOIN " + count + " HASH TABLES:");
+ List<String> planSteps = Lists.newArrayList(plan.getExplainPlan().getPlanSteps());
+ int count = subPlans.length;
+ planSteps.add(" PARALLEL EQUI/SEMI/ANTI-JOIN " + count + " TABLES:");
for (int i = 0; i < count; i++) {
- boolean earlyEvaluation = joinInfo.earlyEvaluation()[i];
- boolean skipMerge = joinInfo.getSchemas()[i].getFieldCount() == 0;
- planSteps.add(" BUILD HASH TABLE " + i + (earlyEvaluation ? "" : "(DELAYED EVALUATION)") + (skipMerge ? " (SKIP MERGE)" : ""));
- List<String> steps = hashPlans[i].getExplainPlan().getPlanSteps();
- for (String step : steps) {
- planSteps.add(" " + step);
- }
+ planSteps.addAll(subPlans[i].getPreSteps(this));
}
- String dynamicFilters = null;
- int filterCount = 0;
for (int i = 0; i < count; i++) {
- if (keyRangeLhsExpressions[i] != null) {
- if (filterCount == 1) {
- dynamicFilters = "(" + dynamicFilters + ")";
- }
- String filter = keyRangeLhsExpressions[i].toString()
- + (useInClause(hasFilters[i]) ? " IN " : " BETWEEN MIN/MAX OF ")
- + "(" + keyRangeRhsExpressions[i].toString() + ")";
- dynamicFilters = dynamicFilters == null ? filter : (dynamicFilters + " AND (" + filter + ")");
- filterCount++;
- }
- }
- if (dynamicFilters != null) {
- planSteps.add(" DYNAMIC SERVER FILTER BY " + dynamicFilters);
+ planSteps.addAll(subPlans[i].getPostSteps(this));
}
- if (joinInfo.getPostJoinFilterExpression() != null) {
+
+ if (joinInfo != null && joinInfo.getPostJoinFilterExpression() != null) {
planSteps.add(" AFTER-JOIN SERVER FILTER BY " + joinInfo.getPostJoinFilterExpression().toString());
}
- if (joinInfo.getLimit() != null) {
+ if (joinInfo != null && joinInfo.getLimit() != null) {
planSteps.add(" JOIN-SCANNER " + joinInfo.getLimit() + " ROW LIMIT");
}
@@ -330,5 +317,158 @@ public class HashJoinPlan implements QueryPlan {
return false;
}
+ protected interface SubPlan {
+ public Object execute(HashJoinPlan parent) throws SQLException;
+ public void postProcess(Object result, HashJoinPlan parent) throws SQLException;
+ public List<String> getPreSteps(HashJoinPlan parent) throws SQLException;
+ public List<String> getPostSteps(HashJoinPlan parent) throws SQLException;
+ }
+
+ public static class WhereClauseSubPlan implements SubPlan {
+ private final QueryPlan plan;
+ private final SelectStatement select;
+ private final boolean expectSingleRow;
+
+ public WhereClauseSubPlan(QueryPlan plan, SelectStatement select, boolean expectSingleRow) {
+ this.plan = plan;
+ this.select = select;
+ this.expectSingleRow = expectSingleRow;
+ }
+
+ @Override
+ public Object execute(HashJoinPlan parent) throws SQLException {
+ List<Object> values = Lists.<Object> newArrayList();
+ ResultIterator iterator = plan.iterator();
+ RowProjector projector = plan.getProjector();
+ ImmutableBytesWritable ptr = new ImmutableBytesWritable();
+ int columnCount = projector.getColumnCount();
+ int rowCount = 0;
+ PDataType baseType = null;
+ for (Tuple tuple = iterator.next(); tuple != null; tuple = iterator.next()) {
+ if (expectSingleRow && rowCount >= 1)
+ throw new SQLExceptionInfo.Builder(SQLExceptionCode.SINGLE_ROW_SUBQUERY_RETURNS_MULTIPLE_ROWS).build().buildException();
+
+ if (columnCount == 1) {
+ ColumnProjector columnProjector = projector.getColumnProjector(0);
+ baseType = columnProjector.getExpression().getDataType();
+ Object value = columnProjector.getValue(tuple, baseType, ptr);
+ values.add(value);
+ } else {
+ List<Expression> expressions = Lists.<Expression>newArrayListWithExpectedSize(columnCount);
+ for (int i = 0; i < columnCount; i++) {
+ ColumnProjector columnProjector = projector.getColumnProjector(i);
+ PDataType type = columnProjector.getExpression().getDataType();
+ Object value = columnProjector.getValue(tuple, type, ptr);
+ expressions.add(LiteralExpression.newConstant(value, type));
+ }
+ Expression expression = new RowValueConstructorExpression(expressions, true);
+ baseType = expression.getDataType();
+ expression.evaluate(null, ptr);
+ values.add(baseType.toObject(ptr));
+ }
+ rowCount++;
+ }
+
+ Object result = expectSingleRow ? (values.isEmpty() ? null : values.get(0)) : PArrayDataType.instantiatePhoenixArray(baseType, values.toArray());
+ parent.getContext().setSubqueryResult(select, result);
+ return null;
+ }
+
+ @Override
+ public void postProcess(Object result, HashJoinPlan parent) throws SQLException {
+ }
+
+ @Override
+ public List<String> getPreSteps(HashJoinPlan parent) throws SQLException {
+ List<String> steps = Lists.newArrayList();
+ steps.add(" EXECUTE " + (expectSingleRow ? "SINGLE" : "MULTIPLE") + "-ROW SUBQUERY");
+ for (String step : plan.getExplainPlan().getPlanSteps()) {
+ steps.add(" " + step);
+ }
+ return steps;
+ }
+
+ @Override
+ public List<String> getPostSteps(HashJoinPlan parent) throws SQLException {
+ return Collections.<String>emptyList();
+ }
+ }
+
+ public static class HashSubPlan implements SubPlan {
+ private final int index;
+ private final QueryPlan plan;
+ private final List<Expression> hashExpressions;
+ private final Expression keyRangeLhsExpression;
+ private final Expression keyRangeRhsExpression;
+ private final TupleProjector clientProjector;
+ private final boolean hasFilters;
+
+ public HashSubPlan(int index, QueryPlan subPlan,
+ List<Expression> hashExpressions,
+ Expression keyRangeLhsExpression,
+ Expression keyRangeRhsExpression,
+ TupleProjector clientProjector, boolean hasFilters) {
+ this.index = index;
+ this.plan = subPlan;
+ this.hashExpressions = hashExpressions;
+ this.keyRangeLhsExpression = keyRangeLhsExpression;
+ this.keyRangeRhsExpression = keyRangeRhsExpression;
+ this.clientProjector = clientProjector;
+ this.hasFilters = hasFilters;
+ }
+
+ @Override
+ public Object execute(HashJoinPlan parent) throws SQLException {
+ ScanRanges ranges = parent.plan.getContext().getScanRanges();
+ List<ImmutableBytesWritable> keyRangeRhsValues = null;
+ if (keyRangeRhsExpression != null) {
+ keyRangeRhsValues = Lists.<ImmutableBytesWritable>newArrayList();
+ }
+ ServerCache cache = parent.hashClient.addHashCache(ranges, plan.iterator(),
+ clientProjector, plan.getEstimatedSize(), hashExpressions, parent.plan.getTableRef(), keyRangeRhsExpression, keyRangeRhsValues);
+ long endTime = System.currentTimeMillis();
+ boolean isSet = parent.firstJobEndTime.compareAndSet(0, endTime);
+ if (!isSet && (endTime - parent.firstJobEndTime.get()) > parent.maxServerCacheTimeToLive) {
+ LOG.warn(addCustomAnnotations("Hash plan [" + index + "] execution seems too slow. Earlier hash cache(s) might have expired on servers.", parent.customAnnotations));
+ }
+ if (keyRangeRhsValues != null) {
+ parent.keyRangeExpressions.add(parent.createKeyRangeExpression(keyRangeLhsExpression, keyRangeRhsExpression, keyRangeRhsValues, plan.getContext().getTempPtr(), hasFilters));
+ }
+ return cache;
+ }
+
+ @Override
+ public void postProcess(Object result, HashJoinPlan parent)
+ throws SQLException {
+ ServerCache cache = (ServerCache) result;
+ parent.joinInfo.getJoinIds()[index].set(cache.getId());
+ parent.dependencies.add(cache);
+ }
+
+ @Override
+ public List<String> getPreSteps(HashJoinPlan parent) throws SQLException {
+ List<String> steps = Lists.newArrayList();
+ boolean earlyEvaluation = parent.joinInfo.earlyEvaluation()[index];
+ boolean skipMerge = parent.joinInfo.getSchemas()[index].getFieldCount() == 0;
+ steps.add(" BUILD HASH TABLE " + index + (earlyEvaluation ? "" : "(DELAYED EVALUATION)") + (skipMerge ? " (SKIP MERGE)" : ""));
+ for (String step : plan.getExplainPlan().getPlanSteps()) {
+ steps.add(" " + step);
+ }
+ return steps;
+ }
+
+ @Override
+ public List<String> getPostSteps(HashJoinPlan parent) throws SQLException {
+ if (keyRangeLhsExpression == null)
+ return Collections.<String> emptyList();
+
+ String step = " DYNAMIC SERVER FILTER BY " + keyRangeLhsExpression.toString()
+ + (parent.useInClause(hasFilters) ? " IN " : " BETWEEN MIN/MAX OF ")
+ + "(" + keyRangeRhsExpression.toString() + ")";
+ return Collections.<String> singletonList(step);
+ }
+
+ }
}
+
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/java/org/apache/phoenix/expression/ComparisonExpression.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/expression/ComparisonExpression.java b/phoenix-core/src/main/java/org/apache/phoenix/expression/ComparisonExpression.java
index 008ae7b..8e352e6 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/expression/ComparisonExpression.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/expression/ComparisonExpression.java
@@ -29,6 +29,7 @@ import java.util.List;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
import org.apache.hadoop.io.WritableUtils;
+import org.apache.phoenix.expression.function.InlineArrayElemRefExpression;
import org.apache.phoenix.expression.visitor.ExpressionVisitor;
import org.apache.phoenix.schema.PDataType;
import org.apache.phoenix.schema.SortOrder;
@@ -112,7 +113,7 @@ public class ComparisonExpression extends BaseCompoundExpression {
PDataType lhsExprDataType = lhsExpr.getDataType();
PDataType rhsExprDataType = rhsExpr.getDataType();
- if (lhsExpr instanceof RowValueConstructorExpression || rhsExpr instanceof RowValueConstructorExpression) {
+ if ((lhsExpr instanceof RowValueConstructorExpression || rhsExpr instanceof RowValueConstructorExpression) && !(lhsExpr instanceof InlineArrayElemRefExpression) && !(rhsExpr instanceof InlineArrayElemRefExpression)) {
if (op == CompareOp.EQUAL || op == CompareOp.NOT_EQUAL) {
List<Expression> andNodes = Lists.<Expression>newArrayListWithExpectedSize(Math.max(lhsExpr.getChildren().size(), rhsExpr.getChildren().size()));
rewriteRVCAsEqualityExpression(lhsExpr, rhsExpr, andNodes, ptr);
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
index 4af65b9..eb1fda5 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeFactory.java
@@ -500,6 +500,14 @@ public class ParseNodeFactory {
throw new IllegalArgumentException("Unexpcted CompareOp of " + op);
}
}
+
+ public ArrayAnyComparisonNode arrayAny(ParseNode rhs, ComparisonParseNode compareNode) {
+ return new ArrayAnyComparisonNode(rhs, compareNode);
+ }
+
+ public ArrayAllComparisonNode arrayAll(ParseNode rhs, ComparisonParseNode compareNode) {
+ return new ArrayAllComparisonNode(rhs, compareNode);
+ }
public ArrayAnyComparisonNode wrapInAny(CompareOp op, ParseNode lhs, ParseNode rhs) {
return new ArrayAnyComparisonNode(rhs, comparison(op, lhs, elementRef(Arrays.<ParseNode>asList(rhs, literal(1)))));
@@ -598,8 +606,14 @@ public class ParseNodeFactory {
statement.getBindCount(), statement.isAggregate(), statement.hasSequence());
}
- public SubqueryParseNode subquery(SelectStatement select) {
- return new SubqueryParseNode(select);
+ public SelectStatement select(SelectStatement statement, LimitNode limit) {
+ return select(statement.getFrom(), statement.getHint(), statement.isDistinct(), statement.getSelect(),
+ statement.getWhere(), statement.getGroupBy(), statement.getHaving(), statement.getOrderBy(), limit,
+ statement.getBindCount(), statement.isAggregate(), statement.hasSequence());
+ }
+
+ public SubqueryParseNode subquery(SelectStatement select, boolean expectSingleRow) {
+ return new SubqueryParseNode(select, expectSingleRow);
}
public LimitNode limit(BindParseNode b) {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeRewriter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeRewriter.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeRewriter.java
index 34d22d6..412fde0 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeRewriter.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeRewriter.java
@@ -348,6 +348,17 @@ public class ParseNodeRewriter extends TraverseAllParseNodeVisitor<ParseNode> {
}
@Override
+ public ParseNode visitLeave(final InParseNode node, List<ParseNode> nodes) throws SQLException {
+ ParseNode normNode = leaveCompoundNode(node, nodes, new CompoundNodeFactory() {
+ @Override
+ public ParseNode createNode(List<ParseNode> children) {
+ return NODE_FACTORY.in(children.get(0), children.get(1), node.isNegate());
+ }
+ });
+ return normNode;
+ }
+
+ @Override
public ParseNode visitLeave(final IsNullParseNode node, List<ParseNode> nodes) throws SQLException {
return leaveCompoundNode(node, nodes, new CompoundNodeFactory() {
@Override
@@ -429,6 +440,11 @@ public class ParseNodeRewriter extends TraverseAllParseNodeVisitor<ParseNode> {
}
@Override
+ public ParseNode visit(SubqueryParseNode node) throws SQLException {
+ return node;
+ }
+
+ @Override
public List<ParseNode> newElementList(int size) {
nodeCount += size;
return new ArrayList<ParseNode>(size);
@@ -546,13 +562,25 @@ public class ParseNodeRewriter extends TraverseAllParseNodeVisitor<ParseNode> {
}
@Override
- public ParseNode visitLeave(ArrayAnyComparisonNode node, List<ParseNode> l) throws SQLException {
- return node;
+ public ParseNode visitLeave(ArrayAnyComparisonNode node, final List<ParseNode> nodes) throws SQLException {
+ ParseNode normNode = leaveCompoundNode(node, nodes, new CompoundNodeFactory() {
+ @Override
+ public ParseNode createNode(List<ParseNode> children) {
+ return NODE_FACTORY.arrayAny(nodes.get(0), (ComparisonParseNode) nodes.get(1));
+ }
+ });
+ return normNode;
}
@Override
- public ParseNode visitLeave(ArrayAllComparisonNode node, List<ParseNode> l) throws SQLException {
- return node;
+ public ParseNode visitLeave(ArrayAllComparisonNode node, final List<ParseNode> nodes) throws SQLException {
+ ParseNode normNode = leaveCompoundNode(node, nodes, new CompoundNodeFactory() {
+ @Override
+ public ParseNode createNode(List<ParseNode> children) {
+ return NODE_FACTORY.arrayAll(nodes.get(0), (ComparisonParseNode) nodes.get(1));
+ }
+ });
+ return normNode;
}
@Override
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeVisitor.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeVisitor.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeVisitor.java
index 5308677..01925ff 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeVisitor.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/ParseNodeVisitor.java
@@ -18,7 +18,6 @@
package org.apache.phoenix.parse;
import java.sql.SQLException;
-import java.sql.SQLFeatureNotSupportedException;
import java.util.List;
@@ -82,6 +81,9 @@ public interface ParseNodeVisitor<E> {
public boolean visitEnter(InListParseNode node) throws SQLException;
public E visitLeave(InListParseNode node, List<E> l) throws SQLException;
+ public boolean visitEnter(InParseNode node) throws SQLException;
+ public E visitLeave(InParseNode node, List<E> l) throws SQLException;
+
public boolean visitEnter(IsNullParseNode node) throws SQLException;
public E visitLeave(IsNullParseNode node, List<E> l) throws SQLException;
@@ -90,7 +92,8 @@ public interface ParseNodeVisitor<E> {
public E visit(BindParseNode node) throws SQLException;
public E visit(WildcardParseNode node) throws SQLException;
public E visit(TableWildcardParseNode node) throws SQLException;
- public E visit(FamilyWildcardParseNode node) throws SQLException;
+ public E visit(FamilyWildcardParseNode node) throws SQLException;
+ public E visit(SubqueryParseNode node) throws SQLException;
public E visit(ParseNode node) throws SQLException;
public boolean visitEnter(StringConcatParseNode node) throws SQLException;
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/java/org/apache/phoenix/parse/SelectStatementRewriter.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/SelectStatementRewriter.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/SelectStatementRewriter.java
index 194f3bc..ab06d46 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/SelectStatementRewriter.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/SelectStatementRewriter.java
@@ -183,4 +183,17 @@ public class SelectStatementRewriter extends ParseNodeRewriter {
public ParseNode visitLeave(InListParseNode node, List<ParseNode> c) throws SQLException {
return c.isEmpty() ? null : node;
}
+
+ @Override
+ public boolean visitEnter(InParseNode node) throws SQLException {
+ if (removeNodes.contains(node)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public ParseNode visitLeave(InParseNode node, List<ParseNode> c) throws SQLException {
+ return c.isEmpty() ? null : node;
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/java/org/apache/phoenix/parse/StatelessTraverseAllParseNodeVisitor.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/StatelessTraverseAllParseNodeVisitor.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/StatelessTraverseAllParseNodeVisitor.java
index 0be5e01..5e9f727 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/StatelessTraverseAllParseNodeVisitor.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/StatelessTraverseAllParseNodeVisitor.java
@@ -91,6 +91,11 @@ public class StatelessTraverseAllParseNodeVisitor extends TraverseAllParseNodeVi
public Void visitLeave(InListParseNode node, List<Void> l) throws SQLException {
return null;
}
+
+ @Override
+ public Void visitLeave(InParseNode node, List<Void> l) throws SQLException {
+ return null;
+ }
@Override
public Void visitLeave(StringConcatParseNode node, List<Void> l) throws SQLException {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/java/org/apache/phoenix/parse/SubqueryParseNode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/SubqueryParseNode.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/SubqueryParseNode.java
index a3bad0d..92c5284 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/SubqueryParseNode.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/SubqueryParseNode.java
@@ -30,14 +30,20 @@ import java.sql.SQLException;
*/
public class SubqueryParseNode extends TerminalParseNode {
private final SelectStatement select;
+ private final boolean expectSingleRow;
- SubqueryParseNode(SelectStatement select) {
+ SubqueryParseNode(SelectStatement select, boolean expectSingleRow) {
this.select = select;
+ this.expectSingleRow = expectSingleRow;
}
public SelectStatement getSelectNode() {
return select;
}
+
+ public boolean expectSingleRow() {
+ return expectSingleRow;
+ }
@Override
public <T> T accept(ParseNodeVisitor<T> visitor) throws SQLException {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/java/org/apache/phoenix/parse/TraverseAllParseNodeVisitor.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/TraverseAllParseNodeVisitor.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/TraverseAllParseNodeVisitor.java
index af20278..d6b444f 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/TraverseAllParseNodeVisitor.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/TraverseAllParseNodeVisitor.java
@@ -75,6 +75,11 @@ public abstract class TraverseAllParseNodeVisitor<T> extends BaseParseNodeVisito
}
@Override
+ public boolean visitEnter(InParseNode node) throws SQLException {
+ return true;
+ }
+
+ @Override
public boolean visitEnter(IsNullParseNode node) throws SQLException {
return true;
}
@@ -143,6 +148,11 @@ public abstract class TraverseAllParseNodeVisitor<T> extends BaseParseNodeVisito
public T visit(FamilyWildcardParseNode node) throws SQLException {
return null;
}
+
+ @Override
+ public T visit(SubqueryParseNode node) throws SQLException {
+ return null;
+ }
@Override
public boolean visitEnter(StringConcatParseNode node) throws SQLException {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/java/org/apache/phoenix/parse/TraverseNoParseNodeVisitor.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/parse/TraverseNoParseNodeVisitor.java b/phoenix-core/src/main/java/org/apache/phoenix/parse/TraverseNoParseNodeVisitor.java
index 4c0fbea..37be462 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/parse/TraverseNoParseNodeVisitor.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/parse/TraverseNoParseNodeVisitor.java
@@ -100,6 +100,16 @@ public abstract class TraverseNoParseNodeVisitor<T> extends BaseParseNodeVisitor
}
@Override
+ public boolean visitEnter(InParseNode node) throws SQLException {
+ return false;
+ }
+
+ @Override
+ public T visitLeave(InParseNode node, List<T> l) throws SQLException {
+ return null;
+ }
+
+ @Override
public boolean visitEnter(IsNullParseNode node) throws SQLException {
return false;
}
@@ -138,6 +148,11 @@ public abstract class TraverseNoParseNodeVisitor<T> extends BaseParseNodeVisitor
public T visit(FamilyWildcardParseNode node) throws SQLException {
return null;
}
+
+ @Override
+ public T visit(SubqueryParseNode node) throws SQLException {
+ return null;
+ }
@Override
public T visitLeave(AndParseNode node, List<T> l) throws SQLException {
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/test/java/org/apache/phoenix/compile/JoinQueryCompilerTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/compile/JoinQueryCompilerTest.java b/phoenix-core/src/test/java/org/apache/phoenix/compile/JoinQueryCompilerTest.java
index 95c869a..a08b0e3 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/compile/JoinQueryCompilerTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/compile/JoinQueryCompilerTest.java
@@ -59,10 +59,10 @@ public class JoinQueryCompilerTest extends BaseConnectionlessQueryTest {
assertEquals(
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
- " PARALLEL EQUI-JOIN 2 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 2 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_CUSTOMER_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY NAME LIKE 'C%'\n" +
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
index 100b4ad..c7a7c3e 100644
--- a/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
+++ b/phoenix-core/src/test/java/org/apache/phoenix/query/BaseTest.java
@@ -406,33 +406,33 @@ public abstract class BaseTest {
builder.put("SumDoubleTest","create table SumDoubleTest" +
" (id varchar not null primary key, d DOUBLE, f FLOAT, ud UNSIGNED_DOUBLE, uf UNSIGNED_FLOAT, i integer, de decimal)");
builder.put(JOIN_ORDER_TABLE_FULL_NAME, "create table " + JOIN_ORDER_TABLE_FULL_NAME +
- " (\"order_id\" char(15) not null primary key, " +
- " \"customer_id\" char(10), " +
- " \"item_id\" char(10), " +
+ " (\"order_id\" varchar(15) not null primary key, " +
+ " \"customer_id\" varchar(10), " +
+ " \"item_id\" varchar(10), " +
" price integer, " +
" quantity integer, " +
" date timestamp)");
builder.put(JOIN_CUSTOMER_TABLE_FULL_NAME, "create table " + JOIN_CUSTOMER_TABLE_FULL_NAME +
- " (\"customer_id\" char(10) not null primary key, " +
+ " (\"customer_id\" varchar(10) not null primary key, " +
" name varchar, " +
- " phone char(12), " +
+ " phone varchar(12), " +
" address varchar, " +
- " loc_id char(5), " +
+ " loc_id varchar(5), " +
" date date)");
builder.put(JOIN_ITEM_TABLE_FULL_NAME, "create table " + JOIN_ITEM_TABLE_FULL_NAME +
- " (\"item_id\" char(10) not null primary key, " +
+ " (\"item_id\" varchar(10) not null primary key, " +
" name varchar, " +
" price integer, " +
" discount1 integer, " +
" discount2 integer, " +
- " \"supplier_id\" char(10), " +
+ " \"supplier_id\" varchar(10), " +
" description varchar)");
builder.put(JOIN_SUPPLIER_TABLE_FULL_NAME, "create table " + JOIN_SUPPLIER_TABLE_FULL_NAME +
- " (\"supplier_id\" char(10) not null primary key, " +
+ " (\"supplier_id\" varchar(10) not null primary key, " +
" name varchar, " +
- " phone char(12), " +
+ " phone varchar(12), " +
" address varchar, " +
- " loc_id char(5))");
+ " loc_id varchar(5))");
tableDDLMap = builder.build();
}
[2/2] git commit: PHOENIX-1168 Support non-correlated sub-queries in
where clause having a comparison operator with no modifier or a comparison
operator modified by ANY, SOME or ALL
Posted by ma...@apache.org.
PHOENIX-1168 Support non-correlated sub-queries in where clause having a comparison operator with no modifier or a comparison operator modified by ANY, SOME or ALL
Project: http://git-wip-us.apache.org/repos/asf/phoenix/repo
Commit: http://git-wip-us.apache.org/repos/asf/phoenix/commit/a0694b77
Tree: http://git-wip-us.apache.org/repos/asf/phoenix/tree/a0694b77
Diff: http://git-wip-us.apache.org/repos/asf/phoenix/diff/a0694b77
Branch: refs/heads/master
Commit: a0694b77c1e16c90af96d3092b1f941052493244
Parents: ea5a797
Author: maryannxue <ma...@apache.org>
Authored: Thu Sep 25 12:30:03 2014 -0400
Committer: maryannxue <ma...@apache.org>
Committed: Thu Sep 25 12:30:03 2014 -0400
----------------------------------------------------------------------
.../org/apache/phoenix/end2end/HashJoinIT.java | 322 +++++++++++++-----
phoenix-core/src/main/antlr3/PhoenixSQL.g | 4 +-
.../phoenix/compile/ExpressionCompiler.java | 37 ++
.../apache/phoenix/compile/JoinCompiler.java | 7 +
.../apache/phoenix/compile/QueryCompiler.java | 57 ++--
.../phoenix/compile/StatementContext.java | 15 +
.../phoenix/compile/StatementNormalizer.java | 13 +
.../apache/phoenix/compile/WhereCompiler.java | 46 ++-
.../phoenix/exception/SQLExceptionCode.java | 1 +
.../apache/phoenix/execute/BaseQueryPlan.java | 2 +-
.../apache/phoenix/execute/HashJoinPlan.java | 334 +++++++++++++------
.../expression/ComparisonExpression.java | 3 +-
.../apache/phoenix/parse/ParseNodeFactory.java | 18 +-
.../apache/phoenix/parse/ParseNodeRewriter.java | 36 +-
.../apache/phoenix/parse/ParseNodeVisitor.java | 7 +-
.../phoenix/parse/SelectStatementRewriter.java | 13 +
.../StatelessTraverseAllParseNodeVisitor.java | 5 +
.../apache/phoenix/parse/SubqueryParseNode.java | 8 +-
.../parse/TraverseAllParseNodeVisitor.java | 10 +
.../parse/TraverseNoParseNodeVisitor.java | 15 +
.../phoenix/compile/JoinQueryCompilerTest.java | 4 +-
.../java/org/apache/phoenix/query/BaseTest.java | 22 +-
22 files changed, 738 insertions(+), 241 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java b/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
index dcd96d3..ceba009 100644
--- a/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
+++ b/phoenix-core/src/it/java/org/apache/phoenix/end2end/HashJoinIT.java
@@ -119,7 +119,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO DISTINCT ROWS BY [I.NAME]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [I.NAME]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME,
/*
@@ -132,7 +132,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO DISTINCT ROWS BY [I.item_id]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [SUM(O.QUANTITY) DESC]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY FIRST KEY ONLY",
@@ -147,7 +147,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [I.item_id]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [SUM(O.QUANTITY) DESC NULLS LAST, I.item_id]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME,
/*
@@ -160,7 +160,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO DISTINCT ROWS BY [I.NAME]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [I.NAME]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME,
/*
@@ -174,7 +174,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [I.item_id]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [SUM(O.QUANTITY) DESC NULLS LAST, I.item_id]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME,
/*
@@ -184,7 +184,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
* ORDER BY item_id
*/
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME,
/*
@@ -197,7 +197,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
*/
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY (NAME >= 'T1' AND NAME <= 'T5')\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY (NAME >= 'S1' AND NAME <= 'S5')",
@@ -211,7 +211,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
*/
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY (NAME = 'T1' OR NAME = 'T5')\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY (NAME = 'S1' OR NAME = 'S5')",
@@ -222,7 +222,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
* JOIN joinSupplierTable s ON i.supplier_id = s.supplier_id
*/
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
- " PARALLEL EQUI-JOIN 2 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 2 TABLES:\n" +
" BUILD HASH TABLE 0 (SKIP MERGE)\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY QUANTITY < 5000\n" +
@@ -236,7 +236,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
* ORDER BY i1.item_id
*/
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
@@ -250,7 +250,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" SERVER SORTED BY [I1.NAME, I2.NAME]\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" DYNAMIC SERVER FILTER BY item_id BETWEEN MIN/MAX OF (I2.supplier_id)",
@@ -263,7 +263,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
* ORDER BY order_id
*/
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
- " PARALLEL EQUI-JOIN 2 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 2 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_CUSTOMER_TABLE_DISPLAY_NAME + "\n" +
" BUILD HASH TABLE 1\n" +
@@ -279,10 +279,10 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" SERVER SORTED BY [O.order_id]\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_CUSTOMER_TABLE_DISPLAY_NAME + "\n" +
" DYNAMIC SERVER FILTER BY item_id BETWEEN MIN/MAX OF (O.item_id)",
@@ -302,15 +302,15 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
"CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + JOIN_CUSTOMER_TABLE_DISPLAY_NAME + " [*] - ['0000000005']\n" +
" SERVER SORTED BY [C.customer_id, I.NAME]\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY order_id != '000000000000003'\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY NAME != 'T3'\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
" DYNAMIC SERVER FILTER BY customer_id IN (O.customer_id)",
@@ -325,7 +325,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO DISTINCT ROWS BY [I.NAME]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [I.NAME]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME,
/*
@@ -340,7 +340,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO DISTINCT ROWS BY [O.IID]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [SUM(O.QUANTITY) DESC]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0 (SKIP MERGE)\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY FIRST KEY ONLY",
@@ -356,7 +356,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER FILTER BY FIRST KEY ONLY\n" +
" SERVER SORTED BY [O.Q DESC NULLS LAST, I.IID]\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY [item_id]\n" +
@@ -373,7 +373,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER FILTER BY FIRST KEY ONLY\n" +
" SERVER SORTED BY [O.Q DESC, I.IID]\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY [item_id]\n" +
@@ -400,15 +400,15 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
"CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + JOIN_CUSTOMER_TABLE_DISPLAY_NAME + " [*] - ['0000000005']\n" +
" SERVER SORTED BY [C.CID, QO.INAME]\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY order_id != '000000000000003'\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY NAME != 'T3'\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME,
/*
@@ -422,7 +422,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER FILTER BY PageFilter 4\n" +
" SERVER 4 ROW LIMIT\n" +
"CLIENT 4 ROW LIMIT\n" +
- " PARALLEL EQUI-JOIN 2 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 2 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" BUILD HASH TABLE 1(DELAYED EVALUATION)\n" +
@@ -437,7 +437,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
*/
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
"CLIENT 4 ROW LIMIT\n" +
- " PARALLEL EQUI-JOIN 2 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 2 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
" BUILD HASH TABLE 1(DELAYED EVALUATION)\n" +
@@ -452,7 +452,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
*/
"CLIENT PARALLEL 4-WAY FULL SCAN OVER TEMP_TABLE_COMPOSITE_PK\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 4-WAY FULL SCAN OVER TEMP_TABLE_COMPOSITE_PK\n" +
" CLIENT MERGE SORT",
@@ -464,7 +464,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
*/
"CLIENT PARALLEL 4-WAY FULL SCAN OVER TEMP_TABLE_COMPOSITE_PK\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 4-WAY FULL SCAN OVER TEMP_TABLE_COMPOSITE_PK\n" +
" CLIENT MERGE SORT\n" +
@@ -477,7 +477,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
*/
"CLIENT PARALLEL 4-WAY FULL SCAN OVER TEMP_TABLE_COMPOSITE_PK\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 4-WAY FULL SCAN OVER TEMP_TABLE_COMPOSITE_PK\n" +
" CLIENT MERGE SORT\n" +
@@ -499,7 +499,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO DISTINCT ROWS BY [I.0:NAME]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [I.0:NAME]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SCHEMA + ".idx_item\n" +
" SERVER FILTER BY FIRST KEY ONLY",
@@ -513,7 +513,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO DISTINCT ROWS BY [I.:item_id]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [SUM(O.QUANTITY) DESC]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SCHEMA + ".idx_item\n" +
" SERVER FILTER BY FIRST KEY ONLY",
@@ -528,7 +528,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [I.item_id]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [SUM(O.QUANTITY) DESC NULLS LAST, I.item_id]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME,
/*
@@ -541,7 +541,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER FILTER BY FIRST KEY ONLY\n" +
" SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [I.0:NAME]\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME,
/*
@@ -555,7 +555,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [I.item_id]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [SUM(O.QUANTITY) DESC NULLS LAST, I.item_id]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME,
/*
@@ -565,7 +565,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
* ORDER BY item_id
*/
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME,
/*
@@ -578,7 +578,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
*/
"CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + JOIN_SCHEMA + ".idx_item ['T1'] - ['T5']\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + JOIN_SCHEMA + ".idx_supplier ['S1'] - ['S5']",
/*
@@ -590,7 +590,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
* AND (supp.name = 'S1' OR supp.name = 'S5')
*/
"CLIENT PARALLEL 1-WAY SKIP SCAN ON 2 KEYS OVER " + JOIN_SCHEMA + ".idx_item ['T1'] - ['T5']\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY SKIP SCAN ON 2 KEYS OVER " + JOIN_SCHEMA + ".idx_supplier ['S1'] - ['S5']",
/*
@@ -600,7 +600,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
* JOIN joinSupplierTable s ON i.supplier_id = s.supplier_id
*/
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SCHEMA + ".idx_item\n" +
- " PARALLEL EQUI-JOIN 2 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 2 TABLES:\n" +
" BUILD HASH TABLE 0 (SKIP MERGE)\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY QUANTITY < 5000\n" +
@@ -613,7 +613,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
* ORDER BY i1.item_id
*/
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SCHEMA + ".idx_item\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
@@ -628,7 +628,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER FILTER BY FIRST KEY ONLY\n" +
" SERVER SORTED BY [I1.0:NAME, I2.0:NAME]\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SCHEMA + ".idx_item",
/*
@@ -640,7 +640,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
* ORDER BY order_id
*/
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
- " PARALLEL EQUI-JOIN 2 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 2 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SCHEMA + ".idx_customer\n" +
" BUILD HASH TABLE 1\n" +
@@ -658,10 +658,10 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER FILTER BY FIRST KEY ONLY\n" +
" SERVER SORTED BY [O.order_id]\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SCHEMA + ".idx_customer",
/*
@@ -680,15 +680,15 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
"CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + JOIN_CUSTOMER_TABLE_DISPLAY_NAME + " [*] - ['0000000005']\n" +
" SERVER SORTED BY [C.customer_id, I.0:NAME]\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY order_id != '000000000000003'\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SCHEMA + ".idx_item\n" +
" SERVER FILTER BY NAME != 'T3'\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
" DYNAMIC SERVER FILTER BY customer_id IN (O.customer_id)",
@@ -703,7 +703,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO DISTINCT ROWS BY [I.NAME]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [I.NAME]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SCHEMA + ".idx_item\n" +
" SERVER FILTER BY FIRST KEY ONLY",
@@ -719,7 +719,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO DISTINCT ROWS BY [O.IID]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [SUM(O.QUANTITY) DESC]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0 (SKIP MERGE)\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SCHEMA + ".idx_item\n" +
" SERVER FILTER BY FIRST KEY ONLY",
@@ -735,7 +735,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER FILTER BY FIRST KEY ONLY\n" +
" SERVER SORTED BY [O.Q DESC NULLS LAST, I.IID]\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY [item_id]\n" +
@@ -752,7 +752,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER FILTER BY FIRST KEY ONLY\n" +
" SERVER SORTED BY [O.Q DESC, I.IID]\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY [item_id]\n" +
@@ -779,15 +779,15 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
"CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + JOIN_CUSTOMER_TABLE_DISPLAY_NAME + " [*] - ['0000000005']\n" +
" SERVER SORTED BY [C.CID, QO.INAME]\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY order_id != '000000000000003'\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SCHEMA + ".idx_item\n" +
" SERVER FILTER BY NAME != 'T3'\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME,
/*
@@ -801,7 +801,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER FILTER BY PageFilter 4\n" +
" SERVER 4 ROW LIMIT\n" +
"CLIENT 4 ROW LIMIT\n" +
- " PARALLEL EQUI-JOIN 2 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 2 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_SCHEMA + ".idx_item\n" +
" BUILD HASH TABLE 1(DELAYED EVALUATION)\n" +
@@ -816,7 +816,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
*/
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
"CLIENT 4 ROW LIMIT\n" +
- " PARALLEL EQUI-JOIN 2 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 2 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER "+ JOIN_SCHEMA + ".idx_item\n" +
" BUILD HASH TABLE 1(DELAYED EVALUATION)\n" +
@@ -831,7 +831,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
*/
"CLIENT PARALLEL 4-WAY FULL SCAN OVER TEMP_TABLE_COMPOSITE_PK\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 4-WAY FULL SCAN OVER TEMP_TABLE_COMPOSITE_PK\n" +
" CLIENT MERGE SORT",
@@ -843,7 +843,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
*/
"CLIENT PARALLEL 4-WAY FULL SCAN OVER TEMP_TABLE_COMPOSITE_PK\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 4-WAY FULL SCAN OVER TEMP_TABLE_COMPOSITE_PK\n" +
" CLIENT MERGE SORT\n" +
@@ -856,7 +856,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
*/
"CLIENT PARALLEL 4-WAY FULL SCAN OVER TEMP_TABLE_COMPOSITE_PK\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 4-WAY FULL SCAN OVER TEMP_TABLE_COMPOSITE_PK\n" +
" CLIENT MERGE SORT\n" +
@@ -878,7 +878,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO DISTINCT ROWS BY [I.0:NAME]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [I.0:NAME]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + "" + JOIN_ITEM_TABLE_DISPLAY_NAME +" [-32768]\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
@@ -893,7 +893,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO DISTINCT ROWS BY [I.:item_id]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [SUM(O.QUANTITY) DESC]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + "" + JOIN_ITEM_TABLE_DISPLAY_NAME +" [-32768]\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
@@ -909,7 +909,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [I.item_id]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [SUM(O.QUANTITY) DESC NULLS LAST, I.item_id]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME,
/*
@@ -923,7 +923,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO DISTINCT ROWS BY [I.0:NAME]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [I.0:NAME]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME,
/*
@@ -937,7 +937,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO ORDERED DISTINCT ROWS BY [I.item_id]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [SUM(O.QUANTITY) DESC NULLS LAST, I.item_id]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME,
/*
@@ -947,7 +947,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
* ORDER BY item_id
*/
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME,
/*
@@ -961,7 +961,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
"CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + "" + JOIN_ITEM_TABLE_DISPLAY_NAME + " [-32768,'T1'] - [-32768,'T5']\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + "" + JOIN_SUPPLIER_TABLE_DISPLAY_NAME +" [-32768,'S1'] - [-32768,'S5']\n" +
" CLIENT MERGE SORT",
@@ -975,7 +975,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
*/
"CLIENT PARALLEL 1-WAY SKIP SCAN ON 2 KEYS OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + "" + JOIN_ITEM_TABLE_DISPLAY_NAME + " [-32768,'T1'] - [-32768,'T5']\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY SKIP SCAN ON 2 KEYS OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + "" + JOIN_SUPPLIER_TABLE_DISPLAY_NAME +" [-32768,'S1'] - [-32768,'S5']\n" +
" CLIENT MERGE SORT",
@@ -987,7 +987,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
*/
"CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + "" + JOIN_ITEM_TABLE_DISPLAY_NAME + " [-32768]\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 2 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 2 TABLES:\n" +
" BUILD HASH TABLE 0 (SKIP MERGE)\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY QUANTITY < 5000\n" +
@@ -1002,7 +1002,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
* ORDER BY i1.item_id
*/
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ITEM_TABLE_DISPLAY_NAME + "\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER "+ MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX +""+ JOIN_ITEM_TABLE_DISPLAY_NAME +" [-32768]\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
@@ -1018,7 +1018,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER FILTER BY FIRST KEY ONLY\n" +
" SERVER SORTED BY [I1.0:NAME, I2.0:NAME]\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX +""+ JOIN_ITEM_TABLE_DISPLAY_NAME +" [-32768]\n" +
" CLIENT MERGE SORT\n" +
@@ -1032,7 +1032,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
* ORDER BY order_id
*/
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
- " PARALLEL EQUI-JOIN 2 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 2 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + "" + JOIN_CUSTOMER_TABLE_DISPLAY_NAME + " [-32768]\n" +
" CLIENT MERGE SORT\n" +
@@ -1052,10 +1052,10 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER FILTER BY FIRST KEY ONLY\n" +
" SERVER SORTED BY [O.order_id]\n"+
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX + "" + JOIN_CUSTOMER_TABLE_DISPLAY_NAME+" [-32768]\n"+
" CLIENT MERGE SORT\n" +
@@ -1076,16 +1076,16 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
"CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + JOIN_CUSTOMER_TABLE_DISPLAY_NAME + " [*] - ['0000000005']\n" +
" SERVER SORTED BY [C.customer_id, I.0:NAME]\n"+
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY order_id != '000000000000003'\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX +""+ JOIN_ITEM_TABLE_DISPLAY_NAME +" [-32768]\n" +
" SERVER FILTER BY NAME != 'T3'\n" +
" CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
" DYNAMIC SERVER FILTER BY customer_id IN (O.customer_id)",
@@ -1100,7 +1100,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO DISTINCT ROWS BY [I.NAME]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [I.NAME]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX +""+JOIN_ITEM_TABLE_DISPLAY_NAME+" [-32768]\n"+
" SERVER FILTER BY FIRST KEY ONLY\n" +
@@ -1117,7 +1117,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER AGGREGATE INTO DISTINCT ROWS BY [O.IID]\n" +
"CLIENT MERGE SORT\n" +
"CLIENT SORTED BY [SUM(O.QUANTITY) DESC]\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0 (SKIP MERGE)\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX +""+JOIN_ITEM_TABLE_DISPLAY_NAME + " [-32768]\n" +
" SERVER FILTER BY FIRST KEY ONLY\n" +
@@ -1134,7 +1134,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER FILTER BY FIRST KEY ONLY\n" +
" SERVER SORTED BY [O.Q DESC NULLS LAST, I.IID]\n"+
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY [item_id]\n" +
@@ -1151,7 +1151,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER FILTER BY FIRST KEY ONLY\n" +
" SERVER SORTED BY [O.Q DESC, I.IID]\n"+
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER AGGREGATE INTO DISTINCT ROWS BY [item_id]\n" +
@@ -1178,16 +1178,16 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
"CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + JOIN_CUSTOMER_TABLE_DISPLAY_NAME + " [*] - ['0000000005']\n" +
" SERVER SORTED BY [C.CID, QO.INAME]\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_ORDER_TABLE_DISPLAY_NAME + "\n" +
" SERVER FILTER BY order_id != '000000000000003'\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER " + MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX +""+JOIN_ITEM_TABLE_DISPLAY_NAME + " [-32768]\n" +
" SERVER FILTER BY NAME != 'T3'\n" +
" CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME,
/*
@@ -1201,7 +1201,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
" SERVER FILTER BY PageFilter 4\n" +
" SERVER 4 ROW LIMIT\n" +
"CLIENT 4 ROW LIMIT\n" +
- " PARALLEL EQUI-JOIN 2 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 2 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER "+ MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX +""+JOIN_ITEM_TABLE_DISPLAY_NAME + " [-32768]\n" +
" CLIENT MERGE SORT\n" +
@@ -1217,7 +1217,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
*/
"CLIENT PARALLEL 1-WAY FULL SCAN OVER " + JOIN_SUPPLIER_TABLE_DISPLAY_NAME + "\n" +
"CLIENT 4 ROW LIMIT\n" +
- " PARALLEL EQUI-JOIN 2 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 2 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 1-WAY RANGE SCAN OVER "+ MetaDataUtil.LOCAL_INDEX_TABLE_PREFIX +""+JOIN_ITEM_TABLE_DISPLAY_NAME + " [-32768]\n" +
" CLIENT MERGE SORT\n" +
@@ -1233,7 +1233,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
*/
"CLIENT PARALLEL 4-WAY FULL SCAN OVER TEMP_TABLE_COMPOSITE_PK\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 4-WAY FULL SCAN OVER TEMP_TABLE_COMPOSITE_PK\n" +
" CLIENT MERGE SORT",
@@ -1245,7 +1245,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
*/
"CLIENT PARALLEL 4-WAY FULL SCAN OVER TEMP_TABLE_COMPOSITE_PK\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 4-WAY FULL SCAN OVER TEMP_TABLE_COMPOSITE_PK\n" +
" CLIENT MERGE SORT\n" +
@@ -1258,7 +1258,7 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
*/
"CLIENT PARALLEL 4-WAY FULL SCAN OVER TEMP_TABLE_COMPOSITE_PK\n" +
"CLIENT MERGE SORT\n" +
- " PARALLEL EQUI-JOIN 1 HASH TABLES:\n" +
+ " PARALLEL EQUI/SEMI/ANTI-JOIN 1 TABLES:\n" +
" BUILD HASH TABLE 0\n" +
" CLIENT PARALLEL 4-WAY FULL SCAN OVER TEMP_TABLE_COMPOSITE_PK\n" +
" CLIENT MERGE SORT\n" +
@@ -3883,5 +3883,153 @@ public class HashJoinIT extends BaseHBaseManagedTimeIT {
}
}
+ @Test
+ public void testNonCorrelatedSubquery() throws Exception {
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ Connection conn = DriverManager.getConnection(getUrl(), props);
+ try {
+ String query = "SELECT \"item_id\", name FROM " + JOIN_ITEM_TABLE_FULL_NAME + " WHERE \"item_id\" NOT IN (SELECT \"item_id\" FROM " + JOIN_ORDER_TABLE_FULL_NAME + ") ORDER BY \"item_id\"";
+ PreparedStatement statement = conn.prepareStatement(query);
+ ResultSet rs = statement.executeQuery();
+ assertTrue (rs.next());
+ assertEquals(rs.getString(1), "0000000004");
+ assertEquals(rs.getString(2), "T4");
+ assertTrue (rs.next());
+ assertEquals(rs.getString(1), "0000000005");
+ assertEquals(rs.getString(2), "T5");
+ assertTrue (rs.next());
+ assertEquals(rs.getString(1), "invalid001");
+ assertEquals(rs.getString(2), "INVALID-1");
+
+ assertFalse(rs.next());
+
+ query = "SELECT \"item_id\", name FROM " + JOIN_ITEM_TABLE_FULL_NAME + " WHERE \"item_id\" >= ALL (SELECT \"item_id\" FROM " + JOIN_ORDER_TABLE_FULL_NAME + ") ORDER BY \"item_id\"";
+ statement = conn.prepareStatement(query);
+ rs = statement.executeQuery();
+ assertTrue (rs.next());
+ assertEquals(rs.getString(1), "0000000006");
+ assertEquals(rs.getString(2), "T6");
+ assertTrue (rs.next());
+ assertEquals(rs.getString(1), "invalid001");
+ assertEquals(rs.getString(2), "INVALID-1");
+
+ assertFalse(rs.next());
+
+ query = "SELECT \"item_id\", name FROM " + JOIN_ITEM_TABLE_FULL_NAME + " WHERE \"item_id\" < ANY (SELECT \"item_id\" FROM " + JOIN_ORDER_TABLE_FULL_NAME + ")";
+ statement = conn.prepareStatement(query);
+ rs = statement.executeQuery();
+ assertTrue (rs.next());
+ assertEquals(rs.getString(1), "0000000001");
+ assertEquals(rs.getString(2), "T1");
+ assertTrue (rs.next());
+ assertEquals(rs.getString(1), "0000000002");
+ assertEquals(rs.getString(2), "T2");
+ assertTrue (rs.next());
+ assertEquals(rs.getString(1), "0000000003");
+ assertEquals(rs.getString(2), "T3");
+ assertTrue (rs.next());
+ assertEquals(rs.getString(1), "0000000004");
+ assertEquals(rs.getString(2), "T4");
+ assertTrue (rs.next());
+ assertEquals(rs.getString(1), "0000000005");
+ assertEquals(rs.getString(2), "T5");
+
+ assertFalse(rs.next());
+
+ query = "SELECT \"item_id\", name FROM " + JOIN_ITEM_TABLE_FULL_NAME + " WHERE \"item_id\" < (SELECT max(\"item_id\") FROM " + JOIN_ORDER_TABLE_FULL_NAME + ")";
+ statement = conn.prepareStatement(query);
+ rs = statement.executeQuery();
+ assertTrue (rs.next());
+ assertEquals(rs.getString(1), "0000000001");
+ assertEquals(rs.getString(2), "T1");
+ assertTrue (rs.next());
+ assertEquals(rs.getString(1), "0000000002");
+ assertEquals(rs.getString(2), "T2");
+ assertTrue (rs.next());
+ assertEquals(rs.getString(1), "0000000003");
+ assertEquals(rs.getString(2), "T3");
+ assertTrue (rs.next());
+ assertEquals(rs.getString(1), "0000000004");
+ assertEquals(rs.getString(2), "T4");
+ assertTrue (rs.next());
+ assertEquals(rs.getString(1), "0000000005");
+ assertEquals(rs.getString(2), "T5");
+
+ assertFalse(rs.next());
+ } finally {
+ conn.close();
+ }
+ }
+
+ @Test
+ public void testNonCorrelatedSubqueryWithRowConstructor() throws Exception {
+ String tempItemJoinTable = "TEMP_ITEM_JOIN_TABLE";
+ Properties props = PropertiesUtil.deepCopy(TEST_PROPERTIES);
+ Connection conn = DriverManager.getConnection(getUrl(), props);
+ try {
+ conn.createStatement().execute("CREATE TABLE " + tempItemJoinTable
+ + " (item_id varchar(10) NOT NULL, "
+ + " item_name varchar NOT NULL, "
+ + " co_item_id varchar(10), "
+ + " co_item_name varchar "
+ + " CONSTRAINT pk PRIMARY KEY (item_id, item_name)) "
+ + " SALT_BUCKETS=4");
+
+ PreparedStatement upsertStmt = conn.prepareStatement(
+ "upsert into " + tempItemJoinTable + "(item_id, item_name, co_item_id, co_item_name) " + "values (?, ?, ?, ?)");
+ upsertStmt.setString(1, "0000000001");
+ upsertStmt.setString(2, "T1");
+ upsertStmt.setString(3, "0000000002");
+ upsertStmt.setString(4, "T3");
+ upsertStmt.execute();
+ upsertStmt.setString(1, "0000000004");
+ upsertStmt.setString(2, "T4");
+ upsertStmt.setString(3, "0000000003");
+ upsertStmt.setString(4, "T3");
+ upsertStmt.execute();
+ upsertStmt.setString(1, "0000000003");
+ upsertStmt.setString(2, "T4");
+ upsertStmt.setString(3, "0000000005");
+ upsertStmt.setString(4, "T5");
+ upsertStmt.execute();
+ upsertStmt.setString(1, "0000000006");
+ upsertStmt.setString(2, "T6");
+ upsertStmt.setString(3, "0000000001");
+ upsertStmt.setString(4, "T1");
+ upsertStmt.execute();
+ conn.commit();
+
+ String query = "SELECT * FROM " + tempItemJoinTable + " WHERE (item_id, item_name) != ALL (SELECT \"item_id\", name FROM " + JOIN_ITEM_TABLE_FULL_NAME + ")";
+ PreparedStatement statement = conn.prepareStatement(query);
+ ResultSet rs = statement.executeQuery();
+ assertTrue (rs.next());
+ assertEquals(rs.getString(1), "0000000003");
+ assertEquals(rs.getString(2), "T4");
+ assertEquals(rs.getString(3), "0000000005");
+ assertEquals(rs.getString(4), "T5");
+
+ assertFalse(rs.next());
+
+ query = "SELECT * FROM " + tempItemJoinTable + " WHERE (item_id, item_name) IN (SELECT \"item_id\", name FROM " + JOIN_ITEM_TABLE_FULL_NAME + " WHERE \"item_id\" NOT IN (SELECT \"item_id\" FROM " + JOIN_ORDER_TABLE_FULL_NAME + "))"
+ + " OR (co_item_id, co_item_name) IN (SELECT \"item_id\", name FROM " + JOIN_ITEM_TABLE_FULL_NAME + " WHERE \"item_id\" IN (SELECT \"item_id\" FROM " + JOIN_ORDER_TABLE_FULL_NAME + "))";
+ statement = conn.prepareStatement(query);
+ rs = statement.executeQuery();
+ assertTrue (rs.next());
+ assertEquals(rs.getString(1), "0000000004");
+ assertEquals(rs.getString(2), "T4");
+ assertEquals(rs.getString(3), "0000000003");
+ assertEquals(rs.getString(4), "T3");
+ assertTrue (rs.next());
+ assertEquals(rs.getString(1), "0000000006");
+ assertEquals(rs.getString(2), "T6");
+ assertEquals(rs.getString(3), "0000000001");
+ assertEquals(rs.getString(4), "T1");
+
+ assertFalse(rs.next());
+ } finally {
+ conn.close();
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/antlr3/PhoenixSQL.g
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/antlr3/PhoenixSQL.g b/phoenix-core/src/main/antlr3/PhoenixSQL.g
index 8432f6e..893c3de 100644
--- a/phoenix-core/src/main/antlr3/PhoenixSQL.g
+++ b/phoenix-core/src/main/antlr3/PhoenixSQL.g
@@ -551,7 +551,7 @@ select_expression returns [SelectStatement ret]
;
subquery_expression returns [ParseNode ret]
- : s=select_expression {$ret = factory.subquery(s);}
+ : s=select_expression {$ret = factory.subquery(s, false);}
;
// Parse a full select expression structure.
@@ -713,7 +713,7 @@ comparison_op returns [CompareOp ret]
;
boolean_expression returns [ParseNode ret]
- : l=value_expression ((op=comparison_op (r=value_expression | ((all=ALL | any=ANY) LPAREN r=value_expression RPAREN)) {$ret = all != null ? factory.wrapInAll(op, l, r) : any != null ? factory.wrapInAny(op, l, r) : factory.comparison(op,l,r); } )
+ : l=value_expression ((op=comparison_op (r=value_expression | (LPAREN r=subquery_expression RPAREN) | ((all=ALL | any=ANY) LPAREN r=value_expression RPAREN) | ((all=ALL | any=ANY) LPAREN r=subquery_expression RPAREN)) {$ret = all != null ? factory.wrapInAll(op, l, r) : any != null ? factory.wrapInAny(op, l, r) : factory.comparison(op,l,r); } )
| (IS n=NOT? NULL {$ret = factory.isNull(l,n!=null); } )
| ( n=NOT? ((LIKE r=value_expression {$ret = factory.like(l,r,n!=null,LikeType.CASE_SENSITIVE); } )
| (ILIKE r=value_expression {$ret = factory.like(l,r,n!=null,LikeType.CASE_INSENSITIVE); } )
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
index cb3bc74..1511539 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/ExpressionCompiler.java
@@ -82,6 +82,7 @@ import org.apache.phoenix.parse.FunctionParseNode;
import org.apache.phoenix.parse.FunctionParseNode.BuiltInFunctionInfo;
import org.apache.phoenix.parse.LikeParseNode.LikeType;
import org.apache.phoenix.parse.InListParseNode;
+import org.apache.phoenix.parse.InParseNode;
import org.apache.phoenix.parse.IsNullParseNode;
import org.apache.phoenix.parse.LikeParseNode;
import org.apache.phoenix.parse.LiteralParseNode;
@@ -93,6 +94,7 @@ import org.apache.phoenix.parse.ParseNode;
import org.apache.phoenix.parse.RowValueConstructorParseNode;
import org.apache.phoenix.parse.SequenceValueParseNode;
import org.apache.phoenix.parse.StringConcatParseNode;
+import org.apache.phoenix.parse.SubqueryParseNode;
import org.apache.phoenix.parse.SubtractParseNode;
import org.apache.phoenix.parse.UnsupportedAllParseNodeVisitor;
import org.apache.phoenix.schema.ColumnFamilyNotFoundException;
@@ -107,6 +109,7 @@ import org.apache.phoenix.schema.PDatum;
import org.apache.phoenix.schema.PTable;
import org.apache.phoenix.schema.PTable.IndexType;
import org.apache.phoenix.schema.PTableType;
+import org.apache.phoenix.schema.PhoenixArray;
import org.apache.phoenix.schema.RowKeyValueAccessor;
import org.apache.phoenix.schema.SortOrder;
import org.apache.phoenix.schema.TableRef;
@@ -115,6 +118,8 @@ import org.apache.phoenix.util.ExpressionUtil;
import org.apache.phoenix.util.IndexUtil;
import org.apache.phoenix.util.SchemaUtil;
+import com.google.common.collect.Lists;
+
public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expression> {
private boolean isAggregate;
@@ -1239,4 +1244,36 @@ public class ExpressionCompiler extends UnsupportedAllParseNodeVisitor<Expressio
public boolean visitEnter(ArrayConstructorNode node) throws SQLException {
return true;
}
+
+ @Override
+ public boolean visitEnter(InParseNode node) throws SQLException {
+ return true;
+ }
+
+ @Override
+ public Expression visitLeave(InParseNode node, List<Expression> l)
+ throws SQLException {
+ Expression firstChild = l.get(0);
+ LiteralExpression secondChild = (LiteralExpression) l.get(1);
+ ImmutableBytesWritable ptr = context.getTempPtr();
+ ParseNode firstChildNode = node.getChildren().get(0);
+
+ if (firstChildNode instanceof BindParseNode) {
+ context.getBindManager().addParamMetaData((BindParseNode)firstChildNode, firstChild);
+ }
+
+ List<Expression> children = Lists.<Expression> newArrayList(firstChild);
+ PhoenixArray array = (PhoenixArray) secondChild.getValue();
+ PDataType type = PDataType.fromTypeId(array.getBaseType());
+ for (Object obj : (Object[]) array.getArray()) {
+ children.add(LiteralExpression.newConstant(obj, type));
+ }
+ return wrapGroupByExpression(InListExpression.create(children, node.isNegate(), ptr));
+ }
+
+ @Override
+ public Expression visit(SubqueryParseNode node) throws SQLException {
+ Object result = context.getSubqueryResult(node.getSelectNode());
+ return LiteralExpression.newConstant(result);
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
index 81d169c..41f58e0 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/JoinCompiler.java
@@ -56,6 +56,7 @@ import org.apache.phoenix.parse.FunctionParseNode;
import org.apache.phoenix.parse.HintNode;
import org.apache.phoenix.parse.HintNode.Hint;
import org.apache.phoenix.parse.InListParseNode;
+import org.apache.phoenix.parse.InParseNode;
import org.apache.phoenix.parse.IsNullParseNode;
import org.apache.phoenix.parse.JoinTableNode;
import org.apache.phoenix.parse.JoinTableNode.JoinType;
@@ -833,6 +834,12 @@ public class JoinCompiler {
List<Void> l) throws SQLException {
return leaveBooleanNode(node, l);
}
+
+ @Override
+ public Void visitLeave(InParseNode node,
+ List<Void> l) throws SQLException {
+ return leaveBooleanNode(node, l);
+ }
@Override
public Void visitLeave(IsNullParseNode node, List<Void> l)
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
index 6f9d688..1512d82 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/QueryCompiler.java
@@ -21,6 +21,7 @@ import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.Collections;
import java.util.List;
+import java.util.Set;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.util.Pair;
@@ -33,8 +34,9 @@ import org.apache.phoenix.compile.JoinCompiler.ProjectedPTableWrapper;
import org.apache.phoenix.compile.JoinCompiler.Table;
import org.apache.phoenix.compile.OrderByCompiler.OrderBy;
import org.apache.phoenix.execute.AggregatePlan;
-import org.apache.phoenix.execute.BaseQueryPlan;
import org.apache.phoenix.execute.HashJoinPlan;
+import org.apache.phoenix.execute.HashJoinPlan.HashSubPlan;
+import org.apache.phoenix.execute.HashJoinPlan.WhereClauseSubPlan;
import org.apache.phoenix.execute.ScanPlan;
import org.apache.phoenix.expression.Expression;
import org.apache.phoenix.expression.RowValueConstructorExpression;
@@ -50,6 +52,7 @@ import org.apache.phoenix.parse.JoinTableNode.JoinType;
import org.apache.phoenix.parse.ParseNode;
import org.apache.phoenix.parse.SQLParser;
import org.apache.phoenix.parse.SelectStatement;
+import org.apache.phoenix.parse.SubqueryParseNode;
import org.apache.phoenix.query.QueryConstants;
import org.apache.phoenix.schema.AmbiguousColumnException;
import org.apache.phoenix.schema.ColumnNotFoundException;
@@ -181,15 +184,10 @@ public class QueryCompiler {
int count = joinSpecs.size();
ImmutableBytesPtr[] joinIds = new ImmutableBytesPtr[count];
List<Expression>[] joinExpressions = new List[count];
- List<Expression>[] hashExpressions = new List[count];
- Expression[] keyRangeLhsExpressions = new Expression[count];
- Expression[] keyRangeRhsExpressions = new Expression[count];
- boolean[] hasFilters = new boolean[count];
JoinType[] joinTypes = new JoinType[count];
PTable[] tables = new PTable[count];
int[] fieldPositions = new int[count];
- QueryPlan[] joinPlans = new QueryPlan[count];
- TupleProjector[] clientProjectors = new TupleProjector[count];
+ HashSubPlan[] subPlans = new HashSubPlan[count];
fieldPositions[0] = projectedTable.getTable().getColumns().size() - projectedTable.getTable().getPKColumns().size();
boolean forceProjection = table.isSubselect();
boolean needsProject = forceProjection || asSubquery;
@@ -197,9 +195,9 @@ public class QueryCompiler {
JoinSpec joinSpec = joinSpecs.get(i);
Scan subScan = ScanUtil.newScan(originalScan);
StatementContext subContext = new StatementContext(statement, context.getResolver(), subScan, new SequenceManager(statement));
- joinPlans[i] = compileJoinQuery(subContext, binds, joinSpec.getJoinTable(), true);
+ QueryPlan joinPlan = compileJoinQuery(subContext, binds, joinSpec.getJoinTable(), true);
ColumnResolver resolver = subContext.getResolver();
- clientProjectors[i] = subContext.getClientTupleProjector();
+ TupleProjector clientProjector = subContext.getClientTupleProjector();
boolean hasPostReference = joinSpec.getJoinTable().hasPostReference();
if (hasPostReference) {
PTableWrapper subProjTable = ((JoinedTableColumnResolver) (resolver)).getPTableWrapper();
@@ -216,29 +214,30 @@ public class QueryCompiler {
joinIds[i] = new ImmutableBytesPtr(emptyByteArray); // place-holder
Pair<List<Expression>, List<Expression>> joinConditions = joinSpec.compileJoinConditions(context, leftResolver, resolver);
joinExpressions[i] = joinConditions.getFirst();
- hashExpressions[i] = joinConditions.getSecond();
- Pair<Expression, Expression> keyRangeExpressions = getKeyExpressionCombinations(context, tableRef, joinSpec.getType(), joinExpressions[i], hashExpressions[i]);
- keyRangeLhsExpressions[i] = keyRangeExpressions.getFirst();
- keyRangeRhsExpressions[i] = keyRangeExpressions.getSecond();
- hasFilters[i] = joinSpec.getJoinTable().hasFilters();
+ List<Expression> hashExpressions = joinConditions.getSecond();
+ Pair<Expression, Expression> keyRangeExpressions = getKeyExpressionCombinations(context, tableRef, joinSpec.getType(), joinExpressions[i], hashExpressions);
+ Expression keyRangeLhsExpression = keyRangeExpressions.getFirst();
+ Expression keyRangeRhsExpression = keyRangeExpressions.getSecond();
+ boolean hasFilters = joinSpec.getJoinTable().hasFilters();
joinTypes[i] = joinSpec.getType();
if (i < count - 1) {
fieldPositions[i + 1] = fieldPositions[i] + (tables[i] == null ? 0 : (tables[i].getColumns().size() - tables[i].getPKColumns().size()));
}
+ subPlans[i] = new HashSubPlan(i, joinPlan, hashExpressions, keyRangeLhsExpression, keyRangeRhsExpression, clientProjector, hasFilters);
}
if (needsProject) {
TupleProjector.serializeProjectorIntoScan(context.getScan(), initialProjectedTable.createTupleProjector());
}
context.setCurrentTable(tableRef);
context.setResolver(needsProject ? projectedTable.createColumnResolver() : joinTable.getOriginalResolver());
- BaseQueryPlan plan = compileSingleQuery(context, query, binds, asSubquery, joinTable.isAllLeftJoin());
+ QueryPlan plan = compileSingleQuery(context, query, binds, asSubquery, joinTable.isAllLeftJoin());
Expression postJoinFilterExpression = joinTable.compilePostFilterExpression(context);
Integer limit = null;
if (query.getLimit() != null && !query.isAggregate() && !query.isDistinct() && query.getOrderBy().isEmpty()) {
limit = LimitCompiler.compile(context, query);
}
HashJoinInfo joinInfo = new HashJoinInfo(projectedTable.getTable(), joinIds, joinExpressions, joinTypes, starJoinVector, tables, fieldPositions, postJoinFilterExpression, limit, forceProjection);
- return new HashJoinPlan(joinTable.getStatement(), plan, joinInfo, hashExpressions, keyRangeLhsExpressions, keyRangeRhsExpressions, joinPlans, clientProjectors, hasFilters);
+ return HashJoinPlan.create(joinTable.getStatement(), plan, joinInfo, subPlans);
}
JoinSpec lastJoinSpec = joinSpecs.get(joinSpecs.size() - 1);
@@ -286,7 +285,7 @@ public class QueryCompiler {
TupleProjector.serializeProjectorIntoScan(context.getScan(), rhsProjTable.createTupleProjector());
context.setCurrentTable(rhsTableRef);
context.setResolver(projectedTable.createColumnResolver());
- BaseQueryPlan rhsPlan = compileSingleQuery(context, rhs, binds, asSubquery, type == JoinType.Right);
+ QueryPlan rhsPlan = compileSingleQuery(context, rhs, binds, asSubquery, type == JoinType.Right);
Expression postJoinFilterExpression = joinTable.compilePostFilterExpression(context);
Integer limit = null;
if (rhs.getLimit() != null && !rhs.isAggregate() && !rhs.isDistinct() && rhs.getOrderBy().isEmpty()) {
@@ -294,7 +293,7 @@ public class QueryCompiler {
}
HashJoinInfo joinInfo = new HashJoinInfo(projectedTable.getTable(), joinIds, new List[] {joinExpressions}, new JoinType[] {type == JoinType.Inner ? type : JoinType.Left}, new boolean[] {true}, new PTable[] {lhsProjTable.getTable()}, new int[] {fieldPosition}, postJoinFilterExpression, limit, forceProjection);
Pair<Expression, Expression> keyRangeExpressions = getKeyExpressionCombinations(context, rhsTableRef, type, joinExpressions, hashExpressions);
- return new HashJoinPlan(joinTable.getStatement(), rhsPlan, joinInfo, new List[] {hashExpressions}, new Expression[] {keyRangeExpressions.getFirst()}, new Expression[] {keyRangeExpressions.getSecond()}, new QueryPlan[] {lhsPlan}, new TupleProjector[] {clientProjector}, new boolean[] {lhsJoin.hasFilters()});
+ return HashJoinPlan.create(joinTable.getStatement(), rhsPlan, joinInfo, new HashSubPlan[] {new HashSubPlan(0, lhsPlan, hashExpressions, keyRangeExpressions.getFirst(), keyRangeExpressions.getSecond(), clientProjector, lhsJoin.hasFilters())});
}
// Do not support queries like "A right join B left join C" with hash-joins.
@@ -336,7 +335,7 @@ public class QueryCompiler {
return statement.getConnection().getQueryServices().getOptimizer().optimize(statement, plan);
}
- protected BaseQueryPlan compileSingleQuery(StatementContext context, SelectStatement select, List<Object> binds, boolean asSubquery, boolean allowPageFilter) throws SQLException{
+ protected QueryPlan compileSingleQuery(StatementContext context, SelectStatement select, List<Object> binds, boolean asSubquery, boolean allowPageFilter) throws SQLException{
PhoenixConnection connection = statement.getConnection();
ColumnResolver resolver = context.getResolver();
TableRef tableRef = context.getCurrentTable();
@@ -360,7 +359,7 @@ public class QueryCompiler {
// Don't pass groupBy when building where clause expression, because we do not want to wrap these
// expressions as group by key expressions since they're pre, not post filtered.
context.setResolver(FromCompiler.getResolverForQuery(select, connection));
- WhereCompiler.compile(context, select, viewWhere);
+ Set<SubqueryParseNode> subqueries = WhereCompiler.compile(context, select, viewWhere);
context.setResolver(resolver); // recover resolver
OrderBy orderBy = OrderByCompiler.compile(context, select, groupBy, limit);
RowProjector projector = ProjectionCompiler.compile(context, select, groupBy, asSubquery ? Collections.<PDatum>emptyList() : targetColumns);
@@ -375,11 +374,21 @@ public class QueryCompiler {
}
}
ParallelIteratorFactory parallelIteratorFactory = asSubquery ? null : this.parallelIteratorFactory;
- if (select.isAggregate() || select.isDistinct()) {
- return new AggregatePlan(context, select, tableRef, projector, limit, orderBy, parallelIteratorFactory, groupBy, having);
- } else {
- return new ScanPlan(context, select, tableRef, projector, limit, orderBy, parallelIteratorFactory, allowPageFilter);
+ QueryPlan plan = select.isAggregate() || select.isDistinct() ?
+ new AggregatePlan(context, select, tableRef, projector, limit, orderBy, parallelIteratorFactory, groupBy, having)
+ : new ScanPlan(context, select, tableRef, projector, limit, orderBy, parallelIteratorFactory, allowPageFilter);
+ if (!subqueries.isEmpty()) {
+ int count = subqueries.size();
+ WhereClauseSubPlan[] subPlans = new WhereClauseSubPlan[count];
+ int i = 0;
+ for (SubqueryParseNode subqueryNode : subqueries) {
+ SelectStatement stmt = subqueryNode.getSelectNode();
+ subPlans[i++] = new WhereClauseSubPlan(compileSubquery(stmt), stmt, subqueryNode.expectSingleRow());
+ }
+ plan = HashJoinPlan.create(select, plan, null, subPlans);
}
+
+ return plan;
}
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementContext.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementContext.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementContext.java
index 1c75527..56e63ae 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementContext.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementContext.java
@@ -32,6 +32,7 @@ import org.apache.hadoop.hbase.util.Pair;
import org.apache.phoenix.jdbc.PhoenixConnection;
import org.apache.phoenix.jdbc.PhoenixStatement;
import org.apache.phoenix.join.TupleProjector;
+import org.apache.phoenix.parse.SelectStatement;
import org.apache.phoenix.query.KeyRange;
import org.apache.phoenix.query.QueryConstants;
import org.apache.phoenix.query.QueryServices;
@@ -78,6 +79,8 @@ public class StatementContext {
private TupleProjector clientTupleProjector;
private TimeRange scanTimeRange = null;
+ private Map<SelectStatement, Object> subqueryResults;
+
public StatementContext(PhoenixStatement statement) {
this(statement, FromCompiler.EMPTY_TABLE_RESOLVER, new Scan(), new SequenceManager(statement));
}
@@ -99,6 +102,7 @@ public class StatementContext {
this.currentTable = resolver != null && !resolver.getTables().isEmpty() ? resolver.getTables().get(0) : null;
this.whereConditionColumns = new ArrayList<Pair<byte[],byte[]>>();
this.dataColumns = this.currentTable == null ? Collections.<PColumn, Integer>emptyMap() : Maps.<PColumn, Integer>newLinkedHashMap();
+ this.subqueryResults = Maps.<SelectStatement, Object>newHashMap();
}
/**
@@ -289,5 +293,16 @@ public class StatementContext {
public TimeRange getScanTimeRange() {
return this.scanTimeRange;
}
+
+ public boolean isSubqueryResultAvailable(SelectStatement select) {
+ return subqueryResults.containsKey(select);
+ }
+ public Object getSubqueryResult(SelectStatement select) {
+ return subqueryResults.get(select);
+ }
+
+ public void setSubqueryResult(SelectStatement select, Object result) {
+ subqueryResults.put(select, result);
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementNormalizer.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementNormalizer.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementNormalizer.java
index e29a20a..88aa81c 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementNormalizer.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/StatementNormalizer.java
@@ -34,6 +34,7 @@ import org.apache.phoenix.parse.NamedTableNode;
import org.apache.phoenix.parse.ParseNode;
import org.apache.phoenix.parse.ParseNodeRewriter;
import org.apache.phoenix.parse.SelectStatement;
+import org.apache.phoenix.parse.SubqueryParseNode;
import org.apache.phoenix.parse.TableName;
import org.apache.phoenix.parse.TableNode;
import org.apache.phoenix.parse.TableNodeVisitor;
@@ -150,6 +151,18 @@ public class StatementNormalizer extends ParseNodeRewriter {
nodes = normNodes;
node = NODE_FACTORY.comparison(node.getInvertFilterOp(), nodes.get(0), nodes.get(1));
}
+ // Add limit 2 to direct comparison with sub-query without ANY/SOME/ALL modifiers.
+ ParseNode rhs = nodes.get(1);
+ if (rhs instanceof SubqueryParseNode) {
+ SelectStatement subquery = ((SubqueryParseNode) rhs).getSelectNode();
+ subquery = NODE_FACTORY.select(subquery, NODE_FACTORY.limit(NODE_FACTORY.literal(2)));
+ rhs = NODE_FACTORY.subquery(subquery, true);
+ List<ParseNode> normNodes = Lists.newArrayListWithExpectedSize(2);
+ normNodes.add(nodes.get(0));
+ normNodes.add(rhs);
+ nodes = normNodes;
+ node = NODE_FACTORY.comparison(node.getFilterOp(), nodes.get(0), nodes.get(1));
+ }
return super.visitLeave(node, nodes);
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
index 2e72f43..27a4490 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/compile/WhereCompiler.java
@@ -43,10 +43,12 @@ import org.apache.phoenix.parse.FilterableStatement;
import org.apache.phoenix.parse.HintNode.Hint;
import org.apache.phoenix.parse.ParseNode;
import org.apache.phoenix.parse.ParseNodeFactory;
+import org.apache.phoenix.parse.SelectStatement;
+import org.apache.phoenix.parse.StatelessTraverseAllParseNodeVisitor;
+import org.apache.phoenix.parse.SubqueryParseNode;
import org.apache.phoenix.schema.AmbiguousColumnException;
import org.apache.phoenix.schema.ColumnNotFoundException;
import org.apache.phoenix.schema.ColumnRef;
-import org.apache.phoenix.schema.LocalIndexDataColumnRef;
import org.apache.phoenix.schema.PDataType;
import org.apache.phoenix.schema.PTable;
import org.apache.phoenix.schema.PTable.IndexType;
@@ -75,7 +77,7 @@ public class WhereCompiler {
private WhereCompiler() {
}
- public static Expression compile(StatementContext context, FilterableStatement statement) throws SQLException {
+ public static Set<SubqueryParseNode> compile(StatementContext context, FilterableStatement statement) throws SQLException {
return compile(context, statement, null);
}
@@ -89,7 +91,7 @@ public class WhereCompiler {
* @throws ColumnNotFoundException if column name could not be resolved
* @throws AmbiguousColumnException if an unaliased column name is ambiguous across multiple tables
*/
- public static Expression compile(StatementContext context, FilterableStatement statement, ParseNode viewWhere) throws SQLException {
+ public static Set<SubqueryParseNode> compile(StatementContext context, FilterableStatement statement, ParseNode viewWhere) throws SQLException {
return compile(context, statement, viewWhere, Collections.<Expression>emptyList(), false);
}
@@ -103,10 +105,21 @@ public class WhereCompiler {
* @throws ColumnNotFoundException if column name could not be resolved
* @throws AmbiguousColumnException if an unaliased column name is ambiguous across multiple tables
*/
- public static Expression compile(StatementContext context, FilterableStatement statement, ParseNode viewWhere, List<Expression> dynamicFilters, boolean hashJoinOptimization) throws SQLException {
+ public static Set<SubqueryParseNode> compile(StatementContext context, FilterableStatement statement, ParseNode viewWhere, List<Expression> dynamicFilters, boolean hashJoinOptimization) throws SQLException {
+ ParseNode where = statement.getWhere();
+ Set<SubqueryParseNode> subqueryNodes = Sets.<SubqueryParseNode> newHashSet();
+ SubqueryParseNodeVisitor subqueryVisitor = new SubqueryParseNodeVisitor(context, subqueryNodes);
+ if (where != null) {
+ where.accept(subqueryVisitor);
+ }
+ if (viewWhere != null) {
+ viewWhere.accept(subqueryVisitor);
+ }
+ if (!subqueryNodes.isEmpty())
+ return subqueryNodes;
+
Set<Expression> extractedNodes = Sets.<Expression>newHashSet();
WhereExpressionCompiler whereCompiler = new WhereExpressionCompiler(context);
- ParseNode where = statement.getWhere();
Expression expression = where == null ? LiteralExpression.newConstant(true,PDataType.BOOLEAN,true) : where.accept(whereCompiler);
if (whereCompiler.isAggregate()) {
throw new SQLExceptionInfo.Builder(SQLExceptionCode.AGGREGATE_IN_WHERE).build().buildException();
@@ -128,7 +141,7 @@ public class WhereCompiler {
expression = WhereOptimizer.pushKeyExpressionsToScan(context, statement, expression, extractedNodes);
setScanFilter(context, statement, expression, whereCompiler.disambiguateWithFamily, hashJoinOptimization);
- return expression;
+ return subqueryNodes;
}
private static class WhereExpressionCompiler extends ExpressionCompiler {
@@ -212,7 +225,6 @@ public class WhereCompiler {
*/
private static void setScanFilter(StatementContext context, FilterableStatement statement, Expression whereClause, boolean disambiguateWithFamily, boolean hashJoinOptimization) {
Scan scan = context.getScan();
- assert scan.getFilter() == null;
if (LiteralExpression.isFalse(whereClause)) {
context.setScanRanges(ScanRanges.NOTHING);
@@ -259,4 +271,24 @@ public class WhereCompiler {
ScanUtil.andFilterAtBeginning(scan, scanRanges.getSkipScanFilter());
}
}
+
+ private static class SubqueryParseNodeVisitor extends StatelessTraverseAllParseNodeVisitor {
+ private final StatementContext context;
+ private final Set<SubqueryParseNode> subqueryNodes;
+
+ SubqueryParseNodeVisitor(StatementContext context, Set<SubqueryParseNode> subqueryNodes) {
+ this.context = context;
+ this.subqueryNodes = subqueryNodes;
+ }
+
+ @Override
+ public Void visit(SubqueryParseNode node) throws SQLException {
+ SelectStatement select = node.getSelectNode();
+ if (!context.isSubqueryResultAvailable(select)) {
+ this.subqueryNodes.add(node);
+ }
+ return null;
+ }
+
+ }
}
http://git-wip-us.apache.org/repos/asf/phoenix/blob/a0694b77/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
----------------------------------------------------------------------
diff --git a/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java b/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
index 3d5e302..bbb09dc 100644
--- a/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
+++ b/phoenix-core/src/main/java/org/apache/phoenix/exception/SQLExceptionCode.java
@@ -78,6 +78,7 @@ public enum SQLExceptionCode {
SERVER_ARITHMETIC_ERROR(212, "22012", "Arithmetic error on server."),
VALUE_OUTSIDE_RANGE(213,"22003","Value outside range."),
VALUE_IN_LIST_NOT_CONSTANT(214, "22008", "Values in IN must evaluate to a constant."),
+ SINGLE_ROW_SUBQUERY_RETURNS_MULTIPLE_ROWS(215, "22015", "Single-row subquery returns more than one row."),
/**
* Constraint Violation (errorcode 03, sqlstate 23)