Files
Baradb/docs/en/baraql.md
T
dimgigov a5d34c001a
CI / test (push) Has been cancelled
CI / verify (push) Has been cancelled
docs: add German (DE) documentation + update all docs for Sessions 10-12
New German documentation (docs/de/):
- index.md, quickstart.md, installation.md
- baraql.md, graph.md, vector.md, mcp.md

Updated English documentation:
- changelog.md: all Sessions 10-12 features
- graph.md: SQL GRAPH_TABLE, CREATE GRAPH, all 8 algorithms, Cypher, similarity_nodes, node2vec
- vector.md: hybrid RAG, chunk(), embed_text(), auto-embed, nl_to_sql(), schema_prompt()
- baraql.md: new AI & Cross-Modal Functions section, updated keyword tables
- mcp.md: MCP Server documentation (new file)
- index.md: added German (DE) language link
2026-05-17 16:15:45 +03:00

16 KiB

BaraQL - Query Language Reference

BaraQL is a SQL-compatible query language with extensions for graph, vector, and document operations.

Data Types

Type Description Example
null Null value null
bool Boolean true, false
int8 8-bit signed integer 127
int16 16-bit signed integer 32767
int32 32-bit signed integer 2147483647
int64 64-bit signed integer 9223372036854775807
float32 32-bit float 3.14
float64 64-bit float 3.14159265359
str UTF-8 string 'hello'
bytes Raw bytes 0xDEADBEEF
array<T> Homogeneous array [1, 2, 3]
vector Float32 vector [0.1, 0.2, 0.3]
vector(n) Fixed-dimension float32 vector (SQL) VECTOR(768)
object Key-value object {"a": 1}
datetime ISO 8601 timestamp '2025-01-15T10:30:00Z'
uuid UUID v4 '550e8400-e29b-41d4-a716-446655440000'
json JSON document {"key": "value"}
jsonb Binary JSON (validated) {"key": "value"}

Basic Queries

SELECT

-- All columns
SELECT * FROM users;

-- Specific columns
SELECT name, age FROM users;

-- Aliases
SELECT name AS full_name, age AS years FROM users;

-- DISTINCT
SELECT DISTINCT department FROM employees;

-- LIMIT and OFFSET
SELECT * FROM users LIMIT 10 OFFSET 20;

WHERE

-- Comparison operators
SELECT * FROM users WHERE age > 18;
SELECT * FROM users WHERE age >= 18 AND age <= 65;
SELECT * FROM users WHERE name = 'Alice';
SELECT * FROM users WHERE name != 'Bob';

-- Range
SELECT * FROM users WHERE age BETWEEN 18 AND 65;

-- Set membership
SELECT * FROM users WHERE department IN ('Engineering', 'Sales');

-- Pattern matching
SELECT * FROM users WHERE name LIKE 'A%';
SELECT * FROM users WHERE name ILIKE 'alice';  -- Case-insensitive

-- NULL checks
SELECT * FROM users WHERE email IS NOT NULL;

-- Logical operators
SELECT * FROM users WHERE age > 18 AND (department = 'Engineering' OR department = 'Sales');

ORDER BY

-- Ascending (default)
SELECT * FROM users ORDER BY age;

-- Descending
SELECT * FROM users ORDER BY age DESC;

-- Multiple columns
SELECT * FROM users ORDER BY department ASC, age DESC;

INSERT

-- Single row
INSERT users { name := 'Alice', age := 30 };

-- With explicit type
INSERT User { name := 'Alice', age := 30 };

-- Multiple rows
INSERT users {
  { name := 'Alice', age := 30 },
  { name := 'Bob', age := 25 }
};

UPDATE

-- Update all rows
UPDATE users SET status = 'active';

-- Conditional update
UPDATE users SET age = 31 WHERE name = 'Alice';

-- Update multiple columns
UPDATE users SET age = 32, status = 'premium' WHERE name = 'Alice';

DELETE

-- Delete all rows
DELETE FROM users;

-- Conditional delete
DELETE FROM users WHERE age < 18;

Aggregates and Grouping

Aggregate Functions

Function Description
count(*) Count all rows
count(column) Count non-NULL values
sum(column) Sum of values
avg(column) Average
min(column) Minimum value
max(column) Maximum value
stddev(column) Standard deviation
variance(column) Variance

GROUP BY

SELECT department, count(*) as emp_count, avg(salary) as avg_salary
FROM employees
GROUP BY department;

-- With HAVING
SELECT department, count(*) as emp_count
FROM employees
GROUP BY department
HAVING count(*) > 5;

-- Multiple groupings
SELECT department, role, count(*), avg(salary)
FROM employees
GROUP BY department, role;

JOINs

-- INNER JOIN
SELECT u.name, o.total
FROM users u
INNER JOIN orders o ON u.id = o.user_id;

-- LEFT JOIN
SELECT u.name, o.total
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;

-- RIGHT JOIN
SELECT u.name, o.total
FROM users u
RIGHT JOIN orders o ON u.id = o.user_id;

-- FULL JOIN
SELECT u.name, o.total
FROM users u
FULL JOIN orders o ON u.id = o.user_id;

-- CROSS JOIN
SELECT u.name, p.name
FROM users u
CROSS JOIN products p;

-- Multiple JOINs
SELECT u.name, o.id, p.name
FROM orders o
JOIN users u ON o.user_id = u.id
JOIN products p ON o.product_id = p.id;

-- Self JOIN
SELECT e.name, m.name as manager
FROM employees e
JOIN employees m ON e.manager_id = m.id;

CTEs (Common Table Expressions)

-- Single CTE
WITH active_users AS (
  SELECT * FROM users WHERE active = true
)
SELECT * FROM active_users;

-- Multiple CTEs
WITH
  recent AS (
    SELECT * FROM orders WHERE date > '2025-01-01'
  ),
  totals AS (
    SELECT user_id, sum(amount) as total FROM recent GROUP BY user_id
  )
SELECT u.name, t.total
FROM users u
JOIN totals t ON u.id = t.user_id;

-- Recursive CTE
WITH RECURSIVE subordinates AS (
  SELECT id, name, manager_id FROM employees WHERE name = 'CEO'
  UNION ALL
  SELECT e.id, e.name, e.manager_id
  FROM employees e
  JOIN subordinates s ON e.manager_id = s.id
)
SELECT * FROM subordinates;

Subqueries

-- Subquery in SELECT
SELECT name, (SELECT count(*) FROM orders WHERE user_id = u.id) as order_count
FROM users u;

-- Subquery in FROM
SELECT * FROM (SELECT id, name FROM users WHERE active = true) AS active;

-- Subquery in WHERE (IN)
SELECT name FROM users WHERE id IN (SELECT user_id FROM orders);

-- Subquery in WHERE (EXISTS)
SELECT name FROM users WHERE EXISTS (SELECT 1 FROM orders WHERE orders.user_id = users.id);

-- Correlated subquery
SELECT name FROM users u
WHERE age > (SELECT avg(age) FROM users WHERE department = u.department);

CASE Expressions

SELECT name,
  CASE
    WHEN age < 13 THEN 'child'
    WHEN age < 20 THEN 'teenager'
    WHEN age < 65 THEN 'adult'
    ELSE 'senior'
  END AS category
FROM users;

-- Simple CASE
SELECT name,
  CASE department
    WHEN 'Engineering' THEN 'Tech'
    WHEN 'Sales' THEN 'Revenue'
    ELSE 'Other'
  END AS division
FROM employees;

Set Operations

-- UNION (distinct)
SELECT name FROM customers
UNION
SELECT name FROM suppliers;

-- UNION ALL (with duplicates)
SELECT name FROM customers
UNION ALL
SELECT name FROM suppliers;

-- INTERSECT
SELECT name FROM customers
INTERSECT
SELECT name FROM suppliers;

-- EXCEPT
SELECT name FROM customers
EXCEPT
SELECT name FROM suppliers;

Schema Definition

CREATE TYPE

CREATE TYPE Person {
  name: str,
  age: int32
};

-- With required fields
CREATE TYPE User {
  email: str REQUIRED,
  name: str,
  age: int32,
  created_at: datetime DEFAULT now()
};

-- With links
CREATE TYPE Movie {
  title: str,
  year: int32,
  director: Person
};

-- With computed properties
CREATE TYPE Employee {
  name: str,
  base_salary: float64,
  bonus: float64,
  total_compensation: float64 COMPUTED (base_salary + bonus)
};

Inheritance

CREATE TYPE Animal {
  name: str
};

CREATE TYPE Dog EXTENDING Animal {
  breed: str
};

CREATE TYPE Cat EXTENDING Animal {
  indoor: bool
};

Indexes

CREATE INDEX idx_users_name ON users(name);
CREATE UNIQUE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_age ON users(age) USING btree;
CREATE INDEX idx_vectors ON items(embedding) USING hnsw;

DROP

DROP TYPE User;
DROP INDEX idx_users_name;

JSON Path Operators

-- Extract JSON field as JSON
SELECT data->'name' FROM users;

-- Extract JSON field as text
SELECT data->>'name' FROM users;

Full-Text Search (SQL)

-- Create FTS index with BM25
CREATE INDEX idx_fts ON articles(body) USING FTS;

-- Search with BM25 ranking
SELECT * FROM articles WHERE body @@ 'machine learning';

Point-in-Time Recovery

RECOVER TO TIMESTAMP '2026-05-07T12:00:00';

Vector Search (SQL)

Creating Vector Columns

CREATE TABLE items (
  id INT PRIMARY KEY,
  embedding VECTOR(768)
);

Inserting Vectors

INSERT INTO items (id, embedding) VALUES (1, '[0.1, 0.2, 0.3, 0.4]');

Distance Functions

-- Cosine distance (0 = identical, 2 = opposite)
SELECT id, cosine_distance(embedding, '[0.1, 0.2, 0.3, 0.4]') AS dist
FROM items;

-- Euclidean / L2 distance
SELECT id, euclidean_distance(embedding, '[0.1, 0.2, 0.3, 0.4]') AS dist
FROM items;

-- L2 distance with <-> operator
SELECT id, embedding <-> '[0.1, 0.2, 0.3, 0.4]' AS dist
FROM items;

-- Inner product (negative dot product)
SELECT id, inner_product(embedding, '[0.1, 0.2, 0.3, 0.4]') AS dist
FROM items;

-- Manhattan / L1 distance
SELECT id, l1_distance(embedding, '[0.1, 0.2, 0.3, 0.4]') AS dist
FROM items;
-- Top-10 nearest neighbors by cosine distance
SELECT id FROM items
ORDER BY cosine_distance(embedding, '[0.1, 0.2, 0.3, 0.4]') ASC
LIMIT 10;

-- Top-5 nearest neighbors by Euclidean distance
SELECT id FROM items
ORDER BY embedding <-> '[0.1, 0.2, 0.3, 0.4]'
LIMIT 5;

-- With metadata filter
SELECT id FROM items
WHERE category = 'tech'
ORDER BY cosine_distance(embedding, '[0.1, 0.2, 0.3, 0.4]')
LIMIT 5;

Vector Indexes

-- Create HNSW index for approximate nearest neighbor search
CREATE INDEX idx_items_vec ON items(embedding) USING hnsw;

-- Supported index methods: hnsw, ivfpq

Graph Patterns

-- Find friends of Alice
MATCH (p:Person)-[:KNOWS]->(friend:Person)
WHERE p.name = 'Alice'
RETURN friend.name;

-- Find shortest path
MATCH path = shortestPath((a:Person)-[:KNOWS*1..5]->(b:Person))
WHERE a.name = 'Alice' AND b.name = 'Bob'
RETURN path;

-- Find all relationships
MATCH (p:Person)-[r]->(other)
WHERE p.name = 'Alice'
RETURN type(r), other.name;

-- Multiple hops
MATCH (a:Person)-[:KNOWS]->(b:Person)-[:KNOWS]->(c:Person)
WHERE a.name = 'Alice'
RETURN c.name;

-- With aggregates
MATCH (p:Person)-[:KNOWS]->(friend)
RETURN p.name, count(friend) as friend_count
ORDER BY friend_count DESC;
-- Basic search
SELECT * FROM articles
WHERE MATCH(title, body) AGAINST('database programming');

-- With relevance score
SELECT title, relevance()
FROM articles
WHERE MATCH(title, body) AGAINST('Nim language')
ORDER BY relevance() DESC;

-- Boolean mode
SELECT * FROM articles
WHERE MATCH(title, body) AGAINST('+Nim -Python' IN BOOLEAN MODE);

-- Fuzzy search
SELECT * FROM articles
WHERE MATCH(title) AGAINST('programing' WITH FUZZINESS 2);

Transactions

BEGIN;
INSERT users { name := 'Alice', age := 30 };
INSERT orders { user_id := last_insert_id(), total := 100 };
COMMIT;

-- With savepoint
BEGIN;
INSERT users { name := 'Bob', age := 25 };
SAVEPOINT sp1;
INSERT orders { user_id := last_insert_id(), total := 200 };
-- Oops, rollback to savepoint
ROLLBACK TO sp1;
COMMIT;

User-Defined Functions

-- Register a UDF
CREATE FUNCTION greet(name str) -> str {
  RETURN 'Hello, ' || name || '!';
};

-- Use it
SELECT greet(name) FROM users;

-- Built-in functions
SELECT abs(-5), sqrt(16), lower('HELLO'), len('test');

Query Hints

-- Force index usage
SELECT /*+ USE_INDEX(idx_users_age) */ * FROM users WHERE age > 18;

-- Force approximate vector search
SELECT /*+ APPROXIMATE */ * FROM vectors
ORDER BY cosine_distance(embedding, [...])
LIMIT 10;

-- Parallel execution
SELECT /*+ PARALLEL(4) */ * FROM large_table;

Window Functions

-- Ranking functions
SELECT
  name,
  department,
  ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS rn,
  RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS r,
  DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dr
FROM employees;

-- Value functions
SELECT
  name,
  salary,
  LAG(salary, 1, 0) OVER (ORDER BY salary) AS prev_salary,
  LEAD(salary, 1, 0) OVER (ORDER BY salary) AS next_salary,
  FIRST_VALUE(name) OVER (PARTITION BY department ORDER BY salary) AS cheapest,
  LAST_VALUE(name) OVER (PARTITION BY department ORDER BY salary) AS most_expensive
FROM employees;

-- Distribution functions
SELECT name, NTILE(4) OVER (ORDER BY salary) AS quartile FROM employees;

Frame Specifications

-- ROWS frame
SUM(salary) OVER (
  PARTITION BY department
  ORDER BY hire_date
  ROWS BETWEEN 1 PRECEDING AND CURRENT ROW
)

-- RANGE frame
SUM(salary) OVER (
  PARTITION BY department
  ORDER BY hire_date
  RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
)

Multi-Tenant ERP

BaraDB supports running multiple companies (tenants) in a single database instance, using Row-Level Security (RLS) combined with session variables.

Session Variables

SET app.tenant_id = 'company-123';
SELECT current_setting('app.tenant_id') AS tenant;

Current User / Role

SELECT current_user AS me, current_role AS my_role;

RLS Tenant Isolation

-- Enable RLS on a table
ALTER TABLE invoices ENABLE ROW LEVEL SECURITY;

-- Create a policy that filters by tenant
CREATE POLICY tenant_isolation ON invoices
  FOR SELECT USING (tenant_id = current_setting('app.tenant_id'));

-- Each session only sees its own data
SET app.tenant_id = 'company-a';
SELECT * FROM invoices;  -- only company-a rows

Why Multi-Tenant?

  • One instance, many tenants — no need to run 100 separate databases
  • JSONB documents — schema-flexible storage, easy to add fields per tenant
  • RLS guarantees isolation — the database enforces tenant boundaries, not just the application

AI & Cross-Modal Functions

Vector / RAG

-- Hybrid search (vector + FTS + RRF reranking)
SELECT hybrid_search('query text', embedding, content, 10) AS result;
SELECT hybrid_search_ids('query', embedding, content, 5) AS result;
SELECT hybrid_search_filtered('query', embedding, content, 10, 'category', 'news') AS result;

-- Rerank
SELECT rerank('query text', results_json) AS result;

Graph Traversal

-- BFS, DFS, PageRank, ShortestPath, Dijkstra, Louvain
SELECT * FROM GRAPH_TABLE(g MATCH (n)-[r]->(m)
    ALGORITHM bfs START 1 MAXDEPTH 2
    COLUMNS (id, node_label));

SELECT similarity_nodes('graph_name', 'jaccard') AS result;
SELECT node2vec_embed('graph_name', 64) AS result;
SELECT cypher('MATCH (a)-[r]->(b) RETURN a.label') AS result;

AI / LLM

-- Text chunking
SELECT chunk('long text...', 1024, 128) AS result;

-- Embedding generation (external service)
SELECT embed_text('query text') AS result;

-- Natural Language → SQL (external LLM)
SELECT nl_to_sql('Show users over 25', 'users') AS result;

-- Schema prompt for LLM context
SELECT schema_prompt('users') AS result;

Supported Keywords

Category Keywords
DQL SELECT, FROM, WHERE, ORDER BY, GROUP BY, HAVING, LIMIT, OFFSET, DISTINCT
DML INSERT, UPDATE, DELETE, SET, VALUES
DDL CREATE TYPE, DROP TYPE, CREATE INDEX, DROP INDEX, ALTER TYPE, CREATE GRAPH, DROP GRAPH
Join INNER JOIN, LEFT JOIN, RIGHT JOIN, FULL JOIN, CROSS JOIN, ON
Set UNION, UNION ALL, INTERSECT, EXCEPT
CTEs WITH, RECURSIVE, AS
Case CASE, WHEN, THEN, ELSE, END
Transaction BEGIN, COMMIT, ROLLBACK, SAVEPOINT
Graph MATCH, RETURN, WHERE, shortestPath, type, GRAPH_TABLE, ALGORITHM, bfs, dfs, pagerank
FTS MATCH, AGAINST, relevance, IN BOOLEAN MODE, WITH FUZZINESS
Vector cosine_distance, euclidean_distance, inner_product, l1_distance, l2_distance, <->
AI hybrid_search, rerank, chunk, embed_text, nl_to_sql, schema_prompt, similarity_nodes, node2vec_embed, cypher
JSON ->, ->>
Recovery RECOVER TO TIMESTAMP
Functions count, sum, avg, min, max, stddev, variance, abs, sqrt, lower, upper, len, trim, substr, now, last_insert_id, current_setting
Session SET, current_setting, current_user, current_role
Window OVER, PARTITION BY, ROWS, RANGE, UNBOUNDED PRECEDING, CURRENT ROW, FOLLOWING
Window Functions ROW_NUMBER, RANK, DENSE_RANK, LEAD, LAG, FIRST_VALUE, LAST_VALUE, NTILE