db-derby-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Satheesh Bandaram <sathe...@Sourcery.Org>
Subject [VOTE] [PATCH] Intersect and Except
Date Tue, 21 Dec 2004 01:33:13 GMT
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
  <title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
-----BEGIN PGP SIGNED MESSAGE----- <br>
Hash: SHA1 <br>
&nbsp;<br>
I am submitting this patch for a VOTE. It has been pending for about a
week. My vote is "+1", with the following comments. Since this is a new
feature, I think, three +1 votes are requied. Here is the status of
this patch. I am basically waiting for the final +1 vote....<br>
<br>
&nbsp;&nbsp; 1. It passed build and all tests.<br>
&nbsp;&nbsp; 2. Mike and myself have voted +1.<br>
&nbsp;&nbsp; 3. Dan provided a suggestion, with some syntax improvement. Any
response from the contributor? I am assuming Dan's vote is a +1. If
not, please speak up.. :-)<br>
<br>
Here are my comments:<br>
<br>
&nbsp;&nbsp; 1. IntersectOrExceptNode still refers to SetOpProjectRestrict.
Should this be SetOpResultSet?<br>
&nbsp;&nbsp; 2. Doesn't tableConstructor logic apply only to UnionNode? If so,
should the fields like tableConstructor, topTableConstructor and
methods like setTableConstructorTypes() be moved to UnionNode? Current
code in SetOperatorNode refers to subclass UnionNode a lot, which could
be improved?<br>
<br>
Jack Klebanoff wrote:<br>
<br>
&gt; I have attached an update to my previous INTERSECT/EXCEPT patch.
It addresses a number of concerns brought up in this thread.<br>
&gt;<br>
&gt; 1. It includes the fix for order by syntax checking posted by
Satheesh.<br>
&gt; 2. It fixes the execution of an order by clause in the statement.
Previously an order by clause was ignored.<br>
&gt; 3. The intersect/except is still implemented by sorting its two
inputs, but optimizer is given a chance to perform sort avoidance on
the inputs.<br>
&gt; 4. If there is an order by clause on the output of the
intersect/except then that ordering is used for the inputs, avoiding a
separate sort on the intersect/except output.<br>
&gt; 5. Test cases were added to cover the above code.<br>
&gt; 6. The copyright notices for the new files were changed to 2004.<br>
&gt; 7. The SetOpProjectRestrictResultSet class was renamed to
SetOpResultSet, which is more appropriate.<br>
&gt; 8. The IntersectNode and ExceptNode classes were removed and
subsumed in the IntersectOrExceptNode class.<br>
&gt;<br>
&gt; Some of the concerns about optimization were not entirely
addressed.<br>
&gt;<br>
&gt; There is still just the one execution strategy: sort the two
inputs and scan them together. I did not implement other strategies and
an optimizer that picks the best of them. I think that my
implementation strategy performs decently in all cases, and is the best
in many cases. I don't think that it is wise to write a lot of code to
optimize an operation that is probably only used infrequently.
(Cloudscape customers have gotten along without it for all these years).<br>
&gt;<br>
&gt; While this update allows the optimizer to avoid sorting the
intersect/except inputs it does not try to pick an ordering that is
more likely to avoid a sort. For instance, suppose one of the inputs is
a single table select that selects the columns of a unique key. Then
you only have to order that input on the key columns. Depending on the
where clause the optimizer might decide to use the unique key index to
traverse the table in sort order, avoiding a separate sort. The other
input to the intersect/except may be a different story. Those same
columns may not specify a unique key in the other input, in which case
that input must be ordered on more columns.<br>
&gt;<br>
&gt; Unfortunately the Derby compiler architecture does not make it
easy for the IntersectOrExceptNode class to determine a column ordering
that is likely to avoid a sort on its inputs. Its inputs are
represented as ResultSetNodes. It is not easy to determine a
ResultSetNode represents a single table select, and if so whether the
selected columns contain a unique key. One would like to try avoiding a
sort on the larger input, and then try a column ordering that might
avoid a sort on the smaller input if the optimizer cannot avoid sorting
the larger input. Unfortunately this does not work: the architecture
requires that the order by clause be pushed down by the start of
optimization.<br>
&gt;<br>
&gt; It is easy to see if the output of the intersect/except must be
ordered and use this ordering to order the inputs, avoiding a separate
sort on the output of the intersect/except. I did this in the attached
patch update.<br>
&gt;<br>
&gt; Jack<br>
&gt;<br>
&gt; Jack Klebanoff wrote:<br>
&gt;<br>
&gt;&gt; Attached is a patch that implements the SQL INTERSECT and
EXCEPT operators. The INTERSECT operator constructs the intersection of
two tables. The EXCEPT operator finds all rows in one table but not in
the other. The syntax is (roughly):<br>
&gt;&gt;<br>
&gt;&gt; &lt;query expression&gt; INTERSECT [ALL] &lt;query
expression&gt;<br>
&gt;&gt; &lt;query expression&gt; EXCEPT [ALL] &lt;query expression&gt;<br>
&gt;&gt;<br>
&gt;&gt; By default these operators remove duplicates, which can occur
if there are duplicates in the inputs. If ALL is specified then
duplicates are not returned. If t1 has m copies of row R and t2 has n
copies then t1 INTERSECT ALL t2 returns min(m,n) copies of R, and t1
EXCEPT ALL t2 returns max( 0, m-n) copies of R.<br>
&gt;&gt;<br>
&gt;&gt; The EXCEPT operator has the same precedence as UNION.
INTERSECT has higher precedence.<br>
&gt;&gt;<br>
&gt;&gt; This follows the SQL-92 spec. (At least it follows my
understanding of the spec. Spec lawyers are invited to comment).<br>
&gt;&gt;<br>
&gt;&gt; The implementation uses sorting. The two input tables are
sorted and then scanned together. The appropriate rows from the left
input are output.<br>
&gt;&gt;<br>
&gt;&gt; The compiler binds INTERSECT and EXCEPT like UNION. Therefore
a new class, org.apache.derby.impl.sql.compile.SetOperatorNode, was
carved out of UnionNode. It mainly contains bind methods. Classes
UnionNode and IntersectOrExceptNode extend SetOperatorNode. Classes
IntersectNode and ExceptNode extend IntersectOrExceptNode.
IntersectOrExceptNode does most of the optimization and code generation
work. It puts OrderBy nodes in front of its inputs.<br>
&gt;&gt;<br>
&gt;&gt; The generated code creates a SetOpProjectRestrictResultSet
that reads its sorted inputs to produce the required output table.<br>
&gt;&gt;<br>
&gt;&gt; Jack Klebanoff<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;<br>
&gt;<br>
&gt;-------------------------<br>
&gt;<br>
&gt;Index:
java/engine/org/apache/derby/impl/sql/compile/NodeFactoryImpl.java<br>
&gt;===================================================================<br>
&gt;---
java/engine/org/apache/derby/impl/sql/compile/NodeFactoryImpl.java&nbsp;&nbsp;&nbsp;
(revision 111907)<br>
&gt;+++
java/engine/org/apache/derby/impl/sql/compile/NodeFactoryImpl.java&nbsp;&nbsp;&nbsp;
(working copy)<br>
&gt;@@ -512,6 +512,9 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case C_NodeTypes.UNION_NODE:<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return C_NodeNames.UNION_NODE_NAME;<br>
&gt;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case C_NodeTypes.INTERSECT_OR_EXCEPT_NODE:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return C_NodeNames.INTERSECT_OR_EXCEPT_NODE_NAME;<br>
&gt;+<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case C_NodeTypes.CREATE_TRIGGER_NODE:<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return C_NodeNames.CREATE_TRIGGER_NODE_NAME;<br>
&gt;<br>
&gt;Index:
java/engine/org/apache/derby/impl/sql/compile/C_NodeNames.java<br>
&gt;===================================================================<br>
&gt;---
java/engine/org/apache/derby/impl/sql/compile/C_NodeNames.java&nbsp;&nbsp;&nbsp;
(revision 111907)<br>
&gt;+++
java/engine/org/apache/derby/impl/sql/compile/C_NodeNames.java&nbsp;&nbsp;&nbsp;
(working copy)<br>
&gt;@@ -258,6 +258,8 @@<br>
&gt;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; static final String UNION_NODE_NAME =
"org.apache.derby.impl.sql.compile.UnionNode";<br>
&gt;<br>
&gt;+&nbsp;&nbsp;&nbsp; static final String INTERSECT_OR_EXCEPT_NODE_NAME =
"org.apache.derby.impl.sql.compile.IntersectOrExceptNode";<br>
&gt;+<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; static final String UNTYPED_NULL_CONSTANT_NODE_NAME =
"org.apache.derby.impl.sql.compile.UntypedNullConstantNode";<br>
&gt;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; static final String UPDATE_NODE_NAME =
"org.apache.derby.impl.sql.compile.UpdateNode";<br>
&gt;Index: java/engine/org/apache/derby/impl/sql/compile/UnionNode.java<br>
&gt;===================================================================<br>
&gt;--- java/engine/org/apache/derby/impl/sql/compile/UnionNode.java&nbsp;&nbsp;&nbsp;
(revision 111907)<br>
&gt;+++ java/engine/org/apache/derby/impl/sql/compile/UnionNode.java&nbsp;&nbsp;&nbsp;
(working copy)<br>
&gt;@@ -20,15 +20,12 @@<br>
&gt;<br>
&gt; package&nbsp;&nbsp;&nbsp; org.apache.derby.impl.sql.compile;<br>
&gt;<br>
&gt;-import org.apache.derby.iapi.services.context.ContextManager;<br>
&gt;-<br>
&gt; import org.apache.derby.iapi.services.compiler.MethodBuilder;<br>
&gt;<br>
&gt; import org.apache.derby.iapi.services.sanity.SanityManager;<br>
&gt;<br>
&gt; import org.apache.derby.iapi.error.StandardException;<br>
&gt;<br>
&gt;-import org.apache.derby.iapi.sql.compile.CompilerContext;<br>
&gt; import org.apache.derby.iapi.sql.compile.Optimizable;<br>
&gt; import org.apache.derby.iapi.sql.compile.OptimizablePredicate;<br>
&gt; import org.apache.derby.iapi.sql.compile.OptimizablePredicateList;<br>
&gt;@@ -37,33 +34,16 @@<br>
&gt; import org.apache.derby.iapi.sql.compile.RowOrdering;<br>
&gt; import org.apache.derby.iapi.sql.compile.C_NodeTypes;<br>
&gt;<br>
&gt;-import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;<br>
&gt;-import org.apache.derby.iapi.sql.dictionary.DataDictionary;<br>
&gt;-import org.apache.derby.iapi.sql.dictionary.DefaultDescriptor;<br>
&gt;-import org.apache.derby.iapi.sql.dictionary.TableDescriptor;<br>
&gt; import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;<br>
&gt;<br>
&gt;-import org.apache.derby.iapi.types.DataTypeDescriptor;<br>
&gt;-<br>
&gt; import org.apache.derby.iapi.reference.SQLState;<br>
&gt; import org.apache.derby.iapi.reference.ClassName;<br>
&gt;<br>
&gt;-import org.apache.derby.iapi.sql.Activation;<br>
&gt;-import org.apache.derby.iapi.types.DataTypeDescriptor;<br>
&gt;-import org.apache.derby.iapi.sql.ResultSet;<br>
&gt;-import org.apache.derby.iapi.sql.Row;<br>
&gt;-<br>
&gt;-import org.apache.derby.iapi.types.TypeId;<br>
&gt;-<br>
&gt; import org.apache.derby.impl.sql.compile.ActivationClassBuilder;<br>
&gt;<br>
&gt; import org.apache.derby.iapi.util.JBitSet;<br>
&gt; import org.apache.derby.iapi.services.classfile.VMOpcode;<br>
&gt;<br>
&gt;-import org.apache.derby.catalog.types.DefaultInfoImpl;<br>
&gt;-<br>
&gt;-import java.util.Properties;<br>
&gt;-<br>
&gt; /**<br>
&gt;&nbsp; * A UnionNode represents a UNION in a DML statement.&nbsp; It contains
a boolean<br>
&gt;&nbsp; * telling whether the union operation should eliminate duplicate
rows.<br>
&gt;@@ -71,155 +51,12 @@<br>
&gt;&nbsp; * @author Jeff Lichtman<br>
&gt;&nbsp; */<br>
&gt;<br>
&gt;-public class UnionNode extends TableOperatorNode<br>
&gt;+public class UnionNode extends SetOperatorNode<br>
&gt; {<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp; ** Tells whether to eliminate duplicate rows.&nbsp; all == TRUE
means do<br>
&gt;-&nbsp;&nbsp;&nbsp; ** not eliminate duplicates, all == FALSE means eliminate
duplicates.<br>
&gt;-&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp; boolean&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; all;<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /* Is this a UNION ALL generated for a table constructor. */<br>
&gt;-&nbsp;&nbsp;&nbsp; boolean&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tableConstructor;<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /* True if this is the top node of a table constructor */<br>
&gt;-&nbsp;&nbsp;&nbsp; boolean&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; topTableConstructor;<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /* Only optimize a UNION once */<br>
&gt;+&nbsp;&nbsp;&nbsp; /* Only optimize it once */<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; /* Only call addNewNodes() once */<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; private boolean addNewNodesCalled;<br>
&gt;<br>
&gt;-&nbsp;&nbsp;&nbsp; private OrderByList orderByList;<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Initializer for a UnionNode.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param leftResult&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The ResultSetNode on the left side
of this union<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param rightResult&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The ResultSetNode on the right
side of this union<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param all&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Whether or not this is a UNION
ALL.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param tableConstructor&nbsp;&nbsp;&nbsp; Whether or not this is from a
table constructor.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param tableProperties&nbsp;&nbsp;&nbsp; Properties list associated with
the table<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; public void init(<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object leftResult,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object rightResult,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object all,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object tableConstructor,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object tableProperties)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.init(leftResult, rightResult, tableProperties);<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.all = ((Boolean) all).booleanValue();<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Is this a UNION ALL for a table constructor? */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.tableConstructor = ((Boolean)
tableConstructor).booleanValue();<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* resultColumns cannot be null, so we make a copy of the
left RCL<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * for now.&nbsp; At bind() time, we need to recopy the list
because there<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * may have been a "*" in the list.&nbsp; (We will set the
names and<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * column types at that time, as expected.)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resultColumns =
leftResultSet.getResultColumns().copyListAndObjects();<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Mark this as the top node of a table constructor.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp; public void markTopTableConstructor()<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; topTableConstructor = true;<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Tell whether this is a UNION for a table constructor.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp; boolean tableConstructor()<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return tableConstructor;<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Check for (and reject) ? parameters directly under the
ResultColumns.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * This is done for SELECT statements.&nbsp; Don't reject
parameters that<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * are in a table constructor - these are allowed, as long as
the<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * table constructor is in an INSERT statement or each column
of the<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * table constructor has at least one non-? column.&nbsp; The
latter case<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * is checked below, in bindExpressions().<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; Nothing<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown if a ? parameter
found<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; directly under a
ResultColumn<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp; public void rejectParameters() throws StandardException<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( ! tableConstructor())<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.rejectParameters();<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Set the type of column in the result column lists of each<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * source of this union tree to the type in the given result
column list<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * (which represents the result columns for an insert).<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * This is only for table constructors that appear in insert
statements.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param typeColumns&nbsp;&nbsp;&nbsp; The ResultColumnList containing the
desired result<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; types.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp; void setTableConstructorTypes(ResultColumnList typeColumns)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (SanityManager.DEBUG)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SanityManager.ASSERT(resultColumns.size() &lt;=
typeColumns.size(),<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "More columns in ResultColumnList than in base
table.");<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultSetNode&nbsp;&nbsp;&nbsp; rsn;<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** Should only set types of ? parameters to types of
result columns<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** if it's a table constructor.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (tableConstructor())<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* By looping through the union nodes, we avoid
recursion */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (rsn = this; rsn instanceof UnionNode; )<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UnionNode union = (UnionNode) rsn;<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** Assume that table constructors are left-deep
trees of UnionNodes<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** with RowResultSet nodes on the right.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (SanityManager.DEBUG)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SanityManager.ASSERT(<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; union.rightResultSet instanceof
RowResultSetNode,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "A " +
union.rightResultSet.getClass().getName() +<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " is on the right of a union in a table
constructor");<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((RowResultSetNode)
union.rightResultSet).setTableConstructorTypes(<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
typeColumns);<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rsn = union.leftResultSet;<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* The last node on the left should be a result set
node */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (SanityManager.DEBUG)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SanityManager.ASSERT(rsn instanceof
RowResultSetNode,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "A " + rsn.getClass().getName() +<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " is at the left end of a table constructor");<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((RowResultSetNode)
rsn).setTableConstructorTypes(typeColumns);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; Optimizable interface<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;@@ -411,654 +248,6 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return treeTop;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Convert this object to a String.&nbsp; See comments in
QueryTreeNode.java<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * for how this should be done for tree printing.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; This object as a String<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; public String toString()<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (SanityManager.DEBUG)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp;&nbsp;&nbsp;&nbsp; "all: " + all + "\n" +<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "tableConstructor: " + tableConstructor + "\n" +<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "orderByList: " +<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (orderByList != null ? orderByList.toString() :
"null") + "\n" +<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.toString();<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "";<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Bind the expressions under this TableOperatorNode.&nbsp; This
means<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * binding the sub-expressions, as well as figuring out what
the<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * return type is for each expression.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; Nothing<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; public void bindExpressions(FromList fromListParam)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.bindExpressions(fromListParam);<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** Each ? parameter in a table constructor that is not in
an insert<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** statement takes its type from the first non-? in its
column<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** of the table constructor.&nbsp; It's an error to have a
column that<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** has all ?s.&nbsp; Do this only for the top of the table
constructor<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** list - we don't want to do this for every level of
union node<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** in the table constructor.&nbsp; Also, don't do this for an
INSERT -<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** the types of the ? parameters come from the columns
being inserted<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** into in that case.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (topTableConstructor &amp;&amp; ( ! insertSource) )<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** Step through all the rows in the table constructor
to<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** get the type of the first non-? in each column.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataTypeDescriptor[]&nbsp;&nbsp;&nbsp; types =<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new
DataTypeDescriptor[leftResultSet.getResultColumns().size()];<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultSetNode&nbsp;&nbsp;&nbsp; rsn;<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; numTypes = 0;<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* By looping through the union nodes, we avoid
recursion */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (rsn = this; rsn instanceof UnionNode; )<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UnionNode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; union = (UnionNode) rsn;<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** Assume that table constructors are left-deep
trees of<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** UnionNodes with RowResultSet nodes on the right.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (SanityManager.DEBUG)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SanityManager.ASSERT(<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; union.rightResultSet instanceof
RowResultSetNode,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "A " +
union.rightResultSet.getClass().getName() +<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " is on the right side of a union in a table
constructor");<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RowResultSetNode&nbsp;&nbsp;&nbsp; rrsn =<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (RowResultSetNode)
union.rightResultSet;<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; numTypes += getParamColumnTypes(types, rrsn);<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rsn = union.leftResultSet;<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* The last node on the left should be a result set
node */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (SanityManager.DEBUG)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SanityManager.ASSERT(rsn instanceof
RowResultSetNode);<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; numTypes += getParamColumnTypes(types,
(RowResultSetNode) rsn);<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Are there any columns that are all ? parameters? */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (numTypes &lt; types.length)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw
StandardException.newException(SQLState.LANG_TABLE_CONSTRUCTOR_ALL_PARAM_COLUMN);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** Loop through the nodes again. This time, look for
parameter<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** nodes, and give them the type from the type array
we just<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** constructed.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (rsn = this; rsn instanceof UnionNode; )<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UnionNode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; union = (UnionNode) rsn;<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RowResultSetNode&nbsp;&nbsp;&nbsp; rrsn =<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (RowResultSetNode)
union.rightResultSet;<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setParamColumnTypes(types, rrsn);<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rsn = union.leftResultSet;<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setParamColumnTypes(types, (RowResultSetNode) rsn);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Bind the result columns of this ResultSetNode when there is
no<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * base table to bind them to.&nbsp; This is useful for SELECT
statements,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * where the result columns get their types from the
expressions that<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * live under them.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param fromListParam&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FromList to use/append to.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; Nothing<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp; public void bindResultColumns(FromList fromListParam)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.bindResultColumns(fromListParam);<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Now we build our RCL */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buildRCL();<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Bind the result columns for this ResultSetNode to a base
table.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * This is useful for INSERT and UPDATE statements, where the<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * result columns get their types from the table being updated
or<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * inserted into.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * If a result column list is specified, then the verification
that the<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * result column list does not contain any duplicates will be
done when<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * binding them by name.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param targetTableDescriptor&nbsp;&nbsp;&nbsp; The TableDescriptor for the
table being<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; updated or inserted into<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param targetColumnList&nbsp;&nbsp;&nbsp; For INSERT statements, the user<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; does not have to supply column<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; names (for example, "insert into t<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; values (1,2,3)".&nbsp; When this<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parameter is null, it means that<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the user did not supply column<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; names, and so the binding should<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; be done based on order.&nbsp; When it<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is not null, it means do the binding<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by name, not position.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param statement&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Calling DMLStatementNode
(Insert or Update)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param fromListParam&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FromList to use/append to.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; Nothing<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; public void bindResultColumns(TableDescriptor
targetTableDescriptor,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FromVTI targetVTI,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumnList targetColumnList,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DMLStatementNode statement,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FromList fromListParam)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.bindResultColumns(targetTableDescriptor,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; targetVTI,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; targetColumnList, statement,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fromListParam);<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Now we build our RCL */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buildRCL();<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Build the RCL for this node.&nbsp; We propagate the RCL up from
the<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * left child to form this node's RCL.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; Nothing<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; private void buildRCL() throws StandardException<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Verify that both sides of the union have the same # of
columns in their<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * RCL.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (leftResultSet.getResultColumns().size() !=<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightResultSet.getResultColumns().size())<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw
StandardException.newException(SQLState.LANG_UNION_UNMATCHED_COLUMNS);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* We need to recreate resultColumns for this node, since
there<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * may have been 1 or more *'s in the left's SELECT list.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resultColumns =
leftResultSet.getResultColumns().copyListAndObjects();<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Create new expressions with the dominant types after
verifying<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * union compatibility between left and right sides.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
resultColumns.setUnionResultExpression(rightResultSet.getResultColumns(),
tableNumber, level);<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Bind the result columns of a table constructor to the types
in the<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * given ResultColumnList.&nbsp; Use when inserting from a table
constructor,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * and there are nulls in the values clauses.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param rcl&nbsp;&nbsp;&nbsp; The ResultColumnList with the types to bind to<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp; public void bindUntypedNullsToResultColumns(ResultColumnList
rcl)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** If the RCL from the parent is null, then<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** the types are coming from the union itself.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** So we have to cross check the two child<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** rcls.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rcl == null)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumnList lrcl =
rightResultSet.getResultColumns();<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumnList rrcl =
leftResultSet.getResultColumns();<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftResultSet.bindUntypedNullsToResultColumns(rrcl);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightResultSet.bindUntypedNullsToResultColumns(lrcl);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp; &nbsp;<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftResultSet.bindUntypedNullsToResultColumns(rcl);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightResultSet.bindUntypedNullsToResultColumns(rcl);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Get the parameter types from the given RowResultSetNode
into the<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * given array of types.&nbsp; If an array position is already
filled in,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * don't clobber it.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param types&nbsp;&nbsp;&nbsp; The array of types to fill in<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param rrsn&nbsp;&nbsp;&nbsp; The RowResultSetNode from which to take the
param types<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; The number of new types found in the
RowResultSetNode<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp; int getParamColumnTypes(DataTypeDescriptor[] types,
RowResultSetNode rrsn)<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp; numTypes = 0;<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Look for columns where we have not found a non-? yet. */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; types.length; i++)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (types[i] == null)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumn rc =<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (ResultColumn)
rrsn.getResultColumns().elementAt(i);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( ! (rc.getExpression().isParameterNode()))<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; types[i] = rc.getExpressionType();<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; numTypes++;<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return numTypes;<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Set the type of each ? parameter in the given
RowResultSetNode<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * according to its ordinal position in the given array of
types.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param types&nbsp;&nbsp;&nbsp; An array of types containing the proper
type for each<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ? parameter, by ordinal position.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param rrsn&nbsp;&nbsp;&nbsp; A RowResultSetNode that could contain ?
parameters whose<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; types need to be set.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp; void setParamColumnTypes(DataTypeDescriptor[] types,
RowResultSetNode rrsn)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** Look for ? parameters in the result column list<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** of each RowResultSetNode<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumnList rrcl = rrsn.getResultColumns();<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int rrclSize = rrcl.size();<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int index = 0; index &lt; rrclSize; index++)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumn&nbsp;&nbsp;&nbsp; rc = (ResultColumn)
rrcl.elementAt(index);<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rc.getExpression().isParameterNode())<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** We found a ? - set its type to the type from the<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** type array.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((ParameterNode) rc.getExpression()).setDescriptor(<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; types[index]);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Bind the expressions in the target list.&nbsp; This means
binding the<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * sub-expressions, as well as figuring out what the return
type is<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * for each expression.&nbsp; This is useful for EXISTS subqueries,
where we<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * need to validate the target list before blowing it away and
replacing<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * it with a SELECT true.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; Nothing<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; public void bindTargetExpressions(FromList fromListParam)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftResultSet.bindTargetExpressions(fromListParam);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightResultSet.bindTargetExpressions(fromListParam);<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Push the order by list down from the cursor node<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * into its child result set so that the optimizer<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * has all of the information that it needs to<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * consider sort avoidance.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param orderByList&nbsp;&nbsp;&nbsp; The order by list<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @return Nothing.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp; void pushOrderByList(OrderByList orderByList)<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.orderByList = orderByList;<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Put a ProjectRestrictNode on top of each FromTable in the
FromList.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * ColumnReferences must continue to point to the same
ResultColumn, so<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * that ResultColumn must percolate up to the new PRN.&nbsp;
However,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * that ResultColumn will point to a new expression, a
VirtualColumnNode,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * which points to the FromTable and the ResultColumn that is
the source for<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * the ColumnReference. &nbsp;<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * (The new PRN will have the original of the ResultColumnList
and<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * the ResultColumns from that list.&nbsp; The FromTable will get
shallow copies<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * of the ResultColumnList and its ResultColumns.&nbsp;
ResultColumn.expression<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * will remain at the FromTable, with the PRN getting a new<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * VirtualColumnNode for each ResultColumn.expression.)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * We then project out the non-referenced columns.&nbsp; If there
are no referenced<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * columns, then the PRN's ResultColumnList will consist of a
single ResultColumn<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * whose expression is 1.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param numTables&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number of tables in the DML
Statement<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param gbl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The group by list, if any<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param fromList&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The from list, if any<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @return The generated ProjectRestrictNode atop the original
FromTable.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; public ResultSetNode preprocess(int numTables,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GroupByList gbl,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FromList fromList)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultSetNode newTop = this;<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* RESOLVE - what does numTables and referencedTableMap
mean here? */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftResultSet = leftResultSet.preprocess(numTables, gbl,
fromList);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightResultSet = rightResultSet.preprocess(numTables, gbl,
fromList);<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Build the referenced table map (left || right) */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; referencedTableMap = (JBitSet)
leftResultSet.getReferencedTableMap().clone();<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; referencedTableMap.or((JBitSet)
rightResultSet.getReferencedTableMap());<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* If this is a UNION without an all and we have<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * an order by then we can consider eliminating the sort
for the<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * order by.&nbsp; All of the columns in the order by list must<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * be ascending in order to do this.&nbsp; There are 2 cases:<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp; o&nbsp;&nbsp;&nbsp; The order by list is an in order prefix of the
columns<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; in the select list.&nbsp; In this case the output of
the<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sort from the distinct will be in the right order<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; so we simply eliminate the order by list.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp; o&nbsp;&nbsp;&nbsp; The order by list is a subset of the columns in
the<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the select list.&nbsp; In this case we need to
reorder the<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; columns in the select list so that the ordering
columns<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; are an in order prefix of the select list and
put a PRN<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; above the select so that the shape of the result
set<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is as expected.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((! all) &amp;&amp; orderByList != null &amp;&amp;
orderByList.allAscending())<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Order by list currently restricted to columns in
select<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * list, so we will always eliminate the order by here.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (orderByList.isInOrderPrefix(resultColumns))<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; orderByList = null;<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* RESOLVE - We currently only eliminate the order by
if it is<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * a prefix of the select list.&nbsp; We do not currently
do the<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * elimination if the order by is not a prefix because
the code<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * doesn't work.&nbsp; The problem has something to do with
the<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * fact that we generate additional nodes between the
union<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * and the PRN (for reordering that we would generate
here)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * when modifying the access paths.&nbsp; VCNs under the
PRN can be<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * seen as correlated since their source resultset is
the Union<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * which is no longer the result set directly under
them.&nbsp; This<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * causes the wrong code to get generated. (jerry -
11/3/98)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * (bug 59)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return newTop;<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-&nbsp;&nbsp; &nbsp;<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Ensure that the top of the RSN tree has a PredicateList.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param numTables&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The number of tables in the
query.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @return ResultSetNode&nbsp;&nbsp;&nbsp; A RSN tree with a node which has a
PredicateList on top.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp; public ResultSetNode ensurePredicateList(int numTables)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return genProjectRestrict(numTables);<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Verify that a SELECT * is valid for this type of subquery.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param outerFromList&nbsp;&nbsp;&nbsp; The FromList from the outer query
block(s)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param subqueryType&nbsp;&nbsp;&nbsp; The subquery type<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; None<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp; public void verifySelectStarSubquery(FromList outerFromList,
int subqueryType)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Check both sides - SELECT * is not valid on either side
*/<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftResultSet.verifySelectStarSubquery(outerFromList,
subqueryType);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightResultSet.verifySelectStarSubquery(outerFromList,
subqueryType);<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Determine whether or not the specified name is an exposed
name in<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * the current query block.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param name&nbsp;&nbsp;&nbsp; The specified name to search for as an
exposed name.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param schemaName&nbsp;&nbsp;&nbsp; Schema name, if non-null.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param exactMatch&nbsp;&nbsp;&nbsp; Whether or not we need an exact match
on specified schema and table<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; names or match on table id.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @return The FromTable, if any, with the exposed name.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp; protected FromTable getFromTableByName(String name, String
schemaName, boolean exactMatch)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* We search both sides for a TableOperatorNode (join
nodes)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * but only the left side for a UnionNode.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return leftResultSet.getFromTableByName(name, schemaName,
exactMatch);<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Set the result column for the subquery to a boolean true,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Useful for transformations such as<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * changing:<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where exists (select ... from ...)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * to:<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where (select true from ...)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * NOTE: No transformation is performed if the
ResultColumn.expression is<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * already the correct boolean constant.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param onlyConvertAlls&nbsp;&nbsp;&nbsp; Boolean, whether or not to just
convert *'s<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @return Nothing.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp; public void setResultToBooleanTrueNode(boolean onlyConvertAlls)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.setResultToBooleanTrueNode(onlyConvertAlls);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftResultSet.setResultToBooleanTrueNode(onlyConvertAlls);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightResultSet.setResultToBooleanTrueNode(onlyConvertAlls);<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * This ResultSet is the source for an Insert.&nbsp; The target RCL<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * is in a different order and/or a superset of this RCL.&nbsp; In
most cases<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * we will reorder and/or add defaults to the current RCL so
that is<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * matches the target RCL.&nbsp; Those RSNs whose generate() method
does<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * not handle projects will insert a PRN, with a new RCL which
matches<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * the target RCL, above the current RSN.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * NOTE - The new or enhanced RCL will be fully bound.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param numTargetColumns&nbsp;&nbsp;&nbsp; # of columns in target RCL<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param colMap[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int array representation of
correspondence between<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RCLs - colmap[i] = -1 -&gt;
missing in current RCL<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; colmap[i] = j -&gt;
targetRCL(i) &lt;-&gt; thisRCL(j+1)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param dataDictionary&nbsp;&nbsp;&nbsp; DataDictionary to use<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param targetTD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TableDescriptor for target if
the target is not a VTI, null if a VTI<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param targetVTI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Target description if it is a VTI,
null if not a VTI<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @return ResultSetNode&nbsp;&nbsp;&nbsp; The new top of the tree<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp; public ResultSetNode enhanceRCLForInsert(int numTargetColumns,
int[] colMap,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataDictionary
dataDictionary,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TableDescriptor
targetTD,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FromVTI targetVTI)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // our newResultCols are put into the bound form straight
away.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumnList newResultCols =<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (ResultColumnList)
getNodeFactory().getNode(<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
C_NodeTypes.RESULT_COLUMN_LIST,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
getContextManager());<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int numResultSetColumns = resultColumns.size();<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Create a massaged version of the source RCL.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * (Much simpler to build new list and then assign to
source,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * rather than massage the source list in place.)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int index = 0; index &lt; numTargetColumns; index++)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumn&nbsp;&nbsp;&nbsp; newResultColumn;<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumn&nbsp;&nbsp;&nbsp; oldResultColumn;<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ColumnReference newColumnReference;<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (colMap[index] != -1)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // getResultColumn uses 1-based positioning, so
offset the colMap entry appropriately<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oldResultColumn =
resultColumns.getResultColumn(colMap[index]+1);<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newColumnReference = (ColumnReference)
getNodeFactory().getNode(<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
C_NodeTypes.COLUMN_REFERENCE,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
oldResultColumn.getName(),<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
getContextManager());<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* The ColumnReference points to the source of the
value */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newColumnReference.setSource(oldResultColumn);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // colMap entry is 0-based, columnId is 1-based.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
newColumnReference.setType(oldResultColumn.getExpressionType());<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Source of an insert, so nesting levels must be 0<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newColumnReference.setNestingLevel(0);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newColumnReference.setSourceLevel(0);<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // because the insert already copied the target
table's<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // column descriptors into the result, we grab it
from there.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // alternatively, we could do what the else clause
does,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // and look it up in the DD again.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newResultColumn = (ResultColumn)
getNodeFactory().getNode(<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C_NodeTypes.RESULT_COLUMN,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oldResultColumn.getType(),<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newColumnReference,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getContextManager());<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newResultColumn = genNewRCForInsert(targetTD,
targetVTI, index + 1, dataDictionary);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newResultCols.addResultColumn(newResultColumn);<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* The generated ProjectRestrictNode now has the
ResultColumnList<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * in the order that the InsertNode expects.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * NOTE: This code here is an exception to several "rules":<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o&nbsp; This is the only ProjectRestrictNode that is
currently<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; generated outside of preprocess().<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o&nbsp; The UnionNode is the only node which is not
at the<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; top of the query tree which has
ColumnReferences under<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; its ResultColumnList prior to expression push
down.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (ResultSetNode) getNodeFactory().getNode(<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
C_NodeTypes.PROJECT_RESTRICT_NODE,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newResultCols,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tableProperties,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getContextManager());<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Evaluate whether or not the subquery in a FromSubquery is
flattenable. &nbsp;<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Currently, a FSqry is flattenable if all of the following
are true:<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o&nbsp; Subquery is a SelectNode. (ie, not a
RowResultSetNode or a UnionNode)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o&nbsp; It contains no top level subqueries.&nbsp; (RESOLVE -
we can relax this)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o&nbsp; It does not contain a group by or having clause<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o&nbsp; It does not contain aggregates.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @param fromList&nbsp;&nbsp;&nbsp; The outer from list<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @return boolean&nbsp;&nbsp;&nbsp; Whether or not the FromSubquery is
flattenable.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp; public boolean flattenableInFromSubquery(FromList fromList)<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Unions in FromSubquerys are not flattenable.&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Return whether or not to materialize this ResultSet tree.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @return Whether or not to materialize this ResultSet tree.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; would return valid results.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp; public boolean performMaterialization(JBitSet outerTables)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;-&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // RESOLVE - just say no to materialization right now -
should be a cost based decision<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br>
&gt;-<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Actual materialization, if appropriate, will be placed
by our parent PRN.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * This is because PRN might have a join condition to
apply.&nbsp; (Materialization<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * can only occur before that.<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //return true;<br>
&gt;-&nbsp;&nbsp;&nbsp; }<br>
&gt;-<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; /**<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Generate the code for this UnionNode.<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;@@ -1134,4 +323,9 @@<br>
&gt;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null,
"getUnionResultSet", ClassName.NoPutResultSet, 7);<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; String getOperatorName()<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "UNION";<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt; }<br>
&gt;Index:
java/engine/org/apache/derby/impl/sql/compile/SetOperatorNode.java<br>
&gt;===================================================================<br>
&gt;---
java/engine/org/apache/derby/impl/sql/compile/SetOperatorNode.java&nbsp;&nbsp;&nbsp;
(revision 0)<br>
&gt;+++
java/engine/org/apache/derby/impl/sql/compile/SetOperatorNode.java&nbsp;&nbsp;&nbsp;
(revision 0)<br>
&gt;@@ -0,0 +1,845 @@<br>
&gt;+/*<br>
&gt;+<br>
&gt;+&nbsp;&nbsp; Derby - Class org.apache.derby.impl.sql.compile.SetOperatorNode<br>
&gt;+<br>
&gt;+&nbsp;&nbsp; Copyright 2004 The Apache Software Foundation or its licensors,
as applicable.<br>
&gt;+<br>
&gt;+&nbsp;&nbsp; Licensed under the Apache License, Version 2.0 (the "License");<br>
&gt;+&nbsp;&nbsp; you may not use this file except in compliance with the License.<br>
&gt;+&nbsp;&nbsp; You may obtain a copy of the License at<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a class="moz-txt-link-freetext" href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a><br>
&gt;+<br>
&gt;+&nbsp;&nbsp; Unless required by applicable law or agreed to in writing,
software<br>
&gt;+&nbsp;&nbsp; distributed under the License is distributed on an "AS IS"
BASIS,<br>
&gt;+&nbsp;&nbsp; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.<br>
&gt;+&nbsp;&nbsp; See the License for the specific language governing permissions
and<br>
&gt;+&nbsp;&nbsp; limitations under the License.<br>
&gt;+<br>
&gt;+ */<br>
&gt;+<br>
&gt;+package&nbsp;&nbsp;&nbsp; org.apache.derby.impl.sql.compile;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.services.sanity.SanityManager;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.error.StandardException;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.sql.compile.C_NodeTypes;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.sql.dictionary.DataDictionary;<br>
&gt;+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.reference.SQLState;<br>
&gt;+import org.apache.derby.iapi.types.DataTypeDescriptor;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.util.JBitSet;<br>
&gt;+<br>
&gt;+/**<br>
&gt;+ * A SetOperatorNode represents a UNION, INTERSECT, or EXCEPT in a
DML statement. Binding and optimization<br>
&gt;+ * preprocessing is the same for all of these operations, so they
share bind methods in this abstract class.<br>
&gt;+ *<br>
&gt;+ * The class contains a boolean telling whether the operation
should eliminate<br>
&gt;+ * duplicate rows.<br>
&gt;+ *<br>
&gt;+ * @author Jeff Lichtman<br>
&gt;+ */<br>
&gt;+<br>
&gt;+public abstract class SetOperatorNode extends TableOperatorNode<br>
&gt;+{<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp; ** Tells whether to eliminate duplicate rows.&nbsp; all == TRUE
means do<br>
&gt;+&nbsp;&nbsp;&nbsp; ** not eliminate duplicates, all == FALSE means eliminate
duplicates.<br>
&gt;+&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; boolean&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; all;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /* Is this a UNION ALL generated for a table constructor. */<br>
&gt;+&nbsp;&nbsp;&nbsp; boolean&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tableConstructor;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /* True if this is the top node of a table constructor */<br>
&gt;+&nbsp;&nbsp;&nbsp; boolean&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; topTableConstructor;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; OrderByList orderByList;<br>
&gt;+<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Initializer for a SetOperatorNode.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param leftResult&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The ResultSetNode on the left side
of this union<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param rightResult&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The ResultSetNode on the right
side of this union<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param all&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Whether or not this is an ALL.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param tableConstructor&nbsp;&nbsp;&nbsp; Whether or not this is from a
table constructor.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param tableProperties&nbsp;&nbsp;&nbsp; Properties list associated with
the table<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; public void init(<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object leftResult,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object rightResult,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object all,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object tableConstructor,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object tableProperties)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.init(leftResult, rightResult, tableProperties);<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.all = ((Boolean) all).booleanValue();<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Is this an ALL for a table constructor? */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.tableConstructor = ((Boolean)
tableConstructor).booleanValue();<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* resultColumns cannot be null, so we make a copy of the
left RCL<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * for now.&nbsp; At bind() time, we need to recopy the list
because there<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * may have been a "*" in the list.&nbsp; (We will set the
names and<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * column types at that time, as expected.)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resultColumns =
leftResultSet.getResultColumns().copyListAndObjects();<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Mark this as the top node of a table constructor.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public void markTopTableConstructor()<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; topTableConstructor = true;<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Tell whether this is a UNION for a table constructor.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; boolean tableConstructor()<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return tableConstructor;<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Check for (and reject) ? parameters directly under the
ResultColumns.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * This is done for SELECT statements.&nbsp; Don't reject
parameters that<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * are in a table constructor - these are allowed, as long as
the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * table constructor is in an INSERT statement or each column
of the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * table constructor has at least one non-? column.&nbsp; The
latter case<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * is checked below, in bindExpressions().<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; Nothing<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown if a ? parameter
found<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; directly under a
ResultColumn<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public void rejectParameters() throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( ! tableConstructor())<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.rejectParameters();<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Set the type of column in the result column lists of each<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * source of this union tree to the type in the given result
column list<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * (which represents the result columns for an insert).<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * This is only for table constructors that appear in insert
statements.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param typeColumns&nbsp;&nbsp;&nbsp; The ResultColumnList containing the
desired result<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; types.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; void setTableConstructorTypes(ResultColumnList typeColumns)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (SanityManager.DEBUG)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SanityManager.ASSERT(resultColumns.size() &lt;=
typeColumns.size(),<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "More columns in ResultColumnList than in base
table.");<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultSetNode&nbsp;&nbsp;&nbsp; rsn;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** Should only set types of ? parameters to types of
result columns<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** if it's a table constructor.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (tableConstructor())<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* By looping through the union nodes, we avoid
recursion */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (rsn = this; rsn instanceof UnionNode; )<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UnionNode union = (UnionNode) rsn;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** Assume that table constructors are left-deep
trees of UnionNodes<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** with RowResultSet nodes on the right.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (SanityManager.DEBUG)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SanityManager.ASSERT(<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; union.rightResultSet instanceof
RowResultSetNode,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "A " +
union.rightResultSet.getClass().getName() +<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " is on the right of a union in a table
constructor");<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((RowResultSetNode)
union.rightResultSet).setTableConstructorTypes(<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
typeColumns);<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rsn = union.leftResultSet;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* The last node on the left should be a result set
node */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (SanityManager.DEBUG)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SanityManager.ASSERT(rsn instanceof
RowResultSetNode,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "A " + rsn.getClass().getName() +<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " is at the left end of a table constructor");<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((RowResultSetNode)
rsn).setTableConstructorTypes(typeColumns);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Convert this object to a String.&nbsp; See comments in
QueryTreeNode.java<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * for how this should be done for tree printing.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; This object as a String<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; public String toString()<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (SanityManager.DEBUG)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp;&nbsp;&nbsp;&nbsp; "all: " + all + "\n" +<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "tableConstructor: " + tableConstructor + "\n" +<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "orderByList: " +<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (orderByList != null ? orderByList.toString() :
"null") + "\n" +<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.toString();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "";<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Bind the expressions under this TableOperatorNode.&nbsp; This
means<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * binding the sub-expressions, as well as figuring out what
the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * return type is for each expression.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; Nothing<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; public void bindExpressions(FromList fromListParam)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.bindExpressions(fromListParam);<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** Each ? parameter in a table constructor that is not in
an insert<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** statement takes its type from the first non-? in its
column<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** of the table constructor.&nbsp; It's an error to have a
column that<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** has all ?s.&nbsp; Do this only for the top of the table
constructor<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** list - we don't want to do this for every level of
union node<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** in the table constructor.&nbsp; Also, don't do this for an
INSERT -<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** the types of the ? parameters come from the columns
being inserted<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** into in that case.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (topTableConstructor &amp;&amp; ( ! insertSource) )<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** Step through all the rows in the table constructor
to<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** get the type of the first non-? in each column.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataTypeDescriptor[] types =<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new
DataTypeDescriptor[leftResultSet.getResultColumns().size()];<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultSetNode rsn;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int numTypes = 0;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* By looping through the union nodes, we avoid
recursion */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (rsn = this; rsn instanceof SetOperatorNode; )<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SetOperatorNode&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setOperator =
(SetOperatorNode) rsn;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** Assume that table constructors are left-deep
trees of<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** SetOperatorNodes with RowResultSet nodes on the
right.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (SanityManager.DEBUG)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SanityManager.ASSERT(<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setOperator.rightResultSet instanceof
RowResultSetNode,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "A " +
setOperator.rightResultSet.getClass().getName() +<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; " is on the right side of a setOperator in a
table constructor");<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RowResultSetNode&nbsp;&nbsp;&nbsp; rrsn =<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (RowResultSetNode)
setOperator.rightResultSet;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; numTypes += getParamColumnTypes(types, rrsn);<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rsn = setOperator.leftResultSet;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* The last node on the left should be a result set
node */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (SanityManager.DEBUG)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SanityManager.ASSERT(rsn instanceof
RowResultSetNode);<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; numTypes += getParamColumnTypes(types,
(RowResultSetNode) rsn);<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Are there any columns that are all ? parameters? */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (numTypes &lt; types.length)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw
StandardException.newException(SQLState.LANG_TABLE_CONSTRUCTOR_ALL_PARAM_COLUMN);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** Loop through the nodes again. This time, look for
parameter<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** nodes, and give them the type from the type array
we just<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** constructed.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (rsn = this; rsn instanceof SetOperatorNode; )<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SetOperatorNode&nbsp;&nbsp;&nbsp; setOperator = (SetOperatorNode)
rsn;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RowResultSetNode rrsn = (RowResultSetNode)
setOperator.rightResultSet;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setParamColumnTypes(types, rrsn);<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rsn = setOperator.leftResultSet;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setParamColumnTypes(types, (RowResultSetNode) rsn);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Bind the result columns of this ResultSetNode when there is
no<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * base table to bind them to.&nbsp; This is useful for SELECT
statements,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * where the result columns get their types from the
expressions that<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * live under them.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param fromListParam&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FromList to use/append to.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; Nothing<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public void bindResultColumns(FromList fromListParam)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.bindResultColumns(fromListParam);<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Now we build our RCL */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buildRCL();<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Bind the result columns for this ResultSetNode to a base
table.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * This is useful for INSERT and UPDATE statements, where the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * result columns get their types from the table being updated
or<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * inserted into.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * If a result column list is specified, then the verification
that the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * result column list does not contain any duplicates will be
done when<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * binding them by name.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param targetTableDescriptor&nbsp;&nbsp;&nbsp; The TableDescriptor for the
table being<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; updated or inserted into<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param targetColumnList&nbsp;&nbsp;&nbsp; For INSERT statements, the user<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; does not have to supply column<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; names (for example, "insert into t<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; values (1,2,3)".&nbsp; When this<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parameter is null, it means that<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the user did not supply column<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; names, and so the binding should<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; be done based on order.&nbsp; When it<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is not null, it means do the binding<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by name, not position.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param statement&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Calling DMLStatementNode
(Insert or Update)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param fromListParam&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FromList to use/append to.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; Nothing<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; public void bindResultColumns(TableDescriptor
targetTableDescriptor,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FromVTI targetVTI,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumnList targetColumnList,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DMLStatementNode statement,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FromList fromListParam)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.bindResultColumns(targetTableDescriptor,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; targetVTI,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; targetColumnList, statement,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; fromListParam);<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Now we build our RCL */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buildRCL();<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Build the RCL for this node.&nbsp; We propagate the RCL up from
the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * left child to form this node's RCL.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; Nothing<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; private void buildRCL() throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Verify that both sides of the union have the same # of
columns in their<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * RCL.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (leftResultSet.getResultColumns().size() !=<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightResultSet.getResultColumns().size())<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw
StandardException.newException(SQLState.LANG_UNION_UNMATCHED_COLUMNS,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
getOperatorName());<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* We need to recreate resultColumns for this node, since
there<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * may have been 1 or more *'s in the left's SELECT list.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resultColumns =
leftResultSet.getResultColumns().copyListAndObjects();<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Create new expressions with the dominant types after
verifying<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * union compatibility between left and right sides.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
resultColumns.setUnionResultExpression(rightResultSet.getResultColumns(),
tableNumber, level, getOperatorName());<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Bind the result columns of a table constructor to the types
in the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * given ResultColumnList.&nbsp; Use when inserting from a table
constructor,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * and there are nulls in the values clauses.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param rcl&nbsp;&nbsp;&nbsp; The ResultColumnList with the types to bind to<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public void bindUntypedNullsToResultColumns(ResultColumnList
rcl)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** If the RCL from the parent is null, then<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** the types are coming from the union itself.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** So we have to cross check the two child<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** rcls.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rcl == null)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumnList lrcl =
rightResultSet.getResultColumns();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumnList rrcl =
leftResultSet.getResultColumns();<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftResultSet.bindUntypedNullsToResultColumns(rrcl);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightResultSet.bindUntypedNullsToResultColumns(lrcl);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else&nbsp;&nbsp; &nbsp;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftResultSet.bindUntypedNullsToResultColumns(rcl);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightResultSet.bindUntypedNullsToResultColumns(rcl);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Get the parameter types from the given RowResultSetNode
into the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * given array of types.&nbsp; If an array position is already
filled in,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * don't clobber it.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param types&nbsp;&nbsp;&nbsp; The array of types to fill in<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param rrsn&nbsp;&nbsp;&nbsp; The RowResultSetNode from which to take the
param types<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; The number of new types found in the
RowResultSetNode<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; int getParamColumnTypes(DataTypeDescriptor[] types,
RowResultSetNode rrsn)<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int&nbsp;&nbsp;&nbsp; numTypes = 0;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Look for columns where we have not found a non-? yet. */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt; types.length; i++)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (types[i] == null)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumn rc =<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (ResultColumn)
rrsn.getResultColumns().elementAt(i);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( ! (rc.getExpression().isParameterNode()))<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; types[i] = rc.getExpressionType();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; numTypes++;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return numTypes;<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Set the type of each ? parameter in the given
RowResultSetNode<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * according to its ordinal position in the given array of
types.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param types&nbsp;&nbsp;&nbsp; An array of types containing the proper
type for each<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ? parameter, by ordinal position.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param rrsn&nbsp;&nbsp;&nbsp; A RowResultSetNode that could contain ?
parameters whose<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; types need to be set.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; void setParamColumnTypes(DataTypeDescriptor[] types,
RowResultSetNode rrsn)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** Look for ? parameters in the result column list<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** of each RowResultSetNode<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumnList rrcl = rrsn.getResultColumns();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int rrclSize = rrcl.size();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int index = 0; index &lt; rrclSize; index++)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumn&nbsp;&nbsp;&nbsp; rc = (ResultColumn)
rrcl.elementAt(index);<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rc.getExpression().isParameterNode())<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** We found a ? - set its type to the type from the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** type array.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((ParameterNode) rc.getExpression()).setDescriptor(<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; types[index]);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Bind the expressions in the target list.&nbsp; This means
binding the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * sub-expressions, as well as figuring out what the return
type is<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * for each expression.&nbsp; This is useful for EXISTS subqueries,
where we<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * need to validate the target list before blowing it away and
replacing<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * it with a SELECT true.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; Nothing<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; public void bindTargetExpressions(FromList fromListParam)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftResultSet.bindTargetExpressions(fromListParam);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightResultSet.bindTargetExpressions(fromListParam);<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Push the order by list down from the cursor node<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * into its child result set so that the optimizer<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * has all of the information that it needs to<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * consider sort avoidance.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param orderByList&nbsp;&nbsp;&nbsp; The order by list<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return Nothing.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; void pushOrderByList(OrderByList orderByList)<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.orderByList = orderByList;<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Put a ProjectRestrictNode on top of each FromTable in the
FromList.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * ColumnReferences must continue to point to the same
ResultColumn, so<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * that ResultColumn must percolate up to the new PRN.&nbsp;
However,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * that ResultColumn will point to a new expression, a
VirtualColumnNode,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * which points to the FromTable and the ResultColumn that is
the source for<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * the ColumnReference. &nbsp;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * (The new PRN will have the original of the ResultColumnList
and<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * the ResultColumns from that list.&nbsp; The FromTable will get
shallow copies<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * of the ResultColumnList and its ResultColumns.&nbsp;
ResultColumn.expression<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * will remain at the FromTable, with the PRN getting a new<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * VirtualColumnNode for each ResultColumn.expression.)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * We then project out the non-referenced columns.&nbsp; If there
are no referenced<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * columns, then the PRN's ResultColumnList will consist of a
single ResultColumn<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * whose expression is 1.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param numTables&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number of tables in the DML
Statement<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param gbl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The group by list, if any<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param fromList&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The from list, if any<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return The generated ProjectRestrictNode atop the original
FromTable.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; public ResultSetNode preprocess(int numTables,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GroupByList gbl,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FromList fromList)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultSetNode newTop = this;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* RESOLVE - what does numTables and referencedTableMap
mean here? */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftResultSet = leftResultSet.preprocess(numTables, gbl,
fromList);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightResultSet = rightResultSet.preprocess(numTables, gbl,
fromList);<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Build the referenced table map (left || right) */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; referencedTableMap = (JBitSet)
leftResultSet.getReferencedTableMap().clone();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; referencedTableMap.or((JBitSet)
rightResultSet.getReferencedTableMap());<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* If this is a UNION without an all and we have<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * an order by then we can consider eliminating the sort
for the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * order by.&nbsp; All of the columns in the order by list must<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * be ascending in order to do this.&nbsp; There are 2 cases:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp; o&nbsp;&nbsp;&nbsp; The order by list is an in order prefix of the
columns<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; in the select list.&nbsp; In this case the output of
the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sort from the distinct will be in the right order<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; so we simply eliminate the order by list.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp; o&nbsp;&nbsp;&nbsp; The order by list is a subset of the columns in
the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the select list.&nbsp; In this case we need to
reorder the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; columns in the select list so that the ordering
columns<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; are an in order prefix of the select list and
put a PRN<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; above the select so that the shape of the result
set<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; is as expected.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((! all) &amp;&amp; orderByList != null &amp;&amp;
orderByList.allAscending())<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Order by list currently restricted to columns in
select<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * list, so we will always eliminate the order by here.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (orderByList.isInOrderPrefix(resultColumns))<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; orderByList = null;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* RESOLVE - We currently only eliminate the order by
if it is<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * a prefix of the select list.&nbsp; We do not currently
do the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * elimination if the order by is not a prefix because
the code<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * doesn't work.&nbsp; The problem has something to do with
the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * fact that we generate additional nodes between the
union<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * and the PRN (for reordering that we would generate
here)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * when modifying the access paths.&nbsp; VCNs under the
PRN can be<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * seen as correlated since their source resultset is
the Union<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * which is no longer the result set directly under
them.&nbsp; This<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * causes the wrong code to get generated. (jerry -
11/3/98)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * (bug 59)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return newTop;<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp; &nbsp;<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Ensure that the top of the RSN tree has a PredicateList.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param numTables&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The number of tables in the
query.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return ResultSetNode&nbsp;&nbsp;&nbsp; A RSN tree with a node which has a
PredicateList on top.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public ResultSetNode ensurePredicateList(int numTables)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return genProjectRestrict(numTables);<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Verify that a SELECT * is valid for this type of subquery.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param outerFromList&nbsp;&nbsp;&nbsp; The FromList from the outer query
block(s)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param subqueryType&nbsp;&nbsp;&nbsp; The subquery type<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; None<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public void verifySelectStarSubquery(FromList outerFromList,
int subqueryType)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Check both sides - SELECT * is not valid on either side
*/<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftResultSet.verifySelectStarSubquery(outerFromList,
subqueryType);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightResultSet.verifySelectStarSubquery(outerFromList,
subqueryType);<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Determine whether or not the specified name is an exposed
name in<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * the current query block.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param name&nbsp;&nbsp;&nbsp; The specified name to search for as an
exposed name.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param schemaName&nbsp;&nbsp;&nbsp; Schema name, if non-null.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param exactMatch&nbsp;&nbsp;&nbsp; Whether or not we need an exact match
on specified schema and table<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; names or match on table id.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return The FromTable, if any, with the exposed name.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; protected FromTable getFromTableByName(String name, String
schemaName, boolean exactMatch)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* We search both sides for a TableOperatorNode (join
nodes)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * but only the left side for a UnionNode.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return leftResultSet.getFromTableByName(name, schemaName,
exactMatch);<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Set the result column for the subquery to a boolean true,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Useful for transformations such as<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * changing:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where exists (select ... from ...)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * to:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; where (select true from ...)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * NOTE: No transformation is performed if the
ResultColumn.expression is<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * already the correct boolean constant.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param onlyConvertAlls&nbsp;&nbsp;&nbsp; Boolean, whether or not to just
convert *'s<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return Nothing.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public void setResultToBooleanTrueNode(boolean onlyConvertAlls)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.setResultToBooleanTrueNode(onlyConvertAlls);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftResultSet.setResultToBooleanTrueNode(onlyConvertAlls);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightResultSet.setResultToBooleanTrueNode(onlyConvertAlls);<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * This ResultSet is the source for an Insert.&nbsp; The target RCL<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * is in a different order and/or a superset of this RCL.&nbsp; In
most cases<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * we will reorder and/or add defaults to the current RCL so
that is<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * matches the target RCL.&nbsp; Those RSNs whose generate() method
does<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * not handle projects will insert a PRN, with a new RCL which
matches<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * the target RCL, above the current RSN.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * NOTE - The new or enhanced RCL will be fully bound.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param numTargetColumns&nbsp;&nbsp;&nbsp; # of columns in target RCL<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param colMap[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int array representation of
correspondence between<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RCLs - colmap[i] = -1 -&gt;
missing in current RCL<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; colmap[i] = j -&gt;
targetRCL(i) &lt;-&gt; thisRCL(j+1)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param dataDictionary&nbsp;&nbsp;&nbsp; DataDictionary to use<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param targetTD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TableDescriptor for target if
the target is not a VTI, null if a VTI<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param targetVTI&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Target description if it is a VTI,
null if not a VTI<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return ResultSetNode&nbsp;&nbsp;&nbsp; The new top of the tree<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public ResultSetNode enhanceRCLForInsert(int numTargetColumns,
int[] colMap,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataDictionary
dataDictionary,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TableDescriptor
targetTD,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FromVTI targetVTI)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // our newResultCols are put into the bound form straight
away.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumnList newResultCols =<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (ResultColumnList)
getNodeFactory().getNode(<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
C_NodeTypes.RESULT_COLUMN_LIST,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
getContextManager());<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int numResultSetColumns = resultColumns.size();<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Create a massaged version of the source RCL.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * (Much simpler to build new list and then assign to
source,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * rather than massage the source list in place.)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int index = 0; index &lt; numTargetColumns; index++)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumn&nbsp;&nbsp;&nbsp; newResultColumn;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumn&nbsp;&nbsp;&nbsp; oldResultColumn;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ColumnReference newColumnReference;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (colMap[index] != -1)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // getResultColumn uses 1-based positioning, so
offset the colMap entry appropriately<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oldResultColumn =
resultColumns.getResultColumn(colMap[index]+1);<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newColumnReference = (ColumnReference)
getNodeFactory().getNode(<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
C_NodeTypes.COLUMN_REFERENCE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
oldResultColumn.getName(),<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
getContextManager());<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* The ColumnReference points to the source of the
value */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newColumnReference.setSource(oldResultColumn);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // colMap entry is 0-based, columnId is 1-based.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
newColumnReference.setType(oldResultColumn.getExpressionType());<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Source of an insert, so nesting levels must be 0<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newColumnReference.setNestingLevel(0);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newColumnReference.setSourceLevel(0);<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // because the insert already copied the target
table's<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // column descriptors into the result, we grab it
from there.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // alternatively, we could do what the else clause
does,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // and look it up in the DD again.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newResultColumn = (ResultColumn)
getNodeFactory().getNode(<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C_NodeTypes.RESULT_COLUMN,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oldResultColumn.getType(),<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newColumnReference,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getContextManager());<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newResultColumn = genNewRCForInsert(targetTD,
targetVTI, index + 1, dataDictionary);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newResultCols.addResultColumn(newResultColumn);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* The generated ProjectRestrictNode now has the
ResultColumnList<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * in the order that the InsertNode expects.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * NOTE: This code here is an exception to several "rules":<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o&nbsp; This is the only ProjectRestrictNode that is
currently<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; generated outside of preprocess().<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o&nbsp; The UnionNode is the only node which is not
at the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; top of the query tree which has
ColumnReferences under<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; its ResultColumnList prior to expression push
down.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (ResultSetNode) getNodeFactory().getNode(<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
C_NodeTypes.PROJECT_RESTRICT_NODE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; newResultCols,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tableProperties,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getContextManager());<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Evaluate whether or not the subquery in a FromSubquery is
flattenable. &nbsp;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Currently, a FSqry is flattenable if all of the following
are true:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o&nbsp; Subquery is a SelectNode. (ie, not a
RowResultSetNode or a UnionNode)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o&nbsp; It contains no top level subqueries.&nbsp; (RESOLVE -
we can relax this)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o&nbsp; It does not contain a group by or having clause<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o&nbsp; It does not contain aggregates.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param fromList&nbsp;&nbsp;&nbsp; The outer from list<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return boolean&nbsp;&nbsp;&nbsp; Whether or not the FromSubquery is
flattenable.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public boolean flattenableInFromSubquery(FromList fromList)<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Unions in FromSubquerys are not flattenable.&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Return whether or not to materialize this ResultSet tree.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return Whether or not to materialize this ResultSet tree.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; would return valid results.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public boolean performMaterialization(JBitSet outerTables)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // RESOLVE - just say no to materialization right now -
should be a cost based decision<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Actual materialization, if appropriate, will be placed
by our parent PRN.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * This is because PRN might have a join condition to
apply.&nbsp; (Materialization<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * can only occur before that.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //return true;<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return the operator name: "UNION", "INTERSECT", or "EXCEPT"<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; abstract String getOperatorName();<br>
&gt;+}<br>
&gt;Index: java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj<br>
&gt;===================================================================<br>
&gt;--- java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj&nbsp;&nbsp;&nbsp;
(revision 111907)<br>
&gt;+++ java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj&nbsp;&nbsp;&nbsp;
(working copy)<br>
&gt;@@ -85,6 +85,7 @@<br>
&gt; import org.apache.derby.impl.sql.compile.TransactionStatementNode;<br>
&gt; import org.apache.derby.impl.sql.compile.TriggerReferencingStruct;<br>
&gt; import org.apache.derby.impl.sql.compile.UnionNode;<br>
&gt;+import org.apache.derby.impl.sql.compile.IntersectOrExceptNode;<br>
&gt; import org.apache.derby.impl.sql.compile.UntypedNullConstantNode;<br>
&gt; import org.apache.derby.impl.sql.compile.UpdateNode;<br>
&gt; import org.apache.derby.impl.sql.compile.UserTypeConstantNode;<br>
&gt;@@ -175,6 +176,15 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; // Define for UTF8 max<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; private static final int&nbsp;&nbsp;&nbsp; MAX_UTF8_LENGTH = 65535;<br>
&gt;<br>
&gt;+&nbsp;&nbsp;&nbsp; // Constants for set operator types<br>
&gt;+&nbsp;&nbsp;&nbsp; private static final int NO_SET_OP = 0;<br>
&gt;+&nbsp;&nbsp;&nbsp; private static final int UNION_OP = 1;<br>
&gt;+&nbsp;&nbsp;&nbsp; private static final int UNION_ALL_OP = 2;<br>
&gt;+&nbsp;&nbsp;&nbsp; private static final int EXCEPT_OP = 3;<br>
&gt;+&nbsp;&nbsp;&nbsp; private static final int EXCEPT_ALL_OP = 4;<br>
&gt;+&nbsp;&nbsp;&nbsp; private static final int INTERSECT_OP = 5;<br>
&gt;+&nbsp;&nbsp;&nbsp; private static final int INTERSECT_ALL_OP = 6;<br>
&gt;+<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; private StringSlicer&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; stringSlicer;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; private Object[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; paramDefaults;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; private String&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; statementSQLText;<br>
&gt;@@ -2683,7 +2693,7 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; OrderByList orderCols = null;<br>
&gt; }<br>
&gt; {<br>
&gt;-&nbsp;&nbsp;&nbsp; queryExpression = queryExpression(null, Boolean.FALSE)<br>
&gt;+&nbsp;&nbsp;&nbsp; queryExpression = queryExpression(null, NO_SET_OP)<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ orderCols = orderByClause() ]<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ &lt;FOR&gt; forUpdateState =
forUpdateClause(updateColumns) ]<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ isolationLevel = atIsolationLevel() ]<br>
&gt;@@ -4129,24 +4139,37 @@<br>
&gt;<br>
&gt; /*<br>
&gt;&nbsp; * &lt;A NAME="queryExpression"&gt;queryExpression&lt;/A&gt;<br>
&gt;+ *<br>
&gt;+ * We have to be carefull to get the associativity correct.
According to the SQL spec<br>
&gt;+ *&nbsp;&nbsp; &lt;non-join query expression&gt; ::=<br>
&gt;+ *&nbsp;&nbsp;&nbsp;&nbsp; &lt;non-join query term&gt;<br>
&gt;+ *&nbsp;&nbsp;&nbsp; | &lt;query expression body&gt; UNION [ ALL ] &lt;query
term&gt;<br>
&gt;+ *&nbsp;&nbsp;&nbsp; | &lt;query expression body&gt; EXCEPT [ ALL ] &lt;query
term&gt;<br>
&gt;+ * Meaning that<br>
&gt;+ *&nbsp;&nbsp; t1 UNION ALL t2 UNION t3<br>
&gt;+ * is equivalent to<br>
&gt;+ *&nbsp;&nbsp; (t1 UNION ALL t2) UNION t3<br>
&gt;+ * However recursive descent parsers want recursion to be on the
right, so this kind of associativity is unnatural<br>
&gt;+ * for our parser. The queryExpression method must know whether it
is being called as the right hand side of a<br>
&gt;+ * set operator to produce a query tree with the correct
associativity.<br>
&gt;&nbsp; */<br>
&gt; ResultSetNode<br>
&gt;-queryExpression(ResultSetNode leftSide, Boolean unionAll) throws
StandardException :<br>
&gt;+queryExpression(ResultSetNode leftSide, int operatorType) throws
StandardException :<br>
&gt; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; ResultSetNode&nbsp;&nbsp;&nbsp; term;<br>
&gt; }<br>
&gt; {<br>
&gt;-&nbsp;&nbsp;&nbsp; term = nonJoinQueryTerm(leftSide, unionAll) [ term =
union(term) ]<br>
&gt;+&nbsp;&nbsp;&nbsp; term = nonJoinQueryTerm(leftSide, operatorType) [ term =
unionOrExcept(term) ]<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return term;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt; }<br>
&gt;<br>
&gt; /*<br>
&gt;- * &lt;A NAME="union"&gt;union&lt;/A&gt;<br>
&gt;+ * &lt;A NAME="unionOrExcept"&gt;unionOrExcept&lt;/A&gt;<br>
&gt;&nbsp; */<br>
&gt; ResultSetNode<br>
&gt;-union(ResultSetNode term) throws StandardException :<br>
&gt;+unionOrExcept(ResultSetNode term) throws StandardException :<br>
&gt; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; ResultSetNode&nbsp;&nbsp;&nbsp; expression;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; Token&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tok = null;<br>
&gt;@@ -4154,42 +4177,133 @@<br>
&gt; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; &lt;UNION&gt; [ tok = &lt;ALL&gt; ] expression =<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; queryExpression(term,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (tok != null) ? Boolean.TRUE :
Boolean.FALSE)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (tok != null) ? UNION_ALL_OP :
UNION_OP)<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return expression;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+|<br>
&gt;+&nbsp;&nbsp;&nbsp; &lt;EXCEPT&gt; [ tok = &lt;ALL&gt; ] expression =<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; queryExpression(term,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (tok != null) ? EXCEPT_ALL_OP :
EXCEPT_OP)<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return expression;<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt; }<br>
&gt;<br>
&gt;<br>
&gt; /*<br>
&gt;&nbsp; * &lt;A NAME="nonJoinQueryTerm"&gt;nonJoinQueryTerm&lt;/A&gt;<br>
&gt;+ *<br>
&gt;+ * Be careful with the associativity of INTERSECT. According to
the SQL spec<br>
&gt;+ *&nbsp;&nbsp; t1 INTERSECT t2 INTERSECT ALL t3<br>
&gt;+ * is equivalent to<br>
&gt;+ *&nbsp;&nbsp; (t1 INTERSECT t2) INTERSECT ALL t3<br>
&gt;+ * which is not the same as<br>
&gt;+ *&nbsp;&nbsp; t1 INTERSECT (t2 INTERSECT ALL t3)<br>
&gt;+ * See the comment on queryExpression.<br>
&gt;&nbsp; */<br>
&gt; ResultSetNode<br>
&gt;-nonJoinQueryTerm(ResultSetNode leftSide, Boolean unionAll) throws
StandardException :<br>
&gt;+nonJoinQueryTerm(ResultSetNode leftSide, int operatorType) throws
StandardException :<br>
&gt; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; ResultSetNode&nbsp;&nbsp;&nbsp; term;<br>
&gt; }<br>
&gt; {<br>
&gt;-&nbsp;&nbsp;&nbsp; /*<br>
&gt;-&nbsp;&nbsp;&nbsp; ** Omitted "intersect".<br>
&gt;-&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp; term = nonJoinQueryPrimary()<br>
&gt;+&nbsp;&nbsp;&nbsp; term = nonJoinQueryPrimary() [ term = intersect( term) ]<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (leftSide != null)<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (ResultSetNode) nodeFactory.getNode(<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C_NodeTypes.UNION_NODE,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftSide,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; term,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unionAll,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boolean.FALSE,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getContextManager());<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return term;<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch( operatorType)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case NO_SET_OP:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return term;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case UNION_OP:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (ResultSetNode) nodeFactory.getNode(<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C_NodeTypes.UNION_NODE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftSide,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; term,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boolean.FALSE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boolean.FALSE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getContextManager());<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case UNION_ALL_OP:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (ResultSetNode) nodeFactory.getNode(<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C_NodeTypes.UNION_NODE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftSide,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; term,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boolean.TRUE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boolean.FALSE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getContextManager());<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case EXCEPT_OP:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (ResultSetNode) nodeFactory.getNode(<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C_NodeTypes.INTERSECT_OR_EXCEPT_NODE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ReuseFactory.getInteger(
IntersectOrExceptNode.EXCEPT_OP),<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftSide,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; term,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boolean.FALSE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boolean.FALSE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getContextManager());<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case EXCEPT_ALL_OP:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (ResultSetNode) nodeFactory.getNode(<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C_NodeTypes.INTERSECT_OR_EXCEPT_NODE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ReuseFactory.getInteger(
IntersectOrExceptNode.EXCEPT_OP),<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftSide,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; term,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boolean.TRUE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boolean.FALSE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getContextManager());<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case INTERSECT_OP:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (ResultSetNode) nodeFactory.getNode(<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C_NodeTypes.INTERSECT_OR_EXCEPT_NODE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ReuseFactory.getInteger(
IntersectOrExceptNode.INTERSECT_OP),<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftSide,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; term,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boolean.FALSE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boolean.FALSE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getContextManager());<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case INTERSECT_ALL_OP:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (ResultSetNode) nodeFactory.getNode(<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C_NodeTypes.INTERSECT_OR_EXCEPT_NODE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ReuseFactory.getInteger(
IntersectOrExceptNode.INTERSECT_OP),<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftSide,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; term,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boolean.TRUE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Boolean.FALSE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; null,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getContextManager());<br>
&gt;+<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (SanityManager.DEBUG)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SanityManager.THROWASSERT( "Invalid set operator
type: " + operatorType);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+}<br>
&gt;+<br>
&gt;+/*<br>
&gt;+ * &lt;A NAME="intersect"&gt;intersect&lt;/A&gt;<br>
&gt;+ */<br>
&gt;+ResultSetNode<br>
&gt;+intersect(ResultSetNode term) throws StandardException :<br>
&gt;+{<br>
&gt;+&nbsp;&nbsp;&nbsp; ResultSetNode&nbsp;&nbsp;&nbsp; expression;<br>
&gt;+&nbsp;&nbsp;&nbsp; Token&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tok = null;<br>
&gt;+}<br>
&gt;+{<br>
&gt;+&nbsp;&nbsp;&nbsp; &lt;INTERSECT&gt; [ tok = &lt;ALL&gt; ] expression =<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nonJoinQueryTerm(term, (tok != null) ?
INTERSECT_ALL_OP : INTERSECT_OP)<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return expression;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt; }<br>
&gt;<br>
&gt;@@ -4207,7 +4321,7 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return primary;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt; |<br>
&gt;-&nbsp;&nbsp;&nbsp; &lt;LEFT_PAREN&gt; primary = queryExpression(null,
Boolean.FALSE) &lt;RIGHT_PAREN&gt;<br>
&gt;+&nbsp;&nbsp;&nbsp; &lt;LEFT_PAREN&gt; primary = queryExpression(null, NO_SET_OP)
&lt;RIGHT_PAREN&gt;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return primary;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;@@ -6750,7 +6864,7 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;LEFT_PAREN&gt; columnList = insertColumnList()
&lt;RIGHT_PAREN&gt;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; ]<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; [ targetProperties = propertyList() ]<br>
&gt;-&nbsp;&nbsp;&nbsp; queryExpression = queryExpression(null, Boolean.FALSE)<br>
&gt;+&nbsp;&nbsp;&nbsp; queryExpression = queryExpression(null, NO_SET_OP)<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (QueryTreeNode) nodeFactory.getNode(<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C_NodeTypes.INSERT_NODE,<br>
&gt;@@ -6997,7 +7111,7 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; SubqueryNode&nbsp;&nbsp;&nbsp; subqueryNode;<br>
&gt; }<br>
&gt; {<br>
&gt;-&nbsp;&nbsp;&nbsp; queryExpression = queryExpression(null, Boolean.FALSE)<br>
&gt;+&nbsp;&nbsp;&nbsp; queryExpression = queryExpression(null, NO_SET_OP)<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; subqueryNode = (SubqueryNode) nodeFactory.getNode(<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C_NodeTypes.SUBQUERY_NODE,<br>
&gt;@@ -8778,7 +8892,7 @@<br>
&gt; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; &lt;VIEW&gt; tableName =
qualifiedName(DB2Limit.DB2_MAX_IDENTIFIER_LENGTH128)<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ &lt;LEFT_PAREN&gt; resultColumns = viewColumnList()
&lt;RIGHT_PAREN&gt; ]<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;AS&gt; queryExpression = queryExpression(null,
Boolean.FALSE)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;AS&gt; queryExpression = queryExpression(null,
NO_SET_OP)<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; checkOptionType = ViewDescriptor.NO_CHECK_OPTION;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; endToken = getToken(0);<br>
&gt;@@ -9662,7 +9776,7 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; &lt;EXECUTE&gt; &lt;STATEMENT&gt; stmtName =
qualifiedName(DB2Limit.DB2_MAX_IDENTIFIER_LENGTH128)<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [ LOOKAHEAD( { getToken(1).kind == USING } )<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; usingToken = &lt;USING&gt; usingClause =<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; queryExpression(null,
Boolean.FALSE) ]<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; queryExpression(null,
NO_SET_OP) ]<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; endToken = getToken(0);<br>
&gt;<br>
&gt;Index:
java/engine/org/apache/derby/impl/sql/compile/IntersectOrExceptNode.java<br>
&gt;===================================================================<br>
&gt;---
java/engine/org/apache/derby/impl/sql/compile/IntersectOrExceptNode.java&nbsp;&nbsp;&nbsp;
(revision 0)<br>
&gt;+++
java/engine/org/apache/derby/impl/sql/compile/IntersectOrExceptNode.java&nbsp;&nbsp;&nbsp;
(revision 0)<br>
&gt;@@ -0,0 +1,397 @@<br>
&gt;+/*<br>
&gt;+<br>
&gt;+&nbsp;&nbsp; Derby - Class org.apache.derby.impl.sql.compile.IntersectNode<br>
&gt;+<br>
&gt;+&nbsp;&nbsp; Copyright 2004 The Apache Software Foundation or its licensors,
as applicable.<br>
&gt;+<br>
&gt;+&nbsp;&nbsp; Licensed under the Apache License, Version 2.0 (the "License");<br>
&gt;+&nbsp;&nbsp; you may not use this file except in compliance with the License.<br>
&gt;+&nbsp;&nbsp; You may obtain a copy of the License at<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a class="moz-txt-link-freetext" href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a><br>
&gt;+<br>
&gt;+&nbsp;&nbsp; Unless required by applicable law or agreed to in writing,
software<br>
&gt;+&nbsp;&nbsp; distributed under the License is distributed on an "AS IS"
BASIS,<br>
&gt;+&nbsp;&nbsp; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.<br>
&gt;+&nbsp;&nbsp; See the License for the specific language governing permissions
and<br>
&gt;+&nbsp;&nbsp; limitations under the License.<br>
&gt;+<br>
&gt;+ */<br>
&gt;+<br>
&gt;+package&nbsp;&nbsp;&nbsp; org.apache.derby.impl.sql.compile;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.reference.ClassName;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.services.sanity.SanityManager;<br>
&gt;+import org.apache.derby.iapi.services.classfile.VMOpcode;<br>
&gt;+import org.apache.derby.iapi.services.compiler.MethodBuilder;<br>
&gt;+import org.apache.derby.iapi.services.context.ContextManager;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.error.StandardException;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.sql.compile.NodeFactory;<br>
&gt;+import org.apache.derby.iapi.sql.compile.Optimizable;<br>
&gt;+import org.apache.derby.iapi.sql.compile.OptimizablePredicate;<br>
&gt;+import org.apache.derby.iapi.sql.compile.OptimizablePredicateList;<br>
&gt;+import org.apache.derby.iapi.sql.compile.Optimizer;<br>
&gt;+import org.apache.derby.iapi.sql.compile.CostEstimate;<br>
&gt;+import org.apache.derby.iapi.sql.compile.RowOrdering;<br>
&gt;+import org.apache.derby.iapi.sql.compile.C_NodeTypes;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.reference.SQLState;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.types.DataTypeDescriptor;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.util.JBitSet;<br>
&gt;+import org.apache.derby.iapi.util.ReuseFactory;<br>
&gt;+<br>
&gt;+import java.sql.Types;<br>
&gt;+<br>
&gt;+import java.util.BitSet;<br>
&gt;+<br>
&gt;+/**<br>
&gt;+ * A IntersectOrExceptNode represents an INTERSECT or EXCEPT DML
statement.<br>
&gt;+ *<br>
&gt;+ * @author Jack Klebanoff<br>
&gt;+ */<br>
&gt;+<br>
&gt;+public class IntersectOrExceptNode extends SetOperatorNode<br>
&gt;+{<br>
&gt;+&nbsp;&nbsp;&nbsp; /* Currently we implement INTERSECT and EXCEPT by rewriting<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; t1 (INTERSECT|EXCEPT) [ALL] t2<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * as (roughly)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp; setOpProjectRestrict( opType, all, (select * from t1
order by 1,2,...n), (select * from t2 ORDER BY 1,2,...,n))<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * where n is the number of columns in t1 (which must be the
same as the number of columns in t2),<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * and opType is INTERSECT, or EXCEPT.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * The setOpProjectRestrict result set simultaneously scans
through its two ordered inputs and<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * performs the intersect or except.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * There are other query plans that may be more efficient,
depending on the sizes. One plan is<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * to make a hash table from one of the input tables and then
look up each row of the other input<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * table in the hash table.&nbsp; However, we have not yet
implemented spilling to disk in the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * BackingStoreHashtable class: currently the whole hash table
is in RAM. If we were to use it<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * we would blow up on large input tables.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; private int opType;<br>
&gt;+&nbsp;&nbsp;&nbsp; public static final int INTERSECT_OP = 1;<br>
&gt;+&nbsp;&nbsp;&nbsp; public static final int EXCEPT_OP = 2;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /* Only optimize it once */<br>
&gt;+&nbsp;&nbsp;&nbsp; /* Only call addNewNodes() once */<br>
&gt;+&nbsp;&nbsp;&nbsp; private boolean addNewNodesCalled;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; private int[] intermediateOrderByColumns; // The input result
sets will be ordered on these columns. 0 indexed<br>
&gt;+&nbsp;&nbsp;&nbsp; private int[] intermediateOrderByDirection; // ascending = 1,
descending = -1<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Initializer for a SetOperatorNode.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param leftResult&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The ResultSetNode on the left side
of this union<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param rightResult&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The ResultSetNode on the right
side of this union<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param all&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Whether or not this is an ALL.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param tableConstructor&nbsp;&nbsp;&nbsp; Whether or not this is from a
table constructor.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param tableProperties&nbsp;&nbsp;&nbsp; Properties list associated with
the table<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; public void init( Object opType,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object leftResult,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object rightResult,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object all,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object tableConstructor,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object tableProperties)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.init( leftResult, rightResult, all,
tableConstructor, tableProperties);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.opType = ((Integer) opType).intValue();<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; private int getOpType()<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return opType;<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp; &nbsp;<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Push order by lists down to the children so that we can
implement the intersect/except<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * by scan of the two sorted inputs.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param numTables&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Number of tables in the DML
Statement<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param gbl&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The group by list, if any<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param fromList&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The from list, if any<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return The generated ProjectRestrictNode atop the original
FromTable.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; public ResultSetNode preprocess(int numTables,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GroupByList gbl,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FromList fromList)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // RESOLVE: We are in a quandary as to when and how we
should generate order by lists. SelectNode processing<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // requires order by lists at the start of preprocess.
That is why we are doing it here. However we can<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // pick any column ordering. Depending on the child
expressions the optimizer may be able to avoid a<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // sort if we pick the right column ordering. For instance
if one of the child expressions is<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // "select &lt;key columns&gt;, &lt;other expressions&gt;
from T" where there is a unique index on &lt;key columns&gt;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // then we can just generate an order by on the key
columns and the optimizer should use the unique index<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // to produce the sorted result set. However the
ResultSetNode class does not make it easy to<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // find the structure of the query expression. Furthermore
we most want to avoid a sort on the larger<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // input, but the size estimate is not available at
preprocess time.<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intermediateOrderByColumns = new int[
getResultColumns().size()];<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intermediateOrderByDirection = new int[
intermediateOrderByColumns.length];<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* If there is an order by on the result of the intersect
then use that because we know that doing so<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * will avoid a sort.&nbsp; If the output of the
intersect/except is small relative to its inputs then in some<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * cases it would be better to sort the inputs on a
different sequence of columns, but it is hard to analyze<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * the input query expressions to see if a sort can be
avoided.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( orderByList != null)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; BitSet colsOrdered = new BitSet(
intermediateOrderByColumns.length);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int orderByListSize = orderByList.size();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int intermediateOrderByIdx = 0;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for( int i = 0; i &lt; orderByListSize; i++)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( colsOrdered.get(i))<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OrderByColumn orderByColumn =
orderByList.getOrderByColumn(i);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
intermediateOrderByDirection[intermediateOrderByIdx] =
orderByColumn.isAscending() ? 1 : -1;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int columnIdx =
orderByColumn.getResultColumn().getColumnPosition() - 1;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intermediateOrderByColumns[intermediateOrderByIdx]
= columnIdx;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; colsOrdered.set( columnIdx);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intermediateOrderByIdx++;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for( int i = 0; i &lt;
intermediateOrderByColumns.length; i++)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( ! colsOrdered.get(i))<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
intermediateOrderByDirection[intermediateOrderByIdx] = 1;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
intermediateOrderByColumns[intermediateOrderByIdx] = i;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intermediateOrderByIdx++;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; orderByList = null; // It will be pushed down.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else // The output of the intersect/except does not have
to be ordered<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Pick an intermediate ordering that minimizes the
cost.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // RESOLVE: how do you do that?<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for( int i = 0; i &lt;
intermediateOrderByColumns.length; i++)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intermediateOrderByDirection[i] = 1;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intermediateOrderByColumns[i] = i;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pushOrderingDown( leftResultSet);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pushOrderingDown( rightResultSet);<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return super.preprocess( numTables, gbl, fromList);<br>
&gt;+&nbsp;&nbsp;&nbsp; } // end of preprocess<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; private void pushOrderingDown( ResultSetNode rsn)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ContextManager cm = getContextManager();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NodeFactory nf = getNodeFactory();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OrderByList orderByList = (OrderByList) nf.getNode(
C_NodeTypes.ORDER_BY_LIST, cm);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for( int i = 0; i &lt; intermediateOrderByColumns.length;
i++)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OrderByColumn orderByColumn = (OrderByColumn)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nf.getNode( C_NodeTypes.ORDER_BY_COLUMN,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ReuseFactory.getInteger(
intermediateOrderByColumns[i] + 1),<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cm);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( intermediateOrderByDirection[i] &lt; 0)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; orderByColumn.setDescending();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; orderByList.addOrderByColumn( orderByColumn);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; orderByList.bindOrderByColumns( rsn);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rsn.pushOrderByList( orderByList);<br>
&gt;+&nbsp;&nbsp;&nbsp; } // end of pushOrderingDown<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @see
org.apache.derby.iapi.sql.compile.Optimizable#estimateCost<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public CostEstimate estimateCost( OptimizablePredicateList
predList,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ConglomerateDescriptor cd,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CostEstimate outerCost,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Optimizer optimizer,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RowOrdering rowOrdering)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CostEstimate costEstimate = getCostEstimate(optimizer);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CostEstimate leftCostEstimate =
leftResultSet.getCostEstimate();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CostEstimate rightCostEstimate =
rightResultSet.getCostEstimate();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // The cost is the sum of the two child costs plus the
cost of sorting the union.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; costEstimate.setCost( leftCostEstimate.getEstimatedCost()
+ rightCostEstimate.getEstimatedCost(),<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getRowCountEstimate(
leftCostEstimate.rowCount(),<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
rightCostEstimate.rowCount()),<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getSingleScanRowCountEstimate(
leftCostEstimate.singleScanRowCount(),<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
rightCostEstimate.singleScanRowCount()));<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // RESOLVE: We should add in the cost of the generated
project/restrict, but this is not high.<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return costEstimate;<br>
&gt;+&nbsp;&nbsp;&nbsp; } // End of estimateCost<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @see Optimizable#modifyAccessPath<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public Optimizable modifyAccessPath(JBitSet outerTables)
throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Optimizable retOptimizable;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retOptimizable = super.modifyAccessPath(outerTables);<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* We only want call addNewNodes() once */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (addNewNodesCalled)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retOptimizable;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (Optimizable) addNewNodes();<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @see ResultSetNode#modifyAccessPaths<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public ResultSetNode modifyAccessPaths() throws
StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultSetNode retRSN;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; retRSN = super.modifyAccessPaths();<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* We only want call addNewNodes() once */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (addNewNodesCalled)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return retRSN;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return addNewNodes();<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Add any new ResultSetNodes that are necessary to the tree.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * We wait until after optimization to do this in order to<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * make it easier on the optimizer.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return (Potentially new) head of the ResultSetNode tree.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; private ResultSetNode addNewNodes()<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Only call addNewNodes() once */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (addNewNodesCalled)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; addNewNodesCalled = true;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( orderByList == null)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Generate an order by node on top of the intersect/except<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (ResultSetNode) getNodeFactory().getNode(
C_NodeTypes.ORDER_BY_NODE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
orderByList,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
tableProperties,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
getContextManager());<br>
&gt;+&nbsp;&nbsp;&nbsp; } // end of addNewNodes<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Generate the code.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public void generate( ActivationClassBuilder acb,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; MethodBuilder mb)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Get the next ResultSet #, so that we can number this
ResultSetNode, its<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * ResultColumnList and ResultSet.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; assignResultSetNumber();<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // build up the tree.<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Generate the SetOpResultSet. Arguments:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; 1) expression for left child ResultSet<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; 2) expression for right child ResultSet<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; 3) activation<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; 4) resultSetNumber<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; 5) estimated row count<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; 6) estimated cost<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; 7) opType<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; 8) all<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; 9) close method<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; 10) intermediateOrderByColumns saved object index<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; 11) intermediateOrderByDirection saved object index<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; acb.pushGetResultSetFactoryExpression(mb); // instance for
getUnionResultSet<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getLeftResultSet().generate( acb, mb);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getRightResultSet().generate( acb, mb);<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; acb.pushThisAsActivation(mb);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mb.push(resultSetNumber);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mb.push( costEstimate.getEstimatedRowCount());<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mb.push( costEstimate.getEstimatedCost());<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mb.push( getOpType());<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mb.push( all);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; closeMethodArgument(acb, mb);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mb.push( getCompilerContext().addSavedObject(
intermediateOrderByColumns));<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mb.push( getCompilerContext().addSavedObject(
intermediateOrderByDirection));<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mb.callMethod(VMOpcode.INVOKEINTERFACE,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (String) null,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "getSetOpResultSet",<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ClassName.NoPutResultSet, 11);<br>
&gt;+&nbsp;&nbsp;&nbsp; } // end of generate<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; String getOperatorName()<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch( opType)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case INTERSECT_OP:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "INTERSECT";<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case EXCEPT_OP:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "EXCEPT";<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( SanityManager.DEBUG)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SanityManager.THROWASSERT( "Invalid intersectOrExcept
opType: " + opType);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "?";<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp; &nbsp;<br>
&gt;+&nbsp;&nbsp;&nbsp; double getRowCountEstimate( double leftRowCount, double
rightRowCount)<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch( opType)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case INTERSECT_OP:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // The result has at most min( leftRowCount,
rightRowCount). Estimate the actual row count at<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // half that.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Math.min( leftRowCount, rightRowCount)/2;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case EXCEPT_OP:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // The result has at most leftRowCount rows and at
least min( 0, leftRowCount - rightRowCount) rows.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Use the mean of those two as the estimate.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (leftRowCount + Math.min( 0, leftRowCount -
rightRowCount))/2;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( SanityManager.DEBUG)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SanityManager.THROWASSERT( "Invalid intersectOrExcept
opType: " + opType);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 1.0;<br>
&gt;+&nbsp;&nbsp;&nbsp; } // end of getRowCountEstimate<br>
&gt;+&nbsp;&nbsp; &nbsp;<br>
&gt;+&nbsp;&nbsp;&nbsp; double getSingleScanRowCountEstimate( double
leftSingleScanRowCount, double rightSingleScanRowCount)<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return getRowCountEstimate( leftSingleScanRowCount,
rightSingleScanRowCount);<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+}<br>
&gt;Index:
java/engine/org/apache/derby/impl/sql/compile/TableOperatorNode.java<br>
&gt;===================================================================<br>
&gt;---
java/engine/org/apache/derby/impl/sql/compile/TableOperatorNode.java&nbsp;&nbsp;&nbsp;
(revision 111907)<br>
&gt;+++
java/engine/org/apache/derby/impl/sql/compile/TableOperatorNode.java&nbsp;&nbsp;&nbsp;
(working copy)<br>
&gt;@@ -376,8 +376,8 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** Parameters not allowed in select list of either side of
union,<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** except when the union is for a table constructor.<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( ! (this instanceof UnionNode) ||<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! ((UnionNode) this).tableConstructor())<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( ! (this instanceof SetOperatorNode) ||<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! ((SetOperatorNode) this).tableConstructor())<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftResultSet.rejectParameters();<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightResultSet.rejectParameters();<br>
&gt;@@ -419,11 +419,11 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** Parameters not allowed in select list of either side of
union,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** except when the union is for a table constructor.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** Parameters not allowed in select list of either side of
a set operator,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ** except when the set operator is for a table constructor.<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( ! (this instanceof UnionNode) ||<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! ((UnionNode) this).tableConstructor())<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( ! (this instanceof SetOperatorNode) ||<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ! ((SetOperatorNode) this).tableConstructor())<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftResultSet.rejectParameters();<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightResultSet.rejectParameters();<br>
&gt;Index:
java/engine/org/apache/derby/impl/sql/compile/OrderByColumn.java<br>
&gt;===================================================================<br>
&gt;---
java/engine/org/apache/derby/impl/sql/compile/OrderByColumn.java&nbsp;&nbsp;&nbsp;
(revision 111907)<br>
&gt;+++
java/engine/org/apache/derby/impl/sql/compile/OrderByColumn.java&nbsp;&nbsp;&nbsp;
(working copy)<br>
&gt;@@ -172,7 +172,7 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ResultColumnList&nbsp;&nbsp;&nbsp; targetCols = target.getResultColumns();<br>
&gt;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //bug 5716 - for db2 compatibility - no qualified names
allowed in order by clause when union/union all operator is used<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (target instanceof UnionNode &amp;&amp; correlationName
!= null)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (target instanceof SetOperatorNode &amp;&amp;
correlationName != null)<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String fullName = (schemaName != null) ?<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (schemaName + "." + correlationName + "." +
columnName) :<br>
&gt;@@ -207,7 +207,7 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * because of the gyrations we go to with building the
RCLs<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * for a UnionNode.<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (target instanceof UnionNode)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (target instanceof SetOperatorNode)<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sourceTableNumber = ((FromTable)
target).getTableNumber();<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;Index:
java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java<br>
&gt;===================================================================<br>
&gt;---
java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java&nbsp;&nbsp;&nbsp;
(revision 111907)<br>
&gt;+++
java/engine/org/apache/derby/impl/sql/compile/ResultColumnList.java&nbsp;&nbsp;&nbsp;
(working copy)<br>
&gt;@@ -2025,7 +2025,7 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; /**<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp; * Set up the result expressions for a UNION:<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Set up the result expressions for a UNION, INTERSECT, or
EXCEPT:<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp; o Verify union type compatiblity<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp; o Get dominant type for result (type + max length +
nullability)<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp; o Create a new ColumnReference with dominant type and name
of from this<br>
&gt;@@ -2038,14 +2038,16 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param otherRCL&nbsp;&nbsp;&nbsp; RCL from other side of the UNION.<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param tableNumber&nbsp;&nbsp;&nbsp; The tableNumber for the UNION.<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @param level&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The nesting level for the UNION.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param operatorName "UNION", "INTERSECT", or "EXCEPT"<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @return Nothing.<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on error<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; public void&nbsp;&nbsp;&nbsp; setUnionResultExpression(ResultColumnList
otherRCL,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int tableNumber,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int level)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int tableNumber,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int level,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String operatorName)<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; TableName&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dummyTN;<br>
&gt;@@ -2116,8 +2118,9 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; !otherExpr.getTypeCompiler().storable(thisTypeId,
cf))<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw
StandardException.newException(SQLState.LANG_NOT_UNION_COMPATIBLE,<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; thisTypeId.getSQLTypeName(),<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; otherTypeId.getSQLTypeName() );<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
thisTypeId.getSQLTypeName(),<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
otherTypeId.getSQLTypeName(),<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; operatorName);<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataTypeDescriptor resultType =
thisExpr.getTypeServices().getDominantType(<br>
&gt;Index: java/engine/org/apache/derby/impl/sql/build.xml<br>
&gt;===================================================================<br>
&gt;--- java/engine/org/apache/derby/impl/sql/build.xml&nbsp;&nbsp;&nbsp; (revision
111907)<br>
&gt;+++ java/engine/org/apache/derby/impl/sql/build.xml&nbsp;&nbsp;&nbsp; (working
copy)<br>
&gt;@@ -16,6 +16,8 @@<br>
&gt;&nbsp;&nbsp; &lt;property file="${properties.dir}/extrapath.properties"/&gt;<br>
&gt;&nbsp;&nbsp; &lt;property file="${properties.dir}/compilepath.properties"/&gt;<br>
&gt;<br>
&gt;+&nbsp; &lt;property name="cur.dir" value="impl/sql"/&gt;<br>
&gt;+<br>
&gt; &lt;!-- Targets --&gt;<br>
&gt;&nbsp;&nbsp; &lt;target name="parser"&gt;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; &lt;ant antfile="${src.dir}/build.xml" target="genParser"&gt;<br>
&gt;@@ -42,9 +44,9 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;classpath&gt;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;pathelement path="${compile.classpath}"/&gt;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/classpath&gt;<br>
&gt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;include name="${derby.dir}/impl/sql/**"/&gt;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;include name="${derby.dir}/${cur.dir}/**"/&gt;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/javac&gt;<br>
&gt;-&nbsp;&nbsp;&nbsp; &lt;copy file="catalog/metadata_net.properties"
tofile="${out.dir}/org/apache/derby/impl/sql/catalog/metadata_net.properties"/&gt;<br>
&gt;+&nbsp;&nbsp;&nbsp; &lt;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"/&gt;<br>
&gt;&nbsp;&nbsp; &lt;/target&gt;<br>
&gt;<br>
&gt; &lt;/project&gt;<br>
&gt;Index:
java/engine/org/apache/derby/impl/sql/execute/GenericResultSetFactory.java<br>
&gt;===================================================================<br>
&gt;---
java/engine/org/apache/derby/impl/sql/execute/GenericResultSetFactory.java&nbsp;&nbsp;&nbsp;
(revision 111907)<br>
&gt;+++
java/engine/org/apache/derby/impl/sql/execute/GenericResultSetFactory.java&nbsp;&nbsp;&nbsp;
(working copy)<br>
&gt;@@ -1053,6 +1053,32 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; closeCleanup);<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;<br>
&gt;+&nbsp;&nbsp;&nbsp; public NoPutResultSet getSetOpResultSet( NoPutResultSet
leftSource,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NoPutResultSet
rightSource,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Activation activation,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int resultSetNumber,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long
optimizerEstimatedRowCount,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double
optimizerEstimatedCost,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int opType,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean all,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GeneratedMethod
closeCleanup,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int
intermediateOrderByColumnsSavedObject,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int
intermediateOrderByDirectionSavedObject)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new SetOpResultSet( leftSource,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightSource,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; activation,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; resultSetNumber,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; optimizerEstimatedRowCount,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; optimizerEstimatedCost,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; opType,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; all,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; closeCleanup,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
intermediateOrderByColumnsSavedObject,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
intermediateOrderByDirectionSavedObject);<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; /**<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * A last index key sresult set returns the last row from<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * the index in question.&nbsp; It is used as an ajunct to max().<br>
&gt;Index:
java/engine/org/apache/derby/impl/sql/execute/SetOpResultSet.java<br>
&gt;===================================================================<br>
&gt;---
java/engine/org/apache/derby/impl/sql/execute/SetOpResultSet.java&nbsp;&nbsp;&nbsp;
(revision 0)<br>
&gt;+++
java/engine/org/apache/derby/impl/sql/execute/SetOpResultSet.java&nbsp;&nbsp;&nbsp;
(revision 0)<br>
&gt;@@ -0,0 +1,288 @@<br>
&gt;+/*<br>
&gt;+<br>
&gt;+&nbsp;&nbsp; Derby - Class org.apache.derby.impl.sql.execute.SetOpResultSet<br>
&gt;+<br>
&gt;+&nbsp;&nbsp; Copyright 2004 The Apache Software Foundation or its licensors,
as applicable.<br>
&gt;+<br>
&gt;+&nbsp;&nbsp; Licensed under the Apache License, Version 2.0 (the "License");<br>
&gt;+&nbsp;&nbsp; you may not use this file except in compliance with the License.<br>
&gt;+&nbsp;&nbsp; You may obtain a copy of the License at<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <a class="moz-txt-link-freetext" href="http://www.apache.org/licenses/LICENSE-2.0">http://www.apache.org/licenses/LICENSE-2.0</a><br>
&gt;+<br>
&gt;+&nbsp;&nbsp; Unless required by applicable law or agreed to in writing,
software<br>
&gt;+&nbsp;&nbsp; distributed under the License is distributed on an "AS IS"
BASIS,<br>
&gt;+&nbsp;&nbsp; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.<br>
&gt;+&nbsp;&nbsp; See the License for the specific language governing permissions
and<br>
&gt;+&nbsp;&nbsp; limitations under the License.<br>
&gt;+<br>
&gt;+ */<br>
&gt;+<br>
&gt;+package org.apache.derby.impl.sql.execute;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.error.StandardException;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.services.loader.GeneratedMethod;<br>
&gt;+import org.apache.derby.iapi.services.sanity.SanityManager;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.sql.Activation;<br>
&gt;+import org.apache.derby.iapi.sql.ResultDescription;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.sql.execute.CursorResultSet;<br>
&gt;+import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;<br>
&gt;+import org.apache.derby.iapi.sql.execute.ExecRow;<br>
&gt;+import org.apache.derby.iapi.sql.execute.NoPutResultSet;<br>
&gt;+<br>
&gt;+import org.apache.derby.iapi.types.DataValueDescriptor;<br>
&gt;+import org.apache.derby.iapi.types.Orderable;<br>
&gt;+import org.apache.derby.iapi.types.RowLocation;<br>
&gt;+<br>
&gt;+import org.apache.derby.impl.sql.compile.IntersectOrExceptNode;<br>
&gt;+<br>
&gt;+/**<br>
&gt;+ * Takes the result set produced by an ordered UNION ALL of two
tagged result sets and produces<br>
&gt;+ * the INTERSECT or EXCEPT of the two input result sets. This also
projects out the tag, the last column<br>
&gt;+ * of the input rows.<br>
&gt;+ */<br>
&gt;+public class SetOpResultSet extends NoPutResultSetImpl<br>
&gt;+&nbsp;&nbsp;&nbsp; implements CursorResultSet<br>
&gt;+{<br>
&gt;+&nbsp;&nbsp;&nbsp; private final NoPutResultSet leftSource;<br>
&gt;+&nbsp;&nbsp;&nbsp; private final NoPutResultSet rightSource;<br>
&gt;+&nbsp;&nbsp;&nbsp; private final GeneratedMethod closeCleanup;<br>
&gt;+&nbsp;&nbsp;&nbsp; private final Activation activation;<br>
&gt;+&nbsp;&nbsp;&nbsp; private final int opType;<br>
&gt;+&nbsp;&nbsp;&nbsp; private final boolean all;<br>
&gt;+&nbsp;&nbsp;&nbsp; private final int resultSetNumber;<br>
&gt;+&nbsp;&nbsp;&nbsp; private DataValueDescriptor[] prevCols; /* Used to remove
duplicates in the EXCEPT DISTINCT case.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * It is equal to the
previously output columns.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; private int rightDuplicateCount; // Number of duplicates of
the current row from the right input<br>
&gt;+&nbsp;&nbsp;&nbsp; private ExecRow leftInputRow;<br>
&gt;+&nbsp;&nbsp;&nbsp; private ExecRow rightInputRow;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; private final int[] intermediateOrderByColumns;<br>
&gt;+&nbsp;&nbsp;&nbsp; private final int[] intermediateOrderByDirection;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; SetOpResultSet( NoPutResultSet leftSource,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NoPutResultSet rightSource,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Activation activation,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int resultSetNumber,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long optimizerEstimatedRowCount,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double optimizerEstimatedCost,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int opType,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean all,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GeneratedMethod closeCleanup,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int intermediateOrderByColumnsSavedObject,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int intermediateOrderByDirectionSavedObject)<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(activation, resultSetNumber,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; optimizerEstimatedRowCount, optimizerEstimatedCost);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.leftSource = leftSource;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.rightSource = rightSource;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.activation = activation;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.resultSetNumber = resultSetNumber;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.opType = opType;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.all = all;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.closeCleanup = closeCleanup;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ExecPreparedStatement eps =
activation.getPreparedStatement();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intermediateOrderByColumns = (int[])
eps.getSavedObject(intermediateOrderByColumnsSavedObject);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; intermediateOrderByDirection = (int[])
eps.getSavedObject(intermediateOrderByDirectionSavedObject);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; constructorTime += getElapsedMillis(beginTime);<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * open the first source.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp; @exception StandardException thrown on failure<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public void&nbsp;&nbsp;&nbsp; openCore() throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; beginTime = getCurrentTimeMillis();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (SanityManager.DEBUG)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SanityManager.ASSERT( ! isOpen,
"SetOpProjectRestrictResultSet already open");<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isOpen = true;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftSource.openCore();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightSource.openCore();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightInputRow = rightSource.getNextRowCore();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; numOpens++;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; openTime += getElapsedMillis(beginTime);<br>
&gt;+&nbsp;&nbsp;&nbsp; } // end of openCore<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return the next row of the intersect or except, null if
there is none<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp; @exception StandardException thrown on failure<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public ExecRow&nbsp;&nbsp;&nbsp; getNextRowCore() throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; beginTime = getCurrentTimeMillis();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( isOpen )<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while( (leftInputRow = leftSource.getNextRowCore()) !=
null)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DataValueDescriptor[] leftColumns =
leftInputRow.getRowArray();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( !all)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( isDuplicate( leftColumns))<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue; // Get the next left row<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; prevCols = leftInputRow.getRowArrayClone();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int compare = 0;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Advance the right until there are no more right
rows or leftRow &lt;= rightRow<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while( rightInputRow != null &amp;&amp; (compare =
compare( leftColumns, rightInputRow.getRowArray())) &gt; 0)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightInputRow = rightSource.getNextRowCore();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( rightInputRow == null || compare &lt; 0)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // The left row is not in the right source.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( opType == IntersectOrExceptNode.EXCEPT_OP)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Output this row<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // The left and right rows are the same<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( SanityManager.DEBUG)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SanityManager.ASSERT( rightInputRow !=
null &amp;&amp; compare == 0,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Insert/Except
execution has gotten confused.");<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( all)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Just advance the right input by one row.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightInputRow =
rightSource.getNextRowCore();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // If !all then we will skip past duplicates
on the left at the top of this loop,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // which will then force us to skip past any
right duplicates.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( opType ==
IntersectOrExceptNode.INTERSECT_OP)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break; // output this row<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // opType == IntersectOrExceptNode.EXCEPT_OP<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // This row should not be ouput<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; currentRow = leftInputRow;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setCurrentRow( currentRow);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; nextTime += getElapsedMillis(beginTime);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return currentRow;<br>
&gt;+&nbsp;&nbsp;&nbsp; } // end of getNextRowCore<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; private void advanceRightPastDuplicates( DataValueDescriptor[]
leftColumns)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while((rightInputRow = rightSource.getNextRowCore()) !=
null<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &amp;&amp; compare( leftColumns,
rightInputRow.getRowArray()) == 0)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;<br>
&gt;+&nbsp;&nbsp;&nbsp; } // end of advanceRightPastDuplicates<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+&nbsp;&nbsp;&nbsp; private int compare( DataValueDescriptor[] leftCols,
DataValueDescriptor[] rightCols)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for( int i = 0; ; i++)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( i &gt;= intermediateOrderByColumns.length)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int colIdx = intermediateOrderByColumns[i];<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( leftCols[colIdx].compare(
Orderable.ORDER_OP_LESSTHAN,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightCols[colIdx],<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; true, // nulls sort high<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; false))<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -1 * intermediateOrderByDirection[i];<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( ! leftCols[colIdx].compare(
Orderable.ORDER_OP_EQUALS,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightCols[colIdx],<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; true, // nulls sort
high<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; false))<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return intermediateOrderByDirection[i];<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp; } // end of compare<br>
&gt;+&nbsp;&nbsp; &nbsp;<br>
&gt;+&nbsp;&nbsp;&nbsp; private boolean isDuplicate( DataValueDescriptor[] curColumns)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( prevCols == null)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Note that intermediateOrderByColumns.length can be less
than prevCols.length if we know that a<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * subset of the columns is a unique key. In that case we
only need to look at the unique key.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for( int i = 0; i &lt; intermediateOrderByColumns.length;
i++)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int colIdx = intermediateOrderByColumns[i];<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if( ! curColumns[colIdx].compare(
Orderable.ORDER_OP_EQUALS, prevCols[colIdx], true, false))<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return false;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return true;<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; public ExecRow getCurrentRow()<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return currentRow;<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp; &nbsp;<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * If the result set has been opened,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * close the currently open source.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException thrown on error<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public void&nbsp;&nbsp;&nbsp; close() throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; beginTime = getCurrentTimeMillis();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( isOpen )<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (closeCleanup != null)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; closeCleanup.invoke(activation); // let activation
tidy up<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clearCurrentRow();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; currentRow = null;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; prevCols = null;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftSource.close();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightSource.close();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super.close();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (SanityManager.DEBUG)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SanityManager.DEBUG("CloseRepeatInfo","Close of
UnionResultSet repeated");<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; closeTime += getElapsedMillis(beginTime);<br>
&gt;+&nbsp;&nbsp;&nbsp; } // end of close<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; public void&nbsp;&nbsp;&nbsp; finish() throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; leftSource.finish();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rightSource.finish();<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; finishAndRTS();<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * Return the total amount of time spent in this ResultSet<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param type&nbsp;&nbsp;&nbsp; CURRENT_RESULTSET_ONLY - time spent only in
this ResultSet<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENTIRE_RESULTSET_TREE&nbsp; - time spent in this
ResultSet and below.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return long&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The total amount of time spent (in
milliseconds).<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public long getTimeSpent(int type)<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long totTime = constructorTime + openTime + nextTime +
closeTime;<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (type == NoPutResultSet.CURRENT_RESULTSET_ONLY)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp;&nbsp;&nbsp; totTime -
leftSource.getTimeSpent(ENTIRE_RESULTSET_TREE)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - rightSource.getTimeSpent(ENTIRE_RESULTSET_TREE);<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return totTime;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
&gt;+&nbsp;&nbsp;&nbsp; } // end of getTimeSpent<br>
&gt;+<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @see CursorResultSet<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return the row location of the current cursor row.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException thrown on failure<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; public RowLocation getRowLocation() throws StandardException<br>
&gt;+&nbsp;&nbsp;&nbsp; {<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // RESOLVE: What is the row location of an INTERSECT
supposed to be: the location from the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // left side, the right side, or null?<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ((CursorResultSet)leftSource).getRowLocation();<br>
&gt;+&nbsp;&nbsp;&nbsp; }<br>
&gt;+}<br>
&gt;Index:
java/engine/org/apache/derby/iapi/sql/compile/C_NodeTypes.java<br>
&gt;===================================================================<br>
&gt;---
java/engine/org/apache/derby/iapi/sql/compile/C_NodeTypes.java&nbsp;&nbsp;&nbsp;
(revision 111907)<br>
&gt;+++
java/engine/org/apache/derby/iapi/sql/compile/C_NodeTypes.java&nbsp;&nbsp;&nbsp;
(working copy)<br>
&gt;@@ -185,7 +185,8 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; static final int SUBSTRING_OPERATOR_NODE = 154;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; // UNUSED static final int BOOLEAN_NODE = 155;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; static final int DROP_ALIAS_NODE = 156;<br>
&gt;-&nbsp;&nbsp;&nbsp; // 157 - 185 available<br>
&gt;+&nbsp;&nbsp;&nbsp; static final int INTERSECT_OR_EXCEPT_NODE = 157;<br>
&gt;+&nbsp;&nbsp;&nbsp; // 158 - 185 available<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; static final int MODIFY_COLUMN_TYPE_NODE = 186;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; static final int MODIFY_COLUMN_CONSTRAINT_NODE = 187;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; static final int ABSOLUTE_OPERATOR_NODE = 188;<br>
&gt;Index:
java/engine/org/apache/derby/iapi/sql/execute/ResultSetFactory.java<br>
&gt;===================================================================<br>
&gt;---
java/engine/org/apache/derby/iapi/sql/execute/ResultSetFactory.java&nbsp;&nbsp;&nbsp;
(revision 111907)<br>
&gt;+++
java/engine/org/apache/derby/iapi/sql/execute/ResultSetFactory.java&nbsp;&nbsp;&nbsp;
(working copy)<br>
&gt;@@ -1428,6 +1428,45 @@<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException;<br>
&gt;<br>
&gt;<br>
&gt;+&nbsp;&nbsp;&nbsp; /**<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * The SetOpResultSet is used to implement an INTERSECT or
EXCEPT operation.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * It selects rows from two ordered input result sets.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param leftSource The result set that implements the left
input<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param rightSource The result set that implements the right
input<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param activation the activation for this result set<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param resultSetNumber<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param optimizerEstimatedRowCount<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param optimizerEstimatedCost<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param opType IntersectOrExceptNode.INTERSECT_OP or
EXCEPT_OP<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param all true if the operation is an INTERSECT ALL or an
EXCEPT ALL,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; false if the operation is an INTERSECT DISCTINCT
or an EXCEPT DISCTINCT<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param closeCleanup a method to be called by close<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param intermediateOrderByColumnsSavedObject The saved
object index for the array of order by columns for the<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ordering of the left and right sources. That is,
both the left and right sources have an order by<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clause of the form ORDER BY
intermediateOrderByColumns[0],intermediateOrderByColumns[1],...<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @param intermediateOrderByDirectionSavedObject The saved
object index for the array of source<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; order by directions. That is, the ordering of the
i'th order by column in the input is ascending<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if intermediateOrderByDirection[i] is 1, descending
if intermediateOrderByDirection[i] is -1.<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @return&nbsp;&nbsp;&nbsp; A ResultSet from which the caller can get the
INTERSECT or EXCEPT<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; *<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; * @exception StandardException&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thrown on failure<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp; */<br>
&gt;+&nbsp;&nbsp;&nbsp; NoPutResultSet getSetOpResultSet( NoPutResultSet leftSource,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; NoPutResultSet rightSource,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Activation activation,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int resultSetNumber,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long
optimizerEstimatedRowCount,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double
optimizerEstimatedCost,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int opType,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; boolean all,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GeneratedMethod closeCleanup,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int
intermediateOrderByColumnsSavedObject,<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int
intermediateOrderByDirectionSavedObject)<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws StandardException;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; //<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; // Misc operations<br>
&gt;&nbsp;&nbsp;&nbsp;&nbsp; //<br>
&gt;Index: java/engine/org/apache/derby/loc/messages_en.properties<br>
&gt;===================================================================<br>
&gt;--- java/engine/org/apache/derby/loc/messages_en.properties&nbsp;&nbsp;&nbsp;
(revision 111907)<br>
&gt;+++ java/engine/org/apache/derby/loc/messages_en.properties&nbsp;&nbsp;&nbsp;
(working copy)<br>
&gt;@@ -469,10 +469,10 @@<br>
&gt; 42X55=Table name ''{1}'' should be the same as ''{0}''.<br>
&gt; 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}''.<br>
&gt; 42X57=The getColumnCount() for external virtual table ''{0}''
returned an invalid value ''{1}''.&nbsp; Valid values are &gt;= 1.<br>
&gt;-42X58=The number of columns on the left and right sides of the
UNION must be the same.<br>
&gt;+42X58=The number of columns on the left and right sides of the {0}
must be the same.<br>
&gt; 42X59=The number of columns in each VALUES constructor must be the
same.<br>
&gt; 42X60=Invalid value ''{0}'' for insertMode property specified for
table ''{1}''.<br>
&gt;-42X61=Types ''{0}'' and ''{1}'' are not UNION compatible.<br>
&gt;+42X61=Types ''{0}'' and ''{1}'' are not {2} compatible.<br>
&gt; 42X62=''{0}'' is not allowed in the ''{1}'' schema.<br>
&gt; 42X63=The USING clause did not return any results, no parameters
can be set.<br>
&gt; 42X64=Invalid value ''{0}'' specified for useStatistics property
in the Properties list. TRUE or FALSE are the only valid values.<br>
&gt;@@ -919,7 +919,7 @@<br>
&gt; X0X61.S=The values for column ''{4}'' in index ''{0}'' and table
''{1}.{2}'' do not match for row location {3}.&nbsp; The value in the index
is ''{5}'', while the value in the base table is ''{6}''.&nbsp; The full
index key, including the row location, is ''{7}''.&nbsp; The suggested
corrective action is to recreate the index.<br>
&gt; X0X62.S=Inconsistency found between table ''{0}'' and index
''{1}''.&nbsp; Error when trying to retrieve row location ''{2}'' from the
table.&nbsp; The full index key, including the row location, is ''{3}''. The
suggested corrective action is to recreate the index.<br>
&gt; X0X63.S=Got IOException ''{0}''.<br>
&gt;-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.<br>
&gt;+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.<br>
&gt; X0X81.S={0} ''{1}'' does not exist.<br>
&gt; X0X85.S=Index ''{0}'' was not created because ''{1}'' is not a
valid index type.<br>
&gt; X0X86.S=0 is an invalid parameter value for ResultSet.absolute(int
row).<br>
&gt;Index:
java/testing/org/apache/derbyTesting/functionTests/tests/lang/intersect.sql<br>
&gt;===================================================================<br>
&gt;---
java/testing/org/apache/derbyTesting/functionTests/tests/lang/intersect.sql&nbsp;&nbsp;&nbsp;
(revision 0)<br>
&gt;+++
java/testing/org/apache/derbyTesting/functionTests/tests/lang/intersect.sql&nbsp;&nbsp;&nbsp;
(revision 0)<br>
&gt;@@ -0,0 +1,141 @@<br>
&gt;+create table t1( id integer not null primary key, i1 integer, i2
integer, c10 char(10), c30 char(30), tm time);<br>
&gt;+create table t2( id integer not null primary key, i1 integer, i2
integer, vc20 varchar(20), d double, dt date);<br>
&gt;+insert into t1(id,i1,i2,c10,c30) values<br>
&gt;+&nbsp; (1,1,1,'a','123456789012345678901234567890'),<br>
&gt;+&nbsp; (2,1,2,'a','bb'),<br>
&gt;+&nbsp; (3,1,3,'b','bb'),<br>
&gt;+&nbsp; (4,1,3,'zz','5'),<br>
&gt;+&nbsp; (5,null,null,null,'1.0'),<br>
&gt;+&nbsp; (6,null,null,null,'a');<br>
&gt;+insert into t2(id,i1,i2,vc20,d) values<br>
&gt;+&nbsp; (1,1,1,'a',1.0),<br>
&gt;+&nbsp; (2,1,2,'a',1.1),<br>
&gt;+&nbsp; (5,null,null,'12345678901234567890',3),<br>
&gt;+&nbsp; (100,1,3,'zz',3),<br>
&gt;+&nbsp; (101,1,2,'bb',null),<br>
&gt;+&nbsp; (102,5,5,'',null),<br>
&gt;+&nbsp; (103,1,3,' a',null),<br>
&gt;+&nbsp; (104,1,3,'null',7.4);<br>
&gt;+<br>
&gt;+-- no duplicates<br>
&gt;+select id,i1,i2 from t1 intersect select id,i1,i2 from t2 order by
id DESC,i1,i2;<br>
&gt;+select id,i1,i2 from t1 intersect all select id,i1,i2 from t2
order by 1,2,3;<br>
&gt;+<br>
&gt;+-- Only specify order by on some columns<br>
&gt;+select id,i1,i2 from t1 intersect select id,i1,i2 from t2 order by
i2, id DESC;<br>
&gt;+select id,i1,i2 from t1 intersect all select id,i1,i2 from t2
order by 3 DESC, 1;<br>
&gt;+<br>
&gt;+-- duplicates<br>
&gt;+select i1,i2 from t1 intersect select i1,i2 from t2 order by 1,2;<br>
&gt;+select i1,i2 from t1 intersect all select i1,i2 from t2 order by
1,2;<br>
&gt;+<br>
&gt;+-- right side is empty<br>
&gt;+select i1,i2 from t1 intersect select i1,i2 from t2 where id = -1;<br>
&gt;+select i1,i2 from t1 intersect all select i1,i2 from t2 where id =
-1;<br>
&gt;+<br>
&gt;+-- left side is empty<br>
&gt;+select i1,i2 from t1 where id = -1 intersect all select i1,i2 from
t2;<br>
&gt;+<br>
&gt;+-- check precedence<br>
&gt;+select i1,i2 from t1 intersect all select i1,i2 from t2 intersect
values(5,5),(1,3) order by 1,2;<br>
&gt;+(select i1,i2 from t1 intersect all select i1,i2 from t2)
intersect values(5,5),(1,3) order by 1,2;<br>
&gt;+<br>
&gt;+values(-1,-1,-1) union select id,i1,i2 from t1 intersect select
id,i1,i2 from t2 order by 1,2,3;<br>
&gt;+select id,i1,i2 from t1 intersect select id,i1,i2 from t2 union
values(-1,-1,-1) order by 1,2,3;<br>
&gt;+<br>
&gt;+-- check conversions<br>
&gt;+select c10 from t1 intersect select vc20 from t2 order by 1;<br>
&gt;+select c30 from t1 intersect select vc20 from t2;<br>
&gt;+select c30 from t1 intersect all select vc20 from t2;<br>
&gt;+<br>
&gt;+-- check insert intersect into table and intersect without order by<br>
&gt;+create table r( i1 integer, i2 integer);<br>
&gt;+insert into r select i1,i2 from t1 intersect select i1,i2 from t2;<br>
&gt;+select i1,i2 from r order by 1,2;<br>
&gt;+delete from r;<br>
&gt;+<br>
&gt;+insert into r select i1,i2 from t1 intersect all select i1,i2 from
t2;<br>
&gt;+select i1,i2 from r order by 1,2;<br>
&gt;+delete from r;<br>
&gt;+<br>
&gt;+-- test LOB<br>
&gt;+create table t3( i1 integer, cl clob(64), bl blob(1M));<br>
&gt;+insert into t3 values<br>
&gt;+&nbsp; (1, cast( 'aa' as clob(64)), cast(X'01' as blob(1M)));<br>
&gt;+create table t4( i1 integer, cl clob(64), bl blob(1M));<br>
&gt;+insert into t4 values<br>
&gt;+&nbsp; (1, cast( 'aa' as clob(64)), cast(X'01' as blob(1M)));<br>
&gt;+<br>
&gt;+select cl from t3 intersect select cl from t4 order by 1;<br>
&gt;+<br>
&gt;+select bl from t3 intersect select bl from t4 order by 1;<br>
&gt;+<br>
&gt;+-- invalid conversion<br>
&gt;+select tm from t1 intersect select dt from t2;<br>
&gt;+select c30 from t1 intersect select d from t2;<br>
&gt;+<br>
&gt;+-- different number of columns<br>
&gt;+select i1 from t1 intersect select i1,i2 from t2;<br>
&gt;+<br>
&gt;+-- ? in select list of intersect<br>
&gt;+select ? from t1 intersect select i1 from t2;<br>
&gt;+select i1 from t1 intersect select ? from t2;<br>
&gt;+<br>
&gt;+-- except tests<br>
&gt;+select id,i1,i2 from t1 except select id,i1,i2 from t2 order by
id,i1,i2;<br>
&gt;+select id,i1,i2 from t1 except all select id,i1,i2 from t2 order
by 1 DESC,2,3;<br>
&gt;+select id,i1,i2 from t2 except select id,i1,i2 from t1 order by
1,2,3;<br>
&gt;+select id,i1,i2 from t2 except all select id,i1,i2 from t1 order
by 1,2,3;<br>
&gt;+<br>
&gt;+select i1,i2 from t1 except select i1,i2 from t2 order by 1,2;<br>
&gt;+select i1,i2 from t1 except all select i1,i2 from t2 order by 1,2;<br>
&gt;+select i1,i2 from t2 except select i1,i2 from t1 order by 1,2;<br>
&gt;+select i1,i2 from t2 except all select i1,i2 from t1 order by 1,2;<br>
&gt;+<br>
&gt;+-- right side is empty<br>
&gt;+select i1,i2 from t1 except select i1,i2 from t2 where id = -1
order by 1,2;<br>
&gt;+select i1,i2 from t1 except all select i1,i2 from t2 where id =
-1&nbsp; order by 1,2;<br>
&gt;+<br>
&gt;+-- left side is empty<br>
&gt;+select i1,i2 from t1 where id = -1 except select i1,i2 from t2
order by 1,2;<br>
&gt;+select i1,i2 from t1 where id = -1 except all select i1,i2 from t2
order by 1,2;<br>
&gt;+<br>
&gt;+-- Check precedence. Union and except have the same precedence.
Intersect has higher precedence.<br>
&gt;+select i1,i2 from t1 except select i1,i2 from t2 intersect
values(-1,-1) order by 1,2;<br>
&gt;+select i1,i2 from t1 except (select i1,i2 from t2 intersect
values(-1,-1)) order by 1,2;<br>
&gt;+select i1,i2 from t2 except select i1,i2 from t1 union values(5,5)
order by 1,2;<br>
&gt;+(select i1,i2 from t2 except select i1,i2 from t1) union
values(5,5) order by 1,2;<br>
&gt;+select i1,i2 from t2 except all select i1,i2 from t1 except select
i1,i2 from t1 where id = 3 order by 1,2;<br>
&gt;+(select i1,i2 from t2 except all select i1,i2 from t1) except
select i1,i2 from t1 where id = 3 order by 1,2;<br>
&gt;+<br>
&gt;+-- check conversions<br>
&gt;+select c10 from t1 except select vc20 from t2 order by 1;<br>
&gt;+select c30 from t1 except select vc20 from t2 order by 1;<br>
&gt;+select c30 from t1 except all select vc20 from t2;<br>
&gt;+<br>
&gt;+-- check insert except into table and except without order by<br>
&gt;+insert into r select i1,i2 from t2 except select i1,i2 from t1;<br>
&gt;+select i1,i2 from r order by 1,2;<br>
&gt;+delete from r;<br>
&gt;+<br>
&gt;+insert into r select i1,i2 from t2 except all select i1,i2 from t1;<br>
&gt;+select i1,i2 from r order by 1,2;<br>
&gt;+delete from r;<br>
&gt;+<br>
&gt;+-- test LOB<br>
&gt;+select cl from t3 except select cl from t4 order by 1;<br>
&gt;+select bl from t3 except select bl from t4 order by 1;<br>
&gt;+<br>
&gt;+-- invalid conversion<br>
&gt;+select tm from t1 except select dt from t2;<br>
&gt;+select c30 from t1 except select d from t2;<br>
&gt;+<br>
&gt;+-- different number of columns<br>
&gt;+select i1 from t1 except select i1,i2 from t2;<br>
&gt;+<br>
&gt;+-- ? in select list of except<br>
&gt;+select ? from t1 except select i1 from t2;<br>
&gt;+<br>
&gt;+-- Invalid order by<br>
&gt;+select id,i1,i2 from t1 intersect select id,i1,i2 from t2 order by
t1.i1;<br>
&gt;+select id,i1,i2 from t1 except select id,i1,i2 from t2 order by
t1.i1;<br>
&gt;Index:
java/testing/org/apache/derbyTesting/functionTests/tests/lang/copyfiles.ant<br>
&gt;===================================================================<br>
&gt;---
java/testing/org/apache/derbyTesting/functionTests/tests/lang/copyfiles.ant&nbsp;&nbsp;&nbsp;
(revision 111907)<br>
&gt;+++
java/testing/org/apache/derbyTesting/functionTests/tests/lang/copyfiles.ant&nbsp;&nbsp;&nbsp;
(working copy)<br>
&gt;@@ -95,6 +95,7 @@<br>
&gt; innerjoin.sql<br>
&gt; insert.sql<br>
&gt; insert_sed.properties<br>
&gt;+intersect.sql<br>
&gt; isolationLevels.sql<br>
&gt; joinDeadlock.sql<br>
&gt; joinDeadlock.sql1<br>
&gt;Index:
java/testing/org/apache/derbyTesting/functionTests/master/groupBy.out<br>
&gt;===================================================================<br>
&gt;---
java/testing/org/apache/derbyTesting/functionTests/master/groupBy.out&nbsp;&nbsp;&nbsp;
(revision 111907)<br>
&gt;+++
java/testing/org/apache/derbyTesting/functionTests/master/groupBy.out&nbsp;&nbsp;&nbsp;
(working copy)<br>
&gt;@@ -45,7 +45,7 @@<br>
&gt; create table unmapped(c1 long varchar);<br>
&gt; 0 rows inserted/updated/deleted<br>
&gt; ij&gt; select c1, max(1) from unmapped group by c1;<br>
&gt;-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.<br>
&gt;+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.<br>
&gt; ij&gt; -- clean up<br>
&gt; drop table t1;<br>
&gt; 0 rows inserted/updated/deleted<br>
&gt;Index:
java/testing/org/apache/derbyTesting/functionTests/master/LOB.out<br>
&gt;===================================================================<br>
&gt;---
java/testing/org/apache/derbyTesting/functionTests/master/LOB.out&nbsp;&nbsp;&nbsp;
(revision 111907)<br>
&gt;+++
java/testing/org/apache/derbyTesting/functionTests/master/LOB.out&nbsp;&nbsp;&nbsp;
(working copy)<br>
&gt;@@ -266,13 +266,13 @@<br>
&gt; 0 rows inserted/updated/deleted<br>
&gt; ij&gt; -- create index (not allowed)<br>
&gt; create index ia on a(a);<br>
&gt;-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.<br>
&gt;+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.<br>
&gt; ij&gt; create index ib on b(a);<br>
&gt;-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.<br>
&gt;+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.<br>
&gt; ij&gt; create index ic on c(a);<br>
&gt; ERROR 42Y55: 'CREATE INDEX' cannot be performed on 'C' because it
does not exist.<br>
&gt; ij&gt; create index id on d(a);<br>
&gt;-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.<br>
&gt;+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.<br>
&gt; ij&gt; -- cleanup<br>
&gt; drop table a;<br>
&gt; 0 rows inserted/updated/deleted<br>
&gt;@@ -535,7 +535,7 @@<br>
&gt; 1 row inserted/updated/deleted<br>
&gt; ij&gt; -- UNION<br>
&gt; select * from testPredicate1 union select * from testPredicate2;<br>
&gt;-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.<br>
&gt;+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.<br>
&gt; ij&gt; -- IN predicate<br>
&gt; select c1 from testPredicate1 where c1 IN (select c1 from
testPredicate2);<br>
&gt; ERROR 42818: Comparisons between 'LONG VARCHAR' and 'LONG VARCHAR'
are not supported.<br>
&gt;@@ -544,10 +544,10 @@<br>
&gt; ERROR 42818: Comparisons between 'LONG VARCHAR' and 'LONG VARCHAR'
are not supported.<br>
&gt; ij&gt; -- ORDER BY clause<br>
&gt; select * from testPredicate1 order by c1;<br>
&gt;-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.<br>
&gt;+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.<br>
&gt; ij&gt; -- GROUP BY clause<br>
&gt; select substr(c1,1,2) from testPredicate1 group by c1;<br>
&gt;-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.<br>
&gt;+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.<br>
&gt; ij&gt; -- JOIN<br>
&gt; select * from testPredicate1 t1, testPredicate2 t2 where
t1.c1=t2.c1;<br>
&gt; ERROR 42818: Comparisons between 'LONG VARCHAR' and 'LONG VARCHAR'
are not supported.<br>
&gt;@@ -555,15 +555,15 @@<br>
&gt; ERROR 42818: Comparisons between 'LONG VARCHAR' and 'LONG VARCHAR'
are not supported.<br>
&gt; ij&gt; -- PRIMARY KEY<br>
&gt; create table testConst1(c1 long varchar not null primary key);<br>
&gt;-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.<br>
&gt;+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.<br>
&gt; ij&gt; -- UNIQUE KEY constraints<br>
&gt; CREATE TABLE testconst2 (col1 long varchar not null, CONSTRAINT uk
UNIQUE (col1));<br>
&gt;-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.<br>
&gt;+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.<br>
&gt; ij&gt; -- FOREIGN KEY constraints<br>
&gt; create table testConst3 (c1 char(10) not null, primary key (c1));<br>
&gt; 0 rows inserted/updated/deleted<br>
&gt; ij&gt; create table testConst4 (c1 long varchar not null,
constraint fk foreign key (c1) references testConst3 (c1));<br>
&gt;-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.<br>
&gt;+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.<br>
&gt; ij&gt; drop table testConst3;<br>
&gt; 0 rows inserted/updated/deleted<br>
&gt; ij&gt; -- MAX aggregate function<br>
&gt;Index:
java/testing/org/apache/derbyTesting/functionTests/master/intersect.out<br>
&gt;===================================================================<br>
&gt;---
java/testing/org/apache/derbyTesting/functionTests/master/intersect.out&nbsp;&nbsp;&nbsp;
(revision 0)<br>
&gt;+++
java/testing/org/apache/derbyTesting/functionTests/master/intersect.out&nbsp;&nbsp;&nbsp;
(revision 0)<br>
&gt;@@ -0,0 +1,331 @@<br>
&gt;+ij&gt; create table t1( id integer not null primary key, i1
integer, i2 integer, c10 char(10), c30 char(30), tm time);<br>
&gt;+0 rows inserted/updated/deleted<br>
&gt;+ij&gt; create table t2( id integer not null primary key, i1
integer, i2 integer, vc20 varchar(20), d double, dt date);<br>
&gt;+0 rows inserted/updated/deleted<br>
&gt;+ij&gt; insert into t1(id,i1,i2,c10,c30) values<br>
&gt;+&nbsp; (1,1,1,'a','123456789012345678901234567890'),<br>
&gt;+&nbsp; (2,1,2,'a','bb'),<br>
&gt;+&nbsp; (3,1,3,'b','bb'),<br>
&gt;+&nbsp; (4,1,3,'zz','5'),<br>
&gt;+&nbsp; (5,null,null,null,'1.0'),<br>
&gt;+&nbsp; (6,null,null,null,'a');<br>
&gt;+6 rows inserted/updated/deleted<br>
&gt;+ij&gt; insert into t2(id,i1,i2,vc20,d) values<br>
&gt;+&nbsp; (1,1,1,'a',1.0),<br>
&gt;+&nbsp; (2,1,2,'a',1.1),<br>
&gt;+&nbsp; (5,null,null,'12345678901234567890',3),<br>
&gt;+&nbsp; (100,1,3,'zz',3),<br>
&gt;+&nbsp; (101,1,2,'bb',null),<br>
&gt;+&nbsp; (102,5,5,'',null),<br>
&gt;+&nbsp; (103,1,3,' a',null),<br>
&gt;+&nbsp; (104,1,3,'null',7.4);<br>
&gt;+8 rows inserted/updated/deleted<br>
&gt;+ij&gt; -- no duplicates<br>
&gt;+select id,i1,i2 from t1 intersect select id,i1,i2 from t2 order by
id DESC,i1,i2;<br>
&gt;+ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------------------<br>
&gt;+5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; select id,i1,i2 from t1 intersect all select id,i1,i2 from
t2 order by 1,2,3;<br>
&gt;+ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------------------<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; -- Only specify order by on some columns<br>
&gt;+select id,i1,i2 from t1 intersect select id,i1,i2 from t2 order by
i2, id DESC;<br>
&gt;+ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------------------<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; select id,i1,i2 from t1 intersect all select id,i1,i2 from
t2 order by 3 DESC, 1;<br>
&gt;+ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------------------<br>
&gt;+5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; -- duplicates<br>
&gt;+select i1,i2 from t1 intersect select i1,i2 from t2 order by 1,2;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; select i1,i2 from t1 intersect all select i1,i2 from t2
order by 1,2;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; -- right side is empty<br>
&gt;+select i1,i2 from t1 intersect select i1,i2 from t2 where id = -1;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+ij&gt; select i1,i2 from t1 intersect all select i1,i2 from t2
where id = -1;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+ij&gt; -- left side is empty<br>
&gt;+select i1,i2 from t1 where id = -1 intersect all select i1,i2 from
t2;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+ij&gt; -- check precedence<br>
&gt;+select i1,i2 from t1 intersect all select i1,i2 from t2 intersect
values(5,5),(1,3) order by 1,2;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; (select i1,i2 from t1 intersect all select i1,i2 from t2)
intersect values(5,5),(1,3) order by 1,2;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; values(-1,-1,-1) union select id,i1,i2 from t1 intersect
select id,i1,i2 from t2 order by 1,2,3;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------------------<br>
&gt;+-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; select id,i1,i2 from t1 intersect select id,i1,i2 from t2
union values(-1,-1,-1) order by 1,2,3;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------------------<br>
&gt;+-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |-1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; -- check conversions<br>
&gt;+select c10 from t1 intersect select vc20 from t2 order by 1;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+--------------------<br>
&gt;+a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+zz&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; select c30 from t1 intersect select vc20 from t2;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+------------------------------<br>
&gt;+a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+bb&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; select c30 from t1 intersect all select vc20 from t2;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+------------------------------<br>
&gt;+a&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+bb&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; -- check insert intersect into table and intersect without
order by<br>
&gt;+create table r( i1 integer, i2 integer);<br>
&gt;+0 rows inserted/updated/deleted<br>
&gt;+ij&gt; insert into r select i1,i2 from t1 intersect select i1,i2
from t2;<br>
&gt;+4 rows inserted/updated/deleted<br>
&gt;+ij&gt; select i1,i2 from r order by 1,2;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; delete from r;<br>
&gt;+4 rows inserted/updated/deleted<br>
&gt;+ij&gt; insert into r select i1,i2 from t1 intersect all select
i1,i2 from t2;<br>
&gt;+5 rows inserted/updated/deleted<br>
&gt;+ij&gt; select i1,i2 from r order by 1,2;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; delete from r;<br>
&gt;+5 rows inserted/updated/deleted<br>
&gt;+ij&gt; -- test LOB<br>
&gt;+create table t3( i1 integer, cl clob(64), bl blob(1M));<br>
&gt;+0 rows inserted/updated/deleted<br>
&gt;+ij&gt; insert into t3 values<br>
&gt;+&nbsp; (1, cast( 'aa' as clob(64)), cast(X'01' as blob(1M)));<br>
&gt;+1 row inserted/updated/deleted<br>
&gt;+ij&gt; create table t4( i1 integer, cl clob(64), bl blob(1M));<br>
&gt;+0 rows inserted/updated/deleted<br>
&gt;+ij&gt; insert into t4 values<br>
&gt;+&nbsp; (1, cast( 'aa' as clob(64)), cast(X'01' as blob(1M)));<br>
&gt;+1 row inserted/updated/deleted<br>
&gt;+ij&gt; select cl from t3 intersect select cl from t4 order by 1;<br>
&gt;+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.<br>
&gt;+ij&gt; select bl from t3 intersect select bl from t4 order by 1;<br>
&gt;+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.<br>
&gt;+ij&gt; -- invalid conversion<br>
&gt;+select tm from t1 intersect select dt from t2;<br>
&gt;+ERROR 42X61: Types 'TIME' and 'DATE' are not INTERSECT compatible.<br>
&gt;+ij&gt; select c30 from t1 intersect select d from t2;<br>
&gt;+ERROR 42X61: Types 'CHAR' and 'DOUBLE' are not INTERSECT
compatible.<br>
&gt;+ij&gt; -- different number of columns<br>
&gt;+select i1 from t1 intersect select i1,i2 from t2;<br>
&gt;+ERROR 42X58: The number of columns on the left and right sides of
the INTERSECT must be the same.<br>
&gt;+ij&gt; -- ? in select list of intersect<br>
&gt;+select ? from t1 intersect select i1 from t2;<br>
&gt;+ERROR 42X34: There is a ? parameter in the select list.&nbsp; This is
not allowed.<br>
&gt;+ij&gt; select i1 from t1 intersect select ? from t2;<br>
&gt;+ERROR 42X34: There is a ? parameter in the select list.&nbsp; This is
not allowed.<br>
&gt;+ij&gt; -- except tests<br>
&gt;+select id,i1,i2 from t1 except select id,i1,i2 from t2 order by
id,i1,i2;<br>
&gt;+ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------------------<br>
&gt;+3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; select id,i1,i2 from t1 except all select id,i1,i2 from t2
order by 1 DESC,2,3;<br>
&gt;+ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------------------<br>
&gt;+6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; select id,i1,i2 from t2 except select id,i1,i2 from t1
order by 1,2,3;<br>
&gt;+ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------------------<br>
&gt;+100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; select id,i1,i2 from t2 except all select id,i1,i2 from t1
order by 1,2,3;<br>
&gt;+ID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------------------<br>
&gt;+100&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+101&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+102&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+103&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+104&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; select i1,i2 from t1 except select i1,i2 from t2 order by
1,2;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+ij&gt; select i1,i2 from t1 except all select i1,i2 from t2 order
by 1,2;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; select i1,i2 from t2 except select i1,i2 from t1 order by
1,2;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; select i1,i2 from t2 except all select i1,i2 from t1 order
by 1,2;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; -- right side is empty<br>
&gt;+select i1,i2 from t1 except select i1,i2 from t2 where id = -1
order by 1,2;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; select i1,i2 from t1 except all select i1,i2 from t2 where
id = -1&nbsp; order by 1,2;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; -- left side is empty<br>
&gt;+select i1,i2 from t1 where id = -1 except select i1,i2 from t2
order by 1,2;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+ij&gt; select i1,i2 from t1 where id = -1 except all select i1,i2
from t2 order by 1,2;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+ij&gt; -- Check precedence. Union and except have the same
precedence. Intersect has higher precedence.<br>
&gt;+select i1,i2 from t1 except select i1,i2 from t2 intersect
values(-1,-1) order by 1,2;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; select i1,i2 from t1 except (select i1,i2 from t2 intersect
values(-1,-1)) order by 1,2;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; select i1,i2 from t2 except select i1,i2 from t1 union
values(5,5) order by 1,2;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; (select i1,i2 from t2 except select i1,i2 from t1) union
values(5,5) order by 1,2;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; select i1,i2 from t2 except all select i1,i2 from t1 except
select i1,i2 from t1 where id = 3 order by 1,2;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; (select i1,i2 from t2 except all select i1,i2 from t1)
except select i1,i2 from t1 where id = 3 order by 1,2;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; -- check conversions<br>
&gt;+select c10 from t1 except select vc20 from t2 order by 1;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+--------------------<br>
&gt;+b&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+NULL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; select c30 from t1 except select vc20 from t2 order by 1;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+------------------------------<br>
&gt;+1.0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+123456789012345678901234567890<br>
&gt;+5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; select c30 from t1 except all select vc20 from t2;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+------------------------------<br>
&gt;+1.0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+123456789012345678901234567890<br>
&gt;+5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+bb&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; -- check insert except into table and except without order
by<br>
&gt;+insert into r select i1,i2 from t2 except select i1,i2 from t1;<br>
&gt;+1 row inserted/updated/deleted<br>
&gt;+ij&gt; select i1,i2 from r order by 1,2;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; delete from r;<br>
&gt;+1 row inserted/updated/deleted<br>
&gt;+ij&gt; insert into r select i1,i2 from t2 except all select i1,i2
from t1;<br>
&gt;+3 rows inserted/updated/deleted<br>
&gt;+ij&gt; select i1,i2 from r order by 1,2;<br>
&gt;+I1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+-----------------------<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br>
&gt;+ij&gt; delete from r;<br>
&gt;+3 rows inserted/updated/deleted<br>
&gt;+ij&gt; -- test LOB<br>
&gt;+select cl from t3 except select cl from t4 order by 1;<br>
&gt;+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.<br>
&gt;+ij&gt; select bl from t3 except select bl from t4 order by 1;<br>
&gt;+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.<br>
&gt;+ij&gt; -- invalid conversion<br>
&gt;+select tm from t1 except select dt from t2;<br>
&gt;+ERROR 42X61: Types 'TIME' and 'DATE' are not EXCEPT compatible.<br>
&gt;+ij&gt; select c30 from t1 except select d from t2;<br>
&gt;+ERROR 42X61: Types 'CHAR' and 'DOUBLE' are not EXCEPT compatible.<br>
&gt;+ij&gt; -- different number of columns<br>
&gt;+select i1 from t1 except select i1,i2 from t2;<br>
&gt;+ERROR 42X58: The number of columns on the left and right sides of
the EXCEPT must be the same.<br>
&gt;+ij&gt; -- ? in select list of except<br>
&gt;+select ? from t1 except select i1 from t2;<br>
&gt;+ERROR 42X34: There is a ? parameter in the select list.&nbsp; This is
not allowed.<br>
&gt;+ij&gt; -- Invalid order by<br>
&gt;+select id,i1,i2 from t1 intersect select id,i1,i2 from t2 order by
t1.i1;<br>
&gt;+ERROR 42877: A qualified column name 'T1.I1' is not allowed in the
ORDER BY clause.<br>
&gt;+ij&gt; select id,i1,i2 from t1 except select id,i1,i2 from t2
order by t1.i1;<br>
&gt;+ERROR 42877: A qualified column name 'T1.I1' is not allowed in the
ORDER BY clause.<br>
&gt;+ij&gt;<br>
&gt;Index:
java/testing/org/apache/derbyTesting/functionTests/suites/derbylang.runall<br>
&gt;===================================================================<br>
&gt;---
java/testing/org/apache/derbyTesting/functionTests/suites/derbylang.runall&nbsp;&nbsp;&nbsp;
(revision 111907)<br>
&gt;+++
java/testing/org/apache/derbyTesting/functionTests/suites/derbylang.runall&nbsp;&nbsp;&nbsp;
(working copy)<br>
&gt;@@ -67,6 +67,7 @@<br>
&gt; lang/infostreams.sql<br>
&gt; lang/innerjoin.sql<br>
&gt; lang/insert.sql<br>
&gt;+lang/intersect.sql<br>
&gt; lang/isolationLevels.sql<br>
&gt; lang/joinDeadlock.sql<br>
&gt; lang/joins.sql<br>
-----BEGIN PGP SIGNATURE----- <br>
Version: GnuPG v1.2.5 (MingW32) <br>
Comment: Using GnuPG with Thunderbird - <a class="moz-txt-link-freetext" href="http://enigmail.mozdev.org">http://enigmail.mozdev.org</a> <br>
&nbsp;<br>
iD8DBQFBx31TENVNIY6DZ7ERAnNJAJ9cErrZTOtPQ34k6d52MbJICOYqJACglekB <br>
StvurWxarzgsVV4hCwvVN88= <br>
=+52k <br>
-----END PGP SIGNATURE----- <br>
<br>
</body>
</html>

Mime
View raw message