Skip to main content

rupg_analyze/
insert.rs

1//! `transformInsertStmt` of `analyze.c`, with `checkInsertTargets` and `transformAssignedExpr` of `parse_target.c` and the defaults of `rewriteTargetListIU` and `expand_insert_targetlist`.
2//!
3//! The query of an `INSERT` gives the full row of the table for each new row, in the order of the attributes. A column that the statement does not give gets its default, the default of its domain or a null value. When the table has check constraints, the query reads the rows as a subquery and its targets after the columns are the conditions of the constraints in the order of their names, which the executor tests.
4
5use rupg_catalog::{ConKind, RelKind};
6use rupg_common::{Error, Result, SqlState};
7use rupg_pgcatalog::builtin::{self, Named};
8use rupg_sql::nodes::{
9    InsertStmt, List, LockClauseStrength, Node, OnConflictAction, OnConflictClause, OverridingKind,
10    RangeVar, SelectStmt, SortByDir, SortByNulls,
11};
12use rupg_types::{Value, oid};
13
14use crate::Analyzer;
15use crate::agg::Kind;
16use crate::coerce::{AtOpt, Context};
17use crate::expr::{BoolOp, CastForm, Expr, ExprKind, FieldStore, Func, FuncForm, Var};
18use crate::from::{Column, FromItem, Relation, TABLE_OID_ATTNUM};
19use crate::merge::Merge;
20use crate::modify::{carried_targets, column_var, set_columns};
21use crate::perm::{ACL_DELETE, ACL_INSERT, ACL_SELECT, ACL_UPDATE};
22use crate::select::{Query, Target};
23use crate::typename::place;
24use crate::types;
25
26/// The kind of a statement that writes the rows of a table, `CmdType`.
27#[derive(Clone, Copy, Debug, PartialEq, Eq)]
28pub enum WriteKind {
29    Insert,
30    Update,
31    Delete,
32    Merge,
33}
34
35impl WriteKind {
36    /// The name of the statement.
37    pub fn name(self) -> &'static str {
38        match self {
39            WriteKind::Insert => "INSERT",
40            WriteKind::Update => "UPDATE",
41            WriteKind::Delete => "DELETE",
42            WriteKind::Merge => "MERGE",
43        }
44    }
45}
46
47/// The table that an `INSERT`, an `UPDATE` or a `DELETE` writes.
48///
49/// The rows of the query of an `INSERT` are the new rows, each with the conditions of the check constraints after the columns. The rows of an `UPDATE` are the same, with the ID of the version of the old row at the end. The rows of a `DELETE` have only the ID of the version of the row.
50#[derive(Clone, Debug, PartialEq)]
51pub struct Write {
52    pub kind: WriteKind,
53    /// The OID of the table.
54    pub table: u32,
55    /// The name of the table, for the errors of the constraints.
56    pub name: String,
57    /// The alias of the target table of an `INSERT`, as `INSERT INTO t AS a`, which `EXPLAIN` shows.
58    pub alias: Option<String>,
59    /// The number of columns of the table. The first targets of the query are the columns. For a `DELETE` it is 0.
60    pub width: usize,
61    /// The names of the check constraints in the order of their names. The targets after the columns are the conditions of these constraints, in the same order.
62    pub checks: Vec<String>,
63    /// The unique indexes of the table in the order of their OIDs, as `RelationGetIndexList` gives them. Each new version of a row must have a key that no other version has.
64    pub unique: Vec<Unique>,
65    /// The query of `RETURNING`, which reads one relation: the rows that the statement writes. Each row has the columns of the table, then the values that the query of the statement carries for it. For an `UPDATE` and a `DELETE` the carried values come after the columns and the conditions in each row of the query of the statement, before the ID of the version.
66    pub returning: Option<Box<Query>>,
67    /// The foreign keys that the write checks after the statement, in the order of the names of their triggers.
68    pub foreign: Vec<Foreign>,
69    /// The `ON CONFLICT` clause of an `INSERT`.
70    pub on_conflict: Option<OnConflict>,
71    /// The clauses of a `MERGE`.
72    pub merge: Option<Merge>,
73    /// The query of the checks of the constraints after the triggers `BEFORE ... FOR EACH ROW` of an `INSERT` or an `UPDATE`, which can change the new row. It reads one relation, the new row, and gives its columns, then the conditions of the check constraints. When the write has it, [`Write::checks`] are not checked in the run of the plan: the rows of the run keep the conditions after the columns, and the caller checks the rows after the triggers.
74    pub recheck: Option<Box<Query>>,
75    /// The numbers of the columns that `SET` of an `UPDATE` or of `ON CONFLICT DO UPDATE` gives, in the order of the list, for the triggers of `UPDATE OF`. For a `MERGE` they are the columns of the `SET` of all its clauses `UPDATE`, as `transformMergeStmt` puts them in `updatedCols`.
76    pub updated: Vec<i16>,
77    /// True for a write into a view with a trigger `INSTEAD OF ... FOR EACH ROW` for the event. The rows of the query go to the triggers, not to the heap, and the rows of an `UPDATE` and of a `DELETE` end with the old row of the view in place of the ID of the version.
78    pub instead: bool,
79    /// True for an `UPDATE`, a `DELETE` or a `MERGE` of a table with children of `INHERITS`, with no `ONLY`, as `expand_inherited_rtentry` adds the children. Each row of the query gives the OID of its table before the ID of its version, and each table of the tree checks and changes its rows, as the leaves of a partitioned table do.
80    pub inherit: bool,
81    /// The checks of `WITH CHECK OPTION` of the views of an `INSERT` or an `UPDATE` of an automatically updatable view.
82    pub view_check: Option<ViewCheck>,
83    /// The number of automatically updatable views that the statement writes through. `rewriteTargetView` keeps the entry of each view in the range table and adds the entry of the relation under it.
84    pub views: usize,
85}
86
87impl Write {
88    /// True when the write keeps the rows that it wrote, for `RETURNING` or for [`Write::view_check`].
89    #[must_use]
90    pub fn keeps_written(&self) -> bool {
91        self.returning.is_some() || self.view_check.is_some()
92    }
93}
94
95/// The `WithCheckOption` items of the kind `WCO_VIEW_CHECK` of a write, which `ExecWithCheckOptions` checks after the write of each row, before `RETURNING`.
96#[derive(Clone, Debug, PartialEq)]
97pub struct ViewCheck {
98    /// The query of the checks. It reads one relation, a row that the statement wrote with the columns of the table, and gives the condition of each view in the order of [`ViewCheck::views`].
99    pub query: Box<Query>,
100    /// The names of the views, the inner view first, as `rewriteTargetView` puts each new check at the start of the list.
101    pub views: Vec<String>,
102}
103
104/// `OnConflictExpr`: what an `INSERT` does for a new row with the key of a row that the table has.
105#[derive(Clone, Debug, PartialEq)]
106pub struct OnConflict {
107    /// The places in [`Write::unique`] of the arbiter indexes, which `infer_arbiter_indexes` finds. A conflict in another unique index is an error.
108    pub arbiters: Vec<usize>,
109    /// True for a clause with no inference. Each unique index is then an arbiter, also an index of a partition that the partitioned table does not have.
110    pub all: bool,
111    /// The query of `DO UPDATE`, or `None` for `DO NOTHING`. It reads two relations: the row that the table has, with the ID of its version at the end, and `EXCLUDED`, the row that the statement proposed. It gives the new row, then the conditions of the check constraints, then the values that `RETURNING` carries, or no row when the condition of `WHERE` is not true.
112    pub update: Option<Box<Query>>,
113    /// The strength of the lock of `DO SELECT`, or `None` for `DO UPDATE` and `DO NOTHING`. [`OnConflict::update`] is then the query of `DO SELECT`, which gives the row that the table has, and the statement writes no row.
114    pub select: Option<LockClauseStrength>,
115    /// The number of values that `RETURNING` carries: the columns of the old row. A row that the statement inserts has nulls for them.
116    pub carried: usize,
117    /// The foreign keys that an update of a row checks, in the order of the names of their triggers.
118    pub foreign: Vec<Foreign>,
119}
120
121impl OnConflict {
122    /// True for `DO SELECT` with a lock, such as `FOR UPDATE`.
123    #[must_use]
124    pub fn locks(&self) -> bool {
125        self.select.is_some_and(|strength| strength != LockClauseStrength::LCS_NONE)
126    }
127
128    /// `show_modifytable_info`: what the statement does for a conflict, as `EXPLAIN` shows it. `DO SELECT` shows its lock.
129    #[must_use]
130    pub fn resolution(&self) -> &'static str {
131        match self.select {
132            Some(LockClauseStrength::LCS_NONE) => "SELECT",
133            Some(LockClauseStrength::LCS_FORKEYSHARE) => "SELECT FOR KEY SHARE",
134            Some(LockClauseStrength::LCS_FORSHARE) => "SELECT FOR SHARE",
135            Some(LockClauseStrength::LCS_FORNOKEYUPDATE) => "SELECT FOR NO KEY UPDATE",
136            Some(_) => "SELECT FOR UPDATE",
137            None if self.update.is_some() => "UPDATE",
138            None => "NOTHING",
139        }
140    }
141}
142
143/// What a trigger of a foreign key on the referenced table does for an old key, `confdeltype` and `confupdtype`.
144#[derive(Clone, Copy, Debug, PartialEq, Eq)]
145pub enum Action {
146    /// `NO ACTION`: an error if a row of the referencing table has the old key and no other row of the referenced table has it.
147    NoAction,
148    /// `RESTRICT`: an error if a row of the referencing table has the old key. The check does not look for another row with the old key, as `ri_Check_Pk_Match` does for `NO ACTION`.
149    Restrict,
150    /// `CASCADE`: the rows of the referencing table with the old key go, or get the new key.
151    Cascade,
152    /// `SET NULL`: the rows of the referencing table with the old key get nulls.
153    SetNull,
154    /// `SET DEFAULT`: the rows of the referencing table with the old key get the defaults of the columns.
155    SetDefault,
156}
157
158/// A foreign key that a write checks after the statement for each row that it wrote, as a trigger of `ri_triggers.c` checks it. The target table is the referencing table for `RI_FKey_check_ins` and `RI_FKey_check_upd`, and the referenced table for the triggers of the actions, such as `RI_FKey_noaction_del` and `RI_FKey_cascade_upd`.
159#[derive(Clone, Debug, PartialEq)]
160pub struct Foreign {
161    /// The name of the constraint.
162    pub name: String,
163    /// True when the target table is the referencing table.
164    pub referencing: bool,
165    /// The action for an old key of the referenced table. It is [`Action::NoAction`] for the referencing table.
166    pub action: Action,
167    /// The statement of `CASCADE`, `SET NULL` or `SET DEFAULT` on the referencing table, as `ri_PlanCheck` makes it, or an empty text. Its parameters are the old key, or for `ON UPDATE CASCADE` the new key and then the old key, with the types of [`Foreign::types`].
168    pub query: String,
169    /// `MATCH FULL`: a key with nulls and values is an error.
170    pub full: bool,
171    /// The OID of the other table.
172    pub other: u32,
173    /// The name of the other table, for the error.
174    pub other_name: String,
175    /// The key columns of the target table, from 0.
176    pub columns: Vec<usize>,
177    /// The names of the key columns of the target table, for the detail of the error.
178    pub names: Vec<String>,
179    /// The key columns of the other table, from 0.
180    pub other_columns: Vec<usize>,
181    /// The type of each column of the key of the referenced table. The checks compare the values of the referencing table as values of these types.
182    pub types: Vec<u32>,
183    /// The type of each column of the key of the referencing table.
184    pub referencing_types: Vec<u32>,
185    /// The OID of the constraint, which `SET CONSTRAINTS` names.
186    pub constraint: u32,
187    /// `tgdeferrable`: `SET CONSTRAINTS` can defer the trigger. The trigger of an action is not deferrable.
188    pub deferrable: bool,
189    /// `tginitdeferred`: the trigger fires at the commit when `SET CONSTRAINTS` does not change its mode.
190    pub deferred: bool,
191    /// `tgisclone`: the trigger is a clone of a trigger of the parent table. The delete of a row that an `UPDATE` moves to another partition skips such a trigger of the referenced table, because the event of the update of the partitioned table does its work.
192    pub cloned: bool,
193}
194
195/// A unique index of the target table, which `_bt_check_unique` checks for each new version of a row.
196#[derive(Clone, Debug, PartialEq)]
197pub struct Unique {
198    /// The OID of the index.
199    pub oid: u32,
200    /// The name of the index, for the error.
201    pub name: String,
202    /// The column of the table of each key column, from 0.
203    pub columns: Vec<usize>,
204    /// The type of each key column.
205    pub types: Vec<u32>,
206    /// The key columns as `pg_get_indexdef_columns` gives them, for the detail of the error.
207    pub shown: String,
208    /// `indnullsnotdistinct`: a null is equal to a null, so two keys with nulls can conflict.
209    pub nulls_not_distinct: bool,
210    /// The expressions and the predicate of an index with an expression or a predicate, or `None` for an index whose key is columns of the table.
211    pub derived: Option<Box<Derived>>,
212    /// The constraint of an index that is not `indimmediate`, or `None` for an index that checks each key at once.
213    pub deferrable: Option<Deferrable>,
214}
215
216/// A `DEFERRABLE` unique constraint. A write does not fail on a duplicate key of its index: `unique_key_recheck` checks the key again after the statement, or at the commit when the constraint is deferred.
217#[derive(Clone, Copy, Debug, PartialEq, Eq)]
218pub struct Deferrable {
219    /// The OID of the constraint, for the modes of `SET CONSTRAINTS`.
220    pub constraint: u32,
221    /// `condeferred`: the constraint is `INITIALLY DEFERRED`.
222    pub deferred: bool,
223}
224
225/// The key of a unique index with an expression or a predicate, which `FormIndexDatum` computes for each row. A row that does not pass the predicate is not in the index, as `ExecInsertIndexTuples` checks it with `ExecQual`. [`Unique::columns`] has the places of the key columns in the values of the expressions.
226#[derive(Clone, Debug, PartialEq)]
227pub struct Derived {
228    /// The OID of the table.
229    pub table: u32,
230    /// The type of each column of the table.
231    pub types: Vec<u32>,
232    /// The expression of each key column, with the columns of the table as columns of the relation 0. A key column that is a column of the table is a variable.
233    pub exprs: Vec<Expr>,
234    /// The parts of the predicate, `indpred`, or none for an index with no predicate.
235    pub predicate: Vec<Expr>,
236}
237
238/// `quoteOneName` of `ri_triggers.c`: a name in double quotes, with each double quote doubled.
239fn quote_one(name: &str) -> String {
240    format!("\"{}\"", name.replace('"', "\"\""))
241}
242
243/// The statement of an action of a foreign key on the referencing table `table`, as `RI_FKey_cascade_del`, `RI_FKey_cascade_upd` and `ri_set` make it. `names` are the key columns of the referencing table.
244fn action_query(
245    (action, kind): (Action, WriteKind),
246    (table, only): (&str, bool),
247    names: &[&str],
248    foreign: &Foreign,
249) -> String {
250    let columns: Vec<String> = names.iter().map(|name| quote_one(name)).collect();
251    // `ri_triggers.c` writes `ONLY` unless the referencing table is partitioned.
252    let only = if only { "ONLY " } else { "" };
253    let mut query = match (action, kind) {
254        (Action::Cascade, WriteKind::Delete) => format!("DELETE FROM {only}{table}"),
255        (Action::Cascade, _) => {
256            let set: Vec<String> =
257                columns.iter().enumerate().map(|(at, c)| format!(" {c} = ${}", at + 1)).collect();
258            format!("UPDATE {only}{table} SET{}", set.join(","))
259        }
260        _ => {
261            let value = if action == Action::SetNull { "NULL" } else { "DEFAULT" };
262            let set: Vec<String> = columns.iter().map(|c| format!(" {c} = {value}")).collect();
263            format!("UPDATE {only}{table} SET{}", set.join(","))
264        }
265    };
266    // The parameters of the old key come after the new key for `ON UPDATE CASCADE`.
267    let first =
268        if action == Action::Cascade && kind == WriteKind::Update { names.len() } else { 0 };
269    for (at, column) in columns.iter().enumerate() {
270        let separator = if at == 0 { "WHERE" } else { "AND" };
271        let (pk, fk) = (foreign.types[at], foreign.referencing_types[at]);
272        let (left, right) = operator_types(pk, fk);
273        query.push_str(&format!(" {separator} ${}", first + at + 1));
274        if left != pk {
275            query.push_str(&cast_to(left));
276        }
277        query.push_str(&format!(" OPERATOR(pg_catalog.=) {column}"));
278        if right != fk {
279            query.push_str(&cast_to(right));
280        }
281    }
282    query
283}
284
285/// The input types of the equality operator `pf_eq_oprs` of a key column of the referenced type `pk` and the referencing type `fk`. `ATAddForeignKeyConstraint` takes the operator of the operator class of the index of the referenced key for the two types, or for the type of the class when the family has no operator for the type of the referencing column.
286fn operator_types(pk: u32, fk: u32) -> (u32, u32) {
287    let class = |ty: u32| match types::base(ty) {
288        oid::VARCHAR => oid::TEXT,
289        ty => ty,
290    };
291    let family = |ty: u32| match ty {
292        oid::INT2 | oid::INT4 | oid::INT8 => 1,
293        oid::FLOAT4 | oid::FLOAT8 => 2,
294        oid::DATE | oid::TIMESTAMP | oid::TIMESTAMPTZ => 3,
295        oid::TEXT | oid::NAME => 4,
296        _ => 0,
297    };
298    let (left, other) = (class(pk), class(fk));
299    let right = if other == left || (family(left) != 0 && family(left) == family(other)) {
300        other
301    } else {
302        left
303    };
304    (left, right)
305}
306
307/// `add_cast_to` of `ruleutils.c`: the cast to a type of `pg_catalog`, with the names as `quote_identifier` gives them.
308fn cast_to(ty: u32) -> String {
309    let name = builtin::type_by_oid(ty).map_or("", |row| row.name);
310    format!("::pg_catalog.{}", crate::ddl::quote_identifier(name))
311}
312
313/// An item of a row of `VALUES` or of `UPDATE ... SET`: an expression, or `DEFAULT` at its place.
314pub(crate) enum Item {
315    Expr(Expr),
316    Default(Option<usize>),
317}
318
319impl Item {
320    fn place(&self) -> Option<usize> {
321        match self {
322            Item::Expr(expr) => expr.place(),
323            Item::Default(at) => *at,
324        }
325    }
326}
327
328/// A generated column of a table: the index of the column from 0, its generation expression and `attgenerated`, `s` for a stored column or `v` for a virtual column.
329pub(crate) type Generated = (usize, Expr, u8);
330
331/// A column that the statement gives: the index of the column in the table, the place of its name in the column list, and the subscripts after the name, which are empty when the item sets the whole column.
332pub(crate) type Given = (usize, Option<usize>, List);
333
334/// The bits in `tgtype` of a trigger `INSTEAD OF ... FOR EACH ROW`.
335pub(crate) const INSTEAD_ROW: i16 = rupg_catalog::TRIGGER_ROW | rupg_catalog::TRIGGER_INSTEAD;
336
337/// The error of a clause that the analyzer does not take yet.
338pub(crate) fn not_yet(what: &str) -> Error {
339    Error::new(SqlState::FEATURE_NOT_SUPPORTED, format!("{what} is not supported yet"))
340}
341
342/// `exprLocation` of a list of items: the first place.
343fn first_place(items: &[Item]) -> Option<usize> {
344    items.iter().find_map(Item::place)
345}
346
347impl Analyzer<'_> {
348    /// `transformInsertStmt`: the query tree of an `INSERT`.
349    pub(crate) fn insert(&mut self, s: &InsertStmt) -> Result<Query> {
350        let inverted = std::mem::take(&mut self.rule.inverted);
351        self.write_with(s.withClause.as_deref())?;
352        let rv = s.relation.as_deref().ok_or_else(|| Error::internal("an INSERT with no table"))?;
353        let (table, name, columns) = self.target_table(rv, WriteKind::Insert)?;
354        let rows = std::mem::take(&mut self.rule.rows);
355        if self.auto_view.is_some() && !inverted.is_empty() {
356            return Err(not_yet("a conditional rule DO INSTEAD of an updatable view"));
357        }
358        let given = match self.auto_view_targets(&s.cols, columns.len())? {
359            Some(given) => given,
360            None => self.insert_targets(&s.cols, &name, &columns)?,
361        };
362        let explicit = !s.cols.is_empty();
363        let select = match &s.selectStmt {
364            None => None,
365            Some(Node::SelectStmt(select)) => Some(&**select),
366            Some(_) => return Err(Error::internal("an INSERT source that is not SELECT")),
367        };
368        // `DEFAULT VALUES` gives no column a value.
369        if select.is_some() {
370            self.mark_inserted(&given);
371        }
372        let mut query = match select {
373            None => {
374                let row = self.full_row(table, &columns, &given, Vec::new())?;
375                row_query(&columns, row)
376            }
377            Some(select) if general_select(select) => {
378                self.insert_select(select, table, &columns, &given, explicit, s.r#override)?
379            }
380            Some(select) if select.valuesLists.len() > 1 => {
381                self.insert_values(select, table, &columns, &given, explicit, s.r#override)?
382            }
383            Some(select) => {
384                let Some(Some(Node::List(list))) = select.valuesLists.first() else {
385                    return Err(Error::internal("a VALUES row that is not a list"));
386                };
387                let items = self.value_items(list, Kind::ValuesSingle)?;
388                let exprs =
389                    self.insert_row(items, table, &columns, &given, explicit, s.r#override)?;
390                let row = self.full_row(table, &columns, &given, exprs)?;
391                row_query(&columns, row)
392            }
393        };
394        if rows {
395            // The rows of `*rule*`: the new row, with its generated columns.
396            let generated = self.generated_columns(table)?;
397            let mut query = with_checks(&name, &columns, query, Vec::new(), &generated, &[]);
398            self.end_write_with(&mut query, s.withClause.as_deref())?;
399            self.rule.columns = columns;
400            return Ok(query);
401        }
402        if !inverted.is_empty() {
403            let generated = self.generated_columns(table)?;
404            let mut rows = with_checks(&name, &columns, query, Vec::new(), &[], &[]);
405            let new = crate::rules::relation_row(&columns, 0, 0);
406            let new = crate::rules::with_generated(new, &generated);
407            let new = crate::rules::named_row(&columns, new);
408            let quals = self.inverted_quals(&inverted, None, Some(new))?;
409            rows.filter = crate::rules::and_filter(rows.filter.take(), quals);
410            query = rows;
411        }
412        // `ExecFindPartition` routes each row, and the partition then checks it.
413        let checks = if self.is_partitioned(table) { Vec::new() } else { self.checks(table)? };
414        let names = checks.iter().map(|(n, _)| n.clone()).collect();
415        let conflict_set = s
416            .onConflictClause
417            .as_deref()
418            .filter(|c| matches!(c.action, OnConflictAction::ONCONFLICT_UPDATE))
419            .map(|c| &c.targetList);
420        // The items of `SET` of an updatable view name the columns of its base relation.
421        let renamed = conflict_set.and_then(|list| self.auto_view_set(rv, list, &columns));
422        let conflict_set = renamed.as_ref().map(|(list, _, _)| list).or(conflict_set);
423        let generated = self.generated_columns(table)?;
424        let mut recheck =
425            self.recheck(table, WriteKind::Insert, &name, &columns, &checks, &generated);
426        if recheck.is_none() && conflict_set.is_some() {
427            // The triggers `BEFORE UPDATE ... FOR EACH ROW` of `DO UPDATE` also come before the checks.
428            recheck = self.recheck(table, WriteKind::Update, &name, &columns, &checks, &generated);
429        }
430        let updated = conflict_set.map_or_else(Vec::new, |list| set_columns(list, &columns));
431        // `DO SELECT` with a lock needs `UPDATE` too.
432        let locks = s.onConflictClause.as_deref().is_some_and(|c| {
433            c.action == OnConflictAction::ONCONFLICT_SELECT
434                && c.lockStrength != LockClauseStrength::LCS_NONE
435        });
436        if conflict_set.is_some() || locks {
437            self.mark_updated(&updated);
438        }
439        let updated = crate::modify::with_extra_updated(updated, &generated);
440        if !checks.is_empty() || !generated.is_empty() {
441            query = with_checks(&name, &columns, query, checks, &generated, &[]);
442        }
443        let width = columns.len();
444        let unique = self.unique_keys(table, &columns)?;
445        let foreign = self.foreign_keys(table, WriteKind::Insert, &columns)?;
446        let (mut on_conflict, mut returning) = (None, None);
447        if s.onConflictClause.is_some() || s.returningClause.is_some() {
448            let outer = std::mem::take(&mut self.scope);
449            // `ON CONFLICT` and `RETURNING` can read the queries of `WITH`.
450            self.scope.ctes.clone_from(&outer.ctes);
451            let result = self.insert_clauses(s, rv, table, &name, &columns, &unique);
452            self.scope = outer;
453            (on_conflict, returning) = result?;
454        }
455        query.write = Some(Write {
456            kind: WriteKind::Insert,
457            table,
458            name,
459            alias: rv.alias.as_ref().and_then(|a| a.aliasname.as_ref()).map(ToString::to_string),
460            width,
461            checks: names,
462            unique,
463            returning,
464            foreign,
465            on_conflict,
466            merge: None,
467            recheck,
468            updated,
469            instead: self.is_view(table),
470            inherit: false,
471            view_check: None,
472            views: 0,
473        });
474        self.end_write_with(&mut query, s.withClause.as_deref())?;
475        Ok(query)
476    }
477
478    /// `transformOnConflictClause` and `transformReturningClause` of an `INSERT`, which see only the target table. The query of `DO UPDATE` gets the conditions of the check constraints and the values that `RETURNING` carries.
479    fn insert_clauses(
480        &mut self,
481        s: &InsertStmt,
482        rv: &RangeVar,
483        table: u32,
484        name: &str,
485        columns: &[Column],
486        unique: &[Unique],
487    ) -> Result<(Option<OnConflict>, Option<Box<Query>>)> {
488        if let Some(clause) = s.onConflictClause.as_deref()
489            && clause.action == OnConflictAction::ONCONFLICT_SELECT
490            && s.returningClause.is_none()
491        {
492            return Err(Error::new(
493                SqlState::SYNTAX_ERROR,
494                "ON CONFLICT DO SELECT requires a RETURNING clause",
495            )
496            .at_opt(place(clause.location)));
497        }
498        self.target_from(rv, &[])?;
499        let (mut on_conflict, inference) = match s.onConflictClause.as_deref() {
500            None => (None, Inference::All),
501            Some(clause) => {
502                let (on_conflict, inference) =
503                    self.on_conflict(clause, rv, table, name, columns)?;
504                (Some(on_conflict), inference)
505            }
506        };
507        // With `DO UPDATE`, the old row of `RETURNING` is the row that the statement updates, as for an `UPDATE`. With `DO SELECT`, the old and the new rows are the row that the table has.
508        let update = on_conflict.as_ref().is_some_and(|c| c.update.is_some());
509        let kind = if update { WriteKind::Update } else { WriteKind::Insert };
510        let (returning, carried) = match s.returningClause.as_deref() {
511            None => (None, Vec::new()),
512            Some(clause) => {
513                let (query, carried) = self.returning(clause, kind)?;
514                (Some(Box::new(query)), carried)
515            }
516        };
517        if let Some(conflict) = &mut on_conflict
518            && let Some(mut query) = conflict.update.take()
519        {
520            let tail: Vec<Column> = carried
521                .iter()
522                .map(|expr| Column {
523                    name: String::new(),
524                    ty: expr.ty,
525                    typmod: expr.typmod,
526                    not_null: false,
527                })
528                .collect();
529            conflict.carried = carried.len();
530            query.targets.extend(carried_targets(carried));
531            // The leaf partition checks the new row of a partitioned table, and `DO SELECT` writes no row.
532            let write = conflict.select.is_none() && !self.is_partitioned(table);
533            let checks = if write { self.checks(table)? } else { Vec::new() };
534            let generated =
535                if conflict.select.is_none() { self.generated_columns(table)? } else { Vec::new() };
536            if !checks.is_empty() || !generated.is_empty() {
537                query = Box::new(with_checks(name, columns, *query, checks, &generated, &tail));
538            }
539            conflict.update = Some(query);
540        }
541        // The planner matches the inference with the indexes after the analysis.
542        if let Some(conflict) = &mut on_conflict {
543            conflict.all = matches!(inference, Inference::All);
544            conflict.arbiters = arbiters(inference, unique, self.env.catalog())?;
545        }
546        Ok((on_conflict, returning))
547    }
548
549    /// `transformOnConflictClause`: the inference of the arbiter indexes, and the query of `DO UPDATE` with the new row. `SET` and `WHERE` see the target table and `EXCLUDED`, and the clauses after them see only the target table.
550    fn on_conflict(
551        &mut self,
552        clause: &OnConflictClause,
553        rv: &RangeVar,
554        table: u32,
555        name: &str,
556        columns: &[Column],
557    ) -> Result<(OnConflict, Inference)> {
558        let (update, select) = match clause.action {
559            OnConflictAction::ONCONFLICT_NOTHING => (false, None),
560            OnConflictAction::ONCONFLICT_UPDATE => (true, None),
561            _ => (false, Some(clause.lockStrength)),
562        };
563        let inference = self.inference(clause, update || select.is_some(), table, name, columns)?;
564        let mut on_conflict = OnConflict {
565            arbiters: Vec::new(),
566            all: false,
567            update: None,
568            select,
569            carried: 0,
570            foreign: Vec::new(),
571        };
572        if select.is_some() {
573            // `DO SELECT` gives the row that the table has when `WHERE` lets it through.
574            let excluded = self.add_excluded()?;
575            let filter = self.target_where(clause.whereClause.as_ref());
576            self.hide_last_item();
577            let row = columns.iter().enumerate().map(|(at, c)| column_var(at, c)).collect();
578            let query = Query {
579                relations: self.scope.relations.clone(),
580                from: vec![FromItem::Relation(0), FromItem::Relation(excluded)],
581                targets: targets(columns, row),
582                filter: filter?,
583                ..Query::default()
584            };
585            on_conflict.update = Some(Box::new(query));
586            return Ok((on_conflict, inference));
587        }
588        if !update {
589            return Ok((on_conflict, inference));
590        }
591        let excluded = self.add_excluded()?;
592        // The items of `SET` of an updatable view name the columns of its base relation, and they must name updatable columns of the view.
593        let (renamed, error) = match self.auto_view_set(rv, &clause.targetList, columns) {
594            Some((list, unknown, fixed)) => (Some(list), unknown.or(fixed)),
595            None => (None, None),
596        };
597        let list = renamed.as_ref().unwrap_or(&clause.targetList);
598        let row = match error {
599            Some(error) => self.set_items(list).and(Err(error)),
600            None => self.update_row(rv, table, name, columns, list),
601        };
602        let parts = row.and_then(|row| {
603            let filter = self.target_where(clause.whereClause.as_ref())?;
604            Ok((row, filter))
605        });
606        self.hide_last_item();
607        let (row, filter) = parts?;
608        let query = Query {
609            relations: self.scope.relations.clone(),
610            from: vec![FromItem::Relation(0), FromItem::Relation(excluded)],
611            targets: targets(columns, row),
612            filter,
613            ..Query::default()
614        };
615        on_conflict.update = Some(Box::new(query));
616        on_conflict.foreign = self.foreign_keys(table, WriteKind::Update, columns)?;
617        Ok((on_conflict, inference))
618    }
619
620    /// `transformOnConflictArbiter`: the columns of the inference, or the index of the constraint that the clause names.
621    fn inference(
622        &mut self,
623        clause: &OnConflictClause,
624        update: bool,
625        table: u32,
626        name: &str,
627        columns: &[Column],
628    ) -> Result<Inference> {
629        let Some(infer) = clause.infer.as_deref() else {
630            if update {
631                let what = if clause.action == OnConflictAction::ONCONFLICT_SELECT {
632                    "SELECT"
633                } else {
634                    "UPDATE"
635                };
636                return Err(Error::new(
637                    SqlState::SYNTAX_ERROR,
638                    format!(
639                        "ON CONFLICT DO {what} requires inference specification or constraint name"
640                    ),
641                )
642                .with_hint("For example, ON CONFLICT (column_name).")
643                .at_opt(place(clause.location)));
644            }
645            return Ok(Inference::All);
646        };
647        if let Some(conname) = infer.conname.as_deref() {
648            // The constraint is a constraint of the view that the statement names, which has none.
649            let (table, name) = self.auto_view_target().unwrap_or((table, name));
650            let constraint = self
651                .env
652                .catalog()
653                .and_then(|catalog| catalog.constraints_of(table).find(|c| c.name == conname));
654            let Some(constraint) = constraint else {
655                return Err(Error::new(
656                    SqlState::UNDEFINED_OBJECT,
657                    format!("constraint \"{conname}\" for table \"{name}\" does not exist"),
658                ));
659            };
660            // The columns of the constraint need `SELECT`.
661            let keys = constraint.keys.clone();
662            let index = constraint.index;
663            if let Some(perm) = self.target_perm_mut() {
664                perm.required |= ACL_SELECT;
665                perm.selected.extend(keys);
666            }
667            return Ok(Inference::Constraint(index));
668        }
669        let mut set = Vec::with_capacity(infer.indexElems.len());
670        let mut exprs = Vec::new();
671        let mut exact = Vec::new();
672        for node in &infer.indexElems {
673            let Some(Node::IndexElem(elem)) = node else {
674                return Err(Error::internal("an inference element that is not IndexElem"));
675            };
676            let at = place(elem.location);
677            let not_allowed = |what: &str| {
678                Error::new(
679                    SqlState::INVALID_COLUMN_REFERENCE,
680                    format!("{what} is not allowed in ON CONFLICT clause"),
681                )
682                .at_opt(at)
683            };
684            if elem.ordering != SortByDir::SORTBY_DEFAULT {
685                return Err(not_allowed("ASC/DESC"));
686            }
687            if elem.nulls_ordering != SortByNulls::SORTBY_NULLS_DEFAULT {
688                return Err(not_allowed("NULLS FIRST/LAST"));
689            }
690            if !elem.opclassopts.is_empty() {
691                return Err(Error::new(
692                    SqlState::INVALID_COLUMN_REFERENCE,
693                    "operator class options are not allowed in ON CONFLICT clause",
694                )
695                .at_opt(at));
696            }
697            let collation = match elem.collation.is_empty() {
698                true => 0,
699                false => self.collation_oid(&elem.collation, at)?,
700            };
701            let class = match elem.opclass.is_empty() {
702                true => None,
703                false => Some(self.btree_opclass(&elem.opclass)?),
704            };
705            let mut note = |target: Exact| {
706                if collation != 0 || class.is_some() {
707                    exact.push(ExactElem { target, collation, class });
708                }
709            };
710            let Some(column) = elem.name.as_deref() else {
711                // `resolve_unique_index_expr`: an expression that is a column counts as the column.
712                let expr =
713                    self.with_kind(Kind::IndexExpression, |a| a.transform(elem.expr.as_ref()))?;
714                match expr.kind {
715                    ExprKind::Var(var) if var.levels_up == 0 && var.attnum > 0 => {
716                        note(Exact::Column(var.attnum));
717                        set.extend(usize::try_from(var.attnum - 1).ok());
718                    }
719                    _ => {
720                        note(Exact::Expr(exprs.len()));
721                        exprs.push(expr);
722                    }
723                }
724                continue;
725            };
726            // A column of an updatable view is the expression of the view on the base relation.
727            let index = match self.auto_view_column(column) {
728                None => columns.iter().position(|c| c.name == column),
729                Some(Some(expr)) => match expr.kind {
730                    ExprKind::Var(var) if var.attnum > 0 => usize::try_from(var.attnum - 1).ok(),
731                    _ => {
732                        note(Exact::Expr(exprs.len()));
733                        exprs.push(expr);
734                        continue;
735                    }
736                },
737                Some(None) => None,
738            };
739            let Some(index) = index else {
740                return Err(Error::new(
741                    SqlState::UNDEFINED_COLUMN,
742                    format!("column \"{column}\" does not exist"),
743                )
744                // `resolve_unique_index_expr` puts the column reference at the inference clause.
745                .at_opt(place(infer.location)));
746            };
747            // The column is a reference to the column, which needs `SELECT`.
748            if let Some(perm) = self.target_perm_mut() {
749                perm.required |= ACL_SELECT;
750                perm.selected.insert(i16::try_from(index + 1).unwrap_or(i16::MAX));
751            }
752            note(Exact::Column(i16::try_from(index + 1).unwrap_or(i16::MAX)));
753            set.push(index);
754        }
755        set.sort_unstable();
756        set.dedup();
757        let mut predicate = Vec::new();
758        if let Some(clause) = infer.whereClause.as_ref() {
759            let expr = self.with_kind(Kind::IndexPredicate, |a| a.transform(Some(clause)))?;
760            let expr = self.coerce_to_boolean(expr, "WHERE")?;
761            match expr.kind {
762                ExprKind::Bool(BoolOp::And, parts) => predicate = parts,
763                _ => predicate.push(expr),
764            }
765        }
766        Ok(Inference::Columns { columns: set, exprs, predicate, exact })
767    }
768
769    /// `get_opclass_oid` for `btree`: the operator family and the input type of the operator class that the name gives, in the schema of the name or in the first schema of the search path that has it.
770    fn btree_opclass(&self, list: &[Option<Node>]) -> Result<(u32, u32)> {
771        const BTREE: u32 = 403;
772        let parts = crate::typename::names(list);
773        let (schema, name) = self.split_name(&parts, None)?;
774        let catalog = self.env.catalog();
775        let find = |namespace: u32| {
776            let user = catalog.and_then(|c| {
777                c.opclasses()
778                    .find(|c| c.method == BTREE && c.namespace == namespace && c.name == name)
779                    .map(|c| (c.family, c.intype))
780            });
781            user.or_else(|| {
782                let row = builtin::named(Named::Opclass)
783                    .iter()
784                    .find(|r| r.method == BTREE && r.namespace == namespace && r.name == name)?;
785                let class = builtin::opclasses().iter().find(|c| c.oid == row.oid)?;
786                Some((class.family, class.intype))
787            })
788        };
789        let found = match schema {
790            Some(namespace) => find(namespace),
791            None => self.path.iter().find_map(|&namespace| find(namespace)),
792        };
793        found.ok_or_else(|| {
794            Error::new(
795                SqlState::UNDEFINED_OBJECT,
796                format!(
797                    "operator class \"{}\" does not exist for access method \"btree\"",
798                    parts.join(".")
799                ),
800            )
801        })
802    }
803
804    /// `setTargetTable`: the OID, the name and the columns of the table that the statement writes. A table with a constraint or an object that the executor does not check yet gives `0A000`. The table gets the privileges that the write needs, which a `MERGE` gives later from its clauses.
805    pub(crate) fn target_table(
806        &mut self,
807        rv: &RangeVar,
808        kind: WriteKind,
809    ) -> Result<(u32, String, Vec<Column>)> {
810        let what = match kind {
811            WriteKind::Insert => "INSERT into",
812            WriteKind::Update => "UPDATE of",
813            WriteKind::Delete => "DELETE from",
814            WriteKind::Merge => "MERGE into",
815        };
816        let at = place(rv.location);
817        let name = rv.relname.as_deref().unwrap_or_default().to_string();
818        self.check_target(rv)?;
819        let Some(oid) = self.lookup_relation(rv)? else {
820            let shown = match &rv.schemaname {
821                Some(schema) => format!("{schema}.{name}"),
822                None => name.clone(),
823            };
824            return Err(Error::new(
825                SqlState::UNDEFINED_TABLE,
826                format!("relation \"{shown}\" does not exist"),
827            )
828            .at_opt(at));
829        };
830        let rel = self.env.catalog().and_then(|c| c.relation(oid));
831        let Some(rel) = rel else {
832            return Err(not_yet(&format!("{what} a system catalog")));
833        };
834        match rel.kind {
835            RelKind::Table => {}
836            RelKind::Sequence => {
837                return Err(Error::new(
838                    SqlState::WRONG_OBJECT_TYPE,
839                    format!("cannot change sequence \"{name}\""),
840                ));
841            }
842            // `view_has_instead_trigger`: the triggers `INSTEAD OF` of the view do the write.
843            RelKind::View
844                if kind != WriteKind::Merge
845                    && self.user_triggers(oid, INSTEAD_ROW | trigger_event(kind)) => {}
846            // The rows of a statement for the rules of a view need no write of the view.
847            RelKind::View if self.rule.rows => {}
848            // `rewriteTargetView` writes the base relation of the view.
849            RelKind::View => {}
850            RelKind::Partitioned => {}
851            RelKind::MatView if self.env.filling() == oid => {}
852            RelKind::MatView => {
853                return Err(Error::new(
854                    SqlState::WRONG_OBJECT_TYPE,
855                    format!("cannot change materialized view \"{name}\""),
856                ));
857            }
858            _ => {
859                return Err(Error::new(
860                    SqlState::WRONG_OBJECT_TYPE,
861                    format!("cannot change relation \"{name}\""),
862                ));
863            }
864        }
865        if let Some(catalog) = self.env.catalog() {
866            let mut rules = catalog.rules().filter(|r| r.relation == oid && crate::rules::fires(r));
867            if kind == WriteKind::Merge {
868                // `RewriteQuery`: a rule of an event other than `SELECT` stops a `MERGE`.
869                if rules.any(|r| r.event != b'1') {
870                    return Err(Error::new(
871                        SqlState::FEATURE_NOT_SUPPORTED,
872                        format!("cannot execute MERGE on relation \"{name}\""),
873                    )
874                    .with_detail("MERGE is not supported for relations with rules."));
875                }
876            } else {
877                let code = match kind {
878                    WriteKind::Insert => b'3',
879                    WriteKind::Update => b'2',
880                    _ => b'4',
881                };
882                // [`crate::query_rewrite`] gives the statements of the rules, and a statement that it does not rewrite cannot write the table yet.
883                let done = self.rule.rows || self.rule.defining || self.rule.fired == Some(oid);
884                if !done && rules.any(|r| r.event == code) {
885                    return Err(not_yet(&format!("{what} a table with rules")));
886                }
887            }
888        }
889        let columns = write_columns(rel);
890        let name = rel.name.clone();
891        let required = match kind {
892            WriteKind::Insert => ACL_INSERT,
893            WriteKind::Update => ACL_UPDATE,
894            WriteKind::Delete => ACL_DELETE,
895            WriteKind::Merge => 0,
896        };
897        self.target_perm = Some(self.add_perm(oid, required));
898        // `view_has_instead_trigger`: a `MERGE` with only `DO NOTHING` needs no trigger, and it reads the view as a view with triggers `INSTEAD OF` does.
899        let auto = rel.kind == RelKind::View
900            && !self.rule.rows
901            && !self.view_has_instead_trigger(oid, kind);
902        if !auto {
903            return Ok((oid, name, columns));
904        }
905        let view = self.auto_view(oid, &name, kind)?;
906        let base = view.base_oid();
907        let rel = self.env.catalog().and_then(|c| c.relation(base));
908        let rel = rel.ok_or_else(|| Error::internal("an updatable view with no base relation"))?;
909        let columns = write_columns(rel);
910        let name = rel.name.clone();
911        self.auto_view = Some(view);
912        Ok((base, name, columns))
913    }
914
915    /// True when the table has a trigger of the user that fires in the default mode and whose type has all the bits `bits`, such as `TRIGGER_ROW | TRIGGER_BEFORE | TRIGGER_INSERT`. With no bits, any such trigger counts.
916    pub(crate) fn user_triggers(&self, table: u32, bits: i16) -> bool {
917        let Some(catalog) = self.env.catalog() else { return false };
918        catalog.triggers().any(|t| user_trigger(t, table) && t.kind & bits == bits)
919    }
920
921    /// True when the target of the write is a view, which only a view with a trigger `INSTEAD OF` for the event can be.
922    pub(crate) fn is_view(&self, table: u32) -> bool {
923        crate::ddl::relkind(self.env, table) == b'v'
924    }
925
926    /// [`Write::inherit`] for the target of an `UPDATE`, a `DELETE` or a `MERGE`, the relation 0: a table with children of `INHERITS` and no `ONLY`.
927    pub(crate) fn inherits_target(&self, kind: WriteKind) -> bool {
928        let Some(target) = self.scope.relations.first() else { return false };
929        matches!(kind, WriteKind::Update | WriteKind::Delete | WriteKind::Merge)
930            && !target.only
931            && crate::ddl::relkind(self.env, target.oid) == b'r'
932            && self.env.catalog().is_some_and(|c| !c.children(target.oid).is_empty())
933    }
934
935    /// True for a partitioned table. Its partitions check the rows of a write, and each row of the query of an `UPDATE` or a `DELETE` gives the OID of its partition before the ID of its version.
936    pub(crate) fn is_partitioned(&self, table: u32) -> bool {
937        crate::ddl::relkind(self.env, table) == b'p'
938    }
939
940    /// [`Write::recheck`] for a write of the table with a trigger `BEFORE ... FOR EACH ROW` for the event of `kind`, or `None`.
941    pub(crate) fn recheck(
942        &self,
943        table: u32,
944        kind: WriteKind,
945        name: &str,
946        columns: &[Column],
947        checks: &[(String, Expr)],
948        generated: &[Generated],
949    ) -> Option<Box<Query>> {
950        let bits = rupg_catalog::TRIGGER_ROW | rupg_catalog::TRIGGER_BEFORE | trigger_event(kind);
951        // The triggers of a partitioned table fire as their clones in the leaf partitions, which check the rows.
952        if self.is_partitioned(table) || !self.user_triggers(table, bits) {
953            return None;
954        }
955        let mut query =
956            with_checks(name, columns, Query::default(), checks.to_vec(), generated, &[]);
957        // The relation reads the row that the triggers give, not a subquery.
958        let mut relation = Relation::new(0, columns.to_vec(), None, None, None);
959        relation.name = name.to_string();
960        query.relations = vec![relation];
961        Some(Box::new(query))
962    }
963
964    /// The foreign keys that a write of the table checks after the statement, in the order of the names of their triggers, as `AfterTriggerSaveEvent` queues the triggers for each row.
965    pub(crate) fn foreign_keys(
966        &self,
967        table: u32,
968        kind: WriteKind,
969        columns: &[Column],
970    ) -> Result<Vec<Foreign>> {
971        let Some(catalog) = self.env.catalog() else {
972            return Ok(Vec::new());
973        };
974        // `AfterTriggerSaveEvent`: the leaf partitions fire the triggers of the rows. A partitioned table fires only the triggers of its referenced keys, for the update of a row that moves to another partition.
975        let partitioned = catalog.relation(table).is_some_and(|r| r.kind == RelKind::Partitioned);
976        if partitioned && kind != WriteKind::Update {
977            return Ok(Vec::new());
978        }
979        let mut triggers: Vec<_> = catalog
980            .triggers()
981            .filter(|t| t.relation == table && t.fires())
982            .filter_map(|t| {
983                let function = rupg_catalog::foreign_key_function(t.function)?;
984                let event = match function {
985                    0 => WriteKind::Insert,
986                    f if f % 2 == 1 => WriteKind::Update,
987                    _ => WriteKind::Delete,
988                };
989                (event == kind && !(partitioned && function < 2)).then_some((t, function))
990            })
991            .collect();
992        triggers.sort_by(|a, b| a.0.name.cmp(&b.0.name));
993        let mut list = Vec::with_capacity(triggers.len());
994        for (trigger, function) in triggers {
995            let constraint = catalog.constraint(trigger.constraint);
996            let Some((constraint, foreign)) =
997                constraint.and_then(|c| c.foreign.as_ref().map(|f| (c, f)))
998            else {
999                return Err(Error::internal("a trigger of a foreign key with no foreign key"));
1000            };
1001            let action = match function {
1002                2 | 3 => Action::Cascade,
1003                4 | 5 => Action::Restrict,
1004                6 | 7 => Action::SetNull,
1005                8 | 9 => Action::SetDefault,
1006                _ => Action::NoAction,
1007            };
1008            let referencing = function < 2;
1009            let (other, mine, theirs) = if referencing {
1010                (foreign.table, &constraint.keys, &foreign.keys)
1011            } else {
1012                (constraint.relation, &foreign.keys, &constraint.keys)
1013            };
1014            let Some(other_rel) = catalog.relation(other) else {
1015                return Err(Error::internal("a foreign key of a table that does not exist"));
1016            };
1017            let place = |attnum: i16| usize::try_from(attnum - 1).ok();
1018            let mut check = Foreign {
1019                name: constraint.name.clone(),
1020                referencing,
1021                action,
1022                query: String::new(),
1023                full: foreign.match_type == 'f',
1024                other,
1025                other_name: other_rel.name.clone(),
1026                columns: Vec::with_capacity(mine.len()),
1027                names: Vec::with_capacity(mine.len()),
1028                other_columns: Vec::with_capacity(mine.len()),
1029                types: Vec::with_capacity(mine.len()),
1030                referencing_types: Vec::with_capacity(mine.len()),
1031                constraint: constraint.oid,
1032                deferrable: trigger.deferrable,
1033                deferred: trigger.deferred,
1034                cloned: trigger.parent != 0,
1035            };
1036            for (&attnum, &other_attnum) in mine.iter().zip(theirs) {
1037                let column = place(attnum).and_then(|at| columns.get(at).map(|c| (at, c)));
1038                let other_column =
1039                    place(other_attnum).and_then(|at| other_rel.columns.get(at).map(|c| (at, c)));
1040                let (Some((at, column)), Some((other_at, other_column))) = (column, other_column)
1041                else {
1042                    return Err(Error::internal("a foreign key with a key that is not a column"));
1043                };
1044                check.columns.push(at);
1045                check.names.push(column.name.clone());
1046                check.other_columns.push(other_at);
1047                let (key, referencing_key) = if referencing {
1048                    (other_column.ty, column.ty)
1049                } else {
1050                    (column.ty, other_column.ty)
1051                };
1052                check.types.push(key);
1053                check.referencing_types.push(referencing_key);
1054            }
1055            if matches!(action, Action::Cascade | Action::SetNull | Action::SetDefault) {
1056                let names: Vec<&str> = check
1057                    .other_columns
1058                    .iter()
1059                    .map(|&at| other_rel.columns[at].name.as_str())
1060                    .collect();
1061                let schema = match catalog.schema(other_rel.namespace) {
1062                    Some(schema) => schema.name.clone(),
1063                    None => builtin::named_by_oid(Named::Namespace, other_rel.namespace)
1064                        .map_or_else(String::new, |n| n.name.to_string()),
1065                };
1066                let table = format!("{}.{}", quote_one(&schema), quote_one(&other_rel.name));
1067                let only = other_rel.kind != RelKind::Partitioned;
1068                check.query = action_query((action, kind), (&table, only), &names, &check);
1069            }
1070            list.push(check);
1071        }
1072        Ok(list)
1073    }
1074
1075    /// The unique indexes of a table in the order of their OIDs. The index of a partitioned table has no storage: the indexes of the partitions check the rows, and it is an arbiter of `ON CONFLICT`. An index that is not ready, from a failed `CREATE INDEX CONCURRENTLY`, checks no row.
1076    pub(crate) fn unique_keys(&self, table: u32, columns: &[Column]) -> Result<Vec<Unique>> {
1077        let Some(catalog) = self.env.catalog() else {
1078            return Ok(Vec::new());
1079        };
1080        let mut indexes: Vec<_> = catalog
1081            .relations()
1082            .filter(|rel| matches!(rel.kind, RelKind::Index | RelKind::PartitionedIndex))
1083            .filter_map(|rel| {
1084                rel.index
1085                    .as_ref()
1086                    .filter(|info| info.table == table && info.unique && info.ready)
1087                    .map(|info| (rel, info))
1088            })
1089            .collect();
1090        indexes.sort_by_key(|(rel, _)| rel.oid);
1091        let mut list = Vec::with_capacity(indexes.len());
1092        for (rel, info) in indexes {
1093            let deferrable = if info.immediate {
1094                None
1095            } else {
1096                let constraint = catalog.constraints_of(table).find(|c| c.index == rel.oid);
1097                constraint.map(|c| Deferrable { constraint: c.oid, deferred: c.deferred })
1098            };
1099            let count = usize::try_from(info.key_count).unwrap_or_default();
1100            let mut key = Unique {
1101                oid: rel.oid,
1102                name: rel.name.clone(),
1103                columns: Vec::with_capacity(count),
1104                types: Vec::with_capacity(count),
1105                shown: String::new(),
1106                nulls_not_distinct: info.nulls_not_distinct,
1107                derived: None,
1108                deferrable,
1109            };
1110            if info.exprs.is_some() || info.predicate.is_some() {
1111                let mut exprs = match &info.exprs {
1112                    Some(text) => crate::node::read_list(text)?,
1113                    None => Vec::new(),
1114                }
1115                .into_iter();
1116                let mut derived = Derived {
1117                    table,
1118                    types: columns.iter().map(|c| c.ty).collect(),
1119                    exprs: Vec::with_capacity(count),
1120                    predicate: match &info.predicate {
1121                        Some(text) => match crate::node::read(text)? {
1122                            Expr { kind: ExprKind::Bool(BoolOp::And, parts), .. } => parts,
1123                            part => vec![part],
1124                        },
1125                        None => Vec::new(),
1126                    },
1127                };
1128                for (at, &attnum) in info.keys.iter().take(count).enumerate() {
1129                    let expr = if attnum == 0 {
1130                        exprs
1131                            .next()
1132                            .ok_or_else(|| Error::internal("too few entries in indexprs"))?
1133                    } else {
1134                        let column = usize::try_from(attnum - 1).ok().and_then(|c| columns.get(c));
1135                        let Some(column) = column else {
1136                            return Err(Error::internal(
1137                                "a unique index with a key that is not a column",
1138                            ));
1139                        };
1140                        let var = Var { relation: 0, attnum, levels_up: 0 };
1141                        Expr { typmod: column.typmod, ..Expr::new(ExprKind::Var(var), column.ty) }
1142                    };
1143                    key.columns.push(at);
1144                    key.types.push(expr.ty);
1145                    derived.exprs.push(expr);
1146                }
1147                key.derived = Some(Box::new(derived));
1148                list.push(key);
1149                continue;
1150            }
1151            for &attnum in info.keys.iter().take(count) {
1152                let column = usize::try_from(attnum - 1)
1153                    .ok()
1154                    .and_then(|at| columns.get(at).map(|c| (at, c)));
1155                let Some((at, column)) = column else {
1156                    return Err(Error::internal("a unique index with a key that is not a column"));
1157                };
1158                if !key.shown.is_empty() {
1159                    key.shown.push_str(", ");
1160                }
1161                key.shown.push_str(&crate::ddl::quote_identifier(&column.name));
1162                key.columns.push(at);
1163                key.types.push(column.ty);
1164            }
1165            list.push(key);
1166        }
1167        Ok(list)
1168    }
1169
1170    /// `checkInsertTargets`: the columns of the column list, or all the columns of the table when the statement has no list.
1171    pub(crate) fn insert_targets(
1172        &self,
1173        cols: &List,
1174        name: &str,
1175        columns: &[Column],
1176    ) -> Result<Vec<Given>> {
1177        if cols.is_empty() {
1178            return Ok((0..columns.len())
1179                .filter(|&i| !columns[i].is_dropped())
1180                .map(|i| (i, None, List::new()))
1181                .collect());
1182        }
1183        let mut given: Vec<Given> = Vec::with_capacity(cols.len());
1184        for col in cols {
1185            let Some(Node::ResTarget(rt)) = col else {
1186                return Err(Error::internal("an INSERT column that is not ResTarget"));
1187            };
1188            let at = place(rt.location);
1189            let col_name = rt.name.as_deref().unwrap_or_default();
1190            let Some(index) = columns.iter().position(|c| c.name == col_name) else {
1191                return Err(Error::new(
1192                    SqlState::UNDEFINED_COLUMN,
1193                    format!("column \"{col_name}\" of relation \"{name}\" does not exist"),
1194                )
1195                .at_opt(at));
1196            };
1197            // A column can have more than one item only when each item sets a part of the column.
1198            let part = !rt.indirection.is_empty();
1199            if given.iter().any(|(i, _, other)| *i == index && (!part || other.is_empty())) {
1200                return Err(Error::new(
1201                    SqlState::DUPLICATE_COLUMN,
1202                    format!("column \"{col_name}\" specified more than once"),
1203                )
1204                .at_opt(at));
1205            }
1206            given.push((index, at, rt.indirection.clone()));
1207        }
1208        Ok(given)
1209    }
1210
1211    /// `transformExpressionList` for a row of `VALUES` in an `INSERT`, which keeps `DEFAULT` at the top of an item.
1212    pub(crate) fn value_items(&mut self, list: &List, kind: Kind) -> Result<Vec<Item>> {
1213        let mut items = Vec::with_capacity(list.len());
1214        for node in list {
1215            if let Some(Node::SetToDefault(d)) = node {
1216                items.push(Item::Default(place(d.location)));
1217                continue;
1218            }
1219            items.push(Item::Expr(self.with_kind(kind, |a| a.transform(node.as_ref()))?));
1220        }
1221        Ok(items)
1222    }
1223
1224    /// `transformInsertRow`: the items of a row, each with the type of its column, and `DEFAULT` as the default of the column. An identity column gets its default for `OVERRIDING USER VALUE`, and a column that is `GENERATED ALWAYS` takes only `DEFAULT` without `OVERRIDING SYSTEM VALUE`.
1225    pub(crate) fn insert_row(
1226        &mut self,
1227        items: Vec<Item>,
1228        table: u32,
1229        columns: &[Column],
1230        given: &[Given],
1231        explicit: bool,
1232        overriding: OverridingKind,
1233    ) -> Result<Vec<Expr>> {
1234        if items.len() > given.len() {
1235            return Err(Error::new(
1236                SqlState::SYNTAX_ERROR,
1237                "INSERT has more expressions than target columns",
1238            )
1239            .at_opt(items[given.len()].place()));
1240        }
1241        if explicit && items.len() < given.len() {
1242            let mut error = Error::new(
1243                SqlState::SYNTAX_ERROR,
1244                "INSERT has more target columns than expressions",
1245            );
1246            if let [Item::Expr(expr)] = items.as_slice()
1247                && let ExprKind::Row(fields, _) = &expr.kind
1248                && fields.len() == given.len()
1249            {
1250                error = error.with_hint("The insertion source is a row expression containing the same number of columns expected by the INSERT. Did you accidentally use extra parentheses?");
1251            }
1252            return Err(error.at_opt(given[items.len()].1));
1253        }
1254        self.auto_view_given(items.len())?;
1255        let mut row = Vec::with_capacity(items.len());
1256        for (item, (index, at, indirection)) in items.into_iter().zip(given) {
1257            let (index, at) = (*index, *at);
1258            let column = &columns[index];
1259            // `rewriteTargetListIU`: the value of an identity column with `OVERRIDING`.
1260            let identity = self.identity(table, index);
1261            let item = match item {
1262                Item::Expr(_)
1263                    if identity != 0 && overriding == OverridingKind::OVERRIDING_USER_VALUE =>
1264                {
1265                    Item::Default(None)
1266                }
1267                Item::Expr(_)
1268                    if identity == b'a' && overriding == OverridingKind::OVERRIDING_NOT_SET =>
1269                {
1270                    return Err(Error::new(
1271                        SqlState::GENERATED_ALWAYS,
1272                        format!(
1273                            "cannot insert a non-DEFAULT value into column \"{}\"",
1274                            column.name
1275                        ),
1276                    )
1277                    .with_detail(format!(
1278                        "Column \"{}\" is an identity column defined as GENERATED ALWAYS.",
1279                        column.name
1280                    ))
1281                    .with_hint("Use OVERRIDING SYSTEM VALUE to override."));
1282                }
1283                Item::Expr(_) if self.generated(table, index) != 0 => {
1284                    return Err(Error::new(
1285                        SqlState::GENERATED_ALWAYS,
1286                        format!(
1287                            "cannot insert a non-DEFAULT value into column \"{}\"",
1288                            column.name
1289                        ),
1290                    )
1291                    .with_detail(format!("Column \"{}\" is a generated column.", column.name)));
1292                }
1293                item => item,
1294            };
1295            row.push(match item {
1296                Item::Default(_) if !indirection.is_empty() => {
1297                    return Err(default_part(indirection, at));
1298                }
1299                Item::Default(_) => self.column_default(table, index, column)?,
1300                Item::Expr(expr) if indirection.is_empty() => self.assign(expr, column)?,
1301                Item::Expr(expr) => self.assign_part(column, indirection, at, expr, None)?,
1302            });
1303        }
1304        Ok(row)
1305    }
1306
1307    /// `transformAssignedExpr` for a column with subscripts: the value of the column `old` with `expr` in the part that `indirection` names. With no `old`, as in `INSERT`, the old value is a null value of the type of the column.
1308    ///
1309    /// # Errors
1310    ///
1311    /// The errors of [`Analyzer::assignment_indirection`].
1312    pub(crate) fn assign_part(
1313        &mut self,
1314        column: &Column,
1315        indirection: &List,
1316        at: Option<usize>,
1317        expr: Expr,
1318        old: Option<Expr>,
1319    ) -> Result<Expr> {
1320        let base = old.unwrap_or_else(|| {
1321            let mut null = Expr::new(ExprKind::Const(Value::Null), column.ty);
1322            null.typmod = column.typmod;
1323            null
1324        });
1325        let target = (base, &column.name[..], (column.ty, column.typmod));
1326        self.assignment_indirection(target, indirection, expr, Context::Assignment, at)
1327    }
1328
1329    /// `attidentity` of the column of the table with the index `index` from 0, or 0 for a column that is not an identity column.
1330    pub(crate) fn identity(&self, table: u32, index: usize) -> u8 {
1331        let catalog = self.env.catalog();
1332        let relation = catalog.and_then(|c| c.relation(table));
1333        relation.and_then(|r| r.columns.get(index)).map_or(0, |c| c.identity)
1334    }
1335
1336    /// `attgenerated` of the column of the table with the index `index` from 0, or 0 for a column that is not generated.
1337    pub(crate) fn generated(&self, table: u32, index: usize) -> u8 {
1338        let catalog = self.env.catalog();
1339        let relation = catalog.and_then(|c| c.relation(table));
1340        relation.and_then(|r| r.columns.get(index)).map_or(0, |c| c.generated)
1341    }
1342
1343    /// The generated columns of the table, each with the index of the column from 0, its generation expression and `attgenerated`, as `ExecComputeStoredGenerated` computes them for a new row. The leaf partitions of a partitioned table compute their own columns.
1344    pub(crate) fn generated_columns(&mut self, table: u32) -> Result<Vec<Generated>> {
1345        let Some(catalog) = self.env.catalog() else { return Ok(Vec::new()) };
1346        let Some(relation) = catalog.relation(table) else { return Ok(Vec::new()) };
1347        if relation.kind == RelKind::Partitioned {
1348            return Ok(Vec::new());
1349        }
1350        let mut out = Vec::new();
1351        for (index, column) in relation.columns.iter().enumerate() {
1352            if column.generated == 0 || column.dropped {
1353                continue;
1354            }
1355            let attnum = i16::try_from(index + 1).unwrap_or(i16::MAX);
1356            if let Some(default) = catalog.default_of(table, attnum) {
1357                let mut expr: Expr = crate::node::read(&default.expr)?;
1358                // `ExecComputeStoredGenerated` sets `tts_tableOid` of the new row first, so `tableoid` is the table.
1359                expr.each_mut(0, &mut |e, depth| {
1360                    let ExprKind::Var(var) = e.kind else { return false };
1361                    if var.levels_up != depth || var.attnum != TABLE_OID_ATTNUM {
1362                        return false;
1363                    }
1364                    *e = Expr::constant(Value::Oid(table), oid::OID, -1, None);
1365                    true
1366                });
1367                self.note_funcs(&expr);
1368                out.push((index, expr, column.generated));
1369            }
1370        }
1371        Ok(out)
1372    }
1373
1374    /// `transformAssignedExpr`: the expression cast to the type of the column with an assignment cast.
1375    pub(crate) fn assign(&mut self, expr: Expr, column: &Column) -> Result<Expr> {
1376        let (from, at) = (expr.ty, expr.place());
1377        self.coerce_to_target(expr, column.ty, column.typmod, Context::Assignment, None)?
1378            .ok_or_else(|| {
1379                Error::new(
1380                    SqlState::DATATYPE_MISMATCH,
1381                    format!(
1382                        "column \"{}\" is of type {} but expression is of type {}",
1383                        column.name,
1384                        types::name(column.ty),
1385                        types::name(from)
1386                    ),
1387                )
1388                .with_hint("You will need to rewrite or cast the expression.")
1389                .at_opt(at)
1390            })
1391    }
1392
1393    /// `build_column_default`: the default of the column, or the default of its domain, cast to the type of the column. With no default, the value is a null value of the type, which a domain checks, as `coerce_null_to_domain` gives. The default of an identity column is the next value of its sequence, as `NextValueExpr` gives.
1394    pub(crate) fn column_default(
1395        &mut self,
1396        table: u32,
1397        index: usize,
1398        column: &Column,
1399    ) -> Result<Expr> {
1400        // A dropped column gets a null, as `ExecInitInsertProjection` gives it.
1401        if column.is_dropped() {
1402            return Ok(Expr::new(ExprKind::Const(Value::Null), 0));
1403        }
1404        // The write computes a generated column after the triggers `BEFORE`, which see a null.
1405        if self.generated(table, index) != 0 {
1406            // The default of a view is a value that the generated column of the table does not take.
1407            if self.auto_view_default(table, index).is_some() {
1408                return Err(Error::new(
1409                    SqlState::GENERATED_ALWAYS,
1410                    format!("cannot insert a non-DEFAULT value into column \"{}\"", column.name),
1411                )
1412                .with_detail(format!("Column \"{}\" is a generated column.", column.name)));
1413            }
1414            let mut null = Expr::new(ExprKind::Const(Value::Null), column.ty);
1415            null.typmod = column.typmod;
1416            return Ok(null);
1417        }
1418        let attnum = i16::try_from(index + 1).unwrap_or(i16::MAX);
1419        // A view of an automatically updatable view can have its own default for the column, which `rewriteTargetListIU` of the view gives.
1420        let view_default = self.auto_view_default(table, index);
1421        let sequence = self.env.catalog().and_then(|c| c.root_identity_sequence(table, attnum));
1422        if view_default.is_none()
1423            && self.identity(table, index) != 0
1424            && let Some(sequence) = sequence
1425        {
1426            let mut expr = nextval(sequence)?;
1427            // `NextValueExpr` does not check the privileges of the sequence.
1428            if let ExprKind::Func(func) = &mut expr.kind {
1429                func.args.push(Expr::constant(Value::Bool(true), oid::BOOL, -1, None));
1430            }
1431            return self
1432                .coerce_to_target(expr, column.ty, column.typmod, Context::Assignment, None)?
1433                .ok_or_else(|| {
1434                    Error::internal("an identity column of a type that is not an integer")
1435                });
1436        }
1437        let catalog = self.env.catalog();
1438        let (table, attnum) = view_default.unwrap_or((table, attnum));
1439        let text = catalog.and_then(|c| c.default_of(table, attnum)).map(|d| d.expr.clone());
1440        let text = text.or_else(|| {
1441            catalog
1442                .and_then(|c| c.type_by_oid(column.ty))
1443                .and_then(|ty| ty.domain.as_ref())
1444                .and_then(|d| d.default.clone())
1445        });
1446        let Some(text) = text else {
1447            let null = Expr::new(ExprKind::Const(Value::Null), oid::UNKNOWN);
1448            let mut expr = self
1449                .coerce_to_target(null, column.ty, column.typmod, Context::Assignment, None)?
1450                .unwrap_or_else(|| Expr::new(ExprKind::Const(Value::Null), column.ty));
1451            if let ExprKind::Const(_) = expr.kind {
1452                expr.typmod = column.typmod;
1453            }
1454            return Ok(expr);
1455        };
1456        let expr = crate::node::read(&text)?;
1457        self.note_funcs(&expr);
1458        let from = expr.ty;
1459        self.coerce_to_target(expr, column.ty, column.typmod, Context::Assignment, None)?
1460            .ok_or_else(|| {
1461                Error::new(
1462                    SqlState::DATATYPE_MISMATCH,
1463                    format!(
1464                        "column \"{}\" is of type {} but default expression is of type {}",
1465                        column.name,
1466                        types::name(column.ty),
1467                        types::name(from)
1468                    ),
1469                )
1470                .with_hint("You will need to rewrite or cast the expression.")
1471            })
1472    }
1473
1474    /// The row of the table: the expression of each column that the statement gives, and the default of each other column.
1475    pub(crate) fn full_row(
1476        &mut self,
1477        table: u32,
1478        columns: &[Column],
1479        given: &[Given],
1480        exprs: Vec<Expr>,
1481    ) -> Result<Vec<Expr>> {
1482        let mut slots: Vec<Option<Expr>> = vec![None; columns.len()];
1483        for (expr, &(index, _, _)) in exprs.into_iter().zip(given) {
1484            // `process_matched_tle`: the items that set parts of the same column make one value.
1485            slots[index] = Some(match slots[index].take() {
1486                Some(prior) => merge_parts(prior, expr, &columns[index].name)?,
1487                None => expr,
1488            });
1489        }
1490        let mut row = Vec::with_capacity(columns.len());
1491        for (index, slot) in slots.into_iter().enumerate() {
1492            row.push(match slot {
1493                Some(expr) => expr,
1494                None => self.column_default(table, index, &columns[index])?,
1495            });
1496        }
1497        Ok(row)
1498    }
1499
1500    /// `INSERT ... SELECT`: the query of the `SELECT` is a subquery, and the row reads its columns. A column of type `unknown` that is a constant or a parameter comes as it is, so that the cast to the type of the column can use its text.
1501    fn insert_select(
1502        &mut self,
1503        select: &SelectStmt,
1504        table: u32,
1505        columns: &[Column],
1506        given: &[Given],
1507        explicit: bool,
1508        overriding: OverridingKind,
1509    ) -> Result<Query> {
1510        self.keep_unknowns = true;
1511        let sub = self.sub_select(select, false);
1512        self.keep_unknowns = false;
1513        let sub = sub?;
1514        let shown: Vec<&Target> = sub.targets.iter().filter(|t| !t.junk).collect();
1515        let items: Vec<Item> = shown
1516            .iter()
1517            .enumerate()
1518            .map(|(i, t)| {
1519                let unknown = t.expr.ty == oid::UNKNOWN
1520                    && matches!(t.expr.kind, ExprKind::Const(_) | ExprKind::Param(_));
1521                if unknown {
1522                    return Item::Expr(t.expr.clone());
1523                }
1524                let attnum = i16::try_from(i + 1).unwrap_or(i16::MAX);
1525                let var = Var { relation: 0, attnum, levels_up: 0 };
1526                let mut expr = Expr::new(ExprKind::Var(var), t.expr.ty);
1527                expr.typmod = t.expr.typmod;
1528                expr.location = t.expr.place();
1529                Item::Expr(expr)
1530            })
1531            .collect();
1532        let sub_columns: Vec<Column> = shown
1533            .iter()
1534            .map(|t| Column {
1535                name: t.name.clone(),
1536                ty: t.expr.ty,
1537                typmod: t.expr.typmod,
1538                not_null: false,
1539            })
1540            .collect();
1541        let exprs = self.insert_row(items, table, columns, given, explicit, overriding)?;
1542        let row = self.full_row(table, columns, given, exprs)?;
1543        let mut relation = Relation::new(0, sub_columns, Some(Box::new(sub)), None, None);
1544        relation.name = "*SELECT*".to_string();
1545        Ok(Query {
1546            relations: vec![relation],
1547            from: vec![FromItem::Relation(0)],
1548            targets: targets(columns, row),
1549            ..Query::default()
1550        })
1551    }
1552
1553    /// `INSERT ... VALUES` with more than one row: each row gets the types of the columns, and the rows are a `VALUES` relation that the row reads.
1554    fn insert_values(
1555        &mut self,
1556        select: &SelectStmt,
1557        table: u32,
1558        columns: &[Column],
1559        given: &[Given],
1560        explicit: bool,
1561        overriding: OverridingKind,
1562    ) -> Result<Query> {
1563        let mut rows: Vec<Vec<Expr>> = Vec::with_capacity(select.valuesLists.len());
1564        let mut length = None;
1565        for list in &select.valuesLists {
1566            let Some(Node::List(list)) = list else {
1567                return Err(Error::internal("a VALUES row that is not a list"));
1568            };
1569            let items = self.value_items(list, Kind::Values)?;
1570            match length {
1571                None => length = Some(items.len()),
1572                Some(n) if n != items.len() => {
1573                    return Err(Error::new(
1574                        SqlState::SYNTAX_ERROR,
1575                        "VALUES lists must all be the same length",
1576                    )
1577                    .at_opt(first_place(&items)));
1578                }
1579                Some(_) => {}
1580            }
1581            let row = self.insert_row(items, table, columns, given, explicit, overriding)?;
1582            // `transformInsertRow` with `strip_indirection`: the row keeps the value of a part of a column, and the row of the table sets the part.
1583            let row = row
1584                .into_iter()
1585                .zip(given)
1586                .map(
1587                    |(expr, (_, _, indirection))| {
1588                        if indirection.is_empty() { expr } else { strip_part(expr) }
1589                    },
1590                )
1591                .collect();
1592            rows.push(row);
1593        }
1594        let width = rows.first().map_or(0, Vec::len);
1595        let value_columns: Vec<Column> = given
1596            .iter()
1597            .take(width)
1598            .enumerate()
1599            .map(|(i, (index, _, indirection))| {
1600                let (ty, typmod) = match rows.first().and_then(|row| row.get(i)) {
1601                    Some(expr) if !indirection.is_empty() => (expr.ty, expr.typmod),
1602                    _ => (columns[*index].ty, columns[*index].typmod),
1603                };
1604                Column { name: format!("column{}", i + 1), ty, typmod, not_null: false }
1605            })
1606            .collect();
1607        let mut exprs = Vec::with_capacity(value_columns.len());
1608        for (i, (c, (index, at, indirection))) in value_columns.iter().zip(given).enumerate() {
1609            let attnum = i16::try_from(i + 1).unwrap_or(i16::MAX);
1610            let mut expr =
1611                Expr::new(ExprKind::Var(Var { relation: 0, attnum, levels_up: 0 }), c.ty);
1612            expr.typmod = c.typmod;
1613            if !indirection.is_empty() {
1614                expr = self.assign_part(&columns[*index], indirection, *at, expr, None)?;
1615            }
1616            exprs.push(expr);
1617        }
1618        let row = self.full_row(table, columns, given, exprs)?;
1619        let mut relation = Relation::new(0, value_columns, None, None, Some(rows));
1620        relation.name = "*VALUES*".to_string();
1621        Ok(Query {
1622            relations: vec![relation],
1623            from: vec![FromItem::Relation(0)],
1624            targets: targets(columns, row),
1625            ..Query::default()
1626        })
1627    }
1628
1629    /// The check constraints of the table with their conditions, in the order of their names, as `CheckConstraintFetch` sorts them.
1630    pub(crate) fn checks(&mut self, table: u32) -> Result<Vec<(String, Expr)>> {
1631        let Some(catalog) = self.env.catalog() else { return Ok(Vec::new()) };
1632        let mut checks: Vec<(String, &str)> = catalog
1633            .constraints_of(table)
1634            .filter(|c| c.kind == ConKind::Check && c.enforced)
1635            .map(|c| (c.name.clone(), c.expr.as_deref().unwrap_or_default()))
1636            .collect();
1637        checks.sort_by(|a, b| a.0.cmp(&b.0));
1638        let checks: Vec<(String, Expr)> = checks
1639            .into_iter()
1640            .map(|(name, text)| Ok((name, crate::node::read(text)?)))
1641            .collect::<Result<_>>()?;
1642        for (_, expr) in &checks {
1643            self.note_funcs(expr);
1644        }
1645        Ok(checks)
1646    }
1647}
1648
1649/// The default of a `serial` column or of an identity column before the cast to the type of the column: `nextval('sequence'::regclass)`.
1650pub(crate) fn nextval(sequence: u32) -> Result<Expr> {
1651    let proc = builtin::procs_named("nextval")
1652        .next()
1653        .ok_or_else(|| Error::internal("function nextval does not exist"))?;
1654    let arg = Expr::constant(Value::Oid(sequence), oid::REGCLASS, -1, None);
1655    let func = Func {
1656        oid: proc.oid,
1657        args: vec![arg],
1658        form: FuncForm::Call,
1659        variadic: false,
1660        retset: false,
1661    };
1662    Ok(Expr::new(ExprKind::Func(func), proc.rettype))
1663}
1664
1665/// `isGeneralSelect`: a source that is not a plain `VALUES` list runs as a subquery.
1666fn general_select(s: &SelectStmt) -> bool {
1667    s.valuesLists.is_empty()
1668        || !s.sortClause.is_empty()
1669        || s.limitOffset.is_some()
1670        || s.limitCount.is_some()
1671        || !s.lockingClause.is_empty()
1672        || s.withClause.is_some()
1673}
1674
1675/// The targets of the row, with the names of the columns.
1676pub(crate) fn targets(columns: &[Column], row: Vec<Expr>) -> Vec<Target> {
1677    columns
1678        .iter()
1679        .zip(row)
1680        .map(|(c, expr)| Target { name: c.name.clone(), expr, origin: None, junk: false })
1681        .collect()
1682}
1683
1684/// The query of a row with no `FROM`.
1685fn row_query(columns: &[Column], row: Vec<Expr>) -> Query {
1686    Query { targets: targets(columns, row), ..Query::default() }
1687}
1688
1689/// The arbiters of `ON CONFLICT` that the analysis finds, which the planner matches with the unique indexes.
1690enum Inference {
1691    /// No inference: all the unique indexes.
1692    All,
1693    /// The set of the columns of an inference, from 0, in order, the expressions of the inference, the parts of its predicate, and the elements with a collation or an operator class.
1694    Columns { columns: Vec<usize>, exprs: Vec<Expr>, predicate: Vec<Expr>, exact: Vec<ExactElem> },
1695    /// The OID of the index of the constraint that `ON CONSTRAINT` names, or 0 for a constraint with no index.
1696    Constraint(u32),
1697}
1698
1699/// An element of an inference with a collation or an operator class, `InferenceElem` with `infercollid` or `inferopclass`.
1700struct ExactElem {
1701    target: Exact,
1702    /// The collation, or 0.
1703    collation: u32,
1704    /// The operator family and the input type of the operator class.
1705    class: Option<(u32, u32)>,
1706}
1707
1708/// The column or the expression of an [`ExactElem`].
1709#[derive(Clone, Copy)]
1710enum Exact {
1711    /// The column number in the table.
1712    Column(i16),
1713    /// The place of the expression in the expressions of the inference.
1714    Expr(usize),
1715}
1716
1717/// `infer_collation_opclass_match`: true when a key column of the index is the element with its collation and the family and the input type of its operator class.
1718fn exact_match(
1719    elem: &ExactElem,
1720    exprs: &[Expr],
1721    key: &Unique,
1722    catalog: Option<&rupg_catalog::Catalog>,
1723) -> bool {
1724    let info = catalog.and_then(|c| c.relation(key.oid)).and_then(|rel| rel.index.as_ref());
1725    let Some(info) = info else { return false };
1726    let count = usize::try_from(info.key_count).unwrap_or_default();
1727    for (natt, &attno) in info.keys.iter().take(count).enumerate() {
1728        if let Some(class) = elem.class {
1729            let oid = info.classes.get(natt).copied().unwrap_or_default();
1730            let user = catalog.and_then(|c| c.opclass(oid)).map(|c| (c.family, c.intype));
1731            let found = user.or_else(|| {
1732                builtin::opclasses().iter().find(|c| c.oid == oid).map(|c| (c.family, c.intype))
1733            });
1734            if found != Some(class) {
1735                continue;
1736            }
1737        }
1738        if elem.collation != 0 && info.collations.get(natt) != Some(&elem.collation) {
1739            continue;
1740        }
1741        match elem.target {
1742            Exact::Column(attnum) if attno == attnum => return true,
1743            Exact::Expr(at) if attno == 0 => {
1744                let indexed = key.derived.as_ref().and_then(|d| d.exprs.get(natt));
1745                if indexed.is_some_and(|i| exprs.get(at).is_some_and(|e| e.same(i))) {
1746                    return true;
1747                }
1748            }
1749            _ => {}
1750        }
1751    }
1752    false
1753}
1754
1755/// `infer_arbiter_indexes`: the places in `unique` of the arbiter indexes. An inference takes each unique index whose key has the same set of columns.
1756fn arbiters(
1757    inference: Inference,
1758    unique: &[Unique],
1759    catalog: Option<&rupg_catalog::Catalog>,
1760) -> Result<Vec<usize>> {
1761    let places: Vec<usize> = match inference {
1762        Inference::All => return Ok((0..unique.len()).collect()),
1763        Inference::Constraint(0) => {
1764            return Err(Error::new(
1765                SqlState::WRONG_OBJECT_TYPE,
1766                "constraint in ON CONFLICT clause has no associated index",
1767            ));
1768        }
1769        Inference::Constraint(index) => {
1770            let places: Vec<usize> = unique
1771                .iter()
1772                .enumerate()
1773                .filter(|(_, key)| key.oid == index)
1774                .map(|(at, _)| at)
1775                .collect();
1776            if places.is_empty() {
1777                return Err(not_yet("an exclusion constraint in ON CONFLICT"));
1778            }
1779            return Ok(places);
1780        }
1781        Inference::Columns { columns: set, exprs, predicate, exact } => unique
1782            .iter()
1783            .enumerate()
1784            .filter(|(_, key)| exact.iter().all(|e| exact_match(e, &exprs, key, catalog)))
1785            .filter(|(_, key)| {
1786                let Some(derived) = &key.derived else {
1787                    let mut key = key.columns.clone();
1788                    key.sort_unstable();
1789                    key.dedup();
1790                    return key == set && exprs.is_empty();
1791                };
1792                // The columns of the key must be the columns of the inference, and each expression of the key must be an expression of the inference and the other way around.
1793                let mut columns = Vec::new();
1794                let mut indexed = Vec::new();
1795                for expr in &derived.exprs {
1796                    match expr.kind {
1797                        ExprKind::Var(var) => columns.extend(usize::try_from(var.attnum - 1).ok()),
1798                        _ => indexed.push(expr),
1799                    }
1800                }
1801                columns.sort_unstable();
1802                columns.dedup();
1803                // `predicate_implied_by`: each part of the predicate of the index is a part of the predicate of the inference.
1804                // An expression with a collation or an operator class matched in `exact_match`.
1805                let checked =
1806                    |at: usize| exact.iter().any(|e| matches!(e.target, Exact::Expr(x) if x == at));
1807                columns == set
1808                    && exprs
1809                        .iter()
1810                        .enumerate()
1811                        .all(|(at, e)| checked(at) || indexed.iter().any(|i| i.same(e)))
1812                    && indexed.iter().all(|i| exprs.iter().any(|e| e.same(i)))
1813                    && derived.predicate.iter().all(|p| predicate.iter().any(|e| e.same(p)))
1814            })
1815            .map(|(at, _)| at)
1816            .collect(),
1817    };
1818    if places.is_empty() {
1819        return Err(Error::new(
1820            SqlState::INVALID_COLUMN_REFERENCE,
1821            "there is no unique or exclusion constraint matching the ON CONFLICT specification",
1822        ));
1823    }
1824    Ok(places)
1825}
1826
1827/// The columns of the target table of a write. A dropped column keeps its place with no name and the type 0, and each new row has a null for it.
1828pub(crate) fn write_columns(rel: &rupg_catalog::Relation) -> Vec<Column> {
1829    rel.columns
1830        .iter()
1831        .map(|c| Column {
1832            name: if c.dropped { String::new() } else { c.name.clone() },
1833            ty: c.ty,
1834            typmod: c.typmod,
1835            not_null: c.not_null && !c.not_null_invalid,
1836        })
1837        .collect()
1838}
1839
1840/// True for a trigger of the table `table` that the user made and that fires in the default mode. The session checks the foreign keys itself, and a disabled trigger and a trigger for the replica mode do not fire.
1841fn user_trigger(t: &rupg_catalog::Trigger, table: u32) -> bool {
1842    t.relation == table && !t.internal && t.fires()
1843}
1844
1845/// The bit of `tgtype` for the event of a write.
1846pub(crate) fn trigger_event(kind: WriteKind) -> i16 {
1847    match kind {
1848        WriteKind::Insert => rupg_catalog::TRIGGER_INSERT,
1849        WriteKind::Update => rupg_catalog::TRIGGER_UPDATE,
1850        WriteKind::Delete => rupg_catalog::TRIGGER_DELETE,
1851        WriteKind::Merge => {
1852            rupg_catalog::TRIGGER_INSERT
1853                | rupg_catalog::TRIGGER_UPDATE
1854                | rupg_catalog::TRIGGER_DELETE
1855        }
1856    }
1857}
1858
1859/// The query that reads the rows of `rows` as a subquery with the name of the table, and gives the columns and then the condition of each check constraint. The values of `tail` come after the columns in each row of `rows`, and after the conditions in each row of the query, as the carried values of `RETURNING` and the ID of the version of the old row of an `UPDATE`. A stored generated column of `generated` gets the value of its generation expression on the row, as `ExecComputeStoredGenerated` gives it before `ExecConstraints`, and the checks see that value.
1860pub(crate) fn with_checks(
1861    name: &str,
1862    columns: &[Column],
1863    rows: Query,
1864    checks: Vec<(String, Expr)>,
1865    generated: &[Generated],
1866    tail: &[Column],
1867) -> Query {
1868    let width = columns.len();
1869    let mut columns = columns.to_vec();
1870    columns.extend_from_slice(tail);
1871    let mut targets: Vec<Target> = columns
1872        .iter()
1873        .enumerate()
1874        .map(|(i, c)| {
1875            let attnum = i16::try_from(i + 1).unwrap_or(i16::MAX);
1876            let mut expr =
1877                Expr::new(ExprKind::Var(Var { relation: 0, attnum, levels_up: 0 }), c.ty);
1878            expr.typmod = c.typmod;
1879            Target { name: c.name.clone(), expr, origin: None, junk: false }
1880        })
1881        .collect();
1882    let tail = targets.split_off(width);
1883    // A virtual generated column keeps its null, and a read of the row computes it.
1884    for (index, expr, kind) in generated {
1885        if *kind == b's'
1886            && let Some(target) = targets.get_mut(*index)
1887        {
1888            target.expr = expr.clone();
1889        }
1890    }
1891    targets.extend(checks.into_iter().map(|(n, mut expr)| {
1892        compute_generated(&mut expr, generated, &columns[..width]);
1893        Target { name: n, expr, origin: None, junk: false }
1894    }));
1895    targets.extend(tail);
1896    let mut relation = Relation::new(0, columns, Some(Box::new(rows)), None, None);
1897    relation.name = name.to_string();
1898    Query {
1899        relations: vec![relation],
1900        from: vec![FromItem::Relation(0)],
1901        targets,
1902        ..Query::default()
1903    }
1904}
1905
1906/// The expression with the generation expression of each stored generated column of `generated` in place of the column of the relation 0. The whole row of the relation 0 becomes a `RowExpr` of the `columns`, with the generation expressions in it.
1907fn compute_generated(expr: &mut Expr, generated: &[Generated], columns: &[Column]) {
1908    if generated.is_empty() {
1909        return;
1910    }
1911    expr.each_mut(0, &mut |e, depth| {
1912        let ExprKind::Var(var) = e.kind else { return false };
1913        if var.levels_up != depth || var.relation != 0 {
1914            return false;
1915        }
1916        if var.attnum == 0 {
1917            // A dropped column has no field.
1918            let fields = columns.iter().enumerate().filter(|(_, c)| c.ty != 0);
1919            let fields = fields
1920                .map(|(i, c)| match generated.iter().find(|(at, ..)| *at == i) {
1921                    Some((_, value, _)) => {
1922                        let mut value = value.clone();
1923                        value.raise(depth);
1924                        value
1925                    }
1926                    None => {
1927                        let attnum = i16::try_from(i + 1).unwrap_or(i16::MAX);
1928                        let var = Var { relation: 0, attnum, levels_up: depth };
1929                        let mut field = Expr::new(ExprKind::Var(var), c.ty);
1930                        field.typmod = c.typmod;
1931                        field
1932                    }
1933                })
1934                .collect();
1935            e.kind = ExprKind::Row(fields, CastForm::Implicit);
1936            return true;
1937        }
1938        let index = usize::try_from(var.attnum).ok().and_then(|n| n.checked_sub(1));
1939        let Some((_, value, _)) = generated.iter().find(|(i, ..)| Some(*i) == index) else {
1940            return false;
1941        };
1942        let mut value = value.clone();
1943        value.raise(depth);
1944        *e = value;
1945        true
1946    });
1947}
1948
1949/// The error of `DEFAULT` for a part of a column, which has no default.
1950pub(crate) fn default_part(indirection: &List, at: Option<usize>) -> Error {
1951    let what = match indirection.first() {
1952        Some(Some(Node::A_Indices(_))) => "an array element",
1953        _ => "a subfield",
1954    };
1955    Error::new(SqlState::FEATURE_NOT_SUPPORTED, format!("cannot set {what} to DEFAULT")).at_opt(at)
1956}
1957
1958/// The value that an assignment to a part of a column sets, without the assignments of each level.
1959fn strip_part(expr: Expr) -> Expr {
1960    match expr.kind {
1961        ExprKind::CoerceToDomain(arg, _) => strip_part(*arg),
1962        ExprKind::Subscript(sub) if sub.assign.is_some() => {
1963            sub.assign.map_or_else(|| Expr::new(ExprKind::Const(Value::Null), 0), strip_part)
1964        }
1965        ExprKind::FieldStore(store) if store.fields.len() == 1 => {
1966            store.fields.into_iter().next().map_or_else(
1967                || Expr::new(ExprKind::Const(Value::Null), 0),
1968                |(_, value)| strip_part(value),
1969            )
1970        }
1971        _ => expr,
1972    }
1973}
1974
1975/// Whether the value is an assignment to a part of a column.
1976fn is_part(expr: &Expr) -> bool {
1977    match &expr.kind {
1978        ExprKind::Subscript(sub) => sub.assign.is_some(),
1979        ExprKind::FieldStore(_) => true,
1980        _ => false,
1981    }
1982}
1983
1984/// `process_matched_tle`: two assignments to parts of the same column as one assignment, in which `prior` gives the old value for `src`. When both check the same domain, the domain checks the value after both.
1985///
1986/// # Errors
1987///
1988/// `multiple assignments to same column` when one of the two sets the whole column.
1989pub(crate) fn merge_parts(prior: Expr, mut src: Expr, name: &str) -> Result<Expr> {
1990    let domain = |e: &Expr| matches!(e.kind, ExprKind::CoerceToDomain(..));
1991    if prior.ty == src.ty && domain(&prior) && domain(&src) {
1992        let (ExprKind::CoerceToDomain(prior, _), ExprKind::CoerceToDomain(arg, _)) =
1993            (prior.kind, &mut src.kind)
1994        else {
1995            return Err(Error::internal("an assignment to a domain that is not CoerceToDomain"));
1996        };
1997        let inner = std::mem::replace(&mut **arg, Expr::new(ExprKind::Const(Value::Null), 0));
1998        **arg = merge_parts(*prior, inner, name)?;
1999        return Ok(src);
2000    }
2001    if prior.ty != src.ty || !is_part(&prior) || !is_part(&src) {
2002        return Err(Error::new(
2003            SqlState::SYNTAX_ERROR,
2004            format!("multiple assignments to same column \"{name}\""),
2005        ));
2006    }
2007    match (&mut src.kind, prior.kind) {
2008        // Two assignments to fields are one `FieldStore` with the fields of both.
2009        (ExprKind::FieldStore(store), ExprKind::FieldStore(old)) => {
2010            let FieldStore { arg, mut fields, .. } = *old;
2011            fields.append(&mut store.fields);
2012            store.fields = fields;
2013            store.arg = arg;
2014        }
2015        (ExprKind::FieldStore(store), kind) => store.arg = Expr { kind, ..prior },
2016        (ExprKind::Subscript(sub), kind) => sub.container = Expr { kind, ..prior },
2017        _ => {}
2018    }
2019    Ok(src)
2020}