@malloydata/malloy 0.0.434 → 0.0.435

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/api/foundation/compile.d.ts +0 -1
  2. package/dist/api/foundation/compile.js +0 -3
  3. package/dist/api/foundation/runtime.d.ts +0 -1
  4. package/dist/api/foundation/runtime.js +1 -23
  5. package/dist/api/foundation/types.d.ts +0 -1
  6. package/dist/dialect/dialect.d.ts +14 -1
  7. package/dist/dialect/dialect.js +34 -2
  8. package/dist/dialect/dialect_map.js +2 -0
  9. package/dist/dialect/index.d.ts +2 -1
  10. package/dist/dialect/index.js +3 -1
  11. package/dist/dialect/sqlserver/dialect_functions.d.ts +2 -0
  12. package/dist/dialect/sqlserver/dialect_functions.js +42 -0
  13. package/dist/dialect/sqlserver/function_overrides.d.ts +2 -0
  14. package/dist/dialect/sqlserver/function_overrides.js +55 -0
  15. package/dist/dialect/sqlserver/index.d.ts +1 -0
  16. package/dist/dialect/sqlserver/index.js +22 -0
  17. package/dist/dialect/sqlserver/sqlserver.d.ts +102 -0
  18. package/dist/dialect/sqlserver/sqlserver.js +538 -0
  19. package/dist/dialect/sqlserver/windows_zones.d.ts +1 -0
  20. package/dist/dialect/sqlserver/windows_zones.js +613 -0
  21. package/dist/index.d.ts +1 -1
  22. package/dist/index.js +5 -3
  23. package/dist/lang/ast/source-elements/named-source.js +0 -2
  24. package/dist/lang/ast/source-elements/sql-source.js +0 -3
  25. package/dist/lang/ast/source-elements/table-source.js +1 -2
  26. package/dist/lang/ast/statements/import-statement.js +4 -0
  27. package/dist/lang/ast/types/malloy-element.d.ts +0 -7
  28. package/dist/lang/ast/types/malloy-element.js +0 -18
  29. package/dist/lang/parse-malloy.d.ts +17 -2
  30. package/dist/lang/parse-malloy.js +48 -14
  31. package/dist/lang/parse-tree-walkers/find-external-references.d.ts +3 -3
  32. package/dist/lang/parse-tree-walkers/find-external-references.js +17 -16
  33. package/dist/lang/test/test-translator.d.ts +10 -1
  34. package/dist/lang/test/test-translator.js +15 -1
  35. package/dist/model/expression_compiler.js +1 -1
  36. package/dist/model/query_query.d.ts +3 -1
  37. package/dist/model/query_query.js +157 -139
  38. package/dist/model/source_def_utils.d.ts +7 -1
  39. package/dist/model/source_def_utils.js +20 -0
  40. package/dist/test/index.js +16 -8
  41. package/dist/test/matchers.d.ts +1 -1
  42. package/dist/test/matchers.js +1 -1
  43. package/dist/test/test-models.js +6 -13
  44. package/dist/version.d.ts +1 -1
  45. package/dist/version.js +1 -1
  46. package/femto-config.motly +13 -1
  47. package/package.json +7 -5
@@ -35,7 +35,6 @@ export interface MalloyCompileOptions {
35
35
  noThrowOnError?: boolean;
36
36
  eventStream?: EventStream;
37
37
  importBaseURL?: URL;
38
- testEnvironment?: boolean;
39
38
  virtualMap?: VirtualMap;
40
39
  }
41
40
  export interface MalloyRunOptions {
@@ -88,9 +88,6 @@ class Malloy {
88
88
  const translator = new lang_1.MalloyTranslator(url.toString(), importBaseURL.toString(), {
89
89
  urls: { [url.toString()]: source },
90
90
  }, eventStream, (_a = options === null || options === void 0 ? void 0 : options.restrictedMode) !== null && _a !== void 0 ? _a : false);
91
- if (options === null || options === void 0 ? void 0 : options.testEnvironment) {
92
- translator.allDialectsEnabled = true;
93
- }
94
91
  return new document_1.Parse(translator, invalidationKey);
95
92
  }
96
93
  static parse({ url, urlReader, source, eventStream, options, }) {
@@ -42,7 +42,6 @@ declare class FluentState<T> {
42
42
  * An environment for compiling and running Malloy queries.
43
43
  */
44
44
  export declare class Runtime {
45
- isTestRuntime: boolean;
46
45
  private _urlReader;
47
46
  private _connections;
48
47
  private _eventStream;
@@ -51,7 +51,6 @@ class FluentState {
51
51
  class Runtime {
52
52
  constructor({ urlReader, connections, connection, config, buildManifest, eventStream, cacheManager, givens, }) {
53
53
  var _a, _b;
54
- this.isTestRuntime = false;
55
54
  if (config !== undefined) {
56
55
  this._config = config;
57
56
  connections = connections !== null && connections !== void 0 ? connections : config.connections;
@@ -350,14 +349,6 @@ class Runtime {
350
349
  */
351
350
  loadModel(source, options) {
352
351
  const { refreshSchemaCache, noThrowOnError } = options || {};
353
- if (this.isTestRuntime) {
354
- if (options === undefined) {
355
- options = { testEnvironment: true };
356
- }
357
- else {
358
- options = { ...options, testEnvironment: true };
359
- }
360
- }
361
352
  const compilable = source instanceof URL ? { url: source } : { source };
362
353
  return new ModelMaterializer(this, async () => {
363
354
  var _a;
@@ -369,7 +360,6 @@ class Runtime {
369
360
  noThrowOnError,
370
361
  eventStream: this.eventStream,
371
362
  importBaseURL: options === null || options === void 0 ? void 0 : options.importBaseURL,
372
- testEnvironment: options === null || options === void 0 ? void 0 : options.testEnvironment,
373
363
  cacheManager: this.cacheManager,
374
364
  virtualMap: (_a = options === null || options === void 0 ? void 0 : options.virtualMap) !== null && _a !== void 0 ? _a : this.virtualMap,
375
365
  });
@@ -631,7 +621,7 @@ class ModelMaterializer extends FluentState {
631
621
  // `restrictedMode` and `method` are named to hold them back: this entry
632
622
  // point has never honored them, and `loadRestrictedQuery` is how a caller
633
623
  // asks for restricted compilation.
634
- const { importBaseURL, testEnvironment, refreshSchemaCache, noThrowOnError, restrictedMode: _restrictedMode, method: _method, ...callQueryOptions } = options !== null && options !== void 0 ? options : {};
624
+ const { importBaseURL, refreshSchemaCache, noThrowOnError, restrictedMode: _restrictedMode, method: _method, ...callQueryOptions } = options !== null && options !== void 0 ? options : {};
635
625
  const compileQueryOptions = {
636
626
  ...this.compileQueryOptions,
637
627
  ...callQueryOptions,
@@ -647,7 +637,6 @@ class ModelMaterializer extends FluentState {
647
637
  refreshSchemaCache,
648
638
  noThrowOnError,
649
639
  importBaseURL,
650
- testEnvironment: testEnvironment || this.runtime.isTestRuntime,
651
640
  ...compileQueryOptions,
652
641
  virtualMap: (_a = compileQueryOptions.virtualMap) !== null && _a !== void 0 ? _a : this.runtime.virtualMap,
653
642
  });
@@ -701,7 +690,6 @@ class ModelMaterializer extends FluentState {
701
690
  return this.makeQueryMaterializer(async () => {
702
691
  const urlReader = this.runtime.urlReader;
703
692
  const connections = this.runtime.connections;
704
- const testEnvironment = this.runtime.isTestRuntime ? true : undefined;
705
693
  const model = await this.getModel();
706
694
  const queryModel = await compile_1.Malloy.compile({
707
695
  source: text,
@@ -710,7 +698,6 @@ class ModelMaterializer extends FluentState {
710
698
  urlReader,
711
699
  connections,
712
700
  model,
713
- testEnvironment,
714
701
  ...this.compileQueryOptions,
715
702
  });
716
703
  return queryModel.preparedQuery;
@@ -726,14 +713,6 @@ class ModelMaterializer extends FluentState {
726
713
  extendModel(query, options) {
727
714
  var _a, _b;
728
715
  const virtualMap = (_a = options === null || options === void 0 ? void 0 : options.virtualMap) !== null && _a !== void 0 ? _a : (_b = this.compileQueryOptions) === null || _b === void 0 ? void 0 : _b.virtualMap;
729
- if (this.runtime.isTestRuntime) {
730
- if (options === undefined) {
731
- options = { testEnvironment: true };
732
- }
733
- else {
734
- options = { ...options, testEnvironment: true };
735
- }
736
- }
737
716
  return new ModelMaterializer(this.runtime, async () => {
738
717
  const urlReader = this.runtime.urlReader;
739
718
  const connections = this.runtime.connections;
@@ -748,7 +727,6 @@ class ModelMaterializer extends FluentState {
748
727
  refreshSchemaCache: options === null || options === void 0 ? void 0 : options.refreshSchemaCache,
749
728
  noThrowOnError: options === null || options === void 0 ? void 0 : options.noThrowOnError,
750
729
  importBaseURL: options === null || options === void 0 ? void 0 : options.importBaseURL,
751
- testEnvironment: options === null || options === void 0 ? void 0 : options.testEnvironment,
752
730
  ...this.compileQueryOptions,
753
731
  virtualMap: virtualMap !== null && virtualMap !== void 0 ? virtualMap : this.runtime.virtualMap,
754
732
  });
@@ -20,7 +20,6 @@ export interface Loggable {
20
20
  }
21
21
  export interface ParseOptions {
22
22
  importBaseURL?: URL;
23
- testEnvironment?: boolean;
24
23
  /** Reject language constructs that reach outside the trusted model. */
25
24
  restrictedMode?: boolean;
26
25
  /**
@@ -83,6 +83,7 @@ export declare function qtz(qi: QueryInfo): string | undefined;
83
83
  */
84
84
  export declare function turtleGroupSetCondition(groupSet: number | undefined, filterSQL: string | undefined): string | undefined;
85
85
  export type OrderByClauseType = 'output_name' | 'ordinal' | 'expression';
86
+ export type GroupByClauseType = 'ordinal' | 'expression';
86
87
  export type OrderByRequest = 'query' | 'turtle' | 'analytical';
87
88
  export type BooleanTypeSupport = 'supported' | 'simulated' | 'none';
88
89
  /**
@@ -115,6 +116,14 @@ export declare abstract class Dialect {
115
116
  abstract supportsSafeCast: boolean;
116
117
  abstract supportsNesting: boolean;
117
118
  abstract experimental: boolean;
119
+ /**
120
+ * What the compiler consults, not `experimental` itself. The test harness
121
+ * calls `acceptExperimental()` on the dialect under test so the shared
122
+ * suites can run on an experimental dialect without every test enabling it.
123
+ */
124
+ private experimentalAccepted;
125
+ isExperimental(): boolean;
126
+ acceptExperimental(): void;
118
127
  cantPartitionWindowFunctionsOnExpressions: boolean;
119
128
  sqlLateralJoinBag(_expressions: LateralJoinExpression[]): string;
120
129
  supportsPipelinesInViews: boolean;
@@ -123,6 +132,9 @@ export declare abstract class Dialect {
123
132
  hasTimestamptz: boolean;
124
133
  readsNestedData: boolean;
125
134
  orderByClause: OrderByClauseType;
135
+ groupByClause: GroupByClauseType;
136
+ /** The ordering and row limit which end a SELECT stage */
137
+ sqlOrderByLimit(orderTerms: string[], limit: number | undefined): string;
126
138
  nullMatchesFunctionSignature: boolean;
127
139
  supportsSelectReplace: boolean;
128
140
  supportsBigIntPrecision: boolean;
@@ -140,6 +152,7 @@ export declare abstract class Dialect {
140
152
  compoundObjectInSchema: boolean;
141
153
  booleanType: BooleanTypeSupport;
142
154
  likeEscape: boolean;
155
+ likeExtraWildcards: string[];
143
156
  /**
144
157
  * Mappings from integer value ranges to Malloy number types.
145
158
  *
@@ -503,7 +516,7 @@ export declare abstract class Dialect {
503
516
  exprToSQL(qi: QueryInfo, df: Expr): string | undefined;
504
517
  sqlSumDistinct(_key: string, _value: string, _funcName: string): string;
505
518
  sqlAggDistinct(_key: string, _values: string[], _func: (valNames: string[]) => string): string;
506
- sqlSampleTable(tableSQL: string, sample: Sampling | undefined): string;
519
+ sqlSampleTable(tableSQL: string, sample: Sampling | undefined, _onBaseTable?: boolean): string;
507
520
  /**
508
521
  * MySQL is NULLs first, all other dialects have a way to make NULLs last.
509
522
  * isBaseOrdering is a hack to allow the MySQL dialect to partially implement
@@ -81,6 +81,12 @@ function turtleGroupSetCondition(groupSet, filterSQL) {
81
81
  }
82
82
  class Dialect {
83
83
  constructor() {
84
+ /**
85
+ * What the compiler consults, not `experimental` itself. The test harness
86
+ * calls `acceptExperimental()` on the dialect under test so the shared
87
+ * suites can run on an experimental dialect without every test enabling it.
88
+ */
89
+ this.experimentalAccepted = false;
84
90
  // -- we should add flags with default values from now on so as to not break
85
91
  // dialects outside our repository
86
92
  //
@@ -106,6 +112,9 @@ class Dialect {
106
112
  this.readsNestedData = true;
107
113
  // ORDER BY 1 DESC
108
114
  this.orderByClause = 'ordinal';
115
+ // GROUP BY 1, or GROUP BY the dimension expressions for an engine whose
116
+ // GROUP BY takes no ordinals
117
+ this.groupByClause = 'ordinal';
109
118
  // null will match in a function signature
110
119
  this.nullMatchesFunctionSignature = true;
111
120
  // support select * replace(...)
@@ -147,6 +156,8 @@ class Dialect {
147
156
  this.booleanType = 'supported';
148
157
  // Like characters are escaped with ESCAPE clause
149
158
  this.likeEscape = true;
159
+ // Characters LIKE reads as wildcards beyond % and _, escaped like them
160
+ this.likeExtraWildcards = [];
150
161
  /**
151
162
  * Mappings from integer value ranges to Malloy number types.
152
163
  *
@@ -209,6 +220,12 @@ class Dialect {
209
220
  */
210
221
  this.identifierEscapeStyle = exports.EscapeStyle.Unset;
211
222
  }
223
+ isExperimental() {
224
+ return this.experimental && !this.experimentalAccepted;
225
+ }
226
+ acceptExperimental() {
227
+ this.experimentalAccepted = true;
228
+ }
212
229
  // Generate the lateral join bag clause for window function partitioning.
213
230
  // The expressions are dimension fields that need to be referenced by name
214
231
  // in PARTITION BY clauses. Must be overridden by any dialect that sets
@@ -219,6 +236,14 @@ class Dialect {
219
236
  }
220
237
  throw new Error('Internal error: sqlLateralJoinBag called but cantPartitionWindowFunctionsOnExpressions is false');
221
238
  }
239
+ /** The ordering and row limit which end a SELECT stage */
240
+ sqlOrderByLimit(orderTerms, limit) {
241
+ let s = orderTerms.length > 0 ? this.sqlOrderBy(orderTerms, 'query') + '\n' : '';
242
+ if (limit !== undefined) {
243
+ s += `LIMIT ${limit}\n`;
244
+ }
245
+ return s;
246
+ }
222
247
  /**
223
248
  * Determine the Malloy number type for a numeric literal.
224
249
  */
@@ -623,7 +648,9 @@ class Dialect {
623
648
  _func) {
624
649
  return 'sqlAggDistinct called but not implemented';
625
650
  }
626
- sqlSampleTable(tableSQL, sample) {
651
+ // onBaseTable: the source is a table the engine can sample in place; a
652
+ // dialect whose sampling reads the table itself ignores a sample elsewhere
653
+ sqlSampleTable(tableSQL, sample, _onBaseTable = true) {
627
654
  if (sample !== undefined) {
628
655
  throw new Error(`Sampling is not supported on dialect ${this.name}.`);
629
656
  }
@@ -694,6 +721,11 @@ class Dialect {
694
721
  escapeActive = false;
695
722
  escapeClause = true;
696
723
  }
724
+ else if (this.likeEscape && this.likeExtraWildcards.includes(c)) {
725
+ escaped += '^' + c;
726
+ escapeActive = false;
727
+ escapeClause = true;
728
+ }
697
729
  else {
698
730
  if (escapeActive) {
699
731
  if (this.likeEscape) {
@@ -720,7 +752,7 @@ class Dialect {
720
752
  */
721
753
  sqlBoolean(bv) {
722
754
  if (this.booleanType === 'none') {
723
- return bv ? '(1=1)' : '(1-0)';
755
+ return bv ? '(1=1)' : '(1=0)';
724
756
  }
725
757
  return bv ? 'true' : 'false';
726
758
  }
@@ -14,6 +14,7 @@ const standardsql_1 = require("./standardsql");
14
14
  const trino_1 = require("./trino");
15
15
  const mysql_1 = require("./mysql");
16
16
  const databricks_1 = require("./databricks");
17
+ const sqlserver_1 = require("./sqlserver");
17
18
  const dialectMap = new Map();
18
19
  function getDialect(name) {
19
20
  const d = dialectMap.get(name);
@@ -36,4 +37,5 @@ registerDialect(new trino_1.TrinoDialect());
36
37
  registerDialect(new trino_1.PrestoDialect());
37
38
  registerDialect(new mysql_1.MySQLDialect());
38
39
  registerDialect(new databricks_1.DatabricksDialect());
40
+ registerDialect(new sqlserver_1.SQLServerDialect());
39
41
  //# sourceMappingURL=dialect_map.js.map
@@ -1,7 +1,7 @@
1
1
  export type { DialectFunctionOverloadDef, DefinitionBlueprint, DefinitionBlueprintMap, OverloadedDefinitionBlueprint, } from './functions/util';
2
2
  export { arg, anyExprType, makeParam, overload, minScalar, minAggregate, maxScalar, spread, param, variadicParam, literal, sql, } from './functions/util';
3
3
  export { Dialect, qtz } from './dialect';
4
- export type { DialectFieldList, CompiledOrderBy, LateralJoinExpression, QueryInfo, FieldReferenceType, } from './dialect';
4
+ export type { DialectFieldList, CompiledOrderBy, LateralJoinExpression, QueryInfo, FieldReferenceType, GroupByClauseType, OrderByClauseType, } from './dialect';
5
5
  export { StandardSQLDialect } from './standardsql';
6
6
  export { PostgresDialect } from './postgres';
7
7
  export { DuckDBDialect } from './duckdb';
@@ -9,6 +9,7 @@ export { SnowflakeDialect } from './snowflake';
9
9
  export { TrinoDialect } from './trino';
10
10
  export { MySQLDialect } from './mysql';
11
11
  export { DatabricksDialect } from './databricks';
12
+ export { SQLServerDialect } from './sqlserver';
12
13
  export { getDialect, registerDialect } from './dialect_map';
13
14
  export { getMalloyStandardFunctions } from './functions';
14
15
  export type { MalloyStandardFunctionImplementations } from './functions';
@@ -4,7 +4,7 @@
4
4
  * SPDX-License-Identifier: MIT
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.validateDottedTablePath = exports.decodeDottedTablePath = exports.TinyParser = exports.getMalloyStandardFunctions = exports.registerDialect = exports.getDialect = exports.DatabricksDialect = exports.MySQLDialect = exports.TrinoDialect = exports.SnowflakeDialect = exports.DuckDBDialect = exports.PostgresDialect = exports.StandardSQLDialect = exports.qtz = exports.Dialect = exports.sql = exports.literal = exports.variadicParam = exports.param = exports.spread = exports.maxScalar = exports.minAggregate = exports.minScalar = exports.overload = exports.makeParam = exports.anyExprType = exports.arg = void 0;
7
+ exports.validateDottedTablePath = exports.decodeDottedTablePath = exports.TinyParser = exports.getMalloyStandardFunctions = exports.registerDialect = exports.getDialect = exports.SQLServerDialect = exports.DatabricksDialect = exports.MySQLDialect = exports.TrinoDialect = exports.SnowflakeDialect = exports.DuckDBDialect = exports.PostgresDialect = exports.StandardSQLDialect = exports.qtz = exports.Dialect = exports.sql = exports.literal = exports.variadicParam = exports.param = exports.spread = exports.maxScalar = exports.minAggregate = exports.minScalar = exports.overload = exports.makeParam = exports.anyExprType = exports.arg = void 0;
8
8
  var util_1 = require("./functions/util");
9
9
  Object.defineProperty(exports, "arg", { enumerable: true, get: function () { return util_1.arg; } });
10
10
  Object.defineProperty(exports, "anyExprType", { enumerable: true, get: function () { return util_1.anyExprType; } });
@@ -35,6 +35,8 @@ var mysql_1 = require("./mysql");
35
35
  Object.defineProperty(exports, "MySQLDialect", { enumerable: true, get: function () { return mysql_1.MySQLDialect; } });
36
36
  var databricks_1 = require("./databricks");
37
37
  Object.defineProperty(exports, "DatabricksDialect", { enumerable: true, get: function () { return databricks_1.DatabricksDialect; } });
38
+ var sqlserver_1 = require("./sqlserver");
39
+ Object.defineProperty(exports, "SQLServerDialect", { enumerable: true, get: function () { return sqlserver_1.SQLServerDialect; } });
38
40
  var dialect_map_1 = require("./dialect_map");
39
41
  Object.defineProperty(exports, "getDialect", { enumerable: true, get: function () { return dialect_map_1.getDialect; } });
40
42
  Object.defineProperty(exports, "registerDialect", { enumerable: true, get: function () { return dialect_map_1.registerDialect; } });
@@ -0,0 +1,2 @@
1
+ import type { DefinitionBlueprintMap } from '../functions/util';
2
+ export declare const SQLSERVER_DIALECT_FUNCTIONS: DefinitionBlueprintMap;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright Contributors to the Malloy project
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.SQLSERVER_DIALECT_FUNCTIONS = void 0;
8
+ const util_1 = require("../functions/util");
9
+ const order_by = {
10
+ node: 'aggregate_order_by',
11
+ prefix: ' WITHIN GROUP (',
12
+ suffix: ')',
13
+ };
14
+ // STRING_AGG's result is limited to 8000 bytes unless its input is a MAX type.
15
+ const string_agg = {
16
+ default_separator: {
17
+ takes: { 'value': { dimension: 'string' } },
18
+ returns: { measure: 'string' },
19
+ supportsOrderBy: true,
20
+ impl: {
21
+ expr: (0, util_1.sql) `STRING_AGG(CAST(${(0, util_1.arg)('value')} AS NVARCHAR(MAX)), ',')${order_by}`,
22
+ },
23
+ },
24
+ with_separator: {
25
+ takes: {
26
+ 'value': { dimension: 'string' },
27
+ 'separator': { literal: 'string' },
28
+ },
29
+ returns: { measure: 'string' },
30
+ supportsOrderBy: true,
31
+ impl: {
32
+ expr: (0, util_1.sql) `STRING_AGG(CAST(${(0, util_1.arg)('value')} AS NVARCHAR(MAX)), ${(0, util_1.arg)('separator')})${order_by}`,
33
+ },
34
+ },
35
+ };
36
+ // No string_agg_distinct: STRING_AGG accepts no DISTINCT, so the translator
37
+ // reports the function as unknown for this dialect.
38
+ exports.SQLSERVER_DIALECT_FUNCTIONS = {
39
+ string_agg,
40
+ ...(0, util_1.def)('reverse', { 'str': 'string' }, 'string'),
41
+ };
42
+ //# sourceMappingURL=dialect_functions.js.map
@@ -0,0 +1,2 @@
1
+ import type { MalloyStandardFunctionImplementations as OverrideMap } from '../functions/malloy_standard_functions';
2
+ export declare const SQLSERVER_MALLOY_STANDARD_OVERLOADS: OverrideMap;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright Contributors to the Malloy project
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.SQLSERVER_MALLOY_STANDARD_OVERLOADS = void 0;
8
+ // LEN ignores trailing spaces: append one character, count, subtract one
9
+ const len = (arg) => `(LEN(${arg} + N'x') - 1)`;
10
+ exports.SQLSERVER_MALLOY_STANDARD_OVERLOADS = {
11
+ ceil: { function: 'CEILING' },
12
+ chr: { sql: "CASE WHEN ${value} = 0 THEN '' ELSE NCHAR(${value}) END" },
13
+ div: { sql: 'FLOOR(${dividend} / ${divisor})' },
14
+ // starts_with and ends_with are written as comparisons because SQL Server
15
+ // has no boolean values: legal as a condition (where:, having:), a server
16
+ // error as a value. A NULL input matches nothing, where the standard's
17
+ // COALESCE(..., false) returns false.
18
+ ends_with: {
19
+ sql: `RIGHT(\${value}, ${len('${suffix}')}) = \${suffix}`,
20
+ },
21
+ ifnull: { function: 'ISNULL' },
22
+ // A FLOAT holds neither infinity nor NaN, so neither condition is ever true
23
+ is_inf: { sql: '(1=0)' },
24
+ is_nan: { sql: '(1=0)' },
25
+ length: { sql: len('${value}') },
26
+ ln: { sql: 'LOG(${value})' },
27
+ log: { sql: 'LOG(${value}, ${base})' },
28
+ // POWER answers in the type of its base, so an integer base truncates
29
+ pow: { sql: 'POWER(CAST(${base} AS FLOAT(53)), ${exponent})' },
30
+ round: {
31
+ to_integer: { sql: 'ROUND(${value}, 0)' },
32
+ to_precision: { sql: 'ROUND(${value}, ${precision})' },
33
+ },
34
+ atan2: { function: 'ATN2' },
35
+ trim: { characters: { sql: 'TRIM(${trim_characters} FROM ${value})' } },
36
+ starts_with: {
37
+ sql: `LEFT(\${value}, ${len('${prefix}')}) = \${prefix}`,
38
+ },
39
+ stddev: { function: 'STDEV' },
40
+ string_repeat: { function: 'REPLICATE' },
41
+ strpos: { sql: 'CHARINDEX(${search_string}, ${test_string})' },
42
+ substr: {
43
+ position_only: {
44
+ sql: `SUBSTRING(\${value}, CASE WHEN \${position} < 0 THEN ${len('${value}')} + \${position} + 1 ELSE \${position} END, ${len('${value}')})`,
45
+ },
46
+ with_length: {
47
+ sql: `SUBSTRING(\${value}, CASE WHEN \${position} < 0 THEN ${len('${value}')} + \${position} + 1 ELSE \${position} END, \${length})`,
48
+ },
49
+ },
50
+ trunc: {
51
+ to_integer: { sql: 'ROUND(${value}, 0, 1)' },
52
+ to_precision: { sql: 'ROUND(${value}, ${precision}, 1)' },
53
+ },
54
+ };
55
+ //# sourceMappingURL=function_overrides.js.map
@@ -0,0 +1 @@
1
+ export * from './sqlserver';
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ /*
3
+ * Copyright Contributors to the Malloy project
4
+ * SPDX-License-Identifier: MIT
5
+ */
6
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
7
+ if (k2 === undefined) k2 = k;
8
+ var desc = Object.getOwnPropertyDescriptor(m, k);
9
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
10
+ desc = { enumerable: true, get: function() { return m[k]; } };
11
+ }
12
+ Object.defineProperty(o, k2, desc);
13
+ }) : (function(o, m, k, k2) {
14
+ if (k2 === undefined) k2 = k;
15
+ o[k2] = m[k];
16
+ }));
17
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
18
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
19
+ };
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ __exportStar(require("./sqlserver"), exports);
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,102 @@
1
+ import type { Sampling, AtomicTypeDef, ATimestampTypeDef, TypecastExpr, MeasureTimeExpr, BasicAtomicTypeDef, RegexMatchExpr, TimeExtractExpr, TimestampUnit, OrderBy } from '../../model/malloy_types';
2
+ import type { DialectFunctionOverloadDef } from '../functions';
3
+ import type { BooleanTypeSupport, DialectFieldList, FieldReferenceType, GroupByClauseType, QueryInfo } from '../dialect';
4
+ import { Dialect } from '../dialect';
5
+ import type { ValidateTablePathResult } from '../table-path';
6
+ /** T-SQL for SQL Server 2017 and later, and Azure SQL Database. */
7
+ export declare class SQLServerDialect extends Dialect {
8
+ name: string;
9
+ experimental: boolean;
10
+ stringLiteralStyle: "doubled";
11
+ identifierEscapeStyle: "doubled";
12
+ identifierQuoteChar: string;
13
+ defaultNumberType: string;
14
+ defaultDecimalType: string;
15
+ udfPrefix: string;
16
+ hasFinalStage: boolean;
17
+ divisionIsInteger: boolean;
18
+ supportsSumDistinctFunction: boolean;
19
+ unnestWithNumbers: boolean;
20
+ defaultSampling: {
21
+ rows: number;
22
+ };
23
+ supportUnnestArrayAgg: boolean;
24
+ supportsAggDistinct: boolean;
25
+ supportsCTEinCoorelatedSubQueries: boolean;
26
+ dontUnionIndex: boolean;
27
+ supportsQualify: boolean;
28
+ supportsSafeCast: boolean;
29
+ supportsNesting: boolean;
30
+ supportsPipelinesInViews: boolean;
31
+ supportsFullJoin: boolean;
32
+ readsNestedData: boolean;
33
+ supportsComplexFilteredSources: boolean;
34
+ supportsArraysInData: boolean;
35
+ compoundObjectInSchema: boolean;
36
+ supportsSelectReplace: boolean;
37
+ supportsTempTables: boolean;
38
+ booleanType: BooleanTypeSupport;
39
+ hasTimestamptz: boolean;
40
+ supportsBigIntPrecision: boolean;
41
+ maxIdentifierLength: number;
42
+ likeEscape: boolean;
43
+ likeExtraWildcards: string[];
44
+ groupByClause: GroupByClauseType;
45
+ tablePathBareIdentRegex: RegExp;
46
+ /**
47
+ * `[schema].[table]` is read as the ANSI-quoted path it stands for, and the
48
+ * canonical form is the ANSI spelling the base validates.
49
+ */
50
+ sqlValidateTableName(input: string): ValidateTablePathResult;
51
+ malloyTypeToSQLType(malloyType: AtomicTypeDef): string;
52
+ sqlTypeToMalloyType(sqlType: string): BasicAtomicTypeDef;
53
+ validateTypeName(sqlType: string): boolean;
54
+ sqlGroupSetTable(groupSetCount: number): string;
55
+ sqlAnyValue(_groupSet: number, fieldName: string): string;
56
+ sqlAggregateTurtle(): string;
57
+ sqlAnyValueTurtle(): string;
58
+ sqlAnyValueLastTurtle(): string;
59
+ sqlCoaleseMeasuresInline(): string;
60
+ sqlUnnestAlias(): string;
61
+ sqlSelectAliasAsStruct(): string;
62
+ sqlLiteralRecord(): string;
63
+ sqlLiteralArray(): string;
64
+ sqlFieldReference(parentAlias: string, _parentType: FieldReferenceType, childName: string, _childType: string): string;
65
+ private unsupported;
66
+ sqlUnnestPipelineHead(_isSingleton: boolean, _sourceSQLExpression: string, _fieldList?: DialectFieldList): string;
67
+ sqlCreateFunction(_id: string, _funcText: string): string;
68
+ sqlCreateFunctionCombineLastStage(_lastStageName: string, _fieldList: DialectFieldList, _orderBy: OrderBy[] | undefined): string;
69
+ sqlCreateTableAsSelect(tableName: string, sql: string): string;
70
+ sqlGenerateUUID(): string;
71
+ sqlLiteralString(literal: string): string;
72
+ sqlSumDistinctHashedKey(sqlDistinctKey: string): string;
73
+ sqlSumDistinct(key: string, value: string, funcName: string): string;
74
+ sqlAggDistinct(_key: string, _values: string[], _func: (valNames: string[]) => string): string;
75
+ sqlOrderByLimit(orderTerms: string[], limit: number | undefined): string;
76
+ sqlSampleTable(tableSQL: string, sample: Sampling | undefined, onBaseTable?: boolean): string;
77
+ castToString(expression: string): string;
78
+ concat(...values: string[]): string;
79
+ sqlDateToString(sqlDateExp: string): string;
80
+ sqlNowExpr(): string;
81
+ sqlTimeExtractExpr(qi: QueryInfo, from: TimeExtractExpr): string;
82
+ sqlCast(qi: QueryInfo, cast: TypecastExpr): string;
83
+ sqlRegexpMatch(_df: RegexMatchExpr): string;
84
+ sqlDateLiteral(_qi: QueryInfo, literal: string): string;
85
+ sqlTimestampLiteral(qi: QueryInfo, literal: string, timezone: string | undefined): string;
86
+ sqlTimestamptzLiteral(_qi: QueryInfo, _literal: string, _timezone: string): string;
87
+ sqlTimezoneLiteral(timezone: string): string;
88
+ sqlConvertToCivilTime(expr: string, timezone: string, _typeDef: AtomicTypeDef): {
89
+ sql: string;
90
+ typeDef: AtomicTypeDef;
91
+ };
92
+ sqlConvertFromCivilTime(expr: string, timezone: string, _destTypeDef: ATimestampTypeDef): string;
93
+ sqlTruncate(expr: string, unit: TimestampUnit, typeDef: AtomicTypeDef, _inCivilTime: boolean, _timezone?: string): string;
94
+ sqlOffsetTime(expr: string, op: '+' | '-', magnitude: string, unit: TimestampUnit, _typeDef: AtomicTypeDef, _inCivilTime: boolean, _timezone?: string): string;
95
+ sqlMeasureTimeExpr(df: MeasureTimeExpr): string;
96
+ getDialectFunctionOverrides(): {
97
+ [name: string]: DialectFunctionOverloadDef[];
98
+ };
99
+ getDialectFunctions(): {
100
+ [name: string]: DialectFunctionOverloadDef[];
101
+ };
102
+ }