* use positional arguments in SQL functions
* only allow omitting set of last arguments in functions
* disallow omitting of a non default argument in functions
These changes also add a new type, PGColumnType, between PGColInfo and
PGScalarType, and they process PGRawColumnType values into PGColumnType
values during schema cache generation.
This mostly simplifies the RootFlds type to make it clearer what it’s
used for, but it has the convenient side-effect of preventing some
“impossible” cases using the type system.
* Listens for SIGTERM as the termination signal
* Stops accepting new connections once the signal is received
* Waits for all connections to be drained, before shutting down
* Forcefully kills all pending connections after 30 seconds
Currently this does not send a close message to websocket clients, I'd
like to submit that change as a separate pull request, but at least this
solve my biggest concern which is not getting confirmation for mutations
while restarting the server.
* allow altering type of a column iff session vars are defined in permissions
* use a sum type to define dependency reason
* set jwt expiry test's expiry time to 4 seconds
* derive Data instance for necessary types to simplify 'hasStaticExp'
At the moment we can...
...run tests in isolation, generating coverage report:
$ dev.sh test
You can pass args to pytest as well. e.g. to run a specific test:
$ dev.sh test -k "test_jsonb_has_all"
Launch a postgres container with useful dev defaults, with PostGIS,
cleaning up afterwards:
$ dev.sh postgres
Build and launch graphql-engine in dev mode, connecting with a
`postgres` launched above
$ dev.sh graphql-engine
This seems to resolve the issue locally (and has worked in the past),
but it's not clear what exactly is going on here (in particular, why
this should resolve what looks like a memory leak). It certainly seems
like a GHC issue of some sort.
Closes#2565
query templates is a little known feature that lets you template rql
queries and serve them as rest apis. This is not relevant anymore
given the GraphQL interface and getting rid of it reduces the dev
time when adding features in few subsystems.
This feature has never been used outside hasura's internal projects or
documented or exposed through console and hence can safely be removed.
* fix bug in audience check while verifying JWT
- previously the check was converting the audience type into a string
and then comparing with the conf value. all audience types (as it is a
string or URI) will convert to plain strings
- use the Audience type from the jose library for comparing
* add docs for audience
* add issuer check as well
* docs minor syntax fix
* skip audience check if not given in conf
* minor docs update
* qualify import jose library
Currently, we allow tracking of a table with the same name as an already tracked function, and vice-versa. This causes an issue when querying from GraphQL since it will only query the table and not the function. I've made changes to disallow this by throwing an error.
* Bump node-sass to version ^4.12.0
This avoids sass/node-sass#2632, which causes compilation failures on
Node v12.x.
* Do most of the work in /pg_dump in Haskell instead of shell
The shell version caused problems on non-Linux systems since it relied
on the non-POSIX -i option for sed, which works slightly differently on
BSD and macOS.
This PR builds console static assets into the server docker image at `/srv/console-assets`. When env var `HASURA_GRAPHQL_CONSOLE_ASSETS_DIR=/srv/console-assets` or flag `--console-assets-dir=/srv/console-assets` is set on the server, the files in this directory are served at `/console/assets/*`.
The console html template will have a variable called `cdnAssets: false` when this flag is set and it loads assets from server itself instead of CDN.
The assets are moved to a new bucket with a new naming scheme:
```
graphql-engine-cdn.hasura.io/console/assets/
/common/{}
/versioned/<version/{}
/channel/<channel>/<version>/{}
```
Console served by CLI will still load assets from CDN - will fix that in the next release.
Changes compared to `/v1alpha1/graphql`
* Changed all graphql responses in **/v1/graphql** endpoint to be 200. All graphql clients expect responses to be HTTP 200. Non-200 responses are considered transport layer errors.
* Errors in http and websocket layer are now consistent and have similar structure.
1. Reuses postgres connections during startup which reduces the overhead of opening and closing connections.
2. Faster schema cache building. This is done by fetching all the required data in a single sql statement.
* build schema cache function without db setup
The setup shouldn't happen for sync. The database is already setup by the instance which generated the event. This means that the sync is now faster.
* use SQL loop to drop hdb_views schema views and routines with ordering
This avoids deadlocks when schema is being changed concurrently
* schema sync now only processes the latest event
This becomes useful when a lot of schema change
events happen while we are still processing an
earlier event.
* split stm transactions when snapshotting to make it faster
* mx subs: push to both old and new sinks at the same time
* expose dev APIs through allowed APIs flag
* add types to represent unparsed http gql requests
This will help when we add caching of frequently used ASTs
* query plan caching
* move livequery to execute
* add multiplexed module
* session variable can be customised depending on the context
Previously the value was always "current_setting('hasura.user')"
* get rid of typemap requirement in reusable plan
* subscriptions are multiplexed when possible
* use lazytx for introspection to avoid acquiring a pg connection
* refactor to make execute a completely decoupled module
* don't issue a transaction for a query
* don't use current setting for explained sql
* move postgres related types to a different module
* validate variableValues on postgres before multiplexing subs
* don't user current_setting for queries over ws
* plan_cache is only visible when developer flag is enabled
* introduce 'batch size' when multiplexing subscriptions
* bump stackage to 13.16
* fix schema_stitching test case error code
* store hashes instead of actual responses for subscriptions
* internal api to dump subscriptions state
* remove PlanCache from SchemaCacheRef
* allow live query options to be configured on server startup
* capture metrics for multiplexed subscriptions
* more metrics captured for multiplexed subs
* switch to tvar based hashmap for faster snapshotting
* livequery modules do not expose internal details
* fix typo in live query env vars
* switch to hasura's pg-client-hs
* read version from env var at build time (close#1398)
* remove un-used imports, edit makefile
* edit makefile to add new targets and export variables
* only export VERSION in makefile
* read version by executing the script if env var is absent
Examples
1) `
pytest --hge-urls "http://127.0.0.1:8080" --pg-urls "postgresql://admin@127.0.0.1:5432/hge_tests" -vv
`
2) `pytest --hge-urls "http://127.0.0.1:8080" "http://127.0.0.1:8081" --pg-urls "postgresql://admin@127.0.0.1:5432/hge_tests" "postgresql://admin@127.0.0.1:5432/hge_tests2" -vv
`
### Solution and Design
<!-- How is this issue solved/fixed? What is the design? -->
<!-- It's better if we elaborate -->
#### Reducing execution time of tests
- The Schema setup and teardown, which were earlier done per test method, usually takes around 1 sec.
- For mutations, the model has now been changed to only do schema setup and teardown once per test class.
- A data setup and teardown will be done once per test instead (usually takes ~10ms).
- For the test class to get this behaviour, one can can extend the class `DefaultTestMutations`.
- The function `dir()` should be define which returns the location of the configuration folder.
- Inside the configuration folder, there should be
- Files `<conf_dir>/schema_setup.yaml` and `<conf_dir>/schema_teardown.yaml`, which has the metadata query executed during schema setup and teardown respectively
- Files named `<conf_dir>/values_setup.yaml` and `<conf_dir>/values_teardown.yaml`. These files are executed to setup and remove data from the tables respectively.
#### Running Graphql queries on both http and websockets
- Each GraphQL query/mutation is run on the both HTTP and websocket protocols
- Pytests test parameterisation is used to achieve this
- The errors over websockets are slightly different from that on HTTP
- The code takes care of converting the errors in HTTP to errors in websockets
#### Parallel executation of tests.
- The plugin pytest-xdist helps in running tests on parallel workers.
- We are using this plugin to group tests by file and run on different workers.
- Parallel test worker processes operate on separate postgres databases(and separate graphql-engines connected to these databases). Thus tests on one worker will not affect the tests on the other worker.
- With two workers, this decreases execution times by half, as the tests on event triggers usually takes a long time, but does not consume much CPU.
From `alpha-40` we've been using a `WHERE` clause to fetch required rows and generate mutation response. This has a few limitations like the requirement of a primary key/unique constraint. This also returns inconsistent data on `delete` mutation as mentioned in #1794.
Now, we're using `VALUES (..)` (refer [here](https://www.postgresql.org/docs/current/sql-values.html)) expression to form virtual table rows in `SQL` to generate mutation response.
Internal changes:-
- Not to use primary key/unique constraint columns:-
- Revert back to `ConstraintName` from `TableConstraint` in `TableInfo` type
- Remove `tcCols` field in `TableConstraint` type
- Modify `table_info.sql` and `fetchTableMeta` function `SQL`
- A test case to perform `delete` mutation and returning relational objects.
1. Haskel library `pg-client-hs` has been updated to expose a function that helps listen to `postgres` notifications over a `channel` in this [PR](https://github.com/hasura/pg-client-hs/pull/5)
2. The server records an event in a table `hdb_catalog.hdb_cache_update_event` whenever any `/v1/query` (that changes metadata) is requested. A trigger notifies a `cache update` event via `hasura_cache_update` channel
3. The server runs two concurrent threads namely `listener` and `processor`. The `listener` thread listens to events on `hasura_cache_update` channel and pushed into a `Queue`. The `processor` thread fetches events from that `Queue` and processes it. Thus server rebuilds schema cache from database and updates.
If returning field contains nested selections then mutation is performed in two steps
1. Mutation is performed with returning columns of any primary key and unique constraints
2. returning fields are queried on rows returned by selecting from table by filtering with column values returned in Step 1.
Since mutation takes two courses based on selecting relations in returning field, it is hard to maintain sequence of prepared arguments (PrepArg) generated while resolving returning field. So, we're using txtConverter instead of prepare to resolve mutation fields.
* read cookie while initialising websocket connection (fix#1660)
* add tests for cookie on websocket init
* fix logic for tests
* enforce cors, and flag to force read cookie when cors disabled
- as browsers don't enforce SOP on websockets, we enforce CORS policy
on websocket handshake
- if CORS is disabled, by default cookie is not read (because XSS
risk!). Add special flag to force override this behaviour
* add log and forward origin header to webhook
- add log notice when cors is disabled, and cookie is not read on
websocket handshake
- forward origin header to webhook in POST mode. So that when CORS is
disabled, webhook can also enforce CORS independently.
* add docs, and forward all client headers to webhook
Rename the admin secret key header used to access GraphQL engine from X-Hasura-Access-Key to X-Hasura-Admin-Secret.
Server CLI and console all support the older flag but marks it as deprecated.
* support jsonb and geometry operators on RQL bool exps, close#1408
* add tests for jsonb operators in /v1/query
TODO:-
-> add tests for geometry (postgis) operators
* support parsing session variables for st_d_within and has_key ops
-> Add tests for boolExp operators and select permissions
* improve parsing $st_d_within op's json value logic
Support HASURA_GRAPHQL_AUTH_HOOK_MODE env var for --auth-hook-mode flag.
Drop support for HASURA_GRAPHQL_AUTH_HOOK_TYPE env var in next major
update (beta/stable)
* console now works on local builds of the server
1. local console assets can be served at /static/ by a build time flag
'local-console'. This can be set with stack as follows:
`stack build --flag graphql-engine:local-console`
2. the --root-dir option is removed which was used as a temporary hack
for serving graphiql
3. remove server's graphiql source code
Server templates `consolePath` key in `window.__env` object in console html template.
If server is hit at `/console/table/author` then `window.__env` in served html looks like
```
{
consoleMode: "server",
urlPrefix: "/console",
consolePath: "/console/table/author",
isAccessKeySet: true
}
```
* remove phase one/two distinction and hdbquery typeclass
* move extensions to default-extensions
* switch to LazyTx which only acquires a connection if needed
* move defns from TH module into Ops module
* remove tojson orphan instance for http exception
* remove orphan instance for dmlp1
* getTopLevelNodes will not throw any exceptions
When using self referential relationships in boolean expressions, the exists clause incorrectly uses the table names to qualify columns which will be the same for parent table and the child table. This is now fixed by generating unique aliases as we traverse down the relationships.
* improved nested insert execution logic
* integrate error path, improve executing 'withExp' and improve tests
* add more readable types in '/Resolve/Insert.hs'
* set conflict context just before executing WITH expression
* 1) Tests for creating permissions
2) Test for constraint_on with GraphQL insert on_conflict
* Run tests with access key and webhook
* Tests for GraphQL query with quoted columns
* Rewrite test-server.sh so that it can be run locally
* JWT based tests
* Tests with various postgres types
* For tests on select queries, run setup only once per class
* Tests for v1 count queries
* Skip teardown for tests that does not modify data
* Workaround for hpc 'parse error when reading .tix file'
* Move GeoJson tests to the new structure
* Basic tests for v1 queries
* Tests for column, table or operator not found error cases on GraphQL queries
* Skip test teardown for mutation tests which does not change database state, even when it returns 200.
* allow ordering using columns from object relationships, close#463
* validate table fields in nested insert
* add tests
* add docs
* change 'table_order_by' type from enums to ordered map
* remove unwanted code from 'Schema.hs' file
* 'AnnGObject' is not list of field name and value tuple
* update docs for new order_by type
* use 'InsOrdHashMap' for 'AnnGObj'
* handle empty fields in order_by
* remove '_' prefixes for asc/desc
* fix the changed order_by syntax across the repo
* support for count and aggregations on columns, close#786
* support explain query for aggregations
* '<arr-rel>_agg' in '<table>' type, fix order by for aggregations
* add 'allow_aggregations' key in select permissions
* Add checkbox to toggle count and aggregations on columns on select permission
* align aggregation checkbox with columns div
* improve readability of the generated sql
* alias is needed at the top level aggregation
* throw internal errors for unexpected fields
* rename SelFld to more readable TableAggFld
* rename agg to aggregate
Better SQL generation for select queries (the query plans will be the same but much more readable). This closes some long standing issues (#6, #121, #278).
This is breaking change where bigint and bigserial Postgres types will be encoded as GraphQL String types, as opposed to Int as present in earlier releases.
Input types were already encoded as String.
This is achieved by selecting `bigint` and `bigserial` columns as `text`s in the SQL query: `select "big_id"::text ..` instead of `select "big_id" .. `.
Reason for that change is outlined in #633 where JavaScript cannot decode 64 bit Integers.
Insert trigger function: If query affects no rows then return `null`
Insert trigger function is modified to have
`IF r IS NULL THEN RETURN null; ELSE RETURN r; END IF;` in return statement.
Fix migration logic to accommodate for non superuser permissions. Closes#567
- [x] Server
By clearing the `hdb_views` schema of existing views and functions instead of dropping and creating it again.
- [x] Bug fix (non-breaking change which fixes an issue)
Removes the seconds unit (trailing `s`) from `query_execution_time` in logs.
- [x] Server
It was a string before, changed to double.
- [x] Bug fix (non-breaking change which fixes an issue)
Docs should mention the type/unit of `query_execution_time` is numeric/double.
Changes `consoleMode` variable templated by HGE to `server` and modified console to respect in the same way and adds a patch to continue working with the older HGEs
- [x] Server
- [x] Console
JWT config now takes an optional jwk_url parameter (which points to published JWK Set). This is useful for providers who rotate their JWK Set.
Optional jwk_url parameter is taken. The published JWK set under that URL should be in standard JWK format (tools.ietf.org/html/rfc7517#section-4.8).
If the response contains an Expires header, the JWK set is automatically refreshed.
### Description
What component does this PR affect?
- [x] Server
### Related Issue
#494
### Solution and Design
Use `quote_ident()` SQL function over `constraint_name` in insert trigger function definition.
### Type
- [x] Bug fix (non-breaking change which fixes an issue)
### Description
Fixes#495
What component does this PR affect?
- [x] Server
### Solution and Design
Create the extension explicitly mentioning the public schema.
### Type
- [x] Bug fix (non-breaking change which fixes an issue)
* fix primary key changing on upsert, fix#342
* add 'update_columns' in 'on_conflict' object, consider 'allowUpsert'
* 'ConflictCtx' type should respect upsert cases
* validation for not null fields in an object
The API:
1. HGE has `--jwt-secret` flag or `HASURA_GRAPHQL_JWT_SECRET` env var. The value of which is a JSON.
2. The structure of this JSON is: `{"type": "<standard-JWT-algorithms>", "key": "<the-key>"}`
`type` : Standard JWT algos : `HS256`, `RS256`, `RS512` etc. (see jwt.io).
`key`:
i. Incase of symmetric key, the key as it is.
ii. Incase of asymmetric keys, only the public key, in a PEM encoded string or as a X509 certificate.
3. The claims in the JWT token must contain the following:
i. `x-hasura-default-role` field: default role of that user
ii. `x-hasura-allowed-roles` : A list of allowed roles for the user. The default role is overriden by `x-hasura-role` header.
4. The claims in the JWT token, can have other `x-hasura-*` fields where their values can only be strings.
5. The JWT tokens are sent as `Authorization: Bearer <token>` headers.
---
To test:
1. Generate a shared secret (for HMAC-SHA256) or RSA key pair.
2. Goto https://jwt.io/ , add the keys
3. Edit the claims to have `x-hasura-role` (mandatory) and other `x-hasura-*` fields. Add permissions related to the claims to test permissions.
4. Start HGE with `--jwt-secret` flag or `HASURA_GRAPHQL_JWT_SECRET` env var, which takes a JSON string: `{"type": "HS256", "key": "mylongsharedsecret"}` or `{"type":"RS256", "key": "<PEM-encoded-public-key>"}`
5. Copy the JWT token from jwt.io and use it in the `Authorization: Bearer <token>` header.
---
TODO: Support EC public keys. It is blocked on frasertweedale/hs-jose#61
* don't allow fkey based relations from/to a table that isn't tracked, fix#185
Check if remote table exist in metadata when creating foreign-key
based object relationship.
* add tests for adding object relation using fkey if remote table is untracked
* filter schema identifiers to conform to graphql naming scheme,closes #134
Filter out tables, columns, relationships etc which does not conform to
graphql naming scheme.
This ensures GraphiQL initialisation works properly for existing
databases.
* rename `isGraphQLConform` to `isValidName`
* rename all graphQL validators
* add 'on_conflict' condition to allow upsert mutation, closes#105
* check for empty unique or primary key constraints
* add 'on_conflict' condition test cases and introspection test case
* update 'conflict_action' enum values' description
* server: basic test setup
* server: use the default transaction mode
* server: basic tests in yaml files
* server: restructure test setup and some more tests