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

Implement derived column list syntax on table alias

上级 d4891863
......@@ -2256,7 +2256,8 @@ ID + 20
"
"Other Grammar","Table Expression","
{ [ schemaName. ] tableName | ( select ) | valuesExpression } [ [ AS ] newTableAlias ]
{ [ schemaName. ] tableName | ( select ) | valuesExpression }
[ [ AS ] newTableAlias [ ( columnName [,...] ) ] ]
[ USE INDEX ([ indexName [,...] ]) ]
[ { { LEFT | RIGHT } [ OUTER ] | [ INNER ] | CROSS | NATURAL }
JOIN tableExpression [ ON expression ] ]
......
......@@ -1374,6 +1374,14 @@ public class Parser {
alias = readFromAlias(null);
if (alias != null) {
top.setAlias(alias);
if (readIf("(")) {
ArrayList<String> derivedColumnNames = New.arrayList();
do {
derivedColumnNames.add(readAliasIdentifier());
} while (readIf(","));
read(")");
top.setDerivedColumns(derivedColumnNames);
}
}
return top;
}
......
......@@ -737,8 +737,9 @@ public class Select extends Query {
if (filter.isNaturalJoinColumn(c)) {
continue;
}
String name = filter.getDerivedColumnName(c);
ExpressionColumn ec = new ExpressionColumn(
session.getDatabase(), null, alias, c.getName());
session.getDatabase(), null, alias, name != null ? name : c.getName());
expressions.add(index++, ec);
}
return index;
......
......@@ -52,6 +52,11 @@ public class SelectListColumnResolver implements ColumnResolver {
return columns;
}
@Override
public String getDerivedColumnName(Column column) {
return null;
}
@Override
public String getSchemaName() {
return null;
......
......@@ -33,7 +33,7 @@ public class ExpressionColumn extends Expression {
private final Database database;
private final String schemaName;
private final String tableAlias;
private final String columnName;
private String columnName;
private ColumnResolver columnResolver;
private int queryLevel;
private Column column;
......@@ -89,7 +89,10 @@ public class ExpressionColumn extends Expression {
return;
}
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)) {
mapColumn(resolver, col, level);
return;
......@@ -253,6 +256,12 @@ public class ExpressionColumn extends Expression {
@Override
public String getAlias() {
if (column != null) {
if (columnResolver != null) {
String name = columnResolver.getDerivedColumnName(column);
if (name != null) {
return name;
}
}
return column.getName();
}
if (tableAlias != null) {
......
......@@ -30,6 +30,14 @@ public interface ColumnResolver {
*/
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.
*
......
......@@ -42,6 +42,11 @@ public class SingleColumnResolver implements ColumnResolver {
return new Column[] { column };
}
@Override
public String getDerivedColumnName(Column column) {
return null;
}
@Override
public String getSchemaName() {
return null;
......
......@@ -6,6 +6,7 @@
package org.h2.table;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import org.h2.api.ErrorCode;
import org.h2.command.Parser;
......@@ -117,6 +118,8 @@ public class TableFilter implements ColumnResolver {
private final int hashCode;
private final int orderInFrom;
private HashMap<Column, String> derivedColumnMap;
/**
* Create a new table filter object.
*
......@@ -992,6 +995,12 @@ public class TableFilter implements ColumnResolver {
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
* compatibility with other databases. The columns are only returned if the
......@@ -1056,6 +1065,30 @@ public class TableFilter implements ColumnResolver {
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
public Expression optimize(ExpressionColumn expressionColumn, Column column) {
return expressionColumn;
......
......@@ -82,6 +82,7 @@ public class TestScript extends TestBase {
reconnectOften = !config.memory && config.big;
testScript("testScript.sql");
testScript("aliases.sql");
testScript("joins.sql");
testScript("altertable-index-reuse.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 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论