@malloydata/malloy 0.0.24-dev230224184907 → 0.0.24-dev230228224434

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 (310) hide show
  1. package/dist/connection_utils.js +10 -10
  2. package/dist/dialect/dialect.d.ts +2 -2
  3. package/dist/dialect/dialect.js +13 -13
  4. package/dist/dialect/dialect_map.d.ts +1 -1
  5. package/dist/dialect/duckdb.d.ts +3 -3
  6. package/dist/dialect/duckdb.js +44 -44
  7. package/dist/dialect/index.d.ts +6 -6
  8. package/dist/dialect/postgres.d.ts +3 -3
  9. package/dist/dialect/postgres.js +46 -46
  10. package/dist/dialect/standardsql.d.ts +4 -4
  11. package/dist/dialect/standardsql.js +51 -51
  12. package/dist/index.d.ts +10 -10
  13. package/dist/lang/ast/ast-utils.d.ts +1 -1
  14. package/dist/lang/ast/ast-utils.js +3 -3
  15. package/dist/lang/ast/elements/define-query.d.ts +3 -3
  16. package/dist/lang/ast/elements/define-query.js +6 -6
  17. package/dist/lang/ast/elements/define-source.d.ts +4 -4
  18. package/dist/lang/ast/elements/define-source.js +8 -8
  19. package/dist/lang/ast/elements/import-statement.d.ts +2 -2
  20. package/dist/lang/ast/elements/import-statement.js +7 -7
  21. package/dist/lang/ast/elements/pipeline-desc.d.ts +5 -5
  22. package/dist/lang/ast/elements/pipeline-desc.js +11 -11
  23. package/dist/lang/ast/elements/refined-source.d.ts +4 -4
  24. package/dist/lang/ast/elements/refined-source.js +6 -6
  25. package/dist/lang/ast/elements/source.d.ts +3 -3
  26. package/dist/lang/ast/elements/source.js +1 -1
  27. package/dist/lang/ast/error-factory.d.ts +1 -1
  28. package/dist/lang/ast/error-factory.js +15 -15
  29. package/dist/lang/ast/executors/index-executor.d.ts +7 -7
  30. package/dist/lang/ast/executors/index-executor.js +4 -4
  31. package/dist/lang/ast/executors/project-executor.d.ts +5 -5
  32. package/dist/lang/ast/executors/project-executor.js +2 -2
  33. package/dist/lang/ast/executors/reduce-executor.d.ts +8 -8
  34. package/dist/lang/ast/executors/reduce-executor.js +5 -5
  35. package/dist/lang/ast/expressions/apply.d.ts +2 -2
  36. package/dist/lang/ast/expressions/apply.js +1 -1
  37. package/dist/lang/ast/expressions/binary-boolean.d.ts +3 -3
  38. package/dist/lang/ast/expressions/binary-boolean.js +6 -6
  39. package/dist/lang/ast/expressions/binary-numeric.d.ts +3 -3
  40. package/dist/lang/ast/expressions/binary-numeric.js +2 -2
  41. package/dist/lang/ast/expressions/boolean.d.ts +4 -4
  42. package/dist/lang/ast/expressions/boolean.js +2 -2
  43. package/dist/lang/ast/expressions/constant-sub-expression.d.ts +4 -4
  44. package/dist/lang/ast/expressions/constant-sub-expression.js +12 -12
  45. package/dist/lang/ast/expressions/expr-add-sub.d.ts +2 -2
  46. package/dist/lang/ast/expressions/expr-add-sub.js +1 -1
  47. package/dist/lang/ast/expressions/expr-aggregate-function.d.ts +5 -5
  48. package/dist/lang/ast/expressions/expr-aggregate-function.js +15 -15
  49. package/dist/lang/ast/expressions/expr-alternation-tree.d.ts +6 -6
  50. package/dist/lang/ast/expressions/expr-alternation-tree.js +6 -6
  51. package/dist/lang/ast/expressions/expr-asymmetric.d.ts +5 -5
  52. package/dist/lang/ast/expressions/expr-asymmetric.js +3 -3
  53. package/dist/lang/ast/expressions/expr-avg.d.ts +3 -3
  54. package/dist/lang/ast/expressions/expr-avg.js +2 -2
  55. package/dist/lang/ast/expressions/expr-cast.d.ts +4 -4
  56. package/dist/lang/ast/expressions/expr-cast.js +6 -6
  57. package/dist/lang/ast/expressions/expr-compare.d.ts +5 -5
  58. package/dist/lang/ast/expressions/expr-compare.js +9 -9
  59. package/dist/lang/ast/expressions/expr-count-distinct.d.ts +2 -2
  60. package/dist/lang/ast/expressions/expr-count-distinct.js +1 -1
  61. package/dist/lang/ast/expressions/expr-count.d.ts +4 -4
  62. package/dist/lang/ast/expressions/expr-count.js +10 -10
  63. package/dist/lang/ast/expressions/expr-filter.d.ts +4 -4
  64. package/dist/lang/ast/expressions/expr-filter.js +13 -13
  65. package/dist/lang/ast/expressions/expr-func.d.ts +3 -3
  66. package/dist/lang/ast/expressions/expr-func.js +8 -8
  67. package/dist/lang/ast/expressions/expr-granular-time.d.ts +4 -4
  68. package/dist/lang/ast/expressions/expr-granular-time.js +17 -17
  69. package/dist/lang/ast/expressions/expr-id-reference.d.ts +4 -4
  70. package/dist/lang/ast/expressions/expr-id-reference.js +11 -11
  71. package/dist/lang/ast/expressions/expr-logical-op.d.ts +2 -2
  72. package/dist/lang/ast/expressions/expr-logical-op.js +1 -1
  73. package/dist/lang/ast/expressions/expr-max.d.ts +4 -4
  74. package/dist/lang/ast/expressions/expr-max.js +1 -1
  75. package/dist/lang/ast/expressions/expr-min.d.ts +4 -4
  76. package/dist/lang/ast/expressions/expr-min.js +1 -1
  77. package/dist/lang/ast/expressions/expr-minus.d.ts +3 -3
  78. package/dist/lang/ast/expressions/expr-minus.js +5 -5
  79. package/dist/lang/ast/expressions/expr-mul-div.d.ts +2 -2
  80. package/dist/lang/ast/expressions/expr-mul-div.js +1 -1
  81. package/dist/lang/ast/expressions/expr-not.d.ts +4 -4
  82. package/dist/lang/ast/expressions/expr-not.js +3 -3
  83. package/dist/lang/ast/expressions/expr-now.d.ts +3 -3
  84. package/dist/lang/ast/expressions/expr-now.js +8 -8
  85. package/dist/lang/ast/expressions/expr-null.d.ts +2 -2
  86. package/dist/lang/ast/expressions/expr-null.js +4 -4
  87. package/dist/lang/ast/expressions/expr-number.d.ts +3 -3
  88. package/dist/lang/ast/expressions/expr-number.js +2 -2
  89. package/dist/lang/ast/expressions/expr-parens.d.ts +3 -3
  90. package/dist/lang/ast/expressions/expr-parens.js +3 -3
  91. package/dist/lang/ast/expressions/expr-regex.d.ts +2 -2
  92. package/dist/lang/ast/expressions/expr-regex.js +4 -4
  93. package/dist/lang/ast/expressions/expr-string.d.ts +3 -3
  94. package/dist/lang/ast/expressions/expr-string.js +8 -8
  95. package/dist/lang/ast/expressions/expr-sum.d.ts +3 -3
  96. package/dist/lang/ast/expressions/expr-sum.js +2 -2
  97. package/dist/lang/ast/expressions/expr-time-extract.d.ts +4 -4
  98. package/dist/lang/ast/expressions/expr-time-extract.js +30 -30
  99. package/dist/lang/ast/expressions/expr-time.d.ts +4 -4
  100. package/dist/lang/ast/expressions/expr-time.js +10 -10
  101. package/dist/lang/ast/expressions/expr-ungroup.d.ts +6 -6
  102. package/dist/lang/ast/expressions/expr-ungroup.js +13 -13
  103. package/dist/lang/ast/expressions/for-range.d.ts +4 -4
  104. package/dist/lang/ast/expressions/for-range.js +17 -17
  105. package/dist/lang/ast/expressions/granular-literal.d.ts +4 -4
  106. package/dist/lang/ast/expressions/granular-literal.js +34 -34
  107. package/dist/lang/ast/expressions/partial-compare.d.ts +4 -4
  108. package/dist/lang/ast/expressions/partial-compare.js +4 -4
  109. package/dist/lang/ast/expressions/pick-when.d.ts +4 -4
  110. package/dist/lang/ast/expressions/pick-when.js +32 -32
  111. package/dist/lang/ast/expressions/range.d.ts +3 -3
  112. package/dist/lang/ast/expressions/range.js +20 -20
  113. package/dist/lang/ast/expressions/time-frame.d.ts +2 -2
  114. package/dist/lang/ast/expressions/time-frame.js +3 -3
  115. package/dist/lang/ast/expressions/top-by.d.ts +4 -4
  116. package/dist/lang/ast/expressions/top-by.js +5 -5
  117. package/dist/lang/ast/expressions/unary.d.ts +1 -1
  118. package/dist/lang/ast/expressions/unary.js +1 -1
  119. package/dist/lang/ast/expressions/utils.d.ts +2 -2
  120. package/dist/lang/ast/expressions/utils.js +6 -6
  121. package/dist/lang/ast/field-space/column-space-field.d.ts +3 -3
  122. package/dist/lang/ast/field-space/dynamic-space.d.ts +7 -7
  123. package/dist/lang/ast/field-space/dynamic-space.js +2 -2
  124. package/dist/lang/ast/field-space/field-definition-value.d.ts +5 -5
  125. package/dist/lang/ast/field-space/index-field-space.d.ts +3 -3
  126. package/dist/lang/ast/field-space/index-field-space.js +4 -4
  127. package/dist/lang/ast/field-space/join-space-field.d.ts +3 -3
  128. package/dist/lang/ast/field-space/project-field-space.d.ts +2 -2
  129. package/dist/lang/ast/field-space/project-field-space.js +5 -5
  130. package/dist/lang/ast/field-space/query-field-struct.d.ts +3 -3
  131. package/dist/lang/ast/field-space/query-field-struct.js +1 -1
  132. package/dist/lang/ast/field-space/query-space-field.d.ts +4 -4
  133. package/dist/lang/ast/field-space/query-space-field.js +1 -1
  134. package/dist/lang/ast/field-space/query-spaces.d.ts +11 -11
  135. package/dist/lang/ast/field-space/query-spaces.js +8 -8
  136. package/dist/lang/ast/field-space/reference-field.d.ts +5 -5
  137. package/dist/lang/ast/field-space/reference-field.js +1 -1
  138. package/dist/lang/ast/field-space/refined-space.d.ts +4 -4
  139. package/dist/lang/ast/field-space/refined-space.js +2 -2
  140. package/dist/lang/ast/field-space/rename-space-field.d.ts +3 -3
  141. package/dist/lang/ast/field-space/rename-space-field.js +2 -2
  142. package/dist/lang/ast/field-space/static-space.d.ts +7 -7
  143. package/dist/lang/ast/field-space/static-space.js +12 -12
  144. package/dist/lang/ast/field-space/struct-space-field-base.d.ts +4 -4
  145. package/dist/lang/ast/field-space/struct-space-field-base.js +1 -1
  146. package/dist/lang/ast/field-space/wild-space-field.d.ts +4 -4
  147. package/dist/lang/ast/field-space/wild-space-field.js +1 -1
  148. package/dist/lang/ast/fragtype-utils.d.ts +1 -1
  149. package/dist/lang/ast/fragtype-utils.js +15 -15
  150. package/dist/lang/ast/index.d.ts +90 -90
  151. package/dist/lang/ast/parameters/constant-parameter.d.ts +3 -3
  152. package/dist/lang/ast/parameters/constant-parameter.js +10 -10
  153. package/dist/lang/ast/parameters/has-parameter.d.ts +3 -3
  154. package/dist/lang/ast/parameters/has-parameter.js +7 -7
  155. package/dist/lang/ast/query-elements/anonymous-query.d.ts +3 -3
  156. package/dist/lang/ast/query-elements/anonymous-query.js +2 -2
  157. package/dist/lang/ast/query-elements/existing-query.d.ts +4 -4
  158. package/dist/lang/ast/query-elements/existing-query.js +10 -10
  159. package/dist/lang/ast/query-elements/full-query.d.ts +4 -4
  160. package/dist/lang/ast/query-elements/full-query.js +10 -10
  161. package/dist/lang/ast/query-elements/query-head-struct.d.ts +2 -2
  162. package/dist/lang/ast/query-elements/query-head-struct.js +2 -2
  163. package/dist/lang/ast/query-items/field-declaration.d.ts +6 -6
  164. package/dist/lang/ast/query-items/field-declaration.js +14 -14
  165. package/dist/lang/ast/query-items/field-references.d.ts +6 -6
  166. package/dist/lang/ast/query-items/field-references.js +9 -9
  167. package/dist/lang/ast/query-properties/aggregate.d.ts +2 -2
  168. package/dist/lang/ast/query-properties/aggregate.js +1 -1
  169. package/dist/lang/ast/query-properties/declare-fields.d.ts +2 -2
  170. package/dist/lang/ast/query-properties/declare-fields.js +1 -1
  171. package/dist/lang/ast/query-properties/dimmensions.d.ts +2 -2
  172. package/dist/lang/ast/query-properties/dimmensions.js +1 -1
  173. package/dist/lang/ast/query-properties/filters.d.ts +4 -4
  174. package/dist/lang/ast/query-properties/filters.js +16 -16
  175. package/dist/lang/ast/query-properties/group-by.d.ts +2 -2
  176. package/dist/lang/ast/query-properties/group-by.js +1 -1
  177. package/dist/lang/ast/query-properties/indexing.d.ts +3 -3
  178. package/dist/lang/ast/query-properties/indexing.js +3 -3
  179. package/dist/lang/ast/query-properties/joins.d.ts +6 -6
  180. package/dist/lang/ast/query-properties/joins.js +27 -27
  181. package/dist/lang/ast/query-properties/limit.d.ts +1 -1
  182. package/dist/lang/ast/query-properties/limit.js +1 -1
  183. package/dist/lang/ast/query-properties/measures.d.ts +2 -2
  184. package/dist/lang/ast/query-properties/measures.js +1 -1
  185. package/dist/lang/ast/query-properties/nest-reference.d.ts +2 -2
  186. package/dist/lang/ast/query-properties/nest-reference.js +1 -1
  187. package/dist/lang/ast/query-properties/nest.d.ts +7 -7
  188. package/dist/lang/ast/query-properties/nest.js +7 -7
  189. package/dist/lang/ast/query-properties/nests.d.ts +2 -2
  190. package/dist/lang/ast/query-properties/nests.js +1 -1
  191. package/dist/lang/ast/query-properties/ordering.d.ts +3 -3
  192. package/dist/lang/ast/query-properties/ordering.js +6 -6
  193. package/dist/lang/ast/query-properties/project-statement.d.ts +2 -2
  194. package/dist/lang/ast/query-properties/project-statement.js +1 -1
  195. package/dist/lang/ast/query-properties/qop-desc.d.ts +7 -7
  196. package/dist/lang/ast/query-properties/qop-desc.js +20 -20
  197. package/dist/lang/ast/query-properties/sampling.d.ts +2 -2
  198. package/dist/lang/ast/query-properties/sampling.js +1 -1
  199. package/dist/lang/ast/query-properties/top.d.ts +4 -4
  200. package/dist/lang/ast/query-properties/top.js +5 -5
  201. package/dist/lang/ast/source-properties/field-list-edit.d.ts +4 -4
  202. package/dist/lang/ast/source-properties/field-list-edit.js +2 -2
  203. package/dist/lang/ast/source-properties/primary-key.d.ts +2 -2
  204. package/dist/lang/ast/source-properties/primary-key.js +2 -2
  205. package/dist/lang/ast/source-properties/renames.d.ts +2 -2
  206. package/dist/lang/ast/source-properties/renames.js +3 -3
  207. package/dist/lang/ast/source-properties/turtles.d.ts +2 -2
  208. package/dist/lang/ast/source-properties/turtles.js +1 -1
  209. package/dist/lang/ast/sources/named-source.d.ts +4 -4
  210. package/dist/lang/ast/sources/named-source.js +5 -5
  211. package/dist/lang/ast/sources/query-source.d.ts +3 -3
  212. package/dist/lang/ast/sources/query-source.js +3 -3
  213. package/dist/lang/ast/sources/sql-source.d.ts +2 -2
  214. package/dist/lang/ast/sources/sql-source.js +2 -2
  215. package/dist/lang/ast/sources/table-source.d.ts +2 -2
  216. package/dist/lang/ast/sources/table-source.js +7 -7
  217. package/dist/lang/ast/space-seed.d.ts +2 -2
  218. package/dist/lang/ast/space-seed.js +1 -1
  219. package/dist/lang/ast/sql-elements/sql-statement.d.ts +4 -4
  220. package/dist/lang/ast/sql-elements/sql-statement.js +9 -9
  221. package/dist/lang/ast/sql-elements/sql-string.d.ts +3 -3
  222. package/dist/lang/ast/sql-elements/sql-string.js +6 -6
  223. package/dist/lang/ast/struct-utils.d.ts +2 -2
  224. package/dist/lang/ast/struct-utils.js +3 -3
  225. package/dist/lang/ast/time-utils.d.ts +6 -6
  226. package/dist/lang/ast/time-utils.js +46 -46
  227. package/dist/lang/ast/types/document-compile-result.d.ts +2 -2
  228. package/dist/lang/ast/types/executor.d.ts +3 -3
  229. package/dist/lang/ast/types/explore-desc.d.ts +2 -2
  230. package/dist/lang/ast/types/explore-desc.js +1 -1
  231. package/dist/lang/ast/types/explore-field.d.ts +3 -3
  232. package/dist/lang/ast/types/expr-result.d.ts +2 -2
  233. package/dist/lang/ast/types/expr-value.d.ts +2 -2
  234. package/dist/lang/ast/types/expression-def.d.ts +4 -4
  235. package/dist/lang/ast/types/expression-def.js +86 -86
  236. package/dist/lang/ast/types/field-collection-member.d.ts +3 -3
  237. package/dist/lang/ast/types/field-decl.d.ts +5 -5
  238. package/dist/lang/ast/types/field-space.d.ts +5 -5
  239. package/dist/lang/ast/types/field-space.js +1 -1
  240. package/dist/lang/ast/types/granular-result.d.ts +3 -3
  241. package/dist/lang/ast/types/granular-result.js +1 -1
  242. package/dist/lang/ast/types/lookup-result.d.ts +1 -1
  243. package/dist/lang/ast/types/malloy-element.d.ts +6 -6
  244. package/dist/lang/ast/types/malloy-element.js +49 -49
  245. package/dist/lang/ast/types/model-entry.d.ts +1 -1
  246. package/dist/lang/ast/types/name-space.d.ts +1 -1
  247. package/dist/lang/ast/types/nested-query.d.ts +2 -2
  248. package/dist/lang/ast/types/op-desc.d.ts +2 -2
  249. package/dist/lang/ast/types/query-comp.d.ts +1 -1
  250. package/dist/lang/ast/types/query-element.d.ts +3 -3
  251. package/dist/lang/ast/types/query-item.d.ts +4 -4
  252. package/dist/lang/ast/types/query-property.d.ts +15 -15
  253. package/dist/lang/ast/types/source-property.d.ts +8 -8
  254. package/dist/lang/ast/types/space-entry.d.ts +2 -2
  255. package/dist/lang/ast/types/space-field.d.ts +4 -4
  256. package/dist/lang/ast/types/space-field.js +4 -4
  257. package/dist/lang/ast/types/space-param.d.ts +4 -4
  258. package/dist/lang/ast/types/space-param.js +4 -4
  259. package/dist/lang/ast/types/time-result.d.ts +2 -2
  260. package/dist/lang/ast/types/turtle-headed-pipe.d.ts +2 -2
  261. package/dist/lang/ast/types/turtle-headed-pipe.js +1 -1
  262. package/dist/lang/ast/types/type-desc.d.ts +3 -3
  263. package/dist/lang/field-utils.d.ts +1 -1
  264. package/dist/lang/field-utils.js +4 -4
  265. package/dist/lang/index.d.ts +10 -10
  266. package/dist/lang/malloy-to-ast.d.ts +8 -8
  267. package/dist/lang/malloy-to-ast.js +68 -68
  268. package/dist/lang/parse-error-handler.d.ts +3 -3
  269. package/dist/lang/parse-error-handler.js +4 -4
  270. package/dist/lang/parse-log.d.ts +2 -2
  271. package/dist/lang/parse-log.js +1 -1
  272. package/dist/lang/parse-malloy.d.ts +7 -7
  273. package/dist/lang/parse-malloy.js +81 -81
  274. package/dist/lang/parse-tree-walkers/document-completion-walker.d.ts +2 -2
  275. package/dist/lang/parse-tree-walkers/document-completion-walker.js +38 -38
  276. package/dist/lang/parse-tree-walkers/document-help-context-walker.d.ts +1 -1
  277. package/dist/lang/parse-tree-walkers/document-help-context-walker.js +14 -14
  278. package/dist/lang/parse-tree-walkers/document-highlight-walker.d.ts +3 -3
  279. package/dist/lang/parse-tree-walkers/document-highlight-walker.js +85 -85
  280. package/dist/lang/parse-tree-walkers/document-symbol-walker.d.ts +4 -4
  281. package/dist/lang/parse-tree-walkers/document-symbol-walker.js +40 -40
  282. package/dist/lang/parse-tree-walkers/explore-query-walker.d.ts +3 -3
  283. package/dist/lang/parse-tree-walkers/explore-query-walker.js +3 -3
  284. package/dist/lang/parse-tree-walkers/find-external-references.d.ts +4 -4
  285. package/dist/lang/parse-tree-walkers/find-external-references.js +2 -2
  286. package/dist/lang/reference-list.d.ts +1 -1
  287. package/dist/lang/test/document-help-context-walker.spec.js +9 -9
  288. package/dist/lang/test/document-symbol-walker.spec.js +32 -32
  289. package/dist/lang/test/field-symbols.spec.js +87 -87
  290. package/dist/lang/test/parse.spec.d.ts +1 -1
  291. package/dist/lang/test/parse.spec.js +768 -768
  292. package/dist/lang/test/test-translator.d.ts +6 -6
  293. package/dist/lang/test/test-translator.js +159 -159
  294. package/dist/lang/translate-response.d.ts +7 -7
  295. package/dist/lang/translate-response.js +1 -1
  296. package/dist/lang/zone.d.ts +5 -5
  297. package/dist/lang/zone.js +8 -8
  298. package/dist/malloy.d.ts +7 -7
  299. package/dist/malloy.js +192 -192
  300. package/dist/model/index.d.ts +2 -2
  301. package/dist/model/malloy_query.d.ts +12 -12
  302. package/dist/model/malloy_query.js +497 -502
  303. package/dist/model/malloy_types.d.ts +68 -68
  304. package/dist/model/malloy_types.js +102 -102
  305. package/dist/model/sql_block.d.ts +1 -1
  306. package/dist/model/sql_block.js +4 -4
  307. package/dist/model/utils.d.ts +1 -1
  308. package/dist/model/utils.js +10 -10
  309. package/dist/runtime_types.d.ts +2 -2
  310. package/package.json +4 -1
@@ -40,7 +40,7 @@ class StageWriter {
40
40
  this.withs = [];
41
41
  this.udfs = [];
42
42
  this.pdts = [];
43
- this.stagePrefix = "__stage";
43
+ this.stagePrefix = '__stage';
44
44
  this.parent = parent;
45
45
  this.useCTE = useCTE;
46
46
  }
@@ -69,7 +69,7 @@ class StageWriter {
69
69
  // eslint-disable-next-line prefer-const
70
70
  let { sql, lastStageName } = stageWriter.combineStages(true);
71
71
  if (lastStageName === undefined) {
72
- throw new Error("Internal Error: no stage to combine");
72
+ throw new Error('Internal Error: no stage to combine');
73
73
  }
74
74
  sql += dialect.sqlCreateFunctionCombineLastStage(lastStageName, structDef);
75
75
  const id = `${dialect.udfPrefix}${this.root().udfs.length}`;
@@ -79,7 +79,7 @@ class StageWriter {
79
79
  }
80
80
  addPDT(baseName, dialect) {
81
81
  const sql = this.combineStages(false).sql + this.withs[this.withs.length - 1];
82
- const tableName = "scratch." + baseName + (0, utils_1.generateHash)(sql);
82
+ const tableName = 'scratch.' + baseName + (0, utils_1.generateHash)(sql);
83
83
  this.root().pdts.push(dialect.sqlCreateTableAsSelect(tableName, sql));
84
84
  return tableName;
85
85
  }
@@ -87,11 +87,11 @@ class StageWriter {
87
87
  // return SQL and the last stage name
88
88
  combineStages(includeLastStage) {
89
89
  if (!this.useCTE) {
90
- return { "sql": this.withs[0], "lastStageName": this.withs[0] };
90
+ return { sql: this.withs[0], lastStageName: this.withs[0] };
91
91
  }
92
92
  let lastStageName = this.getName(0);
93
- let prefix = `WITH `;
94
- let w = "";
93
+ let prefix = 'WITH ';
94
+ let w = '';
95
95
  for (let i = 0; i < this.withs.length - (includeLastStage ? 0 : 1); i++) {
96
96
  const sql = this.withs[i];
97
97
  lastStageName = this.getName(i);
@@ -99,18 +99,18 @@ class StageWriter {
99
99
  throw new Error(`Expected sql WITH to be present for stage ${lastStageName}.`);
100
100
  }
101
101
  w += `${prefix}${lastStageName} AS (\n${(0, utils_1.indent)(sql)})\n`;
102
- prefix = ", ";
102
+ prefix = ', ';
103
103
  }
104
- return { "sql": w, lastStageName };
104
+ return { sql: w, lastStageName };
105
105
  }
106
106
  /** emit the SQL for all the stages. */
107
107
  generateSQLStages() {
108
108
  const lastStageNum = this.withs.length - 1;
109
109
  if (lastStageNum < 0) {
110
- throw new Error("No SQL generated");
110
+ throw new Error('No SQL generated');
111
111
  }
112
- const udfs = this.udfs.join(`\n`);
113
- const pdts = this.pdts.join(`\n`);
112
+ const udfs = this.udfs.join('\n');
113
+ const pdts = this.pdts.join('\n');
114
114
  const sql = this.combineStages(false).sql;
115
115
  return udfs + pdts + sql + this.withs[lastStageNum];
116
116
  }
@@ -180,12 +180,12 @@ class QueryField extends QueryNode {
180
180
  getJoinableParent() {
181
181
  // if it is inline it should always have a parent
182
182
  const parent = this.parent;
183
- if (parent.fieldDef.structRelationship.type === "inline") {
183
+ if (parent.fieldDef.structRelationship.type === 'inline') {
184
184
  if (parent) {
185
185
  return parent.getJoinableParent();
186
186
  }
187
187
  else {
188
- throw new Error(`Internal Error: inline struct cannot be root`);
188
+ throw new Error('Internal Error: inline struct cannot be root');
189
189
  }
190
190
  }
191
191
  return parent;
@@ -197,7 +197,7 @@ class QueryField extends QueryNode {
197
197
  else {
198
198
  const exp = groupSets.length === 1
199
199
  ? `=${groupSets[0]}`
200
- : ` IN (${groupSets.join(",")})`;
200
+ : ` IN (${groupSets.join(',')})`;
201
201
  return `CASE WHEN group_set${exp} THEN\n ${s}\n END`;
202
202
  }
203
203
  }
@@ -248,12 +248,12 @@ class QueryField extends QueryNode {
248
248
  }
249
249
  generateUngroupedFragment(resultSet, context, expr, state) {
250
250
  if (state.totalGroupSet !== -1) {
251
- throw new Error(`Already in ALL. Cannot nest within an all calcuation.`);
251
+ throw new Error('Already in ALL. Cannot nest within an all calcuation.');
252
252
  }
253
253
  let totalGroupSet;
254
254
  let ungroupSet;
255
255
  if (expr.fields && expr.fields.length > 0) {
256
- const key = expr.fields.sort().join("|") + expr.type;
256
+ const key = expr.fields.sort().join('|') + expr.type;
257
257
  ungroupSet = resultSet.ungroupedSets.get(key);
258
258
  if (ungroupSet === undefined) {
259
259
  throw new Error(`Internal Error, cannot find groupset with key ${key}`);
@@ -265,8 +265,8 @@ class QueryField extends QueryNode {
265
265
  }
266
266
  const s = this.generateExpressionFromExpr(resultSet, context, expr.e, state.withTotal(totalGroupSet));
267
267
  const fields = resultSet.getUngroupPartitions(ungroupSet);
268
- let partitionBy = "";
269
- const fieldsString = fields.map((f) => f.getPartitionSQL()).join(", ");
268
+ let partitionBy = '';
269
+ const fieldsString = fields.map(f => f.getPartitionSQL()).join(', ');
270
270
  if (fieldsString.length > 0) {
271
271
  partitionBy = `PARTITION BY ${fieldsString}`;
272
272
  }
@@ -303,9 +303,9 @@ class QueryField extends QueryNode {
303
303
  }
304
304
  generateSymmetricFragment(resultSet, context, expr, state) {
305
305
  const dimSQL = this.generateDimFragment(resultSet, context, expr, state);
306
- const f = expr.function === "count_distinct"
307
- ? "count(distinct "
308
- : expr.function + "(";
306
+ const f = expr.function === 'count_distinct'
307
+ ? 'count(distinct '
308
+ : expr.function + '(';
309
309
  return `${f}${dimSQL})`;
310
310
  }
311
311
  generateAvgFragment(resultSet, context, expr, state) {
@@ -331,11 +331,11 @@ class QueryField extends QueryNode {
331
331
  }
332
332
  }
333
333
  generateCountFragment(resultSet, context, expr, state) {
334
- let func = "COUNT(";
335
- let thing = "1";
334
+ let func = 'COUNT(';
335
+ let thing = '1';
336
336
  const distinctKeySQL = this.generateDistinctKeyIfNecessary(resultSet, context, expr.structPath);
337
337
  if (distinctKeySQL) {
338
- func = "COUNT(DISTINCT";
338
+ func = 'COUNT(DISTINCT';
339
339
  thing = distinctKeySQL;
340
340
  }
341
341
  // find the structDef and return the path to the field...
@@ -351,46 +351,46 @@ class QueryField extends QueryNode {
351
351
  }
352
352
  generateAnalyticFragment(resultStruct, context, expr, state) {
353
353
  const fields = resultStruct.getUngroupPartitions(undefined);
354
- let partitionBy = "";
355
- const fieldsString = fields.map((f) => f.getPartitionSQL()).join(", ");
354
+ let partitionBy = '';
355
+ const fieldsString = fields.map(f => f.getPartitionSQL()).join(', ');
356
356
  if (fieldsString.length > 0) {
357
357
  partitionBy = `PARTITION BY ${fieldsString}`;
358
358
  }
359
- let orderBy = "";
359
+ let orderBy = '';
360
360
  // calculate the ordering.
361
361
  const obSQL = [];
362
362
  let orderingField;
363
363
  const orderByDef = resultStruct.firstSegment.orderBy ||
364
364
  resultStruct.calculateDefaultOrderBy();
365
365
  for (const ordering of orderByDef) {
366
- if (typeof ordering.field === "string") {
366
+ if (typeof ordering.field === 'string') {
367
367
  orderingField = {
368
- "name": ordering.field,
369
- "fif": resultStruct.getField(ordering.field)
368
+ name: ordering.field,
369
+ fif: resultStruct.getField(ordering.field),
370
370
  };
371
371
  }
372
372
  else {
373
373
  orderingField = resultStruct.getFieldByNumber(ordering.field);
374
374
  }
375
- if (resultStruct.firstSegment.type === "reduce") {
375
+ if (resultStruct.firstSegment.type === 'reduce') {
376
376
  obSQL.push(` ${orderingField.fif.getSQL()}` +
377
377
  // this.parent.dialect.sqlMaybeQuoteIdentifier(
378
378
  // `${orderingField.name}__${resultStruct.groupSet}`
379
379
  // ) +
380
- ` ${ordering.dir || "ASC"}`);
380
+ ` ${ordering.dir || 'ASC'}`);
381
381
  }
382
- else if (resultStruct.firstSegment.type === "project") {
383
- obSQL.push(` ${orderingField.fif.f.generateExpression(resultStruct)} ${ordering.dir || "ASC"}`);
382
+ else if (resultStruct.firstSegment.type === 'project') {
383
+ obSQL.push(` ${orderingField.fif.f.generateExpression(resultStruct)} ${ordering.dir || 'ASC'}`);
384
384
  }
385
385
  }
386
386
  const func = malloy_types_1.malloyFunctions[expr.function];
387
387
  const paramSQL = [];
388
388
  if (expr.parameters !== undefined) {
389
389
  for (const e of expr.parameters) {
390
- if (typeof e === "string") {
390
+ if (typeof e === 'string') {
391
391
  paramSQL.push(e); // need to map to dimensional expression.
392
392
  }
393
- else if (typeof e === "number") {
393
+ else if (typeof e === 'number') {
394
394
  paramSQL.push(e.toString());
395
395
  }
396
396
  else {
@@ -399,15 +399,15 @@ class QueryField extends QueryNode {
399
399
  }
400
400
  }
401
401
  if (obSQL.length > 0) {
402
- orderBy = " " + this.parent.dialect.sqlOrderBy(obSQL);
402
+ orderBy = ' ' + this.parent.dialect.sqlOrderBy(obSQL);
403
403
  }
404
404
  const sqlName = func.sqlName || expr.function;
405
- return `${sqlName}(${paramSQL.join(", ")}) OVER(${partitionBy} ${orderBy} )`;
405
+ return `${sqlName}(${paramSQL.join(', ')}) OVER(${partitionBy} ${orderBy} )`;
406
406
  }
407
407
  generateExpressionFromExpr(resultSet, context, e, state = new GenerateState()) {
408
- let s = "";
408
+ let s = '';
409
409
  for (const expr of e) {
410
- if (typeof expr === "string") {
410
+ if (typeof expr === 'string') {
411
411
  s += expr;
412
412
  }
413
413
  else if ((0, malloy_types_1.isFieldFragment)(expr)) {
@@ -427,16 +427,16 @@ class QueryField extends QueryNode {
427
427
  }
428
428
  else if ((0, malloy_types_1.isAggregateFragment)(expr)) {
429
429
  let agg;
430
- if (expr.function === "sum") {
430
+ if (expr.function === 'sum') {
431
431
  agg = this.generateSumFragment(resultSet, context, expr, state);
432
432
  }
433
- else if (expr.function === "avg") {
433
+ else if (expr.function === 'avg') {
434
434
  agg = this.generateAvgFragment(resultSet, context, expr, state);
435
435
  }
436
- else if (expr.function === "count") {
436
+ else if (expr.function === 'count') {
437
437
  agg = this.generateCountFragment(resultSet, context, expr, state);
438
438
  }
439
- else if (["count_distinct", "min", "max"].includes(expr.function)) {
439
+ else if (['count_distinct', 'min', 'max'].includes(expr.function)) {
440
440
  agg = this.generateSymmetricFragment(resultSet, context, expr, state);
441
441
  }
442
442
  else {
@@ -462,10 +462,10 @@ class QueryField extends QueryNode {
462
462
  s += state.applyValue;
463
463
  }
464
464
  else {
465
- throw new Error(`Internal Error: Partial application value referenced but not provided`);
465
+ throw new Error('Internal Error: Partial application value referenced but not provided');
466
466
  }
467
467
  }
468
- else if (expr.type == "dialect") {
468
+ else if (expr.type === 'dialect') {
469
469
  s += this.generateDialect(resultSet, context, expr, state);
470
470
  }
471
471
  else {
@@ -479,11 +479,11 @@ class QueryField extends QueryNode {
479
479
  return this.fieldDef.e;
480
480
  }
481
481
  return [
482
- this.parent.dialect.sqlFieldReference(this.parent.getSQLIdentifier(), this.fieldDef.name, this.fieldDef.type, this.parent.fieldDef.structSource.type === "nested" ||
483
- this.parent.fieldDef.structSource.type === "inline" ||
484
- (this.parent.fieldDef.structSource.type === "sql" &&
485
- this.parent.fieldDef.structSource.method === "nested"), this.parent.fieldDef.structRelationship.type === "nested" &&
486
- this.parent.fieldDef.structRelationship.isArray)
482
+ this.parent.dialect.sqlFieldReference(this.parent.getSQLIdentifier(), this.fieldDef.name, this.fieldDef.type, this.parent.fieldDef.structSource.type === 'nested' ||
483
+ this.parent.fieldDef.structSource.type === 'inline' ||
484
+ (this.parent.fieldDef.structSource.type === 'sql' &&
485
+ this.parent.fieldDef.structSource.method === 'nested'), this.parent.fieldDef.structRelationship.type === 'nested' &&
486
+ this.parent.fieldDef.structRelationship.isArray),
487
487
  ];
488
488
  }
489
489
  generateExpression(resultSet) {
@@ -536,17 +536,17 @@ class QueryFieldStruct extends QueryAtomicField {
536
536
  getAsJoinedStructDef(foreignKeyName) {
537
537
  return {
538
538
  ...this.parent.fieldDef,
539
- "structRelationship": {
540
- "type": "one",
541
- "onExpression": [
539
+ structRelationship: {
540
+ type: 'one',
541
+ onExpression: [
542
542
  {
543
- "type": "field",
544
- "path": this.primaryKey
543
+ type: 'field',
544
+ path: this.primaryKey,
545
545
  },
546
- "=",
547
- { "type": "field", "path": foreignKeyName }
548
- ]
549
- }
546
+ '=',
547
+ { type: 'field', path: foreignKeyName },
548
+ ],
549
+ },
550
550
  };
551
551
  }
552
552
  }
@@ -557,7 +557,7 @@ class QueryFieldDate extends QueryAtomicField {
557
557
  return super.generateExpression(resultSet);
558
558
  }
559
559
  else {
560
- const truncated = this.parent.dialect.sqlTrunc({ "value": this.getExpr(), "valueType": "date" }, fd.timeframe);
560
+ const truncated = this.parent.dialect.sqlTrunc({ value: this.getExpr(), valueType: 'date' }, fd.timeframe);
561
561
  return this.generateExpressionFromExpr(resultSet, this.parent, truncated);
562
562
  }
563
563
  }
@@ -565,8 +565,8 @@ class QueryFieldDate extends QueryAtomicField {
565
565
  getChildByName(name) {
566
566
  const fieldDef = {
567
567
  ...this.fieldDef,
568
- "as": `${this.getIdentifier()}_${name}`,
569
- "timeframe": name
568
+ as: `${this.getIdentifier()}_${name}`,
569
+ timeframe: name,
570
570
  };
571
571
  return new QueryFieldDate(fieldDef, this.parent);
572
572
  }
@@ -576,8 +576,8 @@ class QueryFieldTimestamp extends QueryAtomicField {
576
576
  getChildByName(name) {
577
577
  const fieldDef = {
578
578
  ...this.fieldDef,
579
- "as": `${this.getIdentifier()}_${name}`,
580
- "timeframe": name
579
+ as: `${this.getIdentifier()}_${name}`,
580
+ timeframe: name,
581
581
  };
582
582
  return new QueryFieldTimestamp(fieldDef, this.parent);
583
583
  }
@@ -589,13 +589,13 @@ class QueryFieldDistinctKey extends QueryAtomicField {
589
589
  const pk = this.parent.getPrimaryKeyField(this.fieldDef);
590
590
  return pk.generateExpression(resultSet);
591
591
  }
592
- else if (this.parent.fieldDef.structSource.type === "nested") {
592
+ else if (this.parent.fieldDef.structSource.type === 'nested') {
593
593
  const parentKey = (_a = this.parent.parent) === null || _a === void 0 ? void 0 : _a.getDistinctKey().generateExpression(resultSet);
594
- return `CONCAT(${parentKey}, 'x', ${this.parent.dialect.sqlFieldReference(this.parent.getIdentifier(), "__row_id", "string", true, false)})`;
594
+ return `CONCAT(${parentKey}, 'x', ${this.parent.dialect.sqlFieldReference(this.parent.getIdentifier(), '__row_id', 'string', true, false)})`;
595
595
  }
596
596
  else {
597
597
  // return this.parent.getIdentifier() + "." + "__distinct_key";
598
- return this.parent.dialect.sqlFieldReference(this.parent.getIdentifier(), "__distinct_key", "string", this.parent.fieldDef.structRelationship.type === "nested", false);
598
+ return this.parent.dialect.sqlFieldReference(this.parent.getIdentifier(), '__distinct_key', 'string', this.parent.fieldDef.structRelationship.type === 'nested', false);
599
599
  }
600
600
  }
601
601
  includeInWildcard() {
@@ -622,7 +622,7 @@ function sqlSumDistinct(dialect, sqlExp, sqlDistintKey) {
622
622
  }
623
623
  class FieldInstanceField {
624
624
  constructor(f, fieldUsage, parent) {
625
- this.type = "field";
625
+ this.type = 'field';
626
626
  this.additionalGroupSets = [];
627
627
  this.f = f;
628
628
  this.fieldUsage = fieldUsage;
@@ -651,7 +651,7 @@ class FieldInstanceField {
651
651
  }
652
652
  class FieldInstanceResult {
653
653
  constructor(turtleDef, parent) {
654
- this.type = "query";
654
+ this.type = 'query';
655
655
  this.allFields = new Map();
656
656
  this.groupSet = 0;
657
657
  this.depth = 0;
@@ -667,12 +667,12 @@ class FieldInstanceResult {
667
667
  addField(as, field, usage) {
668
668
  let fi;
669
669
  if ((fi = this.allFields.get(as))) {
670
- if (fi.type === "query") {
670
+ if (fi.type === 'query') {
671
671
  throw new Error(`Redefinition of field ${field.fieldDef.name} as struct`);
672
672
  }
673
673
  const fif = fi;
674
- if (fif.fieldUsage.type === "result") {
675
- if (usage.type !== "result") {
674
+ if (fif.fieldUsage.type === 'result') {
675
+ if (usage.type !== 'result') {
676
676
  // its already in the result, we can just ignore it.
677
677
  return;
678
678
  }
@@ -711,9 +711,9 @@ class FieldInstanceResult {
711
711
  getFieldByNumber(index) {
712
712
  for (const [name, fi] of this.allFields) {
713
713
  if (fi instanceof FieldInstanceField) {
714
- if (fi.fieldUsage.type === "result" &&
714
+ if (fi.fieldUsage.type === 'result' &&
715
715
  fi.fieldUsage.resultIndex === index) {
716
- return { name, "fif": fi };
716
+ return { name, fif: fi };
717
717
  }
718
718
  }
719
719
  }
@@ -737,10 +737,10 @@ class FieldInstanceResult {
737
737
  let isComplex = false;
738
738
  let children = [this.groupSet];
739
739
  for (const [_name, fi] of this.allFields) {
740
- if (fi.type === "query") {
740
+ if (fi.type === 'query') {
741
741
  const fir = fi;
742
742
  isComplex = true;
743
- if (fir.firstSegment.type === "reduce") {
743
+ if (fir.firstSegment.type === 'reduce') {
744
744
  const r = fir.computeGroups(nextGroupSetNumber, depth + 1);
745
745
  children = children.concat(r.children);
746
746
  nextGroupSetNumber = r.nextGroupSetNumber;
@@ -779,14 +779,14 @@ class FieldInstanceResult {
779
779
  // and emit the resulting structure as a RECORD instead of REPEATED
780
780
  // if we have all numbers, we need to know because we'll have to conjur a record.
781
781
  getRepeatedResultType() {
782
- let ret = "inline_all_numbers";
782
+ let ret = 'inline_all_numbers';
783
783
  for (const f of this.fields()) {
784
- if (f.fieldUsage.type === "result") {
784
+ if (f.fieldUsage.type === 'result') {
785
785
  if (isScalarField(f.f)) {
786
- return "nested";
786
+ return 'nested';
787
787
  }
788
788
  if (f.f instanceof QueryStruct) {
789
- ret = "inline";
789
+ ret = 'inline';
790
790
  }
791
791
  }
792
792
  }
@@ -819,19 +819,19 @@ class FieldInstanceResult {
819
819
  let firstField;
820
820
  for (const [_name, fi] of this.allFields) {
821
821
  if (fi instanceof FieldInstanceField) {
822
- if (fi.fieldUsage.type === "result") {
822
+ if (fi.fieldUsage.type === 'result') {
823
823
  firstField || (firstField = fi.fieldUsage.resultIndex);
824
- if (["date", "timestamp"].indexOf(fi.f.fieldDef.type) > -1) {
825
- return [{ "dir": "desc", "field": fi.fieldUsage.resultIndex }];
824
+ if (['date', 'timestamp'].indexOf(fi.f.fieldDef.type) > -1) {
825
+ return [{ dir: 'desc', field: fi.fieldUsage.resultIndex }];
826
826
  }
827
827
  else if (isCalculatedField(fi.f)) {
828
- return [{ "dir": "desc", "field": fi.fieldUsage.resultIndex }];
828
+ return [{ dir: 'desc', field: fi.fieldUsage.resultIndex }];
829
829
  }
830
830
  }
831
831
  }
832
832
  }
833
833
  if (firstField) {
834
- return [{ "dir": "asc", "field": firstField }];
834
+ return [{ dir: 'asc', field: firstField }];
835
835
  }
836
836
  return [];
837
837
  }
@@ -863,7 +863,7 @@ class FieldInstanceResult {
863
863
  joinStack.indexOf(name) === -1) {
864
864
  query.addDependantExpr(this, qs.parent, sr.onExpression, [
865
865
  ...joinStack,
866
- name
866
+ name,
867
867
  ]);
868
868
  }
869
869
  if (!(join = this.root().joins.get(name))) {
@@ -884,7 +884,7 @@ class FieldInstanceResult {
884
884
  if (this.parent) {
885
885
  return this.parent.root();
886
886
  }
887
- throw new Error(`Internal Error, Null parent FieldInstanceResult`);
887
+ throw new Error('Internal Error, Null parent FieldInstanceResult');
888
888
  }
889
889
  getUngroupPartitions(ungroupSet) {
890
890
  let ret = [];
@@ -892,13 +892,13 @@ class FieldInstanceResult {
892
892
  let excludeFields = [];
893
893
  let inScopeFieldNames = [];
894
894
  // all defaults to all fields at the current level.
895
- if (ungroupSet === undefined || ungroupSet.type === "all") {
895
+ if (ungroupSet === undefined || ungroupSet.type === 'all') {
896
896
  // fields specified an an all, convert it to an exclude set.
897
897
  const allFields = (ungroupSet === null || ungroupSet === void 0 ? void 0 : ungroupSet.fields) || [];
898
898
  // convert an All into the equivalent exclude
899
- excludeFields = this.fields((fi) => isScalarField(fi.f) &&
900
- fi.fieldUsage.type === "result" &&
901
- allFields.indexOf(fi.f.getIdentifier()) === -1).map((fi) => fi.f.getIdentifier());
899
+ excludeFields = this.fields(fi => isScalarField(fi.f) &&
900
+ fi.fieldUsage.type === 'result' &&
901
+ allFields.indexOf(fi.f.getIdentifier()) === -1).map(fi => fi.f.getIdentifier());
902
902
  }
903
903
  else {
904
904
  excludeFields = ungroupSet.fields;
@@ -906,13 +906,13 @@ class FieldInstanceResult {
906
906
  let firstScope = true;
907
907
  while (p !== undefined) {
908
908
  // get a list of valid fieldnames for the current scope.
909
- if (firstScope || (ungroupSet === null || ungroupSet === void 0 ? void 0 : ungroupSet.type) === "exclude") {
909
+ if (firstScope || (ungroupSet === null || ungroupSet === void 0 ? void 0 : ungroupSet.type) === 'exclude') {
910
910
  inScopeFieldNames = inScopeFieldNames.concat(p
911
- .fields((fi) => isScalarField(fi.f) && fi.fieldUsage.type === "result")
912
- .map((fi) => fi.f.getIdentifier()));
911
+ .fields(fi => isScalarField(fi.f) && fi.fieldUsage.type === 'result')
912
+ .map(fi => fi.f.getIdentifier()));
913
913
  }
914
- ret = ret.concat(p.fields((fi) => isScalarField(fi.f) &&
915
- fi.fieldUsage.type === "result" &&
914
+ ret = ret.concat(p.fields(fi => isScalarField(fi.f) &&
915
+ fi.fieldUsage.type === 'result' &&
916
916
  excludeFields.indexOf(fi.f.getIdentifier()) === -1));
917
917
  p = p.parent;
918
918
  firstScope = false;
@@ -954,12 +954,12 @@ class FieldInstanceResultRoot extends FieldInstanceResult {
954
954
  // groups that were used in ungroup calculations. We need to do this only
955
955
  // once and in the very next stage.
956
956
  eliminateComputeGroupsSQL() {
957
- if (this.elimatedComputeGroups || this.computeOnlyGroups.length == 0) {
958
- return "";
957
+ if (this.elimatedComputeGroups || this.computeOnlyGroups.length === 0) {
958
+ return '';
959
959
  }
960
960
  else {
961
961
  this.elimatedComputeGroups = true;
962
- return `group_set NOT IN (${this.computeOnlyGroups.join(",")})`;
962
+ return `group_set NOT IN (${this.computeOnlyGroups.join(',')})`;
963
963
  }
964
964
  }
965
965
  // look at all the fields again in the structs in the query
@@ -968,14 +968,14 @@ class FieldInstanceResultRoot extends FieldInstanceResult {
968
968
  for (const [name, join] of this.joins) {
969
969
  // first join is by default the
970
970
  const relationship = join.parentRelationship();
971
- if (relationship === "many_to_many") {
971
+ if (relationship === 'many_to_many') {
972
972
  // everything must be calculated with symmetric aggregates
973
- leafiest = "0never";
973
+ leafiest = '0never';
974
974
  }
975
975
  else if (leafiest === undefined) {
976
976
  leafiest = name;
977
977
  }
978
- else if (join.parentRelationship() === "one_to_many") {
978
+ else if (join.parentRelationship() === 'one_to_many') {
979
979
  // check up the parent relationship until you find
980
980
  // the current leafiest node. If it isn't in the direct path
981
981
  // we need symmetric aggregate for everything.
@@ -986,7 +986,7 @@ class FieldInstanceResultRoot extends FieldInstanceResult {
986
986
  }
987
987
  else {
988
988
  // we have more than on one_to_many join chain, all bets are off.
989
- leafiest = "0never";
989
+ leafiest = '0never';
990
990
  }
991
991
  }
992
992
  }
@@ -1005,7 +1005,7 @@ class FieldInstanceResultRoot extends FieldInstanceResult {
1005
1005
  if (!j.queryStruct.primaryKey()) {
1006
1006
  j.makeUniqueKey = true;
1007
1007
  }
1008
- if (j.queryStruct.fieldDef.structRelationship.type === "nested") {
1008
+ if (j.queryStruct.fieldDef.structRelationship.type === 'nested') {
1009
1009
  j = j.parent;
1010
1010
  }
1011
1011
  else {
@@ -1034,9 +1034,9 @@ class JoinInstance {
1034
1034
  this.joinFilterConditions = [];
1035
1035
  for (const filter of this.queryStruct.fieldDef.filterList) {
1036
1036
  const qf = new QueryFieldBoolean({
1037
- "type": "boolean",
1038
- "name": "ignoreme",
1039
- "e": filter.expression
1037
+ type: 'boolean',
1038
+ name: 'ignoreme',
1039
+ e: filter.expression,
1040
1040
  }, this.queryStruct);
1041
1041
  this.joinFilterConditions.push(qf);
1042
1042
  }
@@ -1044,19 +1044,19 @@ class JoinInstance {
1044
1044
  }
1045
1045
  parentRelationship() {
1046
1046
  if (this.queryStruct.parent === undefined) {
1047
- return "root";
1047
+ return 'root';
1048
1048
  }
1049
1049
  switch (this.queryStruct.fieldDef.structRelationship.type) {
1050
- case "one":
1051
- return "many_to_one";
1052
- case "cross":
1053
- return "many_to_many";
1054
- case "many":
1055
- return "one_to_many";
1056
- case "nested":
1057
- return "one_to_many";
1058
- case "inline":
1059
- return "one_to_one";
1050
+ case 'one':
1051
+ return 'many_to_one';
1052
+ case 'cross':
1053
+ return 'many_to_many';
1054
+ case 'many':
1055
+ return 'one_to_many';
1056
+ case 'nested':
1057
+ return 'one_to_many';
1058
+ case 'inline':
1059
+ return 'one_to_one';
1060
1060
  default:
1061
1061
  throw new Error(`Internal error unknown relationship type to parent for ${this.queryStruct.fieldDef.name}`);
1062
1062
  }
@@ -1066,9 +1066,9 @@ class JoinInstance {
1066
1066
  const dialectFieldList = [];
1067
1067
  for (const f of this.queryStruct.fieldDef.fields.filter(malloy_types_1.isPhysical)) {
1068
1068
  dialectFieldList.push({
1069
- "type": f.type,
1070
- "sqlExpression": (0, malloy_types_1.getIdentifier)(f),
1071
- "sqlOutputName": (0, malloy_types_1.getIdentifier)(f)
1069
+ type: f.type,
1070
+ sqlExpression: (0, malloy_types_1.getIdentifier)(f),
1071
+ sqlOutputName: (0, malloy_types_1.getIdentifier)(f),
1072
1072
  });
1073
1073
  }
1074
1074
  return dialectFieldList;
@@ -1086,12 +1086,12 @@ class Segment {
1086
1086
  // static nextStructDef(s: StructDef, q: AnonymousQueryDef): StructDef
1087
1087
  static nextStructDef(structDef, segment) {
1088
1088
  const qs = new QueryStruct(structDef, {
1089
- "model": new QueryModel(undefined)
1089
+ model: new QueryModel(undefined),
1090
1090
  });
1091
1091
  const turtleDef = {
1092
- "type": "turtle",
1093
- "name": "ignoreme",
1094
- "pipeline": [segment]
1092
+ type: 'turtle',
1093
+ name: 'ignoreme',
1094
+ pipeline: [segment],
1095
1095
  };
1096
1096
  const queryQueryQuery = QueryQuery.makeQuery(turtleDef, qs, new StageWriter(true, undefined) // stage write indicates we want to get a result.
1097
1097
  );
@@ -1125,28 +1125,25 @@ class QueryQuery extends QueryField {
1125
1125
  firstStage.extendSource !== undefined) {
1126
1126
  parent = new QueryStruct({
1127
1127
  ...parentStruct.fieldDef,
1128
- "fields": [
1129
- ...parentStruct.fieldDef.fields,
1130
- ...firstStage.extendSource
1131
- ]
1132
- }, parent.parent ? { "struct": parent } : { "model": parent.model });
1128
+ fields: [...parentStruct.fieldDef.fields, ...firstStage.extendSource],
1129
+ }, parent.parent ? { struct: parent } : { model: parent.model });
1133
1130
  flatTurtleDef = {
1134
1131
  ...flatTurtleDef,
1135
- "pipeline": [
1132
+ pipeline: [
1136
1133
  {
1137
1134
  ...firstStage,
1138
- "extendSource": undefined
1135
+ extendSource: undefined,
1139
1136
  },
1140
- ...flatTurtleDef.pipeline.slice(1)
1141
- ]
1137
+ ...flatTurtleDef.pipeline.slice(1),
1138
+ ],
1142
1139
  };
1143
1140
  }
1144
1141
  switch (firstStage.type) {
1145
- case "reduce":
1142
+ case 'reduce':
1146
1143
  return new QueryQueryReduce(flatTurtleDef, parent, stageWriter);
1147
- case "project":
1144
+ case 'project':
1148
1145
  return new QueryQueryProject(flatTurtleDef, parent, stageWriter);
1149
- case "index":
1146
+ case 'index':
1150
1147
  return new QueryQueryIndex(flatTurtleDef, parent, stageWriter);
1151
1148
  }
1152
1149
  }
@@ -1154,11 +1151,11 @@ class QueryQuery extends QueryField {
1154
1151
  switch (this.firstSegment.type) {
1155
1152
  // case "index":
1156
1153
  // return this.firstSegment.fields || [];
1157
- case "reduce":
1154
+ case 'reduce':
1158
1155
  return this.firstSegment.fields;
1159
1156
  // probably need some way of checking type class of field here...
1160
1157
  // project should only contain scalars
1161
- case "project":
1158
+ case 'project':
1162
1159
  return this.firstSegment.fields;
1163
1160
  default:
1164
1161
  throw new Error(`Query contains no fields ${JSON.stringify(this.fieldDef)}`);
@@ -1169,19 +1166,19 @@ class QueryQuery extends QueryField {
1169
1166
  let as;
1170
1167
  let field;
1171
1168
  // if it is a string
1172
- if (typeof f === "string") {
1169
+ if (typeof f === 'string') {
1173
1170
  field = this.parent.getQueryFieldByName(f);
1174
1171
  }
1175
- else if ("type" in f) {
1172
+ else if ('type' in f) {
1176
1173
  field = this.parent.makeQueryField(f);
1177
1174
  }
1178
1175
  // or FilteredAliasedName or a hacked timestamp field.
1179
- else if ("name" in f && "as" in f) {
1176
+ else if ('name' in f && 'as' in f) {
1180
1177
  field = this.parent.getQueryFieldByName(f.name);
1181
1178
  // QueryFieldStructs return new names...
1182
1179
  as = field.fieldDef.as || f.as;
1183
1180
  if (field instanceof QueryFieldStruct) {
1184
- throw new Error("Syntax currently disallowed. Semantics up for discussion");
1181
+ throw new Error('Syntax currently disallowed. Semantics up for discussion');
1185
1182
  }
1186
1183
  // Types of aliased fields.
1187
1184
  // turtles
@@ -1249,17 +1246,17 @@ class QueryQuery extends QueryField {
1249
1246
  expandWildCards(fields, filter = undefined) {
1250
1247
  let ret = [];
1251
1248
  for (const f of fields) {
1252
- if (typeof f !== "string") {
1249
+ if (typeof f !== 'string') {
1253
1250
  ret.push(f);
1254
1251
  }
1255
1252
  else {
1256
1253
  const fieldName = f;
1257
- const path = fieldName.split(".");
1258
- if (!path[path.length - 1].startsWith("*")) {
1254
+ const path = fieldName.split('.');
1255
+ if (!path[path.length - 1].startsWith('*')) {
1259
1256
  ret.push(f);
1260
1257
  }
1261
1258
  else {
1262
- const expandChildren = path.pop() === "**";
1259
+ const expandChildren = path.pop() === '**';
1263
1260
  let struct = this.parent;
1264
1261
  let pathElementName;
1265
1262
  while (path.length > 0 && (pathElementName = path.shift())) {
@@ -1290,7 +1287,7 @@ class QueryQuery extends QueryField {
1290
1287
  struct = node;
1291
1288
  }
1292
1289
  else {
1293
- throw new Error(`Internal Error: Unknown object type`);
1290
+ throw new Error('Internal Error: Unknown object type');
1294
1291
  }
1295
1292
  resultStruct
1296
1293
  .root()
@@ -1303,12 +1300,12 @@ class QueryQuery extends QueryField {
1303
1300
  resultStruct.root().isComplexQuery = true;
1304
1301
  resultStruct.root().queryUsesPartitioning = true;
1305
1302
  if (expr.fields && expr.fields.length > 0) {
1306
- const key = expr.fields.sort().join("|") + expr.type;
1303
+ const key = expr.fields.sort().join('|') + expr.type;
1307
1304
  if (resultStruct.ungroupedSets.get(key) === undefined) {
1308
1305
  resultStruct.ungroupedSets.set(key, {
1309
- "type": expr.type,
1310
- "fields": expr.fields,
1311
- "groupSet": -1
1306
+ type: expr.type,
1307
+ fields: expr.fields,
1308
+ groupSet: -1,
1312
1309
  });
1313
1310
  }
1314
1311
  }
@@ -1334,28 +1331,28 @@ class QueryQuery extends QueryField {
1334
1331
  else if ((0, malloy_types_1.isDialectFragment)(expr)) {
1335
1332
  const expressions = [];
1336
1333
  switch (expr.function) {
1337
- case "now":
1334
+ case 'now':
1338
1335
  break;
1339
- case "div":
1336
+ case 'div':
1340
1337
  expressions.push(expr.denominator);
1341
1338
  expressions.push(expr.numerator);
1342
1339
  break;
1343
- case "timeLiteral":
1340
+ case 'timeLiteral':
1344
1341
  break;
1345
- case "stringLiteral":
1342
+ case 'stringLiteral':
1346
1343
  break;
1347
- case "timeDiff":
1344
+ case 'timeDiff':
1348
1345
  expressions.push(expr.left.value, expr.right.value);
1349
1346
  break;
1350
- case "delta":
1347
+ case 'delta':
1351
1348
  expressions.push(expr.base.value, expr.delta);
1352
1349
  break;
1353
- case "trunc":
1354
- case "extract":
1350
+ case 'trunc':
1351
+ case 'extract':
1355
1352
  expressions.push(expr.expr.value);
1356
1353
  break;
1357
- case "regexpMatch":
1358
- case "cast":
1354
+ case 'regexpMatch':
1355
+ case 'cast':
1359
1356
  expressions.push(expr.expr);
1360
1357
  break;
1361
1358
  default:
@@ -1392,7 +1389,7 @@ class QueryQuery extends QueryField {
1392
1389
  for (const f of this.expandWildCards(resultStruct.firstSegment.fields)) {
1393
1390
  const { as, field } = this.expandField(f);
1394
1391
  if (field instanceof QueryTurtle || field instanceof QueryQuery) {
1395
- if (this.firstSegment.type === "project") {
1392
+ if (this.firstSegment.type === 'project') {
1396
1393
  throw new Error(`Turtled Queries cannot be used in PROJECT - '${field.fieldDef.name}'`);
1397
1394
  }
1398
1395
  const fir = new FieldInstanceResult(field.fieldDef, resultStruct);
@@ -1402,11 +1399,11 @@ class QueryQuery extends QueryField {
1402
1399
  else if (field instanceof QueryAtomicField) {
1403
1400
  resultStruct.addField(as, field, {
1404
1401
  resultIndex,
1405
- "type": "result"
1402
+ type: 'result',
1406
1403
  });
1407
1404
  this.addDependancies(resultStruct, field);
1408
1405
  if (isCalculatedField(field)) {
1409
- if (this.firstSegment.type === "project") {
1406
+ if (this.firstSegment.type === 'project') {
1410
1407
  throw new Error(`Aggregate Fields cannot be used in PROJECT - '${field.fieldDef.name}'`);
1411
1408
  }
1412
1409
  }
@@ -1446,7 +1443,7 @@ class QueryQuery extends QueryField {
1446
1443
  }
1447
1444
  for (const join of resultStruct.root().joins.values() || []) {
1448
1445
  for (const qf of join.joinFilterConditions || []) {
1449
- if (qf.fieldDef.type === "boolean" && qf.fieldDef.e) {
1446
+ if (qf.fieldDef.type === 'boolean' && qf.fieldDef.e) {
1450
1447
  this.addDependantExpr(resultStruct, qf.parent, qf.fieldDef.e, []);
1451
1448
  }
1452
1449
  }
@@ -1463,8 +1460,8 @@ class QueryQuery extends QueryField {
1463
1460
  // in the correct catgory.
1464
1461
  for (const cond of list || []) {
1465
1462
  const context = this.parent;
1466
- if ((which === "having" && (0, malloy_types_1.expressionIsCalculation)(cond.expressionType)) ||
1467
- (which === "where" && cond.expressionType === "scalar")) {
1463
+ if ((which === 'having' && (0, malloy_types_1.expressionIsCalculation)(cond.expressionType)) ||
1464
+ (which === 'where' && cond.expressionType === 'scalar')) {
1468
1465
  const sqlClause = this.generateExpressionFromExpr(resultStruct, context, cond.expression, undefined);
1469
1466
  resultFilters.add(sqlClause);
1470
1467
  }
@@ -1482,11 +1479,11 @@ class QueryQuery extends QueryField {
1482
1479
  // get the source fieldname and filters associated with the field (so we can drill later)
1483
1480
  getResultMetadata(fi) {
1484
1481
  if (fi instanceof FieldInstanceField) {
1485
- if (fi.fieldUsage.type === "result") {
1482
+ if (fi.fieldUsage.type === 'result') {
1486
1483
  const fieldDef = fi.f.fieldDef;
1487
1484
  let filterList;
1488
1485
  const sourceField = fi.f.parent.getFullOutputName() +
1489
- (fieldDef.name || fieldDef.as || "undefined");
1486
+ (fieldDef.name || fieldDef.as || 'undefined');
1490
1487
  const sourceExpression = fieldDef.code;
1491
1488
  const sourceClasses = [sourceField];
1492
1489
  if (isCalculatedField(fi.f)) {
@@ -1496,7 +1493,7 @@ class QueryQuery extends QueryField {
1496
1493
  sourceExpression,
1497
1494
  filterList,
1498
1495
  sourceClasses,
1499
- "fieldKind": "measure"
1496
+ fieldKind: 'measure',
1500
1497
  };
1501
1498
  }
1502
1499
  if (isScalarField(fi.f)) {
@@ -1505,7 +1502,7 @@ class QueryQuery extends QueryField {
1505
1502
  sourceExpression,
1506
1503
  filterList,
1507
1504
  sourceClasses,
1508
- "fieldKind": "dimension"
1505
+ fieldKind: 'dimension',
1509
1506
  };
1510
1507
  }
1511
1508
  else {
@@ -1524,8 +1521,8 @@ class QueryQuery extends QueryField {
1524
1521
  sourceField,
1525
1522
  filterList,
1526
1523
  sourceClasses,
1527
- "fieldKind": "struct",
1528
- limit
1524
+ fieldKind: 'struct',
1525
+ limit,
1529
1526
  };
1530
1527
  }
1531
1528
  }
@@ -1540,22 +1537,22 @@ class QueryQuery extends QueryField {
1540
1537
  for (const [name, fi] of resultStruct.allFields) {
1541
1538
  const resultMetadata = this.getResultMetadata(fi);
1542
1539
  if (fi instanceof FieldInstanceResult) {
1543
- const { structDef } = this.generateTurtlePipelineSQL(fi, new StageWriter(true, undefined), "<nosource>");
1540
+ const { structDef } = this.generateTurtlePipelineSQL(fi, new StageWriter(true, undefined), '<nosource>');
1544
1541
  // LTNOTE: This is probably broken now. Need to look at the last stage
1545
1542
  // to figure out the resulting nested/inline state...
1546
- const resultType = fi.getRepeatedResultType() === "nested" ? "nested" : "inline";
1543
+ const resultType = fi.getRepeatedResultType() === 'nested' ? 'nested' : 'inline';
1547
1544
  structDef.name = name;
1548
1545
  structDef.structRelationship = {
1549
- "field": name,
1550
- "type": resultType,
1551
- "isArray": false
1546
+ field: name,
1547
+ type: resultType,
1548
+ isArray: false,
1552
1549
  };
1553
- structDef.structSource = { "type": resultType };
1550
+ structDef.structSource = { type: resultType };
1554
1551
  structDef.resultMetadata = resultMetadata;
1555
1552
  fields.push(structDef);
1556
1553
  }
1557
1554
  else if (fi instanceof FieldInstanceField) {
1558
- if (fi.fieldUsage.type === "result") {
1555
+ if (fi.fieldUsage.type === 'result') {
1559
1556
  if (fi.f instanceof QueryFieldStruct) {
1560
1557
  fields.push(fi.f.getAsJoinedStructDef(name));
1561
1558
  }
@@ -1573,74 +1570,74 @@ class QueryQuery extends QueryField {
1573
1570
  const location = fi.f.fieldDef.location;
1574
1571
  // build out the result fields...
1575
1572
  switch (fi.f.fieldDef.type) {
1576
- case "boolean":
1577
- case "json":
1578
- case "string":
1573
+ case 'boolean':
1574
+ case 'json':
1575
+ case 'string':
1579
1576
  fields.push({
1580
1577
  name,
1581
- "type": fi.f.fieldDef.type,
1578
+ type: fi.f.fieldDef.type,
1582
1579
  resultMetadata,
1583
- location
1580
+ location,
1584
1581
  });
1585
1582
  break;
1586
- case "timestamp": {
1583
+ case 'timestamp': {
1587
1584
  const timeframe = fi.f.fieldDef.timeframe;
1588
1585
  switch (timeframe) {
1589
- case "year":
1590
- case "month":
1591
- case "week":
1592
- case "quarter":
1593
- case "day":
1586
+ case 'year':
1587
+ case 'month':
1588
+ case 'week':
1589
+ case 'quarter':
1590
+ case 'day':
1594
1591
  fields.push({
1595
1592
  name,
1596
- "type": "date",
1593
+ type: 'date',
1597
1594
  timeframe,
1598
1595
  resultMetadata,
1599
- location
1596
+ location,
1600
1597
  });
1601
1598
  break;
1602
- case "second":
1603
- case "minute":
1604
- case "hour":
1599
+ case 'second':
1600
+ case 'minute':
1601
+ case 'hour':
1605
1602
  fields.push({
1606
1603
  name,
1607
- "type": "timestamp",
1604
+ type: 'timestamp',
1608
1605
  timeframe,
1609
1606
  resultMetadata,
1610
- location
1607
+ location,
1611
1608
  });
1612
1609
  break;
1613
1610
  default:
1614
1611
  fields.push({
1615
1612
  name,
1616
- "type": "timestamp",
1613
+ type: 'timestamp',
1617
1614
  resultMetadata,
1618
- location
1615
+ location,
1619
1616
  });
1620
1617
  break;
1621
1618
  }
1622
1619
  break;
1623
1620
  }
1624
- case "date": {
1621
+ case 'date': {
1625
1622
  fields.push({
1626
1623
  name,
1627
- "type": fi.f.fieldDef.type,
1628
- "timeframe": fi.f.fieldDef.timeframe,
1624
+ type: fi.f.fieldDef.type,
1625
+ timeframe: fi.f.fieldDef.timeframe,
1629
1626
  resultMetadata,
1630
- location
1627
+ location,
1631
1628
  });
1632
1629
  break;
1633
1630
  }
1634
- case "number":
1631
+ case 'number':
1635
1632
  fields.push({
1636
1633
  name,
1637
- "numberType": fi.f.fieldDef.numberType,
1638
- "type": "number",
1634
+ numberType: fi.f.fieldDef.numberType,
1635
+ type: 'number',
1639
1636
  resultMetadata,
1640
- location
1637
+ location,
1641
1638
  });
1642
1639
  break;
1643
- case "unsupported":
1640
+ case 'unsupported':
1644
1641
  fields.push({ ...fi.f.fieldDef, resultMetadata, location });
1645
1642
  break;
1646
1643
  default:
@@ -1651,20 +1648,20 @@ class QueryQuery extends QueryField {
1651
1648
  }
1652
1649
  return {
1653
1650
  fields,
1654
- "name": this.resultStage || "result",
1655
- "dialect": this.parent.dialect.name,
1651
+ name: this.resultStage || 'result',
1652
+ dialect: this.parent.dialect.name,
1656
1653
  primaryKey,
1657
- "structRelationship": {
1658
- "type": "basetable",
1659
- "connectionName": this.parent.connectionName
1654
+ structRelationship: {
1655
+ type: 'basetable',
1656
+ connectionName: this.parent.connectionName,
1660
1657
  },
1661
- "structSource": { "type": "query_result" },
1662
- "resultMetadata": this.getResultMetadata(this.rootResult),
1663
- "type": "struct"
1658
+ structSource: { type: 'query_result' },
1659
+ resultMetadata: this.getResultMetadata(this.rootResult),
1660
+ type: 'struct',
1664
1661
  };
1665
1662
  }
1666
1663
  generateSQLJoinBlock(stageWriter, ji) {
1667
- let s = "";
1664
+ let s = '';
1668
1665
  const qs = ji.queryStruct;
1669
1666
  const structRelationship = qs.fieldDef.structRelationship;
1670
1667
  let structSQL = qs.structSourceSQL(stageWriter);
@@ -1672,55 +1669,55 @@ class QueryQuery extends QueryField {
1672
1669
  if (ji.makeUniqueKey) {
1673
1670
  structSQL = `(SELECT ${qs.dialect.sqlGenerateUUID()} as __distinct_key, * FROM ${structSQL})`;
1674
1671
  }
1675
- let onCondition = "";
1672
+ let onCondition = '';
1676
1673
  if (qs.parent === undefined) {
1677
- throw new Error("Expected joined struct to have a parent.");
1674
+ throw new Error('Expected joined struct to have a parent.');
1678
1675
  }
1679
1676
  if (structRelationship.onExpression) {
1680
1677
  onCondition = new QueryFieldBoolean({
1681
- "type": "boolean",
1682
- "name": "ignoreme",
1683
- "e": structRelationship.onExpression
1678
+ type: 'boolean',
1679
+ name: 'ignoreme',
1680
+ e: structRelationship.onExpression,
1684
1681
  }, qs.parent).generateExpression(this.rootResult);
1685
1682
  }
1686
1683
  else {
1687
- onCondition = "1=1";
1684
+ onCondition = '1=1';
1688
1685
  }
1689
- let filters = "";
1686
+ let filters = '';
1690
1687
  let conditions = undefined;
1691
1688
  if (ji.joinFilterConditions) {
1692
- conditions = ji.joinFilterConditions.map((qf) => qf.generateExpression(this.rootResult));
1689
+ conditions = ji.joinFilterConditions.map(qf => qf.generateExpression(this.rootResult));
1693
1690
  }
1694
1691
  if (ji.children.length === 0 || conditions === undefined) {
1695
1692
  if (conditions !== undefined && conditions.length >= 1) {
1696
- filters = ` AND (${conditions.join(" AND ")})`;
1693
+ filters = ` AND (${conditions.join(' AND ')})`;
1697
1694
  }
1698
1695
  s += `LEFT JOIN ${structSQL} AS ${ji.alias}\n ON ${onCondition}${filters}\n`;
1699
1696
  }
1700
1697
  else {
1701
1698
  let select = `SELECT ${ji.alias}.*`;
1702
- let joins = "";
1699
+ let joins = '';
1703
1700
  for (const childJoin of ji.children) {
1704
1701
  joins += this.generateSQLJoinBlock(stageWriter, childJoin);
1705
- const physicalFields = (0, malloy_types_1.getPhysicalFields)(childJoin.queryStruct.fieldDef).map((fieldDef) => this.parent.dialect.sqlMaybeQuoteIdentifier(fieldDef.name));
1702
+ const physicalFields = (0, malloy_types_1.getPhysicalFields)(childJoin.queryStruct.fieldDef).map(fieldDef => this.parent.dialect.sqlMaybeQuoteIdentifier(fieldDef.name));
1706
1703
  select += `, ${this.parent.dialect.sqlSelectAliasAsStruct(childJoin.alias, physicalFields)} AS ${childJoin.alias}`;
1707
1704
  }
1708
- select += `\nFROM ${structSQL} AS ${ji.alias}\n${joins}\nWHERE ${conditions === null || conditions === void 0 ? void 0 : conditions.join(" AND ")}\n`;
1705
+ select += `\nFROM ${structSQL} AS ${ji.alias}\n${joins}\nWHERE ${conditions === null || conditions === void 0 ? void 0 : conditions.join(' AND ')}\n`;
1709
1706
  s += `LEFT JOIN (\n${(0, utils_1.indent)(select)}) AS ${ji.alias}\n ON ${onCondition}\n`;
1710
1707
  return s;
1711
1708
  }
1712
1709
  }
1713
- else if (structRelationship.type === "nested") {
1710
+ else if (structRelationship.type === 'nested') {
1714
1711
  if (qs.parent === undefined || ji.parent === undefined) {
1715
- throw new Error("Internal Error, nested structure with no parent.");
1712
+ throw new Error('Internal Error, nested structure with no parent.');
1716
1713
  }
1717
- const fieldExpression = this.parent.dialect.sqlFieldReference(qs.parent.getSQLIdentifier(), structRelationship.field, "struct", qs.parent.fieldDef.structRelationship.type === "nested", this.parent.fieldDef.structRelationship.type === "nested" &&
1714
+ const fieldExpression = this.parent.dialect.sqlFieldReference(qs.parent.getSQLIdentifier(), structRelationship.field, 'struct', qs.parent.fieldDef.structRelationship.type === 'nested', this.parent.fieldDef.structRelationship.type === 'nested' &&
1718
1715
  this.parent.fieldDef.structRelationship.isArray);
1719
1716
  // we need to generate primary key. If parent has a primary key combine
1720
1717
  s += `${this.parent.dialect.sqlUnnestAlias(fieldExpression, ji.alias, ji.getDialectFieldList(), ji.makeUniqueKey, structRelationship.isArray)}\n`;
1721
1718
  }
1722
- else if (structRelationship.type === "inline") {
1723
- throw new Error("Internal Error: inline structs should never appear in join trees");
1719
+ else if (structRelationship.type === 'inline') {
1720
+ throw new Error('Internal Error: inline structs should never appear in join trees');
1724
1721
  }
1725
1722
  else {
1726
1723
  throw new Error(`Join type not implemented ${JSON.stringify(qs.fieldDef.structRelationship)}`);
@@ -1731,7 +1728,7 @@ class QueryQuery extends QueryField {
1731
1728
  return s;
1732
1729
  }
1733
1730
  generateSQLJoins(stageWriter) {
1734
- let s = "";
1731
+ let s = '';
1735
1732
  // get the first value from the map (weird, I know)
1736
1733
  const [[, ji]] = this.rootResult.joins;
1737
1734
  const qs = ji.queryStruct;
@@ -1744,14 +1741,14 @@ class QueryQuery extends QueryField {
1744
1741
  }
1745
1742
  }
1746
1743
  const structRelationship = qs.fieldDef.structRelationship;
1747
- if (structRelationship.type === "basetable") {
1744
+ if (structRelationship.type === 'basetable') {
1748
1745
  if (ji.makeUniqueKey) {
1749
1746
  structSQL = `(SELECT ${qs.dialect.sqlGenerateUUID()} as __distinct_key, * FROM ${structSQL} as x)`;
1750
1747
  }
1751
1748
  s += `FROM ${structSQL} as ${this.parent.getIdentifier()}\n`;
1752
1749
  }
1753
1750
  else {
1754
- throw new Error("Internal Error, queries must start from a basetable");
1751
+ throw new Error('Internal Error, queries must start from a basetable');
1755
1752
  }
1756
1753
  for (const childJoin of ji.children) {
1757
1754
  s += this.generateSQLJoinBlock(stageWriter, childJoin);
@@ -1759,60 +1756,60 @@ class QueryQuery extends QueryField {
1759
1756
  return s;
1760
1757
  }
1761
1758
  genereateSQLOrderBy(queryDef, resultStruct) {
1762
- let s = "";
1763
- if (this.firstSegment.type === "project" && !queryDef.orderBy) {
1764
- return ""; // No default ordering for project.
1759
+ let s = '';
1760
+ if (this.firstSegment.type === 'project' && !queryDef.orderBy) {
1761
+ return ''; // No default ordering for project.
1765
1762
  }
1766
1763
  const orderBy = queryDef.orderBy || resultStruct.calculateDefaultOrderBy();
1767
1764
  const o = [];
1768
1765
  for (const f of orderBy) {
1769
- if (typeof f.field === "string") {
1766
+ if (typeof f.field === 'string') {
1770
1767
  // convert name to an index
1771
1768
  const fi = resultStruct.getField(f.field);
1772
- if (fi && fi.fieldUsage.type === "result") {
1773
- o.push(`${fi.fieldUsage.resultIndex} ${f.dir || "ASC"}`);
1769
+ if (fi && fi.fieldUsage.type === 'result') {
1770
+ o.push(`${fi.fieldUsage.resultIndex} ${f.dir || 'ASC'}`);
1774
1771
  }
1775
1772
  else {
1776
1773
  throw new Error(`Unknown field in ORDER BY ${f.field}`);
1777
1774
  }
1778
1775
  }
1779
1776
  else {
1780
- o.push(`${f.field} ${f.dir || "ASC"}`);
1777
+ o.push(`${f.field} ${f.dir || 'ASC'}`);
1781
1778
  }
1782
1779
  }
1783
1780
  if (o.length > 0) {
1784
- s = this.parent.dialect.sqlOrderBy(o) + `\n`;
1781
+ s = this.parent.dialect.sqlOrderBy(o) + '\n';
1785
1782
  }
1786
1783
  return s;
1787
1784
  }
1788
1785
  generateSimpleSQL(stageWriter) {
1789
- let s = "";
1790
- s += "SELECT \n";
1786
+ let s = '';
1787
+ s += 'SELECT \n';
1791
1788
  const fields = [];
1792
1789
  for (const [name, field] of this.rootResult.allFields) {
1793
1790
  const fi = field;
1794
1791
  const sqlName = this.parent.dialect.sqlMaybeQuoteIdentifier(name);
1795
- if (fi.fieldUsage.type === "result") {
1792
+ if (fi.fieldUsage.type === 'result') {
1796
1793
  fields.push(` ${fi.f.generateExpression(this.rootResult)} as ${sqlName}`);
1797
1794
  }
1798
1795
  }
1799
- s += (0, utils_1.indent)(fields.join(",\n")) + "\n";
1796
+ s += (0, utils_1.indent)(fields.join(',\n')) + '\n';
1800
1797
  s += this.generateSQLJoins(stageWriter);
1801
- s += this.generateSQLFilters(this.rootResult, "where").sql("where");
1798
+ s += this.generateSQLFilters(this.rootResult, 'where').sql('where');
1802
1799
  // group by
1803
- if (this.firstSegment.type === "reduce") {
1800
+ if (this.firstSegment.type === 'reduce') {
1804
1801
  const n = [];
1805
1802
  for (const field of this.rootResult.fields()) {
1806
1803
  const fi = field;
1807
- if (fi.fieldUsage.type === "result" && isScalarField(fi.f)) {
1804
+ if (fi.fieldUsage.type === 'result' && isScalarField(fi.f)) {
1808
1805
  n.push(fi.fieldUsage.resultIndex.toString());
1809
1806
  }
1810
1807
  }
1811
1808
  if (n.length > 0) {
1812
- s += `GROUP BY ${n.join(",")}\n`;
1809
+ s += `GROUP BY ${n.join(',')}\n`;
1813
1810
  }
1814
1811
  }
1815
- s += this.generateSQLFilters(this.rootResult, "having").sql("having");
1812
+ s += this.generateSQLFilters(this.rootResult, 'having').sql('having');
1816
1813
  // order by
1817
1814
  s += this.genereateSQLOrderBy(this.firstSegment, this.rootResult);
1818
1815
  // limit
@@ -1829,9 +1826,9 @@ class QueryQuery extends QueryField {
1829
1826
  return lastStageName;
1830
1827
  }
1831
1828
  const pipelinesSQL = outputPipelinedSQL
1832
- .map((o) => `${o.pipelineSQL} as ${o.sqlFieldName}
1829
+ .map(o => `${o.pipelineSQL} as ${o.sqlFieldName}
1833
1830
  `)
1834
- .join(",\n");
1831
+ .join(',\n');
1835
1832
  return stageWriter.addStage(`SELECT * replace (${pipelinesSQL}) FROM ${lastStageName}
1836
1833
  `);
1837
1834
  }
@@ -1839,15 +1836,15 @@ class QueryQuery extends QueryField {
1839
1836
  for (const [name, fi] of resultSet.allFields) {
1840
1837
  const outputName = this.parent.dialect.sqlMaybeQuoteIdentifier(`${name}__${resultSet.groupSet}`);
1841
1838
  if (fi instanceof FieldInstanceField) {
1842
- if (fi.fieldUsage.type === "result") {
1839
+ if (fi.fieldUsage.type === 'result') {
1843
1840
  const exp = fi.getSQL();
1844
1841
  if (isScalarField(fi.f)) {
1845
- if (this.parent.dialect.name === "standardsql" &&
1842
+ if (this.parent.dialect.name === 'standardsql' &&
1846
1843
  this.rootResult.queryUsesPartitioning) {
1847
1844
  // BigQuery can't partition aggregate function except when the field has no
1848
1845
  // expression. Additionally it can't partition by floats. We stuff expressions
1849
1846
  // and numbers as strings into a lateral join when the query has ungrouped expressions
1850
- if (fi.f.fieldDef.type === "number") {
1847
+ if (fi.f.fieldDef.type === 'number') {
1851
1848
  // make an extra dimension as a string
1852
1849
  output.sql.push(`${exp} as ${outputName}`);
1853
1850
  const outputFieldName = `__lateral_join_bag.${outputName}_string`;
@@ -1876,10 +1873,10 @@ class QueryQuery extends QueryField {
1876
1873
  }
1877
1874
  }
1878
1875
  else if (fi instanceof FieldInstanceResult) {
1879
- if (fi.firstSegment.type === "reduce") {
1876
+ if (fi.firstSegment.type === 'reduce') {
1880
1877
  this.generateStage0Fields(fi, output, stageWriter);
1881
1878
  }
1882
- else if (fi.firstSegment.type === "project") {
1879
+ else if (fi.firstSegment.type === 'project') {
1883
1880
  const s = this.generateTurtleSQL(fi, stageWriter, outputName, output.outputPipelinedSQL);
1884
1881
  output.sql.push(`${s} as ${outputName}`);
1885
1882
  output.fieldIndex++;
@@ -1890,7 +1887,7 @@ class QueryQuery extends QueryField {
1890
1887
  // leaf turtles can have their having clauses in the main query
1891
1888
  // turtles with leaves need to promote their state to their
1892
1889
  // children.
1893
- const having = this.generateSQLFilters(resultSet, "having");
1890
+ const having = this.generateSQLFilters(resultSet, 'having');
1894
1891
  if (!having.empty()) {
1895
1892
  // if we have no children, the having can run at the root level
1896
1893
  if (resultSet.childGroups.length === 1) {
@@ -1908,11 +1905,11 @@ class QueryQuery extends QueryField {
1908
1905
  generateSQLWhereChildren(resultStruct) {
1909
1906
  const wheres = new utils_1.AndChain();
1910
1907
  for (const [, field] of resultStruct.allFields) {
1911
- if (field.type === "query") {
1908
+ if (field.type === 'query') {
1912
1909
  const fir = field;
1913
- const turtleWhere = this.generateSQLFilters(fir, "where");
1910
+ const turtleWhere = this.generateSQLFilters(fir, 'where');
1914
1911
  if (turtleWhere.present()) {
1915
- const groupSets = fir.childGroups.join(",");
1912
+ const groupSets = fir.childGroups.join(',');
1916
1913
  wheres.add(`(group_set NOT IN (${groupSets})` +
1917
1914
  ` OR (group_set IN (${groupSets}) AND ${turtleWhere.sql()}))`);
1918
1915
  }
@@ -1922,9 +1919,9 @@ class QueryQuery extends QueryField {
1922
1919
  return wheres;
1923
1920
  }
1924
1921
  generateSQLWhereTurtled() {
1925
- const wheres = this.generateSQLFilters(this.rootResult, "where");
1922
+ const wheres = this.generateSQLFilters(this.rootResult, 'where');
1926
1923
  wheres.addChain(this.generateSQLWhereChildren(this.rootResult));
1927
- return wheres.sql("where");
1924
+ return wheres.sql('where');
1928
1925
  }
1929
1926
  // iterate over the nested queries looking for Havings (and someday limits).
1930
1927
  // if you find any, generate a new stage(s) to perform these functions.
@@ -1937,51 +1934,51 @@ class QueryQuery extends QueryField {
1937
1934
  const dimensions = [];
1938
1935
  let r = result;
1939
1936
  while (r) {
1940
- for (const name of r.fieldNames((fi) => isScalarField(fi.f))) {
1937
+ for (const name of r.fieldNames(fi => isScalarField(fi.f))) {
1941
1938
  dimensions.push(this.parent.dialect.sqlMaybeQuoteIdentifier(`${name}__${r.groupSet}`));
1942
1939
  }
1943
1940
  r = r.parent;
1944
1941
  }
1945
- fields.push(`MAX(CASE WHEN group_set IN (${result.childGroups.join(",")}) THEN __delete__${result.groupSet} END) OVER(partition by ${dimensions
1946
- .map((x) => `CAST(${x} AS ${this.parent.dialect.stringTypeName}) `)
1947
- .join(",")}) as __shaving__${result.groupSet}`);
1942
+ fields.push(`MAX(CASE WHEN group_set IN (${result.childGroups.join(',')}) THEN __delete__${result.groupSet} END) OVER(partition by ${dimensions
1943
+ .map(x => `CAST(${x} AS ${this.parent.dialect.stringTypeName}) `)
1944
+ .join(',')}) as __shaving__${result.groupSet}`);
1948
1945
  }
1949
1946
  }
1950
1947
  if (resultsWithHaving.length > 0) {
1951
- lastStageName = stageWriter.addStage(`SELECT\n *,\n ${fields.join(",\n ")} \nFROM ${lastStageName}`);
1948
+ lastStageName = stageWriter.addStage(`SELECT\n *,\n ${fields.join(',\n ')} \nFROM ${lastStageName}`);
1952
1949
  const havings = new utils_1.AndChain();
1953
1950
  for (const result of resultsWithHaving) {
1954
- havings.add(`group_set IN (${result.childGroups.join(",")}) AND __shaving__${result.groupSet}=1`);
1951
+ havings.add(`group_set IN (${result.childGroups.join(',')}) AND __shaving__${result.groupSet}=1`);
1955
1952
  }
1956
1953
  lastStageName = stageWriter.addStage(`SELECT *\nFROM ${lastStageName}\nWHERE NOT (${havings.sqlOr()})`);
1957
1954
  }
1958
1955
  return lastStageName;
1959
1956
  }
1960
1957
  generateSQLStage0(stageWriter) {
1961
- let s = "SELECT\n";
1958
+ let s = 'SELECT\n';
1962
1959
  let from = this.generateSQLJoins(stageWriter);
1963
1960
  const wheres = this.generateSQLWhereTurtled();
1964
1961
  const f = {
1965
- "dimensionIndexes": [1],
1966
- "fieldIndex": 2,
1967
- "sql": ["group_set"],
1968
- "lateralJoinSQLExpressions": [],
1969
- "groupsAggregated": [],
1970
- "outputPipelinedSQL": []
1962
+ dimensionIndexes: [1],
1963
+ fieldIndex: 2,
1964
+ sql: ['group_set'],
1965
+ lateralJoinSQLExpressions: [],
1966
+ groupsAggregated: [],
1967
+ outputPipelinedSQL: [],
1971
1968
  };
1972
1969
  this.generateStage0Fields(this.rootResult, f, stageWriter);
1973
- if (this.firstSegment.type === "project") {
1974
- throw new Error("PROJECT cannot be used on queries with turtles");
1970
+ if (this.firstSegment.type === 'project') {
1971
+ throw new Error('PROJECT cannot be used on queries with turtles');
1975
1972
  }
1976
- const groupBy = "GROUP BY " + f.dimensionIndexes.join(",") + "\n";
1977
- from += this.parent.dialect.sqlGroupSetTable(this.maxGroupSet) + "\n";
1978
- s += (0, utils_1.indent)(f.sql.join(",\n")) + "\n";
1973
+ const groupBy = 'GROUP BY ' + f.dimensionIndexes.join(',') + '\n';
1974
+ from += this.parent.dialect.sqlGroupSetTable(this.maxGroupSet) + '\n';
1975
+ s += (0, utils_1.indent)(f.sql.join(',\n')) + '\n';
1979
1976
  // this should only happen on standard SQL, BigQuery can't partition by expressions and
1980
1977
  // aggregates.
1981
1978
  if (f.lateralJoinSQLExpressions.length > 0) {
1982
- from += `LEFT JOIN UNNEST([STRUCT(${f.lateralJoinSQLExpressions.join(",\n")})]) as __lateral_join_bag\n`;
1979
+ from += `LEFT JOIN UNNEST([STRUCT(${f.lateralJoinSQLExpressions.join(',\n')})]) as __lateral_join_bag\n`;
1983
1980
  }
1984
- s += from + wheres + groupBy + this.rootResult.havings.sql("having");
1981
+ s += from + wheres + groupBy + this.rootResult.havings.sql('having');
1985
1982
  // generate the stage
1986
1983
  const resultStage = stageWriter.addStage(s);
1987
1984
  // generate stages for havings and limits
@@ -1994,7 +1991,7 @@ class QueryQuery extends QueryField {
1994
1991
  for (const [name, fi] of resultSet.allFields) {
1995
1992
  const sqlFieldName = this.parent.dialect.sqlMaybeQuoteIdentifier(`${name}__${resultSet.groupSet}`);
1996
1993
  if (fi instanceof FieldInstanceField) {
1997
- if (fi.fieldUsage.type === "result") {
1994
+ if (fi.fieldUsage.type === 'result') {
1998
1995
  if (isScalarField(fi.f)) {
1999
1996
  const exp = this.caseGroup(resultSet.groupSet > 0 ? resultSet.childGroups : [], sqlFieldName);
2000
1997
  output.sql.push(`${exp} as ${sqlFieldName}`);
@@ -2014,8 +2011,8 @@ class QueryQuery extends QueryField {
2014
2011
  else if (fi.depth === depth) {
2015
2012
  const s = this.generateTurtleSQL(fi, stageWriter, sqlFieldName, output.outputPipelinedSQL);
2016
2013
  output.groupsAggregated.push({
2017
- "fromGroup": fi.groupSet,
2018
- "toGroup": resultSet.groupSet
2014
+ fromGroup: fi.groupSet,
2015
+ toGroup: resultSet.groupSet,
2019
2016
  });
2020
2017
  groupsToMap.push(fi.groupSet);
2021
2018
  output.sql.push(`${s} as ${sqlFieldName}`);
@@ -2027,39 +2024,39 @@ class QueryQuery extends QueryField {
2027
2024
  }
2028
2025
  }
2029
2026
  if (output.groupsAggregated.length > 0) {
2030
- output.sql[0] = `CASE `;
2027
+ output.sql[0] = 'CASE ';
2031
2028
  for (const m of output.groupsAggregated) {
2032
2029
  output.sql[0] += `WHEN group_set=${m.fromGroup} THEN ${m.toGroup} `;
2033
2030
  }
2034
- output.sql[0] += ` ELSE group_set END as group_set`;
2031
+ output.sql[0] += ' ELSE group_set END as group_set';
2035
2032
  }
2036
2033
  }
2037
2034
  generateSQLDepthN(depth, stageWriter, stageName) {
2038
- let s = "SELECT \n";
2035
+ let s = 'SELECT \n';
2039
2036
  const f = {
2040
- "dimensionIndexes": [1],
2041
- "fieldIndex": 2,
2042
- "sql": ["group_set"],
2043
- "lateralJoinSQLExpressions": [],
2044
- "groupsAggregated": [],
2045
- "outputPipelinedSQL": []
2037
+ dimensionIndexes: [1],
2038
+ fieldIndex: 2,
2039
+ sql: ['group_set'],
2040
+ lateralJoinSQLExpressions: [],
2041
+ groupsAggregated: [],
2042
+ outputPipelinedSQL: [],
2046
2043
  };
2047
2044
  this.generateDepthNFields(depth, this.rootResult, f, stageWriter);
2048
- s += (0, utils_1.indent)(f.sql.join(",\n")) + "\n";
2045
+ s += (0, utils_1.indent)(f.sql.join(',\n')) + '\n';
2049
2046
  s += `FROM ${stageName}\n`;
2050
2047
  const where = this.rootResult.eliminateComputeGroupsSQL();
2051
2048
  if (where.length > 0) {
2052
2049
  s += `WHERE ${where}\n`;
2053
2050
  }
2054
2051
  if (f.dimensionIndexes.length > 0) {
2055
- s += `GROUP BY ${f.dimensionIndexes.join(",")}\n`;
2052
+ s += `GROUP BY ${f.dimensionIndexes.join(',')}\n`;
2056
2053
  }
2057
2054
  this.resultStage = stageWriter.addStage(s);
2058
2055
  this.resultStage = this.generatePipelinedStages(f.outputPipelinedSQL, this.resultStage, stageWriter);
2059
2056
  return this.resultStage;
2060
2057
  }
2061
2058
  genereateSQLCombineTurtles(stageWriter, stage0Name) {
2062
- let s = "SELECT\n";
2059
+ let s = 'SELECT\n';
2063
2060
  const fieldsSQL = [];
2064
2061
  let fieldIndex = 1;
2065
2062
  const outputPipelinedSQL = [];
@@ -2067,7 +2064,7 @@ class QueryQuery extends QueryField {
2067
2064
  for (const [name, fi] of this.rootResult.allFields) {
2068
2065
  const sqlName = this.parent.dialect.sqlMaybeQuoteIdentifier(name);
2069
2066
  if (fi instanceof FieldInstanceField) {
2070
- if (fi.fieldUsage.type === "result") {
2067
+ if (fi.fieldUsage.type === 'result') {
2071
2068
  if (isScalarField(fi.f)) {
2072
2069
  fieldsSQL.push(this.parent.dialect.sqlMaybeQuoteIdentifier(`${name}__${this.rootResult.groupSet}`) + ` as ${sqlName}`);
2073
2070
  dimensionIndexes.push(fieldIndex++);
@@ -2079,23 +2076,23 @@ class QueryQuery extends QueryField {
2079
2076
  }
2080
2077
  }
2081
2078
  else if (fi instanceof FieldInstanceResult) {
2082
- if (fi.firstSegment.type === "reduce") {
2079
+ if (fi.firstSegment.type === 'reduce') {
2083
2080
  fieldsSQL.push(`${this.generateTurtleSQL(fi, stageWriter, sqlName, outputPipelinedSQL)} as ${sqlName}`);
2084
2081
  fieldIndex++;
2085
2082
  }
2086
- else if (fi.firstSegment.type === "project") {
2083
+ else if (fi.firstSegment.type === 'project') {
2087
2084
  fieldsSQL.push(this.parent.dialect.sqlAnyValueLastTurtle(name, this.rootResult.groupSet, sqlName));
2088
2085
  fieldIndex++;
2089
2086
  }
2090
2087
  }
2091
2088
  }
2092
- s += (0, utils_1.indent)(fieldsSQL.join(",\n")) + `\nFROM ${stage0Name}\n`;
2089
+ s += (0, utils_1.indent)(fieldsSQL.join(',\n')) + `\nFROM ${stage0Name}\n`;
2093
2090
  const where = this.rootResult.eliminateComputeGroupsSQL();
2094
2091
  if (where.length > 0) {
2095
2092
  s += `WHERE ${where}\n`;
2096
2093
  }
2097
2094
  if (dimensionIndexes.length > 0) {
2098
- s += `GROUP BY ${dimensionIndexes.join(",")}\n`;
2095
+ s += `GROUP BY ${dimensionIndexes.join(',')}\n`;
2099
2096
  }
2100
2097
  // order by
2101
2098
  s += this.genereateSQLOrderBy(this.firstSegment, this.rootResult);
@@ -2110,7 +2107,7 @@ class QueryQuery extends QueryField {
2110
2107
  generateTurtleSQL(resultStruct, stageWriter, sqlFieldName, outputPipelinedSQL) {
2111
2108
  // let fieldsSQL: string[] = [];
2112
2109
  const dialectFieldList = [];
2113
- let orderBy = "";
2110
+ let orderBy = '';
2114
2111
  const limit = resultStruct.firstSegment.limit;
2115
2112
  // calculate the ordering.
2116
2113
  const obSQL = [];
@@ -2118,61 +2115,61 @@ class QueryQuery extends QueryField {
2118
2115
  const orderByDef = resultStruct.firstSegment.orderBy ||
2119
2116
  resultStruct.calculateDefaultOrderBy();
2120
2117
  for (const ordering of orderByDef) {
2121
- if (typeof ordering.field === "string") {
2118
+ if (typeof ordering.field === 'string') {
2122
2119
  orderingField = {
2123
- "name": ordering.field,
2124
- "fif": resultStruct.getField(ordering.field)
2120
+ name: ordering.field,
2121
+ fif: resultStruct.getField(ordering.field),
2125
2122
  };
2126
2123
  }
2127
2124
  else {
2128
2125
  orderingField = resultStruct.getFieldByNumber(ordering.field);
2129
2126
  }
2130
- if (resultStruct.firstSegment.type === "reduce") {
2131
- obSQL.push(" " +
2127
+ if (resultStruct.firstSegment.type === 'reduce') {
2128
+ obSQL.push(' ' +
2132
2129
  this.parent.dialect.sqlMaybeQuoteIdentifier(`${orderingField.name}__${resultStruct.groupSet}`) +
2133
- ` ${ordering.dir || "ASC"}`);
2130
+ ` ${ordering.dir || 'ASC'}`);
2134
2131
  }
2135
- else if (resultStruct.firstSegment.type === "project") {
2136
- obSQL.push(` ${orderingField.fif.f.generateExpression(resultStruct)} ${ordering.dir || "ASC"}`);
2132
+ else if (resultStruct.firstSegment.type === 'project') {
2133
+ obSQL.push(` ${orderingField.fif.f.generateExpression(resultStruct)} ${ordering.dir || 'ASC'}`);
2137
2134
  }
2138
2135
  }
2139
2136
  if (obSQL.length > 0) {
2140
- orderBy = " " + this.parent.dialect.sqlOrderBy(obSQL);
2137
+ orderBy = ' ' + this.parent.dialect.sqlOrderBy(obSQL);
2141
2138
  }
2142
2139
  for (const [name, field] of resultStruct.allFields) {
2143
2140
  const sqlName = this.parent.dialect.sqlMaybeQuoteIdentifier(name);
2144
2141
  //
2145
- if (resultStruct.firstSegment.type === "reduce" &&
2142
+ if (resultStruct.firstSegment.type === 'reduce' &&
2146
2143
  (field instanceof FieldInstanceResult ||
2147
2144
  (field instanceof FieldInstanceField &&
2148
- field.fieldUsage.type === "result"))) {
2145
+ field.fieldUsage.type === 'result'))) {
2149
2146
  // fieldsSQL.push(`${name}__${resultStruct.groupSet} as ${sqlName}`);
2150
2147
  // outputFieldNames.push(name);
2151
2148
  dialectFieldList.push({
2152
- "type": field instanceof FieldInstanceField
2149
+ type: field instanceof FieldInstanceField
2153
2150
  ? field.f.fieldDef.type
2154
- : "struct",
2155
- "sqlExpression": this.parent.dialect.sqlMaybeQuoteIdentifier(`${name}__${resultStruct.groupSet}`),
2156
- "sqlOutputName": sqlName
2151
+ : 'struct',
2152
+ sqlExpression: this.parent.dialect.sqlMaybeQuoteIdentifier(`${name}__${resultStruct.groupSet}`),
2153
+ sqlOutputName: sqlName,
2157
2154
  });
2158
2155
  }
2159
- else if (resultStruct.firstSegment.type === "project" &&
2156
+ else if (resultStruct.firstSegment.type === 'project' &&
2160
2157
  field instanceof FieldInstanceField &&
2161
- field.fieldUsage.type === "result") {
2158
+ field.fieldUsage.type === 'result') {
2162
2159
  // fieldsSQL.push(
2163
2160
  // `${field.f.generateExpression(resultStruct)} as ${sqlName}`
2164
2161
  // );
2165
2162
  dialectFieldList.push({
2166
- "type": field.type,
2167
- "sqlExpression": field.f.generateExpression(resultStruct),
2168
- "sqlOutputName": sqlName
2163
+ type: field.type,
2164
+ sqlExpression: field.f.generateExpression(resultStruct),
2165
+ sqlOutputName: sqlName,
2169
2166
  });
2170
2167
  }
2171
2168
  }
2172
2169
  let resultType;
2173
2170
  let ret;
2174
- if ((resultType = resultStruct.getRepeatedResultType()) !== "nested") {
2175
- if (resultType === "inline_all_numbers") {
2171
+ if ((resultType = resultStruct.getRepeatedResultType()) !== 'nested') {
2172
+ if (resultType === 'inline_all_numbers') {
2176
2173
  ret = this.parent.dialect.sqlCoaleseMeasuresInline(resultStruct.groupSet, dialectFieldList);
2177
2174
  }
2178
2175
  else {
@@ -2194,7 +2191,7 @@ class QueryQuery extends QueryField {
2194
2191
  else {
2195
2192
  outputPipelinedSQL.push({
2196
2193
  sqlFieldName,
2197
- "pipelineSQL": `(${sql})`
2194
+ pipelineSQL: `(${sql})`,
2198
2195
  });
2199
2196
  }
2200
2197
  }
@@ -2212,14 +2209,14 @@ class QueryQuery extends QueryField {
2212
2209
  const pipeline = [...fi.turtleDef.pipeline];
2213
2210
  pipeline.shift();
2214
2211
  const newTurtle = {
2215
- "type": "turtle",
2216
- "name": "starthere",
2217
- pipeline
2212
+ type: 'turtle',
2213
+ name: 'starthere',
2214
+ pipeline,
2218
2215
  };
2219
- structDef.name = this.parent.dialect.sqlUnnestPipelineHead(repeatedResultType === "inline_all_numbers", sourceSQLExpression);
2220
- structDef.structSource = { "type": "sql", "method": "nested" };
2216
+ structDef.name = this.parent.dialect.sqlUnnestPipelineHead(repeatedResultType === 'inline_all_numbers', sourceSQLExpression);
2217
+ structDef.structSource = { type: 'sql', method: 'nested' };
2221
2218
  const qs = new QueryStruct(structDef, {
2222
- "model": this.parent.getModel()
2219
+ model: this.parent.getModel(),
2223
2220
  });
2224
2221
  const q = QueryQuery.makeQuery(newTurtle, qs, stageWriter);
2225
2222
  pipeOut = q.generateSQLFromPipeline(stageWriter);
@@ -2228,7 +2225,7 @@ class QueryQuery extends QueryField {
2228
2225
  }
2229
2226
  return {
2230
2227
  structDef,
2231
- pipeOut
2228
+ pipeOut,
2232
2229
  };
2233
2230
  }
2234
2231
  generateComplexSQL(stageWriter) {
@@ -2259,7 +2256,7 @@ class QueryQuery extends QueryField {
2259
2256
  }
2260
2257
  toMalloy() {
2261
2258
  let ret = `EXPLORE ${(0, malloy_types_1.getIdentifier)(this.parent.fieldDef)} | `;
2262
- ret += this.fieldDef.type.toUpperCase() + " ";
2259
+ ret += this.fieldDef.type.toUpperCase() + ' ';
2263
2260
  return ret;
2264
2261
  }
2265
2262
  generateSQLFromPipeline(stageWriter) {
@@ -2271,20 +2268,20 @@ class QueryQuery extends QueryField {
2271
2268
  const pipeline = [...this.fieldDef.pipeline];
2272
2269
  let structDef = {
2273
2270
  ...outputStruct,
2274
- "structSource": { "type": "sql", "method": "lastStage" }
2271
+ structSource: { type: 'sql', method: 'lastStage' },
2275
2272
  };
2276
2273
  pipeline.shift();
2277
2274
  for (const transform of pipeline) {
2278
2275
  const s = new QueryStruct(structDef, {
2279
- "model": this.parent.getModel()
2276
+ model: this.parent.getModel(),
2280
2277
  });
2281
- const q = QueryQuery.makeQuery({ "type": "turtle", "name": "ignoreme", "pipeline": [transform] }, s, stageWriter);
2278
+ const q = QueryQuery.makeQuery({ type: 'turtle', name: 'ignoreme', pipeline: [transform] }, s, stageWriter);
2282
2279
  q.prepare(stageWriter);
2283
2280
  lastStageName = q.generateSQL(stageWriter);
2284
2281
  outputStruct = q.getResultStructDef();
2285
2282
  structDef = {
2286
2283
  ...outputStruct,
2287
- "structSource": { "type": "sql", "method": "lastStage" }
2284
+ structSource: { type: 'sql', method: 'lastStage' },
2288
2285
  };
2289
2286
  }
2290
2287
  }
@@ -2306,7 +2303,7 @@ class QueryQueryIndexStage extends QueryQuery {
2306
2303
  // get a field ref and expand it.
2307
2304
  expandField(f) {
2308
2305
  const field = this.parent.getFieldByName(f);
2309
- return { "as": f, field };
2306
+ return { as: f, field };
2310
2307
  }
2311
2308
  expandFields(resultStruct) {
2312
2309
  let resultIndex = 1;
@@ -2317,7 +2314,7 @@ class QueryQueryIndexStage extends QueryQuery {
2317
2314
  const { as, field } = this.expandField(f);
2318
2315
  resultStruct.addField(as, field, {
2319
2316
  resultIndex,
2320
- "type": "result"
2317
+ type: 'result',
2321
2318
  });
2322
2319
  if (field instanceof QueryAtomicField) {
2323
2320
  this.addDependancies(resultStruct, field);
@@ -2329,19 +2326,19 @@ class QueryQueryIndexStage extends QueryQuery {
2329
2326
  const f = this.parent.getFieldByName(measure);
2330
2327
  resultStruct.addField(measure, f, {
2331
2328
  resultIndex,
2332
- "type": "result"
2329
+ type: 'result',
2333
2330
  });
2334
2331
  this.addDependancies(resultStruct, f);
2335
2332
  }
2336
2333
  this.expandFilters(resultStruct);
2337
2334
  }
2338
2335
  generateSQL(stageWriter) {
2339
- let measureSQL = "COUNT(*)";
2336
+ let measureSQL = 'COUNT(*)';
2340
2337
  const dialect = this.parent.dialect;
2341
- const fieldNameColumn = dialect.sqlMaybeQuoteIdentifier("fieldName");
2342
- const fieldValueColumn = dialect.sqlMaybeQuoteIdentifier("fieldValue");
2343
- const fieldTypeColumn = dialect.sqlMaybeQuoteIdentifier("fieldType");
2344
- const fieldRangeColumn = dialect.sqlMaybeQuoteIdentifier("fieldRange");
2338
+ const fieldNameColumn = dialect.sqlMaybeQuoteIdentifier('fieldName');
2339
+ const fieldValueColumn = dialect.sqlMaybeQuoteIdentifier('fieldValue');
2340
+ const fieldTypeColumn = dialect.sqlMaybeQuoteIdentifier('fieldType');
2341
+ const fieldRangeColumn = dialect.sqlMaybeQuoteIdentifier('fieldRange');
2345
2342
  const measureName = this.firstSegment.weightMeasure;
2346
2343
  if (measureName) {
2347
2344
  measureSQL = this.rootResult
@@ -2351,37 +2348,37 @@ class QueryQueryIndexStage extends QueryQuery {
2351
2348
  const fields = [];
2352
2349
  for (const [name, field] of this.rootResult.allFields) {
2353
2350
  const fi = field;
2354
- if (fi.fieldUsage.type === "result" && isScalarField(fi.f)) {
2351
+ if (fi.fieldUsage.type === 'result' && isScalarField(fi.f)) {
2355
2352
  const expression = fi.f.generateExpression(this.rootResult);
2356
- fields.push({ name, "type": fi.f.fieldDef.type, expression });
2353
+ fields.push({ name, type: fi.f.fieldDef.type, expression });
2357
2354
  }
2358
2355
  }
2359
- let s = `SELECT\n group_set,\n`;
2360
- s += ` CASE group_set\n`;
2356
+ let s = 'SELECT\n group_set,\n';
2357
+ s += ' CASE group_set\n';
2361
2358
  for (let i = 0; i < fields.length; i++) {
2362
2359
  s += ` WHEN ${i} THEN '${fields[i].name}'\n`;
2363
2360
  }
2364
2361
  s += ` END as ${fieldNameColumn},`;
2365
- s += ` CASE group_set\n`;
2362
+ s += ' CASE group_set\n';
2366
2363
  for (let i = 0; i < fields.length; i++) {
2367
2364
  s += ` WHEN ${i} THEN '${fields[i].type}'\n`;
2368
2365
  }
2369
2366
  s += ` END as ${fieldTypeColumn},`;
2370
- s += ` CASE group_set WHEN 99999 THEN NULL\n`;
2367
+ s += ' CASE group_set WHEN 99999 THEN NULL\n';
2371
2368
  for (let i = 0; i < fields.length; i++) {
2372
- if (fields[i].type === "string") {
2369
+ if (fields[i].type === 'string') {
2373
2370
  s += ` WHEN ${i} THEN ${fields[i].expression}\n`;
2374
2371
  }
2375
2372
  }
2376
2373
  s += ` END as ${fieldValueColumn},\n`;
2377
2374
  s += ` ${measureSQL} as weight,\n`;
2378
2375
  // just in case we don't have any field types, force the case statement to have at least one value.
2379
- s += ` CASE group_set\n WHEN 99999 THEN ''`;
2376
+ s += " CASE group_set\n WHEN 99999 THEN ''";
2380
2377
  for (let i = 0; i < fields.length; i++) {
2381
- if (fields[i].type === "number") {
2378
+ if (fields[i].type === 'number') {
2382
2379
  s += ` WHEN ${i} THEN CAST(MIN(${fields[i].expression}) AS ${dialect.stringTypeName}) || ' to ' || CAST(MAX(${fields[i].expression}) AS ${dialect.stringTypeName})\n`;
2383
2380
  }
2384
- if (fields[i].type === "timestamp" || fields[i].type === "date") {
2381
+ if (fields[i].type === 'timestamp' || fields[i].type === 'date') {
2385
2382
  s += ` WHEN ${i} THEN MIN(${dialect.sqlDateToString(fields[i].expression)}) || ' to ' || MAX(${dialect.sqlDateToString(fields[i].expression)})\n`;
2386
2383
  }
2387
2384
  }
@@ -2394,9 +2391,9 @@ class QueryQueryIndexStage extends QueryQuery {
2394
2391
  // ELSE NULL
2395
2392
  // END as field_range\n`;
2396
2393
  s += this.generateSQLJoins(stageWriter);
2397
- s += dialect.sqlGroupSetTable(fields.length) + "\n";
2398
- s += this.generateSQLFilters(this.rootResult, "where").sql("where");
2399
- s += "GROUP BY 1,2,3,4\n";
2394
+ s += dialect.sqlGroupSetTable(fields.length) + '\n';
2395
+ s += this.generateSQLFilters(this.rootResult, 'where').sql('where');
2396
+ s += 'GROUP BY 1,2,3,4\n';
2400
2397
  // limit
2401
2398
  if (this.firstSegment.limit) {
2402
2399
  s += `LIMIT ${this.firstSegment.limit}\n`;
@@ -2425,8 +2422,8 @@ class QueryQueryIndex extends QueryQuery {
2425
2422
  findFanPrefexes(qs) {
2426
2423
  for (const [_name, f] of qs.nameMap) {
2427
2424
  if (f instanceof QueryStruct &&
2428
- (f.fieldDef.structRelationship.type === "many" ||
2429
- f.fieldDef.structRelationship.type === "nested") &&
2425
+ (f.fieldDef.structRelationship.type === 'many' ||
2426
+ f.fieldDef.structRelationship.type === 'nested') &&
2430
2427
  f.fieldDef.fields.length > 1 && // leave arrays in parent.
2431
2428
  this.parent.dialect.dontUnionIndex === false) {
2432
2429
  const key = f.getFullOutputName();
@@ -2439,9 +2436,9 @@ class QueryQueryIndex extends QueryQuery {
2439
2436
  // if no fields were specified, look in the parent struct for strings.
2440
2437
  let fieldNames = this.firstSegment.fields || [];
2441
2438
  if (fieldNames.length === 0) {
2442
- fieldNames.push("**");
2439
+ fieldNames.push('**');
2443
2440
  }
2444
- fieldNames = this.expandWildCards(fieldNames, (qf) => ["string", "number", "timestamp", "date"].indexOf(qf.fieldDef.type) !==
2441
+ fieldNames = this.expandWildCards(fieldNames, qf => ['string', 'number', 'timestamp', 'date'].indexOf(qf.fieldDef.type) !==
2445
2442
  -1);
2446
2443
  return fieldNames;
2447
2444
  }
@@ -2495,12 +2492,12 @@ class QueryQueryIndex extends QueryQuery {
2495
2492
  for (const fields of stages) {
2496
2493
  const q = new QueryQueryIndexStage({
2497
2494
  ...this.fieldDef,
2498
- "pipeline": [
2495
+ pipeline: [
2499
2496
  {
2500
2497
  ...this.fieldDef.pipeline[0],
2501
- "fields": fields
2502
- }
2503
- ]
2498
+ fields: fields,
2499
+ },
2500
+ ],
2504
2501
  }, this.parent, stageWriter);
2505
2502
  q.prepare(stageWriter);
2506
2503
  const lastStageName = q.generateSQL(stageWriter);
@@ -2510,29 +2507,27 @@ class QueryQueryIndex extends QueryQuery {
2510
2507
  this.resultStage = outputStageNames[0];
2511
2508
  }
2512
2509
  else {
2513
- this.resultStage = stageWriter.addStage(outputStageNames
2514
- .map((n) => `SELECT * FROM ${n}\n`)
2515
- .join(" UNION ALL \n"));
2510
+ this.resultStage = stageWriter.addStage(outputStageNames.map(n => `SELECT * FROM ${n}\n`).join(' UNION ALL \n'));
2516
2511
  }
2517
2512
  return this.resultStage;
2518
2513
  }
2519
2514
  /** All Indexes have the same output schema */
2520
2515
  getResultStructDef() {
2521
2516
  return {
2522
- "type": "struct",
2523
- "name": this.resultStage || "result",
2524
- "dialect": this.parent.fieldDef.dialect,
2525
- "fields": [
2526
- { "type": "string", "name": "fieldName" },
2527
- { "type": "string", "name": "fieldValue" },
2528
- { "type": "string", "name": "fieldType" },
2529
- { "type": "number", "name": "weight", "numberType": "integer" }
2517
+ type: 'struct',
2518
+ name: this.resultStage || 'result',
2519
+ dialect: this.parent.fieldDef.dialect,
2520
+ fields: [
2521
+ { type: 'string', name: 'fieldName' },
2522
+ { type: 'string', name: 'fieldValue' },
2523
+ { type: 'string', name: 'fieldType' },
2524
+ { type: 'number', name: 'weight', numberType: 'integer' },
2530
2525
  ],
2531
- "structRelationship": {
2532
- "type": "basetable",
2533
- "connectionName": this.parent.connectionName
2526
+ structRelationship: {
2527
+ type: 'basetable',
2528
+ connectionName: this.parent.connectionName,
2534
2529
  },
2535
- "structSource": { "type": "query_result" }
2530
+ structSource: { type: 'query_result' },
2536
2531
  };
2537
2532
  }
2538
2533
  }
@@ -2542,14 +2537,14 @@ class QueryStruct extends QueryNode {
2542
2537
  super(fieldDef);
2543
2538
  this.nameMap = new Map();
2544
2539
  this.setParent(parent);
2545
- if ("model" in parent) {
2540
+ if ('model' in parent) {
2546
2541
  this.model = parent.model;
2547
2542
  this.pathAliasMap = new Map();
2548
- if (fieldDef.structRelationship.type === "basetable") {
2543
+ if (fieldDef.structRelationship.type === 'basetable') {
2549
2544
  this.connectionName = fieldDef.structRelationship.connectionName;
2550
2545
  }
2551
2546
  else {
2552
- throw new Error("All root StructDefs should be a baseTable");
2547
+ throw new Error('All root StructDefs should be a baseTable');
2553
2548
  }
2554
2549
  }
2555
2550
  else {
@@ -2569,14 +2564,14 @@ class QueryStruct extends QueryNode {
2569
2564
  for (const field of fields) {
2570
2565
  const as = (0, malloy_types_1.getIdentifier)(field);
2571
2566
  switch (field.type) {
2572
- case "struct": {
2567
+ case 'struct': {
2573
2568
  this.addFieldToNameMap(as, new QueryStruct(field, {
2574
- "struct": this
2569
+ struct: this,
2575
2570
  }));
2576
2571
  break;
2577
2572
  }
2578
2573
  // case "reduce" || "project" || "index": {
2579
- case "turtle": {
2574
+ case 'turtle': {
2580
2575
  // not sure why we need to cast here...
2581
2576
  this.addFieldToNameMap(as, QueryQuery.makeQuery(field, this));
2582
2577
  break;
@@ -2587,8 +2582,8 @@ class QueryStruct extends QueryNode {
2587
2582
  }
2588
2583
  }
2589
2584
  // if we don't have distinct key yet for this struct, add it.
2590
- if (!this.nameMap.has("__distinct_key")) {
2591
- this.addFieldToNameMap("__distinct_key", new QueryFieldDistinctKey({ "type": "string", "name": "__distinct_key" }, this));
2585
+ if (!this.nameMap.has('__distinct_key')) {
2586
+ this.addFieldToNameMap('__distinct_key', new QueryFieldDistinctKey({ type: 'string', name: '__distinct_key' }, this));
2592
2587
  }
2593
2588
  }
2594
2589
  // generate unique string for the alias.
@@ -2612,7 +2607,7 @@ class QueryStruct extends QueryNode {
2612
2607
  return name;
2613
2608
  }
2614
2609
  else {
2615
- throw new Error("Internal Error: cannot create unique alias name");
2610
+ throw new Error('Internal Error: cannot create unique alias name');
2616
2611
  }
2617
2612
  // get the malloy name for this struct (will include a trailing dot)
2618
2613
  // return this.getFullOutputName().replace(/\.$/, "").replace(/\./g, "_o_");
@@ -2629,28 +2624,28 @@ class QueryStruct extends QueryNode {
2629
2624
  }
2630
2625
  const pkField = this.getPrimaryKeyField(this.fieldDef);
2631
2626
  const pkType = pkField.fieldDef.type;
2632
- if (pkType !== "string" && pkType !== "number") {
2627
+ if (pkType !== 'string' && pkType !== 'number') {
2633
2628
  throw new Error(`Unknown Primary key data type for ${pkField.fieldDef.name}`);
2634
2629
  }
2635
2630
  const aliasName = (0, malloy_types_1.getIdentifier)(this.fieldDef);
2636
2631
  const pkName = this.fieldDef.primaryKey;
2637
2632
  const fieldDef = {
2638
- "type": pkType,
2639
- "name": `${aliasName}_id`,
2640
- "e": [
2633
+ type: pkType,
2634
+ name: `${aliasName}_id`,
2635
+ e: [
2641
2636
  {
2642
- "type": "field",
2637
+ type: 'field',
2643
2638
  // path: pkField.getFullOutputName(),
2644
- "path": pkField.getIdentifier()
2645
- }
2646
- ]
2639
+ path: pkField.getIdentifier(),
2640
+ },
2641
+ ],
2647
2642
  };
2648
2643
  return new QueryFieldStruct(fieldDef, this, `${aliasName}.${pkName}`);
2649
2644
  }
2650
2645
  getSQLIdentifier() {
2651
2646
  if (this.unnestWithNumbers() && this.parent !== undefined) {
2652
2647
  const x = this.parent.getSQLIdentifier() +
2653
- "." +
2648
+ '.' +
2654
2649
  (0, malloy_types_1.getIdentifier)(this.fieldDef) +
2655
2650
  `[${this.getIdentifier()}.__row_id]`;
2656
2651
  return x;
@@ -2662,17 +2657,17 @@ class QueryStruct extends QueryNode {
2662
2657
  // return the name of the field in SQL
2663
2658
  getIdentifier() {
2664
2659
  // if it is the root table, use provided alias if we have one.
2665
- if (this.fieldDef.structRelationship.type === "basetable") {
2660
+ if (this.fieldDef.structRelationship.type === 'basetable') {
2666
2661
  if (this.fieldDef.as === undefined) {
2667
- return "base";
2662
+ return 'base';
2668
2663
  }
2669
2664
  else {
2670
2665
  return super.getIdentifier();
2671
2666
  }
2672
2667
  }
2673
2668
  // if this is an inline object, include the parents alias.
2674
- if (this.fieldDef.structRelationship.type === "inline" && this.parent) {
2675
- return this.parent.getSQLIdentifier() + "." + super.getIdentifier();
2669
+ if (this.fieldDef.structRelationship.type === 'inline' && this.parent) {
2670
+ return this.parent.getSQLIdentifier() + '.' + super.getIdentifier();
2676
2671
  }
2677
2672
  // we are somewhere in the join tree. Make sure the alias is unique.
2678
2673
  return this.getAliasIdentifier();
@@ -2680,10 +2675,10 @@ class QueryStruct extends QueryNode {
2680
2675
  // return the name of the field in Malloy
2681
2676
  getFullOutputName() {
2682
2677
  if (this.parent) {
2683
- return (this.parent.getFullOutputName() + (0, malloy_types_1.getIdentifier)(this.fieldDef) + ".");
2678
+ return (this.parent.getFullOutputName() + (0, malloy_types_1.getIdentifier)(this.fieldDef) + '.');
2684
2679
  }
2685
2680
  else {
2686
- return "";
2681
+ return '';
2687
2682
  }
2688
2683
  }
2689
2684
  needsSymetricCalculation(resultSet) {
@@ -2696,16 +2691,16 @@ class QueryStruct extends QueryNode {
2696
2691
  }
2697
2692
  unnestWithNumbers() {
2698
2693
  return (this.dialect.unnestWithNumbers &&
2699
- this.fieldDef.structRelationship.type === "nested");
2694
+ this.fieldDef.structRelationship.type === 'nested');
2700
2695
  }
2701
2696
  getJoinableParent() {
2702
2697
  // if it is inline it should always have a parent
2703
- if (this.fieldDef.structRelationship.type === "inline") {
2698
+ if (this.fieldDef.structRelationship.type === 'inline') {
2704
2699
  if (this.parent) {
2705
2700
  return this.parent.getJoinableParent();
2706
2701
  }
2707
2702
  else {
2708
- throw new Error(`Internal Error: inline struct cannot be root`);
2703
+ throw new Error('Internal Error: inline struct cannot be root');
2709
2704
  }
2710
2705
  }
2711
2706
  return this;
@@ -2732,7 +2727,7 @@ class QueryStruct extends QueryNode {
2732
2727
  * they exist) to the structure.
2733
2728
  */
2734
2729
  resolveQueryFields() {
2735
- if (this.fieldDef.structSource.type === "query") {
2730
+ if (this.fieldDef.structSource.type === 'query') {
2736
2731
  const structDef = this.model
2737
2732
  .loadQuery(this.fieldDef.structSource.query, undefined)
2738
2733
  .structs.pop();
@@ -2765,16 +2760,16 @@ class QueryStruct extends QueryNode {
2765
2760
  }
2766
2761
  else {
2767
2762
  if (this.parent === undefined) {
2768
- throw new Error("Expected this query struct to have a parent, as no model was present.");
2763
+ throw new Error('Expected this query struct to have a parent, as no model was present.');
2769
2764
  }
2770
2765
  return this.parent.getModel();
2771
2766
  }
2772
2767
  }
2773
2768
  setParent(parent) {
2774
- if ("struct" in parent) {
2769
+ if ('struct' in parent) {
2775
2770
  this.parent = parent.struct;
2776
2771
  }
2777
- if ("model" in parent) {
2772
+ if ('model' in parent) {
2778
2773
  this.model = parent.model;
2779
2774
  }
2780
2775
  else {
@@ -2784,24 +2779,24 @@ class QueryStruct extends QueryNode {
2784
2779
  /** makes a new queryable field object from a fieldDef */
2785
2780
  makeQueryField(field) {
2786
2781
  switch (field.type) {
2787
- case "string":
2782
+ case 'string':
2788
2783
  return new QueryFieldString(field, this);
2789
- case "date":
2784
+ case 'date':
2790
2785
  return new QueryFieldDate(field, this);
2791
- case "timestamp":
2786
+ case 'timestamp':
2792
2787
  return new QueryFieldTimestamp(field, this);
2793
- case "number":
2788
+ case 'number':
2794
2789
  return new QueryFieldNumber(field, this);
2795
- case "boolean":
2790
+ case 'boolean':
2796
2791
  return new QueryFieldBoolean(field, this);
2797
- case "json":
2792
+ case 'json':
2798
2793
  return new QueryFieldJSON(field, this);
2799
- case "unsupported":
2794
+ case 'unsupported':
2800
2795
  return new QueryFieldUnsupported(field, this);
2801
2796
  // case "reduce":
2802
2797
  // case "project":
2803
2798
  // case "index":
2804
- case "turtle":
2799
+ case 'turtle':
2805
2800
  return new QueryTurtle(field, this);
2806
2801
  default:
2807
2802
  throw new Error(`unknown field definition ${JSON.stringify(field)}`);
@@ -2811,7 +2806,7 @@ class QueryStruct extends QueryNode {
2811
2806
  * return a field if it exists, make one if we are passed a field definition.
2812
2807
  */
2813
2808
  getOrMakeField(fieldRef) {
2814
- if (typeof fieldRef === "string") {
2809
+ if (typeof fieldRef === 'string') {
2815
2810
  return this.getFieldByName(fieldRef);
2816
2811
  }
2817
2812
  else {
@@ -2830,31 +2825,31 @@ class QueryStruct extends QueryNode {
2830
2825
  }
2831
2826
  structSourceSQL(stageWriter) {
2832
2827
  switch (this.fieldDef.structSource.type) {
2833
- case "table": {
2828
+ case 'table': {
2834
2829
  const tablePath = this.fieldDef.structSource.tablePath;
2835
2830
  return this.dialect.quoteTablePath(tablePath);
2836
2831
  }
2837
- case "sql":
2838
- if (this.fieldDef.structSource.method === "nested" ||
2839
- this.fieldDef.structSource.method === "lastStage") {
2832
+ case 'sql':
2833
+ if (this.fieldDef.structSource.method === 'nested' ||
2834
+ this.fieldDef.structSource.method === 'lastStage') {
2840
2835
  return this.fieldDef.name;
2841
2836
  }
2842
- else if (this.fieldDef.structSource.method === "subquery") {
2837
+ else if (this.fieldDef.structSource.method === 'subquery') {
2843
2838
  return `(${this.fieldDef.structSource.sqlBlock.selectStr})`;
2844
2839
  }
2845
2840
  throw new Error("Internal Error: Unknown structSource type 'sql' method");
2846
- case "nested":
2841
+ case 'nested':
2847
2842
  // 'name' is always the source field even if has been renamed through
2848
2843
  // 'as'
2849
- return `UNNEST(this.fieldDef.name)`;
2850
- case "inline":
2851
- return "";
2852
- case "query": {
2844
+ return 'UNNEST(this.fieldDef.name)';
2845
+ case 'inline':
2846
+ return '';
2847
+ case 'query': {
2853
2848
  // cache derived table.
2854
2849
  const name = (0, malloy_types_1.getIdentifier)(this.fieldDef);
2855
2850
  // this is a hack for now. Need some way to denote this table
2856
2851
  // should be cached.
2857
- if (name.includes("cache")) {
2852
+ if (name.includes('cache')) {
2858
2853
  const dtStageWriter = new StageWriter(true, stageWriter);
2859
2854
  this.model.loadQuery(this.fieldDef.structSource.query, dtStageWriter);
2860
2855
  return dtStageWriter.addPDT(name, this.dialect);
@@ -2886,7 +2881,7 @@ class QueryStruct extends QueryNode {
2886
2881
  }
2887
2882
  /** get the componennts of a field path */
2888
2883
  static resolvePath(name) {
2889
- return name.split(".");
2884
+ return name.split('.');
2890
2885
  }
2891
2886
  getChildByName(name) {
2892
2887
  return this.nameMap.get(name);
@@ -2942,14 +2937,14 @@ class QueryStruct extends QueryNode {
2942
2937
  }
2943
2938
  }
2944
2939
  getDistinctKey() {
2945
- if (this.fieldDef.structRelationship.type !== "inline") {
2946
- return this.getDimensionByName("__distinct_key");
2940
+ if (this.fieldDef.structRelationship.type !== 'inline') {
2941
+ return this.getDimensionByName('__distinct_key');
2947
2942
  }
2948
2943
  else if (this.parent) {
2949
2944
  return this.parent.getDistinctKey();
2950
2945
  }
2951
2946
  else {
2952
- throw new Error("Internal Error. inline struct can not be top level");
2947
+ throw new Error('Internal Error. inline struct can not be top level');
2953
2948
  }
2954
2949
  }
2955
2950
  // take a TurtleDef that might have names and make it so it doesn't.
@@ -2970,10 +2965,10 @@ class QueryStruct extends QueryNode {
2970
2965
  pipeline = (0, cloneDeep_1.default)(pipeline);
2971
2966
  pipeline[0].filterList = addedFilters.concat(pipeline[0].filterList || [], this.fieldDef.filterList || []);
2972
2967
  const flatTurtleDef = {
2973
- "type": "turtle",
2974
- "name": turtleDef.name,
2968
+ type: 'turtle',
2969
+ name: turtleDef.name,
2975
2970
  pipeline,
2976
- "location": turtleDef.location
2971
+ location: turtleDef.location,
2977
2972
  };
2978
2973
  return flatTurtleDef;
2979
2974
  }
@@ -2995,21 +2990,21 @@ class QueryModel {
2995
2990
  this.modelDef = modelDef;
2996
2991
  for (const s of Object.values(this.modelDef.contents)) {
2997
2992
  let qs;
2998
- if (s.type === "struct") {
2999
- qs = new QueryStruct(s, { "model": this });
2993
+ if (s.type === 'struct') {
2994
+ qs = new QueryStruct(s, { model: this });
3000
2995
  this.structs.set((0, malloy_types_1.getIdentifier)(s), qs);
3001
2996
  qs.resolveQueryFields();
3002
2997
  }
3003
- else if (s.type === "query") {
2998
+ else if (s.type === 'query') {
3004
2999
  /* TODO */
3005
3000
  }
3006
3001
  else {
3007
- throw new Error("Internal Error: Unknown structure type");
3002
+ throw new Error('Internal Error: Unknown structure type');
3008
3003
  }
3009
3004
  }
3010
3005
  }
3011
3006
  parseQueryPath(name) {
3012
- const path = name.split(".");
3007
+ const path = name.split('.');
3013
3008
  let struct;
3014
3009
  if ((struct = this.structs.get(path[0]))) {
3015
3010
  if (path.length > 1) {
@@ -3018,7 +3013,7 @@ class QueryModel {
3018
3013
  else {
3019
3014
  throw new Error(`No query specified in Struct '${path[0]}'`);
3020
3015
  }
3021
- return { "queryName": path.join("."), struct };
3016
+ return { queryName: path.join('.'), struct };
3022
3017
  }
3023
3018
  else {
3024
3019
  throw new Error(`Cannot find Struct '${path[0]}' Model`);
@@ -3035,28 +3030,28 @@ class QueryModel {
3035
3030
  }
3036
3031
  getStructFromRef(structRef) {
3037
3032
  let structDef;
3038
- if (typeof structRef === "string") {
3033
+ if (typeof structRef === 'string') {
3039
3034
  return this.getStructByName(structRef);
3040
3035
  }
3041
- else if (structRef.type === "struct") {
3036
+ else if (structRef.type === 'struct') {
3042
3037
  structDef = structRef;
3043
3038
  }
3044
3039
  else {
3045
- throw new Error("Broken for now");
3040
+ throw new Error('Broken for now');
3046
3041
  }
3047
- return new QueryStruct(structDef, { "model": this });
3042
+ return new QueryStruct(structDef, { model: this });
3048
3043
  }
3049
3044
  loadQuery(query, stageWriter, emitFinalStage = false) {
3050
- const malloy = "";
3045
+ const malloy = '';
3051
3046
  if (!stageWriter) {
3052
3047
  stageWriter = new StageWriter(true, undefined);
3053
3048
  }
3054
3049
  const turtleDef = {
3055
- "type": "turtle",
3056
- "name": "ignoreme",
3057
- "pipeHead": query.pipeHead,
3058
- "pipeline": query.pipeline,
3059
- "filterList": query.filterList
3050
+ type: 'turtle',
3051
+ name: 'ignoreme',
3052
+ pipeHead: query.pipeHead,
3053
+ pipeline: query.pipeline,
3054
+ filterList: query.filterList,
3060
3055
  };
3061
3056
  const q = QueryQuery.makeQuery(turtleDef, this.getStructFromRef(query.structRef), stageWriter);
3062
3057
  const ret = q.generateSQLFromPipeline(stageWriter);
@@ -3065,28 +3060,28 @@ class QueryModel {
3065
3060
  // for (const f of ret.outputStruct.fields) {
3066
3061
  // fieldNames.push(getIdentifier(f));
3067
3062
  // }
3068
- const fieldNames = (0, malloy_types_1.getPhysicalFields)(ret.outputStruct).map((fieldDef) => q.parent.dialect.sqlMaybeQuoteIdentifier(fieldDef.name));
3063
+ const fieldNames = (0, malloy_types_1.getPhysicalFields)(ret.outputStruct).map(fieldDef => q.parent.dialect.sqlMaybeQuoteIdentifier(fieldDef.name));
3069
3064
  ret.lastStageName = stageWriter.addStage(q.parent.dialect.sqlFinalStage(ret.lastStageName, fieldNames));
3070
3065
  }
3071
3066
  return {
3072
- "lastStageName": ret.lastStageName,
3067
+ lastStageName: ret.lastStageName,
3073
3068
  malloy,
3074
3069
  stageWriter,
3075
- "structs": [ret.outputStruct],
3076
- "connectionName": q.parent.connectionName
3070
+ structs: [ret.outputStruct],
3071
+ connectionName: q.parent.connectionName,
3077
3072
  };
3078
3073
  }
3079
3074
  compileQuery(query, finalize = true) {
3080
3075
  let newModel;
3081
3076
  const m = newModel || this;
3082
3077
  const ret = m.loadQuery(query, undefined, finalize);
3083
- const sourceExplore = typeof query.structRef === "string"
3078
+ const sourceExplore = typeof query.structRef === 'string'
3084
3079
  ? query.structRef
3085
3080
  : // LTNOTE: the parser needs to capture the query before the |. This will work
3086
3081
  // in most cases but isn't actually complete.
3087
- query.structRef.type === "struct"
3082
+ query.structRef.type === 'struct'
3088
3083
  ? query.structRef.as || query.structRef.name
3089
- : "(need to figure this out)";
3084
+ : '(need to figure this out)';
3090
3085
  // LTNote: I don't understand why this might be here. It should have happened in loadQuery...
3091
3086
  if (finalize && this.dialect.hasFinalStage) {
3092
3087
  ret.lastStageName = ret.stageWriter.addStage(
@@ -3094,16 +3089,16 @@ class QueryModel {
3094
3089
  this.dialect.sqlFinalStage(ret.lastStageName, []));
3095
3090
  }
3096
3091
  return {
3097
- "lastStageName": ret.lastStageName,
3098
- "malloy": ret.malloy,
3099
- "sql": ret.stageWriter.generateSQLStages(),
3100
- "structs": ret.structs,
3092
+ lastStageName: ret.lastStageName,
3093
+ malloy: ret.malloy,
3094
+ sql: ret.stageWriter.generateSQLStages(),
3095
+ structs: ret.structs,
3101
3096
  sourceExplore,
3102
- "sourceFilters": query.filterList,
3103
- "queryName": query.pipeHead && query.pipeline.length === 0
3097
+ sourceFilters: query.filterList,
3098
+ queryName: query.pipeHead && query.pipeline.length === 0
3104
3099
  ? query.pipeHead.name
3105
3100
  : undefined,
3106
- "connectionName": ret.connectionName
3101
+ connectionName: ret.connectionName,
3107
3102
  };
3108
3103
  }
3109
3104
  async searchIndex(connection, explore, searchValue, limit = 1000, searchField = undefined) {
@@ -3113,28 +3108,28 @@ class QueryModel {
3113
3108
  // make a search index if one isn't modelled.
3114
3109
  const struct = this.getStructByName(explore);
3115
3110
  let indexQuery;
3116
- if (!struct.nameMap.get("search_index")) {
3111
+ if (!struct.nameMap.get('search_index')) {
3117
3112
  indexQuery = {
3118
- "structRef": explore,
3119
- "pipeline": [
3113
+ structRef: explore,
3114
+ pipeline: [
3120
3115
  {
3121
- "type": "index",
3122
- "fields": ["*"],
3123
- "sample": struct.dialect.defaultSampling
3124
- }
3125
- ]
3116
+ type: 'index',
3117
+ fields: ['*'],
3118
+ sample: struct.dialect.defaultSampling,
3119
+ },
3120
+ ],
3126
3121
  };
3127
3122
  }
3128
3123
  else {
3129
3124
  indexQuery = {
3130
- "structRef": explore,
3131
- "pipeHead": { "name": "search_index" },
3132
- "pipeline": []
3125
+ structRef: explore,
3126
+ pipeHead: { name: 'search_index' },
3127
+ pipeline: [],
3133
3128
  };
3134
3129
  }
3135
- const fieldNameColumn = struct.dialect.sqlMaybeQuoteIdentifier("fieldName");
3136
- const fieldValueColumn = struct.dialect.sqlMaybeQuoteIdentifier("fieldValue");
3137
- const fieldTypeColumn = struct.dialect.sqlMaybeQuoteIdentifier("fieldType");
3130
+ const fieldNameColumn = struct.dialect.sqlMaybeQuoteIdentifier('fieldName');
3131
+ const fieldValueColumn = struct.dialect.sqlMaybeQuoteIdentifier('fieldValue');
3132
+ const fieldTypeColumn = struct.dialect.sqlMaybeQuoteIdentifier('fieldType');
3138
3133
  // if we've compiled the SQL before use it otherwise
3139
3134
  let sqlPDT = this.exploreSearchSQLMap.get(explore);
3140
3135
  if (sqlPDT === undefined) {
@@ -3146,25 +3141,25 @@ class QueryModel {
3146
3141
  ${fieldValueColumn},
3147
3142
  ${fieldTypeColumn},
3148
3143
  weight,
3149
- CASE WHEN lower(${fieldValueColumn}) LIKE lower(${generateSQLStringLiteral(searchValue + "%")}) THEN 1 ELSE 0 END as match_first
3144
+ CASE WHEN lower(${fieldValueColumn}) LIKE lower(${generateSQLStringLiteral(searchValue + '%')}) THEN 1 ELSE 0 END as match_first
3150
3145
  FROM ${await connection.manifestTemporaryTable(sqlPDT)}
3151
- WHERE lower(${fieldValueColumn}) LIKE lower(${generateSQLStringLiteral("%" + searchValue + "%")}) ${searchField !== undefined
3146
+ WHERE lower(${fieldValueColumn}) LIKE lower(${generateSQLStringLiteral('%' + searchValue + '%')}) ${searchField !== undefined
3152
3147
  ? ` AND ${fieldNameColumn} = '` + searchField + "' \n"
3153
- : ""}
3154
- ORDER BY CASE WHEN lower(${fieldValueColumn}) LIKE lower(${generateSQLStringLiteral(searchValue + "%")}) THEN 1 ELSE 0 END DESC, weight DESC
3148
+ : ''}
3149
+ ORDER BY CASE WHEN lower(${fieldValueColumn}) LIKE lower(${generateSQLStringLiteral(searchValue + '%')}) THEN 1 ELSE 0 END DESC, weight DESC
3155
3150
  LIMIT ${limit}
3156
3151
  `;
3157
3152
  if (struct.dialect.hasFinalStage) {
3158
- query = `WITH __stage0 AS(\n${query}\n)\n${struct.dialect.sqlFinalStage("__stage0", [
3153
+ query = `WITH __stage0 AS(\n${query}\n)\n${struct.dialect.sqlFinalStage('__stage0', [
3159
3154
  fieldNameColumn,
3160
3155
  fieldValueColumn,
3161
3156
  fieldTypeColumn,
3162
- "weight",
3163
- "match_first"
3157
+ 'weight',
3158
+ 'match_first',
3164
3159
  ])}`;
3165
3160
  }
3166
3161
  const result = await connection.runSQL(query, {
3167
- "rowLimit": 1000
3162
+ rowLimit: 1000,
3168
3163
  });
3169
3164
  return result.rows;
3170
3165
  }
@@ -3172,14 +3167,14 @@ class QueryModel {
3172
3167
  exports.QueryModel = QueryModel;
3173
3168
  function flattenQuery(model, query) {
3174
3169
  let structRef = query.structRef;
3175
- if (typeof structRef !== "string") {
3170
+ if (typeof structRef !== 'string') {
3176
3171
  structRef = structRef.as || structRef.name;
3177
3172
  }
3178
3173
  const queryModel = new QueryModel(model);
3179
3174
  const queryStruct = queryModel.getStructByName(structRef);
3180
3175
  const turtleDef = queryStruct.flattenTurtleDef({
3181
3176
  ...query,
3182
- "type": "turtle"
3177
+ type: 'turtle',
3183
3178
  });
3184
3179
  return turtleDef;
3185
3180
  }