@malloydata/render 0.0.119-dev240116200529 → 0.0.119-dev240118211537

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.
@@ -3612,16 +3612,16 @@ ${(0, utils_1.indent)(sql)}
3612
3612
  return "GEN_RANDOM_UUID()";
3613
3613
  }
3614
3614
  sqlFieldReference(alias, fieldName, fieldType, isNested, _isArray) {
3615
- let ret = `${alias}->>'${fieldName}'`;
3615
+ let ret = `(${alias}->>'${fieldName}')`;
3616
3616
  if (isNested) {
3617
3617
  switch (fieldType) {
3618
3618
  case "string":
3619
3619
  break;
3620
3620
  case "number":
3621
- ret = `(${ret})::double precision`;
3621
+ ret = `${ret}::double precision`;
3622
3622
  break;
3623
3623
  case "struct":
3624
- ret = `(${ret})::jsonb`;
3624
+ ret = `${ret}::jsonb`;
3625
3625
  break;
3626
3626
  }
3627
3627
  return ret;
@@ -4678,6 +4678,16 @@ ${hackSplitComment}
4678
4678
  function identifierNormalize(s8) {
4679
4679
  return s8.replace(/[^a-zA-Z0-9_]/g, "_o_");
4680
4680
  }
4681
+ var UniqueKeyUse = class extends Set {
4682
+ add_use(k2) {
4683
+ if (k2 !== void 0) {
4684
+ return this.add(k2);
4685
+ }
4686
+ }
4687
+ hasAsymetricFunctions() {
4688
+ return this.has("sum") || this.has("avg") || this.has("count");
4689
+ }
4690
+ };
4681
4691
  var StageWriter = class {
4682
4692
  constructor(useCTE = true, parent) {
4683
4693
  this.parent = parent;
@@ -4809,8 +4819,8 @@ ${(0, utils_1.indent)(sql)})
4809
4819
  this.parent = parent;
4810
4820
  this.fieldDef = fieldDef;
4811
4821
  }
4812
- mayNeedUniqueKey() {
4813
- return false;
4822
+ uniqueKeyPossibleUse() {
4823
+ return void 0;
4814
4824
  }
4815
4825
  getJoinableParent() {
4816
4826
  const parent = this.parent;
@@ -5027,10 +5037,18 @@ ${(0, utils_1.indent)(sql)})
5027
5037
  generateCountFragment(resultSet, context3, expr2, state) {
5028
5038
  let func = "COUNT(";
5029
5039
  let thing = "1";
5030
- const distinctKeySQL = this.generateDistinctKeyIfNecessary(resultSet, context3, expr2.structPath);
5031
- if (distinctKeySQL) {
5040
+ let struct = context3;
5041
+ if (expr2.structPath) {
5042
+ struct = this.parent.root().getStructByName(expr2.structPath);
5043
+ }
5044
+ const joinName = struct.getJoinableParent().getIdentifier();
5045
+ const join3 = resultSet.root().joins.get(joinName);
5046
+ if (!join3) {
5047
+ throw new Error(`Join ${joinName} not found in result set`);
5048
+ }
5049
+ if (!join3.leafiest || join3.makeUniqueKey) {
5032
5050
  func = "COUNT(DISTINCT";
5033
- thing = distinctKeySQL;
5051
+ thing = struct.getDistinctKey().generateExpression(resultSet);
5034
5052
  }
5035
5053
  if (state.whereSQL) {
5036
5054
  return `${func} CASE WHEN ${state.whereSQL} THEN ${thing} END)`;
@@ -5293,7 +5311,12 @@ ${(0, utils_1.indent)(sql)})
5293
5311
  return pk.generateExpression(resultSet);
5294
5312
  } else if (this.parent.fieldDef.structSource.type === "nested") {
5295
5313
  const parentKey = (_a = this.parent.parent) === null || _a === void 0 ? void 0 : _a.getDistinctKey().generateExpression(resultSet);
5296
- return `CONCAT(${parentKey}, 'x', ${this.parent.dialect.sqlFieldReference(this.parent.getIdentifier(), "__row_id", "string", true, false)})`;
5314
+ return this.parent.dialect.concat(
5315
+ parentKey || "",
5316
+ // shouldn't have to do this...
5317
+ "'x'",
5318
+ this.parent.dialect.sqlFieldReference(this.parent.getIdentifier(), "__row_id", "string", true, false)
5319
+ );
5297
5320
  } else {
5298
5321
  return this.parent.dialect.sqlFieldReference(this.parent.getIdentifier(), "__distinct_key", "string", this.parent.fieldDef.structRelationship.type === "nested", false);
5299
5322
  }
@@ -5531,7 +5554,7 @@ ${(0, utils_1.indent)(sql)})
5531
5554
  }
5532
5555
  return [];
5533
5556
  }
5534
- addStructToJoin(qs, query, mayNeedUniqueKey, joinStack) {
5557
+ addStructToJoin(qs, query, uniqueKeyPossibleUse, joinStack) {
5535
5558
  var _a;
5536
5559
  const name = qs.getIdentifier();
5537
5560
  if (joinStack.indexOf(name) !== -1) {
@@ -5539,13 +5562,13 @@ ${(0, utils_1.indent)(sql)})
5539
5562
  }
5540
5563
  let join3;
5541
5564
  if (join3 = this.root().joins.get(name)) {
5542
- join3.mayNeedUniqueKey || (join3.mayNeedUniqueKey = mayNeedUniqueKey);
5565
+ join3.uniqueKeyPossibleUses.add_use(uniqueKeyPossibleUse);
5543
5566
  return;
5544
5567
  }
5545
5568
  let parent;
5546
5569
  const parentStruct = (_a = qs.parent) === null || _a === void 0 ? void 0 : _a.getJoinableParent();
5547
5570
  if (parentStruct) {
5548
- this.addStructToJoin(parentStruct, query, false, joinStack);
5571
+ this.addStructToJoin(parentStruct, query, void 0, joinStack);
5549
5572
  parent = this.root().joins.get(parentStruct.getIdentifier());
5550
5573
  }
5551
5574
  const sr = qs.fieldDef.structRelationship;
@@ -5560,11 +5583,11 @@ ${(0, utils_1.indent)(sql)})
5560
5583
  join3 = new JoinInstance(qs, name, parent);
5561
5584
  this.root().joins.set(name, join3);
5562
5585
  }
5563
- join3.mayNeedUniqueKey || (join3.mayNeedUniqueKey = mayNeedUniqueKey);
5586
+ join3.uniqueKeyPossibleUses.add_use(uniqueKeyPossibleUse);
5564
5587
  }
5565
5588
  findJoins(query) {
5566
5589
  for (const dim of this.fields()) {
5567
- this.addStructToJoin(dim.f.getJoinableParent(), query, dim.f.mayNeedUniqueKey(), []);
5590
+ this.addStructToJoin(dim.f.getJoinableParent(), query, dim.f.uniqueKeyPossibleUse(), []);
5568
5591
  }
5569
5592
  for (const s8 of this.structs()) {
5570
5593
  s8.findJoins(query);
@@ -5660,7 +5683,11 @@ ${(0, utils_1.indent)(sql)})
5660
5683
  join3.leafiest = name === leafiest;
5661
5684
  }
5662
5685
  for (const [_name, join3] of this.joins) {
5663
- if (!join3.leafiest && join3.mayNeedUniqueKey) {
5686
+ if (join3.leafiest) {
5687
+ if (join3.parent !== null && join3.uniqueKeyPossibleUses.has("count") && !join3.queryStruct.primaryKey()) {
5688
+ join3.makeUniqueKey = true;
5689
+ }
5690
+ } else if (!join3.leafiest && join3.uniqueKeyPossibleUses.hasAsymetricFunctions()) {
5664
5691
  let j2 = join3;
5665
5692
  while (j2) {
5666
5693
  if (!j2.queryStruct.primaryKey()) {
@@ -5681,7 +5708,7 @@ ${(0, utils_1.indent)(sql)})
5681
5708
  this.queryStruct = queryStruct;
5682
5709
  this.alias = alias;
5683
5710
  this.parent = parent;
5684
- this.mayNeedUniqueKey = false;
5711
+ this.uniqueKeyPossibleUses = new UniqueKeyUse();
5685
5712
  this.makeUniqueKey = false;
5686
5713
  this.leafiest = false;
5687
5714
  this.children = [];
@@ -5914,7 +5941,7 @@ ${(0, utils_1.indent)(sql)})
5914
5941
  }
5915
5942
  return ret;
5916
5943
  }
5917
- addDependantPath(resultStruct, context3, path3, mayNeedUniqueKey, joinStack) {
5944
+ addDependantPath(resultStruct, context3, path3, uniqueKeyPossibleUse, joinStack) {
5918
5945
  const node = context3.getFieldByName(path3);
5919
5946
  let struct;
5920
5947
  if (node instanceof QueryField) {
@@ -5924,7 +5951,7 @@ ${(0, utils_1.indent)(sql)})
5924
5951
  } else {
5925
5952
  throw new Error("Internal Error: Unknown object type");
5926
5953
  }
5927
- resultStruct.root().addStructToJoin(struct.getJoinableParent(), this, mayNeedUniqueKey, joinStack);
5954
+ resultStruct.root().addStructToJoin(struct.getJoinableParent(), this, uniqueKeyPossibleUse, joinStack);
5928
5955
  }
5929
5956
  addDependantExpr(resultStruct, context3, e12, joinStack) {
5930
5957
  for (const expr2 of e12) {
@@ -5952,7 +5979,7 @@ ${(0, utils_1.indent)(sql)})
5952
5979
  if ((0, malloy_types_1.hasExpression)(field3.fieldDef)) {
5953
5980
  this.addDependantExpr(resultStruct, field3.parent, field3.fieldDef.e, joinStack);
5954
5981
  } else {
5955
- resultStruct.root().addStructToJoin(field3.parent.getJoinableParent(), this, false, joinStack);
5982
+ resultStruct.root().addStructToJoin(field3.parent.getJoinableParent(), this, void 0, joinStack);
5956
5983
  }
5957
5984
  } else if ((0, malloy_types_1.isFilterFragment)(expr2)) {
5958
5985
  for (const filterCond of expr2.filterList) {
@@ -5997,15 +6024,15 @@ ${(0, utils_1.indent)(sql)})
5997
6024
  } else if ((0, malloy_types_1.isAggregateFragment)(expr2)) {
5998
6025
  if ((0, malloy_types_1.isAsymmetricFragment)(expr2)) {
5999
6026
  if (expr2.structPath) {
6000
- this.addDependantPath(resultStruct, context3, expr2.structPath, true, joinStack);
6027
+ this.addDependantPath(resultStruct, context3, expr2.structPath, expr2.function, joinStack);
6001
6028
  } else {
6002
- resultStruct.addStructToJoin(context3, this, true, joinStack);
6029
+ resultStruct.addStructToJoin(context3, this, expr2.function, joinStack);
6003
6030
  }
6004
6031
  }
6005
6032
  this.addDependantExpr(resultStruct, context3, expr2.e, joinStack);
6006
6033
  } else if ((0, malloy_types_1.isFunctionCallFragment)(expr2)) {
6007
6034
  if (expr2.structPath) {
6008
- this.addDependantPath(resultStruct, context3, expr2.structPath, true, joinStack);
6035
+ this.addDependantPath(resultStruct, context3, expr2.structPath, "generic_aggregate", joinStack);
6009
6036
  }
6010
6037
  for (const e13 of expr2.args) {
6011
6038
  this.addDependantExpr(resultStruct, context3, e13, joinStack);
@@ -6082,7 +6109,7 @@ ${(0, utils_1.indent)(sql)})
6082
6109
  prepare(_stageWriter) {
6083
6110
  if (!this.prepared) {
6084
6111
  this.expandFields(this.rootResult);
6085
- this.rootResult.addStructToJoin(this.parent, this, false, []);
6112
+ this.rootResult.addStructToJoin(this.parent, this, void 0, []);
6086
6113
  this.rootResult.findJoins(this);
6087
6114
  this.rootResult.calculateSymmetricAggregates();
6088
6115
  this.prepared = true;