Skip to content

Commit d4d6a20

Browse files
Merge branch 'main' into statement-structs
2 parents 7782556 + e7d42f3 commit d4d6a20

File tree

13 files changed

+762
-483
lines changed

13 files changed

+762
-483
lines changed

.asf.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,7 @@ github:
5050
- "test (beta)"
5151
- "test (nightly)"
5252
- "Release Audit Tool (RAT)"
53+
pull_requests:
54+
# enable updating head branches of pull requests
55+
allow_update_branch: true
56+
allow_auto_merge: true

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ serde = { version = "1.0", default-features = false, features = ["derive", "allo
5454
# of dev-dependencies because of
5555
# https://github.com/rust-lang/cargo/issues/1596
5656
serde_json = { version = "1.0", optional = true }
57-
sqlparser_derive = { version = "0.3.0", path = "derive", optional = true }
57+
sqlparser_derive = { version = "0.4.0", path = "derive", optional = true }
5858

5959
[dev-dependencies]
6060
simple_logger = "5.0"

derive/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
[package]
1919
name = "sqlparser_derive"
2020
description = "Procedural (proc) macros for sqlparser"
21-
version = "0.3.0"
21+
version = "0.4.0"
2222
authors = ["sqlparser-rs authors"]
2323
homepage = "https://github.com/sqlparser-rs/sqlparser-rs"
2424
documentation = "https://docs.rs/sqlparser_derive/"

src/ast/ddl.rs

Lines changed: 13 additions & 291 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ use crate::ast::{
3737
HiveDistributionStyle, HiveFormat, HiveIOFormat, HiveRowFormat, HiveSetLocation, Ident,
3838
InitializeKind, MySQLColumnPosition, ObjectName, OnCommit, OneOrManyWithParens,
3939
OperateFunctionArg, OrderByExpr, ProjectionSelect, Query, RefreshModeKind, RowAccessPolicy,
40-
SequenceOptions, Spanned, SqlOption, StorageSerializationPolicy, TableVersion, Tag,
41-
TriggerEvent, TriggerExecBody, TriggerObject, TriggerPeriod, TriggerReferencing, Value,
40+
SequenceOptions, Spanned, SqlOption, StorageSerializationPolicy, TableConstraint, TableVersion,
41+
Tag, TriggerEvent, TriggerExecBody, TriggerObject, TriggerPeriod, TriggerReferencing, Value,
4242
ValueWithSpan, WrappedCollection,
4343
};
4444
use crate::display_utils::{DisplayCommaSeparated, Indent, NewLine, SpaceOrNewline};
@@ -1030,291 +1030,6 @@ impl fmt::Display for AlterColumnOperation {
10301030
}
10311031
}
10321032

1033-
/// A table-level constraint, specified in a `CREATE TABLE` or an
1034-
/// `ALTER TABLE ADD <constraint>` statement.
1035-
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
1036-
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
1037-
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
1038-
pub enum TableConstraint {
1039-
/// MySQL [definition][1] for `UNIQUE` constraints statements:\
1040-
/// * `[CONSTRAINT [<name>]] UNIQUE <index_type_display> [<index_name>] [index_type] (<columns>) <index_options>`
1041-
///
1042-
/// where:
1043-
/// * [index_type][2] is `USING {BTREE | HASH}`
1044-
/// * [index_options][3] is `{index_type | COMMENT 'string' | ... %currently unsupported stmts% } ...`
1045-
/// * [index_type_display][4] is `[INDEX | KEY]`
1046-
///
1047-
/// [1]: https://dev.mysql.com/doc/refman/8.3/en/create-table.html
1048-
/// [2]: IndexType
1049-
/// [3]: IndexOption
1050-
/// [4]: KeyOrIndexDisplay
1051-
Unique {
1052-
/// Constraint name.
1053-
///
1054-
/// Can be not the same as `index_name`
1055-
name: Option<Ident>,
1056-
/// Index name
1057-
index_name: Option<Ident>,
1058-
/// Whether the type is followed by the keyword `KEY`, `INDEX`, or no keyword at all.
1059-
index_type_display: KeyOrIndexDisplay,
1060-
/// Optional `USING` of [index type][1] statement before columns.
1061-
///
1062-
/// [1]: IndexType
1063-
index_type: Option<IndexType>,
1064-
/// Identifiers of the columns that are unique.
1065-
columns: Vec<IndexColumn>,
1066-
index_options: Vec<IndexOption>,
1067-
characteristics: Option<ConstraintCharacteristics>,
1068-
/// Optional Postgres nulls handling: `[ NULLS [ NOT ] DISTINCT ]`
1069-
nulls_distinct: NullsDistinctOption,
1070-
},
1071-
/// MySQL [definition][1] for `PRIMARY KEY` constraints statements:\
1072-
/// * `[CONSTRAINT [<name>]] PRIMARY KEY [index_name] [index_type] (<columns>) <index_options>`
1073-
///
1074-
/// Actually the specification have no `[index_name]` but the next query will complete successfully:
1075-
/// ```sql
1076-
/// CREATE TABLE unspec_table (
1077-
/// xid INT NOT NULL,
1078-
/// CONSTRAINT p_name PRIMARY KEY index_name USING BTREE (xid)
1079-
/// );
1080-
/// ```
1081-
///
1082-
/// where:
1083-
/// * [index_type][2] is `USING {BTREE | HASH}`
1084-
/// * [index_options][3] is `{index_type | COMMENT 'string' | ... %currently unsupported stmts% } ...`
1085-
///
1086-
/// [1]: https://dev.mysql.com/doc/refman/8.3/en/create-table.html
1087-
/// [2]: IndexType
1088-
/// [3]: IndexOption
1089-
PrimaryKey {
1090-
/// Constraint name.
1091-
///
1092-
/// Can be not the same as `index_name`
1093-
name: Option<Ident>,
1094-
/// Index name
1095-
index_name: Option<Ident>,
1096-
/// Optional `USING` of [index type][1] statement before columns.
1097-
///
1098-
/// [1]: IndexType
1099-
index_type: Option<IndexType>,
1100-
/// Identifiers of the columns that form the primary key.
1101-
columns: Vec<IndexColumn>,
1102-
index_options: Vec<IndexOption>,
1103-
characteristics: Option<ConstraintCharacteristics>,
1104-
},
1105-
/// A referential integrity constraint (`[ CONSTRAINT <name> ] FOREIGN KEY (<columns>)
1106-
/// REFERENCES <foreign_table> (<referred_columns>)
1107-
/// { [ON DELETE <referential_action>] [ON UPDATE <referential_action>] |
1108-
/// [ON UPDATE <referential_action>] [ON DELETE <referential_action>]
1109-
/// }`).
1110-
ForeignKey {
1111-
name: Option<Ident>,
1112-
/// MySQL-specific field
1113-
/// <https://dev.mysql.com/doc/refman/8.4/en/create-table-foreign-keys.html>
1114-
index_name: Option<Ident>,
1115-
columns: Vec<Ident>,
1116-
foreign_table: ObjectName,
1117-
referred_columns: Vec<Ident>,
1118-
on_delete: Option<ReferentialAction>,
1119-
on_update: Option<ReferentialAction>,
1120-
characteristics: Option<ConstraintCharacteristics>,
1121-
},
1122-
/// `[ CONSTRAINT <name> ] CHECK (<expr>) [[NOT] ENFORCED]`
1123-
Check {
1124-
name: Option<Ident>,
1125-
expr: Box<Expr>,
1126-
/// MySQL-specific syntax
1127-
/// <https://dev.mysql.com/doc/refman/8.4/en/create-table.html>
1128-
enforced: Option<bool>,
1129-
},
1130-
/// MySQLs [index definition][1] for index creation. Not present on ANSI so, for now, the usage
1131-
/// is restricted to MySQL, as no other dialects that support this syntax were found.
1132-
///
1133-
/// `{INDEX | KEY} [index_name] [index_type] (key_part,...) [index_option]...`
1134-
///
1135-
/// [1]: https://dev.mysql.com/doc/refman/8.0/en/create-table.html
1136-
Index {
1137-
/// Whether this index starts with KEY (true) or INDEX (false), to maintain the same syntax.
1138-
display_as_key: bool,
1139-
/// Index name.
1140-
name: Option<Ident>,
1141-
/// Optional [index type][1].
1142-
///
1143-
/// [1]: IndexType
1144-
index_type: Option<IndexType>,
1145-
/// Referred column identifier list.
1146-
columns: Vec<IndexColumn>,
1147-
/// Optional index options such as `USING`; see [`IndexOption`].
1148-
index_options: Vec<IndexOption>,
1149-
},
1150-
/// MySQLs [fulltext][1] definition. Since the [`SPATIAL`][2] definition is exactly the same,
1151-
/// and MySQL displays both the same way, it is part of this definition as well.
1152-
///
1153-
/// Supported syntax:
1154-
///
1155-
/// ```markdown
1156-
/// {FULLTEXT | SPATIAL} [INDEX | KEY] [index_name] (key_part,...)
1157-
///
1158-
/// key_part: col_name
1159-
/// ```
1160-
///
1161-
/// [1]: https://dev.mysql.com/doc/refman/8.0/en/fulltext-natural-language.html
1162-
/// [2]: https://dev.mysql.com/doc/refman/8.0/en/spatial-types.html
1163-
FulltextOrSpatial {
1164-
/// Whether this is a `FULLTEXT` (true) or `SPATIAL` (false) definition.
1165-
fulltext: bool,
1166-
/// Whether the type is followed by the keyword `KEY`, `INDEX`, or no keyword at all.
1167-
index_type_display: KeyOrIndexDisplay,
1168-
/// Optional index name.
1169-
opt_index_name: Option<Ident>,
1170-
/// Referred column identifier list.
1171-
columns: Vec<IndexColumn>,
1172-
},
1173-
}
1174-
1175-
impl fmt::Display for TableConstraint {
1176-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1177-
match self {
1178-
TableConstraint::Unique {
1179-
name,
1180-
index_name,
1181-
index_type_display,
1182-
index_type,
1183-
columns,
1184-
index_options,
1185-
characteristics,
1186-
nulls_distinct,
1187-
} => {
1188-
write!(
1189-
f,
1190-
"{}UNIQUE{nulls_distinct}{index_type_display:>}{}{} ({})",
1191-
display_constraint_name(name),
1192-
display_option_spaced(index_name),
1193-
display_option(" USING ", "", index_type),
1194-
display_comma_separated(columns),
1195-
)?;
1196-
1197-
if !index_options.is_empty() {
1198-
write!(f, " {}", display_separated(index_options, " "))?;
1199-
}
1200-
1201-
write!(f, "{}", display_option_spaced(characteristics))?;
1202-
Ok(())
1203-
}
1204-
TableConstraint::PrimaryKey {
1205-
name,
1206-
index_name,
1207-
index_type,
1208-
columns,
1209-
index_options,
1210-
characteristics,
1211-
} => {
1212-
write!(
1213-
f,
1214-
"{}PRIMARY KEY{}{} ({})",
1215-
display_constraint_name(name),
1216-
display_option_spaced(index_name),
1217-
display_option(" USING ", "", index_type),
1218-
display_comma_separated(columns),
1219-
)?;
1220-
1221-
if !index_options.is_empty() {
1222-
write!(f, " {}", display_separated(index_options, " "))?;
1223-
}
1224-
1225-
write!(f, "{}", display_option_spaced(characteristics))?;
1226-
Ok(())
1227-
}
1228-
TableConstraint::ForeignKey {
1229-
name,
1230-
index_name,
1231-
columns,
1232-
foreign_table,
1233-
referred_columns,
1234-
on_delete,
1235-
on_update,
1236-
characteristics,
1237-
} => {
1238-
write!(
1239-
f,
1240-
"{}FOREIGN KEY{} ({}) REFERENCES {}",
1241-
display_constraint_name(name),
1242-
display_option_spaced(index_name),
1243-
display_comma_separated(columns),
1244-
foreign_table,
1245-
)?;
1246-
if !referred_columns.is_empty() {
1247-
write!(f, "({})", display_comma_separated(referred_columns))?;
1248-
}
1249-
if let Some(action) = on_delete {
1250-
write!(f, " ON DELETE {action}")?;
1251-
}
1252-
if let Some(action) = on_update {
1253-
write!(f, " ON UPDATE {action}")?;
1254-
}
1255-
if let Some(characteristics) = characteristics {
1256-
write!(f, " {characteristics}")?;
1257-
}
1258-
Ok(())
1259-
}
1260-
TableConstraint::Check {
1261-
name,
1262-
expr,
1263-
enforced,
1264-
} => {
1265-
write!(f, "{}CHECK ({})", display_constraint_name(name), expr)?;
1266-
if let Some(b) = enforced {
1267-
write!(f, " {}", if *b { "ENFORCED" } else { "NOT ENFORCED" })
1268-
} else {
1269-
Ok(())
1270-
}
1271-
}
1272-
TableConstraint::Index {
1273-
display_as_key,
1274-
name,
1275-
index_type,
1276-
columns,
1277-
index_options,
1278-
} => {
1279-
write!(f, "{}", if *display_as_key { "KEY" } else { "INDEX" })?;
1280-
if let Some(name) = name {
1281-
write!(f, " {name}")?;
1282-
}
1283-
if let Some(index_type) = index_type {
1284-
write!(f, " USING {index_type}")?;
1285-
}
1286-
write!(f, " ({})", display_comma_separated(columns))?;
1287-
if !index_options.is_empty() {
1288-
write!(f, " {}", display_comma_separated(index_options))?;
1289-
}
1290-
Ok(())
1291-
}
1292-
Self::FulltextOrSpatial {
1293-
fulltext,
1294-
index_type_display,
1295-
opt_index_name,
1296-
columns,
1297-
} => {
1298-
if *fulltext {
1299-
write!(f, "FULLTEXT")?;
1300-
} else {
1301-
write!(f, "SPATIAL")?;
1302-
}
1303-
1304-
write!(f, "{index_type_display:>}")?;
1305-
1306-
if let Some(name) = opt_index_name {
1307-
write!(f, " {name}")?;
1308-
}
1309-
1310-
write!(f, " ({})", display_comma_separated(columns))?;
1311-
1312-
Ok(())
1313-
}
1314-
}
1315-
}
1316-
}
1317-
13181033
/// Representation whether a definition can can contains the KEY or INDEX keywords with the same
13191034
/// meaning.
13201035
///
@@ -1459,12 +1174,19 @@ pub struct ProcedureParam {
14591174
pub name: Ident,
14601175
pub data_type: DataType,
14611176
pub mode: Option<ArgMode>,
1177+
pub default: Option<Expr>,
14621178
}
14631179

14641180
impl fmt::Display for ProcedureParam {
14651181
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
14661182
if let Some(mode) = &self.mode {
1467-
write!(f, "{mode} {} {}", self.name, self.data_type)
1183+
if let Some(default) = &self.default {
1184+
write!(f, "{mode} {} {} = {}", self.name, self.data_type, default)
1185+
} else {
1186+
write!(f, "{mode} {} {}", self.name, self.data_type)
1187+
}
1188+
} else if let Some(default) = &self.default {
1189+
write!(f, "{} {} = {}", self.name, self.data_type, default)
14681190
} else {
14691191
write!(f, "{} {}", self.name, self.data_type)
14701192
}
@@ -2066,7 +1788,7 @@ pub enum GeneratedExpressionMode {
20661788
}
20671789

20681790
#[must_use]
2069-
fn display_constraint_name(name: &'_ Option<Ident>) -> impl fmt::Display + '_ {
1791+
pub(crate) fn display_constraint_name(name: &'_ Option<Ident>) -> impl fmt::Display + '_ {
20701792
struct ConstraintName<'a>(&'a Option<Ident>);
20711793
impl fmt::Display for ConstraintName<'_> {
20721794
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -2083,7 +1805,7 @@ fn display_constraint_name(name: &'_ Option<Ident>) -> impl fmt::Display + '_ {
20831805
/// * `Some(inner)` => create display struct for `"{prefix}{inner}{postfix}"`
20841806
/// * `_` => do nothing
20851807
#[must_use]
2086-
fn display_option<'a, T: fmt::Display>(
1808+
pub(crate) fn display_option<'a, T: fmt::Display>(
20871809
prefix: &'a str,
20881810
postfix: &'a str,
20891811
option: &'a Option<T>,
@@ -2105,7 +1827,7 @@ fn display_option<'a, T: fmt::Display>(
21051827
/// * `Some(inner)` => create display struct for `" {inner}"`
21061828
/// * `_` => do nothing
21071829
#[must_use]
2108-
fn display_option_spaced<T: fmt::Display>(option: &Option<T>) -> impl fmt::Display + '_ {
1830+
pub(crate) fn display_option_spaced<T: fmt::Display>(option: &Option<T>) -> impl fmt::Display + '_ {
21091831
display_option(" ", "", option)
21101832
}
21111833

0 commit comments

Comments
 (0)