orez 0.2.27 → 0.2.29

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 (150) hide show
  1. package/package.json +3 -4
  2. package/src/admin/admin-data.test.ts +0 -348
  3. package/src/admin/http-proxy.ts +0 -252
  4. package/src/admin/log-store.ts +0 -192
  5. package/src/admin/server.ts +0 -471
  6. package/src/admin/ui.ts +0 -1322
  7. package/src/bench/proxy-throughput.bench.ts +0 -343
  8. package/src/bench/serial-mutations.bench.ts +0 -270
  9. package/src/browser.ts +0 -203
  10. package/src/cf-do/.wrangler/cache/cf.json +0 -1
  11. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite +0 -0
  12. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-shm +0 -0
  13. package/src/cf-do/.wrangler/state/v3/cache/miniflare-CacheObject/metadata.sqlite-wal +0 -0
  14. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/0ffaabee41a60e04dd0eb7db3073f0a40139e6a97ccd26823967acb652b89a7b.sqlite +0 -0
  15. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite +0 -0
  16. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-shm +0 -0
  17. package/src/cf-do/.wrangler/state/v3/do/zero-do-ZeroDO/metadata.sqlite-wal +0 -0
  18. package/src/cf-do/.wrangler/tmp/bundle-0z4CpE/middleware-insertion-facade.js +0 -11
  19. package/src/cf-do/.wrangler/tmp/bundle-0z4CpE/middleware-loader.entry.ts +0 -134
  20. package/src/cf-do/.wrangler/tmp/bundle-vYmw0E/middleware-insertion-facade.js +0 -11
  21. package/src/cf-do/.wrangler/tmp/bundle-vYmw0E/middleware-loader.entry.ts +0 -134
  22. package/src/cf-do/.wrangler/tmp/dev-cbILNo/worker.js +0 -1059
  23. package/src/cf-do/.wrangler/tmp/dev-cbILNo/worker.js.map +0 -8
  24. package/src/cf-do/.wrangler/tmp/dev-qbho19/worker.js +0 -1059
  25. package/src/cf-do/.wrangler/tmp/dev-qbho19/worker.js.map +0 -8
  26. package/src/cf-do/ARCHITECTURE.md +0 -93
  27. package/src/cf-do/CHAT_E2E.md +0 -213
  28. package/src/cf-do/watermark.test.ts +0 -103
  29. package/src/cf-do/watermark.ts +0 -118
  30. package/src/cf-do/worker.ts +0 -1041
  31. package/src/cf-do/wrangler.toml +0 -11
  32. package/src/cf-pglite/README.md +0 -19
  33. package/src/change-tracking.ts +0 -25
  34. package/src/child-process.test.ts +0 -147
  35. package/src/child-process.ts +0 -90
  36. package/src/cli-entry.ts +0 -72
  37. package/src/cli.test.ts +0 -40
  38. package/src/cli.ts +0 -1214
  39. package/src/config.ts +0 -150
  40. package/src/do-sql-tracking.test.ts +0 -19
  41. package/src/do-sql-tracking.ts +0 -19
  42. package/src/index.ts +0 -1215
  43. package/src/integration/integration.test.ts +0 -517
  44. package/src/integration/native-binary.guard.test.ts +0 -13
  45. package/src/integration/native-startup.test.ts +0 -44
  46. package/src/integration/replication-latency.test.ts +0 -428
  47. package/src/integration/restore-live-stress.test.ts +0 -433
  48. package/src/integration/restore-reset.test.ts +0 -400
  49. package/src/integration/restore.test.ts +0 -274
  50. package/src/integration/test-permissions.ts +0 -147
  51. package/src/load-config.ts +0 -46
  52. package/src/log.ts +0 -96
  53. package/src/mutex.ts +0 -47
  54. package/src/pg-proxy-browser.singledb.test.ts +0 -233
  55. package/src/pg-proxy-browser.ts +0 -2022
  56. package/src/pg-proxy-do-backend.test.ts +0 -3890
  57. package/src/pg-proxy-do-backend.ts +0 -7191
  58. package/src/pg-proxy.ts +0 -1087
  59. package/src/pg-sqlite-compiler/README.md +0 -53
  60. package/src/pg-sqlite-compiler/catalog/seed.ts +0 -524
  61. package/src/pg-sqlite-compiler/fixtures/pgsqlite/arithmetic.json +0 -307
  62. package/src/pg-sqlite-compiler/fixtures/pgsqlite/array.json +0 -377
  63. package/src/pg-sqlite-compiler/fixtures/pgsqlite/cast.json +0 -12
  64. package/src/pg-sqlite-compiler/fixtures/pgsqlite/catalog.json +0 -447
  65. package/src/pg-sqlite-compiler/fixtures/pgsqlite/create-table.json +0 -32
  66. package/src/pg-sqlite-compiler/fixtures/pgsqlite/datetime.json +0 -397
  67. package/src/pg-sqlite-compiler/fixtures/pgsqlite/enum.json +0 -337
  68. package/src/pg-sqlite-compiler/fixtures/pgsqlite/insert.json +0 -337
  69. package/src/pg-sqlite-compiler/fixtures/pgsqlite/json.json +0 -537
  70. package/src/pg-sqlite-compiler/fixtures/pgsqlite/misc.json +0 -1837
  71. package/src/pg-sqlite-compiler/index.ts +0 -73
  72. package/src/pg-sqlite-compiler/integration.test.ts +0 -136
  73. package/src/pg-sqlite-compiler/passes/ast-utils.ts +0 -113
  74. package/src/pg-sqlite-compiler/passes/catalog.ts +0 -65
  75. package/src/pg-sqlite-compiler/passes/datetime.ts +0 -74
  76. package/src/pg-sqlite-compiler/passes/index.ts +0 -49
  77. package/src/pg-sqlite-compiler/passes/types.ts +0 -156
  78. package/src/pg-sqlite-compiler/smoke.test.ts +0 -69
  79. package/src/pg-sqlite-compiler/test/catalog.test.ts +0 -171
  80. package/src/pg-sqlite-compiler/test/corpus.test.ts +0 -161
  81. package/src/pg-sqlite-compiler/test/datetime.oracle.test.ts +0 -102
  82. package/src/pg-sqlite-compiler/test/oracle.ts +0 -237
  83. package/src/pg-sqlite-compiler/test/types.test.ts +0 -109
  84. package/src/pg-sqlite-compiler/types.ts +0 -63
  85. package/src/pglite-ipc.test.ts +0 -116
  86. package/src/pglite-ipc.ts +0 -266
  87. package/src/pglite-manager.ts +0 -557
  88. package/src/pglite-web-proxy.test.ts +0 -57
  89. package/src/pglite-web-proxy.ts +0 -221
  90. package/src/pglite-web-worker.ts +0 -152
  91. package/src/pglite-worker-thread.ts +0 -253
  92. package/src/port.ts +0 -25
  93. package/src/process-title.ts +0 -9
  94. package/src/recovery.ts +0 -155
  95. package/src/replication/change-tracker.test.ts +0 -357
  96. package/src/replication/change-tracker.ts +0 -279
  97. package/src/replication/handler.test.ts +0 -511
  98. package/src/replication/handler.ts +0 -1190
  99. package/src/replication/pgoutput-encoder.test.ts +0 -697
  100. package/src/replication/pgoutput-encoder.ts +0 -373
  101. package/src/replication/tcp-replication.test.ts +0 -876
  102. package/src/replication/zero-compat.test.ts +0 -1150
  103. package/src/restore-stress.test.ts +0 -188
  104. package/src/s3-local.ts +0 -203
  105. package/src/shim/hooks.mjs +0 -120
  106. package/src/shim/register.mjs +0 -4
  107. package/src/sqlite-mode/apply-mode.ts +0 -224
  108. package/src/sqlite-mode/index.ts +0 -15
  109. package/src/sqlite-mode/native-binary.ts +0 -89
  110. package/src/sqlite-mode/package-resolve.ts +0 -17
  111. package/src/sqlite-mode/resolve-mode.ts +0 -80
  112. package/src/sqlite-mode/shim-template.ts +0 -159
  113. package/src/sqlite-mode/sqlite-mode.test.ts +0 -427
  114. package/src/sqlite-mode/types.ts +0 -30
  115. package/src/vite-plugin.ts +0 -67
  116. package/src/wasm-sqlite.test.ts +0 -537
  117. package/src/worker/browser-admin.ts +0 -52
  118. package/src/worker/browser-build-config.test.ts +0 -71
  119. package/src/worker/browser-build-config.ts +0 -109
  120. package/src/worker/browser-embed-admin.test.ts +0 -75
  121. package/src/worker/browser-embed.ts +0 -345
  122. package/src/worker/cf-patches.ts +0 -384
  123. package/src/worker/embed-integration.test.ts +0 -321
  124. package/src/worker/index.ts +0 -138
  125. package/src/worker/shims/fastify.test.ts +0 -255
  126. package/src/worker/shims/fastify.ts +0 -306
  127. package/src/worker/shims/http-service.test.ts +0 -355
  128. package/src/worker/shims/http-service.ts +0 -293
  129. package/src/worker/shims/node-stub.ts +0 -290
  130. package/src/worker/shims/oxfmt.ts +0 -3
  131. package/src/worker/shims/postgres-browser.ts +0 -59
  132. package/src/worker/shims/postgres-socket.test.ts +0 -576
  133. package/src/worker/shims/postgres-socket.ts +0 -310
  134. package/src/worker/shims/postgres.test.ts +0 -364
  135. package/src/worker/shims/postgres.ts +0 -1454
  136. package/src/worker/shims/sqlite-browser.test.ts +0 -233
  137. package/src/worker/shims/sqlite-browser.ts +0 -175
  138. package/src/worker/shims/sqlite.test.ts +0 -786
  139. package/src/worker/shims/sqlite.ts +0 -978
  140. package/src/worker/shims/stream-browser.ts +0 -15
  141. package/src/worker/shims/ws-browser.test.ts +0 -205
  142. package/src/worker/shims/ws-browser.ts +0 -248
  143. package/src/worker/shims/ws.test.ts +0 -288
  144. package/src/worker/shims/ws.ts +0 -467
  145. package/src/worker/shims/zero-process-env.ts +0 -11
  146. package/src/worker/types.ts +0 -75
  147. package/src/worker/worker-integration.test.ts +0 -223
  148. package/src/worker/worker.test.ts +0 -136
  149. package/src/worker/zero-cache-embed-cf.ts +0 -463
  150. 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
- })