📄 select.java
字号:
return true;
}
// fredt@users 20030810 - patch 1.7.2 - OUTER JOIN rewrite
private Result buildResult(Session session,
int limitcount) throws HsqlException {
GroupedResult gResult = new GroupedResult(this, resultMetaData);
final int len = exprColumns.length;
final int filter = tFilter.length;
boolean[] first = new boolean[filter];
boolean[] outerused = new boolean[filter];
int level = 0;
// fredt - shortcut needed by OpenOffice to speed up empty query processing for metadata
boolean notempty = !(queryCondition != null
&& queryCondition.isFixedConditional()
&&!queryCondition.testCondition(session));
while (notempty && level >= 0) {
// perform a join
TableFilter t = tFilter[level];
boolean found;
boolean outerfound;
if (!first[level]) {
found = t.findFirst(session);
// if outer join, and no inner result, get next outer row
// nonJoinIsNull disallows getting the next outer row in some circumstances
outerused[level] = outerfound = t.isOuterJoin &&!found
&&!outerused[level]
&&!t.nonJoinIsNull
&& t.nextOuter(session);
first[level] = found;
} else {
found = t.next(session);
outerused[level] = outerfound = t.isOuterJoin &&!found
&&!first[level]
&&!outerused[level]
&&!t.nonJoinIsNull
&& t.nextOuter(session);
first[level] = found;
}
if (!found &&!outerfound) {
level--;
continue;
}
if (level < filter - 1) {
level++;
continue;
} else {
while (outerused[level]) {
outerused[level--] = false;
}
}
// apply condition
if (queryCondition == null
|| queryCondition.testCondition(session)) {
try {
Object[] row = new Object[len];
// gets the group by column values first.
for (int i = gResult.groupBegin; i < gResult.groupEnd;
i++) {
row[i] = exprColumns[i].getValue(session);
}
row = gResult.getRow(row);
// Get all other values
for (int i = 0; i < gResult.groupBegin; i++) {
row[i] =
isAggregated && exprColumns[i].isAggregate()
? exprColumns[i].updateAggregatingValue(session,
row[i])
: exprColumns[i].getValue(session);
}
for (int i = gResult.groupEnd; i < len; i++) {
row[i] =
isAggregated && exprColumns[i].isAggregate()
? exprColumns[i].updateAggregatingValue(session,
row[i])
: exprColumns[i].getValue(session);
}
gResult.addRow(row);
if (gResult.size() >= limitcount) {
break;
}
} catch (HsqlInternalException e) {
continue;
}
}
}
if (isAggregated &&!isGrouped && gResult.size() == 0) {
Object[] row = new Object[len];
for (int i = 0; i < len; i++) {
row[i] = exprColumns[i].isAggregate() ? null
: exprColumns[i]
.getValue(session);
}
gResult.addRow(row);
}
Iterator it = gResult.iterator();
while (it.hasNext()) {
Object[] row = (Object[]) it.next();
if (isAggregated) {
for (int i = 0; i < len; i++) {
if (exprColumns[i].isAggregate()) {
row[i] = exprColumns[i].getAggregatedValue(session,
row[i]);
}
}
}
if (iHavingLen > 0) {
// The test value, either aggregate or not, is set already.
// Removes the row that does not satisfy the HAVING
// condition.
if (!Boolean.TRUE.equals(row[iResultLen + iGroupLen])) {
it.remove();
}
}
}
return gResult.getResult();
}
/**
* Skeleton under development. Needs a lot of work.
*/
public StringBuffer getDDL() throws HsqlException {
StringBuffer sb = new StringBuffer();
sb.append(Token.T_SELECT).append(' ');
//limitStart;
//limitCount;
for (int i = 0; i < iResultLen; i++) {
sb.append(exprColumns[i].getDDL());
if (i < iResultLen - 1) {
sb.append(',');
}
}
sb.append(Token.T_FROM);
for (int i = 0; i < tFilter.length; i++) {
// find out if any expression in any of the filters isInJoin then use this form
TableFilter filter = tFilter[i];
// if any expression isInJoin
if (i != 0) {
if (filter.isOuterJoin) {
sb.append(Token.T_FROM).append(' ');
sb.append(Token.T_JOIN).append(' ');
}
// eStart and eEnd expressions
}
// otherwise use a comma delimited table list
sb.append(',');
}
// if there are any expressions that are not isInJoin
sb.append(' ').append(Token.T_WHERE).append(' ');
for (int i = 0; i < tFilter.length; i++) {
TableFilter filter = tFilter[i];
// eStart and eEnd expressions that are not isInJoin
}
// if has GROUP BY
sb.append(' ').append(Token.T_GROUP).append(' ');
for (int i = iResultLen; i < iResultLen + iGroupLen; i++) {
sb.append(exprColumns[i].getDDL());
if (i < iResultLen + iGroupLen - 1) {
sb.append(',');
}
}
// if has HAVING
sb.append(' ').append(Token.T_HAVING).append(' ');
for (int i = iResultLen + iGroupLen;
i < iResultLen + iGroupLen + iHavingLen; i++) {
sb.append(exprColumns[i].getDDL());
if (i < iResultLen + iGroupLen - 1) {
sb.append(',');
}
}
if (unionSelect != null) {
switch (unionType) {
case EXCEPT :
sb.append(' ').append(Token.T_EXCEPT).append(' ');
break;
case INTERSECT :
sb.append(' ').append(Token.T_INTERSECT).append(' ');
break;
case UNION :
sb.append(' ').append(Token.T_UNION).append(' ');
break;
case UNIONALL :
sb.append(' ').append(Token.T_UNION).append(' ').append(
Token.T_ALL).append(' ');
break;
}
}
// if has ORDER BY
int groupByEnd = iResultLen + iGroupLen;
int orderByStart = groupByEnd + iHavingLen;
int orderByEnd = orderByStart + iOrderLen;
sb.append(' ').append(Token.T_ORDER).append(Token.T_BY).append(' ');
for (int i = orderByStart; i < orderByEnd; i++) {
sb.append(exprColumns[i].getDDL());
if (i < iResultLen + iGroupLen - 1) {
sb.append(',');
}
}
return sb;
}
boolean isResolved = false;
/**
* @todo - post 1.8.0 - review resolve and check resolve -
* determine if isResolved is specific to main query or the full set including UNION
*
*/
boolean resolveAll(Session session, boolean check) throws HsqlException {
if (isResolved) {
return true;
}
resolve(session);
isResolved = checkResolved(check);
if (unionSelect != null) {
if (unionSelect.iResultLen != iResultLen) {
throw Trace.error(Trace.COLUMN_COUNT_DOES_NOT_MATCH);
}
for (int i = 0; i < iResultLen; i++) {
Expression e = exprColumns[i];
if (!e.isTypeEqual(unionSelect.exprColumns[i])) {
unionSelect.exprColumns[i] =
new Expression(unionSelect.exprColumns[i],
e.getDataType(), e.getColumnSize(),
e.getColumnScale());
}
}
isResolved &= unionSelect.resolveAll(session, check);
}
return isResolved;
}
boolean isResolved() {
return isResolved;
}
public String describe(Session session) {
StringBuffer sb;
String temp;
// temporary : it is currently unclear whether this may affect
// later attempts to retrieve an actual result (calls getResult(1)
// in preProcess mode). Thus, toString() probably should not be called
// on Select objects that will actually be used to retrieve results,
// only on Select objects used by EXPLAIN PLAN FOR
try {
getResult(session, 1);
} catch (HsqlException e) {}
sb = new StringBuffer();
sb.append(super.toString()).append("[\n");
if (sIntoTable != null) {
sb.append("into table=[").append(sIntoTable.name).append("]\n");
}
if (limitCondition != null) {
sb.append("offset=[").append(
limitCondition.getArg().describe(session)).append("]\n");
sb.append("limit=[").append(
limitCondition.getArg2().describe(session)).append("]\n");
}
sb.append("isDistinctSelect=[").append(isDistinctSelect).append(
"]\n");
sb.append("isGrouped=[").append(isGrouped).append("]\n");
sb.append("isAggregated=[").append(isAggregated).append("]\n");
sb.append("columns=[");
int columns = exprColumns.length - iOrderLen;
for (int i = 0; i < columns; i++) {
sb.append(exprColumns[i].describe(session));
}
sb.append("\n]\n");
sb.append("tableFilters=[\n");
for (int i = 0; i < tFilter.length; i++) {
sb.append("[\n");
sb.append(tFilter[i].describe(session));
sb.append("\n]");
}
sb.append("]\n");
temp = queryCondition == null ? "null"
: queryCondition.describe(session);
sb.append("eCondition=[").append(temp).append("]\n");
temp = havingCondition == null ? "null"
: havingCondition.describe(session);
sb.append("havingCondition=[").append(temp).append("]\n");
sb.append("groupColumns=[").append(groupColumnNames).append("]\n");
if (unionSelect != null) {
switch (unionType) {
case EXCEPT :
sb.append(" EXCEPT ");
break;
case INTERSECT :
sb.append(" INTERSECT ");
break;
case UNION :
sb.append(" UNION ");
break;
case UNIONALL :
sb.append(" UNION ALL ");
break;
default :
sb.append(" UNKNOWN SET OPERATION ");
}
sb.append("[\n").append(unionSelect.describe(session)).append(
"]\n");
}
return sb.toString();
}
Result describeResult() {
Result r;
Result.ResultMetaData rmd;
Expression e;
r = new Result(ResultConstants.DATA, iResultLen);
rmd = r.metaData;
for (int i = 0; i < iResultLen; i++) {
e = exprColumns[i];
rmd.colTypes[i] = e.getDataType();
rmd.colSizes[i] = e.getColumnSize();
rmd.colScales[i] = e.getColumnScale();
rmd.colLabels[i] = e.getAlias();
rmd.isLabelQuoted[i] = e.isAliasQuoted();
rmd.tableNames[i] = e.getTableName();
rmd.colNames[i] = e.getColumnName();
if (rmd.isTableColumn(i)) {
rmd.colNullable[i] = e.nullability;
rmd.isIdentity[i] = e.isIdentity;
rmd.isWritable[i] = e.isWritable;
}
}
return r;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -