Merge branch 'main' into solontsev/clickhouse-map-setting-support

This commit is contained in:
Sergey Olontsev 2025-06-28 05:22:26 +01:00
commit bfb5ba6477
No known key found for this signature in database
GPG key ID: 67DDC06CA52E8A39
27 changed files with 284 additions and 233 deletions

View file

@ -63,7 +63,7 @@ $ cargo run --example cli - [--dialectname]
};
let contents = if filename == "-" {
println!("Parsing from stdin using {:?}", dialect);
println!("Parsing from stdin using {dialect:?}");
let mut buf = Vec::new();
stdin()
.read_to_end(&mut buf)

View file

@ -45,25 +45,24 @@ fn basic_queries(c: &mut Criterion) {
let large_statement = {
let expressions = (0..1000)
.map(|n| format!("FN_{}(COL_{})", n, n))
.map(|n| format!("FN_{n}(COL_{n})"))
.collect::<Vec<_>>()
.join(", ");
let tables = (0..1000)
.map(|n| format!("TABLE_{}", n))
.map(|n| format!("TABLE_{n}"))
.collect::<Vec<_>>()
.join(" JOIN ");
let where_condition = (0..1000)
.map(|n| format!("COL_{} = {}", n, n))
.map(|n| format!("COL_{n} = {n}"))
.collect::<Vec<_>>()
.join(" OR ");
let order_condition = (0..1000)
.map(|n| format!("COL_{} DESC", n))
.map(|n| format!("COL_{n} DESC"))
.collect::<Vec<_>>()
.join(", ");
format!(
"SELECT {} FROM {} WHERE {} ORDER BY {}",
expressions, tables, where_condition, order_condition
"SELECT {expressions} FROM {tables} WHERE {where_condition} ORDER BY {order_condition}"
)
};

View file

@ -666,7 +666,7 @@ impl fmt::Display for DataType {
}
DataType::Enum(vals, bits) => {
match bits {
Some(bits) => write!(f, "ENUM{}", bits),
Some(bits) => write!(f, "ENUM{bits}"),
None => write!(f, "ENUM"),
}?;
write!(f, "(")?;
@ -714,16 +714,16 @@ impl fmt::Display for DataType {
}
// ClickHouse
DataType::Nullable(data_type) => {
write!(f, "Nullable({})", data_type)
write!(f, "Nullable({data_type})")
}
DataType::FixedString(character_length) => {
write!(f, "FixedString({})", character_length)
write!(f, "FixedString({character_length})")
}
DataType::LowCardinality(data_type) => {
write!(f, "LowCardinality({})", data_type)
write!(f, "LowCardinality({data_type})")
}
DataType::Map(key_data_type, value_data_type) => {
write!(f, "Map({}, {})", key_data_type, value_data_type)
write!(f, "Map({key_data_type}, {value_data_type})")
}
DataType::Tuple(fields) => {
write!(f, "Tuple({})", display_comma_separated(fields))
@ -745,7 +745,7 @@ impl fmt::Display for DataType {
DataType::NamedTable { name, columns } => {
write!(f, "{} TABLE ({})", name, display_comma_separated(columns))
}
DataType::GeometricType(kind) => write!(f, "{}", kind),
DataType::GeometricType(kind) => write!(f, "{kind}"),
DataType::TsVector => write!(f, "TSVECTOR"),
DataType::TsQuery => write!(f, "TSQUERY"),
}
@ -942,7 +942,7 @@ impl fmt::Display for CharacterLength {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
CharacterLength::IntegerLength { length, unit } => {
write!(f, "{}", length)?;
write!(f, "{length}")?;
if let Some(unit) = unit {
write!(f, " {unit}")?;
}
@ -997,7 +997,7 @@ impl fmt::Display for BinaryLength {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
BinaryLength::IntegerLength { length } => {
write!(f, "{}", length)?;
write!(f, "{length}")?;
}
BinaryLength::Max => {
write!(f, "MAX")?;

View file

@ -173,7 +173,7 @@ impl fmt::Display for AlterRoleOperation {
in_database,
} => {
if let Some(database_name) = in_database {
write!(f, "IN DATABASE {} ", database_name)?;
write!(f, "IN DATABASE {database_name} ")?;
}
match config_value {
@ -187,7 +187,7 @@ impl fmt::Display for AlterRoleOperation {
in_database,
} => {
if let Some(database_name) = in_database {
write!(f, "IN DATABASE {} ", database_name)?;
write!(f, "IN DATABASE {database_name} ")?;
}
match config_name {
@ -218,15 +218,15 @@ impl fmt::Display for Use {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("USE ")?;
match self {
Use::Catalog(name) => write!(f, "CATALOG {}", name),
Use::Schema(name) => write!(f, "SCHEMA {}", name),
Use::Database(name) => write!(f, "DATABASE {}", name),
Use::Warehouse(name) => write!(f, "WAREHOUSE {}", name),
Use::Role(name) => write!(f, "ROLE {}", name),
Use::Catalog(name) => write!(f, "CATALOG {name}"),
Use::Schema(name) => write!(f, "SCHEMA {name}"),
Use::Database(name) => write!(f, "DATABASE {name}"),
Use::Warehouse(name) => write!(f, "WAREHOUSE {name}"),
Use::Role(name) => write!(f, "ROLE {name}"),
Use::SecondaryRoles(secondary_roles) => {
write!(f, "SECONDARY ROLES {}", secondary_roles)
write!(f, "SECONDARY ROLES {secondary_roles}")
}
Use::Object(name) => write!(f, "{}", name),
Use::Object(name) => write!(f, "{name}"),
Use::Default => write!(f, "DEFAULT"),
}
}

View file

@ -57,7 +57,7 @@ impl fmt::Display for ReplicaIdentity {
ReplicaIdentity::None => f.write_str("NONE"),
ReplicaIdentity::Full => f.write_str("FULL"),
ReplicaIdentity::Default => f.write_str("DEFAULT"),
ReplicaIdentity::Index(idx) => write!(f, "USING INDEX {}", idx),
ReplicaIdentity::Index(idx) => write!(f, "USING INDEX {idx}"),
}
}
}
@ -450,7 +450,7 @@ pub enum Owner {
impl fmt::Display for Owner {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Owner::Ident(ident) => write!(f, "{}", ident),
Owner::Ident(ident) => write!(f, "{ident}"),
Owner::CurrentRole => write!(f, "CURRENT_ROLE"),
Owner::CurrentUser => write!(f, "CURRENT_USER"),
Owner::SessionUser => write!(f, "SESSION_USER"),
@ -525,7 +525,7 @@ impl fmt::Display for AlterTableOperation {
if *if_not_exists {
write!(f, " IF NOT EXISTS")?;
}
write!(f, " {} ({})", name, query)
write!(f, " {name} ({query})")
}
AlterTableOperation::Algorithm { equals, algorithm } => {
write!(
@ -540,7 +540,7 @@ impl fmt::Display for AlterTableOperation {
if *if_exists {
write!(f, " IF EXISTS")?;
}
write!(f, " {}", name)
write!(f, " {name}")
}
AlterTableOperation::MaterializeProjection {
if_exists,
@ -551,9 +551,9 @@ impl fmt::Display for AlterTableOperation {
if *if_exists {
write!(f, " IF EXISTS")?;
}
write!(f, " {}", name)?;
write!(f, " {name}")?;
if let Some(partition) = partition {
write!(f, " IN PARTITION {}", partition)?;
write!(f, " IN PARTITION {partition}")?;
}
Ok(())
}
@ -566,9 +566,9 @@ impl fmt::Display for AlterTableOperation {
if *if_exists {
write!(f, " IF EXISTS")?;
}
write!(f, " {}", name)?;
write!(f, " {name}")?;
if let Some(partition) = partition {
write!(f, " IN PARTITION {}", partition)?;
write!(f, " IN PARTITION {partition}")?;
}
Ok(())
}
@ -1168,7 +1168,7 @@ impl fmt::Display for TableConstraint {
write!(f, " ON UPDATE {action}")?;
}
if let Some(characteristics) = characteristics {
write!(f, " {}", characteristics)?;
write!(f, " {characteristics}")?;
}
Ok(())
}
@ -1308,7 +1308,7 @@ impl fmt::Display for IndexType {
Self::SPGiST => write!(f, "SPGIST"),
Self::BRIN => write!(f, "BRIN"),
Self::Bloom => write!(f, "BLOOM"),
Self::Custom(name) => write!(f, "{}", name),
Self::Custom(name) => write!(f, "{name}"),
}
}
}
@ -1450,7 +1450,7 @@ impl fmt::Display for ViewColumnDef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name)?;
if let Some(data_type) = self.data_type.as_ref() {
write!(f, " {}", data_type)?;
write!(f, " {data_type}")?;
}
if let Some(options) = self.options.as_ref() {
match options {
@ -1845,7 +1845,7 @@ impl fmt::Display for ColumnOption {
} => {
write!(f, "{}", if *is_primary { "PRIMARY KEY" } else { "UNIQUE" })?;
if let Some(characteristics) = characteristics {
write!(f, " {}", characteristics)?;
write!(f, " {characteristics}")?;
}
Ok(())
}
@ -1867,7 +1867,7 @@ impl fmt::Display for ColumnOption {
write!(f, " ON UPDATE {action}")?;
}
if let Some(characteristics) = characteristics {
write!(f, " {}", characteristics)?;
write!(f, " {characteristics}")?;
}
Ok(())
}
@ -1927,7 +1927,7 @@ impl fmt::Display for ColumnOption {
write!(f, "{parameters}")
}
OnConflict(keyword) => {
write!(f, "ON CONFLICT {:?}", keyword)?;
write!(f, "ON CONFLICT {keyword:?}")?;
Ok(())
}
Policy(parameters) => {

View file

@ -55,7 +55,7 @@ impl Display for IndexColumn {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.column)?;
if let Some(operator_class) = &self.operator_class {
write!(f, " {}", operator_class)?;
write!(f, " {operator_class}")?;
}
Ok(())
}
@ -266,7 +266,7 @@ impl Display for CreateTable {
name = self.name,
)?;
if let Some(on_cluster) = &self.on_cluster {
write!(f, " ON CLUSTER {}", on_cluster)?;
write!(f, " ON CLUSTER {on_cluster}")?;
}
if !self.columns.is_empty() || !self.constraints.is_empty() {
f.write_str(" (")?;
@ -383,15 +383,15 @@ impl Display for CreateTable {
match &self.table_options {
options @ CreateTableOptions::With(_)
| options @ CreateTableOptions::Plain(_)
| options @ CreateTableOptions::TableProperties(_) => write!(f, " {}", options)?,
| options @ CreateTableOptions::TableProperties(_) => write!(f, " {options}")?,
_ => (),
}
if let Some(primary_key) = &self.primary_key {
write!(f, " PRIMARY KEY {}", primary_key)?;
write!(f, " PRIMARY KEY {primary_key}")?;
}
if let Some(order_by) = &self.order_by {
write!(f, " ORDER BY {}", order_by)?;
write!(f, " ORDER BY {order_by}")?;
}
if let Some(inherits) = &self.inherits {
write!(f, " INHERITS ({})", display_comma_separated(inherits))?;
@ -403,7 +403,7 @@ impl Display for CreateTable {
write!(f, " CLUSTER BY {cluster_by}")?;
}
if let options @ CreateTableOptions::Options(_) = &self.table_options {
write!(f, " {}", options)?;
write!(f, " {options}")?;
}
if let Some(external_volume) = self.external_volume.as_ref() {
write!(f, " EXTERNAL_VOLUME = '{external_volume}'")?;

View file

@ -67,7 +67,7 @@ impl fmt::Display for KeyValueOptions {
} else {
f.write_str(" ")?;
}
write!(f, "{}", option)?;
write!(f, "{option}")?;
}
}
Ok(())

View file

@ -357,7 +357,7 @@ impl ObjectNamePart {
impl fmt::Display for ObjectNamePart {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ObjectNamePart::Identifier(ident) => write!(f, "{}", ident),
ObjectNamePart::Identifier(ident) => write!(f, "{ident}"),
}
}
}
@ -1210,8 +1210,8 @@ pub enum AccessExpr {
impl fmt::Display for AccessExpr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
AccessExpr::Dot(expr) => write!(f, ".{}", expr),
AccessExpr::Subscript(subscript) => write!(f, "[{}]", subscript),
AccessExpr::Dot(expr) => write!(f, ".{expr}"),
AccessExpr::Subscript(subscript) => write!(f, "[{subscript}]"),
}
}
}
@ -1413,12 +1413,12 @@ impl fmt::Display for Expr {
match self {
Expr::Identifier(s) => write!(f, "{s}"),
Expr::Wildcard(_) => f.write_str("*"),
Expr::QualifiedWildcard(prefix, _) => write!(f, "{}.*", prefix),
Expr::QualifiedWildcard(prefix, _) => write!(f, "{prefix}.*"),
Expr::CompoundIdentifier(s) => write!(f, "{}", display_separated(s, ".")),
Expr::CompoundFieldAccess { root, access_chain } => {
write!(f, "{}", root)?;
write!(f, "{root}")?;
for field in access_chain {
write!(f, "{}", field)?;
write!(f, "{field}")?;
}
Ok(())
}
@ -1547,7 +1547,7 @@ impl fmt::Display for Expr {
} => {
let not_ = if *negated { "NOT " } else { "" };
if form.is_none() {
write!(f, "{} IS {}NORMALIZED", expr, not_)
write!(f, "{expr} IS {not_}NORMALIZED")
} else {
write!(
f,
@ -1869,7 +1869,7 @@ impl fmt::Display for Expr {
}
}
Expr::Named { expr, name } => {
write!(f, "{} AS {}", expr, name)
write!(f, "{expr} AS {name}")
}
Expr::Dictionary(fields) => {
write!(f, "{{{}}}", display_comma_separated(fields))
@ -2425,7 +2425,7 @@ impl fmt::Display for ConditionalStatements {
}
Ok(())
}
ConditionalStatements::BeginEnd(bes) => write!(f, "{}", bes),
ConditionalStatements::BeginEnd(bes) => write!(f, "{bes}"),
}
}
}
@ -2945,9 +2945,7 @@ impl Display for Set {
write!(
f,
"SET {modifier}ROLE {role_name}",
modifier = context_modifier
.map(|m| format!("{}", m))
.unwrap_or_default()
modifier = context_modifier.map(|m| format!("{m}")).unwrap_or_default()
)
}
Self::SetSessionParam(kind) => write!(f, "SET {kind}"),
@ -2980,7 +2978,7 @@ impl Display for Set {
charset_name,
collation_name,
} => {
write!(f, "SET NAMES {}", charset_name)?;
write!(f, "SET NAMES {charset_name}")?;
if let Some(collation) = collation_name {
f.write_str(" COLLATE ")?;
@ -3003,7 +3001,7 @@ impl Display for Set {
write!(
f,
"SET {}{}{} = {}",
scope.map(|s| format!("{}", s)).unwrap_or_default(),
scope.map(|s| format!("{s}")).unwrap_or_default(),
if *hivevar { "HIVEVAR:" } else { "" },
variable,
display_comma_separated(values)
@ -4405,7 +4403,7 @@ impl fmt::Display for Statement {
write!(f, "{describe_alias} ")?;
if let Some(format) = hive_format {
write!(f, "{} ", format)?;
write!(f, "{format} ")?;
}
if *has_table_keyword {
write!(f, "TABLE ")?;
@ -5241,7 +5239,7 @@ impl fmt::Display for Statement {
if *only {
write!(f, "ONLY ")?;
}
write!(f, "{name} ", name = name)?;
write!(f, "{name} ")?;
if let Some(cluster) = on_cluster {
write!(f, "ON CLUSTER {cluster} ")?;
}
@ -5319,7 +5317,7 @@ impl fmt::Display for Statement {
)?;
if !session_params.options.is_empty() {
if *set {
write!(f, " {}", session_params)?;
write!(f, " {session_params}")?;
} else {
let options = session_params
.options
@ -5353,7 +5351,7 @@ impl fmt::Display for Statement {
if *purge { " PURGE" } else { "" },
)?;
if let Some(table_name) = table.as_ref() {
write!(f, " ON {}", table_name)?;
write!(f, " ON {table_name}")?;
};
Ok(())
}
@ -5608,7 +5606,7 @@ impl fmt::Display for Statement {
} => {
if *syntax_begin {
if let Some(modifier) = *modifier {
write!(f, "BEGIN {}", modifier)?;
write!(f, "BEGIN {modifier}")?;
} else {
write!(f, "BEGIN")?;
}
@ -5644,7 +5642,7 @@ impl fmt::Display for Statement {
if *end_syntax {
write!(f, "END")?;
if let Some(modifier) = *modifier {
write!(f, " {}", modifier)?;
write!(f, " {modifier}")?;
}
if *chain {
write!(f, " AND CHAIN")?;
@ -5743,7 +5741,7 @@ impl fmt::Display for Statement {
write!(f, " GRANTED BY {grantor}")?;
}
if let Some(cascade) = cascade {
write!(f, " {}", cascade)?;
write!(f, " {cascade}")?;
}
Ok(())
}
@ -5922,13 +5920,13 @@ impl fmt::Display for Statement {
if_not_exists = if *if_not_exists { "IF NOT EXISTS " } else { "" },
)?;
if !directory_table_params.options.is_empty() {
write!(f, " DIRECTORY=({})", directory_table_params)?;
write!(f, " DIRECTORY=({directory_table_params})")?;
}
if !file_format.options.is_empty() {
write!(f, " FILE_FORMAT=({})", file_format)?;
write!(f, " FILE_FORMAT=({file_format})")?;
}
if !copy_options.options.is_empty() {
write!(f, " COPY_OPTIONS=({})", copy_options)?;
write!(f, " COPY_OPTIONS=({copy_options})")?;
}
if comment.is_some() {
write!(f, " COMMENT='{}'", comment.as_ref().unwrap())?;
@ -5951,7 +5949,7 @@ impl fmt::Display for Statement {
validation_mode,
partition,
} => {
write!(f, "COPY INTO {}", into)?;
write!(f, "COPY INTO {into}")?;
if let Some(into_columns) = into_columns {
write!(f, " ({})", display_comma_separated(into_columns))?;
}
@ -5967,12 +5965,12 @@ impl fmt::Display for Statement {
)?;
}
if let Some(from_obj_alias) = from_obj_alias {
write!(f, " AS {}", from_obj_alias)?;
write!(f, " AS {from_obj_alias}")?;
}
write!(f, ")")?;
} else if let Some(from_obj) = from_obj {
// Standard data load
write!(f, " FROM {}{}", from_obj, stage_params)?;
write!(f, " FROM {from_obj}{stage_params}")?;
if let Some(from_obj_alias) = from_obj_alias {
write!(f, " AS {from_obj_alias}")?;
}
@ -5985,24 +5983,24 @@ impl fmt::Display for Statement {
write!(f, " FILES = ('{}')", display_separated(files, "', '"))?;
}
if let Some(pattern) = pattern {
write!(f, " PATTERN = '{}'", pattern)?;
write!(f, " PATTERN = '{pattern}'")?;
}
if let Some(partition) = partition {
write!(f, " PARTITION BY {partition}")?;
}
if !file_format.options.is_empty() {
write!(f, " FILE_FORMAT=({})", file_format)?;
write!(f, " FILE_FORMAT=({file_format})")?;
}
if !copy_options.options.is_empty() {
match kind {
CopyIntoSnowflakeKind::Table => {
write!(f, " COPY_OPTIONS=({})", copy_options)?
write!(f, " COPY_OPTIONS=({copy_options})")?
}
CopyIntoSnowflakeKind::Location => write!(f, " {copy_options}")?,
}
}
if let Some(validation_mode) = validation_mode {
write!(f, " VALIDATION_MODE = {}", validation_mode)?;
write!(f, " VALIDATION_MODE = {validation_mode}")?;
}
Ok(())
}
@ -6048,10 +6046,10 @@ impl fmt::Display for Statement {
} => {
write!(f, "OPTIMIZE TABLE {name}")?;
if let Some(on_cluster) = on_cluster {
write!(f, " ON CLUSTER {on_cluster}", on_cluster = on_cluster)?;
write!(f, " ON CLUSTER {on_cluster}")?;
}
if let Some(partition) = partition {
write!(f, " {partition}", partition = partition)?;
write!(f, " {partition}")?;
}
if *include_final {
write!(f, " FINAL")?;
@ -6178,7 +6176,7 @@ impl fmt::Display for SetAssignment {
write!(
f,
"{}{} = {}",
self.scope.map(|s| format!("{}", s)).unwrap_or_default(),
self.scope.map(|s| format!("{s}")).unwrap_or_default(),
self.name,
self.value
)
@ -6907,7 +6905,7 @@ impl fmt::Display for GranteeName {
match self {
GranteeName::ObjectName(name) => name.fmt(f),
GranteeName::UserHost { user, host } => {
write!(f, "{}@{}", user, host)
write!(f, "{user}@{host}")
}
}
}
@ -6922,6 +6920,12 @@ pub enum GrantObjects {
AllSequencesInSchema { schemas: Vec<ObjectName> },
/// Grant privileges on `ALL TABLES IN SCHEMA <schema_name> [, ...]`
AllTablesInSchema { schemas: Vec<ObjectName> },
/// Grant privileges on `FUTURE SCHEMAS IN DATABASE <database_name> [, ...]`
FutureSchemasInDatabase { databases: Vec<ObjectName> },
/// Grant privileges on `FUTURE TABLES IN SCHEMA <schema_name> [, ...]`
FutureTablesInSchema { schemas: Vec<ObjectName> },
/// Grant privileges on `FUTURE VIEWS IN SCHEMA <schema_name> [, ...]`
FutureViewsInSchema { schemas: Vec<ObjectName> },
/// Grant privileges on specific databases
Databases(Vec<ObjectName>),
/// Grant privileges on specific schemas
@ -6990,6 +6994,27 @@ impl fmt::Display for GrantObjects {
display_comma_separated(schemas)
)
}
GrantObjects::FutureSchemasInDatabase { databases } => {
write!(
f,
"FUTURE SCHEMAS IN DATABASE {}",
display_comma_separated(databases)
)
}
GrantObjects::FutureTablesInSchema { schemas } => {
write!(
f,
"FUTURE TABLES IN SCHEMA {}",
display_comma_separated(schemas)
)
}
GrantObjects::FutureViewsInSchema { schemas } => {
write!(
f,
"FUTURE VIEWS IN SCHEMA {}",
display_comma_separated(schemas)
)
}
GrantObjects::ResourceMonitors(objects) => {
write!(f, "RESOURCE MONITOR {}", display_comma_separated(objects))
}
@ -7077,7 +7102,7 @@ pub enum AssignmentTarget {
impl fmt::Display for AssignmentTarget {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
AssignmentTarget::ColumnName(column) => write!(f, "{}", column),
AssignmentTarget::ColumnName(column) => write!(f, "{column}"),
AssignmentTarget::Tuple(columns) => write!(f, "({})", display_comma_separated(columns)),
}
}
@ -7322,8 +7347,8 @@ impl fmt::Display for FunctionArguments {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
FunctionArguments::None => Ok(()),
FunctionArguments::Subquery(query) => write!(f, "({})", query),
FunctionArguments::List(args) => write!(f, "({})", args),
FunctionArguments::Subquery(query) => write!(f, "({query})"),
FunctionArguments::List(args) => write!(f, "({args})"),
}
}
}
@ -7344,7 +7369,7 @@ pub struct FunctionArgumentList {
impl fmt::Display for FunctionArgumentList {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(duplicate_treatment) = self.duplicate_treatment {
write!(f, "{} ", duplicate_treatment)?;
write!(f, "{duplicate_treatment} ")?;
}
write!(f, "{}", display_comma_separated(&self.args))?;
if !self.clauses.is_empty() {
@ -7404,7 +7429,7 @@ impl fmt::Display for FunctionArgumentClause {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
FunctionArgumentClause::IgnoreOrRespectNulls(null_treatment) => {
write!(f, "{}", null_treatment)
write!(f, "{null_treatment}")
}
FunctionArgumentClause::OrderBy(order_by) => {
write!(f, "ORDER BY {}", display_comma_separated(order_by))
@ -7860,12 +7885,12 @@ pub enum SqlOption {
impl fmt::Display for SqlOption {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
SqlOption::Clustered(c) => write!(f, "{}", c),
SqlOption::Clustered(c) => write!(f, "{c}"),
SqlOption::Ident(ident) => {
write!(f, "{}", ident)
write!(f, "{ident}")
}
SqlOption::KeyValue { key: name, value } => {
write!(f, "{} = {}", name, value)
write!(f, "{name} = {value}")
}
SqlOption::Partition {
column_name,
@ -7905,7 +7930,7 @@ impl fmt::Display for SqlOption {
SqlOption::NamedParenthesizedList(value) => {
write!(f, "{} = ", value.key)?;
if let Some(key) = &value.name {
write!(f, "{}", key)?;
write!(f, "{key}")?;
}
if !value.values.is_empty() {
write!(f, "({})", display_comma_separated(&value.values))?
@ -7962,7 +7987,7 @@ impl fmt::Display for AttachDuckDBDatabaseOption {
AttachDuckDBDatabaseOption::ReadOnly(Some(true)) => write!(f, "READ_ONLY true"),
AttachDuckDBDatabaseOption::ReadOnly(Some(false)) => write!(f, "READ_ONLY false"),
AttachDuckDBDatabaseOption::ReadOnly(None) => write!(f, "READ_ONLY"),
AttachDuckDBDatabaseOption::Type(t) => write!(f, "TYPE {}", t),
AttachDuckDBDatabaseOption::Type(t) => write!(f, "TYPE {t}"),
}
}
}
@ -9485,10 +9510,10 @@ impl fmt::Display for ShowStatementIn {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.clause)?;
if let Some(parent_type) = &self.parent_type {
write!(f, " {}", parent_type)?;
write!(f, " {parent_type}")?;
}
if let Some(parent_name) = &self.parent_name {
write!(f, " {}", parent_name)?;
write!(f, " {parent_name}")?;
}
Ok(())
}
@ -9569,7 +9594,7 @@ impl fmt::Display for TableObject {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::TableName(table_name) => write!(f, "{table_name}"),
Self::TableFunction(func) => write!(f, "FUNCTION {}", func),
Self::TableFunction(func) => write!(f, "FUNCTION {func}"),
}
}
}
@ -9757,7 +9782,7 @@ pub struct ReturnStatement {
impl fmt::Display for ReturnStatement {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match &self.value {
Some(ReturnStatementValue::Expr(expr)) => write!(f, "RETURN {}", expr),
Some(ReturnStatementValue::Expr(expr)) => write!(f, "RETURN {expr}"),
None => write!(f, "RETURN"),
}
}

View file

@ -1183,7 +1183,7 @@ impl fmt::Display for TableIndexHints {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {} ", self.hint_type, self.index_type)?;
if let Some(for_clause) = &self.for_clause {
write!(f, "FOR {} ", for_clause)?;
write!(f, "FOR {for_clause} ")?;
}
write!(f, "({})", display_comma_separated(&self.index_names))
}
@ -1459,7 +1459,7 @@ impl fmt::Display for TableSampleQuantity {
}
write!(f, "{}", self.value)?;
if let Some(unit) = &self.unit {
write!(f, " {}", unit)?;
write!(f, " {unit}")?;
}
if self.parenthesized {
write!(f, ")")?;
@ -1552,7 +1552,7 @@ impl fmt::Display for TableSampleBucket {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "BUCKET {} OUT OF {}", self.bucket, self.total)?;
if let Some(on) = &self.on {
write!(f, " ON {}", on)?;
write!(f, " ON {on}")?;
}
Ok(())
}
@ -1561,19 +1561,19 @@ impl fmt::Display for TableSample {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.modifier)?;
if let Some(name) = &self.name {
write!(f, " {}", name)?;
write!(f, " {name}")?;
}
if let Some(quantity) = &self.quantity {
write!(f, " {}", quantity)?;
write!(f, " {quantity}")?;
}
if let Some(seed) = &self.seed {
write!(f, " {}", seed)?;
write!(f, " {seed}")?;
}
if let Some(bucket) = &self.bucket {
write!(f, " ({})", bucket)?;
write!(f, " ({bucket})")?;
}
if let Some(offset) = &self.offset {
write!(f, " OFFSET {}", offset)?;
write!(f, " OFFSET {offset}")?;
}
Ok(())
}
@ -1651,7 +1651,7 @@ impl fmt::Display for RowsPerMatch {
RowsPerMatch::AllRows(mode) => {
write!(f, "ALL ROWS PER MATCH")?;
if let Some(mode) = mode {
write!(f, " {}", mode)?;
write!(f, " {mode}")?;
}
Ok(())
}
@ -1777,7 +1777,7 @@ impl fmt::Display for MatchRecognizePattern {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
use MatchRecognizePattern::*;
match self {
Symbol(symbol) => write!(f, "{}", symbol),
Symbol(symbol) => write!(f, "{symbol}"),
Exclude(symbol) => write!(f, "{{- {symbol} -}}"),
Permute(symbols) => write!(f, "PERMUTE({})", display_comma_separated(symbols)),
Concat(patterns) => write!(f, "{}", display_separated(patterns, " ")),
@ -2148,7 +2148,7 @@ impl fmt::Display for TableAliasColumnDef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.name)?;
if let Some(ref data_type) = self.data_type {
write!(f, " {}", data_type)?;
write!(f, " {data_type}")?;
}
Ok(())
}
@ -2398,7 +2398,7 @@ impl fmt::Display for OrderBy {
write!(f, " {}", display_comma_separated(exprs))?;
}
OrderByKind::All(all) => {
write!(f, " ALL{}", all)?;
write!(f, " ALL{all}")?;
}
}
@ -2429,7 +2429,7 @@ impl fmt::Display for OrderByExpr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}{}", self.expr, self.options)?;
if let Some(ref with_fill) = self.with_fill {
write!(f, " {}", with_fill)?
write!(f, " {with_fill}")?
}
Ok(())
}
@ -2452,13 +2452,13 @@ impl fmt::Display for WithFill {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "WITH FILL")?;
if let Some(ref from) = self.from {
write!(f, " FROM {}", from)?;
write!(f, " FROM {from}")?;
}
if let Some(ref to) = self.to {
write!(f, " TO {}", to)?;
write!(f, " TO {to}")?;
}
if let Some(ref step) = self.step {
write!(f, " STEP {}", step)?;
write!(f, " STEP {step}")?;
}
Ok(())
}
@ -2487,7 +2487,7 @@ impl fmt::Display for InterpolateExpr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.column)?;
if let Some(ref expr) = self.expr {
write!(f, " AS {}", expr)?;
write!(f, " AS {expr}")?;
}
Ok(())
}
@ -2565,7 +2565,7 @@ impl fmt::Display for LimitClause {
Ok(())
}
LimitClause::OffsetCommaLimit { offset, limit } => {
write!(f, " LIMIT {}, {}", offset, limit)
write!(f, " LIMIT {offset}, {limit}")
}
}
}
@ -2702,12 +2702,12 @@ impl fmt::Display for PipeOperator {
write!(f, "DROP {}", display_comma_separated(columns.as_slice()))
}
PipeOperator::As { alias } => {
write!(f, "AS {}", alias)
write!(f, "AS {alias}")
}
PipeOperator::Limit { expr, offset } => {
write!(f, "LIMIT {}", expr)?;
write!(f, "LIMIT {expr}")?;
if let Some(offset) = offset {
write!(f, " OFFSET {}", offset)?;
write!(f, " OFFSET {offset}")?;
}
Ok(())
}
@ -2730,14 +2730,14 @@ impl fmt::Display for PipeOperator {
}
PipeOperator::Where { expr } => {
write!(f, "WHERE {}", expr)
write!(f, "WHERE {expr}")
}
PipeOperator::OrderBy { exprs } => {
write!(f, "ORDER BY {}", display_comma_separated(exprs.as_slice()))
}
PipeOperator::TableSample { sample } => {
write!(f, "{}", sample)
write!(f, "{sample}")
}
}
}
@ -3016,7 +3016,7 @@ pub enum FormatClause {
impl fmt::Display for FormatClause {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
FormatClause::Identifier(ident) => write!(f, "FORMAT {}", ident),
FormatClause::Identifier(ident) => write!(f, "FORMAT {ident}"),
FormatClause::Null => write!(f, "FORMAT NULL"),
}
}
@ -3078,9 +3078,9 @@ impl fmt::Display for ForClause {
without_array_wrapper,
} => {
write!(f, "FOR JSON ")?;
write!(f, "{}", for_json)?;
write!(f, "{for_json}")?;
if let Some(root) = root {
write!(f, ", ROOT('{}')", root)?;
write!(f, ", ROOT('{root}')")?;
}
if *include_null_values {
write!(f, ", INCLUDE_NULL_VALUES")?;
@ -3098,7 +3098,7 @@ impl fmt::Display for ForClause {
r#type,
} => {
write!(f, "FOR XML ")?;
write!(f, "{}", for_xml)?;
write!(f, "{for_xml}")?;
if *binary_base64 {
write!(f, ", BINARY BASE64")?;
}
@ -3106,7 +3106,7 @@ impl fmt::Display for ForClause {
write!(f, ", TYPE")?;
}
if let Some(root) = root {
write!(f, ", ROOT('{}')", root)?;
write!(f, ", ROOT('{root}')")?;
}
if *elements {
write!(f, ", ELEMENTS")?;
@ -3133,7 +3133,7 @@ impl fmt::Display for ForXml {
ForXml::Raw(root) => {
write!(f, "RAW")?;
if let Some(root) = root {
write!(f, "('{}')", root)?;
write!(f, "('{root}')")?;
}
Ok(())
}
@ -3142,7 +3142,7 @@ impl fmt::Display for ForXml {
ForXml::Path(root) => {
write!(f, "PATH")?;
if let Some(root) = root {
write!(f, "('{}')", root)?;
write!(f, "('{root}')")?;
}
Ok(())
}
@ -3205,7 +3205,7 @@ impl fmt::Display for JsonTableColumn {
JsonTableColumn::Named(json_table_named_column) => {
write!(f, "{json_table_named_column}")
}
JsonTableColumn::ForOrdinality(ident) => write!(f, "{} FOR ORDINALITY", ident),
JsonTableColumn::ForOrdinality(ident) => write!(f, "{ident} FOR ORDINALITY"),
JsonTableColumn::Nested(json_table_nested_column) => {
write!(f, "{json_table_nested_column}")
}
@ -3271,10 +3271,10 @@ impl fmt::Display for JsonTableNamedColumn {
self.path
)?;
if let Some(on_empty) = &self.on_empty {
write!(f, " {} ON EMPTY", on_empty)?;
write!(f, " {on_empty} ON EMPTY")?;
}
if let Some(on_error) = &self.on_error {
write!(f, " {} ON ERROR", on_error)?;
write!(f, " {on_error} ON ERROR")?;
}
Ok(())
}
@ -3296,7 +3296,7 @@ impl fmt::Display for JsonTableColumnErrorHandling {
match self {
JsonTableColumnErrorHandling::Null => write!(f, "NULL"),
JsonTableColumnErrorHandling::Default(json_string) => {
write!(f, "DEFAULT {}", json_string)
write!(f, "DEFAULT {json_string}")
}
JsonTableColumnErrorHandling::Error => write!(f, "ERROR"),
}
@ -3429,12 +3429,12 @@ impl fmt::Display for XmlTableColumn {
default,
nullable,
} => {
write!(f, " {}", r#type)?;
write!(f, " {type}")?;
if let Some(p) = path {
write!(f, " PATH {}", p)?;
write!(f, " PATH {p}")?;
}
if let Some(d) = default {
write!(f, " DEFAULT {}", d)?;
write!(f, " DEFAULT {d}")?;
}
if !*nullable {
write!(f, " NOT NULL")?;
@ -3465,7 +3465,7 @@ impl fmt::Display for XmlPassingArgument {
}
write!(f, "{}", self.expr)?;
if let Some(alias) = &self.alias {
write!(f, " AS {}", alias)?;
write!(f, " AS {alias}")?;
}
Ok(())
}

View file

@ -550,16 +550,16 @@ impl fmt::Display for EscapeUnicodeStringLiteral<'_> {
write!(f, r#"\\"#)?;
}
x if x.is_ascii() => {
write!(f, "{}", c)?;
write!(f, "{c}")?;
}
_ => {
let codepoint = c as u32;
// if the character fits in 32 bits, we can use the \XXXX format
// otherwise, we need to use the \+XXXXXX format
if codepoint <= 0xFFFF {
write!(f, "\\{:04X}", codepoint)?;
write!(f, "\\{codepoint:04X}")?;
} else {
write!(f, "\\+{:06X}", codepoint)?;
write!(f, "\\+{codepoint:06X}")?;
}
}
}

View file

@ -926,10 +926,10 @@ mod tests {
#[test]
fn overflow() {
let cond = (0..1000)
.map(|n| format!("X = {}", n))
.map(|n| format!("X = {n}"))
.collect::<Vec<_>>()
.join(" OR ");
let sql = format!("SELECT x where {0}", cond);
let sql = format!("SELECT x where {cond}");
let dialect = GenericDialect {};
let tokens = Tokenizer::new(&dialect, sql.as_str()).tokenize().unwrap();

View file

@ -587,7 +587,7 @@ pub trait Dialect: Debug + Any {
}
let token = parser.peek_token();
debug!("get_next_precedence_full() {:?}", token);
debug!("get_next_precedence_full() {token:?}");
match token.token {
Token::Word(w) if w.keyword == Keyword::OR => Ok(p!(Or)),
Token::Word(w) if w.keyword == Keyword::AND => Ok(p!(And)),

View file

@ -104,7 +104,7 @@ impl Dialect for PostgreSqlDialect {
fn get_next_precedence(&self, parser: &Parser) -> Option<Result<u8, ParserError>> {
let token = parser.peek_token();
debug!("get_next_precedence() {:?}", token);
debug!("get_next_precedence() {token:?}");
// we only return some custom value here when the behaviour (not merely the numeric value) differs
// from the default implementation

View file

@ -395,6 +395,7 @@ define_keywords!(
FUNCTION,
FUNCTIONS,
FUSION,
FUTURE,
GENERAL,
GENERATE,
GENERATED,

View file

@ -436,7 +436,7 @@ impl<'a> Parser<'a> {
///
/// See example on [`Parser::new()`] for an example
pub fn try_with_sql(self, sql: &str) -> Result<Self, ParserError> {
debug!("Parsing sql '{}'...", sql);
debug!("Parsing sql '{sql}'...");
let tokens = Tokenizer::new(self.dialect, sql)
.with_unescape(self.options.unescape)
.tokenize_with_location()?;
@ -1226,10 +1226,10 @@ impl<'a> Parser<'a> {
expr = self.parse_compound_expr(expr, vec![])?;
debug!("prefix: {:?}", expr);
debug!("prefix: {expr:?}");
loop {
let next_precedence = self.get_next_precedence()?;
debug!("next precedence: {:?}", next_precedence);
debug!("next precedence: {next_precedence:?}");
if precedence >= next_precedence {
break;
@ -1631,8 +1631,7 @@ impl<'a> Parser<'a> {
Token::QuestionPipe => UnaryOperator::QuestionPipe,
_ => {
return Err(ParserError::ParserError(format!(
"Unexpected token in unary operator parsing: {:?}",
tok
"Unexpected token in unary operator parsing: {tok:?}"
)))
}
};
@ -13656,7 +13655,7 @@ impl<'a> Parser<'a> {
let ident = self.parse_identifier()?;
if let GranteeName::ObjectName(namespace) = name {
name = GranteeName::ObjectName(ObjectName::from(vec![Ident::new(
format!("{}:{}", namespace, ident),
format!("{namespace}:{ident}"),
)]));
};
}
@ -13693,6 +13692,33 @@ impl<'a> Parser<'a> {
Some(GrantObjects::AllTablesInSchema {
schemas: self.parse_comma_separated(|p| p.parse_object_name(false))?,
})
} else if self.parse_keywords(&[
Keyword::FUTURE,
Keyword::SCHEMAS,
Keyword::IN,
Keyword::DATABASE,
]) {
Some(GrantObjects::FutureSchemasInDatabase {
databases: self.parse_comma_separated(|p| p.parse_object_name(false))?,
})
} else if self.parse_keywords(&[
Keyword::FUTURE,
Keyword::TABLES,
Keyword::IN,
Keyword::SCHEMA,
]) {
Some(GrantObjects::FutureTablesInSchema {
schemas: self.parse_comma_separated(|p| p.parse_object_name(false))?,
})
} else if self.parse_keywords(&[
Keyword::FUTURE,
Keyword::VIEWS,
Keyword::IN,
Keyword::SCHEMA,
]) {
Some(GrantObjects::FutureViewsInSchema {
schemas: self.parse_comma_separated(|p| p.parse_object_name(false))?,
})
} else if self.parse_keywords(&[
Keyword::ALL,
Keyword::SEQUENCES,
@ -14626,7 +14652,7 @@ impl<'a> Parser<'a> {
self.dialect
.get_reserved_keywords_for_select_item_operator(),
)
.map(|keyword| Ident::new(format!("{:?}", keyword)));
.map(|keyword| Ident::new(format!("{keyword:?}")));
match self.parse_wildcard_expr()? {
Expr::QualifiedWildcard(prefix, token) => Ok(SelectItem::QualifiedWildcard(

View file

@ -270,7 +270,7 @@ impl TestedDialects {
tokenizer = tokenizer.with_unescape(options.unescape);
}
let tokens = tokenizer.tokenize().unwrap();
assert_eq!(expected, tokens, "Tokenized differently for {:?}", dialect);
assert_eq!(expected, tokens, "Tokenized differently for {dialect:?}");
});
}
}

View file

@ -1751,7 +1751,7 @@ impl<'a> Tokenizer<'a> {
(None, Some(tok)) => Ok(Some(tok)),
(None, None) => self.tokenizer_error(
chars.location(),
format!("Expected a valid binary operator after '{}'", prefix),
format!("Expected a valid binary operator after '{prefix}'"),
),
}
}
@ -1809,7 +1809,7 @@ impl<'a> Tokenizer<'a> {
chars.next();
let mut temp = String::new();
let end_delimiter = format!("${}$", value);
let end_delimiter = format!("${value}$");
loop {
match chars.next() {
@ -2402,13 +2402,13 @@ fn take_char_from_hex_digits(
location: chars.location(),
})?;
let digit = next_char.to_digit(16).ok_or_else(|| TokenizerError {
message: format!("Invalid hex digit in escaped unicode string: {}", next_char),
message: format!("Invalid hex digit in escaped unicode string: {next_char}"),
location: chars.location(),
})?;
result = result * 16 + digit;
}
char::from_u32(result).ok_or_else(|| TokenizerError {
message: format!("Invalid unicode character: {:x}", result),
message: format!("Invalid unicode character: {result:x}"),
location: chars.location(),
})
}
@ -3504,7 +3504,7 @@ mod tests {
}
fn check_unescape(s: &str, expected: Option<&str>) {
let s = format!("'{}'", s);
let s = format!("'{s}'");
let mut state = State {
peekable: s.chars().peekable(),
line: 0,

View file

@ -1410,7 +1410,7 @@ fn parse_use() {
for object_name in &valid_object_names {
// Test single identifier without quotes
assert_eq!(
clickhouse().verified_stmt(&format!("USE {}", object_name)),
clickhouse().verified_stmt(&format!("USE {object_name}")),
Statement::Use(Use::Object(ObjectName::from(vec![Ident::new(
object_name.to_string()
)])))
@ -1418,7 +1418,7 @@ fn parse_use() {
for &quote in &quote_styles {
// Test single identifier with different type of quotes
assert_eq!(
clickhouse().verified_stmt(&format!("USE {0}{1}{0}", quote, object_name)),
clickhouse().verified_stmt(&format!("USE {quote}{object_name}{quote}")),
Statement::Use(Use::Object(ObjectName::from(vec![Ident::with_quote(
quote,
object_name.to_string(),
@ -1432,7 +1432,7 @@ fn parse_use() {
fn test_query_with_format_clause() {
let format_options = vec!["TabSeparated", "JSONCompact", "NULL"];
for format in &format_options {
let sql = format!("SELECT * FROM t FORMAT {}", format);
let sql = format!("SELECT * FROM t FORMAT {format}");
match clickhouse_and_generic().verified_stmt(&sql) {
Statement::Query(query) => {
if *format == "NULL" {

View file

@ -3563,7 +3563,7 @@ fn test_double_value() {
for (input, expected) in test_cases {
for (i, expr) in input.iter().enumerate() {
if let Statement::Query(query) =
dialects.one_statement_parses_to(&format!("SELECT {}", expr), "")
dialects.one_statement_parses_to(&format!("SELECT {expr}"), "")
{
if let SetExpr::Select(select) = *query.body {
assert_eq!(expected[i], select.projection[0]);
@ -4023,13 +4023,13 @@ fn parse_create_table_column_constraint_characteristics() {
syntax
};
let sql = format!("CREATE TABLE t (a int UNIQUE {})", syntax);
let sql = format!("CREATE TABLE t (a int UNIQUE {syntax})");
let expected_clause = if syntax.is_empty() {
String::new()
} else {
format!(" {syntax}")
};
let expected = format!("CREATE TABLE t (a INT UNIQUE{})", expected_clause);
let expected = format!("CREATE TABLE t (a INT UNIQUE{expected_clause})");
let ast = one_statement_parses_to(&sql, &expected);
let expected_value = if deferrable.is_some() || initially.is_some() || enforced.is_some() {
@ -7499,7 +7499,7 @@ fn parse_cte_in_data_modification_statements() {
assert_eq!(query.with.unwrap().to_string(), "WITH x AS (SELECT 1)");
assert!(matches!(*query.body, SetExpr::Update(_)));
}
other => panic!("Expected: UPDATE, got: {:?}", other),
other => panic!("Expected: UPDATE, got: {other:?}"),
}
match verified_stmt("WITH t (x) AS (SELECT 9) DELETE FROM q WHERE id IN (SELECT x FROM t)") {
@ -7507,7 +7507,7 @@ fn parse_cte_in_data_modification_statements() {
assert_eq!(query.with.unwrap().to_string(), "WITH t (x) AS (SELECT 9)");
assert!(matches!(*query.body, SetExpr::Delete(_)));
}
other => panic!("Expected: DELETE, got: {:?}", other),
other => panic!("Expected: DELETE, got: {other:?}"),
}
match verified_stmt("WITH x AS (SELECT 42) INSERT INTO t SELECT foo FROM x") {
@ -7515,7 +7515,7 @@ fn parse_cte_in_data_modification_statements() {
assert_eq!(query.with.unwrap().to_string(), "WITH x AS (SELECT 42)");
assert!(matches!(*query.body, SetExpr::Insert(_)));
}
other => panic!("Expected: INSERT, got: {:?}", other),
other => panic!("Expected: INSERT, got: {other:?}"),
}
}
@ -9386,9 +9386,11 @@ fn parse_grant() {
verified_stmt("GRANT SELECT ON VIEW view1 TO ROLE role1");
verified_stmt("GRANT EXEC ON my_sp TO runner");
verified_stmt("GRANT UPDATE ON my_table TO updater_role AS dbo");
all_dialects_where(|d| d.identifier_quote_style("none") == Some('['))
.verified_stmt("GRANT SELECT ON [my_table] TO [public]");
verified_stmt("GRANT SELECT ON FUTURE SCHEMAS IN DATABASE db1 TO ROLE role1");
verified_stmt("GRANT SELECT ON FUTURE TABLES IN SCHEMA db1.sc1 TO ROLE role1");
verified_stmt("GRANT SELECT ON FUTURE VIEWS IN SCHEMA db1.sc1 TO ROLE role1");
}
#[test]
@ -10043,7 +10045,7 @@ fn parse_offset_and_limit() {
#[test]
fn parse_time_functions() {
fn test_time_function(func_name: &'static str) {
let sql = format!("SELECT {}()", func_name);
let sql = format!("SELECT {func_name}()");
let select = verified_only_select(&sql);
let select_localtime_func_call_ast = Function {
name: ObjectName::from(vec![Ident::new(func_name)]),
@ -10065,7 +10067,7 @@ fn parse_time_functions() {
);
// Validating Parenthesis
let sql_without_parens = format!("SELECT {}", func_name);
let sql_without_parens = format!("SELECT {func_name}");
let mut ast_without_parens = select_localtime_func_call_ast;
ast_without_parens.args = FunctionArguments::None;
assert_eq!(
@ -14306,7 +14308,7 @@ fn overflow() {
let expr = std::iter::repeat_n("1", 1000)
.collect::<Vec<_>>()
.join(" + ");
let sql = format!("SELECT {}", expr);
let sql = format!("SELECT {expr}");
let mut statements = Parser::parse_sql(&GenericDialect {}, sql.as_str()).unwrap();
let statement = statements.pop().unwrap();
@ -14606,7 +14608,7 @@ fn test_conditional_statement_span() {
else_block.unwrap().span()
);
}
stmt => panic!("Unexpected statement: {:?}", stmt),
stmt => panic!("Unexpected statement: {stmt:?}"),
}
}

View file

@ -213,7 +213,7 @@ fn parse_use() {
for object_name in &valid_object_names {
// Test single identifier without quotes
assert_eq!(
databricks().verified_stmt(&format!("USE {}", object_name)),
databricks().verified_stmt(&format!("USE {object_name}")),
Statement::Use(Use::Object(ObjectName::from(vec![Ident::new(
object_name.to_string()
)])))
@ -221,7 +221,7 @@ fn parse_use() {
for &quote in &quote_styles {
// Test single identifier with different type of quotes
assert_eq!(
databricks().verified_stmt(&format!("USE {0}{1}{0}", quote, object_name)),
databricks().verified_stmt(&format!("USE {quote}{object_name}{quote}")),
Statement::Use(Use::Object(ObjectName::from(vec![Ident::with_quote(
quote,
object_name.to_string(),
@ -233,21 +233,21 @@ fn parse_use() {
for &quote in &quote_styles {
// Test single identifier with keyword and different type of quotes
assert_eq!(
databricks().verified_stmt(&format!("USE CATALOG {0}my_catalog{0}", quote)),
databricks().verified_stmt(&format!("USE CATALOG {quote}my_catalog{quote}")),
Statement::Use(Use::Catalog(ObjectName::from(vec![Ident::with_quote(
quote,
"my_catalog".to_string(),
)])))
);
assert_eq!(
databricks().verified_stmt(&format!("USE DATABASE {0}my_database{0}", quote)),
databricks().verified_stmt(&format!("USE DATABASE {quote}my_database{quote}")),
Statement::Use(Use::Database(ObjectName::from(vec![Ident::with_quote(
quote,
"my_database".to_string(),
)])))
);
assert_eq!(
databricks().verified_stmt(&format!("USE SCHEMA {0}my_schema{0}", quote)),
databricks().verified_stmt(&format!("USE SCHEMA {quote}my_schema{quote}")),
Statement::Use(Use::Schema(ObjectName::from(vec![Ident::with_quote(
quote,
"my_schema".to_string(),
@ -357,6 +357,6 @@ fn data_type_timestamp_ntz() {
}]
);
}
s => panic!("Unexpected statement: {:?}", s),
s => panic!("Unexpected statement: {s:?}"),
}
}

View file

@ -368,7 +368,7 @@ fn test_duckdb_specific_int_types() {
("HUGEINT", DataType::HugeInt),
];
for (dtype_string, data_type) in duckdb_dtypes {
let sql = format!("SELECT 123::{}", dtype_string);
let sql = format!("SELECT 123::{dtype_string}");
let select = duckdb().verified_only_select(&sql);
assert_eq!(
&Expr::Cast {
@ -792,7 +792,7 @@ fn parse_use() {
for object_name in &valid_object_names {
// Test single identifier without quotes
assert_eq!(
duckdb().verified_stmt(&format!("USE {}", object_name)),
duckdb().verified_stmt(&format!("USE {object_name}")),
Statement::Use(Use::Object(ObjectName::from(vec![Ident::new(
object_name.to_string()
)])))
@ -800,7 +800,7 @@ fn parse_use() {
for &quote in &quote_styles {
// Test single identifier with different type of quotes
assert_eq!(
duckdb().verified_stmt(&format!("USE {0}{1}{0}", quote, object_name)),
duckdb().verified_stmt(&format!("USE {quote}{object_name}{quote}")),
Statement::Use(Use::Object(ObjectName::from(vec![Ident::with_quote(
quote,
object_name.to_string(),
@ -812,7 +812,9 @@ fn parse_use() {
for &quote in &quote_styles {
// Test double identifier with different type of quotes
assert_eq!(
duckdb().verified_stmt(&format!("USE {0}CATALOG{0}.{0}my_schema{0}", quote)),
duckdb().verified_stmt(&format!(
"USE {quote}CATALOG{quote}.{quote}my_schema{quote}"
)),
Statement::Use(Use::Object(ObjectName::from(vec![
Ident::with_quote(quote, "CATALOG"),
Ident::with_quote(quote, "my_schema")

View file

@ -524,7 +524,7 @@ fn parse_use() {
for object_name in &valid_object_names {
// Test single identifier without quotes
assert_eq!(
hive().verified_stmt(&format!("USE {}", object_name)),
hive().verified_stmt(&format!("USE {object_name}")),
Statement::Use(Use::Object(ObjectName::from(vec![Ident::new(
object_name.to_string()
)])))
@ -532,7 +532,7 @@ fn parse_use() {
for &quote in &quote_styles {
// Test single identifier with different type of quotes
assert_eq!(
hive().verified_stmt(&format!("USE {}{}{}", quote, object_name, quote)),
hive().verified_stmt(&format!("USE {quote}{object_name}{quote}")),
Statement::Use(Use::Object(ObjectName::from(vec![Ident::with_quote(
quote,
object_name.to_string(),

View file

@ -1673,7 +1673,7 @@ fn parse_use() {
for object_name in &valid_object_names {
// Test single identifier without quotes
assert_eq!(
ms().verified_stmt(&format!("USE {}", object_name)),
ms().verified_stmt(&format!("USE {object_name}")),
Statement::Use(Use::Object(ObjectName::from(vec![Ident::new(
object_name.to_string()
)])))
@ -1681,7 +1681,7 @@ fn parse_use() {
for &quote in &quote_styles {
// Test single identifier with different type of quotes
assert_eq!(
ms().verified_stmt(&format!("USE {}{}{}", quote, object_name, quote)),
ms().verified_stmt(&format!("USE {quote}{object_name}{quote}")),
Statement::Use(Use::Object(ObjectName::from(vec![Ident::with_quote(
quote,
object_name.to_string(),
@ -2187,7 +2187,7 @@ fn parse_mssql_if_else() {
"IF 1 = 1 BEGIN SET @A = 1; END ELSE SET @A = 2;"
);
}
_ => panic!("Unexpected statements: {:?}", stmts),
_ => panic!("Unexpected statements: {stmts:?}"),
}
}
@ -2237,7 +2237,7 @@ fn test_mssql_if_statements_span() {
Span::new(Location::new(1, 21), Location::new(1, 36))
);
}
stmt => panic!("Unexpected statement: {:?}", stmt),
stmt => panic!("Unexpected statement: {stmt:?}"),
}
// Blocks
@ -2258,7 +2258,7 @@ fn test_mssql_if_statements_span() {
Span::new(Location::new(1, 32), Location::new(1, 57))
);
}
stmt => panic!("Unexpected statement: {:?}", stmt),
stmt => panic!("Unexpected statement: {stmt:?}"),
}
}

View file

@ -593,7 +593,7 @@ fn parse_use() {
for object_name in &valid_object_names {
// Test single identifier without quotes
assert_eq!(
mysql_and_generic().verified_stmt(&format!("USE {}", object_name)),
mysql_and_generic().verified_stmt(&format!("USE {object_name}")),
Statement::Use(Use::Object(ObjectName::from(vec![Ident::new(
object_name.to_string()
)])))
@ -601,8 +601,7 @@ fn parse_use() {
for &quote in &quote_styles {
// Test single identifier with different type of quotes
assert_eq!(
mysql_and_generic()
.verified_stmt(&format!("USE {}{}{}", quote, object_name, quote)),
mysql_and_generic().verified_stmt(&format!("USE {quote}{object_name}{quote}")),
Statement::Use(Use::Object(ObjectName::from(vec![Ident::with_quote(
quote,
object_name.to_string(),
@ -2263,11 +2262,11 @@ fn parse_qualified_identifiers_with_numeric_prefix() {
Some(SelectItem::UnnamedExpr(Expr::CompoundIdentifier(parts))) => {
assert_eq!(&[Ident::new("t"), Ident::new("15to29")], &parts[..]);
}
proj => panic!("Unexpected projection: {:?}", proj),
proj => panic!("Unexpected projection: {proj:?}"),
},
body => panic!("Unexpected statement body: {:?}", body),
body => panic!("Unexpected statement body: {body:?}"),
},
stmt => panic!("Unexpected statement: {:?}", stmt),
stmt => panic!("Unexpected statement: {stmt:?}"),
}
// Case 2: Qualified column name that starts with digits and on its own represents a number.
@ -2277,11 +2276,11 @@ fn parse_qualified_identifiers_with_numeric_prefix() {
Some(SelectItem::UnnamedExpr(Expr::CompoundIdentifier(parts))) => {
assert_eq!(&[Ident::new("t"), Ident::new("15e29")], &parts[..]);
}
proj => panic!("Unexpected projection: {:?}", proj),
proj => panic!("Unexpected projection: {proj:?}"),
},
body => panic!("Unexpected statement body: {:?}", body),
body => panic!("Unexpected statement body: {body:?}"),
},
stmt => panic!("Unexpected statement: {:?}", stmt),
stmt => panic!("Unexpected statement: {stmt:?}"),
}
// Case 3: Unqualified, the same token is parsed as a number.
@ -2295,11 +2294,11 @@ fn parse_qualified_identifiers_with_numeric_prefix() {
Some(SelectItem::UnnamedExpr(Expr::Value(ValueWithSpan { value, .. }))) => {
assert_eq!(&number("15e29"), value);
}
proj => panic!("Unexpected projection: {:?}", proj),
proj => panic!("Unexpected projection: {proj:?}"),
},
body => panic!("Unexpected statement body: {:?}", body),
body => panic!("Unexpected statement body: {body:?}"),
},
stmt => panic!("Unexpected statement: {:?}", stmt),
stmt => panic!("Unexpected statement: {stmt:?}"),
}
// Case 4: Quoted simple identifier.
@ -2309,11 +2308,11 @@ fn parse_qualified_identifiers_with_numeric_prefix() {
Some(SelectItem::UnnamedExpr(Expr::Identifier(name))) => {
assert_eq!(&Ident::with_quote('`', "15e29"), name);
}
proj => panic!("Unexpected projection: {:?}", proj),
proj => panic!("Unexpected projection: {proj:?}"),
},
body => panic!("Unexpected statement body: {:?}", body),
body => panic!("Unexpected statement body: {body:?}"),
},
stmt => panic!("Unexpected statement: {:?}", stmt),
stmt => panic!("Unexpected statement: {stmt:?}"),
}
// Case 5: Quoted compound identifier.
@ -2326,11 +2325,11 @@ fn parse_qualified_identifiers_with_numeric_prefix() {
&parts[..]
);
}
proj => panic!("Unexpected projection: {:?}", proj),
proj => panic!("Unexpected projection: {proj:?}"),
},
body => panic!("Unexpected statement body: {:?}", body),
body => panic!("Unexpected statement body: {body:?}"),
},
stmt => panic!("Unexpected statement: {:?}", stmt),
stmt => panic!("Unexpected statement: {stmt:?}"),
}
// Case 6: Multi-level compound identifiers.
@ -2347,11 +2346,11 @@ fn parse_qualified_identifiers_with_numeric_prefix() {
&parts[..]
);
}
proj => panic!("Unexpected projection: {:?}", proj),
proj => panic!("Unexpected projection: {proj:?}"),
},
body => panic!("Unexpected statement body: {:?}", body),
body => panic!("Unexpected statement body: {body:?}"),
},
stmt => panic!("Unexpected statement: {:?}", stmt),
stmt => panic!("Unexpected statement: {stmt:?}"),
}
// Case 7: Multi-level compound quoted identifiers.
@ -2368,11 +2367,11 @@ fn parse_qualified_identifiers_with_numeric_prefix() {
&parts[..]
);
}
proj => panic!("Unexpected projection: {:?}", proj),
proj => panic!("Unexpected projection: {proj:?}"),
},
body => panic!("Unexpected statement body: {:?}", body),
body => panic!("Unexpected statement body: {body:?}"),
},
stmt => panic!("Unexpected statement: {:?}", stmt),
stmt => panic!("Unexpected statement: {stmt:?}"),
}
}

View file

@ -2535,12 +2535,12 @@ fn parse_create_indices_with_operator_classes() {
for expected_operator_class in &operator_classes {
let single_column_sql_statement = format!(
"CREATE INDEX the_index_name ON users USING {expected_index_type} (concat_users_name(first_name, last_name){})",
expected_operator_class.as_ref().map(|oc| format!(" {}", oc))
expected_operator_class.as_ref().map(|oc| format!(" {oc}"))
.unwrap_or_default()
);
let multi_column_sql_statement = format!(
"CREATE INDEX the_index_name ON users USING {expected_index_type} (column_name,concat_users_name(first_name, last_name){})",
expected_operator_class.as_ref().map(|oc| format!(" {}", oc))
expected_operator_class.as_ref().map(|oc| format!(" {oc}"))
.unwrap_or_default()
);
@ -3273,7 +3273,7 @@ fn test_fn_arg_with_value_operator() {
assert!(matches!(
&args[..],
&[FunctionArg::ExprNamed { operator: FunctionArgOperator::Value, .. }]
), "Invalid function argument: {:?}", args);
), "Invalid function argument: {args:?}");
}
other => panic!("Expected: JSON_OBJECT('name' VALUE 'value') to be parsed as a function, but got {other:?}"),
}
@ -5679,7 +5679,7 @@ fn parse_drop_trigger() {
"DROP TRIGGER{} check_update ON table_name{}",
if if_exists { " IF EXISTS" } else { "" },
option
.map(|o| format!(" {}", o))
.map(|o| format!(" {o}"))
.unwrap_or_else(|| "".to_string())
);
assert_eq!(
@ -5773,8 +5773,7 @@ fn parse_trigger_related_functions() {
// Now we parse the statements and check if they are parsed correctly.
let mut statements = pg()
.parse_sql_statements(&format!(
"{}{}{}{}",
sql_table_creation, sql_create_function, sql_create_trigger, sql_drop_trigger
"{sql_table_creation}{sql_create_function}{sql_create_trigger}{sql_drop_trigger}"
))
.unwrap();

View file

@ -2510,10 +2510,7 @@ fn test_snowflake_stage_object_names_into_location() {
.zip(allowed_object_names.iter_mut())
{
let (formatted_name, object_name) = it;
let sql = format!(
"COPY INTO {} FROM 'gcs://mybucket/./../a.csv'",
formatted_name
);
let sql = format!("COPY INTO {formatted_name} FROM 'gcs://mybucket/./../a.csv'");
match snowflake().verified_stmt(&sql) {
Statement::CopyIntoSnowflake { into, .. } => {
assert_eq!(into.0, object_name.0)
@ -2536,10 +2533,7 @@ fn test_snowflake_stage_object_names_into_table() {
.zip(allowed_object_names.iter_mut())
{
let (formatted_name, object_name) = it;
let sql = format!(
"COPY INTO {} FROM 'gcs://mybucket/./../a.csv'",
formatted_name
);
let sql = format!("COPY INTO {formatted_name} FROM 'gcs://mybucket/./../a.csv'");
match snowflake().verified_stmt(&sql) {
Statement::CopyIntoSnowflake { into, .. } => {
assert_eq!(into.0, object_name.0)
@ -3020,7 +3014,7 @@ fn parse_use() {
for object_name in &valid_object_names {
// Test single identifier without quotes
assert_eq!(
snowflake().verified_stmt(&format!("USE {}", object_name)),
snowflake().verified_stmt(&format!("USE {object_name}")),
Statement::Use(Use::Object(ObjectName::from(vec![Ident::new(
object_name.to_string()
)])))
@ -3028,7 +3022,7 @@ fn parse_use() {
for &quote in &quote_styles {
// Test single identifier with different type of quotes
assert_eq!(
snowflake().verified_stmt(&format!("USE {}{}{}", quote, object_name, quote)),
snowflake().verified_stmt(&format!("USE {quote}{object_name}{quote}")),
Statement::Use(Use::Object(ObjectName::from(vec![Ident::with_quote(
quote,
object_name.to_string(),
@ -3040,7 +3034,9 @@ fn parse_use() {
for &quote in &quote_styles {
// Test double identifier with different type of quotes
assert_eq!(
snowflake().verified_stmt(&format!("USE {0}CATALOG{0}.{0}my_schema{0}", quote)),
snowflake().verified_stmt(&format!(
"USE {quote}CATALOG{quote}.{quote}my_schema{quote}"
)),
Statement::Use(Use::Object(ObjectName::from(vec![
Ident::with_quote(quote, "CATALOG"),
Ident::with_quote(quote, "my_schema")
@ -3059,35 +3055,37 @@ fn parse_use() {
for &quote in &quote_styles {
// Test single and double identifier with keyword and different type of quotes
assert_eq!(
snowflake().verified_stmt(&format!("USE DATABASE {0}my_database{0}", quote)),
snowflake().verified_stmt(&format!("USE DATABASE {quote}my_database{quote}")),
Statement::Use(Use::Database(ObjectName::from(vec![Ident::with_quote(
quote,
"my_database".to_string(),
)])))
);
assert_eq!(
snowflake().verified_stmt(&format!("USE SCHEMA {0}my_schema{0}", quote)),
snowflake().verified_stmt(&format!("USE SCHEMA {quote}my_schema{quote}")),
Statement::Use(Use::Schema(ObjectName::from(vec![Ident::with_quote(
quote,
"my_schema".to_string(),
)])))
);
assert_eq!(
snowflake().verified_stmt(&format!("USE SCHEMA {0}CATALOG{0}.{0}my_schema{0}", quote)),
snowflake().verified_stmt(&format!(
"USE SCHEMA {quote}CATALOG{quote}.{quote}my_schema{quote}"
)),
Statement::Use(Use::Schema(ObjectName::from(vec![
Ident::with_quote(quote, "CATALOG"),
Ident::with_quote(quote, "my_schema")
])))
);
assert_eq!(
snowflake().verified_stmt(&format!("USE ROLE {0}my_role{0}", quote)),
snowflake().verified_stmt(&format!("USE ROLE {quote}my_role{quote}")),
Statement::Use(Use::Role(ObjectName::from(vec![Ident::with_quote(
quote,
"my_role".to_string(),
)])))
);
assert_eq!(
snowflake().verified_stmt(&format!("USE WAREHOUSE {0}my_wh{0}", quote)),
snowflake().verified_stmt(&format!("USE WAREHOUSE {quote}my_wh{quote}")),
Statement::Use(Use::Warehouse(ObjectName::from(vec![Ident::with_quote(
quote,
"my_wh".to_string(),
@ -3629,7 +3627,7 @@ fn test_alter_session_followed_by_statement() {
.unwrap();
match stmts[..] {
[Statement::AlterSession { .. }, Statement::Query { .. }] => {}
_ => panic!("Unexpected statements: {:?}", stmts),
_ => panic!("Unexpected statements: {stmts:?}"),
}
}

View file

@ -324,7 +324,7 @@ fn parse_create_table_on_conflict_col() {
Keyword::IGNORE,
Keyword::REPLACE,
] {
let sql = format!("CREATE TABLE t1 (a INT, b INT ON CONFLICT {:?})", keyword);
let sql = format!("CREATE TABLE t1 (a INT, b INT ON CONFLICT {keyword:?})");
match sqlite_and_generic().verified_stmt(&sql) {
Statement::CreateTable(CreateTable { columns, .. }) => {
assert_eq!(
@ -410,7 +410,7 @@ fn parse_window_function_with_filter() {
"count",
"user_defined_function",
] {
let sql = format!("SELECT {}(x) FILTER (WHERE y) OVER () FROM t", func_name);
let sql = format!("SELECT {func_name}(x) FILTER (WHERE y) OVER () FROM t");
let select = sqlite().verified_only_select(&sql);
assert_eq!(select.to_string(), sql);
assert_eq!(
@ -444,7 +444,7 @@ fn parse_window_function_with_filter() {
fn parse_attach_database() {
let sql = "ATTACH DATABASE 'test.db' AS test";
let verified_stmt = sqlite().verified_stmt(sql);
assert_eq!(sql, format!("{}", verified_stmt));
assert_eq!(sql, format!("{verified_stmt}"));
match verified_stmt {
Statement::AttachDatabase {
schema_name,