Skip to content

Conversation

@jgellin-sf
Copy link
Contributor

What does this PR do?

This PR models the WHERE clause. All types of conditions are modeled except for the following, which are modeled as UnmodeledSyntax:

  • conditions with semi-joins, such as field IN (SELECT A FROM B)
  • distance conditions, such as DISTANCE(field,GEOLOCATION(37,122),'mi') < 100
  • calculated conditions, such as A + B > 10
  • conditions with colon expressions, such as field = :var

This PR also updates the soql parser to version 0.17. This update includes better handling of WHERE expressions (timely!) and several other updates. Some rules were renamed, resulting in some minor code changes in this PR.

What issues does this PR fix or reference?

W-8295457

@codecov
Copy link

codecov bot commented Nov 11, 2020

Codecov Report

Merging #68 (8bd8fb3) into develop (98474e7) will increase coverage by 0.02%.
The diff coverage is 94.27%.

Impacted file tree graph

@@             Coverage Diff             @@
##           develop      #68      +/-   ##
===========================================
+ Coverage    94.12%   94.14%   +0.02%     
===========================================
  Files           33       42       +9     
  Lines          851     1076     +225     
  Branches       177      227      +50     
===========================================
+ Hits           801     1013     +212     
- Misses          48       61      +13     
  Partials         2        2              
Flag Coverage Δ
language-server 100.00% <ø> (ø)
soql-builder-ui 92.57% <ø> (ø)
soql-model 94.99% <94.27%> (-0.40%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...kages/soql-model/src/serialization/deserializer.ts 92.59% <87.00%> (-2.55%) ⬇️
...es/soql-model/src/model/impl/andOrConditionImpl.ts 100.00% <100.00%> (ø)
...-model/src/model/impl/fieldCompareConditionImpl.ts 100.00% <100.00%> (ø)
...s/soql-model/src/model/impl/inListConditionImpl.ts 100.00% <100.00%> (ø)
...soql-model/src/model/impl/includesConditionImpl.ts 100.00% <100.00%> (ø)
packages/soql-model/src/model/impl/index.ts 100.00% <100.00%> (ø)
...ges/soql-model/src/model/impl/likeConditionImpl.ts 100.00% <100.00%> (ø)
packages/soql-model/src/model/impl/literalImpl.ts 100.00% <100.00%> (ø)
...s/soql-model/src/model/impl/nestedConditionImpl.ts 100.00% <100.00%> (ø)
...ages/soql-model/src/model/impl/notConditionImpl.ts 100.00% <100.00%> (ø)
... and 12 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 98474e7...8bd8fb3. Read the comment docs.

Comment on lines 16 to 22
new model.Impl.WhereImpl(
new model.Impl.FieldCompareConditionImpl(
new model.Impl.FieldRefImpl('field1'),
model.Soql.CompareOperator.EQ,
new model.Impl.LiteralImpl(model.Soql.LiteralType.Number, '5')
)
),
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sample script update

Comment on lines +24 to +32
var where = queryModel.where ? queryModel.where.toSoqlSyntax() : undefined;
var orderBy = queryModel.orderBy.orderByExpressions.map(
(expr) => `${expr.field.fieldName} ${expr.order} ${expr.nullsOrder}`
);
var limit = queryModel.limit ? queryModel.limit.limit : 'undefined';
console.log(`Query: ${query}`);
console.log(`SObject: ${sObject}`);
console.log(`Fields: ${fields}`);
console.log(`Where: ${where}`);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sample script update

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would line 32 be good to look at to get an idea of whats available to the UI for a where clause?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No that's just the where clause transformed back to SOQL syntax. Line 16 of getquery.js is indicative of how the model is created. For raw JSON, deserializer.test.ts has lots of examples of what these different conditions look like when modeled in a WHERE clause.

protected isIncompleteLimitError(error: ParserError): boolean {
const context = this.matchErrorToContext(error);
return context instanceof Parser.SoqlIntegerContext
return context instanceof Parser.SoqlIntegerValueContext
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is due to a parser rule rename in the new soql parser version

Comment on lines +477 to +502
protected toLiteral(ctx: ParserRuleContext): Soql.Literal {
if (ctx instanceof Parser.SoqlLiteralLiteralValueContext) {
ctx = ctx.soqlLiteral();
}
if (ctx instanceof Parser.SoqlLiteralCommonLiteralsContext) {
ctx = ctx.soqlCommonLiterals();
}
if (ctx instanceof Parser.SoqlDateLiteralContext) {
return new Impl.LiteralImpl(Soql.LiteralType.Date, ctx.getText());
} else if (ctx instanceof Parser.SoqlDateTimeLiteralContext) {
return new Impl.LiteralImpl(Soql.LiteralType.Date, ctx.getText());
} else if (ctx instanceof Parser.SoqlTimeLiteralContext) {
return new Impl.LiteralImpl(Soql.LiteralType.Date, ctx.getText());
} else if (ctx instanceof Parser.SoqlDateFormulaLiteralContext) {
return new Impl.LiteralImpl(Soql.LiteralType.Date, ctx.getText());
} else if (ctx instanceof Parser.SoqlNumberLiteralContext) {
return new Impl.LiteralImpl(Soql.LiteralType.Number, ctx.getText());
} else if (ctx instanceof Parser.SoqlNullLiteralContext) {
return new Impl.LiteralImpl(Soql.LiteralType.Null, ctx.getText());
} else if (ctx instanceof Parser.SoqlBooleanLiteralContext) {
return new Impl.LiteralImpl(Soql.LiteralType.Boolean, ctx.getText());
} else if (ctx instanceof Parser.SoqlMultiCurrencyContext) {
return new Impl.LiteralImpl(Soql.LiteralType.Currency, ctx.getText());
}
return new Impl.LiteralImpl(Soql.LiteralType.String, ctx.getText());
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Literals are stored as a type (date, number, null, boolean, currency, string) and a value. The value is the string value of the token. So a literal of type string has a value that includes the quotes. Storing the literal values this way, as opposed to storing as a Javascript version of the type, avoids any messy type transformations.

@jgellin-sf
Copy link
Contributor Author

The latest commit make IN and INCLUDES conditions unmodeled syntax removes support for these conditions.

@jgellin-sf
Copy link
Contributor Author

The commit implement condition simplicity utils adds utilities to determine whether a condition can be expressed as a flat list of AND's ("All") or OR's ("Any").

@dobladez
Copy link
Contributor

Looks good to me 👍

For future PRs: Given that model is growing, Have you thought of providing "builders" to make it easier to build model structures? (for unit tests and for the UI editor). Something like:

 QueryBuilder.select(["a", "b"])
             .from("Account")
             .where( andExpr(fieldExpr("name", EQUAL, "John"),
                             fieldExpr("deleted", EQUAL, false))).build();

@dehru dehru merged commit 65eb027 into develop Nov 19, 2020
@tmock12 tmock12 deleted the jg/where branch November 20, 2020 14:42
dehru added a commit that referenced this pull request Jan 15, 2021
* model WHERE clause (#68)
* Remote SOQL Errors - Language Server Part (#93)
* remove code builder (#92)
* Move from antlr4JS to antlr4TS (#96)
* SOQL code completion for SELECT fields (#99)
* publish language server 0.2.9 (#102)
* Fix LSP dependency (#104)
* Disabled 'Running...' button while query running (#106)
* Add basic code-completion for ORDER BY and other improvements (#107)
* Dehru and JG telemetry - Send GDPR clean data to telemetry when errors/unsupported syntax present (#110)
* Disable WHERE in model (#113)
* Bump versions for publishing (#114)
* Code-completion for WHERE clause expressions (#112)
Co-authored-by: Jonathan Gellin <jgellin@salesforce.com>
Co-authored-by: jgellin-sf <55159130+jgellin-sf@users.noreply.github.com>
Co-authored-by: Chase McCarthy <charles.mccarthy@heroku.com>
Co-authored-by: Jonny Hork <jhork@salesforce.com>
Co-authored-by: Fernando Dobladez <fernandodobladez@salesforce.com>
Co-authored-by: Jonathan Gellin <jgellin@salesforce.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants