import { SqlComponent } from "./SqlComponent";
import { ForClause, FromClause, GroupByClause, HavingClause, LimitClause, OrderByClause, SelectClause, SourceExpression, WhereClause, WindowsClause as WindowClause, WithClause, CommonTable, OffsetClause, FetchClause } from "./Clause";
import { ValueComponent, SqlParameterValue } from "./ValueComponent";
import { BinarySelectQuery } from "./BinarySelectQuery";
import type { SelectQuery, CTEOptions, CTEManagement, InsertQueryConversionOptions, UpdateQueryConversionOptions, DeleteQueryConversionOptions, MergeQueryConversionOptions } from "./SelectQuery";
import { TableColumnResolver } from "../transformers/TableColumnResolver";
import type { InsertQuery } from "./InsertQuery";
import type { UpdateQuery } from "./UpdateQuery";
import type { DeleteQuery } from "./DeleteQuery";
import type { MergeQuery } from "./MergeQuery";
/**
 * Represents a single SELECT statement with full clause support (WITH, JOIN, GROUP BY, etc.).
 * Provides the fluent CTE management API used throughout packages/core/tests/models/SelectQuery.cte-management.test.ts.
 *
 * @example
 * ```typescript
 * const query = SelectQueryParser.parse('SELECT id, email FROM users').toSimpleQuery();
 * const active = SelectQueryParser.parse('SELECT id FROM users WHERE active = true');
 *
 * query
 *   .addCTE('active_users', active)
 *   .toUnionAll(SelectQueryParser.parse('SELECT id, email FROM legacy_users'));
 * ```
 */
export declare class SimpleSelectQuery extends SqlComponent implements SelectQuery, CTEManagement {
    static kind: symbol;
    readonly __selectQueryType: 'SelectQuery';
    headerComments: string[] | null;
    withClause: WithClause | null;
    selectClause: SelectClause;
    fromClause: FromClause | null;
    whereClause: WhereClause | null;
    groupByClause: GroupByClause | null;
    havingClause: HavingClause | null;
    orderByClause: OrderByClause | null;
    windowClause: WindowClause | null;
    limitClause: LimitClause | null;
    offsetClause: OffsetClause | null;
    fetchClause: FetchClause | null;
    forClause: ForClause | null;
    private cteNameCache;
    constructor(params: {
        selectClause: SelectClause;
        fromClause?: FromClause | null;
        whereClause?: WhereClause | null;
        groupByClause?: GroupByClause | null;
        havingClause?: HavingClause | null;
        orderByClause?: OrderByClause | null;
        windowClause?: WindowClause | null;
        limitClause?: LimitClause | null;
        offsetClause?: OffsetClause | null;
        fetchClause?: FetchClause | null;
        forClause?: ForClause | null;
        withClause?: WithClause | null;
    });
    /**
     * Initializes the CTE name cache from existing withClause.
     * Called during construction and when withClause is modified externally.
     * @private
     */
    private initializeCTECache;
    /**
     * Creates a new BinarySelectQuery with this query as the left side and the provided query as the right side,
     * using UNION as the operator.
     *
     * @param rightQuery The right side of the UNION
     * @returns A new BinarySelectQuery representing "this UNION rightQuery"
     */
    toUnion(rightQuery: SelectQuery): BinarySelectQuery;
    /**
     * Creates a new BinarySelectQuery with this query as the left side and the provided query as the right side,
     * using UNION ALL as the operator.
     *
     * @param rightQuery The right side of the UNION ALL
     * @returns A new BinarySelectQuery representing "this UNION ALL rightQuery"
     */
    toUnionAll(rightQuery: SelectQuery): BinarySelectQuery;
    /**
     * Converts this query into an INSERT statement definition.
     * @remarks
     * Calling this method may reorder the current SELECT clause to match the requested column order.
     */
    toInsertQuery(options: InsertQueryConversionOptions): InsertQuery;
    /**
     * Converts this query into an UPDATE statement definition.
     * @remarks
     * The conversion may reorder the SELECT list so that primary keys and updated columns align with the target table.
     */
    toUpdateQuery(options: UpdateQueryConversionOptions): UpdateQuery;
    /**
     * Converts this query into a DELETE statement definition.
     * @remarks
     * The SELECT clause may be reordered to ensure primary keys and comparison columns appear first.
     */
    toDeleteQuery(options: DeleteQueryConversionOptions): DeleteQuery;
    /**
     * Converts this query into a MERGE statement definition.
     * @remarks
     * This method may reorder the SELECT clause to align with the specified MERGE column lists.
     */
    toMergeQuery(options: MergeQueryConversionOptions): MergeQuery;
    /**
     * Creates a new BinarySelectQuery with this query as the left side and the provided query as the right side,
     * using INTERSECT as the operator.
     *
     * @param rightQuery The right side of the INTERSECT
     * @returns A new BinarySelectQuery representing "this INTERSECT rightQuery"
     */
    toIntersect(rightQuery: SelectQuery): BinarySelectQuery;
    /**
     * Creates a new BinarySelectQuery with this query as the left side and the provided query as the right side,
     * using INTERSECT ALL as the operator.
     *
     * @param rightQuery The right side of the INTERSECT ALL
     * @returns A new BinarySelectQuery representing "this INTERSECT ALL rightQuery"
     */
    toIntersectAll(rightQuery: SelectQuery): BinarySelectQuery;
    /**
     * Creates a new BinarySelectQuery with this query as the left side and the provided query as the right side,
     * using EXCEPT as the operator.
     *
     * @param rightQuery The right side of the EXCEPT
     * @returns A new BinarySelectQuery representing "this EXCEPT rightQuery"
     */
    toExcept(rightQuery: SelectQuery): BinarySelectQuery;
    /**
     * Creates a new BinarySelectQuery with this query as the left side and the provided query as the right side,
     * using EXCEPT ALL as the operator.
     *
     * @param rightQuery The right side of the EXCEPT ALL
     * @returns A new BinarySelectQuery representing "this EXCEPT ALL rightQuery"
     */
    toExceptAll(rightQuery: SelectQuery): BinarySelectQuery;
    /**
     * Creates a new BinarySelectQuery with this query as the left side and the provided query as the right side,
     * using the specified operator.
     *
     * @param operator SQL operator to use (e.g. 'union', 'union all', 'intersect', 'except')
     * @param rightQuery The right side of the binary operation
     * @returns A new BinarySelectQuery representing "this [operator] rightQuery"
     */
    toBinaryQuery(operator: string, rightQuery: SelectQuery): BinarySelectQuery;
    /**
     * Appends a new condition to the query's WHERE clause using AND logic.
     * The condition is provided as a raw SQL string which is parsed internally.
     *
     * @param rawCondition Raw SQL string representing the condition (e.g. "status = 'active'")
     */
    appendWhereRaw(rawCondition: string): void;
    /**
     * Appends a new condition to the query's WHERE clause using AND logic.
     * The condition is provided as a ValueComponent object.
     *
     * @param condition ValueComponent representing the condition
     */
    appendWhere(condition: ValueComponent): void;
    /**
     * Appends a new condition to the query's HAVING clause using AND logic.
     * The condition is provided as a raw SQL string which is parsed internally.
     *
     * @param rawCondition Raw SQL string representing the condition (e.g. "count(*) > 5")
     */
    appendHavingRaw(rawCondition: string): void;
    /**
     * Appends a new condition to the query's HAVING clause using AND logic.
     * The condition is provided as a ValueComponent object.
     *
     * @param condition ValueComponent representing the condition
     */
    appendHaving(condition: ValueComponent): void;
    /**
     * Appends an INNER JOIN clause to the query.
     * @param joinSourceRawText The table source text to join (e.g., "my_table", "schema.my_table")
     * @param alias The alias for the joined table
     * @param columns The columns to use for the join condition (e.g. ["user_id"] or "user_id")
     */
    innerJoinRaw(joinSourceRawText: string, alias: string, columns: string | string[], resolver?: TableColumnResolver | null): void;
    /**
     * Appends a LEFT JOIN clause to the query.
     * @param joinSourceRawText The table source text to join
     * @param alias The alias for the joined table
     * @param columns The columns to use for the join condition
     */
    leftJoinRaw(joinSourceRawText: string, alias: string, columns: string | string[], resolver?: TableColumnResolver | null): void;
    /**
     * Appends a RIGHT JOIN clause to the query.
     * @param joinSourceRawText The table source text to join
     * @param alias The alias for the joined table
     * @param columns The columns to use for the join condition
     */
    rightJoinRaw(joinSourceRawText: string, alias: string, columns: string | string[], resolver?: TableColumnResolver | null): void;
    /**
     * Appends an INNER JOIN clause to the query using a SourceExpression.
     * @param sourceExpr The source expression to join
     * @param columns The columns to use for the join condition
     */
    innerJoin(sourceExpr: SourceExpression, columns: string | string[], resolver?: TableColumnResolver | null): void;
    /**
     * Appends a LEFT JOIN clause to the query using a SourceExpression.
     * @param sourceExpr The source expression to join
     * @param columns The columns to use for the join condition
     */
    leftJoin(sourceExpr: SourceExpression, columns: string | string[], resolver?: TableColumnResolver | null): void;
    /**
     * Appends a RIGHT JOIN clause to the query using a SourceExpression.
     * @param sourceExpr The source expression to join
     * @param columns The columns to use for the join condition
     */
    rightJoin(sourceExpr: SourceExpression, columns: string | string[], resolver?: TableColumnResolver | null): void;
    /**
     * Internal helper to append a JOIN clause.
     * Parses the table source, finds the corresponding columns in the existing query context,
     * and builds the JOIN condition.
     * @param joinType Type of join (e.g., 'inner join', 'left join')
     * @param joinSourceRawText Raw text for the table/source to join (e.g., "my_table", "schema.another_table")
     * @param alias Alias for the table/source being joined
     * @param columns Array or string of column names to join on
     */
    private joinSourceRaw;
    /**
     * Internal helper to append a JOIN clause using a SourceExpression.
     * @param joinType Type of join (e.g., 'inner join', 'left join')
     * @param sourceExpr The source expression to join
     * @param columns Array or string of column names to join on
     */
    private joinSource;
    toSource(alias: string): SourceExpression;
    appendWith(commonTable: CommonTable | CommonTable[]): void;
    /**
     * Appends a CommonTable (CTE) to the WITH clause from raw SQL text and alias.
     * If alias is provided, it will be used as the CTE name.
     *
     * @param rawText Raw SQL string representing the CTE body (e.g. '(SELECT ...)')
     * @param alias Optional alias for the CTE (e.g. 'cte_name')
     */
    appendWithRaw(rawText: string, alias: string): void;
    /**
     * Overrides a select item using a template literal function.
     * The callback receives the SQL string of the original expression and must return a new SQL string.
     * The result is parsed and set as the new select item value.
     *
     * Example usage:
     *   query.overrideSelectItemRaw("journal_date", expr => `greatest(${expr}, DATE '2025-01-01')`)
     *
     * @param columnName The name of the column to override
     * @param fn Callback that receives the SQL string of the original expression and returns a new SQL string
     */
    overrideSelectItemExpr(columnName: string, fn: (expr: string) => string): void;
    /**
     * Appends a WHERE clause using the expression for the specified column.
     * If `options.upstream` is true, applies to all upstream queries containing the column.
     * If false or omitted, applies only to the current query.
     *
     * @param columnName The name of the column to target.
     * @param exprBuilder Function that receives the column expression as a string and returns the WHERE condition string.
     * @param options Optional settings. If `upstream` is true, applies to upstream queries.
     */
    appendWhereExpr(columnName: string, exprBuilder: (expr: string) => string, options?: {
        upstream?: boolean;
    }): void;
    /**
     * Sets the value of a parameter by name in this query.
     * @param name Parameter name
     * @param value Value to set
     */
    setParameter(name: string, value: SqlParameterValue): this;
    /**
     * Returns this SimpleSelectQuery instance (identity function).
     * @returns This SimpleSelectQuery instance
     */
    toSimpleQuery(): SimpleSelectQuery;
    /**
     * Adds a CTE (Common Table Expression) to the query.
     *
     * @param name CTE name/alias (must be non-empty)
     * @param query SelectQuery to use as CTE
     * @param options Optional configuration
     * @param options.materialized PostgreSQL-specific: true = MATERIALIZED, false = NOT MATERIALIZED, null/undefined = no hint
     *
     * @throws {InvalidCTENameError} When name is empty or whitespace-only
     * @throws {DuplicateCTEError} When CTE with same name already exists
     *
     * @example
     * ```typescript
     * // Basic CTE
     * query.addCTE('active_users',
     *   SelectQueryParser.parse('SELECT * FROM users WHERE active = true')
     * );
     *
     * // PostgreSQL MATERIALIZED CTE (forces materialization)
     * query.addCTE('expensive_calc', expensiveQuery, { materialized: true });
     *
     * // PostgreSQL NOT MATERIALIZED CTE (prevents materialization)
     * query.addCTE('simple_view', simpleQuery, { materialized: false });
     * ```
     *
     * @remarks
     * - MATERIALIZED/NOT MATERIALIZED is PostgreSQL-specific syntax
     * - Other databases will ignore the materialized hint
     * - CTE names must be unique within the query
     * - Method supports fluent chaining
     */
    addCTE(name: string, query: SelectQuery, options?: CTEOptions): this;
    /**
     * Removes a CTE by name from the query.
     *
     * @param name CTE name to remove
     *
     * @throws {CTENotFoundError} When CTE with specified name doesn't exist
     *
     * @example
     * ```typescript
     * query.addCTE('temp_data', tempQuery);
     * query.removeCTE('temp_data'); // Removes the CTE
     *
     * // Throws CTENotFoundError
     * query.removeCTE('non_existent');
     * ```
     *
     * @remarks
     * - Throws error if CTE doesn't exist (strict mode for safety)
     * - Use hasCTE() to check existence before removal if needed
     * - Method supports fluent chaining
     */
    removeCTE(name: string): this;
    /**
     * Checks if a CTE with the given name exists in the query.
     * Optimized with O(1) lookup using internal cache.
     *
     * @param name CTE name to check
     * @returns true if CTE exists, false otherwise
     *
     * @example
     * ```typescript
     * query.addCTE('user_stats', statsQuery);
     *
     * if (query.hasCTE('user_stats')) {
     *   console.log('CTE exists');
     * }
     *
     * query.removeCTE('user_stats');
     * console.log(query.hasCTE('user_stats')); // false
     * ```
     *
     * @remarks
     * - Performs case-sensitive name matching
     * - Returns false for queries without any CTEs
     * - Useful for conditional CTE operations
     * - O(1) performance using internal cache
     */
    hasCTE(name: string): boolean;
    /**
     * Returns an array of all CTE names in the query.
     *
     * @returns Array of CTE names in the order they were defined
     *
     * @example
     * ```typescript
     * const query = SelectQueryParser.parse('SELECT * FROM data').toSimpleQuery();
     *
     * // Empty query
     * console.log(query.getCTENames()); // []
     *
     * // Add CTEs
     * query.addCTE('users', userQuery);
     * query.addCTE('orders', orderQuery);
     *
     * console.log(query.getCTENames()); // ['users', 'orders']
     *
     * // Use for validation
     * const expectedCTEs = ['users', 'orders', 'products'];
     * const actualCTEs = query.getCTENames();
     * const missingCTEs = expectedCTEs.filter(name => !actualCTEs.includes(name));
     * ```
     *
     * @remarks
     * - Returns empty array for queries without CTEs
     * - Names are returned in definition order
     * - Useful for debugging and validation
     * - Names reflect actual CTE aliases, not table references
     * - Performance: O(n) but avoids redundant array mapping
     */
    getCTENames(): string[];
    /**
     * Replaces an existing CTE or adds a new one with the given name.
     *
     * @param name CTE name to replace/add (must be non-empty)
     * @param query SelectQuery to use as CTE
     * @param options Optional configuration
     * @param options.materialized PostgreSQL-specific: true = MATERIALIZED, false = NOT MATERIALIZED, null/undefined = no hint
     *
     * @throws {InvalidCTENameError} When name is empty or whitespace-only
     *
     * @example
     * ```typescript
     * const query = SelectQueryParser.parse('SELECT * FROM final_data').toSimpleQuery();
     * const oldQuery = SelectQueryParser.parse('SELECT id FROM old_table');
     * const newQuery = SelectQueryParser.parse('SELECT id, status FROM new_table WHERE active = true');
     *
     * // Add initial CTE
     * query.addCTE('data_source', oldQuery);
     *
     * // Replace with improved version
     * query.replaceCTE('data_source', newQuery, { materialized: true });
     *
     * // Safe replacement - adds if doesn't exist
     * query.replaceCTE('new_cte', newQuery); // Won't throw error
     *
     * // Chaining replacements
     * query
     *   .replaceCTE('cte1', query1, { materialized: false })
     *   .replaceCTE('cte2', query2, { materialized: true });
     * ```
     *
     * @remarks
     * - Unlike addCTE(), this method won't throw error if CTE already exists
     * - Unlike removeCTE(), this method won't throw error if CTE doesn't exist
     * - Useful for upsert-style CTE operations
     * - MATERIALIZED/NOT MATERIALIZED is PostgreSQL-specific
     * - Method supports fluent chaining
     * - Maintains CTE order when replacing existing CTEs
     */
    replaceCTE(name: string, query: SelectQuery, options?: CTEOptions): this;
}
