import type { Expr, Sampling, AtomicTypeDef, MeasureTimeExpr, TimeTruncExpr, TimeExtractExpr, TimeDeltaExpr, TypecastExpr, RegexMatchExpr, TimeLiteralNode, RecordLiteralNode, ArrayLiteralNode, BasicAtomicTypeDef, OrderBy } from '../model/malloy_types'; import type { DialectFunctionOverloadDef } from './functions'; interface DialectField { typeDef: AtomicTypeDef; sqlExpression: string; rawName: string; sqlOutputName: string; } export type DialectFieldList = DialectField[]; /** * Data which dialect methods need in order to correctly generate SQL. * Initially this is just timezone related, but I made this an interface * so it would be extensible with other useful information which might not be * available until runtime (e.g. version number of db) * mtoy TODO rename this interface to something other than "QueryInfo" */ export interface QueryInfo { queryTimezone?: string; systemTimezone?: string; } export type FieldReferenceType = 'table' | 'nest source' | 'array[scalar]' | 'array[record]' | 'record'; export declare const dayIndex: number; export declare function inDays(units: string): boolean; export declare function qtz(qi: QueryInfo): string | undefined; export type OrderByClauseType = 'output_name' | 'ordinal' | 'expression'; export type OrderByRequest = 'query' | 'turtle' | 'analytical'; export type BooleanTypeSupport = 'supported' | 'simulated' | 'none'; export declare abstract class Dialect { abstract name: string; abstract defaultNumberType: string; abstract defaultDecimalType: string; abstract udfPrefix: string; abstract hasFinalStage: boolean; abstract divisionIsInteger: boolean; abstract supportsSumDistinctFunction: boolean; abstract unnestWithNumbers: boolean; abstract defaultSampling: Sampling; abstract supportsAggDistinct: boolean; abstract supportUnnestArrayAgg: boolean; abstract supportsCTEinCoorelatedSubQueries: boolean; abstract dontUnionIndex: boolean; abstract supportsQualify: boolean; abstract supportsSafeCast: boolean; abstract supportsNesting: boolean; abstract experimental: boolean; cantPartitionWindowFunctionsOnExpressions: boolean; supportsPipelinesInViews: boolean; supportsArraysInData: boolean; readsNestedData: boolean; orderByClause: OrderByClauseType; nullMatchesFunctionSignature: boolean; supportsSelectReplace: boolean; supportsComplexFilteredSources: boolean; supportsTempTables: boolean; hasModOperator: boolean; supportsLeftJoinUnnest: boolean; supportsCountApprox: boolean; supportsHyperLogLog: boolean; supportsFullJoin: boolean; nestedArrays: boolean; compoundObjectInSchema: boolean; booleanType: BooleanTypeSupport; likeEscape: boolean; abstract getDialectFunctionOverrides(): { [name: string]: DialectFunctionOverloadDef[]; }; abstract getDialectFunctions(): { [name: string]: DialectFunctionOverloadDef[]; }; abstract quoteTablePath(tablePath: string): string; abstract sqlGroupSetTable(groupSetCount: number): string; abstract sqlAnyValue(groupSet: number, fieldName: string): string; abstract sqlAggregateTurtle(groupSet: number, fieldList: DialectFieldList, orderBy: string | undefined): string; abstract sqlAnyValueTurtle(groupSet: number, fieldList: DialectFieldList): string; abstract sqlAnyValueLastTurtle(name: string, groupSet: number, sqlName: string): string; abstract sqlCoaleseMeasuresInline(groupSet: number, fieldList: DialectFieldList): string; abstract sqlUnnestAlias(source: string, alias: string, fieldList: DialectFieldList, needDistinctKey: boolean, isArray: boolean, isInNestedPipeline: boolean): string; abstract sqlSumDistinctHashedKey(sqlDistinctKey: string): string; abstract sqlGenerateUUID(): string; abstract sqlFieldReference(parentAlias: string, parentType: FieldReferenceType, childName: string, childType: string): string; abstract sqlUnnestPipelineHead(isSingleton: boolean, sourceSQLExpression: string, fieldList?: DialectFieldList): string; abstract sqlCreateFunction(id: string, funcText: string): string; abstract sqlCreateFunctionCombineLastStage(lastStageName: string, fieldList: DialectFieldList, orderBy: OrderBy[] | undefined): string; abstract sqlCreateTableAsSelect(tableName: string, sql: string): string; abstract sqlSelectAliasAsStruct(alias: string, fieldList: DialectFieldList): string; sqlFinalStage(_lastStageName: string, _fields: string[]): string; sqlDateToString(sqlDateExp: string): string; abstract sqlMaybeQuoteIdentifier(identifier: string): string; abstract castToString(expression: string): string; abstract concat(...values: string[]): string; sqlLiteralNumber(literal: string): string; ignoreInProject(_fieldName: string): boolean; abstract sqlNowExpr(): string; abstract sqlTruncExpr(qi: QueryInfo, toTrunc: TimeTruncExpr): string; abstract sqlTimeExtractExpr(qi: QueryInfo, xFrom: TimeExtractExpr): string; abstract sqlMeasureTimeExpr(e: MeasureTimeExpr): string; abstract sqlAlterTimeExpr(df: TimeDeltaExpr): string; abstract sqlCast(qi: QueryInfo, cast: TypecastExpr): string; abstract sqlRegexpMatch(df: RegexMatchExpr): string; abstract sqlLiteralTime(qi: QueryInfo, df: TimeLiteralNode): string; abstract sqlLiteralString(literal: string): string; abstract sqlLiteralRegexp(literal: string): string; abstract sqlLiteralArray(lit: ArrayLiteralNode): string; abstract sqlLiteralRecord(lit: RecordLiteralNode): string; /** * The dialect has a chance to over-ride how expressions are translated. If * "undefined" is returned then the translation is left to the query translator. * * Any child nodes of the expression will already have been translated, and * the translated value will be in the ".sql" fields for those nodes * @param qi Info from the query containing this expression * @param df The expression being translated * @returns The SQL translation of the expression, or undefined */ exprToSQL(qi: QueryInfo, df: Expr): string | undefined; sqlSumDistinct(_key: string, _value: string, _funcName: string): string; sqlAggDistinct(_key: string, _values: string[], _func: (valNames: string[]) => string): string; sqlSampleTable(tableSQL: string, sample: Sampling | undefined): string; /** * MySQL is NULLs first, all other dialects have a way to make NULLs last. * isBaseOrdering is a hack to allow the MySQL dialect to partially implement * NULLs last, but should go away once MySQL fully implements NULLs last. */ sqlOrderBy(orderTerms: string[], _orderFor?: OrderByRequest): string; sqlTzStr(qi: QueryInfo): string; sqlMakeUnnestKey(key: string, rowKey: string): string; sqlStringAggDistinct(distinctKey: string, valueSQL: string, separatorSQL: string): string; abstract sqlTypeToMalloyType(sqlType: string): BasicAtomicTypeDef; abstract malloyTypeToSQLType(malloyType: AtomicTypeDef): string; abstract validateTypeName(sqlType: string): boolean; /** * Helper function for sql cast implementations. Handles the * wrangling of the raw type and also inferring the source * type if it was not provided. */ sqlCastPrep(cast: TypecastExpr): { op: string; srcTypeDef: BasicAtomicTypeDef | undefined; dstTypeDef: BasicAtomicTypeDef | undefined; dstSQLType: string; }; /** * Write a LIKE expression. Malloy like strings are escaped with \\% and \\_ * but some SQL dialects use an ESCAPE clause. */ sqlLike(likeOp: 'LIKE' | 'NOT LIKE', left: string, likeStr: string): string; /** * SQL to generate to get a boolean value for a boolean expression */ sqlBoolean(bv: boolean): string; /** * What a boolean value looks like in a query result */ resultBoolean(bv: boolean): boolean | 0 | 1; } export {};