0001: /*
0002:
0003: Derby - Class org.apache.derby.iapi.types.SQLBoolean
0004:
0005: Licensed to the Apache Software Foundation (ASF) under one or more
0006: contributor license agreements. See the NOTICE file distributed with
0007: this work for additional information regarding copyright ownership.
0008: The ASF licenses this file to you under the Apache License, Version 2.0
0009: (the "License"); you may not use this file except in compliance with
0010: the License. You may obtain a copy of the License at
0011:
0012: http://www.apache.org/licenses/LICENSE-2.0
0013:
0014: Unless required by applicable law or agreed to in writing, software
0015: distributed under the License is distributed on an "AS IS" BASIS,
0016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017: See the License for the specific language governing permissions and
0018: limitations under the License.
0019:
0020: */
0021:
0022: package org.apache.derby.iapi.types;
0023:
0024: import org.apache.derby.iapi.services.io.ArrayInputStream;
0025:
0026: import org.apache.derby.iapi.services.sanity.SanityManager;
0027:
0028: import org.apache.derby.iapi.services.io.Storable;
0029: import org.apache.derby.iapi.services.io.StoredFormatIds;
0030:
0031: import org.apache.derby.iapi.error.StandardException;
0032:
0033: import org.apache.derby.iapi.types.DataValueDescriptor;
0034: import org.apache.derby.iapi.types.TypeId;
0035: import org.apache.derby.iapi.types.BooleanDataValue;
0036:
0037: import org.apache.derby.iapi.services.cache.ClassSize;
0038: import org.apache.derby.iapi.util.StringUtil;
0039:
0040: import java.io.ObjectOutput;
0041: import java.io.ObjectInput;
0042: import java.io.IOException;
0043:
0044: import java.sql.ResultSet;
0045: import java.sql.PreparedStatement;
0046: import java.sql.SQLException;
0047:
0048: /**
0049: * SQLBoolean satisfies the DataValueDescriptor
0050: * interfaces (i.e., DataType). It implements a boolean column,
0051: * e.g. for * storing a column value; it can be specified
0052: * when constructed to not allow nulls. Nullability cannot be changed
0053: * after construction, as it affects the storage size and mechanism.
0054: * <p>
0055: * Because DataType is a subtype of DataType,
0056: * SQLBoolean can play a role in either a DataType/Row
0057: * or a DataType/Row, interchangeably.
0058: * <p>
0059: * We assume the store has a flag for nullness of the value,
0060: * and simply return a 0-length array for the stored form
0061: * when the value is null.
0062: * <p>
0063: * PERFORMANCE: There are likely alot of performance improvements
0064: * possible for this implementation -- it new's Integer
0065: * more than it probably wants to.
0066: */
0067: public final class SQLBoolean extends DataType implements
0068: BooleanDataValue {
0069: /*
0070: * DataValueDescriptor interface
0071: * (mostly implemented in DataType)
0072: */
0073:
0074: /*
0075: * see if the integer value is null.
0076: */
0077: public boolean isNull() {
0078: return isnull;
0079: }
0080:
0081: public boolean getBoolean() {
0082: return value;
0083: }
0084:
0085: private static int makeInt(boolean b) {
0086: return (b ? 1 : 0);
0087: }
0088:
0089: /**
0090: * @see DataValueDescriptor#getByte
0091: */
0092: public byte getByte() {
0093: return (byte) makeInt(value);
0094: }
0095:
0096: /**
0097: * @see DataValueDescriptor#getShort
0098: */
0099: public short getShort() {
0100: return (short) makeInt(value);
0101: }
0102:
0103: /**
0104: * @see DataValueDescriptor#getInt
0105: */
0106: public int getInt() {
0107: return makeInt(value);
0108: }
0109:
0110: /**
0111: * @see DataValueDescriptor#getLong
0112: */
0113: public long getLong() {
0114: return (long) makeInt(value);
0115: }
0116:
0117: /**
0118: * @see DataValueDescriptor#getFloat
0119: */
0120: public float getFloat() {
0121: return (float) makeInt(value);
0122: }
0123:
0124: /**
0125: * @see DataValueDescriptor#getDouble
0126: */
0127: public double getDouble() {
0128: return (double) makeInt(value);
0129: }
0130:
0131: /**
0132: * Implementation for BOOLEAN type. Convert to a BigDecimal using long
0133: */
0134: public int typeToBigDecimal() {
0135: return java.sql.Types.BIGINT;
0136: }
0137:
0138: public String getString() {
0139: if (isNull())
0140: return null;
0141: else if (value == true)
0142: return "true";
0143: else
0144: return "false";
0145: }
0146:
0147: public Object getObject() {
0148: if (isNull())
0149: return null;
0150: else
0151: return new Boolean(value);
0152: }
0153:
0154: public int getLength() {
0155: return BOOLEAN_LENGTH;
0156: }
0157:
0158: // this is for DataType's error generator
0159: public String getTypeName() {
0160: return TypeId.BOOLEAN_NAME;
0161: }
0162:
0163: /*
0164: * Storable interface, implies Externalizable, TypedFormat
0165: */
0166:
0167: /**
0168: Return my format identifier.
0169:
0170: @see org.apache.derby.iapi.services.io.TypedFormat#getTypeFormatId
0171: */
0172: public int getTypeFormatId() {
0173: return StoredFormatIds.SQL_BOOLEAN_ID;
0174: }
0175:
0176: public void writeExternal(ObjectOutput out) throws IOException {
0177:
0178: // never called when value is null
0179: if (SanityManager.DEBUG)
0180: SanityManager.ASSERT(!isNull());
0181:
0182: out.writeBoolean(value);
0183: }
0184:
0185: /** @see java.io.Externalizable#readExternal */
0186: public void readExternal(ObjectInput in) throws IOException {
0187:
0188: if (SanityManager.DEBUG)
0189: SanityManager
0190: .ASSERT(!immutable,
0191: "Attempt to set the value of an immutable SQLBoolean");
0192:
0193: value = in.readBoolean();
0194: isnull = false;
0195: }
0196:
0197: public void readExternalFromArray(ArrayInputStream in)
0198: throws IOException {
0199:
0200: if (SanityManager.DEBUG)
0201: SanityManager
0202: .ASSERT(!immutable,
0203: "Attempt to set the value of an immutable SQLBoolean");
0204:
0205: value = in.readBoolean();
0206: isnull = false;
0207: }
0208:
0209: /**
0210: * @see Storable#restoreToNull
0211: *
0212: */
0213: public void restoreToNull() {
0214: if (SanityManager.DEBUG)
0215: SanityManager
0216: .ASSERT(!immutable,
0217: "Attempt to set the value of an immutable SQLBoolean");
0218:
0219: value = false;
0220: isnull = true;
0221: }
0222:
0223: /*
0224: * Orderable interface
0225: */
0226:
0227: /**
0228: @exception StandardException thrown on error
0229: */
0230: public int compare(DataValueDescriptor other)
0231: throws StandardException {
0232: /* Use compare method from dominant type, negating result
0233: * to reflect flipping of sides.
0234: */
0235: if (typePrecedence() < other.typePrecedence()) {
0236: return -(other.compare(this ));
0237: }
0238:
0239: boolean this Null, otherNull;
0240: this Null = this .isNull();
0241: otherNull = other.isNull();
0242:
0243: /*
0244: * thisNull otherNull thisValue thatValue return
0245: * T T X X 0 (this == other)
0246: * F T X X 1 (this > other)
0247: * T F X X -1 (this < other)
0248: *
0249: * F F T T 0 (this == other)
0250: * F F T F 1 (this > other)
0251: * F F F T -1 (this < other)
0252: * F F F F 0 (this == other)
0253: */
0254: if (this Null || otherNull) {
0255: if (!this Null) // otherNull must be true
0256: return 1;
0257: if (!otherNull) // thisNull must be true
0258: return -1;
0259: return 0;
0260: }
0261:
0262: /* neither are null, get the value */
0263: boolean this Value;
0264: boolean otherValue = false;
0265: this Value = this .getBoolean();
0266:
0267: otherValue = other.getBoolean();
0268:
0269: if (this Value == otherValue)
0270: return 0;
0271: else if (this Value && !otherValue)
0272: return 1;
0273: else
0274: return -1;
0275: }
0276:
0277: /**
0278: @exception StandardException thrown on error
0279: */
0280: public boolean compare(int op, DataValueDescriptor other,
0281: boolean orderedNulls, boolean unknownRV)
0282: throws StandardException {
0283: if (!orderedNulls) // nulls are unordered
0284: {
0285: if (this .isNull() || other.isNull())
0286: return unknownRV;
0287: }
0288: /* Do the comparison */
0289: return super .compare(op, other, orderedNulls, unknownRV);
0290: }
0291:
0292: /*
0293: * DataValueDescriptor interface
0294: */
0295:
0296: /** @see DataValueDescriptor#getClone */
0297: public DataValueDescriptor getClone() {
0298: return new SQLBoolean(value, isnull);
0299: }
0300:
0301: /**
0302: * @see DataValueDescriptor#getNewNull
0303: */
0304: public DataValueDescriptor getNewNull() {
0305: return new SQLBoolean();
0306: }
0307:
0308: /**
0309: * @see DataValueDescriptor#setValueFromResultSet
0310: *
0311: * @exception SQLException Thrown on error
0312: */
0313: public void setValueFromResultSet(ResultSet resultSet,
0314: int colNumber, boolean isNullable) throws SQLException {
0315: value = resultSet.getBoolean(colNumber);
0316: isnull = (isNullable && resultSet.wasNull());
0317: }
0318:
0319: /**
0320: Set the value into a PreparedStatement.
0321:
0322: @exception SQLException Error setting value in PreparedStatement
0323: */
0324: public final void setInto(PreparedStatement ps, int position)
0325: throws SQLException {
0326:
0327: if (isNull()) {
0328: ps.setNull(position, java.sql.Types.BIT);
0329: return;
0330: }
0331:
0332: ps.setBoolean(position, value);
0333: }
0334:
0335: /*
0336: * class interface
0337: */
0338:
0339: /*
0340: * constructors
0341: */
0342:
0343: /* NOTE - other data types have both (type value) and (boolean nulls),
0344: * (value, nulls)
0345: * We can't do both (boolean value) and (boolean nulls) here,
0346: * so we'll skip over (boolean value) and have (Boolean value) so
0347: * that we can support (boolean nulls).
0348: */
0349:
0350: public SQLBoolean() {
0351: isnull = true;
0352: }
0353:
0354: public SQLBoolean(boolean val) {
0355: value = val;
0356: }
0357:
0358: public SQLBoolean(Boolean obj) {
0359: if (isnull = (obj == null))
0360: ;
0361: else
0362: value = obj.booleanValue();
0363: }
0364:
0365: /* This constructor gets used for the getClone() method */
0366: private SQLBoolean(boolean val, boolean isnull) {
0367: value = val;
0368: this .isnull = isnull;
0369: }
0370:
0371: /** @see BooleanDataValue#setValue */
0372: public void setValue(boolean theValue) {
0373: if (SanityManager.DEBUG)
0374: SanityManager
0375: .ASSERT(!immutable,
0376: "Attempt to set the value of an immutable SQLBoolean");
0377: value = theValue;
0378: isnull = false;
0379:
0380: }
0381:
0382: public void setValue(Boolean theValue) {
0383: if (SanityManager.DEBUG)
0384: SanityManager
0385: .ASSERT(!immutable,
0386: "Attempt to set the value of an immutable SQLBoolean");
0387: if (theValue == null) {
0388: value = false;
0389: isnull = true;
0390: } else {
0391: value = theValue.booleanValue();
0392: isnull = false;
0393: }
0394:
0395: }
0396:
0397: // REMIND: do we need this, or is long enough?
0398: public void setValue(byte theValue) {
0399: if (SanityManager.DEBUG)
0400: SanityManager
0401: .ASSERT(!immutable,
0402: "Attempt to set the value of an immutable SQLBoolean");
0403: value = theValue != 0;
0404: isnull = false;
0405:
0406: }
0407:
0408: // REMIND: do we need this, or is long enough?
0409: public void setValue(short theValue) {
0410: if (SanityManager.DEBUG)
0411: SanityManager
0412: .ASSERT(!immutable,
0413: "Attempt to set the value of an immutable SQLBoolean");
0414: value = theValue != 0;
0415: isnull = false;
0416:
0417: }
0418:
0419: // REMIND: do we need this, or is long enough?
0420: public void setValue(int theValue) {
0421: if (SanityManager.DEBUG)
0422: SanityManager
0423: .ASSERT(!immutable,
0424: "Attempt to set the value of an immutable SQLBoolean");
0425: value = theValue != 0;
0426: isnull = false;
0427:
0428: }
0429:
0430: public void setValue(long theValue) {
0431: if (SanityManager.DEBUG)
0432: SanityManager
0433: .ASSERT(!immutable,
0434: "Attempt to set the value of an immutable SQLBoolean");
0435: value = theValue != 0;
0436: isnull = false;
0437:
0438: }
0439:
0440: // REMIND: do we need this, or is double enough?
0441: public void setValue(float theValue) {
0442: if (SanityManager.DEBUG)
0443: SanityManager
0444: .ASSERT(!immutable,
0445: "Attempt to set the value of an immutable SQLBoolean");
0446: value = theValue != 0;
0447: isnull = false;
0448:
0449: }
0450:
0451: public void setValue(double theValue) {
0452: if (SanityManager.DEBUG)
0453: SanityManager
0454: .ASSERT(!immutable,
0455: "Attempt to set the value of an immutable SQLBoolean");
0456: value = theValue != 0;
0457: isnull = false;
0458:
0459: }
0460:
0461: public void setBigDecimal(Number bigDecimal)
0462: throws StandardException {
0463: if (SanityManager.DEBUG)
0464: SanityManager
0465: .ASSERT(!immutable,
0466: "Attempt to set the value of an immutable SQLBoolean");
0467: if (bigDecimal == null) {
0468: value = false;
0469: isnull = true;
0470: } else {
0471: DataValueDescriptor tempDecimal = NumberDataType.ZERO_DECIMAL
0472: .getNewNull();
0473: tempDecimal.setBigDecimal(bigDecimal);
0474: value = NumberDataType.ZERO_DECIMAL.compare(tempDecimal) != 0;
0475: isnull = false;
0476: }
0477:
0478: }
0479:
0480: /**
0481: * Set the value of this BooleanDataValue to the given byte array value
0482: *
0483: * @param theValue The value to set this BooleanDataValue to
0484: */
0485: public void setValue(byte[] theValue) {
0486: if (SanityManager.DEBUG)
0487: SanityManager
0488: .ASSERT(!immutable,
0489: "Attempt to set the value of an immutable SQLBoolean");
0490:
0491: if (theValue != null) {
0492: isnull = false;
0493: int length = theValue.length;
0494:
0495: /*
0496: ** Step through all bytes. As soon
0497: ** as we get one with something other
0498: ** than 0, then we know we have a 'true'
0499: */
0500: for (int i = 0; i < length; i++) {
0501: if (theValue[i] != 0) {
0502: value = true;
0503: return;
0504: }
0505: }
0506: } else {
0507: isnull = true;
0508: }
0509: value = false;
0510:
0511: }
0512:
0513: /**
0514: * Set the value of this BooleanDataValue to the given String.
0515: * String is trimmed and upcased. If resultant string is not
0516: * TRUE or FALSE, then an error is thrown.
0517: *
0518: * @param theValue The value to set this BooleanDataValue to
0519: *
0520: * @exception StandardException Thrown on error
0521: */
0522: public void setValue(String theValue) throws StandardException {
0523: if (SanityManager.DEBUG)
0524: SanityManager
0525: .ASSERT(!immutable,
0526: "Attempt to set the value of an immutable SQLBoolean");
0527: if (theValue == null) {
0528: value = false;
0529: isnull = true;
0530: } else {
0531: /*
0532: ** Note: cannot use getBoolean(String) here because
0533: ** it doesn't trim, and doesn't throw exceptions.
0534: */
0535: String cleanedValue = StringUtil.SQLToUpperCase(theValue
0536: .trim());
0537: if (cleanedValue.equals("TRUE")) {
0538: value = true;
0539: } else if (cleanedValue.equals("FALSE")) {
0540: value = false;
0541: } else {
0542: throw invalidFormat();
0543: }
0544: isnull = false;
0545: }
0546:
0547: }
0548:
0549: private void setValueCore(Number theValue) {
0550: if (SanityManager.DEBUG)
0551: SanityManager
0552: .ASSERT(!immutable,
0553: "Attempt to set the value of an immutable SQLBoolean");
0554:
0555: if (theValue == null) {
0556: isnull = true;
0557: value = false;
0558: } else {
0559: value = (theValue.intValue() != 0);
0560: isnull = false;
0561: }
0562: }
0563:
0564: /**
0565: * @see DataValueDescriptor#setValue
0566: */
0567: void setObject(Object theValue) {
0568: setValue((Boolean) theValue);
0569: }
0570:
0571: protected void setFrom(DataValueDescriptor theValue)
0572: throws StandardException {
0573:
0574: setValue(theValue.getBoolean());
0575: }
0576:
0577: /*
0578: ** SQL Operators
0579: */
0580:
0581: /**
0582: * The = operator as called from the language module, as opposed to
0583: * the storage module.
0584: *
0585: * @param left The value on the left side of the =
0586: * @param right The value on the right side of the =
0587: *
0588: * @return A SQL boolean value telling whether the two parameters are equal
0589: *
0590: * @exception StandardException Thrown on error
0591: */
0592:
0593: public BooleanDataValue equals(DataValueDescriptor left,
0594: DataValueDescriptor right) throws StandardException {
0595: return truthValue(left, right, left.getBoolean() == right
0596: .getBoolean());
0597: }
0598:
0599: /**
0600: * The <> operator as called from the language module, as opposed to
0601: * the storage module.
0602: *
0603: * @param left The value on the left side of the <>
0604: * @param right The value on the right side of the <>
0605: *
0606: * @return A SQL boolean value telling whether the two parameters are
0607: * not equal
0608: *
0609: * @exception StandardException Thrown on error
0610: */
0611:
0612: public BooleanDataValue notEquals(DataValueDescriptor left,
0613: DataValueDescriptor right) throws StandardException {
0614: return truthValue(left, right, left.getBoolean() != right
0615: .getBoolean());
0616: }
0617:
0618: /**
0619: * The < operator as called from the language module, as opposed to
0620: * the storage module.
0621: *
0622: * @param left The value on the left side of the <
0623: * @param right The value on the right side of the <
0624: *
0625: * @return A SQL boolean value telling whether the left operand is
0626: * less than the right operand
0627: *
0628: * @exception StandardException Thrown on error
0629: */
0630:
0631: public BooleanDataValue lessThan(DataValueDescriptor left,
0632: DataValueDescriptor right) throws StandardException {
0633: /* We must call getBoolean() on both sides in order
0634: * to catch any invalid casts.
0635: */
0636: boolean leftBoolean = left.getBoolean();
0637: boolean rightBoolean = right.getBoolean();
0638: /* By convention, false is less than true */
0639: return truthValue(left, right, leftBoolean == false
0640: && rightBoolean == true);
0641: }
0642:
0643: /**
0644: * The > operator as called from the language module, as opposed to
0645: * the storage module.
0646: *
0647: * @param left The value on the left side of the >
0648: * @param right The value on the right side of the >
0649: *
0650: * @return A SQL boolean value telling whether the left operand is
0651: * greater than the right operand
0652: *
0653: * @exception StandardException Thrown on error
0654: */
0655:
0656: public BooleanDataValue greaterThan(DataValueDescriptor left,
0657: DataValueDescriptor right) throws StandardException {
0658: /* We must call getBoolean() on both sides in order
0659: * to catch any invalid casts.
0660: */
0661: boolean leftBoolean = left.getBoolean();
0662: boolean rightBoolean = right.getBoolean();
0663: /* By convention, true is greater than false */
0664: return truthValue(left, right, leftBoolean == true
0665: && rightBoolean == false);
0666: }
0667:
0668: /**
0669: * The <= operator as called from the language module, as opposed to
0670: * the storage module.
0671: *
0672: * @param left The value on the left side of the <=
0673: * @param right The value on the right side of the <=
0674: *
0675: * @return A SQL boolean value telling whether the left operand is
0676: * less than or equal to the right operand
0677: *
0678: * @exception StandardException Thrown on error
0679: */
0680:
0681: public BooleanDataValue lessOrEquals(DataValueDescriptor left,
0682: DataValueDescriptor right) throws StandardException {
0683: /* We must call getBoolean() on both sides in order
0684: * to catch any invalid casts.
0685: */
0686: boolean leftBoolean = left.getBoolean();
0687: boolean rightBoolean = right.getBoolean();
0688: /* By convention, false is less than true */
0689: return truthValue(left, right, leftBoolean == false
0690: || rightBoolean == true);
0691: }
0692:
0693: /**
0694: * The >= operator as called from the language module, as opposed to
0695: * the storage module.
0696: *
0697: * @param left The value on the left side of the >=
0698: * @param right The value on the right side of the >=
0699: *
0700: * @return A SQL boolean value telling whether the left operand is
0701: * greater than or equal to the right operand
0702: *
0703: * @exception StandardException Thrown on error
0704: */
0705:
0706: public BooleanDataValue greaterOrEquals(DataValueDescriptor left,
0707: DataValueDescriptor right) throws StandardException {
0708: /* We must call getBoolean() on both sides in order
0709: * to catch any invalid casts.
0710: */
0711: boolean leftBoolean = left.getBoolean();
0712: boolean rightBoolean = right.getBoolean();
0713: /* By convention, true is greater than false */
0714: return truthValue(left, right, leftBoolean == true
0715: || rightBoolean == false);
0716: }
0717:
0718: /**
0719: * The AND operator. This implements SQL semantics for AND with unknown
0720: * truth values - consult any standard SQL reference for an explanation.
0721: *
0722: * @param otherValue The other boolean to AND with this one
0723: *
0724: * @return this AND otherValue
0725: *
0726: */
0727:
0728: public BooleanDataValue and(BooleanDataValue otherValue) {
0729: /*
0730: ** Catch those cases where standard SQL null semantics don't work.
0731: */
0732: if (this .equals(false) || otherValue.equals(false)) {
0733: return BOOLEAN_FALSE;
0734: } else {
0735: return truthValue(this , otherValue, this .getBoolean()
0736: && otherValue.getBoolean());
0737: }
0738: }
0739:
0740: /**
0741: * The OR operator. This implements SQL semantics for OR with unknown
0742: * truth values - consult any standard SQL reference for an explanation.
0743: *
0744: * @param otherValue The other boolean to OR with this one
0745: *
0746: * @return this OR otherValue
0747: *
0748: */
0749:
0750: public BooleanDataValue or(BooleanDataValue otherValue) {
0751: /*
0752: ** Catch those cases where standard SQL null semantics don't work.
0753: */
0754: if (this .equals(true) || otherValue.equals(true)) {
0755: return BOOLEAN_TRUE;
0756: } else {
0757: return truthValue(this , otherValue, this .getBoolean()
0758: || otherValue.getBoolean());
0759: }
0760: }
0761:
0762: /**
0763: * The SQL IS operator - consult any standard SQL reference for an explanation.
0764: *
0765: * Implements the following truth table:
0766: *
0767: * otherValue
0768: * | TRUE | FALSE | UNKNOWN
0769: * this |----------------------------
0770: * |
0771: * TRUE | TRUE | FALSE | FALSE
0772: * FALSE | FALSE | TRUE | FALSE
0773: * UNKNOWN | FALSE | FALSE | TRUE
0774: *
0775: *
0776: * @param otherValue BooleanDataValue to compare to. May be TRUE, FALSE, or UNKNOWN.
0777: *
0778: * @return whether this IS otherValue
0779: *
0780: */
0781: public BooleanDataValue is(BooleanDataValue otherValue) {
0782: if (this .equals(true) && otherValue.equals(true)) {
0783: return BOOLEAN_TRUE;
0784: }
0785:
0786: if (this .equals(false) && otherValue.equals(false)) {
0787: return BOOLEAN_TRUE;
0788: }
0789:
0790: if (this .isNull() && otherValue.isNull()) {
0791: return BOOLEAN_TRUE;
0792: }
0793:
0794: return BOOLEAN_FALSE;
0795: }
0796:
0797: /**
0798: * Implements NOT IS. This reverses the sense of the is() call.
0799: *
0800: *
0801: * @param otherValue BooleanDataValue to compare to. May be TRUE, FALSE, or UNKNOWN.
0802: *
0803: * @return NOT( this IS otherValue )
0804: *
0805: */
0806: public BooleanDataValue isNot(BooleanDataValue otherValue) {
0807: BooleanDataValue isValue = is(otherValue);
0808:
0809: if (isValue.equals(true)) {
0810: return BOOLEAN_FALSE;
0811: } else {
0812: return BOOLEAN_TRUE;
0813: }
0814: }
0815:
0816: /**
0817: * Throw an exception with the given SQLState if this BooleanDataValue
0818: * is false. This method is useful for evaluating constraints.
0819: *
0820: * @param sqlState The SQLState of the exception to throw if
0821: * this SQLBoolean is false.
0822: * @param tableName The name of the table to include in the exception
0823: * message.
0824: * @param constraintName The name of the failed constraint to include
0825: * in the exception message.
0826: *
0827: * @return this
0828: *
0829: * @exception StandardException Thrown if this BooleanDataValue
0830: * is false.
0831: */
0832: public BooleanDataValue throwExceptionIfFalse(String sqlState,
0833: String tableName, String constraintName)
0834: throws StandardException {
0835: if ((!isNull()) && (value == false)) {
0836: throw StandardException.newException(sqlState, tableName,
0837: constraintName);
0838: }
0839:
0840: return this ;
0841: }
0842:
0843: /*
0844: * DataValueDescriptor interface
0845: */
0846:
0847: /** @see DataValueDescriptor#typePrecedence */
0848: public int typePrecedence() {
0849: return TypeId.BOOLEAN_PRECEDENCE;
0850: }
0851:
0852: /*
0853: ** Support functions
0854: */
0855:
0856: /**
0857: * Return the SQL truth value for a comparison.
0858: *
0859: * This method first looks at the operands - if either is null, it
0860: * returns the unknown truth value. This implements "normal" SQL
0861: * null semantics, where if any operand is null, the result is null.
0862: * Note that there are cases where these semantics are incorrect -
0863: * for example, NULL AND FALSE is supposed to be FALSE, not NULL
0864: * (the NULL truth value is the same as the UNKNOWN truth value).
0865: *
0866: * If neither operand is null, it returns a static final variable
0867: * containing the SQLBoolean truth value. It returns different values
0868: * depending on whether the truth value is supposed to be nullable.
0869: *
0870: * This method always returns a pre-allocated static final SQLBoolean.
0871: * This is practical because there are so few possible return values.
0872: * Using pre-allocated values allows us to avoid constructing new
0873: * SQLBoolean values during execution.
0874: *
0875: * @param leftOperand The left operand of the binary comparison
0876: * @param rightOperand The right operand of the binary comparison
0877: * @param truth The truth value of the comparison
0878: *
0879: * @return A SQLBoolean containing the desired truth value.
0880: */
0881:
0882: public static SQLBoolean truthValue(
0883: DataValueDescriptor leftOperand,
0884: DataValueDescriptor rightOperand, boolean truth) {
0885: /* Return UNKNOWN if either operand is null */
0886: if (leftOperand.isNull() || rightOperand.isNull()) {
0887: return unknownTruthValue();
0888: }
0889:
0890: /* Return the appropriate SQLBoolean for the given truth value */
0891: if (truth == true) {
0892: return BOOLEAN_TRUE;
0893: } else {
0894: return BOOLEAN_FALSE;
0895: }
0896: }
0897:
0898: /**
0899: * same as above, but takes a Boolean, if it is null, unknownTruthValue is returned
0900: */
0901: public static SQLBoolean truthValue(
0902: DataValueDescriptor leftOperand,
0903: DataValueDescriptor rightOperand, Boolean truth) {
0904: /* Return UNKNOWN if either operand is null */
0905: if (leftOperand.isNull() || rightOperand.isNull()
0906: || truth == null) {
0907: return unknownTruthValue();
0908: }
0909:
0910: /* Return the appropriate SQLBoolean for the given truth value */
0911: if (truth == Boolean.TRUE) {
0912: return BOOLEAN_TRUE;
0913: } else {
0914: return BOOLEAN_FALSE;
0915: }
0916: }
0917:
0918: /**
0919: * Get a truth value.
0920: *
0921: * @param value The value of the SQLBoolean
0922: *
0923: * @return A SQLBoolean with the given truth value
0924: */
0925: public static SQLBoolean truthValue(boolean value) {
0926: /*
0927: ** Return the non-nullable versions of TRUE and FALSE, since they
0928: ** can never be null.
0929: */
0930: if (value == true)
0931: return BOOLEAN_TRUE;
0932: else
0933: return BOOLEAN_FALSE;
0934: }
0935:
0936: /**
0937: * Return an unknown truth value. Check to be sure the return value is
0938: * nullable.
0939: *
0940: * @return A SQLBoolean representing the UNKNOWN truth value
0941: */
0942: public static SQLBoolean unknownTruthValue() {
0943: return UNKNOWN;
0944: }
0945:
0946: /**
0947: * Return a false truth value.
0948: *
0949: *
0950: * @return A SQLBoolean representing the FALSE truth value
0951: */
0952: public static SQLBoolean falseTruthValue() {
0953: return BOOLEAN_FALSE;
0954: }
0955:
0956: /**
0957: * Return a true truth value.
0958: *
0959: *
0960: * @return A SQLBoolean representing the TRUE truth value
0961: */
0962: public static SQLBoolean trueTruthValue() {
0963: return BOOLEAN_TRUE;
0964: }
0965:
0966: /**
0967: * Determine whether this SQLBoolean contains the given boolean value.
0968: *
0969: * This method is used by generated code to determine when to do
0970: * short-circuiting for an AND or OR.
0971: *
0972: * @param val The value to look for
0973: *
0974: * @return true if the given value equals the value in this SQLBoolean,
0975: * false if not
0976: */
0977:
0978: public boolean equals(boolean val) {
0979: if (isNull())
0980: return false;
0981: else
0982: return value == val;
0983: }
0984:
0985: /**
0986: * Return an immutable BooleanDataValue with the same value as this.
0987: * @return An immutable BooleanDataValue with the same value as this.
0988: */
0989: public BooleanDataValue getImmutable() {
0990: if (isNull())
0991: return SQLBoolean.UNKNOWN;
0992:
0993: return value ? SQLBoolean.BOOLEAN_TRUE
0994: : SQLBoolean.BOOLEAN_FALSE;
0995: }
0996:
0997: /*
0998: * String display of value
0999: */
1000:
1001: public String toString() {
1002: if (isNull())
1003: return "NULL";
1004: else if (value == true)
1005: return "true";
1006: else
1007: return "false";
1008: }
1009:
1010: /*
1011: * Hash code
1012: */
1013: public int hashCode() {
1014: if (isNull()) {
1015: return -1;
1016: }
1017:
1018: return (value) ? 1 : 0;
1019: }
1020:
1021: /*
1022: * useful constants...
1023: */
1024: static final int BOOLEAN_LENGTH = 1; // must match the number of bytes written by DataOutput.writeBoolean()
1025:
1026: private static final SQLBoolean BOOLEAN_TRUE = new SQLBoolean(true);
1027: private static final SQLBoolean BOOLEAN_FALSE = new SQLBoolean(
1028: false);
1029: static final SQLBoolean UNKNOWN = new SQLBoolean();
1030:
1031: /* Static initialization block */
1032: static {
1033: /* Mark all the static SQLBooleans as immutable */
1034: BOOLEAN_TRUE.immutable = true;
1035: BOOLEAN_FALSE.immutable = true;
1036: UNKNOWN.immutable = true;
1037: }
1038:
1039: private static final int BASE_MEMORY_USAGE = ClassSize
1040: .estimateBaseFromCatalog(SQLBoolean.class);
1041:
1042: public int estimateMemoryUsage() {
1043: return BASE_MEMORY_USAGE;
1044: }
1045:
1046: /*
1047: * object state
1048: */
1049: private boolean value;
1050: private boolean isnull;
1051: private boolean immutable;
1052: }
|