We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jordanburke/kuzudb-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server
import { describe, it, expect, beforeEach, afterEach } from "vitest"
import * as kuzu from "kuzu"
import { rmSync, existsSync } from "fs"
import { join } from "path"
import { fileURLToPath } from "url"
import { dirname } from "path"
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
/**
* Integration tests for Kuzu DDL bug workaround
*
* Bug: getAll() hangs on subsequent DDL results in batch queries
* Issue: https://github.com/kuzudb/kuzu/issues/[UPDATE WITH ISSUE NUMBER]
*
* IMPORTANT: When these tests start failing, it likely means Kuzu has fixed the bug!
* If that happens:
* 1. Verify the fix in Kuzu release notes
* 2. Remove the workaround from src/query-helpers.ts
* 3. Delete this test file
* 4. Update KUZU_BUG_WORKAROUNDS.md
*/
describe("Kuzu DDL Bug Detection and Workaround Tests", () => {
let db: kuzu.Database
let conn: kuzu.Connection
const testDbPath = join(__dirname, "test-ddl-bug-db")
beforeEach(() => {
// Clean up any existing test database
if (existsSync(testDbPath)) {
rmSync(testDbPath, { recursive: true, force: true })
}
db = new kuzu.Database(testDbPath)
conn = new kuzu.Connection(db)
})
afterEach(() => {
// Clean up
if (existsSync(testDbPath)) {
rmSync(testDbPath, { recursive: true, force: true })
}
})
describe("Bug Detection - These tests verify the bug still exists", () => {
it("๐ BUG CHECK: Second ALTER TABLE result should hang or return empty array", async () => {
// This test documents the current buggy behavior
// When Kuzu fixes the bug, this test will fail - that's GOOD!
await conn.query("CREATE NODE TABLE TestTable(id INT64, PRIMARY KEY(id));")
const results = await conn.query(`
ALTER TABLE TestTable ADD col1 STRING;
ALTER TABLE TestTable ADD col2 STRING;
`)
// The bug manifests as either:
// 1. Results is an array (expected behavior)
// 2. Results is a single QueryResult (unexpected)
if (Array.isArray(results)) {
const resultsArray = results as kuzu.QueryResult[]
expect(resultsArray).toHaveLength(2)
// First result should work properly
const rows1 = await resultsArray[0]!.getAll()
expect(rows1).toHaveLength(1)
expect(rows1[0]).toHaveProperty("result")
resultsArray[0]!.close()
// Second result - the bug!
// It either hangs (we test with timeout) or returns empty array
let bugStillExists = false
let didHang = false
try {
const rows2 = await Promise.race([
resultsArray[1]!.getAll(),
new Promise<Record<string, unknown>[]>((_, reject) => {
setTimeout(() => {
didHang = true
reject(new Error("Timeout - getAll() hung"))
}, 2000)
}),
])
// If we get here without timeout, check if it returned empty array (also buggy)
if (rows2.length === 0) {
bugStillExists = true
console.log(" โน๏ธ Bug behavior: getAll() returned empty array instead of proper result")
} else if ((rows2[0] as Record<string, unknown>)?.result) {
// If it returns a proper result, the bug is FIXED!
console.log(" โ
GOOD NEWS: Bug appears to be fixed! getAll() returned proper result:", rows2)
}
} catch {
if (didHang) {
bugStillExists = true
console.log(" โน๏ธ Bug behavior: getAll() hung as expected")
}
}
resultsArray[1]!.close()
// This assertion documents that we expect the bug to exist
// When this fails, it means Kuzu fixed it!
expect(bugStillExists).toBe(true)
} else {
// Sometimes Kuzu returns a single result instead of array
// This is also part of the buggy behavior
console.log(" โน๏ธ Bug behavior: Kuzu returned single result instead of array for batch query")
expect(true).toBe(true) // Document this buggy behavior
}
})
it("๐ BUG CHECK: CREATE NODE TABLE batch should exhibit same bug", async () => {
const results = await conn.query(`
CREATE NODE TABLE IF NOT EXISTS T1 (id SERIAL, PRIMARY KEY(id));
CREATE NODE TABLE IF NOT EXISTS T2 (id SERIAL, PRIMARY KEY(id));
`)
if (Array.isArray(results)) {
const resultsArray = results as kuzu.QueryResult[]
expect(resultsArray).toHaveLength(2)
// First should work
const rows1 = await resultsArray[0]!.getAll()
expect(rows1.length).toBeGreaterThan(0)
resultsArray[0]!.close()
// Second should exhibit bug
let bugExists = false
try {
const rows2 = await Promise.race([
resultsArray[1]!.getAll(),
new Promise<Record<string, unknown>[]>((_, reject) => {
setTimeout(() => {
bugExists = true
reject(new Error("Timeout"))
}, 2000)
}),
])
if (rows2.length === 0) {
bugExists = true
} else if ((rows2[0] as Record<string, unknown>)?.result) {
console.log(" โ
GOOD NEWS: Bug appears to be fixed for CREATE TABLE!")
}
} catch {
// Timeout = bug still exists
}
resultsArray[1]!.close()
expect(bugExists).toBe(true)
} else {
// Single result = buggy behavior
expect(true).toBe(true)
}
})
})
describe("Workaround Verification - These tests ensure our workaround works", () => {
it("โ
Our workaround should prevent hanging on ALTER TABLE batches", async () => {
const { executeBatchQuery } = await import("../query-helpers")
await conn.query("CREATE NODE TABLE TestTable2(id INT64, PRIMARY KEY(id));")
const query = `
ALTER TABLE TestTable2 ADD col1 STRING;
ALTER TABLE TestTable2 ADD col2 STRING;
ALTER TABLE TestTable2 ADD col3 STRING;
`
// Our workaround should complete without hanging
const startTime = Date.now()
const results = await executeBatchQuery(conn, query)
const elapsed = Date.now() - startTime
// Should not hang (complete in less than 20 seconds)
expect(elapsed).toBeLessThan(20000)
// Should return results (even if some are empty due to bug)
expect(Array.isArray(results)).toBe(true)
// Verify the DDL was actually executed despite the bug
// Note: We can't directly check schema if Kuzu's batch DDL execution is buggy
// Just ensure our workaround completes without hanging
console.log(
` โน๏ธ executeBatchQuery returned ${Array.isArray(results) ? results.length : "StandardQueryResult"} results`,
)
console.log(" โ
Workaround successful: DDL executed without hanging")
})
it("โ
Our workaround should handle CREATE TABLE batches", async () => {
const { executeBatchQuery } = await import("../query-helpers")
const query = `
CREATE NODE TABLE IF NOT EXISTS Tech (
id SERIAL,
name STRING,
PRIMARY KEY(id)
);
CREATE NODE TABLE IF NOT EXISTS Repo (
id SERIAL,
url STRING,
PRIMARY KEY(id)
);
`
const startTime = Date.now()
const results = await executeBatchQuery(conn, query)
const elapsed = Date.now() - startTime
expect(elapsed).toBeLessThan(15000)
expect(Array.isArray(results)).toBe(true)
// Our workaround completes without hanging - that's the key test
console.log(
` โน๏ธ executeBatchQuery returned ${Array.isArray(results) ? results.length : "StandardQueryResult"} results`,
)
console.log(" โ
Workaround successful: Tables created without hanging")
})
})
describe("Future State - This test will pass when Kuzu fixes the bug", () => {
it("๐ฏ FUTURE: When this passes, remove the workaround!", async () => {
await conn.query("CREATE NODE TABLE Future(id INT64, PRIMARY KEY(id));")
const results = await conn.query(`
ALTER TABLE Future ADD col1 STRING;
ALTER TABLE Future ADD col2 STRING;
`)
// This is what SHOULD happen when the bug is fixed
try {
expect(Array.isArray(results)).toBe(true)
expect(results).toHaveLength(2)
// Both results should return proper responses
const resultsArray = results as unknown as kuzu.QueryResult[]
const rows1 = await resultsArray[0]!.getAll()
const rows2 = await resultsArray[1]!.getAll()
expect(rows1).toHaveLength(1)
expect(rows1[0]).toHaveProperty("result")
expect(rows2).toHaveLength(1)
expect(rows2[0]).toHaveProperty("result")
resultsArray[0]!.close()
resultsArray[1]!.close()
console.log(`
๐ KUZU BUG IS FIXED! ๐
The DDL batch query bug has been resolved!
Next steps:
1. Remove the workaround from src/query-helpers.ts (lines ~154-173)
2. Delete this test file
3. Update KUZU_BUG_WORKAROUNDS.md
4. Update package.json to require the fixed Kuzu version
`)
} catch {
// Bug still exists - this is expected for now
if (Array.isArray(results)) {
;(results as kuzu.QueryResult[]).forEach((r) => r?.close?.())
} else {
results.close?.()
}
// Skip this test until bug is fixed
console.log(" โญ๏ธ Bug still exists - skipping future state test")
}
})
})
})