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;