Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main' into sf-pos
Browse files Browse the repository at this point in the history
  • Loading branch information
alamb committed Oct 23, 2023
2 parents 04ef88c + e857a45 commit 01ab7c8
Show file tree
Hide file tree
Showing 13 changed files with 362 additions and 175 deletions.
3 changes: 3 additions & 0 deletions src/ast/ddl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,9 @@ pub struct ColumnDef {
impl fmt::Display for ColumnDef {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} {}", self.name, self.data_type)?;
if let Some(collation) = &self.collation {
write!(f, " COLLATE {collation}")?;
}
for option in &self.options {
write!(f, " {option}")?;
}
Expand Down
85 changes: 82 additions & 3 deletions src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,16 @@ impl fmt::Display for JsonOperator {
}
}

/// Options for `CAST` / `TRY_CAST`
/// BigQuery: <https://cloud.google.com/bigquery/docs/reference/standard-sql/format-elements#formatting_syntax>
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
pub enum CastFormat {
Value(Value),
ValueAtTimeZone(Value, Value),
}

/// An SQL expression of any type.
///
/// The parser does not distinguish between expressions of different types
Expand Down Expand Up @@ -419,6 +429,14 @@ pub enum Expr {
pattern: Box<Expr>,
escape_char: Option<char>,
},
/// MySQL: RLIKE regex or REGEXP regex
RLike {
negated: bool,
expr: Box<Expr>,
pattern: Box<Expr>,
// true for REGEXP, false for RLIKE (no difference in semantics)
regexp: bool,
},
/// Any operation e.g. `foo > ANY(bar)`, comparison operator is one of [=, >, <, =>, =<, !=]
AnyOp {
left: Box<Expr>,
Expand All @@ -437,19 +455,28 @@ pub enum Expr {
Cast {
expr: Box<Expr>,
data_type: DataType,
// Optional CAST(string_expression AS type FORMAT format_string_expression) as used by BigQuery
// https://cloud.google.com/bigquery/docs/reference/standard-sql/format-elements#formatting_syntax
format: Option<CastFormat>,
},
/// TRY_CAST an expression to a different data type e.g. `TRY_CAST(foo AS VARCHAR(123))`
// this differs from CAST in the choice of how to implement invalid conversions
TryCast {
expr: Box<Expr>,
data_type: DataType,
// Optional CAST(string_expression AS type FORMAT format_string_expression) as used by BigQuery
// https://cloud.google.com/bigquery/docs/reference/standard-sql/format-elements#formatting_syntax
format: Option<CastFormat>,
},
/// SAFE_CAST an expression to a different data type e.g. `SAFE_CAST(foo AS FLOAT64)`
// only available for BigQuery: https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators#safe_casting
// this works the same as `TRY_CAST`
SafeCast {
expr: Box<Expr>,
data_type: DataType,
// Optional CAST(string_expression AS type FORMAT format_string_expression) as used by BigQuery
// https://cloud.google.com/bigquery/docs/reference/standard-sql/format-elements#formatting_syntax
format: Option<CastFormat>,
},
/// AT a timestamp to a different timezone e.g. `FROM_UNIXTIME(0) AT TIME ZONE 'UTC-06:00'`
AtTimeZone {
Expand Down Expand Up @@ -597,6 +624,15 @@ pub enum Expr {
},
}

impl fmt::Display for CastFormat {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
CastFormat::Value(v) => write!(f, "{v}"),
CastFormat::ValueAtTimeZone(v, tz) => write!(f, "{v} AT TIME ZONE {tz}"),
}
}
}

impl fmt::Display for Expr {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Expand Down Expand Up @@ -712,6 +748,19 @@ impl fmt::Display for Expr {
pattern
),
},
Expr::RLike {
negated,
expr,
pattern,
regexp,
} => write!(
f,
"{} {}{} {}",
expr,
if *negated { "NOT " } else { "" },
if *regexp { "REGEXP" } else { "RLIKE" },
pattern
),
Expr::SimilarTo {
negated,
expr,
Expand Down Expand Up @@ -753,9 +802,39 @@ impl fmt::Display for Expr {
write!(f, "{op}{expr}")
}
}
Expr::Cast { expr, data_type } => write!(f, "CAST({expr} AS {data_type})"),
Expr::TryCast { expr, data_type } => write!(f, "TRY_CAST({expr} AS {data_type})"),
Expr::SafeCast { expr, data_type } => write!(f, "SAFE_CAST({expr} AS {data_type})"),
Expr::Cast {
expr,
data_type,
format,
} => {
if let Some(format) = format {
write!(f, "CAST({expr} AS {data_type} FORMAT {format})")
} else {
write!(f, "CAST({expr} AS {data_type})")
}
}
Expr::TryCast {
expr,
data_type,
format,
} => {
if let Some(format) = format {
write!(f, "TRY_CAST({expr} AS {data_type} FORMAT {format})")
} else {
write!(f, "TRY_CAST({expr} AS {data_type})")
}
}
Expr::SafeCast {
expr,
data_type,
format,
} => {
if let Some(format) = format {
write!(f, "SAFE_CAST({expr} AS {data_type} FORMAT {format})")
} else {
write!(f, "SAFE_CAST({expr} AS {data_type})")
}
}
Expr::Extract { field, expr } => write!(f, "EXTRACT({field} FROM {expr})"),
Expr::Ceil { expr, field } => {
if field == &DateTimeField::NoDateTime {
Expand Down
7 changes: 6 additions & 1 deletion src/ast/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ impl fmt::Display for SetExpr {
SetQuantifier::All
| SetQuantifier::Distinct
| SetQuantifier::ByName
| SetQuantifier::AllByName => write!(f, " {set_quantifier}")?,
| SetQuantifier::AllByName
| SetQuantifier::DistinctByName => write!(f, " {set_quantifier}")?,
SetQuantifier::None => write!(f, "{set_quantifier}")?,
}
write!(f, " {right}")?;
Expand Down Expand Up @@ -160,6 +161,7 @@ pub enum SetQuantifier {
Distinct,
ByName,
AllByName,
DistinctByName,
None,
}

Expand All @@ -170,6 +172,7 @@ impl fmt::Display for SetQuantifier {
SetQuantifier::Distinct => write!(f, "DISTINCT"),
SetQuantifier::ByName => write!(f, "BY NAME"),
SetQuantifier::AllByName => write!(f, "ALL BY NAME"),
SetQuantifier::DistinctByName => write!(f, "DISTINCT BY NAME"),
SetQuantifier::None => write!(f, ""),
}
}
Expand Down Expand Up @@ -431,11 +434,13 @@ pub struct WildcardAdditionalOptions {
/// `[EXCLUDE...]`.
pub opt_exclude: Option<ExcludeSelectItem>,
/// `[EXCEPT...]`.
/// Clickhouse syntax: <https://clickhouse.com/docs/en/sql-reference/statements/select#except>
pub opt_except: Option<ExceptSelectItem>,
/// `[RENAME ...]`.
pub opt_rename: Option<RenameSelectItem>,
/// `[REPLACE]`
/// BigQuery syntax: <https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#select_replace>
/// Clickhouse syntax: <https://clickhouse.com/docs/en/sql-reference/statements/select#replace>
pub opt_replace: Option<ReplaceSelectItem>,
}

Expand Down
2 changes: 2 additions & 0 deletions src/keywords.rs
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,7 @@ define_keywords!(
REFERENCES,
REFERENCING,
REGCLASS,
REGEXP,
REGR_AVGX,
REGR_AVGY,
REGR_COUNT,
Expand All @@ -524,6 +525,7 @@ define_keywords!(
RETURNS,
REVOKE,
RIGHT,
RLIKE,
ROLE,
ROLLBACK,
ROLLUP,
Expand Down
Loading

0 comments on commit 01ab7c8

Please sign in to comment.