⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 setoperatornode.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
		 */

		// See if we already have a scoped version of the predicate cached,
		// and if so just use that.
		Predicate scopedPred = null;
		if (leftScopedPreds == null)
			leftScopedPreds = new HashMap();
		else
			scopedPred = (Predicate)leftScopedPreds.get(pred);
		if (scopedPred == null)
		{
			scopedPred = pred.getPredScopedForResultSet(
				tableNums, leftResultSet);
			leftScopedPreds.put(pred, scopedPred);
		}

		// Add the scoped predicate to our list for the left child.
		getLeftOptPredicateList().addOptPredicate(scopedPred);

		scopedPred = null;
		if (rightScopedPreds == null)
			rightScopedPreds = new HashMap();
		else
			scopedPred = (Predicate)rightScopedPreds.get(pred);
		if (scopedPred == null)
		{
			scopedPred = pred.getPredScopedForResultSet(
				tableNums, rightResultSet);
			rightScopedPreds.put(pred, scopedPred);
		}

		// Add the scoped predicate to our list for the right child.
		getRightOptPredicateList().addOptPredicate(scopedPred);

		// Restore the original predicate to the way it was before we got
		// here--i.e. remap it again if needed.
		if (opWasRemapped)
		{
			rcrv = new RemapCRsVisitor(true);
			pred.getAndNode().accept(rcrv);
		}

		// Add the predicate (in its original form) to our list of predicates
		// that we've pushed during this phase of optimization.  We need to
		// keep this list of pushed predicates around so that we can do
		// a "pull" of them later, if needed.  We also need this list for
		// cases where predicates are not pushed all the way down; see
		// modifyAccessPaths() in this class for more.
		if (pushedPredicates == null)
			pushedPredicates = new PredicateList();

		pushedPredicates.addOptPredicate(pred);
		return true;
	}

	/**
	 * @see Optimizable#pullOptPredicates
	 *
	 * @exception StandardException		Thrown on error
	 */
	public void pullOptPredicates(
		OptimizablePredicateList optimizablePredicates)
		throws StandardException
	{
		if (pushedPredicates == null)
		// we didn't push anything, so nothing to pull.
			return;

		// It's possible that we tried to push a predicate down to this
		// SetOperatorNode's children but weren't actually able to do so
		// (see modifyAccessPaths() in this class for details on when that
		// can happen).  In that case the predicates will still be sitting
		// in the left/right predicate list; we can ignore them here by
		// just discarding them.  When it comes time to modifyAccessPaths,
		// though, we'll handle them correctly--i.e. we'll generate a
		// ProjectRestrictNode over this node to ensure the predicates are
		// enforced.

		if (leftOptPredicates != null)
			leftOptPredicates.removeAllElements();

		if (rightOptPredicates != null)
			rightOptPredicates.removeAllElements();

		/* Note that predicates which have been explicitly scoped should
		 * not be pulled.  The reason is that a scoped predicate can only
		 * be pushed to a specific, target result set.  When it comes time
		 * to pull the predicate up, there's no need to pull the scoped
		 * predicate because it, by definition, was only intended for this
		 * specific result set and therefore cannot be pushed anywhere else.
		 * So at "pull" time, we can just discard the scoped predicates.  We
		 * do, however, need to pull the original, unscoped predicate from
		 * which the scoped predicate was created because we can potentially
		 * push that predicate elsewhere
		 */
		Predicate pred = null;
		for (int i = 0; i < pushedPredicates.size(); i++)
		{
			pred = (Predicate)pushedPredicates.getOptPredicate(i);
			if (pred.isScopedForPush())
				continue;
			optimizablePredicates.addOptPredicate(pred);
		}

		// We're done with the pushedPredicates list, so clear it out
		// in preparation for another phase of optimization.
		pushedPredicates.removeAllElements();
	}

	/**
	 * Convert this object to a String.  See comments in QueryTreeNode.java
	 * for how this should be done for tree printing.
	 *
	 * @return	This object as a String
	 */

	public String toString()
	{
		if (SanityManager.DEBUG)
		{
			return 	"all: " + all + "\n" +
				"orderByList: " + 
				(orderByList != null ? orderByList.toString() : "null") + "\n" +
				super.toString();
		}
		else
		{
			return "";
		}
	}

	/**
	 * Bind the result columns of this ResultSetNode when there is no
	 * base table to bind them to.  This is useful for SELECT statements,
	 * where the result columns get their types from the expressions that
	 * live under them.
	 *
	 * @param fromListParam		FromList to use/append to.
	 *
	 * @return	Nothing
	 *
	 * @exception StandardException		Thrown on error
	 */
	public void bindResultColumns(FromList fromListParam)
					throws StandardException
	{
		super.bindResultColumns(fromListParam);

		/* Now we build our RCL */
		buildRCL();
	}

	/**
	 * Bind the result columns for this ResultSetNode to a base table.
	 * This is useful for INSERT and UPDATE statements, where the
	 * result columns get their types from the table being updated or
	 * inserted into.
	 * If a result column list is specified, then the verification that the 
	 * result column list does not contain any duplicates will be done when
	 * binding them by name.
	 *
	 * @param targetTableDescriptor	The TableDescriptor for the table being
	 *				updated or inserted into
	 * @param targetColumnList	For INSERT statements, the user
	 *					does not have to supply column
	 *					names (for example, "insert into t
	 *					values (1,2,3)".  When this
	 *					parameter is null, it means that
	 *					the user did not supply column
	 *					names, and so the binding should
	 *					be done based on order.  When it
	 *					is not null, it means do the binding
	 *					by name, not position.
	 * @param statement			Calling DMLStatementNode (Insert or Update)
	 * @param fromListParam		FromList to use/append to.
	 *
	 * @return	Nothing
	 *
	 * @exception StandardException		Thrown on error
	 */

	public void bindResultColumns(TableDescriptor targetTableDescriptor,
					FromVTI targetVTI,
					ResultColumnList targetColumnList,
					DMLStatementNode statement,
					FromList fromListParam)
				throws StandardException
	{
		super.bindResultColumns(targetTableDescriptor,
								targetVTI,
								targetColumnList, statement,
								fromListParam);

		/* Now we build our RCL */
		buildRCL();
	}

	/**
	 * Build the RCL for this node.  We propagate the RCL up from the
	 * left child to form this node's RCL.
	 *
	 * @return	Nothing
	 *
	 * @exception StandardException		Thrown on error
	 */

	private void buildRCL() throws StandardException
	{
		/* Verify that both sides of the union have the same # of columns in their
		 * RCL.
		 */
		if (leftResultSet.getResultColumns().size() !=
			rightResultSet.getResultColumns().size())
		{
			throw StandardException.newException(SQLState.LANG_UNION_UNMATCHED_COLUMNS,
                                                 getOperatorName());
		}

		/* We need to recreate resultColumns for this node, since there
		 * may have been 1 or more *'s in the left's SELECT list.
		 */
		resultColumns = leftResultSet.getResultColumns().copyListAndObjects();

		/* Create new expressions with the dominant types after verifying
		 * union compatibility between left and right sides.
		 */
		resultColumns.setUnionResultExpression(rightResultSet.getResultColumns(), tableNumber, level, getOperatorName());
	}

	/**
	 * Bind the result columns of a table constructor to the types in the
	 * given ResultColumnList.  Use when inserting from a table constructor,
	 * and there are nulls in the values clauses.
	 *
	 * @param rcl	The ResultColumnList with the types to bind to
	 *
	 * @exception StandardException		Thrown on error.
	 */
	public void bindUntypedNullsToResultColumns(ResultColumnList rcl)
				throws StandardException
	{
		/*
		** If the RCL from the parent is null, then
		** the types are coming from the union itself.
		** So we have to cross check the two child
		** rcls.
		*/
		if (rcl == null)
		{
			ResultColumnList lrcl = rightResultSet.getResultColumns();
			ResultColumnList rrcl = leftResultSet.getResultColumns();

			leftResultSet.bindUntypedNullsToResultColumns(rrcl);
			rightResultSet.bindUntypedNullsToResultColumns(lrcl);
		}
		else	
		{
			leftResultSet.bindUntypedNullsToResultColumns(rcl);
			rightResultSet.bindUntypedNullsToResultColumns(rcl);
		}			
	}

	/**
	 * Get the parameter types from the given RowResultSetNode into the
	 * given array of types.  If an array position is already filled in,
	 * don't clobber it.
	 *
	 * @param types	The array of types to fill in
	 * @param rrsn	The RowResultSetNode from which to take the param types
	 *
	 * @return	The number of new types found in the RowResultSetNode
	 */
	int getParamColumnTypes(DataTypeDescriptor[] types, RowResultSetNode rrsn)
	{
		int	numTypes = 0;

		/* Look for columns where we have not found a non-? yet. */
		for (int i = 0; i < types.length; i++)
		{
			if (types[i] == null)
			{
				ResultColumn rc =
					(ResultColumn) rrsn.getResultColumns().elementAt(i);
				if ( ! (rc.getExpression().isParameterNode()))
				{
					types[i] = rc.getExpressionType();
					numTypes++;
				}
			}
		}

		return numTypes;
	}

	/**
	 * Set the type of each ? parameter in the given RowResultSetNode
	 * according to its ordinal position in the given array of types.
	 *
	 * @param types	An array of types containing the proper type for each
	 *				? parameter, by ordinal position.
	 * @param rrsn	A RowResultSetNode that could contain ? parameters whose
	 *				types need to be set.
	 *
	 * @exception StandardException		Thrown on error
	 */
	void setParamColumnTypes(DataTypeDescriptor[] types, RowResultSetNode rrsn)
					throws StandardException
	{
		/*
		** Look for ? parameters in the result column list
		** of each RowResultSetNode
		*/
		ResultColumnList rrcl = rrsn.getResultColumns();
		int rrclSize = rrcl.size();
		for (int index = 0; index < rrclSize; index++)
		{
			ResultColumn	rc = (ResultColumn) rrcl.elementAt(index);

			if (rc.getExpression().isParameterNode())
			{
				/*
				** We found a ? - set its type to the type from the
				** type array.
				*/
				((ParameterNode) rc.getExpression()).setDescriptor(
											types[index]);
			}
		}
	}

	/**
	 * Bind the expressions in the target list.  This means binding the
	 * sub-expressions, as well as figuring out what the return type is
	 * for each expression.  This is useful for EXISTS subqueries, where we
	 * need to validate the target list before blowing it away and replacing
	 * it with a SELECT true.
	 *
	 * @return	Nothing
	 *
	 * @exception StandardException		Thrown on error
	 */

	public void bindTargetExpressions(FromList fromListParam)
					throws StandardException
	{
		leftResultSet.bindTargetExpressions(fromListParam);
		rightResultSet.bindTargetExpressions(fromListParam);
	}

	/**
	 * Push the order by list down from the cursor node
	 * into its child result set so that the optimizer
	 * has all of the information that it needs to 
	 * consider sort avoidance.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -