[jOOQ/jOOQ#19137] Support binding a Result value as a MultisetDataType
This includes: - [jOOQ/jOOQ#14462] inline(null, multisetType) doesn't work
This commit is contained in:
parent
3cb53b66aa
commit
efb869e4a3
@ -59,6 +59,7 @@ import org.jooq.Name;
|
||||
import org.jooq.Param;
|
||||
import org.jooq.ParamMode;
|
||||
import org.jooq.QualifiedRecord;
|
||||
import org.jooq.Result;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.conf.ParamType;
|
||||
import org.jooq.impl.DefaultBinding.InternalBinding;
|
||||
@ -109,6 +110,9 @@ abstract class AbstractParam<T> extends AbstractParamX<T> implements SimpleQuery
|
||||
paramName != null
|
||||
? paramName
|
||||
|
||||
: value instanceof Result<?> r
|
||||
? r.fieldsRow().toString()
|
||||
|
||||
// [#3707] Protect value.toString call for certain jOOQ types.
|
||||
: value instanceof QualifiedRecord<?> q
|
||||
? q.getQualifier().getName()
|
||||
|
||||
@ -54,6 +54,8 @@ import static org.jooq.Decfloat.decfloat;
|
||||
import static org.jooq.Decfloat.decfloatOrNull;
|
||||
import static org.jooq.Geography.geography;
|
||||
import static org.jooq.Geometry.geometry;
|
||||
import static org.jooq.JSON.json;
|
||||
import static org.jooq.JSONB.jsonb;
|
||||
// ...
|
||||
// ...
|
||||
// ...
|
||||
@ -92,11 +94,13 @@ import static org.jooq.SQLDialect.SQLITE;
|
||||
import static org.jooq.SQLDialect.TRINO;
|
||||
// ...
|
||||
import static org.jooq.SQLDialect.YUGABYTEDB;
|
||||
import static org.jooq.XML.xml;
|
||||
import static org.jooq.conf.ParamType.INLINED;
|
||||
import static org.jooq.impl.Array.NO_SUPPORT_SQUARE_BRACKETS;
|
||||
import static org.jooq.impl.BlobBinding.readBlob;
|
||||
import static org.jooq.impl.Convert.convert;
|
||||
import static org.jooq.impl.Convert.patchIso8601Timestamp;
|
||||
import static org.jooq.impl.DSL.array;
|
||||
import static org.jooq.impl.DSL.cast;
|
||||
import static org.jooq.impl.DSL.field;
|
||||
import static org.jooq.impl.DSL.inline;
|
||||
@ -118,6 +122,7 @@ import static org.jooq.impl.DefaultDataType.unsupportedDatetimePrecision;
|
||||
import static org.jooq.impl.DefaultExecuteContext.localExecuteContext;
|
||||
import static org.jooq.impl.DefaultExecuteContext.localTargetConnection;
|
||||
import static org.jooq.impl.Internal.arrayType;
|
||||
import static org.jooq.impl.JSONReader.ENCODE_BINARY_AS_HEX;
|
||||
import static org.jooq.impl.Keywords.K_ARRAY;
|
||||
import static org.jooq.impl.Keywords.K_AS;
|
||||
import static org.jooq.impl.Keywords.K_BLOB;
|
||||
@ -276,6 +281,8 @@ import org.jooq.Geography;
|
||||
import org.jooq.Geometry;
|
||||
import org.jooq.JSON;
|
||||
import org.jooq.JSONB;
|
||||
import org.jooq.JSONFormat;
|
||||
import org.jooq.JSONFormat.BinaryFormat;
|
||||
import org.jooq.Package;
|
||||
import org.jooq.Param;
|
||||
// ...
|
||||
@ -295,6 +302,9 @@ import org.jooq.UDT;
|
||||
import org.jooq.UDTField;
|
||||
import org.jooq.UDTRecord;
|
||||
import org.jooq.XML;
|
||||
import org.jooq.XMLFormat;
|
||||
import org.jooq.XMLFormat.ArrayFormat;
|
||||
import org.jooq.XMLFormat.NullFormat;
|
||||
import org.jooq.conf.NestedCollectionEmulation;
|
||||
import org.jooq.exception.ControlFlowSignal;
|
||||
import org.jooq.exception.DataAccessException;
|
||||
@ -4820,13 +4830,68 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
|
||||
|
||||
static final class DefaultResultBinding<U> extends InternalBinding<org.jooq.Result<?>, U> {
|
||||
|
||||
static final JSONFormat JSON_FORMAT_BASE64 = JSONFormat.DEFAULT_FOR_RECORDS.recordFormat(JSONFormat.RecordFormat.ARRAY).nanAsString(true).infinityAsString(true);
|
||||
static final JSONFormat JSON_FORMAT_HEX = JSON_FORMAT_BASE64.binaryFormat(BinaryFormat.HEX);
|
||||
static final XMLFormat XML_FORMAT = XMLFormat.DEFAULT_FOR_RECORDS.recordFormat(XMLFormat.RecordFormat.COLUMN_NAME_ELEMENTS).nullFormat(NullFormat.XSI_NIL).arrayFormat(ArrayFormat.ELEMENTS);
|
||||
|
||||
final DefaultXMLBinding<XML> xmlBinding;
|
||||
final DefaultJSONBinding<JSON> jsonBinding;
|
||||
final DefaultJSONBBinding<JSONB> jsonbBinding;
|
||||
|
||||
DefaultResultBinding(DataType<Result<?>> dataType, Converter<Result<?>, U> converter) {
|
||||
super(dataType, converter);
|
||||
|
||||
xmlBinding = new DefaultXMLBinding<>(SQLDataType.XML, Converters.identity(XML.class));
|
||||
jsonBinding = new DefaultJSONBinding<>(SQLDataType.JSON, Converters.identity(JSON.class));
|
||||
jsonbBinding = new DefaultJSONBBinding<>(SQLDataType.JSONB, Converters.identity(JSONB.class));
|
||||
}
|
||||
|
||||
final JSONFormat jsonFormat(Scope ctx) {
|
||||
return ENCODE_BINARY_AS_HEX.contains(ctx.dialect()) ? JSON_FORMAT_HEX : JSON_FORMAT_BASE64;
|
||||
}
|
||||
|
||||
@Override
|
||||
final void sqlInline0(BindingSQLContext<U> ctx, Result<?> value) throws SQLException {
|
||||
switch (emulateMultiset(ctx.configuration())) {
|
||||
case JSON:
|
||||
jsonBinding.sqlInline0((BindingSQLContext) ctx, json(value.formatJSON(jsonFormat(ctx))));
|
||||
break;
|
||||
|
||||
case JSONB:
|
||||
jsonbBinding.sqlInline0((BindingSQLContext) ctx, jsonb(value.formatJSON(jsonFormat(ctx))));
|
||||
break;
|
||||
|
||||
case XML:
|
||||
xmlBinding.sqlInline0((BindingSQLContext) ctx, xml(value.formatXML(XML_FORMAT)));
|
||||
break;
|
||||
|
||||
case NATIVE:
|
||||
ctx.render().visit(array(map(value, r -> new RowAsField<>(r.valuesRow()))));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new UnsupportedOperationException("Cannot inline a value of type Result using " + emulateMultiset(ctx.configuration()) + " MULTISET emulation.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
final void set0(BindingSetStatementContext<U> ctx, Result<?> value) throws SQLException {
|
||||
throw new UnsupportedOperationException("Cannot bind a value of type Result to a PreparedStatement");
|
||||
switch (emulateMultiset(ctx.configuration())) {
|
||||
case JSON:
|
||||
jsonBinding.set0((BindingSetStatementContext) ctx, json(value.formatJSON(jsonFormat(ctx))));
|
||||
break;
|
||||
|
||||
case JSONB:
|
||||
jsonbBinding.set0((BindingSetStatementContext) ctx, jsonb(value.formatJSON(jsonFormat(ctx))));
|
||||
break;
|
||||
|
||||
case XML:
|
||||
xmlBinding.set0((BindingSetStatementContext) ctx, xml(value.formatXML(XML_FORMAT)));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new UnsupportedOperationException("Cannot bind a value of type Result using " + emulateMultiset(ctx.configuration()) + " MULTISET emulation.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Loading…
Reference in New Issue
Block a user