Skip to content

Latest commit

ย 

History

381 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

libdplyr

A Rust-based transpiler that converts R dplyr syntax to SQL queries.

Crates.io Documentation License CI codecov

Overview

libdplyr enables R users to write database queries using familiar dplyr syntax and converts them to efficient SQL for execution. It supports multiple SQL dialects (PostgreSQL, MySQL, SQLite, DuckDB) for use across various database environments.

โœจ Key Features

  • dplyr Syntax Support: Core support for select(), distinct(), filter(), mutate(), arrange(), group_by(), summarise(), and limited count()/tally()
  • Pipeline Operations: Chain operations using the %>% pipe operator
  • Multiple Dialects: PostgreSQL, MySQL, SQLite, DuckDB
  • Performance: High-performance Rust implementation
  • Dual Mode: Use as a Rust library or standalone CLI tool

๐Ÿš€ Quick Start

Linux/macOS:

curl -sSL https://raw.githubusercontent.com/mrchypark/libdplyr/main/install.sh | bash

Windows (PowerShell):

Irm https://raw.githubusercontent.com/mrchypark/libdplyr/main/install.ps1 | iex

Try it out:

echo "select(name, age) %>% filter(age > 18)" | libdplyr --pretty

Note: For detailed installation options, troubleshooting, and platform support, see the Installation Guide.

Usage

As a CLI Tool

The most efficient way to use libdplyr is through stdin/stdout pipelines:

# Basic usage
echo "select(name, age) %>% filter(age > 18)" | libdplyr

# Specify dialect (postgres, mysql, sqlite, duckdb)
echo "select(name)" | libdplyr --dialect mysql

# Output formatting
echo "select(name)" | libdplyr --pretty
echo "select(name)" | libdplyr --json
echo "select(name)" | libdplyr --compact

As a Rust Library

use libdplyr::{Transpiler, PostgreSqlDialect};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let transpiler = Transpiler::new(Box::new(PostgreSqlDialect::new()));
    let dplyr_code = "select(name, age) %>% filter(age > 18)";
    
    let sql = transpiler.transpile(dplyr_code)?;
    println!("{}", sql);
    Ok(())
}

DuckDB Parser Override

DuckDB 1.5.x์—์„œ๋Š” SET allow_parser_override_extension = 'fallback';๋กœ dplyr pipeline์„ ๋„ค์ดํ‹ฐ๋ธŒ AST๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. parser override๋Š” ํ˜ธ์ถœ ์„ธ์…˜์˜ ์ž„์‹œ ํ…Œ์ด๋ธ”๊ณผ ํŠธ๋žœ์žญ์…˜์„ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์•”์‹œ์  pipeline์˜ dplyr_pipe_syntax๋Š” parser override API์— ClientContext๊ฐ€ ์—†๋Š” ์ œ์•ฝ ๋•Œ๋ฌธ์— DB-global ๊ฐ’๋งŒ ์ฝ์œผ๋ฉฐ, SET GLOBAL dplyr_pipe_syntax = 'native';์ฒ˜๋Ÿผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. session ๊ฐ’์€ ์•”์‹œ์  pipeline์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š์œผ๋ฉฐ, ์—ฐ๊ฒฐ๋ณ„ ๋ฌธ๋ฒ•์ด ํ•„์š”ํ•˜๋ฉด dplyr(query, mode)๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์„ค์ •์ด ์—†์œผ๋ฉด DPLYR_PIPE_SYNTAX ํ™˜๊ฒฝ ๋ณ€์ˆ˜(๊ธฐ๋ณธ๊ฐ’ magrittr)๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ํ˜ธํ™˜์„ฑ ๋ฐ ์„ค์ • ๊ทœ์น™์€ submodule compatibility ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

๐Ÿ“‹ Supported Functions

libdplyr supports a wide range of dplyr verbs and R functions. Exact partial-support and rejection boundaries are documented in the dplyr syntax support matrix.

Core Verbs

Function Description Example
select() Select/rename columns select(id, name)
distinct() Keep distinct rows or identifier columns distinct(dept, role)
filter() Filter rows filter(age > 18)
mutate() Create/modify columns mutate(total = price * qty)
rename() Rename columns rename(new = old)
arrange() Sort rows arrange(desc(date))
group_by() Group rows group_by(dept)
summarise() Aggregate data summarise(avg = mean(val))
count() / tally() Count rows by identifier-only keys or current groups count(dept)
*_join() Equality joins (inner, left, etc.) left_join(other, by=c("id", "left"="right"))
Set Ops union, intersect, setdiff union(other)

Helper Functions

  • Aggregation: mean, sum, min, max, n, n_distinct, count, median, mode
  • Window: row_number, rank, lead, lag, ntile
  • Math: abs, sqrt, round, floor, log, exp
  • String: tolower, toupper, substr, trimws
  • Logic: ifelse, case_when, between, is.na, coalesce

Examples

PostgreSQL

let transpiler = Transpiler::new(Box::new(PostgreSqlDialect::new()));
let sql = transpiler.transpile("select(name) %>% filter(age > 18)")?;
// SELECT "name" FROM "data" WHERE "age" > 18

Complex Pipeline

let code = r#"
    select(dept, salary) %>%
    filter(salary > 50000) %>%
    group_by(dept) %>%
    summarise(avg_sal = mean(salary)) %>%
    arrange(desc(avg_sal))
"#;

Error Handling & Troubleshooting

libdplyr provides detailed error codes:

  • Exit 0: Success
  • Exit 4: Validation Error (syntax issues)
  • Exit 5: Transpilation Error (generation failed)

Debug Mode:

libdplyr --verbose --debug

For more troubleshooting details, see INSTALL.md.

Performance

libdplyr is optimized for speed using Rust's zero-cost abstractions. Run benchmarks:

cargo bench

Development

# Setup
git clone https://github.com/mrchypark/libdplyr.git
cd libdplyr
cargo build

# Test
cargo test

Support

License

MIT License. See LICENSE.

About

No description, website, or topics provided.

Resources

Stars

16 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages