--- title: "Getting started with polyglotSQL" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Getting started with polyglotSQL} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` polyglotSQL gives R a native SQL compiler front-end: parse, tokenize, validate, format, analyze and translate SQL between more than 30 dialects. All the heavy lifting happens in the embedded [polyglot-sql](https://github.com/tobilg/polyglot) Rust crate — in-process, with no external services. ```{r setup} library(polyglotSQL) polyglot_version() ``` ## Your first translation The flagship feature is dialect translation. SQL is parsed with the source dialect into an abstract syntax tree (AST) and regenerated with the target dialect's rules: ```{r} sql_transpile( "SELECT IFNULL(a, b) FROM t", from = "mysql", to = "postgres" ) ``` Multiple statements are supported; the result has one element per statement: ```{r} sql_transpile( "SELECT 1; SELECT IFNULL(a, b) FROM t;", from = "mysql", to = "postgres" ) ``` Set `pretty = TRUE` for indented output, and control what happens when a construct has no equivalent in the target dialect with `unsupported` (`"raise"` — the default — errors; `"warn"`/`"ignore"` return best-effort SQL): ```{r} cat(sql_transpile( "SELECT id, COUNT(*) AS n FROM logs GROUP BY id HAVING COUNT(*) > 10", from = "generic", to = "snowflake", pretty = TRUE )) ``` ## Which dialects? ```{r} head(sql_dialects(full = TRUE), 10) ``` Any function accepting a dialect also accepts the listed aliases — `"mssql"` and `"sqlserver"` both mean `"tsql"`, `"postgresql"` means `"postgres"`. ## Formatting ```{r} cat(sql_format("select id,sum(x) total from t where y=1 group by id")) ``` ## Validating `sql_validate()` returns a structured result instead of throwing: ```{r} sql_validate("SELECT FROM WHERE") ``` ## Parsing and round-tripping ```{r} ast <- sql_parse("SELECT a, b FROM t WHERE x = 1") ast ``` The AST is a plain nested list following the upstream JSON format, and can be rendered back to SQL with any dialect's syntax rules (for full translation with function rewrites, use `sql_transpile()`): ```{r} sql_generate(sql_parse("SELECT `col name` FROM t", dialect = "mysql"), dialect = "postgres") ``` ## Errors are classed conditions All failures raise ordinary R conditions with useful classes (`polyglot_parse_error`, `polyglot_transpile_error`, `polyglot_validation_error`, `polyglot_guard_error`, all inheriting from `polyglot_error`), so you can handle them precisely: ```{r} tryCatch( sql_parse("SELECT ((( FROM"), polyglot_parse_error = function(e) conditionMessage(e) ) ``` A parse failure — even a bug-triggered panic inside Rust — never terminates your R session. ## Where to next? * `vignette("dialect-migration")` — migrating a query base between engines. * `vignette("parsing-validation-lineage")` — ASTs, schemas, lineage and analysis. * `vignette("installation-and-troubleshooting")` — Rust toolchain, offline builds, common problems.