@malloydata/malloy 0.0.314 → 0.0.316

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.
@@ -291,25 +291,33 @@ class MySQLDialect extends dialect_1.Dialect {
291
291
  sqlNowExpr() {
292
292
  return 'LOCALTIMESTAMP';
293
293
  }
294
- // truncToUnit(sql, unit: string): string {
295
- // return `EXTRACT(${unit} FROM ${sql})`;
296
- // }
297
294
  sqlTruncExpr(qi, trunc) {
298
- // LTNOTE: how come this can be undefined?
299
- let truncThis = trunc.e.sql || 'why could this be undefined';
300
- if (trunc.units === 'week') {
301
- truncThis = `DATE_SUB(${truncThis}, INTERVAL DAYOFWEEK(${truncThis}) - 1 DAY)`;
302
- }
295
+ const truncThis = trunc.e.sql || 'internal-error-in-sql-generation';
296
+ const week = trunc.units === 'week';
297
+ // Only do timezone conversion for timestamps, not dates
303
298
  if (malloy_types_1.TD.isTimestamp(trunc.e.typeDef)) {
304
299
  const tz = (0, dialect_1.qtz)(qi);
305
300
  if (tz) {
301
+ // Convert timestamp to the query timezone (civil time)
306
302
  const civilSource = `(CONVERT_TZ(${truncThis}, 'UTC','${tz}'))`;
307
- const civilTrunc = `${this.truncToUnit(civilSource, trunc.units)}`;
303
+ // For week truncation, we need to adjust to Sunday in the civil timezone
304
+ // DAYOFWEEK returns 1=Sunday, 2=Monday, etc., so subtract (DAYOFWEEK-1) days
305
+ const adjustedSource = week
306
+ ? `DATE_SUB(${civilSource}, INTERVAL DAYOFWEEK(${civilSource}) - 1 DAY)`
307
+ : civilSource;
308
+ // Truncate to the appropriate unit in civil time
309
+ const civilTrunc = `${this.truncToUnit(adjustedSource, trunc.units)}`;
310
+ // Convert the truncated civil time back to UTC
308
311
  const truncTsTz = `CONVERT_TZ(${civilTrunc}, '${tz}', 'UTC')`;
309
312
  return `(${truncTsTz})`; // TODO: should it cast?
310
313
  }
311
314
  }
312
- const result = `${this.truncToUnit(truncThis, trunc.units)}`;
315
+ // For dates (civil time) or timestamps without query timezone
316
+ // do the week adjustment before truncating
317
+ const adjustedThis = week
318
+ ? `DATE_SUB(${truncThis}, INTERVAL DAYOFWEEK(${truncThis}) - 1 DAY)`
319
+ : truncThis;
320
+ const result = `${this.truncToUnit(adjustedThis, trunc.units)}`;
313
321
  return result;
314
322
  }
315
323
  truncToUnit(expr, units) {
@@ -27,7 +27,7 @@ class PostgresBase extends dialect_1.Dialect {
27
27
  const tz = (0, dialect_1.qtz)(qi);
28
28
  if (tz) {
29
29
  // get a civil version of the time in the query time zone
30
- const civilSource = `(${truncThis}::TIMESTAMPTZ AT TIME ZONE '${tz}')`;
30
+ const civilSource = `((${truncThis})::TIMESTAMPTZ AT TIME ZONE '${tz}')`;
31
31
  // do truncation in that time space
32
32
  let civilTrunc = `DATE_TRUNC('${df.units}', ${civilSource})`;
33
33
  if (week) {
@@ -20,7 +20,6 @@ type TranslatedQueryField = {
20
20
  * created and paired when a QueryOperationSpace is created.
21
21
  */
22
22
  export declare abstract class QueryOperationSpace extends RefinedSpace implements QueryFieldSpace {
23
- readonly queryInputSpace: SourceFieldSpace;
24
23
  readonly nestParent: QueryOperationSpace | undefined;
25
24
  readonly astEl: MalloyElement;
26
25
  protected exprSpace: QueryInputSpace;
@@ -83,7 +83,6 @@ class QueryOperationSpace extends refined_space_1.RefinedSpace {
83
83
  }
84
84
  constructor(queryInputSpace, refineThis, nestParent, astEl) {
85
85
  super(queryInputSpace.emptyStructDef());
86
- this.queryInputSpace = queryInputSpace;
87
86
  this.nestParent = nestParent;
88
87
  this.astEl = astEl;
89
88
  this.expandedWild = {};
@@ -260,7 +259,7 @@ class QuerySpace extends QueryOperationSpace {
260
259
  if (typeDesc.type === 'turtle') {
261
260
  const pipeline = typeDesc.pipeline;
262
261
  const lastSegment = pipeline[pipeline.length - 1];
263
- const outputStruct = (_b = lastSegment === null || lastSegment === void 0 ? void 0 : lastSegment.outputStruct) !== null && _b !== void 0 ? _b : error_factory_1.ErrorFactory.structDef;
262
+ const outputStruct = (_b = lastSegment === null || lastSegment === void 0 ? void 0 : lastSegment.outputStruct) !== null && _b !== void 0 ? _b : this.exprSpace.emptyStructDef();
264
263
  const isRepeated = lastSegment
265
264
  ? model.isQuerySegment(lastSegment)
266
265
  ? lastSegment.isRepeated
@@ -71,22 +71,36 @@ function refine(logTo, refineTo, refineFrom) {
71
71
  : undefined;
72
72
  if ((0, model_1.isQuerySegment)(from) && (0, model_1.isQuerySegment)(to)) {
73
73
  const overlappingFields = [];
74
- const nonOverlappingFields = [];
74
+ const missingOut = [];
75
75
  const existingNames = new Map(to.queryFields.map((f) => [
76
76
  (0, field_utils_1.nameFromDef)(f),
77
77
  f,
78
78
  ]));
79
+ const outputFields = [...to.outputStruct.fields];
80
+ const queryFields = [...to.queryFields];
79
81
  for (const field of from.queryFields) {
80
- if (existingNames.has((0, field_utils_1.nameFromDef)(field))) {
81
- overlappingFields.push(field);
82
+ const fieldName = (0, field_utils_1.nameFromDef)(field);
83
+ if (existingNames.has(fieldName)) {
84
+ overlappingFields.push(fieldName);
82
85
  }
83
86
  else {
84
- nonOverlappingFields.push(field);
87
+ queryFields.push(field);
88
+ const outField = from.outputStruct.fields.find(f => f.name === fieldName);
89
+ if (outField) {
90
+ outputFields.push(outField);
91
+ }
92
+ else {
93
+ missingOut.push(fieldName);
94
+ }
85
95
  }
86
96
  }
87
- to.queryFields = [...to.queryFields, ...nonOverlappingFields];
97
+ to.queryFields = queryFields;
98
+ to.outputStruct.fields = outputFields;
88
99
  if (overlappingFields.length > 0) {
89
- logTo.logError('name-conflict-in-refinement', `overlapping fields in refinement: ${overlappingFields.map(field_utils_1.nameFromDef)}`);
100
+ logTo.logError('name-conflict-in-refinement', `overlapping fields in refinement: ${overlappingFields.join(', ')}`);
101
+ }
102
+ if (missingOut.length > 0) {
103
+ logTo.logError('name-conflict-in-refinement', `missing output fields in refinement: ${missingOut.join(', ')}`);
90
104
  }
91
105
  to.fieldUsage = (0, composite_source_utils_1.mergeFieldUsage)(to.fieldUsage, from.fieldUsage);
92
106
  }
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const MALLOY_VERSION = "0.0.314";
1
+ export declare const MALLOY_VERSION = "0.0.316";
package/dist/version.js CHANGED
@@ -2,5 +2,5 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MALLOY_VERSION = void 0;
4
4
  // generated with 'generate-version-file' script; do not edit manually
5
- exports.MALLOY_VERSION = '0.0.314';
5
+ exports.MALLOY_VERSION = '0.0.316';
6
6
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@malloydata/malloy",
3
- "version": "0.0.314",
3
+ "version": "0.0.316",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": "./dist/index.js",
@@ -41,9 +41,9 @@
41
41
  "generate-version-file": "VERSION=$(npm pkg get version --workspaces=false | tr -d \\\")\necho \"// generated with 'generate-version-file' script; do not edit manually\\nexport const MALLOY_VERSION = '$VERSION';\" > src/version.ts"
42
42
  },
43
43
  "dependencies": {
44
- "@malloydata/malloy-filter": "0.0.314",
45
- "@malloydata/malloy-interfaces": "0.0.314",
46
- "@malloydata/malloy-tag": "0.0.314",
44
+ "@malloydata/malloy-filter": "0.0.316",
45
+ "@malloydata/malloy-interfaces": "0.0.316",
46
+ "@malloydata/malloy-tag": "0.0.316",
47
47
  "antlr4ts": "^0.5.0-alpha.4",
48
48
  "assert": "^2.0.0",
49
49
  "jaro-winkler": "^0.2.8",