From 5be3edd310dfe37a67489c31be943a8ef18edf22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Westk=C3=A4mper?= Date: Wed, 25 Jun 2014 21:03:47 +0300 Subject: [PATCH] Throw exception on template expression in batch statements --- .../query/sql/dml/AbstractSQLClause.java | 18 +++++---- .../mysema/query/sql/dml/SQLDeleteClause.java | 26 ++++++------- .../mysema/query/sql/dml/SQLInsertClause.java | 36 +++++++---------- .../mysema/query/sql/dml/SQLMergeClause.java | 37 +++++++++--------- .../mysema/query/sql/dml/SQLUpdateClause.java | 39 +++++++------------ .../sql/teradata/SetQueryBandClause.java | 17 +++++--- .../java/com/mysema/query/DeleteBase.java | 28 +++++++------ .../java/com/mysema/query/InsertBase.java | 7 ++++ .../test/java/com/mysema/query/MergeBase.java | 33 +++++++++------- .../java/com/mysema/query/UpdateBase.java | 28 ++++++------- 10 files changed, 136 insertions(+), 133 deletions(-) diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/AbstractSQLClause.java b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/AbstractSQLClause.java index 771042b6e..d17b266dd 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/AbstractSQLClause.java +++ b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/AbstractSQLClause.java @@ -23,14 +23,8 @@ import java.util.Map; import com.google.common.collect.ImmutableList; import com.mysema.query.QueryMetadata; import com.mysema.query.dml.DMLClause; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.SQLBindings; -import com.mysema.query.sql.SQLListener; -import com.mysema.query.sql.SQLListeners; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.ParamNotSetException; -import com.mysema.query.types.Path; +import com.mysema.query.sql.*; +import com.mysema.query.types.*; /** * AbstractSQLClause is a superclass for SQL based DMLClause implementations @@ -55,6 +49,14 @@ public abstract class AbstractSQLClause> implemen this.useLiterals = configuration.getUseLiterals(); } + protected abstract void assertNoTemplateExpressionsInBatch(); + + protected void assertNoTemplateExpressionInBatch(Expression expr) { + if (expr instanceof TemplateExpression) { + throw new IllegalArgumentException("Template expressions are not allowed in batch statements"); + } + } + /** * @param listener */ diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLDeleteClause.java b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLDeleteClause.java index 937673595..430b13f93 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLDeleteClause.java +++ b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLDeleteClause.java @@ -13,33 +13,23 @@ */ package com.mysema.query.sql.dml; +import javax.annotation.Nonnegative; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; -import javax.annotation.Nonnegative; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.google.common.collect.ImmutableList; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinType; -import com.mysema.query.QueryFlag; +import com.mysema.query.*; import com.mysema.query.QueryFlag.Position; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; import com.mysema.query.dml.DeleteClause; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.RelationalPath; -import com.mysema.query.sql.SQLBindings; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.sql.SQLTemplates; +import com.mysema.query.sql.*; import com.mysema.query.types.Expression; import com.mysema.query.types.Predicate; import com.mysema.query.types.ValidatingVisitor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * SQLDeleteClause defines a DELETE clause @@ -109,6 +99,7 @@ public class SQLDeleteClause extends AbstractSQLClause implemen * @return */ public SQLDeleteClause addBatch() { + assertNoTemplateExpressionsInBatch(); batches.add(metadata); metadata = new DefaultQueryMetadata(); metadata.addJoin(JoinType.DEFAULT, entity); @@ -116,6 +107,11 @@ public class SQLDeleteClause extends AbstractSQLClause implemen return this; } + @Override + protected void assertNoTemplateExpressionsInBatch() { + assertNoTemplateExpressionInBatch(metadata.getWhere()); + } + private PreparedStatement createStatement() throws SQLException{ PreparedStatement stmt; if (batches.isEmpty()) { diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLInsertClause.java b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLInsertClause.java index ece68342b..b7d347a82 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLInsertClause.java +++ b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLInsertClause.java @@ -13,21 +13,13 @@ */ package com.mysema.query.sql.dml; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; +import javax.annotation.Nullable; +import java.sql.*; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; -import javax.annotation.Nullable; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.google.common.collect.ImmutableList; import com.mysema.query.DefaultQueryMetadata; import com.mysema.query.JoinType; @@ -35,20 +27,12 @@ import com.mysema.query.QueryFlag; import com.mysema.query.QueryFlag.Position; import com.mysema.query.QueryMetadata; import com.mysema.query.dml.InsertClause; -import com.mysema.query.sql.AbstractSQLSubQuery; -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.RelationalPath; -import com.mysema.query.sql.SQLBindings; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.sql.SQLTemplates; +import com.mysema.query.sql.*; import com.mysema.query.sql.types.Null; -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ParamExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.SubQueryExpression; +import com.mysema.query.types.*; import com.mysema.util.ResultSetAdapter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * SQLInsertClause defines an INSERT INTO clause @@ -137,6 +121,7 @@ public class SQLInsertClause extends AbstractSQLClause implemen * @return */ public SQLInsertClause addBatch() { + assertNoTemplateExpressionsInBatch(); if (subQueryBuilder != null) { subQuery = subQueryBuilder.list(values.toArray(new Expression[values.size()])); values.clear(); @@ -148,6 +133,13 @@ public class SQLInsertClause extends AbstractSQLClause implemen return this; } + @Override + protected void assertNoTemplateExpressionsInBatch() { + for (Expression expr : values) { + assertNoTemplateExpressionInBatch(expr); + } + } + @Override public SQLInsertClause columns(Path... columns) { this.columns.addAll(Arrays.asList(columns)); diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLMergeClause.java b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLMergeClause.java index a0bffe248..867f456d6 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLMergeClause.java +++ b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLMergeClause.java @@ -13,6 +13,7 @@ */ package com.mysema.query.sql.dml; +import javax.annotation.Nullable; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -21,11 +22,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import javax.annotation.Nullable; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import com.google.common.collect.ImmutableList; import com.mysema.query.DefaultQueryMetadata; import com.mysema.query.JoinType; @@ -33,21 +29,12 @@ import com.mysema.query.QueryFlag; import com.mysema.query.QueryFlag.Position; import com.mysema.query.QueryMetadata; import com.mysema.query.dml.StoreClause; -import com.mysema.query.sql.ColumnMetadata; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.RelationalPath; -import com.mysema.query.sql.SQLBindings; -import com.mysema.query.sql.SQLQuery; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.sql.SQLTemplates; +import com.mysema.query.sql.*; import com.mysema.query.sql.types.Null; -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.ExpressionUtils; -import com.mysema.query.types.NullExpression; -import com.mysema.query.types.Path; -import com.mysema.query.types.SubQueryExpression; +import com.mysema.query.types.*; import com.mysema.util.ResultSetAdapter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * SQLMergeClause defines an MERGE INTO clause @@ -121,6 +108,7 @@ public class SQLMergeClause extends AbstractSQLClause implements * @return */ public SQLMergeClause addBatch() { + assertNoTemplateExpressionsInBatch(); if (!configuration.getTemplates().isNativeMerge()) { throw new IllegalStateException("batch only supported for databases that support native merge"); } @@ -133,6 +121,19 @@ public class SQLMergeClause extends AbstractSQLClause implements return this; } + @Override + protected void assertNoTemplateExpressionsInBatch() { + for (Expression expr : keys) { + assertNoTemplateExpressionInBatch(expr); + } + for (Expression expr : columns) { + assertNoTemplateExpressionInBatch(expr); + } + for (Expression expr : values) { + assertNoTemplateExpressionInBatch(expr); + } + } + public SQLMergeClause columns(Path... columns) { this.columns.addAll(Arrays.asList(columns)); return this; diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLUpdateClause.java b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLUpdateClause.java index a3b89b2d5..ca2e217fa 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLUpdateClause.java +++ b/querydsl-sql/src/main/java/com/mysema/query/sql/dml/SQLUpdateClause.java @@ -13,39 +13,22 @@ */ package com.mysema.query.sql.dml; +import javax.annotation.Nonnegative; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import javax.annotation.Nonnegative; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import java.util.*; import com.google.common.collect.ImmutableList; import com.mysema.commons.lang.Pair; -import com.mysema.query.DefaultQueryMetadata; -import com.mysema.query.JoinType; -import com.mysema.query.QueryFlag; +import com.mysema.query.*; import com.mysema.query.QueryFlag.Position; -import com.mysema.query.QueryMetadata; -import com.mysema.query.QueryModifiers; import com.mysema.query.dml.UpdateClause; -import com.mysema.query.sql.Configuration; -import com.mysema.query.sql.RelationalPath; -import com.mysema.query.sql.SQLBindings; -import com.mysema.query.sql.SQLSerializer; -import com.mysema.query.sql.SQLTemplates; +import com.mysema.query.sql.*; import com.mysema.query.sql.types.Null; -import com.mysema.query.types.ConstantImpl; -import com.mysema.query.types.Expression; -import com.mysema.query.types.Path; -import com.mysema.query.types.Predicate; +import com.mysema.query.types.*; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * SQLUpdateClause defines a UPDATE clause @@ -112,6 +95,7 @@ public class SQLUpdateClause extends AbstractSQLClause implemen * @return */ public SQLUpdateClause addBatch() { + assertNoTemplateExpressionsInBatch(); batches.add(new SQLUpdateBatch(metadata, updates)); updates = new ArrayList,Expression>>(); metadata = new DefaultQueryMetadata(); @@ -119,6 +103,13 @@ public class SQLUpdateClause extends AbstractSQLClause implemen return this; } + protected void assertNoTemplateExpressionsInBatch() { + for (Pair, Expression> pair : updates) { + assertNoTemplateExpressionInBatch(pair.getSecond()); + } + assertNoTemplateExpressionInBatch(metadata.getWhere()); + } + private PreparedStatement createStatement() throws SQLException{ PreparedStatement stmt; if (batches.isEmpty()) { diff --git a/querydsl-sql/src/main/java/com/mysema/query/sql/teradata/SetQueryBandClause.java b/querydsl-sql/src/main/java/com/mysema/query/sql/teradata/SetQueryBandClause.java index 8e7e11fbc..bd4ce8e28 100644 --- a/querydsl-sql/src/main/java/com/mysema/query/sql/teradata/SetQueryBandClause.java +++ b/querydsl-sql/src/main/java/com/mysema/query/sql/teradata/SetQueryBandClause.java @@ -13,6 +13,12 @@ */ package com.mysema.query.sql.teradata; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.List; +import java.util.Map; + import com.google.common.collect.ImmutableList; import com.google.common.collect.Maps; import com.mysema.query.sql.Configuration; @@ -20,12 +26,6 @@ import com.mysema.query.sql.SQLBindings; import com.mysema.query.sql.SQLTemplates; import com.mysema.query.sql.dml.AbstractSQLClause; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.List; -import java.util.Map; - /** * SetQueryBandClause provides support for Teradata specific set query_band executions. * @@ -96,6 +96,11 @@ public class SetQueryBandClause extends AbstractSQLClause { } } + @Override + protected void assertNoTemplateExpressionsInBatch() { + // do nothing + } + @Override public List getSQL() { SQLBindings bindings; diff --git a/querydsl-sql/src/test/java/com/mysema/query/DeleteBase.java b/querydsl-sql/src/test/java/com/mysema/query/DeleteBase.java index 23a86c645..95a2cbfe2 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/DeleteBase.java +++ b/querydsl-sql/src/test/java/com/mysema/query/DeleteBase.java @@ -13,27 +13,22 @@ */ package com.mysema.query; -import static com.mysema.query.Constants.survey; -import static com.mysema.query.Target.CUBRID; -import static com.mysema.query.Target.H2; -import static com.mysema.query.Target.MYSQL; -import static com.mysema.query.Target.ORACLE; -import static com.mysema.query.Target.SQLSERVER; -import static org.junit.Assert.assertEquals; - import java.sql.SQLException; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - import com.mysema.query.sql.SQLSubQuery; import com.mysema.query.sql.dml.SQLDeleteClause; import com.mysema.query.sql.domain.QEmployee; import com.mysema.query.sql.domain.QSurvey; +import com.mysema.query.support.Expressions; import com.mysema.query.types.expr.Param; import com.mysema.testutil.ExcludeIn; import com.mysema.testutil.IncludeIn; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import static com.mysema.query.Constants.survey; +import static com.mysema.query.Target.*; +import static org.junit.Assert.assertEquals; public class DeleteBase extends AbstractBaseTest{ @@ -115,4 +110,13 @@ public class DeleteBase extends AbstractBaseTest{ delete.execute(); } + + @Test(expected=IllegalArgumentException.class) + public void Delete_With_TempateExpression_In_Batch() { + delete(survey) + .where(Expressions.booleanTemplate("true")) + .addBatch(); + } + + } diff --git a/querydsl-sql/src/test/java/com/mysema/query/InsertBase.java b/querydsl-sql/src/test/java/com/mysema/query/InsertBase.java index ebca6ff4e..17b5a6609 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/InsertBase.java +++ b/querydsl-sql/src/test/java/com/mysema/query/InsertBase.java @@ -391,5 +391,12 @@ public class InsertBase extends AbstractBaseTest { clause.execute(); } + @Test(expected=IllegalArgumentException.class) + public void Insert_With_TempateExpression_In_Batch() { + insert(survey) + .set(survey.id, 3) + .set(survey.name, Expressions.stringTemplate("'Hello'")) + .addBatch(); + } } diff --git a/querydsl-sql/src/test/java/com/mysema/query/MergeBase.java b/querydsl-sql/src/test/java/com/mysema/query/MergeBase.java index b0d5491d9..3b3cecca7 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/MergeBase.java +++ b/querydsl-sql/src/test/java/com/mysema/query/MergeBase.java @@ -13,30 +13,23 @@ */ package com.mysema.query; -import static com.mysema.query.Constants.survey; -import static com.mysema.query.Constants.survey2; -import static com.mysema.query.Target.CUBRID; -import static com.mysema.query.Target.DERBY; -import static com.mysema.query.Target.H2; -import static com.mysema.query.Target.POSTGRES; -import static com.mysema.query.Target.SQLSERVER; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - import java.sql.ResultSet; import java.sql.SQLException; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - import com.mysema.query.sql.dml.SQLMergeClause; import com.mysema.query.sql.domain.QSurvey; +import com.mysema.query.support.Expressions; import com.mysema.query.types.Path; import com.mysema.query.types.PathImpl; import com.mysema.testutil.ExcludeIn; import com.mysema.testutil.IncludeIn; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import static com.mysema.query.Constants.survey; +import static com.mysema.query.Constants.survey2; +import static com.mysema.query.Target.*; +import static org.junit.Assert.*; public class MergeBase extends AbstractBaseTest{ @@ -171,4 +164,14 @@ public class MergeBase extends AbstractBaseTest{ // assertEquals(1, insert.execute()); } + @Test(expected=IllegalArgumentException.class) + public void Merge_With_TempateExpression_In_Batch() { + SQLMergeClause merge = merge(survey) + .keys(survey.id) + .set(survey.id, 5) + .set(survey.name, Expressions.stringTemplate("'5'")) + .addBatch(); + } + + } diff --git a/querydsl-sql/src/test/java/com/mysema/query/UpdateBase.java b/querydsl-sql/src/test/java/com/mysema/query/UpdateBase.java index 57b3dbda8..d1c6b15a9 100644 --- a/querydsl-sql/src/test/java/com/mysema/query/UpdateBase.java +++ b/querydsl-sql/src/test/java/com/mysema/query/UpdateBase.java @@ -13,29 +13,24 @@ */ package com.mysema.query; -import static com.mysema.query.Constants.survey; -import static com.mysema.query.Target.CUBRID; -import static com.mysema.query.Target.H2; -import static com.mysema.query.Target.MYSQL; -import static com.mysema.query.Target.ORACLE; -import static com.mysema.query.Target.SQLSERVER; -import static org.junit.Assert.assertEquals; - import java.sql.SQLException; import java.util.Collections; import java.util.List; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - import com.mysema.query.sql.SQLSubQuery; import com.mysema.query.sql.dml.SQLUpdateClause; import com.mysema.query.sql.domain.QEmployee; import com.mysema.query.sql.domain.QSurvey; +import com.mysema.query.support.Expressions; import com.mysema.query.types.Path; import com.mysema.query.types.expr.Param; import com.mysema.testutil.IncludeIn; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import static com.mysema.query.Constants.survey; +import static com.mysema.query.Target.*; +import static org.junit.Assert.assertEquals; public class UpdateBase extends AbstractBaseTest { @@ -56,7 +51,6 @@ public class UpdateBase extends AbstractBaseTest { @Test public void Update() throws SQLException{ - // original state long count = query().from(survey).count(); assertEquals(0, query().from(survey).where(survey.name.eq("S")).count()); @@ -174,4 +168,12 @@ public class UpdateBase extends AbstractBaseTest { update.execute(); } + @Test(expected=IllegalArgumentException.class) + public void Update_With_TempateExpression_In_Batch() { + update(survey) + .set(survey.id, 3) + .set(survey.name, Expressions.stringTemplate("'Hello'")) + .addBatch(); + } + }