-
Notifications
You must be signed in to change notification settings - Fork 44
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: Cleanup parsing logic #909
refactor: Cleanup parsing logic #909
Conversation
query/graphql/parser/query.go
Outdated
Name: field.Name.Value, | ||
Alias: getFieldAlias(field), | ||
} | ||
} | ||
|
||
type Aggregate struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll document this (and AggregateTarget) a bit later (outside of this PR), along with all the other models in this package. It'll also probably be refactored a little further.
func parseAggregate(field *ast.Field, index int) (*Aggregate, error) { | ||
targets := make([]*AggregateTarget, len(field.Arguments)) | ||
|
||
for i, argument := range field.Arguments { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function is pretty much a straight-up cut-paste of the trimmed one in mapper
Codecov Report
@@ Coverage Diff @@
## develop #909 +/- ##
===========================================
+ Coverage 59.79% 59.89% +0.09%
===========================================
Files 156 159 +3
Lines 17415 17423 +8
===========================================
+ Hits 10414 10436 +22
+ Misses 6065 6053 -12
+ Partials 936 934 -2
|
4b0084c
to
18534ad
Compare
@@ -58,7 +58,7 @@ func (n *limitNode) Value() core.Doc { return n.plan.Value() } | |||
|
|||
func (n *limitNode) Next() (bool, error) { | |||
// check if we're passed the limit | |||
if n.limit != 0 && n.rowIndex-n.offset >= n.limit { | |||
if n.limit != 0 && n.rowIndex >= n.limit+n.offset { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This had to be changed, as it actually overflows under normal conditions. A bit surprised Golang doesn't panic on overflows...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying to undestand where this overfows. Can you point it out please. I'm curious.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
e.g if rowIndex
is 0, and offset
is greater than 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes I see cuz they are of type uint64
. It should definitely panic on overflow. https://go.dev/play/p/bDfmcZbLKma
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No... my bad. It doesn't panic: https://go.dev/play/p/yHe5EyEu11I
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rust does panic: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=cc6ef0c06d3af96737ec957ef1a823df
I wonder why the Go team made that choice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is really strange behaviour that to me in your linked playgrounds, feels inconsistent to let the runtime pass, but compile fail.
DotNet panics too, and I think so does the JVM. There is a tiny runtime cost to checking, but given how runtime heavy Go can be anyway it seems odd not to do this. Maybe it is because the lang lacks the syntax to opt-out (allowing overflows can be really handy at times, for example during key generation)
1c17c39
to
7e13656
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. This was quite easy to review. Lots of changes but not too much new stuff. Glad you've decided to create PRs as you change things and not wait for everything to be done.
@@ -8,65 +8,20 @@ | |||
// by the Apache License, Version 2.0, included in the file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
question: is the purpose of the consts.go
file different from the types file? I thought there was consensus to keep types under it's own namespace using types
package ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
having a types file in directory full of other files with other types is not very helpful IMO. A types file made sense when there was only a sub set of the model in it (and even that was odd as is was super-arbitrary as to what was in it)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
having a types file in directory full of other files with other types is not very helpful IMO. A types file made sense when there was only a sub set of the model in it (and even that was odd as is was super-arbitrary as to what was in it)
While I agree that it was odd, I am talking from the perspective of keeping things in harmony as the code base grows and having a convention that would be well understood by the team, for example, I am happy with storing constants in consts.go
file as it is very self-evident to know what that file contains. Would like to see us use consistent patterns to store constants, variables etc. (for structs probably more useful names split under different files). I really enjoyed a popular convention in C++ that said no more than one class / struct per file (perhaps too strict for Go peepz haha).
|
||
// Filter contains the parsed condition map to be | ||
// run by the Filter Evaluator. | ||
// @todo: Cache filter structure for faster condition |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
todo: remove or add corresponding issue number.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
out of scope
// of a graphql query. It includes all the possible | ||
// arguments and all | ||
// | ||
// @todo: Change name to ObjectMutation to indicate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
todo: remove or add corresponding issue number.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
out of scope
type OptionalDocKeys struct { | ||
HasValue bool | ||
Value []string | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
praise: Thanks for removal of this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:)
@@ -292,7 +293,7 @@ func (n *selectNode) initFields(parsed *mapper.Select) ([]aggregateNode, error) | |||
// of that Target version we are querying. | |||
// So instead of a LatestCommit subquery, we need | |||
// a OneCommit subquery, with the supplied parameters. | |||
commitSlct.DocKey = parsed.DocKeys.Value[0] // @todo check length | |||
commitSlct.DocKey = client.Some(parsed.DocKeys.Value()[0]) // @todo check length |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
todo: remove or add the corresponding issue number.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
out of scope
Thanks Fred! And thanks for the quick review :) |
7e13656
to
b564448
Compare
Type was added before we had client.Option
Should have been removed in the PR that removed the commit query
The parser models will shortly be exposed as part of the public interface, and it should not be on the users to have to always populate this property. It also makes more sense IMO to do it this way regardless, as alias is optional, but render-keys are not.
Makes it far clearer that it is optional
Also flattens them, as the previous structure suggested if one was present then the other was mandatory. Also switches from int64 to uint64 as they should not be negative (and makes it more consitent with a few other similar props who use uint64).
No reason for this to exist, and will confuse anyone using it.
Now using proper consts, and defined in the same location as everything else.
Previous if was conceptually incorrect. None option added no value (select.Root now defaults to Object, which could be handy for users anyway). Also types the enum.
Also breaks up types.go in preparation for the moving of the rest of the model.
As agreed as a team, commit does not seek to rename all variables referencing this - that can be done later to save drowning this large PR with minor changes
The parser package is now responisble for converting an gql-ast into a shared model. Soon it will be responisble for converting a string into the shared model. Mostly a copy-paste commit.
b564448
to
29ef5f5
Compare
* Remove unused QueryType prop * Remove unused order.statement prop * Replace optionalDocKeys with client.Option Type was added before we had client.Option * Remove legacy commit entry Should have been removed in the PR that removed the commit query * Remove unused statement property * Remove unused func from interface * Remove Root from Field * Remove unused func * Parse aggregates in parser package * Remove statement from parser.Select * Remove ast from OperationDefinition * Remove unused Name from OperationDefinition * Make parser.Alias optional The parser models will shortly be exposed as part of the public interface, and it should not be on the users to have to always populate this property. It also makes more sense IMO to do it this way regardless, as alias is optional, but render-keys are not. * Make commit.DocKey option type Makes it far clearer that it is optional * Use option for parser.limit Also flattens them, as the previous structure suggested if one was present then the other was mandatory. Also switches from int64 to uint64 as they should not be negative (and makes it more consitent with a few other similar props who use uint64). * Use option for parser.order * Remove '.'s from parser.order.fields No reason for this to exist, and will confuse anyone using it. * Use option for parser.GroupBy * Use option for parser.Filter * Cleanup commit-query branching Now using proper consts, and defined in the same location as everything else. * Remove unused param * Remove unused commit.GetRoot func * Remove unused mutation.GetRoot func * Tidy up parser.Root references Previous if was conceptually incorrect. None option added no value (select.Root now defaults to Object, which could be handy for users anyway). Also types the enum. * Move parser.types to client dir Also breaks up types.go in preparation for the moving of the rest of the model. * Rename parser.Query to parser.Request As agreed as a team, commit does not seek to rename all variables referencing this - that can be done later to save drowning this large PR with minor changes * Move request model out of parser package The parser package is now responisble for converting an gql-ast into a shared model. Soon it will be responisble for converting a string into the shared model. Mostly a copy-paste commit.
Relevant issue(s)
Part of #905, but does not yet resolve it
Description
Cleans up some of the parser code and types in preparation for decoupling mapper/planner/defra from gql. Moves the parser model out of the parser package, defining a public strongly typed model for interacting with defra.
There is still a little bit more to be done (mainly abstracting the schema stuff from away db.db), but I'm getting tired and these commits should be alright to review (it is also getting a bit large and will probs be easier for everyone to break this refactor into a couple of reviews).
Strongly suggest reviewing commit by commit, as there is a fair amount going on here now.