001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.compile.UnaryLogicalOperatorNode
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.sql.compile;
023:
024: import org.apache.derby.iapi.sql.dictionary.DataDictionary;
025:
026: import org.apache.derby.iapi.types.TypeId;
027:
028: import org.apache.derby.iapi.reference.SQLState;
029: import org.apache.derby.iapi.error.StandardException;
030: import org.apache.derby.iapi.types.DataTypeDescriptor;
031:
032: import org.apache.derby.iapi.services.sanity.SanityManager;
033:
034: import java.util.Vector;
035:
036: public abstract class UnaryLogicalOperatorNode extends
037: UnaryOperatorNode {
038: /**
039: * Initializer for a UnaryLogicalOperatorNode
040: *
041: * @param operand The operand of the operator
042: * @param methodName The name of the method to call in the generated
043: * class. In this case, it's actually an operator
044: * name.
045: */
046:
047: public void init(Object operand, Object methodName) {
048: /* For logical operators, the operator and method names are the same */
049: super .init(operand, methodName, methodName);
050: }
051:
052: /**
053: * Bind this logical operator. All that has to be done for binding
054: * a logical operator is to bind the operand, check that the operand
055: * is SQLBoolean, and set the result type to SQLBoolean.
056: *
057: * @param fromList The query's FROM list
058: * @param subqueryList The subquery list being built as we find SubqueryNodes
059: * @param aggregateVector The aggregate vector being built as we find AggregateNodes
060: *
061: * @return The new top of the expression tree.
062: *
063: * @exception StandardException Thrown on error
064: */
065:
066: public ValueNode bindExpression(FromList fromList,
067: SubqueryList subqueryList, Vector aggregateVector)
068: throws StandardException {
069: super .bindExpression(fromList, subqueryList, aggregateVector);
070:
071: /*
072: ** Logical operators work only on booleans. If the operand
073: ** is not boolean, throw an exception.
074: **
075: ** For now, this exception will never happen, because the grammar
076: ** does not allow arbitrary expressions with NOT. But when
077: ** we start allowing generalized boolean expressions, we will modify
078: ** the grammar, so this test will become useful.
079: */
080:
081: if (!operand.getTypeServices().getTypeId().equals(
082: TypeId.BOOLEAN_ID)) {
083: operand.treePrint();
084: throw StandardException
085: .newException(SQLState.LANG_UNARY_LOGICAL_NON_BOOLEAN);
086: }
087:
088: /* Set the type info */
089: setFullTypeInfo();
090:
091: return this ;
092: }
093:
094: /**
095: * Set all of the type info (nullability and DataTypeServices) for
096: * this node. Extracts out tasks that must be done by both bind()
097: * and post-bind() AndNode generation.
098: *
099: * @exception StandardException Thrown on error
100: */
101: protected void setFullTypeInfo() throws StandardException {
102: boolean nullableResult;
103:
104: /*
105: ** Set the result type of this comparison operator based on the
106: ** operands. The result type is always SQLBoolean - the only question
107: ** is whether it is nullable or not. If either of the operands is
108: ** nullable, the result of the comparison must be nullable, too, so
109: ** we can represent the unknown truth value.
110: */
111: nullableResult = operand.getTypeServices().isNullable();
112: setType(new DataTypeDescriptor(TypeId.BOOLEAN_ID,
113: nullableResult));
114: }
115: }
|