这是indexloc提供的服务,不要输入任何密码
Skip to content

Conversation

@abooij
Copy link
Contributor

@abooij abooij commented Sep 30, 2020

Description

The server could already execute queries that either fetch data from the database, or, through remotes, from other GraphQL servers. This PR also enables mixing such data sources within one query. So one can have queries such as

query {
  articles {
    title
  }
  weather {
    temperature
  }
}

where the articles are fetched from the database, and the weather is fetched from a remote server.

Changelog

  • CHANGELOG.md is updated with user-facing content relevant to this PR. If no changelog is required, then add the no-changelog-required label.

Affected components

  • Server
  • Tests

Related Issues

This PR depends on #5865.

Solution and Design

For an incoming query we already used to generate an "execution plan" which specified how to execute that query. However, so far an execution plan has been a single execution step, where an execution step can be of database-type, of remote-type or of "raw"-type (used for introspection). This PR changes the type of execution plans to be an insertion-ordered hashmap of execution steps

type ExecutionPlan db remote raw = InsOrdHashMap Text (ExecutionStep db remote raw)

where the key corresponds to a root field name.

Steps to test and verify

A test suite is included.

Limitations, known bugs & workarounds

Although this PR allows to mix root fields originating from different data sources, it does not allow joining between them arbitrarily beyond the existing "remote joins" that load relationships from Postgres to a remote. Such "generalized joins" are part of future work.

Server checklist

Catalog upgrade

Does this PR change Hasura Catalog version?

  • No

Metadata

Does this PR add a new Metadata feature?

  • No

GraphQL

  • No new GraphQL schema is generated

Breaking changes

  • No Breaking changes

Auke Booij and others added 30 commits September 16, 2020 15:46
The "locality" field needs to get additional options.  This commit takes an
opinionated view on this which we should discuss further.
@abooij abooij requested a review from lexi-lambda October 6, 2020 08:17
@abooij
Copy link
Contributor Author

abooij commented Oct 6, 2020

@lexi-lambda Thank you very much for the thorough review!

Copy link
Contributor

@lexi-lambda lexi-lambda left a comment

Choose a reason for hiding this comment

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

Many thanks for the prompt changes; I think this PR generally looks good to me now. I think it would be nice to find some way to deduplicate all the tricky query execution logic and parameterize it over the transport mechanism, but I’m happy to have a call to discuss that, since it seems possibly subtle.

| GQPreExecError ![J.Value]
| GQExecError ![J.Value]
deriving (Show, Eq, Functor, Foldable, Traversable)
type GQResult a = ExceptT GQExecError Identity a
Copy link
Contributor

Choose a reason for hiding this comment

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

ExceptT over Identity is basically just an awkward version of Either. Is there a reason we need ExceptT here specifically?

Copy link
Contributor

Choose a reason for hiding this comment

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

Done!

-- spent in the PG query; for telemetry.
runQueryDB reqId (query, queryParsed) asts _userInfo (tx, genSql) = do
-> Text
-> (Tracing.TraceT (LazyTx QErr) EncJSON, Maybe EQ.GeneratedSqlMap)
Copy link
Contributor

@lexi-lambda lexi-lambda Oct 6, 2020

Choose a reason for hiding this comment

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

Do we ever actually call logQueryLog with a map containing more than one entry in it? If not, I’d be in favor of just changing the signature—I don’t think avoiding the tiny bit of extra downstream effort to update to the new interface is worth the misleading API. (Of course, if we do call it with more than one value somewhere, please point me to it!)

prepArgs = fst <$> IntMap.elems args
in (, Just ps) $ case remoteJoinsM of
Nothing -> do
Tracing.trace "Postgres" . (runExtractProfile ep =<<) . liftTx $ asSingleRowJsonResp (instrument q) prepArgs
Copy link
Contributor

Choose a reason for hiding this comment

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

This is another instance of an operator section involving =<<, which I missed on the first pass, but I personally find confusing. There’s a lot going on all on one line here. I recognize this kind of thing is subjective, but I happen to prefer a formulation like this:

Suggested change
Tracing.trace "Postgres" . (runExtractProfile ep =<<) . liftTx $ asSingleRowJsonResp (instrument q) prepArgs
Tracing.trace "Postgres" $ runExtractProfile ep =<< liftTx do
asSingleRowJsonResp (instrument q) prepArgs

This puts all the “wrapping bits” on a separate line from the actual interesting functionality being executed. Another approach I use sometimes when the “wrapping bits” get complicated is something like this:

Suggested change
Tracing.trace "Postgres" . (runExtractProfile ep =<<) . liftTx $ asSingleRowJsonResp (instrument q) prepArgs
asSingleRowJsonResp (instrument q) prepArgs
& liftTx
>>= runExtractProfile ep
& Tracing.trace "Postgres"

Which has sort of a “pipeline” flavor to it. This works out nicely because & and >>= are both infixl 1. But in this particular case, I’m not sure that it’s actually better; most of the parts of the “pipeline” are pretty boring.

Copy link
Contributor

Choose a reason for hiding this comment

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

Done!

@abooij abooij requested a review from tirumaraiselvan October 7, 2020 07:58
Copy link
Contributor

@tirumaraiselvan tirumaraiselvan left a comment

Choose a reason for hiding this comment

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

changelog

@kodiakhq kodiakhq bot merged commit 84a129c into hasura:master Oct 7, 2020
@tirumaraiselvan tirumaraiselvan added this to the v1.4 milestone Oct 20, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c/server Related to server

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants