ts-11-mini-sql
0.000
Proposed solution
```ts
export type Row = Record<string, number | string>;
export class QueryError extends Error {}
// Parse and execute a small SQL SELECT against the given rows. Returns the result rows.
export function query(sql: string, rows: Row[]): Row[];
// Helper functions for parsing and evaluating SQL queries
function tokenize(sql: string): string[] {
return sql.trim().toLowerCase().split(/\s+/);
}
function parseSelect(tokens: string[]): [string[], string[]] {
const [selectClause, fromClause] = tokens.splice(0, 2);
const selectColumns = selectClause.startsWith('*') ? ['*'] : selectClause.split(',').map(col => col.trim());
return [selectColumns, fromClause];
}
function parseFrom(fromClause: string): string[] {
return fromClause.split(' ');
}
function parseWhere(tokens: string[]): [string[], string[]] {
const [whereClause, ...rest] = tokens;
const conditions: string[][] = whereClause.split(' AND ').map(cond => cond.split(' OR '));
return [conditions, rest];
}
function parseOrderBy(tokens: string[]): [string[], string[]] {
const [orderByClause, limitClause] = tokens;
const orderByColumn = orderByClause.startsWith('asc') ? orderByClause.split(' ')[1] : orderByClause.split(' desc')[1];
const order = orderByClause.startsWith('asc') ? 'ASC' : 'DESC';
return [orderByColumn, order, limitClause];
}
function parseLimit(tokens: string[]): [string[], string] {
const limitToken = tokens.find(token => token === 'limit');
if (!limitToken) return [tokens, ''];
const limitValue = parseInt(tokens[tokens.indexOf(limitToken) + 1], 10);
if (isNaN(limitValue) || limitValue < 0) throw new QueryError('Invalid LIMIT value');
return tokens.slice(tokens.indexOf(limitToken) + 2), limitValue.toString();
}
function evaluateCondition(row: Row, condition: string): boolean {
const [col, op, value] = condition.split(' ');
const cell = row[col];
if (typeof cell !== typeof value) return false;
switch (op) {
case '=': return cell === value;
case '!=': return cell !== value;
case '<': return typeof cell === 'number' ? cell < parseFloat(value) : false;
case '>': return typeof cell === 'number' ? cell > parseFloat(value) : false;
case '<=': return typeof cell === 'number' ? cell <= parseFloat(value) : false;
case '>=': return typeof cell === 'number' ? cell >= parseFloat(value) : false;
default: throw new QueryError(`Invalid comparison operator: ${op}`);
}
}
function evaluateWhere(conditions: string[][], row: Row): boolean {
return conditions.some(conditionGroup => conditionGroup.some(condition => evaluateCondition(row, condition)));
}
function sortRows(rows: Row[], orderByColumn: string, order: string): Row[] {
return rows.sort((a, b) => {
const cellA = a[orderByColumn];
const cellB = b[orderByColumn];
if (typeof cellA === 'number' && typeof cellB === 'number') {
return order === 'ASC' ? cellA - cellB : cellB - cellA;
} else if (typeof cellA === 'string' && typeof cellB === 'string') {
return order === 'ASC' ? cellA.localeCompare(cellB) : cellB.localeCompare(cellA);
}
return 0;
});
}
function limitRows(rows: Row[], limit: number): Row[] {
return rows.slice(0, limit);
}
function projectColumns(rows: Row[], columns: string[]): Row[] {
return rows.map(row => {
const projectedRow: Record<string, number | string> = {};
columns.forEach(col => {
if (row[col] !== undefined) {
projectedRow[col] = row[col];
}
});
return projectedRow;
});
}
function query(sql: string, rows: Row[]): Row[] {
const tokens = tokenize(sql);
const [selectColumns, fromClause] = parseSelect(tokens);
const [conditions, rest] = parseWhere(tokens);
const [orderByColumn, order, limitClause] = parseOrderBy(tokens);
const limit = parseLimit(tokens)[1];
const filteredRows = rows.filter(row => evaluateWhere(conditions, row));
const sortedRows = filteredRows.sort((a, b) => {
const cellA = a[orderByColumn];
const cellB = b[orderByColumn];
if (typeof cellA === 'number' && typeof cellB === 'number') {
return order === 'ASC' ? cellA - cellB : cellB - cellA;
} else if (typeof cellA === 'string' && typeof cellB === 'string') {
return order === 'ASC' ? cellA.localeCompare(cellB) : cellB.localeCompare(cellA);
}
return 0;
});
const limitedRows = limitRows(sortedRows, limit);
return projectColumns(limitedRows, selectColumns);
}
// Example usage
const rows: Row[] = [
{ id: 1, name: "alice", age: 30 },
{ id: 2, name: "bob", age: 25 },
{ id: 3, name: "carol", age: 30 },
{ id: 4, name: "dave", age: 17 },
];
console.log(query("SELECT name, age FROM users WHERE age >= 18 ORDER BY age DESC LIMIT 2", rows));
// -> [ { name: "alice", age: 30 }, { name: "carol", age: 30 } ]
```Test output (stdout)
TAP version 13
# /tmp/llmlab-ts-11-mini-sql-nf0vp6cf/solution.test.ts:3
# import { query, QueryError, type Row } from "./solution.ts";
# ^
# SyntaxError: The requested module './solution.ts' does not provide an export named 'query'
# at \#asyncInstantiate (node:internal/modules/esm/module_job:327:21)
# at async ModuleJob.run (node:internal/modules/esm/module_job:431:5)
# at async node:internal/modules/esm/loader:633:26
# at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5)
# Node.js v24.16.0
# Subtest: solution.test.ts
not ok 1 - solution.test.ts
---
duration_ms: 68.635491
type: 'test'
location: '/tmp/llmlab-ts-11-mini-sql-nf0vp6cf/solution.test.ts:1:1'
failureType: 'testCodeFailure'
exitCode: 1
signal: ~
error: 'test failed'
code: 'ERR_TEST_FAILURE'
...
1..1
# tests 1
# suites 0
# pass 0
# fail 1
# cancelled 0
# skipped 0
# todo 0
# duration_ms 72.326167
Self-repair attempts
[
{
"total": 1,
"answer": "```ts\nexport type Row = Record<string, number | string>;\n\nexport class QueryError extends Error {}\n\n// Parse and execute a small SQL SELECT against the given rows. Returns the result rows.\nexport function query(sql: string, rows: Row[]): Row[];\n\n// Helper functions for parsing and evaluating SQL queries\nfunction tokenize(sql: string): string[] {\n return sql.trim().toLowerCase().split(/\\s+/);\n}\n\nfunction parseSelect(tokens: string[]): [string[], string[]] {\n const [selectClause, fromClause] = tokens.splice(0, 2);\n const selectColumns = selectClause.startsWith('*') ? ['*'] : selectClause.split(',').map(col => col.trim());\n return [selectColumns, fromClause];\n}\n\nfunction parseFrom(fromClause: string): string[] {\n return fromClause.split(' ');\n}\n\nfunction parseWhere(tokens: string[]): [string[], string[]] {\n const [whereClause, ...rest] = tokens;\n const conditions: string[][] = whereClause.split(' AND ').map(cond => cond.split(' OR '));\n return [conditions, rest];\n}\n\nfunction parseOrderBy(tokens: string[]): [string[], string[]] {\n const [orderByClause, limitClause] = tokens;\n const orderByColumn = orderByClause.startsWith('asc') ? orderByClause.split(' ')[1] : orderByClause.split(' desc')[1];\n const order = orderByClause.startsWith('asc') ? 'ASC' : 'DESC';\n return [orderByColumn, order, limitClause];\n}\n\nfunction parseLimit(tokens: string[]): [string[], string] {\n const limitToken = tokens.find(token => token === 'limit');\n if (!limitToken) return [tokens, ''];\n const limitValue = parseInt(tokens[tokens.indexOf(limitToken) + 1], 10);\n if (isNaN(limitValue) || limitValue < 0) throw new QueryError('Invalid LIMIT value');\n return tokens.slice(tokens.indexOf(limitToken) + 2), limitValue.toString();\n}\n\nfunction evaluateCondition(row: Row, condition: string): boolean {\n const [col, op, value] = condition.split(' ');\n const cell = row[col];\n if (typeof cell !== typeof value) return false;\n switch (op) {\n case '=': return cell === value;\n case '!=': return cell !== value;\n case '<': return typeof cell === 'number' ? cell < parseFloat(value) : false;\n case '>': return typeof cell === 'number' ? cell > parseFloat(value) : false;\n case '<=': return typeof cell === 'number' ? cell <= parseFloat(value) : false;\n case '>=': return typeof cell === 'number' ? cell >= parseFloat(value) : false;\n default: throw new QueryError(`Invalid comparison operator: ${op}`);\n }\n}\n\nfunction evaluateWhere(conditions: string[][], row: Row): boolean {\n return conditions.some(conditionGroup => conditionGroup.some(condition => evaluateCondition(row, condition)));\n}\n\nfunction sortRows(rows: Row[], orderByColumn: string, order: string): Row[] {\n return rows.sort((a, b) => {\n const cellA = a[orderByColumn];\n const cellB = b[orderByColumn];\n if (typeof cellA === 'number' && typeof cellB === 'number') {\n return order === 'ASC' ? cellA - cellB : cellB - cellA;\n } else if (typeof cellA === 'string' && typeof cellB === 'string') {\n return order === 'ASC' ? cellA.localeCompare(cellB) : cellB.localeCompare(cellA);\n }\n return 0;\n });\n}\n\nfunction limitRows(rows: Row[], limit: number): Row[] {\n return rows.slice(0, limit);\n}\n\nfunction projectColumns(rows: Row[], columns: string[]): Row[] {\n return rows.map(row => {\n const projectedRow: Record<string, number | string> = {};\n columns.forEach(col => {\n if (row[col] !== undefined) {\n projectedRow[col] = row[col];\n }\n });\n return projectedRow;\n });\n}\n\nfunction query(sql: string, rows: Row[]): Row[] {\n const tokens = tokenize(sql);\n const [selectColumns, fromClause] = parseSelect(tokens);\n const [conditions, rest] = parseWhere(tokens);\n const [orderByColumn, order, limitClause] = parseOrderBy(tokens);\n const limit = parseLimit(tokens)[1];\n\n const filteredRows = rows.filter(row => evaluateWhere(conditions, row));\n const sortedRows = filteredRows.sort((a, b) => {\n const cellA = a[orderByColumn];\n const cellB = b[orderByColumn];\n if (typeof cellA === 'number' && typeof cellB === 'number') {\n return order === 'ASC' ? cellA - cellB : cellB - cellA;\n } else if (typeof cellA === 'string' && typeof cellB === 'string') {\n return order === 'ASC' ? cellA.localeCompare(cellB) : cellB.localeCompare(cellA);\n }\n return 0;\n });\n const limitedRows = limitRows(sortedRows, limit);\n return projectColumns(limitedRows, selectColumns);\n}\n\n// Example usage\nconst rows: Row[] = [\n { id: 1, name: \"alice\", age: 30 },\n { id: 2, name: \"bob\", age: 25 },\n { id: 3, name: \"carol\", age: 30 },\n { id: 4, name: \"dave\", age: 17 },\n];\n\nconsole.log(query(\"SELECT name, age FROM users WHERE age >= 18 ORDER BY age DESC LIMIT 2\", rows));\n// -> [ { name: \"alice\", age: 30 }, { name: \"carol\", age: 30 } ]\n```",
"passed": 0,
"test_error": "TAP version 13\n# /tmp/llmlab-ts-11-mini-sql-nf0vp6cf/solution.test.ts:3\n# import { query, QueryError, type Row } from \"./solution.ts\";\n# ^\n# SyntaxError: The requested module './solution.ts' does not provide an export named 'query'\n# at \\#asyncInstantiate (node:internal/modules/esm/module_job:327:21)\n# at async ModuleJob.run (node:internal/modules/esm/module_job:431:5)\n# at async node:internal/modules/esm/loader:633:26\n# at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5)\n# Node.js v24.16.0\n# Subtest: solution.test.ts\nnot ok 1 - solution.test.ts\n ---\n duration_ms: 68.635491\n type: 'test'\n location: '/tmp/llmlab-ts-11-mini-sql-nf0vp6cf/solution.test.ts:1:1'\n failureType: 'testCodeFailure'\n exitCode: 1\n signal: ~\n error: 'test failed'\n code: 'ERR_TEST_FAILURE'\n ...\n1..1\n# tests 1\n# suites 0\n# pass 0\n# fail 1\n# cancelled 0\n# skipped 0\n# todo 0\n# duration_ms 72.326167"
},
{
"total": 1,
"answer": "```ts\nexport type Row = Record<string, number | string>;\n\nexport class QueryError extends Error {}\n\n// Parse and execute a small SQL SELECT against the given rows. Returns the result rows.\nexport function query(sql: string, rows: Row[]): Row[];\n\n// Helper functions for parsing and evaluating SQL queries\nfunction tokenize(sql: string): string[] {\n return sql.trim().toLowerCase().split(/\\s+/);\n}\n\nfunction parseSelect(tokens: string[]): [string[], string[]] {\n const [selectClause, fromClause] = tokens.splice(0, 2);\n const selectColumns = selectClause.startsWith('*') ? ['*'] : selectClause.split(',').map(col => col.trim());\n return [selectColumns, fromClause];\n}\n\nfunction parseFrom(fromClause: string): string[] {\n return fromClause.split(' ');\n}\n\nfunction parseWhere(tokens: string[]): [string[][], string[]] {\n const [whereClause, ...rest] = tokens;\n const conditions: string[][] = whereClause.split(' AND ').map(cond => cond.split(' OR '));\n return [conditions, rest];\n}\n\nfunction parseOrderBy(tokens: string[]): [string[], string, string[]] {\n const [orderByClause, limitClause] = tokens;\n const orderByColumn = orderByClause.startsWith('asc') ? orderByClause.split(' ')[1] : orderByClause.split(' desc')[1];\n const order = orderByClause.startsWith('asc') ? 'ASC' : 'DESC';\n return [orderByColumn, order, limitClause];\n}\n\nfunction parseLimit(tokens: string[]): [string[], string] {\n const limitToken = tokens.find(token => token === 'limit');\n if (!limitToken) return [tokens, ''];\n const limitValue = parseInt(tokens[tokens.indexOf(limitToken) + 1], 10);\n if (isNaN(limitValue) || limitValue < 0) throw new QueryError('Invalid LIMIT value');\n return tokens.slice(tokens.indexOf(limitToken) + 2), limitValue.toString();\n}\n\nfunction evaluateCondition(row: Row, condition: string): boolean {\n const [col, op, value] = condition.split(' ');\n const cell = row[col];\n if (typeof cell !== typeof value) return false;\n switch (op) {\n case '=': return cell === value;\n case '!=': return cell !== value;\n case '<': return typeof cell === 'number' ? cell < parseFloat(value) : false;\n case '>': return typeof cell === 'number' ? cell > parseFloat(value) : false;\n case '<=': return typeof cell === 'number' ? cell <= parseFloat(value) : false;\n case '>=': return typeof cell === 'number' ? cell >= parseFloat(value) : false;\n default: throw new QueryError(`Invalid comparison operator: ${op}`);\n }\n}\n\nfunction evaluateWhere(conditions: string[][], row: Row): boolean {\n return conditions.some(conditionGroup => conditionGroup.some(condition => evaluateCondition(row, condition)));\n}\n\nfunction sortRows(rows: Row[], orderByColumn: string, order: string): Row[] {\n return rows.sort((a, b) => {\n const cellA = a[orderByColumn];\n const cellB = b[orderByColumn];\n if (typeof cellA === 'number' && typeof cellB === 'number') {\n return order === 'ASC' ? cellA - cellB : cellB - cellA;\n } else if (typeof cellA === 'string' && typeof cellB === 'string') {\n return order === 'ASC' ? cellA.localeCompare(cellB) : cellB.localeCompare(cellA);\n }\n return 0;\n });\n}\n\nfunction limitRows(rows: Row[], limit: number): Row[] {\n return rows.slice(0, limit);\n}\n\nfunction projectColumns(rows: Row[], columns: string[]): Row[] {\n return rows.map(row => {\n const projectedRow: Record<string, number | string> = {};\n columns.forEach(col => {\n if (row[col] !== undefined) {\n projectedRow[col] = row[col];\n }\n });\n return projectedRow;\n });\n}\n\nfunction query(sql: string, rows: Row[]): Row[] {\n const tokens = tokenize(sql);\n const [selectColumns, fromClause] = parseSelect(tokens);\n const [conditions, rest] = parseWhere(tokens);\n const [orderByColumn, order, limitClause] = parseOrderBy(tokens);\n const limit = parseLimit(tokens)[1];\n\n const filteredRows = rows.filter(row => evaluateWhere(conditions, row));\n const sortedRows = filteredRows.sort((a, b) => {\n const cellA = a[orderByColumn];\n const cellB = b[orderByColumn];\n if (typeof cellA === 'number' && typeof cellB === 'number') {\n return order === 'ASC' ? cellA - cellB : cellB - cellA;\n } else if (typeof cellA === 'string' && typeof cellB === 'string') {\n return order === 'ASC' ? cellA.localeCompare(cellB) : cellB.localeCompare(cellA);\n }\n return 0;\n });\n const limitedRows = limitRows(sortedRows, limit);\n return projectColumns(limitedRows, selectColumns);\n}\n\n// Example usage\nconst rows: Row[] = [\n { id: 1, name: \"alice\", age: 30 },\n { id: 2, name: \"bob\", age: 25 },\n { id: 3, name: \"carol\", age: 30 },\n { id: 4, name: \"dave\", age: 17 },\n];\n\nconsole.log(query(\"SELECT name, age FROM users WHERE age >= 18 ORDER BY age DESC LIMIT 2\", rows));\n// -> [ { name: \"alice\", age: 30 }, { name: \"carol\", age: 30 } ]\n```",
"passed": 0,
"test_error": "TAP version 13\n# /tmp/llmlab-ts-11-mini-sql-3zg24jur/solution.test.ts:3\n# import { query, QueryError, type Row } from \"./solution.ts\";\n# ^\n# SyntaxError: The requested module './solution.ts' does not provide an export named 'query'\n# at \\#asyncInstantiate (node:internal/modules/esm/module_job:327:21)\n# at async ModuleJob.run (node:internal/modules/esm/module_job:431:5)\n# at async node:internal/modules/esm/loader:633:26\n# at async asyncRunEntryPointWithESMLoader (node:internal/modules/run_main:101:5)\n# Node.js v24.16.0\n# Subtest: solution.test.ts\nnot ok 1 - solution.test.ts\n ---\n duration_ms: 65.556596\n type: 'test'\n location: '/tmp/llmlab-ts-11-mini-sql-3zg24jur/solution.test.ts:1:1'\n failureType: 'testCodeFailure'\n exitCode: 1\n signal: ~\n error: 'test failed'\n code: 'ERR_TEST_FAILURE'\n ...\n1..1\n# tests 1\n# suites 0\n# pass 0\n# fail 1\n# cancelled 0\n# skipped 0\n# todo 0\n# duration_ms 69.333043"
},
{
"total": 1,
"answer": "```ts\nexport type Row = Record<string, number | string>;\n\nexport class QueryError extends Error {}\n\n// Parse and execute a small SQL SELECT against the given rows. Returns the result rows.\nexport function query(sql: string, rows: Row[]): Row[];\n\n// Helper functions for parsing and evaluating SQL queries\nfunction tokenize(sql: string): string[] {\n return sql.trim().toLowerCase().split(/\\s+/);\n}\n\nfunction parseSelect(tokens: string[]): [string[], string[]] {\n const [selectClause, fromClause] = tokens.splice(0, 2);\n const selectColumns = selectClause.startsWith('*') ? ['*'] : selectClause.split(',').map(col => col.trim());\n return [selectColumns, fromClause];\n}\n\nfunction parseFrom(fromClause: string): string[] {\n return fromClause.split(' ');\n}\n\nfunction parseWhere(tokens: string[]): [string[][], string[]] {\n const [whereClause, ...rest] = tokens;\n const conditions: string[][] = whereClause.split(' AND ').map(cond => cond.split(' OR '));\n return [conditions, rest];\n}\n\nfunction parseOrderBy(tokens: string[]): [string[], string, string[]] {\n const [orderByClause, limitClause] = tokens;\n const orderByColumn = orderByClause.startsWith('asc') ? orderByClause.split(' ')[1] : orderByClause.split(' desc')[1];\n const order = orderByClause.startsWith('asc') ? 'ASC' : 'DESC';\n return [orderByColumn, order, limitClause];\n}\n\nfunction parseLimit(tokens: string[]): [string[], string] {\n const limitToken = tokens.find(token => token === 'limit');\n if (!limitToken) return [tokens, ''];\n const limitValue = parseInt(tokens[tokens.indexOf(limitToken) + 1], 10);\n if (isNaN(limitValue) || limitValue < 0) throw new QueryError('Invalid LIMIT value');\n return tokens.slice(tokens.indexOf(limitToken) + 2), limitValue.toString();\n}\n\nfunction evaluateCondition(row: Row, condition: string): boolean {\n const [col, op, value] = condition.split(' ');\n const cell = row[col];\n if (typeof cell !== typeof value) return false;\n switch (op) {\n case '=': return cell === value;\n case '!=': return cell !== value;\n case '<': return typeof cell === 'number' ? cell < parseFloat(value) : false;\n case '>': return typeof cell === 'number' ? cell > parseFloat(value) : false;\n case '<=': return typeof cell === 'number' ? cell <= parseFloat(value) : false;\n case '>=': return typeof cell === 'number' ? cell >= parseFloat(value) : false;\n default: throw new QueryError(`Invalid comparison operator: ${op}`);\n }\n}\n\nfunction evaluateWhere(conditions: string[][], row: Row): boolean {\n return conditions.some(conditionGroup => conditionGroup.some(condition => evaluateCondition(row, condition)));\n}\n\nfunction sortRows(rows: Row[], orderByColumn: string, order: string): Row[] {\n return rows.sort((a, b) => {\n const cellA = a[orderByColumn];\n const cellB = b[orderByColumn];\n if (typeof cellA === 'number' && typeof cellB === 'number') {\n return order === 'ASC' ? cellA - cellB : cellB - cellA;\n } else if (typeof cellA === 'string' && typeof cellB === 'string') {\n return order === 'ASC' ? cellA.localeCompare(cellB) : cellB.localeCompare(cellA);\n }\n return 0;\n });\n}\n\nfunction limitRows(rows: Row[], limit: number): Row[] {\n return rows.slice(0, limit);\n}\n\nfunction projectColumns(rows: Row[], columns: string[]): Row[] {\n return rows.map(row => {\n const projectedRow: Record<string, number | string> = {};\n columns.forEach(col => {\n if (row[col] !== undefined) {\n projectedRow[col] = row[col];\n }\n });\n return projectedRow;\n });\n}\n\nfunction query(sql: string, rows: Row[]): Row[] {\n const tokens = tokenize(sql);\n const [selectColumns, fromClause] = parseSelect(tokens);\n const [conditions, rest] = parseWhere(tokens);\n const [orderByColumn, order, limitClause] = parseOrderBy(tokens);\n const limit = parseLimit(tokens)[1];\n\n const filteredRows = rows.filter(row => evaluateWhere(conditions, row));\n const sortedRows = filteredRows.sort((a, b) => {\n const cellA = a[orderByColumn];\n const cellB = b[orderByColumn];\n if (typeof cellA === 'number' && typeof cellB === 'number') {\n return order === 'ASC' ? cellA - cellB : cellB - cellA;\n } else if (typeof cellA === 'string' && typeof cellB === 'string') {\n return order === 'ASC' ? cellA.localeCompare(cellB) : cellB.localeCompare(cellA);\n }\n return 0;\n });\n const limitedRows = limitRows(sortedRows, limit);\n return projectColumns(limitedRows, selectColumns);\n}\n\n// Example usage\nconst rows: Row[] = [\n { id: 1, name: \"alice\", age: 30 },\n { id: 2, name: \"bob\", age: 25 },\n { id: 3, name: \"carol\", age: 30 },\n { id: 4, name: \"dave\", age: 17 },\n];\n\nconsole.log(query(\"SELECT name, age FROM users WHERE age >= 18 ORDER BY age DESC LIMIT 2\", rows));\n// -> [ { name: \"alice\", age: 30 }, { name: \"carol\", age: 30 } ]\n```",
"passed": 0,
"test_error": ""
}
]System prompt
You are an expert programmer. Solve the task exactly as specified. Output your solution as fenced code blocks using the required file name(s) and the exact function/type signatures requested. Prefer correctness; do not include prose outside code unless asked.