UNPKG

rawsql-ts

Version:

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

57 lines 2.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WindowClauseParser = void 0; const Clause_1 = require("../models/Clause"); const Lexeme_1 = require("../models/Lexeme"); const SqlTokenizer_1 = require("./SqlTokenizer"); const WindowExpressionParser_1 = require("./WindowExpressionParser"); class WindowClauseParser { // Parse SQL string to AST (was: parse) static parse(query) { const tokenizer = new SqlTokenizer_1.SqlTokenizer(query); const lexemes = tokenizer.readLexmes(); const result = this.parseFromLexeme(lexemes, 0); if (result.newIndex < lexemes.length) { throw new Error(`Syntax error: Unexpected token "${lexemes[result.newIndex].value}" at position ${result.newIndex}. The WINDOW clause is complete but there are additional tokens.`); } return result.value; } // Parse from lexeme array (was: parse) static parseFromLexeme(lexemes, index) { let idx = index; if (lexemes[idx].value !== 'window') { throw new Error(`Syntax error at position ${idx}: Expected 'WINDOW' keyword but found "${lexemes[idx].value}". WINDOW clauses must start with the WINDOW keyword.`); } idx++; if (idx >= lexemes.length) { throw new Error(`Syntax error: Unexpected end of input after 'WINDOW' keyword. The WINDOW clause requires at least one window definition.`); } const windows = []; while (idx < lexemes.length) { if (idx >= lexemes.length || lexemes[idx].type !== Lexeme_1.TokenType.Identifier) { throw new Error(`Syntax error: Expected window name after 'WINDOW' keyword.`); } const name = lexemes[idx].value; idx++; if (idx >= lexemes.length || lexemes[idx].value !== 'as') { throw new Error(`Syntax error at position ${idx}: Expected 'AS' keyword after window name.`); } idx++; const expr = WindowExpressionParser_1.WindowExpressionParser.parseFromLexeme(lexemes, idx); idx = expr.newIndex; windows.push(new Clause_1.WindowFrameClause(name, expr.value)); if (idx < lexemes.length && lexemes[idx].type & Lexeme_1.TokenType.Comma) { idx++; } else { break; } } if (windows.length === 0) { throw new Error('At least one WINDOW clause is required after WINDOW keyword.'); } return { value: new Clause_1.WindowsClause(windows), newIndex: idx }; } } exports.WindowClauseParser = WindowClauseParser; //# sourceMappingURL=WindowClauseParser.js.map