@malloydata/malloy 0.0.11-dev221202152346 → 0.0.11

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.
@@ -89,9 +89,8 @@ function prettyNeeds(response) {
89
89
  needString += "Tables:\n";
90
90
  response.tables.forEach((table) => (needString += ` - ${table}`));
91
91
  }
92
- if (response.sqlStructs) {
93
- needString += "SQL Structs:\n";
94
- response.sqlStructs.forEach((sql) => (needString += ` - ${sql.as || "(unnamed sql struct)"}`));
92
+ if (response.compileSQL) {
93
+ needString += `Compile SQL: ${response.compileSQL.name}`;
95
94
  }
96
95
  if (response.urls) {
97
96
  needString += "URLs:\n";
@@ -112,12 +111,56 @@ function checkForNeededs(trans) {
112
111
  pass: true,
113
112
  };
114
113
  }
114
+ function highlightError(dl, txt) {
115
+ if (dl == undefined) {
116
+ return "~Location Undefined~";
117
+ }
118
+ const { start, end } = dl.range;
119
+ const output = [
120
+ `${start.line}:${start.character}-${end.line}:${end.character}`,
121
+ ];
122
+ let errStart = start.character;
123
+ const doc = txt.split("\n");
124
+ for (let line = start.line; line <= end.line; line += 1) {
125
+ const lineText = doc[line];
126
+ const lineStr = ` ${line}`.slice(-5);
127
+ output.push(`${lineStr}| ${lineText}`);
128
+ const upToError = ` | ` + " ".repeat(errStart);
129
+ let errLen = end.character - errStart;
130
+ if (line < end.line) {
131
+ errLen = lineText.length - errStart;
132
+ errStart = 0;
133
+ }
134
+ output.push(upToError + "-".repeat(errLen));
135
+ }
136
+ return output.join("\n");
137
+ }
138
+ function unlocatedStructDef(sd) {
139
+ const ret = { ...sd };
140
+ ret.fields = sd.fields.map((f) => {
141
+ const nf = { ...f };
142
+ delete nf.location;
143
+ return nf;
144
+ });
145
+ delete ret.location;
146
+ return ret;
147
+ }
115
148
  expect.extend({
116
- toCompile: function (x) {
149
+ toCompile: function (s) {
150
+ const x = new BetaModel(s);
151
+ x.compile();
152
+ const errorCheck = checkForErrors(x);
153
+ if (!errorCheck.pass) {
154
+ return errorCheck;
155
+ }
156
+ x.translate();
157
+ return checkForNeededs(x);
158
+ },
159
+ modelParsed: function (x) {
117
160
  x.compile();
118
161
  return checkForErrors(x);
119
162
  },
120
- toTranslate: function (x) {
163
+ modelCompiled: function (x) {
121
164
  x.compile();
122
165
  const errorCheck = checkForErrors(x);
123
166
  if (!errorCheck.pass) {
@@ -131,7 +174,7 @@ expect.extend({
131
174
  },
132
175
  toReturnType: function (functionCall, returnType) {
133
176
  const exprModel = new BetaModel(`explore: x is a { dimension: d is ${functionCall} }`);
134
- expect(exprModel).toTranslate();
177
+ expect(exprModel).modelCompiled();
135
178
  const x = exprModel.getSourceDef("x");
136
179
  expect(x).toBeDefined();
137
180
  if (x) {
@@ -223,6 +266,21 @@ expect.extend({
223
266
  };
224
267
  }
225
268
  },
269
+ isLocationIn: function (checkAt, at, text) {
270
+ if (this.equals(at, checkAt)) {
271
+ return {
272
+ pass: true,
273
+ message: () => `Locations match`,
274
+ };
275
+ }
276
+ const errMsg = `Locations do not match\n` +
277
+ `Expected: ${highlightError(at, text)}\n` +
278
+ `Received: ${highlightError(checkAt, text)}\n`;
279
+ return {
280
+ pass: false,
281
+ message: () => errMsg,
282
+ };
283
+ },
226
284
  });
227
285
  class BetaExpression extends Testable {
228
286
  constructor(src) {
@@ -254,14 +312,14 @@ class BetaExpression extends Testable {
254
312
  }
255
313
  function exprOK(s) {
256
314
  return () => {
257
- expect(new BetaExpression(s)).toCompile();
315
+ expect(new BetaExpression(s)).modelParsed();
258
316
  return undefined;
259
317
  };
260
318
  }
261
319
  function modelOK(s) {
262
320
  return () => {
263
321
  const m = new BetaModel(s);
264
- expect(m).toTranslate();
322
+ expect(m).modelCompiled();
265
323
  return undefined;
266
324
  };
267
325
  }
@@ -293,9 +351,9 @@ function badModel(s, msg) {
293
351
  describe("model statements", () => {
294
352
  describe("explore:", () => {
295
353
  test("explore table", modelOK(`explore: testA is table('aTable')`));
296
- test("explore shorcut fitlered table", modelOK(`
297
- explore: testA is table('aTable') {? astr ~ 'a%' }
298
- `));
354
+ test("explore shorcut fitlered table", () => {
355
+ expect(`explore: testA is table('aTable') {? astr ~ 'a%' } `).toCompile();
356
+ });
299
357
  test("explore fitlered table", modelOK(`
300
358
  explore: testA is table('aTable') { where: astr ~ 'a%' }
301
359
  `));
@@ -304,7 +362,7 @@ describe("model statements", () => {
304
362
  test("refine explore", modelOK(`explore: aa is a { dimension: a is astr }`));
305
363
  test("source refinement preserves original", () => {
306
364
  const x = new BetaModel("source: na is a + { dimension: one is 1 }");
307
- expect(x).toTranslate();
365
+ expect(x).modelCompiled();
308
366
  const a = x.getSourceDef("a");
309
367
  if (a) {
310
368
  const aFields = a.fields.map((f) => f.as || f.name);
@@ -352,7 +410,7 @@ describe("model statements", () => {
352
410
  query: q is a -> { aggregate: acount is count() }
353
411
  query: nq is -> q + { group_by: astr }
354
412
  `);
355
- expect(x).toTranslate();
413
+ expect(x).modelCompiled();
356
414
  const q = x.getQuery("q");
357
415
  expect(q).toBeDefined();
358
416
  if (q) {
@@ -365,7 +423,7 @@ describe("model statements", () => {
365
423
  query: q is ab -> { aggregate: acount }
366
424
  query: nq is -> q -> { project: * }
367
425
  `);
368
- expect(x).toTranslate();
426
+ expect(x).modelCompiled();
369
427
  const q = x.getQuery("q");
370
428
  expect(q).toBeDefined();
371
429
  if (q) {
@@ -473,7 +531,7 @@ describe("model statements", () => {
473
531
  });
474
532
  test("relative imports", () => {
475
533
  const docParse = new BetaModel(`import "../parent.malloy"`);
476
- expect(docParse).toCompile();
534
+ expect(docParse).modelParsed();
477
535
  const xr = docParse.unresolved();
478
536
  expect(xr).toEqual({ urls: ["internal://test/parent.malloy"] });
479
537
  docParse.update({
@@ -481,11 +539,11 @@ describe("model statements", () => {
481
539
  "internal://test/parent.malloy": `source: aa is table('aTable')`,
482
540
  },
483
541
  });
484
- expect(docParse).toTranslate();
542
+ expect(docParse).modelCompiled();
485
543
  });
486
544
  test("relative imports with errors", () => {
487
545
  const docParse = new BetaModel(`import "../parent.malloy"`);
488
- expect(docParse).toCompile();
546
+ expect(docParse).modelParsed();
489
547
  const xr = docParse.unresolved();
490
548
  expect(xr).toEqual({ urls: ["internal://test/parent.malloy"] });
491
549
  docParse.update({
@@ -510,7 +568,7 @@ describe("model statements", () => {
510
568
  import "middle"
511
569
  `);
512
570
  fullModel.update({ urls: srcFiles });
513
- expect(fullModel).toTranslate();
571
+ expect(fullModel).modelCompiled();
514
572
  const ms = fullModel.getSourceDef("midSrc");
515
573
  expect(ms).toBeDefined();
516
574
  if (ms) {
@@ -595,7 +653,7 @@ describe("explore properties", () => {
595
653
  test("rename", modelOK("explore: c is a { rename: nn is ai }"));
596
654
  test("accept single", () => {
597
655
  const onlyAstr = new BetaModel("explore: c is a { accept: astr }");
598
- expect(onlyAstr).toTranslate();
656
+ expect(onlyAstr).modelCompiled();
599
657
  const c = onlyAstr.getSourceDef("c");
600
658
  if (c) {
601
659
  expect(c.fields.length).toBe(1);
@@ -604,7 +662,7 @@ describe("explore properties", () => {
604
662
  test("accept multi", modelOK("explore: c is a { accept: astr, af }"));
605
663
  test("except single", () => {
606
664
  const noAstr = new BetaModel("explore: c is a { except: astr }");
607
- expect(noAstr).toTranslate();
665
+ expect(noAstr).modelCompiled();
608
666
  const c = noAstr.getSourceDef("c");
609
667
  if (c) {
610
668
  const foundAstr = c.fields.find((f) => f.name == "astr");
@@ -612,7 +670,7 @@ describe("explore properties", () => {
612
670
  }
613
671
  });
614
672
  test("except multi", modelOK("explore: c is a { except: astr, af }"));
615
- test("explore-query", modelOK("explore: c is a {query: q is { group_by: astr }}"));
673
+ test("explore-query", modelOK("explore: c is a {query: q is { group_by: astr } }"));
616
674
  test("refined explore-query", modelOK(`
617
675
  explore: abNew is ab {
618
676
  query: for1 is aturtle {? ai = 1 }
@@ -660,7 +718,7 @@ describe("qops", () => {
660
718
  test("index join.*", modelOK("query:ab->{index: ab.*}"));
661
719
  test("index multiple", () => {
662
720
  const model = new BetaModel("query:a->{index: af, astr}");
663
- expect(model).toTranslate();
721
+ expect(model).modelCompiled();
664
722
  const q = model.getQuery(0);
665
723
  expect(q).toBeDefined();
666
724
  if (q) {
@@ -671,7 +729,7 @@ describe("qops", () => {
671
729
  });
672
730
  test("index star", () => {
673
731
  const model = new BetaModel("query:a->{index: *, astr}");
674
- expect(model).toTranslate();
732
+ expect(model).modelCompiled();
675
733
  const q = model.getQuery(0);
676
734
  expect(q).toBeDefined();
677
735
  if (q) {
@@ -685,7 +743,7 @@ describe("qops", () => {
685
743
  test("index unsampled", modelOK("query:a->{index: *; sample: false}"));
686
744
  test("index sample-percent", () => {
687
745
  const model = new BetaModel("query:a->{index: *; sample: 42%}");
688
- expect(model).toTranslate();
746
+ expect(model).modelCompiled();
689
747
  const q = model.getQuery(0);
690
748
  expect(q).toBeDefined();
691
749
  if (q) {
@@ -716,7 +774,7 @@ describe("qops", () => {
716
774
  test("where multiple", modelOK("query:a->{ group_by: astr; where: af > 10,astr~'a%' }"));
717
775
  test(`filters preserve source formatting in code:`, () => {
718
776
  const model = new BetaModel(`source: notb is a + { where: astr != 'b' }`);
719
- expect(model).toTranslate();
777
+ expect(model).modelCompiled();
720
778
  const notb = model.getSourceDef("notb");
721
779
  expect(notb).toBeDefined();
722
780
  if (notb) {
@@ -729,7 +787,7 @@ describe("qops", () => {
729
787
  });
730
788
  test(`field expressions preserve source formatting in code:`, () => {
731
789
  const model = new BetaModel(`source: notb is a + { dimension: d is 1 + 2 }`);
732
- expect(model).toTranslate();
790
+ expect(model).modelCompiled();
733
791
  const notb = model.getSourceDef("notb");
734
792
  expect(notb).toBeDefined();
735
793
  if (notb) {
@@ -765,7 +823,7 @@ describe("qops", () => {
765
823
  }
766
824
  query: nab -> xturtle + { aggregate: aratio }
767
825
  `);
768
- expect(m).toTranslate();
826
+ expect(m).modelCompiled();
769
827
  const t = m.translate();
770
828
  if (t.translated) {
771
829
  const q = t.translated.queryList[0].pipeline[0];
@@ -789,7 +847,7 @@ describe("qops", () => {
789
847
  aggregate: aratio
790
848
  }
791
849
  `);
792
- expect(m).toTranslate();
850
+ expect(m).modelCompiled();
793
851
  const t = m.translate();
794
852
  if (t.translated) {
795
853
  const q = t.translated.queryList[0].pipeline[0];
@@ -813,7 +871,7 @@ describe("qops", () => {
813
871
  group_by: foo is bb.astr
814
872
  }
815
873
  `);
816
- expect(m).toTranslate();
874
+ expect(m).modelCompiled();
817
875
  const t = m.translate();
818
876
  if (t.translated) {
819
877
  const q = t.translated.queryList[0].pipeline[0];
@@ -989,7 +1047,7 @@ describe("expressions", () => {
989
1047
  var _a, _b;
990
1048
  const modelSrc = `query: z is a -> { group_by: x is 1+(3/4) }`;
991
1049
  const m = new BetaModel(modelSrc);
992
- expect(m).toTranslate();
1050
+ expect(m).modelCompiled();
993
1051
  const queryDef = (_b = (_a = m.translate()) === null || _a === void 0 ? void 0 : _a.translated) === null || _b === void 0 ? void 0 : _b.modelDef.contents.z;
994
1052
  expect(queryDef).toBeDefined();
995
1053
  expect(queryDef === null || queryDef === void 0 ? void 0 : queryDef.type).toBe("query");
@@ -1014,8 +1072,9 @@ describe("expressions", () => {
1014
1072
  }
1015
1073
  });
1016
1074
  });
1017
- describe("sql backdoor", () => {
1075
+ describe("sql:", () => {
1018
1076
  function makeSchemaResponse(sql) {
1077
+ const cname = sql.connection || "bigquery";
1019
1078
  return {
1020
1079
  type: "struct",
1021
1080
  name: sql.name,
@@ -1023,85 +1082,95 @@ describe("sql backdoor", () => {
1023
1082
  structSource: {
1024
1083
  type: "sql",
1025
1084
  method: "subquery",
1026
- sqlBlock: { ...sql },
1085
+ sqlBlock: {
1086
+ type: "sqlBlock",
1087
+ ...sql,
1088
+ selectStr: sql.select.filter((s) => typeof s == "string").join(""),
1089
+ },
1027
1090
  },
1028
- structRelationship: { type: "basetable", connectionName: "bigquery" },
1091
+ structRelationship: { type: "basetable", connectionName: cname },
1029
1092
  fields: test_translator_1.aTableDef.fields,
1030
1093
  };
1031
1094
  }
1032
- test("single sql statement", modelOK("sql: users is || SELECT * FROM USERS;;"));
1033
- test("connection shows up in model", () => {
1095
+ test("definition", () => {
1096
+ const selStmt = "SELECT * FROM aTable";
1034
1097
  const model = new BetaModel(`
1035
- sql: users IS || SELECT * FROM aTable ;; on "someConnection";
1036
- source: malloyUsers is from_sql(users) { primary_key: ai }
1098
+ sql: users IS {
1099
+ select: """${selStmt}"""
1100
+ connection: "aConnection"
1101
+ }
1037
1102
  `);
1038
1103
  const needReq = model.translate();
1039
- expect(model).toBeErrorless();
1040
- const needs = needReq === null || needReq === void 0 ? void 0 : needReq.sqlStructs;
1104
+ expect(model).modelParsed();
1105
+ const needs = needReq === null || needReq === void 0 ? void 0 : needReq.compileSQL;
1041
1106
  expect(needs).toBeDefined();
1042
1107
  if (needs) {
1043
- expect(needs.length).toBe(1);
1044
- const sql = (0, sql_block_1.makeSQLBlock)({
1045
- select: " SELECT * FROM aTable ",
1046
- connection: "someConnection",
1047
- });
1048
- expect(needs[0]).toMatchObject(sql);
1049
- const refKey = needs[0].name;
1108
+ const sql = (0, sql_block_1.makeSQLBlock)([{ sql: selStmt }], "aConnection");
1109
+ expect(needs).toMatchObject(sql);
1110
+ const refKey = needs.name;
1050
1111
  expect(refKey).toBeDefined();
1051
1112
  if (refKey) {
1052
- model.update({ sqlStructs: { [refKey]: makeSchemaResponse(sql) } });
1053
- expect(model).toTranslate();
1113
+ const sr = makeSchemaResponse(sql);
1114
+ model.update({ compileSQL: { [refKey]: sr } });
1115
+ expect(model).modelCompiled();
1116
+ expect(unlocatedStructDef(model.sqlBlocks[0])).toEqual(unlocatedStructDef({ ...sr, as: "users" }));
1054
1117
  }
1055
- const users = model.getSourceDef("malloyUsers");
1056
- expect(users).toBeDefined();
1057
- expect(users).toHaveProperty("structSource.sqlBlock.connection", "someConnection");
1058
1118
  }
1059
1119
  });
1060
- test("explore from sql", () => {
1120
+ test("source from sql", () => {
1121
+ const selStmt = "SELECT * FROM aTable";
1061
1122
  const model = new BetaModel(`
1062
- sql: users IS || SELECT * FROM aTable ;;
1123
+ sql: users IS { select: """${selStmt}""" }
1063
1124
  source: malloyUsers is from_sql(users) { primary_key: ai }
1064
1125
  `);
1126
+ expect(model).modelParsed();
1065
1127
  const needReq = model.translate();
1066
- expect(model).toBeErrorless();
1067
- const needs = needReq === null || needReq === void 0 ? void 0 : needReq.sqlStructs;
1128
+ const needs = needReq === null || needReq === void 0 ? void 0 : needReq.compileSQL;
1068
1129
  expect(needs).toBeDefined();
1069
1130
  if (needs) {
1070
- expect(needs.length).toBe(1);
1071
- const sql = (0, sql_block_1.makeSQLBlock)({ select: " SELECT * FROM aTable " });
1072
- expect(needs[0]).toMatchObject(sql);
1073
- const refKey = needs[0].name;
1074
- expect(refKey).toBeDefined();
1075
- if (refKey) {
1076
- model.update({ sqlStructs: { [refKey]: makeSchemaResponse(sql) } });
1077
- expect(model).toTranslate();
1078
- }
1131
+ const sql = (0, sql_block_1.makeSQLBlock)([{ sql: selStmt }], "aConnection");
1132
+ const refKey = needs.name;
1133
+ model.update({ compileSQL: { [refKey]: makeSchemaResponse(sql) } });
1134
+ expect(model).modelCompiled();
1135
+ const users = model.getSourceDef("malloyUsers");
1136
+ expect(users).toBeDefined();
1079
1137
  }
1080
1138
  });
1081
1139
  test("explore from imported sql-based-source", () => {
1140
+ const selStmt = "SELECT * FROM aTable";
1082
1141
  const createModel = `
1083
- sql: users IS || SELECT * FROM aTable ;;
1142
+ sql: users IS { select: """${selStmt}""" }
1084
1143
  source: malloyUsers is from_sql(users) { primary_key: ai }
1085
1144
  `;
1086
1145
  const model = new BetaModel(`
1087
1146
  import "createModel.malloy"
1088
- source: foo is malloyUsers
1147
+ source: importUsers is malloyUsers
1089
1148
  `);
1090
1149
  model.importZone.define("internal://test/langtests/createModel.malloy", createModel);
1150
+ expect(model).modelParsed();
1091
1151
  const needReq = model.translate();
1092
- expect(model).toBeErrorless();
1093
- const needs = needReq === null || needReq === void 0 ? void 0 : needReq.sqlStructs;
1152
+ const needs = needReq === null || needReq === void 0 ? void 0 : needReq.compileSQL;
1094
1153
  expect(needs).toBeDefined();
1095
- if (needs) {
1096
- expect(needs.length).toBe(1);
1097
- const sql = (0, sql_block_1.makeSQLBlock)({ select: " SELECT * FROM aTable " });
1098
- expect(needs[0]).toMatchObject(sql);
1099
- const refKey = needs[0].name;
1100
- expect(refKey).toBeDefined();
1101
- if (refKey) {
1102
- model.update({ sqlStructs: { [refKey]: makeSchemaResponse(sql) } });
1103
- expect(model).toTranslate();
1104
- }
1154
+ const sql = (0, sql_block_1.makeSQLBlock)([{ sql: selStmt }]);
1155
+ model.update({ compileSQL: { [sql.name]: makeSchemaResponse(sql) } });
1156
+ expect(model).modelCompiled();
1157
+ });
1158
+ it("turducken", () => {
1159
+ const m = new BetaModel(`
1160
+ sql: someSql is {
1161
+ select: """SELECT * FROM %{ a -> { group_by: astr } }% WHERE 1=1"""
1162
+ }
1163
+ `);
1164
+ expect(m).modelParsed();
1165
+ const compileSql = m.translate().compileSQL;
1166
+ expect(compileSql).toBeDefined();
1167
+ if (compileSql) {
1168
+ const select = compileSql.select[0];
1169
+ const star = compileSql.select[1];
1170
+ const where = compileSql.select[2];
1171
+ expect(select).toEqual({ sql: "SELECT * FROM " });
1172
+ expect((0, model_1.isSQLFragment)(star)).toBeFalsy();
1173
+ expect(where).toEqual({ sql: " WHERE 1=1" });
1105
1174
  }
1106
1175
  });
1107
1176
  });
@@ -1146,7 +1215,7 @@ describe("error handling", () => {
1146
1215
  test("undefined field ref in query", badModel(`query: ab -> { aggregate: xyzzy }`, "'xyzzy' is not defined"));
1147
1216
  // test("queries with anonymous expressions", () => {
1148
1217
  // const m = new BetaModel("query: a->{\n group_by: a+1\n}");
1149
- // expect(m).not.toCompile();
1218
+ // expect(m).not.modelParsed();
1150
1219
  // const errList = m.errors().errors;
1151
1220
  // const firstError = errList[0];
1152
1221
  // expect(firstError.message).toBe("Expressions in queries must have names");
@@ -1193,6 +1262,10 @@ describe("error handling", () => {
1193
1262
  `));
1194
1263
  });
1195
1264
  function getSelectOneStruct(sqlBlock) {
1265
+ const selectThis = sqlBlock.select[0];
1266
+ if (!(0, model_1.isSQLFragment)(selectThis)) {
1267
+ throw new Error("weird test support error sorry");
1268
+ }
1196
1269
  return {
1197
1270
  type: "struct",
1198
1271
  name: sqlBlock.name,
@@ -1200,7 +1273,11 @@ function getSelectOneStruct(sqlBlock) {
1200
1273
  structSource: {
1201
1274
  type: "sql",
1202
1275
  method: "subquery",
1203
- sqlBlock,
1276
+ sqlBlock: {
1277
+ type: "sqlBlock",
1278
+ name: sqlBlock.name,
1279
+ selectStr: selectThis.sql,
1280
+ },
1204
1281
  },
1205
1282
  structRelationship: { type: "basetable", connectionName: "bigquery" },
1206
1283
  fields: [{ type: "number", name: "one" }],
@@ -1210,19 +1287,19 @@ describe("source locations", () => {
1210
1287
  test("renamed explore location", () => {
1211
1288
  const source = (0, test_translator_1.markSource) `explore: ${"na is a"}`;
1212
1289
  const m = new BetaModel(source.code);
1213
- expect(m).toCompile();
1290
+ expect(m).modelParsed();
1214
1291
  expect((0, test_translator_1.getExplore)(m.modelDef, "na").location).toMatchObject(source.locations[0]);
1215
1292
  });
1216
1293
  test("refined explore location", () => {
1217
1294
  const source = (0, test_translator_1.markSource) `explore: ${"na is a {}"}`;
1218
1295
  const m = new BetaModel(source.code);
1219
- expect(m).toCompile();
1296
+ expect(m).modelParsed();
1220
1297
  expect((0, test_translator_1.getExplore)(m.modelDef, "na").location).toMatchObject(source.locations[0]);
1221
1298
  });
1222
1299
  test("location of defined dimension", () => {
1223
1300
  const source = (0, test_translator_1.markSource) `explore: na is a { dimension: ${"x is 1"} }`;
1224
1301
  const m = new BetaModel(source.code);
1225
- expect(m).toTranslate();
1302
+ expect(m).modelCompiled();
1226
1303
  const na = (0, test_translator_1.getExplore)(m.modelDef, "na");
1227
1304
  const x = (0, test_translator_1.getField)(na, "x");
1228
1305
  expect(x.location).toMatchObject(source.locations[0]);
@@ -1230,7 +1307,7 @@ describe("source locations", () => {
1230
1307
  test("location of defined measure", () => {
1231
1308
  const source = (0, test_translator_1.markSource) `explore: na is a { measure: ${"x is count()"} }`;
1232
1309
  const m = new BetaModel(source.code);
1233
- expect(m).toTranslate();
1310
+ expect(m).modelCompiled();
1234
1311
  const na = (0, test_translator_1.getExplore)(m.modelDef, "na");
1235
1312
  const x = (0, test_translator_1.getField)(na, "x");
1236
1313
  expect(x.location).toMatchObject(source.locations[0]);
@@ -1238,7 +1315,7 @@ describe("source locations", () => {
1238
1315
  test("location of defined query", () => {
1239
1316
  const source = (0, test_translator_1.markSource) `explore: na is a { query: ${"x is { group_by: y is 1 }"} }`;
1240
1317
  const m = new BetaModel(source.code);
1241
- expect(m).toTranslate();
1318
+ expect(m).modelCompiled();
1242
1319
  const na = (0, test_translator_1.getExplore)(m.modelDef, "na");
1243
1320
  const x = (0, test_translator_1.getField)(na, "x");
1244
1321
  expect(x.location).toMatchObject(source.locations[0]);
@@ -1251,7 +1328,7 @@ describe("source locations", () => {
1251
1328
  }
1252
1329
  }`;
1253
1330
  const m = new BetaModel(source.code);
1254
- expect(m).toTranslate();
1331
+ expect(m).modelCompiled();
1255
1332
  const na = (0, test_translator_1.getExplore)(m.modelDef, "na");
1256
1333
  const x = (0, test_translator_1.getQueryField)(na, "x");
1257
1334
  const y = (0, test_translator_1.getField)(x.pipeline[0], "y");
@@ -1266,7 +1343,7 @@ describe("source locations", () => {
1266
1343
  }
1267
1344
  }`;
1268
1345
  const m = new BetaModel(source.code);
1269
- expect(m).toTranslate();
1346
+ expect(m).modelCompiled();
1270
1347
  const na = (0, test_translator_1.getExplore)(m.modelDef, "na");
1271
1348
  const x = (0, test_translator_1.getQueryField)(na, "x");
1272
1349
  const z = (0, test_translator_1.getField)(x.pipeline[0], "z");
@@ -1275,29 +1352,29 @@ describe("source locations", () => {
1275
1352
  test("location of field inherited from table", () => {
1276
1353
  const source = (0, test_translator_1.markSource) `explore: na is ${"table('aTable')"}`;
1277
1354
  const m = new BetaModel(source.code);
1278
- expect(m).toTranslate();
1355
+ expect(m).modelCompiled();
1279
1356
  const na = (0, test_translator_1.getExplore)(m.modelDef, "na");
1280
1357
  const abool = (0, test_translator_1.getField)(na, "abool");
1281
1358
  expect(abool.location).toMatchObject(source.locations[0]);
1282
1359
  });
1283
1360
  test("location of field inherited from sql block", () => {
1284
- const source = (0, test_translator_1.markSource) `
1285
- sql: ${"s is || SELECT 1 as one ;;"}
1286
-
1361
+ const source = (0, test_translator_1.markSource) `--- comment
1362
+ sql: s is { select: ${'"""SELECT 1 as one """'} }
1287
1363
  explore: na is from_sql(s)
1288
1364
  `;
1289
1365
  const m = new BetaModel(source.code);
1290
- const result = m.translate();
1291
- const sqlBlock = (result.sqlStructs || [])[0];
1292
- m.update({
1293
- sqlStructs: {
1294
- [sqlBlock.name]: getSelectOneStruct(sqlBlock),
1295
- },
1296
- });
1297
- expect(m).toTranslate();
1298
- const na = (0, test_translator_1.getExplore)(m.modelDef, "na");
1299
- const one = (0, test_translator_1.getField)(na, "one");
1300
- expect(one.location).toMatchObject(source.locations[0]);
1366
+ expect(m).modelParsed();
1367
+ const compileSql = m.translate().compileSQL;
1368
+ expect(compileSql).toBeDefined();
1369
+ if (compileSql) {
1370
+ m.update({
1371
+ compileSQL: { [compileSql.name]: getSelectOneStruct(compileSql) },
1372
+ });
1373
+ expect(m).modelCompiled();
1374
+ const na = (0, test_translator_1.getExplore)(m.modelDef, "na");
1375
+ const one = (0, test_translator_1.getField)(na, "one");
1376
+ expect(one.location).isLocationIn(source.locations[0], source.code);
1377
+ }
1301
1378
  });
1302
1379
  test("location of fields inherited from a query", () => {
1303
1380
  const source = (0, test_translator_1.markSource) `
@@ -1310,7 +1387,7 @@ describe("source locations", () => {
1310
1387
  )
1311
1388
  `;
1312
1389
  const m = new BetaModel(source.code);
1313
- expect(m).toTranslate();
1390
+ expect(m).modelCompiled();
1314
1391
  const na = (0, test_translator_1.getExplore)(m.modelDef, "na");
1315
1392
  const abool = (0, test_translator_1.getField)(na, "abool");
1316
1393
  expect(abool.location).toMatchObject(source.locations[0]);
@@ -1320,24 +1397,32 @@ describe("source locations", () => {
1320
1397
  test("location of named query", () => {
1321
1398
  const source = (0, test_translator_1.markSource) `query: ${"q is a -> { project: * }"}`;
1322
1399
  const m = new BetaModel(source.code);
1323
- expect(m).toTranslate();
1400
+ expect(m).modelCompiled();
1324
1401
  const q = (0, test_translator_1.getExplore)(m.modelDef, "q");
1325
1402
  expect(q.location).toMatchObject(source.locations[0]);
1326
1403
  });
1327
1404
  test("location of field in named query", () => {
1328
1405
  const source = (0, test_translator_1.markSource) `query: q is a -> { group_by: ${"b is 1"} }`;
1329
1406
  const m = new BetaModel(source.code);
1330
- expect(m).toTranslate();
1407
+ expect(m).modelCompiled();
1331
1408
  const q = (0, test_translator_1.getModelQuery)(m.modelDef, "q");
1332
1409
  const a = (0, test_translator_1.getField)(q.pipeline[0], "b");
1333
1410
  expect(a.location).toMatchObject(source.locations[0]);
1334
1411
  });
1335
1412
  test("location of named SQL block", () => {
1336
- const source = (0, test_translator_1.markSource) `sql: ${"s is || SELECT 1 as one ;;"}`;
1413
+ const source = (0, test_translator_1.markSource) `${`sql: s is { select: """SELECT 1 as one""" }`}`;
1337
1414
  const m = new BetaModel(source.code);
1338
- expect(m).toTranslate();
1339
- const s = m.sqlBlocks[0];
1340
- expect(s.location).toMatchObject(source.locations[0]);
1415
+ expect(m).modelParsed();
1416
+ const compileSql = m.translate().compileSQL;
1417
+ expect(compileSql).toBeDefined();
1418
+ if (compileSql) {
1419
+ m.update({
1420
+ compileSQL: { [compileSql.name]: getSelectOneStruct(compileSql) },
1421
+ });
1422
+ expect(m).modelCompiled();
1423
+ const s = m.sqlBlocks[0];
1424
+ expect(s.location).isLocationIn(source.locations[0], source.code);
1425
+ }
1341
1426
  });
1342
1427
  test("location of renamed field", () => {
1343
1428
  const source = (0, test_translator_1.markSource) `
@@ -1346,7 +1431,7 @@ describe("source locations", () => {
1346
1431
  }
1347
1432
  `;
1348
1433
  const m = new BetaModel(source.code);
1349
- expect(m).toTranslate();
1434
+ expect(m).modelCompiled();
1350
1435
  const na = (0, test_translator_1.getExplore)(m.modelDef, "na");
1351
1436
  const bbool = (0, test_translator_1.getField)(na, "bbool");
1352
1437
  expect(bbool.location).toMatchObject(source.locations[0]);
@@ -1358,7 +1443,7 @@ describe("source locations", () => {
1358
1443
  }
1359
1444
  `;
1360
1445
  const m = new BetaModel(source.code);
1361
- expect(m).toTranslate();
1446
+ expect(m).modelCompiled();
1362
1447
  const na = (0, test_translator_1.getExplore)(m.modelDef, "na");
1363
1448
  const x = (0, test_translator_1.getField)(na, "x");
1364
1449
  expect(x.location).toMatchObject(source.locations[0]);
@@ -1370,7 +1455,7 @@ describe("source locations", () => {
1370
1455
  }
1371
1456
  `;
1372
1457
  const m = new BetaModel(source.code);
1373
- expect(m).toTranslate();
1458
+ expect(m).modelCompiled();
1374
1459
  const na = (0, test_translator_1.getExplore)(m.modelDef, "na");
1375
1460
  const x = (0, test_translator_1.getField)(na, "x");
1376
1461
  expect(x.location).toMatchObject(source.locations[0]);
@@ -1385,21 +1470,20 @@ describe("source locations", () => {
1385
1470
  }
1386
1471
  `;
1387
1472
  const m = new BetaModel(source.code);
1388
- expect(m).toTranslate();
1473
+ expect(m).modelCompiled();
1389
1474
  const na = (0, test_translator_1.getExplore)(m.modelDef, "na");
1390
1475
  const x = (0, test_translator_1.getJoinField)(na, "x");
1391
1476
  const y = (0, test_translator_1.getField)(x, "y");
1392
1477
  expect(y.location).toMatchObject(source.locations[0]);
1393
1478
  });
1394
- test("multi line sql block token span is correct", () => {
1395
- var _a;
1396
- // There is exactly one token in this file ..
1397
- const sqlSource = "|| // line 0\n//line 1\n// line 2;;";
1398
- const m = new BetaModel(sqlSource);
1399
- expect(m).not.toCompile();
1400
- const errList = m.errors().errors;
1401
- expect((_a = errList[0].at) === null || _a === void 0 ? void 0 : _a.range.end).toEqual({ line: 2, character: 11 });
1402
- });
1479
+ // Since """ strings are not single tokens, I don't know how to do this.
1480
+ // test("multi line sql block token span is correct", () => {
1481
+ // const sqlSource = `sql: { select: """// line 0\n//line 1\n// line 2""" }`;
1482
+ // const m = new BetaModel(sqlSource);
1483
+ // expect(m).not.modelParsed();
1484
+ // const errList = m.errors().errors;
1485
+ // expect(errList[0].at?.range.end).toEqual({ line: 2, character: 11 });
1486
+ // });
1403
1487
  test("undefined query location", badModel((0, test_translator_1.markSource) `query: ${"-> xyz"}`, "Reference to undefined query 'xyz'"));
1404
1488
  test("undefined field reference", badModel((0, test_translator_1.markSource) `query: a -> { group_by: ${"xyz"} }`, "'xyz' is not defined"));
1405
1489
  test("bad query", badModel((0, test_translator_1.markSource) `query: a -> { group_by: astr; ${"project: *"} }`, "project: not legal in grouping query"));
@@ -1413,7 +1497,7 @@ describe("source references", () => {
1413
1497
  query: ${"na"} -> { project: * }
1414
1498
  `;
1415
1499
  const m = new BetaModel(source.code);
1416
- expect(m).toTranslate();
1500
+ expect(m).modelCompiled();
1417
1501
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1418
1502
  location: source.locations[1],
1419
1503
  type: "exploreReference",
@@ -1431,7 +1515,7 @@ describe("source references", () => {
1431
1515
  query: t -> ${"q"}
1432
1516
  `;
1433
1517
  const m = new BetaModel(source.code);
1434
- expect(m).toTranslate();
1518
+ expect(m).modelCompiled();
1435
1519
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1436
1520
  location: source.locations[1],
1437
1521
  type: "fieldReference",
@@ -1447,7 +1531,7 @@ describe("source references", () => {
1447
1531
  query: na -> ${"x"}
1448
1532
  `;
1449
1533
  const m = new BetaModel(source.code);
1450
- expect(m).toTranslate();
1534
+ expect(m).modelCompiled();
1451
1535
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1452
1536
  location: source.locations[1],
1453
1537
  type: "fieldReference",
@@ -1459,26 +1543,29 @@ describe("source references", () => {
1459
1543
  });
1460
1544
  test("reference to sql block", () => {
1461
1545
  const source = (0, test_translator_1.markSource) `
1462
- sql: ${"s is || SELECT 1 as one ;;"}
1546
+ ${`sql: s is {select:"""SELECT 1 as one"""}`}
1463
1547
  explore: na is from_sql(${"s"})
1464
1548
  `;
1465
1549
  const m = new BetaModel(source.code);
1466
- const result = m.translate();
1467
- const sqlBlock = (result.sqlStructs || [])[0];
1468
- m.update({
1469
- sqlStructs: {
1470
- [sqlBlock.name]: getSelectOneStruct(sqlBlock),
1471
- },
1472
- });
1473
- expect(m).toTranslate();
1474
- expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1475
- location: source.locations[1],
1476
- type: "sqlBlockReference",
1477
- text: "s",
1478
- definition: {
1479
- location: source.locations[0],
1480
- },
1481
- });
1550
+ expect(m).modelParsed();
1551
+ const compileSql = m.translate().compileSQL;
1552
+ expect(compileSql).toBeDefined();
1553
+ if (compileSql) {
1554
+ m.update({
1555
+ compileSQL: { [compileSql.name]: getSelectOneStruct(compileSql) },
1556
+ });
1557
+ expect(m).modelCompiled();
1558
+ const ref = m.referenceAt(pos(source.locations[1]));
1559
+ expect(ref).toMatchObject({
1560
+ location: source.locations[1],
1561
+ type: "sqlBlockReference",
1562
+ text: "s",
1563
+ definition: {
1564
+ ...getSelectOneStruct(compileSql),
1565
+ location: source.locations[0],
1566
+ },
1567
+ });
1568
+ }
1482
1569
  });
1483
1570
  test("reference to query in from", () => {
1484
1571
  const source = (0, test_translator_1.markSource) `
@@ -1486,7 +1573,7 @@ describe("source references", () => {
1486
1573
  explore: na is from(-> ${"q"})
1487
1574
  `;
1488
1575
  const m = new BetaModel(source.code);
1489
- expect(m).toTranslate();
1576
+ expect(m).modelCompiled();
1490
1577
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1491
1578
  location: source.locations[1],
1492
1579
  type: "queryReference",
@@ -1502,7 +1589,7 @@ describe("source references", () => {
1502
1589
  query: q2 is -> ${"q"} -> { project: * }
1503
1590
  `;
1504
1591
  const m = new BetaModel(source.code);
1505
- expect(m).toTranslate();
1592
+ expect(m).modelCompiled();
1506
1593
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1507
1594
  location: source.locations[1],
1508
1595
  type: "queryReference",
@@ -1518,7 +1605,7 @@ describe("source references", () => {
1518
1605
  query: q2 is -> ${"q"} { limit: 10 }
1519
1606
  `;
1520
1607
  const m = new BetaModel(source.code);
1521
- expect(m).toTranslate();
1608
+ expect(m).modelCompiled();
1522
1609
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1523
1610
  location: source.locations[1],
1524
1611
  type: "queryReference",
@@ -1534,7 +1621,7 @@ describe("source references", () => {
1534
1621
  query: na -> { project: bbool is not ${"abool"} }
1535
1622
  `;
1536
1623
  const m = new BetaModel(source.code);
1537
- expect(m).toTranslate();
1624
+ expect(m).modelCompiled();
1538
1625
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1539
1626
  location: source.locations[1],
1540
1627
  type: "fieldReference",
@@ -1552,7 +1639,7 @@ describe("source references", () => {
1552
1639
  query: na -> { project: ${"`name`"} }
1553
1640
  `;
1554
1641
  const m = new BetaModel(source.code);
1555
- expect(m).toTranslate();
1642
+ expect(m).modelCompiled();
1556
1643
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1557
1644
  location: source.locations[1],
1558
1645
  type: "fieldReference",
@@ -1571,7 +1658,7 @@ describe("source references", () => {
1571
1658
  query: na -> { project: bstr is self.${"astr"} }
1572
1659
  `;
1573
1660
  const m = new BetaModel(source.code);
1574
- expect(m).toTranslate();
1661
+ expect(m).modelCompiled();
1575
1662
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1576
1663
  location: source.locations[1],
1577
1664
  type: "fieldReference",
@@ -1589,7 +1676,7 @@ describe("source references", () => {
1589
1676
  query: na -> { project: bstr is ${"self"}.astr }
1590
1677
  `;
1591
1678
  const m = new BetaModel(source.code);
1592
- expect(m).toTranslate();
1679
+ expect(m).modelCompiled();
1593
1680
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1594
1681
  location: source.locations[1],
1595
1682
  type: "joinReference",
@@ -1604,7 +1691,7 @@ describe("source references", () => {
1604
1691
  query: ${"table('aTable')"} -> { group_by: ${"abool"} }
1605
1692
  `;
1606
1693
  const m = new BetaModel(source.code);
1607
- expect(m).toTranslate();
1694
+ expect(m).modelCompiled();
1608
1695
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1609
1696
  location: source.locations[1],
1610
1697
  type: "fieldReference",
@@ -1620,7 +1707,7 @@ describe("source references", () => {
1620
1707
  query: na -> { project: ${"abool"} }
1621
1708
  `;
1622
1709
  const m = new BetaModel(source.code);
1623
- expect(m).toTranslate();
1710
+ expect(m).modelCompiled();
1624
1711
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1625
1712
  location: source.locations[1],
1626
1713
  type: "fieldReference",
@@ -1638,7 +1725,7 @@ describe("source references", () => {
1638
1725
  }
1639
1726
  `;
1640
1727
  const m = new BetaModel(source.code);
1641
- expect(m).toTranslate();
1728
+ expect(m).modelCompiled();
1642
1729
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1643
1730
  location: source.locations[1],
1644
1731
  type: "fieldReference",
@@ -1656,7 +1743,7 @@ describe("source references", () => {
1656
1743
  }
1657
1744
  `;
1658
1745
  const m = new BetaModel(source.code);
1659
- expect(m).toTranslate();
1746
+ expect(m).modelCompiled();
1660
1747
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1661
1748
  location: source.locations[1],
1662
1749
  type: "fieldReference",
@@ -1674,7 +1761,7 @@ describe("source references", () => {
1674
1761
  }
1675
1762
  `;
1676
1763
  const m = new BetaModel(source.code);
1677
- expect(m).toTranslate();
1764
+ expect(m).modelCompiled();
1678
1765
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1679
1766
  location: source.locations[1],
1680
1767
  type: "fieldReference",
@@ -1692,7 +1779,7 @@ describe("source references", () => {
1692
1779
  }
1693
1780
  `;
1694
1781
  const m = new BetaModel(source.code);
1695
- expect(m).toTranslate();
1782
+ expect(m).modelCompiled();
1696
1783
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1697
1784
  location: source.locations[1],
1698
1785
  type: "fieldReference",
@@ -1710,7 +1797,7 @@ describe("source references", () => {
1710
1797
  }
1711
1798
  `;
1712
1799
  const m = new BetaModel(source.code);
1713
- expect(m).toTranslate();
1800
+ expect(m).modelCompiled();
1714
1801
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1715
1802
  location: source.locations[1],
1716
1803
  type: "fieldReference",
@@ -1728,7 +1815,7 @@ describe("source references", () => {
1728
1815
  }
1729
1816
  `;
1730
1817
  const m = new BetaModel(source.code);
1731
- expect(m).toTranslate();
1818
+ expect(m).modelCompiled();
1732
1819
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1733
1820
  location: source.locations[1],
1734
1821
  type: "fieldReference",
@@ -1746,7 +1833,7 @@ describe("source references", () => {
1746
1833
  }
1747
1834
  `;
1748
1835
  const m = new BetaModel(source.code);
1749
- expect(m).toTranslate();
1836
+ expect(m).modelCompiled();
1750
1837
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1751
1838
  location: source.locations[1],
1752
1839
  type: "fieldReference",
@@ -1762,7 +1849,7 @@ describe("source references", () => {
1762
1849
  query: na -> { aggregate: ai_sum is ${"ai"}.sum() }
1763
1850
  `;
1764
1851
  const m = new BetaModel(source.code);
1765
- expect(m).toTranslate();
1852
+ expect(m).modelCompiled();
1766
1853
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1767
1854
  location: source.locations[1],
1768
1855
  type: "fieldReference",
@@ -1783,7 +1870,7 @@ describe("source references", () => {
1783
1870
  query: na -> { aggregate: ai_sum is ${"self"}.sum(self.ai) }
1784
1871
  `;
1785
1872
  const m = new BetaModel(source.code);
1786
- expect(m).toTranslate();
1873
+ expect(m).modelCompiled();
1787
1874
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1788
1875
  location: source.locations[1],
1789
1876
  type: "joinReference",
@@ -1801,7 +1888,7 @@ describe("source references", () => {
1801
1888
  query: na -> { aggregate: ai_sum is self.sum(${"self"}.ai) }
1802
1889
  `;
1803
1890
  const m = new BetaModel(source.code);
1804
- expect(m).toTranslate();
1891
+ expect(m).modelCompiled();
1805
1892
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1806
1893
  location: source.locations[1],
1807
1894
  type: "joinReference",
@@ -1819,7 +1906,7 @@ describe("source references", () => {
1819
1906
  }
1820
1907
  `;
1821
1908
  const m = new BetaModel(source.code);
1822
- expect(m).toTranslate();
1909
+ expect(m).modelCompiled();
1823
1910
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1824
1911
  location: source.locations[1],
1825
1912
  type: "exploreReference",
@@ -1835,7 +1922,7 @@ describe("source references", () => {
1835
1922
  query: na -> { aggregate: ai_sum is sum(${"ai"}) }
1836
1923
  `;
1837
1924
  const m = new BetaModel(source.code);
1838
- expect(m).toTranslate();
1925
+ expect(m).modelCompiled();
1839
1926
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1840
1927
  location: source.locations[1],
1841
1928
  type: "fieldReference",
@@ -1852,7 +1939,7 @@ describe("source references", () => {
1852
1939
  }
1853
1940
  `;
1854
1941
  const m = new BetaModel(source.code);
1855
- expect(m).toTranslate();
1942
+ expect(m).modelCompiled();
1856
1943
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1857
1944
  location: source.locations[1],
1858
1945
  type: "fieldReference",
@@ -1870,7 +1957,7 @@ describe("source references", () => {
1870
1957
  }
1871
1958
  `;
1872
1959
  const m = new BetaModel(source.code);
1873
- expect(m).toTranslate();
1960
+ expect(m).modelCompiled();
1874
1961
  expect(m.referenceAt(pos(source.locations[1]))).toMatchObject({
1875
1962
  location: source.locations[1],
1876
1963
  type: "fieldReference",
@@ -1889,27 +1976,26 @@ describe("translation need error locations", () => {
1889
1976
  m.update({
1890
1977
  errors: { urls: { [(result.urls || [])[0]]: "Bad file!" } },
1891
1978
  });
1892
- expect(m).not.toCompile();
1979
+ expect(m).not.modelParsed();
1893
1980
  const errList = m.errors().errors;
1894
- expect(errList[0].at).toEqual(source.locations[0]);
1981
+ expect(errList[0].at).isLocationIn(source.locations[0], source.code);
1895
1982
  return undefined;
1896
1983
  });
1897
1984
  test("sql struct error location", () => {
1898
1985
  const source = (0, test_translator_1.markSource) `
1899
- sql: bad_sql is || BAD SQL ;;
1900
- query: ${"from_sql(bad_sql)"} -> { project: * }
1986
+ sql: bad_sql is {select: ${'"""BAD_SQL"""'}}
1987
+ query: from_sql(bad_sql) -> { project: * }
1901
1988
  `;
1902
1989
  const m = new BetaModel(source.code);
1903
- const result = m.translate();
1904
- m.update({
1905
- errors: {
1906
- sqlStructs: { [(result.sqlStructs || [])[0].name]: "Bad SQL!" },
1907
- },
1908
- });
1909
- expect(m).not.toCompile();
1990
+ expect(m).modelParsed();
1991
+ const req = m.translate().compileSQL;
1992
+ expect(req).toBeDefined();
1993
+ if (req) {
1994
+ m.update({ errors: { compileSQL: { [req.name]: "Bad SQL!" } } });
1995
+ }
1996
+ expect(m).not.modelCompiled();
1910
1997
  const errList = m.errors().errors;
1911
- expect(errList[0].at).toEqual(source.locations[0]);
1912
- return undefined;
1998
+ expect(errList[0].at).isLocationIn(source.locations[0], source.code);
1913
1999
  });
1914
2000
  test("table struct error location", () => {
1915
2001
  const source = (0, test_translator_1.markSource) `
@@ -1922,9 +2008,9 @@ describe("translation need error locations", () => {
1922
2008
  tables: { [(result.tables || [])[0]]: "Bad table!" },
1923
2009
  },
1924
2010
  });
1925
- expect(m).not.toCompile();
2011
+ expect(m).not.modelParsed();
1926
2012
  const errList = m.errors().errors;
1927
- expect(errList[0].at).toEqual(source.locations[0]);
2013
+ expect(errList[0].at).isLocationIn(source.locations[0], source.code);
1928
2014
  return undefined;
1929
2015
  });
1930
2016
  });
@@ -1990,7 +2076,7 @@ describe("pipeline comprehension", () => {
1990
2076
  }
1991
2077
  `;
1992
2078
  const m = new BetaModel(src);
1993
- expect(m).toTranslate();
2079
+ expect(m).modelCompiled();
1994
2080
  const s2 = m.getQuery("s2");
1995
2081
  expect(s2 === null || s2 === void 0 ? void 0 : s2.pipeline.length).toBe(2);
1996
2082
  });