A SQL extension for declarative data visualization based on the Grammar of Graphics.
ggsql allows you to write queries that combine SQL data retrieval with visualization specifications in a single, composable syntax.
SELECT date, revenue, region
FROM sales
WHERE year = 2024
VISUALISE date AS x, revenue AS y, region AS color
DRAW line
LABEL title => 'Sales by Region'
THEME minimal⨠Active Development - Core functionality is working with ongoing feature additions.
Completed:
- β Complete tree-sitter grammar with SQL + VISUALISE parsing
- β Full AST type system with validation
- β DuckDB reader with comprehensive type handling
- β Vega-Lite writer with multi-layer support
- β
CLI tool (
ggsql) with parse, exec, and validate commands - β
REST API server (
ggsql-rest) with CORS support - β
Jupyter kernel (
ggsql-jupyter) with inline Vega-Lite visualizations - β
VS Code extension (
ggsql-vscode) with syntax highlighting and Positron IDE integration
Planned:
- π Additional readers
- π Additional writers
- π More geom types and statistical transformations
- π Enhanced theme system
ggsql splits queries at the VISUALISE boundary:
- SQL portion β passed to pluggable readers (DuckDB, PostgreSQL, CSV, etc.)
- VISUALISE portion β parsed and compiled into visualization specifications
- Output β rendered via pluggable writers (ggplot2, PNG, Vega-Lite, etc.)
-
Clone the repository:
git clone https://github.com/georgestagg/ggsql cd ggsql -
Install tree-sitter CLI:
npm install -g tree-sitter-cli
-
Build the project:
cargo build
-
Run tests:
cargo test
ggsql/
βββ Cargo.toml # Workspace root configuration
βββ README.md # This file
β
βββ tree-sitter-ggsql/ # Tree-sitter grammar package
β
βββ src/ # Main library
β βββ lib.rs # Public API and re-exports
β βββ cli.rs # Command-line interface
β βββ rest.rs # REST API server
β βββ parser/ # Parsing subsystem
β βββ reader/ # Data source readers
β βββ writer/ # Visualization writers
β
βββ ggsql-jupyter/ # Jupyter kernel
β
βββ ggsql-vscode/ # VS Code extension
# Run all tests
cargo test
# Run specific test modules
cargo test ast # AST type tests
cargo test splitter # Query splitter tests
cargo test parser # All parser tests
# Run without default features (avoids database dependencies)
cargo test --no-default-features
# Run with specific features
cargo test --features duckdb,sqliteThe tree-sitter grammar is in tree-sitter-ggsql/grammar.js.
The grammar is automatically regenerated whenever the tree-sitter-ggsql project is build.
After making changes, you can manually test:
-
Regenerate the parser:
cd tree-sitter-ggsql tree-sitter generate -
Test the grammar:
# Test parsing a specific file tree-sitter parse test/corpus/basic.txt # Test all corpus files tree-sitter test
-
Debug parsing issues:
# Enable debug mode tree-sitter parse --debug test/corpus/basic.txt # Check for conflicts tree-sitter generate --report-states-for-rule=query
- AST Types (
src/parser/ast.rs): Core data structures representing parsed ggsql - Query Splitter (
src/parser/splitter.rs): Separates SQL from VISUALISE portions - AST Builder (
src/parser/builder.rs): Converts tree-sitter parse trees to typed AST - Error Handling (
src/parser/error.rs): Parse-time error types and formatting
- Update the grammar in
tree-sitter-ggsql/grammar.js - Add corresponding AST types in
src/parser/ast.rs - Update the AST builder in
src/parser/builder.rs - Add test cases for the new feature
- Update syntax highlighting in
tree-sitter-ggsql/queries/highlights.scm
Located alongside the code they test:
src/parser/ast.rs- AST type functionality and validationsrc/parser/splitter.rs- Query splitting edge casessrc/parser/builder.rs- CST to AST conversion
- Full parsing pipeline tests in
src/parser/mod.rs - End-to-end query processing (planned)
tree-sitter-ggsql/test/corpus/- Example queries with expected parse trees- Run with
tree-sitter test
# Core AST functionality
cargo test ast::tests
# Query splitting logic
cargo test splitter::tests
# Tree-sitter grammar
cd tree-sitter-ggsql && tree-sitter test
# All parser integration tests
cargo test parserSee CLAUDE.md for the in-progress ggsql grammar specification, including:
- Syntax reference
- AST structure
- Implementation phases and architecture
- Design principles and philosophy
Key grammar elements:
VISUALISE [mappings] [FROM source]- Entry point with global aesthetic mappingsDRAW <geom> [MAPPING] [SETTING] [FILTER]- Define geometric layers (point, line, bar, etc.)SCALE <aesthetic> SETTING- Configure data-to-visual mappingsFACET- Create small multiples (WRAP for flowing layout, BY for grid)COORD- Coordinate transformations (cartesian, flip, polar)LABEL,THEME,GUIDE- Styling and annotation
The ggsql-jupyter package provides a Jupyter kernel for interactive ggsql queries with inline Vega-Lite visualizations.
cargo build --release --package ggsql-jupyter
./target/release/ggsql-jupyter --installAfter installation, create a new notebook with the "ggsql" kernel or use %kernel ggsql in an existing notebook.
-- Create data
CREATE TABLE sales AS
SELECT * FROM (VALUES
('2024-01-01'::DATE, 100, 'North'),
('2024-01-02'::DATE, 120, 'South')
) AS t(date, revenue, region)
-- Visualize with ggsql using global mapping
SELECT * FROM sales
VISUALISE date AS x, revenue AS y, region AS color
DRAW line
SCALE x SETTING type => 'date'
LABEL title => 'Sales Trends'The kernel maintains a persistent DuckDB session across cells, so you can create tables in one cell and query them in another.
A Quarto example can be found in ggsql-jupyter/tests/quarto/doc.qmd.
The ggsql-vscode extension provides syntax highlighting for ggsql files in Visual Studio Code and Positron IDE.
# Install dependencies and package the extension
cd ggsql-vscode
npm install
npm install -g @vscode/vsce
vsce package
# Install the VSIX file
code --install-extension ggsql-0.1.0.vsix
# For Positron integration, also install the kernel
cargo run --package ggsql-jupyter -- --install- Syntax highlighting for ggsql keywords, geoms, aesthetics, and SQL
- File association for
.ggsql,.ggsql.sql, and.gsqlextensions - Bracket matching and auto-closing for parentheses and brackets
- Comment support for
--single-line and/* */multi-line comments
The extension uses a TextMate grammar that highlights:
- SQL keywords (SELECT, FROM, WHERE, JOIN, etc.)
- ggsql clauses (VISUALISE, DRAW, SCALE, COORD, FACET, etc.)
- Geometric objects (point, line, bar, area, etc.)
- Aesthetics (x, y, color, size, shape, etc.)
- Scale types (linear, log10, date, viridis, etc.)
When running in Positron IDE, the extension provides additional features:
- Language runtime registration for executing ggsql queries directly within Positron
- Plot pane integration - visualizations are automatically routed to Positron's Plots pane
cargo install --path src