Skip to content

Commit

Permalink
Feature/76 select from values as (#84)
Browse files Browse the repository at this point in the history
* #76: Added `SELECT FROM VALUES ... AS` support
  • Loading branch information
AnastasiiaSergienko authored Jun 30, 2020
1 parent c6a44c8 commit 222ff94
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ final String sql = renderer.render();
* [User Guide](doc/user_guide/user_guide.md)
* [API Documentation](https://javadoc.io/doc/com.exasol/sql-statement-builder)
* [MIT License](LICENSE)
* [Changelog](doc/changes/changelog.md)

### Information for Developers

Expand Down
1 change: 1 addition & 0 deletions doc/changes/changes-4.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

* #80: Added ossindex-maven-plugin and versions-maven-plugin, updated dependencies.
* #81: Ported from Java 8 to Java 11.
* #76: Added `SELECT FROM VALUES ... AS` support.

## Dependency updates

Expand Down
45 changes: 44 additions & 1 deletion src/main/java/com/exasol/sql/ValueTable.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
// [impl->dsn~value-table~1]
public class ValueTable extends AbstractFragment {
private final List<ValueTableRow> rows = new ArrayList<>();
private String tableNameAlias;
private final List<String> columnNameAliases = new ArrayList<>();

/**
* Create a new {@link ValueTable}.
Expand Down Expand Up @@ -173,4 +175,45 @@ public void accept(final ValueTableVisitor visitor) {
}
visitor.leave(this);
}
}

/**
* Set alias for the value table.
*
* @param tableNameAlias table name alias
* @param columnNameAliases zero or more column names aliases
*/
public void alias(final String tableNameAlias, final String... columnNameAliases) {
this.tableNameAlias = tableNameAlias;
if (columnNameAliases.length > 0) {
this.columnNameAliases.addAll(Arrays.asList(columnNameAliases));
}
}

/**
* CHeck if the value table has an alias.
*
* @return true if the value table has an alias
*/
public boolean hasAlias() {
return (this.tableNameAlias != null) && (!this.tableNameAlias.isEmpty()) //
&& (!this.columnNameAliases.isEmpty());
}

/**
* Get a table name alias.
*
* @return table name alias
*/
public String getTableNameAlias() {
return this.tableNameAlias;
}

/**
* Get column name aliases.
*
* @return column name aliases
*/
public List<String> getColumnNameAliases() {
return this.columnNameAliases;
}
}
17 changes: 16 additions & 1 deletion src/main/java/com/exasol/sql/dql/select/FromClause.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public FromClause table(final String name) {
}

/**
* Add a table name with an an alias to the {@link FromClause}.
* Add a table name with an alias to the {@link FromClause}.
*
* @param name table name
* @param as table alias
Expand All @@ -56,6 +56,21 @@ public FromClause valueTable(final ValueTable valueTable) {
return this;
}

/**
* Create a {@link FromClause} from a value table and an alias.
*
* @param valueTable table of value expressions
* @param tableNameAlias table alias
* @param columnNameAliases columns aliases
* @return parent {@code FROM} clause
*/
public FromClause valueTableAs(final ValueTable valueTable, final String tableNameAlias,
final String... columnNameAliases) {
valueTable.alias(tableNameAlias, columnNameAliases);
this.valueTables.add(valueTable);
return this;
}

/**
* Create a new {@link Join} that belongs to a {@code FROM} clause.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.exasol.sql.dql.select.rendering;

import java.util.List;

import com.exasol.sql.*;
import com.exasol.sql.dql.select.*;
import com.exasol.sql.expression.BooleanExpression;
Expand Down Expand Up @@ -129,6 +131,19 @@ public void visit(final ValueTable valueTable) {
@Override
public void leave(final ValueTable valueTable) {
append(")");
if (valueTable.hasAlias()) {
appendKeyWord(" AS ");
appendAutoQuoted(valueTable.getTableNameAlias());
append("(");
final List<String> columnNameAliases = valueTable.getColumnNameAliases();
for (int i = 0; i < columnNameAliases.size(); i++) {
appendAutoQuoted(columnNameAliases.get(i));
if (i < columnNameAliases.size() - 1) {
append(", ");
}
}
append(")");
}
setLastVisited(valueTable);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ void testSelectWithQuotedIdentifiersDoesNotAddExtraQuotes() {
@Test
void testQuotedIdentifiers() {
final StringRendererConfig config = StringRendererConfig.builder().quoteIdentifiers(true).build();
Select select = this.select.all();
final Select select = this.select.all();
select.from().table("person");
select.where(eq(ExpressionTerm.stringLiteral("foo"), ColumnReference.of("test")));
assertThat(select, rendersWithConfigTo(config, "SELECT * FROM \"person\" WHERE 'foo' = \"test\""));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.exasol.sql.dql.select.rendering;

import static com.exasol.hamcrest.SqlFragmentRenderResultMatcher.rendersTo;
import static com.exasol.hamcrest.SqlFragmentRenderResultMatcher.rendersWithConfigTo;
import static org.hamcrest.MatcherAssert.assertThat;

import org.junit.jupiter.api.BeforeEach;
Expand All @@ -9,6 +10,7 @@
import com.exasol.sql.StatementFactory;
import com.exasol.sql.ValueTable;
import com.exasol.sql.dql.select.Select;
import com.exasol.sql.rendering.StringRendererConfig;

class TestValueTableRendering {
private Select select;
Expand All @@ -26,4 +28,34 @@ void testSelectFromMultipleTableAs() {
assertThat(this.select.all().from().valueTable(values),
rendersTo("SELECT * FROM (VALUES ('r1c1', 'r1c2'), ('r2c1', 'r2c2'))"));
}

@Test
void testSelectFromValuesAs() {
final ValueTable values = new ValueTable(this.select);
values.add(1, 2);
final Select select = this.select.field("COL1");
select.from().valueTableAs(values, "T", "COL1", "COL2");
assertThat(select, rendersTo("SELECT COL1 FROM (VALUES (1, 2)) AS T(COL1, COL2)"));
}

@Test
void testSelectFromValuesAsWithQuotation() {
final StringRendererConfig config = StringRendererConfig.builder().quoteIdentifiers(true).build();
final ValueTable values = new ValueTable(this.select);
values.add(1, 2);
final Select select = this.select.field("COL1");
select.from().valueTableAs(values, "T", "COL1", "COL2");
assertThat(select,
rendersWithConfigTo(config, "SELECT \"COL1\" FROM (VALUES (1, 2)) AS \"T\"(\"COL1\", \"COL2\")"));
}

@Test
void testSelectFromValuesAsWithQuotationOneColumn() {
final StringRendererConfig config = StringRendererConfig.builder().quoteIdentifiers(true).build();
final ValueTable values = new ValueTable(this.select);
values.add(1);
final Select select = this.select.field("COL1");
select.from().valueTableAs(values, "T", "COL1");
assertThat(select, rendersWithConfigTo(config, "SELECT \"COL1\" FROM (VALUES (1)) AS \"T\"(\"COL1\")"));
}
}

0 comments on commit 222ff94

Please sign in to comment.