1use crabka_pgtypes::{ColumnType, Datum};
4
5#[rustfmt::skip]
6#[derive(Debug, Clone, PartialEq)]
7pub enum Statement {
8 CompatibilityRefusal(RefusalCommand),
12 CreateTable {
13 name: String,
14 columns: Vec<ColumnDef>,
15 constraints: Vec<TableConstraint>,
16 sharded: bool,
17 sharding: Option<ShardingSpec>,
18 },
19 CreateIndex {
20 name: String,
21 table: String,
22 columns: Vec<String>,
23 unique: bool,
24 placement: IndexPlacement,
25 },
26 DropIndex {
27 name: String,
28 if_exists: bool,
29 },
30 CreateView {
31 name: String,
32 definition: String,
34 query: QueryExpr,
36 },
37 DropTable {
38 name: String,
39 },
40 DropView {
41 name: String,
42 if_exists: bool,
43 },
44 AlterTableRename {
48 table: String,
49 rename: AlterTableRename,
50 },
51 Insert {
52 table: String,
53 columns: Option<Vec<String>>,
54 rows: Vec<Vec<Expr>>,
55 returning: Option<Vec<SelectItem>>,
56 },
57 Query(QueryExpr),
58 Begin {
59 isolation: Option<IsolationLevel>,
60 },
61 Commit,
62 Rollback,
63 Update {
64 table: String,
65 assignments: Vec<(String, Expr)>,
66 filter: Option<Expr>,
67 returning: Option<Vec<SelectItem>>,
68 },
69 Delete {
70 table: String,
71 filter: Option<Expr>,
72 returning: Option<Vec<SelectItem>>,
73 },
74 Set {
76 local: bool,
77 name: String,
78 value: SetValue,
79 },
80 Show {
82 name: String,
83 },
84 Reset {
86 target: ResetTarget,
87 },
88 CreateRole {
89 name: String,
90 can_login: bool,
91 },
92 DropRole {
93 name: String,
94 },
95 GrantTablePrivileges {
96 privileges: Vec<String>,
97 table: String,
98 grantees: Vec<String>,
99 },
100 RevokeTablePrivileges {
101 privileges: Vec<String>,
102 table: String,
103 grantees: Vec<String>,
104 },
105 SetRole {
106 role: Option<String>,
107 },
108 CreateFdw {
111 name: String,
112 options: OptionList,
113 },
114 DropFdw {
116 name: String,
117 if_exists: bool,
118 },
119 CreateServer {
121 name: String,
122 wrapper: String,
123 options: OptionList,
124 },
125 AlterServer {
127 name: String,
128 options: OptionList,
129 },
130 DropServer {
132 name: String,
133 if_exists: bool,
134 },
135 CreateUserMapping {
137 user: String,
138 server: String,
139 options: OptionList,
140 },
141 AlterUserMapping {
143 user: String,
144 server: String,
145 options: OptionList,
146 },
147 DropUserMapping {
149 user: String,
150 server: String,
151 if_exists: bool,
152 },
153 CreateForeignTable {
155 name: String,
156 columns: Vec<ColumnDef>,
157 server: String,
158 options: OptionList,
159 },
160 DropForeignTable {
162 name: String,
163 if_exists: bool,
164 },
165 ImportForeignSchema {
167 remote_schema: String,
168 selector: ImportSelector,
169 server: String,
170 into_schema: String,
171 },
172}
173
174#[derive(Debug, Clone, Copy, PartialEq, Eq)]
176pub enum RefusalCommand {
177 AlterDatabase,
178 CreateDatabase,
179 DropDatabase,
180 AlterExtension,
181 DropExtension,
182 PrepareTransaction,
183 CommitPrepared,
184 RollbackPrepared,
185 AlterServer,
186 AlterUserMapping,
187 NonGoal(NonGoalCommand),
188}
189
190impl RefusalCommand {
191 #[must_use]
192 pub const fn command_name(self) -> &'static str {
193 match self {
194 Self::AlterDatabase => "ALTER DATABASE",
195 Self::CreateDatabase => "CREATE DATABASE",
196 Self::DropDatabase => "DROP DATABASE",
197 Self::AlterExtension => "ALTER EXTENSION",
198 Self::DropExtension => "DROP EXTENSION",
199 Self::PrepareTransaction => "PREPARE TRANSACTION",
200 Self::CommitPrepared => "COMMIT PREPARED",
201 Self::RollbackPrepared => "ROLLBACK PREPARED",
202 Self::AlterServer => "ALTER SERVER",
203 Self::AlterUserMapping => "ALTER USER MAPPING",
204 Self::NonGoal(command) => command.command_name(),
205 }
206 }
207
208 #[must_use]
209 pub const fn sqlstate(self) -> &'static str {
210 match self {
211 Self::PrepareTransaction | Self::CommitPrepared | Self::RollbackPrepared => "55000",
212 _ => "0A000",
213 }
214 }
215
216 #[must_use]
217 pub const fn message(self) -> &'static str {
218 match self {
219 Self::AlterDatabase | Self::CreateDatabase | Self::DropDatabase => {
220 "database lifecycle is managed by tenant provisioning"
221 }
222 Self::AlterExtension | Self::DropExtension => {
223 "extension lifecycle is not supported; use built-in compatibility shims"
224 }
225 Self::PrepareTransaction | Self::CommitPrepared | Self::RollbackPrepared => {
226 "SQL-level prepared transactions are not available"
227 }
228 Self::AlterServer => "ALTER SERVER is not supported",
229 Self::AlterUserMapping => "ALTER USER MAPPING is not supported",
230 Self::NonGoal(command) => command.message(),
231 }
232 }
233}
234
235impl Statement {
236 #[must_use]
238 pub const fn compatibility_refusal(&self) -> Option<RefusalCommand> {
239 match self {
240 Self::CompatibilityRefusal(command) => Some(*command),
241 Self::AlterServer { .. } => Some(RefusalCommand::AlterServer),
242 Self::AlterUserMapping { .. } => Some(RefusalCommand::AlterUserMapping),
243 _ => None,
244 }
245 }
246}
247
248#[derive(Debug, Clone, Copy, PartialEq, Eq)]
250pub enum NonGoalCommand {
251 AlterConversion,
252 AlterLanguage,
253 AlterLargeObject,
254 AlterOperator,
255 AlterOperatorClass,
256 AlterOperatorFamily,
257 AlterPublication,
258 AlterRule,
259 AlterSubscription,
260 AlterTablespace,
261 AlterTextSearchParser,
262 AlterTextSearchTemplate,
263 CreateAccessMethod,
264 CreateConversion,
265 CreateLanguage,
266 CreateOperator,
267 CreateOperatorClass,
268 CreateOperatorFamily,
269 CreatePublication,
270 CreateRule,
271 CreateSubscription,
272 CreateTablespace,
273 CreateTextSearchParser,
274 CreateTextSearchTemplate,
275 CreateTransform,
276 DropAccessMethod,
277 DropConversion,
278 DropLanguage,
279 DropOperator,
280 DropOperatorClass,
281 DropOperatorFamily,
282 DropPublication,
283 DropRule,
284 DropSubscription,
285 DropTablespace,
286 DropTextSearchParser,
287 DropTextSearchTemplate,
288 DropTransform,
289 Load,
290 SecurityLabel,
291}
292
293impl NonGoalCommand {
294 #[must_use]
295 pub const fn command_name(self) -> &'static str {
296 match self {
297 Self::AlterConversion => "ALTER CONVERSION",
298 Self::AlterLanguage => "ALTER LANGUAGE",
299 Self::AlterLargeObject => "ALTER LARGE OBJECT",
300 Self::AlterOperator => "ALTER OPERATOR",
301 Self::AlterOperatorClass => "ALTER OPERATOR CLASS",
302 Self::AlterOperatorFamily => "ALTER OPERATOR FAMILY",
303 Self::AlterPublication => "ALTER PUBLICATION",
304 Self::AlterRule => "ALTER RULE",
305 Self::AlterSubscription => "ALTER SUBSCRIPTION",
306 Self::AlterTablespace => "ALTER TABLESPACE",
307 Self::AlterTextSearchParser => "ALTER TEXT SEARCH PARSER",
308 Self::AlterTextSearchTemplate => "ALTER TEXT SEARCH TEMPLATE",
309 Self::CreateAccessMethod => "CREATE ACCESS METHOD",
310 Self::CreateConversion => "CREATE CONVERSION",
311 Self::CreateLanguage => "CREATE LANGUAGE",
312 Self::CreateOperator => "CREATE OPERATOR",
313 Self::CreateOperatorClass => "CREATE OPERATOR CLASS",
314 Self::CreateOperatorFamily => "CREATE OPERATOR FAMILY",
315 Self::CreatePublication => "CREATE PUBLICATION",
316 Self::CreateRule => "CREATE RULE",
317 Self::CreateSubscription => "CREATE SUBSCRIPTION",
318 Self::CreateTablespace => "CREATE TABLESPACE",
319 Self::CreateTextSearchParser => "CREATE TEXT SEARCH PARSER",
320 Self::CreateTextSearchTemplate => "CREATE TEXT SEARCH TEMPLATE",
321 Self::CreateTransform => "CREATE TRANSFORM",
322 Self::DropAccessMethod => "DROP ACCESS METHOD",
323 Self::DropConversion => "DROP CONVERSION",
324 Self::DropLanguage => "DROP LANGUAGE",
325 Self::DropOperator => "DROP OPERATOR",
326 Self::DropOperatorClass => "DROP OPERATOR CLASS",
327 Self::DropOperatorFamily => "DROP OPERATOR FAMILY",
328 Self::DropPublication => "DROP PUBLICATION",
329 Self::DropRule => "DROP RULE",
330 Self::DropSubscription => "DROP SUBSCRIPTION",
331 Self::DropTablespace => "DROP TABLESPACE",
332 Self::DropTextSearchParser => "DROP TEXT SEARCH PARSER",
333 Self::DropTextSearchTemplate => "DROP TEXT SEARCH TEMPLATE",
334 Self::DropTransform => "DROP TRANSFORM",
335 Self::Load => "LOAD",
336 Self::SecurityLabel => "SECURITY LABEL",
337 }
338 }
339
340 #[must_use]
341 pub const fn message(self) -> &'static str {
342 match self {
343 Self::AlterConversion | Self::CreateConversion | Self::DropConversion => {
344 "conversion objects are unavailable on the UTF-8-only server"
345 }
346 Self::AlterLanguage | Self::CreateLanguage | Self::DropLanguage => {
347 "only built-in procedural languages are available"
348 }
349 Self::AlterLargeObject => "large objects are unavailable; use bytea storage",
350 Self::AlterOperator
351 | Self::AlterOperatorClass
352 | Self::AlterOperatorFamily
353 | Self::CreateOperator
354 | Self::CreateOperatorClass
355 | Self::CreateOperatorFamily
356 | Self::DropOperator
357 | Self::DropOperatorClass
358 | Self::DropOperatorFamily => "C-bound operator objects are not supported",
359 Self::AlterPublication
360 | Self::AlterSubscription
361 | Self::CreatePublication
362 | Self::CreateSubscription
363 | Self::DropPublication
364 | Self::DropSubscription => "physical replication SQL is not supported",
365 Self::AlterRule | Self::CreateRule | Self::DropRule => {
366 "the legacy rewrite rule system is not supported"
367 }
368 Self::AlterTablespace | Self::CreateTablespace | Self::DropTablespace => {
369 "tablespaces are not part of the chapter storage model"
370 }
371 Self::AlterTextSearchParser
372 | Self::AlterTextSearchTemplate
373 | Self::CreateTextSearchParser
374 | Self::CreateTextSearchTemplate
375 | Self::DropTextSearchParser
376 | Self::DropTextSearchTemplate => "C-bound text search objects are not supported",
377 Self::CreateAccessMethod | Self::DropAccessMethod => {
378 "C-bound access methods are not supported"
379 }
380 Self::CreateTransform | Self::DropTransform => {
381 "C-bound transform objects are not supported"
382 }
383 Self::Load => "C-bound code loading is not supported",
384 Self::SecurityLabel => "C-bound security labels are not supported",
385 }
386 }
387}
388
389#[derive(Debug, Clone, Copy, PartialEq, Eq)]
391pub struct NonGoalRefusalSpec {
392 pub command: RefusalCommand,
393 pub identity: crate::command::CommandIdentity,
394 pub representative_sql: &'static str,
395}
396
397macro_rules! non_goal_specs {
398 ($(($variant:ident, $sql:literal)),+ $(,)?) => {
399 pub const NON_GOAL_REFUSALS: &[NonGoalRefusalSpec] = &[
400 $(NonGoalRefusalSpec {
401 command: RefusalCommand::NonGoal(NonGoalCommand::$variant),
402 identity: crate::command::CommandIdentity::$variant,
403 representative_sql: $sql,
404 }),+
405 ];
406 };
407}
408
409non_goal_specs!(
410 (AlterConversion, "ALTER CONVERSION conv RENAME TO conv2"),
411 (AlterLanguage, "ALTER LANGUAGE lang RENAME TO lang2"),
412 (AlterLargeObject, "ALTER LARGE OBJECT 1 OWNER TO postgres"),
413 (
414 AlterOperator,
415 "ALTER OPERATOR +(integer, integer) OWNER TO postgres"
416 ),
417 (
418 AlterOperatorClass,
419 "ALTER OPERATOR CLASS opc USING btree RENAME TO opc2"
420 ),
421 (
422 AlterOperatorFamily,
423 "ALTER OPERATOR FAMILY opf USING btree RENAME TO opf2"
424 ),
425 (AlterPublication, "ALTER PUBLICATION pub ADD TABLE t"),
426 (AlterRule, "ALTER RULE r ON t RENAME TO r2"),
427 (AlterSubscription, "ALTER SUBSCRIPTION sub DISABLE"),
428 (AlterTablespace, "ALTER TABLESPACE ts RENAME TO ts2"),
429 (
430 AlterTextSearchParser,
431 "ALTER TEXT SEARCH PARSER p RENAME TO p2"
432 ),
433 (
434 AlterTextSearchTemplate,
435 "ALTER TEXT SEARCH TEMPLATE t RENAME TO t2"
436 ),
437 (
438 CreateAccessMethod,
439 "CREATE ACCESS METHOD am TYPE INDEX HANDLER handler_fn"
440 ),
441 (
442 CreateConversion,
443 "CREATE CONVERSION conv FOR 'UTF8' TO 'LATIN1' FROM func"
444 ),
445 (CreateLanguage, "CREATE LANGUAGE lang"),
446 (
447 CreateOperator,
448 "CREATE OPERATOR === (FUNCTION = int4eq, LEFTARG = integer, RIGHTARG = integer)"
449 ),
450 (
451 CreateOperatorClass,
452 "CREATE OPERATOR CLASS opc FOR TYPE integer USING btree AS OPERATOR 1 < (integer, integer)"
453 ),
454 (
455 CreateOperatorFamily,
456 "CREATE OPERATOR FAMILY opf USING btree"
457 ),
458 (CreatePublication, "CREATE PUBLICATION pub"),
459 (
460 CreateRule,
461 "CREATE RULE r AS ON SELECT TO t DO INSTEAD NOTHING"
462 ),
463 (
464 CreateSubscription,
465 "CREATE SUBSCRIPTION sub CONNECTION 'host=x' PUBLICATION pub"
466 ),
467 (CreateTablespace, "CREATE TABLESPACE ts LOCATION '/tmp/ts'"),
468 (
469 CreateTextSearchParser,
470 "CREATE TEXT SEARCH PARSER p (START = f, GETTOKEN = f, END = f, LEXTYPES = f)"
471 ),
472 (
473 CreateTextSearchTemplate,
474 "CREATE TEXT SEARCH TEMPLATE t (LEXIZE = f)"
475 ),
476 (
477 CreateTransform,
478 "CREATE TRANSFORM FOR integer LANGUAGE sql (FROM SQL WITH FUNCTION f(integer), TO SQL WITH FUNCTION f(integer))"
479 ),
480 (DropAccessMethod, "DROP ACCESS METHOD am"),
481 (DropConversion, "DROP CONVERSION conv"),
482 (DropLanguage, "DROP LANGUAGE lang"),
483 (DropOperator, "DROP OPERATOR +(integer, integer)"),
484 (DropOperatorClass, "DROP OPERATOR CLASS opc USING btree"),
485 (DropOperatorFamily, "DROP OPERATOR FAMILY opf USING btree"),
486 (DropPublication, "DROP PUBLICATION pub"),
487 (DropRule, "DROP RULE r ON t"),
488 (DropSubscription, "DROP SUBSCRIPTION sub"),
489 (DropTablespace, "DROP TABLESPACE ts"),
490 (DropTextSearchParser, "DROP TEXT SEARCH PARSER p"),
491 (DropTextSearchTemplate, "DROP TEXT SEARCH TEMPLATE t"),
492 (DropTransform, "DROP TRANSFORM FOR integer LANGUAGE sql"),
493 (Load, "LOAD 'lib'"),
494 (SecurityLabel, "SECURITY LABEL ON TABLE t IS 'label'"),
495);
496
497#[derive(Debug, Clone, PartialEq, Eq)]
498pub enum AlterTableRename {
499 Table { new_name: String },
500 Column { column: String, new_name: String },
501}
502
503#[derive(Debug, Clone, PartialEq, Eq)]
504pub struct CopyStmt {
505 pub table: String,
506 pub columns: Option<Vec<String>>,
507 pub format: CopyFormat,
508}
509
510pub const COPY_FROM_STDIN_SENTINEL: &str = "__copy_from_stdin";
511
512#[derive(Debug, Clone, Copy, PartialEq, Eq)]
513pub enum CopyFormat {
514 Text,
515 Csv,
516}
517
518#[derive(Debug, Clone, PartialEq, Eq)]
519pub enum ResetTarget {
520 Name(String),
521 All,
522}
523
524#[derive(Debug, Clone, Copy, PartialEq, Eq)]
525pub enum IndexPlacement {
526 Local,
527 Global,
528}
529
530#[derive(Debug, Clone, PartialEq, Eq)]
531pub enum ShardingSpec {
532 Hash(HashShardingSpec),
533}
534
535#[derive(Debug, Clone, PartialEq, Eq)]
536pub struct HashShardingSpec {
537 pub columns: Vec<String>,
538 pub buckets: u32,
539 pub co_location_group: Option<String>,
540}
541
542pub type OptionList = Vec<(String, String)>;
544
545#[derive(Debug, Clone, PartialEq, Eq)]
547pub enum ImportSelector {
548 All,
550 LimitTo(Vec<String>),
552 Except(Vec<String>),
554}
555
556#[derive(Debug, Clone, PartialEq, Eq)]
560pub enum SetValue {
561 Default,
562 Value(String),
563}
564
565#[derive(Debug, Clone, Copy, PartialEq, Eq)]
567pub enum IsolationLevel {
568 ReadCommitted,
569 RepeatableRead,
570}
571
572#[derive(Debug, Clone, PartialEq)]
573pub struct ColumnDef {
574 pub name: String,
575 pub ty: ColumnType,
576 pub serial: Option<SerialKind>,
577 pub constraints: Vec<ColumnConstraint>,
578}
579
580#[derive(Debug, Clone, Copy, PartialEq, Eq)]
581pub enum SerialKind {
582 Serial,
583 BigSerial,
584}
585
586#[derive(Debug, Clone, PartialEq, Eq, Default)]
587pub struct SequenceOptions {
588 pub start: Option<i64>,
589 pub increment: Option<i64>,
590 pub min: Option<i64>,
591 pub max: Option<i64>,
592 pub cache: Option<i64>,
593 pub cycle: Option<bool>,
594}
595
596#[derive(Debug, Clone, PartialEq)]
597pub enum ColumnConstraint {
598 NotNull,
599 Default(Expr),
600 PrimaryKey,
601 Unique,
602 Check(Expr),
603}
604
605#[derive(Debug, Clone, PartialEq)]
606pub enum TableConstraint {
607 PrimaryKey(Vec<String>),
608 Unique(Vec<String>),
609 Check(Expr),
610}
611
612#[derive(Debug, Clone, Copy, PartialEq, Eq)]
613pub enum RowLockStrength {
614 ForUpdate,
615 ForShare,
616}
617
618#[derive(Debug, Clone, PartialEq)]
619pub struct SelectStmt {
620 pub projection: Vec<SelectItem>,
621 pub from: Vec<TableExpr>,
625 pub filter: Option<Expr>,
626 pub distinct: bool,
628 pub group_by: Vec<Expr>,
630 pub having: Option<Expr>,
632 pub order_by: Vec<OrderItem>,
633 pub limit: Option<i64>,
634 pub offset: Option<i64>,
636 pub locking: Option<RowLockStrength>,
637}
638
639#[derive(Debug, Clone, PartialEq)]
643pub struct QueryExpr {
644 pub with: Option<WithClause>,
645 pub body: SetExpr,
646 pub order_by: Vec<OrderItem>,
647 pub limit: Option<i64>,
648 pub offset: Option<i64>,
649 pub locking: Option<RowLockStrength>,
650}
651
652#[derive(Debug, Clone, PartialEq)]
655pub struct ValuesStmt {
656 pub rows: Vec<Vec<Expr>>,
657}
658
659#[derive(Debug, Clone, PartialEq)]
660pub struct WithClause {
661 pub recursive: bool,
662 pub ctes: Vec<Cte>,
663}
664
665#[derive(Debug, Clone, PartialEq)]
666pub struct Cte {
667 pub name: String,
668 pub columns: Option<Vec<String>>,
669 pub query: QueryExpr,
670}
671
672#[derive(Debug, Clone, PartialEq)]
674pub enum QueryBody {
675 Select(Box<SelectStmt>),
676 Values(ValuesStmt),
677 Nested(Box<QueryExpr>),
678}
679
680#[derive(Debug, Clone, PartialEq)]
684pub enum SetExpr {
685 Query(QueryBody),
686 SetOp {
687 op: SetOp,
688 all: bool,
691 left: Box<SetExpr>,
692 right: Box<SetExpr>,
693 },
694}
695
696#[derive(Debug, Clone, Copy, PartialEq, Eq)]
697pub enum SetOp {
698 Union,
699 Intersect,
700 Except,
701}
702
703#[derive(Debug, Clone, PartialEq)]
704pub enum SelectItem {
705 Wildcard,
706 QualifiedWildcard(String),
708 Expr {
709 expr: Expr,
710 alias: Option<String>,
711 },
712}
713
714#[derive(Debug, Clone, PartialEq)]
718pub enum TableExpr {
719 Table {
720 name: String,
721 alias: Option<String>,
722 },
723 Derived {
724 subquery: QueryExpr,
725 alias: String, columns: Option<Vec<String>>,
727 },
728 Join {
729 left: Box<TableExpr>,
730 right: Box<TableExpr>,
731 kind: JoinKind,
732 constraint: JoinConstraint,
733 },
734}
735
736#[derive(Debug, Clone, Copy, PartialEq, Eq)]
737pub enum JoinKind {
738 Inner,
739 Left,
740 Right,
741 Full,
742 Cross,
743}
744
745#[derive(Debug, Clone, PartialEq)]
746pub enum JoinConstraint {
747 On(Expr),
748 Using(Vec<String>),
749 Natural,
750 None, }
752
753#[derive(Debug, Clone, PartialEq)]
754pub struct OrderItem {
755 pub expr: Expr,
756 pub asc: bool,
757}
758
759#[derive(Debug, Clone, PartialEq)]
760pub enum Expr {
761 IntLiteral(String),
762 NumericLiteral(String),
766 StringLiteral(String),
767 BoolLiteral(bool),
768 NullLiteral,
769 Column {
772 table: Option<String>,
773 name: String,
774 },
775 Param(u32),
776 Default,
779 Unary {
780 op: UnaryOp,
781 expr: Box<Expr>,
782 },
783 Binary {
784 op: BinaryOp,
785 left: Box<Expr>,
786 right: Box<Expr>,
787 },
788 Func(FuncCall),
792 IsNull {
794 expr: Box<Expr>,
795 negated: bool,
796 },
797 InList {
799 expr: Box<Expr>,
800 list: Vec<Expr>,
801 negated: bool,
802 },
803 Between {
805 expr: Box<Expr>,
806 low: Box<Expr>,
807 high: Box<Expr>,
808 negated: bool,
809 },
810 Like {
813 expr: Box<Expr>,
814 pattern: Box<Expr>,
815 negated: bool,
816 case_insensitive: bool,
817 },
818 Case {
822 operand: Option<Box<Expr>>,
823 whens: Vec<(Expr, Expr)>,
824 else_result: Option<Box<Expr>>,
825 },
826 Cast {
830 expr: Box<Expr>,
831 ty: ColumnType,
832 },
833 ScalarSubquery(Box<QueryExpr>),
836 Exists(Box<QueryExpr>),
839 InSubquery {
841 expr: Box<Expr>,
842 subquery: Box<QueryExpr>,
843 negated: bool,
844 },
845 Quantified {
848 expr: Box<Expr>,
849 op: BinaryOp,
850 all: bool,
851 subquery: Box<QueryExpr>,
852 },
853 Const {
857 value: Datum,
858 ty: ColumnType,
859 },
860}
861
862#[derive(Debug, Clone, PartialEq)]
864pub struct FuncCall {
865 pub name: String,
866 pub distinct: bool,
868 pub args: FuncArgs,
869}
870
871#[derive(Debug, Clone, PartialEq)]
874pub enum FuncArgs {
875 Star,
876 Exprs(Vec<Expr>),
877}
878
879#[derive(Debug, Clone, Copy, PartialEq, Eq)]
880pub enum UnaryOp {
881 Not,
882 Neg,
883}
884
885#[derive(Debug, Clone, Copy, PartialEq, Eq)]
886pub enum BinaryOp {
887 Add,
888 Sub,
889 Mul,
890 Div,
891 Concat,
893 Eq,
894 Ne,
895 Lt,
896 Le,
897 Gt,
898 Ge,
899 And,
900 Or,
901}