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