postgrejs 3.4.0 → 3.6.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 (41) hide show
  1. package/CHANGELOG.md +43 -1
  2. package/README.md +29 -4
  3. package/connection/connection.d.ts +37 -0
  4. package/connection/connection.js +85 -7
  5. package/connection/cursor.d.ts +8 -0
  6. package/connection/cursor.js +39 -1
  7. package/connection/intl-connection.d.ts +6 -1
  8. package/connection/intl-connection.js +284 -122
  9. package/connection/pool.d.ts +16 -0
  10. package/connection/pool.js +52 -6
  11. package/connection/portal.d.ts +1 -1
  12. package/connection/portal.js +3 -2
  13. package/connection/prepared-statement.js +8 -4
  14. package/data-type-map.d.ts +11 -0
  15. package/data-type-map.js +20 -2
  16. package/data-types/char-type.js +15 -0
  17. package/data-types/date-type.js +4 -18
  18. package/data-types/float4-type.js +79 -1
  19. package/data-types/json-type.js +7 -12
  20. package/data-types/jsonb-type.js +7 -12
  21. package/data-types/time-type.js +2 -15
  22. package/data-types/timestamp-type.js +8 -29
  23. package/data-types/timestamptz-type.js +7 -31
  24. package/interfaces/batch-result.d.ts +1 -1
  25. package/interfaces/command-result.d.ts +21 -1
  26. package/interfaces/data-mapping-options.d.ts +16 -0
  27. package/interfaces/data-type.d.ts +11 -0
  28. package/interfaces/query-options.d.ts +25 -3
  29. package/package.json +1 -1
  30. package/protocol/frontend.d.ts +7 -0
  31. package/protocol/frontend.js +5 -3
  32. package/protocol/pg-socket.d.ts +2 -2
  33. package/protocol/pg-socket.js +12 -6
  34. package/util/channel-name.d.ts +24 -0
  35. package/util/channel-name.js +44 -0
  36. package/util/get-parsers.d.ts +2 -1
  37. package/util/get-parsers.js +16 -1
  38. package/util/resolve-column-formats.d.ts +33 -0
  39. package/util/resolve-column-formats.js +67 -0
  40. package/util/wrap-row-description.d.ts +2 -1
  41. package/util/wrap-row-description.js +7 -1
package/CHANGELOG.md CHANGED
@@ -1,6 +1,48 @@
1
1
  ## Changelog
2
2
 
3
- ### [v3.4.0](https://github.com/panates/postgrejs/compare/v3.3.0...v3.4.0) -
3
+ ### [v3.6.0](https://github.com/panates/postgrejs/compare/v3.5.0...v3.6.0) -
4
+
5
+ #### 🚀 New Features
6
+
7
+ - feat: make fetchAsString request text from the server @Eray Hanoğlu
8
+
9
+ #### 🪲 Fixes
10
+
11
+ - fix: decode float4 as the number the server would print @Eray Hanoğlu
12
+ - fix: report rowsAffected for MERGE @Eray Hanoğlu
13
+ - fix: quote LISTEN channel names instead of restricting them @Eray Hanoğlu
14
+ - fix: stop a pooled cursor's connection going back into the pool @Eray Hanoğlu
15
+ - fix: stop inferring "char" for one-character strings @Eray Hanoğlu
16
+ - fix: copy both indexes when a DataTypeMap is built from another @Eray Hanoğlu
17
+ - fix: emit 'notification' once per NOTIFY @Eray Hanoğlu
18
+ - fix: accept single-character savepoint names @Eray Hanoğlu
19
+
20
+ #### 📖 Documentation Changes
21
+
22
+ - docs: record what 3.6 changes for existing code @Eray Hanoğlu
23
+
24
+ #### 💬 General Changes
25
+
26
+ - feat!: fetch every row by default instead of the first 100 @Eray Hanoğlu
27
+
28
+ ### [v3.5.0](https://github.com/panates/postgrejs/compare/v3.4.0...v3.5.0) - 16 September 2026
29
+
30
+ #### 🚀 New Features
31
+
32
+ - feat: add transaction(fn) and let a Cursor be iterated with for await @Eray Hanoğlu
33
+
34
+ #### 📖 Documentation Changes
35
+
36
+ - docs: refresh Unit of Work after pipeline() started reusing statements @Eray Hanoğlu
37
+ - docs: record scoped transactions and cursor iteration in the README @Eray Hanoğlu
38
+ - docs: stop signing commits on the assistant's behalf @Eray Hanoğlu
39
+ - docs: note that pipeline() reuses cached prepared statements @Eray Hanoğlu
40
+
41
+ #### ⚡️ Performance Improvments
42
+
43
+ - perf: let pipeline() bind to the connection's cached statements @Eray Hanoğlu
44
+
45
+ ### [v3.4.0](https://github.com/panates/postgrejs/compare/v3.3.0...v3.4.0) - 16 September 2026
4
46
 
5
47
  - feat: add PreparedStatement.executeBatch() for multi-set execution
6
48
 
package/README.md CHANGED
@@ -59,6 +59,9 @@ $ npm install postgrejs --save
59
59
  Please read :small_orange_diamond: [DOCUMENTATION](https://www.postgrejs.com/) :small_orange_diamond: for detailed
60
60
  usage.
61
61
 
62
+ Upgrading from 3.5? See [doc/MIGRATION-v3.5-to-v3.6.md](doc/MIGRATION-v3.5-to-v3.6.md) - `query()` no longer stops at
63
+ 100 rows, and `fetchAsString` now returns the server's own text.
64
+
62
65
  ## Library Overview
63
66
 
64
67
  - **Language:** Pure JavaScript, with no native/binary dependencies to compile or ship.
@@ -82,12 +85,23 @@ usage.
82
85
  statement leaves the transaction usable instead of aborting the whole block. The `SAVEPOINT`/`RELEASE` pair travels
83
86
  in the statement's own round trip rather than costing one each - 36µs for the pair, against 507µs sent separately.
84
87
  `rollbackOnError: false` to opt out.
85
- - **Cursors:** Features fast double-link cache cursors for efficient data retrieval.
88
+ - **Complete Results:** `query()` returns every row the statement produced. A `fetchCount` limit is a limit rather
89
+ than a silent cap: the result carries `suspended: true` when the server stopped at it, so a prefix can never be
90
+ mistaken for the whole answer. `0` means unlimited, as it does in the protocol.
91
+ - **Cursors:** Features fast double-link cache cursors for efficient data retrieval, iterable with `for await` a row
92
+ at a time and closed when the loop ends - by exhaustion, a `break`, or a throw. A cursor reads through a portal, and
93
+ a portal lives as long as the transaction that created it - `Pool.query()` keeps its connection out of the pool
94
+ until the cursor closes, and on a bare `Connection` open the cursor inside a transaction if anything else will run
95
+ on that connection meanwhile.
96
+ - **Scoped Transactions:** `transaction(fn)` commits when the callback returns and rolls back when it throws, on a
97
+ connection or straight from the pool. A call made while a transaction is already open takes a savepoint rather than
98
+ a second `BEGIN`, so a nested scope that fails rolls back its own work and leaves the outer transaction standing.
86
99
  - **Batch Execution:** `executeBatch()` runs one prepared statement over many parameter sets under a single `Sync`,
87
100
  reporting each set's row count - 1000 updates in 20ms where the same calls pipelined individually take 188ms.
88
101
  - **Notifications:** High-level implementation for PostgreSQL notifications (LISTEN/NOTIFY), enabling real-time data
89
- updates.
90
- - **Extensibility:** Extensible data-types and type mapping to accommodate custom requirements.
102
+ updates. Channel names are quoted rather than pattern-matched, so any name PostgreSQL accepts works.
103
+ - **Extensibility:** Extensible data-types and type mapping to accommodate custom requirements. A type can set
104
+ `inferrable: false` to stay out of parameter type inference while still decoding its own columns.
91
105
  - **Parameter Binding:** Bind parameters with OID mappings for precise and efficient query execution.
92
106
  - **Array Handling:** Supports multidimensional arrays with fast binary encoding/decoding.
93
107
  - **Performance Optimization:** Low memory utilization and boosted performance through the use of shared buffers.
@@ -99,7 +113,8 @@ usage.
99
113
  - **Query Pipelining:** Pooled queries can share connections so a burst is not capped by pool size - opt-in per call.
100
114
  `pipeline()` goes further for a known set of statements: several different ones travel under a single `Sync`, so they
101
115
  cost one round trip instead of one each and commit or roll back together - around 2x faster than the same calls
102
- through `Promise.all()`, which is already pipelined.
116
+ through `Promise.all()`, which is already pipelined. Statements the connection has run before bind to their cached
117
+ prepared names, so a repeated set sends no `Parse` at all - worth 2.5x on twenty statements.
103
118
  - **Dynamic SQL:** A `sql` tag builds statements from composable fragments - values become parameters, names are quoted,
104
119
  and `sql.values()`/`sql.set()` write INSERT and UPDATE clauses from objects.
105
120
  - **Multiple Hosts:** A connection can list several servers and pick one by role
@@ -114,6 +129,10 @@ usage.
114
129
  `rollbackPrepared()`, from any connection.
115
130
  - **Cancellation:** Any call takes an `AbortSignal`, which also gives per-query timeouts via `AbortSignal.timeout()`.
116
131
  - **Flexible Data Retrieval:** Can return both array and object rows to suit different data processing needs.
132
+ - **Values as Text:** `fetchAsString: [DataTypeOIDs.int8]` asks the server for those columns in its own text format
133
+ and hands the bytes back unparsed - so `count(*)` arrives as `'3'`, one consistent type where a decoded `int8` is a
134
+ `number` or a `BigInt` depending on magnitude. Any OID, arrays included. The string is PostgreSQL's own rendering
135
+ rather than one reconstructed from the binary value, so it cannot drift from what the server would print.
117
136
  - **Resource Management:** Auto disposal of resources with the "using" syntax
118
137
  ([TC39 Explicit Resource Management](https://github.com/tc39/proposal-explicit-resource-management)), ensuring
119
138
  efficient resource cleanup.
@@ -162,6 +181,7 @@ in · 🟡 partial or needs a separate package · ❌ not supported.
162
181
  | Parameter type casting | ✅ | 🟡 <sup>10</sup> | ✅ |
163
182
  | Prepared statements <sup>24</sup> | ✅ automatic | ✅ manual | ✅ automatic |
164
183
  | Statement-level rollback <sup>25</sup> | ✅ automatic | ❌ | 🟡 manual |
184
+ | Scoped transaction helper <sup>26</sup> | ✅ nests | ❌ | ✅ |
165
185
  | Batch execution <sup>21</sup> | ✅ | ❌ | ❌ |
166
186
  | Multi-statement round trip <sup>23</sup> | ✅ | ❌ | ❌ |
167
187
  | Multi-statement scripts | ✅ | ✅ | ✅ |
@@ -265,6 +285,11 @@ in · 🟡 partial or needs a separate package · ❌ not supported.
265
285
  trip for each. postgres.js has savepoints, but as a scope the caller opens around a callback (`savepoint(name, fn)`
266
286
  in `src/index.js`), so a statement is protected only where someone wrapped it; pg has no savepoint handling in
267
287
  `lib/` at all, so a failed statement leaves the block aborted until the caller rolls back themselves.
288
+ - <sup>26</sup> Whether the library runs a callback inside a transaction for you, committing or rolling back on the way
289
+ out. PostgreJS has `transaction(fn)` on both a connection and the pool, and a call made inside one already open takes
290
+ a savepoint, so nesting needs nothing from the caller. postgres.js has `sql.begin(fn)` (`src/index.js`), where a
291
+ nested scope is opened explicitly with `sql.savepoint(fn)` instead. pg has no such helper in `lib/` - `BEGIN` and
292
+ `COMMIT` are statements the caller sends, and getting a transaction onto one connection is the caller's problem too.
268
293
 
269
294
 
270
295
  ## Benchmarks
@@ -282,6 +282,34 @@ export declare class Connection extends SafeEventEmitter implements AsyncDisposa
282
282
  * Starts a transaction
283
283
  */
284
284
  startTransaction(): Promise<void>;
285
+ /**
286
+ * Runs `fn` inside a transaction and commits when it returns, or rolls
287
+ * back and rethrows when it throws - the try/catch every caller of
288
+ * startTransaction()/commit()/rollback() ends up writing by hand.
289
+ *
290
+ * ```ts
291
+ * const id = await connection.transaction(async tx => {
292
+ * const r = await tx.query(
293
+ * 'insert into orders (total) values ($1) returning id',
294
+ * { params: [total] },
295
+ * );
296
+ * await tx.query('update stock set n = n - 1 where sku = $1', {
297
+ * params: [sku],
298
+ * });
299
+ * return r.rows![0][0];
300
+ * });
301
+ * ```
302
+ *
303
+ * A call made while a transaction is already open becomes a savepoint
304
+ * rather than a second BEGIN, so an inner scope that fails rolls back
305
+ * its own work and leaves the outer transaction to decide what to do -
306
+ * instead of taking everything down with it, which is what a shared
307
+ * BEGIN/ROLLBACK pair would do.
308
+ *
309
+ * `fn` is handed this same connection: every statement it runs on it is
310
+ * inside the transaction, and one it runs on another connection is not.
311
+ */
312
+ transaction<T>(fn: (connection: this) => Promise<T>): Promise<T>;
285
313
  /**
286
314
  * Commits current transaction.
287
315
  * @param immediate - Commits right away, ignoring how many nested
@@ -383,6 +411,15 @@ export declare class Connection extends SafeEventEmitter implements AsyncDisposa
383
411
  * microtask tick on top of the one `promise`/`.catch()` already goes
384
412
  * through - paid on every single query this wraps, disabled or not.
385
413
  */
414
+ /**
415
+ * The nested half of transaction(): a savepoint of its own, released on
416
+ * success and rolled back to on failure.
417
+ *
418
+ * The `inTransaction` checks are re-read rather than assumed - `fn` is
419
+ * free to commit or roll back the outer transaction itself, and there is
420
+ * no savepoint left to release once it has.
421
+ */
422
+ private _savepointScope;
386
423
  protected _captureErrorStack<T>(promise: Promise<T>, entry?: (...args: any[]) => any, asyncErrorHandling?: boolean): Promise<T>;
387
424
  [Symbol.asyncDispose](): Promise<void>;
388
425
  }
@@ -2,12 +2,16 @@ import { ConnectionState, DataTypeOIDs } from '../constants.js';
2
2
  import { GlobalTypeMap } from '../data-type-map.js';
3
3
  import { SafeEventEmitter } from '../safe-event-emitter.js';
4
4
  import { withAbortSignal } from '../util/abort-signal.js';
5
+ import { normalizeChannelName } from '../util/channel-name.js';
6
+ import { escapeIdentifier } from '../util/escape-identifier.js';
5
7
  import { QueryRequest } from '../util/sql-tag.js';
6
8
  import { BindParam } from './bind-param.js';
7
9
  import { IntlConnection } from './intl-connection.js';
8
10
  import { LargeObject, LargeObjectMode } from './large-object.js';
9
11
  import { PreparedStatement } from './prepared-statement.js';
10
12
  const CAPTURE_STACK_TRACE_LIMIT = 5;
13
+ /** Names the savepoint a nested transaction() scope takes. */
14
+ let transactionScopeCounter = 0;
11
15
  export class Connection extends SafeEventEmitter {
12
16
  _pool;
13
17
  _intlCon;
@@ -477,6 +481,50 @@ export class Connection extends SafeEventEmitter {
477
481
  startTransaction() {
478
482
  return this._captureErrorStack(this._intlCon.startTransaction());
479
483
  }
484
+ /**
485
+ * Runs `fn` inside a transaction and commits when it returns, or rolls
486
+ * back and rethrows when it throws - the try/catch every caller of
487
+ * startTransaction()/commit()/rollback() ends up writing by hand.
488
+ *
489
+ * ```ts
490
+ * const id = await connection.transaction(async tx => {
491
+ * const r = await tx.query(
492
+ * 'insert into orders (total) values ($1) returning id',
493
+ * { params: [total] },
494
+ * );
495
+ * await tx.query('update stock set n = n - 1 where sku = $1', {
496
+ * params: [sku],
497
+ * });
498
+ * return r.rows![0][0];
499
+ * });
500
+ * ```
501
+ *
502
+ * A call made while a transaction is already open becomes a savepoint
503
+ * rather than a second BEGIN, so an inner scope that fails rolls back
504
+ * its own work and leaves the outer transaction to decide what to do -
505
+ * instead of taking everything down with it, which is what a shared
506
+ * BEGIN/ROLLBACK pair would do.
507
+ *
508
+ * `fn` is handed this same connection: every statement it runs on it is
509
+ * inside the transaction, and one it runs on another connection is not.
510
+ */
511
+ async transaction(fn) {
512
+ if (this._intlCon.inTransaction)
513
+ return await this._savepointScope(fn);
514
+ await this.startTransaction();
515
+ try {
516
+ const result = await fn(this);
517
+ await this.commit();
518
+ return result;
519
+ }
520
+ catch (e) {
521
+ // A rollback that fails in turn must not replace the error that
522
+ // caused it: the connection is already in trouble, and the original
523
+ // is what the caller needs to see.
524
+ await this.rollback().catch(() => undefined);
525
+ throw e;
526
+ }
527
+ }
480
528
  /**
481
529
  * Commits current transaction.
482
530
  * @param immediate - Commits right away, ignoring how many nested
@@ -553,8 +601,7 @@ export class Connection extends SafeEventEmitter {
553
601
  return this._captureErrorStack(this._intlCon.releaseSavepoint(name, immediate));
554
602
  }
555
603
  async listen(channel, callback) {
556
- if (!/^[A-Z]\w+$/i.test(channel))
557
- throw new TypeError(`Invalid channel name`);
604
+ channel = normalizeChannelName(channel);
558
605
  if (!this._notificationListeners) {
559
606
  this._notificationListeners = new SafeEventEmitter();
560
607
  this._intlCon.on('notification', (msg) => this._handleNotification(msg));
@@ -567,14 +614,13 @@ export class Connection extends SafeEventEmitter {
567
614
  const alreadyListening = !!this._notificationListeners.listenerCount(channel);
568
615
  this._notificationListeners.on(channel, callback);
569
616
  if (!alreadyListening)
570
- await this._captureErrorStack(this.query('LISTEN ' + channel));
617
+ await this._captureErrorStack(this.query('LISTEN ' + escapeIdentifier(channel)));
571
618
  }
572
619
  async unListen(channel) {
573
- if (!/^[A-Z]\w+$/i.test(channel))
574
- throw new TypeError(`Invalid channel name`);
620
+ channel = normalizeChannelName(channel);
575
621
  if (this._notificationListeners?.listenerCount(channel)) {
576
622
  this._notificationListeners?.removeAllListeners(channel);
577
- await this._captureErrorStack(this.query('UNLISTEN ' + channel));
623
+ await this._captureErrorStack(this.query('UNLISTEN ' + escapeIdentifier(channel)));
578
624
  }
579
625
  }
580
626
  async unListenAll() {
@@ -636,7 +682,13 @@ export class Connection extends SafeEventEmitter {
636
682
  return new LargeObject(this, oid, Number(opened.rows?.[0][0]), ownsTransaction);
637
683
  }
638
684
  _handleNotification(msg) {
639
- this.emit('notification', msg);
685
+ // Deliberately no `this.emit('notification', msg)` here:
686
+ // IntlConnection.emit() re-emits every event on its owner, which is
687
+ // this Connection, so the raw event has already been delivered by the
688
+ // time this runs. Emitting it again fired 'notification' twice for one
689
+ // NOTIFY - but only once listen() had been called, since that is what
690
+ // installs this handler, so the same listener saw one event or two
691
+ // depending on whether anything else had subscribed.
640
692
  this._notificationListeners?.emit(msg.channel, msg);
641
693
  }
642
694
  async _close() {
@@ -695,6 +747,32 @@ export class Connection extends SafeEventEmitter {
695
747
  * microtask tick on top of the one `promise`/`.catch()` already goes
696
748
  * through - paid on every single query this wraps, disabled or not.
697
749
  */
750
+ /**
751
+ * The nested half of transaction(): a savepoint of its own, released on
752
+ * success and rolled back to on failure.
753
+ *
754
+ * The `inTransaction` checks are re-read rather than assumed - `fn` is
755
+ * free to commit or roll back the outer transaction itself, and there is
756
+ * no savepoint left to release once it has.
757
+ */
758
+ async _savepointScope(fn) {
759
+ const name = 'txscope' + ++transactionScopeCounter;
760
+ await this._captureErrorStack(this._intlCon.execute('SAVEPOINT ' + name));
761
+ try {
762
+ const result = await fn(this);
763
+ if (this._intlCon.inTransaction)
764
+ await this._intlCon.execute('RELEASE SAVEPOINT ' + name);
765
+ return result;
766
+ }
767
+ catch (e) {
768
+ if (this._intlCon.inTransaction) {
769
+ await this._intlCon
770
+ .execute('ROLLBACK TO SAVEPOINT ' + name + '; RELEASE SAVEPOINT ' + name)
771
+ .catch(() => undefined);
772
+ }
773
+ throw e;
774
+ }
775
+ }
698
776
  _captureErrorStack(promise, entry, asyncErrorHandling) {
699
777
  const enabled = asyncErrorHandling ?? this._intlCon.config.asyncErrorHandling ?? true;
700
778
  if (!enabled)
@@ -21,5 +21,13 @@ export declare class Cursor extends SafeEventEmitter implements AsyncDisposable
21
21
  fetch(nRows: number): Promise<Row[]>;
22
22
  close(): Promise<void>;
23
23
  private _fetchRows;
24
+ /**
25
+ * Iterates the remaining rows, fetching a batch at a time, and closes
26
+ * the cursor when the loop ends - whether it ran out of rows, broke
27
+ * early, or the body threw. Nothing is decoded ahead of what is asked
28
+ * for, so this streams a result larger than memory the same way next()
29
+ * does one row at a time.
30
+ */
31
+ [Symbol.asyncIterator](): AsyncIterableIterator<Row>;
24
32
  [Symbol.asyncDispose](): Promise<void>;
25
33
  }
@@ -69,7 +69,28 @@ export class Cursor extends SafeEventEmitter {
69
69
  await this._taskQueue
70
70
  .enqueue(async () => {
71
71
  const queryOptions = this._queryOptions;
72
- const r = await portal.execute(queryOptions.fetchCount || 100);
72
+ let r;
73
+ try {
74
+ r = await portal.execute(queryOptions.fetchCount ?? 100);
75
+ }
76
+ catch (e) {
77
+ // 34000 here means the portal is gone, and the only thing that
78
+ // takes a portal away mid-cursor is another statement on this
79
+ // connection: its Sync ends the implicit transaction the portal
80
+ // lives in. The server's own message says nothing about why, and
81
+ // a caller cannot act on it without knowing. Closing first keeps
82
+ // the statement from leaking and lets whoever is holding the
83
+ // connection for this cursor (Pool.query()) have it back.
84
+ if (e?.code === '34000') {
85
+ await this.close().catch(() => undefined);
86
+ e.message +=
87
+ ' - the portal was destroyed by another statement running on' +
88
+ ' the same connection, which ends the implicit transaction it' +
89
+ ' lives in. Open the cursor inside an explicit transaction, or' +
90
+ ' give it a connection of its own.';
91
+ }
92
+ throw e;
93
+ }
73
94
  if (r && r.rows && r.rows.length) {
74
95
  const rows = r.rows;
75
96
  if (this._parsers) {
@@ -92,6 +113,23 @@ export class Cursor extends SafeEventEmitter {
92
113
  })
93
114
  .toPromise();
94
115
  }
116
+ /**
117
+ * Iterates the remaining rows, fetching a batch at a time, and closes
118
+ * the cursor when the loop ends - whether it ran out of rows, broke
119
+ * early, or the body threw. Nothing is decoded ahead of what is asked
120
+ * for, so this streams a result larger than memory the same way next()
121
+ * does one row at a time.
122
+ */
123
+ async *[Symbol.asyncIterator]() {
124
+ try {
125
+ let row;
126
+ while ((row = await this.next()) !== undefined)
127
+ yield row;
128
+ }
129
+ finally {
130
+ await this.close();
131
+ }
132
+ }
95
133
  [Symbol.asyncDispose]() {
96
134
  return this.close();
97
135
  }
@@ -207,6 +207,11 @@ export declare class IntlConnection extends SafeEventEmitter {
207
207
  */
208
208
  protected _inlineSavepointFor(sql: string, options: QueryOptions): Maybe<string>;
209
209
  protected _queryCached(sql: string, paramTypes: Maybe<Maybe<OID>[]>, params: Maybe<Maybe<any>[]>, options: QueryOptions, savepoint: Maybe<string>): Promise<QueryResult>;
210
+ /**
211
+ * Counts one more use of this SQL and says whether it has now been seen
212
+ * often enough to be worth preparing under a name.
213
+ */
214
+ protected _earnsAName(key: string): boolean;
210
215
  /** Closes the least recently used statement once the cache is full. */
211
216
  protected _evictPreparedIfFull(): Promise<void>;
212
217
  /**
@@ -240,7 +245,7 @@ export declare class IntlConnection extends SafeEventEmitter {
240
245
  * so repeated executes of the same statement don't rebuild them.
241
246
  * Shared by executeReused() and executeBatchReused().
242
247
  */
243
- protected _resolveReusedParsers(cachedFields: Protocol.RowDescription[], typeMap: DataTypeMap, options: QueryOptions): {
248
+ protected _resolveReusedParsers(cachedFields: Protocol.RowDescription[], typeMap: DataTypeMap, options: QueryOptions, columnFormat: Protocol.DataFormat | Protocol.DataFormat[]): {
244
249
  parsers: AnyParseFunction[];
245
250
  resultFields: FieldInfo[];
246
251
  };