--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.impl.sql.compile.TestConstraintNode\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.impl.sql.compile;\r
+\r
+import org.apache.derby.iapi.sql.compile.C_NodeTypes;\r
+\r
+import org.apache.derby.iapi.services.compiler.MethodBuilder;\r
+import org.apache.derby.iapi.reference.ClassName;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.types.TypeId;\r
+import org.apache.derby.iapi.types.BooleanDataValue;\r
+import org.apache.derby.iapi.types.DataTypeDescriptor;\r
+\r
+import org.apache.derby.impl.sql.compile.ExpressionClassBuilder;\r
+import org.apache.derby.iapi.services.classfile.VMOpcode;\r
+\r
+import java.util.Vector;\r
+\r
+/**\r
+ * A TestConstraintNode is used to determine when a constraint\r
+ * has been violated.\r
+ *\r
+ */\r
+\r
+public class TestConstraintNode extends UnaryLogicalOperatorNode\r
+{\r
+ private String sqlState;\r
+ private String tableName;\r
+ private String constraintName;\r
+\r
+ /**\r
+ * Initializer for a TestConstraintNode\r
+ *\r
+ * @param booleanValue The operand of the constraint test\r
+ * @param sqlState The SQLState of the exception to throw if the\r
+ * constraint has failed\r
+ * @param tableName The name of the table that the constraint is on\r
+ * @param constraintName The name of the constraint being checked\r
+ */\r
+\r
+ public void init(Object booleanValue,\r
+ Object sqlState,\r
+ Object tableName,\r
+ Object constraintName)\r
+ {\r
+ super.init(booleanValue, "throwExceptionIfFalse");\r
+ this.sqlState = (String) sqlState;\r
+ this.tableName = (String) tableName;\r
+ this.constraintName = (String) constraintName;\r
+ }\r
+\r
+ /**\r
+ * Bind this logical operator. All that has to be done for binding\r
+ * a logical operator is to bind the operand, check that the operand\r
+ * is SQLBoolean, and set the result type to SQLBoolean.\r
+ *\r
+ * @param fromList The query's FROM list\r
+ * @param subqueryList The subquery list being built as we find SubqueryNodes\r
+ * @param aggregateVector The aggregate vector being built as we find AggregateNodes\r
+ *\r
+ * @return The new top of the expression tree.\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+\r
+ public ValueNode bindExpression(\r
+ FromList fromList, SubqueryList subqueryList,\r
+ Vector aggregateVector)\r
+ throws StandardException\r
+ {\r
+ bindOperand(fromList, subqueryList, aggregateVector);\r
+\r
+ /*\r
+ ** If the operand is not boolean, cast it.\r
+ */\r
+\r
+ if (!operand.getTypeServices().getTypeId().isBooleanTypeId())\r
+ {\r
+ operand = (ValueNode)\r
+ getNodeFactory().getNode(\r
+ C_NodeTypes.CAST_NODE,\r
+ operand,\r
+ new DataTypeDescriptor(TypeId.BOOLEAN_ID, true),\r
+ getContextManager());\r
+ ((CastNode) operand).bindCastNodeOnly();\r
+ }\r
+\r
+ /* Set the type info */\r
+ setFullTypeInfo();\r
+\r
+ return this;\r
+ }\r
+\r
+ /**\r
+ * Do code generation for the TestConstraint operator.\r
+ *\r
+ * @param acb The ExpressionClassBuilder for the class we're generating\r
+ * @param mb The method the expression will go into\r
+ *\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+\r
+ public void generateExpression(ExpressionClassBuilder acb,\r
+ MethodBuilder mb)\r
+ throws StandardException\r
+ {\r
+\r
+ /*\r
+ ** This generates the following code:\r
+ **\r
+ ** operand.testConstraint(sqlState, tableName, constraintName)\r
+ */\r
+\r
+ operand.generateExpression(acb, mb);\r
+\r
+ mb.push(sqlState);\r
+ mb.push(tableName);\r
+ mb.push(constraintName);\r
+\r
+ mb.callMethod(VMOpcode.INVOKEINTERFACE, ClassName.BooleanDataValue,\r
+ "throwExceptionIfFalse", ClassName.BooleanDataValue, 3);\r
+\r
+ }\r
+}\r