提交 db1612f4 authored 作者: Evgenij Ryazanov's avatar Evgenij Ryazanov

Implement derived column list syntax on table alias

上级 d4891863
...@@ -2256,7 +2256,8 @@ ID + 20 ...@@ -2256,7 +2256,8 @@ ID + 20
" "
"Other Grammar","Table Expression"," "Other Grammar","Table Expression","
{ [ schemaName. ] tableName | ( select ) | valuesExpression } [ [ AS ] newTableAlias ] { [ schemaName. ] tableName | ( select ) | valuesExpression }
[ [ AS ] newTableAlias [ ( columnName [,...] ) ] ]
[ USE INDEX ([ indexName [,...] ]) ] [ USE INDEX ([ indexName [,...] ]) ]
[ { { LEFT | RIGHT } [ OUTER ] | [ INNER ] | CROSS | NATURAL } [ { { LEFT | RIGHT } [ OUTER ] | [ INNER ] | CROSS | NATURAL }
JOIN tableExpression [ ON expression ] ] JOIN tableExpression [ ON expression ] ]
......
...@@ -1374,6 +1374,14 @@ public class Parser { ...@@ -1374,6 +1374,14 @@ public class Parser {
alias = readFromAlias(null); alias = readFromAlias(null);
if (alias != null) { if (alias != null) {
top.setAlias(alias); top.setAlias(alias);
if (readIf("(")) {
ArrayList<String> derivedColumnNames = New.arrayList();
do {
derivedColumnNames.add(readAliasIdentifier());
} while (readIf(","));
read(")");
top.setDerivedColumns(derivedColumnNames);
}
} }
return top; return top;
} }
......
...@@ -737,8 +737,9 @@ public class Select extends Query { ...@@ -737,8 +737,9 @@ public class Select extends Query {
if (filter.isNaturalJoinColumn(c)) { if (filter.isNaturalJoinColumn(c)) {
continue; continue;
} }
String name = filter.getDerivedColumnName(c);
ExpressionColumn ec = new ExpressionColumn( ExpressionColumn ec = new ExpressionColumn(
session.getDatabase(), null, alias, c.getName()); session.getDatabase(), null, alias, name != null ? name : c.getName());
expressions.add(index++, ec); expressions.add(index++, ec);
} }
return index; return index;
......
...@@ -52,6 +52,11 @@ public class SelectListColumnResolver implements ColumnResolver { ...@@ -52,6 +52,11 @@ public class SelectListColumnResolver implements ColumnResolver {
return columns; return columns;
} }
@Override
public String getDerivedColumnName(Column column) {
return null;
}
@Override @Override
public String getSchemaName() { public String getSchemaName() {
return null; return null;
......
...@@ -33,7 +33,7 @@ public class ExpressionColumn extends Expression { ...@@ -33,7 +33,7 @@ public class ExpressionColumn extends Expression {
private final Database database; private final Database database;
private final String schemaName; private final String schemaName;
private final String tableAlias; private final String tableAlias;
private final String columnName; private String columnName;
private ColumnResolver columnResolver; private ColumnResolver columnResolver;
private int queryLevel; private int queryLevel;
private Column column; private Column column;
...@@ -89,7 +89,10 @@ public class ExpressionColumn extends Expression { ...@@ -89,7 +89,10 @@ public class ExpressionColumn extends Expression {
return; return;
} }
for (Column col : resolver.getColumns()) { for (Column col : resolver.getColumns()) {
String n = col.getName(); String n = resolver.getDerivedColumnName(col);
if (n == null) {
n = col.getName();
}
if (database.equalsIdentifiers(columnName, n)) { if (database.equalsIdentifiers(columnName, n)) {
mapColumn(resolver, col, level); mapColumn(resolver, col, level);
return; return;
...@@ -253,6 +256,12 @@ public class ExpressionColumn extends Expression { ...@@ -253,6 +256,12 @@ public class ExpressionColumn extends Expression {
@Override @Override
public String getAlias() { public String getAlias() {
if (column != null) { if (column != null) {
if (columnResolver != null) {
String name = columnResolver.getDerivedColumnName(column);
if (name != null) {
return name;
}
}
return column.getName(); return column.getName();
} }
if (tableAlias != null) { if (tableAlias != null) {
......
...@@ -30,6 +30,14 @@ public interface ColumnResolver { ...@@ -30,6 +30,14 @@ public interface ColumnResolver {
*/ */
Column[] getColumns(); Column[] getColumns();
/**
* Get derived column name, or {@code null}.
*
* @param column column
* @return derived column name, or {@code null}
*/
String getDerivedColumnName(Column column);
/** /**
* Get the list of system columns, if any. * Get the list of system columns, if any.
* *
......
...@@ -42,6 +42,11 @@ public class SingleColumnResolver implements ColumnResolver { ...@@ -42,6 +42,11 @@ public class SingleColumnResolver implements ColumnResolver {
return new Column[] { column }; return new Column[] { column };
} }
@Override
public String getDerivedColumnName(Column column) {
return null;
}
@Override @Override
public String getSchemaName() { public String getSchemaName() {
return null; return null;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
package org.h2.table; package org.h2.table;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import org.h2.api.ErrorCode; import org.h2.api.ErrorCode;
import org.h2.command.Parser; import org.h2.command.Parser;
...@@ -117,6 +118,8 @@ public class TableFilter implements ColumnResolver { ...@@ -117,6 +118,8 @@ public class TableFilter implements ColumnResolver {
private final int hashCode; private final int hashCode;
private final int orderInFrom; private final int orderInFrom;
private HashMap<Column, String> derivedColumnMap;
/** /**
* Create a new table filter object. * Create a new table filter object.
* *
...@@ -992,6 +995,12 @@ public class TableFilter implements ColumnResolver { ...@@ -992,6 +995,12 @@ public class TableFilter implements ColumnResolver {
return table.getColumns(); return table.getColumns();
} }
@Override
public String getDerivedColumnName(Column column) {
HashMap<Column, String> map = derivedColumnMap;
return map != null ? map.get(column) : null;
}
/** /**
* Get the system columns that this table understands. This is used for * Get the system columns that this table understands. This is used for
* compatibility with other databases. The columns are only returned if the * compatibility with other databases. The columns are only returned if the
...@@ -1056,6 +1065,30 @@ public class TableFilter implements ColumnResolver { ...@@ -1056,6 +1065,30 @@ public class TableFilter implements ColumnResolver {
this.alias = alias; this.alias = alias;
} }
/**
* Set derived column list.
*
* @param derivedColumnNames names of derived columns
*/
public void setDerivedColumns(ArrayList<String> derivedColumnNames) {
Column[] columns = getColumns();
int count = columns.length;
if (count != derivedColumnNames.size()) {
throw DbException.get(ErrorCode.COLUMN_COUNT_DOES_NOT_MATCH);
}
HashMap<Column, String> map = new HashMap<>(count);
for (int i = 0; i < count; i++) {
String alias = derivedColumnNames.get(i);
for (int j = 0; j < i; j++) {
if (alias.equals(derivedColumnNames.get(j))) {
throw DbException.get(ErrorCode.DUPLICATE_COLUMN_NAME_1, alias);
}
}
map.put(columns[i], alias);
}
this.derivedColumnMap = map;
}
@Override @Override
public Expression optimize(ExpressionColumn expressionColumn, Column column) { public Expression optimize(ExpressionColumn expressionColumn, Column column) {
return expressionColumn; return expressionColumn;
......
...@@ -82,6 +82,7 @@ public class TestScript extends TestBase { ...@@ -82,6 +82,7 @@ public class TestScript extends TestBase {
reconnectOften = !config.memory && config.big; reconnectOften = !config.memory && config.big;
testScript("testScript.sql"); testScript("testScript.sql");
testScript("aliases.sql");
testScript("joins.sql"); testScript("joins.sql");
testScript("altertable-index-reuse.sql"); testScript("altertable-index-reuse.sql");
testScript("query-optimisations.sql"); testScript("query-optimisations.sql");
......
-- Copyright 2004-2018 H2 Group. Multiple-Licensed under the MPL 2.0,
-- and the EPL 1.0 (http://h2database.com/html/license.html).
-- Initial Developer: H2 Group
--
SELECT * FROM (VALUES(1, 2));
> C1 C2
> -- --
> 1 2
> rows: 1
SELECT * FROM (VALUES(1, 2)) AS T;
> C1 C2
> -- --
> 1 2
> rows: 1
SELECT * FROM (VALUES(1, 2)) AS T(A, B);
> A B
> - -
> 1 2
> rows: 1
SELECT A AS A1, B AS B1 FROM (VALUES(1, 2)) AS T(A, B);
> A1 B1
> -- --
> 1 2
> rows: 1
SELECT A AS A1, B AS B1 FROM (VALUES(1, 2)) AS T(A, B) WHERE A <> B;
> A1 B1
> -- --
> 1 2
> rows: 1
SELECT A AS A1, B AS B1 FROM (VALUES(1, 2)) AS T(A, B) WHERE A1 <> B1;
> exception
SELECT * FROM (VALUES(1, 2)) AS T(A);
> exception
SELECT * FROM (VALUES(1, 2)) AS T(A, a);
> exception
SELECT * FROM (VALUES(1, 2)) AS T(A, B, C);
> exception
SELECT V AS V1, A AS A1, B AS B1 FROM (VALUES (1)) T1(V) INNER JOIN (VALUES(1, 2)) T2(A, B) ON V = A;
> V1 A1 B1
> -- -- --
> 1 1 2
> rows: 1
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论