nedb-engine 4.3.2 → 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -18,7 +18,7 @@ One Rust core → ships to **PyPI** and **npm** from a single source.
18
18
  **[Studio → studio.interchained.org](https://studio.interchained.org)** · **[nedb.aiassist.net](https://nedb.aiassist.net)**
19
19
 
20
20
  > ## 🟢 Free in production under $1M revenue
21
- > NEDB 4.0.0 is licensed under the **Business Source License 1.1**. If your organisation's annual
21
+ > NEDB is licensed under the **Business Source License 1.1** (since 4.0.0). If your organisation's annual
22
22
  > revenue is **under USD $1,000,000**, you may use it in production — commercially, embedded, in
23
23
  > closed-source software — with **no permission needed and no royalty**. At **$1M or more**, you
24
24
  > need an additional use grant from Interchained LLC: **licensing@interchained.org**.
@@ -38,14 +38,74 @@ endpoint already answers `psql`, SQLAlchemy Core **and** ORM, asyncpg and
38
38
  node-postgres against a live store — but it gets there by *translating* SQL into
39
39
  NQL, and a translation can only reach as far as the target language's shape.
40
40
 
41
- **[neSQL](https://github.com/Eth-Interchained/neSQL)** removes the translation:
42
- PostgreSQL's real grammar, vendored with its licence intact, extended with NEDB's
43
- temporal and causal clauses. Two front-ends, one plan. NQL folded in, not deleted.
41
+ **[neSQL](https://github.com/Eth-Interchained/neSQL)** removes the translation.
42
+ PostgreSQL's real grammar (`gram.y`, 19,513 lines, 492 keywords, vendored from
43
+ 17.4 at [`vendor/postgresql/`](vendor/postgresql/) with its licence intact),
44
+ extended with NEDB's temporal and causal clauses. **Two front-ends, one plan.
45
+ NQL folded in, not deleted.**
44
46
 
45
47
  [![neSQL on PyPI](https://img.shields.io/pypi/v/nesql?label=nesql%20·%20PyPI&color=a855f7)](https://pypi.org/project/nesql/)
46
48
  [![neSQL on crates.io](https://img.shields.io/crates/v/nesql?label=nesql%20·%20crates.io&color=a855f7)](https://crates.io/crates/nesql)
47
49
  [![neSQL on npm](https://img.shields.io/npm/v/nesql-engine?label=nesql-engine%20·%20npm&color=a855f7)](https://www.npmjs.com/package/nesql-engine)
48
50
 
51
+ ### Available now, opt-in: `NEDBD_SQL_ENGINE=1`
52
+
53
+ The SQL engine is in this release and it is **off by default**. Turn it on and a
54
+ user collection is answered by a real SQL evaluator instead of a translation —
55
+ every one of these works, and every one is refused *by name* without it:
56
+
57
+ ```sql
58
+ SELECT o._id, d.name FROM orders o JOIN drivers d ON o.driver = d._id;
59
+ SELECT status, sum(total), avg(total) FROM orders GROUP BY status;
60
+ SELECT _id FROM orders WHERE driver IN (SELECT _id FROM drivers);
61
+ SELECT DISTINCT status FROM orders;
62
+ SELECT _id FROM orders UNION SELECT _id FROM drivers;
63
+ SELECT status, array_agg(_id ORDER BY total DESC) FROM orders GROUP BY status;
64
+ ```
65
+
66
+ `sum(total), avg(total)` in one grouped row is the one worth pointing at. An NQL
67
+ grouped row carries the group key, `count`, and **one** named aggregate — so that
68
+ query was never slow, it was *unrepresentable*. No translator can fix a row
69
+ model, which is the whole reason neSQL exists.
70
+
71
+ **And NQL's own verbs are now SQL clauses**, so they compose with all of the
72
+ above rather than living on a separate path:
73
+
74
+ ```sql
75
+ -- full-text search from NQL, a join from SQL, one statement
76
+ SELECT o._id, d.name
77
+ FROM orders SEARCH 'acme' o
78
+ JOIN drivers d ON o.driver = d._id;
79
+
80
+ -- one relation in the past, joined against another at the tip
81
+ SELECT h.total, n.total
82
+ FROM orders AS OF SYSTEM TIME 412 h
83
+ JOIN audit n ON h._id = n._id;
84
+
85
+ SELECT _id FROM orders VALID AS OF '2026-01-01';
86
+ ```
87
+
88
+ There is **one implementation** of each verb — the SQL side parses them and the
89
+ NQL engine still executes them — so neither language is a reimplementation of
90
+ the other. `AS OF SYSTEM TIME`, `VALID AS OF` and `SEARCH` are **unreserved
91
+ keywords**: a collection aliased `search`, or a column named `valid`, keeps
92
+ working exactly as before.
93
+
94
+ **Why it is opt-in rather than the default**, stated plainly because the reason
95
+ is the interesting part. A parity harness runs the same corpus through both
96
+ engines and asserts identical answers — 44 checks, in CI, and it is what earns
97
+ the flag being flipped rather than a benchmark. It already found two real
98
+ divergences: `SELECT *` returned its columns in a different order on each
99
+ engine, and the SQL evaluator built its column list from the **first row alone**,
100
+ so a field only later documents carried silently did not appear at all.
101
+
102
+ Both are fixed. But 44 checks over six documents proves agreement on the shapes
103
+ we thought to test, and the evaluator still materialises each relation — the
104
+ `WHERE` is pushed into the scan, which narrows *what* is read but not *whether*.
105
+ Flipping the default changes the read path of every existing deployment, and
106
+ "correct on six rows" is not "safe on six million". So it ships as a flag, with
107
+ the bar for changing that written down.
108
+
49
109
  ---
50
110
 
51
111
  ## New in 3.3.0 — the query language grew up
@@ -200,46 +260,59 @@ all the work in this sentence. Every refusal below traces to the same cause:
200
260
  NQL is the engine's native language, so SQL has to be rewritten into it, and a
201
261
  rewrite can only ever reach as far as the target language's shape.
202
262
 
203
- | Supported today | Refused, with the reason | neSQL |
263
+ | Supported on the default path | Refused there, with the reason | `NEDBD_SQL_ENGINE=1` |
204
264
  | --- | --- | --- |
205
- | `*`, a column list, `COUNT(*)`, `SUM`/`AVG`/`MIN`/`MAX(col)` | `JOIN` — NQL is single-collection | ✅ joins already exist in the executor |
206
- | `WHERE` — the whole NQL predicate surface | subqueries, `UNION`, window functions | ✅ subqueries + set ops exist; windows arrive with the grammar |
207
- | `GROUP BY`, `HAVING`, `ORDER BY`, `LIMIT`, `OFFSET` | expressions in the select list | ✅ |
208
- | one named aggregate per grouped row | `sum(x), avg(x)` in one query — NQL's grouped row holds *one* | ✅ the row-model cap goes away |
209
- | `AS OF SYSTEM TIME <seq>` | DDL, `TRUNCATE`, `GRANT`/`REVOKE` | ⛔️ still refused, and always will be |
210
- | `INSERT` / `UPDATE` / `DELETE`, all with `RETURNING` | an `INSERT` with no column list | |
211
- | `_caused_by` / `_valid_from` / `_valid_to` as INSERT columns | values that are expressions, not literals | |
265
+ | `*`, a column list, `COUNT(*)`, `SUM`/`AVG`/`MIN`/`MAX(col)` | `JOIN` — NQL is single-collection | ✅ **works** (nested-loop + hash) |
266
+ | `WHERE` — the whole NQL predicate surface | subqueries, `UNION`, window functions | ✅ **subqueries, `EXISTS`, `UNION`/`INTERSECT`/`EXCEPT` work**; window functions arrive with the grammar |
267
+ | `GROUP BY`, `HAVING`, `ORDER BY`, `LIMIT`, `OFFSET` | expressions in the select list | ✅ **works** |
268
+ | one named aggregate per grouped row | `sum(x), avg(x)` in one query — NQL's grouped row holds *one* | ✅ **works** — the row-model cap is gone |
269
+ | | `DISTINCT`, `array_agg(x ORDER BY y)`, derived tables | **works** |
270
+ | `AS OF SYSTEM TIME <seq>`, `VALID AS OF`, `SEARCH` | | **also works**, and composes with joins and aggregates |
271
+ | `TRACE`, `TRAVERSE`, `LINK` | | ↩︎ still answered by the NQL path; SQL has no spelling for them yet |
272
+ | `INSERT` / `UPDATE` / `DELETE`, all with `RETURNING` | an `INSERT` with no column list | writes always take the NQL path |
273
+ | `_caused_by` / `_valid_from` / `_valid_to` as INSERT columns | values that are expressions, not literals | as above |
274
+ | — | DDL, `TRUNCATE`, `GRANT`/`REVOKE` | ⛔️ **refused on both**, and always will be |
212
275
 
213
276
  The `⛔️` row is the one that is not a limitation. `TRUNCATE` is refused because
214
277
  NEDB is append-only *so that history cannot be discarded* — that is the product,
215
278
  not a gap — and DDL is refused because collections are created by the first write
216
279
  to them. Those answers do not change.
217
280
 
218
- ### Every other row on that table is a translation artefact, and it is going away
281
+ ### Every other row on that table was a translation artefact and one flag removes them
219
282
 
220
283
  > ### 🆕 [**neSQL**](https://github.com/Eth-Interchained/neSQL) — PostgreSQL's grammar, NEDB's memory
221
284
  >
222
- > We stopped translating. neSQL vendors PostgreSQL's **real grammar** `gram.y`,
223
- > 19,513 lines and 492 keywords, from PostgreSQL 17.4, licence intact and extends
224
- > it with the clauses NEDB needs, rather than rewriting SQL into a language that
225
- > cannot express it.
285
+ > Those refusals were never the engine's limits. `sqlselect.rs` has had
286
+ > nested-loop and hash joins, subqueries, `EXISTS`, quantified comparisons, set
287
+ > operations, `array_agg(x ORDER BY y)` and derived tables for some time they
288
+ > were simply unreachable *through a translator*, because the translator's
289
+ > target was NQL. Set `NEDBD_SQL_ENGINE=1` and they are reachable.
290
+ >
291
+ > neSQL vendors PostgreSQL's **real grammar** — `gram.y`, 19,513 lines and 492
292
+ > keywords, from 17.4, licence intact — and extends it with the clauses NEDB
293
+ > needs, rather than rewriting SQL into a language that cannot express it.
226
294
  >
227
- > It is worth knowing *why* this was never free: `SYSTEM_TIME`, `PERIOD` and
228
- > `PORTION` appear **zero** times in PostgreSQL's grammar. Postgres has no temporal
229
- > SQL at all. `AS OF SYSTEM TIME` is a CockroachDB extension, which means NEDB's
230
- > temporal clauses are additions to the vendored grammar rather than deviations
231
- > from it the same road CockroachDB, Materialize and RisingWave took.
295
+ > It is worth knowing *why* the temporal clauses were never free: `SYSTEM_TIME`,
296
+ > `PERIOD` and `PORTION` appear **zero** times in PostgreSQL's grammar. Postgres
297
+ > has no temporal SQL at all, and `AS OF SYSTEM TIME` is a CockroachDB
298
+ > extension — so NEDB's temporal clauses are additions *to* the vendored grammar
299
+ > rather than deviations *from* it. The same road CockroachDB, Materialize and
300
+ > RisingWave took. What the grammar does hand over free: `WITH RECURSIVE`,
301
+ > window functions, `GROUPING SETS` and `MERGE`.
232
302
  >
233
303
  > ```bash
234
304
  > pip install nesql · cargo add nesql · npm install nesql-engine
235
305
  > ```
236
306
  >
237
- > Names reserved, grammar vendored, executor foundations already shipping inside
238
- > this engine. Each package loads and answers `is_release() == false`, because a
239
- > package that imports cleanly and then lies is worse than one that isn't published.
307
+ > Those three are **reserved names**, not a product: each loads and answers
308
+ > `is_release() == false`, because a package that imports cleanly and then lies
309
+ > is worse than one that isn't published. The engine is what ships today, and
310
+ > neSQL will be this same engine under its own name.
240
311
  >
241
- > **NQL is not being deleted.** It gets folded in: two front-ends compiling to one
242
- > plan, so nothing translates and neither language is a second-class guest.
312
+ > **NQL is not being deleted, and it is not being wrapped.** Its verbs are SQL
313
+ > clauses now `AS OF SYSTEM TIME`, `VALID AS OF`, `SEARCH` — parsed by the SQL
314
+ > side and executed by the NQL engine. One implementation, two front-ends,
315
+ > neither one a second-class guest.
243
316
 
244
317
  Every refusal names the boundary instead of saying "syntax error", and a
245
318
  grouped query that projects a column SQL would reject gets Postgres's own
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nedb-engine",
3
- "version": "4.3.2",
3
+ "version": "5.0.0",
4
4
  "description": "NEDB \u2014 hash-chained, time-traveling, bi-temporal embedded database with Rust native core. SQL, Redis, MongoDB adapters. Causal Write Provenance. RESP2 wire protocol.",
5
5
  "main": "index.js",
6
6
  "exports": {