@malloydata/malloy 0.0.336 → 0.0.338

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 (42) hide show
  1. package/dist/api/foundation/compile.d.ts +26 -0
  2. package/dist/api/foundation/compile.js +38 -0
  3. package/dist/api/foundation/result.d.ts +4 -4
  4. package/dist/api/foundation/result.js +9 -9
  5. package/dist/api/foundation/writers.d.ts +1 -1
  6. package/dist/api/foundation/writers.js +9 -8
  7. package/dist/connection/index.d.ts +1 -0
  8. package/dist/connection/index.js +1 -0
  9. package/dist/connection/registry.d.ts +73 -0
  10. package/dist/connection/registry.js +106 -0
  11. package/dist/connection/types.d.ts +2 -17
  12. package/dist/dialect/dialect.d.ts +2 -1
  13. package/dist/dialect/dialect.js +3 -0
  14. package/dist/dialect/duckdb/duckdb.js +22 -1
  15. package/dist/dialect/mysql/mysql.d.ts +1 -0
  16. package/dist/dialect/mysql/mysql.js +1 -0
  17. package/dist/dialect/postgres/postgres.d.ts +1 -0
  18. package/dist/dialect/postgres/postgres.js +10 -0
  19. package/dist/dialect/standardsql/standardsql.js +21 -0
  20. package/dist/index.d.ts +5 -3
  21. package/dist/index.js +11 -2
  22. package/dist/lang/ast/expressions/expr-cast.d.ts +3 -3
  23. package/dist/lang/ast/expressions/expr-cast.js +4 -2
  24. package/dist/lang/ast/expressions/expr-func.d.ts +3 -3
  25. package/dist/lang/ast/expressions/expr-func.js +7 -9
  26. package/dist/lang/ast/expressions/for-range.js +1 -1
  27. package/dist/lang/ast/source-elements/named-source.js +4 -2
  28. package/dist/lang/ast/time-utils.d.ts +2 -2
  29. package/dist/lang/ast/time-utils.js +4 -5
  30. package/dist/lang/lib/Malloy/MalloyParser.d.ts +88 -45
  31. package/dist/lang/lib/Malloy/MalloyParser.js +2193 -1862
  32. package/dist/lang/lib/Malloy/MalloyParserListener.d.ts +33 -0
  33. package/dist/lang/lib/Malloy/MalloyParserVisitor.d.ts +21 -0
  34. package/dist/lang/malloy-to-ast.d.ts +4 -4
  35. package/dist/lang/malloy-to-ast.js +38 -22
  36. package/dist/model/malloy_types.d.ts +11 -8
  37. package/dist/model/malloy_types.js +23 -15
  38. package/dist/model/utils.d.ts +3 -5
  39. package/dist/model/utils.js +6 -10
  40. package/dist/version.d.ts +1 -1
  41. package/dist/version.js +1 -1
  42. package/package.json +5 -6
@@ -1,5 +1,6 @@
1
1
  import type { LogMessage } from '../../lang';
2
2
  import type { Connection, InfoConnection, LookupConnection, FetchSchemaOptions } from '../../connection/types';
3
+ import type { ConnectionTypeDef, ConnectionPropertyDefinition, ConnectionsConfig } from '../../connection/registry';
3
4
  import type { URLReader, EventStream } from '../../runtime_types';
4
5
  import type { SQLSourceDef, QueryRunStats } from '../../model';
5
6
  import type { RunSQLOptions } from '../../run_sql_options';
@@ -55,6 +56,31 @@ export declare class MalloyError extends Error {
55
56
  }
56
57
  export declare class Malloy {
57
58
  static get version(): string;
59
+ /**
60
+ * Register a connection type with the global registry.
61
+ * Typically called by db-* packages on import as a side effect.
62
+ */
63
+ static registerConnectionType(typeName: string, def: ConnectionTypeDef): void;
64
+ /**
65
+ * Get the property definitions for a registered connection type.
66
+ */
67
+ static getConnectionProperties(typeName: string): ConnectionPropertyDefinition[] | undefined;
68
+ /**
69
+ * Get the names of all registered connection types.
70
+ */
71
+ static getRegisteredConnectionTypes(): string[];
72
+ /**
73
+ * Parse a JSON config string into an editable ConnectionsConfig.
74
+ */
75
+ static readConnectionsConfig(jsonText: string): ConnectionsConfig;
76
+ /**
77
+ * Serialize a ConnectionsConfig to a JSON string.
78
+ */
79
+ static writeConnectionsConfig(config: ConnectionsConfig): string;
80
+ /**
81
+ * Create a LookupConnection from a ConnectionsConfig using registered factories.
82
+ */
83
+ static createConnectionsFromConfig(config: ConnectionsConfig): LookupConnection<Connection>;
58
84
  private static _parse;
59
85
  /**
60
86
  * Parse a Malloy document by URL.
@@ -6,6 +6,7 @@
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.Malloy = exports.MalloyError = void 0;
8
8
  const lang_1 = require("../../lang");
9
+ const registry_1 = require("../../connection/registry");
9
10
  const model_1 = require("../../model");
10
11
  const sql_block_1 = require("../../model/sql_block");
11
12
  const version_1 = require("../../version");
@@ -43,6 +44,43 @@ class Malloy {
43
44
  static get version() {
44
45
  return version_1.MALLOY_VERSION;
45
46
  }
47
+ /**
48
+ * Register a connection type with the global registry.
49
+ * Typically called by db-* packages on import as a side effect.
50
+ */
51
+ static registerConnectionType(typeName, def) {
52
+ (0, registry_1.registerConnectionType)(typeName, def);
53
+ }
54
+ /**
55
+ * Get the property definitions for a registered connection type.
56
+ */
57
+ static getConnectionProperties(typeName) {
58
+ return (0, registry_1.getConnectionProperties)(typeName);
59
+ }
60
+ /**
61
+ * Get the names of all registered connection types.
62
+ */
63
+ static getRegisteredConnectionTypes() {
64
+ return (0, registry_1.getRegisteredConnectionTypes)();
65
+ }
66
+ /**
67
+ * Parse a JSON config string into an editable ConnectionsConfig.
68
+ */
69
+ static readConnectionsConfig(jsonText) {
70
+ return (0, registry_1.readConnectionsConfig)(jsonText);
71
+ }
72
+ /**
73
+ * Serialize a ConnectionsConfig to a JSON string.
74
+ */
75
+ static writeConnectionsConfig(config) {
76
+ return (0, registry_1.writeConnectionsConfig)(config);
77
+ }
78
+ /**
79
+ * Create a LookupConnection from a ConnectionsConfig using registered factories.
80
+ */
81
+ static createConnectionsFromConfig(config) {
82
+ return (0, registry_1.createConnectionsFromConfig)(config);
83
+ }
46
84
  static _parse(source, url, eventStream, options, invalidationKey) {
47
85
  if (url === undefined) {
48
86
  url = new URL(MALLOY_INTERNAL_URL);
@@ -1,4 +1,4 @@
1
- import type { QueryData, QueryDataRow, QueryResult, QueryRunStats, ModelDef } from '../../model';
1
+ import type { QueryData, QueryRecord, QueryResult, QueryRunStats, ModelDef } from '../../model';
2
2
  import type { Explore, Field, AtomicField, StringField, NumberField, BooleanField, DateField, TimestampField, JSONField, UnsupportedField } from './core';
3
3
  import { PreparedResult } from './core';
4
4
  export type ResultJSON = {
@@ -163,17 +163,17 @@ export declare class DataRecord extends Data<{
163
163
  protected _field: Explore;
164
164
  readonly index: number | undefined;
165
165
  private cellCache;
166
- constructor(queryDataRow: QueryDataRow, index: number | undefined, field: Explore, parent: DataArrayOrRecord | undefined, parentRecord: DataRecord | undefined);
166
+ constructor(queryDataRow: QueryRecord, index: number | undefined, field: Explore, parent: DataArrayOrRecord | undefined, parentRecord: DataRecord | undefined);
167
167
  /**
168
168
  * @return Normalized data with JS native types (number | bigint, Date).
169
169
  * Use this for CSV output, tests, and general programmatic access.
170
170
  */
171
- toObject(): QueryDataRow;
171
+ toObject(): QueryRecord;
172
172
  /**
173
173
  * @return Normalized data with JSON-safe types (numbers as number | string, dates as ISO strings).
174
174
  * Use this for JSON serialization.
175
175
  */
176
- toJSON(): QueryDataRow;
176
+ toJSON(): QueryRecord;
177
177
  path(...path: (number | string)[]): DataColumn;
178
178
  cell(fieldOrName: string | Field): DataColumn;
179
179
  get value(): {
@@ -406,12 +406,12 @@ const JSON_NORMALIZERS = {
406
406
  * Walk a QueryData array and normalize values according to the given normalizers.
407
407
  */
408
408
  function walkQueryData(data, structDef, normalizers) {
409
- return data.map(row => walkQueryDataRow(row, structDef, normalizers));
409
+ return data.map(row => walkQueryRecord(row, structDef, normalizers));
410
410
  }
411
411
  /**
412
- * Walk a QueryDataRow and normalize values according to the given normalizers.
412
+ * Walk a QueryRecord and normalize values according to the given normalizers.
413
413
  */
414
- function walkQueryDataRow(row, structDef, normalizers) {
414
+ function walkQueryRecord(row, structDef, normalizers) {
415
415
  var _a;
416
416
  const result = {};
417
417
  for (const fieldDef of structDef.fields) {
@@ -458,7 +458,7 @@ function walkValue(value, fieldDef, normalizers) {
458
458
  }
459
459
  if ((0, model_1.isRepeatedRecord)(fieldDef)) {
460
460
  // Array of records - recurse into each record
461
- return value.map(item => walkQueryDataRow(item, fieldDef, normalizers));
461
+ return value.map(item => walkQueryRecord(item, fieldDef, normalizers));
462
462
  }
463
463
  else if ((0, model_1.isBasicArray)(fieldDef)) {
464
464
  // Scalar array - normalize each element based on elementTypeDef
@@ -470,7 +470,7 @@ function walkValue(value, fieldDef, normalizers) {
470
470
  // Handle records (non-array)
471
471
  if (fieldDef.type === 'record') {
472
472
  if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
473
- return walkQueryDataRow(value, fieldDef, normalizers);
473
+ return walkQueryRecord(value, fieldDef, normalizers);
474
474
  }
475
475
  }
476
476
  // Fallback - pass through
@@ -505,7 +505,7 @@ function walkScalarValue(value, typeDef, normalizers) {
505
505
  return value.map(item => walkScalarValue(item, elementType, normalizers));
506
506
  }
507
507
  else if ((0, model_1.isRepeatedRecord)(typeDef)) {
508
- return value.map(item => walkQueryDataRow(item, typeDef, normalizers));
508
+ return value.map(item => walkQueryRecord(item, typeDef, normalizers));
509
509
  }
510
510
  }
511
511
  // Pass through other types
@@ -612,14 +612,14 @@ class DataRecord extends Data {
612
612
  * Use this for CSV output, tests, and general programmatic access.
613
613
  */
614
614
  toObject() {
615
- return walkQueryDataRow(this.queryDataRow, this._field.structDef, OBJECT_NORMALIZERS);
615
+ return walkQueryRecord(this.queryDataRow, this._field.structDef, OBJECT_NORMALIZERS);
616
616
  }
617
617
  /**
618
618
  * @return Normalized data with JSON-safe types (numbers as number | string, dates as ISO strings).
619
619
  * Use this for JSON serialization.
620
620
  */
621
621
  toJSON() {
622
- return walkQueryDataRow(this.queryDataRow, this._field.structDef, JSON_NORMALIZERS);
622
+ return walkQueryRecord(this.queryDataRow, this._field.structDef, JSON_NORMALIZERS);
623
623
  }
624
624
  path(...path) {
625
625
  return getPath(this, path);
@@ -657,7 +657,7 @@ class DataRecord extends Data {
657
657
  }
658
658
  }
659
659
  else if (field.isExploreField()) {
660
- if (Array.isArray(value)) {
660
+ if ((0, model_1.isCompoundArrayData)(value)) {
661
661
  column = new DataArray(value, field, this, this);
662
662
  }
663
663
  else {
@@ -15,7 +15,7 @@ export declare class JSONWriter extends DataWriter {
15
15
  * CSV writer class that handles nested data.
16
16
  * This writer creates CSV using a DFS traversal of the result dataset.
17
17
  * Each trivial column value is converted to a CSV of 1x1 matrix and all the
18
- * columns are merged together to create a CSV that represents 1 QueryDataRow.
18
+ * columns are merged together to create a CSV that represents 1 QueryRecord.
19
19
  * Since this follows DFS, each non trivial data is rendered into a NxM matrix
20
20
  * where N is the number of rows in the nested data and M is the number of
21
21
  * columns it has.
@@ -5,6 +5,7 @@
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.CSVWriter = exports.JSONWriter = exports.DataWriter = void 0;
8
+ const model_1 = require("../../model");
8
9
  // =============================================================================
9
10
  // DataWriter Base Class
10
11
  // =============================================================================
@@ -47,7 +48,7 @@ exports.JSONWriter = JSONWriter;
47
48
  * CSV writer class that handles nested data.
48
49
  * This writer creates CSV using a DFS traversal of the result dataset.
49
50
  * Each trivial column value is converted to a CSV of 1x1 matrix and all the
50
- * columns are merged together to create a CSV that represents 1 QueryDataRow.
51
+ * columns are merged together to create a CSV that represents 1 QueryRecord.
51
52
  * Since this follows DFS, each non trivial data is rendered into a NxM matrix
52
53
  * where N is the number of rows in the nested data and M is the number of
53
54
  * columns it has.
@@ -108,7 +109,7 @@ class CSVWriter extends DataWriter {
108
109
  for (const key in firstVal) {
109
110
  numKeys = numKeys + 1;
110
111
  const val = firstVal[key];
111
- if (Array.isArray(val)) {
112
+ if ((0, model_1.isCompoundArrayData)(val)) {
112
113
  const weight = this.getColWeight(val) - 1;
113
114
  numKeys = numKeys + weight;
114
115
  }
@@ -123,7 +124,7 @@ class CSVWriter extends DataWriter {
123
124
  csv.push(this.escape(key));
124
125
  const val = row[key];
125
126
  width++;
126
- if (Array.isArray(val)) {
127
+ if ((0, model_1.isCompoundArrayData)(val)) {
127
128
  const numKeys = this.getColWeight(val) - 1;
128
129
  width = width + numKeys;
129
130
  for (let i = 0; i < numKeys; i++) {
@@ -193,7 +194,11 @@ class CSVWriter extends DataWriter {
193
194
  const matrices = [];
194
195
  for (const key in row) {
195
196
  const val = row[key];
196
- if (!Array.isArray(val)) {
197
+ if ((0, model_1.isCompoundArrayData)(val)) {
198
+ const cell = this.getChildMatrix(val);
199
+ matrices.push(cell);
200
+ }
201
+ else {
197
202
  const cell = {
198
203
  rows: [this.stringify(val)],
199
204
  length: 1,
@@ -201,10 +206,6 @@ class CSVWriter extends DataWriter {
201
206
  };
202
207
  matrices.push(cell);
203
208
  }
204
- else {
205
- const cell = this.getChildMatrix(val);
206
- matrices.push(cell);
207
- }
208
209
  }
209
210
  return this.mergeMatrices(matrices);
210
211
  }
@@ -1,2 +1,3 @@
1
1
  export * from './types';
2
2
  export * from './base_connection';
3
+ export * from './registry';
@@ -16,4 +16,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./types"), exports);
18
18
  __exportStar(require("./base_connection"), exports);
19
+ __exportStar(require("./registry"), exports);
19
20
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,73 @@
1
+ import type { Connection, ConnectionConfig, LookupConnection } from './types';
2
+ /**
3
+ * A factory function that creates a Connection from a config object.
4
+ */
5
+ export type ConnectionTypeFactory = (config: ConnectionConfig) => Connection;
6
+ /**
7
+ * The type of a connection property value.
8
+ */
9
+ export type ConnectionPropertyType = 'string' | 'number' | 'boolean' | 'password' | 'file' | 'text';
10
+ /**
11
+ * Describes a single configuration property for a connection type.
12
+ */
13
+ export interface ConnectionPropertyDefinition {
14
+ name: string;
15
+ displayName: string;
16
+ type: ConnectionPropertyType;
17
+ optional?: true;
18
+ default?: string;
19
+ description?: string;
20
+ /** For type 'file': extension filters for picker dialogs. */
21
+ fileFilters?: Record<string, string[]>;
22
+ }
23
+ /**
24
+ * A connection type definition: factory plus property metadata.
25
+ */
26
+ export interface ConnectionTypeDef {
27
+ factory: ConnectionTypeFactory;
28
+ properties: ConnectionPropertyDefinition[];
29
+ }
30
+ /**
31
+ * A single connection entry in a JSON config.
32
+ */
33
+ export interface ConnectionConfigEntry {
34
+ is: string;
35
+ [key: string]: string | number | boolean | undefined;
36
+ }
37
+ /**
38
+ * The editable intermediate representation of a connections config file.
39
+ */
40
+ export interface ConnectionsConfig {
41
+ connections: Record<string, ConnectionConfigEntry>;
42
+ }
43
+ /**
44
+ * Register a connection type with its factory and property definitions.
45
+ *
46
+ * @param typeName The connection type name (e.g. "duckdb", "bigquery").
47
+ * @param def The connection type definition (factory + properties).
48
+ */
49
+ export declare function registerConnectionType(typeName: string, def: ConnectionTypeDef): void;
50
+ /**
51
+ * Get the property definitions for a registered connection type.
52
+ *
53
+ * @param typeName The connection type name.
54
+ * @returns The property definitions, or undefined if the type is not registered.
55
+ */
56
+ export declare function getConnectionProperties(typeName: string): ConnectionPropertyDefinition[] | undefined;
57
+ /**
58
+ * Get the names of all registered connection types.
59
+ */
60
+ export declare function getRegisteredConnectionTypes(): string[];
61
+ /**
62
+ * Parse a JSON config string into a ConnectionsConfig.
63
+ * Validates that each connection entry has an `is` field.
64
+ */
65
+ export declare function readConnectionsConfig(jsonText: string): ConnectionsConfig;
66
+ /**
67
+ * Serialize a ConnectionsConfig to a JSON string with 2-space indent.
68
+ */
69
+ export declare function writeConnectionsConfig(config: ConnectionsConfig): string;
70
+ /**
71
+ * Create a LookupConnection from a ConnectionsConfig using registered factories.
72
+ */
73
+ export declare function createConnectionsFromConfig(config: ConnectionsConfig): LookupConnection<Connection>;
@@ -0,0 +1,106 @@
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.registerConnectionType = registerConnectionType;
8
+ exports.getConnectionProperties = getConnectionProperties;
9
+ exports.getRegisteredConnectionTypes = getRegisteredConnectionTypes;
10
+ exports.readConnectionsConfig = readConnectionsConfig;
11
+ exports.writeConnectionsConfig = writeConnectionsConfig;
12
+ exports.createConnectionsFromConfig = createConnectionsFromConfig;
13
+ // Module-level registry
14
+ const registry = new Map();
15
+ /**
16
+ * Register a connection type with its factory and property definitions.
17
+ *
18
+ * @param typeName The connection type name (e.g. "duckdb", "bigquery").
19
+ * @param def The connection type definition (factory + properties).
20
+ */
21
+ function registerConnectionType(typeName, def) {
22
+ registry.set(typeName, def);
23
+ }
24
+ /**
25
+ * Get the property definitions for a registered connection type.
26
+ *
27
+ * @param typeName The connection type name.
28
+ * @returns The property definitions, or undefined if the type is not registered.
29
+ */
30
+ function getConnectionProperties(typeName) {
31
+ var _a;
32
+ return (_a = registry.get(typeName)) === null || _a === void 0 ? void 0 : _a.properties;
33
+ }
34
+ /**
35
+ * Get the names of all registered connection types.
36
+ */
37
+ function getRegisteredConnectionTypes() {
38
+ return [...registry.keys()];
39
+ }
40
+ /**
41
+ * Parse a JSON config string into a ConnectionsConfig.
42
+ * Validates that each connection entry has an `is` field.
43
+ */
44
+ function readConnectionsConfig(jsonText) {
45
+ const parsed = JSON.parse(jsonText);
46
+ const connections = parsed.connections;
47
+ if (connections === undefined || typeof connections !== 'object') {
48
+ throw new Error('Invalid connections config: missing "connections" object');
49
+ }
50
+ for (const [name, entry] of Object.entries(connections)) {
51
+ if (typeof entry !== 'object' ||
52
+ entry === null ||
53
+ !entry.is) {
54
+ throw new Error(`Connection "${name}" is missing required "is" property`);
55
+ }
56
+ }
57
+ return parsed;
58
+ }
59
+ /**
60
+ * Serialize a ConnectionsConfig to a JSON string with 2-space indent.
61
+ */
62
+ function writeConnectionsConfig(config) {
63
+ return JSON.stringify(config, null, 2);
64
+ }
65
+ /**
66
+ * Create a LookupConnection from a ConnectionsConfig using registered factories.
67
+ */
68
+ function createConnectionsFromConfig(config) {
69
+ const entries = Object.entries(config.connections);
70
+ const firstConnectionName = entries.length > 0 ? entries[0][0] : undefined;
71
+ const cache = new Map();
72
+ return {
73
+ async lookupConnection(connectionName) {
74
+ if (connectionName === undefined) {
75
+ connectionName = firstConnectionName;
76
+ }
77
+ if (connectionName === undefined) {
78
+ throw new Error('No connections defined in config');
79
+ }
80
+ const cached = cache.get(connectionName);
81
+ if (cached)
82
+ return cached;
83
+ const entry = config.connections[connectionName];
84
+ if (!entry) {
85
+ throw new Error(`No connection named "${connectionName}" found in config`);
86
+ }
87
+ const typeDef = registry.get(entry.is);
88
+ if (!typeDef) {
89
+ throw new Error(`No registered connection type "${entry.is}" for connection "${connectionName}". ` +
90
+ 'Did you forget to import the connection package?');
91
+ }
92
+ const connConfig = { name: connectionName };
93
+ for (const [key, value] of Object.entries(entry)) {
94
+ if (key === 'is')
95
+ continue;
96
+ if (value !== undefined) {
97
+ connConfig[key] = value;
98
+ }
99
+ }
100
+ const connection = typeDef.factory(connConfig);
101
+ cache.set(connectionName, connection);
102
+ return connection;
103
+ },
104
+ };
105
+ }
106
+ //# sourceMappingURL=registry.js.map
@@ -1,6 +1,5 @@
1
1
  import type { RunSQLOptions } from '../run_sql_options';
2
- import type { Annotation, MalloyQueryData, QueryDataRow, QueryRunStats, SQLSourceDef, TableSourceDef } from '../model/malloy_types';
3
- import type { Dialect } from '../dialect';
2
+ import type { Annotation, MalloyQueryData, QueryRecord, QueryRunStats, SQLSourceDef, TableSourceDef } from '../model/malloy_types';
4
3
  import type { SQLSourceRequest } from '../lang/translate-response';
5
4
  /**
6
5
  * Options passed to fetchSchema methods.
@@ -49,24 +48,10 @@ export interface InfoConnection {
49
48
  getDigest(): string;
50
49
  }
51
50
  export type ConnectionParameterValue = string | number | boolean | Array<ConnectionParameterValue>;
52
- export interface ConnectionParameter {
53
- name: string;
54
- label: string;
55
- type: 'string' | 'number' | 'boolean';
56
- isOptional?: boolean;
57
- isSecret?: boolean;
58
- defaultValue?: ConnectionParameterValue;
59
- }
60
- export type ConnectionConfigSchema = ConnectionParameter[];
61
51
  export interface ConnectionConfig {
62
52
  name: string;
63
53
  [key: string]: ConnectionParameterValue | undefined;
64
54
  }
65
- export interface ConnectionFactory {
66
- connectionName: string;
67
- configSchema: ConnectionConfigSchema;
68
- createConnection(connectionConfig: ConnectionConfig, dialectRegistrar?: (dialect: Dialect) => void): Connection & TestableConnection;
69
- }
70
55
  export interface ConnectionMetadata {
71
56
  url?: string;
72
57
  }
@@ -105,7 +90,7 @@ export interface PersistSQLResults extends Connection {
105
90
  manifestTemporaryTable(sqlCommand: string): Promise<string>;
106
91
  }
107
92
  export interface StreamingConnection extends Connection {
108
- runSQLStream(sqlCommand: string, options?: RunSQLOptions): AsyncIterableIterator<QueryDataRow>;
93
+ runSQLStream(sqlCommand: string, options?: RunSQLOptions): AsyncIterableIterator<QueryRecord>;
109
94
  }
110
95
  /**
111
96
  * A mapping of connection names to connections.
@@ -74,6 +74,7 @@ export declare abstract class Dialect {
74
74
  supportsBigIntPrecision: boolean;
75
75
  supportsComplexFilteredSources: boolean;
76
76
  supportsTempTables: boolean;
77
+ maxIdentifierLength: number;
77
78
  hasModOperator: boolean;
78
79
  supportsLeftJoinUnnest: boolean;
79
80
  requiresExplicitUnnestOrdering: boolean;
@@ -368,7 +369,7 @@ export declare abstract class Dialect {
368
369
  sqlCastPrep(cast: TypecastExpr): {
369
370
  op: string;
370
371
  srcTypeDef: BasicAtomicTypeDef | undefined;
371
- dstTypeDef: BasicAtomicTypeDef | undefined;
372
+ dstTypeDef: AtomicTypeDef | undefined;
372
373
  dstSQLType: string;
373
374
  };
374
375
  /**
@@ -95,6 +95,9 @@ class Dialect {
95
95
  this.supportsComplexFilteredSources = true;
96
96
  // can create temp tables
97
97
  this.supportsTempTables = true;
98
+ // Maximum length of a table/view identifier. Used to truncate
99
+ // generated temp table names. 128 is a safe default for most databases.
100
+ this.maxIdentifierLength = 128;
98
101
  this.hasModOperator = true;
99
102
  // can LEFT JOIN UNNEST
100
103
  this.supportsLeftJoinUnnest = true;
@@ -289,9 +289,30 @@ class DuckDBDialect extends pg_impl_1.PostgresBase {
289
289
  else if (malloyType.type === 'string') {
290
290
  return 'varchar';
291
291
  }
292
- if (malloyType.type === 'timestamptz') {
292
+ else if (malloyType.type === 'timestamptz') {
293
293
  return 'timestamp with time zone';
294
294
  }
295
+ else if (malloyType.type === 'record') {
296
+ const typeSpec = [];
297
+ for (const f of malloyType.fields) {
298
+ if ((0, malloy_types_1.isAtomic)(f)) {
299
+ typeSpec.push(`${this.sqlMaybeQuoteIdentifier(f.name)} ${this.malloyTypeToSQLType(f)}`);
300
+ }
301
+ }
302
+ return `STRUCT(${typeSpec.join(', ')})`;
303
+ }
304
+ else if (malloyType.type === 'array') {
305
+ if ((0, malloy_types_1.isRepeatedRecord)(malloyType)) {
306
+ const typeSpec = [];
307
+ for (const f of malloyType.fields) {
308
+ if ((0, malloy_types_1.isAtomic)(f)) {
309
+ typeSpec.push(`${this.sqlMaybeQuoteIdentifier(f.name)} ${this.malloyTypeToSQLType(f)}`);
310
+ }
311
+ }
312
+ return `STRUCT(${typeSpec.join(', ')})[]`;
313
+ }
314
+ return `${this.malloyTypeToSQLType(malloyType.elementTypeDef)}[]`;
315
+ }
295
316
  return malloyType.type;
296
317
  }
297
318
  parseDuckDBType(sqlType) {
@@ -31,6 +31,7 @@ export declare class MySQLDialect extends Dialect {
31
31
  compoundObjectInSchema: boolean;
32
32
  booleanType: BooleanTypeSupport;
33
33
  orderByClause: OrderByClauseType;
34
+ maxIdentifierLength: number;
34
35
  malloyTypeToSQLType(malloyType: AtomicTypeDef): string;
35
36
  sqlTypeToMalloyType(sqlType: string): BasicAtomicTypeDef;
36
37
  quoteTablePath(tablePath: string): string;
@@ -120,6 +120,7 @@ class MySQLDialect extends dialect_1.Dialect {
120
120
  this.compoundObjectInSchema = false;
121
121
  this.booleanType = 'simulated';
122
122
  this.orderByClause = 'ordinal';
123
+ this.maxIdentifierLength = 64;
123
124
  }
124
125
  malloyTypeToSQLType(malloyType) {
125
126
  switch (malloyType.type) {
@@ -26,6 +26,7 @@ export declare class PostgresDialect extends PostgresBase {
26
26
  supportsComplexFilteredSources: boolean;
27
27
  compoundObjectInSchema: boolean;
28
28
  likeEscape: boolean;
29
+ maxIdentifierLength: number;
29
30
  quoteTablePath(tablePath: string): string;
30
31
  sqlGroupSetTable(groupSetCount: number): string;
31
32
  sqlAnyValue(groupSet: number, fieldName: string): string;
@@ -97,6 +97,7 @@ class PostgresDialect extends pg_impl_1.PostgresBase {
97
97
  this.supportsComplexFilteredSources = false;
98
98
  this.compoundObjectInSchema = false;
99
99
  this.likeEscape = false;
100
+ this.maxIdentifierLength = 63;
100
101
  }
101
102
  quoteTablePath(tablePath) {
102
103
  return tablePath
@@ -331,6 +332,15 @@ class PostgresDialect extends pg_impl_1.PostgresBase {
331
332
  else if (malloyType.type === 'string') {
332
333
  return 'varchar';
333
334
  }
335
+ else if (malloyType.type === 'record') {
336
+ throw new Error('PostgreSQL does not support CAST to record type');
337
+ }
338
+ else if (malloyType.type === 'array') {
339
+ if ((0, malloy_types_1.isRepeatedRecord)(malloyType)) {
340
+ throw new Error('PostgreSQL does not support CAST to array of records');
341
+ }
342
+ return `${this.malloyTypeToSQLType(malloyType.elementTypeDef)}[]`;
343
+ }
334
344
  return malloyType.type;
335
345
  }
336
346
  sqlTypeToMalloyType(rawSqlType) {
@@ -377,6 +377,27 @@ ${(0, utils_1.indent)(sql)}
377
377
  return 'FLOAT64';
378
378
  }
379
379
  }
380
+ else if (malloyType.type === 'record') {
381
+ const typeSpec = [];
382
+ for (const f of malloyType.fields) {
383
+ if ((0, malloy_types_1.isAtomic)(f)) {
384
+ typeSpec.push(`${f.name} ${this.malloyTypeToSQLType(f)}`);
385
+ }
386
+ }
387
+ return `STRUCT<${typeSpec.join(', ')}>`;
388
+ }
389
+ else if (malloyType.type === 'array') {
390
+ if ((0, malloy_types_1.isRepeatedRecord)(malloyType)) {
391
+ const typeSpec = [];
392
+ for (const f of malloyType.fields) {
393
+ if ((0, malloy_types_1.isAtomic)(f)) {
394
+ typeSpec.push(`${f.name} ${this.malloyTypeToSQLType(f)}`);
395
+ }
396
+ }
397
+ return `ARRAY<STRUCT<${typeSpec.join(', ')}>>`;
398
+ }
399
+ return `ARRAY<${this.malloyTypeToSQLType(malloyType.elementTypeDef)}>`;
400
+ }
380
401
  return malloyType.type;
381
402
  }
382
403
  sqlTypeToMalloyType(sqlType) {
package/dist/index.d.ts CHANGED
@@ -1,14 +1,16 @@
1
1
  export { DuckDBDialect, StandardSQLDialect, TrinoDialect, PostgresDialect, SnowflakeDialect, MySQLDialect, registerDialect, arg, qtz, overload, minScalar, anyExprType, minAggregate, maxScalar, sql, makeParam, param, variadicParam, literal, spread, Dialect, TinyParser, } from './dialect';
2
2
  export type { DialectFieldList, DialectFunctionOverloadDef, QueryInfo, MalloyStandardFunctionImplementations, DefinitionBlueprint, DefinitionBlueprintMap, OverloadedDefinitionBlueprint, TinyToken, } from './dialect';
3
- export type { QueryDataRow, StructDef, TableSourceDef, SQLSourceDef, SourceDef, JoinFieldDef, NamedSourceDefs, MalloyQueryData, DateUnit, ExtractUnit, TimestampUnit, TemporalFieldType, QueryData, QueryValue, Expr, FilterCondition, Argument, Parameter, FieldDef, PipeSegment, QueryFieldDef, IndexFieldDef, TurtleDef, SearchValueMapResult, SearchIndexResult, ModelDef, Query, QueryResult, QueryResultDef, QueryRunStats, QueryScalar, NamedQueryDef, NamedModelObject, ExpressionType, FunctionDef, FunctionOverloadDef, FunctionParameterDef, ExpressionValueType, TypeDesc, FunctionParamTypeDesc, DocumentLocation, DocumentRange, DocumentPosition, Sampling, Annotation, BasicAtomicTypeDef, BasicAtomicDef, AtomicTypeDef, AtomicFieldDef, ArrayDef, ArrayTypeDef, RecordTypeDef, RepeatedRecordTypeDef, RecordDef, RepeatedRecordDef, RecordLiteralNode, StringLiteralNode, ArrayLiteralNode, SourceComponentInfo, DateLiteralNode, TimestampLiteralNode, TimestamptzLiteralNode, TimeLiteralExpr, TypecastExpr, BuildManifest, BuildManifestEntry, } from './model';
4
- export { isSourceDef, isBasicAtomic, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isBasicArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, isTimestampUnit, isDateUnit, constantExprToSQL, } from './model';
3
+ export type { QueryRecord, StructDef, TableSourceDef, SQLSourceDef, SourceDef, JoinFieldDef, NamedSourceDefs, MalloyQueryData, DateUnit, ExtractUnit, TimestampUnit, TemporalFieldType, QueryData, QueryValue, Expr, FilterCondition, Argument, Parameter, FieldDef, PipeSegment, QueryFieldDef, IndexFieldDef, TurtleDef, SearchValueMapResult, SearchIndexResult, ModelDef, Query, QueryResult, QueryResultDef, QueryRunStats, QueryScalar, NamedQueryDef, NamedModelObject, ExpressionType, FunctionDef, FunctionOverloadDef, FunctionParameterDef, ExpressionValueType, TypeDesc, FunctionParamTypeDesc, DocumentLocation, DocumentRange, DocumentPosition, Sampling, Annotation, BasicAtomicTypeDef, BasicAtomicDef, AtomicTypeDef, AtomicFieldDef, ArrayDef, ArrayTypeDef, RecordTypeDef, RepeatedRecordTypeDef, RecordDef, RepeatedRecordDef, RecordLiteralNode, StringLiteralNode, ArrayLiteralNode, SourceComponentInfo, DateLiteralNode, TimestampLiteralNode, TimestamptzLiteralNode, TimeLiteralExpr, TypecastExpr, BuildManifest, BuildManifestEntry, } from './model';
4
+ export { isSourceDef, isAtomic, isBasicAtomic, isCompoundArrayData, isJoined, isJoinedSource, isSamplingEnable, isSamplingPercent, isSamplingRows, isRepeatedRecord, isBasicArray, mkArrayDef, mkFieldDef, expressionIsAggregate, expressionIsAnalytic, expressionIsCalculation, expressionIsScalar, expressionIsUngroupedAggregate, indent, composeSQLExpr, isTimestampUnit, isDateUnit, constantExprToSQL, } from './model';
5
5
  export { malloyToQuery, MalloyTranslator, } from './lang';
6
6
  export type { LogMessage, TranslateResponse } from './lang';
7
7
  export { Model, Malloy, Runtime, AtomicFieldType, ConnectionRuntime, SingleConnectionRuntime, EmptyURLReader, InMemoryURLReader, FixedConnectionMap, MalloyError, JoinRelationship, SourceRelationship, DateTimeframe, TimestampTimeframe, PreparedResult, Result, QueryMaterializer, CSVWriter, JSONWriter, Parse, DataWriter, Explore, InMemoryModelCache, CacheManager, } from './api/foundation';
8
8
  export type { PreparedQuery, Field, AtomicField, ExploreField, QueryField, SortableField, DataArray, DataRecord, DataColumn, DataArrayOrRecord, Loggable, ModelMaterializer, DocumentTablePath, DocumentSymbol, ResultJSON, PreparedResultJSON, PreparedResultMaterializer, ExploreMaterializer, WriteStream, SerializedExplore, ModelCache, CachedModel, DateField, TimestampField, } from './api/foundation';
9
9
  export type { QueryOptionsReader, RunSQLOptions } from './run_sql_options';
10
10
  export type { EventStream, ModelString, ModelURL, QueryString, QueryURL, URLReader, InvalidationKey, } from './runtime_types';
11
- export type { Connection, ConnectionConfig, ConnectionFactory, ConnectionParameter, ConnectionParameterValue, ConnectionConfigSchema, FetchSchemaOptions, InfoConnection, LookupConnection, PersistSQLResults, PooledConnection, TestableConnection, StreamingConnection, } from './connection/types';
11
+ export type { Connection, ConnectionConfig, ConnectionParameterValue, FetchSchemaOptions, InfoConnection, LookupConnection, PersistSQLResults, PooledConnection, TestableConnection, StreamingConnection, } from './connection/types';
12
+ export { registerConnectionType, getConnectionProperties, getRegisteredConnectionTypes, readConnectionsConfig, writeConnectionsConfig, createConnectionsFromConfig, } from './connection/registry';
13
+ export type { ConnectionTypeFactory, ConnectionPropertyType, ConnectionPropertyDefinition, ConnectionTypeDef, ConnectionConfigEntry, ConnectionsConfig, } from './connection/registry';
12
14
  export { toAsyncGenerator } from './connection_utils';
13
15
  export { modelDefToModelInfo, sourceDefToSourceInfo, writeMalloyObjectToTag, extractMalloyObjectFromTag, } from './to_stable';
14
16
  export * as API from './api';