compile method

  1. @override
String compile(
  1. MssqlParameterAllocator parameters,
  2. MssqlDialect dialect
)
override

Writes this expression's SQL, binding any values through parameters.

Implementation

@override
String compile(MssqlParameterAllocator parameters, MssqlDialect dialect) {
  if (!function.ranking) {
    dialect.require(
      dialect.supportsWindowOffsetFunctions,
      feature: '${function.sql}()',
      requires:
          'SQL Server 2012 or newer, at database compatibility level 110 '
          'or higher. An older target reads the neighbouring row by joining '
          'the table to itself on a ROW_NUMBER() column, which is a '
          'different query rather than a translation of this one',
    );
  }
  if (window.orderBy.isEmpty) {
    throw StateError(
      '${function.sql}() needs an ordered window: without orderBy the '
      'result depends on the order rows happen to arrive in, so two runs '
      'of the same query can disagree. Pass '
      'MssqlWindow(orderBy: [...]).',
    );
  }
  if (function.ranking && window.frame != null) {
    throw StateError(
      '${function.sql}() takes no frame; SQL Server rejects one. A ranking '
      'function reads the whole partition by definition, so drop the frame '
      'from the window it is given.',
    );
  }
  final compiled = <String>[
    ...arguments.map((a) => a.compile(parameters, dialect)),
  ];
  // LAG's optional default follows its offset, so the rendered integers go
  // between the first expression and the rest.
  final rendered = switch (compiled.length) {
    0 => literalSuffix,
    1 => '${compiled.first}$literalSuffix',
    _ => '${compiled.first}$literalSuffix, ${compiled.last}',
  };
  return '${function.sql}($rendered) OVER '
      '(${window.compile(parameters, dialect)})';
}