I was doing some work[*] with Java's java.sql.Types class recently and took a look at the values for the constants defined in there. I was surprised to see that some of them were negative. (They are all int constants.)
I'll admit that there is no particular reason to always choose int constant values that are positive or follow some specific pattern. You could of course make them any unique value across the whole space of [Integer.MIN_VALUE, Integer.MAX_VALUE] and it wouldn't really make any difference to any client code, as long as the constant values remained ... constant.
But usually, one sees constants that follow one of two patterns:
- [0,] 1, 2, 3, 4, 5, ...
- [0x0,] 0x1, 0x2, 0x4, 0x8, ...
The one with the hex values is usually done for "flags" which is another name for a bitmask for packing lots of distinct values into a single int value.
Since it never makes any sense to have java.sql.Types constants stacking-up on each other like in a bitmask, I was expecting to see "simple" constant values.
But some of them are negative, and I see no rhyme or reason to which ones are positive/negative, even/odd, etc.
Here's the list of constants and their int values:
BIT = -7;
TINYINT = -6;
SMALLINT = 5;
INTEGER = 4;
BIGINT = -5;
FLOAT = 6;
REAL = 7;
DOUBLE = 8;
NUMERIC = 2;
DECIMAL = 3;
CHAR = 1;
VARCHAR = 12;
LONGVARCHAR = -1;
DATE = 91;
TIME = 92;
TIMESTAMP = 93;
BINARY = -2;
VARBINARY = -3;
LONGVARBINARY = -4;
NULL = 0;
OTHER = 1111;
JAVA_OBJECT = 2000;
DISTINCT = 2001;
STRUCT = 2002;
ARRAY = 2003;
BLOB = 2004;
CLOB = 2005;
REF = 2006;
DATALINK = 70;
BOOLEAN = 16;
ROWID = -8;
NCHAR = -15;
NVARCHAR = -9;
LONGNVARCHAR = -16;
NCLOB = 2011;
SQLXML = 2009;
REF_CURSOR = 2012;
TIME_WITH_TIMEZONE = 2013;
TIMESTAMP_WITH_TIMEZONE = 2014;
Sorting by order-in-file, alphabetically, etc. doesn't seem to reveal any pattern.
I'd be happy to entertain theories as to why these particular values were chosen, but it would be great if anyone had a pointer to any official justification of the values chosen for these constants.
[*] I was actually looking for all the CHAR-y codes, and was hoping that they were conveniently located within some predictable range for easy evaluation. Nope: you gotta use a bunch of individual == checks, or a switch with a bunch of different case statements. Oh, well.