You are viewing a plain text version of this content. The canonical link for it is here.
Posted to torque-dev@db.apache.org by tf...@apache.org on 2014/09/16 21:50:42 UTC
svn commit: r1625364 - in /db/torque/torque4/trunk/torque-runtime/src:
main/java/org/apache/torque/adapter/ main/java/org/apache/torque/criteria/
main/java/org/apache/torque/sql/ test/java/org/apache/torque/sql/
Author: tfischer
Date: Tue Sep 16 19:50:41 2014
New Revision: 1625364
URL: http://svn.apache.org/r1625364
Log:
TORQUE-322 provide support for set operations
Modified:
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/adapter/AbstractAdapter.java
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/adapter/Adapter.java
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/adapter/OracleAdapter.java
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Criteria.java
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/SqlEnum.java
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/JoinBuilder.java
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/Query.java
db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/SqlBuilder.java
db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/SqlBuilderTest.java
Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/adapter/AbstractAdapter.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/adapter/AbstractAdapter.java?rev=1625364&r1=1625363&r2=1625364&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/adapter/AbstractAdapter.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/adapter/AbstractAdapter.java Tue Sep 16 19:50:41 2014
@@ -160,7 +160,7 @@ public abstract class AbstractAdapter im
*
* @return The string in a case that can be ignored.
*/
- public String ignoreCaseInOrderBy(String in)
+ public String ignoreCaseInOrderBy(final String in)
{
return ignoreCase(in);
}
@@ -199,7 +199,7 @@ public abstract class AbstractAdapter im
*
* @throws TorqueException if any error occurs when building the query
*/
- public void generateLimits(Query query, long offset, int limit)
+ public void generateLimits(final Query query, final long offset, final int limit)
throws TorqueException
{
if (supportsNativeLimit())
@@ -249,4 +249,19 @@ public abstract class AbstractAdapter im
{
return false;
}
+
+ /**
+ * Whether to use the MINUS operator instead of the EXCEPT operator.
+ *
+ * As most databases do not need to replace the EXCEPT operator
+ * by the MINUS operator, this implementationalways returns
+ * <code>false</code>.
+ * This behaviour can be overwritten in subclasses.
+ *
+ * @return whether to use the MINUS operator instead of the EXCEPT operator.
+ */
+ public boolean useExceptForMinus()
+ {
+ return false;
+ }
}
Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/adapter/Adapter.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/adapter/Adapter.java?rev=1625364&r1=1625363&r2=1625364&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/adapter/Adapter.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/adapter/Adapter.java Tue Sep 16 19:50:41 2014
@@ -219,4 +219,11 @@ public interface Adapter extends Seriali
* @return whether the escape clause should be appended or not.
*/
boolean useEscapeClauseForLike();
+
+ /**
+ * Whether to use the MINUS operator instead of the EXCEPT operator.
+ *
+ * @return whether to use the MINUS operator instead of the EXCEPT operator.
+ */
+ boolean useExceptForMinus();
}
Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/adapter/OracleAdapter.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/adapter/OracleAdapter.java?rev=1625364&r1=1625363&r2=1625364&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/adapter/OracleAdapter.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/adapter/OracleAdapter.java Tue Sep 16 19:50:41 2014
@@ -65,7 +65,7 @@ public class OracleAdapter extends Abstr
* @return The upper case string.
*/
@Override
- public String toUpperCase(String in)
+ public String toUpperCase(final String in)
{
return new StringBuffer("UPPER(").append(in).append(")").toString();
}
@@ -77,7 +77,7 @@ public class OracleAdapter extends Abstr
* @return The string in a case that can be ignored.
*/
@Override
- public String ignoreCase(String in)
+ public String ignoreCase(final String in)
{
return new StringBuffer("UPPER(").append(in).append(")").toString();
}
@@ -105,7 +105,7 @@ public class OracleAdapter extends Abstr
* @see org.apache.torque.adapter.Adapter#getIDMethodSQL(Object)
*/
@Override
- public String getIDMethodSQL(Object sequenceName)
+ public String getIDMethodSQL(final Object sequenceName)
{
return ("select " + sequenceName + ".nextval from dual");
}
@@ -118,7 +118,7 @@ public class OracleAdapter extends Abstr
* @exception SQLException No Statement could be created or executed.
*/
@Override
- public void lockTable(Connection con, String table) throws SQLException
+ public void lockTable(final Connection con, final String table) throws SQLException
{
Statement statement = null;
try
@@ -150,7 +150,7 @@ public class OracleAdapter extends Abstr
* @exception SQLException No Statement could be created or executed.
*/
@Override
- public void unlockTable(Connection con, String table) throws SQLException
+ public void unlockTable(final Connection con, final String table) throws SQLException
{
// Tables in Oracle are unlocked when a commit is issued. The
// user may have issued a commit but do it here to be sure.
@@ -195,7 +195,7 @@ public class OracleAdapter extends Abstr
* @param limit the limit Value
*/
@Override
- public void generateLimits(Query query, long offset, int limit)
+ public void generateLimits(final Query query, final long offset, final int limit)
{
StringBuffer preLimit = new StringBuffer()
.append("SELECT B.* FROM ( ")
@@ -346,4 +346,18 @@ public class OracleAdapter extends Abstr
{
return true;
}
+
+ /**
+ * Whether to use the MINUS operator instead of the EXCEPT operator.
+ *
+ * Oracle needs this, so this implementation always returns
+ * <code>true</code>.
+ *
+ * @return whether to use the MINUS operator instead of the EXCEPT operator.
+ */
+ @Override
+ public boolean useExceptForMinus()
+ {
+ return true;
+ }
}
Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Criteria.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Criteria.java?rev=1625364&r1=1625363&r2=1625364&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Criteria.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/Criteria.java Tue Sep 16 19:50:41 2014
@@ -31,6 +31,7 @@ import java.util.Map;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.torque.Column;
+import org.apache.torque.TorqueRuntimeException;
import org.apache.torque.sql.OrderBy;
import org.apache.torque.sql.Query;
import org.apache.torque.sql.SqlBuilder;
@@ -193,6 +194,10 @@ public class Criteria implements Seriali
/** The JDBC statement fetch size, if any. */
private Integer fetchSize;
+ private SqlEnum setOperator;
+
+ private final List<Criteria> setCriteriaParts;
+
/**
* Constructor.
*/
@@ -206,6 +211,7 @@ public class Criteria implements Seriali
asColumns = new LinkedHashMap<String, Column>();
joins = new ArrayList<Join>();
aliases = new HashMap<String, Object>();
+ setCriteriaParts = new ArrayList<Criteria>();
}
/**
@@ -251,6 +257,41 @@ public class Criteria implements Seriali
offset = toCopy.offset;
aliases = new HashMap<String, Object>(toCopy.aliases);
fetchSize = toCopy.fetchSize;
+ setOperator = toCopy.setOperator;
+ setCriteriaParts = new ArrayList<Criteria>(
+ toCopy.setCriteriaParts.size());
+ for (Criteria setCriteriaPart : toCopy.setCriteriaParts)
+ {
+ setCriteriaParts.add(new Criteria(setCriteriaPart));
+ }
+ }
+
+ /**
+ * Resets this Criteria to its original state.
+ *
+ * @param toCopy the criteria to copy.
+ */
+ protected void clear()
+ {
+ ignoreCase = false;
+ singleRecord = false;
+ selectModifiers.clear();
+ selectColumns.clear();
+ orderByColumns.clear();
+ groupByColumns.clear();
+ fromElements.clear();
+ having = null;
+ forUpdate = false;
+ topLevelCriterion = null;
+ asColumns.clear();
+ joins.clear();
+ dbName = null;
+ limit = -1;
+ offset = 0;
+ aliases.clear();
+ fetchSize = null;
+ setOperator = null;
+ setCriteriaParts.clear();
}
/**
@@ -268,9 +309,13 @@ public class Criteria implements Seriali
* @param clause SQL clause to select from the table
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria addAsColumn(final String name, final Column clause)
{
+ assertNoComposite();
asColumns.put(name, clause);
return this;
}
@@ -302,9 +347,13 @@ public class Criteria implements Seriali
*
* @param alias the alias for the table name.
* @param table the table name as known in the database.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria addAlias(final String alias, final String table)
{
+ assertNoComposite();
aliases.put(alias, table);
return this;
}
@@ -314,9 +363,13 @@ public class Criteria implements Seriali
*
* @param alias the alias for the subselect.
* @param subselect the Criteria for the subselect.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria addAlias(final String alias, final Criteria subselect)
{
+ assertNoComposite();
aliases.put(alias, subselect);
return this;
}
@@ -401,9 +454,13 @@ public class Criteria implements Seriali
* (but this is not resolved here).
*
* @param dbName The Database(Map) name.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public void setDbName(final String dbName)
{
+ assertNoComposite();
this.dbName = dbName;
}
@@ -418,10 +475,15 @@ public class Criteria implements Seriali
* </code>
*
* @param having A Criterion object
+ *
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria addHaving(final Criterion having)
{
+ assertNoComposite();
this.having = having;
return this;
}
@@ -440,9 +502,13 @@ public class Criteria implements Seriali
* Sets that FOR UPDATE clause should be added to the query.
*
* @return this object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria forUpdate()
{
+ assertNoComposite();
forUpdate = true;
return this;
}
@@ -454,9 +520,13 @@ public class Criteria implements Seriali
* false if not.
*
* @return this object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria setForUpdate(final boolean forUpdate)
{
+ assertNoComposite();
this.forUpdate = forUpdate;
return this;
}
@@ -482,10 +552,15 @@ public class Criteria implements Seriali
*
* @param left A String with the left side of the join.
* @param right A String with the right side of the join.
+ *
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria addJoin(final Column left, final Column right)
{
+ assertNoComposite();
return addJoin(left, right, null);
}
@@ -503,12 +578,19 @@ public class Criteria implements Seriali
* @param right A String with the right side of the join.
* @param joinType The operator used for the join: must be one of null,
* Criteria.LEFT_JOIN, Criteria.RIGHT_JOIN, Criteria.INNER_JOIN
+ *
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
- public Criteria addJoin(final Column left, final Column right, final JoinType joinType)
+ public Criteria addJoin(
+ final Column left,
+ final Column right,
+ final JoinType joinType)
{
+ assertNoComposite();
joins.add(new Join(left, right, Criteria.EQUAL, joinType));
-
return this;
}
@@ -533,6 +615,9 @@ public class Criteria implements Seriali
* Criteria.LEFT_JOIN, Criteria.RIGHT_JOIN, Criteria.INNER_JOIN
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria addJoin(
final Column left,
@@ -540,8 +625,8 @@ public class Criteria implements Seriali
final SqlEnum comparison,
final JoinType joinType)
{
+ assertNoComposite();
joins.add(new Join(left, right, comparison, joinType));
-
return this;
}
@@ -569,6 +654,9 @@ public class Criteria implements Seriali
* Criteria.LEFT_JOIN, Criteria.RIGHT_JOIN, Criteria.INNER_JOIN
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria addJoin(
final String leftTable,
@@ -576,12 +664,12 @@ public class Criteria implements Seriali
final Criterion joinCondition,
final JoinType joinType)
{
+ assertNoComposite();
joins.add(new Join(
new PreparedStatementPart(leftTable),
new PreparedStatementPart(rightTable),
joinCondition,
joinType));
-
return this;
}
@@ -609,6 +697,9 @@ public class Criteria implements Seriali
* Criteria.LEFT_JOIN, Criteria.RIGHT_JOIN, Criteria.INNER_JOIN
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria addJoin(
final PreparedStatementPart leftTable,
@@ -616,12 +707,12 @@ public class Criteria implements Seriali
final Criterion joinCondition,
final JoinType joinType)
{
+ assertNoComposite();
joins.add(new Join(
leftTable,
rightTable,
joinCondition,
joinType));
-
return this;
}
@@ -637,17 +728,25 @@ public class Criteria implements Seriali
/**
* Adds "ALL " to the SQL statement.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public void setAll()
{
+ assertNoComposite();
selectModifiers.add(ALL.toString());
}
/**
* Adds "DISTINCT " to the SQL statement.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public void setDistinct()
{
+ assertNoComposite();
selectModifiers.add(DISTINCT.toString());
}
@@ -656,11 +755,22 @@ public class Criteria implements Seriali
* whenever String columns are encountered.
*
* @param ignoreCase True if case should be ignored.
+ *
* @return A modified Criteria object.
*/
public Criteria setIgnoreCase(final boolean ignoreCase)
{
- this.ignoreCase = ignoreCase;
+ if (isComposite())
+ {
+ for (Criteria criteria : setCriteriaParts)
+ {
+ criteria.setIgnoreCase(true);
+ }
+ }
+ else
+ {
+ this.ignoreCase = ignoreCase;
+ }
return this;
}
@@ -777,9 +887,13 @@ public class Criteria implements Seriali
* @param column The select column to add.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria addSelectColumn(final Column column)
{
+ assertNoComposite();
selectColumns.add(column);
return this;
}
@@ -810,9 +924,13 @@ public class Criteria implements Seriali
* @param groupBy The column to group by.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria addGroupByColumn(final Column groupBy)
{
+ assertNoComposite();
groupByColumns.add(groupBy);
return this;
}
@@ -848,7 +966,9 @@ public class Criteria implements Seriali
*
* @return A modified Criteria object.
*/
- public Criteria addAscendingOrderByColumn(final Column column, final boolean ignoreCase)
+ public Criteria addAscendingOrderByColumn(
+ final Column column,
+ final boolean ignoreCase)
{
orderByColumns.add(new OrderBy(column, SqlEnum.ASC, ignoreCase));
return this;
@@ -909,9 +1029,13 @@ public class Criteria implements Seriali
* Adds a table to the from clause, not using a joinType or joinCondition.
*
* @return the modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria addFrom(final String tableName)
{
+ assertNoComposite();
fromElements.add(new FromElement(tableName));
return this;
}
@@ -920,9 +1044,13 @@ public class Criteria implements Seriali
* Adds a new Element to the from clause.
*
* @return the modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria addFrom(final FromElement fromElement)
{
+ assertNoComposite();
fromElements.add(fromElement);
return this;
}
@@ -992,6 +1120,8 @@ public class Criteria implements Seriali
equalsBuilder.append(criteria.asColumns, this.asColumns);
equalsBuilder.append(criteria.joins, this.joins);
equalsBuilder.append(criteria.fetchSize, this.fetchSize);
+ equalsBuilder.append(criteria.setOperator, this.setOperator);
+ equalsBuilder.append(criteria.setCriteriaParts, this.setCriteriaParts);
return equalsBuilder.isEquals();
}
@@ -1018,6 +1148,8 @@ public class Criteria implements Seriali
hashCodeBuilder.append(asColumns);
hashCodeBuilder.append(joins);
hashCodeBuilder.append(fetchSize);
+ hashCodeBuilder.append(setOperator);
+ hashCodeBuilder.append(setCriteriaParts);
return hashCodeBuilder.toHashCode();
}
@@ -1062,9 +1194,13 @@ public class Criteria implements Seriali
* @param criterion A Criterion object.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria and(final Criterion criterion)
{
+ assertNoComposite();
if (topLevelCriterion == null)
{
topLevelCriterion = new Criterion(criterion);
@@ -1101,6 +1237,9 @@ public class Criteria implements Seriali
* literal value.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria and(final Object lValue, final Object rValue)
{
@@ -1134,9 +1273,16 @@ public class Criteria implements Seriali
* to specify the expression manually in the rValue parameter.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
- public Criteria and(final Object lValue, final Object rValue, final SqlEnum comparison)
+ public Criteria and(
+ final Object lValue,
+ final Object rValue,
+ final SqlEnum comparison)
{
+ assertNoComposite();
Criterion newCriterion = new Criterion(lValue, rValue, comparison);
if (topLevelCriterion == null)
{
@@ -1168,8 +1314,15 @@ public class Criteria implements Seriali
* @param day The day to compare to.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
- public Criteria andDate(final Object lValue, final int year, final int month, final int day)
+ public Criteria andDate(
+ final Object lValue,
+ final int year,
+ final int month,
+ final int day)
{
return and(lValue,
new GregorianCalendar(year, month, day).getTime(),
@@ -1196,8 +1349,15 @@ public class Criteria implements Seriali
* @param comparison The comparison operator.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
- public Criteria andDate(final Object lValue, final int year, final int month, final int day,
+ public Criteria andDate(
+ final Object lValue,
+ final int year,
+ final int month,
+ final int day,
final SqlEnum comparison)
{
return and(lValue,
@@ -1222,6 +1382,9 @@ public class Criteria implements Seriali
* @param rValues The values to compare against.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria andIn(final Object lValue, final Object[] rValues)
{
@@ -1245,6 +1408,9 @@ public class Criteria implements Seriali
* @param rValues The values to compare against.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria andIn(final Object lValue, final Collection<?> rValues)
{
@@ -1268,6 +1434,9 @@ public class Criteria implements Seriali
* @param rValues The values to compare against.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria andNotIn(final Object lValue, final Object[] rValues)
{
@@ -1291,6 +1460,9 @@ public class Criteria implements Seriali
* @param rValues The values to compare against.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria andNotIn(final Object lValue, final Collection<?> rValues)
{
@@ -1310,8 +1482,13 @@ public class Criteria implements Seriali
* @param replacements the replacements for the "?" placeholders in SQL.
*
* @return the modified Criteria.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
- public Criteria andVerbatimSql(final String sql, final Object[] replacements)
+ public Criteria andVerbatimSql(
+ final String sql,
+ final Object[] replacements)
{
Criterion criterion
= new Criterion(null, null, null, sql, replacements);
@@ -1338,6 +1515,9 @@ public class Criteria implements Seriali
* @param toAddToFromClause2 a column to add to from clause, may be null.
*
* @return the modified Criteria.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria andVerbatimSql(
final String sql,
@@ -1377,9 +1557,13 @@ public class Criteria implements Seriali
* @param criterion A Criterion object.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria or(final Criterion criterion)
{
+ assertNoComposite();
if (topLevelCriterion == null)
{
topLevelCriterion = new Criterion(criterion);
@@ -1416,6 +1600,9 @@ public class Criteria implements Seriali
* literal value.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria or(final Object lValue, final Object rValue)
{
@@ -1449,9 +1636,16 @@ public class Criteria implements Seriali
* to specify the expression manually in the value parameter.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
- public Criteria or(final Object lValue, final Object rValue, final SqlEnum comparison)
+ public Criteria or(
+ final Object lValue,
+ final Object rValue,
+ final SqlEnum comparison)
{
+ assertNoComposite();
Criterion newCriterion = new Criterion(lValue, rValue, comparison);
if (topLevelCriterion == null)
{
@@ -1483,8 +1677,15 @@ public class Criteria implements Seriali
* @param day The day to compare to.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
- public Criteria orDate(final Object lValue, final int year, final int month, final int day)
+ public Criteria orDate(
+ final Object lValue,
+ final int year,
+ final int month,
+ final int day)
{
return or(lValue,
new GregorianCalendar(year, month, day).getTime(),
@@ -1511,8 +1712,15 @@ public class Criteria implements Seriali
* @param comparison The comparison operator.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
- public Criteria orDate(final Object lValue, final int year, final int month, final int day,
+ public Criteria orDate(
+ final Object lValue,
+ final int year,
+ final int month,
+ final int day,
final SqlEnum comparison)
{
return or(lValue,
@@ -1537,6 +1745,9 @@ public class Criteria implements Seriali
* @param rValues The values to compare against.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria orIn(final Object lValue, final Object[] rValues)
{
@@ -1560,6 +1771,9 @@ public class Criteria implements Seriali
* @param rValues The values to compare against.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria orIn(final Object lValue, final Collection<?> rValues)
{
@@ -1583,6 +1797,9 @@ public class Criteria implements Seriali
* @param rValues The values to compare against.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria orNotIn(final Object lValue, final Object[] rValues)
{
@@ -1606,6 +1823,9 @@ public class Criteria implements Seriali
* @param rValues The values to compare against.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria orNotIn(final Object lValue, final Collection<?> rValues)
{
@@ -1625,6 +1845,9 @@ public class Criteria implements Seriali
* @param replacements the replacements for the "?" placeholders in SQL.
*
* @return the modified Criteria.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria orVerbatimSql(final String sql, final Object[] replacements)
{
@@ -1653,6 +1876,9 @@ public class Criteria implements Seriali
* @param toAddToFromClause2 a column to add to from clause, may be null.
*
* @return the modified Criteria.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria orVerbatimSql(
final String sql,
@@ -1686,6 +1912,9 @@ public class Criteria implements Seriali
* @param criterion A Criterion object.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria where(final Criterion criterion)
{
@@ -1719,6 +1948,9 @@ public class Criteria implements Seriali
* literal value.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria where(final Object lValue, final Object rValue)
{
@@ -1746,8 +1978,14 @@ public class Criteria implements Seriali
* to specify the expression manually in the value parameter.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
- public Criteria where(final Object lValue, final Object rValue, final SqlEnum comparison)
+ public Criteria where(
+ final Object lValue,
+ final Object rValue,
+ final SqlEnum comparison)
{
return and(lValue, rValue, comparison);
}
@@ -1769,8 +2007,15 @@ public class Criteria implements Seriali
* @param day The day to compare to.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
- public Criteria whereDate(final Object lValue, final int year, final int month, final int day)
+ public Criteria whereDate(
+ final Object lValue,
+ final int year,
+ final int month,
+ final int day)
{
return andDate(lValue, year, month, day);
}
@@ -1793,8 +2038,15 @@ public class Criteria implements Seriali
* @param comparison The comparison operator.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
- public Criteria whereDate(final Object lValue, final int year, final int month, final int day,
+ public Criteria whereDate(
+ final Object lValue,
+ final int year,
+ final int month,
+ final int day,
final SqlEnum comparison)
{
return andDate(lValue, year, month, day, comparison);
@@ -1815,6 +2067,9 @@ public class Criteria implements Seriali
* @param rValues The values to compare against.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria whereIn(final Object lValue, final Object[] rValues)
{
@@ -1836,6 +2091,9 @@ public class Criteria implements Seriali
* @param rValues The values to compare against.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria whereIn(final Object lValue, final Collection<?> rValues)
{
@@ -1857,6 +2115,9 @@ public class Criteria implements Seriali
* @param rValues The values to compare against.
*
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria whereNotIn(final Object lValue, final Object[] rValues)
{
@@ -1876,7 +2137,11 @@ public class Criteria implements Seriali
* In all other cases, (e.G. string object), it is interpreted as
* literal value.
* @param rValues The values to compare against.
+ *
* @return A modified Criteria object.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria whereNotIn(final Object lValue, final Collection<?> rValues)
{
@@ -1899,8 +2164,13 @@ public class Criteria implements Seriali
* @param replacements the replacements for the "?" placeholders in SQL.
*
* @return the modified Criteria.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
- public Criteria whereVerbatimSql(final String sql, final Object[] replacements)
+ public Criteria whereVerbatimSql(
+ final String sql,
+ final Object[] replacements)
{
Criterion criterion
= new Criterion(null, null, null, sql, replacements);
@@ -1930,6 +2200,9 @@ public class Criteria implements Seriali
* @param toAddToFromClause2 a column to add to from clause, may be null.
*
* @return the modified Criteria.
+ *
+ * @throws TorqueRuntimeException if this operation is performed on a
+ * Criteria composed of set parts (e.g. union, intersect, except).
*/
public Criteria whereVerbatimSql(
final String sql,
@@ -1946,4 +2219,176 @@ public class Criteria implements Seriali
and(criterion);
return this;
}
+
+ /**
+ * Creates a SQL UNION between this Criteria and the passed other criteria.
+ *
+ * @param other the other part of the union.
+ *
+ * @return the modified Criteria.
+ */
+ public Criteria union(final Criteria other)
+ {
+ appendSetOperation(other, SqlEnum.UNION);
+ return this;
+ }
+
+ /**
+ * Creates a SQL UNION ALL between this Criteria
+ * and the passed other criteria.
+ *
+ * @param other the other part of the union.
+ *
+ * @return the modified Criteria.
+ */
+ public Criteria unionAll(final Criteria other)
+ {
+ appendSetOperation(other, SqlEnum.UNION_ALL);
+ return this;
+ }
+
+ /**
+ * Creates a SQL INTERSECT between this Criteria
+ * and the passed other criteria.
+ *
+ * @param other the other part of the union.
+ *
+ * @return the modified Criteria.
+ */
+ public Criteria intersect(final Criteria other)
+ {
+ appendSetOperation(other, SqlEnum.INTERSECT);
+ return this;
+ }
+
+ /**
+ * Creates a SQL INTERSECT ALL between this Criteria
+ * and the passed other criteria.
+ *
+ * @param other the other part of the union.
+ *
+ * @return the modified Criteria.
+ */
+ public Criteria intersectAll(final Criteria other)
+ {
+ appendSetOperation(other, SqlEnum.INTERSECT_ALL);
+ return this;
+ }
+
+ /**
+ * Creates a SQL EXCEPT between this Criteria
+ * and the passed other criteria.
+ *
+ * @param other the other part of the union.
+ *
+ * @return the modified Criteria.
+ */
+ public Criteria except(final Criteria other)
+ {
+ appendSetOperation(other, SqlEnum.EXCEPT);
+ return this;
+ }
+
+ /**
+ * Creates a SQL EXCEPT between this Criteria
+ * and the passed other criteria.
+ *
+ * @param other the other part of the union.
+ *
+ * @return the modified Criteria.
+ */
+ public Criteria exceptAll(final Criteria other)
+ {
+ appendSetOperation(other, SqlEnum.EXCEPT_ALL);
+ return this;
+ }
+
+ /**
+ * Appends a set operation (union, except, intersect) to this Criteria.
+ * If not already done, this criteria is converted to a composite criteria.
+ *
+ * @param other the other criteria, not null.
+ * @param setOperator the set operator, not null.
+ *
+ * @throws NullPointerException if other or setOperator are null.
+ */
+ protected void appendSetOperation(
+ final Criteria other,
+ final SqlEnum setOperator)
+ {
+ if (other == null)
+ {
+ throw new NullPointerException("other must not be null");
+ }
+ if (setOperator == null)
+ {
+ throw new NullPointerException("setOperator must not be null");
+ }
+ if (isComposite() && this.setOperator.equals(setOperator))
+ {
+ setCriteriaParts.add(other);
+ }
+ else
+ {
+ Criteria copy = new Criteria(this);
+ this.clear();
+ setCriteriaParts.add(copy);
+ setCriteriaParts.add(other);
+ }
+ this.setOperator = setOperator;
+ }
+
+ /**
+ * Return the parts of the criteria which compose a query using
+ * set operations (union, except, intersect).
+ *
+ * @return the parts, not null, empty if this query does not contain set
+ * operations
+ */
+ public List<Criteria> getSetCriteriaParts()
+ {
+ return setCriteriaParts;
+ }
+
+ /**
+ * Returns the operator between the set operations.
+ *
+ * @return the operator, or null if this is not a composite criteria.
+ */
+ public SqlEnum getSetOperator()
+ {
+ return setOperator;
+ }
+
+ /**
+ * Returns whether this Criteria is a composite criteria, i.e. is composed
+ * from more than one Criteria related by set operations
+ * (e.g. union, except, intersect)..
+ *
+ * @return true if the criteria consists of several parts connected
+ * by set operations, false otherwise.
+ */
+ public boolean isComposite()
+ {
+ return !setCriteriaParts.isEmpty();
+ }
+
+ /**
+ * Checks that this Criteria is no composite Criteria, and throws a
+ * TorqueRuntimeException otherwise.
+ *
+ * @throws TorqueRuntimeException if this Criteria is a composite Criteria.
+ */
+ protected void assertNoComposite() throws TorqueRuntimeException
+ {
+ if (isComposite())
+ {
+ throw new TorqueRuntimeException(
+ "This operation cannot be performed "
+ + "on a composite Criteria, which is composed "
+ + "of several set operations."
+ + " Try to perform the operation on the single parts"
+ + " of this Criteria");
+ }
+ }
}
Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/SqlEnum.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/SqlEnum.java?rev=1625364&r1=1625363&r2=1625364&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/SqlEnum.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/criteria/SqlEnum.java Tue Sep 16 19:50:41 2014
@@ -124,10 +124,10 @@ public final class SqlEnum implements ja
/** SQL Expression "DESC". */
public static final SqlEnum DESC =
new SqlEnum("DESC", -1);
- /** SQL Expression " IS NULL ". */
+ /** SQL Expression " IS NULL". */
public static final SqlEnum ISNULL =
new SqlEnum(" IS NULL", 1);
- /** SQL Expression " IS NOT NULL ". */
+ /** SQL Expression " IS NOT NULL". */
public static final SqlEnum ISNOTNULL =
new SqlEnum(" IS NOT NULL", 1);
/** SQL Expression "CURRENT_DATE". */
@@ -148,6 +148,30 @@ public final class SqlEnum implements ja
/** SQL Expression " ESCAPE ". */
public static final SqlEnum ESCAPE =
new SqlEnum(" ESCAPE ", -1);
+ /** SQL Expression " UNION ". */
+ public static final SqlEnum UNION =
+ new SqlEnum(" UNION ", -1);
+ /** SQL Expression " UNION ALL ". */
+ public static final SqlEnum UNION_ALL =
+ new SqlEnum(" UNION ALL ", -1);
+ /** SQL Expression " INTERSECT ". */
+ public static final SqlEnum INTERSECT =
+ new SqlEnum(" INTERSECT ", -1);
+ /** SQL Expression " INTERSECT ALL ". */
+ public static final SqlEnum INTERSECT_ALL =
+ new SqlEnum(" INTERSECT ALL ", -1);
+ /** SQL Expression " EXCEPT ". */
+ public static final SqlEnum EXCEPT =
+ new SqlEnum(" EXCEPT ", -1);
+ /** SQL Expression " EXCEPT ALL ". */
+ public static final SqlEnum EXCEPT_ALL =
+ new SqlEnum(" EXCEPT ALL ", -1);
+ /** SQL Expression " MINUS ". */
+ public static final SqlEnum MINUS =
+ new SqlEnum(" MINUS ", -1);
+ /** SQL Expression " MINUS ALL ". */
+ public static final SqlEnum MINUS_ALL =
+ new SqlEnum(" MINUS ALL ", -1);
/**
* returns whether o is the same SqlEnum as this object.
Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/JoinBuilder.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/JoinBuilder.java?rev=1625364&r1=1625363&r2=1625364&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/JoinBuilder.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/JoinBuilder.java Tue Sep 16 19:50:41 2014
@@ -63,6 +63,11 @@ public final class JoinBuilder
final Query query)
throws TorqueException
{
+ if (criteria.isComposite())
+ {
+ return;
+ }
+
List<Join> criteriaJoins = criteria.getJoins();
if (criteriaJoins.isEmpty())
Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/Query.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/Query.java?rev=1625364&r1=1625363&r2=1625364&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/Query.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/Query.java Tue Sep 16 19:50:41 2014
@@ -171,6 +171,16 @@ public class Query
private Integer fetchSize;
/**
+ * The parts of this query.
+ */
+ private final List<Query> parts = new ArrayList<Query>();
+
+ /**
+ * The Operator connecting the parts of the query.
+ */
+ public String partOperator;
+
+ /**
* Retrieve the modifier buffer in order to add modifiers to this
* query. E.g. DISTINCT and ALL.
*
@@ -252,6 +262,10 @@ public class Query
{
result.addAll(fromElement.getPreparedStatementReplacements());
}
+ for (Query part : parts)
+ {
+ result.addAll(part.getPreparedStatementReplacements());
+ }
result.addAll(whereClausePreparedStatementReplacements);
return Collections.unmodifiableList(result);
}
@@ -492,6 +506,36 @@ public class Query
}
/**
+ * Returns the parts of this query.
+ *
+ * @return a modifiable list containing the parts of this query, not null.
+ */
+ public List<Query> getParts()
+ {
+ return parts;
+ }
+
+ /**
+ * Returns the operator connecting the query parts.
+ *
+ * @return the operator connecting the parts, or null.
+ */
+ public String getPartOperator()
+ {
+ return this.partOperator;
+ }
+
+ /**
+ * Sets the operator connecting the query parts.
+ *
+ * @param partOperator the operator connecting the parts, or null.
+ */
+ public void setPartOperator(final String partOperator)
+ {
+ this.partOperator = partOperator;
+ }
+
+ /**
* Outputs the query statement.
*
* @return A String with the query statement.
@@ -523,89 +567,107 @@ public class Query
.append(" ");
}
- if (Type.SELECT == type)
+ if (parts.isEmpty())
{
- stringBuilder.append(SELECT)
- .append(StringUtils.join(selectModifiers.iterator(), " "))
- .append(StringUtils.join(columns.iterator(), ", "))
- .append(FROM);
- }
- else if (Type.UPDATE == type)
- {
- stringBuilder.append(UPDATE);
- }
- else if (Type.DELETE == type)
- {
- stringBuilder.append(DELETE_FROM);
- }
+ if (Type.SELECT == type)
+ {
+ stringBuilder.append(SELECT)
+ .append(StringUtils.join(selectModifiers.iterator(), " "))
+ .append(StringUtils.join(columns.iterator(), ", "))
+ .append(FROM);
+ }
+ else if (Type.UPDATE == type)
+ {
+ stringBuilder.append(UPDATE);
+ }
+ else if (Type.DELETE == type)
+ {
+ stringBuilder.append(DELETE_FROM);
+ }
- boolean first = true;
- for (Iterator<FromElement> it = fromClause.iterator(); it.hasNext();)
- {
- FromElement fromElement = it.next();
+ boolean first = true;
+ for (Iterator<FromElement> it = fromClause.iterator(); it.hasNext();)
+ {
+ FromElement fromElement = it.next();
+
+ if (!first && fromElement.getJoinCondition() == null)
+ {
+ stringBuilder.append(", ");
+ }
+ first = false;
+ stringBuilder.append(fromElement.toString());
+ }
- if (!first && fromElement.getJoinCondition() == null)
+ if (Type.SELECT == type
+ && (forUpdate != null)
+ && !"FOR UPDATE".equals(forUpdate))
{
- stringBuilder.append(", ");
+ stringBuilder.append(" ").append(forUpdate);
}
- first = false;
- stringBuilder.append(fromElement.toString());
- }
- if (Type.SELECT == type
- && (forUpdate != null)
- && !"FOR UPDATE".equals(forUpdate))
- {
- stringBuilder.append(" ").append(forUpdate);
- }
+ if (Type.UPDATE == type)
+ {
+ stringBuilder.append(SET);
+ first = true;
+ for (Map.Entry<Column, JdbcTypedValue> entry
+ : updateValues.entrySet())
+ {
+ if (!first)
+ {
+ stringBuilder.append(",");
+ }
+ Column column = entry.getKey();
+ String columnName = column.getColumnName();
+ if (columnName == null)
+ {
+ columnName = column.getSqlExpression();
+ }
+ stringBuilder.append(columnName);
+ if (entry.getValue().getSqlExpression() == null)
+ {
+ stringBuilder.append("=?");
+ }
+ else
+ {
+ Column sqlExpression = entry.getValue().getSqlExpression();
+ stringBuilder.append("=")
+ .append(sqlExpression.getSqlExpression());
+ }
+ first = false;
+ }
+ }
- if (Type.UPDATE == type)
+ if (!whereClause.isEmpty())
+ {
+ stringBuilder.append(WHERE)
+ .append(StringUtils.join(whereClause.iterator(), AND));
+ }
+ if (!groupByColumns.isEmpty())
+ {
+ stringBuilder.append(GROUP_BY)
+ .append(StringUtils.join(groupByColumns.iterator(), ", "));
+ }
+ if (having != null)
+ {
+ stringBuilder.append(HAVING)
+ .append(having);
+ }
+ }
+ else
{
- stringBuilder.append(SET);
- first = true;
- for (Map.Entry<Column, JdbcTypedValue> entry
- : updateValues.entrySet())
+ boolean first = true;
+ for (Query part : parts)
{
if (!first)
{
- stringBuilder.append(",");
- }
- Column column = entry.getKey();
- String columnName = column.getColumnName();
- if (columnName == null)
- {
- columnName = column.getSqlExpression();
- }
- stringBuilder.append(columnName);
- if (entry.getValue().getSqlExpression() == null)
- {
- stringBuilder.append("=?");
- }
- else
- {
- Column sqlExpression = entry.getValue().getSqlExpression();
- stringBuilder.append("=")
- .append(sqlExpression.getSqlExpression());
+ stringBuilder.append(partOperator);
}
+ stringBuilder.append('(');
+ part.toStringBuilder(stringBuilder);
+ stringBuilder.append(')');
first = false;
}
}
-
- if (!whereClause.isEmpty())
- {
- stringBuilder.append(WHERE)
- .append(StringUtils.join(whereClause.iterator(), AND));
- }
- if (!groupByColumns.isEmpty())
- {
- stringBuilder.append(GROUP_BY)
- .append(StringUtils.join(groupByColumns.iterator(), ", "));
- }
- if (having != null)
- {
- stringBuilder.append(HAVING)
- .append(having);
- }
if (!orderByColumns.isEmpty())
{
stringBuilder.append(ORDER_BY)
Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/SqlBuilder.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/SqlBuilder.java?rev=1625364&r1=1625363&r2=1625364&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/SqlBuilder.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/sql/SqlBuilder.java Tue Sep 16 19:50:41 2014
@@ -69,9 +69,6 @@ public final class SqlBuilder
public static final String[] FUNCTION_DELIMITERS
= {" ", ",", "(", ")", "<", ">"};
- /** The backslash character*/
- private static final char BACKSLASH = '\\';
-
/**
* The list of WhereClausePsPartBuilders which can build the where clause.
*/
@@ -133,6 +130,7 @@ public final class SqlBuilder
processGroupBy(crit, sqlStatement);
processHaving(crit, sqlStatement);
processOrderBy(crit, sqlStatement);
+ processSetOperations(crit, sqlStatement);
processLimits(crit, sqlStatement);
processFromElements(crit, sqlStatement);
processForUpdate(crit, sqlStatement);
@@ -154,6 +152,10 @@ public final class SqlBuilder
final Query query)
throws TorqueException
{
+ if (criteria.isComposite())
+ {
+ return;
+ }
UniqueList<String> selectClause = query.getSelectClause();
UniqueColumnList selectColumns = criteria.getSelectColumns();
@@ -190,6 +192,10 @@ public final class SqlBuilder
final Query query)
throws TorqueException
{
+ if (criteria.isComposite())
+ {
+ return;
+ }
UniqueList<String> querySelectClause = query.getSelectClause();
Map<String, Column> criteriaAsColumns = criteria.getAsColumns();
@@ -219,6 +225,10 @@ public final class SqlBuilder
final Criteria criteria,
final Query query)
{
+ if (criteria.isComposite())
+ {
+ return;
+ }
UniqueList<String> selectModifiers = query.getSelectModifiers();
UniqueList<String> modifiers = criteria.getSelectModifiers();
for (String modifier : modifiers)
@@ -240,6 +250,10 @@ public final class SqlBuilder
final Query query)
throws TorqueException
{
+ if (criteria.isComposite())
+ {
+ return;
+ }
if (criteria.getTopLevelCriterion() == null)
{
return;
@@ -350,21 +364,21 @@ public final class SqlBuilder
* @throws TorqueException if the OrderBy-Columns can not be processed
*/
private static void processOrderBy(
- final Criteria crit,
+ final Criteria criteria,
final Query query)
throws TorqueException
{
UniqueList<String> orderByClause = query.getOrderByClause();
UniqueList<String> selectClause = query.getSelectClause();
- UniqueList<OrderBy> orderByList = crit.getOrderByColumns();
+ UniqueList<OrderBy> orderByList = criteria.getOrderByColumns();
// Check for each String/Character column and apply
// toUpperCase().
for (OrderBy orderBy : orderByList)
{
Column column = orderBy.getColumn();
- ColumnMap columnMap = MapHelper.getColumnMap(column, crit);
+ ColumnMap columnMap = MapHelper.getColumnMap(column, criteria);
String sqlExpression = column.getSqlExpression();
// Either we are not able to look up the column in the
@@ -377,9 +391,9 @@ public final class SqlBuilder
|| (columnMap.getType() instanceof String
&& sqlExpression.indexOf('(') == -1))
{
- if (orderBy.isIgnoreCase() || crit.isIgnoreCase())
+ if (orderBy.isIgnoreCase() || criteria.isIgnoreCase())
{
- final Adapter adapter = Torque.getAdapter(crit.getDbName());
+ final Adapter adapter = Torque.getAdapter(criteria.getDbName());
orderByClause.add(
adapter.ignoreCaseInOrderBy(sqlExpression)
+ ' ' + orderBy.getOrder());
@@ -389,7 +403,7 @@ public final class SqlBuilder
else
{
orderByClause.add(sqlExpression + ' ' + orderBy.getOrder());
- if (crit.getAsColumns().get(sqlExpression) == null)
+ if (criteria.getAsColumns().get(sqlExpression) == null)
{
selectClause.add(sqlExpression);
}
@@ -398,14 +412,14 @@ public final class SqlBuilder
else
{
orderByClause.add(sqlExpression + ' ' + orderBy.getOrder());
- if (crit.getAsColumns().get(sqlExpression) == null)
+ if (criteria.getAsColumns().get(sqlExpression) == null)
{
selectClause.add(sqlExpression);
}
}
addTableToFromClause(
column,
- crit,
+ criteria,
query);
}
}
@@ -423,6 +437,10 @@ public final class SqlBuilder
final Query query)
throws TorqueException
{
+ if (criteria.isComposite())
+ {
+ return;
+ }
UniqueList<String> groupByClause = query.getGroupByClause();
UniqueList<String> selectClause = query.getSelectClause();
UniqueColumnList groupBy = criteria.getGroupByColumns();
@@ -444,17 +462,22 @@ public final class SqlBuilder
}
/**
- * adds the Having-Columns from the criteria to the query
+ * Adds the Having-Columns from the criteria to the query.
+ *
* @param criteria the criteria from which the Having-Columns are taken
* @param query the query to which the Having-Columns should be added
* @throws TorqueException if the Having-Columns can not be processed
*/
private static void processHaving(
- final Criteria crit,
+ final Criteria criteria,
final Query query)
throws TorqueException
{
- Criterion having = crit.getHaving();
+ if (criteria.isComposite())
+ {
+ return;
+ }
+ Criterion having = criteria.getHaving();
if (having != null)
{
query.setHaving(having.toString());
@@ -471,16 +494,16 @@ public final class SqlBuilder
* @throws TorqueException if the Database adapter cannot be obtained
*/
private static void processLimits(
- final Criteria crit,
+ final Criteria criteria,
final Query query)
throws TorqueException
{
- int limit = crit.getLimit();
- long offset = crit.getOffset();
+ int limit = criteria.getLimit();
+ long offset = criteria.getOffset();
if (offset > 0 || limit >= 0)
{
- Adapter adapter = Torque.getAdapter(crit.getDbName());
+ Adapter adapter = Torque.getAdapter(criteria.getDbName());
adapter.generateLimits(query, offset, limit);
}
}
@@ -496,6 +519,10 @@ public final class SqlBuilder
final Criteria criteria,
final Query query)
{
+ if (criteria.isComposite())
+ {
+ return;
+ }
if (criteria.getFromElements().isEmpty())
{
log.trace("criteria's from Elements is empty,"
@@ -527,6 +554,31 @@ public final class SqlBuilder
}
/**
+ * Adds set operations to the query.
+ *
+ * @param criteria the criteria from which the query should be built.
+ * @param query the query to build.
+ *
+ * @throws TorqueException if the Database adapter cannot be obtained
+ */
+ private static void processSetOperations(
+ final Criteria criteria,
+ final Query query)
+ throws TorqueException
+ {
+ if (!criteria.isComposite())
+ {
+ return;
+ }
+ query.setPartOperator(criteria.getSetOperator().toString());
+ for (Criteria part : criteria.getSetCriteriaParts())
+ {
+ Query queryPart = buildQuery(part);
+ query.getParts().add(queryPart);
+ }
+ }
+
+ /**
* Returns the tablename which can be added to a From Clause.
* This takes care of any aliases that might be defined.
* For example, if an alias "a" for the table AUTHOR is defined
Modified: db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/SqlBuilderTest.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/SqlBuilderTest.java?rev=1625364&r1=1625363&r2=1625364&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/SqlBuilderTest.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/test/java/org/apache/torque/sql/SqlBuilderTest.java Tue Sep 16 19:50:41 2014
@@ -2202,4 +2202,178 @@ public class SqlBuilderTest extends Base
assertEquals(1, query.getPreparedStatementReplacements().size());
assertEquals(1, query.getPreparedStatementReplacements().get(0));
}
+
+
+ public void testUnion() throws Exception
+ {
+ Criteria criteria = new Criteria()
+ .addSelectColumn(new ColumnImpl("table2.column2"))
+ .where(new ColumnImpl("table2.columnb"), 3)
+ .union(new Criteria()
+ .addSelectColumn(new ColumnImpl("table1.column1"))
+ .where(new ColumnImpl("table1.columna"), 1));
+ Query query = SqlBuilder.buildQuery(criteria);
+ assertEquals("(SELECT table2.column2 FROM table2 "
+ + "WHERE table2.columnb=?) "
+ + "UNION (SELECT table1.column1 FROM table1 "
+ + "WHERE table1.columna=?)",
+ query.toString());
+ assertEquals(2, query.getPreparedStatementReplacements().size());
+ assertEquals(3, query.getPreparedStatementReplacements().get(0));
+ assertEquals(1, query.getPreparedStatementReplacements().get(1));
+ }
+
+ public void testUnionAll() throws Exception
+ {
+ Criteria criteria = new Criteria()
+ .addSelectColumn(new ColumnImpl("table2.column2"))
+ .where(new ColumnImpl("table2.columnb"), 3)
+ .unionAll(new Criteria()
+ .addSelectColumn(new ColumnImpl("table1.column1"))
+ .where(new ColumnImpl("table1.columna"), 1));
+ Query query = SqlBuilder.buildQuery(criteria);
+ assertEquals("(SELECT table2.column2 FROM table2 "
+ + "WHERE table2.columnb=?) "
+ + "UNION ALL (SELECT table1.column1 FROM table1 "
+ + "WHERE table1.columna=?)",
+ query.toString());
+ assertEquals(2, query.getPreparedStatementReplacements().size());
+ assertEquals(3, query.getPreparedStatementReplacements().get(0));
+ assertEquals(1, query.getPreparedStatementReplacements().get(1));
+ }
+
+ public void testExcept() throws Exception
+ {
+ Criteria criteria = new Criteria()
+ .addSelectColumn(new ColumnImpl("table2.column2"))
+ .where(new ColumnImpl("table2.columnb"), 3)
+ .except(new Criteria()
+ .addSelectColumn(new ColumnImpl("table1.column1"))
+ .where(new ColumnImpl("table1.columna"), 1));
+ Query query = SqlBuilder.buildQuery(criteria);
+ assertEquals("(SELECT table2.column2 FROM table2 "
+ + "WHERE table2.columnb=?) "
+ + "EXCEPT (SELECT table1.column1 FROM table1 "
+ + "WHERE table1.columna=?)",
+ query.toString());
+ assertEquals(2, query.getPreparedStatementReplacements().size());
+ assertEquals(3, query.getPreparedStatementReplacements().get(0));
+ assertEquals(1, query.getPreparedStatementReplacements().get(1));
+ }
+
+ public void testExceptAll() throws Exception
+ {
+ Criteria criteria = new Criteria()
+ .addSelectColumn(new ColumnImpl("table2.column2"))
+ .where(new ColumnImpl("table2.columnb"), 3)
+ .exceptAll(new Criteria()
+ .addSelectColumn(new ColumnImpl("table1.column1"))
+ .where(new ColumnImpl("table1.columna"), 1));
+ Query query = SqlBuilder.buildQuery(criteria);
+ assertEquals("(SELECT table2.column2 FROM table2 "
+ + "WHERE table2.columnb=?) "
+ + "EXCEPT ALL (SELECT table1.column1 FROM table1 "
+ + "WHERE table1.columna=?)",
+ query.toString());
+ assertEquals(2, query.getPreparedStatementReplacements().size());
+ assertEquals(3, query.getPreparedStatementReplacements().get(0));
+ assertEquals(1, query.getPreparedStatementReplacements().get(1));
+ }
+
+ public void testIntersect() throws Exception
+ {
+ Criteria criteria = new Criteria()
+ .addSelectColumn(new ColumnImpl("table2.column2"))
+ .where(new ColumnImpl("table2.columnb"), 3)
+ .intersect(new Criteria()
+ .addSelectColumn(new ColumnImpl("table1.column1"))
+ .where(new ColumnImpl("table1.columna"), 1));
+ Query query = SqlBuilder.buildQuery(criteria);
+ assertEquals("(SELECT table2.column2 FROM table2 "
+ + "WHERE table2.columnb=?) "
+ + "INTERSECT (SELECT table1.column1 FROM table1 "
+ + "WHERE table1.columna=?)",
+ query.toString());
+ assertEquals(2, query.getPreparedStatementReplacements().size());
+ assertEquals(3, query.getPreparedStatementReplacements().get(0));
+ assertEquals(1, query.getPreparedStatementReplacements().get(1));
+ }
+
+ public void testIntersectAll() throws Exception
+ {
+ Criteria criteria = new Criteria()
+ .addSelectColumn(new ColumnImpl("table2.column2"))
+ .where(new ColumnImpl("table2.columnb"), 3)
+ .intersectAll(new Criteria()
+ .addSelectColumn(new ColumnImpl("table1.column1"))
+ .where(new ColumnImpl("table1.columna"), 1));
+ Query query = SqlBuilder.buildQuery(criteria);
+ assertEquals("(SELECT table2.column2 FROM table2 "
+ + "WHERE table2.columnb=?) "
+ + "INTERSECT ALL (SELECT table1.column1 FROM table1 "
+ + "WHERE table1.columna=?)",
+ query.toString());
+ assertEquals(2, query.getPreparedStatementReplacements().size());
+ assertEquals(3, query.getPreparedStatementReplacements().get(0));
+ assertEquals(1, query.getPreparedStatementReplacements().get(1));
+ }
+
+ public void testUnionOrderByLimitOffset() throws Exception
+ {
+ Criteria criteria = new Criteria()
+ .addSelectColumn(new ColumnImpl("table2.column2"))
+ .where(new ColumnImpl("table2.columnb"), 3)
+ .union(new Criteria()
+ .addSelectColumn(new ColumnImpl("table1.column1"))
+ .where(new ColumnImpl("table1.columna"), 1))
+ .addAscendingOrderByColumn(new ColumnImpl("table2.column2"))
+ .setLimit(10)
+ .setOffset(20);
+ Query query = SqlBuilder.buildQuery(criteria);
+ assertEquals("(SELECT table2.column2 FROM table2 "
+ + "WHERE table2.columnb=?) "
+ + "UNION (SELECT table1.column1 FROM table1 "
+ + "WHERE table1.columna=?)"
+ + " ORDER BY table2.column2 ASC"
+ + " LIMIT 10 OFFSET 20",
+ query.toString());
+ assertEquals(2, query.getPreparedStatementReplacements().size());
+ assertEquals(3, query.getPreparedStatementReplacements().get(0));
+ assertEquals(1, query.getPreparedStatementReplacements().get(1));
+ }
+
+ public void testSetOperationBraces() throws Exception
+ {
+ Criteria criteria = new Criteria()
+ .addSelectColumn(new ColumnImpl("table4.column4"))
+ .where(new ColumnImpl("table4.columnd"), 4);
+ Criteria otherCriteria = new Criteria()
+ .addSelectColumn(new ColumnImpl("table3.column3"))
+ .where(new ColumnImpl("table3.columnc"), 3);
+ criteria.unionAll(otherCriteria);
+ Criteria intersectCriteria = new Criteria()
+ .addSelectColumn(new ColumnImpl("table2.column2"))
+ .where(new ColumnImpl("table2.columnb"), 2);
+ otherCriteria = new Criteria()
+ .addSelectColumn(new ColumnImpl("table1.column1"))
+ .where(new ColumnImpl("table1.columna"), 1);
+ intersectCriteria.unionAll(otherCriteria);
+ criteria.intersect(intersectCriteria);
+
+ Query query = SqlBuilder.buildQuery(criteria);
+ assertEquals("((SELECT table4.column4 FROM table4 "
+ + "WHERE table4.columnd=?) "
+ + "UNION ALL (SELECT table3.column3 FROM table3 "
+ + "WHERE table3.columnc=?))"
+ + " INTERSECT ((SELECT table2.column2 FROM table2 "
+ + "WHERE table2.columnb=?) "
+ + "UNION ALL (SELECT table1.column1 FROM table1 "
+ + "WHERE table1.columna=?))",
+ query.toString());
+ assertEquals(4, query.getPreparedStatementReplacements().size());
+ assertEquals(4, query.getPreparedStatementReplacements().get(0));
+ assertEquals(3, query.getPreparedStatementReplacements().get(1));
+ assertEquals(2, query.getPreparedStatementReplacements().get(2));
+ assertEquals(1, query.getPreparedStatementReplacements().get(3));
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: torque-dev-unsubscribe@db.apache.org
For additional commands, e-mail: torque-dev-help@db.apache.org