mirror of
https://github.com/zhigang1992/graphql-engine.git
synced 2026-05-24 08:54:11 +08:00
update custom column names on renaming/dropping columns (#2933)
This commit is contained in:
committed by
Shahidh K Muhammed
parent
44da458c81
commit
55a788594b
@@ -6,6 +6,7 @@ module Hasura.RQL.DDL.Schema.Catalog
|
||||
, updateTableIsEnumInCatalog
|
||||
, updateTableConfig
|
||||
, deleteTableFromCatalog
|
||||
, getTableConfig
|
||||
) where
|
||||
|
||||
import Hasura.Prelude
|
||||
@@ -56,3 +57,11 @@ deleteTableFromCatalog (QualifiedObject sn tn) = liftTx $ Q.unitQE defaultTxErro
|
||||
DELETE FROM "hdb_catalog"."hdb_table"
|
||||
WHERE table_schema = $1 AND table_name = $2
|
||||
|] (sn, tn) False
|
||||
|
||||
getTableConfig :: MonadTx m => QualifiedTable -> m TableConfig
|
||||
getTableConfig (QualifiedObject sn tn) = liftTx $
|
||||
Q.getAltJ . runIdentity . Q.getRow <$> Q.withQE defaultTxErrorHandler
|
||||
[Q.sql|
|
||||
SELECT configuration::json FROM hdb_catalog.hdb_table
|
||||
WHERE table_schema = $1 AND table_name = $2
|
||||
|] (sn, tn) True
|
||||
|
||||
@@ -16,6 +16,7 @@ import qualified Hasura.RQL.DDL.EventTrigger as DS
|
||||
import Hasura.RQL.DDL.Permission
|
||||
import Hasura.RQL.DDL.Permission.Internal
|
||||
import Hasura.RQL.DDL.Relationship.Types
|
||||
import Hasura.RQL.DDL.Schema.Catalog
|
||||
import Hasura.RQL.Types
|
||||
import Hasura.SQL.Types
|
||||
|
||||
@@ -97,6 +98,8 @@ renameColInCatalog oCol nCol qt ti = do
|
||||
SOTableObj _ (TOTrigger triggerName) ->
|
||||
updateColInEventTriggerDef triggerName $ RenameItem qt oCol nCol
|
||||
d -> otherDeps errMsg d
|
||||
-- Update custom column names
|
||||
possiblyUpdateCustomColumnNames qt oCol nCol
|
||||
where
|
||||
errMsg = "cannot rename column " <> oCol <<> " to " <>> nCol
|
||||
assertFldNotExists =
|
||||
@@ -414,6 +417,16 @@ updateColMap fromQT toQT rnCol colMap =
|
||||
RenameItem qt oCol nCol = rnCol
|
||||
modCol colQt col = if colQt == qt && col == oCol then nCol else col
|
||||
|
||||
possiblyUpdateCustomColumnNames
|
||||
:: MonadTx m => QualifiedTable -> PGCol -> PGCol -> m ()
|
||||
possiblyUpdateCustomColumnNames qt oCol nCol = do
|
||||
TableConfig customRootFields customColumns <- getTableConfig qt
|
||||
let updatedCustomColumns =
|
||||
M.fromList $ flip map (M.toList customColumns) $
|
||||
\(dbCol, val) -> (, val) $ if dbCol == oCol then nCol else dbCol
|
||||
when (updatedCustomColumns /= customColumns) $
|
||||
updateTableConfig qt $ TableConfig customRootFields updatedCustomColumns
|
||||
|
||||
-- database functions for relationships
|
||||
getRelDef :: QualifiedTable -> RelName -> Q.TxE QErr Value
|
||||
getRelDef (QualifiedObject sn tn) rn =
|
||||
|
||||
@@ -190,9 +190,8 @@ runSetTableCustomFieldsQV2
|
||||
=> SetTableCustomFields -> m EncJSON
|
||||
runSetTableCustomFieldsQV2 (SetTableCustomFields tableName rootFields columnNames) = do
|
||||
adminOnly
|
||||
tableInfo <- askTabInfo tableName
|
||||
void $ askTabInfo tableName
|
||||
let tableConfig = TableConfig rootFields columnNames
|
||||
validateTableConfig tableInfo tableConfig
|
||||
updateTableConfig tableName tableConfig
|
||||
buildSchemaCacheFor (MOTable tableName)
|
||||
return successMsg
|
||||
@@ -249,30 +248,31 @@ processTableChanges ti tableDiff = do
|
||||
-- process dropped/added columns, because schema reload happens eventually
|
||||
sc <- askSchemaCache
|
||||
let tn = _tiName ti
|
||||
withOldTabName = do
|
||||
withOldTabName ccn = do
|
||||
replaceConstraints tn
|
||||
-- replace description
|
||||
replaceDescription tn
|
||||
-- for all the dropped columns
|
||||
procDroppedCols tn
|
||||
procAddedCols tn
|
||||
procAlteredCols sc tn
|
||||
procAddedCols ccn tn
|
||||
procAlteredCols sc ccn tn
|
||||
|
||||
withNewTabName newTN = do
|
||||
withNewTabName ccn newTN = do
|
||||
let tnGQL = GS.qualObjectToName newTN
|
||||
defGCtx = scDefaultRemoteGCtx sc
|
||||
-- check for GraphQL schema conflicts on new name
|
||||
GS.checkConflictingNode defGCtx tnGQL
|
||||
void $ procAlteredCols sc tn
|
||||
void $ procAlteredCols sc ccn tn
|
||||
-- update new table in catalog
|
||||
renameTableInCatalog newTN tn
|
||||
return True
|
||||
|
||||
maybe withOldTabName withNewTabName mNewName
|
||||
-- Drop custom column names for dropped columns
|
||||
customColumnNames <- possiblyDropCustomColumnNames tn
|
||||
maybe (withOldTabName customColumnNames) (withNewTabName customColumnNames) mNewName
|
||||
|
||||
where
|
||||
TableDiff mNewName droppedCols addedCols alteredCols _ constraints descM = tableDiff
|
||||
customFields = _tcCustomColumnNames $ _tiCustomConfig ti
|
||||
replaceConstraints tn = flip modTableInCache tn $ \tInfo ->
|
||||
return $ tInfo {_tiUniqOrPrimConstraints = constraints}
|
||||
|
||||
@@ -284,7 +284,20 @@ processTableChanges ti tableDiff = do
|
||||
-- Drop the column from the cache
|
||||
delColFromCache droppedCol tn
|
||||
|
||||
procAddedCols tn =
|
||||
possiblyDropCustomColumnNames tn = do
|
||||
let TableConfig customFields customColumnNames = _tiCustomConfig ti
|
||||
modifiedCustomColumnNames = foldl' (flip M.delete) customColumnNames droppedCols
|
||||
if modifiedCustomColumnNames == customColumnNames then
|
||||
pure customColumnNames
|
||||
else do
|
||||
let updatedTableConfig =
|
||||
TableConfig customFields modifiedCustomColumnNames
|
||||
flip modTableInCache tn $ \tInfo ->
|
||||
pure $ tInfo{_tiCustomConfig = updatedTableConfig}
|
||||
liftTx $ updateTableConfig tn updatedTableConfig
|
||||
pure modifiedCustomColumnNames
|
||||
|
||||
procAddedCols customColumnNames tn =
|
||||
-- In the newly added columns check that there is no conflict with relationships
|
||||
forM_ addedCols $ \rawInfo -> do
|
||||
let colName = prciName rawInfo
|
||||
@@ -294,14 +307,14 @@ processTableChanges ti tableDiff = do
|
||||
<<> " in table " <> tn <<>
|
||||
" as a relationship with the name already exists"
|
||||
_ -> do
|
||||
info <- processColumnInfoUsingCache tn customFields rawInfo
|
||||
info <- processColumnInfoUsingCache tn customColumnNames rawInfo
|
||||
addColToCache colName info tn
|
||||
|
||||
procAlteredCols sc tn = fmap or $ forM alteredCols $
|
||||
procAlteredCols sc customColumnNames tn = fmap or $ forM alteredCols $
|
||||
\( PGRawColumnInfo oldName oldType _ _ _
|
||||
, newRawInfo@(PGRawColumnInfo newName newType _ _ _) ) -> do
|
||||
let performColumnUpdate = do
|
||||
newInfo <- processColumnInfoUsingCache tn customFields newRawInfo
|
||||
newInfo <- processColumnInfoUsingCache tn customColumnNames newRawInfo
|
||||
updColInCache newName newInfo tn
|
||||
|
||||
if | oldName /= newName -> renameColInCatalog oldName newName tn ti $> True
|
||||
@@ -404,6 +417,7 @@ buildTableCache = processTableCache <=< buildRawTableCache
|
||||
where
|
||||
enumTables = M.mapMaybe _tiEnumValues rawTables
|
||||
|
||||
|
||||
-- | “Processes” a 'PGRawColumnInfo' into a 'PGColumnInfo' by resolving its type using a map of known
|
||||
-- enum tables.
|
||||
processColumnInfo
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
- description: Set custom column names
|
||||
url: /v1/query
|
||||
status: 200
|
||||
response:
|
||||
message: success
|
||||
query:
|
||||
type: set_table_custom_fields
|
||||
version: 2
|
||||
args:
|
||||
table: author
|
||||
custom_root_fields:
|
||||
select: Authors
|
||||
custom_column_names:
|
||||
id: AuthorId
|
||||
name: AuthorName
|
||||
|
||||
- description: "Rename column 'id' and drop column 'name'"
|
||||
url: /v1/query
|
||||
status: 200
|
||||
response:
|
||||
result_type: CommandOk
|
||||
result: null
|
||||
query:
|
||||
type: run_sql
|
||||
args:
|
||||
sql: |
|
||||
ALTER TABLE author DROP COLUMN name;
|
||||
ALTER TABLE author RENAME COLUMN id to author_id;
|
||||
|
||||
- description: Test if custom column names are updated
|
||||
url: /v1/graphql
|
||||
status: 200
|
||||
response:
|
||||
data:
|
||||
Authors:
|
||||
- AuthorId: 1
|
||||
age: 23
|
||||
- AuthorId: 2
|
||||
age: null
|
||||
query:
|
||||
query: |
|
||||
query {
|
||||
Authors{
|
||||
AuthorId
|
||||
age
|
||||
}
|
||||
}
|
||||
@@ -646,3 +646,6 @@ class TestSetTableCustomFields(DefaultTestQueries):
|
||||
|
||||
def test_set_invalid_table(self, hge_ctx):
|
||||
check_query_f(hge_ctx, self.dir() + '/set_invalid_table.yaml')
|
||||
|
||||
def test_alter_column(self, hge_ctx):
|
||||
check_query_f(hge_ctx, self.dir() + '/alter_column.yaml')
|
||||
|
||||
Reference in New Issue
Block a user