@malloydata/render 0.0.119-dev240116200529 → 0.0.119-dev240118215411
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.
|
@@ -235,8 +235,8 @@
|
|
|
235
235
|
"../malloy/dist/model/malloy_types.js"(exports) {
|
|
236
236
|
"use strict";
|
|
237
237
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
238
|
-
exports.
|
|
239
|
-
exports.isValueDate = exports.isValueTimestamp = exports.isValueBoolean = exports.isValueNumber = exports.isValueString = exports.isMeasureLike = exports.getPhysicalFields = exports.getDimensions = exports.isPhysical = exports.isDimensional = exports.isAtomicField = exports.isTurtleDef = exports.getIdentifier = exports.isFieldStructDef = exports.isFieldTimeBased = exports.isFieldTypeDef = exports.isSQLBlockStruct = exports.mergeEvalSpaces = exports.isSQLFragment = exports.isJoinOn = void 0;
|
|
238
|
+
exports.isSamplingEnable = exports.isSamplingPercent = exports.isSamplingRows = exports.isQuerySegment = exports.isProjectSegment = exports.isPartialSegment = exports.isReduceSegment = exports.refIsStructDef = exports.isByExpression = exports.isByName = exports.ValueType = exports.isExtractUnit = exports.isTimestampUnit = exports.isDateUnit = exports.FieldIsIntrinsic = exports.isCastType = exports.isAtomicFieldType = exports.isTimeFieldType = exports.hasExpression = exports.maxOfExpressionTypes = exports.maxExpressionType = exports.isExpressionTypeLEQ = exports.expressionIsAnalytic = exports.expressionIsCalculation = exports.expressionInvolvesAggregate = exports.expressionIsUngroupedAggregate = exports.expressionIsAggregate = exports.expressionIsScalar = exports.mkExpr = exports.isApplyFragment = exports.isApplyValue = exports.isParameterFragment = exports.isSourceReferenceFragment = exports.isSqlStringFragment = exports.isFieldReferenceFragment = exports.isFieldFragment = exports.isSpreadFragment = exports.isSQLExpressionFragment = exports.isFunctionCallFragment = exports.isFunctionParameterFragment = exports.isUngroupFragment = exports.isAsymmetricFragment = exports.isAggregateFragment = exports.isDialectFragment = exports.isFilterFragment = exports.isOutputFieldFragment = exports.isFilteredAliasedName = exports.paramHasValue = exports.isConditionParameter = exports.isValueParameter = void 0;
|
|
239
|
+
exports.isValueDate = exports.isValueTimestamp = exports.isValueBoolean = exports.isValueNumber = exports.isValueString = exports.isMeasureLike = exports.getPhysicalFields = exports.getDimensions = exports.isPhysical = exports.isDimensional = exports.isAtomicField = exports.isTurtleDef = exports.getIdentifier = exports.isFieldStructDef = exports.isFieldTimeBased = exports.isFieldTypeDef = exports.isSQLBlockStruct = exports.mergeEvalSpaces = exports.isSQLFragment = exports.isJoinOn = exports.isMatrixOperation = exports.isIndexSegment = exports.isRawSegment = void 0;
|
|
240
240
|
function isValueParameter(p3) {
|
|
241
241
|
return p3.value !== void 0;
|
|
242
242
|
}
|
|
@@ -303,6 +303,18 @@
|
|
|
303
303
|
return (f4 === null || f4 === void 0 ? void 0 : f4.type) === "field";
|
|
304
304
|
}
|
|
305
305
|
exports.isFieldFragment = isFieldFragment;
|
|
306
|
+
function isFieldReferenceFragment(f4) {
|
|
307
|
+
return (f4 === null || f4 === void 0 ? void 0 : f4.type) === "field-reference";
|
|
308
|
+
}
|
|
309
|
+
exports.isFieldReferenceFragment = isFieldReferenceFragment;
|
|
310
|
+
function isSqlStringFragment(f4) {
|
|
311
|
+
return (f4 === null || f4 === void 0 ? void 0 : f4.type) === "sql-string";
|
|
312
|
+
}
|
|
313
|
+
exports.isSqlStringFragment = isSqlStringFragment;
|
|
314
|
+
function isSourceReferenceFragment(f4) {
|
|
315
|
+
return (f4 === null || f4 === void 0 ? void 0 : f4.type) === "source-reference";
|
|
316
|
+
}
|
|
317
|
+
exports.isSourceReferenceFragment = isSourceReferenceFragment;
|
|
306
318
|
function isParameterFragment(f4) {
|
|
307
319
|
return (f4 === null || f4 === void 0 ? void 0 : f4.type) === "parameter";
|
|
308
320
|
}
|
|
@@ -1349,6 +1361,11 @@
|
|
|
1349
1361
|
case "parameter":
|
|
1350
1362
|
case "outputField":
|
|
1351
1363
|
return fragment2;
|
|
1364
|
+
case "sql-string":
|
|
1365
|
+
return {
|
|
1366
|
+
...fragment2,
|
|
1367
|
+
e: exprMap(fragment2.e, func)
|
|
1368
|
+
};
|
|
1352
1369
|
case "function_call":
|
|
1353
1370
|
return {
|
|
1354
1371
|
...fragment2,
|
|
@@ -1455,6 +1472,11 @@
|
|
|
1455
1472
|
...fragment,
|
|
1456
1473
|
args: fragment.args.map((arg) => exprWalk(arg, func))
|
|
1457
1474
|
};
|
|
1475
|
+
case "sql-string":
|
|
1476
|
+
return {
|
|
1477
|
+
...fragment,
|
|
1478
|
+
e: exprWalk(fragment.e, func)
|
|
1479
|
+
};
|
|
1458
1480
|
case "filterExpression":
|
|
1459
1481
|
return {
|
|
1460
1482
|
...fragment,
|
|
@@ -2433,6 +2455,51 @@
|
|
|
2433
2455
|
}
|
|
2434
2456
|
});
|
|
2435
2457
|
|
|
2458
|
+
// ../malloy/dist/dialect/functions/sql.js
|
|
2459
|
+
var require_sql = __commonJS({
|
|
2460
|
+
"../malloy/dist/dialect/functions/sql.js"(exports) {
|
|
2461
|
+
"use strict";
|
|
2462
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
2463
|
+
exports.fnSqlBoolean = exports.fnSqlTimestamp = exports.fnSqlDate = exports.fnSqlString = exports.fnSqlNumber = void 0;
|
|
2464
|
+
var util_1 = require_util();
|
|
2465
|
+
function fnSqlNumber() {
|
|
2466
|
+
const value3 = (0, util_1.makeParam)("value", (0, util_1.literal)((0, util_1.maxScalar)("string")));
|
|
2467
|
+
return [
|
|
2468
|
+
(0, util_1.overload)((0, util_1.minScalar)("number"), [value3.param], [{ type: "sql-string", e: [value3.arg] }])
|
|
2469
|
+
];
|
|
2470
|
+
}
|
|
2471
|
+
exports.fnSqlNumber = fnSqlNumber;
|
|
2472
|
+
function fnSqlString() {
|
|
2473
|
+
const value3 = (0, util_1.makeParam)("value", (0, util_1.literal)((0, util_1.maxScalar)("string")));
|
|
2474
|
+
return [
|
|
2475
|
+
(0, util_1.overload)((0, util_1.minScalar)("string"), [value3.param], [{ type: "sql-string", e: [value3.arg] }])
|
|
2476
|
+
];
|
|
2477
|
+
}
|
|
2478
|
+
exports.fnSqlString = fnSqlString;
|
|
2479
|
+
function fnSqlDate() {
|
|
2480
|
+
const value3 = (0, util_1.makeParam)("value", (0, util_1.literal)((0, util_1.maxScalar)("string")));
|
|
2481
|
+
return [
|
|
2482
|
+
(0, util_1.overload)((0, util_1.minScalar)("date"), [value3.param], [{ type: "sql-string", e: [value3.arg] }])
|
|
2483
|
+
];
|
|
2484
|
+
}
|
|
2485
|
+
exports.fnSqlDate = fnSqlDate;
|
|
2486
|
+
function fnSqlTimestamp() {
|
|
2487
|
+
const value3 = (0, util_1.makeParam)("value", (0, util_1.literal)((0, util_1.maxScalar)("string")));
|
|
2488
|
+
return [
|
|
2489
|
+
(0, util_1.overload)((0, util_1.minScalar)("timestamp"), [value3.param], [{ type: "sql-string", e: [value3.arg] }])
|
|
2490
|
+
];
|
|
2491
|
+
}
|
|
2492
|
+
exports.fnSqlTimestamp = fnSqlTimestamp;
|
|
2493
|
+
function fnSqlBoolean() {
|
|
2494
|
+
const value3 = (0, util_1.makeParam)("value", (0, util_1.literal)((0, util_1.maxScalar)("string")));
|
|
2495
|
+
return [
|
|
2496
|
+
(0, util_1.overload)((0, util_1.minScalar)("boolean"), [value3.param], [{ type: "sql-string", e: [value3.arg] }])
|
|
2497
|
+
];
|
|
2498
|
+
}
|
|
2499
|
+
exports.fnSqlBoolean = fnSqlBoolean;
|
|
2500
|
+
}
|
|
2501
|
+
});
|
|
2502
|
+
|
|
2436
2503
|
// ../malloy/dist/dialect/functions/all_functions.js
|
|
2437
2504
|
var require_all_functions = __commonJS({
|
|
2438
2505
|
"../malloy/dist/dialect/functions/all_functions.js"(exports) {
|
|
@@ -2476,6 +2543,7 @@
|
|
|
2476
2543
|
var avg_moving_1 = require_avg_moving();
|
|
2477
2544
|
var function_map_1 = require_function_map();
|
|
2478
2545
|
var coalesce_1 = require_coalesce();
|
|
2546
|
+
var sql_1 = require_sql();
|
|
2479
2547
|
exports.FUNCTIONS = new function_map_1.FunctionMap();
|
|
2480
2548
|
exports.FUNCTIONS.add("concat", concat_1.fnConcat);
|
|
2481
2549
|
exports.FUNCTIONS.add("round", round_1.fnRound);
|
|
@@ -2538,6 +2606,11 @@
|
|
|
2538
2606
|
exports.FUNCTIONS.add("max_window", sum_min_max_window_1.fnMaxWindow);
|
|
2539
2607
|
exports.FUNCTIONS.add("sum_window", sum_min_max_window_1.fnSumWindow);
|
|
2540
2608
|
exports.FUNCTIONS.add("avg_moving", avg_moving_1.fnAvgRolling);
|
|
2609
|
+
exports.FUNCTIONS.add("sql_number", sql_1.fnSqlNumber);
|
|
2610
|
+
exports.FUNCTIONS.add("sql_string", sql_1.fnSqlString);
|
|
2611
|
+
exports.FUNCTIONS.add("sql_date", sql_1.fnSqlDate);
|
|
2612
|
+
exports.FUNCTIONS.add("sql_timestamp", sql_1.fnSqlTimestamp);
|
|
2613
|
+
exports.FUNCTIONS.add("sql_boolean", sql_1.fnSqlBoolean);
|
|
2541
2614
|
exports.FUNCTIONS.seal();
|
|
2542
2615
|
}
|
|
2543
2616
|
});
|
|
@@ -3612,16 +3685,16 @@ ${(0, utils_1.indent)(sql)}
|
|
|
3612
3685
|
return "GEN_RANDOM_UUID()";
|
|
3613
3686
|
}
|
|
3614
3687
|
sqlFieldReference(alias, fieldName, fieldType, isNested, _isArray) {
|
|
3615
|
-
let ret =
|
|
3688
|
+
let ret = `(${alias}->>'${fieldName}')`;
|
|
3616
3689
|
if (isNested) {
|
|
3617
3690
|
switch (fieldType) {
|
|
3618
3691
|
case "string":
|
|
3619
3692
|
break;
|
|
3620
3693
|
case "number":
|
|
3621
|
-
ret =
|
|
3694
|
+
ret = `${ret}::double precision`;
|
|
3622
3695
|
break;
|
|
3623
3696
|
case "struct":
|
|
3624
|
-
ret =
|
|
3697
|
+
ret = `${ret}::jsonb`;
|
|
3625
3698
|
break;
|
|
3626
3699
|
}
|
|
3627
3700
|
return ret;
|
|
@@ -4678,6 +4751,16 @@ ${hackSplitComment}
|
|
|
4678
4751
|
function identifierNormalize(s8) {
|
|
4679
4752
|
return s8.replace(/[^a-zA-Z0-9_]/g, "_o_");
|
|
4680
4753
|
}
|
|
4754
|
+
var UniqueKeyUse = class extends Set {
|
|
4755
|
+
add_use(k2) {
|
|
4756
|
+
if (k2 !== void 0) {
|
|
4757
|
+
return this.add(k2);
|
|
4758
|
+
}
|
|
4759
|
+
}
|
|
4760
|
+
hasAsymetricFunctions() {
|
|
4761
|
+
return this.has("sum") || this.has("avg") || this.has("count");
|
|
4762
|
+
}
|
|
4763
|
+
};
|
|
4681
4764
|
var StageWriter = class {
|
|
4682
4765
|
constructor(useCTE = true, parent) {
|
|
4683
4766
|
this.parent = parent;
|
|
@@ -4809,8 +4892,8 @@ ${(0, utils_1.indent)(sql)})
|
|
|
4809
4892
|
this.parent = parent;
|
|
4810
4893
|
this.fieldDef = fieldDef;
|
|
4811
4894
|
}
|
|
4812
|
-
|
|
4813
|
-
return
|
|
4895
|
+
uniqueKeyPossibleUse() {
|
|
4896
|
+
return void 0;
|
|
4814
4897
|
}
|
|
4815
4898
|
getJoinableParent() {
|
|
4816
4899
|
const parent = this.parent;
|
|
@@ -5027,10 +5110,18 @@ ${(0, utils_1.indent)(sql)})
|
|
|
5027
5110
|
generateCountFragment(resultSet, context3, expr2, state) {
|
|
5028
5111
|
let func = "COUNT(";
|
|
5029
5112
|
let thing = "1";
|
|
5030
|
-
|
|
5031
|
-
if (
|
|
5113
|
+
let struct = context3;
|
|
5114
|
+
if (expr2.structPath) {
|
|
5115
|
+
struct = this.parent.root().getStructByName(expr2.structPath);
|
|
5116
|
+
}
|
|
5117
|
+
const joinName = struct.getJoinableParent().getIdentifier();
|
|
5118
|
+
const join3 = resultSet.root().joins.get(joinName);
|
|
5119
|
+
if (!join3) {
|
|
5120
|
+
throw new Error(`Join ${joinName} not found in result set`);
|
|
5121
|
+
}
|
|
5122
|
+
if (!join3.leafiest || join3.makeUniqueKey) {
|
|
5032
5123
|
func = "COUNT(DISTINCT";
|
|
5033
|
-
thing =
|
|
5124
|
+
thing = struct.getDistinctKey().generateExpression(resultSet);
|
|
5034
5125
|
}
|
|
5035
5126
|
if (state.whereSQL) {
|
|
5036
5127
|
return `${func} CASE WHEN ${state.whereSQL} THEN ${thing} END)`;
|
|
@@ -5041,6 +5132,19 @@ ${(0, utils_1.indent)(sql)})
|
|
|
5041
5132
|
generateDialect(resultSet, context3, expr2, state) {
|
|
5042
5133
|
return this.generateExpressionFromExpr(resultSet, context3, context3.dialect.dialectExpr(resultSet.getQueryInfo(), expr2), state);
|
|
5043
5134
|
}
|
|
5135
|
+
generateFieldReference(resultSet, context3, expr2, state) {
|
|
5136
|
+
return this.generateFieldFragment(resultSet, context3, { type: "field", path: expr2.path }, state);
|
|
5137
|
+
}
|
|
5138
|
+
generateSqlString(resultSet, context3, expr2, state) {
|
|
5139
|
+
return expr2.e.map((part) => typeof part === "string" ? part : this.generateExpressionFromExpr(resultSet, context3, [part], state)).join("");
|
|
5140
|
+
}
|
|
5141
|
+
generateSourceReference(resultSet, context3, expr2) {
|
|
5142
|
+
if (expr2.path === void 0) {
|
|
5143
|
+
return context3.getSQLIdentifier();
|
|
5144
|
+
} else {
|
|
5145
|
+
return context3.getFieldByName(expr2.path).getIdentifier();
|
|
5146
|
+
}
|
|
5147
|
+
}
|
|
5044
5148
|
getAnalyticPartitions(resultStruct) {
|
|
5045
5149
|
const ret = [];
|
|
5046
5150
|
let p3 = resultStruct.parent;
|
|
@@ -5174,6 +5278,12 @@ ${(0, utils_1.indent)(sql)})
|
|
|
5174
5278
|
s8 += this.generateSpread(resultSet, context3, expr2, state);
|
|
5175
5279
|
} else if (expr2.type === "dialect") {
|
|
5176
5280
|
s8 += this.generateDialect(resultSet, context3, expr2, state);
|
|
5281
|
+
} else if (expr2.type === "sql-string") {
|
|
5282
|
+
s8 += this.generateSqlString(resultSet, context3, expr2, state);
|
|
5283
|
+
} else if (expr2.type === "source-reference") {
|
|
5284
|
+
s8 += this.generateSourceReference(resultSet, context3, expr2);
|
|
5285
|
+
} else if (expr2.type === "field-reference") {
|
|
5286
|
+
s8 += this.generateFieldReference(resultSet, context3, expr2, state);
|
|
5177
5287
|
} else {
|
|
5178
5288
|
throw new Error(`Internal Error: Unknown expression fragment ${JSON.stringify(expr2, void 0, 2)}`);
|
|
5179
5289
|
}
|
|
@@ -5293,7 +5403,12 @@ ${(0, utils_1.indent)(sql)})
|
|
|
5293
5403
|
return pk.generateExpression(resultSet);
|
|
5294
5404
|
} else if (this.parent.fieldDef.structSource.type === "nested") {
|
|
5295
5405
|
const parentKey = (_a = this.parent.parent) === null || _a === void 0 ? void 0 : _a.getDistinctKey().generateExpression(resultSet);
|
|
5296
|
-
return
|
|
5406
|
+
return this.parent.dialect.concat(
|
|
5407
|
+
parentKey || "",
|
|
5408
|
+
// shouldn't have to do this...
|
|
5409
|
+
"'x'",
|
|
5410
|
+
this.parent.dialect.sqlFieldReference(this.parent.getIdentifier(), "__row_id", "string", true, false)
|
|
5411
|
+
);
|
|
5297
5412
|
} else {
|
|
5298
5413
|
return this.parent.dialect.sqlFieldReference(this.parent.getIdentifier(), "__distinct_key", "string", this.parent.fieldDef.structRelationship.type === "nested", false);
|
|
5299
5414
|
}
|
|
@@ -5531,7 +5646,7 @@ ${(0, utils_1.indent)(sql)})
|
|
|
5531
5646
|
}
|
|
5532
5647
|
return [];
|
|
5533
5648
|
}
|
|
5534
|
-
addStructToJoin(qs, query,
|
|
5649
|
+
addStructToJoin(qs, query, uniqueKeyPossibleUse, joinStack) {
|
|
5535
5650
|
var _a;
|
|
5536
5651
|
const name = qs.getIdentifier();
|
|
5537
5652
|
if (joinStack.indexOf(name) !== -1) {
|
|
@@ -5539,13 +5654,13 @@ ${(0, utils_1.indent)(sql)})
|
|
|
5539
5654
|
}
|
|
5540
5655
|
let join3;
|
|
5541
5656
|
if (join3 = this.root().joins.get(name)) {
|
|
5542
|
-
join3.
|
|
5657
|
+
join3.uniqueKeyPossibleUses.add_use(uniqueKeyPossibleUse);
|
|
5543
5658
|
return;
|
|
5544
5659
|
}
|
|
5545
5660
|
let parent;
|
|
5546
5661
|
const parentStruct = (_a = qs.parent) === null || _a === void 0 ? void 0 : _a.getJoinableParent();
|
|
5547
5662
|
if (parentStruct) {
|
|
5548
|
-
this.addStructToJoin(parentStruct, query,
|
|
5663
|
+
this.addStructToJoin(parentStruct, query, void 0, joinStack);
|
|
5549
5664
|
parent = this.root().joins.get(parentStruct.getIdentifier());
|
|
5550
5665
|
}
|
|
5551
5666
|
const sr = qs.fieldDef.structRelationship;
|
|
@@ -5560,11 +5675,11 @@ ${(0, utils_1.indent)(sql)})
|
|
|
5560
5675
|
join3 = new JoinInstance(qs, name, parent);
|
|
5561
5676
|
this.root().joins.set(name, join3);
|
|
5562
5677
|
}
|
|
5563
|
-
join3.
|
|
5678
|
+
join3.uniqueKeyPossibleUses.add_use(uniqueKeyPossibleUse);
|
|
5564
5679
|
}
|
|
5565
5680
|
findJoins(query) {
|
|
5566
5681
|
for (const dim of this.fields()) {
|
|
5567
|
-
this.addStructToJoin(dim.f.getJoinableParent(), query, dim.f.
|
|
5682
|
+
this.addStructToJoin(dim.f.getJoinableParent(), query, dim.f.uniqueKeyPossibleUse(), []);
|
|
5568
5683
|
}
|
|
5569
5684
|
for (const s8 of this.structs()) {
|
|
5570
5685
|
s8.findJoins(query);
|
|
@@ -5660,7 +5775,11 @@ ${(0, utils_1.indent)(sql)})
|
|
|
5660
5775
|
join3.leafiest = name === leafiest;
|
|
5661
5776
|
}
|
|
5662
5777
|
for (const [_name, join3] of this.joins) {
|
|
5663
|
-
if (
|
|
5778
|
+
if (join3.leafiest) {
|
|
5779
|
+
if (join3.parent !== null && join3.uniqueKeyPossibleUses.has("count") && !join3.queryStruct.primaryKey()) {
|
|
5780
|
+
join3.makeUniqueKey = true;
|
|
5781
|
+
}
|
|
5782
|
+
} else if (!join3.leafiest && join3.uniqueKeyPossibleUses.hasAsymetricFunctions()) {
|
|
5664
5783
|
let j2 = join3;
|
|
5665
5784
|
while (j2) {
|
|
5666
5785
|
if (!j2.queryStruct.primaryKey()) {
|
|
@@ -5681,7 +5800,7 @@ ${(0, utils_1.indent)(sql)})
|
|
|
5681
5800
|
this.queryStruct = queryStruct;
|
|
5682
5801
|
this.alias = alias;
|
|
5683
5802
|
this.parent = parent;
|
|
5684
|
-
this.
|
|
5803
|
+
this.uniqueKeyPossibleUses = new UniqueKeyUse();
|
|
5685
5804
|
this.makeUniqueKey = false;
|
|
5686
5805
|
this.leafiest = false;
|
|
5687
5806
|
this.children = [];
|
|
@@ -5914,7 +6033,7 @@ ${(0, utils_1.indent)(sql)})
|
|
|
5914
6033
|
}
|
|
5915
6034
|
return ret;
|
|
5916
6035
|
}
|
|
5917
|
-
addDependantPath(resultStruct, context3, path3,
|
|
6036
|
+
addDependantPath(resultStruct, context3, path3, uniqueKeyPossibleUse, joinStack) {
|
|
5918
6037
|
const node = context3.getFieldByName(path3);
|
|
5919
6038
|
let struct;
|
|
5920
6039
|
if (node instanceof QueryField) {
|
|
@@ -5924,7 +6043,7 @@ ${(0, utils_1.indent)(sql)})
|
|
|
5924
6043
|
} else {
|
|
5925
6044
|
throw new Error("Internal Error: Unknown object type");
|
|
5926
6045
|
}
|
|
5927
|
-
resultStruct.root().addStructToJoin(struct.getJoinableParent(), this,
|
|
6046
|
+
resultStruct.root().addStructToJoin(struct.getJoinableParent(), this, uniqueKeyPossibleUse, joinStack);
|
|
5928
6047
|
}
|
|
5929
6048
|
addDependantExpr(resultStruct, context3, e12, joinStack) {
|
|
5930
6049
|
for (const expr2 of e12) {
|
|
@@ -5952,7 +6071,7 @@ ${(0, utils_1.indent)(sql)})
|
|
|
5952
6071
|
if ((0, malloy_types_1.hasExpression)(field3.fieldDef)) {
|
|
5953
6072
|
this.addDependantExpr(resultStruct, field3.parent, field3.fieldDef.e, joinStack);
|
|
5954
6073
|
} else {
|
|
5955
|
-
resultStruct.root().addStructToJoin(field3.parent.getJoinableParent(), this,
|
|
6074
|
+
resultStruct.root().addStructToJoin(field3.parent.getJoinableParent(), this, void 0, joinStack);
|
|
5956
6075
|
}
|
|
5957
6076
|
} else if ((0, malloy_types_1.isFilterFragment)(expr2)) {
|
|
5958
6077
|
for (const filterCond of expr2.filterList) {
|
|
@@ -5997,15 +6116,15 @@ ${(0, utils_1.indent)(sql)})
|
|
|
5997
6116
|
} else if ((0, malloy_types_1.isAggregateFragment)(expr2)) {
|
|
5998
6117
|
if ((0, malloy_types_1.isAsymmetricFragment)(expr2)) {
|
|
5999
6118
|
if (expr2.structPath) {
|
|
6000
|
-
this.addDependantPath(resultStruct, context3, expr2.structPath,
|
|
6119
|
+
this.addDependantPath(resultStruct, context3, expr2.structPath, expr2.function, joinStack);
|
|
6001
6120
|
} else {
|
|
6002
|
-
resultStruct.addStructToJoin(context3, this,
|
|
6121
|
+
resultStruct.addStructToJoin(context3, this, expr2.function, joinStack);
|
|
6003
6122
|
}
|
|
6004
6123
|
}
|
|
6005
6124
|
this.addDependantExpr(resultStruct, context3, expr2.e, joinStack);
|
|
6006
6125
|
} else if ((0, malloy_types_1.isFunctionCallFragment)(expr2)) {
|
|
6007
6126
|
if (expr2.structPath) {
|
|
6008
|
-
this.addDependantPath(resultStruct, context3, expr2.structPath,
|
|
6127
|
+
this.addDependantPath(resultStruct, context3, expr2.structPath, "generic_aggregate", joinStack);
|
|
6009
6128
|
}
|
|
6010
6129
|
for (const e13 of expr2.args) {
|
|
6011
6130
|
this.addDependantExpr(resultStruct, context3, e13, joinStack);
|
|
@@ -6082,7 +6201,7 @@ ${(0, utils_1.indent)(sql)})
|
|
|
6082
6201
|
prepare(_stageWriter) {
|
|
6083
6202
|
if (!this.prepared) {
|
|
6084
6203
|
this.expandFields(this.rootResult);
|
|
6085
|
-
this.rootResult.addStructToJoin(this.parent, this,
|
|
6204
|
+
this.rootResult.addStructToJoin(this.parent, this, void 0, []);
|
|
6086
6205
|
this.rootResult.findJoins(this);
|
|
6087
6206
|
this.rootResult.calculateSymmetricAggregates();
|
|
6088
6207
|
this.prepared = true;
|
|
@@ -55150,7 +55269,7 @@ QUERY: ${(0, util_1.inspect)(opDesc, { breakLength: 72, depth: Infinity })}`);
|
|
|
55150
55269
|
this.log(`Cannot call function ${this.name}(${argExprs.map((e12) => e12.dataType).join(", ")}) with source`);
|
|
55151
55270
|
return (0, ast_utils_1.errorFor)("cannot call with source");
|
|
55152
55271
|
}
|
|
55153
|
-
|
|
55272
|
+
let funcCall = [
|
|
55154
55273
|
{
|
|
55155
55274
|
type: "function_call",
|
|
55156
55275
|
overload,
|
|
@@ -55159,6 +55278,36 @@ QUERY: ${(0, util_1.inspect)(opDesc, { breakLength: 72, depth: Infinity })}`);
|
|
|
55159
55278
|
structPath
|
|
55160
55279
|
}
|
|
55161
55280
|
];
|
|
55281
|
+
if ([
|
|
55282
|
+
"sql_number",
|
|
55283
|
+
"sql_string",
|
|
55284
|
+
"sql_date",
|
|
55285
|
+
"sql_timestamp",
|
|
55286
|
+
"sql_boolean"
|
|
55287
|
+
].includes(func.name)) {
|
|
55288
|
+
if (!this.inExperiment("sql_functions", true)) {
|
|
55289
|
+
return (0, ast_utils_1.errorFor)(`Cannot use sql_function \`${func.name}\`; use \`sql_functions\` experiment to enable this behavior`);
|
|
55290
|
+
}
|
|
55291
|
+
const str = argExprs[0].value;
|
|
55292
|
+
if (str.length !== 1 || typeof str[0] === "string" || str[0].type !== "dialect" || str[0].function !== "stringLiteral") {
|
|
55293
|
+
this.log(`Invalid string literal for \`${func.name}\``);
|
|
55294
|
+
} else {
|
|
55295
|
+
const literal = str[0].literal;
|
|
55296
|
+
const parts = parseSQLInterpolation(literal);
|
|
55297
|
+
const unsupportedInterpolations = parts.filter((part) => part.type === "interpolation" && part.name.includes(".")).map((unsupportedPart) => unsupportedPart.type === "interpolation" ? `\${${unsupportedPart.name}}` : `\${${unsupportedPart.value}}`);
|
|
55298
|
+
if (unsupportedInterpolations.length > 0) {
|
|
55299
|
+
const unsupportedInterpolationMsg = unsupportedInterpolations.length === 1 ? `'.' paths are not yet supported in sql interpolations, found ${unsupportedInterpolations.at(0)}` : `'.' paths are not yet supported in sql interpolations, found [${unsupportedInterpolations.join(", ")}]`;
|
|
55300
|
+
this.log(unsupportedInterpolationMsg);
|
|
55301
|
+
return (0, ast_utils_1.errorFor)(`${unsupportedInterpolationMsg}. See LookML \${...} documentation at https://cloud.google.com/looker/docs/reference/param-field-sql#sql_for_dimensions`);
|
|
55302
|
+
}
|
|
55303
|
+
funcCall = [
|
|
55304
|
+
{
|
|
55305
|
+
type: "sql-string",
|
|
55306
|
+
e: parts.map((part) => part.type === "string" ? part.value : part.name === "TABLE" ? { type: "source-reference" } : { type: "field-reference", path: part.name })
|
|
55307
|
+
}
|
|
55308
|
+
];
|
|
55309
|
+
}
|
|
55310
|
+
}
|
|
55162
55311
|
if (type3.dataType === "any") {
|
|
55163
55312
|
this.log(`Invalid return type ${type3.dataType} for function '${this.name}'`);
|
|
55164
55313
|
return (0, ast_utils_1.errorFor)("invalid return type");
|
|
@@ -55251,6 +55400,32 @@ QUERY: ${(0, util_1.inspect)(opDesc, { breakLength: 72, depth: Infinity })}`);
|
|
|
55251
55400
|
}
|
|
55252
55401
|
}
|
|
55253
55402
|
}
|
|
55403
|
+
function parseSQLInterpolation(template) {
|
|
55404
|
+
const parts = [];
|
|
55405
|
+
let remaining = template;
|
|
55406
|
+
while (remaining.length) {
|
|
55407
|
+
const nextInterp = remaining.indexOf("${");
|
|
55408
|
+
if (nextInterp === -1) {
|
|
55409
|
+
parts.push({ type: "string", value: remaining });
|
|
55410
|
+
break;
|
|
55411
|
+
} else {
|
|
55412
|
+
const interpEnd = remaining.slice(nextInterp).indexOf("}");
|
|
55413
|
+
if (interpEnd === -1) {
|
|
55414
|
+
parts.push({ type: "string", value: remaining });
|
|
55415
|
+
break;
|
|
55416
|
+
}
|
|
55417
|
+
if (nextInterp > 0) {
|
|
55418
|
+
parts.push({ type: "string", value: remaining.slice(0, nextInterp) });
|
|
55419
|
+
}
|
|
55420
|
+
parts.push({
|
|
55421
|
+
type: "interpolation",
|
|
55422
|
+
name: remaining.slice(nextInterp + 2, interpEnd + nextInterp)
|
|
55423
|
+
});
|
|
55424
|
+
remaining = remaining.slice(interpEnd + nextInterp + 1);
|
|
55425
|
+
}
|
|
55426
|
+
}
|
|
55427
|
+
return parts;
|
|
55428
|
+
}
|
|
55254
55429
|
}
|
|
55255
55430
|
});
|
|
55256
55431
|
|
|
@@ -135500,7 +135675,7 @@ ${errText}`, errors);
|
|
|
135500
135675
|
const fieldMeta = metadata2.fields[fieldKey2];
|
|
135501
135676
|
let width2 = 0;
|
|
135502
135677
|
if (f4.isAtomicField()) {
|
|
135503
|
-
const font2 =
|
|
135678
|
+
const font2 = "12px Inter, sans-serif";
|
|
135504
135679
|
const titleWidth = getTextWidth(f4.name, font2);
|
|
135505
135680
|
if (f4.isAtomicField() && f4.isString()) {
|
|
135506
135681
|
width2 = Math.max(getTextWidth(fieldMeta.maxString, font2), titleWidth) + COLUMN_BUFFER;
|