[jOOQ/jOOQ#13872] PostgreSQL arrays don't deserialise correctly when

using XML MULTISET emulation
This commit is contained in:
Lukas Eder 2022-08-17 16:49:01 +02:00
parent ba1432a439
commit 6de6e31214
3 changed files with 30 additions and 11 deletions

View File

@ -114,7 +114,11 @@ implements
case HSQLDB:
ctx.visit(when(cardinality(array).ge(index), new Standard()));
if (Boolean.TRUE.equals(ctx.data(DATA_STORE_ASSIGNMENT)))
ctx.visit(new Standard());
else
ctx.visit(when(cardinality(array).ge(index), new Standard()));
break;
default:
@ -131,7 +135,15 @@ implements
@Override
public void accept(Context<?> ctx) {
ctx.sql('(').visit(array).sql(')').sql('[').visit(index).sql(']');
// [#13808] When using an array element reference as a store assignment
// target, the parentheses must not be rendered
if (array instanceof TableField || Boolean.TRUE.equals(ctx.data(DATA_STORE_ASSIGNMENT)))
ctx.visit(array).sql('[').visit(index).sql(']');
// [#12480] For expressions the parens might be required
else
ctx.sql('(').visit(array).sql(')').sql('[').visit(index).sql(']');
}
}

View File

@ -83,8 +83,8 @@ import static org.jooq.impl.Tools.flattenEntrySet;
import static org.jooq.impl.Tools.map;
import static org.jooq.impl.Tools.row0;
import static org.jooq.impl.Tools.unqualified;
import static org.jooq.impl.Tools.visitSubquery;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_FORCE_LIMIT_WITH_ORDER_BY;
import static org.jooq.impl.Tools.BooleanDataKey.DATA_STORE_ASSIGNMENT;
import static org.jooq.impl.Tools.SimpleDataKey.DATA_ON_DUPLICATE_KEY_WHERE;
import java.util.ArrayList;
@ -103,6 +103,7 @@ import org.jooq.FieldOrRow;
import org.jooq.FieldOrRowOrSelect;
import org.jooq.GeneratorStatementType;
// ...
import org.jooq.QueryPart;
import org.jooq.RenderContext.CastMode;
import org.jooq.Row;
import org.jooq.SQLDialect;
@ -268,9 +269,7 @@ final class FieldMapForUpdate extends AbstractQueryPartMap<FieldOrRow, FieldOrRo
// [#10523] Simplify special case
if (size == 1) {
ctx.qualify(false, c -> c.visit(row.field(0)))
.sql(" = ");
acceptStoreAssignment(ctx, false, row.field(0));
visitSubquery(ctx, select);
}
else {
@ -287,9 +286,7 @@ final class FieldMapForUpdate extends AbstractQueryPartMap<FieldOrRow, FieldOrRo
}
else {
Row row = removeReadonly(ctx, multiRow);
ctx.qualify(false, c -> c.visit(row))
.sql(" = ");
acceptStoreAssignment(ctx, false, row);
if (multiValue != null) {
@ -325,8 +322,7 @@ final class FieldMapForUpdate extends AbstractQueryPartMap<FieldOrRow, FieldOrRo
// A regular (non-multi-row) update was specified
else {
ctx.qualify(supportsQualify, c -> c.visit(key))
.sql(" = ");
acceptStoreAssignment(ctx, supportsQualify, key);
// [#8479] Emulate WHERE clause using CASE
Condition condition = (Condition) ctx.data(DATA_ON_DUPLICATE_KEY_WHERE);
@ -346,6 +342,11 @@ final class FieldMapForUpdate extends AbstractQueryPartMap<FieldOrRow, FieldOrRo
return ",";
}
private static final void acceptStoreAssignment(Context<?> ctx, boolean qualify, QueryPart target) {
ctx.qualify(qualify, c1 -> c1.data(DATA_STORE_ASSIGNMENT, true, c2 -> c2.visit(target)))
.sql(" = ");
}
private static final void visitSubquery(Context<?> ctx, Select<?> select) {

View File

@ -636,6 +636,12 @@ final class Tools {
*/
DATA_PARSE_ON_CONFLICT,
/**
* [#13808] We're in a store assignment context (e.g.
* <code>UPDATE</code> or assignment statement).
*/
DATA_STORE_ASSIGNMENT,
;
private final boolean resetInSubqueryScope;