📄 valuenode.java
字号:
return Qualifier.VARIANT; } /** * Bind time logic. Raises an error if this ValueNode does not resolve to * a boolean value. This method is called by WHERE clauses. * * @return bound coercion of this node to a builtin type as necessary * * @exception StandardException Thrown on error */ public ValueNode checkIsBoolean() throws StandardException { ValueNode whereClause = this; /* ** Is the datatype of the WHERE clause BOOLEAN? ** ** NOTE: This test is not necessary in SQL92 entry level, because ** it is syntactically impossible to have a non-Boolean WHERE clause ** in that level of the standard. But we intend to extend the ** language to allow Boolean user functions in the WHERE clause, ** so we need to test for the error condition. */ TypeId whereTypeId = whereClause.getTypeId(); /* If the where clause is not a built-in type, then generate a bound * conversion tree to a built-in type. */ if (! whereTypeId.systemBuiltIn()) { whereClause = whereClause.genSQLJavaSQLTree(); whereTypeId = whereClause.getTypeId(); } if (! whereTypeId.equals(TypeId.BOOLEAN_ID)) { throw StandardException.newException(SQLState.LANG_NON_BOOLEAN_WHERE_CLAUSE, whereTypeId.getSQLTypeName() ); } return whereClause; } /** * Return an Object representing the bind time value of this * expression tree. If the expression tree does not evaluate to * a constant at bind time then we return null. * This is useful for bind time resolution of VTIs. * RESOLVE: What do we do for primitives? * * @return An Object representing the bind time value of this expression tree. * (null if not a bind time constant.) * * @exception StandardException Thrown on error */ Object getConstantValueAsObject() throws StandardException { return null; } ///////////////////////////////////////////////////////////////////////// // // The ValueNode defers its generate() work to a method that works on // ExpressionClassBuilders rather than ActivationClassBuilders. This // is so that expression generation can be shared by the Core compiler // AND the Replication Filter compiler. // ///////////////////////////////////////////////////////////////////////// /** * Do the code generation for this node. Call the more general * routine that generates expressions. * * @param acb The ActivationClassBuilder for the class being built * @param mb The method the expression will go into * * * @exception StandardException Thrown on error */ protected final void generate(ActivationClassBuilder acb, MethodBuilder mb) throws StandardException { generateExpression( acb, mb ); } /** * The only reason this routine exists is so that I don't have to change * the protection on generateExpression() and rototill all of QueryTree. * * @param ecb The ExpressionClassBuilder for the class being built * @param mb The method the expression will go into * * * @exception StandardException Thrown on error */ public void generateFilter(ExpressionClassBuilder ecb, MethodBuilder mb) throws StandardException { generateExpression( ecb, mb ); } /** * The default selectivity for value nodes is 50%. This is overridden * in specific cases, such as the RelationalOperators. */ public double selectivity(Optimizable optTable) { // Return 1 if additional predicates have been generated from this one. if (transformed) { return 1.0; } else { return 0.5d; } } /** * Update the array of columns in = conditions with expressions without * column references from the same table. This is useful when doing * subquery flattening on the basis of an equality condition. * eqOuterCols or tableColMap may be null if the calling routine * doesn't need the information provided * * @param tableNumber The tableNumber of the table from which * the columns of interest come from. * @param eqOuterCols Array of booleans for noting which columns * are in = predicates without columns from the * subquery block. May be null. * @param tableNumbers Array of table numbers in this query block. * @param tableColMap Array of bits for noting which columns * are in = predicates for each table in the * query block. May be null. * @param resultColTable True if tableNumber is the table containing result * columns * * @return Nothing. * * @exception StandardException Thrown on error * */ void checkTopPredicatesForEqualsConditions( int tableNumber, boolean[] eqOuterCols, int[] tableNumbers, JBitSet[] tableColMap, boolean resultColTable) throws StandardException { for (ValueNode whereWalker = this; whereWalker instanceof AndNode; whereWalker = ((AndNode) whereWalker).getRightOperand()) { // See if this is a candidate = AndNode and = (AndNode) whereWalker; if (!and.getLeftOperand().isRelationalOperator() || !(((RelationalOperator)(and.getLeftOperand())).getOperator() == RelationalOperator.EQUALS_RELOP)) { continue; } BinaryRelationalOperatorNode beon = (BinaryRelationalOperatorNode) and.getLeftOperand(); ValueNode left = beon.getLeftOperand(); ValueNode right = beon.getRightOperand(); int resultTable = 0; if (resultColTable) { for ( ; resultTable < tableNumbers.length; resultTable++) { if (tableNumbers[resultTable] == tableNumber) break; } } else resultTable = -1; /* Is this = of the right form? */ if ((left instanceof ColumnReference) && ((ColumnReference) left).getTableNumber() == tableNumber) { updateMaps(tableColMap, eqOuterCols, tableNumbers, tableNumber, resultTable, right, left); } else if ((right instanceof ColumnReference) && ((ColumnReference) right).getTableNumber() == tableNumber) { updateMaps(tableColMap, eqOuterCols, tableNumbers, tableNumber, resultTable, left, right); } } } /** * Does this represent a true constant. * * @return Whether or not this node represents a true constant. */ boolean isBooleanTrue() { return false; } /** * Does this represent a false constant. * * @return Whether or not this node represents a false constant. */ boolean isBooleanFalse() { return false; } /** * Generate code for this calculation. This is a place-holder method - * it should not be called. * * @param ecb The ExpressionClassBuilder for the class being built * @param mb The method the expression will go into * * * @exception StandardException Thrown on error */ public void generateExpression(ExpressionClassBuilder acb, MethodBuilder mb) throws StandardException { if (SanityManager.DEBUG) SanityManager.ASSERT(false, "Code generation for this type of ValueNode is unimplemented"); } /** * Set the correct bits in tableColMap and set the boolean value in eqOuterCols * given two arguments to an = predicate * tableColMap[t] - bit is set if the column is in an = predicate with a column * in table t, or a bit is set if the column is in an * = predicate with a constant,parameter or correlation variable * (for all table t, if this tableColMap is not for the * table with the result columns) * eqOuterCols[c] - is true if the column is in an = predicate with a constant, * parameter or correlation variable * * * @param tableColMap Array of bitmaps for noting which columns are in = * predicates with columns from each table * @param eqOuterCols Array of booleans for noting which columns * are in = predicates without columns from the * subquery block. * @param tableNumber table number for which we are setting up the Maps * @param resultTable -1 if this table is not the result table; otherwise * the index into tableNumbers for the result table * @param arg1 one side of the = predicate * @param arg2 other side of the = predicate * * * @exception StandardException Thrown on error */ private void updateMaps(JBitSet[] tableColMap, boolean[] eqOuterCols, int[] tableNumbers, int tableNumber, int resultTable, ValueNode arg1, ValueNode arg2) throws StandardException { /* arg2 is a column from our table. This * is a good = for both All tables and Outer arrays * if the right side is a constant or a parameter * or a column from an outer table. * It is a good = for only the All array if * the right side is a column from this query block. */ if ((arg1 instanceof ConstantNode) || (arg1.isParameterNode())) { setValueCols(tableColMap, eqOuterCols, ((ColumnReference) arg2).getColumnNumber(), resultTable); } else if((arg1 instanceof ColumnReference && ((ColumnReference) arg1).getTableNumber() != tableNumber)) { /* See if other columns is a correlation column */ int otherTN = ((ColumnReference) arg1).getTableNumber(); int index = 0; int colNumber = ((ColumnReference) arg2).getColumnNumber(); for ( ; index < tableNumbers.length; index++) { if (otherTN == tableNumbers[index]) { break; } } /* Correlation column, so we can treat it as a constant */ if (index == tableNumbers.length) { setValueCols(tableColMap, eqOuterCols, colNumber, resultTable); } else if (tableColMap != null) { tableColMap[index].set(colNumber); } } else { /* See if other side contains a column reference from the same table */ JBitSet referencedTables = arg1.getTablesReferenced(); /* See if other columns are all correlation columns */ int index = 0; int colNumber = ((ColumnReference) arg2).getColumnNumber(); for ( ; index < tableNumbers.length; index++) { if (referencedTables.get(tableNumbers[index])) { break; } } /* Correlation column, so we can treat it as a constant */ if (index == tableNumbers.length) { setValueCols(tableColMap, eqOuterCols, colNumber, resultTable); } else if (tableColMap != null && !referencedTables.get(tableNumber)) { tableColMap[index].set(colNumber); } } } /** * Set eqOuterCols and the column in all the tables for constants, * parmeters and correlation columns * The column in the tableColMap is set only for the current table * if the table is the result column table. For other tables in the * query we set the column for all the tables since the constant will * reduced the number of columns required in a unique multicolumn index for * distinctness. * For example, given an unique index on t1(a,b), setting b=1 means that * t1(a) is unique since there can be no duplicates for a where b=1 without * destroying the uniqueness of t1(a,b). However, for the result columns * setting b=1, does not mean that a select list of t1.a is distinct if * t1.a is the only column used in joining with another table * e.g. select t1.a from t1, t2 where t1.a = t2.a and t1.b = 1; * * t1 t2 result * a b a a * 1 1 1 1 * 1 2 2 1 * 2 1 * * * @param tableColMap Array of bitmaps for noting which columns are in = * predicates with columns from each table * @param eqOuterCols Array of booleans for noting which columns * are in = predicates without columns from the * subquery block. * @param colReference The column to set * @param resultTable If -1 set all the bit for all the tables for that * column; otherwise set the bit for the specified table * * */ private void setValueCols(JBitSet[] tableColMap, boolean[] eqOuterCols, int colReference, int resultTable) { if (eqOuterCols != null) eqOuterCols[colReference] = true; if (tableColMap != null) { if (resultTable == -1) { for (int i = 0; i < tableColMap.length; i++) tableColMap[i].set(colReference); } else tableColMap[resultTable].set(colReference); } } /** * Returns true if this ValueNode is a relational operator. Relational * Operators are <, <=, =, >, >=, <> as well as IS NULL and IS NOT * NULL. This is the preferred way of figuring out if a ValueNode is * relational or not. * @see RelationalOperator * @see BinaryRelationalOperatorNode * @see IsNullNode */ public boolean isRelationalOperator() { return false; } /** * Returns true if this value node is a <em>equals</em> operator. * * @see ValueNode#isRelationalOperator */ public boolean isBinaryEqualsOperatorNode() { return false; } /** Return true if the predicate represents an optimizable equality node. * an expression is considered to be an optimizable equality node if all the * following conditions are met: * <ol> * <li> the operator is an <em>=</em> or <em>IS NULL</em> operator </li> * <li> one of the operands is a column specified by optTable/columnNumber</li> * <li> Both operands are not the same column; i.e tab.col = tab.col </li> * <li> There are no implicit varchar comparisons of the operands; i.e * either both operands are string like (varchar, char, longvarchar) or * neither operand is string like </li> * </ol> * * @param optTable the table being optimized. Column reference must be from * this table. * @param columnNumber the column number. One of the operands of this * predicate must be the column number specified by optTable/columnNumber * @param isNullOkay if set to true we also consider IS NULL predicates; * otherwise consider only = predicates. */ public boolean optimizableEqualityNode(Optimizable optTable, int columnNumber, boolean isNullOkay) throws StandardException { return false; } /** * Returns TRUE if this is a parameter node. We do lots of special things * with Parameter Nodes. * */ public boolean isParameterNode() { return false; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -