Read neverError via getNodeParameter dot-path with explicit fallback
(true), matching the pattern used by HTTP Request node. Ensures the
option works for existing nodes where the collection entry is absent.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When enabled (default: true), SQL validation and execution errors are
returned as data instead of crashing the workflow. This lets the AI agent
see the error message and retry with corrected SQL.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a column name matched a table name (e.g. "employee"."department" where
"department" is also a table), the rewriter incorrectly replaced the column
with the physical table name, causing SQLITE_ERROR: no such column.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The PRAGMA was being set on the write pool connection while the SELECT
ran on the read pool — a different connection. Read-only is already
enforced at the connection level via SQLITE_OPEN_READONLY.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The closed-world validator allowed SQL keywords (INTO, FOR, UPDATE) to
pass as column names when a table had columns with those names. This
enabled write-oriented clauses like SELECT INTO and FOR UPDATE to bypass
validation.
All user-provided names (tables, columns, aliases) must now be
double-quoted. Unquoted identifiers can only be allowed function names
or CAST types, both validated against allowlists. This structurally
eliminates the entire class of keyword confusion attacks.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The SQL validator's closed-world identifier check rejected column aliases
(e.g. `SUM(amount) AS total_revenue ... ORDER BY total_revenue`) because
aliases were recognized at definition but never recorded for later reference.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
FROM-less queries (e.g. SELECT NOW()) bypassed table authorization entirely.
AS aliases in FROM broke comma-separated table extraction, leaving subsequent
table names unrewritten — which could resolve to internal DB tables.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace AST-based node-sql-parser validation with a custom tokenizer that
scans every character and validates every identifier against known tables,
columns, and functions. No aliases, no external parser dependency.
Security model:
- Every character must produce a recognized token
- First token must be SELECT, only one SELECT allowed
- Every identifier must be a known table, column, function, or cast type
- Table-qualified columns validated against schema
- CAST types validated only inside CAST() context
Also removes node-sql-parser dependency entirely and updates tool
description with explicit SQL format rules for the LLM.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace blocklist-based validation with a strict allowlist that verifies
every AST node against an explicit set of permitted types and operators.
Anything not explicitly recognized is rejected.
Restricted SQL subset for v1:
- No CTEs (WITH), no UNION, no subqueries, no derived tables
- No window functions (OVER clause)
- Only simple SELECT with JOINs, WHERE, GROUP BY, ORDER BY, LIMIT
- Every expression type, operator, and function must be in the allowlist
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tool nodes need both execute and supplyData methods — execute for standalone
usage (SQL passed via input items), supplyData for agent tool usage. Also adds
Main input so the node can receive data when not connected as a tool.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Fix eslint errors in sql-validator.ts (consistent-type-imports, no-unsafe-argument, unnecessary assertion)
- Fix existing proxy integration test to pass new DataTableSqlService constructor arg
- Fix node-param lint rules in tool node (displayName and description for dynamic multi-options)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>