KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > iapi > types > SQLLongint


1 /*
2
3    Derby - Class org.apache.derby.iapi.types.SQLLongint
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.iapi.types;
23
24 import org.apache.derby.iapi.services.io.ArrayInputStream;
25
26 import org.apache.derby.iapi.types.DataValueDescriptor;
27 import org.apache.derby.iapi.types.TypeId;
28 import org.apache.derby.iapi.types.NumberDataValue;
29 import org.apache.derby.iapi.types.BooleanDataValue;
30 import org.apache.derby.iapi.reference.SQLState;
31
32 import org.apache.derby.iapi.services.io.StoredFormatIds;
33 import org.apache.derby.iapi.services.io.Storable;
34
35 import org.apache.derby.iapi.error.StandardException;
36 import org.apache.derby.iapi.services.sanity.SanityManager;
37
38 import org.apache.derby.iapi.services.cache.ClassSize;
39
40 import org.apache.derby.iapi.types.NumberDataType;
41 import org.apache.derby.iapi.types.SQLBoolean;
42
43 import java.io.ObjectOutput JavaDoc;
44 import java.io.ObjectInput JavaDoc;
45 import java.io.IOException JavaDoc;
46
47 import java.sql.ResultSet JavaDoc;
48 import java.sql.PreparedStatement JavaDoc;
49 import java.sql.SQLException JavaDoc;
50
51 /**
52  * SQLLongint satisfies the DataValueDescriptor
53  * interfaces (i.e., OrderableDataType). It implements a bigint column,
54  * e.g. for * storing a column value; it can be specified
55  * when constructed to not allow nulls. Nullability cannot be changed
56  * after construction, as it affects the storage size and mechanism.
57  * <p>
58  * Because OrderableDataType is a subtype of DataType,
59  * SQLLongint can play a role in either a DataType/Row
60  * or a OrderableDataType/Row, interchangeably.
61  * <p>
62  * We assume the store has a flag for nullness of the value,
63  * and simply return a 0-length array for the stored form
64  * when the value is null.
65  * <p>
66  * PERFORMANCE: There are likely alot of performance improvements
67  * possible for this implementation -- it new's Long
68  * more than it probably wants to.
69  */

70 public final class SQLLongint
71     extends NumberDataType
72 {
73     /*
74      * DataValueDescriptor interface
75      * (mostly implemented in DataType)
76      */

77
78
79     // JDBC is lax in what it permits and what it
80
// returns, so we are similarly lax
81
// @see DataValueDescriptor
82
/**
83      * @exception StandardException thrown on failure to convert
84      */

85     public int getInt() throws StandardException
86     {
87         /* This value is bogus if the SQLLongint is null */
88
89         if (value > Integer.MAX_VALUE || value < Integer.MIN_VALUE)
90             throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, "INTEGER");
91         return (int) value;
92     }
93
94     /**
95      * @exception StandardException thrown on failure to convert
96      */

97     public byte getByte() throws StandardException
98     {
99         if (value > Byte.MAX_VALUE || value < Byte.MIN_VALUE)
100             throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, "TINYINT");
101         return (byte) value;
102     }
103
104     /**
105      * @exception StandardException thrown on failure to convert
106      */

107     public short getShort() throws StandardException
108     {
109         if (value > Short.MAX_VALUE || value < Short.MIN_VALUE)
110             throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, "SMALLINT");
111         return (short) value;
112     }
113
114     public long getLong()
115     {
116         return value;
117     }
118
119     public float getFloat()
120     {
121         return (float) value;
122     }
123
124     public double getDouble()
125     {
126         return (double) value;
127     }
128
129     // for lack of a specification: 0 or null is false,
130
// all else is true
131
public boolean getBoolean()
132     {
133         return (value != 0);
134     }
135
136     public String JavaDoc getString()
137     {
138         if (isNull())
139             return null;
140         else
141             return Long.toString(value);
142     }
143
144     public Object JavaDoc getObject()
145     {
146         if (isNull())
147             return null;
148         else
149             return new Long JavaDoc(value);
150     }
151
152     public int getLength()
153     {
154         return TypeId.LONGINT_MAXWIDTH;
155     }
156
157     // this is for DataType's error generator
158
public String JavaDoc getTypeName()
159     {
160         return TypeId.LONGINT_NAME;
161     }
162
163     /*
164      * Storable interface, implies Externalizable, TypedFormat
165      */

166
167
168     /**
169         Return my format identifier.
170
171         @see org.apache.derby.iapi.services.io.TypedFormat#getTypeFormatId
172     */

173     public int getTypeFormatId() {
174         return StoredFormatIds.SQL_LONGINT_ID;
175     }
176
177     /*
178      * see if the integer value is null.
179      */

180     /** @see Storable#isNull */
181     public boolean isNull()
182     {
183         return isnull;
184     }
185
186     public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc {
187
188         // never called when value is null
189
if (SanityManager.DEBUG)
190             SanityManager.ASSERT(! isNull());
191
192         out.writeLong(value);
193     }
194
195     /** @see java.io.Externalizable#readExternal */
196     public void readExternal(ObjectInput JavaDoc in) throws IOException JavaDoc {
197
198         value = in.readLong();
199         isnull = false;
200     }
201     public void readExternalFromArray(ArrayInputStream in) throws IOException JavaDoc {
202
203         value = in.readLong();
204         isnull = false;
205     }
206
207     /**
208      * @see Storable#restoreToNull
209      *
210      */

211
212     public void restoreToNull()
213     {
214         value = 0;
215         isnull = true;
216     }
217
218     /** @exception StandardException Thrown on error */
219     protected int typeCompare(DataValueDescriptor arg) throws StandardException
220     {
221
222         /* neither are null, get the value */
223
224         long thisValue = this.getLong();
225
226         long otherValue = arg.getLong();
227
228         if (thisValue == otherValue)
229             return 0;
230         else if (thisValue > otherValue)
231             return 1;
232         else
233             return -1;
234     }
235
236     /*
237      * DataValueDescriptor interface
238      */

239
240     /** @see DataValueDescriptor#getClone */
241     public DataValueDescriptor getClone()
242     {
243         return new SQLLongint(value, isnull);
244     }
245
246     /**
247      * @see DataValueDescriptor#getNewNull
248      */

249     public DataValueDescriptor getNewNull()
250     {
251         return new SQLLongint();
252     }
253
254     /**
255      * @see DataValueDescriptor#setValueFromResultSet
256      *
257      * @exception SQLException Thrown on error
258      */

259     public void setValueFromResultSet(ResultSet JavaDoc resultSet, int colNumber,
260                                       boolean isNullable)
261         throws SQLException JavaDoc
262     {
263             if ((value = resultSet.getLong(colNumber)) == 0L)
264                 isnull = (isNullable && resultSet.wasNull());
265             else
266                 isnull = false;
267     }
268     /**
269         Set the value into a PreparedStatement.
270
271         @exception SQLException Error setting value in PreparedStatement
272     */

273     public final void setInto(PreparedStatement JavaDoc ps, int position) throws SQLException JavaDoc {
274
275         if (isNull()) {
276             ps.setNull(position, java.sql.Types.BIGINT);
277             return;
278         }
279
280         ps.setLong(position, value);
281     }
282     /**
283         Set this value into a ResultSet for a subsequent ResultSet.insertRow
284         or ResultSet.updateRow. This method will only be called for non-null values.
285
286         @exception SQLException thrown by the ResultSet object
287     */

288     public final void setInto(ResultSet JavaDoc rs, int position) throws SQLException JavaDoc {
289         rs.updateLong(position, value);
290     }
291
292     /*
293      * class interface
294      */

295
296     /*
297      * constructors
298      */

299
300     /** no-arg constructor, required by Formattable */
301     // This constructor also gets used when we are
302
// allocating space for a long.
303
public SQLLongint()
304     {
305         isnull = true;
306     }
307
308     public SQLLongint(long val)
309     {
310         value = val;
311     }
312
313     /* This constructor gets used for the getClone() method */
314     private SQLLongint(long val, boolean isnull)
315     {
316         value = val;
317         this.isnull = isnull;
318     }
319     public SQLLongint(Long JavaDoc obj) {
320         if (isnull = (obj == null))
321             ;
322         else
323             value = obj.longValue();
324     }
325
326     /**
327         @exception StandardException thrown if string not accepted
328      */

329     public void setValue(String JavaDoc theValue)
330         throws StandardException
331     {
332         if (theValue == null)
333         {
334             value = 0;
335             isnull = true;
336         }
337         else
338         {
339             try {
340                 value = Long.valueOf(theValue.trim()).longValue();
341             } catch (NumberFormatException JavaDoc nfe) {
342                 throw invalidFormat();
343             }
344             isnull = false;
345         }
346     }
347
348     /**
349      * @see NumberDataValue#setValue
350      *
351      * @exception StandardException Thrown on error
352      */

353     public final void setValue(Number JavaDoc theValue)
354     {
355         if (objectNull(theValue))
356             return;
357         
358         if (SanityManager.ASSERT)
359         {
360             if (!(theValue instanceof java.lang.Long JavaDoc))
361                 SanityManager.THROWASSERT("SQLLongint.setValue(Number) passed a " + theValue.getClass());
362         }
363         
364         setValue(theValue.longValue());
365     }
366
367     public void setValue(long theValue)
368     {
369         value = theValue;
370         isnull = false;
371     }
372
373     public void setValue(int theValue)
374     {
375         value = theValue;
376         isnull = false;
377     }
378
379     /**
380      * @see NumberDataValue#setValue
381      *
382      * @exception StandardException Thrown on error
383      */

384     public void setValue(float theValue) throws StandardException
385     {
386         theValue = NumberDataType.normalizeREAL(theValue);
387
388         if (theValue > Long.MAX_VALUE
389             || theValue < Long.MIN_VALUE)
390             throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, "BIGINT");
391
392         float floorValue = (float)Math.floor(theValue);
393
394         value = (long)floorValue;
395         isnull = false;
396     }
397
398     /**
399      * @see NumberDataValue#setValue
400      *
401      * @exception StandardException Thrown on error
402      */

403     public void setValue(double theValue) throws StandardException
404     {
405         theValue = NumberDataType.normalizeDOUBLE(theValue);
406
407         if (theValue > Long.MAX_VALUE
408             || theValue < Long.MIN_VALUE)
409             throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, "BIGINT");
410
411         double floorValue = Math.floor(theValue);
412
413         value = (long)floorValue;
414         isnull = false;
415
416     }
417
418     /**
419      * @see NumberDataValue#setValue
420      *
421      */

422     public void setValue(boolean theValue)
423     {
424         value = theValue?1:0;
425         isnull = false;
426
427     }
428
429     /**
430      * Set the value from a correctly typed Long object.
431      * @throws StandardException
432      */

433     void setObject(Object JavaDoc theValue)
434     {
435         setValue(((Long JavaDoc) theValue).longValue());
436     }
437     
438     protected void setFrom(DataValueDescriptor theValue) throws StandardException {
439
440         setValue(theValue.getLong());
441     }
442
443     /*
444      * DataValueDescriptor interface
445      */

446
447     /** @see DataValueDescriptor#typePrecedence */
448     public int typePrecedence()
449     {
450         return TypeId.LONGINT_PRECEDENCE;
451     }
452
453     /*
454     ** SQL Operators
455     */

456
457     /**
458      * The = operator as called from the language module, as opposed to
459      * the storage module.
460      *
461      * @param left The value on the left side of the =
462      * @param right The value on the right side of the =
463      *
464      * @return A SQL boolean value telling whether the two parameters are equal
465      *
466      * @exception StandardException Thrown on error
467      */

468
469     public BooleanDataValue equals(DataValueDescriptor left,
470                             DataValueDescriptor right)
471             throws StandardException
472     {
473         return SQLBoolean.truthValue(left,
474                                      right,
475                                      left.getLong() == right.getLong());
476     }
477
478     /**
479      * The <> operator as called from the language module, as opposed to
480      * the storage module.
481      *
482      * @param left The value on the left side of the <>
483      * @param right The value on the right side of the <>
484      *
485      * @return A SQL boolean value telling whether the two parameters
486      * are not equal
487      *
488      * @exception StandardException Thrown on error
489      */

490
491     public BooleanDataValue notEquals(DataValueDescriptor left,
492                             DataValueDescriptor right)
493             throws StandardException
494     {
495         return SQLBoolean.truthValue(left,
496                                      right,
497                                      left.getLong() != right.getLong());
498     }
499
500     /**
501      * The < operator as called from the language module, as opposed to
502      * the storage module.
503      *
504      * @param left The value on the left side of the <
505      * @param right The value on the right side of the <
506      *
507      * @return A SQL boolean value telling whether the first operand is less
508      * than the second operand
509      *
510      * @exception StandardException Thrown on error
511      */

512
513     public BooleanDataValue lessThan(DataValueDescriptor left,
514                             DataValueDescriptor right)
515             throws StandardException
516     {
517         return SQLBoolean.truthValue(left,
518                                      right,
519                                      left.getLong() < right.getLong());
520     }
521
522     /**
523      * The > operator as called from the language module, as opposed to
524      * the storage module.
525      *
526      * @param left The value on the left side of the >
527      * @param right The value on the right side of the >
528      *
529      * @return A SQL boolean value telling whether the first operand is greater
530      * than the second operand
531      *
532      * @exception StandardException Thrown on error
533      */

534
535     public BooleanDataValue greaterThan(DataValueDescriptor left,
536                             DataValueDescriptor right)
537             throws StandardException
538     {
539         return SQLBoolean.truthValue(left,
540                                      right,
541                                      left.getLong() > right.getLong());
542     }
543
544     /**
545      * The <= operator as called from the language module, as opposed to
546      * the storage module.
547      *
548      * @param left The value on the left side of the <=
549      * @param right The value on the right side of the <=
550      *
551      * @return A SQL boolean value telling whether the first operand is less
552      * than or equal to the second operand
553      *
554      * @exception StandardException Thrown on error
555      */

556
557     public BooleanDataValue lessOrEquals(DataValueDescriptor left,
558                             DataValueDescriptor right)
559             throws StandardException
560     {
561         return SQLBoolean.truthValue(left,
562                                      right,
563                                      left.getLong() <= right.getLong());
564     }
565
566     /**
567      * The >= operator as called from the language module, as opposed to
568      * the storage module.
569      *
570      * @param left The value on the left side of the >=
571      * @param right The value on the right side of the >=
572      *
573      * @return A SQL boolean value telling whether the first operand is greater
574      * than or equal to the second operand
575      *
576      * @exception StandardException Thrown on error
577      */

578
579     public BooleanDataValue greaterOrEquals(DataValueDescriptor left,
580                             DataValueDescriptor right)
581             throws StandardException
582     {
583         return SQLBoolean.truthValue(left,
584                                      right,
585                                      left.getLong() >= right.getLong());
586     }
587
588     /**
589      * This method implements the + operator for "bigint + bigint".
590      *
591      * @param addend1 One of the addends
592      * @param addend2 The other addend
593      * @param result The result of a previous call to this method, null
594      * if not called yet
595      *
596      * @return A SQLLongint containing the result of the addition
597      *
598      * @exception StandardException Thrown on error
599      */

600
601     public NumberDataValue plus(NumberDataValue addend1,
602                             NumberDataValue addend2,
603                             NumberDataValue result)
604                 throws StandardException
605     {
606         if (result == null)
607         {
608             result = new SQLLongint();
609         }
610
611         if (addend1.isNull() || addend2.isNull())
612         {
613             result.setToNull();
614             return result;
615         }
616         long addend1Long = addend1.getLong();
617         long addend2Long = addend2.getLong();
618
619         long resultValue = addend1Long + addend2Long;
620
621         /*
622         ** Java does not check for overflow with integral types. We have to
623         ** check the result ourselves.
624         **
625         ** Overflow is possible only if the two addends have the same sign.
626         ** Do they? (This method of checking is approved by "The Java
627         ** Programming Language" by Arnold and Gosling.)
628         */

629         if ((addend1Long < 0) == (addend2Long < 0))
630         {
631             /*
632             ** Addends have the same sign. The result should have the same
633             ** sign as the addends. If not, an overflow has occurred.
634             */

635             if ((addend1Long < 0) != (resultValue < 0))
636             {
637                 throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, "BIGINT");
638             }
639         }
640         result.setValue(resultValue);
641
642         return result;
643     }
644
645     /**
646      * This method implements the - operator for "bigint - bigint".
647      *
648      * @param left The value to be subtracted from
649      * @param right The value to be subtracted
650      * @param result The result of a previous call to this method, null
651      * if not called yet
652      *
653      * @return A SQLLongint containing the result of the subtraction
654      *
655      * @exception StandardException Thrown on error
656      */

657
658     public NumberDataValue minus(NumberDataValue left,
659                             NumberDataValue right,
660                             NumberDataValue result)
661                 throws StandardException
662     {
663         if (result == null)
664         {
665             result = new SQLLongint();
666         }
667
668         if (left.isNull() || right.isNull())
669         {
670             result.setToNull();
671             return result;
672         }
673
674         long diff = left.getLong() - right.getLong();
675
676         /*
677         ** Java does not check for overflow with integral types. We have to
678         ** check the result ourselves.
679         **
680         ** Overflow is possible only if the left and the right side have opposite signs.
681         ** Do they? (This method of checking is approved by "The Java
682         ** Programming Language" by Arnold and Gosling.)
683         */

684         if ((left.getLong() < 0) != (right.getLong() < 0))
685         {
686             /*
687             ** Left and right have opposite signs. The result should have the same
688             ** sign as the left (this). If not, an overflow has occurred.
689             */

690             if ((left.getLong() < 0) != (diff < 0))
691             {
692                 throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, "BIGINT");
693             }
694         }
695
696         result.setValue(diff);
697         return result;
698     }
699
700     /**
701      * This method implements the * operator for "bigint * bigint".
702      *
703      * @param left The first value to be multiplied
704      * @param right The second value to be multiplied
705      * @param result The result of a previous call to this method, null
706      * if not called yet
707      *
708      * @return A SQLLongint containing the result of the multiplication
709      *
710      * @exception StandardException Thrown on error
711      */

712
713     public NumberDataValue times(NumberDataValue left,
714                             NumberDataValue right,
715                             NumberDataValue result)
716                 throws StandardException
717     {
718         long tempResult;
719
720         if (result == null)
721         {
722             result = new SQLLongint();
723         }
724
725         if (left.isNull() || right.isNull())
726         {
727             result.setToNull();
728             return result;
729         }
730
731         /*
732         ** Java does not check for overflow with integral types. We have to
733         ** check the result ourselves.
734         **
735         ** We can't use sign checking tricks like we do for '+' and '-' since
736         ** the product of 2 integers can wrap around multiple times. So, we
737         ** apply the principle that a * b = c => a = c / b. If b != 0 and
738         ** a != c / b, then overflow occurred.
739         */

740         tempResult = left.getLong() * right.getLong();
741         if ((right.getLong() != 0) && (left.getLong() != tempResult / right.getLong()))
742         {
743             throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, "BIGINT");
744         }
745
746         result.setValue(tempResult);
747         return result;
748     }
749
750     /**
751      * This method implements the / operator for "bigint / bigint".
752      *
753      * @param dividend The numerator
754      * @param divisor The denominator
755      * @param result The result of a previous call to this method, null
756      * if not called yet
757      *
758      * @return A SQLLongint containing the result of the division
759      *
760      * @exception StandardException Thrown on error
761      */

762
763     public NumberDataValue divide(NumberDataValue dividend,
764                              NumberDataValue divisor,
765                              NumberDataValue result)
766                 throws StandardException
767     {
768         long longDivisor;
769
770         if (result == null)
771         {
772             result = new SQLLongint();
773         }
774
775         if (dividend.isNull() || divisor.isNull())
776         {
777             result.setToNull();
778             return result;
779         }
780
781         /* Catch divide by 0 */
782         longDivisor = divisor.getLong();
783         if (longDivisor == 0)
784         {
785             throw StandardException.newException(SQLState.LANG_DIVIDE_BY_ZERO);
786         }
787
788         result.setValue(dividend.getLong() / longDivisor);
789         return result;
790     }
791     /**
792         mod(bigint, bigint)
793     */

794     public NumberDataValue mod(NumberDataValue dividend,
795                              NumberDataValue divisor,
796                              NumberDataValue result)
797                 throws StandardException
798     {
799         if (result == null)
800         {
801             result = new SQLLongint();
802         }
803
804         if (dividend.isNull() || divisor.isNull())
805         {
806             result.setToNull();
807             return result;
808         }
809
810         /* Catch divide by 0 */
811         long longDivisor = divisor.getLong();
812         if (longDivisor == 0)
813         {
814             throw StandardException.newException(SQLState.LANG_DIVIDE_BY_ZERO);
815         }
816
817         result.setValue(dividend.getLong() % longDivisor);
818         return result;
819     }
820     /**
821      * This method implements the unary minus operator for bigint.
822      *
823      * @param result The result of a previous call to this method, null
824      * if not called yet
825      *
826      * @return A SQLLongint containing the result of the negation
827      *
828      * @exception StandardException Thrown on error
829      */

830
831     public NumberDataValue minus(NumberDataValue result)
832                                     throws StandardException
833     {
834         long operandValue;
835
836         if (result == null)
837         {
838             result = new SQLLongint();
839         }
840
841         if (this.isNull())
842         {
843             result.setToNull();
844             return result;
845         }
846
847         operandValue = this.getLong();
848
849         /*
850         ** In two's complement arithmetic, the minimum value for a number
851         ** can't be negated, since there is no representation for its
852         ** positive value.
853         */

854         if (operandValue == Long.MIN_VALUE)
855         {
856             throw StandardException.newException(SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, "BIGINT");
857         }
858
859         result.setValue(-operandValue);
860         return result;
861     }
862
863     /**
864      * This method implements the isNegative method.
865      *
866      * @return A boolean. if this.value is negative, return true.
867      *
868      * @exception StandException Thrown on error
869      */

870     
871     protected boolean isNegative()
872     {
873         return !isNull() && value < 0L;
874     }
875
876     /*
877      * String display of value
878      */

879
880     public String JavaDoc toString()
881     {
882         if (isNull())
883             return "NULL";
884         else
885             return Long.toString(value);
886     }
887
888
889     /*
890      * Hash code
891      */

892     public int hashCode()
893     {
894         return (int) (value ^ (value >> 32));
895     }
896
897     private static final int BASE_MEMORY_USAGE = ClassSize.estimateBaseFromCatalog( SQLLongint.class);
898
899     public int estimateMemoryUsage()
900     {
901         return BASE_MEMORY_USAGE;
902     }
903
904     /*
905      * object state
906      */

907     private long value;
908     private boolean isnull;
909 }
910
Popular Tags