Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2004-2013 H2 Group. Multiple-Licensed under the H2 License,
* Version 1.0, and under the Eclipse Public License, Version 1.0
* (http://h2database.com/html/license.html).
* Initial Developer: H2 Group
*/
package org.glowroot.shaded.h2.command.dml;
import java.util.ArrayList;
import java.util.HashSet;
import org.glowroot.shaded.h2.api.ErrorCode;
import org.glowroot.shaded.h2.command.CommandInterface;
import org.glowroot.shaded.h2.engine.Session;
import org.glowroot.shaded.h2.engine.SysProperties;
import org.glowroot.shaded.h2.expression.Expression;
import org.glowroot.shaded.h2.expression.ExpressionColumn;
import org.glowroot.shaded.h2.expression.ExpressionVisitor;
import org.glowroot.shaded.h2.expression.Parameter;
import org.glowroot.shaded.h2.expression.ValueExpression;
import org.glowroot.shaded.h2.message.DbException;
import org.glowroot.shaded.h2.result.LocalResult;
import org.glowroot.shaded.h2.result.ResultInterface;
import org.glowroot.shaded.h2.result.ResultTarget;
import org.glowroot.shaded.h2.result.SortOrder;
import org.glowroot.shaded.h2.table.Column;
import org.glowroot.shaded.h2.table.ColumnResolver;
import org.glowroot.shaded.h2.table.Table;
import org.glowroot.shaded.h2.table.TableFilter;
import org.glowroot.shaded.h2.util.New;
import org.glowroot.shaded.h2.util.StringUtils;
import org.glowroot.shaded.h2.value.Value;
import org.glowroot.shaded.h2.value.ValueInt;
import org.glowroot.shaded.h2.value.ValueNull;
/**
* Represents a union SELECT statement.
*/
public class SelectUnion extends Query {
/**
* The type of a UNION statement.
*/
public static final int UNION = 0;
/**
* The type of a UNION ALL statement.
*/
public static final int UNION_ALL = 1;
/**
* The type of an EXCEPT statement.
*/
public static final int EXCEPT = 2;
/**
* The type of an INTERSECT statement.
*/
public static final int INTERSECT = 3;
private int unionType;
private final Query left;
private Query right;
private ArrayList expressions;
private Expression[] expressionArray;
private ArrayList orderList;
private SortOrder sort;
private boolean isPrepared, checkInit;
private boolean isForUpdate;
public SelectUnion(Session session, Query query) {
super(session);
this.left = query;
}
public void setUnionType(int type) {
this.unionType = type;
}
public int getUnionType() {
return unionType;
}
public void setRight(Query select) {
right = select;
}
public Query getLeft() {
return left;
}
public Query getRight() {
return right;
}
@Override
public void setSQL(String sql) {
this.sqlStatement = sql;
}
@Override
public void setOrder(ArrayList order) {
orderList = order;
}
private Value[] convert(Value[] values, int columnCount) {
Value[] newValues;
if (columnCount == values.length) {
// re-use the array if possible
newValues = values;
} else {
// create a new array if needed,
// for the value hash set
newValues = new Value[columnCount];
}
for (int i = 0; i < columnCount; i++) {
Expression e = expressions.get(i);
newValues[i] = values[i].convertTo(e.getType());
}
return newValues;
}
@Override
public ResultInterface queryMeta() {
int columnCount = left.getColumnCount();
LocalResult result = new LocalResult(session, expressionArray, columnCount);
result.done();
return result;
}
public LocalResult getEmptyResult() {
int columnCount = left.getColumnCount();
return new LocalResult(session, expressionArray, columnCount);
}
@Override
protected LocalResult queryWithoutCache(int maxRows, ResultTarget target) {
if (maxRows != 0) {
// maxRows is set (maxRows 0 means no limit)
int l;
if (limitExpr == null) {
l = -1;
} else {
Value v = limitExpr.getValue(session);
l = v == ValueNull.INSTANCE ? -1 : v.getInt();
}
if (l < 0) {
// for limitExpr, 0 means no rows, and -1 means no limit
l = maxRows;
} else {
l = Math.min(l, maxRows);
}
limitExpr = ValueExpression.get(ValueInt.get(l));
}
if (session.getDatabase().getSettings().optimizeInsertFromSelect) {
if (unionType == UNION_ALL && target != null) {
if (sort == null && !distinct && maxRows == 0 &&
offsetExpr == null && limitExpr == null) {
left.query(0, target);
right.query(0, target);
return null;
}
}
}
int columnCount = left.getColumnCount();
LocalResult result = new LocalResult(session, expressionArray, columnCount);
if (sort != null) {
result.setSortOrder(sort);
}
if (distinct) {
left.setDistinct(true);
right.setDistinct(true);
result.setDistinct();
}
if (randomAccessResult) {
result.setRandomAccess();
}
switch (unionType) {
case UNION:
case EXCEPT:
left.setDistinct(true);
right.setDistinct(true);
result.setDistinct();
break;
case UNION_ALL:
break;
case INTERSECT:
left.setDistinct(true);
right.setDistinct(true);
break;
default:
DbException.throwInternalError("type=" + unionType);
}
ResultInterface l = left.query(0);
ResultInterface r = right.query(0);
l.reset();
r.reset();
switch (unionType) {
case UNION_ALL:
case UNION: {
while (l.next()) {
result.addRow(convert(l.currentRow(), columnCount));
}
while (r.next()) {
result.addRow(convert(r.currentRow(), columnCount));
}
break;
}
case EXCEPT: {
while (l.next()) {
result.addRow(convert(l.currentRow(), columnCount));
}
while (r.next()) {
result.removeDistinct(convert(r.currentRow(), columnCount));
}
break;
}
case INTERSECT: {
LocalResult temp = new LocalResult(session, expressionArray, columnCount);
temp.setDistinct();
temp.setRandomAccess();
while (l.next()) {
temp.addRow(convert(l.currentRow(), columnCount));
}
while (r.next()) {
Value[] values = convert(r.currentRow(), columnCount);
if (temp.containsDistinct(values)) {
result.addRow(values);
}
}
break;
}
default:
DbException.throwInternalError("type=" + unionType);
}
if (offsetExpr != null) {
result.setOffset(offsetExpr.getValue(session).getInt());
}
if (limitExpr != null) {
Value v = limitExpr.getValue(session);
if (v != ValueNull.INSTANCE) {
result.setLimit(v.getInt());
}
}
result.done();
if (target != null) {
while (result.next()) {
target.addRow(result.currentRow());
}
result.close();
return null;
}
return result;
}
@Override
public void init() {
if (SysProperties.CHECK && checkInit) {
DbException.throwInternalError();
}
checkInit = true;
left.init();
right.init();
int len = left.getColumnCount();
if (len != right.getColumnCount()) {
throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH);
}
ArrayList le = left.getExpressions();
// set the expressions to get the right column count and names,
// but can't validate at this time
expressions = New.arrayList();
for (int i = 0; i < len; i++) {
Expression l = le.get(i);
expressions.add(l);
}
}
@Override
public void prepare() {
if (isPrepared) {
// sometimes a subquery is prepared twice (CREATE TABLE AS SELECT)
return;
}
if (SysProperties.CHECK && !checkInit) {
DbException.throwInternalError("not initialized");
}
isPrepared = true;
left.prepare();
right.prepare();
int len = left.getColumnCount();
// set the correct expressions now
expressions = New.arrayList();
ArrayList le = left.getExpressions();
ArrayList re = right.getExpressions();
for (int i = 0; i < len; i++) {
Expression l = le.get(i);
Expression r = re.get(i);
int type = Value.getHigherOrder(l.getType(), r.getType());
long prec = Math.max(l.getPrecision(), r.getPrecision());
int scale = Math.max(l.getScale(), r.getScale());
int displaySize = Math.max(l.getDisplaySize(), r.getDisplaySize());
Column col = new Column(l.getAlias(), type, prec, scale, displaySize);
Expression e = new ExpressionColumn(session.getDatabase(), col);
expressions.add(e);
}
if (orderList != null) {
initOrder(session, expressions, null, orderList, getColumnCount(), true, null);
sort = prepareOrder(orderList, expressions.size());
orderList = null;
}
expressionArray = new Expression[expressions.size()];
expressions.toArray(expressionArray);
}
@Override
public double getCost() {
return left.getCost() + right.getCost();
}
@Override
public HashSet