rupg_analyze/expr.rs
1//! `Expr`, an expression of the query tree with its type, as the `Expr` nodes of `primnodes.h` after `transformExpr`.
2
3use rupg_pgcatalog::builtin;
4use rupg_types::Value;
5
6use crate::select::Query;
7use crate::sort::SortGroup;
8
9/// An expression with its type and its typmod. A typmod of -1 means that the expression has no typmod.
10#[derive(Clone, Debug, PartialEq)]
11pub struct Expr {
12 pub kind: ExprKind,
13 /// The OID of the type of the value.
14 pub ty: u32,
15 pub typmod: i32,
16 /// The byte offset in the query text of the place that the expression starts, for the position of an error, or `None`.
17 pub location: Option<usize>,
18}
19
20/// The kinds of expression.
21#[derive(Clone, Debug, PartialEq)]
22pub enum ExprKind {
23 /// `Const`: a value. A string literal that has no type yet has the type `unknown` and a `Text` value.
24 Const(Value),
25 /// `Param`: the parameter `$n`, from 1.
26 Param(usize),
27 /// `FuncExpr` and `OpExpr`: a call of the function with this `pg_proc` OID.
28 Func(Func),
29 /// `NamedArgExpr`: an argument of a call that the call gives by its name, as `name => value`. The planner puts the arguments in the order of the function.
30 NamedArg(Box<NamedArg>),
31 /// `RelabelType`: the value of the argument with another type that has the same binary form.
32 Relabel(Box<Expr>, CastForm),
33 /// `CoerceViaIO`: the output function of the type of the argument, then the input function of the type of the expression.
34 CoerceViaIo(Box<Expr>, CastForm),
35 /// `ArrayCoerceExpr`: a cast of each element of an array. `element` casts [`ExprKind::CaseTest`], which is the value of one element.
36 ArrayCoerce { arg: Box<Expr>, element: Box<Expr>, form: CastForm },
37 /// `CoerceToDomain`: the value of the argument as a value of the domain of the expression, after the domain checks its constraints. The argument has the base type of the domain.
38 CoerceToDomain(Box<Expr>, CastForm),
39 /// `CoerceToDomainValue`: `VALUE` in a check constraint of a domain, the value that the domain checks.
40 DomainValue,
41 /// `SubscriptingRef`: an element or a slice of an array.
42 Subscript(Box<Subscript>),
43 /// `BoolExpr`: `AND`, `OR` and `NOT`.
44 Bool(BoolOp, Vec<Expr>),
45 /// `NullTest`: `IS NULL` when the flag is true, `IS NOT NULL` when it is false.
46 NullTest(Box<Expr>, bool),
47 /// `BooleanTest`: `IS TRUE`, `IS NOT UNKNOWN` and the others.
48 BooleanTest(Box<Expr>, BoolTest),
49 /// `CaseExpr`. With an argument, each condition compares [`ExprKind::CaseTest`] to a value.
50 Case(Case),
51 /// `CaseTestExpr`: the value of the argument of the `CASE` that holds this expression.
52 CaseTest,
53 /// `CoalesceExpr`: the first argument that is not null.
54 Coalesce(Vec<Expr>),
55 /// `MinMaxExpr`: `GREATEST` or `LEAST`, with the function of the `<` operator of the type.
56 MinMax { greatest: bool, less: u32, args: Vec<Expr> },
57 /// `NullIfExpr`: null when the function of the `=` operator gives true, or else the first argument.
58 NullIf { equal: u32, args: Vec<Expr> },
59 /// `DistinctExpr`: `IS DISTINCT FROM`, or `IS NOT DISTINCT FROM` when `not` is true, with the function of the `=` operator.
60 Distinct { equal: u32, not: bool, args: Vec<Expr> },
61 /// `ScalarArrayOpExpr`: `x op ANY (array)` when `any` is true, or `x op ALL (array)`.
62 ScalarArrayOp { func: u32, any: bool, args: Vec<Expr> },
63 /// `RowExpr`: `ROW(...)`, a value of `record` with a field for each argument. The form is explicit for a cast of a row to a composite type, as `row_format`.
64 Row(Vec<Expr>, CastForm),
65 /// The whole row of a join, as the `Var` with the attribute number 0 of a join, which the planner of PostgreSQL makes a `RowExpr` with the names of the columns. A join with no relation of its own gives the columns of the join as the fields.
66 JoinRow(Box<JoinRow>),
67 /// `RowCompareExpr`: `(a, b) < (c, d)` and the other comparisons of two rows with an ordering operator.
68 RowCompare(Box<RowCompare>),
69 /// `ArrayExpr`: `ARRAY[...]`. The elements of a multidimensional array are arrays.
70 Array { element: u32, multidims: bool, elements: Vec<Expr> },
71 /// `SQLValueFunction`, such as `CURRENT_USER` and `CURRENT_TIMESTAMP(3)`.
72 SqlValue(SqlValue),
73 /// `Var`: a column of a relation of `FROM`, or with the attribute number 0 the whole row of the relation, as a value of its row type.
74 Var(Var),
75 /// `FieldSelect`: the field with this index, from 0, of a row value.
76 FieldSelect(Box<Expr>, usize),
77 /// `FieldStore`: the row value of the argument with new values in some of its fields. The result is the row value.
78 FieldStore(Box<FieldStore>),
79 /// `Aggref`: a call of an aggregate function, which reads all the rows of a group.
80 Agg(Box<Aggref>),
81 /// `WindowFunc`: a call of a window function, which reads the rows of its window.
82 Window(Box<WindowFunc>),
83 /// `GroupingFunc`: a call of `GROUPING`, of type `integer`.
84 Grouping(Box<GroupingFunc>),
85 /// `PlaceHolderVar`: an expression of a subquery that the planner merged below the side of an outer join that can give nulls. Only the planner makes it.
86 PlaceHolder(Box<PlaceHolder>),
87 /// `SubLink`: a subquery in an expression.
88 SubLink(Box<SubLink>),
89 /// `Param` of the kind `PARAM_SUBLINK`: the value of the column with this index, from 0, of a row of the subquery, in the test of `ANY` or `ALL`.
90 SubColumn(usize),
91 /// `JsonValueExpr`: an input of a SQL/JSON function with its `FORMAT` clause, as the value of the formatted expression.
92 JsonValue(Box<JsonValue>),
93 /// `JsonConstructorExpr`: `JSON_OBJECT`, `JSON_ARRAY`, `JSON`, `JSON_SCALAR` or `JSON_SERIALIZE`.
94 JsonCtor(Box<JsonCtor>),
95 /// `JsonIsPredicate`: `IS JSON`, of type `boolean`.
96 IsJson(Box<IsJson>),
97 /// `JsonExpr`: `JSON_EXISTS`, `JSON_QUERY` or `JSON_VALUE`.
98 JsonExpr(Box<JsonExpr>),
99 /// `TableFunc` of the kind `TFT_JSON_TABLE`: the call of `JSON_TABLE` in `FROM`, of type `record`.
100 JsonTable(Box<JsonTable>),
101 /// `XmlExpr`: `XMLELEMENT`, `XMLFOREST`, `XMLCONCAT`, `XMLPARSE`, `XMLPI`, `XMLROOT`, `XMLSERIALIZE` or `IS DOCUMENT`.
102 Xml(Box<XmlExpr>),
103 /// `CurrentOfExpr`: `WHERE CURRENT OF`, of type `boolean`.
104 CurrentOf(Box<CurrentOf>),
105}
106
107/// `CurrentOfExpr`: the condition of `WHERE CURRENT OF` on the target table of an `UPDATE` or a `DELETE`, which is true for the row that the cursor is on, as `execCurrentOf` finds it.
108#[derive(Clone, Debug, PartialEq)]
109pub struct CurrentOf {
110 /// The OID of the target table.
111 pub table: u32,
112 /// The name of the cursor: a constant for `cursor_name`, or the parameter of a variable of PL/pgSQL for `cursor_param`. Then `tableoid` and `ctid` of the target table.
113 pub args: Vec<Expr>,
114}
115
116/// The whole row of a join, or of the alias of `USING`.
117#[derive(Clone, Debug, PartialEq)]
118pub struct JoinRow {
119 /// The alias of the join, which the deparser shows as `alias.*`. `None` for the alias of `USING`, which is a `RowExpr` in PostgreSQL and shows as `ROW(...)`.
120 pub alias: Option<String>,
121 /// The name of each field, which is the name of the column of the join.
122 pub names: Vec<String>,
123 /// The value of each field.
124 pub fields: Vec<Expr>,
125}
126
127/// The parts of an assignment to fields of a row value, as `FieldStore`.
128#[derive(Clone, Debug, PartialEq)]
129pub struct FieldStore {
130 /// `arg`: the old row value. A null value is a row whose fields are all null.
131 pub arg: Expr,
132 /// `fieldnums` and `newvals`: the index from 0 of each field that gets a new value, and the new value. In the new value, `CaseTest` is the old value of the field.
133 pub fields: Vec<(usize, Expr)>,
134 /// The type of each field of the row type, for a row that the null value makes.
135 pub types: Vec<u32>,
136}
137
138/// The parts of a fetch from an array or of an assignment to a part of an array, as `SubscriptingRef`.
139#[derive(Clone, Debug, PartialEq)]
140pub struct Subscript {
141 /// `refexpr`: the array.
142 pub container: Expr,
143 /// `refupperindexpr`: the subscript of each dimension, or the upper bound of a slice. `None` is a bound that the query does not give.
144 pub upper: Vec<Option<Expr>>,
145 /// `reflowerindexpr`: the lower bound of each dimension of a slice, or `None` for one element.
146 pub lower: Option<Vec<Option<Expr>>>,
147 /// `refassgnexpr`: the new value of the element or of the slice in an assignment, as `a[1] := 5` of PL/pgSQL makes it. The result of an assignment is the array with the new value.
148 pub assign: Option<Expr>,
149}
150
151impl Subscript {
152 /// The subscripts that the query gives, the upper bounds first.
153 pub fn bounds(&self) -> impl Iterator<Item = &Expr> {
154 self.upper.iter().chain(self.lower.iter().flatten()).flatten()
155 }
156}
157
158/// A subquery in an expression, as `SubLink`.
159#[derive(Clone, Debug, PartialEq)]
160pub struct SubLink {
161 pub kind: SubLinkKind,
162 /// `testexpr`: for `ANY`, `ALL` and a row comparison, the test of each row of the subquery. It compares the left side with [`ExprKind::SubColumn`].
163 pub test: Option<Expr>,
164 pub query: Query,
165 /// For a correlated `EXISTS`, the same test as `ANY` on a subquery that reads no column of the query, as `convert_EXISTS_to_ANY` makes it. The planner fills it and runs the subquery that costs less, as an `AlternativeSubPlan`.
166 pub alternative: Option<Box<SubLink>>,
167}
168
169/// The comparison of two rows with an ordering operator, as `RowCompareExpr`.
170#[derive(Clone, Debug, PartialEq)]
171pub struct RowCompare {
172 pub kind: RowCompareKind,
173 /// The operator call for each pair of fields, with the field of the left row and the field of the right row as its arguments.
174 pub ops: Vec<Expr>,
175 /// The btree comparison function of each pair of fields, from the operator family of the operator.
176 pub compares: Vec<u32>,
177}
178
179/// The comparison of a [`RowCompare`], as `rctype`.
180#[derive(Clone, Copy, Debug, PartialEq, Eq)]
181pub enum RowCompareKind {
182 Less,
183 LessEqual,
184 GreaterEqual,
185 Greater,
186}
187
188impl RowCompareKind {
189 /// The kind of a btree strategy number, or `None` for `=` and the numbers that are not a strategy.
190 pub fn of_strategy(strategy: u32) -> Option<RowCompareKind> {
191 match strategy {
192 1 => Some(RowCompareKind::Less),
193 2 => Some(RowCompareKind::LessEqual),
194 4 => Some(RowCompareKind::GreaterEqual),
195 5 => Some(RowCompareKind::Greater),
196 _ => None,
197 }
198 }
199
200 /// The result of the comparison for the result of a btree comparison function: below 0, 0 or above 0.
201 pub fn test(self, order: i32) -> bool {
202 match self {
203 RowCompareKind::Less => order < 0,
204 RowCompareKind::LessEqual => order <= 0,
205 RowCompareKind::GreaterEqual => order >= 0,
206 RowCompareKind::Greater => order > 0,
207 }
208 }
209
210 /// The name of the kind in the text of a stored expression.
211 pub fn name(self) -> &'static str {
212 match self {
213 RowCompareKind::Less => "lt",
214 RowCompareKind::LessEqual => "le",
215 RowCompareKind::GreaterEqual => "ge",
216 RowCompareKind::Greater => "gt",
217 }
218 }
219
220 /// The kind with this name, as [`RowCompareKind::name`] gives it.
221 pub fn of_name(name: &str) -> Option<RowCompareKind> {
222 [
223 RowCompareKind::Less,
224 RowCompareKind::LessEqual,
225 RowCompareKind::GreaterEqual,
226 RowCompareKind::Greater,
227 ]
228 .into_iter()
229 .find(|kind| kind.name() == name)
230 }
231}
232
233/// The kinds of `SubLink` that the analyzer takes.
234#[derive(Clone, Copy, Debug, PartialEq, Eq)]
235pub enum SubLinkKind {
236 /// `EXISTS (SELECT ...)`.
237 Exists,
238 /// `x op ALL (SELECT ...)`.
239 All,
240 /// `x op ANY (SELECT ...)` and `x IN (SELECT ...)`.
241 Any,
242 /// `(SELECT ...)`, which gives the value of the one column of the one row.
243 Expr,
244 /// `ARRAY(SELECT ...)`, which gives the values of the one column as an array.
245 Array,
246 /// `(a, b) op (SELECT ...)`, which gives the result of the test on the one row.
247 RowCompare,
248 /// `SET (a, b) = (SELECT ...)` of `UPDATE`, as `MULTIEXPR_SUBLINK` with its `PARAM_MULTIEXPR`: the value of the column `column`, from 0, of the one row. Each column of the item has a copy of the subquery with the same `id`, and the subquery runs once for each row.
249 Multi { id: u32, column: usize },
250}
251
252/// A column of a relation of `FROM`.
253#[derive(Clone, Copy, Debug, PartialEq, Eq)]
254pub struct Var {
255 /// The index of the relation in [`crate::Query::relations`].
256 pub relation: usize,
257 /// The attribute number: from 1 for a column of the relation, or a negative number for a system column.
258 pub attnum: i16,
259 /// `varlevelsup`: 0 for a relation of the query that has the expression, 1 for a relation of the query outside it, and so on.
260 pub levels_up: usize,
261}
262
263/// A call of a function.
264#[derive(Clone, Debug, PartialEq)]
265pub struct Func {
266 /// The OID of the function in `pg_proc`.
267 pub oid: u32,
268 pub args: Vec<Expr>,
269 /// The way the call was written.
270 pub form: FuncForm,
271 /// True when the last argument is the array of a variadic function, as `funcvariadic` of `FuncExpr`. A function with `VARIADIC "any"` then takes the elements of the array as its arguments.
272 pub variadic: bool,
273 /// `funcretset`: true when the function gives a set.
274 pub retset: bool,
275}
276
277/// An argument by its name, as `NamedArgExpr`.
278#[derive(Clone, Debug, PartialEq)]
279pub struct NamedArg {
280 pub arg: Expr,
281 pub name: String,
282 /// `argnumber`: the position of the argument in the input arguments of the function, from 0.
283 pub number: usize,
284}
285
286/// A call of an aggregate function, as `Aggref`.
287#[derive(Clone, Debug, PartialEq)]
288pub struct Aggref {
289 /// `aggfnoid`: the OID of the aggregate function in `pg_proc`.
290 pub oid: u32,
291 /// `aggkind`: `n` for a normal aggregate, `o` for an ordered-set aggregate or `h` for a hypothetical-set aggregate.
292 pub kind: u8,
293 /// `aggdirectargs`: the direct arguments of an ordered-set aggregate, which the aggregate reads once for each group.
294 pub direct: Vec<Expr>,
295 /// The arguments, then the expressions that only the `ORDER BY` of the call reads.
296 pub args: Vec<Expr>,
297 /// The number of arguments at the start of `args`.
298 pub nargs: usize,
299 /// `aggorder`: the items of the `ORDER BY` of the call. Each item names an expression of `args`.
300 pub order: Vec<SortGroup>,
301 /// `aggdistinct`: the items of `DISTINCT`, which are all the arguments. The items of `ORDER BY` come first.
302 pub distinct: Vec<SortGroup>,
303 /// `aggstar`: true for `count(*)`.
304 pub star: bool,
305 /// `aggvariadic`: true when the last argument is the array of a variadic aggregate.
306 pub variadic: bool,
307 /// `aggfilter`: the condition of `FILTER (WHERE ...)`.
308 pub filter: Option<Box<Expr>>,
309 /// `agglevelsup`: 0 for an aggregate of the query that has the call, 1 for an aggregate of the query outside it, and so on. The arguments of an aggregate of an outer query read only the columns of that query and of the queries outside it.
310 pub levels_up: usize,
311}
312
313/// A call of `GROUPING`, as `GroupingFunc`. The result has a bit for each argument, with the bit of the last argument as the lowest bit. A bit is 1 when the grouping set of the group does not have the argument.
314#[derive(Clone, Debug, PartialEq)]
315pub struct GroupingFunc {
316 /// The arguments, which are items of `GROUP BY`.
317 pub args: Vec<Expr>,
318 /// `refs`: the target of the item of `GROUP BY` of each argument. `parseCheckAggregates` sets them.
319 pub refs: Vec<usize>,
320 /// `agglevelsup`: 0 for a call of the query that has the call, 1 for a call of the query outside it, and so on.
321 pub levels_up: usize,
322}
323
324/// A `PlaceHolderVar`: the value of `expr` at the scan or the join of the relations of the subquery, which is null in a row where an outer join above them gives nulls for them, as a column of those relations is.
325#[derive(Clone, Debug, PartialEq)]
326pub struct PlaceHolder {
327 pub expr: Expr,
328 /// `phrels`: the relations of the subquery in the query.
329 pub relations: Vec<usize>,
330 /// `phlevelsup`: 0 for the query of the expression, 1 for the query outside it, and so on.
331 pub levels_up: usize,
332}
333
334/// `JsonFormatType`: the format of a `FORMAT` clause.
335#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
336pub enum JsonFormatKind {
337 /// No `FORMAT` clause.
338 #[default]
339 Default,
340 /// `FORMAT JSON`.
341 Json,
342 /// The format of a `jsonb` value, which no clause can give.
343 Jsonb,
344}
345
346/// `JsonEncoding`: the `ENCODING` of a `FORMAT JSON` clause.
347#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
348pub enum JsonEncoding {
349 /// No `ENCODING` clause.
350 #[default]
351 Default,
352 Utf8,
353 Utf16,
354 Utf32,
355}
356
357impl JsonEncoding {
358 /// The name of the encoding in the SQL text.
359 pub fn name(self) -> &'static str {
360 match self {
361 JsonEncoding::Default | JsonEncoding::Utf8 => "UTF8",
362 JsonEncoding::Utf16 => "UTF16",
363 JsonEncoding::Utf32 => "UTF32",
364 }
365 }
366}
367
368/// `JsonFormat`: a `FORMAT` clause.
369#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
370pub struct JsonFormat {
371 pub kind: JsonFormatKind,
372 pub encoding: JsonEncoding,
373}
374
375/// `JsonValueExpr`: an input of a SQL/JSON function. The executor reads `formatted`, and the deparser shows `raw` and the format.
376#[derive(Clone, Debug, PartialEq)]
377pub struct JsonValue {
378 /// The input as the query wrote it.
379 pub raw: Expr,
380 /// The input as a value of `json` or `jsonb`, or as `text` for an input of `bytea`.
381 pub formatted: Expr,
382 pub format: JsonFormat,
383}
384
385/// `JsonConstructorType`: the function of a [`JsonCtor`].
386#[derive(Clone, Copy, Debug, PartialEq, Eq)]
387pub enum JsonCtorKind {
388 /// `JSON_OBJECT`. The arguments are the keys and the values, one after the other.
389 Object,
390 /// `JSON_ARRAY` with a list of values.
391 Array,
392 /// `JSON`, which checks that a text is JSON.
393 Parse,
394 /// `JSON_SCALAR`, which makes a JSON value from a SQL value.
395 Scalar,
396 /// `JSON_SERIALIZE`, which makes a string from a JSON value.
397 Serialize,
398 /// `JSON_OBJECTAGG`. The call of the aggregate is [`JsonCtor::func`].
399 ObjectAgg,
400 /// `JSON_ARRAYAGG`. The call of the aggregate is [`JsonCtor::func`].
401 ArrayAgg,
402 /// `JSON_ARRAY` with a subquery. [`JsonCtor::func`] is `COALESCE((SELECT JSON_ARRAYAGG(q.a) FROM (subquery) q(a)), '[]')`.
403 ArrayQuery,
404}
405
406/// `JsonReturning`: the type of the result of a SQL/JSON function and its format.
407#[derive(Clone, Copy, Debug, PartialEq, Eq)]
408pub struct JsonReturning {
409 pub format: JsonFormat,
410 pub ty: u32,
411 pub typmod: i32,
412}
413
414/// `JsonConstructorExpr`: a SQL/JSON constructor.
415#[derive(Clone, Debug, PartialEq)]
416pub struct JsonCtor {
417 pub kind: JsonCtorKind,
418 pub args: Vec<Expr>,
419 /// The expression that gives the value of `JSON_OBJECTAGG`, `JSON_ARRAYAGG` and `JSON_ARRAY` with a subquery.
420 pub func: Option<Expr>,
421 /// The `FORMAT` clause of the subquery of `JSON_ARRAY`.
422 pub format: JsonFormat,
423 /// The `RETURNING` clause, or the type that the analyzer gives when the call has no clause.
424 pub returning: JsonReturning,
425 /// `WITH UNIQUE KEYS`.
426 pub unique: bool,
427 /// `ABSENT ON NULL`.
428 pub absent_on_null: bool,
429 /// The cast of the `json` or `jsonb` value to the type of `RETURNING`. [`ExprKind::CaseTest`] is the value.
430 pub coercion: Option<Expr>,
431}
432
433/// `JsonValueType`: the kind of JSON value that `IS JSON` accepts.
434#[derive(Clone, Copy, Debug, PartialEq, Eq)]
435pub enum JsonItemType {
436 /// `IS JSON` or `IS JSON VALUE`.
437 Any,
438 Object,
439 Array,
440 Scalar,
441}
442
443/// `XmlExprOp`: the function of an [`XmlExpr`].
444#[derive(Clone, Copy, Debug, PartialEq, Eq)]
445pub enum XmlOp {
446 Concat,
447 Element,
448 Forest,
449 Parse,
450 Pi,
451 Root,
452 Serialize,
453 Document,
454}
455
456/// `XmlExpr`: a SQL/XML function with its own syntax. The type is `boolean` for `IS DOCUMENT`, `text` for `XMLSERIALIZE` and `xml` for the others.
457#[derive(Clone, Debug, PartialEq)]
458pub struct XmlExpr {
459 pub op: XmlOp,
460 /// The XML name of the element of `XMLELEMENT` or the target of `XMLPI`.
461 pub name: Option<String>,
462 /// The attributes of `XMLELEMENT` or the elements of `XMLFOREST`, with their XML names.
463 pub named: Vec<(String, Expr)>,
464 /// The other arguments. `XMLPARSE` has the text and the flag of `PRESERVE WHITESPACE`. `XMLROOT` has the value, the version or a null `text` and the `integer` of `STANDALONE`.
465 pub args: Vec<Expr>,
466 /// `DOCUMENT`, not `CONTENT`, for `XMLPARSE` and `XMLSERIALIZE`.
467 pub document: bool,
468 /// `INDENT` of `XMLSERIALIZE`.
469 pub indent: bool,
470 /// The type and the type modifier of `AS` of `XMLSERIALIZE`.
471 pub target: (u32, i32),
472}
473
474impl XmlExpr {
475 /// The expressions of the named arguments, then the other arguments.
476 pub fn children(&self) -> Vec<&Expr> {
477 self.named.iter().map(|(_, e)| e).chain(&self.args).collect()
478 }
479
480 /// The expressions of the named arguments, then the other arguments.
481 pub fn children_mut(&mut self) -> Vec<&mut Expr> {
482 self.named.iter_mut().map(|(_, e)| e).chain(&mut self.args).collect()
483 }
484}
485
486/// `JsonIsPredicate`: `IS JSON`.
487#[derive(Clone, Debug, PartialEq)]
488pub struct IsJson {
489 /// The value, of type `text`, `json` or `jsonb`.
490 pub expr: Expr,
491 pub item: JsonItemType,
492 /// `WITH UNIQUE KEYS`.
493 pub unique: bool,
494 /// `exprBaseType`: the type of the value, `text`, `json` or `jsonb`.
495 pub base_type: u32,
496}
497
498/// `JsonExprOp`: the function of a [`JsonExpr`].
499#[derive(Clone, Copy, Debug, PartialEq, Eq)]
500pub enum JsonExprOp {
501 /// `JSON_EXISTS`, which gives true when the path finds an item.
502 Exists,
503 /// `JSON_QUERY`, which gives the item that the path finds as JSON.
504 Query,
505 /// `JSON_VALUE`, which gives the scalar item that the path finds as a SQL value.
506 Value,
507}
508
509/// `JsonWrapper`: the `WRAPPER` clause of `JSON_QUERY`.
510#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
511pub enum JsonWrapper {
512 /// No clause, which is the same as `WITHOUT WRAPPER`.
513 #[default]
514 Unspec,
515 /// `WITHOUT WRAPPER`.
516 None,
517 /// `WITH CONDITIONAL WRAPPER`: an array only for more than one item.
518 Conditional,
519 /// `WITH UNCONDITIONAL WRAPPER`: always an array.
520 Unconditional,
521}
522
523/// `JsonBehaviorType`: what a SQL/JSON function gives on an error or when the path finds no item.
524#[derive(Clone, Copy, Debug, PartialEq, Eq)]
525pub enum JsonBehaviorKind {
526 Null,
527 Error,
528 Empty,
529 True,
530 False,
531 Unknown,
532 EmptyArray,
533 EmptyObject,
534 Default,
535}
536
537impl JsonBehaviorKind {
538 /// The name of the behavior as `ON ERROR` and `ON EMPTY` show it.
539 pub fn name(self) -> &'static str {
540 match self {
541 JsonBehaviorKind::Null => "NULL",
542 JsonBehaviorKind::Error => "ERROR",
543 JsonBehaviorKind::Empty => "EMPTY",
544 JsonBehaviorKind::True => "TRUE",
545 JsonBehaviorKind::False => "FALSE",
546 JsonBehaviorKind::Unknown => "UNKNOWN",
547 JsonBehaviorKind::EmptyArray => "EMPTY ARRAY",
548 JsonBehaviorKind::EmptyObject => "EMPTY OBJECT",
549 JsonBehaviorKind::Default => "DEFAULT",
550 }
551 }
552}
553
554/// `JsonBehavior`: an `ON ERROR` or an `ON EMPTY` clause.
555#[derive(Clone, Debug, PartialEq)]
556pub struct JsonBehavior {
557 pub kind: JsonBehaviorKind,
558 /// The value of the behavior, or `None` for `ERROR`.
559 pub expr: Option<Expr>,
560 /// True when the executor casts the value to the type of `RETURNING` at run time, as `json_populate_type` does.
561 pub coerce: bool,
562}
563
564/// `JsonExpr`: `JSON_EXISTS`, `JSON_QUERY` or `JSON_VALUE`.
565#[derive(Clone, Debug, PartialEq)]
566pub struct JsonExpr {
567 pub op: JsonExprOp,
568 /// The context item as a `jsonb` value.
569 pub formatted: Expr,
570 /// The path, of type `jsonpath`.
571 pub path: Expr,
572 /// The names and the values of the `PASSING` clause.
573 pub passing: Vec<(String, Expr)>,
574 pub returning: JsonReturning,
575 /// `ON EMPTY`, which `JSON_EXISTS` does not have.
576 pub on_empty: Option<JsonBehavior>,
577 pub on_error: JsonBehavior,
578 pub wrapper: JsonWrapper,
579 /// `OMIT QUOTES`, which is always true for `JSON_VALUE`.
580 pub omit_quotes: bool,
581 /// True when the executor casts the result to the type of `RETURNING` as `json_populate_type` does.
582 pub json_coercion: bool,
583 /// True when the executor casts the text of the result to the type of `RETURNING` with its input function.
584 pub io_coercion: bool,
585 /// `column_name`: the name of the column of `JSON_TABLE` that the node computes, which the errors show.
586 pub column: Option<String>,
587}
588
589impl JsonExpr {
590 /// The context item, the path, the values of `PASSING` and the values of the behaviors.
591 pub fn children(&self) -> Vec<&Expr> {
592 let mut all = vec![&self.formatted, &self.path];
593 all.extend(self.passing.iter().map(|(_, e)| e));
594 let behaviors = self.on_empty.iter().chain([&self.on_error]);
595 all.extend(behaviors.filter_map(|b| b.expr.as_ref()));
596 all
597 }
598
599 /// [`JsonExpr::children`], to change.
600 pub fn children_mut(&mut self) -> Vec<&mut Expr> {
601 let JsonExpr { formatted, path, passing, on_empty, on_error, .. } = self;
602 let mut all = vec![formatted, path];
603 all.extend(passing.iter_mut().map(|(_, e)| e));
604 all.extend(on_empty.iter_mut().chain([on_error]).filter_map(|b| b.expr.as_mut()));
605 all
606 }
607}
608
609/// `TableFunc` of the kind `TFT_JSON_TABLE`: the call of `JSON_TABLE`.
610#[derive(Clone, Debug, PartialEq)]
611pub struct JsonTable {
612 /// `docexpr`: the context item as a `jsonb` value.
613 pub context: Expr,
614 /// The names and the values of the `PASSING` clause.
615 pub passing: Vec<(String, Expr)>,
616 /// The top `ON ERROR` clause: `ERROR`, `EMPTY` or `EMPTY ARRAY`.
617 pub on_error: JsonBehaviorKind,
618 /// The plan that gives the rows.
619 pub plan: JsonTablePlan,
620 /// The columns, with no `NESTED` parts, in the order of the result.
621 pub columns: Vec<JsonTableColumn>,
622}
623
624impl JsonTable {
625 /// The context item, the values of `PASSING` and the expressions of the columns.
626 pub fn children(&self) -> Vec<&Expr> {
627 let mut all = vec![&self.context];
628 all.extend(self.passing.iter().map(|(_, e)| e));
629 all.extend(self.columns.iter().filter_map(|c| c.expr.as_ref()));
630 all
631 }
632
633 /// [`JsonTable::children`], to change.
634 pub fn children_mut(&mut self) -> Vec<&mut Expr> {
635 let JsonTable { context, passing, columns, .. } = self;
636 let mut all = vec![context];
637 all.extend(passing.iter_mut().map(|(_, e)| e));
638 all.extend(columns.iter_mut().filter_map(|c| c.expr.as_mut()));
639 all
640 }
641}
642
643/// A column of `JSON_TABLE`.
644#[derive(Clone, Debug, PartialEq)]
645pub struct JsonTableColumn {
646 pub name: String,
647 pub ty: u32,
648 pub typmod: i32,
649 /// The `JsonExpr` that gives the value from the row of the plan, which reads the row as a `CaseTest`, or `None` for `FOR ORDINALITY`.
650 pub expr: Option<Expr>,
651}
652
653/// `JsonTablePlan`: the plan that gives the rows of `JSON_TABLE`.
654#[derive(Clone, Debug, PartialEq)]
655pub enum JsonTablePlan {
656 /// `JsonTablePathScan`.
657 Scan(Box<JsonTableScan>),
658 /// `JsonTableSiblingJoin`: the rows of the left plan, and then the rows of the right plan.
659 Sibling(Box<JsonTablePlan>, Box<JsonTablePlan>),
660}
661
662/// `JsonTablePathScan`: a row pattern path and the columns that read its rows.
663#[derive(Clone, Debug, PartialEq)]
664pub struct JsonTableScan {
665 /// The path, as a `jsonpath` value.
666 pub path: Value,
667 /// The name of the path, which the analyzer gives when the query does not.
668 pub name: String,
669 /// True when an error of the path is an error of the query, for `ERROR ON ERROR` at the top.
670 pub error_on_error: bool,
671 /// The indexes of the columns of the scan in [`JsonTable::columns`].
672 pub columns: std::ops::Range<usize>,
673 /// The plan of the `NESTED` parts.
674 pub child: Option<JsonTablePlan>,
675}
676
677/// A call of a window function, as `WindowFunc`.
678#[derive(Clone, Debug, PartialEq)]
679pub struct WindowFunc {
680 /// `winfnoid`: the OID of the function in `pg_proc`.
681 pub oid: u32,
682 pub args: Vec<Expr>,
683 /// `winref`: the number of the window in [`crate::Query::windows`], from 1.
684 pub winref: usize,
685 /// `winstar`: true for `f(*)`.
686 pub star: bool,
687 /// `winagg`: true for an aggregate function.
688 pub agg: bool,
689 /// `aggfilter`: the condition of `FILTER (WHERE ...)` of an aggregate.
690 pub filter: Option<Box<Expr>>,
691 /// `ignore_nulls`: the clause `RESPECT NULLS` or `IGNORE NULLS` of the call.
692 pub nulls: NullTreatment,
693}
694
695/// The null treatment of a call of a window function, as `ignore_nulls`.
696#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
697pub enum NullTreatment {
698 /// No clause.
699 #[default]
700 None,
701 /// `IGNORE NULLS`: `lag`, `lead`, `first_value`, `last_value` and `nth_value` skip the rows where the argument is null.
702 Ignore,
703 /// `RESPECT NULLS`, which is the same as no clause for the functions that accept it.
704 Respect,
705}
706
707/// The way a call was written, which a deparse function shows.
708#[derive(Clone, Copy, Debug, PartialEq, Eq)]
709pub enum FuncForm {
710 /// `f(x)`.
711 Call,
712 /// An operator with this `pg_operator` OID.
713 Operator(u32),
714 /// `x::type`, `CAST(x AS type)` or `type(x)`.
715 ExplicitCast,
716 /// A cast that the analyzer added.
717 ImplicitCast,
718 /// A call in the special syntax of the SQL standard, such as `SUBSTRING(x FROM 2)` or `x AT TIME ZONE 'UTC'`, as `COERCE_SQL_SYNTAX`.
719 SqlSyntax,
720}
721
722/// `CoercionForm` of a cast node: the way a cast was written, which a deparse function shows.
723#[derive(Clone, Copy, Debug, PartialEq, Eq)]
724pub enum CastForm {
725 /// `x::type` or `CAST(x AS type)`.
726 Explicit,
727 /// A cast that the analyzer added.
728 Implicit,
729}
730
731/// The operators of `BoolExpr`.
732#[derive(Clone, Copy, Debug, PartialEq, Eq)]
733pub enum BoolOp {
734 And,
735 Or,
736 Not,
737}
738
739/// The tests of `BooleanTest`.
740#[derive(Clone, Copy, Debug, PartialEq, Eq)]
741pub enum BoolTest {
742 IsTrue,
743 IsNotTrue,
744 IsFalse,
745 IsNotFalse,
746 IsUnknown,
747 IsNotUnknown,
748}
749
750/// A `CASE` expression.
751#[derive(Clone, Debug, PartialEq)]
752pub struct Case {
753 /// The value that the conditions compare, for `CASE x WHEN ...`.
754 pub arg: Option<Box<Expr>>,
755 /// Each condition with its result.
756 pub whens: Vec<(Expr, Expr)>,
757 /// The result of `ELSE`, which is a null constant when the query has no `ELSE`.
758 pub default: Box<Expr>,
759}
760
761/// The functions of the SQL standard that take no parentheses.
762#[derive(Clone, Copy, Debug, PartialEq, Eq)]
763pub enum SqlValue {
764 CurrentDate,
765 /// `CURRENT_TIME`, with the precision if the query gives one.
766 CurrentTime(Option<i32>),
767 CurrentTimestamp(Option<i32>),
768 LocalTime(Option<i32>),
769 LocalTimestamp(Option<i32>),
770 CurrentRole,
771 CurrentUser,
772 User,
773 SessionUser,
774 CurrentCatalog,
775 CurrentSchema,
776}
777
778impl Expr {
779 /// An expression with no typmod and no location.
780 pub fn new(kind: ExprKind, ty: u32) -> Expr {
781 Expr { kind, ty, typmod: -1, location: None }
782 }
783
784 /// A constant.
785 pub fn constant(value: Value, ty: u32, typmod: i32, location: Option<usize>) -> Expr {
786 Expr { kind: ExprKind::Const(value), ty, typmod, location }
787 }
788
789 /// Sets the location.
790 #[must_use]
791 pub fn at(mut self, location: Option<usize>) -> Expr {
792 self.location = location;
793 self
794 }
795
796 /// The value of a constant, or `None` for any other expression.
797 pub fn as_const(&self) -> Option<&Value> {
798 match &self.kind {
799 ExprKind::Const(value) => Some(value),
800 _ => None,
801 }
802 }
803
804 /// The cost of the calls of functions and operators in the node of this expression, without its children, in units of `cpu_operator_cost`, as `cost_qual_eval_walker` adds it. A call, an operator, `NULLIF` and `IS DISTINCT FROM` cost the `procost` of their function, as `add_function_cost` adds it.
805 pub fn own_cost(&self) -> f64 {
806 match &self.kind {
807 ExprKind::Func(f) => func_cost(f.oid),
808 ExprKind::NullIf { equal, .. } | ExprKind::Distinct { equal, .. } => func_cost(*equal),
809 ExprKind::ScalarArrayOp { .. } | ExprKind::MinMax { .. } => 1.0,
810 // The input function of the new type and the output function of the old type.
811 ExprKind::CoerceViaIo(..) => 2.0,
812 _ => 0.0,
813 }
814 }
815
816 /// `contain_leaked_vars`: true when the expression can give information about a column of the query other than through its result, as a call of a function that is not leakproof with a column in its arguments does. An expression of a kind that the check does not know is leaky.
817 pub fn leaky(&self) -> bool {
818 let func = match &self.kind {
819 ExprKind::CurrentOf(_) => return false,
820 ExprKind::Var(_)
821 | ExprKind::Const(_)
822 | ExprKind::Param(_)
823 | ExprKind::Array { .. }
824 | ExprKind::FieldSelect(..)
825 | ExprKind::FieldStore(_)
826 | ExprKind::NamedArg(_)
827 | ExprKind::Bool(..)
828 | ExprKind::Relabel(..)
829 | ExprKind::Case(_)
830 | ExprKind::CaseTest
831 | ExprKind::Row(..)
832 | ExprKind::SqlValue(_)
833 | ExprKind::NullTest(..)
834 | ExprKind::BooleanTest(..) => None,
835 ExprKind::Func(f) => Some(f.oid),
836 ExprKind::NullIf { equal, .. } | ExprKind::Distinct { equal, .. } => Some(*equal),
837 ExprKind::ScalarArrayOp { func, .. } => Some(*func),
838 _ => return true,
839 };
840 if let Some(func) = func
841 && !builtin::proc_by_oid(func).is_some_and(|p| p.leakproof)
842 && self
843 .find(0, &mut |e, depth| {
844 matches!(e.kind, ExprKind::Var(v) if v.levels_up == depth).then_some(())
845 })
846 .is_some()
847 {
848 return true;
849 }
850 self.children().into_iter().any(Expr::leaky)
851 }
852
853 /// The expressions that this expression has as its arguments.
854 pub fn children(&self) -> Vec<&Expr> {
855 match &self.kind {
856 ExprKind::Const(_)
857 | ExprKind::Param(_)
858 | ExprKind::CaseTest
859 | ExprKind::DomainValue
860 | ExprKind::SqlValue(_)
861 | ExprKind::Var(_)
862 | ExprKind::SubColumn(_) => Vec::new(),
863 ExprKind::SubLink(sub) => sub.test.iter().collect(),
864 ExprKind::RowCompare(rc) => rc.ops.iter().collect(),
865 ExprKind::Func(f) => f.args.iter().collect(),
866 ExprKind::NamedArg(na) => vec![&na.arg],
867 ExprKind::Agg(agg) => {
868 agg.direct.iter().chain(&agg.args).chain(agg.filter.as_deref()).collect()
869 }
870 ExprKind::Window(w) => w.args.iter().chain(w.filter.as_deref()).collect(),
871 ExprKind::Grouping(g) => g.args.iter().collect(),
872 ExprKind::PlaceHolder(p) => vec![&p.expr],
873 ExprKind::Relabel(arg, _)
874 | ExprKind::CoerceViaIo(arg, _)
875 | ExprKind::CoerceToDomain(arg, _)
876 | ExprKind::NullTest(arg, _)
877 | ExprKind::BooleanTest(arg, _)
878 | ExprKind::FieldSelect(arg, _) => vec![&**arg],
879 ExprKind::ArrayCoerce { arg, element, .. } => vec![&**arg, &**element],
880 ExprKind::Subscript(sub) => {
881 sub.bounds().chain([&sub.container]).chain(&sub.assign).collect()
882 }
883 ExprKind::FieldStore(store) => {
884 [&store.arg].into_iter().chain(store.fields.iter().map(|(_, v)| v)).collect()
885 }
886 ExprKind::Bool(_, args)
887 | ExprKind::Coalesce(args)
888 | ExprKind::Row(args, _)
889 | ExprKind::MinMax { args, .. }
890 | ExprKind::NullIf { args, .. }
891 | ExprKind::Distinct { args, .. }
892 | ExprKind::ScalarArrayOp { args, .. }
893 | ExprKind::Array { elements: args, .. } => args.iter().collect(),
894 ExprKind::CurrentOf(c) => c.args.iter().collect(),
895 ExprKind::JoinRow(row) => row.fields.iter().collect(),
896 ExprKind::JsonValue(v) => vec![&v.raw, &v.formatted],
897 ExprKind::JsonCtor(c) => c.args.iter().chain(&c.func).chain(&c.coercion).collect(),
898 ExprKind::IsJson(p) => vec![&p.expr],
899 ExprKind::JsonExpr(j) => j.children(),
900 ExprKind::Xml(x) => x.children(),
901 ExprKind::JsonTable(j) => j.children(),
902 ExprKind::Case(case) => {
903 let mut all: Vec<&Expr> = case.arg.as_deref().into_iter().collect();
904 for (when, then) in &case.whens {
905 all.push(when);
906 all.push(then);
907 }
908 all.push(&case.default);
909 all
910 }
911 }
912 }
913
914 pub(crate) fn children_mut(&mut self) -> Vec<&mut Expr> {
915 match &mut self.kind {
916 ExprKind::Const(_)
917 | ExprKind::Param(_)
918 | ExprKind::CaseTest
919 | ExprKind::DomainValue
920 | ExprKind::SqlValue(_)
921 | ExprKind::Var(_)
922 | ExprKind::SubColumn(_) => Vec::new(),
923 ExprKind::SubLink(sub) => sub.test.iter_mut().collect(),
924 ExprKind::RowCompare(rc) => rc.ops.iter_mut().collect(),
925 ExprKind::Func(f) => f.args.iter_mut().collect(),
926 ExprKind::NamedArg(na) => vec![&mut na.arg],
927 ExprKind::Agg(agg) => {
928 let Aggref { direct, args, filter, .. } = &mut **agg;
929 direct.iter_mut().chain(args.iter_mut()).chain(filter.as_deref_mut()).collect()
930 }
931 ExprKind::Window(w) => {
932 let WindowFunc { args, filter, .. } = &mut **w;
933 args.iter_mut().chain(filter.as_deref_mut()).collect()
934 }
935 ExprKind::Grouping(g) => g.args.iter_mut().collect(),
936 ExprKind::PlaceHolder(p) => vec![&mut p.expr],
937 ExprKind::Relabel(arg, _)
938 | ExprKind::CoerceViaIo(arg, _)
939 | ExprKind::CoerceToDomain(arg, _)
940 | ExprKind::NullTest(arg, _)
941 | ExprKind::BooleanTest(arg, _)
942 | ExprKind::FieldSelect(arg, _) => vec![&mut **arg],
943 ExprKind::ArrayCoerce { arg, element, .. } => vec![&mut **arg, &mut **element],
944 ExprKind::Subscript(sub) => {
945 let Subscript { container, upper, lower, assign } = &mut **sub;
946 let bounds = upper.iter_mut().chain(lower.iter_mut().flatten()).flatten();
947 bounds.chain([container]).chain(assign).collect()
948 }
949 ExprKind::FieldStore(store) => {
950 let FieldStore { arg, fields, .. } = &mut **store;
951 [arg].into_iter().chain(fields.iter_mut().map(|(_, v)| v)).collect()
952 }
953 ExprKind::Bool(_, args)
954 | ExprKind::Coalesce(args)
955 | ExprKind::Row(args, _)
956 | ExprKind::MinMax { args, .. }
957 | ExprKind::NullIf { args, .. }
958 | ExprKind::Distinct { args, .. }
959 | ExprKind::ScalarArrayOp { args, .. }
960 | ExprKind::Array { elements: args, .. } => args.iter_mut().collect(),
961 ExprKind::CurrentOf(c) => c.args.iter_mut().collect(),
962 ExprKind::JoinRow(row) => row.fields.iter_mut().collect(),
963 ExprKind::JsonValue(v) => vec![&mut v.raw, &mut v.formatted],
964 ExprKind::JsonCtor(c) => {
965 let JsonCtor { args, func, coercion, .. } = &mut **c;
966 args.iter_mut().chain(func).chain(coercion).collect()
967 }
968 ExprKind::IsJson(p) => vec![&mut p.expr],
969 ExprKind::JsonExpr(j) => j.children_mut(),
970 ExprKind::Xml(x) => x.children_mut(),
971 ExprKind::JsonTable(j) => j.children_mut(),
972 ExprKind::Case(case) => {
973 let mut all: Vec<&mut Expr> = case.arg.as_deref_mut().into_iter().collect();
974 for (when, then) in &mut case.whens {
975 all.push(when);
976 all.push(then);
977 }
978 all.push(&mut case.default);
979 all
980 }
981 }
982 }
983
984 /// `equal` of PostgreSQL: true when the two expressions are the same apart from their locations.
985 pub fn same(&self, other: &Expr) -> bool {
986 fn strip(expr: &mut Expr) {
987 expr.location = None;
988 for child in expr.children_mut() {
989 strip(child);
990 }
991 if let ExprKind::SubLink(sub) = &mut expr.kind {
992 sub.query.each_expr_mut(0, &mut |e, _| strip(e));
993 }
994 }
995 let (mut a, mut b) = (self.clone(), other.clone());
996 strip(&mut a);
997 strip(&mut b);
998 a == b
999 }
1000
1001 /// Calls `f` for the expression and for each expression in it, also in its subqueries, with the number of subqueries between the expression and this expression. The search stops at the first `Some` that `f` gives.
1002 pub fn find<'a, T>(
1003 &'a self,
1004 depth: usize,
1005 f: &mut impl FnMut(&'a Expr, usize) -> Option<T>,
1006 ) -> Option<T> {
1007 if let Some(found) = f(self, depth) {
1008 return Some(found);
1009 }
1010 for child in self.children() {
1011 if let Some(found) = child.find(depth, f) {
1012 return Some(found);
1013 }
1014 }
1015 if let ExprKind::SubLink(sub) = &self.kind {
1016 for (expr, depth) in sub.query.all_exprs(depth + 1) {
1017 if let Some(found) = expr.find(depth, f) {
1018 return Some(found);
1019 }
1020 }
1021 }
1022 None
1023 }
1024
1025 /// The first column of the query of the expression that the expression reads, also in a subquery, as `locate_var_of_level` finds it with level 0.
1026 pub fn first_var(&self) -> Option<&Expr> {
1027 self.find(0, &mut |e, depth| match e.kind {
1028 ExprKind::Var(var) if var.levels_up == depth => Some(e),
1029 _ => None,
1030 })
1031 }
1032
1033 /// `IncrementVarSublevelsUp`: the columns of the outer queries in the expression, also in its subqueries, are `levels` more levels up. A column of a query in the expression does not change.
1034 pub fn raise(&mut self, levels: usize) {
1035 self.raise_from(levels, 0);
1036 }
1037
1038 /// `IncrementVarSublevelsUp` with `min_sublevels_up`: as [`Expr::raise`], but only the columns that are `depth` or more levels up change.
1039 pub(crate) fn raise_from(&mut self, levels: usize, depth: usize) {
1040 match &mut self.kind {
1041 ExprKind::Var(var) if var.levels_up >= depth => var.levels_up += levels,
1042 ExprKind::PlaceHolder(p) if p.levels_up >= depth => p.levels_up += levels,
1043 _ => {}
1044 }
1045 for child in self.children_mut() {
1046 child.raise_from(levels, depth);
1047 }
1048 if let ExprKind::SubLink(sub) = &mut self.kind {
1049 sub.query.each_expr_mut(depth + 1, &mut |e, depth| e.raise_from(levels, depth));
1050 }
1051 }
1052
1053 /// `expression_tree_mutator`: calls `f` for the expression and for each expression in it, also in its subqueries, with the number of subqueries between the expression and this expression. `f` sees an expression before the expressions in it, and when `f` gives true, the walk does not go into the expression, as for an expression that `f` put in its place.
1054 pub fn each_mut(&mut self, depth: usize, f: &mut impl FnMut(&mut Expr, usize) -> bool) {
1055 if f(self, depth) {
1056 return;
1057 }
1058 for child in self.children_mut() {
1059 child.each_mut(depth, f);
1060 }
1061 if let ExprKind::SubLink(sub) = &mut self.kind {
1062 sub.query.each_expr_mut(depth + 1, &mut |e, depth| e.each_mut(depth, f));
1063 }
1064 }
1065
1066 /// `map_variable_attnos` for an expression on one relation, such as a check constraint or an index expression: each column gets the number that `map` gives for it, the number in a partition for each column of its parent table. A system column and a whole-row column keep their numbers.
1067 pub fn map_attnos(&mut self, map: &[i16]) {
1068 if let ExprKind::Var(var) = &mut self.kind
1069 && var.levels_up == 0
1070 && var.attnum > 0
1071 && let Some(&to) = map.get(usize::try_from(var.attnum - 1).unwrap_or(usize::MAX))
1072 {
1073 var.attnum = to;
1074 }
1075 for child in self.children_mut() {
1076 child.map_attnos(map);
1077 }
1078 }
1079
1080 /// `IncrementVarSublevelsUp` with a negative delta: each column of a query outside the expression comes `levels` levels down, as the planner moves an aggregate of an outer query to that query. A column of a level that is less than `levels` levels up does not change.
1081 pub fn lower(&mut self, levels: usize) {
1082 self.lower_from(levels, 0);
1083 }
1084
1085 fn lower_from(&mut self, levels: usize, depth: usize) {
1086 match &mut self.kind {
1087 ExprKind::Var(var) if var.levels_up >= depth + levels => var.levels_up -= levels,
1088 ExprKind::PlaceHolder(p) if p.levels_up >= depth + levels => p.levels_up -= levels,
1089 _ => {}
1090 }
1091 for child in self.children_mut() {
1092 child.lower_from(levels, depth);
1093 }
1094 if let ExprKind::SubLink(sub) = &mut self.kind {
1095 sub.query.each_expr_mut(depth + 1, &mut |e, depth| e.lower_from(levels, depth));
1096 }
1097 }
1098
1099 /// `contain_aggs_of_level` and `locate_agg_of_level`: the first aggregate call or call of `GROUPING` in the expression.
1100 pub fn first_agg(&self) -> Option<&Expr> {
1101 if matches!(&self.kind, ExprKind::Agg(agg) if agg.levels_up == 0)
1102 || matches!(&self.kind, ExprKind::Grouping(g) if g.levels_up == 0)
1103 {
1104 return Some(self);
1105 }
1106 self.children().into_iter().find_map(Expr::first_agg)
1107 }
1108
1109 /// `contain_windowfuncs` and `locate_windowfunc`: the first call of a window function in the expression, outside its subqueries.
1110 pub fn first_window(&self) -> Option<&Expr> {
1111 if matches!(self.kind, ExprKind::Window(_)) {
1112 return Some(self);
1113 }
1114 self.children().into_iter().find_map(Expr::first_window)
1115 }
1116
1117 /// `expression_returns_set` and `exprLocation` of the first call: the first call of a function that gives a set in the expression, outside its subqueries.
1118 pub fn first_set_call(&self) -> Option<&Expr> {
1119 if matches!(&self.kind, ExprKind::Func(f) if f.retset) {
1120 return Some(self);
1121 }
1122 self.children().into_iter().find_map(Expr::first_set_call)
1123 }
1124
1125 /// `strip_implicit_coercions`: the expression without the casts that the analyzer added.
1126 pub fn strip_implicit(&self) -> &Expr {
1127 match &self.kind {
1128 ExprKind::Func(Func { form: FuncForm::ImplicitCast, args, .. }) if !args.is_empty() => {
1129 args[0].strip_implicit()
1130 }
1131 ExprKind::Relabel(arg, CastForm::Implicit)
1132 | ExprKind::CoerceViaIo(arg, CastForm::Implicit)
1133 | ExprKind::CoerceToDomain(arg, CastForm::Implicit)
1134 | ExprKind::ArrayCoerce { arg, form: CastForm::Implicit, .. } => arg.strip_implicit(),
1135 _ => self,
1136 }
1137 }
1138
1139 /// `exprLocation`: the place of the expression. For a call, an operator or a test it is the leftmost of the place of the node and the place of the first argument, as in PostgreSQL.
1140 pub fn place(&self) -> Option<usize> {
1141 let first = match &self.kind {
1142 ExprKind::Func(Func { args, .. })
1143 | ExprKind::Bool(_, args)
1144 | ExprKind::NullIf { args, .. }
1145 | ExprKind::Distinct { args, .. }
1146 | ExprKind::ScalarArrayOp { args, .. } => args.first(),
1147 ExprKind::Relabel(arg, _)
1148 | ExprKind::CoerceViaIo(arg, _)
1149 | ExprKind::CoerceToDomain(arg, _)
1150 | ExprKind::ArrayCoerce { arg, .. }
1151 | ExprKind::NullTest(arg, _)
1152 | ExprKind::BooleanTest(arg, _)
1153 | ExprKind::FieldSelect(arg, _) => Some(&**arg),
1154 ExprKind::Subscript(sub) => Some(&sub.container),
1155 ExprKind::FieldStore(store) => Some(&store.arg),
1156 ExprKind::SubLink(sub) => sub.test.as_ref(),
1157 ExprKind::RowCompare(rc) => rc.ops.first(),
1158 ExprKind::NamedArg(na) => Some(&na.arg),
1159 ExprKind::Xml(x) => x.args.first(),
1160 _ => None,
1161 };
1162 match (self.location, first.and_then(Expr::place)) {
1163 (Some(a), Some(b)) => Some(a.min(b)),
1164 (a, b) => a.or(b),
1165 }
1166 }
1167}
1168
1169/// `procost` of the function `func`, as `get_func_cost` reads it, or 1 for a function that is not known.
1170pub fn func_cost(func: u32) -> f64 {
1171 builtin::proc_by_oid(func).map_or(1.0, |p| f64::from(p.cost))
1172}