@@ -32,11 +32,11 @@ use sqlparser_derive::{Visit, VisitMut};
32
32
pub use super :: ddl:: { ColumnDef , TableConstraint } ;
33
33
34
34
use super :: {
35
- display_comma_separated, display_separated, ClusteredBy , CommentDef , Expr , FileFormat ,
36
- FromTable , HiveDistributionStyle , HiveFormat , HiveIOFormat , HiveRowFormat , Ident ,
37
- InsertAliases , MysqlInsertPriority , ObjectName , OnCommit , OnInsert , OneOrManyWithParens ,
38
- OrderByExpr , Query , RowAccessPolicy , SelectItem , SqlOption , SqliteOnConflict , TableEngine ,
39
- TableWithJoins , Tag , WrappedCollection ,
35
+ display_comma_separated, display_separated, query :: InputFormatClause , Assignment , ClusteredBy ,
36
+ CommentDef , Expr , FileFormat , FromTable , HiveDistributionStyle , HiveFormat , HiveIOFormat ,
37
+ HiveRowFormat , Ident , InsertAliases , MysqlInsertPriority , ObjectName , OnCommit , OnInsert ,
38
+ OneOrManyWithParens , OrderByExpr , Query , RowAccessPolicy , SelectItem , Setting , SqlOption ,
39
+ SqliteOnConflict , TableEngine , TableObject , TableWithJoins , Tag , WrappedCollection ,
40
40
} ;
41
41
42
42
/// CREATE INDEX statement.
@@ -470,8 +470,7 @@ pub struct Insert {
470
470
/// INTO - optional keyword
471
471
pub into : bool ,
472
472
/// TABLE
473
- #[ cfg_attr( feature = "visitor" , visit( with = "visit_relation" ) ) ]
474
- pub table_name : ObjectName ,
473
+ pub table : TableObject ,
475
474
/// table_name as foo (for PostgreSQL)
476
475
pub table_alias : Option < Ident > ,
477
476
/// COLUMNS
@@ -480,12 +479,15 @@ pub struct Insert {
480
479
pub overwrite : bool ,
481
480
/// A SQL query that specifies what to insert
482
481
pub source : Option < Box < Query > > ,
482
+ /// MySQL `INSERT INTO ... SET`
483
+ /// See: <https://dev.mysql.com/doc/refman/8.4/en/insert.html>
484
+ pub assignments : Vec < Assignment > ,
483
485
/// partitioned insert (Hive)
484
486
pub partitioned : Option < Vec < Expr > > ,
485
487
/// Columns defined after PARTITION
486
488
pub after_columns : Vec < Ident > ,
487
489
/// whether the insert has the table keyword (Hive)
488
- pub table : bool ,
490
+ pub has_table_keyword : bool ,
489
491
pub on : Option < OnInsert > ,
490
492
/// RETURNING
491
493
pub returning : Option < Vec < SelectItem > > ,
@@ -495,14 +497,27 @@ pub struct Insert {
495
497
pub priority : Option < MysqlInsertPriority > ,
496
498
/// Only for mysql
497
499
pub insert_alias : Option < InsertAliases > ,
500
+ /// Settings used for ClickHouse.
501
+ ///
502
+ /// ClickHouse syntax: `INSERT INTO tbl SETTINGS format_template_resultset = '/some/path/resultset.format'`
503
+ ///
504
+ /// [ClickHouse `INSERT INTO`](https://clickhouse.com/docs/en/sql-reference/statements/insert-into)
505
+ pub settings : Option < Vec < Setting > > ,
506
+ /// Format for `INSERT` statement when not using standard SQL format. Can be e.g. `CSV`,
507
+ /// `JSON`, `JSONAsString`, `LineAsString` and more.
508
+ ///
509
+ /// ClickHouse syntax: `INSERT INTO tbl FORMAT JSONEachRow {"foo": 1, "bar": 2}, {"foo": 3}`
510
+ ///
511
+ /// [ClickHouse formats JSON insert](https://clickhouse.com/docs/en/interfaces/formats#json-inserting-data)
512
+ pub format_clause : Option < InputFormatClause > ,
498
513
}
499
514
500
515
impl Display for Insert {
501
516
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
502
517
let table_name = if let Some ( alias) = & self . table_alias {
503
- format ! ( "{0} AS {alias}" , self . table_name )
518
+ format ! ( "{0} AS {alias}" , self . table )
504
519
} else {
505
- self . table_name . to_string ( )
520
+ self . table . to_string ( )
506
521
} ;
507
522
508
523
if let Some ( on_conflict) = self . or {
@@ -528,7 +543,7 @@ impl Display for Insert {
528
543
ignore = if self . ignore { " IGNORE" } else { "" } ,
529
544
over = if self . overwrite { " OVERWRITE" } else { "" } ,
530
545
int = if self . into { " INTO" } else { "" } ,
531
- tbl = if self . table { " TABLE" } else { "" } ,
546
+ tbl = if self . has_table_keyword { " TABLE" } else { "" } ,
532
547
) ?;
533
548
}
534
549
if !self . columns . is_empty ( ) {
@@ -543,11 +558,18 @@ impl Display for Insert {
543
558
write ! ( f, "({}) " , display_comma_separated( & self . after_columns) ) ?;
544
559
}
545
560
546
- if let Some ( source ) = & self . source {
547
- write ! ( f, "{source}" ) ?;
561
+ if let Some ( settings ) = & self . settings {
562
+ write ! ( f, "SETTINGS {} " , display_comma_separated ( settings ) ) ?;
548
563
}
549
564
550
- if self . source . is_none ( ) && self . columns . is_empty ( ) {
565
+ if let Some ( source) = & self . source {
566
+ write ! ( f, "{source}" ) ?;
567
+ } else if !self . assignments . is_empty ( ) {
568
+ write ! ( f, "SET " ) ?;
569
+ write ! ( f, "{}" , display_comma_separated( & self . assignments) ) ?;
570
+ } else if let Some ( format_clause) = & self . format_clause {
571
+ write ! ( f, "{format_clause}" ) ?;
572
+ } else if self . columns . is_empty ( ) {
551
573
write ! ( f, "DEFAULT VALUES" ) ?;
552
574
}
553
575
0 commit comments