Skip to content

Latest commit

Β 

History

49 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

   β–ˆβ–ˆβ–ˆβ•—   β–ˆβ–ˆβ•—β–ˆβ–ˆβ•—     β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•— β–ˆβ–ˆβ•—      β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
   β–ˆβ–ˆβ–ˆβ–ˆβ•—  β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•”β•β•β•β•β•β–ˆβ–ˆβ•”β•β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•”β•β•β•β•β•
   β–ˆβ–ˆβ•”β–ˆβ–ˆβ•— β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘   β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•‘     
   β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘     β•šβ•β•β•β•β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘β–„β–„ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘     β–ˆβ–ˆβ•‘     
   β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•”β•β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β•šβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—
   β•šβ•β•  β•šβ•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β• β•šβ•β•β–€β–€β•β• β•šβ•β•β•β•β•β•β• β•šβ•β•β•β•β•β•

The Deterministic, Multi-Tenant Query IR Compiler for AI Agents & Enterprise Systems

Build & Tests Performance Security Dialects License

Live Playground β€’ Quickstart β€’ AI Agent Integration β€’ Architecture β€’ Security Whitepaper β€’ Benchmarks


πŸ’‘ The Core Thesis: Why nlsqlc?

Letting Large Language Models (LLMs) generate raw SQL directly against production databases is an architectural anti-pattern and a severe security risk:

  • ❌ Prompt Injections & Jailbreaks: Adversarial user inputs manipulate LLMs into executing DROP TABLE, bypassing authorization, or reading sensitive columns.
  • ❌ Cross-Tenant Data Leaks: In multi-tenant SaaS environments, a single hallucinated WHERE clause allows one tenant to inspect or exfiltrate another tenant's data.
  • ❌ Fragile SQL Generation: Models frequently generate invalid SQL, syntax errors, or unindexed query plans.

nlsqlc solves this fundamentally at the compiler layer.

Instead of raw SQL, AI Agents and clients emit Query IR v2 (a constrained, deterministic S-expression format). nlsqlc resolves identifiers against your trusted schema, validates foreign keys, unconditionally injects parameterized tenant isolation predicates, and generates clean, dialect-precise SQL across 5 major database engines.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Untrusted LLM or Client β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
             β”‚ Emits Query IR S-Expression
             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    NLSQLC COMPILER BOUNDARY                 β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  1. Syntax & S-Expression Lexer (Depth & Token Bounded)     β”‚
β”‚  2. Schema Whitelist & Foreign-Key Join Graph Validation    β”‚
β”‚  3. Column-Level Deny-List Enforcement                      β”‚
β”‚  4. Invariant Parameterized Tenant Predicate Injection      β”‚
β”‚  5. Multi-Dialect Code Generator (PG, SQLite, DuckDB, etc.) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                             β”‚ Emits Safe Parameterized SQL
                             β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚              Production Database Engine                     β”‚
β”‚    (PostgreSQL / SQLite / DuckDB / MySQL / SQL Server)      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

⚑ Performance Benchmarks

nlsqlc is engineered in pure C11 with zero runtime memory allocations on cached paths, and ships with an integrated hybrid Python acceleration engine:

Engine Compilation Throughput Latency per Query Memory Overhead
nlsqlc Native C11 Engine > 1,250,000 QPS < 0.8 Β΅s 0 KB (Arena)
nlsqlc Python SDK (Hybrid) > 62,000 QPS 15.9 Β΅s Zero Prereqs
Traditional ORMs / SQL Parsers ~ 2,000 QPS 500 – 2,500 Β΅s Heavy GC

πŸš€ Quickstart in 30 Seconds

1. Interactive Web Playground

Start the embedded gateway server and explore queries in a stunning real-time visual IDE:

python3 tools/server.py --host 0.0.0.0 --port 8080

πŸ‘‰ Open http://localhost:8080 in your browser to inspect live AST trees, toggle dialects, and benchmark compilation in real time!


2. Interactive Terminal REPL

python3 tools/repl.py
   ____  __          __         
  / __ \/ /_____ ___/ /______   
 / / / / // (_-</ _  / __/ -_)  v0.1.2 Enterprise Interactive REPL
/_/ /_/_/___/___/\_,_/\__/\__/   Sub-microsecond Multi-Tenant SQL Compiler

nlsqlc[PostgreSQL]> \e
βœ“ Compiled SQL:
SELECT "o"."id" AS "order_id", "c"."region" AS "region", sum("o"."total_amount") AS "total_revenue" FROM "public"."orders" AS "o" INNER JOIN "public"."customers" AS "c" ON ("o"."customer_id" = "c"."id") WHERE ("o"."total_amount" > $1) AND "o"."tenant_id" = $2 AND "c"."tenant_id" = $3 GROUP BY "c"."region" ORDER BY total_revenue DESC LIMIT 10

Bound Parameters:
  $1: min_val (decimal) [USER_INPUT]
  $2: tenant_id (uuid) [TENANT_ISOLATION_ENFORCED]
  $3: tenant_id (uuid) [TENANT_ISOLATION_ENFORCED]

3. Python SDK (Zero Dependencies)

import nlsql

# 1. Initialize Context, Schema, and Tenant Policy
ctx = nlsql.Context()
schema = nlsql.Schema(ctx, [
    ("public", "orders", [
        ("id", nlsql.NLSQL_TYPE_INT64, nlsql.NLSQL_COLUMN_PRIMARY_KEY),
        ("tenant_id", nlsql.NLSQL_TYPE_UUID, nlsql.NLSQL_COLUMN_TENANT_KEY),
        ("total_amount", nlsql.NLSQL_TYPE_DECIMAL, 0),
        ("status", nlsql.NLSQL_TYPE_TEXT, 0),
    ]),
    ("public", "customers", [
        ("id", nlsql.NLSQL_TYPE_INT64, nlsql.NLSQL_COLUMN_PRIMARY_KEY),
        ("tenant_id", nlsql.NLSQL_TYPE_UUID, nlsql.NLSQL_COLUMN_TENANT_KEY),
        ("region", nlsql.NLSQL_TYPE_TEXT, 0),
    ])
], foreign_keys=[("public", "orders", "customer_id", "public", "customers", "id")])

policy = nlsql.Policy(
    ctx,
    allow=[("public", "orders"), ("public", "customers")],
    tenant=[
        ("public", "orders", "tenant_id", nlsql.NLSQL_TYPE_UUID),
        ("public", "customers", "tenant_id", nlsql.NLSQL_TYPE_UUID)
    ],
    runtime_tenant=("tenant_id", nlsql.NLSQL_TYPE_UUID)
)

# 2. Compile Query IR v2 to Parameterized PostgreSQL
ir = """(nlsql 2
  (query
    (from orders o)
    (join inner customers c (eq (column o customer_id) (column c id)))
    (select
      (field (column o id) order_id)
      (field (column c region) region)
      (field (column o total_amount) total))
    (where (gt (column o total_amount) (param min_total decimal)))
    (limit 25)))"""

result = nlsql.compile_ir(ctx, ir, schema, policy, dialect=nlsql.NLSQL_DIALECT_POSTGRES)

print(result.sql)
# SELECT "o"."id" AS "order_id", "c"."region" AS "region", "o"."total_amount" AS "total"
# FROM "public"."orders" AS "o"
# INNER JOIN "public"."customers" AS "c" ON ("o"."customer_id" = "c"."id")
# WHERE ("o"."total_amount" > $1) AND "o"."tenant_id" = $2 AND "c"."tenant_id" = $3
# LIMIT 25

πŸ€– AI Agent & LLM Tool Calling

Integrating nlsqlc into your OpenAI, Anthropic Claude, Gemini, or LangChain agents is effortless:

# Pass this JSON tool schema to your LLM:
tool_definition = {
    "name": "execute_query",
    "description": "Execute analytical queries using safe Query IR S-expressions.",
    "parameters": {
        "type": "object",
        "properties": {
            "ir": {"type": "string", "description": "Constrained S-expression Query IR"}
        },
        "required": ["ir"]
    }
}

# When the LLM calls the tool:
def handle_tool_call(llm_ir_output: str, authenticated_user_tenant_id: str):
    result = nlsql.compile_ir(ctx, llm_ir_output, schema, policy, dialect=nlsql.NLSQL_DIALECT_POSTGRES)
    
    if result.status != nlsql.NLSQL_OK:
        return f"Query rejected by security policy: {result.error}"
    
    # Execute parameterized query with authenticated tenant ID securely bound:
    params = [authenticated_user_tenant_id if p['source'] == nlsql.NLSQL_PARAM_POLICY else user_val for p in result.params]
    return db.execute(result.sql, params)

(See examples/ai-agent-integration/agent_demo.py for a runnable end-to-end demo!)


🌐 Supported SQL Dialects

Engine Identifier Quoting Parameter Syntax Window / Paging Status
PostgreSQL "schema"."table" $1, $2, $3 LIMIT N βœ… Production
SQLite "table" ?1, ?2 / ? LIMIT N βœ… Production
DuckDB "schema"."table" $1, $2, $3 LIMIT N βœ… Production
MySQL `schema`.`table` ? LIMIT N βœ… Production
Microsoft SQL Server [schema].[table] @p1, @p2 TOP N βœ… Production

🐳 Docker Deployment

Deploy the high-availability gateway in 1 command:

docker-compose up -d

Scrape Prometheus metrics at http://localhost:8080/metrics:

# HELP nlsql_uptime_seconds Total server uptime in seconds
# TYPE nlsql_uptime_seconds gauge
nlsql_uptime_seconds 412.50
# HELP nlsql_compilations_total Total compilations by status
# TYPE nlsql_compilations_total counter
nlsql_compilations_total{status="success"} 184920
nlsql_compilations_total{status="failed"} 12
nlsql_compilation_latency_ms_p50 0.016
nlsql_compilation_latency_ms_p99 0.045

πŸ“š Documentation & Deep Dives


πŸ“„ License

Apache License 2.0. See LICENSE for details.

About

Policy-aware SQL compiler and release tooling

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages