UNPKG

rawsql-ts

Version:

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

83 lines 3.54 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.JoinClauseParser = void 0; const Clause_1 = require("../models/Clause"); const Lexeme_1 = require("../models/Lexeme"); const CommandTokenReader_1 = require("../tokenReaders/CommandTokenReader"); const SourceExpressionParser_1 = require("./SourceExpressionParser"); const JoinOnClauseParser_1 = require("./JoinOnClauseParser"); const JoinUsingClauseParser_1 = require("./JoinUsingClauseParser"); class JoinClauseParser { static tryParse(lexemes, index) { let idx = index; const joins = []; while (this.isJoinCommand(lexemes, idx)) { const joinClause = this.parseJoinClause(lexemes, idx); joins.push(joinClause.value); idx = joinClause.newIndex; } if (joins.length > 0) { return { value: joins, newIndex: idx }; } return null; } static isJoinKeyword(value) { // Although performance is not ideal, // we use keyword token reader to centralize keyword management const result = CommandTokenReader_1.joinkeywordParser.parse(value, 0); if (result) { return true; } return false; } static parseLateral(lexemes, index) { let idx = index; if (idx < lexemes.length && lexemes[idx].value === 'lateral') { // Skip 'lateral' keyword idx++; return { value: true, newIndex: idx }; } return { value: false, newIndex: idx }; } static isJoinCommand(lexemes, index) { if (index >= lexemes.length) { return false; } if (lexemes[index].type & Lexeme_1.TokenType.Comma || this.isJoinKeyword(lexemes[index].value) === true) { return true; } return false; } static parseJoinClause(lexemes, index) { let idx = index; // Get the join type const joinType = lexemes[idx].value === "," ? "cross join" : lexemes[idx].value; idx++; // Check for lateral join const lateralResult = this.parseLateral(lexemes, idx); const lateral = lateralResult.value; idx = lateralResult.newIndex; // Parse the source expression to join with const sourceResult = SourceExpressionParser_1.SourceExpressionParser.parseFromLexeme(lexemes, idx); idx = sourceResult.newIndex; if (idx < lexemes.length) { // JoinOnClauseParser const onResult = JoinOnClauseParser_1.JoinOnClauseParser.tryParse(lexemes, idx); if (onResult) { const joinClause = new Clause_1.JoinClause(joinType, sourceResult.value, onResult.value, lateral); return { value: joinClause, newIndex: onResult.newIndex }; } // JoinUsingClauseParser const usingResult = JoinUsingClauseParser_1.JoinUsingClauseParser.tryParse(lexemes, idx); if (usingResult) { const joinClause = new Clause_1.JoinClause(joinType, sourceResult.value, usingResult.value, lateral); return { value: joinClause, newIndex: usingResult.newIndex }; } } // If we reach the end of the input, we can treat it as a natural join const joinClause = new Clause_1.JoinClause(joinType, sourceResult.value, null, lateral); return { value: joinClause, newIndex: idx }; } } exports.JoinClauseParser = JoinClauseParser; //# sourceMappingURL=JoinClauseParser.js.map