postgrejs 3.8.0 → 3.9.0

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.
Files changed (45) hide show
  1. package/CHANGELOG.md +38 -1
  2. package/README.md +50 -0
  3. package/connection/connection.d.ts +14 -2
  4. package/connection/connection.js +57 -9
  5. package/connection/intl-connection.d.ts +146 -5
  6. package/connection/intl-connection.js +458 -30
  7. package/connection/pool.d.ts +30 -6
  8. package/connection/pool.js +22 -3
  9. package/connection/prepared-statement.js +22 -2
  10. package/data-type-map.d.ts +16 -0
  11. package/data-type-map.js +56 -12
  12. package/data-types/date-type.js +2 -2
  13. package/data-types/money-type.d.ts +38 -0
  14. package/data-types/money-type.js +203 -0
  15. package/data-types/numeric-type.d.ts +2 -0
  16. package/data-types/numeric-type.js +1 -1
  17. package/data-types/timestamp-type.js +2 -2
  18. package/data-types/timestamptz-type.js +2 -2
  19. package/index.d.ts +1 -0
  20. package/index.js +1 -0
  21. package/interfaces/data-mapping-options.d.ts +27 -0
  22. package/interfaces/database-connection-params.d.ts +32 -5
  23. package/interfaces/query-options.d.ts +32 -0
  24. package/interfaces/script-execute-options.d.ts +32 -0
  25. package/interfaces/transaction-options.d.ts +27 -0
  26. package/interfaces/transaction-options.js +1 -0
  27. package/package.json +1 -1
  28. package/protocol/database-error.d.ts +15 -0
  29. package/protocol/database-error.js +19 -0
  30. package/protocol/frontend.js +1 -1
  31. package/protocol/pg-socket.js +7 -10
  32. package/util/array-leaf.d.ts +10 -0
  33. package/util/array-leaf.js +22 -0
  34. package/util/date-style.d.ts +47 -0
  35. package/util/date-style.js +123 -0
  36. package/util/parse-datetime.d.ts +4 -3
  37. package/util/parse-datetime.js +34 -9
  38. package/util/resolve-column-formats.js +4 -0
  39. package/util/row-decoder.d.ts +24 -4
  40. package/util/row-decoder.js +25 -10
  41. package/util/sql-tag.js +2 -1
  42. package/util/transaction-command.d.ts +7 -0
  43. package/util/transaction-command.js +32 -0
  44. package/util/unspecified-param.d.ts +0 -5
  45. package/util/unspecified-param.js +1 -10
package/CHANGELOG.md CHANGED
@@ -1,6 +1,43 @@
1
1
  ## Changelog
2
2
 
3
- ### [v3.8.0](https://github.com/panates/postgrejs/compare/v3.7.0...v3.8.0) -
3
+ ### [v3.9.0](https://github.com/panates/postgrejs/compare/v3.8.0...v3.9.0) -
4
+
5
+ #### 🚀 New Features
6
+
7
+ - feat: decode money, by asking the server what a minor unit is @Eray Hanoğlu
8
+ - feat: pipeline by default, and let a connection opt out of it @Eray Hanoğlu
9
+ - feat: take the transaction's modes on startTransaction() @Eray Hanoğlu
10
+ - feat: let a connection answer the data-mapping options once @Eray Hanoğlu
11
+ - feat: keep the server's own error text on serverMessage @Eray Hanoğlu
12
+
13
+ #### 🪲 Fixes
14
+
15
+ - fix: read a text date in the DateStyle the server said it wrote @Eray Hanoğlu
16
+ - fix: let SET TRANSACTION run with rollbackOnError on @Eray Hanoğlu
17
+ - fix: ask for money's scale on the two paths that decoded before asking @Eray Hanoğlu
18
+ - fix: name a statement once, not once per caller in a burst @Eray Hanoğlu
19
+ - fix: keep a pooled connection unshared unless the caller asks @Eray Hanoğlu
20
+ - fix: type an array from the first value inside it, not from value[0] @Eray Hanoğlu
21
+ - fix: answer an empty statement instead of raising @Eray Hanoğlu
22
+
23
+ #### 📖 Documentation Changes
24
+
25
+ - docs: list the ORM adapters that run on this client @Eray Hanoğlu
26
+
27
+ #### 🛠 Refactoring and Updates
28
+
29
+ - refactor: let a row decoder declare its own rowType @Eray Hanoğlu
30
+
31
+ #### ⚡️ Performance Improvments
32
+
33
+ - perf: walk fewer types to infer a parameter, and write once per statement @Eray Hanoğlu
34
+ - perf: stop paying for a text row twice @Eray Hanoğlu
35
+
36
+ #### 💬 General Changes
37
+
38
+ - bench: regenerate the reports, and pin the adapter's options @Eray Hanoğlu
39
+
40
+ ### [v3.8.0](https://github.com/panates/postgrejs/compare/v3.7.0...v3.8.0) - 21 September 2026
4
41
 
5
42
  #### 🚀 New Features
6
43
 
package/README.md CHANGED
@@ -48,6 +48,56 @@ prepared statements, server-side cursors, LISTEN/NOTIFY, bulk `COPY` streams, lo
48
48
  two-phase commit, multi-host failover, and SCRAM channel binding - all in the one package, written in
49
49
  strictly-typed TypeScript from the ground up.
50
50
 
51
+ ### 🔌 Bring Your Own ORM
52
+
53
+ PostgreJS is a driver, not a framework, so what you build on top of it stays your choice:
54
+
55
+ <!-- One cell per adapter, so each renders as its own card: a table because
56
+ GitHub strips CSS, and this is the one layout that survives everywhere
57
+ the README is read. The logos come from postgrejs.com rather than being
58
+ hotlinked from each project, and Drizzle's follows the reader's theme. -->
59
+ <table>
60
+ <tr>
61
+ <td align="center" width="230" valign="top">
62
+ <a href="https://www.sqbjs.org"><img src="https://www.postgrejs.com/img/sqb-logo.svg" alt="SQB" height="60"></a><br><br>
63
+ <b><a href="https://www.sqbjs.org">SQB</a></b><br>
64
+ <a href="https://www.npmjs.com/package/@sqb/postgres"><code>@sqb/postgres</code></a><br>
65
+ <sub>native driver</sub>
66
+ </td>
67
+ <td align="center" width="230" valign="top">
68
+ <a href="https://kysely.dev"><img src="https://www.postgrejs.com/img/kysely-logo.svg" alt="Kysely" height="60"></a><br><br>
69
+ <b><a href="https://kysely.dev">Kysely</a></b><br>
70
+ <a href="https://github.com/panates/postgrejs-kysely"><code>kysely-postgrejs</code></a><br>
71
+ <sub>dialect</sub>
72
+ </td>
73
+ <td align="center" width="230" valign="top">
74
+ <a href="https://orm.drizzle.team"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.postgrejs.com/img/drizzle-logo-dark.svg"><img src="https://www.postgrejs.com/img/drizzle-logo-light.svg" alt="Drizzle ORM" height="34"></picture></a><br><br>
75
+ <b><a href="https://orm.drizzle.team">Drizzle ORM</a></b><br>
76
+ <a href="https://github.com/panates/postgrejs-drizzle"><code>drizzle-postgrejs</code></a><br>
77
+ <sub>driver</sub>
78
+ </td>
79
+ </tr>
80
+ <tr>
81
+ <td align="center" width="230" valign="top">
82
+ <a href="https://typeorm.io"><img src="https://www.postgrejs.com/img/typeorm-icon.png" alt="TypeORM" height="60"></a><br><br>
83
+ <b><a href="https://typeorm.io">TypeORM</a></b><br>
84
+ <a href="https://github.com/panates/postgrejs-typeorm"><code>typeorm-postgrejs</code></a><br>
85
+ <sub>driver</sub>
86
+ </td>
87
+ <td align="center" width="230" valign="top">
88
+ <a href="https://www.prisma.io"><img src="https://www.postgrejs.com/img/prisma-icon.svg" alt="Prisma" height="60"></a><br><br>
89
+ <b><a href="https://www.prisma.io">Prisma</a></b><br>
90
+ <a href="https://github.com/panates/postgrejs-prisma"><code>prisma-postgrejs</code></a><br>
91
+ <sub>driver adapter</sub>
92
+ </td>
93
+ <td width="230"></td>
94
+ </tr>
95
+ </table>
96
+
97
+ Each adapter hands the compiled SQL straight to this client, with no `pg` left anywhere in the chain, and each is
98
+ compared query by query against the driver it replaces - and, where the project ships a suite of its own, run
99
+ against that too. So adopting one is a change to how the connection is created and nothing else.
100
+
51
101
  ## Installation
52
102
 
53
103
  ```bash
@@ -9,6 +9,7 @@ import type { QueryResult } from '../interfaces/query-result.js';
9
9
  import type { ScriptExecuteOptions } from '../interfaces/script-execute-options.js';
10
10
  import type { ScriptResult } from '../interfaces/script-result.js';
11
11
  import type { StatementPrepareOptions } from '../interfaces/statement-prepare-options.js';
12
+ import type { TransactionOptions } from '../interfaces/transaction-options.js';
12
13
  import type { DatabaseError } from '../protocol/database-error.js';
13
14
  import type { Protocol } from '../protocol/protocol.js';
14
15
  import { SafeEventEmitter } from '../safe-event-emitter.js';
@@ -281,7 +282,7 @@ export declare class Connection extends SafeEventEmitter implements AsyncDisposa
281
282
  /**
282
283
  * Starts a transaction
283
284
  */
284
- startTransaction(): Promise<void>;
285
+ startTransaction(options?: TransactionOptions): Promise<void>;
285
286
  /**
286
287
  * Runs `fn` inside a transaction and commits when it returns, or rolls
287
288
  * back and rethrows when it throws - the try/catch every caller of
@@ -309,7 +310,7 @@ export declare class Connection extends SafeEventEmitter implements AsyncDisposa
309
310
  * `fn` is handed this same connection: every statement it runs on it is
310
311
  * inside the transaction, and one it runs on another connection is not.
311
312
  */
312
- transaction<T>(fn: (connection: this) => Promise<T>): Promise<T>;
313
+ transaction<T>(fn: (connection: this) => Promise<T>, options?: TransactionOptions): Promise<T>;
313
314
  /**
314
315
  * Commits current transaction.
315
316
  * @param immediate - Commits right away, ignoring how many nested
@@ -370,6 +371,11 @@ export declare class Connection extends SafeEventEmitter implements AsyncDisposa
370
371
  listen(channel: string, callback: NotificationCallback): Promise<void>;
371
372
  unListen(channel: string): Promise<void>;
372
373
  unListenAll(): Promise<void>;
374
+ /**
375
+ * Whether a statement asked for the wire to itself - `pipeline: false`
376
+ * on the call, or on the connection when the call says nothing.
377
+ */
378
+ protected _isExclusive(pipeline: Maybe<boolean>): boolean;
373
379
  protected _query(sql: string, options?: QueryOptions): Promise<QueryResult>;
374
380
  /**
375
381
  * A large object's descriptor is only valid inside the transaction that
@@ -381,6 +387,12 @@ export declare class Connection extends SafeEventEmitter implements AsyncDisposa
381
387
  protected _openLargeObject(oid: number, mode: number, ownsTransaction: boolean): Promise<LargeObject>;
382
388
  protected _handleNotification(msg: NotificationMessage): void;
383
389
  protected _close(): Promise<void>;
390
+ /**
391
+ * Adds the source excerpt the server's `position` points at to
392
+ * `message`, so an error reads in a terminal without the caller doing
393
+ * anything. `err.serverMessage` keeps the undecorated text for
394
+ * anything that parses it.
395
+ */
384
396
  protected _handleError(err: DatabaseError, script: string): DatabaseError;
385
397
  /**
386
398
  * Remembers where a call came from, so the error it may reject with points
@@ -159,9 +159,17 @@ export class Connection extends SafeEventEmitter {
159
159
  sql = sql.stringify({ ...options, typeMap: options?.typeMap });
160
160
  if (this.listenerCount('execute'))
161
161
  this.emit('execute', sql, options);
162
- return withAbortSignal(options?.signal, () => this._intlCon.cancel(), () => this._captureErrorStack(this._intlCon.execute(sql, options), this.execute, options?.asyncErrorHandling).catch((e) => {
163
- throw this._handleError(e, sql);
164
- }));
162
+ let release = this._intlCon.enterWire(this._isExclusive(options?.pipeline));
163
+ if (typeof release !== 'function')
164
+ release = await release;
165
+ try {
166
+ return await withAbortSignal(options?.signal, () => this._intlCon.cancel(), () => this._captureErrorStack(this._intlCon.execute(sql, options), this.execute, options?.asyncErrorHandling).catch((e) => {
167
+ throw this._handleError(e, sql);
168
+ }));
169
+ }
170
+ finally {
171
+ release();
172
+ }
165
173
  }
166
174
  /**
167
175
  * The legacy Function Call sub-protocol - calls a function by OID
@@ -200,7 +208,15 @@ export class Connection extends SafeEventEmitter {
200
208
  /* c8 ignore stop */
201
209
  if (this.listenerCount('query'))
202
210
  this.emit('query', sql, options);
203
- return withAbortSignal(options?.signal, () => this._intlCon.cancel(), () => this._query(sql, options));
211
+ let release = this._intlCon.enterWire(this._isExclusive(options?.pipeline));
212
+ if (typeof release !== 'function')
213
+ release = await release;
214
+ try {
215
+ return await withAbortSignal(options?.signal, () => this._intlCon.cancel(), () => this._query(sql, options));
216
+ }
217
+ finally {
218
+ release();
219
+ }
204
220
  }
205
221
  /**
206
222
  * Runs a `COPY ... TO STDOUT` and returns its output as a stream of the
@@ -479,8 +495,8 @@ export class Connection extends SafeEventEmitter {
479
495
  /**
480
496
  * Starts a transaction
481
497
  */
482
- startTransaction() {
483
- return this._captureErrorStack(this._intlCon.startTransaction());
498
+ startTransaction(options) {
499
+ return this._captureErrorStack(this._intlCon.startTransaction(options));
484
500
  }
485
501
  /**
486
502
  * Runs `fn` inside a transaction and commits when it returns, or rolls
@@ -509,10 +525,19 @@ export class Connection extends SafeEventEmitter {
509
525
  * `fn` is handed this same connection: every statement it runs on it is
510
526
  * inside the transaction, and one it runs on another connection is not.
511
527
  */
512
- async transaction(fn) {
513
- if (this._intlCon.inTransaction)
528
+ async transaction(fn, options) {
529
+ // A call inside a transaction becomes a savepoint scope, which has
530
+ // no BEGIN to carry modes - see startTransaction(), which refuses
531
+ // them for the same reason rather than applying them to somebody
532
+ // else's transaction.
533
+ if (this._intlCon.inTransaction) {
534
+ if (options)
535
+ throw new Error('transaction() cannot set transaction modes inside a transaction ' +
536
+ 'that is already open - the inner scope is a savepoint, and the ' +
537
+ 'modes belong to the BEGIN that opened the outer one');
514
538
  return await this._savepointScope(fn);
515
- await this.startTransaction();
539
+ }
540
+ await this.startTransaction(options);
516
541
  try {
517
542
  const result = await fn(this);
518
543
  await this.commit();
@@ -630,6 +655,15 @@ export class Connection extends SafeEventEmitter {
630
655
  await this._captureErrorStack(this.query('UNLISTEN *'));
631
656
  }
632
657
  }
658
+ /**
659
+ * Whether a statement asked for the wire to itself - `pipeline: false`
660
+ * on the call, or on the connection when the call says nothing.
661
+ */
662
+ _isExclusive(pipeline) {
663
+ return pipeline != null
664
+ ? !pipeline
665
+ : this._intlCon.config.pipeline === false;
666
+ }
633
667
  async _query(sql, options) {
634
668
  const typeMap = options?.typeMap || GlobalTypeMap;
635
669
  const paramTypes = options?.params?.map(prm => prm instanceof BindParam
@@ -644,6 +678,14 @@ export class Connection extends SafeEventEmitter {
644
678
  isUnspecifiedParam(prm)
645
679
  ? 0
646
680
  : typeMap.determine(prm));
681
+ // A money parameter is written as an int64 of minor units, so the
682
+ // scale has to be known before the Bind goes out - the probe fired
683
+ // at connect answers in time for every result, but not necessarily
684
+ // for the encode of the very first statement.
685
+ if (paramTypes &&
686
+ (paramTypes.includes(DataTypeOIDs.money) ||
687
+ paramTypes.includes(DataTypeOIDs._money)))
688
+ await this._intlCon.ensureMoneyFormat();
647
689
  const effectiveAutoCommit = options?.autoCommit != null
648
690
  ? options.autoCommit
649
691
  : this._intlCon.config.autoCommit;
@@ -716,6 +758,12 @@ export class Connection extends SafeEventEmitter {
716
758
  await this._captureErrorStack(this._intlCon.close());
717
759
  this._closing = false;
718
760
  }
761
+ /**
762
+ * Adds the source excerpt the server's `position` points at to
763
+ * `message`, so an error reads in a terminal without the caller doing
764
+ * anything. `err.serverMessage` keeps the undecorated text for
765
+ * anything that parses it.
766
+ */
719
767
  _handleError(err, script) {
720
768
  if (err.position != null) {
721
769
  const i1 = script.lastIndexOf('\n', err.position - 1) + 1;
@@ -2,7 +2,8 @@ import { ConnectionState } from '../constants.js';
2
2
  import type { DataTypeMap } from '../data-type-map.js';
3
3
  import type { BatchResult } from '../interfaces/batch-result.js';
4
4
  import type { CopyFromRowsOptions, CopyFromRowsResult } from '../interfaces/copy-from-rows-options.js';
5
- import type { ConnectionConfiguration } from '../interfaces/database-connection-params.js';
5
+ import type { DataMappingOptions, MoneyFormat } from '../interfaces/data-mapping-options.js';
6
+ import type { ConnectionConfiguration, ConnectionMappingDefaults } from '../interfaces/database-connection-params.js';
6
7
  import type { FieldInfo } from '../interfaces/field-info.js';
7
8
  import type { FunctionCallOptions } from '../interfaces/function-call-options.js';
8
9
  import type { FunctionCallResult } from '../interfaces/function-call-result.js';
@@ -10,13 +11,29 @@ import type { QueryOptions } from '../interfaces/query-options.js';
10
11
  import type { QueryResult } from '../interfaces/query-result.js';
11
12
  import type { ScriptExecuteOptions } from '../interfaces/script-execute-options.js';
12
13
  import type { ScriptResult } from '../interfaces/script-result.js';
14
+ import type { TransactionOptions } from '../interfaces/transaction-options.js';
13
15
  import { PgSocket } from '../protocol/pg-socket.js';
14
16
  import { Protocol } from '../protocol/protocol.js';
15
17
  import { SafeEventEmitter } from '../safe-event-emitter.js';
16
18
  import type { AnyParseFunction, Maybe, OID } from '../types.js';
17
19
  import { type CopyRowSource } from '../util/copy-from-rows.js';
20
+ import { type PgDateStyle } from '../util/date-style.js';
21
+ import { type RowDecoder } from '../util/row-decoder.js';
18
22
  import type { Connection } from './connection.js';
19
23
  import { CopyFromStream, CopyToStream } from './copy-stream.js';
24
+ interface PreparedCacheEntry {
25
+ name: string;
26
+ fields?: Protocol.RowDescription[];
27
+ }
28
+ /** See IntlConnection._decodeDeferredRows(). */
29
+ interface DeferredRows {
30
+ target: {
31
+ rows?: any[];
32
+ };
33
+ raw: Protocol.DataRowMessage[];
34
+ parsers: AnyParseFunction[];
35
+ fields: any;
36
+ }
20
37
  export declare class IntlConnection extends SafeEventEmitter {
21
38
  /**
22
39
  * Server-side prepared statements this connection has built, keyed by
@@ -29,6 +46,15 @@ export declare class IntlConnection extends SafeEventEmitter {
29
46
  * this is per connection and dies with it.
30
47
  */
31
48
  private _preparedCache;
49
+ /**
50
+ * The names being given out right now, one per SQL. A burst of the
51
+ * same statement arrives before any of it is prepared, and without
52
+ * this every call in the burst prepares its own copy: measured at 50
53
+ * concurrent `select $1::int4`, 25 Parse+Describe round trips and 25
54
+ * named statements left on the server that this map's one entry could
55
+ * never close again.
56
+ */
57
+ private _preparing;
32
58
  /** SQL seen once but not yet prepared - see PREPARE_AFTER_USES. */
33
59
  private _preparedCandidates;
34
60
  private _preparedCounter;
@@ -38,6 +64,24 @@ export declare class IntlConnection extends SafeEventEmitter {
38
64
  protected _savepointDepths: Map<string, number>;
39
65
  protected _config: ConnectionConfiguration;
40
66
  protected _onErrorSavePoint: string;
67
+ /**
68
+ * The data-mapping options this connection was configured with, or
69
+ * undefined when it was given none - which is the common case, and
70
+ * the one that must not pay for this.
71
+ */
72
+ protected readonly _mappingDefaults?: ConnectionMappingDefaults;
73
+ /** The session's DateStyle as last reported, and what it parsed to. */
74
+ protected _dateStyleRaw?: string;
75
+ protected _dateStyle?: PgDateStyle;
76
+ /** The server's own money rendering - see ensureMoneyFormat(). */
77
+ protected _moneyFormat?: MoneyFormat;
78
+ protected _moneyFormatPromise?: Promise<void>;
79
+ /** Statements currently holding the wire - see enterWire(). */
80
+ protected _wireUsers: number;
81
+ protected _wireIdleWaiters?: (() => void)[];
82
+ protected _wireLock?: Promise<void>;
83
+ /** Bound once: enterWire()'s fast path hands out this same function. */
84
+ protected _releaseWire: () => void;
41
85
  transactionStatus: string;
42
86
  socket: PgSocket;
43
87
  owner?: SafeEventEmitter;
@@ -74,7 +118,7 @@ export declare class IntlConnection extends SafeEventEmitter {
74
118
  * that point). A matching number of commit() calls is then needed to
75
119
  * actually commit - see commit().
76
120
  */
77
- startTransaction(): Promise<void>;
121
+ startTransaction(options?: TransactionOptions): Promise<void>;
78
122
  /**
79
123
  * Starts a savepoint, or - if one under the same `name` is already open -
80
124
  * marks a nested level of it. Mirrors startTransaction(): only the
@@ -142,6 +186,49 @@ export declare class IntlConnection extends SafeEventEmitter {
142
186
  rollbackToSavepoint(name: string): Promise<void>;
143
187
  /** Asks the server to cancel whatever this session is running. */
144
188
  cancel(): Promise<void>;
189
+ /**
190
+ * Claims the wire for one statement, and hands back the function that
191
+ * releases it.
192
+ *
193
+ * Several statements share it by default: PostgreSQL correlates
194
+ * responses to requests by order, so a connection can carry more than
195
+ * one at a time and a caller that does not wait for each reply is
196
+ * measurably faster. `exclusive` is `pipeline: false` - the statement
197
+ * waits until nothing else is running here, and nothing else starts
198
+ * until it releases.
199
+ *
200
+ * Returns the release function itself rather than a promise of one
201
+ * whenever it can be taken without waiting, which is every statement
202
+ * on a connection nobody has asked to serialise - the common case, and
203
+ * the one that must not pay for this.
204
+ */
205
+ enterWire(exclusive?: boolean): (() => void) | Promise<() => void>;
206
+ /**
207
+ * Asks the server how it renders money, once per connection.
208
+ *
209
+ * `money` travels as an int64 of the smallest currency unit, and how
210
+ * many of those make one unit is `lc_monetary` - which the server
211
+ * does not report among its startup parameters, so `1234` on the wire
212
+ * is $12.34, ¥1234 or 1.234 KWD depending on a setting only the server
213
+ * knows. Asking it to render a value it already knows is the whole
214
+ * answer, and needs no locale data on this side.
215
+ *
216
+ * `1` is the value asked for because it cannot carry a thousands
217
+ * separator: whatever separator comes back can only be the decimal
218
+ * one, and the digits after it can only be the fraction. `$1.00` is
219
+ * two, `¥1` is none.
220
+ */
221
+ ensureMoneyFormat(): Promise<void>;
222
+ /**
223
+ * Whether these columns need the server's money format and this
224
+ * connection has not asked for it yet.
225
+ *
226
+ * The scan costs a look at each column's OID, and only until the
227
+ * answer is in - from then on the first test ends it.
228
+ */
229
+ needsMoneyFormat(fields: Maybe<{
230
+ dataTypeId: OID;
231
+ }[]>, options?: DataMappingOptions): boolean;
145
232
  ref(): void;
146
233
  unref(): boolean;
147
234
  assertConnected(): void;
@@ -204,11 +291,22 @@ export declare class IntlConnection extends SafeEventEmitter {
204
291
  /**
205
292
  * The savepoint rollbackOnError calls for, or undefined when this call
206
293
  * needs none: outside a transaction there is nothing to roll back to,
207
- * and a statement that is itself a transaction command manages its own
208
- * boundaries (wrapping COMMIT in a savepoint would be nonsense).
294
+ * a statement that is itself a transaction command manages its own
295
+ * boundaries (wrapping COMMIT in a savepoint would be nonsense), and
296
+ * PostgreSQL refuses `SET TRANSACTION` inside one outright.
209
297
  */
210
298
  protected _inlineSavepointFor(sql: string, options: QueryOptions): Maybe<string>;
211
- protected _queryCached(sql: string, paramTypes: Maybe<Maybe<OID>[]>, params: Maybe<Maybe<any>[]>, options: QueryOptions, savepoint: Maybe<string>): Promise<QueryResult>;
299
+ protected _queryCached(sql: string, paramTypes: Maybe<Maybe<OID>[]>, params: Maybe<Maybe<any>[]>, options: QueryOptions, savepoint: Maybe<string>,
300
+ /** Whether the CALL asked for text columns, not the connection. */
301
+ callWantsFields: boolean): Promise<QueryResult>;
302
+ /**
303
+ * Gives this SQL a name and caches it, once, however many callers are
304
+ * waiting. A Parse that fails caches nothing and reports itself; the
305
+ * statement is simply never reused. It runs outside the savepoint, as
306
+ * the prepare() the transaction path used to do ahead of its own
307
+ * wrapper.
308
+ */
309
+ protected _prepareForCache(key: string, sql: string, paramTypes: Maybe<Maybe<OID>[]>): Promise<PreparedCacheEntry>;
212
310
  /**
213
311
  * Counts one more use of this SQL and says whether it has now been seen
214
312
  * often enough to be worth preparing under a name.
@@ -283,6 +381,49 @@ export declare class IntlConnection extends SafeEventEmitter {
283
381
  executeBatchReused(statementName: string, cachedFields: Protocol.RowDescription[] | undefined, paramTypes: Maybe<Maybe<OID>[]>, paramSets: Maybe<any>[][], options: QueryOptions): Promise<BatchResult>;
284
382
  executeReused(statementName: string, cachedFields: Protocol.RowDescription[] | undefined, paramTypes: Maybe<Maybe<OID>[]>, params: Maybe<Maybe<any>[]>, options: QueryOptions, savepoint?: string): Promise<QueryResult>;
285
383
  emit(event: string | symbol, ...args: any[]): boolean;
384
+ /**
385
+ * The slow half of enterWire(): either an exclusive statement, or an
386
+ * ordinary one arriving while an exclusive statement holds the wire.
387
+ *
388
+ * The claim itself is synchronous on purpose. Each waiter wakes in its
389
+ * own microtask and runs to its next `await` without interruption, so
390
+ * re-reading `_wireLock` and assigning it in the same stretch is what
391
+ * makes two waiters unable to both believe they took it.
392
+ */
393
+ protected _enterWireQueued(exclusive: boolean): Promise<() => void>;
394
+ /**
395
+ * `options` with whatever this connection can answer for it: the
396
+ * data-mapping defaults it was configured with, and the money format
397
+ * it has learned.
398
+ *
399
+ * At most one shallow copy per statement, and only when there is
400
+ * something to fill in - a connection configured with nothing and no
401
+ * money in sight hands the caller's own object straight back.
402
+ */
403
+ /**
404
+ * Rows left raw because a money column's scale was not in yet.
405
+ *
406
+ * Two paths decode inside the message loop, where there is no longer
407
+ * anywhere to ask the server anything: the Simple Query protocol and
408
+ * a pipeline. Rather than read those against a scale nobody
409
+ * confirmed, they set the rows aside and this reads them once the
410
+ * loop is over and the question can be asked.
411
+ */
412
+ protected _decodeDeferredRows(deferred: DeferredRows[], rowDecoder: RowDecoder, options: QueryOptions): Promise<QueryOptions>;
413
+ withDefaults<T extends DataMappingOptions>(options: T): T;
414
+ /**
415
+ * The session's DateStyle, when it is not ISO.
416
+ *
417
+ * Read off the reported parameters rather than cached once: `SET
418
+ * DateStyle` is answered with a fresh ParameterStatus, so the string
419
+ * changes under us and a connection that changes it mid-session must
420
+ * not go on decoding by the old one. The comparison is against the
421
+ * same string the socket holds, so it costs a read and a pointer
422
+ * compare while nothing changes - which is always, for the ISO
423
+ * default that needs no parsing at all.
424
+ */
425
+ protected _currentDateStyle(): Maybe<PgDateStyle>;
286
426
  protected _onError(err: Error): void;
287
427
  }
288
428
  export declare function getIntlConnection(connection: Connection): IntlConnection;
429
+ export {};