[#1506] Allow for inserting empty records (e.g. INSERT INTO .. VALUES () or INSERT INTO .. DEFAULT VALUES)
This commit is contained in:
parent
52e786b0b6
commit
d6aa41d487
@ -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<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, UU, I, IPK, T7
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertDefaultValues() throws Exception {
|
||||
jOOQAbstractTest.reset = false;
|
||||
|
||||
assertEquals(1,
|
||||
create().insertInto(TTriggers())
|
||||
.defaultValues()
|
||||
.execute());
|
||||
|
||||
assertEquals(1, (int) create().fetchOne(selectCount().from(TTriggers())).getValue(0, int.class));
|
||||
assertEquals(1, create().delete(TTriggers()).execute());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertImplicit() throws Exception {
|
||||
jOOQAbstractTest.reset = false;
|
||||
|
||||
@ -1006,6 +1006,11 @@ public abstract class jOOQAbstractTest<
|
||||
new InsertUpdateTests(this).testInsertIdentity();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInsertDefaultValues() throws Exception {
|
||||
new InsertUpdateTests(this).testInsertDefaultValues();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTableMapping() throws Exception {
|
||||
new SchemaAndMappingTests(this).testTableMapping();
|
||||
|
||||
@ -175,6 +175,12 @@ public interface InsertQuery<R extends Record> extends StoreQuery<R>, Insert<R>
|
||||
@Support({ HSQLDB, MARIADB, MYSQL })
|
||||
void addValuesForUpdate(Map<? extends Field<?>, ?> map);
|
||||
|
||||
/**
|
||||
* Set an empty record with the <code>DEFAULT VALUES</code> clause.
|
||||
*/
|
||||
@Support
|
||||
void setDefaultValues();
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>
|
||||
|
||||
@ -122,6 +122,12 @@ public interface InsertSetStep<R extends Record> {
|
||||
@Support
|
||||
InsertValuesStepN<R> values(Collection<?> values);
|
||||
|
||||
/**
|
||||
* Add an empty record with default values.
|
||||
*/
|
||||
@Support
|
||||
InsertReturningStep<R> defaultValues();
|
||||
|
||||
/**
|
||||
* Use a <code>SELECT</code> statement as the source of values for the
|
||||
* <code>INSERT</code> statement.
|
||||
|
||||
@ -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<R extends Record, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>
|
||||
extends AbstractDelegatingQuery<InsertQuery<R>>
|
||||
implements
|
||||
@ -416,6 +419,15 @@ class InsertImpl<R extends Record, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11,
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an empty record with default values.
|
||||
*/
|
||||
@Override
|
||||
public final InsertImpl defaultValues() {
|
||||
getDelegate().setDefaultValues();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final InsertImpl onDuplicateKeyUpdate() {
|
||||
onDuplicateKeyUpdate = true;
|
||||
|
||||
@ -84,6 +84,7 @@ class InsertQueryImpl<R extends Record> extends AbstractStoreQuery<R> implements
|
||||
|
||||
private final FieldMapForUpdate updateMap;
|
||||
private final FieldMapsForInsert insertMaps;
|
||||
private boolean defaultValues;
|
||||
private boolean onDuplicateKeyUpdate;
|
||||
private boolean onDuplicateKeyIgnore;
|
||||
|
||||
@ -137,6 +138,11 @@ class InsertQueryImpl<R extends Record> extends AbstractStoreQuery<R> implements
|
||||
updateMap.set(map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setDefaultValues() {
|
||||
defaultValues = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void addValues(Map<? extends Field<?>, ?> map) {
|
||||
insertMaps.getMap().set(map);
|
||||
@ -387,11 +393,48 @@ class InsertQueryImpl<R extends Record> extends AbstractStoreQuery<R> 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<R extends Record> extends AbstractStoreQuery<R> implements
|
||||
|
||||
@Override
|
||||
public final boolean isExecutable() {
|
||||
return insertMaps.isExecutable();
|
||||
return insertMaps.isExecutable() || defaultValues;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user