[#2055] MySQL's UPDATE [t1] JOIN [t2] syntax can cause syntax errors as

column references are not fully qualified
This commit is contained in:
Lukas Eder 2012-12-28 15:39:40 +01:00
parent cf4a9e521d
commit 02f45c6439
4 changed files with 59 additions and 4 deletions

View File

@ -1098,6 +1098,36 @@ extends BaseTest<A, AP, B, S, B2S, BS, L, X, DATE, BOOL, D, T, U, I, IPK, T725,
.fetchOne(c));
}
@Test
public void testUpdateJoin() throws Exception {
switch (getDialect()) {
case DB2:
case DERBY:
case H2:
case HSQLDB:
case ORACLE:
case POSTGRES:
case SQLSERVER:
case SQLITE:
log.info("SKIPPING", "UPDATE T1 JOIN T2 .. integration test. This syntax is not supported by " + getDialect());
return;
}
jOOQAbstractTest.reset = false;
create().update(TBook().join(TAuthor()).on(TBook_AUTHOR_ID().eq(TAuthor_ID())))
.set(TAuthor_LAST_NAME(), "XX")
.set(TBook_TITLE(), "YY")
.where(TBook_ID().eq(1))
.execute();
A author = getAuthor(1);
B book = getBook(1);
assertEquals("XX", author.getValue(TAuthor_LAST_NAME()));
assertEquals("YY", book.getValue(TBook_TITLE()));
}
@Test
public void testTruncate() throws Exception {
jOOQAbstractTest.reset = false;

View File

@ -1307,6 +1307,11 @@ public abstract class jOOQAbstractTest<
new InsertUpdateTests(this).testUpdateSelect();
}
@Test
public void testUpdateJoin() throws Exception {
new InsertUpdateTests(this).testUpdateJoin();
}
@Test
public void testInsertOnDuplicateKeyUpdate() throws Exception {
new InsertUpdateTests(this).testInsertOnDuplicateKeyUpdate();

View File

@ -1631,6 +1631,16 @@ public class Executor implements Configuration {
* .where(field1.greaterThan(100))
* .execute();
* </pre></code>
* <p>
* Note that some databases support table expressions more complex than
* simple table references. In CUBRID and MySQL, for instance, you can write
* <code><pre>
* create.update(t1.join(t2).on(t1.id.eq(t2.id)))
* .set(t1.value, value1)
* .set(t2.value, value2)
* .where(t1.id.eq(10))
* .execute();
* </pre></code>
*/
@Support
public final <R extends Record> UpdateSetFirstStep<R> update(Table<R> table) {

View File

@ -35,6 +35,9 @@
*/
package org.jooq.impl;
import static java.util.Arrays.asList;
import static org.jooq.SQLDialect.POSTGRES;
import static org.jooq.SQLDialect.SQLITE;
import static org.jooq.impl.Factory.val;
import java.util.Map;
@ -61,8 +64,15 @@ class FieldMapForUpdate extends AbstractQueryPartMap<Field<?>, Field<?>> {
if (size() > 0) {
String separator = "";
// [#989] Avoid qualifying fields in INSERT field declaration
boolean qualify = context.qualify();
// [#989] Some dialects do not support qualified column references
// in the UPDATE statement's SET clause
// [#2055] Other dialects require qualified column references to
// disambiguated columns in queries like
// UPDATE t1 JOIN t2 .. SET t1.val = ..., t2.val = ...
boolean restoreQualify = context.qualify();
boolean supportsQualify = asList(POSTGRES, SQLITE).contains(context.getDialect()) ? false : restoreQualify;
for (Entry<Field<?>, Field<?>> entry : entrySet()) {
context.sql(separator);
@ -70,9 +80,9 @@ class FieldMapForUpdate extends AbstractQueryPartMap<Field<?>, Field<?>> {
context.formatNewLine();
}
context.qualify(false)
context.qualify(supportsQualify)
.sql(entry.getKey())
.qualify(qualify)
.qualify(restoreQualify)
.sql(" = ")
.sql(entry.getValue());