update custom column names on renaming/dropping columns (#2933)

This commit is contained in:
Rakesh Emmadi
2019-10-03 13:15:52 +05:30
committed by Shahidh K Muhammed
parent 44da458c81
commit 55a788594b
5 changed files with 99 additions and 13 deletions

View File

@@ -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

View File

@@ -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 =

View File

@@ -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

View File

@@ -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
}
}

View File

@@ -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')