feat: JSON/JSONB validation, multi-column indexes, CTE execution, wire protocol column types

- Add fkJson to wire protocol with serialization/deserialization
- Validate JSON/JSONB on INSERT/UPDATE via std/json
- Send real column type metadata in wire protocol responses
- Update all 4 clients (Nim, Python, JS, Rust) for JSON and columnTypes
- Implement multi-column index parser (CREATE INDEX idx ON t(a, b))
- Add ciColumns to AST nkCreateIndex
- Build composite index keys as table.col1.col2 with val1|val2
- Support multi-column exact match in SELECT for AND chains
- Implement non-recursive CTE execution via ctx.cteTables materialization
- Add tkRecursive token and parse WITH RECURSIVE
- Fix test isolation: use temp dirs for JOIN, migration, and RLS tests
- All tests passing (0 failures)
This commit is contained in:
2026-05-07 10:27:40 +03:00
parent ca345eb256
commit eaa5760fd4
14 changed files with 300 additions and 46 deletions
+9
View File
@@ -37,6 +37,7 @@ class FieldKind:
ARRAY = 0x0A
OBJECT = 0x0B
VECTOR = 0x0C
JSON = 0x0D
class MsgKind:
@@ -88,6 +89,7 @@ class WireValue:
class QueryResult:
def __init__(self):
self.columns: list[str] = []
self.column_types: list[str] = []
self.rows: list[list[Any]] = []
self.row_count: int = 0
self.affected_rows: int = 0
@@ -176,7 +178,12 @@ class Client:
val = self._deserialize_value(data, pos)
row.append(val)
rows.append(row)
col_types = []
for _ in range(col_count):
col_types.append(hex(data[pos[0]]))
pos[0] += 1
result.columns = cols
result.column_types = col_types
result.rows = rows
result.row_count = row_count
# Read following COMPLETE message
@@ -281,6 +288,8 @@ class Client:
vec.append(struct.unpack(">f", data[pos[0]:pos[0]+4])[0])
pos[0] += 4
return vec
elif kind == FieldKind.JSON:
return self._read_string(data, pos)
return None
def __enter__(self):