public boolean catalogAlreadyExists(Connection conn) {
    boolean result = false;
    try {
      List<String> constants = TUtil.newList();
      constants.add(CatalogConstants.TB_META);
      constants.add(CatalogConstants.TB_SPACES);
      constants.add(CatalogConstants.TB_DATABASES);
      constants.add(CatalogConstants.TB_TABLES);
      constants.add(CatalogConstants.TB_COLUMNS);
      constants.add(CatalogConstants.TB_OPTIONS);
      constants.add(CatalogConstants.TB_INDEXES);
      constants.add(CatalogConstants.TB_STATISTICS);
      constants.add(CatalogConstants.TB_PARTITION_METHODS);
      constants.add(CatalogConstants.TB_PARTTIONS);
      constants.add(CatalogConstants.TB_PARTTION_KEYS);

      for (String constant : constants) {
        if (checkExistence(conn, DatabaseObjectType.TABLE, constant)) {
          return true;
        }
      }

    } catch (SQLException e) {
      throw new TajoInternalError(e);
    }
    return result;
  }
  public void upgradeBaseSchema(Connection conn, int currentVersion) {
    if (!isLoaded()) {
      throw new TajoInternalError("Database schema files are not loaded.");
    }

    final List<SchemaPatch> candidatePatches = new ArrayList<>();
    Statement stmt;

    for (SchemaPatch patch : this.catalogStore.getPatches()) {
      if (currentVersion >= patch.getPriorVersion()) {
        candidatePatches.add(patch);
      }
    }

    Collections.sort(candidatePatches);
    try {
      stmt = conn.createStatement();
    } catch (SQLException e) {
      throw new TajoInternalError(e);
    }

    for (SchemaPatch patch : candidatePatches) {
      for (DatabaseObject object : patch.getObjects()) {
        try {
          stmt.executeUpdate(object.getSql());
          LOG.info(object.getName() + " " + object.getType() + " was created or altered.");
        } catch (SQLException e) {
          throw new TajoInternalError(e);
        }
      }
    }

    CatalogUtil.closeQuietly(stmt);
  }
    protected List<DatabaseObject> mergeDatabaseObjects(List<DatabaseObject> objects) {
      int maxIdx = -1;

      for (DatabaseObject object : objects) {
        maxIdx = Math.max(maxIdx, object.getOrder());
      }

      final List<DatabaseObject> orderedObjects = createListAndFillNull(maxIdx);
      final List<DatabaseObject> unorderedObjects = new ArrayList<>();
      final List<DatabaseObject> mergedObjects = new ArrayList<>();

      for (DatabaseObject object : objects) {
        if (object.getOrder() > -1) {
          int objIdx = object.getOrder();

          if (objIdx < orderedObjects.size() && orderedObjects.get(objIdx) != null) {
            throw new TajoInternalError(
                "This catalog configuration contains duplicated order of DatabaseObject");
          }

          orderedObjects.add(objIdx, object);
        } else {
          unorderedObjects.add(object);
        }
      }

      for (DatabaseObject object : orderedObjects) {
        if (object != null) {
          mergedObjects.add(object);
        }
      }

      for (DatabaseObject object : unorderedObjects) {
        if (object != null) {
          mergedObjects.add(object);
        }
      }

      return mergedObjects;
    }
  protected String[] listFileResources(URL dirURL, String schemaPath, FilenameFilter filter)
      throws URISyntaxException, IOException {
    String[] files;
    String[] tempFiles;
    List<String> filesList = new ArrayList<>();
    File dirFile = new File(dirURL.toURI());

    tempFiles = dirFile.list(filter);
    files = new String[tempFiles.length];

    for (String fileName : tempFiles) {
      filesList.add(schemaPath + "/" + fileName);
    }

    files = filesList.toArray(files);
    return files;
  }
  public void dropBaseSchema(Connection conn) {
    if (!isLoaded()) {
      throw new TajoInternalError("Schema files are not loaded yet.");
    }

    List<DatabaseObject> failedObjects = new ArrayList<>();
    Statement stmt = null;

    try {
      stmt = conn.createStatement();
    } catch (SQLException e) {
      throw new TajoInternalError(e);
    }

    for (DatabaseObject object : catalogStore.getSchema().getObjects()) {
      try {
        if (DatabaseObjectType.TABLE == object.getType()
            || DatabaseObjectType.SEQUENCE == object.getType()
            || DatabaseObjectType.VIEW == object.getType()) {
          stmt.executeUpdate(getDropSQL(object.getType(), object.getName()));
        }
      } catch (SQLException e) {
        failedObjects.add(object);
      }
    }
    CatalogUtil.closeQuietly(stmt);

    if (failedObjects.size() > 0) {
      StringBuffer errorMessage = new StringBuffer(64);
      errorMessage.append("Failed to drop database objects ");

      for (int idx = 0; idx < failedObjects.size(); idx++) {
        DatabaseObject object = failedObjects.get(idx);
        errorMessage.append(object.getType().toString()).append(" ").append(object.getName());
        if ((idx + 1) < failedObjects.size()) {
          errorMessage.append(',');
        }
      }

      LOG.warn(errorMessage.toString());
    }
  }
  protected void loadFromXmlFile(
      XMLInputFactory xmlIf, URL filePath, List<StoreObject> storeObjects)
      throws IOException, XMLStreamException {
    XMLStreamReader xmlReader;

    xmlReader = xmlIf.createXMLStreamReader(filePath.openStream());

    try {
      while (xmlReader.hasNext()) {
        if (xmlReader.next() == XMLStreamConstants.START_ELEMENT
            && "store".equals(xmlReader.getLocalName())) {
          StoreObject catalogStore = loadCatalogStore(xmlReader);
          if (catalogStore != null) {
            storeObjects.add(catalogStore);
          }
        }
      }
    } finally {
      try {
        xmlReader.close();
      } catch (XMLStreamException ignored) {
      }
    }
  }