rupg_catalog/aggregate.rs
1//! The aggregate functions of `pg_aggregate`, as `AggregateCreate` of `pg_aggregate.c` makes them. The function of an aggregate is a row of `pg_proc` with `prokind` `a`.
2
3use rupg_common::Result;
4
5use super::{Catalog, Function, ObjRef};
6
7/// The OID of `pg_aggregate`.
8pub const PG_AGGREGATE: u32 = 2600;
9
10/// An aggregate function, one row of `pg_aggregate`.
11#[derive(Clone, Debug, PartialEq, Eq)]
12pub struct Aggregate {
13 /// `aggfnoid`: the OID of the function in `pg_proc`. [`Catalog::create_aggregate`] sets it.
14 pub function: u32,
15 /// `aggkind`: `n` for a normal aggregate, `o` for an ordered-set aggregate or `h` for a hypothetical-set aggregate.
16 pub kind: u8,
17 /// `aggnumdirectargs`: the number of direct arguments of an ordered-set aggregate.
18 pub ndirect: i16,
19 /// `aggtransfn`: the transition function.
20 pub transfn: u32,
21 /// `aggfinalfn`: the final function, or 0.
22 pub finalfn: u32,
23 /// `aggcombinefn`: the combine function, or 0.
24 pub combinefn: u32,
25 /// `aggserialfn`: the serialization function, or 0.
26 pub serialfn: u32,
27 /// `aggdeserialfn`: the deserialization function, or 0.
28 pub deserialfn: u32,
29 /// `aggmtransfn`: the forward transition function of the moving-aggregate mode, or 0.
30 pub mtransfn: u32,
31 /// `aggminvtransfn`: the inverse transition function of the moving-aggregate mode, or 0.
32 pub minvtransfn: u32,
33 /// `aggmfinalfn`: the final function of the moving-aggregate mode, or 0.
34 pub mfinalfn: u32,
35 /// `aggfinalextra`: the final function gets a null for each argument of the aggregate after the state.
36 pub finalextra: bool,
37 /// `aggmfinalextra`: the same for the final function of the moving-aggregate mode.
38 pub mfinalextra: bool,
39 /// `aggfinalmodify`: `r` read-only, `s` shareable or `w` read-write.
40 pub finalmodify: u8,
41 /// `aggmfinalmodify`: the same for the final function of the moving-aggregate mode.
42 pub mfinalmodify: u8,
43 /// `aggsortop`: the sort operator, or 0.
44 pub sortop: u32,
45 /// `aggtranstype`: the type of the state.
46 pub transtype: u32,
47 /// `aggtransspace`: the estimate of the size of the state, or 0.
48 pub transspace: i32,
49 /// `aggmtranstype`: the type of the state of the moving-aggregate mode, or 0.
50 pub mtranstype: u32,
51 /// `aggmtransspace`: the estimate of the size of that state, or 0.
52 pub mtransspace: i32,
53 /// `agginitval`: the text of the first state, or `None` for null.
54 pub initval: Option<String>,
55 /// `aggminitval`: the text of the first state of the moving-aggregate mode, or `None` for null.
56 pub minitval: Option<String>,
57}
58
59impl Catalog {
60 /// `AggregateCreate`: the row of `pg_proc` of the aggregate, which gets the next OID, and its row of `pg_aggregate`. The function depends on its schema and on the objects in `refs`, which are its types, its support functions and its sort operator.
61 ///
62 /// # Errors
63 ///
64 /// `42723` when the schema has a function with the name and the argument types.
65 pub fn create_aggregate(
66 &mut self,
67 function: Function,
68 mut aggregate: Aggregate,
69 refs: &[ObjRef],
70 ) -> Result<u32> {
71 let oid = self.create_function(function, refs)?;
72 aggregate.function = oid;
73 self.aggregates.insert(oid, aggregate);
74 Ok(oid)
75 }
76
77 /// `AggregateCreate` with `replace` for the aggregate `oid` that exists: its function and its row of `pg_aggregate` get the new facts, and its dependencies are new.
78 ///
79 /// # Errors
80 ///
81 /// An internal error when no function has the OID.
82 pub fn replace_aggregate(
83 &mut self,
84 oid: u32,
85 function: Function,
86 mut aggregate: Aggregate,
87 refs: &[ObjRef],
88 ) -> Result<()> {
89 self.replace_function(oid, function, refs)?;
90 aggregate.function = oid;
91 self.aggregates.insert(oid, aggregate);
92 Ok(())
93 }
94
95 /// The aggregates, in the order of the OIDs of their functions.
96 pub fn aggregates(&self) -> impl Iterator<Item = &Aggregate> {
97 self.aggregates.values()
98 }
99
100 /// The row of `pg_aggregate` of the function with the OID.
101 pub fn aggregate(&self, function: u32) -> Option<&Aggregate> {
102 self.aggregates.get(&function)
103 }
104}