[#1069] Add support for INSERT INTO table(field1, field2, ...) SELECT syntax - as opposed to the existing INSERT INTO table SELECT
This commit is contained in:
parent
80da298f5e
commit
d249ea6457
@ -287,6 +287,7 @@ public class FactoryProxy implements FactoryOperations, MethodInterceptor {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public final <R extends Record> Insert<R> insertInto(Table<R> into, Select<?> select) {
|
||||
return getDelegate().insertInto(into, select);
|
||||
}
|
||||
|
||||
@ -4395,23 +4395,35 @@ public abstract class jOOQAbstractTest<
|
||||
break;
|
||||
}
|
||||
|
||||
Insert<A> i = create().insertInto(
|
||||
TAuthor(),
|
||||
create().select(vals(
|
||||
1000,
|
||||
val("Lukas")))
|
||||
.select(vals(
|
||||
"Eder",
|
||||
val(new Date(363589200000L)),
|
||||
castNull(Integer.class),
|
||||
nullField)));
|
||||
Insert<A> i =
|
||||
create().insertInto(TAuthor())
|
||||
.select(create().select(vals(
|
||||
1000,
|
||||
val("Lukas")))
|
||||
.select(vals(
|
||||
"Eder",
|
||||
val(new Date(363589200000L)),
|
||||
castNull(Integer.class),
|
||||
nullField)));
|
||||
|
||||
i.execute();
|
||||
assertEquals(1, i.execute());
|
||||
|
||||
A author = create().fetchOne(TAuthor(), TAuthor_FIRST_NAME().equal("Lukas"));
|
||||
assertEquals("Lukas", author.getValue(TAuthor_FIRST_NAME()));
|
||||
assertEquals("Eder", author.getValue(TAuthor_LAST_NAME()));
|
||||
assertEquals(null, author.getValue(TAuthor_YEAR_OF_BIRTH()));
|
||||
A author1 = create().fetchOne(TAuthor(), TAuthor_FIRST_NAME().equal("Lukas"));
|
||||
assertEquals(1000, (int) author1.getValue(TAuthor_ID()));
|
||||
assertEquals("Lukas", author1.getValue(TAuthor_FIRST_NAME()));
|
||||
assertEquals("Eder", author1.getValue(TAuthor_LAST_NAME()));
|
||||
assertEquals(null, author1.getValue(TAuthor_YEAR_OF_BIRTH()));
|
||||
|
||||
// [#1069] Run checks for INSERT INTO t(a, b) SELECT x, y syntax
|
||||
i = create().insertInto(TAuthor(), TAuthor_ID(), TAuthor_LAST_NAME())
|
||||
.select(create().select(vals(1001, "Hesse")));
|
||||
|
||||
assertEquals(1, i.execute());
|
||||
A author2 = create().fetchOne(TAuthor(), TAuthor_LAST_NAME().equal("Hesse"));
|
||||
assertEquals(1001, (int) author2.getValue(TAuthor_ID()));
|
||||
assertEquals(null, author2.getValue(TAuthor_FIRST_NAME()));
|
||||
assertEquals("Hesse", author2.getValue(TAuthor_LAST_NAME()));
|
||||
assertEquals(null, author2.getValue(TAuthor_YEAR_OF_BIRTH()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -416,12 +416,20 @@ public interface FactoryOperations extends Configuration {
|
||||
* Factory create = new Factory();
|
||||
*
|
||||
* create.insertInto(table, create.select(1))
|
||||
* .onDuplicateKeyUpdate()
|
||||
* .set(field1, value1)
|
||||
* .set(field2, value2)
|
||||
* .execute();
|
||||
* </pre></code>
|
||||
*
|
||||
* @deprecated - 2.0.3 - Use any of these methods instead:
|
||||
* <ul>
|
||||
* <li>{@link #insertInto(Table)} and
|
||||
* {@link InsertSetStep#select(Select)}</li> <li>
|
||||
* {@link #insertInto(Table, Field...)} and
|
||||
* {@link InsertValuesStep#select(Select)}</li> <li>
|
||||
* {@link #insertInto(Table, Collection)} and
|
||||
* {@link InsertValuesStep#select(Select)}</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Deprecated
|
||||
@Support
|
||||
<R extends Record> Insert<R> insertInto(Table<R> into, Select<?> select);
|
||||
|
||||
|
||||
@ -99,4 +99,18 @@ public interface InsertSetStep<R extends Record> {
|
||||
*/
|
||||
@Support
|
||||
InsertValuesStep<R> values(Collection<?> values);
|
||||
|
||||
/**
|
||||
* Use a <code>SELECT</code> statement as the source of values for the
|
||||
* <code>INSERT</code> statement
|
||||
* <p>
|
||||
* This variant of the <code>INSERT .. SELECT</code> statement does not
|
||||
* allow for specifying a subset of the fields inserted into. It will insert
|
||||
* into all fields of the table specified in the <code>INTO</code> clause.
|
||||
* Use {@link FactoryOperations#insertInto(Table, Field...)} or
|
||||
* {@link FactoryOperations#insertInto(Table, Collection)} instead, to
|
||||
* define a field set for insertion.
|
||||
*/
|
||||
@Support
|
||||
Insert<R> select(Select<?> select);
|
||||
}
|
||||
|
||||
@ -73,4 +73,17 @@ public interface InsertValuesStep<R extends Record> extends InsertOnDuplicateSte
|
||||
*/
|
||||
@Support
|
||||
InsertValuesStep<R> values(Collection<?> values);
|
||||
|
||||
/**
|
||||
* Use a <code>SELECT</code> statement as the source of values for the
|
||||
* <code>INSERT</code> statement
|
||||
* <p>
|
||||
* This variant of the <code>INSERT .. SELECT</code> statement expects a
|
||||
* select returning exactly as many fields as specified previously in the
|
||||
* <code>INTO</code> clause:
|
||||
* {@link FactoryOperations#insertInto(Table, Field...)} or
|
||||
* {@link FactoryOperations#insertInto(Table, Collection)}
|
||||
*/
|
||||
@Support
|
||||
Insert<R> select(Select<?> select);
|
||||
}
|
||||
|
||||
@ -1056,8 +1056,9 @@ public class Factory implements FactoryOperations {
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
@Override
|
||||
@Deprecated
|
||||
public final <R extends Record> Insert<R> insertInto(Table<R> into, Select<?> select) {
|
||||
return new InsertSelectQueryImpl<R>(this, into, select);
|
||||
return new InsertSelectQueryImpl<R>(this, into, into.getFields(), select);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -44,8 +44,10 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.jooq.AttachableInternal;
|
||||
import org.jooq.Configuration;
|
||||
import org.jooq.Field;
|
||||
import org.jooq.Insert;
|
||||
import org.jooq.InsertOnDuplicateSetMoreStep;
|
||||
import org.jooq.InsertQuery;
|
||||
import org.jooq.InsertResultStep;
|
||||
@ -54,6 +56,7 @@ import org.jooq.InsertValuesStep;
|
||||
import org.jooq.Query;
|
||||
import org.jooq.Record;
|
||||
import org.jooq.Result;
|
||||
import org.jooq.Select;
|
||||
import org.jooq.Table;
|
||||
|
||||
/**
|
||||
@ -108,6 +111,12 @@ class InsertImpl<R extends Record>
|
||||
// The DSL API
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public final Insert<R> select(Select<?> select) {
|
||||
Configuration configuration = getDelegate().internalAPI(AttachableInternal.class).getConfiguration();
|
||||
return new InsertSelectQueryImpl<R>(configuration, into, fields, select);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final InsertImpl<R> values(Object... values) {
|
||||
return values0(vals(convert(getFields(), values)));
|
||||
|
||||
@ -55,15 +55,17 @@ class InsertSelectQueryImpl<R extends Record> extends AbstractQuery implements I
|
||||
/**
|
||||
* Generated UID
|
||||
*/
|
||||
private static final long serialVersionUID = -1540775270159018516L;
|
||||
private static final long serialVersionUID = -1540775270159018516L;
|
||||
|
||||
private final Table<?> into;
|
||||
private final Select<?> select;
|
||||
private final Table<?> into;
|
||||
private final List<Field<?>> fields;
|
||||
private final Select<?> select;
|
||||
|
||||
public InsertSelectQueryImpl(Configuration configuration, Table<?> into, Select<?> select) {
|
||||
InsertSelectQueryImpl(Configuration configuration, Table<?> into, List<Field<?>> fields, Select<?> select) {
|
||||
super(configuration);
|
||||
|
||||
this.into = into;
|
||||
this.fields = (fields == null || fields.isEmpty()) ? into.getFields() : fields;
|
||||
this.select = select;
|
||||
}
|
||||
|
||||
@ -77,7 +79,7 @@ class InsertSelectQueryImpl<R extends Record> extends AbstractQuery implements I
|
||||
context.sql("insert into ").sql(into).sql(" (");
|
||||
|
||||
String separator = "";
|
||||
for (Field<?> field : into.getFields()) {
|
||||
for (Field<?> field : fields) {
|
||||
context.sql(separator).literal(field.getName());
|
||||
separator = ", ";
|
||||
}
|
||||
@ -88,7 +90,7 @@ class InsertSelectQueryImpl<R extends Record> extends AbstractQuery implements I
|
||||
@Override
|
||||
public final void bind(BindContext context) {
|
||||
context.bind(into);
|
||||
context.bind(into.getFields());
|
||||
context.bind(fields);
|
||||
context.bind(select);
|
||||
}
|
||||
}
|
||||
|
||||
@ -723,20 +723,20 @@ public class jOOQTest {
|
||||
@Test
|
||||
public void testLikeCondition() throws Exception {
|
||||
Condition c1 = FIELD_NAME1.like("%a%");
|
||||
assertEquals("\"TABLE1\".\"ID1\" like '%a%')", r_refI().render(c1));
|
||||
assertEquals("\"TABLE1\".\"ID1\" like ?)", r_ref().render(c1));
|
||||
assertEquals("\"TABLE1\".\"NAME1\" like '%a%'", r_refI().render(c1));
|
||||
assertEquals("\"TABLE1\".\"NAME1\" like ?", r_ref().render(c1));
|
||||
|
||||
Condition c2 = FIELD_NAME1.notLike("%a%");
|
||||
assertEquals("\"TABLE1\".\"ID1\" not like '%a%')", r_refI().render(c2));
|
||||
assertEquals("\"TABLE1\".\"ID1\" not like ?)", r_ref().render(c2));
|
||||
assertEquals("\"TABLE1\".\"NAME1\" not like '%a%'", r_refI().render(c2));
|
||||
assertEquals("\"TABLE1\".\"NAME1\" not like ?", r_ref().render(c2));
|
||||
|
||||
Condition c3 = FIELD_NAME1.like("%a%", '!');
|
||||
assertEquals("\"TABLE1\".\"ID1\" like '%a%' escape '!')", r_refI().render(c3));
|
||||
assertEquals("\"TABLE1\".\"ID1\" like ? escape '!')", r_ref().render(c3));
|
||||
assertEquals("\"TABLE1\".\"NAME1\" like '%a%' escape '!'", r_refI().render(c3));
|
||||
assertEquals("\"TABLE1\".\"NAME1\" like ? escape '!'", r_ref().render(c3));
|
||||
|
||||
Condition c4 = FIELD_NAME1.notLike("%a%", '!');
|
||||
assertEquals("\"TABLE1\".\"ID1\" not like '%a%' escape '!')", r_refI().render(c4));
|
||||
assertEquals("\"TABLE1\".\"ID1\" not like ? escape '!')", r_ref().render(c4));
|
||||
assertEquals("\"TABLE1\".\"NAME1\" not like '%a%' escape '!'", r_refI().render(c4));
|
||||
assertEquals("\"TABLE1\".\"NAME1\" not like ? escape '!'", r_ref().render(c4));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -1334,12 +1334,24 @@ public class jOOQTest {
|
||||
|
||||
@Test
|
||||
public void testInsertSelect2() throws Exception {
|
||||
Insert<Table1Record> q = create.insertInto(TABLE1, create.selectQuery());
|
||||
Insert<Table1Record> q = create.insertInto(TABLE1).select(create.selectQuery());
|
||||
|
||||
assertEquals("insert into \"TABLE1\" (\"ID1\", \"NAME1\", \"DATE1\") select 1 from dual", r_refI().render(q));
|
||||
assertEquals("insert into \"TABLE1\" (\"ID1\", \"NAME1\", \"DATE1\") select 1 from dual", r_ref().render(q));
|
||||
|
||||
q = create.insertInto(TABLE1, create.select(val(1), FIELD_NAME1).from(TABLE1).where(FIELD_NAME1.equal("abc")));
|
||||
// [#1069] Allow for specifying custom fields
|
||||
q = create.insertInto(TABLE1, FIELD_ID1).select(create.selectQuery());
|
||||
|
||||
assertEquals("insert into \"TABLE1\" (\"ID1\") select 1 from dual", r_refI().render(q));
|
||||
assertEquals("insert into \"TABLE1\" (\"ID1\") select 1 from dual", r_ref().render(q));
|
||||
|
||||
// [#1069] Allow for specifying custom fields
|
||||
q = create.insertInto(TABLE1, FIELD_ID1, FIELD_NAME1).select(create.selectQuery());
|
||||
|
||||
assertEquals("insert into \"TABLE1\" (\"ID1\", \"NAME1\") select 1 from dual", r_refI().render(q));
|
||||
assertEquals("insert into \"TABLE1\" (\"ID1\", \"NAME1\") select 1 from dual", r_ref().render(q));
|
||||
|
||||
q = create.insertInto(TABLE1).select(create.select(val(1), FIELD_NAME1).from(TABLE1).where(FIELD_NAME1.equal("abc")));
|
||||
|
||||
assertEquals("insert into \"TABLE1\" (\"ID1\", \"NAME1\", \"DATE1\") select 1, \"TABLE1\".\"NAME1\" from \"TABLE1\" where \"TABLE1\".\"NAME1\" = 'abc'", r_refI().render(q));
|
||||
assertEquals("insert into \"TABLE1\" (\"ID1\", \"NAME1\", \"DATE1\") select ?, \"TABLE1\".\"NAME1\" from \"TABLE1\" where \"TABLE1\".\"NAME1\" = ?", r_ref().render(q));
|
||||
|
||||
Loading…
Reference in New Issue
Block a user