import { CompareOptions } from './builder/types.js'; import { Collection, CollectionImpl } from '../collection/index.js'; import { NamespacedRow } from '../types.js'; export interface QueryIR { from: From; select?: Select; join?: Join; where?: Array; groupBy?: GroupBy; having?: Array; orderBy?: OrderBy; limit?: Limit; offset?: Offset; distinct?: true; singleResult?: true; fnSelect?: (row: NamespacedRow) => any; fnWhere?: Array<(row: NamespacedRow) => any>; fnHaving?: Array<(row: NamespacedRow) => any>; } export type IncludesMaterialization = `collection` | `array` | `concat`; export declare const INCLUDES_SCALAR_FIELD = "__includes_scalar__"; export type From = CollectionRef | QueryRef | UnionFrom | UnionAll; export type Select = { [alias: string]: BasicExpression | Aggregate | Select | IncludesSubquery | ConditionalSelect; }; export type Join = Array; export interface JoinClause { from: CollectionRef | QueryRef; type: `left` | `right` | `inner` | `outer` | `full` | `cross`; left: BasicExpression; right: BasicExpression; } export type Where = BasicExpression | { expression: BasicExpression; residual?: boolean; }; export type GroupBy = Array; export type Having = Where; export type OrderBy = Array; export type OrderByClause = { expression: BasicExpression; compareOptions: CompareOptions; }; export type OrderByDirection = `asc` | `desc`; export type Limit = number; export type Offset = number; declare abstract class BaseExpression { abstract type: string; /** @internal - Type brand for TypeScript inference */ readonly __returnType: T; } export declare class CollectionRef extends BaseExpression { collection: CollectionImpl; alias: string; type: "collectionRef"; constructor(collection: CollectionImpl, alias: string); } export declare class QueryRef extends BaseExpression { query: QueryIR; alias: string; type: "queryRef"; constructor(query: QueryIR, alias: string); } export declare class UnionFrom extends BaseExpression { sources: Array; type: "unionFrom"; constructor(sources: Array); get alias(): string; } export declare class UnionAll extends BaseExpression { queries: Array; type: "unionAll"; /** * Result-level UNION ALL. Downstream query clauses see the union result row * shape, not the branch source aliases. Optimizers may push safe operations * into branches, but compiler phases should treat this as a derived relation * unless they are explicitly handling branch lowering. */ constructor(queries: Array); get alias(): string; } export declare class PropRef extends BaseExpression { path: Array; type: "ref"; constructor(path: Array); } export declare class Value extends BaseExpression { value: T; type: "val"; constructor(value: T); } export declare class Func extends BaseExpression { name: string; args: Array; type: "func"; constructor(name: string, // such as eq, gt, lt, upper, lower, etc. args: Array); } export type BasicExpression = PropRef | Value | Func; export declare class Aggregate extends BaseExpression { name: string; args: Array; type: "agg"; constructor(name: string, // such as count, avg, sum, min, max, etc. args: Array); } export declare class IncludesSubquery extends BaseExpression { query: QueryIR; correlationField: PropRef; childCorrelationField: PropRef; fieldName: string; parentFilters?: Array | undefined; parentProjection?: Array | undefined; materialization: IncludesMaterialization; scalarField?: string | undefined; type: "includesSubquery"; constructor(query: QueryIR, // Child query (correlation WHERE removed) correlationField: PropRef, // Parent-side ref (e.g., project.id) childCorrelationField: PropRef, // Child-side ref (e.g., issue.projectId) fieldName: string, // Result field name (e.g., "issues") parentFilters?: Array | undefined, // WHERE clauses referencing parent aliases (applied post-join) parentProjection?: Array | undefined, // Parent field refs used by parentFilters materialization?: IncludesMaterialization, scalarField?: string | undefined); } export type ConditionalSelectBranch = { condition: BasicExpression; value: SelectValueExpression; }; export type SelectValueExpression = BasicExpression | Aggregate | Select | IncludesSubquery | ConditionalSelect; export declare class ConditionalSelect extends BaseExpression { branches: Array; defaultValue?: SelectValueExpression | undefined; type: "conditionalSelect"; constructor(branches: Array, defaultValue?: SelectValueExpression | undefined); } /** * Runtime helper to detect IR expression-like objects. * Prefer this over ad-hoc local implementations to keep behavior consistent. */ export declare function isExpressionLike(value: any): boolean; /** * Helper functions for working with Where clauses */ /** * Extract the expression from a Where clause */ export declare function getWhereExpression(where: Where): BasicExpression; /** * Extract the expression from a HAVING clause * HAVING clauses can contain aggregates, unlike regular WHERE clauses */ export declare function getHavingExpression(having: Having): BasicExpression | Aggregate; /** * Check if a Where clause is marked as residual */ export declare function isResidualWhere(where: Where): boolean; /** * Create a residual Where clause from an expression */ export declare function createResidualWhere(expression: BasicExpression): Where; /** * Follows the given reference in a query * until its finds the root field the reference points to. * @returns The collection, its alias, and the path to the root field in this collection */ export declare function followRef(query: QueryIR, ref: PropRef, collection: Collection): { collection: Collection; path: Array; } | void; export {};