1use crate::ast::ColumnType;
10
11pub mod access_methods;
12pub mod collations;
13pub mod expression_text;
14pub mod foreign_relations;
15pub mod languages;
16pub mod node_tree;
17pub mod oids;
18pub mod resolution;
19pub mod result_type;
20pub mod type_metadata;
21
22pub const AG_CATALOG_SCHEMA: &str = "ag_catalog";
24
25mod virtual_relations;
26pub use virtual_relations::{resolve_virtual_relation, VirtualRelation};
27mod system_relations;
28pub use system_relations::SystemRelation;
29
30impl VirtualRelation {
31 pub const fn accepts_row_lock(self) -> bool {
32 matches!(
33 self,
34 Self::PgNamespace
35 | Self::PgClass
36 | Self::PgInherits
37 | Self::PgPartitionedTable
38 | Self::PgAttribute
39 | Self::PgAttrdef
40 | Self::PgConstraint
41 | Self::PgIndex
42 | Self::PgTrigger
43 | Self::PgRewrite
44 | Self::PgType
45 | Self::PgRange
46 | Self::PgEnum
47 | Self::PgProc
48 | Self::PgLanguage
49 | Self::PgForeignDataWrapper
50 | Self::PgForeignServer
51 | Self::PgForeignTable
52 | Self::PgDatabase
53 | Self::PgAuthid
54 | Self::PgAuthMembers
55 | Self::PgDescription
56 | Self::PgDepend
57 | Self::PgShdepend
58 | Self::AgGraph
59 | Self::AgLabel
60 )
61 }
62
63 #[expect(
64 clippy::too_many_lines,
65 reason = "preserves catalog column and OID order"
66 )]
67 pub fn schema(self) -> Vec<(String, ColumnType)> {
68 macro_rules! columns {
69 ($($name:literal => $ty:expr),* $(,)?) => {
70 vec![$(($name.to_string(), $ty)),*]
71 };
72 }
73
74 match self {
75 Self::PgForeignDataWrapper | Self::PgForeignServer | Self::PgForeignTable => {
76 foreign_relations::schema(self)
77 }
78 Self::InformationSchemaCatalogName => columns![
79 "catalog_name" => sql_identifier(),
80 ],
81 Self::InformationSchemata => columns![
82 "catalog_name" => sql_identifier(),
83 "schema_name" => sql_identifier(),
84 "schema_owner" => sql_identifier(),
85 "default_character_set_catalog" => sql_identifier(),
86 "default_character_set_schema" => sql_identifier(),
87 "default_character_set_name" => sql_identifier(),
88 "sql_path" => character_data(),
89 ],
90 Self::InformationTables => columns![
91 "table_catalog" => sql_identifier(),
92 "table_schema" => sql_identifier(),
93 "table_name" => sql_identifier(),
94 "table_type" => character_data(),
95 "self_referencing_column_name" => sql_identifier(),
96 "reference_generation" => character_data(),
97 "user_defined_type_catalog" => sql_identifier(),
98 "user_defined_type_schema" => sql_identifier(),
99 "user_defined_type_name" => sql_identifier(),
100 "is_insertable_into" => yes_or_no(),
101 "is_typed" => yes_or_no(),
102 "commit_action" => character_data(),
103 ],
104 Self::InformationColumns => columns![
105 "table_catalog" => sql_identifier(),
106 "table_schema" => sql_identifier(),
107 "table_name" => sql_identifier(),
108 "column_name" => sql_identifier(),
109 "ordinal_position" => cardinal_number(),
110 "column_default" => character_data(),
111 "is_nullable" => yes_or_no(),
112 "data_type" => character_data(),
113 "character_maximum_length" => cardinal_number(),
114 "character_octet_length" => cardinal_number(),
115 "numeric_precision" => cardinal_number(),
116 "numeric_precision_radix" => cardinal_number(),
117 "numeric_scale" => cardinal_number(),
118 "datetime_precision" => cardinal_number(),
119 "interval_type" => character_data(),
120 "interval_precision" => cardinal_number(),
121 "character_set_catalog" => sql_identifier(),
122 "character_set_schema" => sql_identifier(),
123 "character_set_name" => sql_identifier(),
124 "collation_catalog" => sql_identifier(),
125 "collation_schema" => sql_identifier(),
126 "collation_name" => sql_identifier(),
127 "domain_catalog" => sql_identifier(),
128 "domain_schema" => sql_identifier(),
129 "domain_name" => sql_identifier(),
130 "udt_catalog" => sql_identifier(),
131 "udt_schema" => sql_identifier(),
132 "udt_name" => sql_identifier(),
133 "scope_catalog" => sql_identifier(),
134 "scope_schema" => sql_identifier(),
135 "scope_name" => sql_identifier(),
136 "maximum_cardinality" => cardinal_number(),
137 "dtd_identifier" => sql_identifier(),
138 "is_self_referencing" => yes_or_no(),
139 "is_identity" => yes_or_no(),
140 "identity_generation" => character_data(),
141 "identity_start" => character_data(),
142 "identity_increment" => character_data(),
143 "identity_maximum" => character_data(),
144 "identity_minimum" => character_data(),
145 "identity_cycle" => yes_or_no(),
146 "is_generated" => character_data(),
147 "generation_expression" => character_data(),
148 "is_updatable" => yes_or_no(),
149 ],
150 Self::InformationColumnPrivileges | Self::InformationRoleColumnGrants => columns![
151 "grantor" => sql_identifier(),
152 "grantee" => sql_identifier(),
153 "table_catalog" => sql_identifier(),
154 "table_schema" => sql_identifier(),
155 "table_name" => sql_identifier(),
156 "column_name" => sql_identifier(),
157 "privilege_type" => character_data(),
158 "is_grantable" => yes_or_no(),
159 ],
160 Self::InformationViews => columns![
161 "table_catalog" => sql_identifier(),
162 "table_schema" => sql_identifier(),
163 "table_name" => sql_identifier(),
164 "view_definition" => character_data(),
165 "check_option" => character_data(),
166 "is_updatable" => yes_or_no(),
167 "is_insertable_into" => yes_or_no(),
168 "is_trigger_updatable" => yes_or_no(),
169 "is_trigger_deletable" => yes_or_no(),
170 "is_trigger_insertable_into" => yes_or_no(),
171 ],
172 Self::InformationRoutines => information_routines_schema(),
173 Self::InformationSequences => columns![
174 "sequence_catalog" => sql_identifier(),
175 "sequence_schema" => sql_identifier(),
176 "sequence_name" => sql_identifier(),
177 "data_type" => character_data(),
178 "numeric_precision" => cardinal_number(),
179 "numeric_precision_radix" => cardinal_number(),
180 "numeric_scale" => cardinal_number(),
181 "start_value" => character_data(),
182 "minimum_value" => character_data(),
183 "maximum_value" => character_data(),
184 "increment" => character_data(),
185 "cycle_option" => yes_or_no(),
186 ],
187 Self::InformationTableConstraints => columns![
188 "constraint_catalog" => sql_identifier(),
189 "constraint_schema" => sql_identifier(),
190 "constraint_name" => sql_identifier(),
191 "table_catalog" => sql_identifier(),
192 "table_schema" => sql_identifier(),
193 "table_name" => sql_identifier(),
194 "constraint_type" => character_data(),
195 "is_deferrable" => yes_or_no(),
196 "initially_deferred" => yes_or_no(),
197 "enforced" => yes_or_no(),
198 "nulls_distinct" => yes_or_no(),
199 ],
200 Self::InformationKeyColumnUsage => columns![
201 "constraint_catalog" => sql_identifier(),
202 "constraint_schema" => sql_identifier(),
203 "constraint_name" => sql_identifier(),
204 "table_catalog" => sql_identifier(),
205 "table_schema" => sql_identifier(),
206 "table_name" => sql_identifier(),
207 "column_name" => sql_identifier(),
208 "ordinal_position" => cardinal_number(),
209 "position_in_unique_constraint" => cardinal_number(),
210 ],
211 Self::PgNamespace => columns![
212 "oid" => ColumnType::Oid,
213 "nspname" => ColumnType::Name,
214 "nspowner" => ColumnType::Oid,
215 "nspacl" => array(ColumnType::AclItem),
216 ],
217 Self::PgClass => columns![
218 "oid" => ColumnType::Oid,
219 "relname" => ColumnType::Name,
220 "relnamespace" => ColumnType::Oid,
221 "reltype" => ColumnType::Oid,
222 "reloftype" => ColumnType::Oid,
223 "relowner" => ColumnType::Oid,
224 "relam" => ColumnType::Oid,
225 "relfilenode" => ColumnType::Oid,
226 "reltablespace" => ColumnType::Oid,
227 "relpages" => ColumnType::Integer,
228 "reltuples" => ColumnType::Real,
229 "relallvisible" => ColumnType::Integer,
230 "relallfrozen" => ColumnType::Integer,
231 "reltoastrelid" => ColumnType::Oid,
232 "relhasindex" => ColumnType::Boolean,
233 "relisshared" => ColumnType::Boolean,
234 "relpersistence" => ColumnType::InternalChar,
235 "relkind" => ColumnType::InternalChar,
236 "relnatts" => ColumnType::SmallInteger,
237 "relchecks" => ColumnType::SmallInteger,
238 "relhasrules" => ColumnType::Boolean,
239 "relhastriggers" => ColumnType::Boolean,
240 "relhassubclass" => ColumnType::Boolean,
241 "relrowsecurity" => ColumnType::Boolean,
242 "relforcerowsecurity" => ColumnType::Boolean,
243 "relispopulated" => ColumnType::Boolean,
244 "relreplident" => ColumnType::InternalChar,
245 "relispartition" => ColumnType::Boolean,
246 "relrewrite" => ColumnType::Oid,
247 "relfrozenxid" => ColumnType::Xid,
248 "relminmxid" => ColumnType::Xid,
249 "relacl" => array(ColumnType::AclItem),
250 "reloptions" => array(ColumnType::Text),
251 "relpartbound" => ColumnType::PgNodeTree,
252 ],
253 Self::PgInherits => columns![
254 "inhrelid" => ColumnType::Oid,
255 "inhparent" => ColumnType::Oid,
256 "inhseqno" => ColumnType::Integer,
257 "inhdetachpending" => ColumnType::Boolean,
258 ],
259 Self::PgPartitionedTable => columns![
260 "partrelid" => ColumnType::Oid,
261 "partstrat" => ColumnType::InternalChar,
262 "partnatts" => ColumnType::SmallInteger,
263 "partdefid" => ColumnType::Oid,
264 "partattrs" => ColumnType::Int2Vector,
265 "partclass" => ColumnType::OidVector,
266 "partcollation" => ColumnType::OidVector,
267 "partexprs" => ColumnType::PgNodeTree,
268 ],
269 Self::PgAttribute => columns![
270 "attrelid" => ColumnType::Oid,
271 "attname" => ColumnType::Name,
272 "atttypid" => ColumnType::Oid,
273 "attlen" => ColumnType::SmallInteger,
274 "attnum" => ColumnType::SmallInteger,
275 "atttypmod" => ColumnType::Integer,
276 "attndims" => ColumnType::SmallInteger,
277 "attbyval" => ColumnType::Boolean,
278 "attalign" => ColumnType::InternalChar,
279 "attstorage" => ColumnType::InternalChar,
280 "attcompression" => ColumnType::InternalChar,
281 "attnotnull" => ColumnType::Boolean,
282 "atthasdef" => ColumnType::Boolean,
283 "atthasmissing" => ColumnType::Boolean,
284 "attidentity" => ColumnType::InternalChar,
285 "attgenerated" => ColumnType::InternalChar,
286 "attisdropped" => ColumnType::Boolean,
287 "attislocal" => ColumnType::Boolean,
288 "attinhcount" => ColumnType::SmallInteger,
289 "attcollation" => ColumnType::Oid,
290 "attstattarget" => ColumnType::SmallInteger,
291 "attacl" => array(ColumnType::AclItem),
292 "attoptions" => array(ColumnType::Text),
293 "attfdwoptions" => array(ColumnType::Text),
294 "attmissingval" => ColumnType::AnyArray,
295 ],
296 Self::PgAttrdef => columns![
297 "oid" => ColumnType::Oid,
298 "adrelid" => ColumnType::Oid,
299 "adnum" => ColumnType::SmallInteger,
300 "adbin" => ColumnType::PgNodeTree,
301 ],
302 Self::PgConstraint => columns![
303 "oid" => ColumnType::Oid,
304 "conname" => ColumnType::Name,
305 "connamespace" => ColumnType::Oid,
306 "contype" => ColumnType::InternalChar,
307 "condeferrable" => ColumnType::Boolean,
308 "condeferred" => ColumnType::Boolean,
309 "conenforced" => ColumnType::Boolean,
310 "convalidated" => ColumnType::Boolean,
311 "conrelid" => ColumnType::Oid,
312 "contypid" => ColumnType::Oid,
313 "conindid" => ColumnType::Oid,
314 "conparentid" => ColumnType::Oid,
315 "confrelid" => ColumnType::Oid,
316 "confupdtype" => ColumnType::InternalChar,
317 "confdeltype" => ColumnType::InternalChar,
318 "confmatchtype" => ColumnType::InternalChar,
319 "conislocal" => ColumnType::Boolean,
320 "coninhcount" => ColumnType::SmallInteger,
321 "connoinherit" => ColumnType::Boolean,
322 "conperiod" => ColumnType::Boolean,
323 "conkey" => array(ColumnType::SmallInteger),
324 "confkey" => array(ColumnType::SmallInteger),
325 "conpfeqop" => array(ColumnType::Oid),
326 "conppeqop" => array(ColumnType::Oid),
327 "conffeqop" => array(ColumnType::Oid),
328 "confdelsetcols" => array(ColumnType::SmallInteger),
329 "conexclop" => array(ColumnType::Oid),
330 "conbin" => ColumnType::PgNodeTree,
331 ],
332 Self::PgIndex => columns![
333 "indexrelid" => ColumnType::Oid,
334 "indrelid" => ColumnType::Oid,
335 "indnatts" => ColumnType::SmallInteger,
336 "indnkeyatts" => ColumnType::SmallInteger,
337 "indisunique" => ColumnType::Boolean,
338 "indnullsnotdistinct" => ColumnType::Boolean,
339 "indisprimary" => ColumnType::Boolean,
340 "indisexclusion" => ColumnType::Boolean,
341 "indimmediate" => ColumnType::Boolean,
342 "indisclustered" => ColumnType::Boolean,
343 "indisvalid" => ColumnType::Boolean,
344 "indcheckxmin" => ColumnType::Boolean,
345 "indisready" => ColumnType::Boolean,
346 "indislive" => ColumnType::Boolean,
347 "indisreplident" => ColumnType::Boolean,
348 "indkey" => ColumnType::Int2Vector,
349 "indcollation" => ColumnType::OidVector,
350 "indclass" => ColumnType::OidVector,
351 "indoption" => ColumnType::Int2Vector,
352 "indexprs" => ColumnType::PgNodeTree,
353 "indpred" => ColumnType::PgNodeTree,
354 ],
355 Self::PgTrigger => columns![
356 "oid" => ColumnType::Oid,
357 "tgrelid" => ColumnType::Oid,
358 "tgparentid" => ColumnType::Oid,
359 "tgname" => ColumnType::Name,
360 "tgfoid" => ColumnType::Oid,
361 "tgtype" => ColumnType::SmallInteger,
362 "tgenabled" => ColumnType::InternalChar,
363 "tgisinternal" => ColumnType::Boolean,
364 "tgconstrrelid" => ColumnType::Oid,
365 "tgconstrindid" => ColumnType::Oid,
366 "tgconstraint" => ColumnType::Oid,
367 "tgdeferrable" => ColumnType::Boolean,
368 "tginitdeferred" => ColumnType::Boolean,
369 "tgnargs" => ColumnType::SmallInteger,
370 "tgattr" => ColumnType::Int2Vector,
371 "tgargs" => ColumnType::Bytea,
372 "tgqual" => ColumnType::PgNodeTree,
373 "tgoldtable" => ColumnType::Name,
374 "tgnewtable" => ColumnType::Name,
375 ],
376 Self::PgRewrite => columns![
377 "oid" => ColumnType::Oid,
378 "rulename" => ColumnType::Name,
379 "ev_class" => ColumnType::Oid,
380 "ev_type" => ColumnType::InternalChar,
381 "ev_enabled" => ColumnType::InternalChar,
382 "is_instead" => ColumnType::Boolean,
383 "ev_qual" => ColumnType::PgNodeTree,
384 "ev_action" => ColumnType::PgNodeTree,
385 ],
386 Self::PgRules => columns![
387 "schemaname" => ColumnType::Name,
388 "tablename" => ColumnType::Name,
389 "rulename" => ColumnType::Name,
390 "definition" => ColumnType::Text,
391 ],
392 Self::PgTables => columns![
393 "schemaname" => ColumnType::Name,
394 "tablename" => ColumnType::Name,
395 "tableowner" => ColumnType::Name,
396 "tablespace" => ColumnType::Name,
397 "hasindexes" => ColumnType::Boolean,
398 "hasrules" => ColumnType::Boolean,
399 "hastriggers" => ColumnType::Boolean,
400 "rowsecurity" => ColumnType::Boolean,
401 ],
402 Self::PgViews => columns![
403 "schemaname" => ColumnType::Name,
404 "viewname" => ColumnType::Name,
405 "viewowner" => ColumnType::Name,
406 "definition" => ColumnType::Text,
407 ],
408 Self::PgIndexes => columns![
409 "schemaname" => ColumnType::Name,
410 "tablename" => ColumnType::Name,
411 "indexname" => ColumnType::Name,
412 "tablespace" => ColumnType::Name,
413 "indexdef" => ColumnType::Text,
414 ],
415 Self::PgType => columns![
416 "oid" => ColumnType::Oid,
417 "typname" => ColumnType::Name,
418 "typnamespace" => ColumnType::Oid,
419 "typowner" => ColumnType::Oid,
420 "typlen" => ColumnType::SmallInteger,
421 "typbyval" => ColumnType::Boolean,
422 "typtype" => ColumnType::InternalChar,
423 "typcategory" => ColumnType::InternalChar,
424 "typispreferred" => ColumnType::Boolean,
425 "typisdefined" => ColumnType::Boolean,
426 "typdelim" => ColumnType::InternalChar,
427 "typrelid" => ColumnType::Oid,
428 "typsubscript" => ColumnType::Regproc,
429 "typelem" => ColumnType::Oid,
430 "typarray" => ColumnType::Oid,
431 "typinput" => ColumnType::Regproc,
432 "typoutput" => ColumnType::Regproc,
433 "typreceive" => ColumnType::Regproc,
434 "typsend" => ColumnType::Regproc,
435 "typmodin" => ColumnType::Regproc,
436 "typmodout" => ColumnType::Regproc,
437 "typanalyze" => ColumnType::Regproc,
438 "typalign" => ColumnType::InternalChar,
439 "typstorage" => ColumnType::InternalChar,
440 "typnotnull" => ColumnType::Boolean,
441 "typbasetype" => ColumnType::Oid,
442 "typtypmod" => ColumnType::Integer,
443 "typndims" => ColumnType::Integer,
444 "typcollation" => ColumnType::Oid,
445 "typdefaultbin" => ColumnType::PgNodeTree,
446 "typdefault" => ColumnType::Text,
447 "typacl" => array(ColumnType::AclItem),
448 ],
449 Self::PgEnum => columns![
450 "oid" => ColumnType::Oid,
451 "enumtypid" => ColumnType::Oid,
452 "enumsortorder" => ColumnType::Real,
453 "enumlabel" => ColumnType::Name,
454 ],
455 Self::PgRange => columns![
456 "rngtypid" => ColumnType::Oid,
457 "rngsubtype" => ColumnType::Oid,
458 "rngmultitypid" => ColumnType::Oid,
459 "rngcollation" => ColumnType::Oid,
460 "rngsubopc" => ColumnType::Oid,
461 "rngcanonical" => ColumnType::Regproc,
462 "rngsubdiff" => ColumnType::Regproc,
463 ],
464 Self::PgProc => columns![
465 "oid" => ColumnType::Oid,
466 "proname" => ColumnType::Name,
467 "pronamespace" => ColumnType::Oid,
468 "proowner" => ColumnType::Oid,
469 "prolang" => ColumnType::Oid,
470 "procost" => ColumnType::Real,
471 "prorows" => ColumnType::Real,
472 "provariadic" => ColumnType::Oid,
473 "prosupport" => ColumnType::Regproc,
474 "prokind" => ColumnType::InternalChar,
475 "prosecdef" => ColumnType::Boolean,
476 "proleakproof" => ColumnType::Boolean,
477 "proisstrict" => ColumnType::Boolean,
478 "proretset" => ColumnType::Boolean,
479 "provolatile" => ColumnType::InternalChar,
480 "proparallel" => ColumnType::InternalChar,
481 "pronargs" => ColumnType::SmallInteger,
482 "pronargdefaults" => ColumnType::SmallInteger,
483 "prorettype" => ColumnType::Oid,
484 "proargtypes" => ColumnType::OidVector,
485 "proallargtypes" => array(ColumnType::Oid),
486 "proargmodes" => array(ColumnType::InternalChar),
487 "proargnames" => array(ColumnType::Text),
488 "proargdefaults" => ColumnType::PgNodeTree,
489 "protrftypes" => array(ColumnType::Oid),
490 "prosrc" => ColumnType::Text,
491 "probin" => ColumnType::Text,
492 "prosqlbody" => ColumnType::PgNodeTree,
493 "proconfig" => array(ColumnType::Text),
494 "proacl" => array(ColumnType::AclItem),
495 ],
496 Self::PgLanguage => columns![
497 "oid" => ColumnType::Oid,
498 "lanname" => ColumnType::Name,
499 "lanowner" => ColumnType::Oid,
500 "lanispl" => ColumnType::Boolean,
501 "lanpltrusted" => ColumnType::Boolean,
502 "lanplcallfoid" => ColumnType::Oid,
503 "laninline" => ColumnType::Oid,
504 "lanvalidator" => ColumnType::Oid,
505 "lanacl" => array(ColumnType::AclItem),
506 ],
507 Self::PgDatabase => columns![
508 "oid" => ColumnType::Oid,
509 "datname" => ColumnType::Name,
510 "datdba" => ColumnType::Oid,
511 "encoding" => ColumnType::Integer,
512 "datlocprovider" => ColumnType::InternalChar,
513 "datistemplate" => ColumnType::Boolean,
514 "datallowconn" => ColumnType::Boolean,
515 "dathasloginevt" => ColumnType::Boolean,
516 "datconnlimit" => ColumnType::Integer,
517 "datfrozenxid" => ColumnType::Xid,
518 "datminmxid" => ColumnType::Xid,
519 "dattablespace" => ColumnType::Oid,
520 "datcollate" => ColumnType::Text,
521 "datctype" => ColumnType::Text,
522 "datlocale" => ColumnType::Text,
523 "daticurules" => ColumnType::Text,
524 "datcollversion" => ColumnType::Text,
525 "datacl" => array(ColumnType::AclItem),
526 ],
527 Self::PgAuthid => columns![
528 "oid" => ColumnType::Oid,
529 "rolname" => ColumnType::Name,
530 "rolsuper" => ColumnType::Boolean,
531 "rolinherit" => ColumnType::Boolean,
532 "rolcreaterole" => ColumnType::Boolean,
533 "rolcreatedb" => ColumnType::Boolean,
534 "rolcanlogin" => ColumnType::Boolean,
535 "rolreplication" => ColumnType::Boolean,
536 "rolbypassrls" => ColumnType::Boolean,
537 "rolconnlimit" => ColumnType::Integer,
538 "rolpassword" => ColumnType::Text,
539 "rolvaliduntil" => ColumnType::TimestampTz,
540 ],
541 Self::PgAuthMembers => columns![
542 "oid" => ColumnType::Oid,
543 "roleid" => ColumnType::Oid,
544 "member" => ColumnType::Oid,
545 "grantor" => ColumnType::Oid,
546 "admin_option" => ColumnType::Boolean,
547 "inherit_option" => ColumnType::Boolean,
548 "set_option" => ColumnType::Boolean,
549 ],
550 Self::PgRoles => columns![
551 "rolname" => ColumnType::Name,
552 "rolsuper" => ColumnType::Boolean,
553 "rolinherit" => ColumnType::Boolean,
554 "rolcreaterole" => ColumnType::Boolean,
555 "rolcreatedb" => ColumnType::Boolean,
556 "rolcanlogin" => ColumnType::Boolean,
557 "rolreplication" => ColumnType::Boolean,
558 "rolconnlimit" => ColumnType::Integer,
559 "rolpassword" => ColumnType::Text,
560 "rolvaliduntil" => ColumnType::TimestampTz,
561 "rolbypassrls" => ColumnType::Boolean,
562 "rolconfig" => array(ColumnType::Text),
563 "oid" => ColumnType::Oid,
564 ],
565 Self::PgUser => columns![
566 "usename" => ColumnType::Name,
567 "usesysid" => ColumnType::Oid,
568 "usecreatedb" => ColumnType::Boolean,
569 "usesuper" => ColumnType::Boolean,
570 "userepl" => ColumnType::Boolean,
571 "usebypassrls" => ColumnType::Boolean,
572 "passwd" => ColumnType::Text,
573 "valuntil" => ColumnType::TimestampTz,
574 "useconfig" => array(ColumnType::Text),
575 ],
576 Self::PgCursors => columns![
577 "name" => ColumnType::Text,
578 "statement" => ColumnType::Text,
579 "is_holdable" => ColumnType::Boolean,
580 "is_binary" => ColumnType::Boolean,
581 "is_scrollable" => ColumnType::Boolean,
582 "creation_time" => ColumnType::TimestampTz,
583 ],
584 Self::PgPreparedStatements => columns![
585 "name" => ColumnType::Text,
586 "statement" => ColumnType::Text,
587 "prepare_time" => ColumnType::TimestampTz,
588 "parameter_types" => array(ColumnType::Regtype),
589 "result_types" => array(ColumnType::Regtype),
590 "from_sql" => ColumnType::Boolean,
591 "generic_plans" => ColumnType::BigInteger,
592 "custom_plans" => ColumnType::BigInteger,
593 ],
594 Self::PgSettings => columns![
595 "name" => ColumnType::Text,
596 "setting" => ColumnType::Text,
597 "unit" => ColumnType::Text,
598 "category" => ColumnType::Text,
599 "short_desc" => ColumnType::Text,
600 "extra_desc" => ColumnType::Text,
601 "context" => ColumnType::Text,
602 "vartype" => ColumnType::Text,
603 "source" => ColumnType::Text,
604 "min_val" => ColumnType::Text,
605 "max_val" => ColumnType::Text,
606 "enumvals" => array(ColumnType::Text),
607 "boot_val" => ColumnType::Text,
608 "reset_val" => ColumnType::Text,
609 "sourcefile" => ColumnType::Text,
610 "sourceline" => ColumnType::Integer,
611 "pending_restart" => ColumnType::Boolean,
612 ],
613 Self::PgDescription => columns![
614 "objoid" => ColumnType::Oid,
615 "classoid" => ColumnType::Oid,
616 "objsubid" => ColumnType::Integer,
617 "description" => ColumnType::Text,
618 ],
619 Self::PgDepend => columns![
620 "classid" => ColumnType::Oid,
621 "objid" => ColumnType::Oid,
622 "objsubid" => ColumnType::Integer,
623 "refclassid" => ColumnType::Oid,
624 "refobjid" => ColumnType::Oid,
625 "refobjsubid" => ColumnType::Integer,
626 "deptype" => ColumnType::InternalChar,
627 ],
628 Self::PgShdepend => columns![
629 "dbid" => ColumnType::Oid,
630 "classid" => ColumnType::Oid,
631 "objid" => ColumnType::Oid,
632 "objsubid" => ColumnType::Integer,
633 "refclassid" => ColumnType::Oid,
634 "refobjid" => ColumnType::Oid,
635 "deptype" => ColumnType::InternalChar,
636 ],
637 Self::PgMatviews => columns![
638 "schemaname" => ColumnType::Name,
639 "matviewname" => ColumnType::Name,
640 "matviewowner" => ColumnType::Name,
641 "tablespace" => ColumnType::Name,
642 "hasindexes" => ColumnType::Boolean,
643 "ispopulated" => ColumnType::Boolean,
644 "definition" => ColumnType::Text,
645 ],
646 Self::PgSequences => columns![
647 "schemaname" => ColumnType::Name,
648 "sequencename" => ColumnType::Name,
649 "sequenceowner" => ColumnType::Name,
650 "data_type" => ColumnType::Regtype,
651 "start_value" => ColumnType::BigInteger,
652 "min_value" => ColumnType::BigInteger,
653 "max_value" => ColumnType::BigInteger,
654 "increment_by" => ColumnType::BigInteger,
655 "cycle" => ColumnType::Boolean,
656 "cache_size" => ColumnType::BigInteger,
657 "last_value" => ColumnType::BigInteger,
658 ],
659 Self::AgGraph => columns![
660 "graphid" => ColumnType::Oid,
661 "name" => ColumnType::Name,
662 "namespace" => ColumnType::Regnamespace,
663 ],
664 Self::AgLabel => columns![
665 "name" => ColumnType::Name,
666 "graph" => ColumnType::Oid,
667 "id" => ag_label_id(),
668 "kind" => ag_label_kind(),
669 "relation" => ColumnType::Regclass,
670 "seq_name" => ColumnType::Name,
671 ],
672 }
673 }
674}
675
676fn ag_catalog_domain(name: &str, base: ColumnType) -> ColumnType {
677 ColumnType::Domain {
678 schema: AG_CATALOG_SCHEMA.into(),
679 name: name.into(),
680 oid: ag_catalog_type_oid(name),
681 array_oid: None,
682 base: Box::new(base),
683 }
684}
685
686pub fn ag_catalog_type_oid(name: &str) -> u32 {
689 let oid = oids::stable_oid("type", &format!("{AG_CATALOG_SCHEMA}.{name}"));
690 u32::try_from(oid).unwrap_or(0)
691}
692
693pub fn ag_label_id() -> ColumnType {
695 ag_catalog_domain("label_id", ColumnType::Integer)
696}
697
698pub fn ag_label_kind() -> ColumnType {
700 ag_catalog_domain("label_kind", ColumnType::InternalChar)
701}
702
703pub fn age_graphid() -> ColumnType {
705 ag_catalog_domain("graphid", ColumnType::BigInteger)
706}
707
708pub fn age_agtype() -> ColumnType {
710 ag_catalog_domain("agtype", ColumnType::JsonB)
711}
712
713pub fn ag_catalog_domains() -> Vec<ColumnType> {
714 vec![ag_label_id(), ag_label_kind()]
715}
716
717#[must_use]
719pub fn system_catalog_domain(oid: u32) -> Option<ColumnType> {
720 information_schema_domains()
721 .into_iter()
722 .chain(ag_catalog_domains())
723 .chain([age_graphid(), age_agtype()])
724 .find(|ty| matches!(ty, ColumnType::Domain { oid: domain_oid, .. } if *domain_oid == oid))
725}
726
727fn array(element: ColumnType) -> ColumnType {
728 ColumnType::Array(Box::new(element))
729}
730
731fn information_schema_domain(name: &str, oid: u32, base: ColumnType) -> ColumnType {
733 ColumnType::Domain {
734 schema: "information_schema".into(),
735 name: name.into(),
736 oid,
737 array_oid: Some(oid - 1),
738 base: Box::new(base),
739 }
740}
741
742fn cardinal_number() -> ColumnType {
743 information_schema_domain("cardinal_number", 13_307, ColumnType::Integer)
744}
745
746fn character_data() -> ColumnType {
747 information_schema_domain("character_data", 13_310, ColumnType::Varchar(None))
748}
749
750fn sql_identifier() -> ColumnType {
751 information_schema_domain("sql_identifier", 13_312, ColumnType::Name)
752}
753
754fn time_stamp() -> ColumnType {
755 information_schema_domain("time_stamp", 13_318, ColumnType::TimestampTz)
756}
757
758fn yes_or_no() -> ColumnType {
759 information_schema_domain("yes_or_no", 13_320, ColumnType::Varchar(Some(3)))
760}
761
762pub fn information_schema_domains() -> Vec<ColumnType> {
763 vec![
764 cardinal_number(),
765 character_data(),
766 sql_identifier(),
767 time_stamp(),
768 yes_or_no(),
769 ]
770}
771
772fn information_routines_schema() -> Vec<(String, ColumnType)> {
773 macro_rules! columns {
774 ($($name:literal => $ty:expr),* $(,)?) => {
775 vec![$(($name.to_string(), $ty)),*]
776 };
777 }
778
779 columns![
780 "specific_catalog" => sql_identifier(),
781 "specific_schema" => sql_identifier(),
782 "specific_name" => sql_identifier(),
783 "routine_catalog" => sql_identifier(),
784 "routine_schema" => sql_identifier(),
785 "routine_name" => sql_identifier(),
786 "routine_type" => character_data(),
787 "module_catalog" => sql_identifier(),
788 "module_schema" => sql_identifier(),
789 "module_name" => sql_identifier(),
790 "udt_catalog" => sql_identifier(),
791 "udt_schema" => sql_identifier(),
792 "udt_name" => sql_identifier(),
793 "data_type" => character_data(),
794 "character_maximum_length" => cardinal_number(),
795 "character_octet_length" => cardinal_number(),
796 "character_set_catalog" => sql_identifier(),
797 "character_set_schema" => sql_identifier(),
798 "character_set_name" => sql_identifier(),
799 "collation_catalog" => sql_identifier(),
800 "collation_schema" => sql_identifier(),
801 "collation_name" => sql_identifier(),
802 "numeric_precision" => cardinal_number(),
803 "numeric_precision_radix" => cardinal_number(),
804 "numeric_scale" => cardinal_number(),
805 "datetime_precision" => cardinal_number(),
806 "interval_type" => character_data(),
807 "interval_precision" => cardinal_number(),
808 "type_udt_catalog" => sql_identifier(),
809 "type_udt_schema" => sql_identifier(),
810 "type_udt_name" => sql_identifier(),
811 "scope_catalog" => sql_identifier(),
812 "scope_schema" => sql_identifier(),
813 "scope_name" => sql_identifier(),
814 "maximum_cardinality" => cardinal_number(),
815 "dtd_identifier" => sql_identifier(),
816 "routine_body" => character_data(),
817 "routine_definition" => character_data(),
818 "external_name" => character_data(),
819 "external_language" => character_data(),
820 "parameter_style" => character_data(),
821 "is_deterministic" => yes_or_no(),
822 "sql_data_access" => character_data(),
823 "is_null_call" => yes_or_no(),
824 "sql_path" => character_data(),
825 "schema_level_routine" => yes_or_no(),
826 "max_dynamic_result_sets" => cardinal_number(),
827 "is_user_defined_cast" => yes_or_no(),
828 "is_implicitly_invocable" => yes_or_no(),
829 "security_type" => character_data(),
830 "to_sql_specific_catalog" => sql_identifier(),
831 "to_sql_specific_schema" => sql_identifier(),
832 "to_sql_specific_name" => sql_identifier(),
833 "as_locator" => yes_or_no(),
834 "created" => time_stamp(),
835 "last_altered" => time_stamp(),
836 "new_savepoint_level" => yes_or_no(),
837 "is_udt_dependent" => yes_or_no(),
838 "result_cast_from_data_type" => character_data(),
839 "result_cast_as_locator" => yes_or_no(),
840 "result_cast_char_max_length" => cardinal_number(),
841 "result_cast_char_octet_length" => cardinal_number(),
842 "result_cast_char_set_catalog" => sql_identifier(),
843 "result_cast_char_set_schema" => sql_identifier(),
844 "result_cast_char_set_name" => sql_identifier(),
845 "result_cast_collation_catalog" => sql_identifier(),
846 "result_cast_collation_schema" => sql_identifier(),
847 "result_cast_collation_name" => sql_identifier(),
848 "result_cast_numeric_precision" => cardinal_number(),
849 "result_cast_numeric_precision_radix" => cardinal_number(),
850 "result_cast_numeric_scale" => cardinal_number(),
851 "result_cast_datetime_precision" => cardinal_number(),
852 "result_cast_interval_type" => character_data(),
853 "result_cast_interval_precision" => cardinal_number(),
854 "result_cast_type_udt_catalog" => sql_identifier(),
855 "result_cast_type_udt_schema" => sql_identifier(),
856 "result_cast_type_udt_name" => sql_identifier(),
857 "result_cast_scope_catalog" => sql_identifier(),
858 "result_cast_scope_schema" => sql_identifier(),
859 "result_cast_scope_name" => sql_identifier(),
860 "result_cast_maximum_cardinality" => cardinal_number(),
861 "result_cast_dtd_identifier" => sql_identifier(),
862 ]
863}
864
865#[cfg(test)]
866mod tests;
867
868pub mod analysis;
869
870pub mod array_type_names;
871
872pub mod composite_type;
873pub mod domain;
874pub mod enum_type;
875pub mod events;
876pub mod foreign_server;
877pub mod foreign_wrapper;
878pub mod index;
879pub mod roles;
880
881pub fn is_virtual_system_schema(name: &str) -> bool {
884 matches!(name, "pg_catalog" | "information_schema" | "ag_catalog")
885}
886
887pub mod view;
888
889pub mod session;
890
891pub mod constraints;
892
893pub mod dependencies;
894
895pub const DATABASE_NAME: &str = "uqa";
896pub const DATABASE_OID: i64 = 5;
897
898pub mod stored_ast;
899
900pub mod regrole_dependencies;
901
902pub mod graph_oids;
903pub mod relation_attributes;
904pub mod relation_oids;
905pub mod temporary_namespace;
906
907pub mod security;
908
909pub mod stored_view;
910
911pub mod errors;
912
913pub mod sequence_functions;