UNPKG

rawsql-ts

Version:

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

79 lines 3.25 kB
import { JoinClause } from "../models/Clause"; import { TokenType } from "../models/Lexeme"; import { joinkeywordParser } from "../tokenReaders/CommandTokenReader"; import { SourceExpressionParser } from "./SourceExpressionParser"; import { JoinOnClauseParser } from "./JoinOnClauseParser"; import { JoinUsingClauseParser } from "./JoinUsingClauseParser"; export 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 = 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 & 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.parseFromLexeme(lexemes, idx); idx = sourceResult.newIndex; if (idx < lexemes.length) { // JoinOnClauseParser const onResult = JoinOnClauseParser.tryParse(lexemes, idx); if (onResult) { const joinClause = new JoinClause(joinType, sourceResult.value, onResult.value, lateral); return { value: joinClause, newIndex: onResult.newIndex }; } // JoinUsingClauseParser const usingResult = JoinUsingClauseParser.tryParse(lexemes, idx); if (usingResult) { const joinClause = new 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 JoinClause(joinType, sourceResult.value, null, lateral); return { value: joinClause, newIndex: idx }; } } //# sourceMappingURL=JoinClauseParser.js.map