Skip to content

Commit efc1e69

Browse files
committed
add more tests and documentation
1 parent 0b5c12e commit efc1e69

File tree

3 files changed

+53
-4
lines changed

3 files changed

+53
-4
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,25 @@ This outputs
4040
AST: [Query(Query { ctes: [], body: Select(Select { distinct: false, projection: [UnnamedExpr(Identifier("a")), UnnamedExpr(Identifier("b")), UnnamedExpr(Value(Long(123))), UnnamedExpr(Function(Function { name: ObjectName(["myfunc"]), args: [Identifier("b")], over: None, distinct: false }))], from: [TableWithJoins { relation: Table { name: ObjectName(["table_1"]), alias: None, args: [], with_hints: [] }, joins: [] }], selection: Some(BinaryOp { left: BinaryOp { left: Identifier("a"), op: Gt, right: Identifier("b") }, op: And, right: BinaryOp { left: Identifier("b"), op: Lt, right: Value(Long(100)) } }), group_by: [], having: None }), order_by: [OrderByExpr { expr: Identifier("a"), asc: Some(false) }, OrderByExpr { expr: Identifier("b"), asc: None }], limit: None, offset: None, fetch: None })]
4141
```
4242

43+
### Analyzing and transforming the AST
44+
45+
Once you have an abstract syntax tree, you can analyze and transform it
46+
using the optional [`derive-visitor`](https://github.com/nikis05/derive-visitor) feature.
47+
48+
For instance, if you want to rename all identifiers in a query:
49+
50+
```rust
51+
use sqlparser::{dialect::GenericDialect, parser::Parser, ast::Ident};
52+
use derive_visitor::{visitor_enter_fn_mut, DriveMut};
53+
54+
let mut statements = Parser::parse_sql(&GenericDialect, "select x").unwrap();
55+
statements[0].drive_mut(&mut visitor_enter_fn_mut(|ident: &mut Ident| {
56+
ident.value = ident.value.replace("x", "y");
57+
}));
58+
assert_eq!(statements[0].to_string(), "SELECT y");
59+
```
60+
61+
4362
## Command line
4463
To parse a file and dump the results as JSON:
4564
```

src/lib.rs

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,31 @@
2525
//!
2626
//! let sql = "SELECT a, b, 123, myfunc(b) \
2727
//! FROM table_1 \
28-
//! WHERE a > b AND b < 100 \
28+
//! WHERE a > b AND b < $x \
2929
//! ORDER BY a DESC, b";
3030
//!
31-
//! let ast = Parser::parse_sql(&dialect, sql).unwrap();
31+
//! let mut ast = Parser::parse_sql(&dialect, sql).unwrap();
3232
//!
3333
//! println!("AST: {:?}", ast);
34+
//!
35+
//! # #[cfg(feature = "derive-visitor")] {
36+
//! // You can activate the derive-visitor feature
37+
//! // to apply transforms to all AST nodes of a given type
38+
//!
39+
//! use derive_visitor::{visitor_enter_fn_mut, DriveMut};
40+
//! use sqlparser::ast;
41+
//!
42+
//! ast[0].drive_mut(&mut visitor_enter_fn_mut(|value: &mut ast::Value| {
43+
//! if let ast::Value::Placeholder(ref mut placeholder) = value {
44+
//! *placeholder += "_transformed";
45+
//! }
46+
//! }));
47+
//!
48+
//! assert_eq!(
49+
//! ast[0].to_string(),
50+
//! "SELECT a, b, 123, myfunc(b) FROM table_1 WHERE a > b AND b < $x_transformed ORDER BY a DESC, b"
51+
//! );
52+
//! # }
3453
//! ```
3554
3655
#![cfg_attr(not(feature = "std"), no_std)]

tests/sqlparser_visitor.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
#[cfg(feature = "derive-visitor")]
22
mod test {
3-
use derive_visitor::{visitor_enter_fn_mut, DriveMut, Drive, Visitor};
3+
use derive_visitor::{visitor_enter_fn_mut, Drive, DriveMut, Visitor};
44
use sqlparser::ast;
55
use sqlparser::ast::TableFactor::Table;
6-
use sqlparser::ast::{Ident, Join, JoinConstraint, JoinOperator, ObjectName, TableFactor, Value};
6+
use sqlparser::ast::{
7+
Ident, Join, JoinConstraint, JoinOperator, ObjectName, TableFactor, Value,
8+
};
79
use sqlparser::dialect::GenericDialect;
810
use sqlparser::parser::Parser;
911

@@ -79,4 +81,13 @@ mod test {
7981
ast[0].drive(&mut counter);
8082
assert_eq!(counter.0, 2, "There are 2 placeholders in the query");
8183
}
84+
85+
#[test]
86+
fn test_readme_example() {
87+
let mut statements = Parser::parse_sql(&GenericDialect, "select x").unwrap();
88+
statements[0].drive_mut(&mut visitor_enter_fn_mut(|ident: &mut Ident| {
89+
ident.value = ident.value.replace("x", "y");
90+
}));
91+
assert_eq!(statements[0].to_string(), "SELECT y");
92+
}
8293
}

0 commit comments

Comments
 (0)