Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
name: CI

on:
push:
branches: [main]
paths:
- "packages/**"
- "Cargo.toml"
- "Cargo.lock"
- ".github/workflows/ci.yml"
- "!**.md"
pull_request:
branches: [main]
paths:
- "packages/**"
- "Cargo.toml"
- "Cargo.lock"
- ".github/workflows/ci.yml"
- "!**.md"
workflow_dispatch:

env:
RUSTFLAGS: "-D warnings"
RUST_BACKTRACE: full
CARGO_TERM_COLOR: always

jobs:
fmt:
name: Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
components: rustfmt

- name: Check formatting
run: cargo fmt --all --check

clippy:
name: Clippy
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable
components: clippy

- name: Run clippy
run: cargo clippy --workspace --all-targets --all-features -- -D warnings

test:
name: Test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
toolchain: stable

- name: Run tests
run: cargo test --workspace --all-features
22 changes: 9 additions & 13 deletions packages/sqltk-codegen/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,25 +105,21 @@ impl SqlParserAstAnalyser {
trait_: Some((_, trait_path, _)),
self_ty,
..
}) => {
if is_impl_of_sqlparser_visit(trait_path) {
let type_path = syn_type_to_path(path, self_ty.deref());
if let Some(ty) = self
.internal_types
.get_mut(&InternalTypePath(type_path.clone()))
{
ty.has_visit_impl = true;
}
}) if is_impl_of_sqlparser_visit(trait_path) => {
let type_path = syn_type_to_path(path, self_ty.deref());
if let Some(ty) = self
.internal_types
.get_mut(&InternalTypePath(type_path.clone()))
{
ty.has_visit_impl = true;
}
}
Item::Use(ItemUse {
tree,
vis: Visibility::Public(_),
..
}) => {
if in_public_mod {
self.walk_use_tree(tree, &mut path.clone());
}
}) if in_public_mod => {
self.walk_use_tree(tree, &mut path.clone());
}
_ => {}
}
Expand Down
6 changes: 2 additions & 4 deletions packages/sqltk-codegen/src/sqlparser_node_extractor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ use super::meta::SqlParserMeta;
use super::*;

pub fn extract() -> SqlParserMeta {
let sqlparser_features = vec!["visitor", "bigdecimal"];
let sqlparser_features = ["visitor", "bigdecimal"];

let sql_parser_dir = Path::new(
std::env::var("CARGO_MANIFEST_DIR").unwrap().as_str()
)
let sql_parser_dir = Path::new(std::env::var("CARGO_MANIFEST_DIR").unwrap().as_str())
.join("..")
.join("sqltk-parser");

Expand Down
8 changes: 2 additions & 6 deletions packages/sqltk-parser/src/ast/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2665,7 +2665,9 @@ impl fmt::Display for Declare {
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Hash)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "visitor", derive(Visit, VisitMut))]
#[derive(Default)]
pub enum CreateTableOptions {
#[default]
None,
/// Options specified using the `WITH` keyword.
/// e.g. `WITH (description = "123")`
Expand Down Expand Up @@ -2694,12 +2696,6 @@ pub enum CreateTableOptions {
TableProperties(Vec<SqlOption>),
}

impl Default for CreateTableOptions {
fn default() -> Self {
Self::None
}
}

impl fmt::Display for CreateTableOptions {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Expand Down
5 changes: 5 additions & 0 deletions packages/sqltk-parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@

#![cfg_attr(not(feature = "std"), no_std)]
#![allow(clippy::upper_case_acronyms)]
// The following lints are allowed to minimise source divergence from the
// upstream sqlparser-rs fork.
#![allow(clippy::empty_line_after_outer_attr)]
#![allow(clippy::large_enum_variant)]
#![allow(clippy::unnecessary_unwrap)]

// Allow proc-macros to find this crate
extern crate self as sqltk_parser;
Expand Down
162 changes: 74 additions & 88 deletions packages/sqltk-parser/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,10 +471,10 @@ impl<'a> Parser<'a> {
Token::EOF => break,

// end of statement
Token::Word(word) => {
if expecting_statement_delimiter && word.keyword == Keyword::END {
break;
}
Token::Word(word)
if expecting_statement_delimiter && word.keyword == Keyword::END =>
{
break;
}
_ => {}
}
Expand Down Expand Up @@ -1150,32 +1150,31 @@ impl<'a> Parser<'a> {

let next_token = self.next_token();
match next_token.token {
t @ (Token::Word(_) | Token::SingleQuotedString(_)) => {
if self.peek_token().token == Token::Period {
let mut id_parts: Vec<Ident> = vec![match t {
Token::Word(w) => w.into_ident(next_token.span),
Token::SingleQuotedString(s) => Ident::with_quote('\'', s),
_ => unreachable!(), // We matched above
}];

while self.consume_token(&Token::Period) {
let next_token = self.next_token();
match next_token.token {
Token::Word(w) => id_parts.push(w.into_ident(next_token.span)),
Token::SingleQuotedString(s) => {
// SQLite has single-quoted identifiers
id_parts.push(Ident::with_quote('\'', s))
}
Token::Mul => {
return Ok(Expr::QualifiedWildcard(
ObjectName::from(id_parts),
AttachedToken(next_token),
));
}
_ => {
return self
.expected("an identifier or a '*' after '.'", next_token);
}
t @ (Token::Word(_) | Token::SingleQuotedString(_))
if self.peek_token().token == Token::Period =>
{
let mut id_parts: Vec<Ident> = vec![match t {
Token::Word(w) => w.into_ident(next_token.span),
Token::SingleQuotedString(s) => Ident::with_quote('\'', s),
_ => unreachable!(), // We matched above
}];

while self.consume_token(&Token::Period) {
let next_token = self.next_token();
match next_token.token {
Token::Word(w) => id_parts.push(w.into_ident(next_token.span)),
Token::SingleQuotedString(s) => {
// SQLite has single-quoted identifiers
id_parts.push(Ident::with_quote('\'', s))
}
Token::Mul => {
return Ok(Expr::QualifiedWildcard(
ObjectName::from(id_parts),
AttachedToken(next_token),
));
}
_ => {
return self.expected("an identifier or a '*' after '.'", next_token);
}
}
}
Expand Down Expand Up @@ -2554,10 +2553,7 @@ impl<'a> Parser<'a> {
self.expect_token(&Token::LParen)?;
let mut trim_where = None;
if let Token::Word(word) = self.peek_token().token {
if [Keyword::BOTH, Keyword::LEADING, Keyword::TRAILING]
.iter()
.any(|d| word.keyword == *d)
{
if [Keyword::BOTH, Keyword::LEADING, Keyword::TRAILING].contains(&word.keyword) {
trim_where = Some(self.parse_trim_where()?);
}
}
Expand Down Expand Up @@ -4517,10 +4513,10 @@ impl<'a> Parser<'a> {
loop {
match &self.peek_nth_token_ref(0).token {
Token::EOF => break,
Token::Word(w) => {
if w.quote_style.is_none() && terminal_keywords.contains(&w.keyword) {
break;
}
Token::Word(w)
if w.quote_style.is_none() && terminal_keywords.contains(&w.keyword) =>
{
break;
}
_ => {}
}
Expand Down Expand Up @@ -6982,70 +6978,60 @@ impl<'a> Parser<'a> {
Keyword::LINES,
Keyword::NULL,
]) {
Some(Keyword::FIELDS) => {
if self.parse_keywords(&[Keyword::TERMINATED, Keyword::BY]) {
Some(Keyword::FIELDS)
if self.parse_keywords(&[Keyword::TERMINATED, Keyword::BY]) =>
{
row_delimiters.push(HiveRowDelimiter {
delimiter: HiveDelimiter::FieldsTerminatedBy,
char: self.parse_identifier()?,
});

if self.parse_keywords(&[Keyword::ESCAPED, Keyword::BY]) {
row_delimiters.push(HiveRowDelimiter {
delimiter: HiveDelimiter::FieldsTerminatedBy,
delimiter: HiveDelimiter::FieldsEscapedBy,
char: self.parse_identifier()?,
});

if self.parse_keywords(&[Keyword::ESCAPED, Keyword::BY]) {
row_delimiters.push(HiveRowDelimiter {
delimiter: HiveDelimiter::FieldsEscapedBy,
char: self.parse_identifier()?,
});
}
} else {
break;
}
}
Some(Keyword::COLLECTION) => {
Some(Keyword::COLLECTION)
if self.parse_keywords(&[
Keyword::ITEMS,
Keyword::TERMINATED,
Keyword::BY,
]) {
row_delimiters.push(HiveRowDelimiter {
delimiter: HiveDelimiter::CollectionItemsTerminatedBy,
char: self.parse_identifier()?,
});
} else {
break;
}
]) =>
{
row_delimiters.push(HiveRowDelimiter {
delimiter: HiveDelimiter::CollectionItemsTerminatedBy,
char: self.parse_identifier()?,
});
}
Some(Keyword::MAP) => {
Some(Keyword::MAP)
if self.parse_keywords(&[
Keyword::KEYS,
Keyword::TERMINATED,
Keyword::BY,
]) {
row_delimiters.push(HiveRowDelimiter {
delimiter: HiveDelimiter::MapKeysTerminatedBy,
char: self.parse_identifier()?,
});
} else {
break;
}
]) =>
{
row_delimiters.push(HiveRowDelimiter {
delimiter: HiveDelimiter::MapKeysTerminatedBy,
char: self.parse_identifier()?,
});
}
Some(Keyword::LINES) => {
if self.parse_keywords(&[Keyword::TERMINATED, Keyword::BY]) {
row_delimiters.push(HiveRowDelimiter {
delimiter: HiveDelimiter::LinesTerminatedBy,
char: self.parse_identifier()?,
});
} else {
break;
}
Some(Keyword::LINES)
if self.parse_keywords(&[Keyword::TERMINATED, Keyword::BY]) =>
{
row_delimiters.push(HiveRowDelimiter {
delimiter: HiveDelimiter::LinesTerminatedBy,
char: self.parse_identifier()?,
});
}
Some(Keyword::NULL) => {
if self.parse_keywords(&[Keyword::DEFINED, Keyword::AS]) {
row_delimiters.push(HiveRowDelimiter {
delimiter: HiveDelimiter::NullDefinedAs,
char: self.parse_identifier()?,
});
} else {
break;
}
Some(Keyword::NULL)
if self.parse_keywords(&[Keyword::DEFINED, Keyword::AS]) =>
{
row_delimiters.push(HiveRowDelimiter {
delimiter: HiveDelimiter::NullDefinedAs,
char: self.parse_identifier()?,
});
}
_ => {
break;
Expand Down Expand Up @@ -8926,10 +8912,10 @@ impl<'a> Parser<'a> {
}),
}))
} else {
return self.expected_ref(
self.expected_ref(
"{RENAME TO | { RENAME | ADD } VALUE}",
self.peek_token_ref(),
);
)
}
}

Expand Down
Loading
Loading