Skip to content

Commit

Permalink
Document scopes a bit more
Browse files Browse the repository at this point in the history
  • Loading branch information
emk committed Dec 5, 2024
1 parent 2600412 commit 3e68d88
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ pub struct Distinct {
/// [ expression. ]*
/// [ EXCEPT ( column_name [, ...] ) ]
/// [ REPLACE ( expression [ AS ] column_name [, ...] ) ]
///
///
/// select_expression:
/// expression [ [ AS ] alias ]
/// ```
Expand Down Expand Up @@ -879,7 +879,7 @@ pub struct IntervalExpression {
pub date_part: DatePart,
}

/// A date part in an `INTERVAL` expression, or in the special date functions.S
/// A date part in an `INTERVAL` expression, or in the special date functions.
#[derive(Clone, Debug, Drive, DriveMut, Emit, EmitDefault, Spanned, ToTokens)]
pub struct DatePart {
pub date_part_token: PseudoKeyword,
Expand Down
34 changes: 34 additions & 0 deletions src/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ use crate::{
pub type ScopeValue = Type;

/// Common interface to all things that support a scope-like `get` function.
///
/// SQL has multiple kinds of scopes, including:
///
/// - [`Scope`] (often wrapped by [`ScopeHandle`] for reference counting), which
/// works more-or-less like a scope in a typical programming language. This
/// has a few unusual features: names can be hidden, or looking up a name
/// might return an error.
/// - [`ColumnSetScope`] (wrapping a [`ColumnSet`]), which implements the
/// special rules for looking up column names in SQL.
pub trait ScopeGet {
/// Get the [`ScopeValue`] associated with `name`.
///
Expand Down Expand Up @@ -294,6 +303,12 @@ TRIM = Fn(STRING) -> STRING;
UPPER = Fn(STRING) -> STRING;
";

/// The name of a column in a [`ColumnSet`].
///
/// In SQL, `t.x` may also be referred to as `x` (if `x` is unambiguous). But
/// depending on how the [`ColumnSet`] was created, a column name may not always
/// have a table name, thanks to things like `USING`. See
/// [`ColumnSet::join_using`].
#[derive(Clone, Debug, PartialEq)]
pub struct ColumnSetColumnName {
table: Option<Name>,
Expand Down Expand Up @@ -337,6 +352,20 @@ impl fmt::Display for ColumnSetColumnName {
}
}

/// A column in a [`ColumnSet`].
///
/// This may be unnamed, because SQL allows `SELECT` clauses to contain
/// anonymous columns. It even allows referring to columns by their ordinal
/// position in the `SELECT` clause!
///
/// ```sql
/// SELECT
/// SUM(goals_scored) AS total_goals,
/// UPPER(last_name),
/// UPPER(first_name)
/// FROM players
/// GROUP BY 2, 3;
/// ```
#[derive(Clone, Debug, PartialEq)]
pub struct ColumnSetColumn {
column_name: Option<ColumnSetColumnName>,
Expand All @@ -362,6 +391,11 @@ impl fmt::Display for ColumnSetColumn {
/// A set of columns and types.
///
/// This is output by a `FROM`, `JOIN`, `GROUP BY` or `PARTITION BY` clause.
///
/// A [`ColumnSet`] also acts as a specialized kind of scope, different from a
/// regular [`Scope`] because of various bits of magic in how SQL looks up
/// names. Normally, you will use a [`ColumnSetScope`], which allows seeing both
/// column names _and_ names from the parent scope.
#[derive(Clone, Debug, PartialEq)]
pub struct ColumnSet {
columns: Vec<ColumnSetColumn>,
Expand Down

0 comments on commit 3e68d88

Please sign in to comment.