mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-15 09:22:43 +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.Prelude
|
||||
import Hasura.RQL.DDL.Utils
|
||||
import Hasura.RQL.Types
|
||||
import Hasura.SQL.Types
|
||||
|
||||
|
@ -13,8 +13,10 @@ module Hasura.RQL.DDL.Schema.Diff
|
||||
, getSchemaChangeDeps
|
||||
|
||||
, FunctionMeta(..)
|
||||
, funcFromMeta
|
||||
, fetchFunctionMeta
|
||||
, getDroppedFuncs
|
||||
, FunctionDiff(..)
|
||||
, getFuncDiff
|
||||
) where
|
||||
|
||||
import Hasura.Prelude
|
||||
@ -226,25 +228,50 @@ getSchemaChangeDeps schemaDiff = do
|
||||
|
||||
data FunctionMeta
|
||||
= FunctionMeta
|
||||
{ fmOid :: !Int
|
||||
, fmFunction :: !QualifiedFunction
|
||||
{ fmOid :: !Int
|
||||
, fmSchema :: !SchemaName
|
||||
, fmName :: !FunctionName
|
||||
, fmType :: !FunctionType
|
||||
} deriving (Show, Eq)
|
||||
$(deriveJSON (aesonDrop 2 snakeCase) ''FunctionMeta)
|
||||
|
||||
funcFromMeta :: FunctionMeta -> QualifiedFunction
|
||||
funcFromMeta fm = QualifiedObject (fmSchema fm) (fmName fm)
|
||||
|
||||
fetchFunctionMeta :: Q.Tx [FunctionMeta]
|
||||
fetchFunctionMeta = do
|
||||
res <- Q.listQ [Q.sql|
|
||||
map (Q.getAltJ . runIdentity) <$> Q.listQ [Q.sql|
|
||||
SELECT
|
||||
f.function_schema,
|
||||
f.function_name,
|
||||
p.oid
|
||||
FROM hdb_catalog.hdb_function_agg f
|
||||
JOIN pg_catalog.pg_proc p ON (p.proname = f.function_name)
|
||||
json_build_object(
|
||||
'oid', p.oid :: integer,
|
||||
'schema', f.function_schema,
|
||||
'name', 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
|
||||
f.function_schema <> 'hdb_catalog'
|
||||
|] () False
|
||||
forM res $ \(sn, fn, foid) ->
|
||||
return $ FunctionMeta foid $ QualifiedObject sn fn
|
||||
f.function_schema <> 'hdb_catalog'
|
||||
|] () False
|
||||
|
||||
getDroppedFuncs :: [FunctionMeta] -> [FunctionMeta] -> [QualifiedFunction]
|
||||
getDroppedFuncs oldMeta newMeta =
|
||||
map fmFunction $ getDifference fmOid oldMeta newMeta
|
||||
data FunctionDiff
|
||||
= FunctionDiff
|
||||
{ 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
|
||||
schemaDiff = getSchemaDiff oldMeta newMeta
|
||||
existingFuncs = M.keys $ scFunctions sc
|
||||
oldFuncMeta = flip filter oldFuncMetaU $ \fm -> fmFunction fm `elem` existingFuncs
|
||||
droppedFuncs = getDroppedFuncs oldFuncMeta newFuncMeta
|
||||
oldFuncMeta = flip filter oldFuncMetaU $ \fm -> funcFromMeta fm `elem` existingFuncs
|
||||
FunctionDiff droppedFuncs alteredFuncs = getFuncDiff oldFuncMeta newFuncMeta
|
||||
|
||||
indirectDeps <- getSchemaChangeDeps schemaDiff
|
||||
|
||||
@ -461,6 +461,12 @@ execWithMDCheck (RunSQL t cascade _) = do
|
||||
liftTx $ delFunctionFromCatalog 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
|
||||
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):
|
||||
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
|
||||
def dir(cls):
|
||||
return 'queries/graphql_query/functions'
|
||||
|
Loading…
Reference in New Issue
Block a user