neon 3.0.0 → 3.1.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 (198) hide show
  1. package/README.md +54 -0
  2. package/dist/_shared/auth_selection.js +76 -79
  3. package/dist/_shared/credentials.js +166 -187
  4. package/dist/_shared/env-core/env.js +354 -517
  5. package/dist/_shared/env-core/reuse-secrets.js +159 -203
  6. package/dist/_shared/paths.js +129 -126
  7. package/dist/_shared/profiles.js +192 -242
  8. package/dist/_shared/secure_file.js +36 -38
  9. package/dist/_virtual/_rolldown/runtime.js +13 -0
  10. package/dist/analytics.js +163 -207
  11. package/dist/api.js +815 -758
  12. package/dist/auth.js +121 -141
  13. package/dist/auth_context.js +39 -53
  14. package/dist/cli.js +4 -7
  15. package/dist/commands/api.js +220 -250
  16. package/dist/commands/api_keys.js +251 -314
  17. package/dist/commands/auth.js +283 -328
  18. package/dist/commands/bootstrap.js +372 -437
  19. package/dist/commands/branches.js +304 -455
  20. package/dist/commands/bucket.js +374 -514
  21. package/dist/commands/checkout.js +213 -298
  22. package/dist/commands/config.js +573 -690
  23. package/dist/commands/connection_string.js +137 -165
  24. package/dist/commands/data_api.js +238 -260
  25. package/dist/commands/databases.js +67 -76
  26. package/dist/commands/deploy.js +31 -25
  27. package/dist/commands/dev.js +639 -719
  28. package/dist/commands/diff.js +156 -200
  29. package/dist/commands/env.js +243 -303
  30. package/dist/commands/functions.js +275 -355
  31. package/dist/commands/index.js +70 -65
  32. package/dist/commands/init.js +84 -119
  33. package/dist/commands/inspect.js +55 -55
  34. package/dist/commands/ip_allow.js +88 -120
  35. package/dist/commands/link.js +874 -1019
  36. package/dist/commands/logs.js +291 -0
  37. package/dist/commands/neon_auth.js +725 -933
  38. package/dist/commands/operations.js +34 -25
  39. package/dist/commands/orgs.js +28 -18
  40. package/dist/commands/profile.js +614 -845
  41. package/dist/commands/projects.js +313 -373
  42. package/dist/commands/psql.js +60 -58
  43. package/dist/commands/roles.js +55 -58
  44. package/dist/commands/schema_diff.js +87 -131
  45. package/dist/commands/set_context.js +34 -26
  46. package/dist/commands/snapshots.js +288 -413
  47. package/dist/commands/status.js +41 -37
  48. package/dist/commands/user.js +21 -10
  49. package/dist/commands/vpc_endpoints.js +85 -113
  50. package/dist/config.js +7 -6
  51. package/dist/config_format.js +50 -66
  52. package/dist/config_template.js +128 -157
  53. package/dist/context.js +183 -235
  54. package/dist/current_branch_fast_path.js +40 -49
  55. package/dist/dev/env.js +313 -394
  56. package/dist/dev/functions.js +54 -68
  57. package/dist/dev/inputs.js +46 -58
  58. package/dist/dev/runtime.js +135 -164
  59. package/dist/dev/websocket.js +766 -959
  60. package/dist/env.js +27 -33
  61. package/dist/env_file.js +118 -132
  62. package/dist/env_services.js +36 -38
  63. package/dist/errors.js +57 -68
  64. package/dist/functions_api.js +45 -43
  65. package/dist/help.js +189 -140
  66. package/dist/index.js +182 -257
  67. package/dist/init/agents.js +137 -118
  68. package/dist/init/auth.js +58 -68
  69. package/dist/init/bootstrap.js +325 -396
  70. package/dist/init/build_config.js +4 -2
  71. package/dist/init/detect_agent.js +56 -101
  72. package/dist/init/editors.js +35 -52
  73. package/dist/init/enrich_output.js +51 -66
  74. package/dist/init/extension.js +134 -171
  75. package/dist/init/inspect.js +179 -266
  76. package/dist/init/interactive.js +510 -622
  77. package/dist/init/neonctl.js +117 -168
  78. package/dist/init/orchestrate.js +157 -173
  79. package/dist/init/phases/auth.js +188 -202
  80. package/dist/init/phases/cleanup.js +23 -23
  81. package/dist/init/phases/db.js +251 -277
  82. package/dist/init/phases/getting_started.js +213 -223
  83. package/dist/init/phases/mcp.js +174 -224
  84. package/dist/init/phases/migrations.js +247 -248
  85. package/dist/init/phases/neon_auth.js +114 -133
  86. package/dist/init/phases/setup.js +546 -703
  87. package/dist/init/phases/skills.js +75 -86
  88. package/dist/init/phases/status.js +72 -67
  89. package/dist/init/resolve_context.js +102 -99
  90. package/dist/init/route_command.js +91 -98
  91. package/dist/init/skills.js +174 -218
  92. package/dist/init/vsix.js +77 -99
  93. package/dist/log.js +17 -16
  94. package/dist/neon_services.js +104 -129
  95. package/dist/parameters.gen.js +481 -471
  96. package/dist/pkg.js +17 -19
  97. package/dist/profile_keys.js +44 -47
  98. package/dist/psql/cli.js +44 -47
  99. package/dist/psql/command/cmd_cond.js +231 -406
  100. package/dist/psql/command/cmd_connect.js +557 -764
  101. package/dist/psql/command/cmd_copy.js +727 -983
  102. package/dist/psql/command/cmd_describe.js +1499 -1688
  103. package/dist/psql/command/cmd_format.js +733 -905
  104. package/dist/psql/command/cmd_io.js +1293 -2082
  105. package/dist/psql/command/cmd_lo.js +297 -359
  106. package/dist/psql/command/cmd_meta.js +727 -878
  107. package/dist/psql/command/cmd_misc.js +138 -172
  108. package/dist/psql/command/cmd_pipeline.js +547 -1099
  109. package/dist/psql/command/cmd_restrict.js +119 -155
  110. package/dist/psql/command/cmd_show.js +529 -688
  111. package/dist/psql/command/dispatch.js +261 -325
  112. package/dist/psql/command/inputQueue.js +35 -33
  113. package/dist/psql/command/shared.js +49 -63
  114. package/dist/psql/complete/filenames.js +90 -133
  115. package/dist/psql/complete/index.js +59 -97
  116. package/dist/psql/complete/matcher.js +236 -300
  117. package/dist/psql/complete/psqlVars.js +218 -223
  118. package/dist/psql/complete/queries.js +159 -177
  119. package/dist/psql/complete/rules.js +1493 -2299
  120. package/dist/psql/core/common.js +762 -1180
  121. package/dist/psql/core/help.js +456 -546
  122. package/dist/psql/core/mainloop.js +692 -1302
  123. package/dist/psql/core/prompt.js +391 -408
  124. package/dist/psql/core/settings.js +429 -644
  125. package/dist/psql/core/sqlHelp.js +480 -554
  126. package/dist/psql/core/startup.js +626 -815
  127. package/dist/psql/core/syncVars.js +67 -110
  128. package/dist/psql/core/variables.js +156 -278
  129. package/dist/psql/describe/formatters.js +884 -1285
  130. package/dist/psql/describe/processNamePattern.js +173 -260
  131. package/dist/psql/describe/queries.js +1368 -2403
  132. package/dist/psql/describe/versionGate.js +32 -41
  133. package/dist/psql/index.js +1414 -1927
  134. package/dist/psql/io/history.js +232 -271
  135. package/dist/psql/io/input.js +103 -108
  136. package/dist/psql/io/lineEditor/buffer.js +238 -319
  137. package/dist/psql/io/lineEditor/complete.js +135 -213
  138. package/dist/psql/io/lineEditor/filename.js +139 -148
  139. package/dist/psql/io/lineEditor/index.js +653 -870
  140. package/dist/psql/io/lineEditor/keymap.js +544 -702
  141. package/dist/psql/io/lineEditor/vt100.js +294 -341
  142. package/dist/psql/io/pgpass.js +158 -187
  143. package/dist/psql/io/pgservice.js +146 -183
  144. package/dist/psql/io/psqlrc.js +328 -403
  145. package/dist/psql/print/aligned.js +1020 -1683
  146. package/dist/psql/print/asciidoc.js +180 -214
  147. package/dist/psql/print/crosstab.js +281 -442
  148. package/dist/psql/print/csv.js +48 -70
  149. package/dist/psql/print/html.js +195 -226
  150. package/dist/psql/print/json.js +75 -88
  151. package/dist/psql/print/latex.js +291 -364
  152. package/dist/psql/print/pager.js +171 -242
  153. package/dist/psql/print/troff.js +194 -226
  154. package/dist/psql/print/unaligned.js +69 -95
  155. package/dist/psql/print/units.js +167 -169
  156. package/dist/psql/scanner/slash.js +428 -483
  157. package/dist/psql/scanner/sql.js +445 -889
  158. package/dist/psql/scanner/stringutils.js +309 -379
  159. package/dist/psql/types/index.js +2 -7
  160. package/dist/psql/types/scanner.js +25 -22
  161. package/dist/psql/wire/connection.js +2042 -2803
  162. package/dist/psql/wire/copy.js +84 -100
  163. package/dist/psql/wire/notify.js +39 -59
  164. package/dist/psql/wire/pipeline.js +305 -518
  165. package/dist/psql/wire/protocol.js +349 -417
  166. package/dist/psql/wire/sasl.js +180 -265
  167. package/dist/psql/wire/tls.js +400 -561
  168. package/dist/storage_api.js +115 -129
  169. package/dist/test_utils/fixtures.js +94 -113
  170. package/dist/test_utils/oauth_server.js +10 -7
  171. package/dist/test_utils/project_dir.js +33 -0
  172. package/dist/utils/ai_gateway_notice.js +131 -162
  173. package/dist/utils/api_enums.js +21 -28
  174. package/dist/utils/auth.js +10 -4
  175. package/dist/utils/branch_notice.js +20 -19
  176. package/dist/utils/branch_picker.js +83 -89
  177. package/dist/utils/cli_name.js +15 -12
  178. package/dist/utils/compute_units.js +20 -27
  179. package/dist/utils/config_diff.js +127 -158
  180. package/dist/utils/enrichers.js +95 -148
  181. package/dist/utils/esbuild.js +130 -189
  182. package/dist/utils/flags.js +35 -47
  183. package/dist/utils/formats.js +8 -15
  184. package/dist/utils/git_diff.js +69 -80
  185. package/dist/utils/inspect_db.js +101 -143
  186. package/dist/utils/inspect_queries.js +179 -142
  187. package/dist/utils/middlewares.js +37 -44
  188. package/dist/utils/openapi.js +87 -99
  189. package/dist/utils/package_manager.js +312 -110
  190. package/dist/utils/point_in_time.js +49 -53
  191. package/dist/utils/psql.js +89 -106
  192. package/dist/utils/service_picker.js +55 -58
  193. package/dist/utils/string.js +5 -5
  194. package/dist/utils/ui.js +38 -55
  195. package/dist/utils/write_sync.js +26 -35
  196. package/dist/utils/zip.js +4 -3
  197. package/dist/writer.js +67 -87
  198. package/package.json +7 -5
@@ -1,1815 +1,1626 @@
1
- /**
2
- * psql `\d*` describe-command dispatchers.
3
- *
4
- * Each command takes an optional pattern, parses verbose / show-system
5
- * suffixes from the command name, runs the appropriate SQL template
6
- * from {@link '../describe/queries.js'} through the pattern parser, and
7
- * prints the result via the aligned printer.
8
- *
9
- * Command name suffix decoding:
10
- *
11
- * - Trailing `+` → `verbose=true` (extra columns)
12
- * - Trailing `S` → `showSystem=true` (include `pg_*` schemas)
13
- * - Both may combine: `\dtS+`, `\dt+S`, etc.
14
- *
15
- * Dispatch model: every `\d*` family registers itself as a separate
16
- * primary name (e.g. `dt`, `dt+`, `dtS`, `dtS+`). That's not how psql
17
- * itself does it — psql parses a single `\d` token and then peels off
18
- * letter-by-letter — but our `BackslashRegistry` is keyed by full
19
- * command name and is much easier to read this way. The semantic
20
- * outcome is identical.
21
- *
22
- * For `\d <name>` (the bare describe), we look the relation up via
23
- * {@link lookupOneRelation} and dispatch to the right `describeOne*`
24
- * renderer based on relkind:
25
- *
26
- * - 'r' / 'p' / 'f' (regular, partitioned, foreign) →
27
- * {@link describeOneTableDetails}
28
- * - 'v' → {@link describeOneViewDetails}
29
- * - 'S' → {@link describeOneSequence}
30
- * - 'i' / 'I' (index, partitioned index) → table-detail with index header
31
- * - 'm' → table-detail with materialized-view header
32
- *
33
- * Connection guard: every command checks `ctx.settings.db` is non-null
34
- * and emits `\<cmd>: no current connection` to stderr on miss.
35
- */
36
- import { describeOneSequence, describeOneTableDetails, describeOneViewDetails, lookupOneRelation, runListQuery, } from "../describe/formatters.js";
37
- import { processSQLNamePattern, } from "../describe/processNamePattern.js";
38
- import { describeAccessMethods, describeAggregates, describeConfigurationParameters, describeFunctions, describeOperators, describeRoleGrants, describeRoles, describeSubscriptions, describeTableDetails, describeTablespaces, describeTypes, listAllDbs, listCasts, listCollations, listConversions, listDbRoleSettings, listDefaultACLs, listDomains, listEventTriggers, listExtendedStats, listExtensions, listForeignDataWrappers, listForeignServers, listForeignTables, listLanguages, listLargeObjects, listOperatorClasses, listOperatorFamilies, listOpFamilyFunctions, listOpFamilyOperators, listPartitionedTables, listPublications, listSchemas, listTables, listTSConfigs, listTSDictionaries, listTSParsers, listTSTemplates, listUserMappings, objectDescription, permissionsList, } from "../describe/queries.js";
39
1
  import { writeErr } from "./shared.js";
2
+ import { processSQLNamePattern } from "../describe/processNamePattern.js";
3
+ import { describeAccessMethods, describeAggregates, describeConfigurationParameters, describeFunctions, describeOperators, describeRoleGrants, describeRoles, describeSubscriptions, describeTableDetails, describeTablespaces, describeTypes, listAllDbs, listCasts, listCollations, listConversions, listDbRoleSettings, listDefaultACLs, listDomains, listEventTriggers, listExtendedStats, listExtensions, listForeignDataWrappers, listForeignServers, listForeignTables, listLanguages, listLargeObjects, listOpFamilyFunctions, listOpFamilyOperators, listOperatorClasses, listOperatorFamilies, listPartitionedTables, listPublications, listSchemas, listTSConfigs, listTSDictionaries, listTSParsers, listTSTemplates, listTables, listUserMappings, objectDescription, permissionsList } from "../describe/queries.js";
4
+ import { describeOneSequence, describeOneTableDetails, describeOneViewDetails, lookupOneRelation, runListQuery } from "../describe/formatters.js";
5
+ //#region src/psql/command/cmd_describe.ts
6
+ /**
7
+ * psql `\d*` describe-command dispatchers.
8
+ *
9
+ * Each command takes an optional pattern, parses verbose / show-system
10
+ * suffixes from the command name, runs the appropriate SQL template
11
+ * from {@link '../describe/queries.js'} through the pattern parser, and
12
+ * prints the result via the aligned printer.
13
+ *
14
+ * Command name suffix decoding:
15
+ *
16
+ * - Trailing `+` → `verbose=true` (extra columns)
17
+ * - Trailing `S` → `showSystem=true` (include `pg_*` schemas)
18
+ * - Both may combine: `\dtS+`, `\dt+S`, etc.
19
+ *
20
+ * Dispatch model: every `\d*` family registers itself as a separate
21
+ * primary name (e.g. `dt`, `dt+`, `dtS`, `dtS+`). That's not how psql
22
+ * itself does it — psql parses a single `\d` token and then peels off
23
+ * letter-by-letter — but our `BackslashRegistry` is keyed by full
24
+ * command name and is much easier to read this way. The semantic
25
+ * outcome is identical.
26
+ *
27
+ * For `\d <name>` (the bare describe), we look the relation up via
28
+ * {@link lookupOneRelation} and dispatch to the right `describeOne*`
29
+ * renderer based on relkind:
30
+ *
31
+ * - 'r' / 'p' / 'f' (regular, partitioned, foreign) →
32
+ * {@link describeOneTableDetails}
33
+ * - 'v' → {@link describeOneViewDetails}
34
+ * - 'S' → {@link describeOneSequence}
35
+ * - 'i' / 'I' (index, partitioned index) → table-detail with index header
36
+ * - 'm' → table-detail with materialized-view header
37
+ *
38
+ * Connection guard: every command checks `ctx.settings.db` is non-null
39
+ * and emits `\<cmd>: no current connection` to stderr on miss.
40
+ */
40
41
  /**
41
- * Helper: split a `\dXY+` command name into base, verbose, showSystem.
42
- *
43
- * "dtS+" → { base: "dt", verbose: true, showSystem: true }
44
- * "df+" → { base: "df", verbose: true, showSystem: false }
45
- * "dnS" → { base: "dn", verbose: false, showSystem: true }
46
- */
42
+ * Helper: split a `\dXY+` command name into base, verbose, showSystem.
43
+ *
44
+ * "dtS+" → { base: "dt", verbose: true, showSystem: true }
45
+ * "df+" → { base: "df", verbose: true, showSystem: false }
46
+ * "dnS" → { base: "dn", verbose: false, showSystem: true }
47
+ */
47
48
  const decodeSuffix = (cmdName, base) => {
48
- const tail = cmdName.slice(base.length);
49
- let verbose = false;
50
- let showSystem = false;
51
- // Suffix order is unrestricted in psql.
52
- for (const ch of tail) {
53
- if (ch === "+")
54
- verbose = true;
55
- else if (ch === "S")
56
- showSystem = true;
57
- }
58
- return { verbose, showSystem };
49
+ const tail = cmdName.slice(base.length);
50
+ let verbose = false;
51
+ let showSystem = false;
52
+ for (const ch of tail) if (ch === "+") verbose = true;
53
+ else if (ch === "S") showSystem = true;
54
+ return {
55
+ verbose,
56
+ showSystem
57
+ };
59
58
  };
60
59
  /** Resolve the current connection or null. */
61
60
  const conn = (ctx) => ctx.settings.db;
62
61
  /** Emit "no current connection" error. */
63
62
  const noConn = (ctx) => {
64
- writeErr(`\\${ctx.cmdName}: no current connection\n`);
65
- return { status: "error", errorWritten: true };
63
+ writeErr(`\\${ctx.cmdName}: no current connection\n`);
64
+ return {
65
+ status: "error",
66
+ errorWritten: true
67
+ };
66
68
  };
67
69
  /**
68
- * Read the connection's current database. Mirrors upstream's
69
- * `PQdb(pset.db)` — used by the cross-database check. PgConnection
70
- * exposes `database` as a getter; mocks typically pass it as a record
71
- * property. Returns `''` on miss; callers compare case-sensitively
72
- * (matching upstream's `strcmp`).
73
- */
70
+ * Read the connection's current database. Mirrors upstream's
71
+ * `PQdb(pset.db)` — used by the cross-database check. PgConnection
72
+ * exposes `database` as a getter; mocks typically pass it as a record
73
+ * property. Returns `''` on miss; callers compare case-sensitively
74
+ * (matching upstream's `strcmp`).
75
+ */
74
76
  const currentDb = (c) => {
75
- const meta = c;
76
- return typeof meta.database === "string" ? meta.database : "";
77
+ const meta = c;
78
+ return typeof meta.database === "string" ? meta.database : "";
77
79
  };
78
80
  /**
79
- * Validate a `processSQLNamePattern` result against the command's max
80
- * dotted-name budget. Mirrors the dot-count check upstream's
81
- * `processSQLNamePattern` performs after parsing:
82
- *
83
- * - `dotCount > maxDots` → "improper qualified name (too many dotted names)"
84
- * - `dotCount == 2 && maxDots == 2 && dbLiteral != current_db` →
85
- * "cross-database references are not implemented"
86
- *
87
- * Pass `maxDots = 0` for commands that don't accept schema-qualified
88
- * patterns (`\dA`, `\dx`, `\dn`, `\db`, `\des`, …). Pass `maxDots = 2`
89
- * for the schema-qualified-with-db family (`\dt`, `\df`, `\dD`, …) so
90
- * the 2-dot case emits the dedicated cross-database error rather than
91
- * a generic "too many" message.
92
- *
93
- * Returns `null` on success; the formatted error string otherwise.
94
- */
81
+ * Validate a `processSQLNamePattern` result against the command's max
82
+ * dotted-name budget. Mirrors the dot-count check upstream's
83
+ * `processSQLNamePattern` performs after parsing:
84
+ *
85
+ * - `dotCount > maxDots` → "improper qualified name (too many dotted names)"
86
+ * - `dotCount == 2 && maxDots == 2 && dbLiteral != current_db` →
87
+ * "cross-database references are not implemented"
88
+ *
89
+ * Pass `maxDots = 0` for commands that don't accept schema-qualified
90
+ * patterns (`\dA`, `\dx`, `\dn`, `\db`, `\des`, …). Pass `maxDots = 2`
91
+ * for the schema-qualified-with-db family (`\dt`, `\df`, `\dD`, …) so
92
+ * the 2-dot case emits the dedicated cross-database error rather than
93
+ * a generic "too many" message.
94
+ *
95
+ * Returns `null` on success; the formatted error string otherwise.
96
+ */
95
97
  const validatePattern = (pattern, result, maxDots, curDb) => {
96
- if (pattern === null)
97
- return null;
98
- if (result.dotCount > maxDots) {
99
- return `improper qualified name (too many dotted names): ${pattern}`;
100
- }
101
- if (maxDots >= 1 &&
102
- result.dotCount === maxDots &&
103
- result.dbLiteral !== null &&
104
- result.dbLiteral !== curDb) {
105
- return `cross-database references are not implemented: ${pattern}`;
106
- }
107
- return null;
98
+ if (pattern === null) return null;
99
+ if (result.dotCount > maxDots) return `improper qualified name (too many dotted names): ${pattern}`;
100
+ if (maxDots >= 1 && result.dotCount === maxDots && result.dbLiteral !== null && result.dbLiteral !== curDb) return `cross-database references are not implemented: ${pattern}`;
101
+ return null;
108
102
  };
109
103
  const runWithPattern = async (ctx, pattern, query, patternOpts, maxDots = 2, overrides = {}) => {
110
- const c = conn(ctx);
111
- if (!c)
112
- return noConn(ctx);
113
- const result = processSQLNamePattern({ ...patternOpts, pattern });
114
- const dotErr = validatePattern(pattern, result, maxDots, currentDb(c));
115
- if (dotErr !== null) {
116
- writeErr(`${dotErr}\n`);
117
- return { status: "error", errorWritten: true };
118
- }
119
- try {
120
- const basePopt = ctx.settings.popt;
121
- const popt = overrides.suppressDefaultFooter
122
- ? { ...basePopt, topt: { ...basePopt.topt, defaultFooter: false } }
123
- : basePopt;
124
- await runListQuery(c, query, result, process.stdout, popt);
125
- return { status: "ok" };
126
- }
127
- catch (err) {
128
- writeErr(`\\${ctx.cmdName}: ${errMsg(err)}\n`);
129
- return { status: "error", errorWritten: true };
130
- }
104
+ const c = conn(ctx);
105
+ if (!c) return noConn(ctx);
106
+ const result = processSQLNamePattern({
107
+ ...patternOpts,
108
+ pattern
109
+ });
110
+ const dotErr = validatePattern(pattern, result, maxDots, currentDb(c));
111
+ if (dotErr !== null) {
112
+ writeErr(`${dotErr}\n`);
113
+ return {
114
+ status: "error",
115
+ errorWritten: true
116
+ };
117
+ }
118
+ try {
119
+ const basePopt = ctx.settings.popt;
120
+ const popt = overrides.suppressDefaultFooter ? {
121
+ ...basePopt,
122
+ topt: {
123
+ ...basePopt.topt,
124
+ defaultFooter: false
125
+ }
126
+ } : basePopt;
127
+ await runListQuery(c, query, result, process.stdout, popt);
128
+ return { status: "ok" };
129
+ } catch (err) {
130
+ writeErr(`\\${ctx.cmdName}: ${errMsg(err)}\n`);
131
+ return {
132
+ status: "error",
133
+ errorWritten: true
134
+ };
135
+ }
131
136
  };
132
137
  /**
133
- * Apply two distinct {@link NamePatternResult}s to a query that emits two
134
- * placeholder occurrences (one per pattern). Mirrors `applyPattern` but
135
- * threads each result into a single occurrence so they can carry
136
- * different column targets (e.g. `\dAc <am> <type>` filters
137
- * `am.amname` first and `t.typname` second). When a slot's result
138
- * carries no conditions we substitute the `true` tautology so the
139
- * surrounding `AND`/`WHERE` chain stays well-formed.
140
- *
141
- * Returns a query string with the placeholders replaced and a unified
142
- * parameter list renumbered so `$N` references stay distinct.
143
- */
138
+ * Apply two distinct {@link NamePatternResult}s to a query that emits two
139
+ * placeholder occurrences (one per pattern). Mirrors `applyPattern` but
140
+ * threads each result into a single occurrence so they can carry
141
+ * different column targets (e.g. `\dAc <am> <type>` filters
142
+ * `am.amname` first and `t.typname` second). When a slot's result
143
+ * carries no conditions we substitute the `true` tautology so the
144
+ * surrounding `AND`/`WHERE` chain stays well-formed.
145
+ *
146
+ * Returns a query string with the placeholders replaced and a unified
147
+ * parameter list renumbered so `$N` references stay distinct.
148
+ */
144
149
  const applyTwoPatterns = (sql, baseParams, results) => {
145
- const placeholder = "true /* TODO(WP-20): pattern matching */";
146
- let rendered = sql;
147
- const params = [...baseParams];
148
- for (const result of results) {
149
- const idx = rendered.indexOf(placeholder);
150
- if (idx < 0)
151
- break;
152
- const conds = [
153
- ...result.schemaConditions,
154
- ...result.nameConditions,
155
- ...result.visibilityConditions,
156
- ];
157
- const slotOffset = params.length;
158
- const renumbered = conds.map((c) => c.replace(/\$(\d+)/g, (_, n) => `$${Number(n) + slotOffset}`));
159
- params.push(...result.params);
160
- const replacement = renumbered.length === 0 ? "true" : `(${renumbered.join(" AND ")})`;
161
- rendered =
162
- rendered.slice(0, idx) +
163
- replacement +
164
- rendered.slice(idx + placeholder.length);
165
- }
166
- return { sql: rendered, params };
150
+ const placeholder = "true /* TODO(WP-20): pattern matching */";
151
+ let rendered = sql;
152
+ const params = [...baseParams];
153
+ for (const result of results) {
154
+ const idx = rendered.indexOf(placeholder);
155
+ if (idx < 0) break;
156
+ const conds = [
157
+ ...result.schemaConditions,
158
+ ...result.nameConditions,
159
+ ...result.visibilityConditions
160
+ ];
161
+ const slotOffset = params.length;
162
+ const renumbered = conds.map((c) => c.replace(/\$(\d+)/g, (_, n) => `$${Number(n) + slotOffset}`));
163
+ params.push(...result.params);
164
+ const replacement = renumbered.length === 0 ? "true" : `(${renumbered.join(" AND ")})`;
165
+ rendered = rendered.slice(0, idx) + replacement + rendered.slice(idx + 40);
166
+ }
167
+ return {
168
+ sql: rendered,
169
+ params
170
+ };
167
171
  };
168
172
  /**
169
- * Run a list query with two distinct pattern slots. Builds the final
170
- * SQL via {@link applyTwoPatterns}, hands it to {@link runListQuery}
171
- * with an empty pattern result (so the second-pass `applyPattern` is a
172
- * no-op — all placeholders are already resolved).
173
- *
174
- * Note: we discard the query builder's `params` because the two-pattern
175
- * builders (`listOperatorClasses`, `listDbRoleSettings`) emit the raw
176
- * user strings there as a courtesy for single-pattern callers. The
177
- * regex-converted values come from `results[*].params` instead, so
178
- * threading the originals would introduce unreferenced bind values.
179
- */
173
+ * Run a list query with two distinct pattern slots. Builds the final
174
+ * SQL via {@link applyTwoPatterns}, hands it to {@link runListQuery}
175
+ * with an empty pattern result (so the second-pass `applyPattern` is a
176
+ * no-op — all placeholders are already resolved).
177
+ *
178
+ * Note: we discard the query builder's `params` because the two-pattern
179
+ * builders (`listOperatorClasses`, `listDbRoleSettings`) emit the raw
180
+ * user strings there as a courtesy for single-pattern callers. The
181
+ * regex-converted values come from `results[*].params` instead, so
182
+ * threading the originals would introduce unreferenced bind values.
183
+ */
180
184
  const runDualPatternList = async (ctx, query, results) => {
181
- const c = conn(ctx);
182
- if (!c)
183
- return noConn(ctx);
184
- const { sql, params } = applyTwoPatterns(query.sql, [], results);
185
- const finalQuery = {
186
- ...query,
187
- sql,
188
- params,
189
- };
190
- const empty = {
191
- schemaConditions: [],
192
- nameConditions: [],
193
- visibilityConditions: [],
194
- params: [],
195
- dotCount: 0,
196
- dbLiteral: null,
197
- };
198
- try {
199
- await runListQuery(c, finalQuery, empty, process.stdout, ctx.settings.popt);
200
- return { status: "ok" };
201
- }
202
- catch (err) {
203
- writeErr(`\\${ctx.cmdName}: ${errMsg(err)}\n`);
204
- return { status: "error", errorWritten: true };
205
- }
185
+ const c = conn(ctx);
186
+ if (!c) return noConn(ctx);
187
+ const { sql, params } = applyTwoPatterns(query.sql, [], results);
188
+ const finalQuery = {
189
+ ...query,
190
+ sql,
191
+ params
192
+ };
193
+ const empty = {
194
+ schemaConditions: [],
195
+ nameConditions: [],
196
+ visibilityConditions: [],
197
+ params: [],
198
+ dotCount: 0,
199
+ dbLiteral: null
200
+ };
201
+ try {
202
+ await runListQuery(c, finalQuery, empty, process.stdout, ctx.settings.popt);
203
+ return { status: "ok" };
204
+ } catch (err) {
205
+ writeErr(`\\${ctx.cmdName}: ${errMsg(err)}\n`);
206
+ return {
207
+ status: "error",
208
+ errorWritten: true
209
+ };
210
+ }
206
211
  };
207
212
  /**
208
- * Apply per-argument type patterns into the `ARG_PATTERN_<i>`
209
- * placeholders emitted by {@link describeFunctions} and
210
- * {@link describeOperators}. Each non-`-` arg pattern produces a set of
211
- * conditions against the `t<i>` / `nt<i>` join, matched against
212
- * `typname`, `nt<i>.nspname`, and the formatted-type expression — same
213
- * semantics as upstream's `validateSQLNamePattern(... ft, tiv, ...)`
214
- * call in `describe.c`. `-` slots emit a literal `typname IS NULL`
215
- * check at SQL build time and don't generate any conditions here.
216
- *
217
- * Returns the rewritten SQL plus the merged parameter list (renumbered
218
- * so `$N` slots from each arg pattern don't collide with prior slots).
219
- */
213
+ * Apply per-argument type patterns into the `ARG_PATTERN_<i>`
214
+ * placeholders emitted by {@link describeFunctions} and
215
+ * {@link describeOperators}. Each non-`-` arg pattern produces a set of
216
+ * conditions against the `t<i>` / `nt<i>` join, matched against
217
+ * `typname`, `nt<i>.nspname`, and the formatted-type expression — same
218
+ * semantics as upstream's `validateSQLNamePattern(... ft, tiv, ...)`
219
+ * call in `describe.c`. `-` slots emit a literal `typname IS NULL`
220
+ * check at SQL build time and don't generate any conditions here.
221
+ *
222
+ * Returns the rewritten SQL plus the merged parameter list (renumbered
223
+ * so `$N` slots from each arg pattern don't collide with prior slots).
224
+ */
220
225
  const applyArgPatterns = (sql, baseParams, argResults) => {
221
- let rendered = sql;
222
- const params = [...baseParams];
223
- for (let i = 0; i < argResults.length; i++) {
224
- const placeholder = `true /* ARG_PATTERN_${i} */`;
225
- const idx = rendered.indexOf(placeholder);
226
- if (idx < 0)
227
- continue;
228
- const r = argResults[i];
229
- let replacement = "true";
230
- if (r !== null) {
231
- const conds = [
232
- ...r.schemaConditions,
233
- ...r.nameConditions,
234
- ...r.visibilityConditions,
235
- ];
236
- if (conds.length > 0) {
237
- const slotOffset = params.length;
238
- const renumbered = conds.map((c) => c.replace(/\$(\d+)/g, (_, n) => `$${Number(n) + slotOffset}`));
239
- params.push(...r.params);
240
- replacement = `(${renumbered.join(" AND ")})`;
241
- }
242
- }
243
- rendered =
244
- rendered.slice(0, idx) +
245
- replacement +
246
- rendered.slice(idx + placeholder.length);
247
- }
248
- return { sql: rendered, params };
226
+ let rendered = sql;
227
+ const params = [...baseParams];
228
+ for (let i = 0; i < argResults.length; i++) {
229
+ const placeholder = `true /* ARG_PATTERN_${i} */`;
230
+ const idx = rendered.indexOf(placeholder);
231
+ if (idx < 0) continue;
232
+ const r = argResults[i];
233
+ let replacement = "true";
234
+ if (r !== null) {
235
+ const conds = [
236
+ ...r.schemaConditions,
237
+ ...r.nameConditions,
238
+ ...r.visibilityConditions
239
+ ];
240
+ if (conds.length > 0) {
241
+ const slotOffset = params.length;
242
+ const renumbered = conds.map((c) => c.replace(/\$(\d+)/g, (_, n) => `$${Number(n) + slotOffset}`));
243
+ params.push(...r.params);
244
+ replacement = `(${renumbered.join(" AND ")})`;
245
+ }
246
+ }
247
+ rendered = rendered.slice(0, idx) + replacement + rendered.slice(idx + placeholder.length);
248
+ }
249
+ return {
250
+ sql: rendered,
251
+ params
252
+ };
249
253
  };
250
254
  /**
251
- * Upstream `map_typename_pattern()`: a few aliases the user can type
252
- * (`int`, `float`, `decimal`, …) get rewritten to the canonical type
253
- * names that appear in `pg_type.typname` / `format_type()`. Mirrors
254
- * `describe.c::map_typename_pattern`. Pattern matching is otherwise
255
- * literal, so this is the only place the user's input gets rewritten.
256
- */
255
+ * Upstream `map_typename_pattern()`: a few aliases the user can type
256
+ * (`int`, `float`, `decimal`, …) get rewritten to the canonical type
257
+ * names that appear in `pg_type.typname` / `format_type()`. Mirrors
258
+ * `describe.c::map_typename_pattern`. Pattern matching is otherwise
259
+ * literal, so this is the only place the user's input gets rewritten.
260
+ */
257
261
  const TYPENAME_ALIASES = {
258
- decimal: "numeric",
259
- float: "double precision",
260
- int: "integer",
261
- "bool[]": "boolean[]",
262
- "decimal[]": "numeric[]",
263
- "float[]": "double precision[]",
264
- "float4[]": "real[]",
265
- "float8[]": "double precision[]",
266
- "int[]": "integer[]",
267
- "int2[]": "smallint[]",
268
- "int4[]": "integer[]",
269
- "int8[]": "bigint[]",
270
- "time[]": "time without time zone[]",
271
- "timetz[]": "time with time zone[]",
272
- "timestamp[]": "timestamp without time zone[]",
273
- "timestamptz[]": "timestamp with time zone[]",
274
- "varbit[]": "bit varying[]",
275
- "varchar[]": "character varying[]",
262
+ decimal: "numeric",
263
+ float: "double precision",
264
+ int: "integer",
265
+ "bool[]": "boolean[]",
266
+ "decimal[]": "numeric[]",
267
+ "float[]": "double precision[]",
268
+ "float4[]": "real[]",
269
+ "float8[]": "double precision[]",
270
+ "int[]": "integer[]",
271
+ "int2[]": "smallint[]",
272
+ "int4[]": "integer[]",
273
+ "int8[]": "bigint[]",
274
+ "time[]": "time without time zone[]",
275
+ "timetz[]": "time with time zone[]",
276
+ "timestamp[]": "timestamp without time zone[]",
277
+ "timestamptz[]": "timestamp with time zone[]",
278
+ "varbit[]": "bit varying[]",
279
+ "varchar[]": "character varying[]"
276
280
  };
277
281
  const mapTypenamePattern = (pattern) => TYPENAME_ALIASES[pattern.toLowerCase()] ?? pattern;
278
282
  /**
279
- * Process a per-argument type pattern slot for `\df` / `\do`. `-`
280
- * returns null (the SQL builder handles the literal `IS NULL` check);
281
- * any other value goes through {@link processSQLNamePattern} configured
282
- * with the `t<i>` / `nt<i>` join columns and the formatted-type
283
- * altnamevar so `\df foo int4` matches `oid -> integer` correctly.
284
- */
283
+ * Process a per-argument type pattern slot for `\df` / `\do`. `-`
284
+ * returns null (the SQL builder handles the literal `IS NULL` check);
285
+ * any other value goes through {@link processSQLNamePattern} configured
286
+ * with the `t<i>` / `nt<i>` join columns and the formatted-type
287
+ * altnamevar so `\df foo int4` matches `oid -> integer` correctly.
288
+ */
285
289
  const processArgPattern = (slot, raw) => {
286
- if (raw === "-")
287
- return null;
288
- const mapped = mapTypenamePattern(raw);
289
- return processSQLNamePattern({
290
- pattern: mapped,
291
- schemavar: `nt${slot}.nspname`,
292
- namevar: `t${slot}.typname`,
293
- altnamevar: `pg_catalog.format_type(t${slot}.oid, NULL)`,
294
- visibilityrule: `pg_catalog.pg_type_is_visible(t${slot}.oid)`,
295
- });
290
+ if (raw === "-") return null;
291
+ const mapped = mapTypenamePattern(raw);
292
+ return processSQLNamePattern({
293
+ pattern: mapped,
294
+ schemavar: `nt${slot}.nspname`,
295
+ namevar: `t${slot}.typname`,
296
+ altnamevar: `pg_catalog.format_type(t${slot}.oid, NULL)`,
297
+ visibilityrule: `pg_catalog.pg_type_is_visible(t${slot}.oid)`
298
+ });
296
299
  };
297
300
  /**
298
- * Drive a `\df` / `\do` style command: collect the main pattern, then
299
- * any extra args as per-arg type filters, splice them all into the
300
- * query, and print. Returns the collected arg patterns so the SQL
301
- * builder upstream can mirror them as joins.
302
- */
301
+ * Drive a `\df` / `\do` style command: collect the main pattern, then
302
+ * any extra args as per-arg type filters, splice them all into the
303
+ * query, and print. Returns the collected arg patterns so the SQL
304
+ * builder upstream can mirror them as joins.
305
+ */
303
306
  const collectArgPatterns = (ctx) => {
304
- const args = [];
305
- // Upstream caps `\do` at 2 args internally but reads all of them
306
- // from the scanner; describeFunctions caps at FUNC_MAX_ARGS (100).
307
- // We let the caller decide what to do with extras (mostly: ignore).
308
- for (;;) {
309
- const arg = ctx.nextArg("normal");
310
- if (arg === null)
311
- break;
312
- args.push(arg);
313
- }
314
- return args;
307
+ const args = [];
308
+ for (;;) {
309
+ const arg = ctx.nextArg("normal");
310
+ if (arg === null) break;
311
+ args.push(arg);
312
+ }
313
+ return args;
315
314
  };
316
315
  /**
317
- * Run a `\df` / `\do` query: handles the main pattern AND the per-arg
318
- * type filters in one go. Mirrors {@link runWithPattern}, but also
319
- * threads per-arg `NamePatternResult`s into the `ARG_PATTERN_<i>`
320
- * placeholders before handing off to {@link runListQuery}.
321
- */
316
+ * Run a `\df` / `\do` query: handles the main pattern AND the per-arg
317
+ * type filters in one go. Mirrors {@link runWithPattern}, but also
318
+ * threads per-arg `NamePatternResult`s into the `ARG_PATTERN_<i>`
319
+ * placeholders before handing off to {@link runListQuery}.
320
+ */
322
321
  const runFunctionOrOperatorQuery = async (ctx, pattern, argPatternResults, query, patternOpts) => {
323
- const c = conn(ctx);
324
- if (!c)
325
- return noConn(ctx);
326
- const result = processSQLNamePattern({ ...patternOpts, pattern });
327
- const dotErr = validatePattern(pattern, result, 2, currentDb(c));
328
- if (dotErr !== null) {
329
- writeErr(`${dotErr}\n`);
330
- return { status: "error", errorWritten: true };
331
- }
332
- // Substitute the arg-pattern placeholders first so the params they
333
- // contribute precede the main pattern's `$N` allocations.
334
- const { sql, params } = applyArgPatterns(query.sql, query.params, argPatternResults);
335
- const finalQuery = {
336
- ...query,
337
- sql,
338
- params,
339
- };
340
- try {
341
- await runListQuery(c, finalQuery, result, process.stdout, ctx.settings.popt);
342
- return { status: "ok" };
343
- }
344
- catch (err) {
345
- writeErr(`\\${ctx.cmdName}: ${errMsg(err)}\n`);
346
- return { status: "error", errorWritten: true };
347
- }
322
+ const c = conn(ctx);
323
+ if (!c) return noConn(ctx);
324
+ const result = processSQLNamePattern({
325
+ ...patternOpts,
326
+ pattern
327
+ });
328
+ const dotErr = validatePattern(pattern, result, 2, currentDb(c));
329
+ if (dotErr !== null) {
330
+ writeErr(`${dotErr}\n`);
331
+ return {
332
+ status: "error",
333
+ errorWritten: true
334
+ };
335
+ }
336
+ const { sql, params } = applyArgPatterns(query.sql, query.params, argPatternResults);
337
+ const finalQuery = {
338
+ ...query,
339
+ sql,
340
+ params
341
+ };
342
+ try {
343
+ await runListQuery(c, finalQuery, result, process.stdout, ctx.settings.popt);
344
+ return { status: "ok" };
345
+ } catch (err) {
346
+ writeErr(`\\${ctx.cmdName}: ${errMsg(err)}\n`);
347
+ return {
348
+ status: "error",
349
+ errorWritten: true
350
+ };
351
+ }
348
352
  };
349
353
  const errMsg = (err) => err instanceof Error ? err.message : String(err);
350
- // ===========================================================================
351
- // Individual command specs
352
- // ===========================================================================
353
- // ---- \d / \d <name> / \dt / \di / \dv / \dm / \ds / \dE -------------------
354
354
  /** Bare `\d [pattern]` — list-or-detail. */
355
355
  const makeDescribeCmd = (baseName) => ({
356
- name: baseName,
357
- run: async (ctx) => {
358
- const pattern = ctx.nextArg("normal");
359
- const c = conn(ctx);
360
- if (!c)
361
- return noConn(ctx);
362
- const { verbose, showSystem } = decodeSuffix(ctx.cmdName, baseName);
363
- // If pattern looks like a single concrete name (no wildcards),
364
- // try a per-relation detail; otherwise list.
365
- if (pattern && !/[*?]/.test(pattern)) {
366
- // Pass the raw pattern straight through — lookupOneRelation folds /
367
- // dequotes / splits schema.name via processSQLNamePattern.
368
- try {
369
- const rel = await lookupOneRelation(c, pattern);
370
- if (rel) {
371
- await dispatchDetail(ctx, c, rel, verbose);
372
- return { status: "ok" };
373
- }
374
- }
375
- catch (err) {
376
- writeErr(`\\${ctx.cmdName}: ${errMsg(err)}\n`);
377
- return { status: "error", errorWritten: true };
378
- }
379
- // Fall through to list (mirrors upstream behaviour: if no exact
380
- // relation, treat the name as a list pattern).
381
- }
382
- // `\d`-family `x` suffix toggles expanded mode for the LIST view
383
- // only — upstream `command.c` declines to apply it when a pattern is
384
- // present and would dispatch to per-relation detail rendering.
385
- const forceExpanded = ctx.cmdName.slice(baseName.length).includes("x") &&
386
- pattern === null;
387
- const savedPopt = ctx.settings.popt;
388
- if (forceExpanded) {
389
- ctx.settings.popt = {
390
- ...savedPopt,
391
- topt: { ...savedPopt.topt, expanded: "on" },
392
- };
393
- }
394
- try {
395
- // List mode — use either describeTableDetails (for bare \d) or
396
- // listTables(tabtypes=...) for the typed variants.
397
- return await runTypedList(ctx, c, baseName, pattern, verbose, showSystem);
398
- }
399
- finally {
400
- ctx.settings.popt = savedPopt;
401
- }
402
- },
356
+ name: baseName,
357
+ run: async (ctx) => {
358
+ const pattern = ctx.nextArg("normal");
359
+ const c = conn(ctx);
360
+ if (!c) return noConn(ctx);
361
+ const { verbose, showSystem } = decodeSuffix(ctx.cmdName, baseName);
362
+ if (pattern && !/[*?]/.test(pattern)) try {
363
+ const rel = await lookupOneRelation(c, pattern);
364
+ if (rel) {
365
+ await dispatchDetail(ctx, c, rel, verbose);
366
+ return { status: "ok" };
367
+ }
368
+ } catch (err) {
369
+ writeErr(`\\${ctx.cmdName}: ${errMsg(err)}\n`);
370
+ return {
371
+ status: "error",
372
+ errorWritten: true
373
+ };
374
+ }
375
+ const forceExpanded = ctx.cmdName.slice(baseName.length).includes("x") && pattern === null;
376
+ const savedPopt = ctx.settings.popt;
377
+ if (forceExpanded) ctx.settings.popt = {
378
+ ...savedPopt,
379
+ topt: {
380
+ ...savedPopt.topt,
381
+ expanded: "on"
382
+ }
383
+ };
384
+ try {
385
+ return await runTypedList(ctx, c, baseName, pattern, verbose, showSystem);
386
+ } finally {
387
+ ctx.settings.popt = savedPopt;
388
+ }
389
+ }
403
390
  });
404
391
  const dispatchDetail = async (ctx, c, rel, verbose) => {
405
- const popt = ctx.settings.popt;
406
- switch (rel.relkind) {
407
- case "S":
408
- await describeOneSequence(c, rel.oid, rel.nspname, rel.relname, process.stdout, popt);
409
- return;
410
- case "v":
411
- await describeOneViewDetails(c, rel.oid, rel.nspname, rel.relname, process.stdout, popt, verbose, ctx.settings.hideCompression);
412
- return;
413
- default:
414
- await describeOneTableDetails(c, rel.oid, rel.nspname, rel.relname, rel.relkind, verbose, process.stdout, popt, ctx.settings.hideTableam, ctx.settings.hideCompression);
415
- }
392
+ const popt = ctx.settings.popt;
393
+ switch (rel.relkind) {
394
+ case "S":
395
+ await describeOneSequence(c, rel.oid, rel.nspname, rel.relname, process.stdout, popt);
396
+ return;
397
+ case "v":
398
+ await describeOneViewDetails(c, rel.oid, rel.nspname, rel.relname, process.stdout, popt, verbose, ctx.settings.hideCompression);
399
+ return;
400
+ default: await describeOneTableDetails(c, rel.oid, rel.nspname, rel.relname, rel.relkind, verbose, process.stdout, popt, ctx.settings.hideTableam, ctx.settings.hideCompression);
401
+ }
416
402
  };
417
403
  const runTypedList = async (ctx, c, baseName, pattern, verbose, showSystem) => {
418
- const serverVersion = c.serverVersion;
419
- const hideTableam = ctx.settings.hideTableam;
420
- let query;
421
- let tabtypes = "";
422
- switch (baseName) {
423
- case "d":
424
- query = describeTableDetails({
425
- pattern: pattern ?? undefined,
426
- verbose,
427
- showSystem,
428
- serverVersion,
429
- hideTableam,
430
- });
431
- break;
432
- case "dt":
433
- tabtypes = "t";
434
- query = listTables({
435
- pattern: pattern ?? undefined,
436
- verbose,
437
- showSystem,
438
- serverVersion,
439
- tabtypes,
440
- hideTableam,
441
- });
442
- break;
443
- case "di":
444
- tabtypes = "i";
445
- query = listTables({
446
- pattern: pattern ?? undefined,
447
- verbose,
448
- showSystem,
449
- serverVersion,
450
- tabtypes,
451
- hideTableam,
452
- });
453
- break;
454
- case "dv":
455
- tabtypes = "v";
456
- query = listTables({
457
- pattern: pattern ?? undefined,
458
- verbose,
459
- showSystem,
460
- serverVersion,
461
- tabtypes,
462
- hideTableam,
463
- });
464
- break;
465
- case "dm":
466
- tabtypes = "m";
467
- query = listTables({
468
- pattern: pattern ?? undefined,
469
- verbose,
470
- showSystem,
471
- serverVersion,
472
- tabtypes,
473
- hideTableam,
474
- });
475
- break;
476
- case "ds":
477
- tabtypes = "s";
478
- query = listTables({
479
- pattern: pattern ?? undefined,
480
- verbose,
481
- showSystem,
482
- serverVersion,
483
- tabtypes,
484
- hideTableam,
485
- });
486
- break;
487
- case "dE":
488
- tabtypes = "E";
489
- query = listTables({
490
- pattern: pattern ?? undefined,
491
- verbose,
492
- showSystem,
493
- serverVersion,
494
- tabtypes,
495
- hideTableam,
496
- });
497
- break;
498
- default:
499
- return { status: "error" };
500
- }
501
- const visibility = baseName === "d"
502
- ? "pg_catalog.pg_table_is_visible(c.oid)"
503
- : "pg_catalog.pg_table_is_visible(c.oid)";
504
- return runWithPattern(ctx, pattern, query, {
505
- namevar: "c.relname",
506
- schemavar: "n.nspname",
507
- visibilityrule: visibility,
508
- });
404
+ const serverVersion = c.serverVersion;
405
+ const hideTableam = ctx.settings.hideTableam;
406
+ let query;
407
+ let tabtypes = "";
408
+ switch (baseName) {
409
+ case "d":
410
+ query = describeTableDetails({
411
+ pattern: pattern ?? void 0,
412
+ verbose,
413
+ showSystem,
414
+ serverVersion,
415
+ hideTableam
416
+ });
417
+ break;
418
+ case "dt":
419
+ tabtypes = "t";
420
+ query = listTables({
421
+ pattern: pattern ?? void 0,
422
+ verbose,
423
+ showSystem,
424
+ serverVersion,
425
+ tabtypes,
426
+ hideTableam
427
+ });
428
+ break;
429
+ case "di":
430
+ tabtypes = "i";
431
+ query = listTables({
432
+ pattern: pattern ?? void 0,
433
+ verbose,
434
+ showSystem,
435
+ serverVersion,
436
+ tabtypes,
437
+ hideTableam
438
+ });
439
+ break;
440
+ case "dv":
441
+ tabtypes = "v";
442
+ query = listTables({
443
+ pattern: pattern ?? void 0,
444
+ verbose,
445
+ showSystem,
446
+ serverVersion,
447
+ tabtypes,
448
+ hideTableam
449
+ });
450
+ break;
451
+ case "dm":
452
+ tabtypes = "m";
453
+ query = listTables({
454
+ pattern: pattern ?? void 0,
455
+ verbose,
456
+ showSystem,
457
+ serverVersion,
458
+ tabtypes,
459
+ hideTableam
460
+ });
461
+ break;
462
+ case "ds":
463
+ tabtypes = "s";
464
+ query = listTables({
465
+ pattern: pattern ?? void 0,
466
+ verbose,
467
+ showSystem,
468
+ serverVersion,
469
+ tabtypes,
470
+ hideTableam
471
+ });
472
+ break;
473
+ case "dE":
474
+ tabtypes = "E";
475
+ query = listTables({
476
+ pattern: pattern ?? void 0,
477
+ verbose,
478
+ showSystem,
479
+ serverVersion,
480
+ tabtypes,
481
+ hideTableam
482
+ });
483
+ break;
484
+ default: return { status: "error" };
485
+ }
486
+ return runWithPattern(ctx, pattern, query, {
487
+ namevar: "c.relname",
488
+ schemavar: "n.nspname",
489
+ visibilityrule: baseName === "d" ? "pg_catalog.pg_table_is_visible(c.oid)" : "pg_catalog.pg_table_is_visible(c.oid)"
490
+ });
509
491
  };
510
- // Register all the relation-list-style commands with all suffix combos.
511
- const RELATION_BASES = ["d", "dt", "di", "dv", "dm", "ds", "dE"];
512
- // Standard suffix matrix. `x` is added separately for the bases that
513
- // accept the expanded-mode toggle (currently `\d`/`\d+`).
514
- const SUFFIX_COMBOS = ["", "+", "S", "S+", "+S"];
515
- // Extended suffix matrix for `\d` only — adds the `x` (expanded) suffix
516
- // in the same combinations regress exercises.
517
- const DESCRIBE_X_SUFFIXES = ["x", "+x", "x+", "Sx", "xS", "+Sx", "+xS"];
518
- // ---- \df / \df+ / \dfS / \dfa / \dfn / \dfp / \dft / \dfw / \dfx -------
519
- // Upstream's `command.c::exec_command_df` accepts a free-form suffix after
520
- // `\df`: `+` for verbose, `S` to include system schemas, `x` to force
521
- // expanded mode (when no pattern), and {a,n,p,t,w} to filter by function
522
- // kind (aggregate / normal / procedure / trigger / window). Multiple may
523
- // combine and order is unrestricted (`\dfax+`, `\df+xn`, etc.).
492
+ const RELATION_BASES = [
493
+ "d",
494
+ "dt",
495
+ "di",
496
+ "dv",
497
+ "dm",
498
+ "ds",
499
+ "dE"
500
+ ];
501
+ const SUFFIX_COMBOS = [
502
+ "",
503
+ "+",
504
+ "S",
505
+ "S+",
506
+ "+S"
507
+ ];
508
+ const DESCRIBE_X_SUFFIXES = [
509
+ "x",
510
+ "+x",
511
+ "x+",
512
+ "Sx",
513
+ "xS",
514
+ "+Sx",
515
+ "+xS"
516
+ ];
524
517
  const cmdDescribeFunctions = (cmdName) => ({
525
- name: cmdName,
526
- run: async (ctx) => {
527
- const pattern = ctx.nextArg("normal");
528
- const c = conn(ctx);
529
- if (!c)
530
- return noConn(ctx);
531
- const { verbose, showSystem } = decodeSuffix(cmdName, "df");
532
- let functypes = "";
533
- const tail = cmdName.slice(2);
534
- for (const ch of tail) {
535
- if (ch === "a" ||
536
- ch === "n" ||
537
- ch === "p" ||
538
- ch === "t" ||
539
- ch === "w") {
540
- functypes += ch;
541
- }
542
- }
543
- // Per-argument type patterns: only collected when the main pattern
544
- // is non-null (upstream: "Collect argument-type patterns too /
545
- // otherwise it was just \df"). Each extra arg filters one slot of
546
- // `proargtypes`; `-` means "no type in that slot".
547
- const argPatterns = [];
548
- if (pattern !== null) {
549
- argPatterns.push(...collectArgPatterns(ctx));
550
- }
551
- const argPatternResults = argPatterns.map((a, i) => processArgPattern(i, a));
552
- // `x` enables expanded mode for the printed result. For `\df` upstream
553
- // applies the toggle whether or not a pattern is present (unlike `\d`,
554
- // which only toggles when no pattern is given). Override popt locally
555
- // so we don't leak the change to subsequent commands.
556
- const forceExpanded = tail.includes("x");
557
- const savedPopt = ctx.settings.popt;
558
- if (forceExpanded) {
559
- ctx.settings.popt = {
560
- ...savedPopt,
561
- topt: { ...savedPopt.topt, expanded: "on" },
562
- };
563
- }
564
- try {
565
- const query = describeFunctions({
566
- pattern: pattern ?? undefined,
567
- verbose,
568
- showSystem,
569
- functypes,
570
- argPatterns,
571
- serverVersion: c.serverVersion,
572
- });
573
- return await runFunctionOrOperatorQuery(ctx, pattern, argPatternResults, query, {
574
- namevar: "p.proname",
575
- schemavar: "n.nspname",
576
- visibilityrule: "pg_catalog.pg_function_is_visible(p.oid)",
577
- });
578
- }
579
- finally {
580
- ctx.settings.popt = savedPopt;
581
- }
582
- },
518
+ name: cmdName,
519
+ run: async (ctx) => {
520
+ const pattern = ctx.nextArg("normal");
521
+ const c = conn(ctx);
522
+ if (!c) return noConn(ctx);
523
+ const { verbose, showSystem } = decodeSuffix(cmdName, "df");
524
+ let functypes = "";
525
+ const tail = cmdName.slice(2);
526
+ for (const ch of tail) if (ch === "a" || ch === "n" || ch === "p" || ch === "t" || ch === "w") functypes += ch;
527
+ const argPatterns = [];
528
+ if (pattern !== null) argPatterns.push(...collectArgPatterns(ctx));
529
+ const argPatternResults = argPatterns.map((a, i) => processArgPattern(i, a));
530
+ const forceExpanded = tail.includes("x");
531
+ const savedPopt = ctx.settings.popt;
532
+ if (forceExpanded) ctx.settings.popt = {
533
+ ...savedPopt,
534
+ topt: {
535
+ ...savedPopt.topt,
536
+ expanded: "on"
537
+ }
538
+ };
539
+ try {
540
+ const query = describeFunctions({
541
+ pattern: pattern ?? void 0,
542
+ verbose,
543
+ showSystem,
544
+ functypes,
545
+ argPatterns,
546
+ serverVersion: c.serverVersion
547
+ });
548
+ return await runFunctionOrOperatorQuery(ctx, pattern, argPatternResults, query, {
549
+ namevar: "p.proname",
550
+ schemavar: "n.nspname",
551
+ visibilityrule: "pg_catalog.pg_function_is_visible(p.oid)"
552
+ });
553
+ } finally {
554
+ ctx.settings.popt = savedPopt;
555
+ }
556
+ }
583
557
  });
584
- // ---- \da ----------------------------------------------------------------
585
558
  const cmdDescribeAggregates = (cmdName) => ({
586
- name: cmdName,
587
- run: async (ctx) => {
588
- const pattern = ctx.nextArg("normal");
589
- const c = conn(ctx);
590
- if (!c)
591
- return noConn(ctx);
592
- const { showSystem } = decodeSuffix(cmdName, "da");
593
- const query = describeAggregates({
594
- pattern: pattern ?? undefined,
595
- showSystem,
596
- serverVersion: c.serverVersion,
597
- });
598
- return runWithPattern(ctx, pattern, query, {
599
- namevar: "p.proname",
600
- schemavar: "n.nspname",
601
- visibilityrule: "pg_catalog.pg_function_is_visible(p.oid)",
602
- });
603
- },
559
+ name: cmdName,
560
+ run: async (ctx) => {
561
+ const pattern = ctx.nextArg("normal");
562
+ const c = conn(ctx);
563
+ if (!c) return noConn(ctx);
564
+ const { showSystem } = decodeSuffix(cmdName, "da");
565
+ const query = describeAggregates({
566
+ pattern: pattern ?? void 0,
567
+ showSystem,
568
+ serverVersion: c.serverVersion
569
+ });
570
+ return runWithPattern(ctx, pattern, query, {
571
+ namevar: "p.proname",
572
+ schemavar: "n.nspname",
573
+ visibilityrule: "pg_catalog.pg_function_is_visible(p.oid)"
574
+ });
575
+ }
604
576
  });
605
- // ---- \dA / \dA+ / \dAm / \dAm+ -----------------------------------------
606
- // `\dAm[+]` is a Neon extension: it lists access methods with their
607
- // handler and description columns always present, equivalent to upstream
608
- // `\dA+`. Upstream psql doesn't accept this spelling; we register it as
609
- // an alias so users who reach for "access methods" by full name get the
610
- // verbose view (Name, Type, Handler, Description) by default.
611
577
  const cmdDescribeAccessMethods = (cmdName) => ({
612
- name: cmdName,
613
- run: async (ctx) => {
614
- const pattern = ctx.nextArg("normal");
615
- const c = conn(ctx);
616
- if (!c)
617
- return noConn(ctx);
618
- const isAlias = cmdName.startsWith("dAm");
619
- const base = isAlias ? "dAm" : "dA";
620
- const { verbose } = decodeSuffix(cmdName, base);
621
- // `\dAm[+]` always displays the verbose columns; trailing `+` is
622
- // accepted for syntactic parity but doesn't change output.
623
- const query = describeAccessMethods({
624
- pattern: pattern ?? undefined,
625
- verbose: isAlias ? true : verbose,
626
- serverVersion: c.serverVersion,
627
- });
628
- // Access methods are global, never schema-qualified; first dot is
629
- // "too many dotted names".
630
- const result = await runWithPattern(ctx, pattern, query, { namevar: "amname" }, 0);
631
- // Upstream `exec_command_d` drains any args past the first AFTER
632
- // running the query and writing the result, emitting one warning
633
- // per leftover token via `pg_log_warning`. Mirror that ordering so
634
- // `\dA foo bar` prints the (empty) result first, then
635
- // `\dA: extra argument "bar" ignored` to stderr.
636
- for (let extra = ctx.nextArg("normal"); extra !== null;) {
637
- writeErr(`\\${base}: extra argument "${extra}" ignored\n`);
638
- extra = ctx.nextArg("normal");
639
- }
640
- return result;
641
- },
578
+ name: cmdName,
579
+ run: async (ctx) => {
580
+ const pattern = ctx.nextArg("normal");
581
+ const c = conn(ctx);
582
+ if (!c) return noConn(ctx);
583
+ const isAlias = cmdName.startsWith("dAm");
584
+ const base = isAlias ? "dAm" : "dA";
585
+ const { verbose } = decodeSuffix(cmdName, base);
586
+ const query = describeAccessMethods({
587
+ pattern: pattern ?? void 0,
588
+ verbose: isAlias ? true : verbose,
589
+ serverVersion: c.serverVersion
590
+ });
591
+ const result = await runWithPattern(ctx, pattern, query, { namevar: "amname" }, 0);
592
+ for (let extra = ctx.nextArg("normal"); extra !== null;) {
593
+ writeErr(`\\${base}: extra argument "${extra}" ignored\n`);
594
+ extra = ctx.nextArg("normal");
595
+ }
596
+ return result;
597
+ }
642
598
  });
643
- // ---- \dAc / \dAc+ ------------------------------------------------------
644
- // `\dAc [AM-pattern [TYPE-pattern]]` — list operator classes. Two-pattern
645
- // command: the first arg filters by access-method name, the second by
646
- // input-type schema/name. Mirrors upstream's `case 'A' / cmd[2] == 'c'`
647
- // dispatch in `command.c::exec_command_d`.
648
599
  const cmdListOperatorClasses = (cmdName) => ({
649
- name: cmdName,
650
- run: async (ctx) => {
651
- const amPat = ctx.nextArg("normal");
652
- const typePat = amPat ? ctx.nextArg("normal") : null;
653
- const c = conn(ctx);
654
- if (!c)
655
- return noConn(ctx);
656
- const { verbose } = decodeSuffix(cmdName, "dAc");
657
- const query = listOperatorClasses({
658
- amPattern: amPat ?? undefined,
659
- typePattern: typePat ?? undefined,
660
- verbose,
661
- serverVersion: c.serverVersion,
662
- });
663
- const results = [];
664
- const curDb = currentDb(c);
665
- if (amPat !== null) {
666
- const r = processSQLNamePattern({
667
- namevar: "am.amname",
668
- pattern: amPat,
669
- });
670
- // Access method names are flat — first dot is "too many".
671
- const err = validatePattern(amPat, r, 0, curDb);
672
- if (err !== null) {
673
- writeErr(`${err}\n`);
674
- return { status: "error", errorWritten: true };
675
- }
676
- results.push(r);
677
- }
678
- if (typePat !== null) {
679
- const r = processSQLNamePattern({
680
- namevar: "t.typname",
681
- schemavar: "tn.nspname",
682
- pattern: typePat,
683
- });
684
- // Type pattern accepts db.schema.name; cross-db check on 2-dot.
685
- const err = validatePattern(typePat, r, 2, curDb);
686
- if (err !== null) {
687
- writeErr(`${err}\n`);
688
- return { status: "error", errorWritten: true };
689
- }
690
- results.push(r);
691
- }
692
- return runDualPatternList(ctx, query, results);
693
- },
600
+ name: cmdName,
601
+ run: async (ctx) => {
602
+ const amPat = ctx.nextArg("normal");
603
+ const typePat = amPat ? ctx.nextArg("normal") : null;
604
+ const c = conn(ctx);
605
+ if (!c) return noConn(ctx);
606
+ const { verbose } = decodeSuffix(cmdName, "dAc");
607
+ const query = listOperatorClasses({
608
+ amPattern: amPat ?? void 0,
609
+ typePattern: typePat ?? void 0,
610
+ verbose,
611
+ serverVersion: c.serverVersion
612
+ });
613
+ const results = [];
614
+ const curDb = currentDb(c);
615
+ if (amPat !== null) {
616
+ const r = processSQLNamePattern({
617
+ namevar: "am.amname",
618
+ pattern: amPat
619
+ });
620
+ const err = validatePattern(amPat, r, 0, curDb);
621
+ if (err !== null) {
622
+ writeErr(`${err}\n`);
623
+ return {
624
+ status: "error",
625
+ errorWritten: true
626
+ };
627
+ }
628
+ results.push(r);
629
+ }
630
+ if (typePat !== null) {
631
+ const r = processSQLNamePattern({
632
+ namevar: "t.typname",
633
+ schemavar: "tn.nspname",
634
+ pattern: typePat
635
+ });
636
+ const err = validatePattern(typePat, r, 2, curDb);
637
+ if (err !== null) {
638
+ writeErr(`${err}\n`);
639
+ return {
640
+ status: "error",
641
+ errorWritten: true
642
+ };
643
+ }
644
+ results.push(r);
645
+ }
646
+ return runDualPatternList(ctx, query, results);
647
+ }
694
648
  });
695
- // ---- \dAf / \dAf+ ------------------------------------------------------
696
- // `\dAf [AM-pattern [TYPE-pattern]]` — list operator families. Same
697
- // two-pattern shape as `\dAc`. Routes through `listOperatorFamilies`
698
- // from queries.ts.
699
649
  const cmdListOperatorFamilies = (cmdName) => ({
700
- name: cmdName,
701
- run: async (ctx) => {
702
- const amPat = ctx.nextArg("normal");
703
- const typePat = amPat ? ctx.nextArg("normal") : null;
704
- const c = conn(ctx);
705
- if (!c)
706
- return noConn(ctx);
707
- const { verbose } = decodeSuffix(cmdName, "dAf");
708
- const query = listOperatorFamilies({
709
- amPattern: amPat ?? undefined,
710
- typePattern: typePat ?? undefined,
711
- verbose,
712
- serverVersion: c.serverVersion,
713
- });
714
- const results = [];
715
- const curDb = currentDb(c);
716
- if (amPat !== null) {
717
- const r = processSQLNamePattern({
718
- namevar: "am.amname",
719
- pattern: amPat,
720
- });
721
- const err = validatePattern(amPat, r, 0, curDb);
722
- if (err !== null) {
723
- writeErr(`${err}\n`);
724
- return { status: "error", errorWritten: true };
725
- }
726
- results.push(r);
727
- }
728
- if (typePat !== null) {
729
- const r = processSQLNamePattern({
730
- namevar: "t.typname",
731
- schemavar: "tn.nspname",
732
- pattern: typePat,
733
- });
734
- const err = validatePattern(typePat, r, 2, curDb);
735
- if (err !== null) {
736
- writeErr(`${err}\n`);
737
- return { status: "error", errorWritten: true };
738
- }
739
- results.push(r);
740
- }
741
- return runDualPatternList(ctx, query, results);
742
- },
650
+ name: cmdName,
651
+ run: async (ctx) => {
652
+ const amPat = ctx.nextArg("normal");
653
+ const typePat = amPat ? ctx.nextArg("normal") : null;
654
+ const c = conn(ctx);
655
+ if (!c) return noConn(ctx);
656
+ const { verbose } = decodeSuffix(cmdName, "dAf");
657
+ const query = listOperatorFamilies({
658
+ amPattern: amPat ?? void 0,
659
+ typePattern: typePat ?? void 0,
660
+ verbose,
661
+ serverVersion: c.serverVersion
662
+ });
663
+ const results = [];
664
+ const curDb = currentDb(c);
665
+ if (amPat !== null) {
666
+ const r = processSQLNamePattern({
667
+ namevar: "am.amname",
668
+ pattern: amPat
669
+ });
670
+ const err = validatePattern(amPat, r, 0, curDb);
671
+ if (err !== null) {
672
+ writeErr(`${err}\n`);
673
+ return {
674
+ status: "error",
675
+ errorWritten: true
676
+ };
677
+ }
678
+ results.push(r);
679
+ }
680
+ if (typePat !== null) {
681
+ const r = processSQLNamePattern({
682
+ namevar: "t.typname",
683
+ schemavar: "tn.nspname",
684
+ pattern: typePat
685
+ });
686
+ const err = validatePattern(typePat, r, 2, curDb);
687
+ if (err !== null) {
688
+ writeErr(`${err}\n`);
689
+ return {
690
+ status: "error",
691
+ errorWritten: true
692
+ };
693
+ }
694
+ results.push(r);
695
+ }
696
+ return runDualPatternList(ctx, query, results);
697
+ }
743
698
  });
744
- // ---- \dAo / \dAo+ ------------------------------------------------------
745
- // `\dAo [AM-pattern [OPFAMILY-pattern]]` — list operators in an opfamily.
746
- // Routes through `listOpFamilyOperators` from queries.ts.
747
699
  const cmdListOpFamilyOperators = (cmdName) => ({
748
- name: cmdName,
749
- run: async (ctx) => {
750
- const amPat = ctx.nextArg("normal");
751
- const familyPat = amPat ? ctx.nextArg("normal") : null;
752
- const c = conn(ctx);
753
- if (!c)
754
- return noConn(ctx);
755
- const { verbose } = decodeSuffix(cmdName, "dAo");
756
- const query = listOpFamilyOperators({
757
- amPattern: amPat ?? undefined,
758
- familyPattern: familyPat ?? undefined,
759
- verbose,
760
- serverVersion: c.serverVersion,
761
- });
762
- const results = [];
763
- const curDb = currentDb(c);
764
- if (amPat !== null) {
765
- const r = processSQLNamePattern({
766
- namevar: "am.amname",
767
- pattern: amPat,
768
- });
769
- const err = validatePattern(amPat, r, 0, curDb);
770
- if (err !== null) {
771
- writeErr(`${err}\n`);
772
- return { status: "error", errorWritten: true };
773
- }
774
- results.push(r);
775
- }
776
- if (familyPat !== null) {
777
- const r = processSQLNamePattern({
778
- namevar: "of.opfname",
779
- schemavar: "nsf.nspname",
780
- pattern: familyPat,
781
- });
782
- const err = validatePattern(familyPat, r, 2, curDb);
783
- if (err !== null) {
784
- writeErr(`${err}\n`);
785
- return { status: "error", errorWritten: true };
786
- }
787
- results.push(r);
788
- }
789
- return runDualPatternList(ctx, query, results);
790
- },
700
+ name: cmdName,
701
+ run: async (ctx) => {
702
+ const amPat = ctx.nextArg("normal");
703
+ const familyPat = amPat ? ctx.nextArg("normal") : null;
704
+ const c = conn(ctx);
705
+ if (!c) return noConn(ctx);
706
+ const { verbose } = decodeSuffix(cmdName, "dAo");
707
+ const query = listOpFamilyOperators({
708
+ amPattern: amPat ?? void 0,
709
+ familyPattern: familyPat ?? void 0,
710
+ verbose,
711
+ serverVersion: c.serverVersion
712
+ });
713
+ const results = [];
714
+ const curDb = currentDb(c);
715
+ if (amPat !== null) {
716
+ const r = processSQLNamePattern({
717
+ namevar: "am.amname",
718
+ pattern: amPat
719
+ });
720
+ const err = validatePattern(amPat, r, 0, curDb);
721
+ if (err !== null) {
722
+ writeErr(`${err}\n`);
723
+ return {
724
+ status: "error",
725
+ errorWritten: true
726
+ };
727
+ }
728
+ results.push(r);
729
+ }
730
+ if (familyPat !== null) {
731
+ const r = processSQLNamePattern({
732
+ namevar: "of.opfname",
733
+ schemavar: "nsf.nspname",
734
+ pattern: familyPat
735
+ });
736
+ const err = validatePattern(familyPat, r, 2, curDb);
737
+ if (err !== null) {
738
+ writeErr(`${err}\n`);
739
+ return {
740
+ status: "error",
741
+ errorWritten: true
742
+ };
743
+ }
744
+ results.push(r);
745
+ }
746
+ return runDualPatternList(ctx, query, results);
747
+ }
791
748
  });
792
- // ---- \dAp / \dAp+ ------------------------------------------------------
793
- // `\dAp [AM-pattern [OPFAMILY-pattern]]` — list support functions of an
794
- // opfamily. Routes through `listOpFamilyFunctions` from queries.ts.
795
749
  const cmdListOpFamilyFunctions = (cmdName) => ({
796
- name: cmdName,
797
- run: async (ctx) => {
798
- const amPat = ctx.nextArg("normal");
799
- const familyPat = amPat ? ctx.nextArg("normal") : null;
800
- const c = conn(ctx);
801
- if (!c)
802
- return noConn(ctx);
803
- const { verbose } = decodeSuffix(cmdName, "dAp");
804
- // `\dApx[+]` — expanded toggle, same convention as `\df`/`\z`.
805
- const forceExpanded = cmdName.slice(3).includes("x");
806
- const savedPopt = ctx.settings.popt;
807
- if (forceExpanded) {
808
- ctx.settings.popt = {
809
- ...savedPopt,
810
- topt: { ...savedPopt.topt, expanded: "on" },
811
- };
812
- }
813
- try {
814
- const query = listOpFamilyFunctions({
815
- amPattern: amPat ?? undefined,
816
- familyPattern: familyPat ?? undefined,
817
- verbose,
818
- serverVersion: c.serverVersion,
819
- });
820
- const results = [];
821
- const curDb = currentDb(c);
822
- if (amPat !== null) {
823
- const r = processSQLNamePattern({
824
- namevar: "am.amname",
825
- pattern: amPat,
826
- });
827
- const err = validatePattern(amPat, r, 0, curDb);
828
- if (err !== null) {
829
- writeErr(`${err}\n`);
830
- return { status: "error", errorWritten: true };
831
- }
832
- results.push(r);
833
- }
834
- if (familyPat !== null) {
835
- const r = processSQLNamePattern({
836
- namevar: "of.opfname",
837
- schemavar: "ns.nspname",
838
- pattern: familyPat,
839
- });
840
- const err = validatePattern(familyPat, r, 2, curDb);
841
- if (err !== null) {
842
- writeErr(`${err}\n`);
843
- return { status: "error", errorWritten: true };
844
- }
845
- results.push(r);
846
- }
847
- return await runDualPatternList(ctx, query, results);
848
- }
849
- finally {
850
- ctx.settings.popt = savedPopt;
851
- }
852
- },
750
+ name: cmdName,
751
+ run: async (ctx) => {
752
+ const amPat = ctx.nextArg("normal");
753
+ const familyPat = amPat ? ctx.nextArg("normal") : null;
754
+ const c = conn(ctx);
755
+ if (!c) return noConn(ctx);
756
+ const { verbose } = decodeSuffix(cmdName, "dAp");
757
+ const forceExpanded = cmdName.slice(3).includes("x");
758
+ const savedPopt = ctx.settings.popt;
759
+ if (forceExpanded) ctx.settings.popt = {
760
+ ...savedPopt,
761
+ topt: {
762
+ ...savedPopt.topt,
763
+ expanded: "on"
764
+ }
765
+ };
766
+ try {
767
+ const query = listOpFamilyFunctions({
768
+ amPattern: amPat ?? void 0,
769
+ familyPattern: familyPat ?? void 0,
770
+ verbose,
771
+ serverVersion: c.serverVersion
772
+ });
773
+ const results = [];
774
+ const curDb = currentDb(c);
775
+ if (amPat !== null) {
776
+ const r = processSQLNamePattern({
777
+ namevar: "am.amname",
778
+ pattern: amPat
779
+ });
780
+ const err = validatePattern(amPat, r, 0, curDb);
781
+ if (err !== null) {
782
+ writeErr(`${err}\n`);
783
+ return {
784
+ status: "error",
785
+ errorWritten: true
786
+ };
787
+ }
788
+ results.push(r);
789
+ }
790
+ if (familyPat !== null) {
791
+ const r = processSQLNamePattern({
792
+ namevar: "of.opfname",
793
+ schemavar: "ns.nspname",
794
+ pattern: familyPat
795
+ });
796
+ const err = validatePattern(familyPat, r, 2, curDb);
797
+ if (err !== null) {
798
+ writeErr(`${err}\n`);
799
+ return {
800
+ status: "error",
801
+ errorWritten: true
802
+ };
803
+ }
804
+ results.push(r);
805
+ }
806
+ return await runDualPatternList(ctx, query, results);
807
+ } finally {
808
+ ctx.settings.popt = savedPopt;
809
+ }
810
+ }
853
811
  });
854
- // ---- \dT / \dT+ / \dTS --------------------------------------------------
855
812
  const cmdDescribeTypes = (cmdName) => ({
856
- name: cmdName,
857
- run: async (ctx) => {
858
- const pattern = ctx.nextArg("normal");
859
- const c = conn(ctx);
860
- if (!c)
861
- return noConn(ctx);
862
- const { verbose, showSystem } = decodeSuffix(cmdName, "dT");
863
- const query = describeTypes({
864
- pattern: pattern ?? undefined,
865
- verbose,
866
- showSystem,
867
- serverVersion: c.serverVersion,
868
- });
869
- return runWithPattern(ctx, pattern, query, {
870
- namevar: "t.typname",
871
- schemavar: "n.nspname",
872
- visibilityrule: "pg_catalog.pg_type_is_visible(t.oid)",
873
- });
874
- },
813
+ name: cmdName,
814
+ run: async (ctx) => {
815
+ const pattern = ctx.nextArg("normal");
816
+ const c = conn(ctx);
817
+ if (!c) return noConn(ctx);
818
+ const { verbose, showSystem } = decodeSuffix(cmdName, "dT");
819
+ const query = describeTypes({
820
+ pattern: pattern ?? void 0,
821
+ verbose,
822
+ showSystem,
823
+ serverVersion: c.serverVersion
824
+ });
825
+ return runWithPattern(ctx, pattern, query, {
826
+ namevar: "t.typname",
827
+ schemavar: "n.nspname",
828
+ visibilityrule: "pg_catalog.pg_type_is_visible(t.oid)"
829
+ });
830
+ }
875
831
  });
876
- // ---- \do / \do+ ---------------------------------------------------------
877
832
  const cmdDescribeOperators = (cmdName) => ({
878
- name: cmdName,
879
- run: async (ctx) => {
880
- const pattern = ctx.nextArg("normal");
881
- const c = conn(ctx);
882
- if (!c)
883
- return noConn(ctx);
884
- const { verbose, showSystem } = decodeSuffix(cmdName, "do");
885
- // Upstream: same arg-collection rule as `\df` (only when main
886
- // pattern is non-null). describeOperators caps at 2 args; we still
887
- // forward the user's input so the SQL builder can decide which
888
- // joins to emit.
889
- let argPatterns = [];
890
- if (pattern !== null) {
891
- argPatterns = collectArgPatterns(ctx);
892
- }
893
- if (argPatterns.length > 2)
894
- argPatterns = argPatterns.slice(0, 2);
895
- const argPatternResults = argPatterns.map((a, i) => processArgPattern(i, a));
896
- const query = describeOperators({
897
- pattern: pattern ?? undefined,
898
- verbose,
899
- showSystem,
900
- argPatterns,
901
- serverVersion: c.serverVersion,
902
- });
903
- return runFunctionOrOperatorQuery(ctx, pattern, argPatternResults, query, {
904
- namevar: "o.oprname",
905
- schemavar: "n.nspname",
906
- visibilityrule: "pg_catalog.pg_operator_is_visible(o.oid)",
907
- });
908
- },
833
+ name: cmdName,
834
+ run: async (ctx) => {
835
+ const pattern = ctx.nextArg("normal");
836
+ const c = conn(ctx);
837
+ if (!c) return noConn(ctx);
838
+ const { verbose, showSystem } = decodeSuffix(cmdName, "do");
839
+ let argPatterns = [];
840
+ if (pattern !== null) argPatterns = collectArgPatterns(ctx);
841
+ if (argPatterns.length > 2) argPatterns = argPatterns.slice(0, 2);
842
+ const argPatternResults = argPatterns.map((a, i) => processArgPattern(i, a));
843
+ const query = describeOperators({
844
+ pattern: pattern ?? void 0,
845
+ verbose,
846
+ showSystem,
847
+ argPatterns,
848
+ serverVersion: c.serverVersion
849
+ });
850
+ return runFunctionOrOperatorQuery(ctx, pattern, argPatternResults, query, {
851
+ namevar: "o.oprname",
852
+ schemavar: "n.nspname",
853
+ visibilityrule: "pg_catalog.pg_operator_is_visible(o.oid)"
854
+ });
855
+ }
909
856
  });
910
- // ---- \du / \dg / \dg+ / \du+ -------------------------------------------
911
857
  const cmdDescribeRoles = (cmdName) => ({
912
- name: cmdName,
913
- run: async (ctx) => {
914
- const pattern = ctx.nextArg("normal");
915
- const c = conn(ctx);
916
- if (!c)
917
- return noConn(ctx);
918
- const base = cmdName.startsWith("du") ? "du" : "dg";
919
- const { verbose, showSystem } = decodeSuffix(cmdName, base);
920
- const query = describeRoles({
921
- pattern: pattern ?? undefined,
922
- verbose,
923
- showSystem,
924
- serverVersion: c.serverVersion,
925
- });
926
- // Roles are global — first dot is "too many". Upstream calls
927
- // `printQuery` with `default_footer = false` (describe.c
928
- // `describeRoles`), so suppress the `(N rows)` counter for both
929
- // populated and empty results to match `psql -E \du`.
930
- return runWithPattern(ctx, pattern, query, { namevar: "r.rolname" }, 0, {
931
- suppressDefaultFooter: true,
932
- });
933
- },
858
+ name: cmdName,
859
+ run: async (ctx) => {
860
+ const pattern = ctx.nextArg("normal");
861
+ const c = conn(ctx);
862
+ if (!c) return noConn(ctx);
863
+ const base = cmdName.startsWith("du") ? "du" : "dg";
864
+ const { verbose, showSystem } = decodeSuffix(cmdName, base);
865
+ const query = describeRoles({
866
+ pattern: pattern ?? void 0,
867
+ verbose,
868
+ showSystem,
869
+ serverVersion: c.serverVersion
870
+ });
871
+ return runWithPattern(ctx, pattern, query, { namevar: "r.rolname" }, 0, { suppressDefaultFooter: true });
872
+ }
934
873
  });
935
- // ---- \drds -------------------------------------------------------------
936
- // `\drds [role-pattern [database-pattern]]` — list role-/database-level
937
- // configuration settings (`pg_db_role_setting`). Two-pattern command:
938
- // first arg filters by role, second by database. Empty results print a
939
- // stderr notice ("Did not find any settings…") when not in quiet mode,
940
- // mirroring upstream `describe.c::listDbRoleSettings`.
941
874
  const cmdListDbRoleSettings = {
942
- name: "drds",
943
- run: async (ctx) => {
944
- const rolePat = ctx.nextArg("normal");
945
- const dbPat = rolePat ? ctx.nextArg("normal") : null;
946
- const c = conn(ctx);
947
- if (!c)
948
- return noConn(ctx);
949
- const query = listDbRoleSettings({
950
- pattern: rolePat ?? undefined,
951
- pattern2: dbPat ?? undefined,
952
- serverVersion: c.serverVersion,
953
- });
954
- const results = [];
955
- const curDb = currentDb(c);
956
- if (rolePat !== null) {
957
- const r = processSQLNamePattern({
958
- namevar: "r.rolname",
959
- pattern: rolePat,
960
- });
961
- // Role names are flat — first dot is "too many".
962
- const err = validatePattern(rolePat, r, 0, curDb);
963
- if (err !== null) {
964
- writeErr(`${err}\n`);
965
- return { status: "error", errorWritten: true };
966
- }
967
- results.push(r);
968
- }
969
- if (dbPat !== null) {
970
- const r = processSQLNamePattern({
971
- namevar: "d.datname",
972
- pattern: dbPat,
973
- });
974
- // Database names are top-level — first dot is "too many".
975
- const err = validatePattern(dbPat, r, 0, curDb);
976
- if (err !== null) {
977
- writeErr(`${err}\n`);
978
- return { status: "error", errorWritten: true };
979
- }
980
- results.push(r);
981
- }
982
- // Upstream deviates from the rest of describe.c here: when the
983
- // result set is empty and we're not in --quiet, emit a stderr
984
- // diagnostic instead of printing an empty table — the two-pattern
985
- // shape makes confusion likely otherwise.
986
- if (rolePat === null && dbPat === null) {
987
- return runDualPatternList(ctx, query, results);
988
- }
989
- const { sql, params } = applyTwoPatterns(query.sql, [], results);
990
- const finalQuery = {
991
- ...query,
992
- sql,
993
- params,
994
- };
995
- try {
996
- const rs = await c.query(sql, params);
997
- if (rs.rows.length === 0 && !ctx.settings.quiet) {
998
- if (rolePat !== null && dbPat !== null) {
999
- writeErr(`Did not find any settings for role "${rolePat}" and database "${dbPat}".\n`);
1000
- }
1001
- else if (rolePat !== null) {
1002
- writeErr(`Did not find any settings for role "${rolePat}".\n`);
1003
- }
1004
- return { status: "ok" };
1005
- }
1006
- // Re-print via the standard runner so the title and formatting
1007
- // match peer list queries. We pass the already-substituted SQL
1008
- // and an empty pattern result so the second-pass replace is a
1009
- // no-op. (We accept the double-query cost on the small `\drds`
1010
- // path; alternatives require duplicating the printer plumbing.)
1011
- const empty = {
1012
- schemaConditions: [],
1013
- nameConditions: [],
1014
- visibilityConditions: [],
1015
- params: [],
1016
- dotCount: 0,
1017
- dbLiteral: null,
1018
- };
1019
- await runListQuery(c, finalQuery, empty, process.stdout, ctx.settings.popt);
1020
- return { status: "ok" };
1021
- }
1022
- catch (err) {
1023
- writeErr(`\\${ctx.cmdName}: ${errMsg(err)}\n`);
1024
- return { status: "error", errorWritten: true };
1025
- }
1026
- },
875
+ name: "drds",
876
+ run: async (ctx) => {
877
+ const rolePat = ctx.nextArg("normal");
878
+ const dbPat = rolePat ? ctx.nextArg("normal") : null;
879
+ const c = conn(ctx);
880
+ if (!c) return noConn(ctx);
881
+ const query = listDbRoleSettings({
882
+ pattern: rolePat ?? void 0,
883
+ pattern2: dbPat ?? void 0,
884
+ serverVersion: c.serverVersion
885
+ });
886
+ const results = [];
887
+ const curDb = currentDb(c);
888
+ if (rolePat !== null) {
889
+ const r = processSQLNamePattern({
890
+ namevar: "r.rolname",
891
+ pattern: rolePat
892
+ });
893
+ const err = validatePattern(rolePat, r, 0, curDb);
894
+ if (err !== null) {
895
+ writeErr(`${err}\n`);
896
+ return {
897
+ status: "error",
898
+ errorWritten: true
899
+ };
900
+ }
901
+ results.push(r);
902
+ }
903
+ if (dbPat !== null) {
904
+ const r = processSQLNamePattern({
905
+ namevar: "d.datname",
906
+ pattern: dbPat
907
+ });
908
+ const err = validatePattern(dbPat, r, 0, curDb);
909
+ if (err !== null) {
910
+ writeErr(`${err}\n`);
911
+ return {
912
+ status: "error",
913
+ errorWritten: true
914
+ };
915
+ }
916
+ results.push(r);
917
+ }
918
+ if (rolePat === null && dbPat === null) return runDualPatternList(ctx, query, results);
919
+ const { sql, params } = applyTwoPatterns(query.sql, [], results);
920
+ const finalQuery = {
921
+ ...query,
922
+ sql,
923
+ params
924
+ };
925
+ try {
926
+ if ((await c.query(sql, params)).rows.length === 0 && !ctx.settings.quiet) {
927
+ if (rolePat !== null && dbPat !== null) writeErr(`Did not find any settings for role "${rolePat}" and database "${dbPat}".\n`);
928
+ else if (rolePat !== null) writeErr(`Did not find any settings for role "${rolePat}".\n`);
929
+ return { status: "ok" };
930
+ }
931
+ await runListQuery(c, finalQuery, {
932
+ schemaConditions: [],
933
+ nameConditions: [],
934
+ visibilityConditions: [],
935
+ params: [],
936
+ dotCount: 0,
937
+ dbLiteral: null
938
+ }, process.stdout, ctx.settings.popt);
939
+ return { status: "ok" };
940
+ } catch (err) {
941
+ writeErr(`\\${ctx.cmdName}: ${errMsg(err)}\n`);
942
+ return {
943
+ status: "error",
944
+ errorWritten: true
945
+ };
946
+ }
947
+ }
1027
948
  };
1028
- // ---- \dn / \dn+ / \dnS --------------------------------------------------
1029
949
  const cmdListSchemas = (cmdName) => ({
1030
- name: cmdName,
1031
- run: async (ctx) => {
1032
- const pattern = ctx.nextArg("normal");
1033
- const c = conn(ctx);
1034
- if (!c)
1035
- return noConn(ctx);
1036
- const { verbose, showSystem } = decodeSuffix(cmdName, "dn");
1037
- const query = listSchemas({
1038
- pattern: pattern ?? undefined,
1039
- verbose,
1040
- showSystem,
1041
- serverVersion: c.serverVersion,
1042
- });
1043
- // Schemas live in a single namespace; the optional qualifier slot
1044
- // is interpreted as a database name (cross-database check fires on
1045
- // mismatch). `maxDots = 1`.
1046
- return runWithPattern(ctx, pattern, query, { namevar: "n.nspname" }, 1);
1047
- },
950
+ name: cmdName,
951
+ run: async (ctx) => {
952
+ const pattern = ctx.nextArg("normal");
953
+ const c = conn(ctx);
954
+ if (!c) return noConn(ctx);
955
+ const { verbose, showSystem } = decodeSuffix(cmdName, "dn");
956
+ const query = listSchemas({
957
+ pattern: pattern ?? void 0,
958
+ verbose,
959
+ showSystem,
960
+ serverVersion: c.serverVersion
961
+ });
962
+ return runWithPattern(ctx, pattern, query, { namevar: "n.nspname" }, 1);
963
+ }
1048
964
  });
1049
- // ---- \db / \db+ ---------------------------------------------------------
1050
- // Tablespaces — not typically relevant on Neon. We still register so the
1051
- // command exists; it returns an empty result against a managed deployment.
1052
965
  const cmdDescribeTablespaces = (cmdName) => ({
1053
- name: cmdName,
1054
- run: async (ctx) => {
1055
- const pattern = ctx.nextArg("normal");
1056
- const c = conn(ctx);
1057
- if (!c)
1058
- return noConn(ctx);
1059
- const { verbose } = decodeSuffix(cmdName, "db");
1060
- const query = describeTablespaces({
1061
- pattern: pattern ?? undefined,
1062
- verbose,
1063
- serverVersion: c.serverVersion,
1064
- });
1065
- // Tablespaces are flat — first dot is "too many".
1066
- return runWithPattern(ctx, pattern, query, { namevar: "spcname" }, 0);
1067
- },
966
+ name: cmdName,
967
+ run: async (ctx) => {
968
+ const pattern = ctx.nextArg("normal");
969
+ const c = conn(ctx);
970
+ if (!c) return noConn(ctx);
971
+ const { verbose } = decodeSuffix(cmdName, "db");
972
+ const query = describeTablespaces({
973
+ pattern: pattern ?? void 0,
974
+ verbose,
975
+ serverVersion: c.serverVersion
976
+ });
977
+ return runWithPattern(ctx, pattern, query, { namevar: "spcname" }, 0);
978
+ }
1068
979
  });
1069
- // ---- \dD / \dDS / \dD+ -------------------------------------------------
1070
980
  const cmdListDomains = (cmdName) => ({
1071
- name: cmdName,
1072
- run: async (ctx) => {
1073
- const pattern = ctx.nextArg("normal");
1074
- const c = conn(ctx);
1075
- if (!c)
1076
- return noConn(ctx);
1077
- const { verbose, showSystem } = decodeSuffix(cmdName, "dD");
1078
- const query = listDomains({
1079
- pattern: pattern ?? undefined,
1080
- verbose,
1081
- showSystem,
1082
- serverVersion: c.serverVersion,
1083
- });
1084
- return runWithPattern(ctx, pattern, query, {
1085
- namevar: "t.typname",
1086
- schemavar: "n.nspname",
1087
- visibilityrule: "pg_catalog.pg_type_is_visible(t.oid)",
1088
- });
1089
- },
981
+ name: cmdName,
982
+ run: async (ctx) => {
983
+ const pattern = ctx.nextArg("normal");
984
+ const c = conn(ctx);
985
+ if (!c) return noConn(ctx);
986
+ const { verbose, showSystem } = decodeSuffix(cmdName, "dD");
987
+ const query = listDomains({
988
+ pattern: pattern ?? void 0,
989
+ verbose,
990
+ showSystem,
991
+ serverVersion: c.serverVersion
992
+ });
993
+ return runWithPattern(ctx, pattern, query, {
994
+ namevar: "t.typname",
995
+ schemavar: "n.nspname",
996
+ visibilityrule: "pg_catalog.pg_type_is_visible(t.oid)"
997
+ });
998
+ }
1090
999
  });
1091
- // ---- \dc / \dcS / \dc+ -------------------------------------------------
1092
1000
  const cmdListConversions = (cmdName) => ({
1093
- name: cmdName,
1094
- run: async (ctx) => {
1095
- const pattern = ctx.nextArg("normal");
1096
- const c = conn(ctx);
1097
- if (!c)
1098
- return noConn(ctx);
1099
- const { verbose, showSystem } = decodeSuffix(cmdName, "dc");
1100
- const query = listConversions({
1101
- pattern: pattern ?? undefined,
1102
- verbose,
1103
- showSystem,
1104
- serverVersion: c.serverVersion,
1105
- });
1106
- return runWithPattern(ctx, pattern, query, {
1107
- namevar: "c.conname",
1108
- schemavar: "n.nspname",
1109
- visibilityrule: "pg_catalog.pg_conversion_is_visible(c.oid)",
1110
- });
1111
- },
1001
+ name: cmdName,
1002
+ run: async (ctx) => {
1003
+ const pattern = ctx.nextArg("normal");
1004
+ const c = conn(ctx);
1005
+ if (!c) return noConn(ctx);
1006
+ const { verbose, showSystem } = decodeSuffix(cmdName, "dc");
1007
+ const query = listConversions({
1008
+ pattern: pattern ?? void 0,
1009
+ verbose,
1010
+ showSystem,
1011
+ serverVersion: c.serverVersion
1012
+ });
1013
+ return runWithPattern(ctx, pattern, query, {
1014
+ namevar: "c.conname",
1015
+ schemavar: "n.nspname",
1016
+ visibilityrule: "pg_catalog.pg_conversion_is_visible(c.oid)"
1017
+ });
1018
+ }
1112
1019
  });
1113
- // ---- \dC / \dC+ --------------------------------------------------------
1114
1020
  const cmdListCasts = (cmdName) => ({
1115
- name: cmdName,
1116
- run: async (ctx) => {
1117
- const pattern = ctx.nextArg("normal");
1118
- const c = conn(ctx);
1119
- if (!c)
1120
- return noConn(ctx);
1121
- const { verbose } = decodeSuffix(cmdName, "dC");
1122
- const query = listCasts({
1123
- pattern: pattern ?? undefined,
1124
- verbose,
1125
- serverVersion: c.serverVersion,
1126
- });
1127
- return runWithPattern(ctx, pattern, query, {
1128
- namevar: "ts.typname",
1129
- schemavar: "ns.nspname",
1130
- });
1131
- },
1021
+ name: cmdName,
1022
+ run: async (ctx) => {
1023
+ const pattern = ctx.nextArg("normal");
1024
+ const c = conn(ctx);
1025
+ if (!c) return noConn(ctx);
1026
+ const { verbose } = decodeSuffix(cmdName, "dC");
1027
+ const query = listCasts({
1028
+ pattern: pattern ?? void 0,
1029
+ verbose,
1030
+ serverVersion: c.serverVersion
1031
+ });
1032
+ return runWithPattern(ctx, pattern, query, {
1033
+ namevar: "ts.typname",
1034
+ schemavar: "ns.nspname"
1035
+ });
1036
+ }
1132
1037
  });
1133
- // ---- \dL / \dLS / \dL+ -------------------------------------------------
1134
1038
  const cmdListLanguages = (cmdName) => ({
1135
- name: cmdName,
1136
- run: async (ctx) => {
1137
- const pattern = ctx.nextArg("normal");
1138
- const c = conn(ctx);
1139
- if (!c)
1140
- return noConn(ctx);
1141
- const { verbose, showSystem } = decodeSuffix(cmdName, "dL");
1142
- const query = listLanguages({
1143
- pattern: pattern ?? undefined,
1144
- verbose,
1145
- showSystem,
1146
- serverVersion: c.serverVersion,
1147
- });
1148
- // Languages are global; first dot is a database qualifier (cross-db).
1149
- return runWithPattern(ctx, pattern, query, { namevar: "l.lanname" }, 1);
1150
- },
1039
+ name: cmdName,
1040
+ run: async (ctx) => {
1041
+ const pattern = ctx.nextArg("normal");
1042
+ const c = conn(ctx);
1043
+ if (!c) return noConn(ctx);
1044
+ const { verbose, showSystem } = decodeSuffix(cmdName, "dL");
1045
+ const query = listLanguages({
1046
+ pattern: pattern ?? void 0,
1047
+ verbose,
1048
+ showSystem,
1049
+ serverVersion: c.serverVersion
1050
+ });
1051
+ return runWithPattern(ctx, pattern, query, { namevar: "l.lanname" }, 1);
1052
+ }
1151
1053
  });
1152
- // ---- \dO / \dO+ / \dOS -------------------------------------------------
1153
1054
  const cmdListCollations = (cmdName) => ({
1154
- name: cmdName,
1155
- run: async (ctx) => {
1156
- const pattern = ctx.nextArg("normal");
1157
- const c = conn(ctx);
1158
- if (!c)
1159
- return noConn(ctx);
1160
- const { verbose, showSystem } = decodeSuffix(cmdName, "dO");
1161
- const query = listCollations({
1162
- pattern: pattern ?? undefined,
1163
- verbose,
1164
- showSystem,
1165
- serverVersion: c.serverVersion,
1166
- });
1167
- return runWithPattern(ctx, pattern, query, {
1168
- namevar: "c.collname",
1169
- schemavar: "n.nspname",
1170
- visibilityrule: "pg_catalog.pg_collation_is_visible(c.oid)",
1171
- });
1172
- },
1055
+ name: cmdName,
1056
+ run: async (ctx) => {
1057
+ const pattern = ctx.nextArg("normal");
1058
+ const c = conn(ctx);
1059
+ if (!c) return noConn(ctx);
1060
+ const { verbose, showSystem } = decodeSuffix(cmdName, "dO");
1061
+ const query = listCollations({
1062
+ pattern: pattern ?? void 0,
1063
+ verbose,
1064
+ showSystem,
1065
+ serverVersion: c.serverVersion
1066
+ });
1067
+ return runWithPattern(ctx, pattern, query, {
1068
+ namevar: "c.collname",
1069
+ schemavar: "n.nspname",
1070
+ visibilityrule: "pg_catalog.pg_collation_is_visible(c.oid)"
1071
+ });
1072
+ }
1173
1073
  });
1174
- // ---- \dp / \z ----------------------------------------------------------
1175
1074
  const cmdPermissionsList = (cmdName) => ({
1176
- name: cmdName,
1177
- run: async (ctx) => {
1178
- const pattern = ctx.nextArg("normal");
1179
- const c = conn(ctx);
1180
- if (!c)
1181
- return noConn(ctx);
1182
- const base = cmdName.startsWith("z") ? "z" : "dp";
1183
- const { showSystem } = decodeSuffix(cmdName, base);
1184
- // `\z[x]`, `\dp[x]` — same expanded-mode toggle convention as `\df`,
1185
- // applied whether or not a pattern is present.
1186
- const forceExpanded = cmdName.slice(base.length).includes("x");
1187
- const savedPopt = ctx.settings.popt;
1188
- if (forceExpanded) {
1189
- ctx.settings.popt = {
1190
- ...savedPopt,
1191
- topt: { ...savedPopt.topt, expanded: "on" },
1192
- };
1193
- }
1194
- try {
1195
- const query = permissionsList({
1196
- pattern: pattern ?? undefined,
1197
- showSystem,
1198
- serverVersion: c.serverVersion,
1199
- });
1200
- return await runWithPattern(ctx, pattern, query, {
1201
- namevar: "c.relname",
1202
- schemavar: "n.nspname",
1203
- visibilityrule: "pg_catalog.pg_table_is_visible(c.oid)",
1204
- });
1205
- }
1206
- finally {
1207
- ctx.settings.popt = savedPopt;
1208
- }
1209
- },
1075
+ name: cmdName,
1076
+ run: async (ctx) => {
1077
+ const pattern = ctx.nextArg("normal");
1078
+ const c = conn(ctx);
1079
+ if (!c) return noConn(ctx);
1080
+ const base = cmdName.startsWith("z") ? "z" : "dp";
1081
+ const { showSystem } = decodeSuffix(cmdName, base);
1082
+ const forceExpanded = cmdName.slice(base.length).includes("x");
1083
+ const savedPopt = ctx.settings.popt;
1084
+ if (forceExpanded) ctx.settings.popt = {
1085
+ ...savedPopt,
1086
+ topt: {
1087
+ ...savedPopt.topt,
1088
+ expanded: "on"
1089
+ }
1090
+ };
1091
+ try {
1092
+ const query = permissionsList({
1093
+ pattern: pattern ?? void 0,
1094
+ showSystem,
1095
+ serverVersion: c.serverVersion
1096
+ });
1097
+ return await runWithPattern(ctx, pattern, query, {
1098
+ namevar: "c.relname",
1099
+ schemavar: "n.nspname",
1100
+ visibilityrule: "pg_catalog.pg_table_is_visible(c.oid)"
1101
+ });
1102
+ } finally {
1103
+ ctx.settings.popt = savedPopt;
1104
+ }
1105
+ }
1210
1106
  });
1211
- // ---- \ddp --------------------------------------------------------------
1212
1107
  const cmdListDefaultACLs = {
1213
- name: "ddp",
1214
- run: async (ctx) => {
1215
- const pattern = ctx.nextArg("normal");
1216
- const c = conn(ctx);
1217
- if (!c)
1218
- return noConn(ctx);
1219
- const query = listDefaultACLs({
1220
- pattern: pattern ?? undefined,
1221
- serverVersion: c.serverVersion,
1222
- });
1223
- return runWithPattern(ctx, pattern, query, {
1224
- namevar: "pg_catalog.pg_get_userbyid(d.defaclrole)",
1225
- schemavar: "n.nspname",
1226
- });
1227
- },
1108
+ name: "ddp",
1109
+ run: async (ctx) => {
1110
+ const pattern = ctx.nextArg("normal");
1111
+ const c = conn(ctx);
1112
+ if (!c) return noConn(ctx);
1113
+ const query = listDefaultACLs({
1114
+ pattern: pattern ?? void 0,
1115
+ serverVersion: c.serverVersion
1116
+ });
1117
+ return runWithPattern(ctx, pattern, query, {
1118
+ namevar: "pg_catalog.pg_get_userbyid(d.defaclrole)",
1119
+ schemavar: "n.nspname"
1120
+ });
1121
+ }
1228
1122
  };
1229
- // ---- \dd ---------------------------------------------------------------
1230
1123
  const cmdObjectDescription = {
1231
- name: "dd",
1232
- run: async (ctx) => {
1233
- const pattern = ctx.nextArg("normal");
1234
- const c = conn(ctx);
1235
- if (!c)
1236
- return noConn(ctx);
1237
- const { showSystem } = decodeSuffix(ctx.cmdName, "dd");
1238
- const query = objectDescription({
1239
- pattern: pattern ?? undefined,
1240
- showSystem,
1241
- serverVersion: c.serverVersion,
1242
- });
1243
- return runWithPattern(ctx, pattern, query, {
1244
- namevar: "tt.name",
1245
- schemavar: "tt.nspname",
1246
- });
1247
- },
1124
+ name: "dd",
1125
+ run: async (ctx) => {
1126
+ const pattern = ctx.nextArg("normal");
1127
+ const c = conn(ctx);
1128
+ if (!c) return noConn(ctx);
1129
+ const { showSystem } = decodeSuffix(ctx.cmdName, "dd");
1130
+ const query = objectDescription({
1131
+ pattern: pattern ?? void 0,
1132
+ showSystem,
1133
+ serverVersion: c.serverVersion
1134
+ });
1135
+ return runWithPattern(ctx, pattern, query, {
1136
+ namevar: "tt.name",
1137
+ schemavar: "tt.nspname"
1138
+ });
1139
+ }
1248
1140
  };
1249
- // ---- \l / \list -------------------------------------------------------
1250
1141
  const cmdListAllDbs = {
1251
- name: "l",
1252
- aliases: ["list"],
1253
- run: async (ctx) => {
1254
- const pattern = ctx.nextArg("normal");
1255
- const c = conn(ctx);
1256
- if (!c)
1257
- return noConn(ctx);
1258
- const { verbose } = decodeSuffix(ctx.cmdName, "l");
1259
- const query = listAllDbs({
1260
- pattern: pattern ?? undefined,
1261
- verbose,
1262
- serverVersion: c.serverVersion,
1263
- });
1264
- return runWithPattern(ctx, pattern, query, { namevar: "d.datname" });
1265
- },
1142
+ name: "l",
1143
+ aliases: ["list"],
1144
+ run: async (ctx) => {
1145
+ const pattern = ctx.nextArg("normal");
1146
+ const c = conn(ctx);
1147
+ if (!c) return noConn(ctx);
1148
+ const { verbose } = decodeSuffix(ctx.cmdName, "l");
1149
+ const query = listAllDbs({
1150
+ pattern: pattern ?? void 0,
1151
+ verbose,
1152
+ serverVersion: c.serverVersion
1153
+ });
1154
+ return runWithPattern(ctx, pattern, query, { namevar: "d.datname" });
1155
+ }
1266
1156
  };
1267
- // ---- \dconfig ----------------------------------------------------------
1268
1157
  const cmdDescribeConfigParams = {
1269
- name: "dconfig",
1270
- run: async (ctx) => {
1271
- const pattern = ctx.nextArg("normal");
1272
- const c = conn(ctx);
1273
- if (!c)
1274
- return noConn(ctx);
1275
- const { verbose } = decodeSuffix(ctx.cmdName, "dconfig");
1276
- const query = describeConfigurationParameters({
1277
- pattern: pattern ?? undefined,
1278
- verbose,
1279
- serverVersion: c.serverVersion,
1280
- });
1281
- // GUC names are flat — any dot is "too many".
1282
- return runWithPattern(ctx, pattern, query, { namevar: "pg_catalog.lower(s.name)" }, 0);
1283
- },
1158
+ name: "dconfig",
1159
+ run: async (ctx) => {
1160
+ const pattern = ctx.nextArg("normal");
1161
+ const c = conn(ctx);
1162
+ if (!c) return noConn(ctx);
1163
+ const { verbose } = decodeSuffix(ctx.cmdName, "dconfig");
1164
+ const query = describeConfigurationParameters({
1165
+ pattern: pattern ?? void 0,
1166
+ verbose,
1167
+ serverVersion: c.serverVersion
1168
+ });
1169
+ return runWithPattern(ctx, pattern, query, { namevar: "pg_catalog.lower(s.name)" }, 0);
1170
+ }
1284
1171
  };
1285
- // ---- \dy ---------------------------------------------------------------
1286
1172
  const cmdListEventTriggers = {
1287
- name: "dy",
1288
- run: async (ctx) => {
1289
- const pattern = ctx.nextArg("normal");
1290
- const c = conn(ctx);
1291
- if (!c)
1292
- return noConn(ctx);
1293
- const { verbose } = decodeSuffix(ctx.cmdName, "dy");
1294
- const query = listEventTriggers({
1295
- pattern: pattern ?? undefined,
1296
- verbose,
1297
- serverVersion: c.serverVersion,
1298
- });
1299
- // Event triggers are global with no schema or database qualifier
1300
- // (upstream `validateSQLNamePattern(..., NULL, 1)`): any dot in
1301
- // the pattern is "too many".
1302
- return runWithPattern(ctx, pattern, query, { namevar: "evtname" }, 0);
1303
- },
1173
+ name: "dy",
1174
+ run: async (ctx) => {
1175
+ const pattern = ctx.nextArg("normal");
1176
+ const c = conn(ctx);
1177
+ if (!c) return noConn(ctx);
1178
+ const { verbose } = decodeSuffix(ctx.cmdName, "dy");
1179
+ const query = listEventTriggers({
1180
+ pattern: pattern ?? void 0,
1181
+ verbose,
1182
+ serverVersion: c.serverVersion
1183
+ });
1184
+ return runWithPattern(ctx, pattern, query, { namevar: "evtname" }, 0);
1185
+ }
1304
1186
  };
1305
- // ---- \dx / \dx+ -------------------------------------------------------
1306
1187
  const cmdListExtensions = {
1307
- name: "dx",
1308
- run: async (ctx) => {
1309
- const pattern = ctx.nextArg("normal");
1310
- const c = conn(ctx);
1311
- if (!c)
1312
- return noConn(ctx);
1313
- const query = listExtensions({
1314
- pattern: pattern ?? undefined,
1315
- serverVersion: c.serverVersion,
1316
- });
1317
- // Extensions are global with no schema or database qualifier
1318
- // (upstream `validateSQLNamePattern(..., NULL, 1)`): any dot is
1319
- // "too many".
1320
- return runWithPattern(ctx, pattern, query, { namevar: "e.extname" }, 0);
1321
- },
1188
+ name: "dx",
1189
+ run: async (ctx) => {
1190
+ const pattern = ctx.nextArg("normal");
1191
+ const c = conn(ctx);
1192
+ if (!c) return noConn(ctx);
1193
+ const query = listExtensions({
1194
+ pattern: pattern ?? void 0,
1195
+ serverVersion: c.serverVersion
1196
+ });
1197
+ return runWithPattern(ctx, pattern, query, { namevar: "e.extname" }, 0);
1198
+ }
1322
1199
  };
1323
- // ---- \dl / \lo_list ---------------------------------------------------
1324
1200
  const cmdListLargeObjects = {
1325
- name: "dl",
1326
- aliases: ["lo_list"],
1327
- run: async (ctx) => {
1328
- const c = conn(ctx);
1329
- if (!c)
1330
- return noConn(ctx);
1331
- const { verbose } = decodeSuffix(ctx.cmdName, "dl");
1332
- const query = listLargeObjects({
1333
- verbose,
1334
- serverVersion: c.serverVersion,
1335
- });
1336
- return runWithPattern(ctx, null, query, { namevar: "oid" });
1337
- },
1201
+ name: "dl",
1202
+ aliases: ["lo_list"],
1203
+ run: async (ctx) => {
1204
+ const c = conn(ctx);
1205
+ if (!c) return noConn(ctx);
1206
+ const { verbose } = decodeSuffix(ctx.cmdName, "dl");
1207
+ const query = listLargeObjects({
1208
+ verbose,
1209
+ serverVersion: c.serverVersion
1210
+ });
1211
+ return runWithPattern(ctx, null, query, { namevar: "oid" });
1212
+ }
1338
1213
  };
1339
- // ---- \dF / \dFp / \dFd / \dFt ----------------------------------------
1340
1214
  const cmdListTSConfigs = {
1341
- name: "dF",
1342
- run: async (ctx) => {
1343
- const pattern = ctx.nextArg("normal");
1344
- const c = conn(ctx);
1345
- if (!c)
1346
- return noConn(ctx);
1347
- const { verbose } = decodeSuffix(ctx.cmdName, "dF");
1348
- const query = listTSConfigs({
1349
- pattern: pattern ?? undefined,
1350
- verbose,
1351
- serverVersion: c.serverVersion,
1352
- });
1353
- return runWithPattern(ctx, pattern, query, {
1354
- namevar: "c.cfgname",
1355
- schemavar: "n.nspname",
1356
- });
1357
- },
1215
+ name: "dF",
1216
+ run: async (ctx) => {
1217
+ const pattern = ctx.nextArg("normal");
1218
+ const c = conn(ctx);
1219
+ if (!c) return noConn(ctx);
1220
+ const { verbose } = decodeSuffix(ctx.cmdName, "dF");
1221
+ const query = listTSConfigs({
1222
+ pattern: pattern ?? void 0,
1223
+ verbose,
1224
+ serverVersion: c.serverVersion
1225
+ });
1226
+ return runWithPattern(ctx, pattern, query, {
1227
+ namevar: "c.cfgname",
1228
+ schemavar: "n.nspname"
1229
+ });
1230
+ }
1358
1231
  };
1359
1232
  const cmdListTSParsers = {
1360
- name: "dFp",
1361
- run: async (ctx) => {
1362
- const pattern = ctx.nextArg("normal");
1363
- const c = conn(ctx);
1364
- if (!c)
1365
- return noConn(ctx);
1366
- const { verbose } = decodeSuffix(ctx.cmdName, "dFp");
1367
- const query = listTSParsers({
1368
- pattern: pattern ?? undefined,
1369
- verbose,
1370
- serverVersion: c.serverVersion,
1371
- });
1372
- return runWithPattern(ctx, pattern, query, {
1373
- namevar: "p.prsname",
1374
- schemavar: "n.nspname",
1375
- });
1376
- },
1233
+ name: "dFp",
1234
+ run: async (ctx) => {
1235
+ const pattern = ctx.nextArg("normal");
1236
+ const c = conn(ctx);
1237
+ if (!c) return noConn(ctx);
1238
+ const { verbose } = decodeSuffix(ctx.cmdName, "dFp");
1239
+ const query = listTSParsers({
1240
+ pattern: pattern ?? void 0,
1241
+ verbose,
1242
+ serverVersion: c.serverVersion
1243
+ });
1244
+ return runWithPattern(ctx, pattern, query, {
1245
+ namevar: "p.prsname",
1246
+ schemavar: "n.nspname"
1247
+ });
1248
+ }
1377
1249
  };
1378
1250
  const cmdListTSDictionaries = {
1379
- name: "dFd",
1380
- run: async (ctx) => {
1381
- const pattern = ctx.nextArg("normal");
1382
- const c = conn(ctx);
1383
- if (!c)
1384
- return noConn(ctx);
1385
- const { verbose } = decodeSuffix(ctx.cmdName, "dFd");
1386
- const query = listTSDictionaries({
1387
- pattern: pattern ?? undefined,
1388
- verbose,
1389
- serverVersion: c.serverVersion,
1390
- });
1391
- return runWithPattern(ctx, pattern, query, {
1392
- namevar: "d.dictname",
1393
- schemavar: "n.nspname",
1394
- });
1395
- },
1251
+ name: "dFd",
1252
+ run: async (ctx) => {
1253
+ const pattern = ctx.nextArg("normal");
1254
+ const c = conn(ctx);
1255
+ if (!c) return noConn(ctx);
1256
+ const { verbose } = decodeSuffix(ctx.cmdName, "dFd");
1257
+ const query = listTSDictionaries({
1258
+ pattern: pattern ?? void 0,
1259
+ verbose,
1260
+ serverVersion: c.serverVersion
1261
+ });
1262
+ return runWithPattern(ctx, pattern, query, {
1263
+ namevar: "d.dictname",
1264
+ schemavar: "n.nspname"
1265
+ });
1266
+ }
1396
1267
  };
1397
1268
  const cmdListTSTemplates = {
1398
- name: "dFt",
1399
- run: async (ctx) => {
1400
- const pattern = ctx.nextArg("normal");
1401
- const c = conn(ctx);
1402
- if (!c)
1403
- return noConn(ctx);
1404
- const { verbose } = decodeSuffix(ctx.cmdName, "dFt");
1405
- const query = listTSTemplates({
1406
- pattern: pattern ?? undefined,
1407
- verbose,
1408
- serverVersion: c.serverVersion,
1409
- });
1410
- return runWithPattern(ctx, pattern, query, {
1411
- namevar: "t.tmplname",
1412
- schemavar: "n.nspname",
1413
- });
1414
- },
1269
+ name: "dFt",
1270
+ run: async (ctx) => {
1271
+ const pattern = ctx.nextArg("normal");
1272
+ const c = conn(ctx);
1273
+ if (!c) return noConn(ctx);
1274
+ const { verbose } = decodeSuffix(ctx.cmdName, "dFt");
1275
+ const query = listTSTemplates({
1276
+ pattern: pattern ?? void 0,
1277
+ verbose,
1278
+ serverVersion: c.serverVersion
1279
+ });
1280
+ return runWithPattern(ctx, pattern, query, {
1281
+ namevar: "t.tmplname",
1282
+ schemavar: "n.nspname"
1283
+ });
1284
+ }
1415
1285
  };
1416
- // ---- \dew / \des / \deu / \det ---------------------------------------
1417
1286
  const cmdListForeignDataWrappers = {
1418
- name: "dew",
1419
- run: async (ctx) => {
1420
- const pattern = ctx.nextArg("normal");
1421
- const c = conn(ctx);
1422
- if (!c)
1423
- return noConn(ctx);
1424
- const { verbose } = decodeSuffix(ctx.cmdName, "dew");
1425
- const query = listForeignDataWrappers({
1426
- pattern: pattern ?? undefined,
1427
- verbose,
1428
- serverVersion: c.serverVersion,
1429
- });
1430
- // FDWs are global with no schema or database qualifier (upstream
1431
- // `validateSQLNamePattern(..., NULL, 1)`): any dot is "too many".
1432
- return runWithPattern(ctx, pattern, query, { namevar: "fdwname" }, 0);
1433
- },
1287
+ name: "dew",
1288
+ run: async (ctx) => {
1289
+ const pattern = ctx.nextArg("normal");
1290
+ const c = conn(ctx);
1291
+ if (!c) return noConn(ctx);
1292
+ const { verbose } = decodeSuffix(ctx.cmdName, "dew");
1293
+ const query = listForeignDataWrappers({
1294
+ pattern: pattern ?? void 0,
1295
+ verbose,
1296
+ serverVersion: c.serverVersion
1297
+ });
1298
+ return runWithPattern(ctx, pattern, query, { namevar: "fdwname" }, 0);
1299
+ }
1434
1300
  };
1435
1301
  const cmdListForeignServers = {
1436
- name: "des",
1437
- run: async (ctx) => {
1438
- const pattern = ctx.nextArg("normal");
1439
- const c = conn(ctx);
1440
- if (!c)
1441
- return noConn(ctx);
1442
- const { verbose } = decodeSuffix(ctx.cmdName, "des");
1443
- const query = listForeignServers({
1444
- pattern: pattern ?? undefined,
1445
- verbose,
1446
- serverVersion: c.serverVersion,
1447
- });
1448
- // Foreign servers are global with no schema or database qualifier
1449
- // (upstream `validateSQLNamePattern(..., NULL, 1)`): any dot is
1450
- // "too many".
1451
- return runWithPattern(ctx, pattern, query, { namevar: "s.srvname" }, 0);
1452
- },
1302
+ name: "des",
1303
+ run: async (ctx) => {
1304
+ const pattern = ctx.nextArg("normal");
1305
+ const c = conn(ctx);
1306
+ if (!c) return noConn(ctx);
1307
+ const { verbose } = decodeSuffix(ctx.cmdName, "des");
1308
+ const query = listForeignServers({
1309
+ pattern: pattern ?? void 0,
1310
+ verbose,
1311
+ serverVersion: c.serverVersion
1312
+ });
1313
+ return runWithPattern(ctx, pattern, query, { namevar: "s.srvname" }, 0);
1314
+ }
1453
1315
  };
1454
1316
  const cmdListUserMappings = {
1455
- name: "deu",
1456
- run: async (ctx) => {
1457
- const pattern = ctx.nextArg("normal");
1458
- const c = conn(ctx);
1459
- if (!c)
1460
- return noConn(ctx);
1461
- const { verbose } = decodeSuffix(ctx.cmdName, "deu");
1462
- const query = listUserMappings({
1463
- pattern: pattern ?? undefined,
1464
- verbose,
1465
- serverVersion: c.serverVersion,
1466
- });
1467
- // User mappings live alongside foreign servers (global, no schema
1468
- // or db qualifier per upstream `validateSQLNamePattern(..., 1)`).
1469
- return runWithPattern(ctx, pattern, query, { namevar: "um.srvname" }, 0);
1470
- },
1317
+ name: "deu",
1318
+ run: async (ctx) => {
1319
+ const pattern = ctx.nextArg("normal");
1320
+ const c = conn(ctx);
1321
+ if (!c) return noConn(ctx);
1322
+ const { verbose } = decodeSuffix(ctx.cmdName, "deu");
1323
+ const query = listUserMappings({
1324
+ pattern: pattern ?? void 0,
1325
+ verbose,
1326
+ serverVersion: c.serverVersion
1327
+ });
1328
+ return runWithPattern(ctx, pattern, query, { namevar: "um.srvname" }, 0);
1329
+ }
1471
1330
  };
1472
1331
  const cmdListForeignTables = {
1473
- name: "det",
1474
- run: async (ctx) => {
1475
- const pattern = ctx.nextArg("normal");
1476
- const c = conn(ctx);
1477
- if (!c)
1478
- return noConn(ctx);
1479
- const { verbose } = decodeSuffix(ctx.cmdName, "det");
1480
- const query = listForeignTables({
1481
- pattern: pattern ?? undefined,
1482
- verbose,
1483
- serverVersion: c.serverVersion,
1484
- });
1485
- return runWithPattern(ctx, pattern, query, {
1486
- namevar: "c.relname",
1487
- schemavar: "n.nspname",
1488
- });
1489
- },
1332
+ name: "det",
1333
+ run: async (ctx) => {
1334
+ const pattern = ctx.nextArg("normal");
1335
+ const c = conn(ctx);
1336
+ if (!c) return noConn(ctx);
1337
+ const { verbose } = decodeSuffix(ctx.cmdName, "det");
1338
+ const query = listForeignTables({
1339
+ pattern: pattern ?? void 0,
1340
+ verbose,
1341
+ serverVersion: c.serverVersion
1342
+ });
1343
+ return runWithPattern(ctx, pattern, query, {
1344
+ namevar: "c.relname",
1345
+ schemavar: "n.nspname"
1346
+ });
1347
+ }
1490
1348
  };
1491
- // ---- \dP / \dPi / \dPt / \dPn -----------------------------------------
1492
1349
  const cmdListPartitionedTables = {
1493
- name: "dP",
1494
- run: async (ctx) => {
1495
- const pattern = ctx.nextArg("normal");
1496
- const c = conn(ctx);
1497
- if (!c)
1498
- return noConn(ctx);
1499
- const { verbose } = decodeSuffix(ctx.cmdName, "dP");
1500
- let reltypes = "";
1501
- if (ctx.cmdName.includes("i"))
1502
- reltypes += "i";
1503
- if (ctx.cmdName.includes("t"))
1504
- reltypes += "t";
1505
- if (ctx.cmdName.includes("n"))
1506
- reltypes += "n";
1507
- const query = listPartitionedTables({
1508
- pattern: pattern ?? undefined,
1509
- verbose,
1510
- reltypes,
1511
- serverVersion: c.serverVersion,
1512
- });
1513
- return runWithPattern(ctx, pattern, query, {
1514
- namevar: "c.relname",
1515
- schemavar: "n.nspname",
1516
- });
1517
- },
1350
+ name: "dP",
1351
+ run: async (ctx) => {
1352
+ const pattern = ctx.nextArg("normal");
1353
+ const c = conn(ctx);
1354
+ if (!c) return noConn(ctx);
1355
+ const { verbose } = decodeSuffix(ctx.cmdName, "dP");
1356
+ let reltypes = "";
1357
+ if (ctx.cmdName.includes("i")) reltypes += "i";
1358
+ if (ctx.cmdName.includes("t")) reltypes += "t";
1359
+ if (ctx.cmdName.includes("n")) reltypes += "n";
1360
+ const query = listPartitionedTables({
1361
+ pattern: pattern ?? void 0,
1362
+ verbose,
1363
+ reltypes,
1364
+ serverVersion: c.serverVersion
1365
+ });
1366
+ return runWithPattern(ctx, pattern, query, {
1367
+ namevar: "c.relname",
1368
+ schemavar: "n.nspname"
1369
+ });
1370
+ }
1518
1371
  };
1519
- // ---- \dX / \dX+ -------------------------------------------------------
1520
- // Extended-statistics objects (`pg_statistic_ext`). Patterns accept the
1521
- // usual schema-qualified form: `\dX` schema.name, with the cross-database
1522
- // 2-dot check applied.
1523
1372
  const cmdListExtendedStats = (cmdName) => ({
1524
- name: cmdName,
1525
- run: async (ctx) => {
1526
- const pattern = ctx.nextArg("normal");
1527
- const c = conn(ctx);
1528
- if (!c)
1529
- return noConn(ctx);
1530
- const { verbose } = decodeSuffix(cmdName, "dX");
1531
- const query = listExtendedStats({
1532
- pattern: pattern ?? undefined,
1533
- verbose,
1534
- serverVersion: c.serverVersion,
1535
- });
1536
- return runWithPattern(ctx, pattern, query, {
1537
- namevar: "es.stxname",
1538
- schemavar: "es.stxnamespace::pg_catalog.regnamespace::pg_catalog.text",
1539
- });
1540
- },
1373
+ name: cmdName,
1374
+ run: async (ctx) => {
1375
+ const pattern = ctx.nextArg("normal");
1376
+ const c = conn(ctx);
1377
+ if (!c) return noConn(ctx);
1378
+ const { verbose } = decodeSuffix(cmdName, "dX");
1379
+ const query = listExtendedStats({
1380
+ pattern: pattern ?? void 0,
1381
+ verbose,
1382
+ serverVersion: c.serverVersion
1383
+ });
1384
+ return runWithPattern(ctx, pattern, query, {
1385
+ namevar: "es.stxname",
1386
+ schemavar: "es.stxnamespace::pg_catalog.regnamespace::pg_catalog.text"
1387
+ });
1388
+ }
1541
1389
  });
1542
- // ---- \drg / \drg+ -----------------------------------------------------
1543
- // Role grants — membership rows from `pg_auth_members`. Two-pattern shape
1544
- // is upstream-specific to `\du`/`\dg`; `\drg` carries the same pattern as
1545
- // `\du` (role name), with the cross-database check declined because roles
1546
- // are global.
1547
1390
  const cmdDescribeRoleGrants = (cmdName) => ({
1548
- name: cmdName,
1549
- run: async (ctx) => {
1550
- const pattern = ctx.nextArg("normal");
1551
- const c = conn(ctx);
1552
- if (!c)
1553
- return noConn(ctx);
1554
- const { showSystem } = decodeSuffix(cmdName, "drg");
1555
- const query = describeRoleGrants({
1556
- pattern: pattern ?? undefined,
1557
- showSystem,
1558
- serverVersion: c.serverVersion,
1559
- });
1560
- return runWithPattern(ctx, pattern, query, { namevar: "m.rolname" }, 0);
1561
- },
1391
+ name: cmdName,
1392
+ run: async (ctx) => {
1393
+ const pattern = ctx.nextArg("normal");
1394
+ const c = conn(ctx);
1395
+ if (!c) return noConn(ctx);
1396
+ const { showSystem } = decodeSuffix(cmdName, "drg");
1397
+ const query = describeRoleGrants({
1398
+ pattern: pattern ?? void 0,
1399
+ showSystem,
1400
+ serverVersion: c.serverVersion
1401
+ });
1402
+ return runWithPattern(ctx, pattern, query, { namevar: "m.rolname" }, 0);
1403
+ }
1562
1404
  });
1563
- // ---- \dRp / \dRs ------------------------------------------------------
1564
1405
  const cmdListPublications = {
1565
- name: "dRp",
1566
- run: async (ctx) => {
1567
- const pattern = ctx.nextArg("normal");
1568
- const c = conn(ctx);
1569
- if (!c)
1570
- return noConn(ctx);
1571
- const query = listPublications({
1572
- pattern: pattern ?? undefined,
1573
- serverVersion: c.serverVersion,
1574
- });
1575
- // Publications are global with no schema or database qualifier
1576
- // (upstream `validateSQLNamePattern(..., NULL, 1)`): any dot is
1577
- // "too many".
1578
- return runWithPattern(ctx, pattern, query, { namevar: "pubname" }, 0);
1579
- },
1406
+ name: "dRp",
1407
+ run: async (ctx) => {
1408
+ const pattern = ctx.nextArg("normal");
1409
+ const c = conn(ctx);
1410
+ if (!c) return noConn(ctx);
1411
+ const query = listPublications({
1412
+ pattern: pattern ?? void 0,
1413
+ serverVersion: c.serverVersion
1414
+ });
1415
+ return runWithPattern(ctx, pattern, query, { namevar: "pubname" }, 0);
1416
+ }
1580
1417
  };
1581
1418
  const cmdDescribeSubscriptions = {
1582
- name: "dRs",
1583
- run: async (ctx) => {
1584
- const pattern = ctx.nextArg("normal");
1585
- const c = conn(ctx);
1586
- if (!c)
1587
- return noConn(ctx);
1588
- const { verbose } = decodeSuffix(ctx.cmdName, "dRs");
1589
- const query = describeSubscriptions({
1590
- pattern: pattern ?? undefined,
1591
- verbose,
1592
- serverVersion: c.serverVersion,
1593
- });
1594
- // Subscriptions are global with no schema or database qualifier
1595
- // (upstream `validateSQLNamePattern(..., NULL, 1)`): any dot is
1596
- // "too many".
1597
- return runWithPattern(ctx, pattern, query, { namevar: "subname" }, 0);
1598
- },
1419
+ name: "dRs",
1420
+ run: async (ctx) => {
1421
+ const pattern = ctx.nextArg("normal");
1422
+ const c = conn(ctx);
1423
+ if (!c) return noConn(ctx);
1424
+ const { verbose } = decodeSuffix(ctx.cmdName, "dRs");
1425
+ const query = describeSubscriptions({
1426
+ pattern: pattern ?? void 0,
1427
+ verbose,
1428
+ serverVersion: c.serverVersion
1429
+ });
1430
+ return runWithPattern(ctx, pattern, query, { namevar: "subname" }, 0);
1431
+ }
1599
1432
  };
1600
- // ===========================================================================
1601
- // Registration
1602
- // ===========================================================================
1603
1433
  /**
1604
- * Register every `\d*` command this WP implements on the given
1605
- * registry. Called from `dispatch.ts::defaultRegistry()`.
1606
- *
1607
- * We register a separate spec per suffix combination so the dispatcher
1608
- * can do a single name lookup without re-parsing. The implementation
1609
- * functions are factory-style (`make…(cmdName)`) so each spec carries
1610
- * the exact command name for suffix decoding.
1611
- */
1612
- export const registerDescribeCommands = (registry) => {
1613
- // Relation list+detail family. Each suffix combination is its own
1614
- // registered name; suffix decoding happens at runtime via the
1615
- // `cmdName` field on the spec (set per-registration).
1616
- for (const base of RELATION_BASES) {
1617
- for (const suffix of SUFFIX_COMBOS) {
1618
- const name = base + suffix;
1619
- registry.register({ ...makeDescribeCmd(base), name });
1620
- }
1621
- }
1622
- // `\d` accepts an additional `x` (expanded-mode toggle) suffix that we
1623
- // register only for the bare `\d` base — upstream only honours it for
1624
- // `\d` itself, not for typed variants like `\dt` or `\dv`.
1625
- for (const suffix of DESCRIBE_X_SUFFIXES) {
1626
- registry.register({ ...makeDescribeCmd("d"), name: "d" + suffix });
1627
- }
1628
- // Functions. Beyond the standard `\df[+S]` matrix, upstream accepts
1629
- // function-kind filter letters (a / n / p / t / w) and an expanded-mode
1630
- // toggle (x) appended in any order, with multiple stacking. The fanout
1631
- // covers the common one-letter additions used in regress; combined
1632
- // letter sequences (`\dfax+`, `\dfxw`, …) are handled by the runtime
1633
- // suffix walk in `cmdDescribeFunctions`.
1634
- const dfTails = [
1635
- "",
1636
- "+",
1637
- "S",
1638
- "S+",
1639
- "+S",
1640
- "a",
1641
- "n",
1642
- "p",
1643
- "t",
1644
- "w",
1645
- "x",
1646
- "ax",
1647
- "nx",
1648
- "px",
1649
- "tx",
1650
- "wx",
1651
- "xa",
1652
- "xn",
1653
- "xp",
1654
- "xt",
1655
- "xw",
1656
- "a+",
1657
- "n+",
1658
- "p+",
1659
- "t+",
1660
- "w+",
1661
- "x+",
1662
- "a+x",
1663
- "x+a",
1664
- ];
1665
- for (const tail of dfTails) {
1666
- registry.register(cmdDescribeFunctions("df" + tail));
1667
- }
1668
- // Aggregates.
1669
- for (const suffix of ["", "S"]) {
1670
- registry.register(cmdDescribeAggregates("da" + suffix));
1671
- }
1672
- // Access methods. `\dA[+]` is upstream; `\dAm[+]` is a Neon-friendly
1673
- // alias that some docs reach for. `\dAc[+]`, `\dAf[+]`, `\dAo[+]`,
1674
- // `\dAp[+]` cover the operator-class / family / family-operator /
1675
- // family-function families upstream's `command.c::exec_command_d`
1676
- // dispatches.
1677
- for (const suffix of ["", "+"]) {
1678
- registry.register(cmdDescribeAccessMethods("dA" + suffix));
1679
- registry.register(cmdDescribeAccessMethods("dAm" + suffix));
1680
- registry.register(cmdListOperatorClasses("dAc" + suffix));
1681
- registry.register(cmdListOperatorFamilies("dAf" + suffix));
1682
- registry.register(cmdListOpFamilyOperators("dAo" + suffix));
1683
- registry.register(cmdListOpFamilyFunctions("dAp" + suffix));
1684
- }
1685
- // `x` (expanded) variants of the two-pattern access-method families.
1686
- for (const tail of ["x", "x+", "+x", "xS", "Sx"]) {
1687
- registry.register(cmdListOpFamilyFunctions("dAp" + tail));
1688
- }
1689
- // Types.
1690
- for (const suffix of SUFFIX_COMBOS) {
1691
- registry.register(cmdDescribeTypes("dT" + suffix));
1692
- }
1693
- // Operators.
1694
- for (const suffix of SUFFIX_COMBOS) {
1695
- registry.register(cmdDescribeOperators("do" + suffix));
1696
- }
1697
- // Roles.
1698
- for (const suffix of ["", "+", "S", "S+", "+S"]) {
1699
- registry.register(cmdDescribeRoles("du" + suffix));
1700
- registry.register(cmdDescribeRoles("dg" + suffix));
1701
- }
1702
- // Schemas.
1703
- for (const suffix of SUFFIX_COMBOS) {
1704
- registry.register(cmdListSchemas("dn" + suffix));
1705
- }
1706
- // Domains.
1707
- for (const suffix of SUFFIX_COMBOS) {
1708
- registry.register(cmdListDomains("dD" + suffix));
1709
- }
1710
- // Conversions.
1711
- for (const suffix of SUFFIX_COMBOS) {
1712
- registry.register(cmdListConversions("dc" + suffix));
1713
- }
1714
- // Casts.
1715
- for (const suffix of ["", "+"]) {
1716
- registry.register(cmdListCasts("dC" + suffix));
1717
- }
1718
- // Tablespaces.
1719
- for (const suffix of ["", "+"]) {
1720
- registry.register(cmdDescribeTablespaces("db" + suffix));
1721
- }
1722
- // Languages.
1723
- for (const suffix of SUFFIX_COMBOS) {
1724
- registry.register(cmdListLanguages("dL" + suffix));
1725
- }
1726
- // Collations.
1727
- for (const suffix of SUFFIX_COMBOS) {
1728
- registry.register(cmdListCollations("dO" + suffix));
1729
- }
1730
- // Permissions / default ACLs. `\dp` and `\z` are independent base names
1731
- // (aliasing them via `aliases` couldn't carry separate `x`-suffix
1732
- // variants), so register each with its own suffix matrix.
1733
- for (const tail of ["", "S", "x", "Sx", "xS"]) {
1734
- registry.register(cmdPermissionsList("dp" + tail));
1735
- registry.register(cmdPermissionsList("z" + tail));
1736
- }
1737
- registry.register(cmdListDefaultACLs);
1738
- // Descriptions.
1739
- registry.register(cmdObjectDescription);
1740
- // Databases. `\l`/`\list` plus their `+` (verbose) variants — the scanner
1741
- // folds the trailing `+` into the command name, so `\l+` needs its own
1742
- // registration or it dispatches to nothing. `decodeSuffix`
1743
- // reads the verbose flag back off `ctx.cmdName` at runtime.
1744
- registry.register(cmdListAllDbs);
1745
- registry.register({ ...cmdListAllDbs, name: "l+", aliases: ["list+"] });
1746
- // Config / event triggers / extensions / large objects.
1747
- registry.register(cmdDescribeConfigParams);
1748
- registry.register({ ...cmdDescribeConfigParams, name: "dconfig+" });
1749
- registry.register(cmdListEventTriggers);
1750
- registry.register(cmdListExtensions);
1751
- registry.register({ ...cmdListExtensions, name: "dx+" });
1752
- registry.register(cmdListLargeObjects);
1753
- // Text search family.
1754
- registry.register(cmdListTSConfigs);
1755
- registry.register({ ...cmdListTSConfigs, name: "dF+" });
1756
- registry.register(cmdListTSParsers);
1757
- registry.register({ ...cmdListTSParsers, name: "dFp+" });
1758
- registry.register(cmdListTSDictionaries);
1759
- registry.register({ ...cmdListTSDictionaries, name: "dFd+" });
1760
- registry.register(cmdListTSTemplates);
1761
- registry.register({ ...cmdListTSTemplates, name: "dFt+" });
1762
- // Foreign-data family.
1763
- for (const variant of ["dew", "dew+"]) {
1764
- registry.register({ ...cmdListForeignDataWrappers, name: variant });
1765
- }
1766
- for (const variant of ["des", "des+"]) {
1767
- registry.register({ ...cmdListForeignServers, name: variant });
1768
- }
1769
- for (const variant of ["deu", "deu+"]) {
1770
- registry.register({ ...cmdListUserMappings, name: variant });
1771
- }
1772
- for (const variant of ["det", "det+"]) {
1773
- registry.register({ ...cmdListForeignTables, name: variant });
1774
- }
1775
- // Partitioned tables. Upstream's `\dP` accepts any concatenation of
1776
- // {i,t,n}: `\dPtn` lists nested partitioned tables (table + nested
1777
- // toggles), `\dPin` lists nested partitioned indexes, etc. We
1778
- // register the most common combinations explicitly; the spec's
1779
- // suffix-decoding loop (`includes('i'|'t'|'n')`) drives the actual
1780
- // `reltypes` selection at runtime.
1781
- for (const variant of [
1782
- "dP",
1783
- "dP+",
1784
- "dPi",
1785
- "dPi+",
1786
- "dPin",
1787
- "dPin+",
1788
- "dPt",
1789
- "dPt+",
1790
- "dPtn",
1791
- "dPtn+",
1792
- "dPn",
1793
- "dPn+",
1794
- ]) {
1795
- registry.register({ ...cmdListPartitionedTables, name: variant });
1796
- }
1797
- // Role-database settings.
1798
- registry.register(cmdListDbRoleSettings);
1799
- registry.register({ ...cmdListDbRoleSettings, name: "drds+" });
1800
- // Extended statistics (\dX / \dX+).
1801
- for (const suffix of ["", "+"]) {
1802
- registry.register(cmdListExtendedStats("dX" + suffix));
1803
- }
1804
- // Role grants (\drg / \drg+ / \drgS).
1805
- for (const suffix of ["", "+", "S", "S+", "+S"]) {
1806
- registry.register(cmdDescribeRoleGrants("drg" + suffix));
1807
- }
1808
- // Publication / subscription.
1809
- for (const variant of ["dRp", "dRp+"]) {
1810
- registry.register({ ...cmdListPublications, name: variant });
1811
- }
1812
- for (const variant of ["dRs", "dRs+"]) {
1813
- registry.register({ ...cmdDescribeSubscriptions, name: variant });
1814
- }
1434
+ * Register every `\d*` command this WP implements on the given
1435
+ * registry. Called from `dispatch.ts::defaultRegistry()`.
1436
+ *
1437
+ * We register a separate spec per suffix combination so the dispatcher
1438
+ * can do a single name lookup without re-parsing. The implementation
1439
+ * functions are factory-style (`make…(cmdName)`) so each spec carries
1440
+ * the exact command name for suffix decoding.
1441
+ */
1442
+ const registerDescribeCommands = (registry) => {
1443
+ for (const base of RELATION_BASES) for (const suffix of SUFFIX_COMBOS) {
1444
+ const name = base + suffix;
1445
+ registry.register({
1446
+ ...makeDescribeCmd(base),
1447
+ name
1448
+ });
1449
+ }
1450
+ for (const suffix of DESCRIBE_X_SUFFIXES) registry.register({
1451
+ ...makeDescribeCmd("d"),
1452
+ name: "d" + suffix
1453
+ });
1454
+ for (const tail of [
1455
+ "",
1456
+ "+",
1457
+ "S",
1458
+ "S+",
1459
+ "+S",
1460
+ "a",
1461
+ "n",
1462
+ "p",
1463
+ "t",
1464
+ "w",
1465
+ "x",
1466
+ "ax",
1467
+ "nx",
1468
+ "px",
1469
+ "tx",
1470
+ "wx",
1471
+ "xa",
1472
+ "xn",
1473
+ "xp",
1474
+ "xt",
1475
+ "xw",
1476
+ "a+",
1477
+ "n+",
1478
+ "p+",
1479
+ "t+",
1480
+ "w+",
1481
+ "x+",
1482
+ "a+x",
1483
+ "x+a"
1484
+ ]) registry.register(cmdDescribeFunctions("df" + tail));
1485
+ for (const suffix of ["", "S"]) registry.register(cmdDescribeAggregates("da" + suffix));
1486
+ for (const suffix of ["", "+"]) {
1487
+ registry.register(cmdDescribeAccessMethods("dA" + suffix));
1488
+ registry.register(cmdDescribeAccessMethods("dAm" + suffix));
1489
+ registry.register(cmdListOperatorClasses("dAc" + suffix));
1490
+ registry.register(cmdListOperatorFamilies("dAf" + suffix));
1491
+ registry.register(cmdListOpFamilyOperators("dAo" + suffix));
1492
+ registry.register(cmdListOpFamilyFunctions("dAp" + suffix));
1493
+ }
1494
+ for (const tail of [
1495
+ "x",
1496
+ "x+",
1497
+ "+x",
1498
+ "xS",
1499
+ "Sx"
1500
+ ]) registry.register(cmdListOpFamilyFunctions("dAp" + tail));
1501
+ for (const suffix of SUFFIX_COMBOS) registry.register(cmdDescribeTypes("dT" + suffix));
1502
+ for (const suffix of SUFFIX_COMBOS) registry.register(cmdDescribeOperators("do" + suffix));
1503
+ for (const suffix of [
1504
+ "",
1505
+ "+",
1506
+ "S",
1507
+ "S+",
1508
+ "+S"
1509
+ ]) {
1510
+ registry.register(cmdDescribeRoles("du" + suffix));
1511
+ registry.register(cmdDescribeRoles("dg" + suffix));
1512
+ }
1513
+ for (const suffix of SUFFIX_COMBOS) registry.register(cmdListSchemas("dn" + suffix));
1514
+ for (const suffix of SUFFIX_COMBOS) registry.register(cmdListDomains("dD" + suffix));
1515
+ for (const suffix of SUFFIX_COMBOS) registry.register(cmdListConversions("dc" + suffix));
1516
+ for (const suffix of ["", "+"]) registry.register(cmdListCasts("dC" + suffix));
1517
+ for (const suffix of ["", "+"]) registry.register(cmdDescribeTablespaces("db" + suffix));
1518
+ for (const suffix of SUFFIX_COMBOS) registry.register(cmdListLanguages("dL" + suffix));
1519
+ for (const suffix of SUFFIX_COMBOS) registry.register(cmdListCollations("dO" + suffix));
1520
+ for (const tail of [
1521
+ "",
1522
+ "S",
1523
+ "x",
1524
+ "Sx",
1525
+ "xS"
1526
+ ]) {
1527
+ registry.register(cmdPermissionsList("dp" + tail));
1528
+ registry.register(cmdPermissionsList("z" + tail));
1529
+ }
1530
+ registry.register(cmdListDefaultACLs);
1531
+ registry.register(cmdObjectDescription);
1532
+ registry.register(cmdListAllDbs);
1533
+ registry.register({
1534
+ ...cmdListAllDbs,
1535
+ name: "l+",
1536
+ aliases: ["list+"]
1537
+ });
1538
+ registry.register(cmdDescribeConfigParams);
1539
+ registry.register({
1540
+ ...cmdDescribeConfigParams,
1541
+ name: "dconfig+"
1542
+ });
1543
+ registry.register(cmdListEventTriggers);
1544
+ registry.register(cmdListExtensions);
1545
+ registry.register({
1546
+ ...cmdListExtensions,
1547
+ name: "dx+"
1548
+ });
1549
+ registry.register(cmdListLargeObjects);
1550
+ registry.register(cmdListTSConfigs);
1551
+ registry.register({
1552
+ ...cmdListTSConfigs,
1553
+ name: "dF+"
1554
+ });
1555
+ registry.register(cmdListTSParsers);
1556
+ registry.register({
1557
+ ...cmdListTSParsers,
1558
+ name: "dFp+"
1559
+ });
1560
+ registry.register(cmdListTSDictionaries);
1561
+ registry.register({
1562
+ ...cmdListTSDictionaries,
1563
+ name: "dFd+"
1564
+ });
1565
+ registry.register(cmdListTSTemplates);
1566
+ registry.register({
1567
+ ...cmdListTSTemplates,
1568
+ name: "dFt+"
1569
+ });
1570
+ for (const variant of ["dew", "dew+"]) registry.register({
1571
+ ...cmdListForeignDataWrappers,
1572
+ name: variant
1573
+ });
1574
+ for (const variant of ["des", "des+"]) registry.register({
1575
+ ...cmdListForeignServers,
1576
+ name: variant
1577
+ });
1578
+ for (const variant of ["deu", "deu+"]) registry.register({
1579
+ ...cmdListUserMappings,
1580
+ name: variant
1581
+ });
1582
+ for (const variant of ["det", "det+"]) registry.register({
1583
+ ...cmdListForeignTables,
1584
+ name: variant
1585
+ });
1586
+ for (const variant of [
1587
+ "dP",
1588
+ "dP+",
1589
+ "dPi",
1590
+ "dPi+",
1591
+ "dPin",
1592
+ "dPin+",
1593
+ "dPt",
1594
+ "dPt+",
1595
+ "dPtn",
1596
+ "dPtn+",
1597
+ "dPn",
1598
+ "dPn+"
1599
+ ]) registry.register({
1600
+ ...cmdListPartitionedTables,
1601
+ name: variant
1602
+ });
1603
+ registry.register(cmdListDbRoleSettings);
1604
+ registry.register({
1605
+ ...cmdListDbRoleSettings,
1606
+ name: "drds+"
1607
+ });
1608
+ for (const suffix of ["", "+"]) registry.register(cmdListExtendedStats("dX" + suffix));
1609
+ for (const suffix of [
1610
+ "",
1611
+ "+",
1612
+ "S",
1613
+ "S+",
1614
+ "+S"
1615
+ ]) registry.register(cmdDescribeRoleGrants("drg" + suffix));
1616
+ for (const variant of ["dRp", "dRp+"]) registry.register({
1617
+ ...cmdListPublications,
1618
+ name: variant
1619
+ });
1620
+ for (const variant of ["dRs", "dRs+"]) registry.register({
1621
+ ...cmdDescribeSubscriptions,
1622
+ name: variant
1623
+ });
1815
1624
  };
1625
+ //#endregion
1626
+ export { registerDescribeCommands };