[jOOQ/jOOQ#11015] Syntax error when data type cannot be inferred from
SQL NULL literals in VALUES()
This commit is contained in:
parent
2b5cc36086
commit
c13e781b8a
@ -103,16 +103,16 @@ import org.jooq.impl.Tools.BooleanDataKey;
|
||||
* @author Lukas Eder
|
||||
*/
|
||||
final class FieldMapsForInsert extends AbstractQueryPart implements UNotYetImplemented {
|
||||
private static final Set<SQLDialect> CASTS_NEEDED = SQLDialect.supportedBy(POSTGRES, YUGABYTEDB);
|
||||
static final Set<SQLDialect> CASTS_NEEDED = SQLDialect.supportedBy(POSTGRES, YUGABYTEDB);
|
||||
|
||||
final Table<?> table;
|
||||
final Map<Field<?>, Field<?>> empty;
|
||||
final Table<?> table;
|
||||
final Map<Field<?>, Field<?>> empty;
|
||||
// Depending on whether embeddable types are allowed, this data structure
|
||||
// needs to be flattened with duplicates removed, prior to consumption
|
||||
// [#2530] [#6124] [#10481] TODO: Refactor and optimise these flattening algorithms
|
||||
final Map<Field<?>, List<Field<?>>> values;
|
||||
int rows;
|
||||
int nextRow = -1;
|
||||
final Map<Field<?>, List<Field<?>>> values;
|
||||
int rows;
|
||||
int nextRow = -1;
|
||||
|
||||
FieldMapsForInsert(Table<?> table) {
|
||||
this.table = table;
|
||||
|
||||
@ -59,6 +59,7 @@ import static org.jooq.SQLDialect.MYSQL;
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.POSTGRES;
|
||||
// ...
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.SQLITE;
|
||||
// ...
|
||||
// ...
|
||||
|
||||
@ -53,6 +53,7 @@ import static org.jooq.SQLDialect.MARIADB;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
// ...
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.POSTGRES;
|
||||
// ...
|
||||
// ...
|
||||
// ...
|
||||
@ -60,6 +61,7 @@ import static org.jooq.SQLDialect.MYSQL;
|
||||
// ...
|
||||
import static org.jooq.conf.ParamType.INLINED;
|
||||
import static org.jooq.impl.DSL.name;
|
||||
import static org.jooq.impl.DSL.row;
|
||||
import static org.jooq.impl.Keywords.K_MULTISET;
|
||||
import static org.jooq.impl.Keywords.K_ROW;
|
||||
import static org.jooq.impl.Keywords.K_STRUCT;
|
||||
@ -69,7 +71,9 @@ import static org.jooq.impl.Keywords.K_VALUES;
|
||||
import static org.jooq.impl.QueryPartListView.wrap;
|
||||
import static org.jooq.impl.SubqueryCharacteristics.DERIVED_TABLE;
|
||||
import static org.jooq.impl.Tools.EMPTY_ROW;
|
||||
import static org.jooq.impl.Tools.anyMatch;
|
||||
import static org.jooq.impl.Tools.isEmpty;
|
||||
import static org.jooq.impl.Tools.isVal;
|
||||
import static org.jooq.impl.Tools.map;
|
||||
import static org.jooq.impl.Tools.visitSubquery;
|
||||
|
||||
@ -101,9 +105,10 @@ implements
|
||||
QOM.Values<R>
|
||||
{
|
||||
|
||||
static final Set<SQLDialect> NO_SUPPORT_VALUES = SQLDialect.supportedUntil(FIREBIRD, MARIADB);
|
||||
static final Set<SQLDialect> REQUIRE_ROWTYPE_CAST = SQLDialect.supportedBy(FIREBIRD);
|
||||
static final Set<SQLDialect> NO_SUPPORT_PARENTHESES = SQLDialect.supportedBy();
|
||||
static final Set<SQLDialect> NO_SUPPORT_VALUES = SQLDialect.supportedUntil(FIREBIRD, MARIADB);
|
||||
static final Set<SQLDialect> REQUIRE_ROWTYPE_CAST = SQLDialect.supportedBy(FIREBIRD);
|
||||
static final Set<SQLDialect> REQUIRE_ROWTYPE_CAST_ON_NULLS = SQLDialect.supportedBy(POSTGRES);
|
||||
static final Set<SQLDialect> NO_SUPPORT_PARENTHESES = SQLDialect.supportedBy();
|
||||
|
||||
private final Row[] rows;
|
||||
private transient DataType<?>[] types;
|
||||
@ -198,6 +203,27 @@ implements
|
||||
return result;
|
||||
}
|
||||
|
||||
private final Row castNullLiteralToRowType(Context<?> ctx, Row row) {
|
||||
if (anyMatch(row.fields(), f -> rendersNullLiteral(ctx, f))) {
|
||||
Field<?>[] result = new Field[row.size()];
|
||||
|
||||
for (int i = 0; i < result.length; i++)
|
||||
if (rendersNullLiteral(ctx, row.field(i)) && rowType()[i].getType() != Object.class)
|
||||
result[i] = row.field(i).cast(rowType()[i]);
|
||||
else
|
||||
result[i] = row.field(i);
|
||||
|
||||
return row(result);
|
||||
}
|
||||
else
|
||||
return row;
|
||||
}
|
||||
|
||||
private final boolean rendersNullLiteral(Context<?> ctx, Field<?> field) {
|
||||
return isVal(field) && ((Val<?>) field).getValue() == null && ((Val<?>) field).isInline(ctx)
|
||||
|| field instanceof NullCondition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void accept(Context<?> ctx) {
|
||||
|
||||
@ -266,7 +292,11 @@ implements
|
||||
|
||||
|
||||
|
||||
ctx.visit(rows[i]);
|
||||
// [#11015] NULL literals of known type should be cast in PostgreSQL in the first row
|
||||
if (i == 0 && ctx.family() == POSTGRES)
|
||||
ctx.visit(castNullLiteralToRowType(ctx, rows[i]));
|
||||
else
|
||||
ctx.visit(rows[i]);
|
||||
}
|
||||
|
||||
if (rows.length > 1)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user