Skip to content

Commit 916caf1

Browse files
nizar-mshahidhk
authored andcommitted
add flag to disable prepared statements (close #1392) (#1396)
1 parent d91d7e6 commit 916caf1

File tree

6 files changed

+155
-58
lines changed

6 files changed

+155
-58
lines changed

.circleci/test-server-flags.sh

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
CIRCLECI_FOLDER="${BASH_SOURCE[0]%/*}"
5+
cd $CIRCLECI_FOLDER
6+
CIRCLECI_FOLDER="$PWD"
7+
8+
SERVER_ROOT="$CIRCLECI_FOLDER/../server"
9+
10+
cd $SERVER_ROOT
11+
12+
if [ -z "${HASURA_GRAPHQL_DATABASE_URL:-}" ] ; then
13+
echo "Env var HASURA_GRAPHQL_DATABASE_URL is not set"
14+
exit 1
15+
fi
16+
17+
if ! stack --allow-different-user exec -- which graphql-engine > /dev/null && [ -z "${GRAPHQL_ENGINE:-}" ] ; then
18+
echo "Do 'stack build' before tests, or export the location of executable in the GRAPHQL_ENGINE envirnoment variable"
19+
exit 1
20+
fi
21+
22+
GRAPHQL_ENGINE=${GRAPHQL_ENGINE:-"$(stack --allow-different-user exec -- which graphql-engine)"}
23+
if ! [ -x "$GRAPHQL_ENGINE" ] ; then
24+
echo "$GRAPHQL_ENGINE is not present or is not an executable"
25+
exit 1
26+
fi
27+
28+
OUTPUT_FOLDER=${OUTPUT_FOLDER:-"$CIRCLECI_FOLDER/test-server-flags-output"}
29+
mkdir -p "$OUTPUT_FOLDER"
30+
31+
32+
########## Test --use-prepared-statements
33+
34+
"$GRAPHQL_ENGINE" serve --use-prepared-statements=false > "$OUTPUT_FOLDER/graphql-engine.log" & PID=$!
35+
36+
sleep 1
37+
38+
kill $PID || true
39+
40+
grep --color -F '"use_prepared_statements":false' "$OUTPUT_FOLDER/graphql-engine.log" >/dev/null
41+
42+
"$GRAPHQL_ENGINE" serve --use-prepared-statements=true > "$OUTPUT_FOLDER/graphql-engine.log" & PID=$!
43+
44+
sleep 1
45+
46+
kill $PID || true
47+
48+
grep --color -F '"use_prepared_statements":true' "$OUTPUT_FOLDER/graphql-engine.log" >/dev/null
49+
50+
######### Test HASURA_GRAPHQL_USE_PREPARED_STATEMENTS environmental variable
51+
52+
export HASURA_GRAPHQL_USE_PREPARED_STATEMENTS=abcd
53+
54+
"$GRAPHQL_ENGINE" serve > "$OUTPUT_FOLDER/graphql-engine.log" 2>&1 & PID=$!
55+
56+
sleep 1
57+
58+
kill $PID || true
59+
60+
grep --color -F 'Not a valid boolean text' "$OUTPUT_FOLDER/graphql-engine.log" >/dev/null
61+
62+
63+
export HASURA_GRAPHQL_USE_PREPARED_STATEMENTS=false
64+
65+
"$GRAPHQL_ENGINE" serve > "$OUTPUT_FOLDER/graphql-engine.log" 2>&1 & PID=$!
66+
67+
sleep 1
68+
69+
kill $PID || true
70+
71+
grep --color -F '"use_prepared_statements":false' "$OUTPUT_FOLDER/graphql-engine.log" >/dev/null

.circleci/test-server.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ CIRCLECI_FOLDER="${BASH_SOURCE[0]%/*}"
8080
cd $CIRCLECI_FOLDER
8181
CIRCLECI_FOLDER="$PWD"
8282

83+
if ! $CIRCLECI_FOLDER/test-server-flags.sh ; then
84+
echo "Testing GraphQL server flags failed"
85+
exit 1
86+
fi
87+
8388
PYTEST_ROOT="$CIRCLECI_FOLDER/../server/tests-py"
8489

8590
OUTPUT_FOLDER=${OUTPUT_FOLDER:-"$CIRCLECI_FOLDER/test-server-output"}

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ npm-debug.log
33
*.DS_Store
44
.tern-project
55
test-server-output
6+
test-server-flags-output
67
.vscode

docs/graphql/manual/deployment/graphql-engine-flags/reference.rst

Lines changed: 56 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -40,44 +40,46 @@ For ``serve`` subcommand these are the flags available
4040

4141
.. code-block:: none
4242
43-
--server-host IP address of network interface that graphql-engine will listen on (default: '*', all interfaces)
43+
--server-host IP address of network interface that graphql-engine will listen on (default: '*', all interfaces)
4444
45-
--server-port Port on which graphql-engine should be served (default: 8080)
45+
--server-port Port on which graphql-engine should be served (default: 8080)
4646
47-
--access-key Secret access key, required to access this instance.
48-
If specified client needs to send 'X-Hasura-Access-Key'
49-
header
47+
--access-key Secret access key, required to access this instance.
48+
If specified client needs to send 'X-Hasura-Access-Key'
49+
header
5050
51-
--cors-domain The domain, including sheme and port, to allow CORS for
51+
--cors-domain The domain, including sheme and port, to allow CORS for
5252
53-
--disable-cors Disable CORS handling
53+
--disable-cors Disable CORS handling
5454
55-
--auth-hook The authentication webhook, required to authenticate
56-
incoming request
55+
--auth-hook The authentication webhook, required to authenticate
56+
incoming request
5757
58-
--auth-hook-mode The authentication webhook mode. GET|POST (default: GET)
58+
--auth-hook-mode The authentication webhook mode. GET|POST (default: GET)
5959
60-
--jwt-secret The JSON containing type and the JWK used for
61-
verifying. e.g: `{"type": "HS256", "key":
62-
"<your-hmac-shared-secret>"}`,`{"type": "RS256",
63-
"key": "<your-PEM-RSA-public-key>"}
60+
--jwt-secret The JSON containing type and the JWK used for
61+
verifying. e.g: `{"type": "HS256", "key":
62+
"<your-hmac-shared-secret>"}`,`{"type": "RS256",
63+
"key": "<your-PEM-RSA-public-key>"}
6464
65-
--unauthorized-role Unauthorized role, used when access-key is not sent in
66-
access-key only mode or "Authorization" header is absent
67-
in JWT mode
65+
--unauthorized-role Unauthorized role, used when access-key is not sent in
66+
access-key only mode or "Authorization" header is absent
67+
in JWT mode
6868
69-
-s, --stripes Number of stripes (default: 1)
69+
-s, --stripes Number of stripes (default: 1)
7070
71-
-c, --connections Number of connections that need to be opened to Postgres
72-
(default: 50)
71+
-c, --connections Number of connections that need to be opened to Postgres
72+
(default: 50)
7373
74-
--timeout Each connection's idle time before it is closed
75-
(default: 180 sec)
74+
--timeout Each connection's idle time before it is closed
75+
(default: 180 sec)
7676
77-
-i, --tx-iso Transaction isolation. read-commited / repeatable-read /
78-
serializable
77+
-i, --tx-iso Transaction isolation. read-commited / repeatable-read /
78+
serializable
7979
80-
--enable-console Enable API console. It is served at '/' and '/console'
80+
--enable-console Enable API console. It is served at '/' and '/console'
81+
82+
--use-prepared-statements Use prepared statements for SQL queries (default: true)
8183
8284
8385
Default environment variables
@@ -109,38 +111,41 @@ These are the environment variables which are available:
109111
HASURA_GRAPHQL_PG_CONNECTIONS Number of connections that need to be opened to
110112
Postgres (default: 50)
111113
112-
HASURA_GRAPHQL_PG_TIMEOUT Each connection's idle time before it is closed
113-
(default: 180 sec)
114+
HASURA_GRAPHQL_PG_TIMEOUT Each connection's idle time before it is closed
115+
(default: 180 sec)
116+
117+
HASURA_GRAPHQL_TX_ISOLATION transaction isolation. read-committed /
118+
repeatable-read / serializable
119+
(default: read-commited)
120+
HASURA_GRAPHQL_SERVER_HOST IP address of network interface that graphql-engine will listen on
114121
115-
HASURA_GRAPHQL_TX_ISOLATION transaction isolation. read-committed /
116-
repeatable-read / serializable
117-
(default: read-commited)
118-
HASURA_GRAPHQL_SERVER_HOST IP address of network interface that graphql-engine will listen on
122+
HASURA_GRAPHQL_SERVER_PORT Port on which graphql-engine should be served
119123
120-
HASURA_GRAPHQL_SERVER_PORT Port on which graphql-engine should be served
124+
HASURA_GRAPHQL_ACCESS_KEY Secret access key, required to access this
125+
instance. If specified client needs to send
126+
'X-Hasura-Access-Key' header
121127
122-
HASURA_GRAPHQL_ACCESS_KEY Secret access key, required to access this
123-
instance. If specified client needs to send
124-
'X-Hasura-Access-Key' header
128+
HASURA_GRAPHQL_AUTH_HOOK The authentication webhook, required to
129+
authenticate incoming request
125130
126-
HASURA_GRAPHQL_AUTH_HOOK The authentication webhook, required to
127-
authenticate incoming request
131+
HASURA_GRAPHQL_AUTH_HOOK_MODE The authentication webhook mode, GET|POST
132+
(default: GET)
128133
129-
HASURA_GRAPHQL_AUTH_HOOK_MODE The authentication webhook mode, GET|POST
130-
(default: GET)
134+
HASURA_GRAPHQL_CORS_DOMAIN The domain, including sheme and port,
135+
to allow CORS for
131136
132-
HASURA_GRAPHQL_CORS_DOMAIN The domain, including sheme and port,
133-
to allow CORS for
137+
HASURA_GRAPHQL_JWT_SECRET The JSON containing type and the JWK used for
138+
verifying. e.g: `{"type": "HS256", "key":
139+
"<your-hmac-shared-secret>"}`,`{"type": "RS256",
140+
"key": "<your-PEM-RSA-public-key>"}
141+
Enable JWT mode, the value of which is a JSON
134142
135-
HASURA_GRAPHQL_JWT_SECRET The JSON containing type and the JWK used for
136-
verifying. e.g: `{"type": "HS256", "key":
137-
"<your-hmac-shared-secret>"}`,`{"type": "RS256",
138-
"key": "<your-PEM-RSA-public-key>"}
139-
Enable JWT mode, the value of which is a JSON
143+
HASURA_GRAPHQL_UNAUTHORIZED_ROLE Unauthorized role, used when access-key is not sent
144+
in access-key only mode or "Authorization" header
145+
is absent in JWT mode
140146
141-
HASURA_GRAPHQL_UNAUTHORIZED_ROLE Unauthorized role, used when access-key is not sent
142-
in access-key only mode or "Authorization" header
143-
is absent in JWT mode
147+
HASURA_GRAPHQL_ENABLE_CONSOLE Enable API console. It is served at
148+
'/' and '/console'
144149
145-
HASURA_GRAPHQL_ENABLE_CONSOLE Enable API console. It is served at
146-
'/' and '/console'
150+
HASURA_GRAPHQL_USE_PREPARED_STATEMENTS Use prepared statements for SQL queries
151+
(default: true)

server/src-lib/Hasura/Server/Init.hs

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,10 @@ initStateTx = clearHdbViews
2828

2929
data RawConnParams
3030
= RawConnParams
31-
{ rcpStripes :: !(Maybe Int)
32-
, rcpConns :: !(Maybe Int)
33-
, rcpIdleTime :: !(Maybe Int)
31+
{ rcpStripes :: !(Maybe Int)
32+
, rcpConns :: !(Maybe Int)
33+
, rcpIdleTime :: !(Maybe Int)
34+
, rcpAllowPrepare :: !(Maybe Bool)
3435
} deriving (Show, Eq)
3536

3637
type RawAuthHook = AuthHookG (Maybe T.Text) (Maybe AuthHookType)
@@ -225,11 +226,12 @@ mkServeOptions rso = do
225226
return $ ServeOptions port host connParams txIso accKey authHook
226227
jwtSecr unAuthRole corsCfg enableConsole
227228
where
228-
mkConnParams (RawConnParams s c i) = do
229+
mkConnParams (RawConnParams s c i p) = do
229230
stripes <- fromMaybe 1 <$> withEnv s (fst pgStripesEnv)
230231
conns <- fromMaybe 50 <$> withEnv c (fst pgConnsEnv)
231232
iTime <- fromMaybe 180 <$> withEnv i (fst pgTimeoutEnv)
232-
return $ Q.ConnParams stripes conns iTime
233+
allowPrepare <- fromMaybe True <$> withEnv p (fst pgUsePrepareEnv)
234+
return $ Q.ConnParams stripes conns iTime allowPrepare
233235

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

366+
pgUsePrepareEnv :: (String, String)
367+
pgUsePrepareEnv =
368+
( "HASURA_GRAPHQL_USE_PREPARED_STATEMENTS"
369+
, "Use prepared statements for queries (default: True)"
370+
)
371+
364372
txIsoEnv :: (String, String)
365373
txIsoEnv =
366374
( "HASURA_GRAPHQL_TX_ISOLATION"
@@ -484,7 +492,7 @@ parseTxIsolation = optional $
484492

485493
parseConnParams :: Parser RawConnParams
486494
parseConnParams =
487-
RawConnParams <$> stripes <*> conns <*> timeout
495+
RawConnParams <$> stripes <*> conns <*> timeout <*> allowPrepare
488496
where
489497
stripes = optional $
490498
option auto
@@ -508,6 +516,12 @@ parseConnParams =
508516
metavar "SECONDS" <>
509517
help (snd pgTimeoutEnv)
510518
)
519+
allowPrepare = optional $
520+
option (eitherReader parseStrAsBool)
521+
( long "use-prepared-statements" <>
522+
metavar "USE PREPARED STATEMENTS" <>
523+
help (snd pgUsePrepareEnv)
524+
)
511525

512526
parseServerPort :: Parser (Maybe Int)
513527
parseServerPort = optional $
@@ -620,6 +634,7 @@ serveOptsToLog so =
620634
, "cors_domain" J..= (ccDomain . soCorsConfig) so
621635
, "cors_disabled" J..= (ccDisabled . soCorsConfig) so
622636
, "enable_console" J..= soEnableConsole so
637+
, "use_prepared_statements" J..= (Q.cpAllowPrepare . soConnParams) so
623638
]
624639

625640
mkGenericStrLog :: T.Text -> String -> StartupLog

server/stack.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ packages:
1717
extra-deps:
1818
# use https URLs so that build systems can clone these repos
1919
- git: https://github.com/hasura/pg-client-hs.git
20-
commit: 47b168d252d4adc800137a8b2cd3fc977cb3468d
20+
commit: f3d1e9e67bdfbfa3de85b7cbdb4c557dce7fd84d
2121
- git: https://github.com/hasura/graphql-parser-hs.git
2222
commit: 75782ae894cce05ed31e5b87fd696fc10e88baf9
2323
- ginger-0.8.1.0

0 commit comments

Comments
 (0)