Liking cljdoc? Tell your friends :D

datahike.pg.interval.decode

DecodeInterval (datetime.c:3364-3749) and the Adjust* helpers (560-670).

It reads the SAME lexed fields the datetime decoders read -- it is a fourth consumer of datetime/lex.clj, with buflen 256 rather than 153 or 129 -- and then interprets them by a different set of rules.

THE LOOP RUNS RIGHT TO LEFT (datetime.c:3397). Units FOLLOW their values in an interval literal, so '1 day' is read as day and then 1, with the unit setting type for the field about to be read. Nothing else in the datetime family works this way, and reversing it is not a detail: parsing_unit_val, AGO's last-field-only rule and DTK_HOUR's hand-off all depend on the direction.

The accumulator is pg_itm_in (timestamp.h:82): {:usec :mday :mon :year}, where YEAR is kept separate from MONTH during decoding and folded in only at the end by itmin2interval. Keeping them apart is what lets AdjustYears multiply by 10, 100 and 1000 for decade, century and millennium without losing the int32 range.

OVERFLOW IS CHECKED AT EVERY STEP in the C, with pg_add_s32_overflow and friends, and each failure is DTERR_FIELD_OVERFLOW -- which interval_in then REMAPS to DTERR_INTERVAL_OVERFLOW, SQLSTATE 22015, not 22008 (timestamp.c:932-941). Clojure longs do not overflow at int32, so the bounds are checked explicitly; a missing check is a silently wrapped value rather than an error.

`DecodeInterval` (datetime.c:3364-3749) and the `Adjust*` helpers
(560-670).

It reads the SAME lexed fields the datetime decoders read -- it is a
fourth consumer of `datetime/lex.clj`, with `buflen` 256 rather than
153 or 129 -- and then interprets them by a different set of rules.

THE LOOP RUNS RIGHT TO LEFT (datetime.c:3397). Units FOLLOW their
values in an interval literal, so `'1 day'` is read as `day` and
then `1`, with the unit setting `type` for the field about to be
read. Nothing else in the datetime family works this way, and
reversing it is not a detail: `parsing_unit_val`, AGO's
last-field-only rule and `DTK_HOUR`'s hand-off all depend on the
direction.

The accumulator is `pg_itm_in` (timestamp.h:82): `{:usec :mday :mon
:year}`, where YEAR is kept separate from MONTH during decoding and
folded in only at the end by `itmin2interval`. Keeping them apart is
what lets `AdjustYears` multiply by 10, 100 and 1000 for decade,
century and millennium without losing the int32 range.

OVERFLOW IS CHECKED AT EVERY STEP in the C, with
`pg_add_s32_overflow` and friends, and each failure is
DTERR_FIELD_OVERFLOW -- which `interval_in` then REMAPS to
DTERR_INTERVAL_OVERFLOW, SQLSTATE 22015, not 22008
(timestamp.c:932-941). Clojure longs do not overflow at int32, so
the bounds are checked explicitly; a missing check is a silently
wrapped value rather than an error.
raw docstring

adjust-daysclj

(adjust-days itm val scale)
source

adjust-fract-daysclj

(adjust-fract-days itm frac scale)

AdjustFractDays (564-578). The INTEGER part of the scaled fraction becomes whole days and only the remainder becomes microseconds.

`AdjustFractDays` (564-578). The INTEGER part of the scaled fraction
becomes whole days and only the remainder becomes microseconds.
sourceraw docstring

adjust-fract-microsecondsclj

(adjust-fract-microseconds itm frac scale)

AdjustFractMicroseconds (536-561). The rounding is explicit and is NOT Math/round: the C truncates to int64 and then nudges by one only when the leftover fraction exceeds a half in either direction, which rounds -0.5 and +0.5 DOWN in magnitude where Math/round would round +0.5 up.

`AdjustFractMicroseconds` (536-561). The rounding is explicit and
is NOT `Math/round`: the C truncates to int64 and then nudges by one
only when the leftover fraction exceeds a half in either direction,
which rounds -0.5 and +0.5 DOWN in magnitude where `Math/round`
would round +0.5 up.
sourceraw docstring

adjust-fract-yearsclj

(adjust-fract-years itm frac scale)

AdjustFractYears (581-588). rint -- round half to EVEN, which is Math/rint, not Math/round. rint(0.5) is 0 and round(0.5) is 1, and the difference is reachable: '0.5 mons' would gain a month.

`AdjustFractYears` (581-588). `rint` -- round half to EVEN, which is
`Math/rint`, not `Math/round`. `rint(0.5)` is 0 and `round(0.5)` is
1, and the difference is reachable: `'0.5 mons'` would gain a month.
sourceraw docstring

adjust-microsecondsclj

(adjust-microseconds itm val fval scale)
source

adjust-monthsclj

(adjust-months itm val)
source

adjust-yearsclj

(adjust-years itm val scale)
source

days-per-monthclj

source

decode-intervalclj

(decode-interval fields)
(decode-interval fields range sql-standard?)

DecodeInterval. Returns {:dtype :delta|:late|:early :months :days :micros}, or throws.

range is the typmod field set, defaulting to every field. sql-standard? enables the force_negative pass, which only IntervalStyle = SQL_STANDARD turns on.

`DecodeInterval`. Returns
`{:dtype :delta|:late|:early :months :days :micros}`, or throws.

`range` is the typmod field set, defaulting to every field.
`sql-standard?` enables the `force_negative` pass, which only
`IntervalStyle = SQL_STANDARD` turns on.
sourceraw docstring

decode-iso8601-intervalclj

(decode-iso8601-interval input)

DecodeISO8601Interval. The designator format (P1Y2M3DT4H5M6S) and both alternative formats -- basic (P00010203T040506) and extended (P0001-02-03T04:05:06).

Two documented departures from the spec, both in the C's own comment: a W field may coexist with other units, and decimals are allowed in fields other than the least significant.

The C reaches the alternative formats by FALLTHROUGH -- case 'T' and case '\0' fall into case '-' when the width-8 test fails -- so the three are not separate branches but one entered at different points. Each branch here yields a uniform [:return m] or [:recur …] step, because the fallthrough targets cannot be inner functions: recur inside one would bind to the function, not the loop.

`DecodeISO8601Interval`. The designator format (`P1Y2M3DT4H5M6S`)
and both alternative formats -- basic (`P00010203T040506`) and
extended (`P0001-02-03T04:05:06`).

Two documented departures from the spec, both in the C's own
comment: a `W` field may coexist with other units, and decimals are
allowed in fields other than the least significant.

The C reaches the alternative formats by FALLTHROUGH -- `case 'T'`
and `case '\0'` fall into `case '-'` when the width-8 test fails --
so the three are not separate branches but one entered at different
points. Each branch here yields a uniform `[:return m]` or
`[:recur …]` step, because the fallthrough targets cannot be inner
functions: `recur` inside one would bind to the function, not the
loop.
sourceraw docstring

empty-itmclj

ClearPgItmIn.

`ClearPgItmIn`.
sourceraw docstring

full-rangeclj

INTERVAL_FULL_RANGE. Every field allowed, which is what a bare ::interval cast uses.

INTERVAL_FULL_RANGE. Every field allowed, which is what a bare
`::interval` cast uses.
sourceraw docstring

int32-maxclj

source

int32-minclj

source

months-per-yearclj

source

range-default-typeclj

(range-default-type range)

What a BARE number means, given the typmod range (datetime.c:3421-3474).

This is the whole reason interval '1' hour is one hour and '1'::interval is one second. The switch is on the EXACT field set, not on its lowest member, and the arms are the ones the C lists -- anything else falls to SECOND.

What a BARE number means, given the typmod `range`
(datetime.c:3421-3474).

This is the whole reason `interval '1' hour` is one hour and
`'1'::interval` is one second. The switch is on the EXACT field set,
not on its lowest member, and the arms are the ones the C lists --
anything else falls to SECOND.
sourceraw docstring

time-fieldsclj

DTK_TIME_M, which a :time field claims whole.

DTK_TIME_M, which a `:time` field claims whole.
sourceraw docstring

usecs-per-dayclj

source

usecs-per-hourclj

source

usecs-per-minuteclj

source

usecs-per-secclj

source

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close