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