Skip to content

Commit

Permalink
update custom column names on renaming/dropping columns (#2933)
Browse files Browse the repository at this point in the history
  • Loading branch information
rakeshkky authored and shahidhk committed Oct 3, 2019
1 parent 44da458 commit 55a7885
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 13 deletions.
9 changes: 9 additions & 0 deletions server/src-lib/Hasura/RQL/DDL/Schema/Catalog.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ module Hasura.RQL.DDL.Schema.Catalog
, updateTableIsEnumInCatalog
, updateTableConfig
, deleteTableFromCatalog
, getTableConfig
) where

import Hasura.Prelude
Expand Down Expand Up @@ -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
13 changes: 13 additions & 0 deletions server/src-lib/Hasura/RQL/DDL/Schema/Rename.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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 =
Expand Down
40 changes: 27 additions & 13 deletions server/src-lib/Hasura/RQL/DDL/Schema/Table.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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}

Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
}
}
3 changes: 3 additions & 0 deletions server/tests-py/test_v1_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,3 +646,6 @@ def test_set_and_unset(self, hge_ctx):

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

0 comments on commit 55a7885

Please sign in to comment.