001: /*
002:
003: Derby - Class org.apache.derby.impl.sql.compile.NotNode
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.services.compiler.MethodBuilder;
025: import org.apache.derby.iapi.services.compiler.LocalField;
026: import org.apache.derby.iapi.reference.ClassName;
027:
028: import org.apache.derby.iapi.services.sanity.SanityManager;
029:
030: import org.apache.derby.iapi.error.StandardException;
031:
032: import org.apache.derby.iapi.types.TypeId;
033:
034: import org.apache.derby.iapi.types.DataValueDescriptor;
035: import org.apache.derby.iapi.types.BooleanDataValue;
036: import org.apache.derby.iapi.types.TypeId;
037: import org.apache.derby.iapi.types.DataTypeDescriptor;
038:
039: import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;
040: import org.apache.derby.iapi.services.classfile.VMOpcode;
041:
042: import java.lang.reflect.Modifier;
043:
044: /**
045: * A NotNode represents a NOT operator. Preprocessing will eliminate the
046: * NotNodes which exist above comparison operators so that the optimizer
047: * will see a query tree in CNF.
048: *
049: * @author Jerry Brenner
050: */
051:
052: public final class NotNode extends UnaryLogicalOperatorNode {
053: /**
054: * Initializer for a NotNode
055: *
056: * @param operand The operand of the NOT
057: */
058:
059: public void init(Object operand) {
060: super .init(operand, "not");
061: }
062:
063: /**
064: * Eliminate NotNodes in the current query block. We traverse the tree,
065: * inverting ANDs and ORs and eliminating NOTs as we go. We stop at
066: * ComparisonOperators and boolean expressions. We invert
067: * ComparisonOperators and replace boolean expressions with
068: * boolean expression = false.
069: *
070: * @param underNotNode Whether or not we are under a NotNode.
071: *
072: *
073: * @return The modified expression
074: *
075: * @exception StandardException Thrown on error
076: */
077: ValueNode eliminateNots(boolean underNotNode)
078: throws StandardException {
079: return operand.eliminateNots(!underNotNode);
080: }
081:
082: /**
083: * Do code generation for the NOT operator.
084: *
085: * @param acb The ExpressionClassBuilder for the class we're generating
086: * @param mb The method the expression will go into
087: *
088: * @exception StandardException Thrown on error
089: */
090:
091: public void generateExpression(ExpressionClassBuilder acb,
092: MethodBuilder mb) throws StandardException {
093: /*
094: ** This generates the following code:
095: **
096: ** <boolean field> = <operand>.equals(<operand>,
097: ** <false truth value>);
098: */
099:
100: /*
101: ** Generate the code for a Boolean false constant value.
102: */
103: String interfaceName = getTypeCompiler().interfaceName();
104: LocalField field = acb.newFieldDeclaration(Modifier.PRIVATE,
105: interfaceName);
106: /*
107: ** Generate the call to the equals method.
108: ** equals is only on Orderable, not any subinterfaces.
109: */
110:
111: /* Generate the code for operand */
112: operand.generateExpression(acb, mb);
113: mb.upCast(ClassName.DataValueDescriptor);
114:
115: mb.dup(); // arg 1 is instance
116:
117: // arg 2
118: mb.push(false);
119: acb.generateDataValue(mb, getTypeCompiler(), field);
120: mb.upCast(ClassName.DataValueDescriptor);
121:
122: mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null,
123: "equals", interfaceName, 2);
124: }
125: }
|