UNPKG

rawsql-ts

Version:

High-performance SQL parser and AST analyzer written in TypeScript. Provides fast parsing and advanced transformation capabilities.

66 lines 2.5 kB
import { WhereClause } from "../models/Clause"; import { BinaryExpression, ParenExpression } from "../models/ValueComponent"; import { formatSqlComponent } from "./SqlComponentFormatter"; // API output shape review: this internal helper keeps optimizer result sql/query shape unchanged; // formatSqlComponent is used only as a caller-configurable canonical key for exact duplicate detection. const unwrapParens = (expression) => { let candidate = expression; while (candidate instanceof ParenExpression) { candidate = candidate.expression; } return candidate; }; const isAndExpression = (expression) => { const candidate = unwrapParens(expression); return candidate instanceof BinaryExpression && candidate.operator.value.trim().toLowerCase() === "and"; }; const collectTopLevelAndTerms = (expression) => { const candidate = unwrapParens(expression); if (!isAndExpression(candidate)) { return [expression]; } return [ ...collectTopLevelAndTerms(candidate.left), ...collectTopLevelAndTerms(candidate.right) ]; }; export const dedupeTopLevelAndConditionsWithMetadata = (expression, options) => { const terms = collectTopLevelAndTerms(expression); if (terms.length < 2) { return { expression, removedConditionSql: [] }; } const seen = new Set(); const uniqueTerms = []; const removedConditionSql = []; for (const term of terms) { const key = formatSqlComponent(unwrapParens(term), options); if (seen.has(key)) { removedConditionSql.push(key); continue; } seen.add(key); uniqueTerms.push(term); } if (uniqueTerms.length === terms.length) { return { expression, removedConditionSql: [] }; } let rebuilt = uniqueTerms[0]; for (let index = 1; index < uniqueTerms.length; index += 1) { rebuilt = new BinaryExpression(rebuilt, "and", uniqueTerms[index]); } return { expression: rebuilt, removedConditionSql }; }; export const dedupeTopLevelAndConditions = (expression, options) => { return dedupeTopLevelAndConditionsWithMetadata(expression, options).expression; }; export const dedupeWhereTopLevelAndConditions = (query, options) => { if (!query.whereClause) { return; } query.whereClause = new WhereClause(dedupeTopLevelAndConditions(query.whereClause.condition, options)); }; //# sourceMappingURL=TopLevelAndConditionDeduper.js.map