mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-11-10 10:29:12 +03:00
https://github.com/hasura/graphql-engine/pull/5826
This commit is contained in:
parent
4062cdcbea
commit
af32ccff36
@ -58,6 +58,8 @@ This release contains the [PDV refactor (#4111)](https://github.com/hasura/graph
|
||||
- server: change `created_at` column type from `timestamp` to `timestamptz` for scheduled triggers tables (fix #5722)
|
||||
- server: allow configuring timeouts for actions (fixes #4966)
|
||||
- server: accept only non-negative integers for batch size and refetch interval (close #5653) (#5759)
|
||||
- server: limit the length of event trigger names (close #5786)
|
||||
**NOTE:** If you have event triggers with names greater than 42 chars, then you should update their names to avoid running into Postgres identifier limit bug (#5786)
|
||||
- console: allow user to cascade Postgres dependencies when dropping Postgres objects (close #5109) (#5248)
|
||||
- console: mark inconsistent remote schemas in the UI (close #5093) (#5181)
|
||||
- console: remove ONLY as default for ALTER TABLE in column alter operations (close #5512) #5706
|
||||
|
@ -198,6 +198,7 @@ const Add: React.FC<Props> = props => {
|
||||
className={`${styles.tableNameInput} form-control`}
|
||||
value={name}
|
||||
onChange={handleTriggerNameChange}
|
||||
maxLength={42}
|
||||
/>
|
||||
<hr />
|
||||
<h4 className={styles.subheading_text}>
|
||||
|
@ -9,7 +9,8 @@ export const manualTriggerInfo = (
|
||||
|
||||
export const triggerNameDescription = (
|
||||
<Tooltip id="tooltip-trigger-name-description">
|
||||
Trigger name can be alphanumeric and can contain underscores and hyphens
|
||||
Trigger name can be alphanumeric, can contain underscores and hyphens, and
|
||||
must be at most 42 characters.
|
||||
</Tooltip>
|
||||
);
|
||||
|
||||
|
@ -514,7 +514,7 @@ processScheduledEvent logEnv pgpool se@ScheduledEventFull {..} type' = Tracing.r
|
||||
(processSuccess pgpool se decodedHeaders type' webhookReqBodyJson)
|
||||
res
|
||||
where
|
||||
traceNote = "Scheduled trigger" <> foldMap ((": " <>) . unNonEmptyText . unTriggerName) sefName
|
||||
traceNote = "Scheduled trigger" <> foldMap ((": " <>) . triggerNameToTxt) sefName
|
||||
|
||||
processError
|
||||
:: (MonadIO m, MonadError QErr m)
|
||||
|
@ -39,6 +39,8 @@ import qualified Text.Shakespeare.Text as ST
|
||||
|
||||
data OpVar = OLD | NEW deriving (Show)
|
||||
|
||||
-- pgIdenTrigger is a method used to construct the name of the pg function
|
||||
-- used for event triggers which are present in the hdb_views schema.
|
||||
pgIdenTrigger:: Ops -> TriggerName -> T.Text
|
||||
pgIdenTrigger op trn = pgFmtIden . qualifyTriggerName op $ triggerNameToTxt trn
|
||||
where
|
||||
|
@ -30,7 +30,7 @@ import Data.Aeson.TH
|
||||
import Hasura.Incremental (Cacheable)
|
||||
import Hasura.Prelude
|
||||
import Hasura.RQL.DDL.Headers
|
||||
import Hasura.RQL.Types.Common (NonEmptyText (..), InputWebhook)
|
||||
import Hasura.RQL.Types.Common (NonEmptyText(..), InputWebhook)
|
||||
import Hasura.SQL.Types
|
||||
import Language.Haskell.TH.Syntax (Lift)
|
||||
|
||||
@ -39,9 +39,17 @@ import qualified Data.Text as T
|
||||
import qualified Database.PG.Query as Q
|
||||
import qualified Text.Regex.TDFA as TDFA
|
||||
|
||||
-- This change helps us create functions for the event triggers
|
||||
-- without the function name being truncated by PG, since PG allows
|
||||
-- for only 63 chars for identifiers.
|
||||
-- Reasoning for the 42 characters:
|
||||
-- 63 - (notify_hasura_) - (_INSERT | _UPDATE | _DELETE)
|
||||
maxTriggerNameLength :: Int
|
||||
maxTriggerNameLength = 42
|
||||
|
||||
-- | Unique name for event trigger.
|
||||
newtype TriggerName = TriggerName { unTriggerName :: NonEmptyText }
|
||||
deriving (Show, Eq, Hashable, Lift, DQuote, FromJSON, ToJSON, ToJSONKey, Q.FromCol, Q.ToPrepArg, Generic, Arbitrary, NFData, Cacheable)
|
||||
deriving (Show, Eq, Hashable, Lift, DQuote, FromJSON, ToJSON, ToJSONKey, Q.ToPrepArg, Generic, NFData, Cacheable, Arbitrary, Q.FromCol)
|
||||
|
||||
triggerNameToTxt :: TriggerName -> Text
|
||||
triggerNameToTxt = unNonEmptyText . unTriggerName
|
||||
@ -116,7 +124,7 @@ instance ToJSON WebhookConf where
|
||||
instance FromJSON WebhookConf where
|
||||
parseJSON (Object o) = WCEnv <$> o .: "from_env"
|
||||
parseJSON t@(String _) =
|
||||
case (fromJSON t) of
|
||||
case fromJSON t of
|
||||
Error s -> fail s
|
||||
Success a -> pure $ WCValue a
|
||||
parseJSON _ = fail "one of string or object must be provided for webhook"
|
||||
@ -146,25 +154,25 @@ data CreateEventTriggerQuery
|
||||
|
||||
instance FromJSON CreateEventTriggerQuery where
|
||||
parseJSON (Object o) = do
|
||||
name <- o .: "name"
|
||||
table <- o .: "table"
|
||||
insert <- o .:? "insert"
|
||||
update <- o .:? "update"
|
||||
delete <- o .:? "delete"
|
||||
enableManual <- o .:? "enable_manual" .!= False
|
||||
retryConf <- o .:? "retry_conf"
|
||||
webhook <- o .:? "webhook"
|
||||
webhookFromEnv <- o .:? "webhook_from_env"
|
||||
headers <- o .:? "headers"
|
||||
replace <- o .:? "replace" .!= False
|
||||
name <- o .: "name"
|
||||
table <- o .: "table"
|
||||
insert <- o .:? "insert"
|
||||
update <- o .:? "update"
|
||||
delete <- o .:? "delete"
|
||||
enableManual <- o .:? "enable_manual" .!= False
|
||||
retryConf <- o .:? "retry_conf"
|
||||
webhook <- o .:? "webhook"
|
||||
webhookFromEnv <- o .:? "webhook_from_env"
|
||||
headers <- o .:? "headers"
|
||||
replace <- o .:? "replace" .!= False
|
||||
let regex = "^[A-Za-z]+[A-Za-z0-9_\\-]*$" :: LBS.ByteString
|
||||
compiledRegex = TDFA.makeRegex regex :: TDFA.Regex
|
||||
isMatch = TDFA.match compiledRegex . T.unpack $ triggerNameToTxt name
|
||||
if isMatch then return ()
|
||||
else fail "only alphanumeric and underscore and hyphens allowed for name"
|
||||
if any isJust [insert, update, delete] || enableManual then
|
||||
return ()
|
||||
else
|
||||
unless isMatch $
|
||||
fail "only alphanumeric and underscore and hyphens allowed for name"
|
||||
unless (T.length (triggerNameToTxt name) <= maxTriggerNameLength) $
|
||||
fail "event trigger name can be at most 42 characters"
|
||||
unless (any isJust [insert, update, delete] || enableManual) $
|
||||
fail "atleast one amongst insert/update/delete/enable_manual spec must be provided"
|
||||
case (webhook, webhookFromEnv) of
|
||||
(Just _, Nothing) -> return ()
|
||||
@ -195,10 +203,8 @@ instance NFData TriggerOpsDef
|
||||
instance Cacheable TriggerOpsDef
|
||||
$(deriveJSON (aesonDrop 2 snakeCase){omitNothingFields=True} ''TriggerOpsDef)
|
||||
|
||||
data DeleteEventTriggerQuery
|
||||
= DeleteEventTriggerQuery
|
||||
{ detqName :: !TriggerName
|
||||
} deriving (Show, Eq, Lift)
|
||||
newtype DeleteEventTriggerQuery = DeleteEventTriggerQuery { detqName :: TriggerName }
|
||||
deriving (Show, Eq, Lift)
|
||||
|
||||
$(deriveJSON (aesonDrop 4 snakeCase){omitNothingFields=True} ''DeleteEventTriggerQuery)
|
||||
|
||||
|
@ -65,7 +65,7 @@ execPGDump b ci = do
|
||||
-- delete front matter
|
||||
|| line `elem` preambleLines
|
||||
-- delete notify triggers
|
||||
|| notifyTriggerRegex `TDFA.match` line
|
||||
|| eventTriggerRegex `TDFA.match` line
|
||||
|
||||
preambleLines =
|
||||
[ "SET statement_timeout = 0;"
|
||||
@ -85,8 +85,10 @@ execPGDump b ci = do
|
||||
, "COMMENT ON SCHEMA public IS 'standard public schema';"
|
||||
]
|
||||
|
||||
notifyTriggerRegex =
|
||||
eventTriggerRegex =
|
||||
let regexStr :: String =
|
||||
-- pg functions created by hasura for event triggers used "notify_hasura"
|
||||
-- These changes are also documented on the method pgIdenTrigger
|
||||
"^CREATE TRIGGER \"?notify_hasura_.+\"? AFTER [[:alnum:]]+ "
|
||||
<> "ON .+ FOR EACH ROW EXECUTE (FUNCTION|PROCEDURE) "
|
||||
<> "\"?hdb_views\"?\\.\"?notify_hasura_.+\"?\\(\\);$"
|
||||
|
Loading…
Reference in New Issue
Block a user