[jOOQ/jOOQ#13181] MULTISET emulation using SQL/XML doesn't correctly distinguish between NULL and ''

This commit is contained in:
Lukas Eder 2022-03-02 15:42:10 +01:00
parent 4f53a60c01
commit 54f2538ae9
2 changed files with 18 additions and 5 deletions

View File

@ -44,6 +44,7 @@ import static java.lang.Boolean.TRUE;
import static org.jooq.SQLDialect.POSTGRES;
import static org.jooq.SQLDialect.YUGABYTEDB;
import static org.jooq.impl.DSL.function;
import static org.jooq.impl.DSL.inline;
import static org.jooq.impl.DSL.jsonArray;
import static org.jooq.impl.DSL.jsonArrayAgg;
import static org.jooq.impl.DSL.jsonEntry;
@ -53,7 +54,9 @@ import static org.jooq.impl.DSL.jsonbArrayAgg;
import static org.jooq.impl.DSL.jsonbObject;
import static org.jooq.impl.DSL.select;
import static org.jooq.impl.DSL.selectFrom;
import static org.jooq.impl.DSL.when;
import static org.jooq.impl.DSL.xmlagg;
import static org.jooq.impl.DSL.xmlattributes;
import static org.jooq.impl.DSL.xmlelement;
import static org.jooq.impl.DSL.xmlserializeContent;
import static org.jooq.impl.JSONArrayAgg.patchOracleArrayAggBug;
@ -411,10 +414,16 @@ final class Multiset<R extends Record> extends AbstractField<Result<R>> implemen
static final XMLAggOrderByStep<XML> xmlaggEmulation(Fields fields, boolean agg) {
return xmlagg(
xmlelement(N_RECORD,
map(fields.fields(), (f, i) -> xmlelement(
fieldNameString(i),
agg ? f : DSL.field(fieldName(i), f.getDataType())
))
map(fields.fields(), (f, i) -> {
Field<?> v = agg ? f : DSL.field(fieldName(i), f.getDataType());
String n = fieldNameString(i);
// [#13181] We must make the '' vs NULL distinction explicit in XML
if (v.getDataType().isString())
return xmlelement(n, xmlattributes(when(v.isNull(), inline("true")).as("xsi:nil")), v);
else
return xmlelement(n, v);
})
)
);
}

View File

@ -216,7 +216,11 @@ final class XMLHandler<R extends Record> extends DefaultHandler {
s.inColumn = true;
DataType<?> t = s.fields.get(s.column).getDataType();
if (!t.isMultiset() && !t.isRecord())
// [#13181] String NULL and '' values cannot be distinguished without xsi:nil
if (t.isString() && !("true".equals(attributes.getValue("xsi:nil"))))
s.values.add("");
else if (!t.isMultiset() && !t.isRecord())
s.values.add(null);
}
}