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