Skip to main content

inbq/
lib.rs

1//! # inbq
2//!
3//! A library for parsing BigQuery queries and extracting schema-aware, column-level lineage.
4//!
5//! # Features
6//!
7//! - Parse BigQuery queries into well-structured ASTs with easy-to-navigate nodes.
8//! - Extract schema-aware, column-level lineage.
9//! - Trace data flow through nested structs and arrays.
10//! - Capture referenced columns and the specific query components (e.g., select, where, join) they appear in.
11//! - Process both single and multi-statement queries with procedural language constructs.
12//! - Combines the performance of a Rust core with the ease of a Python API through efficient, low-overhead bindings.
13//!
14//! # Example
15//!
16//! ```rust,no_run
17//! use inbq::{
18//!     lineage::{
19//!         catalog::{Catalog, Column, SchemaObject, SchemaObjectKind},
20//!         extract_lineage,
21//!     },
22//!     parser::Parser,
23//!     scanner::Scanner,
24//! };
25//!
26//! fn column(name: &str, dtype: &str) -> Column {
27//!     Column {
28//!         name: name.to_owned(),
29//!         dtype: dtype.to_owned(),
30//!     }
31//! }
32//!
33//! fn main() -> anyhow::Result<()> {
34//!     env_logger::init();
35//!
36//!     let sql = r#""
37//!         declare default_val float64 default (select min(val) from project.dataset.out);
38//!
39//!         insert into `project.dataset.out`
40//!         select
41//!             id,
42//!             if(x is null or s.x is null, default_val, x + s.x)
43//!         from `project.dataset.t1` inner join `project.dataset.t2` using (id)
44//!         where s.source = "baz";
45//!     ""#;
46//!     let mut scanner = Scanner::new(sql);
47//!     scanner.scan()?;
48//!     let mut parser = Parser::new(scanner.tokens());
49//!     let ast = parser.parse()?;
50//!     println!("Syntax Tree: {:?}", ast);
51//!
52//!     let data_catalog = Catalog {
53//!         schema_objects: vec![
54//!             SchemaObject {
55//!                 name: "project.dataset.out".to_owned(),
56//!                 kind: SchemaObjectKind::Table {
57//!                     columns: vec![column("id", "int64"), column("val", "int64")],
58//!                 },
59//!             },
60//!             SchemaObject {
61//!                 name: "project.dataset.t1".to_owned(),
62//!                 kind: SchemaObjectKind::Table {
63//!                     columns: vec![column("id", "int64"), column("x", "float64")],
64//!                 },
65//!             },
66//!             SchemaObject {
67//!                 name: "project.dataset.t2".to_owned(),
68//!                 kind: SchemaObjectKind::Table {
69//!                     columns: vec![
70//!                         column("id", "int64"),
71//!                         column("s", "struct<source string, x float64>"),
72//!                     ],
73//!                 },
74//!             },
75//!         ],
76//!     };
77//!
78//!     let lineage = extract_lineage(&[&ast], &data_catalog, false, true)
79//!         .pop()
80//!         .unwrap()?;
81//!
82//!     println!("\nLineage: {:?}", lineage.lineage);
83//!     println!("\nReferenced columns: {:?}", lineage.referenced_columns);
84//!     Ok(())
85//! }
86//! ```
87mod arena;
88pub mod ast;
89pub mod lineage;
90pub mod parser;
91pub mod scanner;
92
93#[doc(hidden)]
94pub mod test_utils;