ATLAS-1636: fix incorrect reverseAttribute for hive_column.table
diff --git a/addons/models/patches/003-hive_column_update_table_remove_constraint.json b/addons/models/patches/003-hive_column_update_table_remove_constraint.json
new file mode 100644
index 0000000..db80722
--- /dev/null
+++ b/addons/models/patches/003-hive_column_update_table_remove_constraint.json
@@ -0,0 +1,21 @@
+{
+  "patches": [
+    {
+      "action": "UPDATE_ATTRIBUTE",
+      "typeName": "hive_column",
+      "applyToVersion": "1.2",
+      "updateToVersion": "1.3",
+      "params": null,
+      "attributeDefs": [
+        {
+          "name": "table",
+          "typeName": "hive_table",
+          "cardinality": "SINGLE",
+          "isIndexable": false,
+          "isOptional": true,
+          "isUnique": false
+        }
+      ]
+    }
+  ]
+}
diff --git a/repository/src/main/java/org/apache/atlas/repository/store/bootstrap/AtlasTypeDefStoreInitializer.java b/repository/src/main/java/org/apache/atlas/repository/store/bootstrap/AtlasTypeDefStoreInitializer.java
index fa4a480..51e4b45 100644
--- a/repository/src/main/java/org/apache/atlas/repository/store/bootstrap/AtlasTypeDefStoreInitializer.java
+++ b/repository/src/main/java/org/apache/atlas/repository/store/bootstrap/AtlasTypeDefStoreInitializer.java
@@ -160,6 +160,7 @@
         PatchHandler[] patchHandlers = new PatchHandler[] {
                 new AddAttributePatchHandler(typeDefStore, typeRegistry),
                 new UpdateTypeDefOptionsPatchHandler(typeDefStore, typeRegistry),
+                new UpdateAttributePatchHandler(typeDefStore, typeRegistry)
         };
 
         Map<String, PatchHandler> patchHandlerRegistry = new HashMap<>();
@@ -381,6 +382,69 @@
         }
     }
 
+    class UpdateAttributePatchHandler extends PatchHandler {
+        public UpdateAttributePatchHandler(AtlasTypeDefStore typeDefStore, AtlasTypeRegistry typeRegistry) {
+            super(typeDefStore, typeRegistry, new String[] { "UPDATE_ATTRIBUTE" });
+        }
+
+        @Override
+        public void applyPatch(TypeDefPatch patch) throws AtlasBaseException {
+            String           typeName = patch.getTypeName();
+            AtlasBaseTypeDef typeDef  = typeRegistry.getTypeDefByName(typeName);
+
+            if (typeDef == null) {
+                throw new AtlasBaseException(AtlasErrorCode.PATCH_FOR_UNKNOWN_TYPE, patch.getAction(), typeName);
+            }
+
+            if (isPatchApplicable(patch, typeDef)) {
+                if (typeDef.getClass().equals(AtlasEntityDef.class)) {
+                    AtlasEntityDef updatedDef = new AtlasEntityDef((AtlasEntityDef)typeDef);
+
+                    addOrUpdateAttributes(updatedDef, patch.getAttributeDefs());
+
+                    updatedDef.setTypeVersion(patch.getUpdateToVersion());
+
+                    typeDefStore.updateEntityDefByName(typeName, updatedDef);
+                } else if (typeDef.getClass().equals(AtlasClassificationDef.class)) {
+                    AtlasClassificationDef updatedDef = new AtlasClassificationDef((AtlasClassificationDef)typeDef);
+
+                    addOrUpdateAttributes(updatedDef, patch.getAttributeDefs());
+
+                    updatedDef.setTypeVersion(patch.getUpdateToVersion());
+
+                    typeDefStore.updateClassificationDefByName(typeName, updatedDef);
+                } else if (typeDef.getClass().equals(AtlasStructDef.class)) {
+                    AtlasStructDef updatedDef = new AtlasStructDef((AtlasStructDef)typeDef);
+
+                    addOrUpdateAttributes(updatedDef, patch.getAttributeDefs());
+
+                    updatedDef.setTypeVersion(patch.getUpdateToVersion());
+
+                    typeDefStore.updateStructDefByName(typeName, updatedDef);
+
+                } else {
+                    throw new AtlasBaseException(AtlasErrorCode.PATCH_NOT_APPLICABLE_FOR_TYPE,
+                                                 patch.getAction(), typeDef.getClass().getSimpleName());
+                }
+            } else {
+                LOG.info("patch skipped: typeName={}; applyToVersion={}; updateToVersion={}",
+                          patch.getTypeName(), patch.getApplyToVersion(), patch.getUpdateToVersion());
+            }
+        }
+
+        private void addOrUpdateAttributes(AtlasStructDef structDef, List<AtlasAttributeDef> attributesToUpdate) {
+            for (AtlasAttributeDef attributeToUpdate : attributesToUpdate) {
+                String attrName = attributeToUpdate.getName();
+
+                if (structDef.hasAttribute(attrName)) {
+                    structDef.removeAttribute(attrName);
+                }
+
+                structDef.addAttribute(attributeToUpdate);
+            }
+        }
+    }
+
     class UpdateTypeDefOptionsPatchHandler extends PatchHandler {
         public UpdateTypeDefOptionsPatchHandler(AtlasTypeDefStore typeDefStore, AtlasTypeRegistry typeRegistry) {
             super(typeDefStore, typeRegistry, new String[] { "UPDATE_TYPEDEF_OPTIONS" });