mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-15 17:31:56 +03:00
This commit is contained in:
parent
729ed5b22f
commit
96f8b05326
@ -32,7 +32,6 @@ import qualified Data.Text as T
|
|||||||
|
|
||||||
import Hasura.GraphQL.Utils
|
import Hasura.GraphQL.Utils
|
||||||
import Hasura.Prelude
|
import Hasura.Prelude
|
||||||
import Hasura.RQL.DDL.Utils
|
|
||||||
import Hasura.RQL.Types
|
import Hasura.RQL.Types
|
||||||
import Hasura.SQL.Types
|
import Hasura.SQL.Types
|
||||||
|
|
||||||
|
@ -13,8 +13,10 @@ module Hasura.RQL.DDL.Schema.Diff
|
|||||||
, getSchemaChangeDeps
|
, getSchemaChangeDeps
|
||||||
|
|
||||||
, FunctionMeta(..)
|
, FunctionMeta(..)
|
||||||
|
, funcFromMeta
|
||||||
, fetchFunctionMeta
|
, fetchFunctionMeta
|
||||||
, getDroppedFuncs
|
, FunctionDiff(..)
|
||||||
|
, getFuncDiff
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Hasura.Prelude
|
import Hasura.Prelude
|
||||||
@ -226,25 +228,50 @@ getSchemaChangeDeps schemaDiff = do
|
|||||||
|
|
||||||
data FunctionMeta
|
data FunctionMeta
|
||||||
= FunctionMeta
|
= FunctionMeta
|
||||||
{ fmOid :: !Int
|
{ fmOid :: !Int
|
||||||
, fmFunction :: !QualifiedFunction
|
, fmSchema :: !SchemaName
|
||||||
|
, fmName :: !FunctionName
|
||||||
|
, fmType :: !FunctionType
|
||||||
} deriving (Show, Eq)
|
} deriving (Show, Eq)
|
||||||
|
$(deriveJSON (aesonDrop 2 snakeCase) ''FunctionMeta)
|
||||||
|
|
||||||
|
funcFromMeta :: FunctionMeta -> QualifiedFunction
|
||||||
|
funcFromMeta fm = QualifiedObject (fmSchema fm) (fmName fm)
|
||||||
|
|
||||||
fetchFunctionMeta :: Q.Tx [FunctionMeta]
|
fetchFunctionMeta :: Q.Tx [FunctionMeta]
|
||||||
fetchFunctionMeta = do
|
fetchFunctionMeta = do
|
||||||
res <- Q.listQ [Q.sql|
|
map (Q.getAltJ . runIdentity) <$> Q.listQ [Q.sql|
|
||||||
SELECT
|
SELECT
|
||||||
f.function_schema,
|
json_build_object(
|
||||||
f.function_name,
|
'oid', p.oid :: integer,
|
||||||
p.oid
|
'schema', f.function_schema,
|
||||||
FROM hdb_catalog.hdb_function_agg f
|
'name', f.function_name,
|
||||||
JOIN pg_catalog.pg_proc p ON (p.proname = f.function_name)
|
'type', f.function_type
|
||||||
|
) AS function_meta
|
||||||
|
FROM
|
||||||
|
hdb_catalog.hdb_function_agg f
|
||||||
|
JOIN pg_catalog.pg_proc p ON (p.proname = f.function_name)
|
||||||
|
JOIN pg_catalog.pg_namespace pn ON (
|
||||||
|
pn.oid = p.pronamespace
|
||||||
|
AND pn.nspname = f.function_schema
|
||||||
|
)
|
||||||
WHERE
|
WHERE
|
||||||
f.function_schema <> 'hdb_catalog'
|
f.function_schema <> 'hdb_catalog'
|
||||||
|] () False
|
|] () False
|
||||||
forM res $ \(sn, fn, foid) ->
|
|
||||||
return $ FunctionMeta foid $ QualifiedObject sn fn
|
|
||||||
|
|
||||||
getDroppedFuncs :: [FunctionMeta] -> [FunctionMeta] -> [QualifiedFunction]
|
data FunctionDiff
|
||||||
getDroppedFuncs oldMeta newMeta =
|
= FunctionDiff
|
||||||
map fmFunction $ getDifference fmOid oldMeta newMeta
|
{ fdDropped :: ![QualifiedFunction]
|
||||||
|
, fdAltered :: ![(QualifiedFunction, FunctionType)]
|
||||||
|
} deriving (Show, Eq)
|
||||||
|
|
||||||
|
getFuncDiff :: [FunctionMeta] -> [FunctionMeta] -> FunctionDiff
|
||||||
|
getFuncDiff oldMeta newMeta =
|
||||||
|
FunctionDiff droppedFuncs alteredFuncs
|
||||||
|
where
|
||||||
|
droppedFuncs = map funcFromMeta $ getDifference fmOid oldMeta newMeta
|
||||||
|
alteredFuncs = mapMaybe mkAltered $ getOverlap fmOid oldMeta newMeta
|
||||||
|
mkAltered (oldfm, newfm) =
|
||||||
|
let isTypeAltered = fmType oldfm /= fmType newfm
|
||||||
|
alteredFunc = (funcFromMeta oldfm, fmType newfm)
|
||||||
|
in bool Nothing (Just alteredFunc) isTypeAltered
|
||||||
|
@ -440,8 +440,8 @@ execWithMDCheck (RunSQL t cascade _) = do
|
|||||||
oldMeta = flip filter oldMetaU $ \tm -> tmTable tm `elem` existingTables
|
oldMeta = flip filter oldMetaU $ \tm -> tmTable tm `elem` existingTables
|
||||||
schemaDiff = getSchemaDiff oldMeta newMeta
|
schemaDiff = getSchemaDiff oldMeta newMeta
|
||||||
existingFuncs = M.keys $ scFunctions sc
|
existingFuncs = M.keys $ scFunctions sc
|
||||||
oldFuncMeta = flip filter oldFuncMetaU $ \fm -> fmFunction fm `elem` existingFuncs
|
oldFuncMeta = flip filter oldFuncMetaU $ \fm -> funcFromMeta fm `elem` existingFuncs
|
||||||
droppedFuncs = getDroppedFuncs oldFuncMeta newFuncMeta
|
FunctionDiff droppedFuncs alteredFuncs = getFuncDiff oldFuncMeta newFuncMeta
|
||||||
|
|
||||||
indirectDeps <- getSchemaChangeDeps schemaDiff
|
indirectDeps <- getSchemaChangeDeps schemaDiff
|
||||||
|
|
||||||
@ -461,6 +461,12 @@ execWithMDCheck (RunSQL t cascade _) = do
|
|||||||
liftTx $ delFunctionFromCatalog qf
|
liftTx $ delFunctionFromCatalog qf
|
||||||
delFunctionFromCache qf
|
delFunctionFromCache qf
|
||||||
|
|
||||||
|
-- Process altered functions
|
||||||
|
forM_ alteredFuncs $ \(qf, newTy) ->
|
||||||
|
when (newTy == FTVOLATILE) $
|
||||||
|
throw400 NotSupported $
|
||||||
|
"type of function " <> qf <<> " is altered to \"VOLATILE\" which is not supported now"
|
||||||
|
|
||||||
-- update the schema cache with the changes
|
-- update the schema cache with the changes
|
||||||
processSchemaChanges schemaDiff
|
processSchemaChanges schemaDiff
|
||||||
|
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
description: Alter SQL function to type VOLATILE (error)
|
||||||
|
url: /v1/query
|
||||||
|
status: 400
|
||||||
|
reponse:
|
||||||
|
path: "$.args"
|
||||||
|
error: type of function "search_posts" is altered to "VOLATILE" which is not supported
|
||||||
|
now
|
||||||
|
code: not-supported
|
||||||
|
query:
|
||||||
|
type: run_sql
|
||||||
|
args:
|
||||||
|
sql: |
|
||||||
|
create or replace function search_posts(search text)
|
||||||
|
returns setof post as $$
|
||||||
|
insert into post (title, content) values (search, search)
|
||||||
|
returning *
|
||||||
|
$$ language sql volatile;
|
@ -339,6 +339,9 @@ class TestGraphQLQueryFunctions(DefaultTestSelectQueries):
|
|||||||
def test_search_posts_aggregate(self, hge_ctx):
|
def test_search_posts_aggregate(self, hge_ctx):
|
||||||
check_query_f(hge_ctx, self.dir() + "/query_search_posts_aggregate.yaml")
|
check_query_f(hge_ctx, self.dir() + "/query_search_posts_aggregate.yaml")
|
||||||
|
|
||||||
|
def test_alter_function_error(self, hge_ctx):
|
||||||
|
check_query_f(hge_ctx, self.dir() + '/alter_function_error.yaml')
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def dir(cls):
|
def dir(cls):
|
||||||
return 'queries/graphql_query/functions'
|
return 'queries/graphql_query/functions'
|
||||||
|
Loading…
Reference in New Issue
Block a user