UNPKG

rhombic

Version:

SQL parsing, lineage extraction and manipulation

90 lines 4.27 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FilterTreeVisitor = void 0; const SqlParser_1 = require("../SqlParser"); const FilterTree_1 = require("../FilterTree"); const getImageFromChildren_1 = require("../utils/getImageFromChildren"); const booleanExpression_1 = require("../utils/booleanExpression"); const booleanExpressionValue_1 = require("../utils/booleanExpressionValue"); const Visitor = SqlParser_1.parser.getBaseCstVisitorConstructorWithDefaults(); /** * Visitor to extract filter tree on the `WHERE` statement */ class FilterTreeVisitor extends Visitor { constructor() { super(...arguments); this.tree = [{ type: "operator", closeParentheses: [], openParentheses: [] }]; this.parenthesisCount = 0; this.parenthesisToClose = []; } getOperator(expressionValue) { if (booleanExpressionValue_1.isBinaryOperation(expressionValue)) { return expressionValue.BinaryOperator[0].image.toLowerCase(); } if (booleanExpressionValue_1.isMultivalOperation(expressionValue)) { return expressionValue.MultivalOperator[0].image.toLowerCase(); } if (booleanExpressionValue_1.isUnaryOperation(expressionValue) && expressionValue.IsNotNull) { return expressionValue.IsNotNull[0].image.toLowerCase(); } if (booleanExpressionValue_1.isUnaryOperation(expressionValue) && expressionValue.IsNull) { return expressionValue.IsNull[0].image.toLowerCase(); } return "="; // This is just to make typescript happy, this case is not possible with the actual grammar } getValue(expressionValue) { if (booleanExpressionValue_1.isBinaryOperation(expressionValue)) { return getImageFromChildren_1.getImageFromChildren(expressionValue.valueExpression[0].children); } if (booleanExpressionValue_1.isMultivalOperation(expressionValue)) { return expressionValue.valueExpression.map(i => getImageFromChildren_1.getImageFromChildren(i.children)).join(", "); } return undefined; } booleanExpression(ctx) { if (booleanExpression_1.isParenthesesContext(ctx)) { // Flag open parenthese const startOperatorNode = this.tree[this.tree.length - 1]; if (FilterTree_1.isOperator(startOperatorNode)) { this.parenthesisToClose.push(this.parenthesisCount); startOperatorNode.openParentheses.unshift(this.parenthesisCount++); } // Visit inside this.booleanExpression(ctx.booleanExpression[0].children); // Flag close parenthese const endOperatorNode = this.tree[this.tree.length - 1]; if (FilterTree_1.isOperator(endOperatorNode)) { endOperatorNode.closeParentheses.push(this.parenthesisToClose.shift() || 0); } } else { // Add predicate + operator on each value ctx.booleanExpressionValue.forEach(predicate => { if (!booleanExpressionValue_1.hasColumnPrimary(predicate.children)) return; this.tree.push({ type: "predicate", dimension: predicate.children.columnPrimary[0].children.Identifier.map(i => i.image).join("."), operator: this.getOperator(predicate.children), value: this.getValue(predicate.children) }); this.tree.push({ type: "operator", openParentheses: [], closeParentheses: [] }); }); } // Deal with `AND`/`OR` if (booleanExpression_1.isAndOrContext(ctx)) { const lastOperatorNode = this.tree[this.tree.length - 1]; if (FilterTree_1.isOperator(lastOperatorNode)) { lastOperatorNode.operator = ctx.Or ? "or" : "and"; } // Visit alternative node this.booleanExpression(ctx.booleanExpression[ctx.booleanExpression.length - 1].children); } } } exports.FilterTreeVisitor = FilterTreeVisitor; //# sourceMappingURL=FilterTreeVisitor.js.map