orez 0.2.27 → 0.2.30

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.
Files changed (157) hide show
  1. package/dist/cf-do/worker.d.ts +3 -0
  2. package/dist/cf-do/worker.d.ts.map +1 -1
  3. package/dist/cf-do/worker.js +37 -15
  4. package/dist/cf-do/worker.js.map +1 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +8 -0
  7. package/dist/index.js.map +1 -1
  8. package/package.json +3 -4
  9. package/src/admin/admin-data.test.ts +0 -348
  10. package/src/admin/http-proxy.ts +0 -252
  11. package/src/admin/log-store.ts +0 -192
  12. package/src/admin/server.ts +0 -471
  13. package/src/admin/ui.ts +0 -1322
  14. package/src/bench/proxy-throughput.bench.ts +0 -343
  15. package/src/bench/serial-mutations.bench.ts +0 -270
  16. package/src/browser.ts +0 -203
  17. package/src/cf-do/.wrangler/cache/cf.json +0 -1
  18. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite +0 -0
  19. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm +0 -0
  20. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal +0 -0
  21. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/0ffaabee41a60e04dd0eb7db3073f0a40139e6a97ccd26823967acb652b89a7b.sqlite +0 -0
  22. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite +0 -0
  23. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-shm +0 -0
  24. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-wal +0 -0
  25. package/src/cf-do/.wrangler/tmp/bundle-0z4CpE/middleware-insertion-facade.js +0 -11
  26. package/src/cf-do/.wrangler/tmp/bundle-0z4CpE/middleware-loader.entry.ts +0 -134
  27. package/src/cf-do/.wrangler/tmp/bundle-vYmw0E/middleware-insertion-facade.js +0 -11
  28. package/src/cf-do/.wrangler/tmp/bundle-vYmw0E/middleware-loader.entry.ts +0 -134
  29. package/src/cf-do/.wrangler/tmp/dev-cbILNo/worker.js +0 -1059
  30. package/src/cf-do/.wrangler/tmp/dev-cbILNo/worker.js.map +0 -8
  31. package/src/cf-do/.wrangler/tmp/dev-qbho19/worker.js +0 -1059
  32. package/src/cf-do/.wrangler/tmp/dev-qbho19/worker.js.map +0 -8
  33. package/src/cf-do/ARCHITECTURE.md +0 -93
  34. package/src/cf-do/CHAT_E2E.md +0 -213
  35. package/src/cf-do/watermark.test.ts +0 -103
  36. package/src/cf-do/watermark.ts +0 -118
  37. package/src/cf-do/worker.ts +0 -1041
  38. package/src/cf-do/wrangler.toml +0 -11
  39. package/src/cf-pglite/README.md +0 -19
  40. package/src/change-tracking.ts +0 -25
  41. package/src/child-process.test.ts +0 -147
  42. package/src/child-process.ts +0 -90
  43. package/src/cli-entry.ts +0 -72
  44. package/src/cli.test.ts +0 -40
  45. package/src/cli.ts +0 -1214
  46. package/src/config.ts +0 -150
  47. package/src/do-sql-tracking.test.ts +0 -19
  48. package/src/do-sql-tracking.ts +0 -19
  49. package/src/index.ts +0 -1215
  50. package/src/integration/integration.test.ts +0 -517
  51. package/src/integration/native-binary.guard.test.ts +0 -13
  52. package/src/integration/native-startup.test.ts +0 -44
  53. package/src/integration/replication-latency.test.ts +0 -428
  54. package/src/integration/restore-live-stress.test.ts +0 -433
  55. package/src/integration/restore-reset.test.ts +0 -400
  56. package/src/integration/restore.test.ts +0 -274
  57. package/src/integration/test-permissions.ts +0 -147
  58. package/src/load-config.ts +0 -46
  59. package/src/log.ts +0 -96
  60. package/src/mutex.ts +0 -47
  61. package/src/pg-proxy-browser.singledb.test.ts +0 -233
  62. package/src/pg-proxy-browser.ts +0 -2022
  63. package/src/pg-proxy-do-backend.test.ts +0 -3890
  64. package/src/pg-proxy-do-backend.ts +0 -7191
  65. package/src/pg-proxy.ts +0 -1087
  66. package/src/pg-sqlite-compiler/README.md +0 -53
  67. package/src/pg-sqlite-compiler/catalog/seed.ts +0 -524
  68. package/src/pg-sqlite-compiler/fixtures/pgsqlite/arithmetic.json +0 -307
  69. package/src/pg-sqlite-compiler/fixtures/pgsqlite/array.json +0 -377
  70. package/src/pg-sqlite-compiler/fixtures/pgsqlite/cast.json +0 -12
  71. package/src/pg-sqlite-compiler/fixtures/pgsqlite/catalog.json +0 -447
  72. package/src/pg-sqlite-compiler/fixtures/pgsqlite/create-table.json +0 -32
  73. package/src/pg-sqlite-compiler/fixtures/pgsqlite/datetime.json +0 -397
  74. package/src/pg-sqlite-compiler/fixtures/pgsqlite/enum.json +0 -337
  75. package/src/pg-sqlite-compiler/fixtures/pgsqlite/insert.json +0 -337
  76. package/src/pg-sqlite-compiler/fixtures/pgsqlite/json.json +0 -537
  77. package/src/pg-sqlite-compiler/fixtures/pgsqlite/misc.json +0 -1837
  78. package/src/pg-sqlite-compiler/index.ts +0 -73
  79. package/src/pg-sqlite-compiler/integration.test.ts +0 -136
  80. package/src/pg-sqlite-compiler/passes/ast-utils.ts +0 -113
  81. package/src/pg-sqlite-compiler/passes/catalog.ts +0 -65
  82. package/src/pg-sqlite-compiler/passes/datetime.ts +0 -74
  83. package/src/pg-sqlite-compiler/passes/index.ts +0 -49
  84. package/src/pg-sqlite-compiler/passes/types.ts +0 -156
  85. package/src/pg-sqlite-compiler/smoke.test.ts +0 -69
  86. package/src/pg-sqlite-compiler/test/catalog.test.ts +0 -171
  87. package/src/pg-sqlite-compiler/test/corpus.test.ts +0 -161
  88. package/src/pg-sqlite-compiler/test/datetime.oracle.test.ts +0 -102
  89. package/src/pg-sqlite-compiler/test/oracle.ts +0 -237
  90. package/src/pg-sqlite-compiler/test/types.test.ts +0 -109
  91. package/src/pg-sqlite-compiler/types.ts +0 -63
  92. package/src/pglite-ipc.test.ts +0 -116
  93. package/src/pglite-ipc.ts +0 -266
  94. package/src/pglite-manager.ts +0 -557
  95. package/src/pglite-web-proxy.test.ts +0 -57
  96. package/src/pglite-web-proxy.ts +0 -221
  97. package/src/pglite-web-worker.ts +0 -152
  98. package/src/pglite-worker-thread.ts +0 -253
  99. package/src/port.ts +0 -25
  100. package/src/process-title.ts +0 -9
  101. package/src/recovery.ts +0 -155
  102. package/src/replication/change-tracker.test.ts +0 -357
  103. package/src/replication/change-tracker.ts +0 -279
  104. package/src/replication/handler.test.ts +0 -511
  105. package/src/replication/handler.ts +0 -1190
  106. package/src/replication/pgoutput-encoder.test.ts +0 -697
  107. package/src/replication/pgoutput-encoder.ts +0 -373
  108. package/src/replication/tcp-replication.test.ts +0 -876
  109. package/src/replication/zero-compat.test.ts +0 -1150
  110. package/src/restore-stress.test.ts +0 -188
  111. package/src/s3-local.ts +0 -203
  112. package/src/shim/hooks.mjs +0 -120
  113. package/src/shim/register.mjs +0 -4
  114. package/src/sqlite-mode/apply-mode.ts +0 -224
  115. package/src/sqlite-mode/index.ts +0 -15
  116. package/src/sqlite-mode/native-binary.ts +0 -89
  117. package/src/sqlite-mode/package-resolve.ts +0 -17
  118. package/src/sqlite-mode/resolve-mode.ts +0 -80
  119. package/src/sqlite-mode/shim-template.ts +0 -159
  120. package/src/sqlite-mode/sqlite-mode.test.ts +0 -427
  121. package/src/sqlite-mode/types.ts +0 -30
  122. package/src/vite-plugin.ts +0 -67
  123. package/src/wasm-sqlite.test.ts +0 -537
  124. package/src/worker/browser-admin.ts +0 -52
  125. package/src/worker/browser-build-config.test.ts +0 -71
  126. package/src/worker/browser-build-config.ts +0 -109
  127. package/src/worker/browser-embed-admin.test.ts +0 -75
  128. package/src/worker/browser-embed.ts +0 -345
  129. package/src/worker/cf-patches.ts +0 -384
  130. package/src/worker/embed-integration.test.ts +0 -321
  131. package/src/worker/index.ts +0 -138
  132. package/src/worker/shims/fastify.test.ts +0 -255
  133. package/src/worker/shims/fastify.ts +0 -306
  134. package/src/worker/shims/http-service.test.ts +0 -355
  135. package/src/worker/shims/http-service.ts +0 -293
  136. package/src/worker/shims/node-stub.ts +0 -290
  137. package/src/worker/shims/oxfmt.ts +0 -3
  138. package/src/worker/shims/postgres-browser.ts +0 -59
  139. package/src/worker/shims/postgres-socket.test.ts +0 -576
  140. package/src/worker/shims/postgres-socket.ts +0 -310
  141. package/src/worker/shims/postgres.test.ts +0 -364
  142. package/src/worker/shims/postgres.ts +0 -1454
  143. package/src/worker/shims/sqlite-browser.test.ts +0 -233
  144. package/src/worker/shims/sqlite-browser.ts +0 -175
  145. package/src/worker/shims/sqlite.test.ts +0 -786
  146. package/src/worker/shims/sqlite.ts +0 -978
  147. package/src/worker/shims/stream-browser.ts +0 -15
  148. package/src/worker/shims/ws-browser.test.ts +0 -205
  149. package/src/worker/shims/ws-browser.ts +0 -248
  150. package/src/worker/shims/ws.test.ts +0 -288
  151. package/src/worker/shims/ws.ts +0 -467
  152. package/src/worker/shims/zero-process-env.ts +0 -11
  153. package/src/worker/types.ts +0 -75
  154. package/src/worker/worker-integration.test.ts +0 -223
  155. package/src/worker/worker.test.ts +0 -136
  156. package/src/worker/zero-cache-embed-cf.ts +0 -463
  157. package/src/worker/zero-cache-embed.ts +0 -277
@@ -1,69 +0,0 @@
1
- /**
2
- * Smoke test for the compiler scaffold.
3
- *
4
- * Validates the pipeline (parse → passes → emit) works end-to-end on a few
5
- * representative cases. Real coverage comes from the snapshot + oracle tests.
6
- */
7
- import { describe, expect, it } from 'vitest'
8
-
9
- import { compile } from './index.js'
10
-
11
- describe('pg-sqlite-compiler smoke', () => {
12
- it('passes through trivial select', () => {
13
- const { sql, warnings } = compile('SELECT 1 AS ok')
14
- expect(warnings).toEqual([])
15
- expect(sql).toMatch(/SELECT\s+1\s+AS\s+ok/i)
16
- })
17
-
18
- it('rewrites NOW() to CURRENT_TIMESTAMP', () => {
19
- const { sql } = compile('SELECT NOW() AS t')
20
- expect(sql).toMatch(/CURRENT_TIMESTAMP/i)
21
- expect(sql).not.toMatch(/NOW\s*\(/i)
22
- })
23
-
24
- it('rewrites NOW() inside CREATE TABLE DEFAULT', () => {
25
- const { sql } = compile(
26
- 'CREATE TABLE event (id text PRIMARY KEY, "createdAt" timestamp DEFAULT NOW() NOT NULL)'
27
- )
28
- expect(sql).toMatch(/CURRENT_TIMESTAMP/i)
29
- expect(sql).not.toMatch(/NOW\s*\(/i)
30
- })
31
-
32
- it('passes CURRENT_TIMESTAMP keyword through unchanged', () => {
33
- // CURRENT_TIMESTAMP is a SQL bareword, not a function call — should already
34
- // round-trip cleanly without our pass touching it.
35
- const { sql } = compile('SELECT CURRENT_TIMESTAMP AS t')
36
- expect(sql).toMatch(/CURRENT_TIMESTAMP/i)
37
- })
38
-
39
- it('rewrites pg_catalog.now() to CURRENT_TIMESTAMP', () => {
40
- const { sql } = compile('SELECT pg_catalog.now() AS t')
41
- expect(sql).toMatch(/CURRENT_TIMESTAMP/i)
42
- expect(sql).not.toMatch(/pg_catalog/i)
43
- })
44
-
45
- it('rewrites NOW() in an UPDATE SET clause', () => {
46
- const { sql } = compile('UPDATE event SET "updatedAt" = NOW() WHERE id = $1')
47
- expect(sql).toMatch(/CURRENT_TIMESTAMP/i)
48
- expect(sql).not.toMatch(/now\s*\(/i)
49
- })
50
-
51
- it('rewrites CURRENT_DATE used as DEFAULT', () => {
52
- const { sql } = compile(
53
- 'CREATE TABLE log (id text PRIMARY KEY, "day" date DEFAULT CURRENT_DATE NOT NULL)'
54
- )
55
- expect(sql).toMatch(/CURRENT_DATE/i)
56
- })
57
-
58
- it('preserves multi-statement input', () => {
59
- const { sql } = compile('SELECT 1; SELECT 2')
60
- expect(sql).toMatch(/SELECT\s+1/i)
61
- expect(sql).toMatch(/SELECT\s+2/i)
62
- })
63
-
64
- it('preserves quoted identifiers', () => {
65
- const { sql } = compile('SELECT id, "createdAt" FROM public.message')
66
- expect(sql).toMatch(/"createdAt"/)
67
- expect(sql).toMatch(/public\.message/i)
68
- })
69
- })
@@ -1,171 +0,0 @@
1
- import Database from '@rocicorp/zero-sqlite3'
2
- /**
3
- * Catalog pass tests.
4
- *
5
- * Validates two things in tandem:
6
- * 1. The pass rewrites catalog refs to _orez_catalog__* (snapshot-style).
7
- * 2. The seed creates matching tables that the rewritten query can
8
- * actually execute against (semantic equivalence with a real catalog).
9
- */
10
- import { describe, expect, it } from 'vitest'
11
-
12
- import { buildCatalogTables } from '../catalog/seed.js'
13
- import { compile } from '../index.js'
14
-
15
- function rewriteParams(sql: string): string {
16
- return sql.replace(/\$\d+/g, '?')
17
- }
18
-
19
- function freshDb(): { db: any; setup: (s: string[]) => void } {
20
- const db = new Database(':memory:')
21
- return {
22
- db,
23
- setup: (statements: string[]) => {
24
- for (const s of statements) {
25
- const { sql } = compile(s)
26
- db.exec(sql)
27
- }
28
- },
29
- }
30
- }
31
-
32
- describe('catalog pass — rewrite', () => {
33
- it('pg_catalog.pg_class → _orez_catalog__pg_class', () => {
34
- const { sql } = compile('SELECT relname FROM pg_catalog.pg_class WHERE relkind = $1')
35
- expect(sql).toMatch(/_orez_catalog__pg_class/)
36
- expect(sql).not.toMatch(/pg_catalog\./)
37
- })
38
-
39
- it('bare pg_class (no schema) is NOT rewritten — would hijack user tables', () => {
40
- // Apps may legitimately have a table called `pg_user`/`pg_views`/etc.
41
- // Catalog clients always qualify (`pg_catalog.pg_class`), so the bare
42
- // form is treated as a user table.
43
- const { sql } = compile('SELECT relname FROM pg_class WHERE relkind = $1')
44
- expect(sql).not.toMatch(/_orez_catalog/)
45
- expect(sql).toMatch(/FROM pg_class/i)
46
- })
47
-
48
- it('information_schema.columns → _orez_catalog__information_schema_columns', () => {
49
- const { sql } = compile(
50
- "SELECT column_name FROM information_schema.columns WHERE table_name = 't'"
51
- )
52
- expect(sql).toMatch(/_orez_catalog__information_schema_columns/)
53
- expect(sql).not.toMatch(/information_schema\./)
54
- })
55
-
56
- it('user table refs (e.g. message) are NOT rewritten', () => {
57
- const { sql } = compile('SELECT id FROM message WHERE id = $1')
58
- expect(sql).not.toMatch(/_orez_catalog/)
59
- expect(sql).toMatch(/FROM message/i)
60
- })
61
-
62
- it('information_schema.tables → flat name', () => {
63
- const { sql } = compile(
64
- "SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'"
65
- )
66
- expect(sql).toMatch(/_orez_catalog__information_schema_tables/)
67
- })
68
-
69
- it('schema-qualified pg_publication → flat name', () => {
70
- const { sql } = compile(
71
- 'SELECT pubname FROM pg_catalog.pg_publication WHERE pubname IN ($1)'
72
- )
73
- expect(sql).toMatch(/_orez_catalog__pg_publication/)
74
- })
75
-
76
- it('INSERT INTO pg_user (bare) is NOT rewritten — user-owned table', () => {
77
- // Regression guard: earlier iterations rewrote bare PG catalog names,
78
- // which silently redirected user DML at synthetic catalog tables.
79
- const { sql } = compile('INSERT INTO pg_user (id) VALUES ($1)')
80
- expect(sql).not.toMatch(/_orez_catalog/)
81
- })
82
- })
83
-
84
- describe('catalog seed + pass roundtrip — executable', () => {
85
- it('pg_class returns the user-table rows after seeding', () => {
86
- const { db, setup } = freshDb()
87
- setup([
88
- 'CREATE TABLE message (id text PRIMARY KEY, content text)',
89
- 'CREATE TABLE event (id text PRIMARY KEY, ts timestamp)',
90
- ])
91
- buildCatalogTables(db)
92
- const { sql } = compile(`SELECT relname FROM pg_catalog.pg_class WHERE relkind = 'r'`)
93
- const rows = db.prepare(rewriteParams(sql)).all() as { relname: string }[]
94
- const names = rows.map((r) => r.relname).sort()
95
- expect(names).toContain('message')
96
- expect(names).toContain('event')
97
- db.close()
98
- })
99
-
100
- it('pg_attribute returns column info per table', () => {
101
- const { db, setup } = freshDb()
102
- setup(['CREATE TABLE message (id text PRIMARY KEY, content text NOT NULL)'])
103
- buildCatalogTables(db)
104
- const { sql } = compile(`
105
- SELECT a.attname, a.attnotnull
106
- FROM pg_catalog.pg_attribute a
107
- JOIN pg_catalog.pg_class c ON a.attrelid = c.oid
108
- WHERE c.relname = 'message'
109
- ORDER BY a.attnum
110
- `)
111
- const rows = db.prepare(rewriteParams(sql)).all() as {
112
- attname: string
113
- attnotnull: number
114
- }[]
115
- expect(rows.map((r) => r.attname)).toEqual(['id', 'content'])
116
- // `content text NOT NULL` is reported NOT NULL; SQLite's PRAGMA table_info
117
- // reports `id text PRIMARY KEY` as NOT NULL only when explicitly written
118
- // that way (historical SQLite quirk), so we only check `content` here.
119
- expect(rows[1].attnotnull).toBe(1)
120
- db.close()
121
- })
122
-
123
- it('information_schema.columns returns column metadata', () => {
124
- const { db, setup } = freshDb()
125
- setup(['CREATE TABLE event (id text PRIMARY KEY, "createdAt" timestamp)'])
126
- buildCatalogTables(db)
127
- const { sql } = compile(
128
- "SELECT column_name, data_type FROM information_schema.columns WHERE table_name = 'event' ORDER BY ordinal_position"
129
- )
130
- const rows = db.prepare(rewriteParams(sql)).all() as {
131
- column_name: string
132
- data_type: string
133
- }[]
134
- expect(rows.map((r) => r.column_name)).toEqual(['id', 'createdAt'])
135
- db.close()
136
- })
137
-
138
- it('pg_namespace contains public + pg_catalog', () => {
139
- const { db, setup } = freshDb()
140
- setup([])
141
- buildCatalogTables(db)
142
- const { sql } = compile('SELECT nspname FROM pg_catalog.pg_namespace ORDER BY oid')
143
- const rows = db.prepare(rewriteParams(sql)).all() as { nspname: string }[]
144
- expect(rows.map((r) => r.nspname)).toEqual([
145
- 'pg_catalog',
146
- 'information_schema',
147
- 'public',
148
- ])
149
- db.close()
150
- })
151
-
152
- it('pg_publication is populated when ZERO_APP_PUBLICATIONS-style names supplied', () => {
153
- const { db, setup } = freshDb()
154
- setup(['CREATE TABLE message (id text PRIMARY KEY)'])
155
- buildCatalogTables(db, { publications: ['orez_zero_public'] })
156
- const { sql } = compile('SELECT pubname FROM pg_catalog.pg_publication')
157
- const rows = db.prepare(rewriteParams(sql)).all() as { pubname: string }[]
158
- expect(rows.map((r) => r.pubname)).toEqual(['orez_zero_public'])
159
-
160
- const { sql: sql2 } = compile(
161
- "SELECT pubname, tablename FROM pg_catalog.pg_publication_tables WHERE pubname = 'orez_zero_public'"
162
- )
163
- const ptRows = db.prepare(rewriteParams(sql2)).all() as {
164
- pubname: string
165
- tablename: string
166
- }[]
167
- expect(ptRows.length).toBeGreaterThanOrEqual(1)
168
- expect(ptRows[0].tablename).toBe('message')
169
- db.close()
170
- })
171
- })
@@ -1,161 +0,0 @@
1
- /**
2
- * Corpus tests — run every vendored pgsqlite fixture through the compiler.
3
- *
4
- * Asserts the compiler doesn't throw for fixtures in each bucket, against a
5
- * per-bucket **minimum-passing-count ratchet** (`BASELINE_OK`). Pass rates
6
- * are already 94–100% — a flat 50% floor would silently mask real
7
- * regressions. The ratchet is in absolute counts (not percentages) so adding
8
- * new fixtures to a bucket can't make the threshold easier to clear.
9
- *
10
- * Bumping a baseline: improve coverage, run the test, copy the new count
11
- * from the summary table into `BASELINE_OK`. Never lower a baseline without
12
- * understanding *why* — that's the regression alarm.
13
- *
14
- * Specific buckets have their own oracle tests (datetime.oracle.test.ts,
15
- * etc.) that check translation correctness in detail.
16
- */
17
- import { readFileSync } from 'node:fs'
18
- import { resolve } from 'node:path'
19
-
20
- import { describe, expect, it } from 'vitest'
21
-
22
- import { compile } from '../index.js'
23
-
24
- const FIXTURES_DIR = resolve(import.meta.dirname, '..', 'fixtures', 'pgsqlite')
25
-
26
- interface BucketFixture {
27
- source: string
28
- bucket: string
29
- count: number
30
- cases: { name: string; sql: string; source: string }[]
31
- }
32
-
33
- function loadBucket(bucket: string): BucketFixture {
34
- return JSON.parse(readFileSync(resolve(FIXTURES_DIR, `${bucket}.json`), 'utf-8'))
35
- }
36
-
37
- const BUCKETS = [
38
- 'datetime',
39
- 'array',
40
- 'cast',
41
- 'json',
42
- 'catalog',
43
- 'enum',
44
- 'create-table',
45
- 'insert',
46
- 'arithmetic',
47
- 'misc',
48
- ]
49
-
50
- /**
51
- * Minimum non-throwing fixture count per bucket. The corpus today passes at
52
- * 99.2% overall; these baselines lock that in. Bump (never lower) when
53
- * coverage improves.
54
- */
55
- const BASELINE_OK: Record<string, number> = {
56
- arithmetic: 60,
57
- array: 74,
58
- cast: 1,
59
- catalog: 87,
60
- 'create-table': 5,
61
- datetime: 74,
62
- enum: 66,
63
- insert: 65,
64
- json: 106,
65
- misc: 365,
66
- }
67
-
68
- interface BucketResult {
69
- bucket: string
70
- total: number
71
- parseOk: number
72
- compileOk: number
73
- // examples of failures (first 5) — useful when diagnosing regressions
74
- failures: { name: string; sql: string; error: string }[]
75
- }
76
-
77
- const results: BucketResult[] = []
78
-
79
- describe('pgsqlite corpus survival', () => {
80
- for (const bucket of BUCKETS) {
81
- describe(bucket, () => {
82
- let fixture: BucketFixture
83
- try {
84
- fixture = loadBucket(bucket)
85
- } catch {
86
- it.skip(`fixture missing for ${bucket}`, () => {})
87
- return
88
- }
89
-
90
- it(`compiles ${fixture.cases.length} cases without throwing`, () => {
91
- const result: BucketResult = {
92
- bucket,
93
- total: fixture.cases.length,
94
- parseOk: 0,
95
- compileOk: 0,
96
- failures: [],
97
- }
98
- for (const c of fixture.cases) {
99
- try {
100
- const { sql, warnings } = compile(c.sql)
101
- if (sql) {
102
- result.compileOk++
103
- result.parseOk++
104
- } else if (warnings.length === 0) {
105
- result.compileOk++
106
- result.parseOk++
107
- }
108
- } catch (err: any) {
109
- if (result.failures.length < 5) {
110
- result.failures.push({
111
- name: c.name,
112
- sql: c.sql.slice(0, 200),
113
- error: (err.message || String(err)).slice(0, 200),
114
- })
115
- }
116
- }
117
- }
118
- results.push(result)
119
- const baseline = BASELINE_OK[bucket] ?? 0
120
- if (result.compileOk < baseline) {
121
- const sample = result.failures
122
- .slice(0, 3)
123
- .map((f) => ` - ${f.name}: ${f.error}`)
124
- .join('\n')
125
- throw new Error(
126
- `corpus regression in bucket "${bucket}": got ${result.compileOk}/${result.total} passing, baseline is ${baseline}.\n` +
127
- `If this is intentional (e.g. fixture set changed), update BASELINE_OK.\n` +
128
- `Sample failures:\n${sample}`
129
- )
130
- }
131
- // also require coverage doesn't collapse against the fixture set
132
- expect(result.compileOk).toBeGreaterThanOrEqual(baseline)
133
- })
134
- })
135
- }
136
- })
137
-
138
- // emit a summary table after all tests run
139
- import { afterAll } from 'vitest'
140
- afterAll(() => {
141
- if (results.length === 0) return
142
- console.log('\n========== CORPUS COMPILER SURVIVAL ==========')
143
- console.log('bucket total ok pct example-failures')
144
- console.log('--------------------------------------------------')
145
- let totalAll = 0
146
- let okAll = 0
147
- for (const r of results.sort((a, b) => a.bucket.localeCompare(b.bucket))) {
148
- const pct = ((r.compileOk / Math.max(1, r.total)) * 100).toFixed(1).padStart(5)
149
- const ex = r.failures[0] ? `${r.failures[0].error.slice(0, 50)}` : ''
150
- console.log(
151
- `${r.bucket.padEnd(14)} ${String(r.total).padStart(5)} ${String(r.compileOk).padStart(5)} ${pct}% ${ex}`
152
- )
153
- totalAll += r.total
154
- okAll += r.compileOk
155
- }
156
- console.log('--------------------------------------------------')
157
- console.log(
158
- `${'TOTAL'.padEnd(14)} ${String(totalAll).padStart(5)} ${String(okAll).padStart(5)} ${((okAll / Math.max(1, totalAll)) * 100).toFixed(1).padStart(5)}%`
159
- )
160
- console.log('==============================================')
161
- })
@@ -1,102 +0,0 @@
1
- /**
2
- * Oracle tests for the datetime pass.
3
- *
4
- * For each PG query: run it against pgsqlite (oracle) AND through our
5
- * compile() + bun:sqlite. Compare result shapes. We don't compare exact
6
- * timestamps (CURRENT_TIMESTAMP returns "now" — non-deterministic) — just
7
- * that both sides return a row of the same shape with a parseable timestamp.
8
- */
9
- import { describe, expect, it } from 'vitest'
10
-
11
- import { compile } from '../index.js'
12
- import {
13
- ORACLE_AVAILABLE,
14
- connectOracle,
15
- runOracleAndCompiler,
16
- startPgsqliteServer,
17
- } from './oracle.js'
18
-
19
- const describeOracle = ORACLE_AVAILABLE ? describe : describe.skip
20
-
21
- describeOracle('datetime pass against pgsqlite oracle', () => {
22
- it('NOW() in SELECT — both sides return a timestamp', async () => {
23
- const { oracle, ours } = await runOracleAndCompiler([], 'SELECT NOW() AS t')
24
- expect(oracle).toHaveLength(1)
25
- expect(ours).toHaveLength(1)
26
- // both should expose 't' with something Date-parseable
27
- const ot = String((oracle[0] as any).t)
28
- const ut = String((ours[0] as any).t)
29
- expect(Number.isNaN(Date.parse(ot))).toBe(false)
30
- expect(Number.isNaN(Date.parse(ut))).toBe(false)
31
- }, 30_000)
32
-
33
- /**
34
- * pgsqlite has a known bug here: it rewrites `DEFAULT NOW()` →
35
- * `DEFAULT datetime('now')`, which isn't valid in a SQLite CREATE TABLE
36
- * DEFAULT clause (only a small expression grammar is permitted). Our
37
- * compiler rewrites to `DEFAULT CURRENT_TIMESTAMP` which IS valid.
38
- *
39
- * So this test validates *our* side standalone; if pgsqlite ever fixes
40
- * this bug, we can promote it to a full oracle test.
41
- */
42
- it('NOW() in CREATE TABLE DEFAULT — ours works (pgsqlite has a known bug here)', async () => {
43
- // @ts-expect-error — test-only sqlite driver
44
- const { default: Database } = await import('@rocicorp/zero-sqlite3')
45
- const db = new Database(':memory:')
46
- const { sql: c1 } = compile(
47
- 'CREATE TABLE event (id text PRIMARY KEY, ts timestamp DEFAULT NOW() NOT NULL)'
48
- )
49
- db.exec(c1)
50
- db.prepare('INSERT INTO event (id) VALUES (?)').run('e1')
51
- const ours = db.prepare('SELECT id, ts FROM event WHERE id = ?').all('e1') as any[]
52
- db.close()
53
- expect(ours).toHaveLength(1)
54
- expect(ours[0].id).toBe('e1')
55
- expect(String(ours[0].ts)).toMatch(/^\d{4}-\d{2}-\d{2}/)
56
- })
57
-
58
- it('CURRENT_DATE in DEFAULT — both sides accept', async () => {
59
- const server = await startPgsqliteServer()
60
- try {
61
- const conn = await connectOracle(server)
62
- try {
63
- await conn.exec(
64
- 'CREATE TABLE log (id text PRIMARY KEY, day date DEFAULT CURRENT_DATE NOT NULL)'
65
- )
66
- await conn.exec('INSERT INTO log (id) VALUES ($1)', ['l1'])
67
- const oracle = (await conn.exec('SELECT id, day FROM log WHERE id = $1', [
68
- 'l1',
69
- ])) as any[]
70
-
71
- // @ts-expect-error — test-only sqlite driver
72
- const { default: Database } = await import('@rocicorp/zero-sqlite3')
73
- const db = new Database(':memory:')
74
- const { sql: c1 } = compile(
75
- 'CREATE TABLE log (id text PRIMARY KEY, day date DEFAULT CURRENT_DATE NOT NULL)'
76
- )
77
- db.exec(c1)
78
- db.prepare('INSERT INTO log (id) VALUES (?)').run('l1')
79
- const ours = db.prepare('SELECT id, day FROM log WHERE id = ?').all('l1') as any[]
80
- db.close()
81
-
82
- expect(oracle).toHaveLength(1)
83
- expect(ours).toHaveLength(1)
84
- // postgres.js parses DATE values into JS Date objects; verify both
85
- // sides produced a Date-equivalent (today). Don't compare strings —
86
- // pgsqlite returns ISO, sqlite returns YYYY-MM-DD, both valid.
87
- const oracleDate = new Date(String(oracle[0].day))
88
- const ourDate = new Date(String(ours[0].day))
89
- expect(Number.isNaN(oracleDate.getTime())).toBe(false)
90
- expect(Number.isNaN(ourDate.getTime())).toBe(false)
91
- // Within ~24h of each other (allowing for TZ).
92
- expect(Math.abs(oracleDate.getTime() - ourDate.getTime())).toBeLessThan(
93
- 86_400_000
94
- )
95
- } finally {
96
- await conn.end()
97
- }
98
- } finally {
99
- await server.stop()
100
- }
101
- }, 30_000)
102
- })