neon 3.0.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. package/README.md +70 -5
  2. package/dist/_chunks/auth_selection-DGgq6ifc.js +83 -0
  3. package/dist/_chunks/cmd_pipeline-CUbBO9U_.js +2818 -0
  4. package/dist/_chunks/credentials-MYdHdKah.js +188 -0
  5. package/dist/_chunks/env-NbA61JR3.js +585 -0
  6. package/dist/_chunks/env_services-Tz9G4JeT.js +531 -0
  7. package/dist/_chunks/paths-DMq0Lt7a.js +151 -0
  8. package/dist/_chunks/profiles-Ir29rqns.js +217 -0
  9. package/dist/_chunks/psql-DWH-kc69.js +2169 -0
  10. package/dist/_chunks/rolldown-runtime-D7D4PA-g.js +13 -0
  11. package/dist/_chunks/secure_file-BucZj4yQ.js +39 -0
  12. package/dist/analytics.js +163 -207
  13. package/dist/api.js +815 -758
  14. package/dist/auth.js +121 -141
  15. package/dist/auth_context.js +39 -53
  16. package/dist/cli.js +4 -7
  17. package/dist/commands/api.js +220 -250
  18. package/dist/commands/api_keys.js +251 -314
  19. package/dist/commands/auth.js +283 -328
  20. package/dist/commands/bootstrap.js +372 -437
  21. package/dist/commands/branches.js +304 -455
  22. package/dist/commands/bucket.js +374 -514
  23. package/dist/commands/checkout.js +213 -298
  24. package/dist/commands/config.js +573 -690
  25. package/dist/commands/connection_string.js +137 -165
  26. package/dist/commands/data_api.js +238 -260
  27. package/dist/commands/databases.js +67 -76
  28. package/dist/commands/deploy.js +31 -25
  29. package/dist/commands/dev.js +639 -719
  30. package/dist/commands/diff.js +156 -200
  31. package/dist/commands/env.js +255 -305
  32. package/dist/commands/functions.js +275 -355
  33. package/dist/commands/index.js +70 -65
  34. package/dist/commands/init.js +84 -119
  35. package/dist/commands/inspect.js +55 -55
  36. package/dist/commands/ip_allow.js +88 -120
  37. package/dist/commands/link.js +874 -1019
  38. package/dist/commands/logs.js +291 -0
  39. package/dist/commands/neon_auth.js +725 -933
  40. package/dist/commands/operations.js +34 -25
  41. package/dist/commands/orgs.js +28 -18
  42. package/dist/commands/profile.js +615 -846
  43. package/dist/commands/projects.js +313 -373
  44. package/dist/commands/psql.js +60 -58
  45. package/dist/commands/roles.js +55 -58
  46. package/dist/commands/schema_diff.js +87 -131
  47. package/dist/commands/set_context.js +34 -26
  48. package/dist/commands/snapshots.js +288 -413
  49. package/dist/commands/status.js +41 -37
  50. package/dist/commands/user.js +21 -10
  51. package/dist/commands/vpc_endpoints.js +85 -113
  52. package/dist/config.js +7 -6
  53. package/dist/config_format.js +50 -66
  54. package/dist/config_template.js +128 -157
  55. package/dist/context.js +183 -235
  56. package/dist/current_branch_fast_path.js +40 -49
  57. package/dist/dev/env.js +2 -446
  58. package/dist/dev/functions.js +54 -68
  59. package/dist/dev/inputs.js +46 -58
  60. package/dist/dev/runtime.js +135 -164
  61. package/dist/dev/websocket.js +766 -959
  62. package/dist/env.js +27 -33
  63. package/dist/env_file.js +118 -132
  64. package/dist/env_services.js +2 -51
  65. package/dist/errors.js +57 -68
  66. package/dist/functions_api.js +45 -43
  67. package/dist/help.js +189 -140
  68. package/dist/index.js +182 -257
  69. package/dist/init/agents.js +137 -118
  70. package/dist/init/auth.js +58 -68
  71. package/dist/init/bootstrap.js +325 -396
  72. package/dist/init/build_config.js +4 -2
  73. package/dist/init/detect_agent.js +56 -101
  74. package/dist/init/editors.js +35 -52
  75. package/dist/init/enrich_output.js +51 -66
  76. package/dist/init/extension.js +134 -171
  77. package/dist/init/inspect.js +179 -266
  78. package/dist/init/interactive.js +510 -622
  79. package/dist/init/neonctl.js +117 -168
  80. package/dist/init/orchestrate.js +157 -173
  81. package/dist/init/phases/auth.js +188 -202
  82. package/dist/init/phases/cleanup.js +23 -23
  83. package/dist/init/phases/db.js +251 -277
  84. package/dist/init/phases/getting_started.js +213 -223
  85. package/dist/init/phases/mcp.js +174 -224
  86. package/dist/init/phases/migrations.js +247 -248
  87. package/dist/init/phases/neon_auth.js +114 -133
  88. package/dist/init/phases/setup.js +546 -703
  89. package/dist/init/phases/skills.js +75 -86
  90. package/dist/init/phases/status.js +72 -67
  91. package/dist/init/resolve_context.js +102 -99
  92. package/dist/init/route_command.js +91 -98
  93. package/dist/init/skills.js +174 -218
  94. package/dist/init/vsix.js +77 -99
  95. package/dist/log.js +17 -16
  96. package/dist/neon_services.js +104 -129
  97. package/dist/parameters.gen.js +481 -471
  98. package/dist/pkg.js +17 -19
  99. package/dist/profile_keys.js +44 -47
  100. package/dist/psql/cli.js +44 -47
  101. package/dist/psql/command/cmd_cond.js +231 -406
  102. package/dist/psql/command/cmd_connect.js +557 -764
  103. package/dist/psql/command/cmd_copy.js +728 -984
  104. package/dist/psql/command/cmd_describe.js +1499 -1688
  105. package/dist/psql/command/cmd_format.js +733 -905
  106. package/dist/psql/command/cmd_io.js +2 -2193
  107. package/dist/psql/command/cmd_lo.js +297 -359
  108. package/dist/psql/command/cmd_meta.js +727 -878
  109. package/dist/psql/command/cmd_misc.js +138 -172
  110. package/dist/psql/command/cmd_pipeline.js +2 -1148
  111. package/dist/psql/command/cmd_restrict.js +119 -155
  112. package/dist/psql/command/cmd_show.js +529 -688
  113. package/dist/psql/command/dispatch.js +260 -325
  114. package/dist/psql/command/inputQueue.js +35 -33
  115. package/dist/psql/command/shared.js +49 -63
  116. package/dist/psql/complete/filenames.js +90 -133
  117. package/dist/psql/complete/index.js +59 -97
  118. package/dist/psql/complete/matcher.js +236 -300
  119. package/dist/psql/complete/psqlVars.js +218 -223
  120. package/dist/psql/complete/queries.js +159 -177
  121. package/dist/psql/complete/rules.js +1493 -2299
  122. package/dist/psql/core/common.js +2 -1253
  123. package/dist/psql/core/help.js +456 -546
  124. package/dist/psql/core/mainloop.js +692 -1303
  125. package/dist/psql/core/prompt.js +391 -408
  126. package/dist/psql/core/settings.js +429 -644
  127. package/dist/psql/core/sqlHelp.js +480 -554
  128. package/dist/psql/core/startup.js +2 -846
  129. package/dist/psql/core/syncVars.js +67 -110
  130. package/dist/psql/core/variables.js +156 -278
  131. package/dist/psql/describe/formatters.js +884 -1285
  132. package/dist/psql/describe/processNamePattern.js +173 -260
  133. package/dist/psql/describe/queries.js +1368 -2403
  134. package/dist/psql/describe/versionGate.js +32 -41
  135. package/dist/psql/index.js +2 -2030
  136. package/dist/psql/io/history.js +232 -271
  137. package/dist/psql/io/input.js +103 -108
  138. package/dist/psql/io/lineEditor/buffer.js +238 -319
  139. package/dist/psql/io/lineEditor/complete.js +135 -213
  140. package/dist/psql/io/lineEditor/filename.js +139 -148
  141. package/dist/psql/io/lineEditor/index.js +653 -870
  142. package/dist/psql/io/lineEditor/keymap.js +544 -702
  143. package/dist/psql/io/lineEditor/vt100.js +294 -341
  144. package/dist/psql/io/pgpass.js +158 -187
  145. package/dist/psql/io/pgservice.js +146 -183
  146. package/dist/psql/io/psqlrc.js +328 -403
  147. package/dist/psql/print/aligned.js +1020 -1683
  148. package/dist/psql/print/asciidoc.js +180 -214
  149. package/dist/psql/print/crosstab.js +281 -442
  150. package/dist/psql/print/csv.js +48 -70
  151. package/dist/psql/print/html.js +195 -226
  152. package/dist/psql/print/json.js +75 -88
  153. package/dist/psql/print/latex.js +291 -364
  154. package/dist/psql/print/pager.js +171 -242
  155. package/dist/psql/print/troff.js +194 -226
  156. package/dist/psql/print/unaligned.js +69 -95
  157. package/dist/psql/print/units.js +167 -169
  158. package/dist/psql/scanner/slash.js +428 -483
  159. package/dist/psql/scanner/sql.js +445 -889
  160. package/dist/psql/scanner/stringutils.js +309 -379
  161. package/dist/psql/types/index.js +8 -7
  162. package/dist/psql/types/scanner.js +25 -22
  163. package/dist/psql/wire/connection.js +2042 -2803
  164. package/dist/psql/wire/copy.js +84 -100
  165. package/dist/psql/wire/notify.js +39 -59
  166. package/dist/psql/wire/pipeline.js +305 -518
  167. package/dist/psql/wire/protocol.js +349 -417
  168. package/dist/psql/wire/sasl.js +180 -265
  169. package/dist/psql/wire/tls.js +400 -561
  170. package/dist/storage_api.js +115 -129
  171. package/dist/test_utils/fixtures.js +94 -113
  172. package/dist/test_utils/oauth_server.js +10 -7
  173. package/dist/test_utils/project_dir.js +33 -0
  174. package/dist/utils/ai_gateway_notice.js +131 -162
  175. package/dist/utils/api_enums.js +21 -28
  176. package/dist/utils/auth.js +10 -4
  177. package/dist/utils/branch_notice.js +20 -19
  178. package/dist/utils/branch_picker.js +83 -89
  179. package/dist/utils/cli_name.js +15 -12
  180. package/dist/utils/compute_units.js +20 -27
  181. package/dist/utils/config_diff.js +127 -158
  182. package/dist/utils/enrichers.js +95 -148
  183. package/dist/utils/esbuild.js +130 -189
  184. package/dist/utils/flags.js +35 -47
  185. package/dist/utils/formats.js +8 -15
  186. package/dist/utils/git_diff.js +69 -80
  187. package/dist/utils/inspect_db.js +101 -143
  188. package/dist/utils/inspect_queries.js +179 -142
  189. package/dist/utils/middlewares.js +39 -45
  190. package/dist/utils/openapi.js +87 -99
  191. package/dist/utils/package_manager.js +312 -110
  192. package/dist/utils/point_in_time.js +49 -53
  193. package/dist/utils/psql.js +89 -106
  194. package/dist/utils/service_picker.js +55 -58
  195. package/dist/utils/string.js +5 -5
  196. package/dist/utils/ui.js +38 -55
  197. package/dist/utils/write_sync.js +26 -35
  198. package/dist/utils/zip.js +4 -3
  199. package/dist/writer.js +67 -87
  200. package/package.json +11 -6
  201. package/dist/_shared/auth_selection.js +0 -86
  202. package/dist/_shared/credentials.js +0 -209
  203. package/dist/_shared/env-core/env.js +0 -558
  204. package/dist/_shared/env-core/reuse-secrets.js +0 -223
  205. package/dist/_shared/paths.js +0 -148
  206. package/dist/_shared/profiles.js +0 -276
  207. package/dist/_shared/secure_file.js +0 -43
@@ -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 };