[#756] CURSOR: Error when aliasing HSQLDB and Postgres UNNESTed tables

This commit is contained in:
Lukas Eder 2011-10-02 15:39:29 +00:00
parent ddffca934d
commit 3d52f6cc2f
3 changed files with 75 additions and 38 deletions

View File

@ -6757,8 +6757,8 @@ public abstract class jOOQAbstractTest<
assertEquals("1", "" + result.getValue(1, 0));
assertEquals("2", "" + result.getValue(2, 0));
// Joining an array table
// ----------------------
// Joining an unnested array table
// -------------------------------
array.set(2, 3);
Table<?> table = create().table(array);
result = create()
@ -6774,6 +6774,8 @@ public abstract class jOOQAbstractTest<
assertEquals("Animal Farm", result.getValue(0, TBook_TITLE()));
assertEquals("O Alquimista", result.getValue(1, TBook_TITLE()));
// Joining an aliased unnested array table
// ---------------------------------------
result = create()
.select(TBook_ID(), TBook_TITLE())
.from(TBook())
@ -6855,8 +6857,8 @@ public abstract class jOOQAbstractTest<
assertEquals(1, result.getValue(1, 0));
assertEquals(2, result.getValue(2, 0));
// Joining an array table
// ----------------------
// Joining an unnested array table
// -------------------------------
array = new Integer[] { 2, 3 };
Table<?> table = create().table(array);
result = create()
@ -6872,46 +6874,49 @@ public abstract class jOOQAbstractTest<
assertEquals("Animal Farm", result.getValue(0, TBook_TITLE()));
assertEquals("O Alquimista", result.getValue(1, TBook_TITLE()));
// [#756] TODO : Error when aliasing HSQLDB and Postgres UNNESTed tables
// Joining an aliased unnested array table
// ---------------------------------------
result = create()
.select(TBook_ID(), TBook_TITLE())
.from(TBook())
.join(table.as("t"))
.on(table.as("t").getField(0).cast(Integer.class).equal(TBook_ID()))
.fetch();
assertEquals(2, result.size());
assertEquals(Integer.valueOf(2), result.getValue(0, TBook_ID()));
assertEquals(Integer.valueOf(3), result.getValue(1, TBook_ID()));
assertEquals("Animal Farm", result.getValue(0, TBook_TITLE()));
assertEquals("O Alquimista", result.getValue(1, TBook_TITLE()));
// Cross join the array table with the unnested string array value
// ---------------------------------------------------------------
switch (getDialect()) {
case HSQLDB:
case POSTGRES:
log.info("SKIPPING", "Aliasing of ARRAY TABLE tests");
case H2:
log.info("SKIPPING", "Cross join of table with unnested array is not supported");
break;
default:
table = create().table(TArrays_STRING()).as("t");
result = create()
.select(TBook_ID(), TBook_TITLE())
.from(TBook())
.join(table.as("t"))
.on(table.as("t").getField(0).cast(Integer.class).equal(TBook_ID()))
.select(TArrays_ID(), table.getField(0))
.from(TArrays(), table)
.orderBy(TArrays_ID())
.fetch();
assertEquals(2, result.size());
assertEquals(Integer.valueOf(2), result.getValue(0, TBook_ID()));
assertEquals(Integer.valueOf(3), result.getValue(1, TBook_ID()));
assertEquals("Animal Farm", result.getValue(0, TBook_TITLE()));
assertEquals("O Alquimista", result.getValue(1, TBook_TITLE()));
//
//
// table = create().table(TArrays_STRING()).as("t");
// result = create()
// .select(TArrays_ID(), table.getField(0))
// .from(TArrays(), table)
// .orderBy(TArrays_ID())
// .fetch();
//
// assertEquals(3, result.size());
// assertEquals(Integer.valueOf(3), result.getValue(0, TArrays_ID()));
// assertEquals(Integer.valueOf(4), result.getValue(1, TArrays_ID()));
// assertEquals(Integer.valueOf(4), result.getValue(2, TArrays_ID()));
//
// assertEquals("a", result.getValue(0, 1));
// assertEquals("a", result.getValue(1, 1));
// assertEquals("b", result.getValue(2, 1));
break;
assertEquals(3, result.size());
assertEquals(Integer.valueOf(3), result.getValue(0, TArrays_ID()));
assertEquals(Integer.valueOf(4), result.getValue(1, TArrays_ID()));
assertEquals(Integer.valueOf(4), result.getValue(2, TArrays_ID()));
assertEquals("a", result.getValue(0, 1));
assertEquals("a", result.getValue(1, 1));
assertEquals("b", result.getValue(2, 1));
}
// Functions returning arrays
// --------------------------
result = create().select().from(create().table(FArrays1Field(null))).fetch();

View File

@ -101,6 +101,27 @@ class AliasProviderImpl<T extends AliasProvider<T>> extends AbstractNamedQueryPa
context.sql(" ");
context.literal(alias);
// [#756] If the aliased object is an anonymous table (usually an
// unnested array), then field names must be part of the alias
// declaration. For example:
//
// SELECT t.column_value FROM UNNEST(ARRAY[1, 2]) AS t(column_value)
switch (context.getDialect()) {
case HSQLDB:
case POSTGRES: {
if (context.declareTables() && aliasProvider instanceof ArrayTable) {
ArrayTable<?> table = (ArrayTable<?>) aliasProvider;
context.sql("(");
table.getFields().toSQLNames(context);
context.sql(")");
}
break;
}
}
}
else {
context.literal(alias);

View File

@ -60,8 +60,13 @@ class ArrayTable<R extends Record> extends AbstractTable<R> {
private final Field<?> array;
private final FieldList field;
private final String alias;
ArrayTable(Field<?> array) {
this(array, "array_table(COLUMN_VALUE)");
}
ArrayTable(Field<?> array, String alias) {
super("array_table");
Class<?> arrayType;
@ -74,6 +79,7 @@ class ArrayTable<R extends Record> extends AbstractTable<R> {
}
this.array = array;
this.alias = alias;
this.field = new FieldList();
this.field.add(create().field("COLUMN_VALUE", arrayType));
}
@ -85,8 +91,8 @@ class ArrayTable<R extends Record> extends AbstractTable<R> {
}
@Override
public final Table<R> as(String alias) {
return new TableAlias<R>(this, alias);
public final Table<R> as(String as) {
return new TableAlias<R>(new ArrayTable<R>(array, ""), as);
}
@Override
@ -113,11 +119,16 @@ class ArrayTable<R extends Record> extends AbstractTable<R> {
break;
}
// [#756] These dialects need special care when aliasing unnested
// arrays
case HSQLDB:
case POSTGRES: {
context.sql("unnest(").sql(array).sql(")");
if (!StringUtils.isBlank(alias)) {
context.sql(" as ").sql(alias);
}
// [#756] TODO: Handle aliasing correctly
context.sql("unnest(").sql(array).sql(") array_table(COLUMN_VALUE)");
break;
}