UNPKG

@uwdata/mosaic-sql

Version:

SQL query construction and analysis.

194 lines 6.16 kB
import { WINDOW, WINDOW_CLAUSE, WINDOW_DEF, WINDOW_FUNCTION } from '../constants.js'; import { nodeList } from '../util/function.js'; import { quoteIdentifier } from '../util/string.js'; import { ExprNode, SQLNode } from './node.js'; export class WindowClauseNode extends SQLNode { /** The window name. */ name; /** The window definition. */ def; /** * Instantiate a window clause node. * @param name The window name. * @param def The window definition. */ constructor(name, def) { super(WINDOW_CLAUSE); this.name = name; this.def = def; } /** * Generate a SQL query string for this node. */ toString() { return `${quoteIdentifier(this.name)} AS ${this.def}`; } } export class WindowNode extends ExprNode { func; def; /** * Instantiate a window node. * @param func The window function call. * @param over The window definition or name. */ constructor(func, over = new WindowDefNode()) { super(WINDOW); this.func = func; this.def = over; } /** * Return an updated window over a named window definition. * @param name The window definition name. * @returns A new window node. */ over(name) { return new WindowNode(this.func, this.def.over(name)); } /** * Return an updated window with the given partitions. * @param expr The partition by criteria. * @returns A new window node. */ partitionby(...expr) { return new WindowNode(this.func, this.def.partitionby(...expr)); } /** * Return an updated window with the given ordering. * @param expr The order by criteria. * @returns A new window node. */ orderby(...expr) { return new WindowNode(this.func, this.def.orderby(...expr)); } /** * Return an updated window with the given frame definition. * @param framedef The frame definition. * @returns A new window node. */ frame(framedef) { return new WindowNode(this.func, this.def.frame(framedef)); } /** * Generate a SQL query string for this node. */ toString() { return `${this.func} OVER ${this.def}`; } } export class WindowFunctionNode extends ExprNode { /** The window function name. */ name; /** The window function arguments. */ args; /** Flag to ignore null values. */ ignoreNulls; /** Order by expression for window arguments. */ order; /** * Instantiate a window function call node. * @param name The window function name. * @param args The window function arguments. * @param ignoreNulls Flag to ignore null values. * @param argOrder Order expressions for window arguments. * Note that this argument ordering is distinct from the window ordering. */ constructor(name, args = [], ignoreNulls = false, argOrder = []) { super(WINDOW_FUNCTION); this.name = name; this.args = args; this.ignoreNulls = ignoreNulls; this.order = nodeList([argOrder]); } /** * Generate a SQL query string for this node. */ toString() { const { name, args, ignoreNulls, order } = this; const arg = [ args.join(', '), order.length ? `ORDER BY ${order.join(', ')}` : '', ignoreNulls ? 'IGNORE NULLS' : '' ].filter(x => x).join(' '); return `${name}(${arg})`; } } export class WindowDefNode extends SQLNode { /** The base window definition name. */ name; /** The partition by criteria. */ partition; /** The order by criteria. */ order; /** The window frame definition. */ framedef; /** * Instantiate a window definition node. * @param name The base window definition name. * @param partition The partition by criteria. * @param order The order by criteria. * @param framedef The window frame definition. */ constructor(name, partition, order, framedef) { super(WINDOW_DEF); this.name = name; this.partition = partition; this.order = order; this.framedef = framedef; } /** * Return an updated window definition with the given base name. * @param name The base window definition name. * @returns A new window definition node. */ over(name) { return deriveDef(this, { name }); } /** * Return an updated window definition with the given partitions. * @param expr The partition by criteria. * @returns A new window definition node. */ partitionby(...expr) { return deriveDef(this, { partition: nodeList(expr) }); } /** * Return an updated window definition with the given ordering. * @param expr The order by criteria. * @returns A new window definition node. */ orderby(...expr) { return deriveDef(this, { order: nodeList(expr) }); } /** * Return an updated window definition with the given frame definition. * @param framedef The frame definition. * @return A new window definition node. */ frame(framedef) { return deriveDef(this, { framedef }); } /** * Generate a SQL query string for this node. */ toString() { const { name, partition, order, framedef } = this; const base = name && quoteIdentifier(name); const def = [ base, partition?.length && `PARTITION BY ${partition.join(', ')}`, order?.length && `ORDER BY ${order.join(', ')}`, framedef ].filter(x => x); return base && def.length < 2 ? base : `(${def.join(' ')})`; } } /** * Derive a new window definition node from an existing one. * @param def The existing window definition. * @param options An options object with new definition properties. */ function deriveDef(def, options) { return new WindowDefNode(options.name ?? def.name, options.partition ?? def.partition, options.order ?? def.order, options.framedef ?? def.framedef); } //# sourceMappingURL=window.js.map