rhombic
Version:
SQL parsing, lineage extraction and manipulation
155 lines • 6.52 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ProjectionItemsVisitor = void 0;
const SqlParser_1 = require("../SqlParser");
const getImageFromChildren_1 = require("../utils/getImageFromChildren");
const getChildrenRange_1 = require("../utils/getChildrenRange");
const isCstNode_1 = require("../utils/isCstNode");
const projectionItem_1 = require("../utils/projectionItem");
const expression_1 = require("../utils/expression");
const Visitor = SqlParser_1.parser.getBaseCstVisitorConstructorWithDefaults();
function ifCastNode(node) {
return isCstNode_1.isCstNode(node) && node.name === "cast" ? node : null;
}
function ifColumnPrimaryNode(node) {
return isCstNode_1.isCstNode(node) && node.name === "columnPrimary" ? node : null;
}
function isExpressionContextColumnBranch(ctx) {
return Boolean(ctx.columnPrimary);
}
function getColumnPrimaryPath(columnPrimary) {
switch (columnPrimary.children.Identifier.length) {
case 1:
return { columnName: columnPrimary.children.Identifier[0].image };
case 2:
return {
tableName: columnPrimary.children.Identifier[0].image,
columnName: columnPrimary.children.Identifier[1].image
};
case 3:
return {
schemaName: columnPrimary.children.Identifier[0].image,
tableName: columnPrimary.children.Identifier[1].image,
columnName: columnPrimary.children.Identifier[2].image
};
case 4:
return {
catalogName: columnPrimary.children.Identifier[0].image,
schemaName: columnPrimary.children.Identifier[1].image,
tableName: columnPrimary.children.Identifier[2].image,
columnName: columnPrimary.children.Identifier[3].image
};
}
throw new Error("columnPrimary can't be parsed");
}
/**
* Visitor to extract `projectionItem` list
*/
class ProjectionItemsVisitor extends Visitor {
constructor() {
super();
this.output = [];
this.sort = [];
this.commas = [];
this.asteriskCount = 0;
this.validateVisitor();
}
projectionItems(ctx) {
if (ctx.Comma) {
this.commas.push(...ctx.Comma);
}
ctx.projectionItem.map(i => this.projectionItem(i.children));
}
cast(ctx) {
return {
value: getImageFromChildren_1.getImageFromChildren(ctx.expression[0].children),
type: getImageFromChildren_1.getImageFromChildren(ctx.type[0].children)
};
}
orderBy(ctx) {
this.sortRange = getChildrenRange_1.getChildrenRange(ctx);
ctx.orderItem.forEach(i => this.orderItem(i.children));
}
orderItem(ctx) {
const expression = getImageFromChildren_1.getImageFromChildren(ctx.expression[0].children);
const expressionRange = getChildrenRange_1.getChildrenRange(ctx.expression[0].children);
const sort = {};
if (ctx.Desc)
sort.order = "desc";
if (ctx.Asc)
sort.order = "asc";
if (ctx.First)
sort.nullsOrder = "first";
if (ctx.Last)
sort.nullsOrder = "last";
this.output = this.output.map(i => i.expression === expression || i.alias === expression
? Object.assign(Object.assign({}, i), { sort: Object.assign(Object.assign({}, sort), { order: sort.order || "asc" }) }) : i);
this.sort.push(Object.assign({ expression, expressionRange }, sort));
}
projectionItem(ctx) {
let isAsterisk = false;
let cast;
let fn;
let expression = "";
let path;
let alias;
if (projectionItem_1.isExpressionContext(ctx)) {
ctx.expression.forEach(i => {
// Extract `fn` information
if (expression_1.isFunctionContext(i.children)) {
fn = {
identifier: i.children.FunctionIdentifier[0].image,
values: i.children.expression.map(exp => ({
path: isExpressionContextColumnBranch(exp.children)
? getColumnPrimaryPath(exp.children.columnPrimary[0])
: undefined,
expression: getImageFromChildren_1.getImageFromChildren(exp.children)
}))
};
}
Object.values(i.children).forEach(j => {
// eslint-disable-next-line
j.map((token) => {
const castNode = ifCastNode(token);
if (castNode) {
cast = this.cast(castNode.children);
fn = {
identifier: castNode.children.Cast[0].image,
values: castNode.children.expression.map(exp => ({
path: isExpressionContextColumnBranch(exp.children)
? getColumnPrimaryPath(exp.children.columnPrimary[0])
: undefined,
expression: getImageFromChildren_1.getImageFromChildren(exp.children)
}))
};
}
const columnPrimary = ifColumnPrimaryNode(token);
if (columnPrimary) {
path = getColumnPrimaryPath(columnPrimary);
}
});
});
});
// Extract `expression`
expression = getImageFromChildren_1.getImageFromChildren(ctx.expression.reduce((mem, i) => (Object.assign({ mem }, i.children)), {}));
}
if (projectionItem_1.isAsteriskContext(ctx)) {
this.asteriskCount++;
isAsterisk = true;
}
if (projectionItem_1.isExpressionContext(ctx) && ctx.As && ctx.Identifier) {
alias = ctx.Identifier[ctx.Identifier.length - 1].image;
}
this.output.push({
range: getChildrenRange_1.getChildrenRange(ctx),
isAsterisk,
alias,
cast,
fn,
expression,
path
});
}
}
exports.ProjectionItemsVisitor = ProjectionItemsVisitor;
//# sourceMappingURL=ProjectionItemsVisitor.js.map