← All projects
Data & analytics · Python
M

minisql

SELECT, joins, aggregates and NULL logic — tokenizer → parser → executor, all in this page.

1 SQL playground

Four CSV tables loaded. Write a query — or an INSERT, UPDATE or DELETE — and press Run (or ⌘/Ctrl+Enter). Errors point at the character that caused them.

2 Schema

columntypenotes

3 Data preview

First 8 rows of the selected table. Types are inferred per column, not per cell — a leading zero keeps the column as text.

4 NULL is unknown, not false

score > 0 where score is NULL is neither true nor false — the row is dropped by WHERE, and so is score <= 0. false AND unknown is false; true OR unknown is true.

SELECT COUNT(*) AS all_rows, COUNT(city) AS with_city FROM customers; -- COUNT(*) counts rows; COUNT(col) counts values. -- Two customers have no city: 25 vs 23.

5 ORDER BY a column you did not select

Each output row is kept beside the input row it came from, so SELECT name FROM people ORDER BY age sorts by age even though age is not in the SELECT list.

error: 'name' is not in GROUP BY and is not an aggregate — add it to GROUP BY or wrap it in one

6 What it supports

SELECT [DISTINCT], expressions with + - * / %, aliases, INNER|LEFT JOIN … ON, WHERE with AND/OR/NOT, comparisons, IS [NOT] NULL, [NOT] IN, [NOT] LIKE 'a%_', GROUP BY + HAVING, aggregates (COUNT SUM AVG MIN MAX incl. DISTINCT), ORDER BY, LIMIT/OFFSET.

Not supported: subqueries, window functions, RIGHT/FULL JOIN, CREATE/DROP TABLE. Joins are nested-loop — suited to files that fit in memory. INSERT, UPDATE and DELETE change the tables in this page only (the CLI writes back to CSV with .save).

7 Schema diagram

All tables with columns, types and foreign keys — animated on load. Hover a table to highlight it; click to jump to its data preview.

━━ foreign keyPK = primary key nullable columns marked *

8 EXPLAIN — parse tree

The recursive-descent parser's AST rendered as a tree, rebuilt live from the query above. Press Run or edit the query and click Explain.

9 Query builder

Dropdowns → generated SQL. Edit the result freely — it lands in the playground above.

10 NULL logic playground

SQL is three-valued: NULL is unknown. Pick values for A and B, choose an operator, and see the result — then study the full truth tables.

A: B: op:
ANDTFNULL
TTFNULL
FFFF
NULLNULLFNULL
ORTFNULL
TTTT
FTFNULL
NULLTNULLNULL
NOTTFNULL
 FTNULL

11 JOIN visualizer

Nested-loop join on real rows: customers ⋈ orders on customer_id = id. Matched pairs glow; unmatched left rows keep NULLs under LEFT JOIN.

customers (left)

ON c.id = o.customer_id

orders (right)

result

12 Error position highlighter

Break something on purpose — the exact offending character is highlighted inline with the parser's message.

139 tests · 95% coverage · Python 3.10–3.12 · Built by Umer Hashmi