Class SystemTypeOfDescription
SYSTEM$TYPEOF answers: a DECLARED type name and a physical storage tag, and the two come
from different places — which is the whole point of this class.
SYSTEM$TYPEOF(<NUMBER(10,2) holding 1.00>) NUMBER(10,2)[SB1] SYSTEM$TYPEOF(<NUMBER(10,2) holding 1000.00>) NUMBER(10,2)[SB4] SYSTEM$TYPEOF(<VARCHAR(5)>) VARCHAR(5)[LOB] SYSTEM$TYPEOF(UPPER(<VARCHAR(5)>)) VARCHAR(15)[LOB]
★ THE NAME IS THE DECLARED TYPE, THE TAG IS THE INTERVAL OF VALUES THE PLAN CAN SEE. The two cells above share a declaration and differ only in what they hold, and their tags differ — so the tag cannot be derived from the type, and the name cannot be derived from the value. Frostlake used to read the VALUE for both, which is why a DATE answered TIMESTAMP_NTZ, a TIME and a BINARY answered VARCHAR, and any expression that happened to evaluate to NULL answered NULL however well typed.
★ THE TAG IS NOT THE ROW'S OWN VALUE EITHER. A column is tagged by its statistics — the widest
value anywhere in the table, on every row alike, whatever a WHERE keeps — and an expression by the
interval those statistics propagate through it (ValueRange): c + 1 widens the
interval by one, SUM(c) multiplies it by a trillion, MAX(c) narrows it to the greatest
value, COUNT(c) runs from zero to the row count. Where no interval can be known — a
ROUND, a LENGTH, a ROW_NUMBER, a cast from text — the tag is the declared width's own.
★ SBn IS THE SMALLEST SIGNED-INTEGER WIDTH THAT HOLDS THE UNSCALED VALUE — the rule itself lives
in SignedStorageWidth, shared with the out-of-representable-range refusal, which reads the same
tag off the value it could not store. Measured at the byte
boundaries rather than guessed: 127 is SB1 and 128 is SB2; 32767 is SB2 and 32768 is SB4; eleven
digits are SB8 and twenty-six are SB16. A NUMBER(38,0) holding only 1 is SB1, so the DECLARED
precision enters only when nothing narrower is known.
★ EVERY OTHER FAMILY'S TAG IS FIXED: BOOLEAN is SB1, DATE is SB4, TIME is SB8, all three
TIMESTAMP flavours are SB16, FLOAT is DOUBLE, and the variable-length families — VARCHAR, BINARY,
ARRAY, OBJECT, VARIANT — are LOB. So [LOB] is not the universal tag it looked like from the string
cells alone. The one exception is a boolean PREDICATE — a comparison, IS NULL, IN, LIKE, a predicate
function, or NOT / AND / OR over one — which the plan carries as ROWINDEX:
SYSTEM$TYPEOF(1 = 2) is BOOLEAN[ROWINDEX] where SYSTEM$TYPEOF(NOT TRUE) is
BOOLEAN[SB1].
★ A NULL VALUE KEEPS ITS DECLARED TYPE and takes the family's smallest tag, so
CAST(NULL AS NUMBER(10,2)) is NUMBER(10,2)[SB1]. Only an argument with no type at
all — a bare NULL — answers NULL[LOB].
-
Method Summary
Modifier and TypeMethodDescriptionstatic Stringof(DataType declared, String typeText, ValueRange range, boolean predicate) The description for an argument ofdeclaredtype whose values lie inrange.
-
Method Details
-
of
The description for an argument ofdeclaredtype whose values lie inrange.- Parameters:
declared- the argument's declared type, or null when it has nonetypeText- the declared type as live spells it, e.g.NUMBER(10,2)range- the interval the argument's values lie in, or null when none is known — that decides an exact numeric's tag and nothing elsepredicate- whether the argument is a predicate, which a BOOLEAN is tagged ROWINDEX for
-