postgrejs 3.11.1 → 3.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/connection/bind-param.d.ts +21 -0
- package/connection/bind-param.js +21 -0
- package/connection/connection.d.ts +136 -0
- package/connection/connection.js +132 -5
- package/connection/copy-stream.d.ts +2 -0
- package/connection/copy-stream.js +2 -0
- package/connection/cursor.d.ts +67 -5
- package/connection/cursor.js +88 -15
- package/connection/intl-connection.d.ts +22 -0
- package/connection/intl-connection.js +107 -17
- package/connection/large-object.d.ts +18 -0
- package/connection/large-object.js +17 -0
- package/connection/logical-replication.d.ts +15 -0
- package/connection/logical-replication.js +6 -0
- package/connection/pool.d.ts +80 -0
- package/connection/pool.js +82 -9
- package/connection/portal.d.ts +37 -0
- package/connection/portal.js +29 -0
- package/connection/prepared-statement.d.ts +109 -0
- package/connection/prepared-statement.js +150 -7
- package/constants.d.ts +18 -0
- package/constants.js +18 -0
- package/data-type-map.d.ts +38 -0
- package/data-type-map.js +38 -0
- package/data-types/bit-type.d.ts +4 -0
- package/data-types/bit-type.js +4 -0
- package/data-types/bool-type.d.ts +2 -0
- package/data-types/bool-type.js +2 -0
- package/data-types/box-type.d.ts +2 -0
- package/data-types/box-type.js +2 -0
- package/data-types/bytea-type.d.ts +2 -0
- package/data-types/bytea-type.js +2 -0
- package/data-types/char-type.d.ts +2 -0
- package/data-types/char-type.js +2 -0
- package/data-types/circle-type.d.ts +2 -0
- package/data-types/circle-type.js +2 -0
- package/data-types/date-type.d.ts +2 -0
- package/data-types/date-type.js +2 -0
- package/data-types/float4-type.d.ts +2 -0
- package/data-types/float4-type.js +2 -0
- package/data-types/float8-type.d.ts +2 -0
- package/data-types/float8-type.js +2 -0
- package/data-types/inet-type.d.ts +4 -0
- package/data-types/inet-type.js +4 -0
- package/data-types/int2-type.d.ts +2 -0
- package/data-types/int2-type.js +3 -1
- package/data-types/int2-vector-type.d.ts +2 -0
- package/data-types/int2-vector-type.js +2 -0
- package/data-types/int4-type.d.ts +2 -0
- package/data-types/int4-type.js +3 -1
- package/data-types/int8-type.d.ts +2 -0
- package/data-types/int8-type.js +4 -2
- package/data-types/interval-type.d.ts +9 -0
- package/data-types/interval-type.js +9 -0
- package/data-types/json-type.d.ts +2 -0
- package/data-types/json-type.js +2 -0
- package/data-types/jsonb-type.d.ts +2 -0
- package/data-types/jsonb-type.js +2 -0
- package/data-types/jsonpath-type.d.ts +2 -0
- package/data-types/jsonpath-type.js +2 -0
- package/data-types/line-type.d.ts +2 -0
- package/data-types/line-type.js +2 -0
- package/data-types/lseg-type.d.ts +2 -0
- package/data-types/lseg-type.js +2 -0
- package/data-types/macaddr-type.d.ts +4 -0
- package/data-types/macaddr-type.js +4 -0
- package/data-types/money-type.d.ts +1 -0
- package/data-types/money-type.js +17 -10
- package/data-types/numeric-type.d.ts +2 -0
- package/data-types/numeric-type.js +2 -0
- package/data-types/oid-type.d.ts +2 -0
- package/data-types/oid-type.js +3 -1
- package/data-types/oid-vector-type.d.ts +1 -0
- package/data-types/oid-vector-type.js +1 -0
- package/data-types/path-type.d.ts +4 -0
- package/data-types/path-type.js +4 -0
- package/data-types/pg-lsn-type.d.ts +2 -0
- package/data-types/pg-lsn-type.js +2 -0
- package/data-types/point-type.d.ts +2 -0
- package/data-types/point-type.js +2 -0
- package/data-types/range-type.d.ts +4 -0
- package/data-types/range-type.js +4 -0
- package/data-types/snapshot-type.d.ts +4 -0
- package/data-types/snapshot-type.js +4 -0
- package/data-types/tid-type.d.ts +2 -0
- package/data-types/tid-type.js +2 -0
- package/data-types/time-type.d.ts +2 -0
- package/data-types/time-type.js +2 -0
- package/data-types/timestamp-type.d.ts +2 -0
- package/data-types/timestamp-type.js +2 -0
- package/data-types/timestamptz-type.d.ts +2 -0
- package/data-types/timestamptz-type.js +2 -0
- package/data-types/timetz-type.d.ts +2 -0
- package/data-types/timetz-type.js +2 -0
- package/data-types/tsvector-type.d.ts +4 -0
- package/data-types/tsvector-type.js +4 -0
- package/data-types/uuid-type.d.ts +2 -0
- package/data-types/uuid-type.js +2 -0
- package/data-types/varchar-type.d.ts +2 -0
- package/data-types/varchar-type.js +2 -0
- package/data-types/xid-type.d.ts +6 -0
- package/data-types/xid-type.js +8 -1
- package/interfaces/command-result.d.ts +7 -0
- package/interfaces/copy-from-rows-options.d.ts +4 -0
- package/interfaces/data-mapping-options.d.ts +6 -0
- package/interfaces/data-type.d.ts +37 -0
- package/interfaces/database-connection-params.d.ts +31 -0
- package/interfaces/field-info.d.ts +8 -0
- package/interfaces/function-call-options.d.ts +1 -0
- package/interfaces/function-call-result.d.ts +6 -0
- package/interfaces/pipeline-request.d.ts +2 -0
- package/interfaces/query-options.d.ts +7 -0
- package/interfaces/query-result.d.ts +7 -0
- package/interfaces/script-execute-options.d.ts +4 -0
- package/interfaces/script-result.d.ts +1 -0
- package/interfaces/statement-prepare-options.d.ts +1 -0
- package/package.json +5 -5
- package/protocol/backend.d.ts +6 -0
- package/protocol/backend.js +35 -5
- package/protocol/cert-signature.d.ts +8 -0
- package/protocol/cert-signature.js +8 -0
- package/protocol/database-error.d.ts +8 -0
- package/protocol/database-error.js +8 -0
- package/protocol/frontend.d.ts +16 -0
- package/protocol/frontend.js +13 -6
- package/protocol/pg-socket.d.ts +10 -0
- package/protocol/pg-socket.js +14 -7
- package/protocol/pgoutput.d.ts +15 -0
- package/protocol/pgoutput.js +7 -0
- package/protocol/protocol.d.ts +50 -2
- package/protocol/protocol.js +17 -1
- package/protocol/sasl.d.ts +22 -0
- package/protocol/sasl.js +21 -0
- package/protocol/smart-buffer.d.ts +4 -0
- package/safe-event-emitter.d.ts +7 -0
- package/safe-event-emitter.js +7 -0
- package/types.d.ts +21 -0
- package/util/array-calculatedim.d.ts +10 -0
- package/util/array-calculatedim.js +10 -0
- package/util/assert-integer.d.ts +40 -25
- package/util/assert-integer.js +97 -32
- package/util/bigint-methods.d.ts +7 -0
- package/util/bigint-methods.js +9 -0
- package/util/config-from-env.d.ts +10 -0
- package/util/config-from-env.js +10 -0
- package/util/connection-config.d.ts +17 -0
- package/util/connection-config.js +17 -0
- package/util/copy-from-rows.d.ts +12 -0
- package/util/copy-from-rows.js +9 -0
- package/util/decimal-as-string.d.ts +6 -0
- package/util/decimal-as-string.js +6 -0
- package/util/decode-binaryarray.d.ts +9 -0
- package/util/decode-binaryarray.js +9 -0
- package/util/escape-literal.d.ts +11 -0
- package/util/escape-literal.js +13 -0
- package/util/fast-parseint.d.ts +14 -0
- package/util/fast-parseint.js +14 -0
- package/util/format-datetime.d.ts +26 -0
- package/util/format-datetime.js +26 -0
- package/util/get-parsers.d.ts +9 -0
- package/util/get-parsers.js +9 -0
- package/util/hex-text.d.ts +13 -21
- package/util/hex-text.js +24 -21
- package/util/local-date.d.ts +2 -41
- package/util/local-date.js +39 -41
- package/util/parse-array.d.ts +8 -0
- package/util/parse-array.js +8 -0
- package/util/parse-bytea.d.ts +15 -0
- package/util/parse-bytea.js +15 -0
- package/util/parse-datetime.d.ts +26 -0
- package/util/parse-datetime.js +26 -0
- package/util/parse-row.d.ts +23 -2
- package/util/parse-row.js +56 -36
- package/util/parse-time.d.ts +10 -0
- package/util/parse-time.js +10 -0
- package/util/resolve-column-formats.d.ts +1 -0
- package/util/row-decoder.d.ts +32 -0
- package/util/row-decoder.js +22 -0
- package/util/stringify-arrayliteral.d.ts +33 -0
- package/util/stringify-arrayliteral.js +242 -7
- package/util/stringify-for-sql.d.ts +17 -0
- package/util/stringify-for-sql.js +17 -0
- package/util/unspecified-param.d.ts +26 -2
- package/util/unspecified-param.js +26 -2
- package/util/wrap-row-description.d.ts +10 -0
- package/util/wrap-row-description.js +10 -0
- package/CHANGELOG.md +0 -1426
package/util/format-datetime.js
CHANGED
|
@@ -38,6 +38,14 @@ function coerce(v) {
|
|
|
38
38
|
return '-infinity';
|
|
39
39
|
return v instanceof Date ? v : new Date(v);
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Renders a value as the `YYYY-MM-DD` a `date` parameter goes out as.
|
|
43
|
+
*
|
|
44
|
+
* @param v The date, an epoch milliseconds, or text to pass through.
|
|
45
|
+
* @param options `utcDates` decides which clock its components are read
|
|
46
|
+
* from.
|
|
47
|
+
* @returns The date's text.
|
|
48
|
+
*/
|
|
41
49
|
export function formatDate(v, options) {
|
|
42
50
|
const d = coerce(v);
|
|
43
51
|
if (typeof d === 'string')
|
|
@@ -45,6 +53,14 @@ export function formatDate(v, options) {
|
|
|
45
53
|
const p = parts(d, options);
|
|
46
54
|
return `${pad(p.year, 4)}-${pad(p.month)}-${pad(p.day)}`;
|
|
47
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Renders a value as the `HH:MM:SS.mmm` a `time` parameter goes out as.
|
|
58
|
+
*
|
|
59
|
+
* @param v The time, an epoch milliseconds, or text to pass through.
|
|
60
|
+
* @param options `utcDates` decides which clock its components are read
|
|
61
|
+
* from.
|
|
62
|
+
* @returns The time's text.
|
|
63
|
+
*/
|
|
48
64
|
export function formatTime(v, options) {
|
|
49
65
|
const d = coerce(v);
|
|
50
66
|
if (typeof d === 'string')
|
|
@@ -52,6 +68,16 @@ export function formatTime(v, options) {
|
|
|
52
68
|
const p = parts(d, options);
|
|
53
69
|
return `${pad(p.hour)}:${pad(p.minute)}:${pad(p.second)}.${pad(p.ms, 3)}`;
|
|
54
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Renders a value as the `YYYY-MM-DD HH:MM:SS.mmm` a `timestamp`
|
|
73
|
+
* parameter goes out as.
|
|
74
|
+
*
|
|
75
|
+
* @param v The timestamp, an epoch milliseconds, or text to pass
|
|
76
|
+
* through.
|
|
77
|
+
* @param options `utcDates` decides which clock its components are read
|
|
78
|
+
* from.
|
|
79
|
+
* @returns The timestamp's text.
|
|
80
|
+
*/
|
|
55
81
|
export function formatTimestamp(v, options) {
|
|
56
82
|
const d = coerce(v);
|
|
57
83
|
if (typeof d === 'string')
|
package/util/get-parsers.d.ts
CHANGED
|
@@ -2,4 +2,13 @@ import type { DataTypeMap } from '../data-type-map.js';
|
|
|
2
2
|
import type { DataMappingOptions } from '../interfaces/data-mapping-options.js';
|
|
3
3
|
import type { Protocol } from '../protocol/protocol.js';
|
|
4
4
|
import type { AnyParseFunction } from '../types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Chooses one parser per column, for the format that column is coming
|
|
7
|
+
* back in.
|
|
8
|
+
*
|
|
9
|
+
* @param typeMap Where the types are registered.
|
|
10
|
+
* @param fields The columns, as the server described them.
|
|
11
|
+
* @param options `fetchAsString` and the rest of the mapping options.
|
|
12
|
+
* @returns One parser per column, in order.
|
|
13
|
+
*/
|
|
5
14
|
export declare function getParsers(typeMap: DataTypeMap, fields: Protocol.RowDescription[], mappingOptions?: DataMappingOptions): AnyParseFunction[];
|
package/util/get-parsers.js
CHANGED
|
@@ -4,6 +4,15 @@ import { fetchAsStringNamesElement, fetchAsStringNamesOid, } from './fetch-as-st
|
|
|
4
4
|
import { parsePostgresArray } from './parse-array.js';
|
|
5
5
|
const DefaultColumnParser = (data, offset, len) => data.subarray(offset, offset + len);
|
|
6
6
|
const DefaultTextColumnParser = (data, offset, len) => data.toString('utf8', offset, offset + len);
|
|
7
|
+
/**
|
|
8
|
+
* Chooses one parser per column, for the format that column is coming
|
|
9
|
+
* back in.
|
|
10
|
+
*
|
|
11
|
+
* @param typeMap Where the types are registered.
|
|
12
|
+
* @param fields The columns, as the server described them.
|
|
13
|
+
* @param options `fetchAsString` and the rest of the mapping options.
|
|
14
|
+
* @returns One parser per column, in order.
|
|
15
|
+
*/
|
|
7
16
|
export function getParsers(typeMap, fields, mappingOptions) {
|
|
8
17
|
const parsers = new Array(fields.length);
|
|
9
18
|
const asString = mappingOptions?.fetchAsString;
|
package/util/hex-text.d.ts
CHANGED
|
@@ -1,26 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Writes `count` bytes of `src` into `scratch` as lowercase hex,
|
|
3
|
-
* byte
|
|
4
|
-
* a type writes between its bytes are put in once, when the scratch is
|
|
5
|
-
* built, and never again.
|
|
2
|
+
* Writes `count` bytes of `src` into `scratch` as lowercase hex, two
|
|
3
|
+
* characters per byte, the first at `positions[i]`.
|
|
6
4
|
*
|
|
7
|
-
* The
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
5
|
+
* The positions are what let a type keep the separators of its own text
|
|
6
|
+
* form - a uuid's dashes, a macaddr's colons - in the scratch, written
|
|
7
|
+
* once when it is built and never again. The scratch is read back with
|
|
8
|
+
* `latin1`, which is what these types' text paths already use: the
|
|
9
|
+
* output is fixed-format ASCII, so it decodes identically to `utf8` and
|
|
10
|
+
* skips V8's multi-byte-sequence detection.
|
|
11
11
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* the bytes. Measured over 5 000 values, medians of nine runs:
|
|
18
|
-
*
|
|
19
|
-
* ```
|
|
20
|
-
* five toString + concat 1.86 ms
|
|
21
|
-
* one toString, then slice 0.81 ms
|
|
22
|
-
* a byte -> two-char table 0.64 ms
|
|
23
|
-
* this 0.33 ms
|
|
24
|
-
* ```
|
|
12
|
+
* @param scratch The buffer to write into, reused across values.
|
|
13
|
+
* @param positions Where each byte's two characters go.
|
|
14
|
+
* @param src The bytes to render.
|
|
15
|
+
* @param offset Where they start in `src`.
|
|
16
|
+
* @param count How many to render.
|
|
25
17
|
*/
|
|
26
18
|
export declare function writeHexBytes(scratch: Buffer, positions: number[], src: Buffer, offset: number, count: number): void;
|
package/util/hex-text.js
CHANGED
|
@@ -1,30 +1,33 @@
|
|
|
1
1
|
/** `0`-`f` as bytes, so a nibble indexes straight into it. */
|
|
2
2
|
const HEX = Buffer.from('0123456789abcdef', 'latin1');
|
|
3
3
|
/**
|
|
4
|
-
* Writes `count` bytes of `src` into `scratch` as lowercase hex,
|
|
5
|
-
* byte
|
|
6
|
-
* a type writes between its bytes are put in once, when the scratch is
|
|
7
|
-
* built, and never again.
|
|
4
|
+
* Writes `count` bytes of `src` into `scratch` as lowercase hex, two
|
|
5
|
+
* characters per byte, the first at `positions[i]`.
|
|
8
6
|
*
|
|
9
|
-
* The
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
7
|
+
* The positions are what let a type keep the separators of its own text
|
|
8
|
+
* form - a uuid's dashes, a macaddr's colons - in the scratch, written
|
|
9
|
+
* once when it is built and never again. The scratch is read back with
|
|
10
|
+
* `latin1`, which is what these types' text paths already use: the
|
|
11
|
+
* output is fixed-format ASCII, so it decodes identically to `utf8` and
|
|
12
|
+
* skips V8's multi-byte-sequence detection.
|
|
13
13
|
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* the bytes. Measured over 5 000 values, medians of nine runs:
|
|
20
|
-
*
|
|
21
|
-
* ```
|
|
22
|
-
* five toString + concat 1.86 ms
|
|
23
|
-
* one toString, then slice 0.81 ms
|
|
24
|
-
* a byte -> two-char table 0.64 ms
|
|
25
|
-
* this 0.33 ms
|
|
26
|
-
* ```
|
|
14
|
+
* @param scratch The buffer to write into, reused across values.
|
|
15
|
+
* @param positions Where each byte's two characters go.
|
|
16
|
+
* @param src The bytes to render.
|
|
17
|
+
* @param offset Where they start in `src`.
|
|
18
|
+
* @param count How many to render.
|
|
27
19
|
*/
|
|
20
|
+
/* Why not Buffer.toString('hex'): a type whose text has separators in it
|
|
21
|
+
has to call that once per group and join the pieces. For uuid that was
|
|
22
|
+
five calls and four concatenations per value - 25 000 strings and
|
|
23
|
+
20 000 concatenations for a 5 000-row column, more work than pg does
|
|
24
|
+
for the same column despite this client reading half the bytes.
|
|
25
|
+
Measured over 5 000 values, medians of nine runs:
|
|
26
|
+
|
|
27
|
+
five toString + concat 1.86 ms
|
|
28
|
+
one toString, then slice 0.81 ms
|
|
29
|
+
a byte -> two-char table 0.64 ms
|
|
30
|
+
this 0.33 ms */
|
|
28
31
|
export function writeHexBytes(scratch, positions, src, offset, count) {
|
|
29
32
|
let i;
|
|
30
33
|
let p;
|
package/util/local-date.d.ts
CHANGED
|
@@ -7,46 +7,7 @@
|
|
|
7
7
|
* comes back as a Date reading 10:30 locally rather than the instant
|
|
8
8
|
* 10:30Z.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* common decode path - the getters alone cost more than either Date:
|
|
13
|
-
*
|
|
14
|
-
* ```
|
|
15
|
-
* new Date(epochMs) 43.6 ns
|
|
16
|
-
* getUTC* x 7 97.4 ns
|
|
17
|
-
* new Date(y, m, d, h, mi, s, ms) 61.7 ns
|
|
18
|
-
* ```
|
|
19
|
-
*
|
|
20
|
-
* Shifting the instant by the zone's own offset lands on the same wall
|
|
21
|
-
* clock for a fraction of that, but only where the offset is a whole
|
|
22
|
-
* number of minutes and holds either side of where the shift lands.
|
|
23
|
-
* Two guards and a floor make that exact rather than usually-right:
|
|
24
|
-
*
|
|
25
|
-
* - **The offset must survive the shift.** Where it does not, the shift
|
|
26
|
-
* crossed a transition and the wall clock it landed on is not the one
|
|
27
|
-
* that was asked for - or does not exist at all.
|
|
28
|
-
* - **The offset must hold for the hour before the landing too.** That
|
|
29
|
-
* is the hour a backward transition repeats, where both instants read
|
|
30
|
-
* the same wall clock and the shift keeps the wrong one of the two.
|
|
31
|
-
* Pacific/Chatham found this: `2024-04-07T03:00Z` is `03:00` in both
|
|
32
|
-
* +12:45 and +13:45, an hour apart.
|
|
33
|
-
* - **Nothing before 1970.** A zone's pre-standard offset carries
|
|
34
|
-
* seconds - Europe/Istanbul was +01:55:52 - and `getTimezoneOffset()`
|
|
35
|
-
* answers in whole minutes, so the shift lands up to 59 seconds off.
|
|
36
|
-
* The tz database does not claim correctness before 1970 either.
|
|
37
|
-
*
|
|
38
|
-
* Whatever fails those goes back to the component route, which is what
|
|
39
|
-
* this has always answered. Checked against it over 1850-2040 at
|
|
40
|
-
* 90-minute steps - 1.1 million instants - in ten zones including the
|
|
41
|
-
* 45-minute and 30-minute DST ones: no disagreement, and
|
|
42
|
-
*
|
|
43
|
-
* ```
|
|
44
|
-
* before after
|
|
45
|
-
* Europe/Istanbul 157.5 ns 123.0 ns
|
|
46
|
-
* America/New_York 245.6 ns 131.2 ns
|
|
47
|
-
* ```
|
|
48
|
-
*
|
|
49
|
-
* The DST zone was dearer before because V8 pays for a transition lookup
|
|
50
|
-
* on every local construction; here it pays for one instant instead.
|
|
10
|
+
* @param ms The instant whose UTC components are the wall clock wanted.
|
|
11
|
+
* @returns A Date reading that wall clock in the local zone.
|
|
51
12
|
*/
|
|
52
13
|
export declare function utcPartsAsLocal(ms: number): Date;
|
package/util/local-date.js
CHANGED
|
@@ -7,48 +7,46 @@
|
|
|
7
7
|
* comes back as a Date reading 10:30 locally rather than the instant
|
|
8
8
|
* 10:30Z.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* common decode path - the getters alone cost more than either Date:
|
|
13
|
-
*
|
|
14
|
-
* ```
|
|
15
|
-
* new Date(epochMs) 43.6 ns
|
|
16
|
-
* getUTC* x 7 97.4 ns
|
|
17
|
-
* new Date(y, m, d, h, mi, s, ms) 61.7 ns
|
|
18
|
-
* ```
|
|
19
|
-
*
|
|
20
|
-
* Shifting the instant by the zone's own offset lands on the same wall
|
|
21
|
-
* clock for a fraction of that, but only where the offset is a whole
|
|
22
|
-
* number of minutes and holds either side of where the shift lands.
|
|
23
|
-
* Two guards and a floor make that exact rather than usually-right:
|
|
24
|
-
*
|
|
25
|
-
* - **The offset must survive the shift.** Where it does not, the shift
|
|
26
|
-
* crossed a transition and the wall clock it landed on is not the one
|
|
27
|
-
* that was asked for - or does not exist at all.
|
|
28
|
-
* - **The offset must hold for the hour before the landing too.** That
|
|
29
|
-
* is the hour a backward transition repeats, where both instants read
|
|
30
|
-
* the same wall clock and the shift keeps the wrong one of the two.
|
|
31
|
-
* Pacific/Chatham found this: `2024-04-07T03:00Z` is `03:00` in both
|
|
32
|
-
* +12:45 and +13:45, an hour apart.
|
|
33
|
-
* - **Nothing before 1970.** A zone's pre-standard offset carries
|
|
34
|
-
* seconds - Europe/Istanbul was +01:55:52 - and `getTimezoneOffset()`
|
|
35
|
-
* answers in whole minutes, so the shift lands up to 59 seconds off.
|
|
36
|
-
* The tz database does not claim correctness before 1970 either.
|
|
37
|
-
*
|
|
38
|
-
* Whatever fails those goes back to the component route, which is what
|
|
39
|
-
* this has always answered. Checked against it over 1850-2040 at
|
|
40
|
-
* 90-minute steps - 1.1 million instants - in ten zones including the
|
|
41
|
-
* 45-minute and 30-minute DST ones: no disagreement, and
|
|
42
|
-
*
|
|
43
|
-
* ```
|
|
44
|
-
* before after
|
|
45
|
-
* Europe/Istanbul 157.5 ns 123.0 ns
|
|
46
|
-
* America/New_York 245.6 ns 131.2 ns
|
|
47
|
-
* ```
|
|
48
|
-
*
|
|
49
|
-
* The DST zone was dearer before because V8 pays for a transition lookup
|
|
50
|
-
* on every local construction; here it pays for one instant instead.
|
|
10
|
+
* @param ms The instant whose UTC components are the wall clock wanted.
|
|
11
|
+
* @returns A Date reading that wall clock in the local zone.
|
|
51
12
|
*/
|
|
13
|
+
/* Doing this by reading the seven getUTC* components off one Date and
|
|
14
|
+
handing them to another was the most expensive thing left in the
|
|
15
|
+
common decode path - the getters alone cost more than either Date:
|
|
16
|
+
|
|
17
|
+
new Date(epochMs) 43.6 ns
|
|
18
|
+
getUTC* x 7 97.4 ns
|
|
19
|
+
new Date(y, m, d, h, mi, s, ms) 61.7 ns
|
|
20
|
+
|
|
21
|
+
Shifting the instant by the zone's own offset lands on the same wall
|
|
22
|
+
clock for a fraction of that, but only where the offset is a whole
|
|
23
|
+
number of minutes and holds either side of where the shift lands. Two
|
|
24
|
+
guards and a floor make that exact rather than usually-right:
|
|
25
|
+
|
|
26
|
+
- The offset must survive the shift. Where it does not, the shift
|
|
27
|
+
crossed a transition and the wall clock it landed on is not the one
|
|
28
|
+
that was asked for - or does not exist at all.
|
|
29
|
+
- The offset must hold for the hour before the landing too. That is
|
|
30
|
+
the hour a backward transition repeats, where both instants read the
|
|
31
|
+
same wall clock and the shift keeps the wrong one of the two.
|
|
32
|
+
Pacific/Chatham found this: 2024-04-07T03:00Z is 03:00 in both
|
|
33
|
+
+12:45 and +13:45, an hour apart.
|
|
34
|
+
- Nothing before 1970. A zone's pre-standard offset carries seconds -
|
|
35
|
+
Europe/Istanbul was +01:55:52 - and getTimezoneOffset() answers in
|
|
36
|
+
whole minutes, so the shift lands up to 59 seconds off. The tz
|
|
37
|
+
database does not claim correctness before 1970 either.
|
|
38
|
+
|
|
39
|
+
Whatever fails those goes back to the component route, which is what
|
|
40
|
+
this has always answered. Checked against it over 1850-2040 at
|
|
41
|
+
90-minute steps - 1.1 million instants - in ten zones including the
|
|
42
|
+
45-minute and 30-minute DST ones: no disagreement, and
|
|
43
|
+
|
|
44
|
+
before after
|
|
45
|
+
Europe/Istanbul 157.5 ns 123.0 ns
|
|
46
|
+
America/New_York 245.6 ns 131.2 ns
|
|
47
|
+
|
|
48
|
+
The DST zone was dearer before because V8 pays for a transition lookup
|
|
49
|
+
on every local construction; here it pays for one instant instead. */
|
|
52
50
|
export function utcPartsAsLocal(ms) {
|
|
53
51
|
if (ms >= 0) {
|
|
54
52
|
const offset = new Date(ms).getTimezoneOffset();
|
package/util/parse-array.d.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { Maybe } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Reads an array literal - `{1,2,{3,4}}` - into a nested array.
|
|
4
|
+
*
|
|
5
|
+
* @param s The literal, as the server wrote it.
|
|
6
|
+
* @param opts `transform` reads each element's text into a value, and
|
|
7
|
+
* `separator` is for the types that do not use a comma.
|
|
8
|
+
* @returns The array, or `undefined` when there was no literal.
|
|
9
|
+
*/
|
|
2
10
|
export declare function parsePostgresArray(s: string, opts?: {
|
|
3
11
|
transform?: (v: string) => any;
|
|
4
12
|
separator?: string;
|
package/util/parse-array.js
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads an array literal - `{1,2,{3,4}}` - into a nested array.
|
|
3
|
+
*
|
|
4
|
+
* @param s The literal, as the server wrote it.
|
|
5
|
+
* @param opts `transform` reads each element's text into a value, and
|
|
6
|
+
* `separator` is for the types that do not use a comma.
|
|
7
|
+
* @returns The array, or `undefined` when there was no literal.
|
|
8
|
+
*/
|
|
1
9
|
export function parsePostgresArray(s, opts) {
|
|
2
10
|
if (!s)
|
|
3
11
|
return;
|
package/util/parse-bytea.d.ts
CHANGED
|
@@ -1,2 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads a `bytea`'s text form into its bytes.
|
|
3
|
+
*
|
|
4
|
+
* @param v The value as the server wrote it - `\\x` hex, or the older
|
|
5
|
+
* escape form.
|
|
6
|
+
* @returns The bytes.
|
|
7
|
+
*/
|
|
1
8
|
export declare function parseBytea(v: string): Buffer;
|
|
9
|
+
/**
|
|
10
|
+
* The same, straight from the wire bytes - no string is made.
|
|
11
|
+
*
|
|
12
|
+
* @param buf The buffer holding the value.
|
|
13
|
+
* @param offset Where it starts.
|
|
14
|
+
* @param len How many bytes it runs for.
|
|
15
|
+
* @returns The decoded bytes.
|
|
16
|
+
*/
|
|
2
17
|
export declare function parseByteaBuffer(buf: Buffer, offset: number, len: number): Buffer;
|
package/util/parse-bytea.js
CHANGED
|
@@ -36,6 +36,13 @@ function parseByteaEscape(input) {
|
|
|
36
36
|
}
|
|
37
37
|
return Buffer.from(output, 'binary');
|
|
38
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Reads a `bytea`'s text form into its bytes.
|
|
41
|
+
*
|
|
42
|
+
* @param v The value as the server wrote it - `\\x` hex, or the older
|
|
43
|
+
* escape form.
|
|
44
|
+
* @returns The bytes.
|
|
45
|
+
*/
|
|
39
46
|
export function parseBytea(v) {
|
|
40
47
|
// PostgreSQL's default bytea_output is "hex" (`\x`-prefixed) - check the
|
|
41
48
|
// two marker chars directly rather than a regex test, and hex-decode
|
|
@@ -65,6 +72,14 @@ const HEX_NIBBLE = (() => {
|
|
|
65
72
|
// format via a single 'latin1' string conversion - its own grammar (\ddd
|
|
66
73
|
// octal triplets, ASCII digits, or a literal backslash) is pure ASCII, same
|
|
67
74
|
// as the hex path, so 'latin1' is safe there too.
|
|
75
|
+
/**
|
|
76
|
+
* The same, straight from the wire bytes - no string is made.
|
|
77
|
+
*
|
|
78
|
+
* @param buf The buffer holding the value.
|
|
79
|
+
* @param offset Where it starts.
|
|
80
|
+
* @param len How many bytes it runs for.
|
|
81
|
+
* @returns The decoded bytes.
|
|
82
|
+
*/
|
|
68
83
|
export function parseByteaBuffer(buf, offset, len) {
|
|
69
84
|
if (buf[offset] === 0x5c /* '\' */ && buf[offset + 1] === 0x78 /* 'x' */) {
|
|
70
85
|
// Truncate a trailing odd nibble instead of throwing, matching
|
package/util/parse-datetime.d.ts
CHANGED
|
@@ -1,4 +1,30 @@
|
|
|
1
1
|
import { type PgDateStyle } from './date-style.js';
|
|
2
|
+
/**
|
|
3
|
+
* Reads a `date` as the server wrote it.
|
|
4
|
+
*
|
|
5
|
+
* @param str The value's text.
|
|
6
|
+
* @param utc Whether to build the Date in UTC rather than locally.
|
|
7
|
+
* @param dateStyle The session's DateStyle, when it is not ISO - which
|
|
8
|
+
* is what says whether `01/02/2024` is January or February.
|
|
9
|
+
* @returns The date, or ±Infinity for the two that are not dates.
|
|
10
|
+
*/
|
|
2
11
|
export declare function parseDate(str: string, utc?: boolean, dateStyle?: PgDateStyle): Date | number;
|
|
12
|
+
/**
|
|
13
|
+
* Reads a `timestamp` (without time zone) as the server wrote it.
|
|
14
|
+
*
|
|
15
|
+
* @param str The value's text.
|
|
16
|
+
* @param utc Whether to build the Date in UTC rather than locally.
|
|
17
|
+
* @param dateStyle The session's DateStyle, when it is not ISO.
|
|
18
|
+
* @returns The timestamp, or ±Infinity.
|
|
19
|
+
*/
|
|
3
20
|
export declare function parseDateTime(str: string, utc?: boolean, dateStyle?: PgDateStyle): Date | number;
|
|
21
|
+
/**
|
|
22
|
+
* Reads a `timestamptz` as the server wrote it, offset included.
|
|
23
|
+
*
|
|
24
|
+
* @param str The value's text.
|
|
25
|
+
* @param utc Whether to build the Date in UTC rather than locally, for
|
|
26
|
+
* a value that carries no offset.
|
|
27
|
+
* @param dateStyle The session's DateStyle, when it is not ISO.
|
|
28
|
+
* @returns The instant, or ±Infinity.
|
|
29
|
+
*/
|
|
4
30
|
export declare function parseDateTimeTz(str: string, utc?: boolean, dateStyle?: PgDateStyle): Date | number;
|
package/util/parse-datetime.js
CHANGED
|
@@ -22,6 +22,15 @@ function fillTimeArgs(m, args) {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Reads a `date` as the server wrote it.
|
|
27
|
+
*
|
|
28
|
+
* @param str The value's text.
|
|
29
|
+
* @param utc Whether to build the Date in UTC rather than locally.
|
|
30
|
+
* @param dateStyle The session's DateStyle, when it is not ISO - which
|
|
31
|
+
* is what says whether `01/02/2024` is January or February.
|
|
32
|
+
* @returns The date, or ±Infinity for the two that are not dates.
|
|
33
|
+
*/
|
|
25
34
|
export function parseDate(str, utc, dateStyle) {
|
|
26
35
|
if (dateStyle) {
|
|
27
36
|
const styled = parseStyledDateTime(str, dateStyle, utc);
|
|
@@ -46,6 +55,14 @@ export function parseDate(str, utc, dateStyle) {
|
|
|
46
55
|
return new Date(Date.UTC(...args));
|
|
47
56
|
return new Date(...args);
|
|
48
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Reads a `timestamp` (without time zone) as the server wrote it.
|
|
60
|
+
*
|
|
61
|
+
* @param str The value's text.
|
|
62
|
+
* @param utc Whether to build the Date in UTC rather than locally.
|
|
63
|
+
* @param dateStyle The session's DateStyle, when it is not ISO.
|
|
64
|
+
* @returns The timestamp, or ±Infinity.
|
|
65
|
+
*/
|
|
49
66
|
export function parseDateTime(str, utc, dateStyle) {
|
|
50
67
|
if (dateStyle) {
|
|
51
68
|
const styled = parseStyledDateTime(str, dateStyle, utc);
|
|
@@ -88,6 +105,15 @@ export function parseDateTime(str, utc, dateStyle) {
|
|
|
88
105
|
return new Date(Date.UTC(...args));
|
|
89
106
|
return new Date(...args);
|
|
90
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Reads a `timestamptz` as the server wrote it, offset included.
|
|
110
|
+
*
|
|
111
|
+
* @param str The value's text.
|
|
112
|
+
* @param utc Whether to build the Date in UTC rather than locally, for
|
|
113
|
+
* a value that carries no offset.
|
|
114
|
+
* @param dateStyle The session's DateStyle, when it is not ISO.
|
|
115
|
+
* @returns The instant, or ±Infinity.
|
|
116
|
+
*/
|
|
91
117
|
export function parseDateTimeTz(str, utc, dateStyle) {
|
|
92
118
|
if (dateStyle) {
|
|
93
119
|
const styled = parseStyledDateTime(str, dateStyle, utc);
|
package/util/parse-row.d.ts
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
import type { DataMappingOptions } from '../interfaces/data-mapping-options.js';
|
|
2
2
|
import type { FieldInfo } from '../interfaces/field-info.js';
|
|
3
3
|
import type { AnyParseFunction } from '../types.js';
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Reads one row into an array of values.
|
|
6
|
+
*
|
|
7
|
+
* @param parsers One per column, already chosen for its format.
|
|
8
|
+
* @param data The row's own bytes, from the DataRow message.
|
|
9
|
+
* @param columnCount How many values it holds.
|
|
10
|
+
* @param options Passed to each parser.
|
|
11
|
+
* @param start Where the row's values begin in `data`.
|
|
12
|
+
* @returns The values, in column order.
|
|
13
|
+
*/
|
|
14
|
+
export declare function parseRow(parsers: AnyParseFunction[], data: Buffer, columnCount: number, options: DataMappingOptions, start?: number): any[];
|
|
15
|
+
/**
|
|
16
|
+
* Reads one row into an object keyed by column name.
|
|
17
|
+
*
|
|
18
|
+
* @param parsers One per column, already chosen for its format.
|
|
19
|
+
* @param data The row's own bytes, from the DataRow message.
|
|
20
|
+
* @param columnCount How many values it holds.
|
|
21
|
+
* @param options Passed to each parser.
|
|
22
|
+
* @param fields The columns, whose names become the keys.
|
|
23
|
+
* @param start Where the row's values begin in `data`.
|
|
24
|
+
* @returns The row as an object.
|
|
25
|
+
*/
|
|
26
|
+
export declare function parseObjectRow(parsers: AnyParseFunction[], data: Buffer, columnCount: number, options: DataMappingOptions, fields: FieldInfo[], start?: number): object;
|
package/util/parse-row.js
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Reads one row into an array of values.
|
|
3
|
+
*
|
|
4
|
+
* @param parsers One per column, already chosen for its format.
|
|
5
|
+
* @param data The row's own bytes, from the DataRow message.
|
|
6
|
+
* @param columnCount How many values it holds.
|
|
7
|
+
* @param options Passed to each parser.
|
|
8
|
+
* @param start Where the row's values begin in `data`.
|
|
9
|
+
* @returns The values, in column order.
|
|
10
|
+
*/
|
|
11
|
+
export function parseRow(parsers, data, columnCount, options, start = 0) {
|
|
2
12
|
const row = new Array(columnCount);
|
|
3
|
-
let offset =
|
|
13
|
+
let offset = start;
|
|
4
14
|
let len;
|
|
5
15
|
let i;
|
|
6
16
|
for (i = 0; i < columnCount; i++) {
|
|
@@ -21,28 +31,26 @@ export function parseRow(parsers, data, columnCount, options) {
|
|
|
21
31
|
}
|
|
22
32
|
return row;
|
|
23
33
|
}
|
|
24
|
-
/**
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
* giving up well under 1% of the win on a result worth compiling for.
|
|
34
|
-
*/
|
|
34
|
+
/** Rows decoded against one `FieldInfo[]` before compiling a factory for it. */
|
|
35
|
+
/* Compiling costs ~0.8µs when the engine can reuse its own compilation
|
|
36
|
+
cache for identical source and several µs when it cannot, against
|
|
37
|
+
~0.1µs saved per row - so a query returning a handful of rows would
|
|
38
|
+
pay more than it ever got back. Since wrapRowDescription() builds a
|
|
39
|
+
fresh fields array per query, a single-row query executed in a loop
|
|
40
|
+
would otherwise recompile on every call. Waiting a few rows keeps that
|
|
41
|
+
case free while giving up well under 1% of the win on a result worth
|
|
42
|
+
compiling for. */
|
|
35
43
|
const OBJECT_ROW_FACTORY_THRESHOLD = 8;
|
|
36
44
|
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
* it leaves behind, which a single-row query (a new fields array every
|
|
40
|
-
* time, never looked up again) would pay on every call for nothing.
|
|
41
|
-
*
|
|
42
|
-
* Keyed weakly, so a finished query's factory goes away with its fields;
|
|
43
|
-
* an entry earns its keep only when the same fields array is decoded
|
|
44
|
-
* against again after something else interrupted it.
|
|
45
|
+
* The compiled factories, keyed weakly by the fields they were built
|
|
46
|
+
* for, so a finished query's factory goes away with them.
|
|
45
47
|
*/
|
|
48
|
+
/* Only factories that were actually compiled go in here, never the row
|
|
49
|
+
counts leading up to one: writing a fresh key costs ~67ns plus the
|
|
50
|
+
garbage it leaves behind, which a single-row query - a new fields
|
|
51
|
+
array every time, never looked up again - would pay on every call for
|
|
52
|
+
nothing. An entry earns its keep only when the same fields array is
|
|
53
|
+
decoded against again after something else interrupted it. */
|
|
46
54
|
const objectRowFactories = new WeakMap();
|
|
47
55
|
// Rows of one result arrive in a run, so a single entry in front of the
|
|
48
56
|
// WeakMap answers nearly every lookup with one identity check - and is
|
|
@@ -58,17 +66,18 @@ let memoDeclined = false;
|
|
|
58
66
|
* Compiles a function that builds this query's row object in one shot,
|
|
59
67
|
* from a single object literal with every column name in it.
|
|
60
68
|
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* Returns null when that isn't possible, leaving the caller on the
|
|
67
|
-
* assignment path: a column named `__proto__` would set the prototype
|
|
68
|
-
* rather than become an own property if it appeared as a literal key, and
|
|
69
|
-
* Function construction itself can be unavailable (a Content-Security-
|
|
70
|
-
* Policy without 'unsafe-eval').
|
|
69
|
+
* @param fields The columns to build the literal from.
|
|
70
|
+
* @param columnCount How many of them the rows carry.
|
|
71
|
+
* @returns The factory, or `null` when this shape cannot be compiled -
|
|
72
|
+
* a column named `__proto__`, or a runtime with Function construction
|
|
73
|
+
* disabled - which leaves the caller on the assignment path.
|
|
71
74
|
*/
|
|
75
|
+
/* Assigning the columns one at a time instead (row[name] = value) walks
|
|
76
|
+
the object through one hidden-class transition per column, per row -
|
|
77
|
+
~6.8x the cost of handing the engine a literal whose shape it can lay
|
|
78
|
+
out once and reuse for every row of the result. A `__proto__` key in a
|
|
79
|
+
literal sets the prototype rather than becoming an own property, which
|
|
80
|
+
is why that one is refused rather than escaped. */
|
|
72
81
|
function buildObjectRowFactory(fields, columnCount) {
|
|
73
82
|
let src = 'return{';
|
|
74
83
|
let name;
|
|
@@ -115,7 +124,18 @@ function getObjectRowFactory(fields, columnCount) {
|
|
|
115
124
|
objectRowFactories.set(fields, factory);
|
|
116
125
|
return factory;
|
|
117
126
|
}
|
|
118
|
-
|
|
127
|
+
/**
|
|
128
|
+
* Reads one row into an object keyed by column name.
|
|
129
|
+
*
|
|
130
|
+
* @param parsers One per column, already chosen for its format.
|
|
131
|
+
* @param data The row's own bytes, from the DataRow message.
|
|
132
|
+
* @param columnCount How many values it holds.
|
|
133
|
+
* @param options Passed to each parser.
|
|
134
|
+
* @param fields The columns, whose names become the keys.
|
|
135
|
+
* @param start Where the row's values begin in `data`.
|
|
136
|
+
* @returns The row as an object.
|
|
137
|
+
*/
|
|
138
|
+
export function parseObjectRow(parsers, data, columnCount, options, fields, start = 0) {
|
|
119
139
|
// A compiled factory is built against `fields`, so it can only be used
|
|
120
140
|
// when the row really does have one value per field.
|
|
121
141
|
const factory = fields.length === columnCount
|
|
@@ -123,7 +143,7 @@ export function parseObjectRow(parsers, data, columnCount, options, fields) {
|
|
|
123
143
|
: null;
|
|
124
144
|
if (factory) {
|
|
125
145
|
const values = new Array(columnCount);
|
|
126
|
-
let offset =
|
|
146
|
+
let offset = start;
|
|
127
147
|
let len;
|
|
128
148
|
let i;
|
|
129
149
|
for (i = 0; i < columnCount; i++) {
|
|
@@ -139,11 +159,11 @@ export function parseObjectRow(parsers, data, columnCount, options, fields) {
|
|
|
139
159
|
}
|
|
140
160
|
return factory(values);
|
|
141
161
|
}
|
|
142
|
-
return parseObjectRowByAssignment(parsers, data, columnCount, options, fields);
|
|
162
|
+
return parseObjectRowByAssignment(parsers, data, columnCount, options, fields, start);
|
|
143
163
|
}
|
|
144
|
-
function parseObjectRowByAssignment(parsers, data, columnCount, options, fields) {
|
|
164
|
+
function parseObjectRowByAssignment(parsers, data, columnCount, options, fields, start = 0) {
|
|
145
165
|
const row = {};
|
|
146
|
-
let offset =
|
|
166
|
+
let offset = start;
|
|
147
167
|
let len;
|
|
148
168
|
let i;
|
|
149
169
|
let value;
|
package/util/parse-time.d.ts
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/** A time as the server writes one: two digits a part, colons in place. */
|
|
1
2
|
export declare const STRICT_TIME_PATTERN: RegExp;
|
|
3
|
+
/** The same, loosened for what a caller might pass as a parameter - the colons and the seconds may be left out. */
|
|
2
4
|
export declare const TIME_PATTERN: RegExp;
|
|
5
|
+
/**
|
|
6
|
+
* Reads a time of day into a Date on the epoch day.
|
|
7
|
+
*
|
|
8
|
+
* @param str The value's text.
|
|
9
|
+
* @param parseTimeZone Whether an offset in the text should be applied.
|
|
10
|
+
* @param utc Whether to build the Date in UTC rather than locally.
|
|
11
|
+
* @returns A Date carrying that clock time.
|
|
12
|
+
*/
|
|
3
13
|
export declare function parseTime(str: string, parseTimeZone?: boolean, utc?: boolean): Date;
|