db-mcp 1.0.2 → 1.1.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/.gitattributes +2 -0
- package/LICENSE +1 -1
- package/README.md +244 -518
- package/dist/chunk-4IA3DB5C.js +135 -0
- package/dist/chunk-AOUL5SHS.js +930 -0
- package/dist/chunk-DWJXQEFA.js +13759 -0
- package/dist/chunk-DZQLDEQS.js +879 -0
- package/dist/chunk-S5IDDSSB.js +74 -0
- package/dist/chunk-Z2GFQU3G.js +363 -0
- package/dist/cli.d.ts +0 -7
- package/dist/cli.js +227 -183
- package/dist/http-VSB7DBJR.js +1541 -0
- package/dist/index.d.ts +842 -10
- package/dist/index.js +5 -17
- package/dist/sqlite-VHBA4ABV.js +600 -0
- package/dist/sqlite-native-D2LH5ZT7.js +2498 -0
- package/dist/worker-script.d.ts +2 -0
- package/dist/worker-script.js +126 -0
- package/package.json +26 -16
- package/playwright.config.ts +101 -0
- package/scripts/generate-server-instructions.ts +111 -0
- package/server.json +5 -6
- package/test-server/README.md +118 -0
- package/test-server/code-map.md +409 -0
- package/test-server/fixtures/sample.csv +6 -0
- package/test-server/reset-database.ps1 +373 -0
- package/test-server/sample.csv +11 -0
- package/test-server/test-agent-experience.md +243 -0
- package/test-server/test-database.sql +388 -0
- package/test-server/test-group-tools.md +861 -0
- package/test-server/test-help-resources.mjs +238 -0
- package/test-server/test-preflight.md +53 -0
- package/test-server/test-prompts.md +354 -0
- package/test-server/test-resources.md +245 -0
- package/test-server/test-tool-annotations.mjs +157 -0
- package/test-server/test-tools-advanced-1.md +517 -0
- package/test-server/test-tools-advanced-2.md +487 -0
- package/test-server/test-tools-codemode.md +629 -0
- package/test-server/test-tools.md +176 -0
- package/test-server/tool-reference.md +236 -0
- package/tsconfig.test.json +9 -0
- package/dist/adapters/DatabaseAdapter.d.ts +0 -141
- package/dist/adapters/DatabaseAdapter.d.ts.map +0 -1
- package/dist/adapters/DatabaseAdapter.js +0 -131
- package/dist/adapters/DatabaseAdapter.js.map +0 -1
- package/dist/adapters/sqlite/SchemaManager.d.ts +0 -58
- package/dist/adapters/sqlite/SchemaManager.d.ts.map +0 -1
- package/dist/adapters/sqlite/SchemaManager.js +0 -187
- package/dist/adapters/sqlite/SchemaManager.js.map +0 -1
- package/dist/adapters/sqlite/SqliteAdapter.d.ts +0 -161
- package/dist/adapters/sqlite/SqliteAdapter.d.ts.map +0 -1
- package/dist/adapters/sqlite/SqliteAdapter.js +0 -741
- package/dist/adapters/sqlite/SqliteAdapter.js.map +0 -1
- package/dist/adapters/sqlite/index.d.ts +0 -9
- package/dist/adapters/sqlite/index.d.ts.map +0 -1
- package/dist/adapters/sqlite/index.js +0 -8
- package/dist/adapters/sqlite/index.js.map +0 -1
- package/dist/adapters/sqlite/json-utils.d.ts +0 -100
- package/dist/adapters/sqlite/json-utils.d.ts.map +0 -1
- package/dist/adapters/sqlite/json-utils.js +0 -274
- package/dist/adapters/sqlite/json-utils.js.map +0 -1
- package/dist/adapters/sqlite/output-schemas.d.ts +0 -1187
- package/dist/adapters/sqlite/output-schemas.d.ts.map +0 -1
- package/dist/adapters/sqlite/output-schemas.js +0 -1337
- package/dist/adapters/sqlite/output-schemas.js.map +0 -1
- package/dist/adapters/sqlite/prompts.d.ts +0 -13
- package/dist/adapters/sqlite/prompts.d.ts.map +0 -1
- package/dist/adapters/sqlite/prompts.js +0 -605
- package/dist/adapters/sqlite/prompts.js.map +0 -1
- package/dist/adapters/sqlite/resources.d.ts +0 -13
- package/dist/adapters/sqlite/resources.d.ts.map +0 -1
- package/dist/adapters/sqlite/resources.js +0 -251
- package/dist/adapters/sqlite/resources.js.map +0 -1
- package/dist/adapters/sqlite/tools/admin.d.ts +0 -14
- package/dist/adapters/sqlite/tools/admin.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/admin.js +0 -788
- package/dist/adapters/sqlite/tools/admin.js.map +0 -1
- package/dist/adapters/sqlite/tools/core.d.ts +0 -25
- package/dist/adapters/sqlite/tools/core.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/core.js +0 -359
- package/dist/adapters/sqlite/tools/core.js.map +0 -1
- package/dist/adapters/sqlite/tools/fts.d.ts +0 -13
- package/dist/adapters/sqlite/tools/fts.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/fts.js +0 -347
- package/dist/adapters/sqlite/tools/fts.js.map +0 -1
- package/dist/adapters/sqlite/tools/geo.d.ts +0 -14
- package/dist/adapters/sqlite/tools/geo.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/geo.js +0 -252
- package/dist/adapters/sqlite/tools/geo.js.map +0 -1
- package/dist/adapters/sqlite/tools/index.d.ts +0 -30
- package/dist/adapters/sqlite/tools/index.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/index.js +0 -61
- package/dist/adapters/sqlite/tools/index.js.map +0 -1
- package/dist/adapters/sqlite/tools/json-helpers.d.ts +0 -14
- package/dist/adapters/sqlite/tools/json-helpers.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/json-helpers.js +0 -477
- package/dist/adapters/sqlite/tools/json-helpers.js.map +0 -1
- package/dist/adapters/sqlite/tools/json-operations.d.ts +0 -14
- package/dist/adapters/sqlite/tools/json-operations.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/json-operations.js +0 -839
- package/dist/adapters/sqlite/tools/json-operations.js.map +0 -1
- package/dist/adapters/sqlite/tools/stats.d.ts +0 -15
- package/dist/adapters/sqlite/tools/stats.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/stats.js +0 -1219
- package/dist/adapters/sqlite/tools/stats.js.map +0 -1
- package/dist/adapters/sqlite/tools/text.d.ts +0 -14
- package/dist/adapters/sqlite/tools/text.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/text.js +0 -1141
- package/dist/adapters/sqlite/tools/text.js.map +0 -1
- package/dist/adapters/sqlite/tools/vector.d.ts +0 -14
- package/dist/adapters/sqlite/tools/vector.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/vector.js +0 -613
- package/dist/adapters/sqlite/tools/vector.js.map +0 -1
- package/dist/adapters/sqlite/tools/virtual.d.ts +0 -13
- package/dist/adapters/sqlite/tools/virtual.d.ts.map +0 -1
- package/dist/adapters/sqlite/tools/virtual.js +0 -930
- package/dist/adapters/sqlite/tools/virtual.js.map +0 -1
- package/dist/adapters/sqlite/types.d.ts +0 -207
- package/dist/adapters/sqlite/types.d.ts.map +0 -1
- package/dist/adapters/sqlite/types.js +0 -186
- package/dist/adapters/sqlite/types.js.map +0 -1
- package/dist/adapters/sqlite-native/NativeSqliteAdapter.d.ts +0 -163
- package/dist/adapters/sqlite-native/NativeSqliteAdapter.d.ts.map +0 -1
- package/dist/adapters/sqlite-native/NativeSqliteAdapter.js +0 -748
- package/dist/adapters/sqlite-native/NativeSqliteAdapter.js.map +0 -1
- package/dist/adapters/sqlite-native/index.d.ts +0 -11
- package/dist/adapters/sqlite-native/index.d.ts.map +0 -1
- package/dist/adapters/sqlite-native/index.js +0 -11
- package/dist/adapters/sqlite-native/index.js.map +0 -1
- package/dist/adapters/sqlite-native/tools/spatialite.d.ts +0 -19
- package/dist/adapters/sqlite-native/tools/spatialite.d.ts.map +0 -1
- package/dist/adapters/sqlite-native/tools/spatialite.js +0 -628
- package/dist/adapters/sqlite-native/tools/spatialite.js.map +0 -1
- package/dist/adapters/sqlite-native/tools/transactions.d.ts +0 -12
- package/dist/adapters/sqlite-native/tools/transactions.d.ts.map +0 -1
- package/dist/adapters/sqlite-native/tools/transactions.js +0 -255
- package/dist/adapters/sqlite-native/tools/transactions.js.map +0 -1
- package/dist/adapters/sqlite-native/tools/window.d.ts +0 -12
- package/dist/adapters/sqlite-native/tools/window.d.ts.map +0 -1
- package/dist/adapters/sqlite-native/tools/window.js +0 -370
- package/dist/adapters/sqlite-native/tools/window.js.map +0 -1
- package/dist/auth/AuthorizationServerDiscovery.d.ts +0 -90
- package/dist/auth/AuthorizationServerDiscovery.d.ts.map +0 -1
- package/dist/auth/AuthorizationServerDiscovery.js +0 -204
- package/dist/auth/AuthorizationServerDiscovery.js.map +0 -1
- package/dist/auth/OAuthResourceServer.d.ts +0 -65
- package/dist/auth/OAuthResourceServer.d.ts.map +0 -1
- package/dist/auth/OAuthResourceServer.js +0 -121
- package/dist/auth/OAuthResourceServer.js.map +0 -1
- package/dist/auth/TokenValidator.d.ts +0 -60
- package/dist/auth/TokenValidator.d.ts.map +0 -1
- package/dist/auth/TokenValidator.js +0 -235
- package/dist/auth/TokenValidator.js.map +0 -1
- package/dist/auth/errors.d.ts +0 -74
- package/dist/auth/errors.d.ts.map +0 -1
- package/dist/auth/errors.js +0 -133
- package/dist/auth/errors.js.map +0 -1
- package/dist/auth/index.d.ts +0 -13
- package/dist/auth/index.d.ts.map +0 -1
- package/dist/auth/index.js +0 -15
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/middleware.d.ts +0 -81
- package/dist/auth/middleware.d.ts.map +0 -1
- package/dist/auth/middleware.js +0 -291
- package/dist/auth/middleware.js.map +0 -1
- package/dist/auth/scopes.d.ts +0 -136
- package/dist/auth/scopes.d.ts.map +0 -1
- package/dist/auth/scopes.js +0 -349
- package/dist/auth/scopes.js.map +0 -1
- package/dist/auth/types.d.ts +0 -257
- package/dist/auth/types.d.ts.map +0 -1
- package/dist/auth/types.js +0 -8
- package/dist/auth/types.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/constants/ServerInstructions.d.ts +0 -45
- package/dist/constants/ServerInstructions.d.ts.map +0 -1
- package/dist/constants/ServerInstructions.js +0 -356
- package/dist/constants/ServerInstructions.js.map +0 -1
- package/dist/filtering/ToolConstants.d.ts +0 -34
- package/dist/filtering/ToolConstants.d.ts.map +0 -1
- package/dist/filtering/ToolConstants.js +0 -174
- package/dist/filtering/ToolConstants.js.map +0 -1
- package/dist/filtering/ToolFilter.d.ts +0 -82
- package/dist/filtering/ToolFilter.d.ts.map +0 -1
- package/dist/filtering/ToolFilter.js +0 -296
- package/dist/filtering/ToolFilter.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/server/McpServer.d.ts +0 -61
- package/dist/server/McpServer.d.ts.map +0 -1
- package/dist/server/McpServer.js +0 -270
- package/dist/server/McpServer.js.map +0 -1
- package/dist/transports/http.d.ts +0 -134
- package/dist/transports/http.d.ts.map +0 -1
- package/dist/transports/http.js +0 -516
- package/dist/transports/http.js.map +0 -1
- package/dist/transports/index.d.ts +0 -5
- package/dist/transports/index.d.ts.map +0 -1
- package/dist/transports/index.js +0 -5
- package/dist/transports/index.js.map +0 -1
- package/dist/types/index.d.ts +0 -380
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -68
- package/dist/types/index.js.map +0 -1
- package/dist/utils/annotations.d.ts +0 -44
- package/dist/utils/annotations.d.ts.map +0 -1
- package/dist/utils/annotations.js +0 -77
- package/dist/utils/annotations.js.map +0 -1
- package/dist/utils/errors.d.ts +0 -155
- package/dist/utils/errors.d.ts.map +0 -1
- package/dist/utils/errors.js +0 -329
- package/dist/utils/errors.js.map +0 -1
- package/dist/utils/identifiers.d.ts +0 -121
- package/dist/utils/identifiers.d.ts.map +0 -1
- package/dist/utils/identifiers.js +0 -319
- package/dist/utils/identifiers.js.map +0 -1
- package/dist/utils/index.d.ts +0 -7
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -7
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/insightsManager.d.ts +0 -39
- package/dist/utils/insightsManager.d.ts.map +0 -1
- package/dist/utils/insightsManager.js +0 -63
- package/dist/utils/insightsManager.js.map +0 -1
- package/dist/utils/logger.d.ts +0 -189
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js +0 -394
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/progress-utils.d.ts +0 -54
- package/dist/utils/progress-utils.d.ts.map +0 -1
- package/dist/utils/progress-utils.js +0 -74
- package/dist/utils/progress-utils.js.map +0 -1
- package/dist/utils/resourceAnnotations.d.ts +0 -36
- package/dist/utils/resourceAnnotations.d.ts.map +0 -1
- package/dist/utils/resourceAnnotations.js +0 -57
- package/dist/utils/resourceAnnotations.js.map +0 -1
- package/dist/utils/where-clause.d.ts +0 -41
- package/dist/utils/where-clause.d.ts.map +0 -1
- package/dist/utils/where-clause.js +0 -116
- package/dist/utils/where-clause.js.map +0 -1
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
# Advanced Stress Test — db-mcp (SQLite)
|
|
2
|
+
|
|
3
|
+
**Test WASM Mode Only. Ignore Native content**
|
|
4
|
+
|
|
5
|
+
**Step 1:** Read `server-instructions.ts` and `src/constants/server-instructions/gotchas.md` using `view_file` (not grep or search) to understand documented behaviors, edge cases, and response structures.
|
|
6
|
+
|
|
7
|
+
**Step 2:** Execute each numbered stress test below using `sqlite_execute_code` (code mode), not scripts/terminal.
|
|
8
|
+
|
|
9
|
+
**Note**: If your attempt to cleanup after testing fails, it's because the database is locked. Move on. I will drop them.
|
|
10
|
+
|
|
11
|
+
## Code Mode Execution
|
|
12
|
+
|
|
13
|
+
All tests should be executed via `sqlite_execute_code` code mode. Tests are written in direct tool call syntax for readability — translate to code mode:
|
|
14
|
+
|
|
15
|
+
| Direct Tool Call | Code Mode Equivalent |
|
|
16
|
+
| --------------------------------------------------------- | ------------------------------------------------------------- |
|
|
17
|
+
| `sqlite_read_query({query: "..."})` | `sqlite.core.readQuery({query: "..."})` |
|
|
18
|
+
| `sqlite_write_query({query: "..."})` | `sqlite.core.writeQuery({query: "..."})` |
|
|
19
|
+
| `sqlite_create_table({tableName: "...", columns: [...]})` | `sqlite.core.createTable({tableName: "...", columns: [...]})` |
|
|
20
|
+
| `sqlite_describe_table({tableName: "..."})` | `sqlite.core.describeTable({tableName: "..."})` |
|
|
21
|
+
| `sqlite_drop_table({tableName: "..."})` | `sqlite.core.dropTable({tableName: "..."})` |
|
|
22
|
+
| `sqlite_create_index({...})` | `sqlite.core.createIndex({...})` |
|
|
23
|
+
| `sqlite_get_indexes({tableName: "..."})` | `sqlite.core.getIndexes({tableName: "..."})` |
|
|
24
|
+
| `sqlite_json_*({...})` | `sqlite.json.*({...})` |
|
|
25
|
+
| `sqlite_text_*` / `sqlite_regex_*` / etc. | `sqlite.text.*` |
|
|
26
|
+
| `sqlite_stats_*` / `sqlite_window_*` | `sqlite.stats.*` |
|
|
27
|
+
| `sqlite_vector_*` | `sqlite.vector.*` |
|
|
28
|
+
| `sqlite_fts_*` | `sqlite.text.*` (FTS tools are in the text group) |
|
|
29
|
+
|
|
30
|
+
**Key rules:**
|
|
31
|
+
|
|
32
|
+
- Use `sqlite.<group>.help()` to discover method names and parameters for each group
|
|
33
|
+
- State **persists** across `sqlite_execute_code` calls — create a table in one call, query it in the next
|
|
34
|
+
- Do **NOT** pass `readonly: true` when tests need to create/write/drop objects
|
|
35
|
+
- Group multiple related tests into a single code mode call when practical
|
|
36
|
+
|
|
37
|
+
## Test Database Schema
|
|
38
|
+
|
|
39
|
+
Same as `test-tools.md` — refer to that file for the full schema reference. Key tables: `test_products` (16 rows), `test_orders` (20), `test_jsonb_docs` (6), `test_articles` (8), `test_users` (9), `test_measurements` (200), `test_embeddings` (20), `test_locations` (15), `test_categories` (17), `test_events` (100).
|
|
40
|
+
|
|
41
|
+
## Naming & Cleanup
|
|
42
|
+
|
|
43
|
+
- **Temporary tables**: Prefix with `stress_` (e.g., `stress_empty_table`)
|
|
44
|
+
- **Temporary indexes**: Prefix with `stress_idx_`
|
|
45
|
+
- **Temporary views**: Prefix with `stress_view_`
|
|
46
|
+
- **Cleanup**: Attempt to remove all `temp_*` tables. If DROP fails due to a database lock, note the leftover tables and move on — they are inert and will be cleaned up on next database regeneration
|
|
47
|
+
|
|
48
|
+
## Reporting Format
|
|
49
|
+
|
|
50
|
+
- ❌ Fail: Tool errors or produces incorrect results (include error message)
|
|
51
|
+
- ⚠️ Issue: Unexpected behavior or improvement opportunity
|
|
52
|
+
- 📦 Payload: Unnecessarily large response that should be optimized — **blocking, equally important as ❌ bugs**. Oversized payloads waste LLM context window tokens and degrade downstream tool-calling quality. Report the response size in KB and suggest a concrete optimization (e.g., filter system tables, add `compact` option, omit empty arrays).
|
|
53
|
+
- ✅ Confirmed: Edge case handled correctly (use only inline during testing; omit from Final Summary)
|
|
54
|
+
|
|
55
|
+
### Error Code Consistency
|
|
56
|
+
|
|
57
|
+
When rating errors, flag any generic code (`RESOURCE_ERROR`, `UNKNOWN_ERROR`) that should be a specific code (e.g., `TABLE_NOT_FOUND`, `COLUMN_NOT_FOUND`, `VALIDATION_ERROR`). These are fixable in `src/utils/errors/` (see `suggestions.ts` and `classes.ts`) by adding a `code` override to the matching error class. Treat as ⚠️ Issue and include in fix plan.
|
|
58
|
+
|
|
59
|
+
## Post-Test Procedures
|
|
60
|
+
|
|
61
|
+
At the end, confirm cleanup of all `stress_*` objects, then **fix every finding** — not just ❌ Fails, but also ⚠️ Issues (behavioral improvements, missing warnings, error code consistency) and 📦 Payload problems (responses that should be truncated or offer a `limit` param). Create a plan covering all finding architecturally consistent with other tools/tool groups. If the plan does not require important decision choices, proceed with implementation. When complete, update the changelog (being careful not to create duplicate headers), and commit without pushing. Then re-test your fixes with direct MCP calls.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## core Group Advanced Tests
|
|
66
|
+
|
|
67
|
+
### Built-in Tools (3)
|
|
68
|
+
|
|
69
|
+
1. server_info
|
|
70
|
+
2. server_health
|
|
71
|
+
3. list_adapters
|
|
72
|
+
|
|
73
|
+
### core Group Tools (9)
|
|
74
|
+
|
|
75
|
+
4. sqlite_read_query
|
|
76
|
+
5. sqlite_write_query
|
|
77
|
+
6. sqlite_create_table
|
|
78
|
+
7. sqlite_list_tables
|
|
79
|
+
8. sqlite_describe_table
|
|
80
|
+
9. sqlite_drop_table
|
|
81
|
+
10. sqlite_get_indexes
|
|
82
|
+
11. sqlite_create_index
|
|
83
|
+
12. sqlite_drop_index
|
|
84
|
+
|
|
85
|
+
### Category 1: Boundary Values & Empty States
|
|
86
|
+
|
|
87
|
+
**1.1 Empty Table Operations**
|
|
88
|
+
|
|
89
|
+
Create `stress_empty_table (id INTEGER PRIMARY KEY, name TEXT, value REAL)`, then test:
|
|
90
|
+
|
|
91
|
+
1. `sqlite_read_query({query: "SELECT COUNT(*) AS n FROM stress_empty_table"})` → `{rows: [{n: 0}]}`
|
|
92
|
+
2. `sqlite_describe_table({tableName: "stress_empty_table"})` → valid schema with 3 columns
|
|
93
|
+
3. `sqlite_get_indexes({tableName: "stress_empty_table"})` → empty or primary key only
|
|
94
|
+
|
|
95
|
+
**1.2 Single-Row Table**
|
|
96
|
+
|
|
97
|
+
Insert one row into `stress_empty_table`: `(1, 'solo', 42.0)`, then test:
|
|
98
|
+
|
|
99
|
+
4. `sqlite_read_query({query: "SELECT * FROM stress_empty_table"})` → exactly 1 row
|
|
100
|
+
|
|
101
|
+
**1.3 NULL-Heavy Data**
|
|
102
|
+
|
|
103
|
+
Insert 4 more rows: 3 with `name IS NULL AND value IS NULL`, 1 with actual values:
|
|
104
|
+
|
|
105
|
+
5. `sqlite_read_query({query: "SELECT COUNT(*) AS n FROM stress_empty_table WHERE value IS NULL"})` → `{rows: [{n: 3}]}`
|
|
106
|
+
6. `sqlite_read_query({query: "SELECT COUNT(value) AS n FROM stress_empty_table"})` → `{rows: [{n: 2}]}` (COUNT of non-null values)
|
|
107
|
+
|
|
108
|
+
### Category 2: State Pollution & Idempotency
|
|
109
|
+
|
|
110
|
+
**2.1 Create-Drop-Recreate Cycles**
|
|
111
|
+
|
|
112
|
+
7. `sqlite_create_table` → create `stress_cycle_table (id INTEGER PRIMARY KEY, data TEXT)`
|
|
113
|
+
8. `sqlite_create_index` → create `stress_idx_cycle` on `stress_cycle_table(data)`
|
|
114
|
+
9. `sqlite_drop_table({tableName: "stress_cycle_table"})` → success
|
|
115
|
+
10. `sqlite_drop_table({tableName: "stress_cycle_table"})` → expect structured error or `{existed: false}` (not a raw crash)
|
|
116
|
+
11. `sqlite_create_table` → recreate `stress_cycle_table` → success (no orphaned metadata)
|
|
117
|
+
12. Cleanup: drop `stress_cycle_table`
|
|
118
|
+
|
|
119
|
+
**2.2 Duplicate Object Detection**
|
|
120
|
+
|
|
121
|
+
13. `sqlite_create_table` with the table name `test_products` → expect error or "already exists" indication (not silent overwrite)
|
|
122
|
+
14. `sqlite_create_index` on `idx_orders_status` (already exists on `test_orders`) → expect error or "already exists" indication
|
|
123
|
+
|
|
124
|
+
### Category 3: Error Message Quality
|
|
125
|
+
|
|
126
|
+
For each test, verify the error returns a **structured response** (`{success: false, error: "..."}`) — NOT a raw MCP exception. Rate each error message: does it include enough context to diagnose the problem?
|
|
127
|
+
|
|
128
|
+
**3.1 Nonexistent Objects**
|
|
129
|
+
|
|
130
|
+
15. `sqlite_describe_table({tableName: "nonexistent_table_xyz"})` → error should mention table name
|
|
131
|
+
16. `sqlite_read_query({query: "SELECT * FROM nonexistent_table_xyz"})` → error should mention table name
|
|
132
|
+
17. `sqlite_get_indexes({tableName: "nonexistent_table_xyz"})` → report behavior
|
|
133
|
+
18. `sqlite_write_query({query: "INSERT INTO nonexistent_table_xyz VALUES (1)"})` → structured error
|
|
134
|
+
|
|
135
|
+
**3.2 Invalid SQL**
|
|
136
|
+
|
|
137
|
+
19. `sqlite_read_query({query: "SELEKT * FROM test_products"})` → structured error with SQL syntax context
|
|
138
|
+
20. `sqlite_write_query({query: "INSERT INTO test_products (nonexistent_col) VALUES (1)"})` → structured error mentioning column
|
|
139
|
+
|
|
140
|
+
**3.3 Type/Constraint Violations**
|
|
141
|
+
|
|
142
|
+
21. `sqlite_write_query({query: "INSERT INTO test_products (id) VALUES (1)"})` → duplicate primary key error (id=1 exists)
|
|
143
|
+
|
|
144
|
+
### Category 4: Large Payload & Truncation Verification
|
|
145
|
+
|
|
146
|
+
22. `sqlite_read_query({query: "SELECT * FROM test_measurements"})` → 200 rows — verify response size, check if truncation/limit is applied
|
|
147
|
+
23. `sqlite_read_query({query: "SELECT * FROM test_measurements LIMIT 5"})` → exactly 5 rows
|
|
148
|
+
24. `sqlite_read_query({query: "SELECT * FROM test_events"})` → 100 rows — check payload size
|
|
149
|
+
|
|
150
|
+
### Final Cleanup
|
|
151
|
+
|
|
152
|
+
Drop all `stress_*` tables created during testing and confirm `test_products` row count is still 16 (no pollution).
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## json Group Advanced Tests
|
|
157
|
+
|
|
158
|
+
### Built-in Tools (3)
|
|
159
|
+
|
|
160
|
+
1. server_info
|
|
161
|
+
2. server_health
|
|
162
|
+
3. list_adapters
|
|
163
|
+
|
|
164
|
+
### json Group Tools (23)
|
|
165
|
+
|
|
166
|
+
4. sqlite_json_valid
|
|
167
|
+
5. sqlite_json_extract
|
|
168
|
+
6. sqlite_json_set
|
|
169
|
+
7. sqlite_json_remove
|
|
170
|
+
8. sqlite_json_type
|
|
171
|
+
9. sqlite_json_array_length
|
|
172
|
+
10. sqlite_json_array_append
|
|
173
|
+
11. sqlite_json_keys
|
|
174
|
+
12. sqlite_json_each
|
|
175
|
+
13. sqlite_json_group_array
|
|
176
|
+
14. sqlite_json_group_object
|
|
177
|
+
15. sqlite_json_pretty
|
|
178
|
+
16. sqlite_jsonb_convert
|
|
179
|
+
17. sqlite_json_storage_info
|
|
180
|
+
18. sqlite_json_normalize_column
|
|
181
|
+
19. sqlite_json_insert
|
|
182
|
+
20. sqlite_json_update
|
|
183
|
+
21. sqlite_json_select
|
|
184
|
+
22. sqlite_json_query
|
|
185
|
+
23. sqlite_json_validate_path
|
|
186
|
+
24. sqlite_json_merge
|
|
187
|
+
25. sqlite_json_analyze_schema
|
|
188
|
+
26. sqlite_create_json_collection
|
|
189
|
+
|
|
190
|
+
### Category 1: Deep JSON Operations
|
|
191
|
+
|
|
192
|
+
**1.1 Deeply Nested Access**
|
|
193
|
+
|
|
194
|
+
1. `sqlite_json_extract({table: "test_jsonb_docs", column: "doc", path: "$.nested.level1.level2", whereClause: "id = 4"})` → `"deep value"`
|
|
195
|
+
2. `sqlite_json_extract({table: "test_jsonb_docs", column: "doc", path: "$.nested.level1.nonexistent", whereClause: "id = 4"})` → null or empty (not error)
|
|
196
|
+
3. `sqlite_json_extract({table: "test_jsonb_docs", column: "doc", path: "$.nonexistent_key", whereClause: "id = 1"})` → null or empty
|
|
197
|
+
|
|
198
|
+
**1.2 Array Manipulation Edge Cases**
|
|
199
|
+
|
|
200
|
+
4. `sqlite_json_array_length({table: "test_jsonb_docs", column: "tags", whereClause: "id = 3"})` → 3 (["mcp","protocol","ai"])
|
|
201
|
+
5. Create `stress_json_test` with a row containing `tags = '[]'` (empty array) → `sqlite_json_array_length` → 0
|
|
202
|
+
6. `sqlite_json_each` on an empty array → 0 expanded rows (not error)
|
|
203
|
+
|
|
204
|
+
**1.3 Merge Conflict Behavior**
|
|
205
|
+
|
|
206
|
+
> **Note:** `sqlite_json_merge` is table-bound (requires `table`, `column`, `mergeData`, `whereClause`) — it uses `json_patch()` which follows RFC 7396 merge-patch semantics.
|
|
207
|
+
|
|
208
|
+
Insert test rows into `stress_json_test`: row 2 = `{"a": 1, "b": {"c": 2}}`, row 3 = `{"a": [1, 2]}`:
|
|
209
|
+
|
|
210
|
+
7. `sqlite_json_merge({table: "stress_json_test", column: "tags", mergeData: {"b": {"d": 3}}, whereClause: "id = 2"})` → verify deep merge: `b.c` should survive (`json_patch` recursively merges objects, so `b.c` is preserved alongside new `b.d`)
|
|
211
|
+
8. `sqlite_json_merge({table: "stress_json_test", column: "tags", mergeData: {"a": [3, 4]}, whereClause: "id = 3"})` → arrays are replaced (not concatenated) per RFC 7396
|
|
212
|
+
|
|
213
|
+
**1.4 Type Coercion Edge Cases**
|
|
214
|
+
|
|
215
|
+
9. `sqlite_json_type({table: "test_jsonb_docs", column: "doc", path: "$.views", whereClause: "id = 1"})` → `"integer"` (views=1250)
|
|
216
|
+
10. `sqlite_json_type({table: "test_jsonb_docs", column: "doc", path: "$.rating", whereClause: "id = 1"})` → `"real"` (rating=4.5)
|
|
217
|
+
11. `sqlite_json_type({table: "test_jsonb_docs", column: "doc", path: "$.nested", whereClause: "id = 4"})` → `"object"`
|
|
218
|
+
|
|
219
|
+
### Category 2: JSON Query & Filter Stress
|
|
220
|
+
|
|
221
|
+
> **Note:** `sqlite_json_query` uses `filterPaths` (equality-only, `Record<path, value>`) and `selectPaths` — not `conditions` with operators.
|
|
222
|
+
|
|
223
|
+
12. `sqlite_json_query({table: "test_jsonb_docs", column: "doc", filterPaths: {"$.type": "article"}})` → 4 rows (all articles)
|
|
224
|
+
13. `sqlite_json_query({table: "test_jsonb_docs", column: "doc", filterPaths: {"$.type": "article", "$.author": "Alice"}, selectPaths: ["$.title", "$.views"]})` → 1 row (Alice's article)
|
|
225
|
+
14. `sqlite_json_query({table: "test_events", column: "payload", filterPaths: {"$.page": "home"}})` → 25 rows (every 4th event)
|
|
226
|
+
|
|
227
|
+
### Category 3: Error Message Quality
|
|
228
|
+
|
|
229
|
+
15. `sqlite_json_extract({table: "nonexistent_table_xyz", column: "doc", path: "$.x"})` → structured error mentioning table name
|
|
230
|
+
16. `sqlite_json_extract({table: "test_jsonb_docs", column: "nonexistent_col", path: "$.x"})` → structured error mentioning column name
|
|
231
|
+
17. `sqlite_json_set({table: "test_jsonb_docs", column: "doc", path: "$.author", value: "\"Modified\"", whereClause: "id = 99999"})` → report behavior for nonexistent row
|
|
232
|
+
18. `sqlite_json_validate_path({path: ""})` → report behavior for empty path
|
|
233
|
+
|
|
234
|
+
### Category 4: Write Operation Safety
|
|
235
|
+
|
|
236
|
+
19. Create `stress_json_write` table → insert 3 JSON documents → perform `sqlite_json_set`, `sqlite_json_remove`, `sqlite_json_insert` → verify mutations → cleanup
|
|
237
|
+
> **Note:** `sqlite_json_insert` is a **row-level INSERT** (creates a new row with JSON data), not a path-level JSON insert like SQLite's `json_insert()` function.
|
|
238
|
+
20. `sqlite_json_normalize_column` on `stress_json_write` → verify keys are sorted/compacted without data loss
|
|
239
|
+
|
|
240
|
+
### Final Cleanup
|
|
241
|
+
|
|
242
|
+
Drop all `stress_*` tables. Confirm `test_jsonb_docs` row count is still 6 and contents are unchanged.
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## text Group Advanced Tests
|
|
247
|
+
|
|
248
|
+
### Built-in Tools (3)
|
|
249
|
+
|
|
250
|
+
1. server_info
|
|
251
|
+
2. server_health
|
|
252
|
+
3. list_adapters
|
|
253
|
+
|
|
254
|
+
### text Group Tools — Native (17)
|
|
255
|
+
|
|
256
|
+
4. sqlite_regex_extract
|
|
257
|
+
5. sqlite_regex_match
|
|
258
|
+
6. sqlite_text_split
|
|
259
|
+
7. sqlite_text_concat
|
|
260
|
+
8. sqlite_text_replace
|
|
261
|
+
9. sqlite_text_trim
|
|
262
|
+
10. sqlite_text_case
|
|
263
|
+
11. sqlite_text_substring
|
|
264
|
+
12. sqlite_fuzzy_match
|
|
265
|
+
13. sqlite_phonetic_match
|
|
266
|
+
14. sqlite_text_normalize
|
|
267
|
+
15. sqlite_text_validate
|
|
268
|
+
16. sqlite_advanced_search
|
|
269
|
+
17. sqlite_fts_create `[NATIVE ONLY]`
|
|
270
|
+
18. sqlite_fts_search `[NATIVE ONLY]`
|
|
271
|
+
19. sqlite_fts_rebuild `[NATIVE ONLY]`
|
|
272
|
+
20. sqlite_fts_match_info `[NATIVE ONLY]`
|
|
273
|
+
|
|
274
|
+
### text Group Tools — WASM (13)
|
|
275
|
+
|
|
276
|
+
Same as Native minus the 4 FTS5 tools (items 17-20).
|
|
277
|
+
|
|
278
|
+
### Category 1: Regex Edge Cases
|
|
279
|
+
|
|
280
|
+
1. `sqlite_regex_match({table: "test_users", column: "email", pattern: "^[a-z]+\\.[a-z]+@"})` → verify matching against dotted local parts (john.doe, jane.smith, etc.)
|
|
281
|
+
2. `sqlite_regex_match({table: "test_users", column: "phone", pattern: "^\\+1"})` → US phone numbers only (6 users, 1 NULL excluded)
|
|
282
|
+
3. `sqlite_regex_extract({table: "test_users", column: "email", pattern: "@(.+)$", groupIndex: 1})` → full domain extraction
|
|
283
|
+
4. `sqlite_regex_match({table: "test_users", column: "bio", pattern: ".*"})` → should match all non-NULL bios (all 9 users have bios)
|
|
284
|
+
|
|
285
|
+
### Category 2: Fuzzy/Phonetic Matching Stress
|
|
286
|
+
|
|
287
|
+
5. `sqlite_fuzzy_match({table: "test_products", column: "name", search: "Keyborad", maxDistance: 3})` → should find "Mechanical Keyboard" (Levenshtein)
|
|
288
|
+
6. `sqlite_fuzzy_match({table: "test_products", column: "name", search: "LAPTOP", maxDistance: 2, tokenize: true})` → should match "Laptop" token in "Laptop Pro 15"
|
|
289
|
+
7. `sqlite_fuzzy_match({table: "test_products", column: "name", search: "xyznonexistent", maxDistance: 1})` → 0 results
|
|
290
|
+
8. `sqlite_phonetic_match({table: "test_users", column: "username", search: "jon", algorithm: "soundex"})` → 0 results expected (Soundex: "jon"=J500 ≠ "johndoe"=J530; single-word usernames aren't tokenized)
|
|
291
|
+
9. `sqlite_phonetic_match({table: "test_users", column: "username", search: "smith", algorithm: "soundex"})` → report behavior (janesmith contains "smith" as suffix)
|
|
292
|
+
10. `sqlite_advanced_search({table: "test_users", column: "username", searchTerm: "jhn", techniques: ["exact", "fuzzy", "phonetic"], fuzzyThreshold: 0.3})` → should find John via fuzzy/phonetic even with low threshold
|
|
293
|
+
|
|
294
|
+
### Category 3: Text Transformation Edge Cases
|
|
295
|
+
|
|
296
|
+
11. `sqlite_text_normalize({table: "test_products", column: "name", mode: "strip_accents"})` → `"Café Décor Light"` becomes `"Cafe Decor Light"` — verify ALL rows returned, not just the accented one
|
|
297
|
+
12. `sqlite_text_normalize({table: "test_products", column: "name", mode: "nfkc"})` → NFKC normalization (compatibility decomposition + canonical composition)
|
|
298
|
+
13. `sqlite_text_case({table: "test_users", column: "username", mode: "upper"})` → verify 9 uppercased usernames
|
|
299
|
+
14. `sqlite_text_case({table: "test_users", column: "username", mode: "lower"})` → verify idempotent (already lowercase)
|
|
300
|
+
15. `sqlite_text_substring({table: "test_users", column: "email", start: 1, length: 3})` → first 3 chars of each email
|
|
301
|
+
|
|
302
|
+
### Category 4: Validation Patterns
|
|
303
|
+
|
|
304
|
+
16. `sqlite_text_validate({table: "test_users", column: "email", pattern: "email"})` → expect all 9 valid
|
|
305
|
+
17. `sqlite_text_validate({table: "test_users", column: "phone", pattern: "phone"})` → report valid/invalid/null counts
|
|
306
|
+
18. `sqlite_text_validate({table: "test_users", column: "email", pattern: "custom", customPattern: "^.+@.+\\..{2,}$"})` → custom regex validation
|
|
307
|
+
|
|
308
|
+
### Category 5: FTS5 State Integrity `[NATIVE ONLY]`
|
|
309
|
+
|
|
310
|
+
19. `sqlite_fts_search({table: "test_articles_fts", query: "database"})` → verify results include articles about databases
|
|
311
|
+
20. After base tests confirm FTS works, test rebuild: `sqlite_fts_rebuild({table: "test_articles_fts"})` → success
|
|
312
|
+
21. `sqlite_fts_search({table: "test_articles_fts", query: "database"})` → verify same results after rebuild (idempotent)
|
|
313
|
+
22. `sqlite_fts_search({table: "test_articles_fts", query: "SQLite AND database"})` → boolean operator test
|
|
314
|
+
23. `sqlite_fts_search({table: "test_articles_fts", query: "\"full-text search\""})` → phrase query test
|
|
315
|
+
|
|
316
|
+
### Category 6: WASM Boundary Verification
|
|
317
|
+
|
|
318
|
+
For WASM testing only — verify graceful degradation:
|
|
319
|
+
|
|
320
|
+
24. Confirm FTS5 tools are NOT present in the tool list (WASM mode should exclude them)
|
|
321
|
+
25. All 13 non-FTS text tools should work identically in WASM and Native
|
|
322
|
+
|
|
323
|
+
### Category 7: Error Message Quality
|
|
324
|
+
|
|
325
|
+
26. `sqlite_regex_match({table: "nonexistent_table_xyz", column: "x", pattern: "."})` → structured error
|
|
326
|
+
27. `sqlite_fuzzy_match({table: "test_users", column: "nonexistent_col", search: "test"})` → structured error
|
|
327
|
+
28. `sqlite_text_validate({table: "test_users", column: "email", pattern: "custom"})` → error about missing `customPattern` when pattern=custom
|
|
328
|
+
29. `sqlite_fts_search({table: "nonexistent_fts_xyz", query: "test"})` `[NATIVE ONLY]` → structured error
|
|
329
|
+
|
|
330
|
+
### Final Cleanup
|
|
331
|
+
|
|
332
|
+
Confirm `test_articles` row count is still 8. Verify FTS index integrity with `sqlite_fts_match_info` `[NATIVE ONLY]`.
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
## stats Group Advanced Tests
|
|
337
|
+
|
|
338
|
+
### Built-in Tools (3)
|
|
339
|
+
|
|
340
|
+
1. server_info
|
|
341
|
+
2. server_health
|
|
342
|
+
3. list_adapters
|
|
343
|
+
|
|
344
|
+
### stats Group Tools — Native (19)
|
|
345
|
+
|
|
346
|
+
4. sqlite_stats_basic
|
|
347
|
+
5. sqlite_stats_count
|
|
348
|
+
6. sqlite_stats_group_by
|
|
349
|
+
7. sqlite_stats_histogram
|
|
350
|
+
8. sqlite_stats_percentile
|
|
351
|
+
9. sqlite_stats_correlation
|
|
352
|
+
10. sqlite_stats_top_n
|
|
353
|
+
11. sqlite_stats_distinct
|
|
354
|
+
12. sqlite_stats_summary
|
|
355
|
+
13. sqlite_stats_frequency
|
|
356
|
+
14. sqlite_stats_outliers
|
|
357
|
+
15. sqlite_stats_regression
|
|
358
|
+
16. sqlite_stats_hypothesis
|
|
359
|
+
17. sqlite_window_row_number `[NATIVE ONLY]`
|
|
360
|
+
18. sqlite_window_rank `[NATIVE ONLY]`
|
|
361
|
+
19. sqlite_window_lag_lead `[NATIVE ONLY]`
|
|
362
|
+
20. sqlite_window_running_total `[NATIVE ONLY]`
|
|
363
|
+
21. sqlite_window_moving_avg `[NATIVE ONLY]`
|
|
364
|
+
22. sqlite_window_ntile `[NATIVE ONLY]`
|
|
365
|
+
|
|
366
|
+
### stats Group Tools — WASM (13)
|
|
367
|
+
|
|
368
|
+
Same as Native minus the 6 window function tools (items 17-22).
|
|
369
|
+
|
|
370
|
+
### Category 1: Boundary Values & Empty States
|
|
371
|
+
|
|
372
|
+
Create `stress_stats_table (id INTEGER PRIMARY KEY, value REAL, category TEXT)`:
|
|
373
|
+
|
|
374
|
+
**1.1 Empty Table Statistics**
|
|
375
|
+
|
|
376
|
+
1. `sqlite_stats_basic({table: "stress_stats_table", column: "value"})` → expect graceful error or empty stats (not a crash)
|
|
377
|
+
2. `sqlite_stats_count({table: "stress_stats_table"})` → `{count: 0}`
|
|
378
|
+
3. `sqlite_stats_histogram({table: "stress_stats_table", column: "value", buckets: 5})` → expect graceful handling
|
|
379
|
+
|
|
380
|
+
**1.2 Single-Row Statistics**
|
|
381
|
+
|
|
382
|
+
Insert one row: `(1, 42.0, 'test')`:
|
|
383
|
+
|
|
384
|
+
4. `sqlite_stats_basic({table: "stress_stats_table", column: "value"})` → count=1, min=max=avg=42.0
|
|
385
|
+
5. `sqlite_stats_percentile({table: "stress_stats_table", column: "value", percentiles: [25, 50, 75]})` → all should equal 42
|
|
386
|
+
6. `sqlite_stats_regression({table: "stress_stats_table", xColumn: "id", yColumn: "value", degree: 1})` → expect graceful handling (regression undefined for n=1)
|
|
387
|
+
|
|
388
|
+
**1.3 NULL-Heavy Data**
|
|
389
|
+
|
|
390
|
+
Insert 5 rows: 3 with `value IS NULL`, 2 with actual values:
|
|
391
|
+
|
|
392
|
+
7. `sqlite_stats_basic({table: "stress_stats_table", column: "value"})` → should only count non-null values (3 total: 42.0 + 2 new)
|
|
393
|
+
8. `sqlite_stats_count({table: "stress_stats_table", column: "value"})` → non-null count only
|
|
394
|
+
|
|
395
|
+
**1.4 Extreme Numeric Values**
|
|
396
|
+
|
|
397
|
+
Insert: `(value: 99999999.99)`, `(value: -99999999.99)`, `(value: 0.0)`, `(value: 0.01)`:
|
|
398
|
+
|
|
399
|
+
9. `sqlite_stats_basic({table: "stress_stats_table", column: "value"})` → verify min/max/avg handle extreme values correctly
|
|
400
|
+
|
|
401
|
+
### Category 2: Statistical Edge Cases
|
|
402
|
+
|
|
403
|
+
10. `sqlite_stats_correlation({table: "test_products", column1: "id", column2: "id"})` → self-correlation = 1.0 (or very close)
|
|
404
|
+
11. `sqlite_stats_hypothesis({table: "test_measurements", column: "temperature", testType: "ttest_one", expectedMean: 999})` → should reject null hypothesis (very different from actual mean)
|
|
405
|
+
12. `sqlite_stats_outliers({table: "test_measurements", column: "temperature", method: "iqr"})` → IQR-based outliers
|
|
406
|
+
13. `sqlite_stats_outliers({table: "test_measurements", column: "temperature", method: "zscore"})` → Z-score-based outliers (compare with IQR)
|
|
407
|
+
14. `sqlite_stats_regression({table: "test_measurements", xColumn: "temperature", yColumn: "humidity", degree: 2})` → quadratic regression coefficients
|
|
408
|
+
|
|
409
|
+
### Category 3: Window Functions `[NATIVE ONLY]`
|
|
410
|
+
|
|
411
|
+
15. `sqlite_window_row_number({table: "test_products", orderBy: "price DESC"})` → 16 rows with sequential row numbers, Laptop Pro 15 at #1
|
|
412
|
+
> **Note:** `window_row_number` and `window_rank` do NOT have a `direction` param — embed direction in the `orderBy` string (e.g., `"price DESC"`).
|
|
413
|
+
16. `sqlite_window_rank({table: "test_orders", orderBy: "total_price DESC"})` → ranks with potential ties
|
|
414
|
+
17. `sqlite_window_running_total({table: "test_orders", valueColumn: "total_price", orderBy: "order_date"})` → monotonically increasing cumulative total
|
|
415
|
+
18. `sqlite_window_moving_avg({table: "test_measurements", valueColumn: "temperature", windowSize: 10, orderBy: "measured_at"})` → moving average with 10-row window
|
|
416
|
+
19. `sqlite_window_ntile({table: "test_products", buckets: 4, orderBy: "price"})` → 4 groups of ~4 products each
|
|
417
|
+
|
|
418
|
+
### Category 4: Error Message Quality
|
|
419
|
+
|
|
420
|
+
20. `sqlite_stats_basic({table: "nonexistent_table_xyz", column: "x"})` → structured error mentioning table name
|
|
421
|
+
21. `sqlite_stats_basic({table: "test_products", column: "nonexistent_col"})` → structured error mentioning column name
|
|
422
|
+
22. `sqlite_stats_correlation({table: "test_products", column1: "name", column2: "description"})` → error about non-numeric columns (both TEXT)
|
|
423
|
+
23. `sqlite_stats_histogram({table: "test_products", column: "price", buckets: 0})` → error (must be > 0)
|
|
424
|
+
24. `sqlite_stats_histogram({table: "test_products", column: "price", buckets: -1})` → error
|
|
425
|
+
|
|
426
|
+
### Category 5: WASM Boundary Verification
|
|
427
|
+
|
|
428
|
+
For WASM testing only:
|
|
429
|
+
|
|
430
|
+
25. Confirm window function tools are NOT present in the tool list
|
|
431
|
+
26. All 13 non-window stats tools should produce identical results in WASM and Native
|
|
432
|
+
|
|
433
|
+
### Final Cleanup
|
|
434
|
+
|
|
435
|
+
Drop `stress_stats_table`. Confirm `test_measurements` (200 rows) and `test_products` (16 rows) are unchanged.
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
## vector Group Advanced Tests
|
|
440
|
+
|
|
441
|
+
> **Note:** Vector tools use pure JS computations with JSON-stored vectors — all 12 tools work identically in both WASM and Native modes.
|
|
442
|
+
|
|
443
|
+
### Built-in Tools (3)
|
|
444
|
+
|
|
445
|
+
1. server_info
|
|
446
|
+
2. server_health
|
|
447
|
+
3. list_adapters
|
|
448
|
+
|
|
449
|
+
### vector Group Tools (11)
|
|
450
|
+
|
|
451
|
+
4. sqlite_vector_create_table
|
|
452
|
+
5. sqlite_vector_store
|
|
453
|
+
6. sqlite_vector_batch_store
|
|
454
|
+
7. sqlite_vector_search
|
|
455
|
+
8. sqlite_vector_get
|
|
456
|
+
9. sqlite_vector_delete
|
|
457
|
+
10. sqlite_vector_count
|
|
458
|
+
11. sqlite_vector_stats
|
|
459
|
+
12. sqlite_vector_dimensions
|
|
460
|
+
13. sqlite_vector_normalize
|
|
461
|
+
14. sqlite_vector_distance
|
|
462
|
+
|
|
463
|
+
### Category 1: Boundary Values
|
|
464
|
+
|
|
465
|
+
> **Note:** Vector tools use `tableName` for create, but `table` for other operations. Store/batch-store require `idColumn` and `vectorColumn`. Search requires `vectorColumn` and `queryVector`.
|
|
466
|
+
|
|
467
|
+
**1.1 Empty Vector Table**
|
|
468
|
+
|
|
469
|
+
1. `sqlite_vector_create_table({tableName: "stress_vec_empty", dimensions: 4})` → success (creates columns: id, vector, dimensions)
|
|
470
|
+
2. `sqlite_vector_count({table: "stress_vec_empty"})` → `{count: 0}`
|
|
471
|
+
3. `sqlite_vector_search({table: "stress_vec_empty", vectorColumn: "vector", queryVector: [1, 2, 3, 4], metric: "cosine", limit: 5})` → empty results (not error)
|
|
472
|
+
4. `sqlite_vector_stats({table: "stress_vec_empty", vectorColumn: "vector"})` → graceful handling: `{count: 0, message: "No valid vectors found"}`
|
|
473
|
+
5. `sqlite_vector_dimensions({table: "stress_vec_empty", vectorColumn: "vector"})` → `{dimensions: null, message: "No vectors found"}` (inferred from data, not schema)
|
|
474
|
+
|
|
475
|
+
**1.2 Single-Vector Table**
|
|
476
|
+
|
|
477
|
+
6. `sqlite_vector_store({table: "stress_vec_empty", idColumn: "id", vectorColumn: "vector", id: 1, vector: [1, 0, 0, 0]})` → success
|
|
478
|
+
7. `sqlite_vector_search({table: "stress_vec_empty", vectorColumn: "vector", queryVector: [1, 0, 0, 0], metric: "cosine", limit: 5})` → exactly 1 result, similarity = 1
|
|
479
|
+
|
|
480
|
+
### Category 2: Distance Metric Verification
|
|
481
|
+
|
|
482
|
+
8. `sqlite_vector_distance({vector1: [1, 0, 0], vector2: [0, 1, 0], metric: "cosine"})` → ≈ 1.0 (orthogonal)
|
|
483
|
+
9. `sqlite_vector_distance({vector1: [1, 0, 0], vector2: [1, 0, 0], metric: "cosine"})` → ≈ 0.0 (identical)
|
|
484
|
+
10. `sqlite_vector_distance({vector1: [1, 0, 0], vector2: [-1, 0, 0], metric: "cosine"})` → ≈ 2.0 (opposite)
|
|
485
|
+
11. `sqlite_vector_distance({vector1: [3, 4], vector2: [0, 0], metric: "euclidean"})` → exactly 5.0
|
|
486
|
+
12. `sqlite_vector_distance({vector1: [1, 2, 3], vector2: [1, 2, 3], metric: "euclidean"})` → exactly 0.0
|
|
487
|
+
13. `sqlite_vector_normalize({vector: [3, 4]})` → `{normalized: [0.6, 0.8], originalMagnitude: 5.0}`
|
|
488
|
+
14. `sqlite_vector_normalize({vector: [0, 0, 0]})` → `{normalized: [0, 0, 0], originalMagnitude: 0}` (zero vector returns zero — no crash)
|
|
489
|
+
|
|
490
|
+
### Category 3: Dimension Mismatch
|
|
491
|
+
|
|
492
|
+
> **Note:** Dimension validation on store is best-effort — checks `dimensions` column of existing rows. `sqlite_vector_distance` enforces strictly.
|
|
493
|
+
|
|
494
|
+
15. `sqlite_vector_store({table: "stress_vec_empty", idColumn: "id", vectorColumn: "vector", id: 2, vector: [1, 2]})` → dimension mismatch error (table has 4-dim rows)
|
|
495
|
+
16. `sqlite_vector_search({table: "stress_vec_empty", vectorColumn: "vector", queryVector: [1, 2], metric: "cosine"})` → search still runs (dimension mismatch is silently handled via try/catch in similarity calculation)
|
|
496
|
+
17. `sqlite_vector_distance({vector1: [1, 2, 3], vector2: [1, 2], metric: "cosine"})` → structured error: "Vector dimensions must match"
|
|
497
|
+
|
|
498
|
+
### Category 4: Batch Operations
|
|
499
|
+
|
|
500
|
+
18. `sqlite_vector_batch_store({table: "stress_vec_empty", idColumn: "id", vectorColumn: "vector", items: []})` → `{stored: 0, message: "No items provided"}`
|
|
501
|
+
19. `sqlite_vector_batch_store` with 50 vectors into `stress_vec_empty` → verify `{stored: 50}`
|
|
502
|
+
20. `sqlite_vector_count({table: "stress_vec_empty"})` → `{count: 51}` (1 from earlier + 50 batch)
|
|
503
|
+
|
|
504
|
+
### Category 5: Category Filtering
|
|
505
|
+
|
|
506
|
+
21. `sqlite_vector_search({table: "test_embeddings", vectorColumn: "embedding", queryVector: [0.12, 0.45, -0.23, 0.78, 0.34, -0.56, 0.89, 0.01], metric: "cosine", limit: 20, whereClause: "category = 'tech'"})` → only tech category results (4 rows)
|
|
507
|
+
22. `sqlite_vector_search({table: "test_embeddings", vectorColumn: "embedding", queryVector: [0.12, 0.45, -0.23, 0.78, 0.34, -0.56, 0.89, 0.01], metric: "cosine", limit: 20, whereClause: "category = 'nonexistent'"})` → 0 results (not error)
|
|
508
|
+
|
|
509
|
+
### Category 6: Error Message Quality
|
|
510
|
+
|
|
511
|
+
23. `sqlite_vector_search({table: "nonexistent_table_xyz", vectorColumn: "v", queryVector: [1, 2, 3], metric: "cosine"})` → structured error mentioning table name
|
|
512
|
+
24. `sqlite_vector_get({table: "test_embeddings", idColumn: "id", vectorColumn: "embedding", id: 99999})` → `{success: false, error: "Vector not found"}`
|
|
513
|
+
25. `sqlite_vector_delete({table: "test_embeddings", idColumn: "id", ids: [99999]})` → `{success: true, deleted: 0}` (idempotent)
|
|
514
|
+
|
|
515
|
+
### Final Cleanup
|
|
516
|
+
|
|
517
|
+
Drop `stress_vec_empty`. Confirm `test_embeddings` count is still 20.
|