From d6aa41d487ed613577e4d2e5478d2151e382ed84 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Tue, 31 Dec 2013 17:38:56 +0100 Subject: [PATCH] [#1506] Allow for inserting empty records (e.g. INSERT INTO .. VALUES () or INSERT INTO .. DEFAULT VALUES) --- .../test/_/testcases/InsertUpdateTests.java | 14 +++++ .../src/org/jooq/test/jOOQAbstractTest.java | 5 ++ jOOQ/src/main/java/org/jooq/InsertQuery.java | 6 ++ .../src/main/java/org/jooq/InsertSetStep.java | 6 ++ .../main/java/org/jooq/impl/InsertImpl.java | 14 ++++- .../java/org/jooq/impl/InsertQueryImpl.java | 55 +++++++++++++++++-- 6 files changed, 93 insertions(+), 7 deletions(-) diff --git a/jOOQ-test/src/org/jooq/test/_/testcases/InsertUpdateTests.java b/jOOQ-test/src/org/jooq/test/_/testcases/InsertUpdateTests.java index 6dc25329a4..db3cadb1ab 100644 --- a/jOOQ-test/src/org/jooq/test/_/testcases/InsertUpdateTests.java +++ b/jOOQ-test/src/org/jooq/test/_/testcases/InsertUpdateTests.java @@ -67,6 +67,7 @@ import static org.jooq.impl.DSL.inline; import static org.jooq.impl.DSL.max; import static org.jooq.impl.DSL.row; import static org.jooq.impl.DSL.select; +import static org.jooq.impl.DSL.selectCount; import static org.jooq.impl.DSL.selectOne; import static org.jooq.impl.DSL.tableByName; import static org.jooq.impl.DSL.trueCondition; @@ -225,6 +226,19 @@ extends BaseTest extends StoreQuery, Insert @Support({ HSQLDB, MARIADB, MYSQL }) void addValuesForUpdate(Map, ?> map); + /** + * Set an empty record with the DEFAULT VALUES clause. + */ + @Support + void setDefaultValues(); + /** * {@inheritDoc} *

diff --git a/jOOQ/src/main/java/org/jooq/InsertSetStep.java b/jOOQ/src/main/java/org/jooq/InsertSetStep.java index 0921f2f56f..5074c72ad8 100644 --- a/jOOQ/src/main/java/org/jooq/InsertSetStep.java +++ b/jOOQ/src/main/java/org/jooq/InsertSetStep.java @@ -122,6 +122,12 @@ public interface InsertSetStep { @Support InsertValuesStepN values(Collection values); + /** + * Add an empty record with default values. + */ + @Support + InsertReturningStep defaultValues(); + /** * Use a SELECT statement as the source of values for the * INSERT statement. diff --git a/jOOQ/src/main/java/org/jooq/impl/InsertImpl.java b/jOOQ/src/main/java/org/jooq/impl/InsertImpl.java index ea7ded7bcc..bf8083b365 100644 --- a/jOOQ/src/main/java/org/jooq/impl/InsertImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/InsertImpl.java @@ -45,6 +45,8 @@ import java.util.Collection; import java.util.List; import java.util.Map; +import javax.annotation.Generated; + import org.jooq.AttachableInternal; import org.jooq.Configuration; import org.jooq.Field; @@ -86,7 +88,8 @@ import org.jooq.Table; /** * @author Lukas Eder */ -@SuppressWarnings({ "rawtypes", "unchecked" }) +@SuppressWarnings({ "rawtypes", "unchecked" }) +@Generated("This class was generated using jOOQ-tools") class InsertImpl extends AbstractDelegatingQuery> implements @@ -416,6 +419,15 @@ class InsertImpl extends AbstractStoreQuery implements private final FieldMapForUpdate updateMap; private final FieldMapsForInsert insertMaps; + private boolean defaultValues; private boolean onDuplicateKeyUpdate; private boolean onDuplicateKeyIgnore; @@ -137,6 +138,11 @@ class InsertQueryImpl extends AbstractStoreQuery implements updateMap.set(map); } + @Override + public final void setDefaultValues() { + defaultValues = true; + } + @Override public final void addValues(Map, ?> map) { insertMaps.getMap().set(map); @@ -387,11 +393,48 @@ class InsertQueryImpl extends AbstractStoreQuery implements .keyword((onDuplicateKeyIgnore && asList(MARIADB, MYSQL).contains(context.configuration().dialect())) ? "ignore " : "") .keyword("into") .sql(" ") - .visit(getInto()) - .sql(" "); - insertMaps.insertMaps.get(0).toSQLReferenceKeys(context); - context.end(INSERT_INSERT_INTO) - .visit(insertMaps); + .visit(getInto()); + + // [#1506] with DEFAULT VALUES, we might not have any columns to render + if (insertMaps.isExecutable()) { + context.sql(" "); + insertMaps.insertMaps.get(0).toSQLReferenceKeys(context); + } + + context.end(INSERT_INSERT_INTO); + + if (defaultValues) { + switch (context.configuration().dialect().family()) { + /* [pro] xx + xxxx xxxx + xxxx xxxxxxx + xx [/pro] */ + + case DERBY: + case MARIADB: + case MYSQL: + context.sql(" ").keyword("values").sql("("); + + int count = getInto().fields().length; + String separator = ""; + + for (int i = 0; i < count; i++) { + context.sql(separator); + context.keyword("default"); + separator = ", "; + } + + context.sql(")"); + break; + + default: + context.sql(" ").keyword("default values"); + break; + } + } + else { + context.visit(insertMaps); + } } private final void bindInsert(BindContext context) { @@ -448,6 +491,6 @@ class InsertQueryImpl extends AbstractStoreQuery implements @Override public final boolean isExecutable() { - return insertMaps.isExecutable(); + return insertMaps.isExecutable() || defaultValues; } }