rhombic
Version:
SQL parsing, lineage extraction and manipulation
171 lines • 7.15 kB
TypeScript
import { EdgeType } from "../Lineage";
import { SqlBaseVisitor } from "./SqlBaseVisitor";
import { AbstractParseTreeVisitor } from "antlr4ts/tree/AbstractParseTreeVisitor";
import { Range } from "../utils/getRange";
import { ColumnRef, QuotableIdentifier } from "./common";
import { ParserRuleContext } from "antlr4ts";
import { AliasedQueryContext, ColumnReferenceContext, DereferenceContext, ExistsContext, ExpressionContext, FromClauseContext, FunctionCallContext, GroupByClauseContext, HavingClauseContext, JoinCriteriaUsingContext, NamedExpressionContext, NamedQueryContext, PredicateContext, PrimaryExpressionContext, QueryContext, QueryOrganizationContext, QueryTermDefaultContext, RegularQuerySpecificationContext, SelectClauseContext, SortItemContext, SubqueryExpressionContext, TableNameContext, WhereClauseContext } from "./SqlBaseParser";
import { TablePrimary } from "..";
export declare const ROOT_QUERY_NAME = "[final result]";
export declare class Column {
readonly id: string;
label: string;
readonly range?: Range | undefined;
readonly data?: unknown;
readonly isAssumed?: boolean | undefined;
readonly columnReferences: Array<ColumnRef>;
constructor(id: string, label: string, range?: Range | undefined, data?: unknown, isAssumed?: boolean | undefined);
}
/**
* Base relation class representing any relation in query: query itself, subquery, source table, CTE
*/
export declare abstract class Relation {
readonly id: string;
readonly columns: Array<Column>;
readonly parent?: QueryRelation | undefined;
readonly range?: Range | undefined;
constructor(id: string, columns: Array<Column>, parent?: QueryRelation | undefined, range?: Range | undefined);
findColumn(columnName: QuotableIdentifier): Column | undefined;
resolveColumn(columnName: QuotableIdentifier): ColumnRef | undefined;
}
/**
* Relation representing source table.
*/
export declare class TableRelation extends Relation {
readonly tablePrimary: TablePrimary;
readonly isFetched: boolean;
readonly data?: unknown;
constructor(id: string, tablePrimary: TablePrimary, columns: Array<Column>, isFetched: boolean, parent?: QueryRelation, range?: Range, data?: unknown);
addAssumedColumn(columnName: QuotableIdentifier, range: Range): ColumnRef;
}
/**
* Relation representing (sub-)query.
*/
export declare class QueryRelation extends Relation {
ctes: Map<string, QueryRelation>;
relations: Map<string, Relation>;
columnIdSeq: number;
currentClause?: EdgeType;
currentColumnId?: string;
columnReferences: Array<ColumnRef>;
constructor(id: string, parent?: QueryRelation, range?: Range);
findLocalRelation(tableName: QuotableIdentifier): Relation | undefined;
findRelation(tableName: QuotableIdentifier): Relation | undefined;
findCTE(tableName: QuotableIdentifier): Relation | undefined;
getCTENames(): string[];
resolveOrAssumeRelationColumn(columnName: QuotableIdentifier, range: Range, tableName?: QuotableIdentifier): ColumnRef | undefined;
getNextColumnId(): string;
}
/**
* Visitor to extract query structure in the sense of relations, columns and used relations/columns.
* This extraction builds a tree of contexts corresponding to (sub-)queries, resolves all column
* references and for each (sub-)query and source table reports separate relation with #onRelation()
* handler. For column/table used when building particular relation it reports the reference with
* #onColumnReference() handler.
*/
export declare abstract class QueryStructureVisitor<Result> extends AbstractParseTreeVisitor<Result> implements SqlBaseVisitor<Result> {
getTable: (table: TablePrimary) => {
table: {
id: string;
data: unknown;
};
columns: {
id: string;
data: unknown;
}[];
} | undefined;
readonly options?: {
positionalRefsEnabled?: boolean | undefined;
} | undefined;
private relationSeq;
lastRelation: QueryRelation | undefined;
protected currentRelation: QueryRelation;
constructor(getTable: (table: TablePrimary) => {
table: {
id: string;
data: unknown;
};
columns: {
id: string;
data: unknown;
}[];
} | undefined, options?: {
positionalRefsEnabled?: boolean | undefined;
} | undefined);
getNextRelationId(): string;
rangeFromContext(ctx: ParserRuleContext): Range;
/**
* Extracts table and column names from PrimaryExpressionContext (if possible).
*/
protected extractTableAndColumn(ctx: PrimaryExpressionContext): {
table?: QuotableIdentifier;
column: QuotableIdentifier;
} | undefined;
private asPrimaryExpression;
/**
* Derives column name from expression if possible.
*/
protected deriveColumnName(ctx: ExpressionContext): string | undefined;
/**
* Called when relation is ready.
* @param _relation
* @param _alias
* @returns
*/
onRelation(_relation: TableRelation | QueryRelation, _alias?: string): void;
private reportTableReferences;
/**
* Called when column reference is ready.
* @param _tableId
* @param _columnId
* @returns
*/
onColumnReference(_tableId: string, _columnId?: string): void;
/**
* Determines whether expression is a star.
*/
private isStar;
private processStar;
private addRelationColumns;
private processClause;
visitQuery(ctx: QueryContext): Result;
/**
* Processing set operations.
*/
visitQueryTermDefault(ctx: QueryTermDefaultContext): Result;
visitRegularQuerySpecification(ctx: RegularQuerySpecificationContext): Result;
/**
* Process JOIN ... USING (...) columns
* @param ctx
*/
visitJoinCriteriaUsing(ctx: JoinCriteriaUsingContext): Result;
visitTableName(ctx: TableNameContext): Result;
visitNamedQuery(ctx: NamedQueryContext): Result;
visitAliasedQuery(ctx: AliasedQueryContext): Result;
visitSelectClause(ctx: SelectClauseContext): Result;
visitFromClause(ctx: FromClauseContext): Result;
visitWhereClause(ctx: WhereClauseContext): Result;
visitGroupByClause(ctx: GroupByClauseContext): Result;
visitHavingClause(ctx: HavingClauseContext): Result;
visitQueryOrganization(ctx: QueryOrganizationContext): Result;
/**
* Handle subquery in EXISTS.
* @param ctx
* @returns
*/
visitExists(ctx: ExistsContext): Result;
/**
* Handle subquery in IN predicate.
* @param ctx
* @returns
*/
visitPredicate(ctx: PredicateContext): Result;
visitNamedExpression(ctx: NamedExpressionContext): Result;
visitSubqueryExpression(ctx: SubqueryExpressionContext): Result;
visitFunctionCall(ctx: FunctionCallContext): Result;
visitSortItem(ctx: SortItemContext): Result;
private processColumnReference;
visitColumnReference(ctx: ColumnReferenceContext): Result;
visitDereference(ctx: DereferenceContext): Result;
}
//# sourceMappingURL=QueryStructureVisitor.d.ts.map