--- /dev/null
+/*\r
+\r
+ Derby - Class org.apache.derby.iapi.types.SQLBoolean\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.iapi.types;\r
+\r
+\r
+import org.apache.derby.iapi.services.io.ArrayInputStream;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.services.io.Storable;\r
+import org.apache.derby.iapi.services.io.StoredFormatIds;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+import org.apache.derby.iapi.types.TypeId;\r
+import org.apache.derby.iapi.types.BooleanDataValue;\r
+\r
+\r
+import org.apache.derby.iapi.services.cache.ClassSize;\r
+import org.apache.derby.iapi.util.StringUtil;\r
+\r
+import java.io.ObjectOutput;\r
+import java.io.ObjectInput;\r
+import java.io.IOException;\r
+\r
+import java.sql.ResultSet;\r
+import java.sql.PreparedStatement;\r
+import java.sql.SQLException;\r
+\r
+/**\r
+ * SQLBoolean satisfies the DataValueDescriptor\r
+ * interfaces (i.e., DataType). It implements a boolean column, \r
+ * e.g. for * storing a column value; it can be specified\r
+ * when constructed to not allow nulls. Nullability cannot be changed\r
+ * after construction, as it affects the storage size and mechanism.\r
+ * <p>\r
+ * Because DataType is a subtype of DataType,\r
+ * SQLBoolean can play a role in either a DataType/Row\r
+ * or a DataType/Row, interchangeably.\r
+ * <p>\r
+ * We assume the store has a flag for nullness of the value,\r
+ * and simply return a 0-length array for the stored form\r
+ * when the value is null.\r
+ * <p>\r
+ * PERFORMANCE: There are likely alot of performance improvements\r
+ * possible for this implementation -- it new's Integer\r
+ * more than it probably wants to.\r
+ */\r
+public final class SQLBoolean\r
+ extends DataType implements BooleanDataValue\r
+{\r
+ /*\r
+ * DataValueDescriptor interface\r
+ * (mostly implemented in DataType)\r
+ */\r
+\r
+ /*\r
+ * see if the integer value is null.\r
+ */\r
+ public boolean isNull()\r
+ {\r
+ return isnull;\r
+ }\r
+\r
+ public boolean getBoolean()\r
+ {\r
+ return value;\r
+ }\r
+\r
+ private static int makeInt(boolean b)\r
+ {\r
+ return (b?1:0);\r
+ }\r
+\r
+ /** \r
+ * @see DataValueDescriptor#getByte \r
+ */\r
+ public byte getByte() \r
+ {\r
+ return (byte) makeInt(value);\r
+ }\r
+\r
+ /** \r
+ * @see DataValueDescriptor#getShort \r
+ */\r
+ public short getShort()\r
+ {\r
+ return (short) makeInt(value);\r
+ }\r
+\r
+ /** \r
+ * @see DataValueDescriptor#getInt \r
+ */\r
+ public int getInt()\r
+ {\r
+ return makeInt(value);\r
+ }\r
+\r
+ /** \r
+ * @see DataValueDescriptor#getLong \r
+ */\r
+ public long getLong()\r
+ {\r
+ return (long) makeInt(value);\r
+ }\r
+\r
+ /** \r
+ * @see DataValueDescriptor#getFloat \r
+ */\r
+ public float getFloat()\r
+ {\r
+ return (float) makeInt(value);\r
+ }\r
+\r
+ /** \r
+ * @see DataValueDescriptor#getDouble \r
+ */\r
+ public double getDouble()\r
+ {\r
+ return (double) makeInt(value);\r
+ }\r
+\r
+ /**\r
+ * Implementation for BOOLEAN type. Convert to a BigDecimal using long\r
+ */\r
+ public int typeToBigDecimal()\r
+ {\r
+ return java.sql.Types.BIGINT;\r
+ }\r
+ public String getString()\r
+ {\r
+ if (isNull())\r
+ return null;\r
+ else if (value == true)\r
+ return "true";\r
+ else\r
+ return "false";\r
+ }\r
+\r
+ public Object getObject()\r
+ {\r
+ if (isNull())\r
+ return null;\r
+ else\r
+ return new Boolean(value);\r
+ }\r
+\r
+ public int getLength()\r
+ {\r
+ return BOOLEAN_LENGTH;\r
+ }\r
+\r
+ // this is for DataType's error generator\r
+ public String getTypeName()\r
+ {\r
+ return TypeId.BOOLEAN_NAME;\r
+ }\r
+\r
+ /**\r
+ * Recycle this SQLBoolean object if possible. If the object is immutable,\r
+ * create and return a new object.\r
+ *\r
+ * @return a new SQLBoolean if this object is immutable; otherwise, this\r
+ * object with value set to null\r
+ */\r
+ public DataValueDescriptor recycle() {\r
+ if (immutable) {\r
+ return new SQLBoolean();\r
+ }\r
+ return super.recycle();\r
+ }\r
+\r
+ /*\r
+ * Storable interface, implies Externalizable, TypedFormat\r
+ */\r
+\r
+\r
+ /**\r
+ Return my format identifier.\r
+\r
+ @see org.apache.derby.iapi.services.io.TypedFormat#getTypeFormatId\r
+ */\r
+ public int getTypeFormatId() {\r
+ return StoredFormatIds.SQL_BOOLEAN_ID;\r
+ }\r
+\r
+ public void writeExternal(ObjectOutput out) throws IOException {\r
+\r
+ // never called when value is null\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT(! isNull());\r
+\r
+ out.writeBoolean(value);\r
+ }\r
+\r
+ /** @see java.io.Externalizable#readExternal */\r
+ public void readExternal(ObjectInput in) throws IOException {\r
+\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT( ! immutable,\r
+ "Attempt to set the value of an immutable SQLBoolean");\r
+\r
+ value = in.readBoolean();\r
+ isnull = false;\r
+ }\r
+ public void readExternalFromArray(ArrayInputStream in) throws IOException {\r
+\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT( ! immutable,\r
+ "Attempt to set the value of an immutable SQLBoolean");\r
+\r
+ value = in.readBoolean();\r
+ isnull = false;\r
+ }\r
+\r
+ /**\r
+ * @see Storable#restoreToNull\r
+ *\r
+ */\r
+ public void restoreToNull()\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT( ! immutable,\r
+ "Attempt to set the value of an immutable SQLBoolean");\r
+\r
+ value = false;\r
+ isnull = true;\r
+ }\r
+\r
+ /*\r
+ * Orderable interface\r
+ */\r
+\r
+ /**\r
+ @exception StandardException thrown on error\r
+ */\r
+ public int compare(DataValueDescriptor other) throws StandardException\r
+ {\r
+ /* Use compare method from dominant type, negating result\r
+ * to reflect flipping of sides.\r
+ */\r
+ if (typePrecedence() < other.typePrecedence())\r
+ {\r
+ return - (other.compare(this));\r
+ }\r
+\r
+ boolean thisNull, otherNull;\r
+ thisNull = this.isNull();\r
+ otherNull = other.isNull();\r
+\r
+ /*\r
+ * thisNull otherNull thisValue thatValue return\r
+ * T T X X 0 (this == other)\r
+ * F T X X 1 (this > other)\r
+ * T F X X -1 (this < other)\r
+ *\r
+ * F F T T 0 (this == other)\r
+ * F F T F 1 (this > other)\r
+ * F F F T -1 (this < other)\r
+ * F F F F 0 (this == other)\r
+ */\r
+ if (thisNull || otherNull)\r
+ {\r
+ if (!thisNull) // otherNull must be true\r
+ return 1;\r
+ if (!otherNull) // thisNull must be true\r
+ return -1;\r
+ return 0;\r
+ }\r
+\r
+ /* neither are null, get the value */\r
+ boolean thisValue;\r
+ boolean otherValue = false;\r
+ thisValue = this.getBoolean();\r
+\r
+ otherValue = other.getBoolean();\r
+\r
+ if (thisValue == otherValue)\r
+ return 0;\r
+ else if (thisValue && !otherValue)\r
+ return 1;\r
+ else\r
+ return -1;\r
+ }\r
+\r
+ /**\r
+ @exception StandardException thrown on error\r
+ */\r
+ public boolean compare(int op,\r
+ DataValueDescriptor other,\r
+ boolean orderedNulls,\r
+ boolean unknownRV)\r
+ throws StandardException\r
+ {\r
+ if (!orderedNulls) // nulls are unordered\r
+ {\r
+ if (this.isNull() || other.isNull())\r
+ return unknownRV;\r
+ }\r
+ /* Do the comparison */\r
+ return super.compare(op, other, orderedNulls, unknownRV);\r
+ }\r
+\r
+ /*\r
+ * DataValueDescriptor interface\r
+ */\r
+\r
+ /** @see DataValueDescriptor#getClone */\r
+ public DataValueDescriptor getClone()\r
+ {\r
+ return new SQLBoolean(value, isnull);\r
+ }\r
+\r
+ /**\r
+ * @see DataValueDescriptor#getNewNull\r
+ */\r
+ public DataValueDescriptor getNewNull()\r
+ {\r
+ return new SQLBoolean();\r
+ }\r
+\r
+ /** \r
+ * @see DataValueDescriptor#setValueFromResultSet \r
+ *\r
+ * @exception SQLException Thrown on error\r
+ */\r
+ public void setValueFromResultSet(ResultSet resultSet, int colNumber,\r
+ boolean isNullable)\r
+ throws SQLException\r
+ {\r
+ value = resultSet.getBoolean(colNumber);\r
+ isnull = (isNullable && resultSet.wasNull());\r
+ }\r
+ /**\r
+ Set the value into a PreparedStatement.\r
+\r
+ @exception SQLException Error setting value in PreparedStatement\r
+ */\r
+ public final void setInto(PreparedStatement ps, int position) throws SQLException {\r
+\r
+ if (isNull()) {\r
+ ps.setNull(position, java.sql.Types.BIT);\r
+ return;\r
+ }\r
+\r
+ ps.setBoolean(position, value);\r
+ }\r
+ /*\r
+ * class interface\r
+ */\r
+\r
+ /*\r
+ * constructors\r
+ */\r
+\r
+ /* NOTE - other data types have both (type value) and (boolean nulls), \r
+ * (value, nulls)\r
+ * We can't do both (boolean value) and (boolean nulls) here,\r
+ * so we'll skip over (boolean value) and have (Boolean value) so\r
+ * that we can support (boolean nulls).\r
+ */\r
+\r
+ public SQLBoolean()\r
+ {\r
+ isnull = true;\r
+ }\r
+\r
+ public SQLBoolean(boolean val)\r
+ {\r
+ value = val;\r
+ }\r
+ public SQLBoolean(Boolean obj) {\r
+ if (isnull = (obj == null))\r
+ ;\r
+ else\r
+ value = obj.booleanValue();\r
+ }\r
+\r
+ /* This constructor gets used for the getClone() method */\r
+ private SQLBoolean(boolean val, boolean isnull)\r
+ {\r
+ value = val;\r
+ this.isnull = isnull;\r
+ }\r
+\r
+ /** @see BooleanDataValue#setValue */\r
+ public void setValue(boolean theValue)\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT( ! immutable,\r
+ "Attempt to set the value of an immutable SQLBoolean");\r
+ value = theValue;\r
+ isnull = false;\r
+\r
+ }\r
+\r
+ public void setValue(Boolean theValue)\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT( ! immutable,\r
+ "Attempt to set the value of an immutable SQLBoolean");\r
+ if (theValue == null)\r
+ {\r
+ value = false;\r
+ isnull = true;\r
+ }\r
+ else\r
+ {\r
+ value = theValue.booleanValue();\r
+ isnull = false;\r
+ }\r
+\r
+ }\r
+\r
+ // REMIND: do we need this, or is long enough?\r
+ public void setValue(byte theValue)\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT( ! immutable,\r
+ "Attempt to set the value of an immutable SQLBoolean");\r
+ value = theValue != 0;\r
+ isnull = false;\r
+\r
+ }\r
+\r
+\r
+ // REMIND: do we need this, or is long enough?\r
+ public void setValue(short theValue)\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT( ! immutable,\r
+ "Attempt to set the value of an immutable SQLBoolean");\r
+ value = theValue != 0;\r
+ isnull = false;\r
+\r
+ }\r
+\r
+\r
+ // REMIND: do we need this, or is long enough?\r
+ public void setValue(int theValue)\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT( ! immutable,\r
+ "Attempt to set the value of an immutable SQLBoolean");\r
+ value = theValue != 0;\r
+ isnull = false;\r
+\r
+ }\r
+\r
+ public void setValue(long theValue)\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT( ! immutable,\r
+ "Attempt to set the value of an immutable SQLBoolean");\r
+ value = theValue != 0;\r
+ isnull = false;\r
+\r
+ }\r
+\r
+ // REMIND: do we need this, or is double enough?\r
+ public void setValue(float theValue)\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT( ! immutable,\r
+ "Attempt to set the value of an immutable SQLBoolean");\r
+ value = theValue != 0;\r
+ isnull = false;\r
+\r
+ }\r
+\r
+ public void setValue(double theValue)\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT( ! immutable,\r
+ "Attempt to set the value of an immutable SQLBoolean");\r
+ value = theValue != 0;\r
+ isnull = false;\r
+\r
+ }\r
+\r
+ public void setBigDecimal(Number bigDecimal) throws StandardException\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT( ! immutable,\r
+ "Attempt to set the value of an immutable SQLBoolean");\r
+ if (bigDecimal == null)\r
+ {\r
+ value = false;\r
+ isnull = true;\r
+ }\r
+ else\r
+ {\r
+ DataValueDescriptor tempDecimal = NumberDataType.ZERO_DECIMAL.getNewNull();\r
+ tempDecimal.setBigDecimal(bigDecimal);\r
+ value = NumberDataType.ZERO_DECIMAL.compare(tempDecimal) != 0;\r
+ isnull = false;\r
+ }\r
+\r
+ }\r
+\r
+ /**\r
+ * Set the value of this BooleanDataValue to the given byte array value\r
+ *\r
+ * @param theValue The value to set this BooleanDataValue to\r
+ */\r
+ public void setValue(byte[] theValue)\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT( ! immutable,\r
+ "Attempt to set the value of an immutable SQLBoolean");\r
+\r
+ if (theValue != null)\r
+ {\r
+ isnull = false;\r
+ int length = theValue.length;\r
+ \r
+ /*\r
+ ** Step through all bytes. As soon\r
+ ** as we get one with something other\r
+ ** than 0, then we know we have a 'true'\r
+ */\r
+ for (int i = 0; i < length; i++)\r
+ {\r
+ if (theValue[i] != 0)\r
+ {\r
+ value = true;\r
+ return;\r
+ }\r
+ }\r
+ }\r
+ else\r
+ {\r
+ isnull = true;\r
+ }\r
+ value = false;\r
+\r
+ }\r
+\r
+\r
+ /**\r
+ * Set the value of this BooleanDataValue to the given String.\r
+ * String is trimmed and upcased. If resultant string is not\r
+ * TRUE or FALSE, then an error is thrown.\r
+ *\r
+ * @param theValue The value to set this BooleanDataValue to\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+ public void setValue(String theValue)\r
+ throws StandardException\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT( ! immutable,\r
+ "Attempt to set the value of an immutable SQLBoolean");\r
+ if (theValue == null)\r
+ {\r
+ value = false;\r
+ isnull = true;\r
+ }\r
+ else\r
+ {\r
+ /*\r
+ ** Note: cannot use getBoolean(String) here because\r
+ ** it doesn't trim, and doesn't throw exceptions.\r
+ */\r
+ String cleanedValue = StringUtil.SQLToUpperCase(theValue.trim());\r
+ if (cleanedValue.equals("TRUE"))\r
+ {\r
+ value = true;\r
+ }\r
+ else if (cleanedValue.equals("FALSE"))\r
+ {\r
+ value = false;\r
+ }\r
+ else\r
+ { \r
+ throw invalidFormat();\r
+ }\r
+ isnull = false;\r
+ }\r
+\r
+ }\r
+\r
+ private void setValueCore(Number theValue)\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ SanityManager.ASSERT( ! immutable,\r
+ "Attempt to set the value of an immutable SQLBoolean");\r
+\r
+ if (theValue == null)\r
+ {\r
+ isnull = true;\r
+ value = false;\r
+ }\r
+ else\r
+ {\r
+ value = (theValue.intValue() != 0);\r
+ isnull = false;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * @see DataValueDescriptor#setValue\r
+ */ \r
+ void setObject(Object theValue)\r
+ {\r
+ setValue((Boolean) theValue);\r
+ }\r
+ protected void setFrom(DataValueDescriptor theValue) throws StandardException {\r
+\r
+ setValue(theValue.getBoolean());\r
+ }\r
+\r
+\r
+ /*\r
+ ** SQL Operators\r
+ */\r
+\r
+ /**\r
+ * The = operator as called from the language module, as opposed to\r
+ * the storage module.\r
+ *\r
+ * @param left The value on the left side of the =\r
+ * @param right The value on the right side of the =\r
+ *\r
+ * @return A SQL boolean value telling whether the two parameters are equal\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+\r
+ public BooleanDataValue equals(DataValueDescriptor left,\r
+ DataValueDescriptor right)\r
+ throws StandardException\r
+ {\r
+ return truthValue(left,\r
+ right,\r
+ left.getBoolean() == right.getBoolean());\r
+ }\r
+\r
+ /**\r
+ * The <> operator as called from the language module, as opposed to\r
+ * the storage module.\r
+ *\r
+ * @param left The value on the left side of the <>\r
+ * @param right The value on the right side of the <>\r
+ *\r
+ * @return A SQL boolean value telling whether the two parameters are\r
+ * not equal\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+\r
+ public BooleanDataValue notEquals(DataValueDescriptor left,\r
+ DataValueDescriptor right)\r
+ throws StandardException\r
+ {\r
+ return truthValue(left,\r
+ right,\r
+ left.getBoolean() != right.getBoolean());\r
+ }\r
+\r
+ /**\r
+ * The < operator as called from the language module, as opposed to\r
+ * the storage module.\r
+ *\r
+ * @param left The value on the left side of the <\r
+ * @param right The value on the right side of the <\r
+ *\r
+ * @return A SQL boolean value telling whether the left operand is\r
+ * less than the right operand\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+\r
+ public BooleanDataValue lessThan(DataValueDescriptor left,\r
+ DataValueDescriptor right)\r
+ throws StandardException\r
+ {\r
+ /* We must call getBoolean() on both sides in order\r
+ * to catch any invalid casts.\r
+ */\r
+ boolean leftBoolean = left.getBoolean();\r
+ boolean rightBoolean = right.getBoolean();\r
+ /* By convention, false is less than true */\r
+ return truthValue(left,\r
+ right,\r
+ leftBoolean == false && rightBoolean == true);\r
+ }\r
+\r
+ /**\r
+ * The > operator as called from the language module, as opposed to\r
+ * the storage module.\r
+ *\r
+ * @param left The value on the left side of the >\r
+ * @param right The value on the right side of the >\r
+ *\r
+ * @return A SQL boolean value telling whether the left operand is\r
+ * greater than the right operand\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+\r
+ public BooleanDataValue greaterThan(DataValueDescriptor left,\r
+ DataValueDescriptor right)\r
+ throws StandardException\r
+ {\r
+ /* We must call getBoolean() on both sides in order\r
+ * to catch any invalid casts.\r
+ */\r
+ boolean leftBoolean = left.getBoolean();\r
+ boolean rightBoolean = right.getBoolean();\r
+ /* By convention, true is greater than false */\r
+ return truthValue(left,\r
+ right,\r
+ leftBoolean == true && rightBoolean == false);\r
+ }\r
+\r
+ /**\r
+ * The <= operator as called from the language module, as opposed to\r
+ * the storage module.\r
+ *\r
+ * @param left The value on the left side of the <=\r
+ * @param right The value on the right side of the <=\r
+ *\r
+ * @return A SQL boolean value telling whether the left operand is\r
+ * less than or equal to the right operand\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+\r
+ public BooleanDataValue lessOrEquals(DataValueDescriptor left,\r
+ DataValueDescriptor right)\r
+ throws StandardException\r
+ {\r
+ /* We must call getBoolean() on both sides in order\r
+ * to catch any invalid casts.\r
+ */\r
+ boolean leftBoolean = left.getBoolean();\r
+ boolean rightBoolean = right.getBoolean();\r
+ /* By convention, false is less than true */\r
+ return truthValue(left,\r
+ right,\r
+ leftBoolean == false || rightBoolean == true);\r
+ }\r
+\r
+ /**\r
+ * The >= operator as called from the language module, as opposed to\r
+ * the storage module.\r
+ *\r
+ * @param left The value on the left side of the >=\r
+ * @param right The value on the right side of the >=\r
+ *\r
+ * @return A SQL boolean value telling whether the left operand is\r
+ * greater than or equal to the right operand\r
+ *\r
+ * @exception StandardException Thrown on error\r
+ */\r
+\r
+ public BooleanDataValue greaterOrEquals(DataValueDescriptor left,\r
+ DataValueDescriptor right)\r
+ throws StandardException\r
+ {\r
+ /* We must call getBoolean() on both sides in order\r
+ * to catch any invalid casts.\r
+ */\r
+ boolean leftBoolean = left.getBoolean();\r
+ boolean rightBoolean = right.getBoolean();\r
+ /* By convention, true is greater than false */\r
+ return truthValue(left,\r
+ right,\r
+ leftBoolean == true || rightBoolean == false);\r
+ }\r
+\r
+ /**\r
+ * The AND operator. This implements SQL semantics for AND with unknown\r
+ * truth values - consult any standard SQL reference for an explanation.\r
+ *\r
+ * @param otherValue The other boolean to AND with this one\r
+ *\r
+ * @return this AND otherValue\r
+ *\r
+ */\r
+\r
+ public BooleanDataValue and(BooleanDataValue otherValue)\r
+ {\r
+ /*\r
+ ** Catch those cases where standard SQL null semantics don't work.\r
+ */\r
+ if (this.equals(false) || otherValue.equals(false))\r
+ {\r
+ return BOOLEAN_FALSE;\r
+ }\r
+ else\r
+ {\r
+ return truthValue(this,\r
+ otherValue,\r
+ this.getBoolean() && otherValue.getBoolean());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * The OR operator. This implements SQL semantics for OR with unknown\r
+ * truth values - consult any standard SQL reference for an explanation.\r
+ *\r
+ * @param otherValue The other boolean to OR with this one\r
+ *\r
+ * @return this OR otherValue\r
+ *\r
+ */\r
+\r
+ public BooleanDataValue or(BooleanDataValue otherValue)\r
+ {\r
+ /*\r
+ ** Catch those cases where standard SQL null semantics don't work.\r
+ */\r
+ if (this.equals(true) || otherValue.equals(true))\r
+ {\r
+ return BOOLEAN_TRUE;\r
+ }\r
+ else\r
+ {\r
+ return truthValue(this,\r
+ otherValue,\r
+ this.getBoolean() || otherValue.getBoolean());\r
+ }\r
+ }\r
+\r
+ /**\r
+ * The SQL IS operator - consult any standard SQL reference for an explanation.\r
+ *\r
+ * Implements the following truth table:\r
+ *\r
+ * otherValue\r
+ * | TRUE | FALSE | UNKNOWN\r
+ * this |----------------------------\r
+ * |\r
+ * TRUE | TRUE | FALSE | FALSE\r
+ * FALSE | FALSE | TRUE | FALSE\r
+ * UNKNOWN | FALSE | FALSE | TRUE\r
+ *\r
+ *\r
+ * @param otherValue BooleanDataValue to compare to. May be TRUE, FALSE, or UNKNOWN.\r
+ *\r
+ * @return whether this IS otherValue\r
+ *\r
+ */\r
+ public BooleanDataValue is(BooleanDataValue otherValue)\r
+ {\r
+ if ( this.equals(true) && otherValue.equals(true) )\r
+ { return BOOLEAN_TRUE; }\r
+\r
+ if ( this.equals(false) && otherValue.equals(false) )\r
+ { return BOOLEAN_TRUE; }\r
+\r
+ if ( this.isNull() && otherValue.isNull() )\r
+ { return BOOLEAN_TRUE; }\r
+\r
+ return BOOLEAN_FALSE;\r
+ }\r
+\r
+ /**\r
+ * Implements NOT IS. This reverses the sense of the is() call.\r
+ *\r
+ *\r
+ * @param otherValue BooleanDataValue to compare to. May be TRUE, FALSE, or UNKNOWN.\r
+ *\r
+ * @return NOT( this IS otherValue )\r
+ *\r
+ */\r
+ public BooleanDataValue isNot(BooleanDataValue otherValue)\r
+ {\r
+ BooleanDataValue isValue = is( otherValue );\r
+\r
+ if ( isValue.equals(true) ) { return BOOLEAN_FALSE; }\r
+ else { return BOOLEAN_TRUE; }\r
+ }\r
+\r
+ /**\r
+ * Throw an exception with the given SQLState if this BooleanDataValue\r
+ * is false. This method is useful for evaluating constraints.\r
+ *\r
+ * @param sqlState The SQLState of the exception to throw if\r
+ * this SQLBoolean is false.\r
+ * @param tableName The name of the table to include in the exception\r
+ * message.\r
+ * @param constraintName The name of the failed constraint to include\r
+ * in the exception message.\r
+ *\r
+ * @return this\r
+ *\r
+ * @exception StandardException Thrown if this BooleanDataValue\r
+ * is false.\r
+ */\r
+ public BooleanDataValue throwExceptionIfFalse(\r
+ String sqlState,\r
+ String tableName,\r
+ String constraintName)\r
+ throws StandardException\r
+ {\r
+ if ( ( ! isNull() ) && (value == false) )\r
+ {\r
+ throw StandardException.newException(sqlState,\r
+ tableName,\r
+ constraintName);\r
+ }\r
+\r
+ return this;\r
+ }\r
+\r
+ /*\r
+ * DataValueDescriptor interface\r
+ */\r
+\r
+ /** @see DataValueDescriptor#typePrecedence */\r
+ public int typePrecedence()\r
+ {\r
+ return TypeId.BOOLEAN_PRECEDENCE;\r
+ }\r
+\r
+ /*\r
+ ** Support functions\r
+ */\r
+\r
+ /**\r
+ * Return the SQL truth value for a comparison.\r
+ *\r
+ * This method first looks at the operands - if either is null, it\r
+ * returns the unknown truth value. This implements "normal" SQL\r
+ * null semantics, where if any operand is null, the result is null.\r
+ * Note that there are cases where these semantics are incorrect -\r
+ * for example, NULL AND FALSE is supposed to be FALSE, not NULL\r
+ * (the NULL truth value is the same as the UNKNOWN truth value).\r
+ *\r
+ * If neither operand is null, it returns a static final variable\r
+ * containing the SQLBoolean truth value. It returns different values\r
+ * depending on whether the truth value is supposed to be nullable.\r
+ *\r
+ * This method always returns a pre-allocated static final SQLBoolean.\r
+ * This is practical because there are so few possible return values.\r
+ * Using pre-allocated values allows us to avoid constructing new\r
+ * SQLBoolean values during execution.\r
+ *\r
+ * @param leftOperand The left operand of the binary comparison\r
+ * @param rightOperand The right operand of the binary comparison\r
+ * @param truth The truth value of the comparison\r
+ *\r
+ * @return A SQLBoolean containing the desired truth value.\r
+ */\r
+\r
+ public static SQLBoolean truthValue(\r
+ DataValueDescriptor leftOperand,\r
+ DataValueDescriptor rightOperand,\r
+ boolean truth)\r
+ {\r
+ /* Return UNKNOWN if either operand is null */\r
+ if (leftOperand.isNull() || rightOperand.isNull())\r
+ {\r
+ return unknownTruthValue();\r
+ }\r
+\r
+ /* Return the appropriate SQLBoolean for the given truth value */\r
+ if (truth == true)\r
+ {\r
+ return BOOLEAN_TRUE;\r
+ }\r
+ else\r
+ {\r
+ return BOOLEAN_FALSE;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * same as above, but takes a Boolean, if it is null, unknownTruthValue is returned\r
+ */\r
+ public static SQLBoolean truthValue(\r
+ DataValueDescriptor leftOperand,\r
+ DataValueDescriptor rightOperand,\r
+ Boolean truth)\r
+ {\r
+ /* Return UNKNOWN if either operand is null */\r
+ if (leftOperand.isNull() || rightOperand.isNull() || truth==null)\r
+ {\r
+ return unknownTruthValue();\r
+ }\r
+\r
+ /* Return the appropriate SQLBoolean for the given truth value */\r
+ if (truth == Boolean.TRUE)\r
+ {\r
+ return BOOLEAN_TRUE;\r
+ }\r
+ else\r
+ {\r
+ return BOOLEAN_FALSE;\r
+ }\r
+ }\r
+\r
+ /**\r
+ * Get a truth value.\r
+ *\r
+ * @param value The value of the SQLBoolean\r
+ *\r
+ * @return A SQLBoolean with the given truth value\r
+ */\r
+ public static SQLBoolean truthValue(boolean value)\r
+ {\r
+ /*\r
+ ** Return the non-nullable versions of TRUE and FALSE, since they\r
+ ** can never be null.\r
+ */\r
+ if (value == true)\r
+ return BOOLEAN_TRUE;\r
+ else\r
+ return BOOLEAN_FALSE;\r
+ }\r
+\r
+ /**\r
+ * Return an unknown truth value. Check to be sure the return value is\r
+ * nullable.\r
+ *\r
+ * @return A SQLBoolean representing the UNKNOWN truth value\r
+ */\r
+ public static SQLBoolean unknownTruthValue()\r
+ {\r
+ return UNKNOWN;\r
+ }\r
+\r
+ /**\r
+ * Return a false truth value.\r
+ *\r
+ *\r
+ * @return A SQLBoolean representing the FALSE truth value\r
+ */\r
+ public static SQLBoolean falseTruthValue()\r
+ {\r
+ return BOOLEAN_FALSE;\r
+ }\r
+\r
+ /**\r
+ * Return a true truth value.\r
+ *\r
+ *\r
+ * @return A SQLBoolean representing the TRUE truth value\r
+ */\r
+ public static SQLBoolean trueTruthValue()\r
+ {\r
+ return BOOLEAN_TRUE;\r
+ }\r
+ \r
+ /**\r
+ * Determine whether this SQLBoolean contains the given boolean value.\r
+ *\r
+ * This method is used by generated code to determine when to do\r
+ * short-circuiting for an AND or OR.\r
+ *\r
+ * @param val The value to look for\r
+ *\r
+ * @return true if the given value equals the value in this SQLBoolean,\r
+ * false if not\r
+ */\r
+\r
+ public boolean equals(boolean val)\r
+ {\r
+ if (isNull())\r
+ return false;\r
+ else\r
+ return value == val;\r
+ }\r
+ \r
+ /**\r
+ * Return an immutable BooleanDataValue with the same value as this.\r
+ * @return An immutable BooleanDataValue with the same value as this.\r
+ */\r
+ public BooleanDataValue getImmutable()\r
+ {\r
+ if (isNull())\r
+ return SQLBoolean.UNKNOWN;\r
+ \r
+ return value ? SQLBoolean.BOOLEAN_TRUE : SQLBoolean.BOOLEAN_FALSE;\r
+ }\r
+\r
+ /*\r
+ * String display of value\r
+ */\r
+\r
+ public String toString()\r
+ {\r
+ if (isNull())\r
+ return "NULL";\r
+ else if (value == true)\r
+ return "true";\r
+ else\r
+ return "false";\r
+ }\r
+\r
+ /*\r
+ * Hash code\r
+ */\r
+ public int hashCode()\r
+ {\r
+ if (isNull())\r
+ {\r
+ return -1;\r
+ }\r
+\r
+ return (value) ? 1 : 0;\r
+ }\r
+\r
+ /*\r
+ * useful constants...\r
+ */\r
+ static final int BOOLEAN_LENGTH = 1; // must match the number of bytes written by DataOutput.writeBoolean()\r
+\r
+ private static final SQLBoolean BOOLEAN_TRUE = new SQLBoolean(true);\r
+ private static final SQLBoolean BOOLEAN_FALSE = new SQLBoolean(false);\r
+ static final SQLBoolean UNKNOWN = new SQLBoolean();\r
+\r
+ /* Static initialization block */\r
+ static\r
+ {\r
+ /* Mark all the static SQLBooleans as immutable */\r
+ BOOLEAN_TRUE.immutable = true;\r
+ BOOLEAN_FALSE.immutable = true;\r
+ UNKNOWN.immutable = true;\r
+ }\r
+\r
+ private static final int BASE_MEMORY_USAGE = ClassSize.estimateBaseFromCatalog( SQLBoolean.class);\r
+\r
+ public int estimateMemoryUsage()\r
+ {\r
+ return BASE_MEMORY_USAGE;\r
+ }\r
+\r
+ /*\r
+ * object state\r
+ */\r
+ private boolean value;\r
+ private boolean isnull;\r
+ private boolean immutable;\r
+}\r