diff --git a/docs/public/packages.json b/docs/public/packages.json index a34f1c99..8d11d14f 100644 --- a/docs/public/packages.json +++ b/docs/public/packages.json @@ -1,4 +1,4 @@ { - "packageId": "04tRb000004400jIAA", + "packageId": "04tRb0000044fYYIA", "componentPackageId": "04tRb0000012Mv8IAE" } diff --git a/expression-src/main/src/interpreter/ContextResolver.cls b/expression-src/main/src/interpreter/ContextResolver.cls index 27ee3b5b..59ac79be 100644 --- a/expression-src/main/src/interpreter/ContextResolver.cls +++ b/expression-src/main/src/interpreter/ContextResolver.cls @@ -341,6 +341,12 @@ public with sharing class ContextResolver implements Visitor { } public Object visit(Expr.MergeFieldOrScopeVariable mergeField) { + if (this.queryStackDepth > 0) { + // Merge fields are not supported within query expressions, since they + // are used to build the query itself. + return null; + } + String fieldName = mergeField.name.lexeme.toLowerCase(); // Check if it is ignored within a function scope if (ignoredScopedVariables.contains(fieldName)) { @@ -422,9 +428,32 @@ public with sharing class ContextResolver implements Visitor { return null; } + private Integer queryStackDepth = 0; public Object visit(Expr.Query query) { - // Nothing to resolve when inside of a Query expression. - // A query expression essentially starts an isolated context. + this.queryStackDepth++; + if (query.fieldsExpression != null) { + resolve(query.fieldsExpression); + } + + if (query.orderBy != null) { + for (Expr orderByExpr : query.orderBy) { + resolve(orderByExpr); + } + } + + if (query.limitExpr != null) { + resolve(query.limitExpr); + } + + if (query.whereExpr != null) { + resolve(query.whereExpr); + } + + if (query.offsetExpr != null) { + resolve(query.offsetExpr); + } + + this.queryStackDepth--; return null; } diff --git a/expression-src/spec/language/global-context/GlobalContextTest.cls b/expression-src/spec/language/global-context/GlobalContextTest.cls index 24e98f41..ea0d36b4 100644 --- a/expression-src/spec/language/global-context/GlobalContextTest.cls +++ b/expression-src/spec/language/global-context/GlobalContextTest.cls @@ -236,6 +236,37 @@ private class GlobalContextTest { Assert.areEqual(1, Limits.getQueries(), 'Expect one query to retrieve the TargetAccount record'); } + @IsTest + private static void canReferenceCustomRecordContextFieldsInQueries() { + Account accountRecord = new Account(Name = 'Acme'); + insert accountRecord; + + CustomRecordContext customRecordContext = new CustomRecordContext('TargetAccount', accountRecord.Id); + + String expressionFormula = 'QUERY(Account(where: Id = @TargetAccount.Id)[Name])'; + Object result = Evaluator.run(expressionFormula, customRecordContext, new Configuration()); + + List queryResults = (List)result; + Assert.areEqual(1, queryResults.size(), 'Expect one record returned from the query'); + } + + @IsTest + private static void canReferenceCustomRecordContextFieldsInQueries_differentSObjects() { + Account accountRecord = new Account(Name = 'John'); + insert accountRecord; + + Contact someContact = new Contact(FirstName = 'John', LastName = 'Doe', AccountId = accountRecord.Id); + insert someContact; + + CustomRecordContext customRecordContext = new CustomRecordContext('TargetAccount', accountRecord.Id); + + String expressionFormula = 'QUERY(Contact(where: FirstName = @TargetAccount.Name)[FirstName])'; + Object result = Evaluator.run(expressionFormula, customRecordContext, new Configuration()); + + List queryResults = (List)result; + Assert.areEqual(1, queryResults.size(), 'Expect one record returned from the query'); + } + @IsTest private static void canChangeTheCustomContextPrefix() { Account accountRecord = new Account(Name = 'Acme'); diff --git a/expression-src/spec/language/global-context/GlobalContextTest.cls-meta.xml b/expression-src/spec/language/global-context/GlobalContextTest.cls-meta.xml index f5e18fd1..82775b98 100644 --- a/expression-src/spec/language/global-context/GlobalContextTest.cls-meta.xml +++ b/expression-src/spec/language/global-context/GlobalContextTest.cls-meta.xml @@ -1,5 +1,5 @@ - 60.0 + 65.0 Active diff --git a/sfdx-project_packaging.json b/sfdx-project_packaging.json index 1ac725c2..0e5dca50 100644 --- a/sfdx-project_packaging.json +++ b/sfdx-project_packaging.json @@ -3,7 +3,7 @@ { "package": "Expression", "versionName": "Version 1.36", - "versionNumber": "1.46.0.NEXT", + "versionNumber": "1.47.0.NEXT", "path": "expression-src", "default": false, "versionDescription": "Expression core language", @@ -75,6 +75,7 @@ "Expression@1.43.0-1": "04tRb000003xzXCIAY", "Expression@1.44.0-1": "04tRb000003z0hJIAQ", "Expression@1.45.0-1": "04tRb0000042CNlIAM", - "Expression@1.46.0-1": "04tRb000004400jIAA" + "Expression@1.46.0-1": "04tRb000004400jIAA", + "Expression@1.47.0-1": "04tRb0000044fYYIAY" } } \ No newline at end of file