You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by ba...@apache.org on 2005/01/07 01:59:43 UTC
svn commit: r124467 - in incubator/derby/code/trunk/java: engine/org/apache/derby/iapi/sql/compile engine/org/apache/derby/iapi/sql/execute engine/org/apache/derby/impl/sql engine/org/apache/derby/impl/sql/compile engine/org/apache/derby/impl/sql/execute engine/org/apache/derby/loc testing/org/apache/derbyTesting/functionTests/master testing/org/apache/derbyTesting/functionTests/suites testing/org/apache/derbyTesting/functionTests/tests/lang
Author: bandaram
Date: Thu Jan 6 16:59:41 2005
New Revision: 124467
URL: http://svn.apache.org/viewcvs?view=rev&rev=124467
Log:
Enhance Derby to support INTERSECT and EXCEPT clauses.
Submitted by Jack Klebanoff (klebanof@Mutagen.Net)
Modified:
incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/C_NodeTypes.java
incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ResultSetFactory.java
incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/build.xml
incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/C_NodeNames.java
incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/NodeFactoryImpl.java
incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OrderByColumn.java
incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java
incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableOperatorNode.java
incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UnionNode.java
incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj
incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericResultSetFactory.java
incubator/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties
incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LOB.out
incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/groupBy.out
incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/derbylang.runall
incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/copyfiles.ant
Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/C_NodeTypes.java
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/C_NodeTypes.java?view=diff&rev=124467&p1=incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/C_NodeTypes.java&r1=124466&p2=incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/C_NodeTypes.java&r2=124467
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/C_NodeTypes.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/C_NodeTypes.java Thu Jan 6 16:59:41 2005
@@ -185,7 +185,8 @@
static final int SUBSTRING_OPERATOR_NODE = 154;
// UNUSED static final int BOOLEAN_NODE = 155;
static final int DROP_ALIAS_NODE = 156;
- // 157 - 185 available
+ static final int INTERSECT_OR_EXCEPT_NODE = 157;
+ // 158 - 185 available
static final int MODIFY_COLUMN_TYPE_NODE = 186;
static final int MODIFY_COLUMN_CONSTRAINT_NODE = 187;
static final int ABSOLUTE_OPERATOR_NODE = 188;
Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ResultSetFactory.java
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ResultSetFactory.java?view=diff&rev=124467&p1=incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ResultSetFactory.java&r1=124466&p2=incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ResultSetFactory.java&r2=124467
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ResultSetFactory.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ResultSetFactory.java Thu Jan 6 16:59:41 2005
@@ -1428,6 +1428,45 @@
throws StandardException;
+ /**
+ * The SetOpResultSet is used to implement an INTERSECT or EXCEPT operation.
+ * It selects rows from two ordered input result sets.
+ *
+ * @param leftSource The result set that implements the left input
+ * @param rightSource The result set that implements the right input
+ * @param activation the activation for this result set
+ * @param resultSetNumber
+ * @param optimizerEstimatedRowCount
+ * @param optimizerEstimatedCost
+ * @param opType IntersectOrExceptNode.INTERSECT_OP or EXCEPT_OP
+ * @param all true if the operation is an INTERSECT ALL or an EXCEPT ALL,
+ * false if the operation is an INTERSECT DISCTINCT or an EXCEPT DISCTINCT
+ * @param closeCleanup a method to be called by close
+ * @param intermediateOrderByColumnsSavedObject The saved object index for the array of order by columns for the
+ * ordering of the left and right sources. That is, both the left and right sources have an order by
+ * clause of the form ORDER BY intermediateOrderByColumns[0],intermediateOrderByColumns[1],...
+ * @param intermediateOrderByDirectionSavedObject The saved object index for the array of source
+ * order by directions. That is, the ordering of the i'th order by column in the input is ascending
+ * if intermediateOrderByDirection[i] is 1, descending if intermediateOrderByDirection[i] is -1.
+ *
+ * @return A ResultSet from which the caller can get the INTERSECT or EXCEPT
+ *
+ * @exception StandardException Thrown on failure
+ */
+ NoPutResultSet getSetOpResultSet( NoPutResultSet leftSource,
+ NoPutResultSet rightSource,
+ Activation activation,
+ int resultSetNumber,
+ long optimizerEstimatedRowCount,
+ double optimizerEstimatedCost,
+ int opType,
+ boolean all,
+ GeneratedMethod closeCleanup,
+ int intermediateOrderByColumnsSavedObject,
+ int intermediateOrderByDirectionSavedObject)
+ throws StandardException;
+
+
//
// Misc operations
//
Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/build.xml
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/build.xml?view=diff&rev=124467&p1=incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/build.xml&r1=124466&p2=incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/build.xml&r2=124467
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/build.xml (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/build.xml Thu Jan 6 16:59:41 2005
@@ -16,6 +16,8 @@
<property file="${properties.dir}/extrapath.properties"/>
<property file="${properties.dir}/compilepath.properties"/>
+ <property name="cur.dir" value="impl/sql"/>
+
<!-- Targets -->
<target name="parser">
<ant antfile="${src.dir}/build.xml" target="genParser">
@@ -42,9 +44,9 @@
<classpath>
<pathelement path="${compile.classpath}"/>
</classpath>
- <include name="${derby.dir}/impl/sql/**"/>
+ <include name="${derby.dir}/${cur.dir}/**"/>
</javac>
- <copy file="catalog/metadata_net.properties" tofile="${out.dir}/org/apache/derby/impl/sql/catalog/metadata_net.properties"/>
+ <copy file="${derby.engine.src.dir}/${derby.dir}/${cur.dir}/catalog/metadata_net.properties" tofile="${out.dir}/org/apache/derby/impl/sql/catalog/metadata_net.properties"/>
</target>
</project>
Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/C_NodeNames.java
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/C_NodeNames.java?view=diff&rev=124467&p1=incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/C_NodeNames.java&r1=124466&p2=incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/C_NodeNames.java&r2=124467
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/C_NodeNames.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/C_NodeNames.java Thu Jan 6 16:59:41 2005
@@ -258,6 +258,8 @@
static final String UNION_NODE_NAME = "org.apache.derby.impl.sql.compile.UnionNode";
+ static final String INTERSECT_OR_EXCEPT_NODE_NAME = "org.apache.derby.impl.sql.compile.IntersectOrExceptNode";
+
static final String UNTYPED_NULL_CONSTANT_NODE_NAME = "org.apache.derby.impl.sql.compile.UntypedNullConstantNode";
static final String UPDATE_NODE_NAME = "org.apache.derby.impl.sql.compile.UpdateNode";
Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/NodeFactoryImpl.java
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/NodeFactoryImpl.java?view=diff&rev=124467&p1=incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/NodeFactoryImpl.java&r1=124466&p2=incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/NodeFactoryImpl.java&r2=124467
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/NodeFactoryImpl.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/NodeFactoryImpl.java Thu Jan 6 16:59:41 2005
@@ -512,6 +512,9 @@
case C_NodeTypes.UNION_NODE:
return C_NodeNames.UNION_NODE_NAME;
+ case C_NodeTypes.INTERSECT_OR_EXCEPT_NODE:
+ return C_NodeNames.INTERSECT_OR_EXCEPT_NODE_NAME;
+
case C_NodeTypes.CREATE_TRIGGER_NODE:
return C_NodeNames.CREATE_TRIGGER_NODE_NAME;
Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OrderByColumn.java
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OrderByColumn.java?view=diff&rev=124467&p1=incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OrderByColumn.java&r1=124466&p2=incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OrderByColumn.java&r2=124467
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OrderByColumn.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OrderByColumn.java Thu Jan 6 16:59:41 2005
@@ -172,7 +172,7 @@
ResultColumnList targetCols = target.getResultColumns();
//bug 5716 - for db2 compatibility - no qualified names allowed in order by clause when union/union all operator is used
- if (target instanceof UnionNode && correlationName != null)
+ if (target instanceof SetOperatorNode && correlationName != null)
{
String fullName = (schemaName != null) ?
(schemaName + "." + correlationName + "." + columnName) :
@@ -207,7 +207,7 @@
* because of the gyrations we go to with building the RCLs
* for a UnionNode.
*/
- if (target instanceof UnionNode)
+ if (target instanceof SetOperatorNode)
{
sourceTableNumber = ((FromTable) target).getTableNumber();
}
Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java?view=diff&rev=124467&p1=incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java&r1=124466&p2=incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java&r2=124467
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java Thu Jan 6 16:59:41 2005
@@ -2025,7 +2025,7 @@
}
/**
- * Set up the result expressions for a UNION:
+ * Set up the result expressions for a UNION, INTERSECT, or EXCEPT:
* o Verify union type compatiblity
* o Get dominant type for result (type + max length + nullability)
* o Create a new ColumnReference with dominant type and name of from this
@@ -2038,14 +2038,16 @@
* @param otherRCL RCL from other side of the UNION.
* @param tableNumber The tableNumber for the UNION.
* @param level The nesting level for the UNION.
+ * @param operatorName "UNION", "INTERSECT", or "EXCEPT"
*
* @return Nothing.
*
* @exception StandardException Thrown on error
*/
public void setUnionResultExpression(ResultColumnList otherRCL,
- int tableNumber,
- int level)
+ int tableNumber,
+ int level,
+ String operatorName)
throws StandardException
{
TableName dummyTN;
@@ -2116,8 +2118,9 @@
!otherExpr.getTypeCompiler().storable(thisTypeId, cf))
{
throw StandardException.newException(SQLState.LANG_NOT_UNION_COMPATIBLE,
- thisTypeId.getSQLTypeName(),
- otherTypeId.getSQLTypeName() );
+ thisTypeId.getSQLTypeName(),
+ otherTypeId.getSQLTypeName(),
+ operatorName);
}
DataTypeDescriptor resultType = thisExpr.getTypeServices().getDominantType(
Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableOperatorNode.java
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableOperatorNode.java?view=diff&rev=124467&p1=incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableOperatorNode.java&r1=124466&p2=incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableOperatorNode.java&r2=124467
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableOperatorNode.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableOperatorNode.java Thu Jan 6 16:59:41 2005
@@ -419,8 +419,8 @@
throws StandardException
{
/*
- ** Parameters not allowed in select list of either side of union,
- ** except when the union is for a table constructor.
+ ** Parameters not allowed in select list of either side of a set operator,
+ ** except when the set operator is for a table constructor.
*/
if ( ! (this instanceof UnionNode) ||
! ((UnionNode) this).tableConstructor())
Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UnionNode.java
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UnionNode.java?view=diff&rev=124467&p1=incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UnionNode.java&r1=124466&p2=incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UnionNode.java&r2=124467
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UnionNode.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/UnionNode.java Thu Jan 6 16:59:41 2005
@@ -20,15 +20,12 @@
package org.apache.derby.impl.sql.compile;
-import org.apache.derby.iapi.services.context.ContextManager;
-
import org.apache.derby.iapi.services.compiler.MethodBuilder;
import org.apache.derby.iapi.services.sanity.SanityManager;
import org.apache.derby.iapi.error.StandardException;
-import org.apache.derby.iapi.sql.compile.CompilerContext;
import org.apache.derby.iapi.sql.compile.Optimizable;
import org.apache.derby.iapi.sql.compile.OptimizablePredicate;
import org.apache.derby.iapi.sql.compile.OptimizablePredicateList;
@@ -37,33 +34,18 @@
import org.apache.derby.iapi.sql.compile.RowOrdering;
import org.apache.derby.iapi.sql.compile.C_NodeTypes;
-import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
-import org.apache.derby.iapi.sql.dictionary.DataDictionary;
-import org.apache.derby.iapi.sql.dictionary.DefaultDescriptor;
-import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
-import org.apache.derby.iapi.types.DataTypeDescriptor;
-
import org.apache.derby.iapi.reference.SQLState;
import org.apache.derby.iapi.reference.ClassName;
-import org.apache.derby.iapi.sql.Activation;
-import org.apache.derby.iapi.types.DataTypeDescriptor;
-import org.apache.derby.iapi.sql.ResultSet;
-import org.apache.derby.iapi.sql.Row;
-
-import org.apache.derby.iapi.types.TypeId;
-
import org.apache.derby.impl.sql.compile.ActivationClassBuilder;
+import org.apache.derby.iapi.types.DataTypeDescriptor;
+
import org.apache.derby.iapi.util.JBitSet;
import org.apache.derby.iapi.services.classfile.VMOpcode;
-import org.apache.derby.catalog.types.DefaultInfoImpl;
-
-import java.util.Properties;
-
/**
* A UnionNode represents a UNION in a DML statement. It contains a boolean
* telling whether the union operation should eliminate duplicate rows.
@@ -71,25 +53,18 @@
* @author Jeff Lichtman
*/
-public class UnionNode extends TableOperatorNode
+public class UnionNode extends SetOperatorNode
{
- /**
- ** Tells whether to eliminate duplicate rows. all == TRUE means do
- ** not eliminate duplicates, all == FALSE means eliminate duplicates.
- */
- boolean all;
+ /* Only optimize it once */
+ /* Only call addNewNodes() once */
+ private boolean addNewNodesCalled;
- /* Is this a UNION ALL generated for a table constructor. */
+ /* Is this a UNION ALL generated for a table constructor -- a VALUES expression with multiple rows. */
boolean tableConstructor;
/* True if this is the top node of a table constructor */
boolean topTableConstructor;
- /* Only optimize a UNION once */
- /* Only call addNewNodes() once */
- private boolean addNewNodesCalled;
-
- private OrderByList orderByList;
/**
* Initializer for a UnionNode.
@@ -111,20 +86,11 @@
Object tableProperties)
throws StandardException
{
- super.init(leftResult, rightResult, tableProperties);
-
- this.all = ((Boolean) all).booleanValue();
+ super.init(leftResult, rightResult, all, tableProperties);
/* Is this a UNION ALL for a table constructor? */
this.tableConstructor = ((Boolean) tableConstructor).booleanValue();
-
- /* resultColumns cannot be null, so we make a copy of the left RCL
- * for now. At bind() time, we need to recopy the list because there
- * may have been a "*" in the list. (We will set the names and
- * column types at that time, as expected.)
- */
- resultColumns = leftResultSet.getResultColumns().copyListAndObjects();
- }
+ } // end of init
/**
* Mark this as the top node of a table constructor.
@@ -422,11 +388,7 @@
{
if (SanityManager.DEBUG)
{
- return "all: " + all + "\n" +
- "tableConstructor: " + tableConstructor + "\n" +
- "orderByList: " +
- (orderByList != null ? orderByList.toString() : "null") + "\n" +
- super.toString();
+ return "tableConstructor: " + tableConstructor + "\n" + super.toString();
}
else
{
@@ -465,33 +427,33 @@
** Step through all the rows in the table constructor to
** get the type of the first non-? in each column.
*/
- DataTypeDescriptor[] types =
+ DataTypeDescriptor[] types =
new DataTypeDescriptor[leftResultSet.getResultColumns().size()];
- ResultSetNode rsn;
- int numTypes = 0;
+ ResultSetNode rsn;
+ int numTypes = 0;
/* By looping through the union nodes, we avoid recursion */
- for (rsn = this; rsn instanceof UnionNode; )
+ for (rsn = this; rsn instanceof SetOperatorNode; )
{
- UnionNode union = (UnionNode) rsn;
+ SetOperatorNode setOperator = (SetOperatorNode) rsn;
/*
** Assume that table constructors are left-deep trees of
- ** UnionNodes with RowResultSet nodes on the right.
+ ** SetOperatorNodes with RowResultSet nodes on the right.
*/
if (SanityManager.DEBUG)
SanityManager.ASSERT(
- union.rightResultSet instanceof RowResultSetNode,
- "A " + union.rightResultSet.getClass().getName() +
- " is on the right side of a union in a table constructor");
+ setOperator.rightResultSet instanceof RowResultSetNode,
+ "A " + setOperator.rightResultSet.getClass().getName() +
+ " is on the right side of a setOperator in a table constructor");
RowResultSetNode rrsn =
- (RowResultSetNode) union.rightResultSet;
+ (RowResultSetNode) setOperator.rightResultSet;
numTypes += getParamColumnTypes(types, rrsn);
- rsn = union.leftResultSet;
+ rsn = setOperator.leftResultSet;
}
/* The last node on the left should be a result set node */
@@ -511,554 +473,20 @@
** nodes, and give them the type from the type array we just
** constructed.
*/
- for (rsn = this; rsn instanceof UnionNode; )
+ for (rsn = this; rsn instanceof SetOperatorNode; )
{
- UnionNode union = (UnionNode) rsn;
- RowResultSetNode rrsn =
- (RowResultSetNode) union.rightResultSet;
+ SetOperatorNode setOperator = (SetOperatorNode) rsn;
+ RowResultSetNode rrsn = (RowResultSetNode) setOperator.rightResultSet;
setParamColumnTypes(types, rrsn);
- rsn = union.leftResultSet;
+ rsn = setOperator.leftResultSet;
}
setParamColumnTypes(types, (RowResultSetNode) rsn);
}
}
- /**
- * Bind the result columns of this ResultSetNode when there is no
- * base table to bind them to. This is useful for SELECT statements,
- * where the result columns get their types from the expressions that
- * live under them.
- *
- * @param fromListParam FromList to use/append to.
- *
- * @return Nothing
- *
- * @exception StandardException Thrown on error
- */
- public void bindResultColumns(FromList fromListParam)
- throws StandardException
- {
- super.bindResultColumns(fromListParam);
-
- /* Now we build our RCL */
- buildRCL();
- }
-
- /**
- * Bind the result columns for this ResultSetNode to a base table.
- * This is useful for INSERT and UPDATE statements, where the
- * result columns get their types from the table being updated or
- * inserted into.
- * If a result column list is specified, then the verification that the
- * result column list does not contain any duplicates will be done when
- * binding them by name.
- *
- * @param targetTableDescriptor The TableDescriptor for the table being
- * updated or inserted into
- * @param targetColumnList For INSERT statements, the user
- * does not have to supply column
- * names (for example, "insert into t
- * values (1,2,3)". When this
- * parameter is null, it means that
- * the user did not supply column
- * names, and so the binding should
- * be done based on order. When it
- * is not null, it means do the binding
- * by name, not position.
- * @param statement Calling DMLStatementNode (Insert or Update)
- * @param fromListParam FromList to use/append to.
- *
- * @return Nothing
- *
- * @exception StandardException Thrown on error
- */
-
- public void bindResultColumns(TableDescriptor targetTableDescriptor,
- FromVTI targetVTI,
- ResultColumnList targetColumnList,
- DMLStatementNode statement,
- FromList fromListParam)
- throws StandardException
- {
- super.bindResultColumns(targetTableDescriptor,
- targetVTI,
- targetColumnList, statement,
- fromListParam);
-
- /* Now we build our RCL */
- buildRCL();
- }
-
- /**
- * Build the RCL for this node. We propagate the RCL up from the
- * left child to form this node's RCL.
- *
- * @return Nothing
- *
- * @exception StandardException Thrown on error
- */
-
- private void buildRCL() throws StandardException
- {
- /* Verify that both sides of the union have the same # of columns in their
- * RCL.
- */
- if (leftResultSet.getResultColumns().size() !=
- rightResultSet.getResultColumns().size())
- {
- throw StandardException.newException(SQLState.LANG_UNION_UNMATCHED_COLUMNS);
- }
-
- /* We need to recreate resultColumns for this node, since there
- * may have been 1 or more *'s in the left's SELECT list.
- */
- resultColumns = leftResultSet.getResultColumns().copyListAndObjects();
-
- /* Create new expressions with the dominant types after verifying
- * union compatibility between left and right sides.
- */
- resultColumns.setUnionResultExpression(rightResultSet.getResultColumns(), tableNumber, level);
- }
-
- /**
- * Bind the result columns of a table constructor to the types in the
- * given ResultColumnList. Use when inserting from a table constructor,
- * and there are nulls in the values clauses.
- *
- * @param rcl The ResultColumnList with the types to bind to
- *
- * @exception StandardException Thrown on error.
- */
- public void bindUntypedNullsToResultColumns(ResultColumnList rcl)
- throws StandardException
- {
- /*
- ** If the RCL from the parent is null, then
- ** the types are coming from the union itself.
- ** So we have to cross check the two child
- ** rcls.
- */
- if (rcl == null)
- {
- ResultColumnList lrcl = rightResultSet.getResultColumns();
- ResultColumnList rrcl = leftResultSet.getResultColumns();
-
- leftResultSet.bindUntypedNullsToResultColumns(rrcl);
- rightResultSet.bindUntypedNullsToResultColumns(lrcl);
- }
- else
- {
- leftResultSet.bindUntypedNullsToResultColumns(rcl);
- rightResultSet.bindUntypedNullsToResultColumns(rcl);
- }
- }
-
- /**
- * Get the parameter types from the given RowResultSetNode into the
- * given array of types. If an array position is already filled in,
- * don't clobber it.
- *
- * @param types The array of types to fill in
- * @param rrsn The RowResultSetNode from which to take the param types
- *
- * @return The number of new types found in the RowResultSetNode
- */
- int getParamColumnTypes(DataTypeDescriptor[] types, RowResultSetNode rrsn)
- {
- int numTypes = 0;
-
- /* Look for columns where we have not found a non-? yet. */
- for (int i = 0; i < types.length; i++)
- {
- if (types[i] == null)
- {
- ResultColumn rc =
- (ResultColumn) rrsn.getResultColumns().elementAt(i);
- if ( ! (rc.getExpression().isParameterNode()))
- {
- types[i] = rc.getExpressionType();
- numTypes++;
- }
- }
- }
-
- return numTypes;
- }
-
- /**
- * Set the type of each ? parameter in the given RowResultSetNode
- * according to its ordinal position in the given array of types.
- *
- * @param types An array of types containing the proper type for each
- * ? parameter, by ordinal position.
- * @param rrsn A RowResultSetNode that could contain ? parameters whose
- * types need to be set.
- *
- * @exception StandardException Thrown on error
- */
- void setParamColumnTypes(DataTypeDescriptor[] types, RowResultSetNode rrsn)
- throws StandardException
- {
- /*
- ** Look for ? parameters in the result column list
- ** of each RowResultSetNode
- */
- ResultColumnList rrcl = rrsn.getResultColumns();
- int rrclSize = rrcl.size();
- for (int index = 0; index < rrclSize; index++)
- {
- ResultColumn rc = (ResultColumn) rrcl.elementAt(index);
-
- if (rc.getExpression().isParameterNode())
- {
- /*
- ** We found a ? - set its type to the type from the
- ** type array.
- */
- ((ParameterNode) rc.getExpression()).setDescriptor(
- types[index]);
- }
- }
- }
-
- /**
- * Bind the expressions in the target list. This means binding the
- * sub-expressions, as well as figuring out what the return type is
- * for each expression. This is useful for EXISTS subqueries, where we
- * need to validate the target list before blowing it away and replacing
- * it with a SELECT true.
- *
- * @return Nothing
- *
- * @exception StandardException Thrown on error
- */
-
- public void bindTargetExpressions(FromList fromListParam)
- throws StandardException
- {
- leftResultSet.bindTargetExpressions(fromListParam);
- rightResultSet.bindTargetExpressions(fromListParam);
- }
-
- /**
- * Push the order by list down from the cursor node
- * into its child result set so that the optimizer
- * has all of the information that it needs to
- * consider sort avoidance.
- *
- * @param orderByList The order by list
- *
- * @return Nothing.
- */
- void pushOrderByList(OrderByList orderByList)
- {
- this.orderByList = orderByList;
- }
-
- /**
- * Put a ProjectRestrictNode on top of each FromTable in the FromList.
- * ColumnReferences must continue to point to the same ResultColumn, so
- * that ResultColumn must percolate up to the new PRN. However,
- * that ResultColumn will point to a new expression, a VirtualColumnNode,
- * which points to the FromTable and the ResultColumn that is the source for
- * the ColumnReference.
- * (The new PRN will have the original of the ResultColumnList and
- * the ResultColumns from that list. The FromTable will get shallow copies
- * of the ResultColumnList and its ResultColumns. ResultColumn.expression
- * will remain at the FromTable, with the PRN getting a new
- * VirtualColumnNode for each ResultColumn.expression.)
- * We then project out the non-referenced columns. If there are no referenced
- * columns, then the PRN's ResultColumnList will consist of a single ResultColumn
- * whose expression is 1.
- *
- * @param numTables Number of tables in the DML Statement
- * @param gbl The group by list, if any
- * @param fromList The from list, if any
- *
- * @return The generated ProjectRestrictNode atop the original FromTable.
- *
- * @exception StandardException Thrown on error
- */
-
- public ResultSetNode preprocess(int numTables,
- GroupByList gbl,
- FromList fromList)
- throws StandardException
- {
- ResultSetNode newTop = this;
-
- /* RESOLVE - what does numTables and referencedTableMap mean here? */
- leftResultSet = leftResultSet.preprocess(numTables, gbl, fromList);
- rightResultSet = rightResultSet.preprocess(numTables, gbl, fromList);
-
- /* Build the referenced table map (left || right) */
- referencedTableMap = (JBitSet) leftResultSet.getReferencedTableMap().clone();
- referencedTableMap.or((JBitSet) rightResultSet.getReferencedTableMap());
-
- /* If this is a UNION without an all and we have
- * an order by then we can consider eliminating the sort for the
- * order by. All of the columns in the order by list must
- * be ascending in order to do this. There are 2 cases:
- * o The order by list is an in order prefix of the columns
- * in the select list. In this case the output of the
- * sort from the distinct will be in the right order
- * so we simply eliminate the order by list.
- * o The order by list is a subset of the columns in the
- * the select list. In this case we need to reorder the
- * columns in the select list so that the ordering columns
- * are an in order prefix of the select list and put a PRN
- * above the select so that the shape of the result set
- * is as expected.
- */
- if ((! all) && orderByList != null && orderByList.allAscending())
- {
- /* Order by list currently restricted to columns in select
- * list, so we will always eliminate the order by here.
- */
- if (orderByList.isInOrderPrefix(resultColumns))
- {
- orderByList = null;
- }
- /* RESOLVE - We currently only eliminate the order by if it is
- * a prefix of the select list. We do not currently do the
- * elimination if the order by is not a prefix because the code
- * doesn't work. The problem has something to do with the
- * fact that we generate additional nodes between the union
- * and the PRN (for reordering that we would generate here)
- * when modifying the access paths. VCNs under the PRN can be
- * seen as correlated since their source resultset is the Union
- * which is no longer the result set directly under them. This
- * causes the wrong code to get generated. (jerry - 11/3/98)
- * (bug 59)
- */
- }
-
- return newTop;
- }
-
- /**
- * Ensure that the top of the RSN tree has a PredicateList.
- *
- * @param numTables The number of tables in the query.
- * @return ResultSetNode A RSN tree with a node which has a PredicateList on top.
- *
- * @exception StandardException Thrown on error
- */
- public ResultSetNode ensurePredicateList(int numTables)
- throws StandardException
- {
- return genProjectRestrict(numTables);
- }
-
- /**
- * Verify that a SELECT * is valid for this type of subquery.
- *
- * @param outerFromList The FromList from the outer query block(s)
- * @param subqueryType The subquery type
- *
- * @return None
- *
- * @exception StandardException Thrown on error
- */
- public void verifySelectStarSubquery(FromList outerFromList, int subqueryType)
- throws StandardException
- {
- /* Check both sides - SELECT * is not valid on either side */
- leftResultSet.verifySelectStarSubquery(outerFromList, subqueryType);
- rightResultSet.verifySelectStarSubquery(outerFromList, subqueryType);
- }
-
- /**
- * Determine whether or not the specified name is an exposed name in
- * the current query block.
- *
- * @param name The specified name to search for as an exposed name.
- * @param schemaName Schema name, if non-null.
- * @param exactMatch Whether or not we need an exact match on specified schema and table
- * names or match on table id.
- *
- * @return The FromTable, if any, with the exposed name.
- *
- * @exception StandardException Thrown on error
- */
- protected FromTable getFromTableByName(String name, String schemaName, boolean exactMatch)
- throws StandardException
- {
- /* We search both sides for a TableOperatorNode (join nodes)
- * but only the left side for a UnionNode.
- */
- return leftResultSet.getFromTableByName(name, schemaName, exactMatch);
- }
-
- /**
- * Set the result column for the subquery to a boolean true,
- * Useful for transformations such as
- * changing:
- * where exists (select ... from ...)
- * to:
- * where (select true from ...)
- *
- * NOTE: No transformation is performed if the ResultColumn.expression is
- * already the correct boolean constant.
- *
- * @param onlyConvertAlls Boolean, whether or not to just convert *'s
- *
- * @return Nothing.
- *
- * @exception StandardException Thrown on error
- */
- public void setResultToBooleanTrueNode(boolean onlyConvertAlls)
- throws StandardException
- {
- super.setResultToBooleanTrueNode(onlyConvertAlls);
- leftResultSet.setResultToBooleanTrueNode(onlyConvertAlls);
- rightResultSet.setResultToBooleanTrueNode(onlyConvertAlls);
- }
-
- /**
- * This ResultSet is the source for an Insert. The target RCL
- * is in a different order and/or a superset of this RCL. In most cases
- * we will reorder and/or add defaults to the current RCL so that is
- * matches the target RCL. Those RSNs whose generate() method does
- * not handle projects will insert a PRN, with a new RCL which matches
- * the target RCL, above the current RSN.
- * NOTE - The new or enhanced RCL will be fully bound.
- *
- * @param numTargetColumns # of columns in target RCL
- * @param colMap[] int array representation of correspondence between
- * RCLs - colmap[i] = -1 -> missing in current RCL
- * colmap[i] = j -> targetRCL(i) <-> thisRCL(j+1)
- * @param dataDictionary DataDictionary to use
- * @param targetTD TableDescriptor for target if the target is not a VTI, null if a VTI
- * @param targetVTI Target description if it is a VTI, null if not a VTI
- *
- * @return ResultSetNode The new top of the tree
- *
- * @exception StandardException Thrown on error
- */
- public ResultSetNode enhanceRCLForInsert(int numTargetColumns, int[] colMap,
- DataDictionary dataDictionary,
- TableDescriptor targetTD,
- FromVTI targetVTI)
- throws StandardException
- {
- // our newResultCols are put into the bound form straight away.
- ResultColumnList newResultCols =
- (ResultColumnList) getNodeFactory().getNode(
- C_NodeTypes.RESULT_COLUMN_LIST,
- getContextManager());
- int numResultSetColumns = resultColumns.size();
-
- /* Create a massaged version of the source RCL.
- * (Much simpler to build new list and then assign to source,
- * rather than massage the source list in place.)
- */
- for (int index = 0; index < numTargetColumns; index++)
- {
- ResultColumn newResultColumn;
- ResultColumn oldResultColumn;
- ColumnReference newColumnReference;
-
- if (colMap[index] != -1)
- {
- // getResultColumn uses 1-based positioning, so offset the colMap entry appropriately
- oldResultColumn = resultColumns.getResultColumn(colMap[index]+1);
-
- newColumnReference = (ColumnReference) getNodeFactory().getNode(
- C_NodeTypes.COLUMN_REFERENCE,
- oldResultColumn.getName(),
- null,
- getContextManager());
- /* The ColumnReference points to the source of the value */
- newColumnReference.setSource(oldResultColumn);
- // colMap entry is 0-based, columnId is 1-based.
- newColumnReference.setType(oldResultColumn.getExpressionType());
-
- // Source of an insert, so nesting levels must be 0
- newColumnReference.setNestingLevel(0);
- newColumnReference.setSourceLevel(0);
-
- // because the insert already copied the target table's
- // column descriptors into the result, we grab it from there.
- // alternatively, we could do what the else clause does,
- // and look it up in the DD again.
- newResultColumn = (ResultColumn) getNodeFactory().getNode(
- C_NodeTypes.RESULT_COLUMN,
- oldResultColumn.getType(),
- newColumnReference,
- getContextManager());
- }
- else
- {
- newResultColumn = genNewRCForInsert(targetTD, targetVTI, index + 1, dataDictionary);
- }
-
- newResultCols.addResultColumn(newResultColumn);
- }
-
- /* The generated ProjectRestrictNode now has the ResultColumnList
- * in the order that the InsertNode expects.
- * NOTE: This code here is an exception to several "rules":
- * o This is the only ProjectRestrictNode that is currently
- * generated outside of preprocess().
- * o The UnionNode is the only node which is not at the
- * top of the query tree which has ColumnReferences under
- * its ResultColumnList prior to expression push down.
- */
- return (ResultSetNode) getNodeFactory().getNode(
- C_NodeTypes.PROJECT_RESTRICT_NODE,
- this,
- newResultCols,
- null,
- null,
- null,
- null,
- tableProperties,
- getContextManager());
- }
-
- /**
- * Evaluate whether or not the subquery in a FromSubquery is flattenable.
- * Currently, a FSqry is flattenable if all of the following are true:
- * o Subquery is a SelectNode. (ie, not a RowResultSetNode or a UnionNode)
- * o It contains no top level subqueries. (RESOLVE - we can relax this)
- * o It does not contain a group by or having clause
- * o It does not contain aggregates.
- *
- * @param fromList The outer from list
- *
- * @return boolean Whether or not the FromSubquery is flattenable.
- */
- public boolean flattenableInFromSubquery(FromList fromList)
- {
- /* Unions in FromSubquerys are not flattenable. */
- return false;
- }
-
- /**
- * Return whether or not to materialize this ResultSet tree.
- *
- * @return Whether or not to materialize this ResultSet tree.
- * would return valid results.
- *
- * @exception StandardException Thrown on error
- */
- public boolean performMaterialization(JBitSet outerTables)
- throws StandardException
- {
- // RESOLVE - just say no to materialization right now - should be a cost based decision
- return false;
-
- /* Actual materialization, if appropriate, will be placed by our parent PRN.
- * This is because PRN might have a join condition to apply. (Materialization
- * can only occur before that.
- */
- //return true;
- }
-
/**
* Generate the code for this UnionNode.
*
@@ -1134,4 +562,9 @@
mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "getUnionResultSet", ClassName.NoPutResultSet, 7);
}
+
+ String getOperatorName()
+ {
+ return "UNION";
+ }
}
Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj?view=diff&rev=124467&p1=incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj&r1=124466&p2=incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj&r2=124467
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj Thu Jan 6 16:59:41 2005
@@ -85,6 +85,7 @@
import org.apache.derby.impl.sql.compile.TransactionStatementNode;
import org.apache.derby.impl.sql.compile.TriggerReferencingStruct;
import org.apache.derby.impl.sql.compile.UnionNode;
+import org.apache.derby.impl.sql.compile.IntersectOrExceptNode;
import org.apache.derby.impl.sql.compile.UntypedNullConstantNode;
import org.apache.derby.impl.sql.compile.UpdateNode;
import org.apache.derby.impl.sql.compile.UserTypeConstantNode;
@@ -173,6 +174,15 @@
// Define for UTF8 max
private static final int MAX_UTF8_LENGTH = 65535;
+ // Constants for set operator types
+ private static final int NO_SET_OP = 0;
+ private static final int UNION_OP = 1;
+ private static final int UNION_ALL_OP = 2;
+ private static final int EXCEPT_OP = 3;
+ private static final int EXCEPT_ALL_OP = 4;
+ private static final int INTERSECT_OP = 5;
+ private static final int INTERSECT_ALL_OP = 6;
+
private StringSlicer stringSlicer;
private Object[] paramDefaults;
private String statementSQLText;
@@ -2662,7 +2672,7 @@
OrderByList orderCols = null;
}
{
- queryExpression = queryExpression(null, Boolean.FALSE)
+ queryExpression = queryExpression(null, NO_SET_OP)
[ orderCols = orderByClause() ]
[ <FOR> forUpdateState = forUpdateClause(updateColumns) ]
[ isolationLevel = atIsolationLevel() ]
@@ -4108,24 +4118,37 @@
/*
* <A NAME="queryExpression">queryExpression</A>
+ *
+ * We have to be carefull to get the associativity correct. According to the SQL spec
+ * <non-join query expression> ::=
+ * <non-join query term>
+ * | <query expression body> UNION [ ALL ] <query term>
+ * | <query expression body> EXCEPT [ ALL ] <query term>
+ * Meaning that
+ * t1 UNION ALL t2 UNION t3
+ * is equivalent to
+ * (t1 UNION ALL t2) UNION t3
+ * However recursive descent parsers want recursion to be on the right, so this kind of associativity is unnatural
+ * for our parser. The queryExpression method must know whether it is being called as the right hand side of a
+ * set operator to produce a query tree with the correct associativity.
*/
ResultSetNode
-queryExpression(ResultSetNode leftSide, Boolean unionAll) throws StandardException :
+queryExpression(ResultSetNode leftSide, int operatorType) throws StandardException :
{
ResultSetNode term;
}
{
- term = nonJoinQueryTerm(leftSide, unionAll) [ term = union(term) ]
+ term = nonJoinQueryTerm(leftSide, operatorType) [ term = unionOrExcept(term) ]
{
return term;
}
}
/*
- * <A NAME="union">union</A>
+ * <A NAME="unionOrExcept">unionOrExcept</A>
*/
ResultSetNode
-union(ResultSetNode term) throws StandardException :
+unionOrExcept(ResultSetNode term) throws StandardException :
{
ResultSetNode expression;
Token tok = null;
@@ -4133,7 +4156,14 @@
{
<UNION> [ tok = <ALL> ] expression =
queryExpression(term,
- (tok != null) ? Boolean.TRUE : Boolean.FALSE)
+ (tok != null) ? UNION_ALL_OP : UNION_OP)
+ {
+ return expression;
+ }
+|
+ <EXCEPT> [ tok = <ALL> ] expression =
+ queryExpression(term,
+ (tok != null) ? EXCEPT_ALL_OP : EXCEPT_OP)
{
return expression;
}
@@ -4142,33 +4172,113 @@
/*
* <A NAME="nonJoinQueryTerm">nonJoinQueryTerm</A>
+ *
+ * Be careful with the associativity of INTERSECT. According to the SQL spec
+ * t1 INTERSECT t2 INTERSECT ALL t3
+ * is equivalent to
+ * (t1 INTERSECT t2) INTERSECT ALL t3
+ * which is not the same as
+ * t1 INTERSECT (t2 INTERSECT ALL t3)
+ * See the comment on queryExpression.
*/
ResultSetNode
-nonJoinQueryTerm(ResultSetNode leftSide, Boolean unionAll) throws StandardException :
+nonJoinQueryTerm(ResultSetNode leftSide, int operatorType) throws StandardException :
{
ResultSetNode term;
}
{
- /*
- ** Omitted "intersect".
- */
- term = nonJoinQueryPrimary()
+ term = nonJoinQueryPrimary() [ term = intersect( term) ]
{
- if (leftSide != null)
- {
- return (ResultSetNode) nodeFactory.getNode(
- C_NodeTypes.UNION_NODE,
- leftSide,
- term,
- unionAll,
- Boolean.FALSE,
- null,
- getContextManager());
- }
- else
- {
- return term;
- }
+ switch( operatorType)
+ {
+ case NO_SET_OP:
+ return term;
+
+ case UNION_OP:
+ return (ResultSetNode) nodeFactory.getNode(
+ C_NodeTypes.UNION_NODE,
+ leftSide,
+ term,
+ Boolean.FALSE,
+ Boolean.FALSE,
+ null,
+ getContextManager());
+
+ case UNION_ALL_OP:
+ return (ResultSetNode) nodeFactory.getNode(
+ C_NodeTypes.UNION_NODE,
+ leftSide,
+ term,
+ Boolean.TRUE,
+ Boolean.FALSE,
+ null,
+ getContextManager());
+
+ case EXCEPT_OP:
+ return (ResultSetNode) nodeFactory.getNode(
+ C_NodeTypes.INTERSECT_OR_EXCEPT_NODE,
+ ReuseFactory.getInteger( IntersectOrExceptNode.EXCEPT_OP),
+ leftSide,
+ term,
+ Boolean.FALSE,
+ null,
+ getContextManager());
+
+ case EXCEPT_ALL_OP:
+ return (ResultSetNode) nodeFactory.getNode(
+ C_NodeTypes.INTERSECT_OR_EXCEPT_NODE,
+ ReuseFactory.getInteger( IntersectOrExceptNode.EXCEPT_OP),
+ leftSide,
+ term,
+ Boolean.TRUE,
+ null,
+ getContextManager());
+
+ case INTERSECT_OP:
+ return (ResultSetNode) nodeFactory.getNode(
+ C_NodeTypes.INTERSECT_OR_EXCEPT_NODE,
+ ReuseFactory.getInteger( IntersectOrExceptNode.INTERSECT_OP),
+ leftSide,
+ term,
+ Boolean.FALSE,
+ null,
+ getContextManager());
+
+ case INTERSECT_ALL_OP:
+ return (ResultSetNode) nodeFactory.getNode(
+ C_NodeTypes.INTERSECT_OR_EXCEPT_NODE,
+ ReuseFactory.getInteger( IntersectOrExceptNode.INTERSECT_OP),
+ leftSide,
+ term,
+ Boolean.TRUE,
+ null,
+ getContextManager());
+
+
+ default:
+ if (SanityManager.DEBUG)
+ {
+ SanityManager.THROWASSERT( "Invalid set operator type: " + operatorType);
+ }
+ return null;
+ }
+ }
+}
+
+/*
+ * <A NAME="intersect">intersect</A>
+ */
+ResultSetNode
+intersect(ResultSetNode term) throws StandardException :
+{
+ ResultSetNode expression;
+ Token tok = null;
+}
+{
+ <INTERSECT> [ tok = <ALL> ] expression =
+ nonJoinQueryTerm(term, (tok != null) ? INTERSECT_ALL_OP : INTERSECT_OP)
+ {
+ return expression;
}
}
@@ -4186,7 +4296,7 @@
return primary;
}
|
- <LEFT_PAREN> primary = queryExpression(null, Boolean.FALSE) <RIGHT_PAREN>
+ <LEFT_PAREN> primary = queryExpression(null, NO_SET_OP) <RIGHT_PAREN>
{
return primary;
}
@@ -6729,7 +6839,7 @@
<LEFT_PAREN> columnList = insertColumnList() <RIGHT_PAREN>
]
[ targetProperties = propertyList() ]
- queryExpression = queryExpression(null, Boolean.FALSE)
+ queryExpression = queryExpression(null, NO_SET_OP)
{
return (QueryTreeNode) nodeFactory.getNode(
C_NodeTypes.INSERT_NODE,
@@ -6976,7 +7086,7 @@
SubqueryNode subqueryNode;
}
{
- queryExpression = queryExpression(null, Boolean.FALSE)
+ queryExpression = queryExpression(null, NO_SET_OP)
{
subqueryNode = (SubqueryNode) nodeFactory.getNode(
C_NodeTypes.SUBQUERY_NODE,
@@ -8757,7 +8867,7 @@
{
<VIEW> tableName = qualifiedName(DB2Limit.DB2_MAX_IDENTIFIER_LENGTH128)
[ <LEFT_PAREN> resultColumns = viewColumnList() <RIGHT_PAREN> ]
- <AS> queryExpression = queryExpression(null, Boolean.FALSE)
+ <AS> queryExpression = queryExpression(null, NO_SET_OP)
{
checkOptionType = ViewDescriptor.NO_CHECK_OPTION;
endToken = getToken(0);
@@ -9641,7 +9751,7 @@
<EXECUTE> <STATEMENT> stmtName = qualifiedName(DB2Limit.DB2_MAX_IDENTIFIER_LENGTH128)
[ LOOKAHEAD( { getToken(1).kind == USING } )
usingToken = <USING> usingClause =
- queryExpression(null, Boolean.FALSE) ]
+ queryExpression(null, NO_SET_OP) ]
{
endToken = getToken(0);
Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericResultSetFactory.java
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericResultSetFactory.java?view=diff&rev=124467&p1=incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericResultSetFactory.java&r1=124466&p2=incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericResultSetFactory.java&r2=124467
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericResultSetFactory.java (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericResultSetFactory.java Thu Jan 6 16:59:41 2005
@@ -1053,6 +1053,32 @@
closeCleanup);
}
+ public NoPutResultSet getSetOpResultSet( NoPutResultSet leftSource,
+ NoPutResultSet rightSource,
+ Activation activation,
+ int resultSetNumber,
+ long optimizerEstimatedRowCount,
+ double optimizerEstimatedCost,
+ int opType,
+ boolean all,
+ GeneratedMethod closeCleanup,
+ int intermediateOrderByColumnsSavedObject,
+ int intermediateOrderByDirectionSavedObject)
+ throws StandardException
+ {
+ return new SetOpResultSet( leftSource,
+ rightSource,
+ activation,
+ resultSetNumber,
+ optimizerEstimatedRowCount,
+ optimizerEstimatedCost,
+ opType,
+ all,
+ closeCleanup,
+ intermediateOrderByColumnsSavedObject,
+ intermediateOrderByDirectionSavedObject);
+ }
+
/**
* A last index key sresult set returns the last row from
* the index in question. It is used as an ajunct to max().
Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties?view=diff&rev=124467&p1=incubator/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties&r1=124466&p2=incubator/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties&r2=124467
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties (original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/loc/messages_en.properties Thu Jan 6 16:59:41 2005
@@ -469,10 +469,10 @@
42X55=Table name ''{1}'' should be the same as ''{0}''.
42X56=The number of columns in the view column list does not match the number of columns in the underlying query expression in the view definition for ''{0}''.
42X57=The getColumnCount() for external virtual table ''{0}'' returned an invalid value ''{1}''. Valid values are >= 1.
-42X58=The number of columns on the left and right sides of the UNION must be the same.
+42X58=The number of columns on the left and right sides of the {0} must be the same.
42X59=The number of columns in each VALUES constructor must be the same.
42X60=Invalid value ''{0}'' for insertMode property specified for table ''{1}''.
-42X61=Types ''{0}'' and ''{1}'' are not UNION compatible.
+42X61=Types ''{0}'' and ''{1}'' are not {2} compatible.
42X62=''{0}'' is not allowed in the ''{1}'' schema.
42X63=The USING clause did not return any results, no parameters can be set.
42X64=Invalid value ''{0}'' specified for useStatistics property in the Properties list. TRUE or FALSE are the only valid values.
@@ -919,7 +919,7 @@
X0X61.S=The values for column ''{4}'' in index ''{0}'' and table ''{1}.{2}'' do not match for row location {3}. The value in the index is ''{5}'', while the value in the base table is ''{6}''. The full index key, including the row location, is ''{7}''. The suggested corrective action is to recreate the index.
X0X62.S=Inconsistency found between table ''{0}'' and index ''{1}''. Error when trying to retrieve row location ''{2}'' from the table. The full index key, including the row location, is ''{3}''. The suggested corrective action is to recreate the index.
X0X63.S=Got IOException ''{0}''.
-X0X67.S=Columns of type ''{0}'' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, or DISTINCT, because comparisons are not supported for that type.
+X0X67.S=Columns of type ''{0}'' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, INTERSECT, EXCEPT or DISTINCT, because comparisons are not supported for that type.
X0X81.S={0} ''{1}'' does not exist.
X0X85.S=Index ''{0}'' was not created because ''{1}'' is not a valid index type.
X0X86.S=0 is an invalid parameter value for ResultSet.absolute(int row).
Modified: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LOB.out
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LOB.out?view=diff&rev=124467&p1=incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LOB.out&r1=124466&p2=incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LOB.out&r2=124467
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LOB.out (original)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/LOB.out Thu Jan 6 16:59:41 2005
@@ -266,13 +266,13 @@
0 rows inserted/updated/deleted
ij> -- create index (not allowed)
create index ia on a(a);
-ERROR X0X67: Columns of type 'BLOB' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, or DISTINCT, because comparisons are not supported for that type.
+ERROR X0X67: Columns of type 'BLOB' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, INTERSECT, EXCEPT or DISTINCT, because comparisons are not supported for that type.
ij> create index ib on b(a);
-ERROR X0X67: Columns of type 'CLOB' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, or DISTINCT, because comparisons are not supported for that type.
+ERROR X0X67: Columns of type 'CLOB' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, INTERSECT, EXCEPT or DISTINCT, because comparisons are not supported for that type.
ij> create index ic on c(a);
ERROR 42Y55: 'CREATE INDEX' cannot be performed on 'C' because it does not exist.
ij> create index id on d(a);
-ERROR X0X67: Columns of type 'CLOB' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, or DISTINCT, because comparisons are not supported for that type.
+ERROR X0X67: Columns of type 'CLOB' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, INTERSECT, EXCEPT or DISTINCT, because comparisons are not supported for that type.
ij> -- cleanup
drop table a;
0 rows inserted/updated/deleted
@@ -535,7 +535,7 @@
1 row inserted/updated/deleted
ij> -- UNION
select * from testPredicate1 union select * from testPredicate2;
-ERROR X0X67: Columns of type 'LONG VARCHAR' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, or DISTINCT, because comparisons are not supported for that type.
+ERROR X0X67: Columns of type 'LONG VARCHAR' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, INTERSECT, EXCEPT or DISTINCT, because comparisons are not supported for that type.
ij> -- IN predicate
select c1 from testPredicate1 where c1 IN (select c1 from testPredicate2);
ERROR 42818: Comparisons between 'LONG VARCHAR' and 'LONG VARCHAR' are not supported.
@@ -544,10 +544,10 @@
ERROR 42818: Comparisons between 'LONG VARCHAR' and 'LONG VARCHAR' are not supported.
ij> -- ORDER BY clause
select * from testPredicate1 order by c1;
-ERROR X0X67: Columns of type 'LONG VARCHAR' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, or DISTINCT, because comparisons are not supported for that type.
+ERROR X0X67: Columns of type 'LONG VARCHAR' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, INTERSECT, EXCEPT or DISTINCT, because comparisons are not supported for that type.
ij> -- GROUP BY clause
select substr(c1,1,2) from testPredicate1 group by c1;
-ERROR X0X67: Columns of type 'LONG VARCHAR' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, or DISTINCT, because comparisons are not supported for that type.
+ERROR X0X67: Columns of type 'LONG VARCHAR' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, INTERSECT, EXCEPT or DISTINCT, because comparisons are not supported for that type.
ij> -- JOIN
select * from testPredicate1 t1, testPredicate2 t2 where t1.c1=t2.c1;
ERROR 42818: Comparisons between 'LONG VARCHAR' and 'LONG VARCHAR' are not supported.
@@ -555,15 +555,15 @@
ERROR 42818: Comparisons between 'LONG VARCHAR' and 'LONG VARCHAR' are not supported.
ij> -- PRIMARY KEY
create table testConst1(c1 long varchar not null primary key);
-ERROR X0X67: Columns of type 'LONG VARCHAR' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, or DISTINCT, because comparisons are not supported for that type.
+ERROR X0X67: Columns of type 'LONG VARCHAR' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, INTERSECT, EXCEPT or DISTINCT, because comparisons are not supported for that type.
ij> -- UNIQUE KEY constraints
CREATE TABLE testconst2 (col1 long varchar not null, CONSTRAINT uk UNIQUE (col1));
-ERROR X0X67: Columns of type 'LONG VARCHAR' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, or DISTINCT, because comparisons are not supported for that type.
+ERROR X0X67: Columns of type 'LONG VARCHAR' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, INTERSECT, EXCEPT or DISTINCT, because comparisons are not supported for that type.
ij> -- FOREIGN KEY constraints
create table testConst3 (c1 char(10) not null, primary key (c1));
0 rows inserted/updated/deleted
ij> create table testConst4 (c1 long varchar not null, constraint fk foreign key (c1) references testConst3 (c1));
-ERROR X0X67: Columns of type 'LONG VARCHAR' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, or DISTINCT, because comparisons are not supported for that type.
+ERROR X0X67: Columns of type 'LONG VARCHAR' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, INTERSECT, EXCEPT or DISTINCT, because comparisons are not supported for that type.
ij> drop table testConst3;
0 rows inserted/updated/deleted
ij> -- MAX aggregate function
Modified: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/groupBy.out
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/groupBy.out?view=diff&rev=124467&p1=incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/groupBy.out&r1=124466&p2=incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/groupBy.out&r2=124467
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/groupBy.out (original)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/master/groupBy.out Thu Jan 6 16:59:41 2005
@@ -45,7 +45,7 @@
create table unmapped(c1 long varchar);
0 rows inserted/updated/deleted
ij> select c1, max(1) from unmapped group by c1;
-ERROR X0X67: Columns of type 'LONG VARCHAR' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, or DISTINCT, because comparisons are not supported for that type.
+ERROR X0X67: Columns of type 'LONG VARCHAR' may not be used in CREATE INDEX, ORDER BY, GROUP BY, UNION, INTERSECT, EXCEPT or DISTINCT, because comparisons are not supported for that type.
ij> -- clean up
drop table t1;
0 rows inserted/updated/deleted
Modified: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/derbylang.runall
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/derbylang.runall?view=diff&rev=124467&p1=incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/derbylang.runall&r1=124466&p2=incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/derbylang.runall&r2=124467
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/derbylang.runall (original)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/suites/derbylang.runall Thu Jan 6 16:59:41 2005
@@ -67,6 +67,7 @@
lang/infostreams.sql
lang/innerjoin.sql
lang/insert.sql
+lang/intersect.sql
lang/isolationLevels.sql
lang/joinDeadlock.sql
lang/joins.sql
Modified: incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/copyfiles.ant
Url: http://svn.apache.org/viewcvs/incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/copyfiles.ant?view=diff&rev=124467&p1=incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/copyfiles.ant&r1=124466&p2=incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/copyfiles.ant&r2=124467
==============================================================================
--- incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/copyfiles.ant (original)
+++ incubator/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/copyfiles.ant Thu Jan 6 16:59:41 2005
@@ -95,6 +95,7 @@
innerjoin.sql
insert.sql
insert_sed.properties
+intersect.sql
isolationLevels.sql
joinDeadlock.sql
joinDeadlock.sql1