private List<SQLNotNullConstraint> addNotNullConstraints(List<SQLNotNullConstraint> nns, boolean retrieveCD)
          throws InvalidObjectException, MetaException {

    List<MConstraint> cstrs = new ArrayList<>();
    String constraintName;

    for (SQLNotNullConstraint nn : nns) {
      final String catName = normalizeIdentifier(nn.getCatName());
      final String tableDB = normalizeIdentifier(nn.getTable_db());
      final String tableName = normalizeIdentifier(nn.getTable_name());
      final String columnName = normalizeIdentifier(nn.getColumn_name());

      // If retrieveCD is false, we do not need to do a deep retrieval of the Table Column Descriptor.
      // For instance, this is the case when we are creating the table.
      AttachedMTableInfo nParentTable = getMTable(catName, tableDB, tableName, retrieveCD);
      MTable parentTable = nParentTable.mtbl;
      if (parentTable == null) {
        throw new InvalidObjectException("Parent table not found: " + tableName);
      }

      MColumnDescriptor parentCD = retrieveCD ? nParentTable.mcd : parentTable.getSd().getCD();
      int parentIntegerIndex = getColumnIndexFromTableColumns(parentCD == null ? null : parentCD.getCols(), columnName);
      if (parentIntegerIndex == -1) {
        if (parentTable.getPartitionKeys() != null) {
          parentCD = null;
          parentIntegerIndex = getColumnIndexFromTableColumns(parentTable.getPartitionKeys(), columnName);
        }
        if (parentIntegerIndex == -1) {
          throw new InvalidObjectException("Parent column not found: " + columnName);
        }
      }
      if (nn.getNn_name() == null) {
        constraintName = generateConstraintName(parentTable, tableDB, tableName, columnName, "nn");
      } else {
        constraintName = normalizeIdentifier(nn.getNn_name());
        if (constraintNameAlreadyExists(parentTable, constraintName)) {
          String fqConstraintName = String.format("%s.%s.%s", parentTable.getDatabase().getName(),
              parentTable.getTableName(), constraintName);
          throw new InvalidObjectException("Constraint name already exists: " + fqConstraintName);
        }
      }

      int enableValidateRely = (nn.isEnable_cstr() ? 4 : 0) +
          (nn.isValidate_cstr() ? 2 : 0) + (nn.isRely_cstr() ? 1 : 0);
      MConstraint muk = new MConstraint(
          constraintName,
          1,
          MConstraint.NOT_NULL_CONSTRAINT, // Not null constraint should reference a single column
          null,
          null,
          enableValidateRely,
          parentTable,
          null,
          parentCD,
          null,
          null,
          parentIntegerIndex);
      cstrs.add(muk);
      // Add normalized identifier back to result
      nn.setCatName(catName);
      nn.setTable_db(tableDB);
      nn.setTable_name(tableName);
      nn.setColumn_name(columnName);
      nn.setNn_name(constraintName);
    }
    pm.makePersistentAll(cstrs);
    return nns;
  }
Called right before an action that would drop a storage descriptor.
This function makes the SD's reference to a CD null, and then deletes the CD
if it no longer is referenced in the table.
@param msd the storage descriptor to drop
standalone-metastore/metastore-server/src/main/java/org/apache/hadoop/hive/metastore/ObjectStore.java