surrealdb_sql/statements/
relate.rs1use surrealdb_types::{SqlFormat, ToSql, write_sql};
2
3use crate::{CoverStmts, Data, Expr, Literal, Output, RecordIdKeyLit, RecordIdLit};
4
5#[derive(Clone, Debug, PartialEq, Eq)]
6#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
7pub struct RelateStatement {
8 pub only: bool,
9 pub or_update: bool,
11 pub through: Expr,
13 pub from: Expr,
15 pub to: Expr,
17 pub data: Option<Data>,
19 pub output: Option<Output>,
21 pub timeout: Expr,
23}
24
25impl ToSql for RelateStatement {
26 fn fmt_sql(&self, f: &mut String, fmt: SqlFormat) {
27 write_sql!(f, fmt, "RELATE");
28 if self.only {
29 write_sql!(f, fmt, " ONLY");
30 }
31 if self.or_update {
32 write_sql!(f, fmt, " OR UPDATE");
33 }
34 write_sql!(f, fmt, " ");
35
36 if matches!(
39 self.from,
40 Expr::Literal(
41 Literal::Array(_)
42 | Literal::RecordId(RecordIdLit {
43 key: RecordIdKeyLit::Number(_)
44 | RecordIdKeyLit::String(_)
45 | RecordIdKeyLit::Generate(_)
46 | RecordIdKeyLit::Array(_)
47 | RecordIdKeyLit::Object(_)
48 | RecordIdKeyLit::Uuid(_),
49 ..
50 })
51 ) | Expr::Param(_)
52 ) {
53 self.from.fmt_sql(f, fmt);
54 } else {
55 write_sql!(f, fmt, "(");
56 self.from.fmt_sql(f, fmt);
57 write_sql!(f, fmt, ")");
58 }
59 write_sql!(f, fmt, " -> ");
60
61 if matches!(self.through, Expr::Param(_) | Expr::Table(_)) {
62 self.through.fmt_sql(f, fmt);
63 } else {
64 write_sql!(f, fmt, "(");
65 self.through.fmt_sql(f, fmt);
66 write_sql!(f, fmt, ")");
67 }
68
69 write_sql!(f, fmt, " -> ");
70
71 if matches!(
74 self.to,
75 Expr::Literal(
76 Literal::Array(_)
77 | Literal::RecordId(RecordIdLit {
78 key: RecordIdKeyLit::Number(_)
79 | RecordIdKeyLit::String(_)
80 | RecordIdKeyLit::Generate(_)
81 | RecordIdKeyLit::Array(_)
82 | RecordIdKeyLit::Object(_)
83 | RecordIdKeyLit::Uuid(_),
84 ..
85 })
86 ) | Expr::Param(_)
87 ) {
88 self.to.fmt_sql(f, fmt);
89 } else {
90 write_sql!(f, fmt, "(");
91 self.to.fmt_sql(f, fmt);
92 write_sql!(f, fmt, ")");
93 }
94
95 if let Some(ref v) = self.data {
96 write_sql!(f, fmt, " {v}");
97 }
98 if let Some(ref v) = self.output {
99 write_sql!(f, fmt, " {v}");
100 }
101 if !matches!(self.timeout, Expr::Literal(Literal::None)) {
102 write_sql!(f, fmt, " TIMEOUT {}", CoverStmts(&self.timeout));
103 }
104 }
105}