From 70dfe83e2a481340ae7b2f7dd5f142f6f9a9675d Mon Sep 17 00:00:00 2001 From: lukaseder Date: Thu, 25 May 2017 15:34:30 +0200 Subject: [PATCH] [#4629] Support INSERT INTO t VALUES with plain SQL tables --- .../org/jooq/impl/AbstractStoreQuery.java | 30 ++++++++++- .../java/org/jooq/impl/FieldMapForInsert.java | 10 ++++ .../org/jooq/impl/FieldMapsForInsert.java | 12 ++--- .../main/java/org/jooq/impl/InsertImpl.java | 50 +++++++++++-------- 4 files changed, 71 insertions(+), 31 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/AbstractStoreQuery.java b/jOOQ/src/main/java/org/jooq/impl/AbstractStoreQuery.java index 21d3e0f4ea..984378ebda 100644 --- a/jOOQ/src/main/java/org/jooq/impl/AbstractStoreQuery.java +++ b/jOOQ/src/main/java/org/jooq/impl/AbstractStoreQuery.java @@ -37,6 +37,8 @@ package org.jooq.impl; import java.util.Map; import org.jooq.Configuration; +import org.jooq.Context; +import org.jooq.DataType; import org.jooq.Field; import org.jooq.Record; import org.jooq.StoreQuery; @@ -74,11 +76,35 @@ abstract class AbstractStoreQuery extends AbstractDMLQuery @Override public final void addValue(Field field, T value) { - getValues().put(field, Tools.field(value, field)); + if (field == null) + addValue(new UnknownField(getValues().size()), value); + else + getValues().put(field, Tools.field(value, field)); } @Override public final void addValue(Field field, Field value) { - getValues().put(field, Tools.field(value, field)); + if (field == null) + addValue(new UnknownField(getValues().size()), value); + else + getValues().put(field, Tools.field(value, field)); + } + + static class UnknownField extends AbstractField { + + /** + * Generated UID + */ + private static final long serialVersionUID = -8950654583203020935L; + + @SuppressWarnings({ "rawtypes", "unchecked" }) + UnknownField(int index) { + super(DSL.name("unknown field " + index), (DataType) SQLDataType.OTHER); + } + + @Override + public void accept(Context ctx) { + ctx.visit(getUnqualifiedName()); + } } } diff --git a/jOOQ/src/main/java/org/jooq/impl/FieldMapForInsert.java b/jOOQ/src/main/java/org/jooq/impl/FieldMapForInsert.java index 33f155fd01..6e5781a5bc 100644 --- a/jOOQ/src/main/java/org/jooq/impl/FieldMapForInsert.java +++ b/jOOQ/src/main/java/org/jooq/impl/FieldMapForInsert.java @@ -43,6 +43,7 @@ import java.util.Map; import org.jooq.Clause; import org.jooq.Context; import org.jooq.Field; +import org.jooq.impl.AbstractStoreQuery.UnknownField; /** * @author Lukas Eder @@ -91,6 +92,15 @@ final class FieldMapForInsert extends AbstractQueryPartMap, Field> { if (size() == 0) return; + // [#4629] Do not generate column lists for unknown columns + unknownFields: { + for (Field field : keySet()) + if (!(field instanceof UnknownField)) + break unknownFields; + + return; + } + boolean indent = (size() > 1); ctx.sql(" ("); diff --git a/jOOQ/src/main/java/org/jooq/impl/FieldMapsForInsert.java b/jOOQ/src/main/java/org/jooq/impl/FieldMapsForInsert.java index 1d03be802d..c912f2faad 100644 --- a/jOOQ/src/main/java/org/jooq/impl/FieldMapsForInsert.java +++ b/jOOQ/src/main/java/org/jooq/impl/FieldMapsForInsert.java @@ -149,12 +149,10 @@ final class FieldMapsForInsert extends AbstractQueryPart { if (map != null) { Select iteration = DSL.using(context.configuration()).select(map.values()); - if (select == null) { + if (select == null) select = iteration; - } - else { + else select = select.unionAll(iteration); - } } } @@ -189,17 +187,15 @@ final class FieldMapsForInsert extends AbstractQueryPart { } public final FieldMapForInsert getMap() { - if (insertMaps.get(index()) == null) { + if (insertMaps.get(index()) == null) insertMaps.set(index(), new FieldMapForInsert()); - } return insertMaps.get(index()); } public final void newRecord() { - if (insertMaps.get(index()) != null) { + if (insertMaps.get(index()) != null) insertMaps.add(null); - } } private final int index() { diff --git a/jOOQ/src/main/java/org/jooq/impl/InsertImpl.java b/jOOQ/src/main/java/org/jooq/impl/InsertImpl.java index 8c625db1f6..c5af3609de 100644 --- a/jOOQ/src/main/java/org/jooq/impl/InsertImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/InsertImpl.java @@ -42,7 +42,6 @@ import static org.jooq.impl.Tools.EMPTY_FIELD; import java.util.Arrays; import java.util.Collection; -import java.util.List; import java.util.Map; import java.util.Optional; @@ -52,9 +51,9 @@ import org.jooq.Condition; import org.jooq.Configuration; import org.jooq.Field; import org.jooq.FieldLike; -import org.jooq.InsertOnDuplicateSetMoreStep; import org.jooq.InsertOnConflictConditionStep; import org.jooq.InsertOnConflictDoUpdateStep; +import org.jooq.InsertOnDuplicateSetMoreStep; import org.jooq.InsertQuery; import org.jooq.InsertResultStep; import org.jooq.InsertSetMoreStep; @@ -87,8 +86,8 @@ import org.jooq.QueryPart; import org.jooq.Record; import org.jooq.Record1; import org.jooq.Result; -import org.jooq.Select; import org.jooq.SQL; +import org.jooq.Select; import org.jooq.Table; /** @@ -273,14 +272,18 @@ class InsertImpl 0 && fields.length != values.length) throw new IllegalArgumentException("The number of values must match the number of fields"); - } getDelegate().newRecord(); - for (int i = 0; i < fields.length; i++) { - addValue(getDelegate(), fields[i], values[i]); - } + if (fields.length == 0) + for (Object value : values) + addValue(getDelegate(), null, value); + else + for (int i = 0; i < fields.length; i++) + addValue(getDelegate(), fields.length > 0 ? fields[i] : null, values[i]); return this; } @@ -293,15 +296,16 @@ class InsertImpl void addValue(InsertQuery delegate, Field field, Object object) { // [#1343] Only convert non-jOOQ objects - if (object instanceof Field) { + if (object instanceof Field) delegate.addValue(field, (Field) object); - } - else if (object instanceof FieldLike) { + else if (object instanceof FieldLike) delegate.addValue(field, ((FieldLike) object).asField()); - } - else { + else if (field != null) delegate.addValue(field, field.getDataType().convert(object)); - } + + // [#4629] Plain SQL INSERT INTO t VALUES (a, b, c) statements don't know the insert columns + else + delegate.addValue(field, (T) object); } @Override @@ -416,16 +420,20 @@ class InsertImpl... values) { - List> values1 = Arrays.asList(values); - if (fields.length != values1.size()) { + + // [#4629] Plain SQL INSERT INTO t VALUES (a, b, c) statements don't know the insert columns + if (fields.length > 0 && fields.length != values.length) throw new IllegalArgumentException("The number of values must match the number of fields"); - } getDelegate().newRecord(); - for (int i = 0; i < fields.length; i++) { - // javac has trouble when inferring Object for T. Use Void instead - getDelegate().addValue((Field) fields[i], (Field) values1.get(i)); - } + + // javac has trouble when inferring Object for T. Use Void instead + if (fields.length == 0) + for (Field value : values) + getDelegate().addValue((Field) null, (Field) value); + else + for (int i = 0; i < fields.length; i++) + getDelegate().addValue((Field) fields[i], (Field) values[i]); return this; }