Skip to main content

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}