JaSQL's an SQL — a query language for AbuDB, the Abu Ecosystem's in-process database.
JaSQL is a DSL that sits on top of AbuDB (Python). You write SQL-style statements; the runtime handles parsing, type validation, lazy loading, hash joins, transactions, and structured errors. JaSQL is deliberately not named after the A-languages (AC, AI, AC+) because its syntax is normal — English keywords, standard operators, quoted strings.
SCT score: 9.2(Shariff Complexity Theorem, 2026 — easier to learn than Python at 10.0)
fromabudbimportDatabaseimportjasqldb=Database()
results=jasql.execute_script(db, """ CREATE TABLE users { id: int, name: string, age?: int } INSERT users { id: 1, name: "Alice", age: 30 } INSERT users { id: 2, name: "Bob", age: 25 } TAKE name FROM users IF age > 26""")
forrinresults:
print(r)Single statement:
print(jasql.execute(db, 'TAKE * FROM users ORDER BY age DESC'))| Type | Example value | Notes |
|---|---|---|
int | 42 | Integer |
float | 3.14 | Floating-point |
string | "hello" | Quoted string |
bool | true / false | |
date | 25.05.26 | dd.mm.yy |
datetime | 25.05.26 14:30 | dd.mm.yy hh:mm |
deltat | 01:30:00 | hh:mm:ss duration |
| nil | NIL | Null / absent value |
CREATETABLEname { field: type, field?: type, ... }- First field is automatically the primary key
?after the field name marks it as nullable (optional on insert)
CREATETABLEproducts { sku: string, name: string, price: float, stock?: int }DROPTABLE productsALTERTABLE products ADD discount?: float DEFAULT 0.0ALTERTABLE products DROP stock
ALTERTABLE products RENAME price TO unit_price
ALTERTABLE products RENAME TO inventoryINSERT users { id: 1, name: "Alice", age: 30 }Required (non-nullable) fields must be present. Types are validated and coerced.
UPDATE users SET age =31 IF id =1UPDATE users SET age +=5 IF name ="Bob"UPDATE users SET score *=1.1 IF active = trueCompound operators: +=, -=, *=, /=
RM FROM users IF age <18CROP 100DESCFROM products BY price -- keep the 100 most expensive
CROP 50ASCFROM logs BY date-- keep the 50 oldestTAKE field, expr AS alias, *FROM table [clauses...]| Clause | Example | Notes |
|---|---|---|
IF | IF age > 18 & active = true | Filter (WHERE) |
JOIN | JOIN orders ON users.id = orders.uid | See JOIN section |
GROUP BY | GROUP BY department | Aggregate grouping |
IF (after GROUP BY) | IF SIZE(*) > 5 | Having |
ORDER BY | ORDER BY age DESC | ASC/DESC or ABC/ZYX |
FILTER | FILTER name, dept | Distinct by fields |
TOP n | TOP 10 | First n rows |
BOTTOM n | BOTTOM 5 | Last n rows |
MIDDLE s e | MIDDLE 3 7 | Rows s through e (1-indexed) |
TAKE SIZE(*), SUM(price), MEAN(age), MAX(score), MIN(score) FROM table
TAKE dept, SIZE(*), MEAN(salary) FROM staff GROUP BY dept ORDER BY dept ASCArithmetic with correct precedence:
TAKE price *1.2AS with_tax FROM products
TAKE first +""+ last AS full_name FROM contactsTAKE name FROM staff IF dept ="eng"UNION
TAKE name FROM contractors IF active = true| Syntax | Meaning |
|---|---|
field = value | Equality |
field != value | Inequality |
field > value | Greater than (also >=, <, <=) |
field = NIL | Is null |
field != NIL | Is not null |
field LIKE "pat%" | Glob pattern (% = wildcard) |
field IN (a, b, c) | Value in list |
field IN RANGE 10 20 | Inclusive range |
field IN (TAKE ... FROM ...) | Subquery |
cond & cond | AND |
cond | cond | OR |
!cond | NOT |
Scalar subquery on RHS:
TAKE name FROM students IF grade > (TAKE MEAN(grade) FROM students)TAKE name, total FROM users JOIN orders ONusers.id=orders.uidJaSQL uses a hash join for equality conditions — O(n+m), not O(n×m). Non-equality conditions fall back to a nested loop.
TAKE name, total FROM users KEEP ALL, ordersReturns all rows from users, with NULLs for unmatched orders rows. Requires a prior CONNECT.
CONNECT users.id TO orders.user_idCONNECT registers a foreign-key-style relationship and merges the tables. Required before KEEP ALL.
IMPORT data/people.datac-- datac format (lazy, multi-table)
IMPORT exports/report.csv TO sales -- CSV (lazy)
IMPORT data/sheet.xlsx TO budget -- Excel (lazy, requires openpyxl)All imports are lazy — schema is read eagerly; rows stream from disk only when queried. Filter pushdown means only matching rows enter memory.
IMPORT classic-regexActivates the regex DSL (see Regex section). This is a module load, not a file import.
SAVE users TO backup/users.datac
MTSAVE users, orders TO backup/snapshot.datac
ALLSAVE TO backup/full.datacBEGIN
INSERT orders { id: 1, total: 500 }
UPDATE inventory SET qty -=1 IF sku ="ABC"COMMITBEGINUPDATE prices SET amount *=1.05 IF category ="food"ROLLBACK-- undo everything since BEGINROLLBACKrestores all tables, indexes, and connections to their state atBEGIN- Nested
BEGINraisesPreposterous: TransactionError COMMITwith no active transaction raisesPreposterous: TransactionError
INDEX users ON id -- build hash index on users.idDROPINDEX users ON id -- remove itIndexes are used automatically for IF field = value conditions on eager (fully-loaded) tables.
Activate with IMPORT classic-regex, then use in any IF condition or TAKE/UPDATE SET expression.
TAKE email FROM contacts IF email MATCH "[a-z]+@corp\.com"-- full match (anchored)
TAKE email FROM contacts IF email NOT MATCH "..."
TAKE name FROM users IF name SEARCH "^A"-- partial (unanchored)
TAKE name FROM users IF name NOT SEARCH "bot"| Function | Returns |
|---|---|
regex.match(field, "pat") | bool — full match |
regex.test(field, "pat") | bool — partial match |
regex.search(field, "pat") | first match string or "" |
regex.replace(field, "pat", "r") | replace first occurrence |
regex.replace_all(f, "pat", "r") | replace all occurrences |
regex.count(field, "pat") | number of matches |
regex.escape(field) | escape regex special chars |
regex.find_all(field, "pat") | comma-joined list of matches |
regex.groups(field, "pat") | comma-joined capture groups |
regex.split(field, "pat") | comma-joined split result |
TAKE regex.replace(email, "@.+", "@***") AS masked FROM contacts
UPDATE users SET email =regex.replace(email, "\\.com$", ".org") IF id =1JaSQL's native file format. Schema headers appear before each data block.
class int property: id
string sub.id: name
int sub.id: age
set inclusion id.age to nil
users {
id: 1, name: "Alice", age: 30
id: 2, name: "Bob", age: 25
id: 3, name: "Carol" ; age is nil — omitted
}
;begins a comment- Multi-table files are supported — each table is a separate named block
nilfields are omitted (absent = null)
All errors use the Preposterous: format with caret pointing to the offending token:
Preposterous: TableNotFound found ln:3 Char:12
TAKE * FROM ghost
^
| Error kind | Cause |
|---|---|
TableNotFound | Table name doesn't exist |
TableExists | CREATE TABLE on an existing name |
MissingFields | INSERT missing a required (non-nullable) field |
TypeError | Value doesn't match schema type |
SyntaxError | Unrecognised clause or malformed statement |
AlterError | ALTER TABLE on missing/protected field |
TransactionError | Nested BEGIN or COMMIT outside transaction |
IOError | File write failure in SAVE |
NoTables | ALLSAVE with no tables defined |
Rated using the Shariff Complexity Theorem (SCT, Abu Shariff, 2026):
| Dimension | Value | Notes |
|---|---|---|
| Coordinate (x, y) | (8, 85) | Very far from machine semantics; near English |
| Esotericosity E | 8 | min(8, 85) — low, DSL reads like English |
| Work Distribution | 12 | Runtime handles joins, validation, lazy load; programmer learns relational model |
| Barrier tax | +0 | Runs on any Python install, free |
| SCT | 9.2 | 0.7(8) + 0.3(12) = 5.6 + 3.6 |
For reference: Python = 10.0, ASM = 30, Lambda Calculus = 35. JaSQL scores below Python because it is a DSL with a single domain — the runtime absorbs far more complexity than a general-purpose language runtime can.
| File | Purpose |
|---|---|
abudb.py | In-memory database engine (Table, Database) |
jasql.py | JaSQL parser, evaluator, dispatcher |
datac_parser.py | datac file format parser (eager + streaming) |
repl.py | Interactive REPL |
test_jasql.py | pytest suite (59 tests) |
*.datac | datac data files |
*.jasql | JaSQL script files |
Part of the Abu Ecosystem — AC · AI · AC+ · AbuDB · JaSQL
Abu Shariff · 2026 · abu.shariffaiml@gmail.com