deltatktbl (datetime.c:187-251), PostgreSQL's INTERVAL unit table.
A THIRD token table, beside datetime/tokens.clj's two. It is not a
superset of either and the three disagree on purpose:
m is MINUTE here and MONTH in datetktbl
mm is only in datetktbl
j is only in datetktbl
And the disagreement is REACHABLE, because DecodeInterval's
DTK_STRING arm tries DecodeUnits (this table) and then FALLS BACK
to DecodeSpecial (datetktbl) -- datetime.c:3659-3663. So '1 m'
is one minute and '1 mm' is also one minute, by two different
routes. Three tables, consulted in a fixed order.
A PLAIN MAP LOOKUP IS WRONG HERE, unlike for the two datetime
tables where datetime.tokens/prefix-safe? holds. datebsearch
compares with strncmp(key, token, TOKMAXLEN) and TOKMAXLEN is 10,
and FIVE keys in this table are exactly ten characters:
microsecon millennium millisecon timezone_h timezone_m
so each is a genuine PREFIX. Checked on the oracle:
'1 millenniumXYZ'::interval is 1000 years and
'2 microsecondsXX'::interval is 00:00:00.000002.
FOUR UNITS RESOLVE HERE AND ARE STILL ERRORS. DTK_QUARTER and the
three timezone units have no arm in DecodeInterval's switch
(datetime.c:3570-3650), so they reach its default and raise
22007. '1 qtr', '1 quarter', '1 timezone',
'1 timezone_hour' and '1 timezone_minute' are all invalid
intervals even though the lookup succeeds. A table-driven decoder
that trusts this table would accept every one of them.
GENERATED -- the extraction command is in the comment below.
`deltatktbl` (datetime.c:187-251), PostgreSQL's INTERVAL unit table. A THIRD token table, beside `datetime/tokens.clj`'s two. It is not a superset of either and the three disagree on purpose: `m` is MINUTE here and MONTH in `datetktbl` `mm` is only in `datetktbl` `j` is only in `datetktbl` And the disagreement is REACHABLE, because `DecodeInterval`'s DTK_STRING arm tries `DecodeUnits` (this table) and then FALLS BACK to `DecodeSpecial` (`datetktbl`) -- datetime.c:3659-3663. So `'1 m'` is one minute and `'1 mm'` is also one minute, by two different routes. Three tables, consulted in a fixed order. A PLAIN MAP LOOKUP IS WRONG HERE, unlike for the two datetime tables where `datetime.tokens/prefix-safe?` holds. `datebsearch` compares with `strncmp(key, token, TOKMAXLEN)` and TOKMAXLEN is 10, and FIVE keys in this table are exactly ten characters: microsecon millennium millisecon timezone_h timezone_m so each is a genuine PREFIX. Checked on the oracle: `'1 millenniumXYZ'::interval` is 1000 years and `'2 microsecondsXX'::interval` is 00:00:00.000002. FOUR UNITS RESOLVE HERE AND ARE STILL ERRORS. `DTK_QUARTER` and the three timezone units have no arm in `DecodeInterval`'s switch (datetime.c:3570-3650), so they reach its `default` and raise 22007. `'1 qtr'`, `'1 quarter'`, `'1 timezone'`, `'1 timezone_hour'` and `'1 timezone_minute'` are all invalid intervals even though the lookup succeeds. A table-driven decoder that trusts this table would accept every one of them. GENERATED -- the extraction command is in the comment below.
(decode-units s)DecodeUnits (datetime.c:4047-4068): an interval unit word to
[type value], or nil.
strncmp(key, token, 10) semantics exactly: an entry matches when
it EQUALS the key, or when the entry is a full ten characters and
the key starts with it. A shorter entry cannot prefix-match, because
its NUL terminator falls inside the ten compared bytes -- which is
why days has to be its own entry rather than matching day.
s must already be ASCII-lowercased, as the lexer leaves it.
`DecodeUnits` (datetime.c:4047-4068): an interval unit word to `[type value]`, or nil. `strncmp(key, token, 10)` semantics exactly: an entry matches when it EQUALS the key, or when the entry is a full ten characters and the key starts with it. A shorter entry cannot prefix-match, because its NUL terminator falls inside the ten compared bytes -- which is why `days` has to be its own entry rather than matching `day`. `s` must already be ASCII-lowercased, as the lexer leaves it.
61 entries: {token -> [type value]}. Keys are LOWERCASE, as
ParseDateTime leaves them.
61 entries: {token -> [type value]}. Keys are LOWERCASE, as
`ParseDateTime` leaves them.TOKMAXLEN. datebsearch compares at most this many characters.
TOKMAXLEN. `datebsearch` compares at most this many characters.
(unit-or-special s)DecodeInterval's DTK_STRING/DTK_SPECIAL resolution, whole
(datetime.c:3659-3663): this table FIRST, then datetktbl.
The order is load-bearing and the two tables disagree -- m is a
minute by this route and a month by the other -- so a caller must
not consult them in the other order or merge them.
`DecodeInterval`'s DTK_STRING/DTK_SPECIAL resolution, whole (datetime.c:3659-3663): this table FIRST, then `datetktbl`. The order is load-bearing and the two tables disagree -- `m` is a minute by this route and a month by the other -- so a caller must not consult them in the other order or merge them.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |