1use rupg_common::Result;
4
5use super::{Catalog, ObjRef, PG_NAMESPACE, PG_PROC, PG_TYPE, no_object};
6
7pub const PG_OPERATOR: u32 = 2617;
9
10#[derive(Clone, Debug, PartialEq, Eq)]
12pub struct Operator {
13 pub oid: u32,
15 pub name: String,
17 pub namespace: u32,
19 pub owner: u32,
21 pub kind: u8,
23 pub can_merge: bool,
25 pub can_hash: bool,
27 pub left: u32,
29 pub right: u32,
31 pub result: u32,
33 pub commutator: u32,
35 pub negator: u32,
37 pub code: u32,
39 pub restrict: u32,
41 pub join: u32,
43}
44
45impl Operator {
46 pub fn shell(name: &str, namespace: u32, owner: u32, left: u32, right: u32) -> Operator {
48 Operator {
49 oid: 0,
50 name: name.to_string(),
51 namespace,
52 owner,
53 kind: if left == 0 { b'l' } else { b'b' },
54 can_merge: false,
55 can_hash: false,
56 left,
57 right,
58 result: 0,
59 commutator: 0,
60 negator: 0,
61 code: 0,
62 restrict: 0,
63 join: 0,
64 }
65 }
66}
67
68impl Catalog {
69 pub fn operators(&self) -> impl Iterator<Item = &Operator> {
71 self.operators.values()
72 }
73
74 pub fn operator(&self, oid: u32) -> Option<&Operator> {
76 self.operators.get(&oid)
77 }
78
79 pub fn operator_by_name(
81 &self,
82 namespace: u32,
83 name: &str,
84 left: u32,
85 right: u32,
86 ) -> Option<&Operator> {
87 self.operators.values().find(|o| {
88 o.namespace == namespace && o.name == name && o.left == left && o.right == right
89 })
90 }
91
92 pub fn create_operator(&mut self, mut new: Operator) -> u32 {
94 let oid = self.new_oid();
95 new.oid = oid;
96 self.operators.insert(oid, new);
97 self.operator_depends(oid);
98 oid
99 }
100
101 pub fn replace_operator(&mut self, oid: u32, mut new: Operator) -> Result<()> {
107 if !self.operators.contains_key(&oid) {
108 return Err(no_object("operator", oid));
109 }
110 new.oid = oid;
111 self.operators.insert(oid, new);
112 let me = ObjRef::new(PG_OPERATOR, oid);
113 self.depends.retain(|d| d.object != me);
114 self.operator_depends(oid);
115 Ok(())
116 }
117
118 pub fn alter_operator(&mut self, oid: u32, change: impl FnOnce(&mut Operator)) -> Result<()> {
124 let operator = self.operators.get_mut(&oid).ok_or_else(|| no_object("operator", oid))?;
125 change(operator);
126 Ok(())
127 }
128
129 pub(crate) fn remove_operator(&mut self, oid: u32) {
131 let Some(old) = self.operators.remove(&oid) else { return };
132 if let Some(commutator) = self.operators.get_mut(&old.commutator) {
133 commutator.commutator = 0;
134 }
135 if let Some(negator) = self.operators.get_mut(&old.negator) {
136 negator.negator = 0;
137 }
138 }
139
140 fn operator_depends(&mut self, oid: u32) {
142 let Some(op) = self.operators.get(&oid) else { return };
143 let mut refs = vec![ObjRef::new(PG_NAMESPACE, op.namespace)];
144 refs.extend(
145 [op.left, op.right, op.result]
146 .into_iter()
147 .filter(|&ty| ty != 0)
148 .map(|ty| ObjRef::new(PG_TYPE, ty)),
149 );
150 refs.extend(
151 [op.code, op.restrict, op.join]
152 .into_iter()
153 .filter(|&f| f != 0)
154 .map(|f| ObjRef::new(PG_PROC, f)),
155 );
156 self.depend_all(ObjRef::new(PG_OPERATOR, oid), refs);
157 }
158}