-
-
Notifications
You must be signed in to change notification settings - Fork 129
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
How lookahead and queries work #522
Comments
Should this be in the docs repo? https://github.com/graphile/graphile.github.io |
Added to the megathread: graphile/graphile.github.io#153 (comment) |
@benjie Some things might have implications on the docs repo, yeah, but I wanted to discuss a few points first which also might have effects on the engine code. |
It's a generic map We use graphile-engine/packages/graphile-build-pg/src/queryFromResolveDataFactory.js Lines 36 to 44 in 2335d6e
Remember that
PRs welcome 👍
Though maybe we should have called this
Yes, this has evolved over time.
Currently.
Great. Not sure; where would you have looked for this? Most users don't need to know this level of detail, so it shouldn't be too prominent as it could be overwhelming. This is why the Graphile Engine and PostGraphile docs are separate.
No; The
AFAIK the
Yes, it's a backwards-compatible addition that was necessary to enable certain advanced features that were not included in 4.0.0. The same is true for many other fields that were added after 4.0.0 was released. It is used when a subquery needs access to the parent query, for examples see https://www.graphile.org/postgraphile/make-extend-schema-plugin/
Everything on QueryBuilder takes callback. Because they don't become permanent until the QueryBuilder is ready to be finalised, because different plugins add different things at different times and they're all inter-dependent. See the lock method that's called when you request certain final features of the query builder.
They help build the query. The QueryBuilder is mutable, but once you've asked for it to
A lot of optimisation has gone into building the SQL query. It is now extremely efficient. Unfortunately we cannot cache it currently, as some clauses might be dependent on the
It's certainly something I've given a lot of thought to. |
I see, thanks for the link to
Yeah, I'm not sure either. I guess the Graphile Engine docs are what only powerusers would read, but then they shouldn't be Postgraphile-specific. Maybe still add a section "For example, this is how this feature is used in Postgraphile", with links to the code? Alternatively, the page https://www.graphile.org/postgraphile/extending-raw/ seems to be the best to explain everything that one needs to write raw plugins. We could also add a "Internals" page to the "Operations" section, where it has a walkthrough of the important parts of the code and how everything is linked together. Similar for the hooks description.
OK, I didn't know that. I thought the
That's another thing I guess that needs better (unified?) documentation, which options from where go into what callbacks. I'll try to come up with a list.
OK, I don't know about pre-4.0 PostGraphile, I guess it's not so important anyway. But it's good to know that this is explicitly designed to be used only in custom plugins, I was confused a bit why the core pg-plugins didn't use this feature.
…but the methods also take plain values. The docs (
OK, that's advanced stuff. From a cursory glance, it seems like this is currently used only for |
You can use it however you want.
Sounds good 👍 Examples are always good. If you link to code, make sure it's a permalink (press y on your keyboard when viewing code on GitHub to get the permalink).
Also a good location. Or you could make subpages or even an entire subsection for it.
Sure; it's rare that adding more docs/links will be the wrong thing to do.
Yes, this definitely needs updating.
GraphQLResolveInfo is basically metadata that
That's https://www.graphile.org/postgraphile/usage-schema/
👍 This is why we have a
That's one place; but I'm certain there are many others. I can't remember what they are off-hand. They might be in external plugins. |
[semi-automated message] Thanks for your question; hopefully we're well on the way to helping you solve your issue. This doesn't currently seem to be a bug in the library so I'm going to close the issue, but please feel free to keep requesting help below and if it does turn out to be a bug we can definitely re-open it 👍 You can also ask for help in the #help-and-support channel in our Discord chat. |
…in greater detail
Originally posted by @benjie in graphile/crystal#387 (comment):
I don't want to derail the discussion about implementing interfaces over there, so I'll start a new thread.
I've already seen the graphile-engine lookahead documentation (describing
parseResolveInfo
andsimplifyParsedResolveInfoFragmentWithType
), but there's some open questions:map
property or objects with apgQuery
property (apparently containing a callback to modify aQueryBuilder
)getDataFromParsedResolveInforFragment
actually is the function that runs the data generators was not obvious from the name, and not well-documented. I'd also like to see such descriptions in the code comments - or a link to the graphile.org documentation page to avoid duplication.I see the docs use the term "meta-data", maybe it would be appropriate to rename the methods to
addFieldMetadata
,addFieldArgMetadata
, andgetMetadataFromParsedResolveInfo
?getData…
at first sounded as if it was already fetching the data from the db, then a second guess was that it constructed a grapqhl resolver ("makeDataGetter"), before it hit me when looking at the implementationpgQueryFromResolveData
function, which is implemented here and added to thebuild
object here. It seems to create the actual SQL (fragment), used either in subqueries of other data generators (e.g. here or there), or in the root queries (e.g. here or there where the sql query is subsequently passed tosql.compile
and then topgPrepareAndRun
which actually executes it.In a
makeExtendSchemaPlugin
however one is advised to useselectGraphQLResultFromTable
method which does all of the above in one step, but executes a normalpgClient.query
not a prepared statement.I think I got this now, would be nice if this was explained somewhere. (Where?)
selectGraphQLResultFromTable
put on a.graphile
property on theresolveInfo
object that is passed to the user-supplied resolver? Wouldn't this fit much, much better on thecontext
(where all the other [post]graphile helper methods live)? Especially since it uses thepgClient
from that very context, being a closure over it.QueryBuilder
is documented on themakeExtendSchemaPlugin
page, I kinda had expected a separate page in the graphile-build docs.The
parentQueryBuilder
appears like a hack, where is this really used? It seems to be set whenever a nested query is constructed, but via direct assignment - I kinda would have expected asetParent()
method (that e.g. checks for overwrites of an existing parent).Why do the
select
andorderBy
methods take callbacks?And what do all those internal methods (that one shouldn't call) do? I'd expect some comments in the code on how this "locking" scheme works and what it is used for.
Could these be stored on the parsed queries that PostGraphile caches? Probably no, because the
ArgData
generators are a little different every time, because thepg-sql2
fragments contain the variable values themselves, and because the heavy use of closures in the builder allows lots ofcontext
stuff to leak inside the queries (instead of them being purely built from the query). But maybe this would be an idea for a V5 architecture :-)The text was updated successfully, but these errors were encountered: