Merge pull request #88 from benesch/hash

Implement Hash on all AST nodes
This commit is contained in:
Nikhil Benesch 2019-06-03 11:29:31 -04:00 committed by GitHub
commit 057518b377
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 34 additions and 31 deletions

View file

@ -20,6 +20,7 @@ path = "src/lib.rs"
[dependencies] [dependencies]
log = "0.4.5" log = "0.4.5"
ordered-float = "1.0.2"
[dev-dependencies] [dev-dependencies]
simple_logger = "1.0.1" simple_logger = "1.0.1"

View file

@ -3,7 +3,7 @@
use super::{ASTNode, SQLIdent, SQLObjectName}; use super::{ASTNode, SQLIdent, SQLObjectName};
/// An `ALTER TABLE` (`SQLStatement::SQLAlterTable`) operation /// An `ALTER TABLE` (`SQLStatement::SQLAlterTable`) operation
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub enum AlterTableOperation { pub enum AlterTableOperation {
/// `ADD <table_constraint>` /// `ADD <table_constraint>`
AddConstraint(TableConstraint), AddConstraint(TableConstraint),
@ -22,7 +22,7 @@ impl ToString for AlterTableOperation {
/// A table-level constraint, specified in a `CREATE TABLE` or an /// A table-level constraint, specified in a `CREATE TABLE` or an
/// `ALTER TABLE ADD <constraint>` statement. /// `ALTER TABLE ADD <constraint>` statement.
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub enum TableConstraint { pub enum TableConstraint {
/// `[ CONSTRAINT <name> ] { PRIMARY KEY | UNIQUE } (<columns>)` /// `[ CONSTRAINT <name> ] { PRIMARY KEY | UNIQUE } (<columns>)`
Unique { Unique {

View file

@ -46,7 +46,7 @@ pub type SQLIdent = String;
/// The parser does not distinguish between expressions of different types /// The parser does not distinguish between expressions of different types
/// (e.g. boolean vs string), so the caller must handle expressions of /// (e.g. boolean vs string), so the caller must handle expressions of
/// inappropriate type, like `WHERE 1` or `SELECT 1=1`, as necessary. /// inappropriate type, like `WHERE 1` or `SELECT 1=1`, as necessary.
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub enum ASTNode { pub enum ASTNode {
/// Identifier e.g. table name or column name /// Identifier e.g. table name or column name
SQLIdentifier(SQLIdent), SQLIdentifier(SQLIdent),
@ -218,7 +218,7 @@ impl ToString for ASTNode {
} }
/// A window specification (i.e. `OVER (PARTITION BY .. ORDER BY .. etc.)`) /// A window specification (i.e. `OVER (PARTITION BY .. ORDER BY .. etc.)`)
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub struct SQLWindowSpec { pub struct SQLWindowSpec {
pub partition_by: Vec<ASTNode>, pub partition_by: Vec<ASTNode>,
pub order_by: Vec<SQLOrderByExpr>, pub order_by: Vec<SQLOrderByExpr>,
@ -262,7 +262,7 @@ impl ToString for SQLWindowSpec {
/// Specifies the data processed by a window function, e.g. /// Specifies the data processed by a window function, e.g.
/// `RANGE UNBOUNDED PRECEDING` or `ROWS BETWEEN 5 PRECEDING AND CURRENT ROW`. /// `RANGE UNBOUNDED PRECEDING` or `ROWS BETWEEN 5 PRECEDING AND CURRENT ROW`.
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub struct SQLWindowFrame { pub struct SQLWindowFrame {
pub units: SQLWindowFrameUnits, pub units: SQLWindowFrameUnits,
pub start_bound: SQLWindowFrameBound, pub start_bound: SQLWindowFrameBound,
@ -271,7 +271,7 @@ pub struct SQLWindowFrame {
// TBD: EXCLUDE // TBD: EXCLUDE
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub enum SQLWindowFrameUnits { pub enum SQLWindowFrameUnits {
Rows, Rows,
Range, Range,
@ -304,7 +304,7 @@ impl FromStr for SQLWindowFrameUnits {
} }
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub enum SQLWindowFrameBound { pub enum SQLWindowFrameBound {
/// "CURRENT ROW" /// "CURRENT ROW"
CurrentRow, CurrentRow,
@ -329,7 +329,7 @@ impl ToString for SQLWindowFrameBound {
/// A top-level statement (SELECT, INSERT, CREATE, etc.) /// A top-level statement (SELECT, INSERT, CREATE, etc.)
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub enum SQLStatement { pub enum SQLStatement {
/// SELECT /// SELECT
SQLQuery(Box<SQLQuery>), SQLQuery(Box<SQLQuery>),
@ -531,7 +531,7 @@ impl ToString for SQLStatement {
} }
/// A name of a table, view, custom type, etc., possibly multi-part, i.e. db.schema.obj /// A name of a table, view, custom type, etc., possibly multi-part, i.e. db.schema.obj
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub struct SQLObjectName(pub Vec<SQLIdent>); pub struct SQLObjectName(pub Vec<SQLIdent>);
impl ToString for SQLObjectName { impl ToString for SQLObjectName {
@ -541,7 +541,7 @@ impl ToString for SQLObjectName {
} }
/// SQL assignment `foo = expr` as used in SQLUpdate /// SQL assignment `foo = expr` as used in SQLUpdate
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub struct SQLAssignment { pub struct SQLAssignment {
id: SQLIdent, id: SQLIdent,
value: ASTNode, value: ASTNode,
@ -554,7 +554,7 @@ impl ToString for SQLAssignment {
} }
/// SQL column definition /// SQL column definition
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub struct SQLColumnDef { pub struct SQLColumnDef {
pub name: SQLIdent, pub name: SQLIdent,
pub data_type: SQLType, pub data_type: SQLType,
@ -584,7 +584,7 @@ impl ToString for SQLColumnDef {
} }
/// SQL function /// SQL function
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub struct SQLFunction { pub struct SQLFunction {
pub name: SQLObjectName, pub name: SQLObjectName,
pub args: Vec<ASTNode>, pub args: Vec<ASTNode>,
@ -609,7 +609,7 @@ impl ToString for SQLFunction {
} }
/// External table's available file format /// External table's available file format
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub enum FileFormat { pub enum FileFormat {
TEXTFILE, TEXTFILE,
SEQUENCEFILE, SEQUENCEFILE,
@ -658,7 +658,7 @@ impl FromStr for FileFormat {
} }
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub enum SQLObjectType { pub enum SQLObjectType {
Table, Table,
View, View,

View file

@ -2,7 +2,7 @@ use super::*;
/// The most complete variant of a `SELECT` query expression, optionally /// The most complete variant of a `SELECT` query expression, optionally
/// including `WITH`, `UNION` / other set operations, and `ORDER BY`. /// including `WITH`, `UNION` / other set operations, and `ORDER BY`.
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub struct SQLQuery { pub struct SQLQuery {
/// WITH (common table expressions, or CTEs) /// WITH (common table expressions, or CTEs)
pub ctes: Vec<Cte>, pub ctes: Vec<Cte>,
@ -44,7 +44,7 @@ impl ToString for SQLQuery {
/// A node in a tree, representing a "query body" expression, roughly: /// A node in a tree, representing a "query body" expression, roughly:
/// `SELECT ... [ {UNION|EXCEPT|INTERSECT} SELECT ...]` /// `SELECT ... [ {UNION|EXCEPT|INTERSECT} SELECT ...]`
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub enum SQLSetExpr { pub enum SQLSetExpr {
/// Restricted SELECT .. FROM .. HAVING (no ORDER BY or set operations) /// Restricted SELECT .. FROM .. HAVING (no ORDER BY or set operations)
Select(Box<SQLSelect>), Select(Box<SQLSelect>),
@ -85,7 +85,7 @@ impl ToString for SQLSetExpr {
} }
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub enum SQLSetOperator { pub enum SQLSetOperator {
Union, Union,
Except, Except,
@ -105,7 +105,7 @@ impl ToString for SQLSetOperator {
/// A restricted variant of `SELECT` (without CTEs/`ORDER BY`), which may /// A restricted variant of `SELECT` (without CTEs/`ORDER BY`), which may
/// appear either as the only body item of an `SQLQuery`, or as an operand /// appear either as the only body item of an `SQLQuery`, or as an operand
/// to a set operation like `UNION`. /// to a set operation like `UNION`.
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub struct SQLSelect { pub struct SQLSelect {
pub distinct: bool, pub distinct: bool,
/// projection expressions /// projection expressions
@ -152,7 +152,7 @@ impl ToString for SQLSelect {
/// The names in the column list before `AS`, when specified, replace the names /// The names in the column list before `AS`, when specified, replace the names
/// of the columns returned by the query. The parser does not validate that the /// of the columns returned by the query. The parser does not validate that the
/// number of columns in the query matches the number of columns in the query. /// number of columns in the query matches the number of columns in the query.
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub struct Cte { pub struct Cte {
pub alias: SQLIdent, pub alias: SQLIdent,
pub query: SQLQuery, pub query: SQLQuery,
@ -170,7 +170,7 @@ impl ToString for Cte {
} }
/// One item of the comma-separated list following `SELECT` /// One item of the comma-separated list following `SELECT`
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub enum SQLSelectItem { pub enum SQLSelectItem {
/// Any expression, not followed by `[ AS ] alias` /// Any expression, not followed by `[ AS ] alias`
UnnamedExpression(ASTNode), UnnamedExpression(ASTNode),
@ -196,7 +196,7 @@ impl ToString for SQLSelectItem {
} }
/// A table name or a parenthesized subquery with an optional alias /// A table name or a parenthesized subquery with an optional alias
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub enum TableFactor { pub enum TableFactor {
Table { Table {
name: SQLObjectName, name: SQLObjectName,
@ -255,7 +255,7 @@ impl ToString for TableFactor {
} }
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub struct Join { pub struct Join {
pub relation: TableFactor, pub relation: TableFactor,
pub join_operator: JoinOperator, pub join_operator: JoinOperator,
@ -307,7 +307,7 @@ impl ToString for Join {
} }
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub enum JoinOperator { pub enum JoinOperator {
Inner(JoinConstraint), Inner(JoinConstraint),
LeftOuter(JoinConstraint), LeftOuter(JoinConstraint),
@ -317,7 +317,7 @@ pub enum JoinOperator {
Cross, Cross,
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub enum JoinConstraint { pub enum JoinConstraint {
On(ASTNode), On(ASTNode),
Using(Vec<SQLIdent>), Using(Vec<SQLIdent>),
@ -325,7 +325,7 @@ pub enum JoinConstraint {
} }
/// SQL ORDER BY expression /// SQL ORDER BY expression
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub struct SQLOrderByExpr { pub struct SQLOrderByExpr {
pub expr: ASTNode, pub expr: ASTNode,
pub asc: Option<bool>, pub asc: Option<bool>,
@ -341,7 +341,7 @@ impl ToString for SQLOrderByExpr {
} }
} }
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub struct Fetch { pub struct Fetch {
pub with_ties: bool, pub with_ties: bool,
pub percent: bool, pub percent: bool,

View file

@ -1,5 +1,5 @@
/// SQL Operator /// SQL Operator
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub enum SQLOperator { pub enum SQLOperator {
Plus, Plus,
Minus, Minus,

View file

@ -1,7 +1,7 @@
use super::SQLObjectName; use super::SQLObjectName;
/// SQL data types /// SQL data types
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub enum SQLType { pub enum SQLType {
/// Fixed-length character type e.g. CHAR(10) /// Fixed-length character type e.g. CHAR(10)
Char(Option<u64>), Char(Option<u64>),

View file

@ -1,10 +1,12 @@
use ordered_float::OrderedFloat;
/// Primitive SQL values such as number and string /// Primitive SQL values such as number and string
#[derive(Debug, Clone, PartialEq)] #[derive(Debug, Clone, PartialEq, Hash)]
pub enum Value { pub enum Value {
/// Unsigned integer value /// Unsigned integer value
Long(u64), Long(u64),
/// Unsigned floating point value /// Unsigned floating point value
Double(f64), Double(OrderedFloat<f64>),
/// 'string value' /// 'string value'
SingleQuotedString(String), SingleQuotedString(String),
/// N'string value' /// N'string value'

View file

@ -1031,7 +1031,7 @@ impl Parser {
} }
}, },
Token::Number(ref n) if n.contains('.') => match n.parse::<f64>() { Token::Number(ref n) if n.contains('.') => match n.parse::<f64>() {
Ok(n) => Ok(Value::Double(n)), Ok(n) => Ok(Value::Double(n.into())),
Err(e) => parser_err!(format!("Could not parse '{}' as f64: {}", n, e)), Err(e) => parser_err!(format!("Could not parse '{}' as f64: {}", n, e)),
}, },
Token::Number(ref n) => match n.parse::<u64>() { Token::Number(ref n) => match n.parse::<u64>() {