Skip to content

Commit

Permalink
add flag to disable prepared statements (close hasura#1392) (hasura#1396
Browse files Browse the repository at this point in the history
)
  • Loading branch information
nizar-m authored and shahidhk committed Jan 18, 2019
1 parent d91d7e6 commit 916caf1
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 58 deletions.
71 changes: 71 additions & 0 deletions .circleci/test-server-flags.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/env bash
set -euo pipefail

CIRCLECI_FOLDER="${BASH_SOURCE[0]%/*}"
cd $CIRCLECI_FOLDER
CIRCLECI_FOLDER="$PWD"

SERVER_ROOT="$CIRCLECI_FOLDER/../server"

cd $SERVER_ROOT

if [ -z "${HASURA_GRAPHQL_DATABASE_URL:-}" ] ; then
echo "Env var HASURA_GRAPHQL_DATABASE_URL is not set"
exit 1
fi

if ! stack --allow-different-user exec -- which graphql-engine > /dev/null && [ -z "${GRAPHQL_ENGINE:-}" ] ; then
echo "Do 'stack build' before tests, or export the location of executable in the GRAPHQL_ENGINE envirnoment variable"
exit 1
fi

GRAPHQL_ENGINE=${GRAPHQL_ENGINE:-"$(stack --allow-different-user exec -- which graphql-engine)"}
if ! [ -x "$GRAPHQL_ENGINE" ] ; then
echo "$GRAPHQL_ENGINE is not present or is not an executable"
exit 1
fi

OUTPUT_FOLDER=${OUTPUT_FOLDER:-"$CIRCLECI_FOLDER/test-server-flags-output"}
mkdir -p "$OUTPUT_FOLDER"


########## Test --use-prepared-statements

"$GRAPHQL_ENGINE" serve --use-prepared-statements=false > "$OUTPUT_FOLDER/graphql-engine.log" & PID=$!

sleep 1

kill $PID || true

grep --color -F '"use_prepared_statements":false' "$OUTPUT_FOLDER/graphql-engine.log" >/dev/null

"$GRAPHQL_ENGINE" serve --use-prepared-statements=true > "$OUTPUT_FOLDER/graphql-engine.log" & PID=$!

sleep 1

kill $PID || true

grep --color -F '"use_prepared_statements":true' "$OUTPUT_FOLDER/graphql-engine.log" >/dev/null

######### Test HASURA_GRAPHQL_USE_PREPARED_STATEMENTS environmental variable

export HASURA_GRAPHQL_USE_PREPARED_STATEMENTS=abcd

"$GRAPHQL_ENGINE" serve > "$OUTPUT_FOLDER/graphql-engine.log" 2>&1 & PID=$!

sleep 1

kill $PID || true

grep --color -F 'Not a valid boolean text' "$OUTPUT_FOLDER/graphql-engine.log" >/dev/null


export HASURA_GRAPHQL_USE_PREPARED_STATEMENTS=false

"$GRAPHQL_ENGINE" serve > "$OUTPUT_FOLDER/graphql-engine.log" 2>&1 & PID=$!

sleep 1

kill $PID || true

grep --color -F '"use_prepared_statements":false' "$OUTPUT_FOLDER/graphql-engine.log" >/dev/null
5 changes: 5 additions & 0 deletions .circleci/test-server.sh
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ CIRCLECI_FOLDER="${BASH_SOURCE[0]%/*}"
cd $CIRCLECI_FOLDER
CIRCLECI_FOLDER="$PWD"

if ! $CIRCLECI_FOLDER/test-server-flags.sh ; then
echo "Testing GraphQL server flags failed"
exit 1
fi

PYTEST_ROOT="$CIRCLECI_FOLDER/../server/tests-py"

OUTPUT_FOLDER=${OUTPUT_FOLDER:-"$CIRCLECI_FOLDER/test-server-output"}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ npm-debug.log
*.DS_Store
.tern-project
test-server-output
test-server-flags-output
.vscode
107 changes: 56 additions & 51 deletions docs/graphql/manual/deployment/graphql-engine-flags/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -40,44 +40,46 @@ For ``serve`` subcommand these are the flags available

.. code-block:: none
--server-host IP address of network interface that graphql-engine will listen on (default: '*', all interfaces)
--server-host IP address of network interface that graphql-engine will listen on (default: '*', all interfaces)
--server-port Port on which graphql-engine should be served (default: 8080)
--server-port Port on which graphql-engine should be served (default: 8080)
--access-key Secret access key, required to access this instance.
If specified client needs to send 'X-Hasura-Access-Key'
header
--access-key Secret access key, required to access this instance.
If specified client needs to send 'X-Hasura-Access-Key'
header
--cors-domain The domain, including sheme and port, to allow CORS for
--cors-domain The domain, including sheme and port, to allow CORS for
--disable-cors Disable CORS handling
--disable-cors Disable CORS handling
--auth-hook The authentication webhook, required to authenticate
incoming request
--auth-hook The authentication webhook, required to authenticate
incoming request
--auth-hook-mode The authentication webhook mode. GET|POST (default: GET)
--auth-hook-mode The authentication webhook mode. GET|POST (default: GET)
--jwt-secret The JSON containing type and the JWK used for
verifying. e.g: `{"type": "HS256", "key":
"<your-hmac-shared-secret>"}`,`{"type": "RS256",
"key": "<your-PEM-RSA-public-key>"}
--jwt-secret The JSON containing type and the JWK used for
verifying. e.g: `{"type": "HS256", "key":
"<your-hmac-shared-secret>"}`,`{"type": "RS256",
"key": "<your-PEM-RSA-public-key>"}
--unauthorized-role Unauthorized role, used when access-key is not sent in
access-key only mode or "Authorization" header is absent
in JWT mode
--unauthorized-role Unauthorized role, used when access-key is not sent in
access-key only mode or "Authorization" header is absent
in JWT mode
-s, --stripes Number of stripes (default: 1)
-s, --stripes Number of stripes (default: 1)
-c, --connections Number of connections that need to be opened to Postgres
(default: 50)
-c, --connections Number of connections that need to be opened to Postgres
(default: 50)
--timeout Each connection's idle time before it is closed
(default: 180 sec)
--timeout Each connection's idle time before it is closed
(default: 180 sec)
-i, --tx-iso Transaction isolation. read-commited / repeatable-read /
serializable
-i, --tx-iso Transaction isolation. read-commited / repeatable-read /
serializable
--enable-console Enable API console. It is served at '/' and '/console'
--enable-console Enable API console. It is served at '/' and '/console'
--use-prepared-statements Use prepared statements for SQL queries (default: true)
Default environment variables
Expand Down Expand Up @@ -109,38 +111,41 @@ These are the environment variables which are available:
HASURA_GRAPHQL_PG_CONNECTIONS Number of connections that need to be opened to
Postgres (default: 50)
HASURA_GRAPHQL_PG_TIMEOUT Each connection's idle time before it is closed
(default: 180 sec)
HASURA_GRAPHQL_PG_TIMEOUT Each connection's idle time before it is closed
(default: 180 sec)
HASURA_GRAPHQL_TX_ISOLATION transaction isolation. read-committed /
repeatable-read / serializable
(default: read-commited)
HASURA_GRAPHQL_SERVER_HOST IP address of network interface that graphql-engine will listen on
HASURA_GRAPHQL_TX_ISOLATION transaction isolation. read-committed /
repeatable-read / serializable
(default: read-commited)
HASURA_GRAPHQL_SERVER_HOST IP address of network interface that graphql-engine will listen on
HASURA_GRAPHQL_SERVER_PORT Port on which graphql-engine should be served
HASURA_GRAPHQL_SERVER_PORT Port on which graphql-engine should be served
HASURA_GRAPHQL_ACCESS_KEY Secret access key, required to access this
instance. If specified client needs to send
'X-Hasura-Access-Key' header
HASURA_GRAPHQL_ACCESS_KEY Secret access key, required to access this
instance. If specified client needs to send
'X-Hasura-Access-Key' header
HASURA_GRAPHQL_AUTH_HOOK The authentication webhook, required to
authenticate incoming request
HASURA_GRAPHQL_AUTH_HOOK The authentication webhook, required to
authenticate incoming request
HASURA_GRAPHQL_AUTH_HOOK_MODE The authentication webhook mode, GET|POST
(default: GET)
HASURA_GRAPHQL_AUTH_HOOK_MODE The authentication webhook mode, GET|POST
(default: GET)
HASURA_GRAPHQL_CORS_DOMAIN The domain, including sheme and port,
to allow CORS for
HASURA_GRAPHQL_CORS_DOMAIN The domain, including sheme and port,
to allow CORS for
HASURA_GRAPHQL_JWT_SECRET The JSON containing type and the JWK used for
verifying. e.g: `{"type": "HS256", "key":
"<your-hmac-shared-secret>"}`,`{"type": "RS256",
"key": "<your-PEM-RSA-public-key>"}
Enable JWT mode, the value of which is a JSON
HASURA_GRAPHQL_JWT_SECRET The JSON containing type and the JWK used for
verifying. e.g: `{"type": "HS256", "key":
"<your-hmac-shared-secret>"}`,`{"type": "RS256",
"key": "<your-PEM-RSA-public-key>"}
Enable JWT mode, the value of which is a JSON
HASURA_GRAPHQL_UNAUTHORIZED_ROLE Unauthorized role, used when access-key is not sent
in access-key only mode or "Authorization" header
is absent in JWT mode
HASURA_GRAPHQL_UNAUTHORIZED_ROLE Unauthorized role, used when access-key is not sent
in access-key only mode or "Authorization" header
is absent in JWT mode
HASURA_GRAPHQL_ENABLE_CONSOLE Enable API console. It is served at
'/' and '/console'
HASURA_GRAPHQL_ENABLE_CONSOLE Enable API console. It is served at
'/' and '/console'
HASURA_GRAPHQL_USE_PREPARED_STATEMENTS Use prepared statements for SQL queries
(default: true)
27 changes: 21 additions & 6 deletions server/src-lib/Hasura/Server/Init.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ initStateTx = clearHdbViews

data RawConnParams
= RawConnParams
{ rcpStripes :: !(Maybe Int)
, rcpConns :: !(Maybe Int)
, rcpIdleTime :: !(Maybe Int)
{ rcpStripes :: !(Maybe Int)
, rcpConns :: !(Maybe Int)
, rcpIdleTime :: !(Maybe Int)
, rcpAllowPrepare :: !(Maybe Bool)
} deriving (Show, Eq)

type RawAuthHook = AuthHookG (Maybe T.Text) (Maybe AuthHookType)
Expand Down Expand Up @@ -225,11 +226,12 @@ mkServeOptions rso = do
return $ ServeOptions port host connParams txIso accKey authHook
jwtSecr unAuthRole corsCfg enableConsole
where
mkConnParams (RawConnParams s c i) = do
mkConnParams (RawConnParams s c i p) = do
stripes <- fromMaybe 1 <$> withEnv s (fst pgStripesEnv)
conns <- fromMaybe 50 <$> withEnv c (fst pgConnsEnv)
iTime <- fromMaybe 180 <$> withEnv i (fst pgTimeoutEnv)
return $ Q.ConnParams stripes conns iTime
allowPrepare <- fromMaybe True <$> withEnv p (fst pgUsePrepareEnv)
return $ Q.ConnParams stripes conns iTime allowPrepare

mkAuthHook (AuthHookG mUrl mType) = do
mUrlEnv <- withEnv mUrl $ fst authHookEnv
Expand Down Expand Up @@ -361,6 +363,12 @@ pgTimeoutEnv =
, "Each connection's idle time before it is closed (default: 180 sec)"
)

pgUsePrepareEnv :: (String, String)
pgUsePrepareEnv =
( "HASURA_GRAPHQL_USE_PREPARED_STATEMENTS"
, "Use prepared statements for queries (default: True)"
)

txIsoEnv :: (String, String)
txIsoEnv =
( "HASURA_GRAPHQL_TX_ISOLATION"
Expand Down Expand Up @@ -484,7 +492,7 @@ parseTxIsolation = optional $

parseConnParams :: Parser RawConnParams
parseConnParams =
RawConnParams <$> stripes <*> conns <*> timeout
RawConnParams <$> stripes <*> conns <*> timeout <*> allowPrepare
where
stripes = optional $
option auto
Expand All @@ -508,6 +516,12 @@ parseConnParams =
metavar "SECONDS" <>
help (snd pgTimeoutEnv)
)
allowPrepare = optional $
option (eitherReader parseStrAsBool)
( long "use-prepared-statements" <>
metavar "USE PREPARED STATEMENTS" <>
help (snd pgUsePrepareEnv)
)

parseServerPort :: Parser (Maybe Int)
parseServerPort = optional $
Expand Down Expand Up @@ -620,6 +634,7 @@ serveOptsToLog so =
, "cors_domain" J..= (ccDomain . soCorsConfig) so
, "cors_disabled" J..= (ccDisabled . soCorsConfig) so
, "enable_console" J..= soEnableConsole so
, "use_prepared_statements" J..= (Q.cpAllowPrepare . soConnParams) so
]

mkGenericStrLog :: T.Text -> String -> StartupLog
Expand Down
2 changes: 1 addition & 1 deletion server/stack.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ packages:
extra-deps:
# use https URLs so that build systems can clone these repos
- git: https://github.com/hasura/pg-client-hs.git
commit: 47b168d252d4adc800137a8b2cd3fc977cb3468d
commit: f3d1e9e67bdfbfa3de85b7cbdb4c557dce7fd84d
- git: https://github.com/hasura/graphql-parser-hs.git
commit: 75782ae894cce05ed31e5b87fd696fc10e88baf9
- ginger-0.8.1.0
Expand Down

0 comments on commit 916caf1

Please sign in to comment.