Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

do not allow overloading already tracked functions #1563

Merged
merged 8 commits into from
Feb 14, 2019
11 changes: 11 additions & 0 deletions server/src-lib/Hasura/RQL/DDL/Schema/Diff.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ module Hasura.RQL.DDL.Schema.Diff
, fetchFunctionMeta
, FunctionDiff(..)
, getFuncDiff
, getOverloadedFuncs
) where

import Hasura.Prelude
import Hasura.RQL.Types
import Hasura.Server.Utils (duplicates)
import Hasura.SQL.Types

import qualified Database.PG.Query as Q
Expand Down Expand Up @@ -257,6 +259,7 @@ fetchFunctionMeta = do
)
WHERE
f.function_schema <> 'hdb_catalog'
GROUP BY p.oid, f.function_schema, f.function_name, f.function_type
|] () False

data FunctionDiff
Expand All @@ -275,3 +278,11 @@ getFuncDiff oldMeta newMeta =
let isTypeAltered = fmType oldfm /= fmType newfm
alteredFunc = (funcFromMeta oldfm, fmType newfm)
in bool Nothing (Just alteredFunc) isTypeAltered

getOverloadedFuncs
:: [QualifiedFunction] -> [FunctionMeta] -> [QualifiedFunction]
getOverloadedFuncs trackedFuncs newFuncMeta =
duplicates $ map funcFromMeta trackedMeta
where
trackedMeta = flip filter newFuncMeta $ \fm ->
funcFromMeta fm `elem` trackedFuncs
10 changes: 9 additions & 1 deletion server/src-lib/Hasura/RQL/DDL/Schema/Table.hs
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,12 @@ execWithMDCheck (RunSQL t cascade _) = do
existingFuncs = M.keys $ scFunctions sc
oldFuncMeta = flip filter oldFuncMetaU $ \fm -> funcFromMeta fm `elem` existingFuncs
FunctionDiff droppedFuncs alteredFuncs = getFuncDiff oldFuncMeta newFuncMeta
overloadedFuncs = getOverloadedFuncs existingFuncs newFuncMeta

-- Do not allow overloading functions
unless (null overloadedFuncs) $
throw400 NotSupported $ "the following tracked function(s) cannot be overloaded: "
<> reportFuncs overloadedFuncs

indirectDeps <- getSchemaChangeDeps schemaDiff

Expand Down Expand Up @@ -490,12 +496,14 @@ execWithMDCheck (RunSQL t cascade _) = do
refreshGCtxMapInSchema

return res
where
reportFuncs = T.intercalate ", " . map dquoteTxt

isAltrDropReplace :: QErrM m => T.Text -> m Bool
isAltrDropReplace = either throwErr return . matchRegex regex False
where
throwErr s = throw500 $ "compiling regex failed: " <> T.pack s
regex = "alter|drop|replace"
regex = "alter|drop|replace|create function"

runRunSQL
:: (QErrM m, UserInfoM m, CacheRWM m, MonadTx m, MonadIO m, HasHttpManager m)
Expand Down
6 changes: 3 additions & 3 deletions server/src-lib/Hasura/SQL/Types.hs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ instance ToSQL ConstraintName where

newtype FunctionName
= FunctionName { getFunctionTxt :: T.Text }
deriving (Show, Eq, FromJSON, ToJSON, Q.ToPrepArg, Q.FromCol, Hashable, Lift)
deriving (Show, Eq, Ord, FromJSON, ToJSON, Q.ToPrepArg, Q.FromCol, Hashable, Lift)

instance IsIden FunctionName where
toIden (FunctionName t) = Iden t
Expand All @@ -159,7 +159,7 @@ instance ToTxt FunctionName where

newtype SchemaName
= SchemaName { getSchemaTxt :: T.Text }
deriving (Show, Eq, FromJSON, ToJSON, Hashable, Q.ToPrepArg, Q.FromCol, Lift)
deriving (Show, Eq, Ord, FromJSON, ToJSON, Hashable, Q.ToPrepArg, Q.FromCol, Lift)

publicSchema :: SchemaName
publicSchema = SchemaName "public"
Expand All @@ -174,7 +174,7 @@ data QualifiedObject a
= QualifiedObject
{ qSchema :: !SchemaName
, qName :: !a
} deriving (Show, Eq, Generic, Lift)
} deriving (Show, Eq, Ord, Generic, Lift)

instance (FromJSON a) => FromJSON (QualifiedObject a) where
parseJSON v@(String _) =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
description: Create a new SQL function with same name (error)
url: /v1/query
status: 400
response:
path: "$.args"
error: 'the following tracked function(s) cannot be overloaded: search_posts'
code: not-supported
query:
type: run_sql
args:
sql: |
create function search_posts(search text, id integer)
returns setof post as $$
select *
from post
where
title ilike ('%' || search || '%') or
content ilike ('%' || search || '%') or
id = id
$$ language sql stable;
3 changes: 3 additions & 0 deletions server/tests-py/test_graphql_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,9 @@ def test_search_posts_aggregate(self, hge_ctx):
def test_alter_function_error(self, hge_ctx):
check_query_f(hge_ctx, self.dir() + '/alter_function_error.yaml')

def test_overloading_function_error(self, hge_ctx):
check_query_f(hge_ctx, self.dir() + '/overloading_function_error.yaml')

@classmethod
def dir(cls):
return 'queries/graphql_query/functions'