Skip to content

File util_sa.c

File List > cubrid > src > executables > util_sa.c

Go to the documentation of this file

/*
 * Copyright 2008 Search Solution Corporation
 * Copyright 2016 CUBRID Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */

/*
 * util_sa.c - Implementation for utilities that operate in standalone mode.
 */

#ident "$Id$"

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <assert.h>
#if defined(WINDOWS)
#include <io.h>
#include <direct.h>
#endif

#include "porting.h"
#include "chartype.h"
#include "error_manager.h"
#include "message_catalog.h"
#include "databases_file.h"
#include "environment_variable.h"
#include "system_parameter.h"
#include "boot_sr.h"
#include "db.h"
#include "authenticate.h"
#include "schema_manager.h"
#include "heap_file.h"
#include "btree.h"
#include "extendible_hash.h"
#include "locator_sr.h"
#include "xserver_interface.h"
#include "utility.h"
#include "transform.h"
#include "csql.h"
#include "locator_cl.h"
#include "network_interface_cl.h"
#include "locale_support.h"
#include "tz_support.h"
#include "tz_compile.h"
#include "tsc_timer.h"
#if defined(WINDOWS)
#include "wintcp.h"
#else
#include <dlfcn.h>
#endif

#include "dbtype.h"
#include "thread_manager.hpp"
#include "log_volids.hpp"
#include "schema_system_catalog.hpp"
#include "catalog_class.h"

#if defined (SUPPRESS_STRLEN_WARNING)
#define strlen(s1)  ((int) strlen(s1))
#endif /* defined (SUPPRESS_STRLEN_WARNING) */

#define MAX_LINE_LEN            4096

#define COMMENT_CHAR            '-'
#define COMMAND_USER            "user"
#define COMMAND_GROUP           "group"
#define COMMAND_MEMBERS         "members"
#define COMMAND_GROUPS          "groups"

#if defined(WINDOWS)
typedef int pid_t;
#define strtok_r    strtok_s
#endif

#define BO_DB_FULLNAME          (bo_Dbfullname)

static char bo_Dbfullname[PATH_MAX];

extern int log_default_input_for_archive_log_location;

static int parse_user_define_line (char *line, FILE * output_file);
static int parse_user_define_file (FILE * user_define_file, FILE * output_file);
static int parse_up_to_date (char *up_to_date, struct tm *time_date);
static int print_backup_info (char *database_name, BO_RESTART_ARG * restart_arg);
static int synccoll_check (const char *db_name, int *db_obs_coll_cnt, int *new_sys_coll_cnt);
static int synccoll_check_tables (const LANG_COLL_COMPAT * db_coll, FILE * f_stmt, bool * need_manual_sync);
static int synccoll_check_foreign_keys (const LANG_COLL_COMPAT * db_coll, FILE * f_stmt, bool * need_manual_sync);
static int synccoll_check_attrs (const LANG_COLL_COMPAT * db_coll, FILE * f_stmt, bool * need_manual_sync);
static int synccoll_check_views (const LANG_COLL_COMPAT * db_coll, FILE * f_stmt, bool * need_manual_sync);
static int synccoll_check_triggers (const LANG_COLL_COMPAT * db_coll, FILE * f_stmt, bool * need_manual_sync);
static int synccoll_check_function_indexes (const LANG_COLL_COMPAT * db_coll, FILE * f_stmt, bool * need_manual_sync);

static int delete_all_ha_apply_info (void);
static int insert_ha_apply_info (char *database_name, char *master_host_name, INT64 database_creation, INT64 pageid,
                 int offset, INT64 committed_pageid, int committed_offset);
static int delete_all_slave_ha_apply_info (char *database_name, char *master_host_name);

static bool check_ha_db_and_node_list (char *database_name, char *source_host_name);


/*
 * util_admin_usage - display an usage of this utility
 *
 * return:
 *
 * NOTE:
 */
void
util_admin_usage (const char *argv0)
{
  const char *exec_name;

  exec_name = basename ((char *) argv0);
  fprintf (stderr, utility_get_generic_message (MSGCAT_UTIL_GENERIC_ADMIN_USAGE), PRODUCT_STRING, exec_name, exec_name,
       exec_name);
}

/*
 * util_admin_version - display a version of this utility
 *
 * return:
 *
 * NOTE:
 */
void
util_admin_version (const char *argv0)
{
  const char *exec_name;

  exec_name = basename ((char *) argv0);
  fprintf (stderr, utility_get_generic_message (MSGCAT_UTIL_GENERIC_VERSION), exec_name, PRODUCT_STRING);
}


/*
 * parse_user_define_line() - parse user information
 *   return: 0 if success
 *   line_buffer(in)
 *   output_file(in)
 */
static int
parse_user_define_line (char *line_buffer, FILE * output_file)
{
  const char *delim = " \t\n";
  char *save_ptr, *token;
  bool group_type;
  int exists;
  MOP database_object, user;

  /* A first word must be the "user" keyword. */
  token = strtok_r (line_buffer, delim, &save_ptr);
  if (token != NULL && strcasecmp (token, COMMAND_USER) == 0)
    {
      /* A second word must be an user's name. */
      token = strtok_r (NULL, delim, &save_ptr);
      if (token == NULL || (user = au_add_user (token, &exists)) == NULL)
    {
      fprintf (output_file,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CREATEDB, CREATEDB_MSG_MISSING_USER), token);
      return ER_GENERIC_ERROR;
    }

      token = strtok_r (NULL, delim, &save_ptr);

      if (token == NULL)
    {
      /* GROUPS or MEMBERS keyword could be omitted */
      return NO_ERROR;
    }
      else if (strcasecmp (token, COMMAND_GROUPS) == 0)
    {
      group_type = true;
    }
      else if (strcasecmp (token, COMMAND_MEMBERS) == 0)
    {
      group_type = false;
    }
      else
    {
      fprintf (output_file,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CREATEDB, CREATEDB_MSG_UNKNOWN_CMD), token);
      return ER_GENERIC_ERROR;
    }

      /* loop for the list of user's name */
      while ((token = strtok_r (NULL, delim, &save_ptr)) != NULL)
    {
      database_object = au_find_user (token);
      if (database_object == NULL)
        {
          /* could not found the user */
          fprintf (output_file,
               msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CREATEDB, CREATEDB_MSG_MISSING_USER),
               token);
          return ER_GENERIC_ERROR;
        }
      else
        {
          if (group_type)
        {
          au_add_member (database_object, user);
        }
          else
        {
          au_add_member (user, database_object);
        }
        }
    }
    }
  else
    {
      if (token != NULL)
    {
      fprintf (output_file,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CREATEDB, CREATEDB_MSG_UNKNOWN_CMD), token);
      return ER_GENERIC_ERROR;
    }
    }
  return NO_ERROR;
}

/*
 * parse_user_define_file() - read user information file and parse it
 *   return: 0 if success
 *   user_define_file(in)
 *   output_file(in)
 *
 * Note: user definition file format :
 *            USER  name GROUPS group1 group2 . . .
 *            USER  name MEMBERS user1 user2 . . .
 */
static int
parse_user_define_file (FILE * user_define_file, FILE * output_file)
{
  int status = NO_ERROR;
  int line_number = 1;
  char line_buffer[MAX_LINE_LEN];

  while (fgets (line_buffer, MAX_LINE_LEN, user_define_file) != NULL)
    {
      if (strlen (line_buffer) == 0 || line_buffer[0] == COMMENT_CHAR)
    {
      line_number++;
      continue;
    }
      status = parse_user_define_line (line_buffer, output_file);
      if (status != NO_ERROR)
    {
      fprintf (stderr, "parse error at line: %d\n", line_number);
      return status;
    }
      line_number++;
    }
  return status;
}

static void
make_valid_page_size (int *v)
{
  int pow_size;

  if (*v < IO_MIN_PAGE_SIZE)
    {
      *v = IO_MIN_PAGE_SIZE;
      return;
    }

  if (*v > IO_MAX_PAGE_SIZE)
    {
      *v = IO_MAX_PAGE_SIZE;
      return;
    }

  pow_size = IO_MIN_PAGE_SIZE;
  if ((*v & (*v - 1)) != 0)
    {
      while (pow_size < *v)
    {
      pow_size *= 2;
    }
      *v = pow_size;
    }
}

static int
execute_query (const char *str)
{
  DB_SESSION *session = NULL;
  STATEMENT_ID stmt_id;
  int error = NO_ERROR;

  session = db_open_buffer (str);
  if (session == NULL)
    {
      assert (er_errid () != NO_ERROR);
      error = er_errid ();
      goto exit;
    }

  stmt_id = db_compile_statement (session);
  if (stmt_id < 0)
    {
      assert (er_errid () != NO_ERROR);
      error = er_errid ();
      goto exit;
    }

  error = db_execute_statement_local (session, stmt_id, NULL);

exit:
  if (session != NULL)
    {
      db_close_session (session);
    }

  return error;
}

/*
 * createdb() - createdb main routine
 *   return: EXIT_SUCCESS/EXIT_FAILURE
 */
int
createdb (UTIL_FUNCTION_ARG * arg)
{
  UTIL_ARG_MAP *arg_map = arg->arg_map;
  char er_msg_file[PATH_MAX];
  int status;
  FILE *output_file = NULL;
  FILE *user_define_file = NULL;

  const char *output_file_name;
  const char *program_name;
  const char *database_name;
  const char *volume_path;
  const char *log_path;
  const char *lob_path;
  const char *host_name;
  bool overwrite;
  bool verbose;
  const char *comment;
  const char *init_file_name;
  const char *volume_spec_file_name;
  const char *user_define_file_name;
  const char *cubrid_charset;

  int db_volume_sect;
  int db_volume_pages;
  int db_page_size;
  UINT64 db_volume_size;
  int log_volume_pages;
  int log_page_size;
  UINT64 log_volume_size;
  char *db_volume_str;
  char *db_page_str;
  char *log_volume_str;
  char *log_page_str;
  const TZ_DATA *tzd;

  char required_size[16];
  char abs_lob_path[PATH_MAX];

  database_name = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 0);
  cubrid_charset = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 1);

  if (database_name == 0 || database_name[0] == 0 || cubrid_charset == 0 || cubrid_charset[0] == 0
      || utility_get_option_string_table_size (arg_map) != 2)
    {
      goto print_create_usage;
    }

  /* initialize time zone data */
  if (tz_load () != NO_ERROR)
    {
      goto error_exit;
    }

  if (sysprm_load_and_init (database_name, NULL, SYSPRM_LOAD_ALL) != NO_ERROR)
    {
      util_log_write_errid (MSGCAT_UTIL_GENERIC_SERVICE_PROPERTY_FAIL);
      goto error_exit;
    }

  output_file_name = utility_get_option_string_value (arg_map, CREATE_OUTPUT_FILE_S, 0);
  program_name = arg->command_name;
  volume_path = utility_get_option_string_value (arg_map, CREATE_FILE_PATH_S, 0);
  log_path = utility_get_option_string_value (arg_map, CREATE_LOG_PATH_S, 0);
  lob_path = utility_get_option_string_value (arg_map, CREATE_LOB_PATH_S, 0);
  host_name = utility_get_option_string_value (arg_map, CREATE_SERVER_NAME_S, 0);
  overwrite = utility_get_option_bool_value (arg_map, CREATE_REPLACE_S);
  verbose = utility_get_option_bool_value (arg_map, CREATE_VERBOSE_S);
  comment = utility_get_option_string_value (arg_map, CREATE_COMMENT_S, 0);
  init_file_name = utility_get_option_string_value (arg_map, CREATE_CSQL_INITIALIZATION_FILE_S, 0);
  volume_spec_file_name = utility_get_option_string_value (arg_map, CREATE_MORE_VOLUME_FILE_S, 0);
  user_define_file_name = utility_get_option_string_value (arg_map, CREATE_USER_DEFINITION_FILE_S, 0);

  db_page_size = utility_get_option_int_value (arg_map, CREATE_PAGE_SIZE_S);
  if (db_page_size != -1)
    {
      util_print_deprecated ("--" CREATE_PAGE_SIZE_L);
    }
  else
    {
      db_page_size = IO_PAGESIZE;
    }

  db_page_str = utility_get_option_string_value (arg_map, CREATE_DB_PAGE_SIZE_S, 0);
  if (db_page_str != NULL)
    {
      UINT64 v;

      if (util_size_string_to_byte (&v, db_page_str) != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG (msgcat_message
                 (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CREATEDB, CREATEDB_MSG_INVALID_SIZE),
                 CREATE_DB_PAGE_SIZE_L, db_page_str);
      goto error_exit;
    }
      db_page_size = (int) v;
    }
  make_valid_page_size (&db_page_size);

  db_volume_str = utility_get_option_string_value (arg_map, CREATE_DB_VOLUME_SIZE_S, 0);
  if (db_volume_str == NULL)
    {
      db_volume_size = prm_get_bigint_value (PRM_ID_DB_VOLUME_SIZE);
    }
  else
    {
      if (util_size_string_to_byte (&db_volume_size, db_volume_str) != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG (msgcat_message
                 (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CREATEDB, CREATEDB_MSG_INVALID_SIZE),
                 CREATE_DB_VOLUME_SIZE_L, db_volume_str);
      goto error_exit;
    }
    }

  db_volume_pages = utility_get_option_int_value (arg_map, CREATE_PAGES_S);
  if (db_volume_pages != -1)
    {
      util_print_deprecated ("--" CREATE_PAGES_L);
    }
  else
    {
      /* round up the number of pages */
      db_volume_pages = (int) ceil ((double) db_volume_size / db_page_size);
    }
  /* determine volume number of sectors */
  db_volume_sect = disk_sectors_to_extend_npages (db_volume_pages);
  /* adjust the number of pages according to the number of sectors */
  db_volume_pages = DISK_SECTOR_NPAGES * db_volume_sect;

  db_volume_size = (UINT64) db_volume_pages *(UINT64) db_page_size;

  log_page_str = utility_get_option_string_value (arg_map, CREATE_LOG_PAGE_SIZE_S, 0);
  if (log_page_str == NULL)
    {
      log_page_size = db_page_size;
    }
  else
    {
      UINT64 v;

      if (util_size_string_to_byte (&v, log_page_str) != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG (msgcat_message
                 (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CREATEDB, CREATEDB_MSG_INVALID_SIZE),
                 CREATE_LOG_PAGE_SIZE_L, log_page_str);
      goto error_exit;
    }
      log_page_size = (int) v;
    }
  make_valid_page_size (&log_page_size);

  log_volume_str = utility_get_option_string_value (arg_map, CREATE_LOG_VOLUME_SIZE_S, 0);
  if (log_volume_str == NULL)
    {
      log_volume_size = prm_get_bigint_value (PRM_ID_LOG_VOLUME_SIZE);
    }
  else
    {
      if (util_size_string_to_byte (&log_volume_size, log_volume_str) != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG (msgcat_message
                 (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CREATEDB, CREATEDB_MSG_INVALID_SIZE),
                 CREATE_LOG_VOLUME_SIZE_L, log_volume_str);
      goto error_exit;
    }
    }

  log_volume_pages = utility_get_option_int_value (arg_map, CREATE_LOG_PAGE_COUNT_S);
  if (log_volume_pages != -1)
    {
      util_print_deprecated ("--" CREATE_LOG_PAGE_COUNT_L);
    }
  else
    {
      log_volume_pages = (int) (log_volume_size / log_page_size);
    }

  if (check_new_database_name (database_name))
    {
      goto error_exit;
    }

  if (output_file_name == 0 || output_file_name[0] == 0)
    {
      output_file = stdout;
    }
  else
    {
      output_file = fopen (output_file_name, "w");
    }

  if (output_file == NULL)
    {
      PRINT_AND_LOG_ERR_MSG (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CREATEDB, CREATEDB_MSG_BAD_OUTPUT),
                 output_file_name);
      goto error_exit;
    }

  if (sysprm_check_range (PRM_ID_DB_VOLUME_SIZE, &db_volume_size) != NO_ERROR)
    {
      UINT64 min, max;
      char min_buf[64], max_buf[64], vol_buf[64];

      if (sysprm_get_range (PRM_ID_DB_VOLUME_SIZE, &min, &max) != NO_ERROR)
    {
      goto error_exit;
    }
      util_byte_to_size_string (min_buf, 64, min);
      util_byte_to_size_string (max_buf, 64, max);
      if (db_volume_str != NULL)
    {
      int len;
      len = strlen (db_volume_str);
      if (char_isdigit (db_volume_str[len - 1]))
        {
          snprintf (vol_buf, 64, "%sB", db_volume_str);
        }
      else
        {
          snprintf (vol_buf, 64, "%s", db_volume_str);
        }
    }
      else
    {
      util_byte_to_size_string (vol_buf, 64, db_volume_size);
    }
      fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CREATEDB, CREATEDB_MSG_FAILURE));

      PRINT_AND_LOG_ERR_MSG (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CREATEDB, CREATEDB_MSG_BAD_RANGE),
                 prm_get_name (PRM_ID_DB_VOLUME_SIZE), vol_buf, min_buf, max_buf);
      goto error_exit;
    }
  if (sysprm_check_range (PRM_ID_LOG_VOLUME_SIZE, &log_volume_size) != NO_ERROR)
    {
      UINT64 min, max;
      char min_buf[64], max_buf[64], vol_buf[64];

      if (sysprm_get_range (PRM_ID_LOG_VOLUME_SIZE, &min, &max) != NO_ERROR)
    {
      goto error_exit;
    }
      util_byte_to_size_string (min_buf, 64, min);
      util_byte_to_size_string (max_buf, 64, max);
      if (log_volume_str != NULL)
    {
      int len;
      len = strlen (log_volume_str);
      if (char_isdigit (log_volume_str[len - 1]))
        {
          snprintf (vol_buf, 64, "%sB", log_volume_str);
        }
      else
        {
          snprintf (vol_buf, 64, "%s", log_volume_str);
        }
    }
      else
    {
      util_byte_to_size_string (vol_buf, 64, log_volume_size);
    }
      fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CREATEDB, CREATEDB_MSG_FAILURE));
      PRINT_AND_LOG_ERR_MSG (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CREATEDB, CREATEDB_MSG_BAD_RANGE),
                 prm_get_name (PRM_ID_LOG_VOLUME_SIZE), vol_buf, min_buf, max_buf);

      goto error_exit;
    }

  if (user_define_file_name != 0)
    {
      user_define_file = fopen (user_define_file_name, "r");
      if (user_define_file == NULL)
    {
      PRINT_AND_LOG_ERR_MSG (msgcat_message
                 (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CREATEDB, CREATEDB_MSG_BAD_USERFILE),
                 user_define_file_name);
      goto error_exit;
    }
    }

  util_byte_to_size_string (er_msg_file, sizeof (er_msg_file), db_volume_size);
  /* total amount of disk space of database is db volume size + log_volume_size + temp_log_volume_size */
  util_byte_to_size_string (required_size, sizeof (required_size), db_volume_size + (UINT64) (log_volume_size * 2));
  fprintf (output_file, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CREATEDB, CREATEDB_MSG_CREATING),
       er_msg_file, cubrid_charset, required_size);

  /* error message log file */
  snprintf (er_msg_file, sizeof (er_msg_file) - 1, "%s_%s.err", database_name, arg->command_name);
  er_init (er_msg_file, ER_NEVER_EXIT);

  /* tuning system parameters */
  sysprm_set_force (PRM_ID_PB_NBUFFERS, "1024");
  sysprm_set_force (PRM_ID_XASL_CACHE_MAX_ENTRIES, "-1");
  sysprm_set_force (PRM_ID_SUPPLEMENTAL_LOG, "0");

  AU_DISABLE_PASSWORDS ();
  db_set_client_type (DB_CLIENT_TYPE_ADMIN_UTILITY);

  if (lob_path && (IS_ABS_PATH (lob_path)) == false)
    {
      char cwd[PATH_MAX];

      if (getcwd (cwd, PATH_MAX) != NULL)
    {
      if (snprintf (abs_lob_path, PATH_MAX, "%s/%s", cwd, lob_path) >= PATH_MAX)
        {
          /* TODO:  Temporarily processed to clean up "-Wformat-truncation=" warning.
           * Additional review will be required.        
           */
          goto error_exit;
        }

      lob_path = abs_lob_path;
    }
      else
    {
      goto error_exit;
    }
    }

  db_login ("DBA", NULL);
  status = db_init (program_name, true, database_name, volume_path, NULL, log_path, lob_path, host_name, overwrite,
            comment, volume_spec_file_name, db_volume_pages, db_page_size, log_volume_pages, log_page_size,
            cubrid_charset);

  if (status != NO_ERROR)
    {
      fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CREATEDB, CREATEDB_MSG_FAILURE));
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      goto error_exit;
    }

  (void) lang_db_put_charset ();

  tzd = tz_get_data ();
  if (put_timezone_checksum ((char *) tzd->checksum) != NO_ERROR)
    {
      goto error_exit;
    }

  if (verbose)
    {
      au_dump_to_file (output_file);
    }
  if (!tf_Metaclass_class.mc_n_variable)
    {
      tf_compile_meta_classes ();
    }
  if ((catcls_Enable != true) && (catcls_compile_catalog_classes (NULL) != NO_ERROR))
    {
      util_log_write_errstr ("%s\n", db_error_string (3));
      db_shutdown ();
      goto error_exit;
    }
  if (catcls_Enable == true)
    {
      if (sm_force_write_all_classes () != NO_ERROR || au_force_write_new_auth () != NO_ERROR)
    {
      util_log_write_errstr ("%s\n", db_error_string (3));
      db_shutdown ();
      goto error_exit;
    }
    }
  if (sm_update_all_catalog_statistics (STATS_WITH_FULLSCAN) != NO_ERROR)
    {
      util_log_write_errstr ("%s\n", db_error_string (3));
      db_shutdown ();
      goto error_exit;
    }

  db_commit_transaction ();

  if (user_define_file != NULL)
    {
      if (parse_user_define_file (user_define_file, output_file) != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG (msgcat_message
                 (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CREATEDB, CREATEDB_MSG_BAD_USERFILE),
                 user_define_file_name);
      db_shutdown ();
      goto error_exit;
    }
      fclose (user_define_file);
    }
  db_commit_transaction ();
  db_shutdown ();

  if (output_file != stdout)
    {
      fclose (output_file);
    }

  if (init_file_name != NULL)
    {
      CSQL_ARGUMENT csql_arg;
      memset (&csql_arg, 0, sizeof (CSQL_ARGUMENT));
      csql_arg.auto_commit = true;
      csql_arg.db_name = database_name;
      csql_arg.in_file_name = init_file_name;
      csql_arg.user_name = strdup ("DBA");
      csql (arg->command_name, &csql_arg);
    }

  return EXIT_SUCCESS;

print_create_usage:
  fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_CREATEDB, CREATEDB_MSG_USAGE),
       basename (arg->argv0));
  util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);

error_exit:
  if (output_file != stdout && output_file != NULL)
    {
      fclose (output_file);
    }
  if (user_define_file != NULL)
    {
      fclose (user_define_file);
    }
  return EXIT_FAILURE;
}

/*
 * deletedb() - deletedb main routine
 *   return: EXIT_SUCCESS/EXIT_FAILURE
 */
int
deletedb (UTIL_FUNCTION_ARG * arg)
{
  UTIL_ARG_MAP *arg_map = arg->arg_map;
  char er_msg_file[PATH_MAX];
  FILE *output_file = NULL;
  const char *output_file_name;
  const char *database_name;
  bool force_delete;

  database_name = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 0);
  if (database_name == NULL)
    {
      goto print_delete_usage;
    }

  output_file_name = utility_get_option_string_value (arg_map, DELETE_OUTPUT_FILE_S, 0);
  force_delete = utility_get_option_bool_value (arg_map, DELETE_DELETE_BACKUP_S);

  if (utility_get_option_string_table_size (arg_map) != 1)
    {
      goto print_delete_usage;
    }

  /* error message log file */
  snprintf (er_msg_file, sizeof (er_msg_file) - 1, "%s_%s.err", database_name, arg->command_name);
  er_init (er_msg_file, ER_NEVER_EXIT);

  if (check_database_name (database_name))
    {
      goto error_exit;
    }

  if (output_file_name == NULL)
    {
      output_file = stdout;
    }
  else
    {
      output_file = fopen (output_file_name, "w");
    }

  if (output_file == NULL)
    {
      PRINT_AND_LOG_ERR_MSG (msgcat_message
                 (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_GENERIC, MSGCAT_UTIL_GENERIC_BAD_OUTPUT_FILE),
                 output_file_name);

      goto error_exit;
    }

  /* tuning system parameters */
  sysprm_set_force (PRM_ID_PB_NBUFFERS, "1024");

  AU_DISABLE_PASSWORDS ();
  db_set_client_type (DB_CLIENT_TYPE_ADMIN_UTILITY);
  db_login ("DBA", NULL);
  if (boot_delete (database_name, force_delete) != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      goto error_exit;
    }

  er_final (ER_ALL_FINAL);
  if (output_file != stdout)
    {
      fclose (output_file);
    }
  return EXIT_SUCCESS;

print_delete_usage:
  fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_DELETEDB, DELETEDB_MSG_USAGE),
       basename (arg->argv0));
  util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);

error_exit:
  er_final (ER_ALL_FINAL);
  if (output_file != stdout && output_file != NULL)
    {
      fclose (output_file);
    }
  return EXIT_FAILURE;
}

static int
parse_up_to_date (char *date_string, struct tm *time_data)
{
  int status;
  int date_index;
  char *save_ptr, *token;
  const char *delim = "-:";

  status = NO_ERROR;
  date_index = 0;
  token = strtok_r (date_string, delim, &save_ptr);
  while (status == NO_ERROR && token != NULL)
    {
      switch (date_index)
    {
    case 0:     /* month-day */
      time_data->tm_mday = atoi (token);
      if (time_data->tm_mday < 1 || time_data->tm_mday > 31)
        {
          status = ER_GENERIC_ERROR;
        }
      break;
    case 1:     /* month */
      time_data->tm_mon = atoi (token) - 1;
      if (time_data->tm_mon < 0 || time_data->tm_mon > 11)
        {
          status = ER_GENERIC_ERROR;
        }
      break;
    case 2:     /* year */
      time_data->tm_year = atoi (token) - 1900;
      if (time_data->tm_year < 0)
        {
          status = ER_GENERIC_ERROR;
        }
      break;
    case 3:     /* hour */
      time_data->tm_hour = atoi (token);
      if (time_data->tm_hour < 0 || time_data->tm_hour > 23)
        {
          status = ER_GENERIC_ERROR;
        }
      break;
    case 4:     /* minute */
      time_data->tm_min = atoi (token);
      if (time_data->tm_min < 0 || time_data->tm_min > 59)
        {
          status = ER_GENERIC_ERROR;
        }
      break;
    case 5:     /* second */
      time_data->tm_sec = atoi (token);
      if (time_data->tm_sec < 0 || time_data->tm_sec > 59)
        {
          status = ER_GENERIC_ERROR;
        }
      break;
    default:
      status = ER_GENERIC_ERROR;
      break;
    }
      date_index++;
      token = strtok_r (NULL, delim, &save_ptr);
    }

  return date_index != 6 ? ER_GENERIC_ERROR : status;
}

static int
print_backup_info (char *database_name, BO_RESTART_ARG * restart_arg)
{
  char from_volbackup[PATH_MAX];
  int error_code = NO_ERROR;
  DB_INFO *dir = NULL, *db;

  error_code = cfg_read_directory (&dir, false);
  if (error_code != NO_ERROR)
    {
      goto exit;
    }

  db = cfg_find_db_list (dir, database_name);
  if (db == NULL)
    {
      error_code = ER_BO_UNKNOWN_DATABASE;
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 1, database_name);
      goto exit;
    }

  COMPOSE_FULL_NAME (BO_DB_FULLNAME, sizeof (BO_DB_FULLNAME), db->pathname, database_name);

  error_code =
    fileio_get_backup_volume (NULL, BO_DB_FULLNAME, db->logpath, restart_arg->backuppath, restart_arg->level,
                  from_volbackup);
  if (error_code != NO_ERROR)
    {
      goto exit;
    }

  error_code =
    fileio_list_restore (NULL, BO_DB_FULLNAME, from_volbackup, (FILEIO_BACKUP_LEVEL) restart_arg->level,
             restart_arg->newvolpath);
exit:
  if (dir != NULL)
    {
      cfg_free_directory (dir);
    }

  return error_code;
}

/*
 * restoredb() - restoredb main routine
 *   return: EXIT_SUCCESS/EXIT_FAILURE
 */
int
restoredb (UTIL_FUNCTION_ARG * arg)
{
  UTIL_ARG_MAP *arg_map = arg->arg_map;
  char er_msg_file[PATH_MAX];
  int status, error_code;
  struct tm time_data;
  char *up_to_date;
  char *database_name;
  bool partial_recovery;
  const char *mk_path;
  BO_RESTART_ARG restart_arg;

  database_name = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 0);
  up_to_date = utility_get_option_string_value (arg_map, RESTORE_UP_TO_DATE_S, 0);
  partial_recovery = utility_get_option_bool_value (arg_map, RESTORE_PARTIAL_RECOVERY_S);
  restart_arg.printtoc = utility_get_option_bool_value (arg_map, RESTORE_LIST_S);
  restart_arg.stopat = -1;
  restart_arg.backuppath = utility_get_option_string_value (arg_map, RESTORE_BACKUP_FILE_PATH_S, 0);
  restart_arg.level = utility_get_option_int_value (arg_map, RESTORE_LEVEL_S);
  restart_arg.verbose_file = utility_get_option_string_value (arg_map, RESTORE_OUTPUT_FILE_S, 0);
  restart_arg.newvolpath = utility_get_option_bool_value (arg_map, RESTORE_USE_DATABASE_LOCATION_PATH_S);
  mk_path = utility_get_option_string_value (arg_map, RESTORE_KEYS_FILE_PATH_S, 0);
  restart_arg.restore_upto_bktime = false;
  restart_arg.restore_slave = false;
  restart_arg.is_restore_from_backup = true;

  if (mk_path != NULL)
    {
      memcpy (restart_arg.keys_file_path, mk_path, PATH_MAX);
    }
  else
    {
      /* prepare the buffer to contain mk path from the backup volume */
      restart_arg.keys_file_path[0] = '\0';
    }

  if (utility_get_option_string_table_size (arg_map) != 1)
    {
      goto print_restore_usage;
    }

  if (up_to_date != NULL && strlen (up_to_date) > 0)
    {
      if (strcasecmp (up_to_date, "backuptime") == 0)
    {
      restart_arg.restore_upto_bktime = true;
    }
      else
    {
      status = parse_up_to_date (up_to_date, &time_data);
      restart_arg.stopat = mktime (&time_data);
      if (status != NO_ERROR || restart_arg.stopat < 0)
        {
          PRINT_AND_LOG_ERR_MSG (msgcat_message
                     (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_RESTOREDB, RESTOREDB_MSG_BAD_DATE));
          goto error_exit;
        }
    }
    }
  else
    {
      restart_arg.stopat = time (NULL);
    }

  /* error message log file */
  snprintf (er_msg_file, sizeof (er_msg_file) - 1, "%s_%s.err", database_name, arg->command_name);
  er_init (er_msg_file, ER_NEVER_EXIT);

  if (restart_arg.printtoc)
    {
      error_code = print_backup_info (database_name, &restart_arg);
      if (error_code != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_RESTOREDB, RESTOREDB_MSG_FAILURE));
      goto error_exit;
    }

      return EXIT_SUCCESS;
    }

  AU_DISABLE_PASSWORDS ();
  db_set_client_type (DB_CLIENT_TYPE_ADMIN_UTILITY);
  db_login ("DBA", NULL);
  if (partial_recovery == true)
    {
      log_default_input_for_archive_log_location = 1;
    }
  status = boot_restart_from_backup (true, database_name, &restart_arg);
  if (status == NULL_TRAN_INDEX)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_RESTOREDB, RESTOREDB_MSG_FAILURE));
      goto error_exit;
    }
  else
    {
      boot_shutdown_server (ER_ALL_FINAL);
    }

  return EXIT_SUCCESS;

print_restore_usage:
  fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_RESTOREDB, RESTOREDB_MSG_USAGE),
       basename (arg->argv0));
  util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);

error_exit:
  return EXIT_FAILURE;
}

/*
 * renamedb() - renamedb main routine
 *   return: EXIT_SUCCESS/EXIT_FAILURE
 */
int
renamedb (UTIL_FUNCTION_ARG * arg)
{
  UTIL_ARG_MAP *arg_map = arg->arg_map;
  char er_msg_file[PATH_MAX];
  const char *src_db_name;
  const char *dest_db_name;
  const char *ext_path;
  const char *control_file_name;
  bool force_delete;

  src_db_name = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 0);
  dest_db_name = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 1);
  if (src_db_name == NULL || dest_db_name == NULL)
    {
      goto print_rename_usage;
    }

  ext_path = utility_get_option_string_value (arg_map, RENAME_EXTENTED_VOLUME_PATH_S, 0);
  control_file_name = utility_get_option_string_value (arg_map, RENAME_CONTROL_FILE_S, 0);
  force_delete = utility_get_option_bool_value (arg_map, RENAME_DELETE_BACKUP_S);

  if (utility_get_option_string_table_size (arg_map) != 2)
    {
      goto print_rename_usage;
    }

  if (check_database_name (src_db_name) || check_new_database_name (dest_db_name))
    {
      goto error_exit;
    }
  else if (ext_path && access (ext_path, F_OK) == -1)
    {
      PRINT_AND_LOG_ERR_MSG (msgcat_message
                 (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_RENAMEDB, RENAMEDB_VOLEXT_PATH_INVALID));
      goto error_exit;
    }
  else if (control_file_name && access (control_file_name, F_OK) == -1)
    {
      PRINT_AND_LOG_ERR_MSG (msgcat_message
                 (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_RENAMEDB, RENAMEDB_VOLS_TOFROM_PATHS_FILE_INVALID));
      goto error_exit;
    }

  /* error message log file */
  snprintf (er_msg_file, sizeof (er_msg_file) - 1, "%s_%s.err", src_db_name, arg->command_name);
  er_init (er_msg_file, ER_NEVER_EXIT);

  /* tuning system parameters */
  sysprm_set_force (PRM_ID_PB_NBUFFERS, "1024");

  AU_DISABLE_PASSWORDS ();
  db_set_client_type (DB_CLIENT_TYPE_ADMIN_UTILITY);
  db_login ("DBA", NULL);
  if (db_restart (arg->command_name, TRUE, src_db_name) != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      goto error_exit;
    }
  else
    {
      if (boot_soft_rename
      (src_db_name, dest_db_name, NULL, NULL, NULL, ext_path, control_file_name, FALSE, TRUE,
       force_delete) != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      db_shutdown ();
      goto error_exit;
    }
      else
    {
      db_commit_transaction ();
      db_shutdown ();
    }
    }
  return EXIT_SUCCESS;

print_rename_usage:
  fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_RENAMEDB, RENAMEDB_MSG_USAGE),
       basename (arg->argv0));
  util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);

error_exit:
  return EXIT_FAILURE;
}

/*
 * installdb() - installb main routine
 *   return: EXIT_SUCCESS/EXIT_FAILURE
 */
int
installdb (UTIL_FUNCTION_ARG * arg)
{
  UTIL_ARG_MAP *arg_map = arg->arg_map;
  char er_msg_file[PATH_MAX];
  char lob_path_buf[PATH_MAX];
  const char *server_name;
  const char *db_path;
  const char *log_path;
  const char *db_name;
  DB_INFO *dir = NULL, *db;
  bool cfg_added = false;

  db_name = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 0);
  if (db_name == NULL)
    {
      goto print_install_usage;
    }

  server_name = utility_get_option_string_value (arg_map, INSTALL_SERVER_NAME_S, 0);
  db_path = utility_get_option_string_value (arg_map, INSTALL_FILE_PATH_S, 0);
  log_path = utility_get_option_string_value (arg_map, INSTALL_LOG_PATH_S, 0);

  if (utility_get_option_string_table_size (arg_map) != 1)
    {
      goto print_install_usage;
    }

  if (check_database_name (db_name))
    {
      goto error_exit;
    }

  /* error message log file */
  snprintf (er_msg_file, sizeof (er_msg_file) - 1, "%s_%s.err", db_name, arg->command_name);
  er_init (er_msg_file, ER_NEVER_EXIT);

  db = cfg_find_db (db_name);
  if (db != NULL)
    {
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_BO_DATABASE_EXISTS, 1, db_name);
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      cfg_free_directory (db);
      goto error_exit;
    }

  /* have to add it to the config before calling boot_restart */
  if (cfg_read_directory (&dir, 1) != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      goto error_exit;
    }

  db = cfg_add_db (&dir, db_name, db_path, log_path, NULL, server_name);
  if (db == NULL)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      goto error_exit;
    }
  if (db->lobpath == NULL)
    {
      /* assign the data volume directory */
      snprintf (lob_path_buf, sizeof (lob_path_buf), "%s%s%clob", LOB_PATH_DEFAULT_PREFIX, db->pathname,
        PATH_SEPARATOR);
      lob_path_buf[PATH_MAX - 1] = '\0';
      db->lobpath = strdup (lob_path_buf);
    }

  cfg_write_directory (dir);

  cfg_added = true;

  AU_DISABLE_PASSWORDS ();
  db_set_client_type (DB_CLIENT_TYPE_ADMIN_UTILITY);
  db_login ("DBA", NULL);
  if (db_restart (arg->command_name, TRUE, db_name) != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      goto error_exit;
    }

  if (boot_soft_rename (NULL, db_name, db_path, log_path, server_name, NULL, NULL, FALSE, FALSE, TRUE) != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      db_shutdown ();
      goto error_exit;
    }

  db_commit_transaction ();
  db_shutdown ();

  cfg_free_directory (dir);
  return EXIT_SUCCESS;

print_install_usage:
  fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_INSTALLDB, INSTALLDB_MSG_USAGE),
       basename (arg->argv0));
  util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);

error_exit:
  if (cfg_added)
    {
      /* got an error, have to back out the addition to the directory */
      cfg_delete_db (&dir, db_name);
      cfg_write_directory (dir);
    }
  if (dir != NULL)
    {
      cfg_free_directory (dir);
    }
  return EXIT_FAILURE;
}

/*
 * copydb() - copydb main routine
 *   return: EXIT_SUCCESS/EXIT_FAILURE
 */
int
copydb (UTIL_FUNCTION_ARG * arg)
{
  UTIL_ARG_MAP *arg_map = arg->arg_map;
  char er_msg_file[PATH_MAX];
  const char *src_db_name;
  const char *dest_db_name;
  const char *server_name;
  const char *db_path;
  const char *log_path;
  const char *lob_path;
  char lob_pathbuf[PATH_MAX];
  const char *ext_path;
  const char *control_file_name;
  bool overwrite, delete_src, copy_lob_path;

  src_db_name = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 0);
  dest_db_name = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 1);
  if (src_db_name == NULL || dest_db_name == NULL)
    {
      goto print_copy_usage;
    }

  server_name = utility_get_option_string_value (arg_map, COPY_SERVER_NAME_S, 0);
  db_path = utility_get_option_string_value (arg_map, COPY_FILE_PATH_S, 0);
  log_path = utility_get_option_string_value (arg_map, COPY_LOG_PATH_S, 0);
  lob_path = utility_get_option_string_value (arg_map, COPY_LOB_PATH_S, 0);
  ext_path = utility_get_option_string_value (arg_map, COPY_EXTENTED_VOLUME_PATH_S, 0);
  control_file_name = utility_get_option_string_value (arg_map, COPY_CONTROL_FILE_S, 0);
  overwrite = utility_get_option_bool_value (arg_map, COPY_REPLACE_S);
  delete_src = utility_get_option_bool_value (arg_map, COPY_DELETE_SOURCE_S);
  copy_lob_path = utility_get_option_bool_value (arg_map, COPY_COPY_LOB_PATH_S);

  if (utility_get_option_string_table_size (arg_map) != 2)
    {
      goto print_copy_usage;
    }

  if (lob_path != NULL && copy_lob_path == true)
    {
      goto print_copy_usage;
    }
  if (delete_src == true && lob_path == NULL)
    {
      copy_lob_path = true;
    }

  /* error message log file */
  snprintf (er_msg_file, sizeof (er_msg_file) - 1, "%s_%s.err", src_db_name, arg->command_name);
  er_init (er_msg_file, ER_NEVER_EXIT);

  if (check_database_name (src_db_name) || check_new_database_name (dest_db_name))
    {
      goto error_exit;
    }

  if (strcmp (src_db_name, dest_db_name) == 0)
    {
      PRINT_AND_LOG_ERR_MSG (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COPYDB, COPYDB_MSG_IDENTICAL));
      goto error_exit;
    }

  /* tuning system parameters */
  sysprm_set_force (PRM_ID_PB_NBUFFERS, "1024");

  AU_DISABLE_PASSWORDS ();
  db_set_client_type (DB_CLIENT_TYPE_ADMIN_UTILITY);
  db_login ("DBA", NULL);

  if (db_restart (arg->command_name, TRUE, src_db_name) != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      goto error_exit;
    }

  if (copy_lob_path)
    {
      const char *s = boot_get_lob_path ();
      if (*s != '\0')
    {
      lob_path = strcpy (lob_pathbuf, s);
    }
    }
  if (boot_copy (src_db_name, dest_db_name, db_path, log_path, lob_path, server_name, ext_path, control_file_name,
         overwrite) != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      goto error_exit;
    }
  if (delete_src)
    {
      boot_delete (src_db_name, true);
    }
  er_final (ER_ALL_FINAL);

  return EXIT_SUCCESS;

print_copy_usage:
  fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_COPYDB, COPYDB_MSG_USAGE),
       basename (arg->argv0));
  util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);

error_exit:
  er_final (ER_ALL_FINAL);

  return EXIT_FAILURE;
}

/*
 * optimizedb() - optimizedb main routine
 *   return: EXIT_SUCCESS/EXIT_FAILURE
 */
int
optimizedb (UTIL_FUNCTION_ARG * arg)
{
  UTIL_ARG_MAP *arg_map = arg->arg_map;
  char er_msg_file[PATH_MAX];
  const char *db_name;
  const char *class_name;
  int status;
  DB_OBJECT *class_mop;

  db_name = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 0);
  if (db_name == NULL)
    {
      goto print_optimize_usage;
    }

  class_name = utility_get_option_string_value (arg_map, OPTIMIZE_CLASS_NAME_S, 0);

  if (utility_get_option_string_table_size (arg_map) != 1)
    {
      goto print_optimize_usage;
    }

  status = NO_ERROR;

  if (check_database_name (db_name))
    {
      goto error_exit;
    }

  /* error message log file */
  snprintf (er_msg_file, sizeof (er_msg_file) - 1, "%s_%s.err", db_name, arg->command_name);
  er_init (er_msg_file, ER_NEVER_EXIT);

  AU_DISABLE_PASSWORDS ();
  db_set_client_type (DB_CLIENT_TYPE_ADMIN_UTILITY);
  db_login ("DBA", NULL);
  if (db_restart (arg->command_name, TRUE, db_name) != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      goto error_exit;
    }

  if (class_name != NULL && class_name[0] != 0)
    {
      const char *class_name_p = NULL;
      const char *class_name_only = NULL;
      char owner_name[DB_MAX_USER_LENGTH] = { '\0' };

      if (utility_check_class_name (class_name) != NO_ERROR)
    {
      db_shutdown ();
      goto error_exit;
    }

      sm_qualifier_name (class_name, owner_name, DB_MAX_USER_LENGTH);
      class_name_only = sm_remove_qualifier_name (class_name);
      if (strcasecmp (owner_name, "dba") == 0 && sm_check_system_class_by_name (class_name_only))
    {
      class_name_p = class_name_only;
    }
      else
    {
      class_name_p = class_name;
    }

      if ((class_mop = db_find_class (class_name_p)) == NULL
      || (db_is_class (class_mop) && sm_update_statistics (class_mop, STATS_WITH_SAMPLING) != NO_ERROR))
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      db_shutdown ();
      goto error_exit;
    }
    }
  else
    {
      if (sm_update_all_statistics (STATS_WITH_SAMPLING) != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      db_shutdown ();
      goto error_exit;
    }
    }
  db_commit_transaction ();
  db_shutdown ();

  return EXIT_SUCCESS;

print_optimize_usage:
  fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_OPTIMIZEDB, OPTIMIZEDB_MSG_USAGE),
       basename (arg->argv0));
  util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);

error_exit:
  return EXIT_FAILURE;
}

typedef enum
{
  DIAGDUMP_ALL = -1,
  DIAGDUMP_FILE_TABLES = 1,
  DIAGDUMP_FILE_CAPACITIES,
  DIAGDUMP_HEAP_CAPACITIES,
  DIAGDUMP_INDEX_CAPACITIES,
  DIAGDUMP_CLASSNAMES,
  DIAGDUMP_DISK_BITMAPS,
  DIAGDUMP_CATALOG,
  DIAGDUMP_LOG,
  DIAGDUMP_HEAP,
  DIAGDUMP_END_OF_OPTION
} DIAGDUMP_TYPE;

/*
 * diagdb() - diagdb main routine
 *   return: EXIT_SUCCESS/EXIT_FAILURE
 */
int
diagdb (UTIL_FUNCTION_ARG * arg)
{
  UTIL_ARG_MAP *arg_map = arg->arg_map;
  char er_msg_file[PATH_MAX];
  const char *db_name;
  const char *output_file = NULL;
  const char *class_name;
  FILE *infp = NULL;
  FILE *outfp = NULL;
  bool is_emergency = false;
  bool need_db_shutdown = false;
  DIAGDUMP_TYPE diag;
  THREAD_ENTRY *thread_p;
  int error_code = NO_ERROR;
  char *class_list_file;

  db_name = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 0);
  if (db_name == NULL)
    {
      goto print_diag_usage;
    }

  is_emergency = utility_get_option_bool_value (arg_map, DIAG_EMERGENCY_S);
  if (is_emergency)
    {
      sysprm_set_force (PRM_ID_DISABLE_VACUUM, "yes");
      sysprm_set_force (PRM_ID_FORCE_RESTART_TO_SKIP_RECOVERY, "yes");
    }

  output_file = utility_get_option_string_value (arg_map, DIAG_OUTPUT_FILE_S, 0);
  if (output_file == NULL)
    {
      outfp = stdout;
    }
  else
    {
      outfp = fopen (output_file, "w");
      if (outfp == NULL)
    {
      PRINT_AND_LOG_ERR_MSG (msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_DIAGDB, DIAGDB_MSG_BAD_OUTPUT),
                 output_file);
      goto error_exit;
    }
    }

  class_name = utility_get_option_string_value (arg_map, DIAG_CLASS_NAME_S, 0);

  class_list_file = utility_get_option_string_value (arg_map, DIAG_INPUT_FILE_S, 0);

  diag = (DIAGDUMP_TYPE) utility_get_option_int_value (arg_map, DIAG_DUMP_TYPE_S);

  if (diag != DIAGDUMP_LOG && utility_get_option_string_table_size (arg_map) != 1)
    {
      goto print_diag_usage;
    }

  if (diag != DIAGDUMP_HEAP && (class_name != NULL || class_list_file != NULL))
    {
      goto print_diag_usage;
    }

  if (class_name && class_list_file)
    {
      fprintf (stderr, "The -n and -i options cannot be used together.\n");
      goto error_exit;
    }

  if (check_database_name (db_name))
    {
      goto error_exit;
    }

  /* error message log file */
  snprintf (er_msg_file, sizeof (er_msg_file) - 1, "%s_%s.err", db_name, arg->command_name);
  er_init (er_msg_file, ER_NEVER_EXIT);

  AU_DISABLE_PASSWORDS ();
  db_set_client_type (DB_CLIENT_TYPE_ADMIN_UTILITY);
  db_login ("DBA", NULL);
  if (db_restart (arg->command_name, TRUE, db_name) != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      goto error_exit;
    }

  need_db_shutdown = true;

  if (diag < DIAGDUMP_ALL || diag >= DIAGDUMP_END_OF_OPTION)
    {
      goto print_diag_usage;
    }

  thread_p = thread_get_thread_entry_info ();

  if (diag == DIAGDUMP_ALL || diag == DIAGDUMP_FILE_TABLES)
    {
      /* this dumps the allocated file stats */
      fprintf (outfp, "\n*** DUMP OF FILE STATISTICS ***\n");
      (void) file_tracker_dump (thread_p, outfp);
    }

  if (diag == DIAGDUMP_ALL || diag == DIAGDUMP_FILE_CAPACITIES)
    {
      /* this dumps the allocated file stats */
      fprintf (outfp, "\n*** DUMP OF FILE DESCRIPTIONS ***\n");
      (void) file_tracker_dump_all_capacities (thread_p, outfp);
    }

  if (diag == DIAGDUMP_ALL || diag == DIAGDUMP_HEAP_CAPACITIES)
    {
      /* this dumps lower level info about capacity of all heaps */
      fprintf (outfp, "\n*** DUMP CAPACITY OF ALL HEAPS ***\n");
      (void) file_tracker_dump_all_heap_capacities (thread_p, outfp);
    }

  if (diag == DIAGDUMP_ALL || diag == DIAGDUMP_INDEX_CAPACITIES)
    {
      /* this dumps lower level info about capacity of all indices */
      fprintf (outfp, "\n*** DUMP CAPACITY OF ALL INDICES ***\n");
      (void) file_tracker_dump_all_btree_capacities (thread_p, outfp);
    }

  if (diag == DIAGDUMP_ALL || diag == DIAGDUMP_CLASSNAMES)
    {
      /* this dumps the known classnames */
      fprintf (outfp, "\n*** DUMP CLASSNAMES ***\n");
      locator_dump_class_names (thread_p, outfp);
    }

  if (diag == DIAGDUMP_ALL || diag == DIAGDUMP_DISK_BITMAPS)
    {
      /* this dumps lower level info about the disk */
      fprintf (outfp, "\n*** DUMP OF DISK STATISTICS ***\n");
      disk_dump_all (thread_p, outfp);
    }

  if (diag == DIAGDUMP_ALL || diag == DIAGDUMP_CATALOG)
    {
      /* this dumps the content of catalog */
      fprintf (outfp, "\n*** DUMP OF CATALOG ***\n");
      catalog_dump (thread_p, outfp, 1);
    }

  if (diag == DIAGDUMP_ALL || diag == DIAGDUMP_LOG)
    {
      /* this dumps the content of log */
      int isforward, dump_npages, desired_tranid;
      LOG_PAGEID start_logpageid;
      long long int s;

      if (diag == DIAGDUMP_ALL || utility_get_option_string_table_size (arg_map) == 1)
    {
      char yn[2];
      do
        {
          printf ("\n");
          printf ("isforward (1 or 0) ? ");
          scanf ("%d", &isforward);
          printf ("start_logpageid (-1 for the first/last page) ? ");
          scanf ("%lld", &s);
          start_logpageid = s;
          printf ("dump_npages (-1 for all pages) ? ");
          scanf ("%d", &dump_npages);
          printf ("desired_tranid (-1 for all transactions) ? ");
          scanf ("%d", &desired_tranid);
          printf ("log_dump(%d, %lld, %d, %d) (y/n) ? ", isforward, (long long int) start_logpageid, dump_npages,
              desired_tranid);
          scanf ("%1s", yn);
        }
      while (yn[0] != 'y');
    }
      else if (utility_get_option_string_table_size (arg_map) == 5)
    {
      const char *cp;
      start_logpageid = isforward = dump_npages = desired_tranid = 0;

      cp = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 1);
      if (cp != NULL)
        {
          isforward = atoi (cp);
        }

      cp = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 2);
      if (cp != NULL)
        {
          start_logpageid = atoll (cp);
        }

      cp = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 3);
      if (cp != NULL)
        {
          dump_npages = atoi (cp);
        }

      cp = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 4);
      if (cp != NULL)
        {
          desired_tranid = atoi (cp);
        }
    }
      else
    {
      goto print_diag_usage;
    }
      fprintf (outfp, "\n*** DUMP OF LOG ***\n");
      xlog_dump (thread_p, outfp, isforward, start_logpageid, dump_npages, desired_tranid);
    }

  if (diag == DIAGDUMP_ALL || diag == DIAGDUMP_HEAP)
    {
      bool dump_records;
      dump_records = utility_get_option_bool_value (arg_map, DIAG_DUMP_RECORDS_S);

      if (class_name != NULL)
    {
      if (!sm_check_system_class_by_name (class_name))
        {
          if (utility_check_class_name (class_name) != NO_ERROR)
        {
          goto error_exit;
        }
        }
      error_code = heap_dump_heap_file (thread_p, outfp, dump_records, class_name);
      if (error_code != NO_ERROR)
        {
          if (error_code == ER_LC_UNKNOWN_CLASSNAME)
        {
          PRINT_AND_LOG_ERR_MSG (msgcat_message
                     (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_DIAGDB, DIAGDB_MSG_UNKNOWN_CLASS),
                     class_name);
        }
          goto error_exit;
        }
    }
      else if (class_list_file != NULL)
    {
      char input_class[SM_MAX_IDENTIFIER_LENGTH];

      infp = fopen (class_list_file, "r");
      if (infp == NULL)
        {
          perror (class_list_file);
          goto error_exit;
        }

      while (fgets (input_class, SM_MAX_IDENTIFIER_LENGTH, infp) != NULL)
        {
          trim (input_class);

          if (strlen (input_class) < 1)
        {
          /* empty string */
          continue;
        }

          if (!sm_check_system_class_by_name (input_class))
        {
          if (utility_check_class_name (input_class) != NO_ERROR)
            {
              goto error_exit;
            }
        }

          error_code = heap_dump_heap_file (thread_p, outfp, dump_records, input_class);

          if (error_code != NO_ERROR)
        {
          if (error_code == ER_LC_UNKNOWN_CLASSNAME)
            {
              PRINT_AND_LOG_ERR_MSG (msgcat_message
                         (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_DIAGDB,
                          DIAGDB_MSG_UNKNOWN_CLASS), input_class);
            }
          goto error_exit;
        }
        }
    }
      else
    {
      fprintf (outfp, "\n*** DUMP OF ALL HEAPS ***\n");
      (void) file_tracker_dump_all_heap (thread_p, outfp, dump_records);
    }
    }

  db_shutdown ();

  fflush (outfp);
  if (output_file != NULL && outfp != NULL && outfp != stdout)
    {
      fclose (outfp);
    }
  if (infp != NULL)
    {
      fclose (infp);
    }

  return EXIT_SUCCESS;

print_diag_usage:
  fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_DIAGDB, DIAGDB_MSG_USAGE),
       basename (arg->argv0));
  util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);

error_exit:
  if (need_db_shutdown)
    {
      db_shutdown ();
    }

  if (output_file != NULL && outfp != NULL && outfp != stdout)
    {
      fclose (outfp);
    }
  if (infp != NULL)
    {
      fclose (infp);
    }

  return EXIT_FAILURE;
}

/*
 * patchdb() - patchdb main routine
 *   return: EXIT_SUCCESS/EXIT_FAILURE
 */
int
patchdb (UTIL_FUNCTION_ARG * arg)
{
  char er_msg_file[PATH_MAX];
  UTIL_ARG_MAP *arg_map = arg->arg_map;
  const char *db_name;
  const char *db_locale = NULL;
  bool recreate_log;
  int error = NO_ERROR;

  db_name = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 0);
  if (db_name == NULL)
    {
      goto print_patch_usage;
    }

  recreate_log = utility_get_option_bool_value (arg_map, PATCH_RECREATE_LOG_S);

  if (recreate_log == true)
    {
      db_locale = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 1);
      if (db_locale == NULL)
    {
      goto print_patch_usage;
    }
    }

  if (utility_get_option_string_table_size (arg_map) != (recreate_log ? 2 : 1))
    {
      goto print_patch_usage;
    }

  if (check_database_name (db_name))
    {
      goto error_exit;
    }

  /* error message log file */
  snprintf (er_msg_file, sizeof (er_msg_file) - 1, "%s_%s.err", db_name, arg->command_name);
  er_init (er_msg_file, ER_NEVER_EXIT);

  error = boot_emergency_patch (db_name, recreate_log, 0, db_locale, NULL);
  if (error != NO_ERROR)
    {
      fprintf (stderr, "emergency patch fail:%s\n", db_error_string (3));
      if (error == ER_LOG_TOO_SANE_TO_RECREATE)
    {
      fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_PATCHDB, PATCHDB_RECREATE_FAILURE));
    }
      er_final (ER_ALL_FINAL);
      goto error_exit;
    }

  return EXIT_SUCCESS;

print_patch_usage:
  fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_PATCHDB, PATCHDB_MSG_USAGE),
       basename (arg->argv0));
error_exit:
  return EXIT_FAILURE;
}

#if defined(ENABLE_UNUSED_FUNCTION)
/*
 * estimatedb_data() - estimatedb_data main routine
 *   return: EXIT_SUCCES/EXIT_FAILURE
 */
int
estimatedb_data (UTIL_FUNCTION_ARG * arg)
{
  /* todo: remove me */
  return -1;
}
#endif /* ENABLE_UNUSED_FUNCTION */

#if defined(ENABLE_UNUSED_FUNCTION )
/*
 * estimatedb_index() - restoredb main routine
 *   return: 0 : success
 *           non-zero : error
 */
int
estimatedb_index (UTIL_FUNCTION_ARG * arg)
{
  UTIL_ARG_MAP *arg_map = arg->arg_map;
  int num_instance;
  int num_diffkeys;
  int avg_key_size;
  const char *key_type;

  int status = -1;
  int npages = 0;
  int blt_npages = 0;
  int blt_wrs_npages = 0;
  const PR_TYPE *type;
  DB_DOMAIN *domain = (DB_DOMAIN *) 0;

  if (utility_get_option_string_table_size (arg_map) != 4)
    {
      goto print_estimate_index_usage;
    }

  num_instance = atoi (utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 0));
  num_diffkeys = atoi (utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 1));
  avg_key_size = atoi (utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 2));
  key_type = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 3);

  sysprm_load_and_init (NULL, NULL);
  (void) db_set_page_size (IO_DEFAULT_PAGE_SIZE, IO_DEFAULT_PAGE_SIZE);
  if (num_instance <= num_diffkeys)
    {
      num_instance = num_diffkeys;
    }
  /* Initialize domain area */
  tp_init ();

  /* Initialize tsc-timer */
  tsc_init ();

  if (key_type != NULL)
    {
      domain = pt_string_to_db_domain (key_type, (const char *) NULL);
      if (domain)
    {
      type = domain->type;
      if (type != NULL)
        {
          if (tp_valid_indextype (type->id))
        {


          switch (type->id)
            {
            case DB_TYPE_BIT:
            case DB_TYPE_VARBIT:
            case DB_TYPE_CHAR:
            case DB_TYPE_VARCHAR:
              /* Do not override any information in Avg_key_size with precision information. Just make sure the
               * input makes sense for these cases.  */
              if (avg_key_size > domain->precision)
            {
              /* Does not make sense to have avg_key_size bigger than precision - inform user of error.
               * This is illegal input since the char precision defaults to 1. estimatedb_index 100000 1000
               * 5 char */
              status = -2;
            }
              break;
            default:
              break;
            }

          if (status != -2)
            {
              /*
               * This will call pr_estimate_size which uses the
               * Avg_key_size and TP_DOMAIN_TYPE(domain) to really
               * compute the correct average key size that we
               * need to estimate the total number of pages.
               */
              npages =
            btree_estimate_total_numpages (NULL, num_diffkeys, avg_key_size, num_instance, &blt_npages,
                               &blt_wrs_npages);

              fprintf (stdout,
                   msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_ESTIMATEDB_INDEX,
                           ESTIMATEDB_INDEX_MSG_INPUT));
              fprintf (stdout,
                   msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_ESTIMATEDB_INDEX,
                           ESTIMATEDB_INDEX_MSG_INSTANCES), num_instance);
              fprintf (stdout,
                   msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_ESTIMATEDB_INDEX,
                           ESTIMATEDB_INDEX_MSG_NUMBER_KEYS), num_diffkeys);
              fprintf (stdout,
                   msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_ESTIMATEDB_INDEX,
                           ESTIMATEDB_INDEX_MSG_AVG_KEYSIZE), avg_key_size);
              fprintf (stdout,
                   msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_ESTIMATEDB_INDEX,
                           ESTIMATEDB_INDEX_MSG_KEYTYPE), key_type);
              fflush (stdout);
              status = 0;
            }
        }
        }
    }
    }

  /* Remove domain area */
  tp_final ();
  switch (status)
    {
    case -1:
      fprintf (stderr,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_ESTIMATEDB_INDEX, ESTIMATEDB_INDEX_BAD_KEYTYPE),
           key_type);
      break;
    case -2:
      fprintf (stderr,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_ESTIMATEDB_INDEX, ESTIMATEDB_INDEX_BAD_KEYLENGTH),
           avg_key_size, domain->precision);
      break;
    case 1:
      fprintf (stderr,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_ESTIMATEDB_INDEX, ESTIMATEDB_INDEX_BAD_ARGUMENTS));
      break;
    default:
      fprintf (stdout,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_ESTIMATEDB_INDEX, ESTIMATEDB_INDEX_MSG_NPAGES),
           npages);
      fprintf (stdout,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_ESTIMATEDB_INDEX, ESTIMATEDB_INDEX_MSG_BLT_NPAGES),
           blt_npages);
      fprintf (stdout,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_ESTIMATEDB_INDEX,
                   ESTIMATEDB_INDEX_MSG_BLT_WRS_NPAGES), blt_wrs_npages);
      break;
    }
  return status;

print_estimate_index_usage:
  fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_ESTIMATEDB_INDEX, ESTIMATEDB_INDEX_MSG_USAGE),
       basename (arg->argv0));
  return EXIT_FAILURE;
}
#endif /* ENABLE_UNUSED_FUNCTION */

/*
 * alterdbhost() - restoredb main routine
 *   return: EXIT_SUCCESS/EXIT_FAILURE
 */
int
alterdbhost (UTIL_FUNCTION_ARG * arg)
{
  UTIL_ARG_MAP *arg_map = arg->arg_map;
  const char *db_name;
  const char *host_name;
  int dbtxt_vdes = NULL_VOLDES;
  int log_vdes = NULL_VOLDES;
  char dbtxt_label[PATH_MAX];
  char host_name_buf[CUB_MAXHOSTNAMELEN + 1];
  DB_INFO *db = NULL;
  DB_INFO *dir = NULL;
  const char *log_prefix;
  int num_hosts;

  if (utility_get_option_string_table_size (arg_map) != 1)
    {
      goto print_alterdbhost_usage;
    }

  db_name = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 0);
  if (db_name == NULL)
    {
      goto print_alterdbhost_usage;
    }

  host_name = utility_get_option_string_value (arg_map, ALTERDBHOST_HOST_S, 0);
  if (check_database_name (db_name))
    {
      goto error_exit;
    }

  /* If a host was not given, assume the current host */
  if (host_name == NULL)
    {
#if 0               /* use Unix-domain socket for localhost */
      if (GETHOSTNAME (host_name_buf, CUB_MAXHOSTNAMELEN) != 0)
    {
      er_set_with_oserror (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_BO_UNABLE_TO_FIND_HOSTNAME, 1, host_name_buf);
      goto error;
    }
#else
      strcpy (host_name_buf, "localhost");
#endif
      host_name = host_name_buf;
    }

  er_init (NULL, ER_NEVER_EXIT);

  /* get the database directory information in write mode */
  if (cfg_maycreate_get_directory_filename (dbtxt_label) == NULL
#if !defined(WINDOWS) || !defined(DONT_USE_MANDATORY_LOCK_IN_WINDOWS)
/* Temporary fix for NT file locking problem */
      || (dbtxt_vdes = fileio_mount (NULL, dbtxt_label, dbtxt_label, LOG_DBTXT_VOLID, 2, true)) == NULL_VOLDES
#endif /* !WINDOWS || !DONT_USE_MANDATORY_LOCK_IN_WINDOWS */
    )
    {
      goto error;
    }

  if (dbtxt_vdes != NULL_VOLDES)
    {
      if (cfg_read_directory_ex (dbtxt_vdes, &dir, true) != NO_ERROR)
    {
      goto error;
    }
    }
  else
    {
      if (cfg_read_directory (&dir, true) != NO_ERROR)
    {
      goto error;
    }
    }
  db = cfg_find_db_list (dir, db_name);
  if (db == NULL)
    {
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_BO_UNKNOWN_DATABASE, 1, db_name);
      goto error;
    }

  /* Compose the full name of the database and find location of logs */
  log_prefix = fileio_get_base_file_name (db_name);
  COMPOSE_FULL_NAME (BO_DB_FULLNAME, sizeof (BO_DB_FULLNAME), db->pathname, db_name);

  /* System is not restarted. Read the header from disk */
  logpb_initialize_log_names (NULL, BO_DB_FULLNAME, db->logpath, log_prefix);

  /* Avoid setting errors at this moment related to existance of files. */
  if (fileio_is_volume_exist (log_Name_active) == false)
    {
      goto error;
    }

  if ((log_vdes =
       fileio_mount (NULL, BO_DB_FULLNAME, log_Name_active, LOG_DBLOG_ACTIVE_VOLID, true, false)) == NULL_VOLDES)
    {
      goto error;
    }

  if (db->hosts != NULL)
    {
      cfg_free_hosts (db->hosts);
    }
  db->hosts = cfg_get_hosts (host_name, &num_hosts, false);

  /* Dismount lgat */
  fileio_dismount (NULL, log_vdes);

#if defined(WINDOWS) && !defined(DONT_USE_MANDATORY_LOCK_IN_WINDOWS)
  /* must unlock this before we can open it again for writing */
  if (dbtxt_vdes != NULL_VOLDES)
    {
      fileio_dismount (NULL, dbtxt_vdes);
      dbtxt_vdes = NULL_VOLDES;
    }
#endif /* WINDOWS && !DONT_USE_MANDATORY_LOCK_IN_WINDOWS */
  if (dbtxt_vdes != NULL_VOLDES)
    {
      cfg_write_directory_ex (dbtxt_vdes, dir);
    }
  else
    {
      cfg_write_directory (dir);
    }

  cfg_free_directory (dir);
  if (dbtxt_vdes != NULL_VOLDES)
    {
      fileio_dismount (NULL, dbtxt_vdes);
    }

  return EXIT_SUCCESS;

error:
  PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));

  /* Deallocate any allocated structures */
  if (dir != NULL)
    {
      cfg_free_directory (dir);
    }

  if (dbtxt_vdes != NULL_VOLDES)
    {
      fileio_dismount (NULL, dbtxt_vdes);
    }

  return EXIT_FAILURE;

print_alterdbhost_usage:
  fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_ALTERDBHOST, ALTERDBHOST_MSG_USAGE),
       basename (arg->argv0));
  util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);

error_exit:
  return EXIT_FAILURE;
}

/*
 * genlocale() - generate locales binary files
 *   return: EXIT_SUCCESS/EXIT_FAILURE
 */
int
genlocale (UTIL_FUNCTION_ARG * arg)
{
  char *locale_str = NULL;
  char *input_path = NULL;
  bool is_scan_locales = false;
  bool is_verbose = false;
  LOCALE_FILE *lf = NULL;
  LOCALE_FILE *curr_lf = NULL;
  int count_loc = 0, i;
  int start_lf_pos = -1;
  int end_lf_pos = -1;
  char er_msg_file[PATH_MAX];
  int str_count = 0;
  UTIL_ARG_MAP *arg_map = NULL;
  LOCALE_DATA **ld = NULL;

  int err_status = EXIT_SUCCESS;

  assert (arg != NULL);

  arg_map = arg->arg_map;

  if (!arg->valid_arg)
    {
      goto print_genlocale_usage;
    }

  str_count = utility_get_option_string_table_size (arg_map);
  if (str_count == 0)
    {
      is_scan_locales = true;
      locale_str = NULL;
    }
  else if (str_count == 1)
    {
      locale_str = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 0);
      if (locale_str == NULL)
    {
      goto print_genlocale_usage;
    }
    }
  else
    {
      goto print_genlocale_usage;
    }

  is_verbose = utility_get_option_bool_value (arg_map, GENLOCALE_VERBOSE_S);

  input_path = utility_get_option_string_value (arg_map, GENLOCALE_INPUT_PATH_S, 0);
  if (input_path != NULL && is_scan_locales)
    {
      goto print_genlocale_usage;
    }

  /* initialization of language module for built-in locales and collations, we don't care about environment here */
  lang_init_builtin ();

  /* error message log file */
  snprintf (er_msg_file, sizeof (er_msg_file) - 1, "%s.err", arg->command_name);
  er_init (er_msg_file, ER_NEVER_EXIT);

  if (locale_get_cfg_locales (&lf, &count_loc, false) != NO_ERROR)
    {
      err_status = EXIT_FAILURE;
      goto exit;
    }

  if (is_scan_locales)
    {
      if (is_verbose)
    {
      printf ("\n\nFound %d locale files\n\n", count_loc);
    }
      start_lf_pos = 0;
      end_lf_pos = count_loc;
    }
  else
    {
      assert (locale_str != NULL);

      for (i = 0; i < count_loc; i++)
    {
      if (strcmp (locale_str, lf[i].locale_name) == 0)
        {
          curr_lf = &(lf[i]);
          start_lf_pos = i;
          end_lf_pos = i + 1;
          break;
        }
    }

      if (curr_lf == NULL)
    {
      LOG_LOCALE_ERROR (msgcat_message
                (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_GENLOCALE, GENLOCALE_MSG_INVALID_LOCALE), ER_LOC_GEN,
                true);
      err_status = EXIT_FAILURE;
      goto exit;
    }

      if (input_path != NULL)
    {
      if (curr_lf->ldml_file != NULL)
        {
          free (curr_lf->ldml_file);
        }

      curr_lf->ldml_file = strdup (input_path);
      if (curr_lf->ldml_file == NULL)
        {
          er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, (size_t) strlen (input_path));
          err_status = EXIT_FAILURE;
          goto exit;
        }
    }
    }

  ld = (LOCALE_DATA **) malloc (count_loc * sizeof (LOCALE_DATA *));
  if (ld == NULL)
    {
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, (size_t) strlen (input_path));
      err_status = EXIT_FAILURE;
      goto exit;
    }
  memset (ld, 0, count_loc * sizeof (LOCALE_DATA *));


  for (i = start_lf_pos; i < end_lf_pos; i++)
    {
      ld[i] = (LOCALE_DATA *) malloc (sizeof (LOCALE_DATA));
      if (ld[i] == NULL)
    {
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, (size_t) strlen (input_path));
      err_status = EXIT_FAILURE;
      goto exit;
    }
      memset (ld[i], 0, sizeof (LOCALE_DATA));
    }

  for (i = start_lf_pos; i < end_lf_pos; i++)
    {
      if (locale_check_and_set_default_files (&(lf[i]), false) != NO_ERROR)
    {
      err_status = EXIT_FAILURE;
      goto exit;
    }

      if (is_verbose)
    {
      printf ("*********************************\n");
      printf ("Compile locale:\n");
      printf ("Locale string: %s\n", lf[i].locale_name);
      printf ("Input LDML: %s\n", lf[i].ldml_file);
      printf ("Output Library: %s\n", lf[i].lib_file);
    }

      if (locale_compile_locale (&(lf[i]), ld[i], is_verbose) != NO_ERROR)
    {
      err_status = EXIT_FAILURE;
      goto exit;
    }

      if (!is_scan_locales)
    {
      break;
    }
    }

  locale_mark_duplicate_collations (ld, start_lf_pos, end_lf_pos, is_verbose);

  if (locale_prepare_C_file () != NO_ERROR || locale_save_all_to_C_file (ld, start_lf_pos, end_lf_pos, lf) != NO_ERROR)
    {
      err_status = EXIT_FAILURE;
      goto exit;
    }

exit:

  /* Deallocate any allocated structures */
  for (i = 0; i < count_loc; i++)
    {
      if (lf[i].locale_name != NULL)
    {
      free_and_init (lf[i].locale_name);
    }
      if (lf[i].ldml_file != NULL)
    {
      free_and_init (lf[i].ldml_file);
    }
      if (lf[i].lib_file != NULL)
    {
      free_and_init (lf[i].lib_file);
    }
      if (ld != NULL && ld[i] != NULL)
    {
      locale_destroy_data (ld[i]);
      free (ld[i]);
    }
    }

  if (ld != NULL)
    {
      free (ld);
    }

  locale_free_shared_data ();

  assert (lf != NULL);
  free_and_init (lf);

  if (err_status != EXIT_SUCCESS && er_errid () != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
    }

  return err_status;

print_genlocale_usage:
  fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_GENLOCALE, GENLOCALE_MSG_USAGE),
       basename (arg->argv0));
  util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);

  return EXIT_FAILURE;
}

/*
 * dumplocale() - generate locales binary files
 *   return: error status
 */
int
dumplocale (UTIL_FUNCTION_ARG * arg)
{
  char *locale_str = NULL;
  char *input_path = NULL;
  char *alphabet_type = NULL;
  LANG_LOCALE_DATA lld;
  void *loclib_handle = NULL;
  LOCALE_FILE *lf = NULL;
  LOCALE_FILE lf_one;
  int dl_settings = 0;
  int str_count, i, count_loc, loc_index;
  int start_value = 0;
  int end_value = 0;
  UTIL_ARG_MAP *arg_map = NULL;
  int err_status = NO_ERROR;

  assert (arg != NULL);
  arg_map = arg->arg_map;

  if (!arg->valid_arg)
    {
      util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);
      goto print_dumplocale_usage;
    }

  str_count = utility_get_option_string_table_size (arg_map);

  locale_str = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 0);

  input_path = utility_get_option_string_value (arg_map, DUMPLOCALE_INPUT_PATH_S, 0);

  if (utility_get_option_bool_value (arg_map, DUMPLOCALE_CALENDAR_S))
    {
      dl_settings |= DUMPLOCALE_IS_CALENDAR;
    }

  if (utility_get_option_bool_value (arg_map, DUMPLOCALE_NUMBERING_S))
    {
      dl_settings |= DUMPLOCALE_IS_NUMBERING;
    }

  alphabet_type = utility_get_option_string_value (arg_map, DUMPLOCALE_ALPHABET_S, 0);
  if (alphabet_type != NULL)
    {
      if (strcmp (alphabet_type, DUMPLOCALE_ALPHABET_LOWER_S) == 0
      || strcmp (alphabet_type, DUMPLOCALE_ALPHABET_LOWER_L) == 0)
    {
      dl_settings |= DUMPLOCALE_IS_ALPHABET;
      dl_settings |= DUMPLOCALE_IS_ALPHABET_LOWER;
      dl_settings &= ~DUMPLOCALE_IS_ALPHABET_UPPER;
    }
      else if (strcmp (alphabet_type, DUMPLOCALE_ALPHABET_UPPER_S) == 0
           || strcmp (alphabet_type, DUMPLOCALE_ALPHABET_UPPER_L) == 0)
    {
      dl_settings |= DUMPLOCALE_IS_ALPHABET;
      dl_settings &= ~DUMPLOCALE_IS_ALPHABET_LOWER;
      dl_settings |= DUMPLOCALE_IS_ALPHABET_UPPER;
    }
      else if (strcmp (alphabet_type, DUMPLOCALE_ALPHABET_ALL_CASING) == 0)
    {
      dl_settings |= DUMPLOCALE_IS_ALPHABET;
      dl_settings |= DUMPLOCALE_IS_ALPHABET_LOWER;
      dl_settings |= DUMPLOCALE_IS_ALPHABET_UPPER;
    }
    }

  alphabet_type = NULL;
  /* check if --identifier-alphabet is set. */
  alphabet_type = utility_get_option_string_value (arg_map, DUMPLOCALE_IDENTIFIER_ALPHABET_S, 0);
  if (alphabet_type != NULL)
    {
      if (strcmp (alphabet_type, DUMPLOCALE_ALPHABET_LOWER_S) == 0
      || strcmp (alphabet_type, DUMPLOCALE_ALPHABET_LOWER_L) == 0)
    {
      dl_settings |= DUMPLOCALE_IS_IDENTIFIER_ALPHABET;
      dl_settings |= DUMPLOCALE_IS_IDENTIFIER_ALPHABET_LOWER;
      dl_settings &= ~DUMPLOCALE_IS_IDENTIFIER_ALPHABET_UPPER;
    }
      else if (strcmp (alphabet_type, DUMPLOCALE_ALPHABET_UPPER_S) == 0
           || strcmp (alphabet_type, DUMPLOCALE_ALPHABET_UPPER_L) == 0)
    {
      dl_settings |= DUMPLOCALE_IS_IDENTIFIER_ALPHABET;
      dl_settings &= ~DUMPLOCALE_IS_IDENTIFIER_ALPHABET_LOWER;
      dl_settings |= DUMPLOCALE_IS_IDENTIFIER_ALPHABET_UPPER;
    }
      else if (strcmp (alphabet_type, DUMPLOCALE_ALPHABET_ALL_CASING) == 0)
    {
      dl_settings |= DUMPLOCALE_IS_IDENTIFIER_ALPHABET;
      dl_settings |= DUMPLOCALE_IS_IDENTIFIER_ALPHABET_LOWER;
      dl_settings |= DUMPLOCALE_IS_IDENTIFIER_ALPHABET_UPPER;
    }
    }

  if (utility_get_option_bool_value (arg_map, DUMPLOCALE_COLLATION_S))
    {
      dl_settings |= DUMPLOCALE_IS_COLLATION_CP_ORDER;
    }

  if (utility_get_option_bool_value (arg_map, DUMPLOCALE_WEIGHT_ORDER_S))
    {
      dl_settings |= DUMPLOCALE_IS_COLLATION_WEIGHT_ORDER;
    }
  start_value = utility_get_option_int_value (arg_map, DUMPLOCALE_START_VALUE_S);
  end_value = utility_get_option_int_value (arg_map, DUMPLOCALE_END_VALUE_S);

  if (utility_get_option_bool_value (arg_map, DUMPLOCALE_NORMALIZATION_S))
    {
      dl_settings |= DUMPLOCALE_IS_NORMALIZATION;
    }

  if (utility_get_option_bool_value (arg_map, DUMPLOCALE_CONSOLE_CONV_S))
    {
      dl_settings |= DUMPLOCALE_IS_TEXT_CONV;
    }

  /* Check command line arguments for incompatibilities. */
  if (locale_str != NULL && input_path != NULL)
    {
      err_status = ER_LOC_GEN;
      LOG_LOCALE_ERROR (msgcat_message
            (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_DUMPLOCALE, DUMPLOCALE_MSG_INCOMPAT_INPUT_SEL),
            ER_LOC_GEN, true);
      goto print_dumplocale_usage;
    }
  if (start_value > end_value)
    {
      err_status = ER_LOC_GEN;
      LOG_LOCALE_ERROR (msgcat_message
            (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_DUMPLOCALE, DUMPLOCALE_MSG_INVALID_CP_RANGE), ER_LOC_GEN,
            true);
      goto print_dumplocale_usage;
    }

  /* Start the dumping process. */
  /* Prepare the locale file(s) to be dumped. */
  memset (&lf_one, 0, sizeof (LOCALE_FILE));
  memset (&lld, 0, sizeof (LANG_LOCALE_DATA));

  if (locale_str != NULL)
    {
      /* Find binary file corresponding to the selected locale. */
      count_loc = 1;
      lf = &lf_one;
      if (locale_str == NULL || strlen (locale_str) > LOC_LOCALE_STR_SIZE)
    {
      err_status = ER_LOC_INIT;
      LOG_LOCALE_ERROR (msgcat_message
                (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_DUMPLOCALE, DUMPLOCALE_MSG_INVALID_LOCALE),
                err_status, true);
      goto error;
    }
      lf->locale_name = (char *) malloc (strlen (locale_str) + 1);
      if (lf->locale_name == NULL)
    {
      err_status = ER_LOC_INIT;
      LOG_LOCALE_ERROR ("memory allocation failed", err_status, true);
      goto error;
    }
      strcpy (lf->locale_name, locale_str);
      err_status = locale_check_and_set_default_files (lf, true);
    }
  else
    {
      /* Parse cubrid_locales.txt and select all locale files. */
      err_status = locale_get_cfg_locales (&lf, &count_loc, false);
    }

  if (err_status != NO_ERROR)
    {
      goto error;
    }

  if (input_path != NULL)
    {
      /* set lib file in all locales */
      for (i = 0; i < count_loc; i++)
    {
      if (lf[i].lib_file != NULL)
        {
          free_and_init (lf[i].lib_file);
        }

      lf[i].lib_file = strdup (input_path);
      if (lf[i].lib_file == NULL)
        {
          err_status = ER_LOC_INIT;
          LOG_LOCALE_ERROR ("memory allocation failed", err_status, true);
          goto error;
        }
    }
    }

  /* Do the actual dumping. */
  for (loc_index = 0; loc_index < count_loc; loc_index++)
    {
      err_status = locale_check_and_set_default_files (&(lf[loc_index]), true);
      if (err_status != NO_ERROR)
    {
      goto error;
    }

      memset (&lld, 0, sizeof (LANG_LOCALE_DATA));

      err_status = lang_load_library (lf[loc_index].lib_file, &loclib_handle);

      if (err_status != NO_ERROR)
    {
      goto error;
    }

      err_status = lang_locale_data_load_from_lib (&lld, loclib_handle, &(lf[loc_index]), true);
      if (err_status != NO_ERROR)
    {
      goto error;
    }
      err_status = locale_dump (&lld, &(lf[loc_index]), dl_settings, start_value, end_value);
      if (err_status != NO_ERROR)
    {
      goto error;
    }

      if (((dl_settings & DUMPLOCALE_IS_COLLATION_CP_ORDER) != 0)
      || ((dl_settings & DUMPLOCALE_IS_COLLATION_WEIGHT_ORDER) != 0))
    {
      err_status =
        locale_dump_lib_collations (loclib_handle, &(lf[loc_index]), dl_settings, start_value, end_value);

      if (err_status != NO_ERROR)
        {
          goto error;
        }
    }

      if (lld.txt_conv != NULL && lld.txt_conv->init_conv_func == NULL)
    {
      free (lld.txt_conv);
      lld.txt_conv = NULL;
    }

#if defined(WINDOWS)
      FreeLibrary ((HMODULE) loclib_handle);
#else
      dlclose (loclib_handle);
#endif
    }

error:
  for (i = 0; i < count_loc; i++)
    {
      if (lf[i].lib_file != NULL)
    {
      free (lf[i].lib_file);
    }
      if (lf[i].ldml_file != NULL)
    {
      free (lf[i].ldml_file);
    }
      if (lf[i].locale_name != NULL)
    {
      free (lf[i].locale_name);
    }
    }

  if (lf != &lf_one)
    {
      free (lf);
      lf = NULL;
    }

  /*
   * Text conversions having init_conv_func not NULL are built-in.
   * They can't be deallocates, as they are static constants.
   */
  if (lld.txt_conv != NULL && lld.txt_conv->init_conv_func == NULL)
    {
      free (lld.txt_conv);
      lld.txt_conv = NULL;
    }

  return err_status;

print_dumplocale_usage:
  fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_DUMPLOCALE, DUMPLOCALE_MSG_USAGE),
       basename (arg->argv0));

  return EXIT_FAILURE;
}

/*
 * synccolldb() - sync_collations main routine
 *   return: EXIT_SUCCESS/EXIT_FAILURE
 */
int
synccolldb (UTIL_FUNCTION_ARG * arg)
{
  UTIL_ARG_MAP *arg_map = arg->arg_map;
  char er_msg_file[PATH_MAX];
  const char *db_name;
  int status = EXIT_SUCCESS;
  bool is_check, is_force, is_sync = true;
  int db_obs_coll_cnt = 0;
  int new_sys_coll_cnt = 0;

  db_name = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 0);
  if (db_name == NULL)
    {
      goto print_sync_collations_usage;
    }

  if (utility_get_option_string_table_size (arg_map) != 1)
    {
      goto print_sync_collations_usage;
    }

  is_check = utility_get_option_bool_value (arg_map, SYNCCOLL_CHECK_S);
  is_force = utility_get_option_bool_value (arg_map, SYNCCOLL_FORCESYNC_S);

  if (is_check && is_force)
    {
      goto print_sync_collations_usage;
    }

  if (is_check || is_force)
    {
      is_sync = false;
    }

  if (check_database_name (db_name))
    {
      goto error_exit;
    }

  /* error message log file */
  snprintf (er_msg_file, sizeof (er_msg_file) - 1, "%s_%s.err", db_name, arg->command_name);
  er_init (er_msg_file, ER_NEVER_EXIT);

  AU_DISABLE_PASSWORDS ();
  db_set_client_type (DB_CLIENT_TYPE_ADMIN_UTILITY);
  db_login ("DBA", NULL);
  if (db_restart (arg->command_name, TRUE, db_name) != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      goto error_exit;
    }

  if (is_check || is_sync)
    {
      status = synccoll_check (db_name, &db_obs_coll_cnt, &new_sys_coll_cnt);
      if (status != EXIT_SUCCESS)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      goto exit;
    }

      if (!is_sync && (db_obs_coll_cnt != 0 || new_sys_coll_cnt != 0))
    {
      /* return error if synchronization is required */
      status = EXIT_FAILURE;
      goto exit;
    }
    }

  if (is_sync || is_force)
    {
      char yn[2];

      if (!is_force && db_obs_coll_cnt == 0 && new_sys_coll_cnt == 0)
    {
      /* message SYNCCOLLDB_MSG_SYNC_NOT_NEEDED displayed in 'synccoll_check' */
      goto exit;
    }

      if (!is_force)
    {
      fprintf (stdout,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_SYNC_CONTINUE));
      scanf ("%1s", yn);
      if (yn[0] != 'y')
        {
          PRINT_AND_LOG_ERR_MSG (msgcat_message
                     (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_SYNC_ABORT));
          goto exit;
        }
    }

      status = synccoll_force ();
      if (status != EXIT_SUCCESS)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      db_abort_transaction ();
      fprintf (stdout,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_SYNC_ABORT));
      goto exit;
    }
      else
    {
      db_commit_transaction ();
      fprintf (stdout, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_SYNC_OK),
           CT_COLLATION_NAME);
    }
    }

exit:
  db_shutdown ();

  return status;

print_sync_collations_usage:
  fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_USAGE),
       basename (arg->argv0));
  util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);

error_exit:
  return EXIT_FAILURE;
}

/*
 * synccoll_check() - sync_collations check
 *   return: EXIT_SUCCESS/EXIT_FAILURE
 */
static int
synccoll_check (const char *db_name, int *db_obs_coll_cnt, int *new_sys_coll_cnt)
{
#define FILE_STMT_NAME "cubrid_synccolldb_"

  LANG_COLL_COMPAT *db_collations = NULL;
  const LANG_COLL_COMPAT *db_coll;
  LANG_COLLATION *lc;
  FILE *f_stmt = NULL;
  char f_stmt_name[PATH_MAX];
  int sys_coll_found[LANG_MAX_COLLATIONS] = { 0 };
  int sys_coll_found_cnt = 0;
  int i, db_coll_cnt;
  int status = EXIT_SUCCESS;
  int db_status;
  bool need_manual_sync = false;
  THREAD_ENTRY *thread_p;

  assert (db_name != NULL);
  assert (db_obs_coll_cnt != NULL);
  assert (new_sys_coll_cnt != NULL);

  *db_obs_coll_cnt = 0;
  *new_sys_coll_cnt = 0;

  thread_p = thread_get_thread_entry_info ();

  /* read all collations from DB : id, name, checksum */
  db_status = catcls_get_db_collation (thread_p, &db_collations, &db_coll_cnt);
  if (db_status != NO_ERROR)
    {
      if (db_collations != NULL)
    {
      db_private_free (thread_p, db_collations);
    }
      status = EXIT_FAILURE;
      goto exit;
    }

  assert (db_collations != NULL);

  strcpy (f_stmt_name, FILE_STMT_NAME);
  strcat (f_stmt_name, db_name);
  strcat (f_stmt_name, ".sql");

  f_stmt = fopen (f_stmt_name, "wt");
  if (f_stmt == NULL)
    {
      fprintf (stderr,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_GENERIC, MSGCAT_UTIL_GENERIC_BAD_OUTPUT_FILE),
           f_stmt_name);
      goto exit;
    }

  for (i = 0; i < db_coll_cnt; i++)
    {
      int j;
      bool is_obs_coll = false;
      bool check_atts = false;
      bool check_views = false;
      bool check_triggers = false;
      bool check_func_index = false;
      bool check_tables = false;

      db_coll = &(db_collations[i]);

      assert (db_coll->coll_id >= 0 && db_coll->coll_id < LANG_MAX_COLLATIONS);

      for (j = 0; j < LANG_MAX_COLLATIONS; j++)
    {
      lc = lang_get_collation (j);
      if (strcmp (db_coll->coll_name, lc->coll.coll_name) == 0)
        {
          sys_coll_found[j] = 1;
          sys_coll_found_cnt++;
          break;
        }
    }

      /* check if same collation */
      lc = lang_get_collation (db_coll->coll_id);
      assert (lc != NULL);

      if (lc->coll.coll_id != db_coll->coll_id || lc->codeset != db_coll->codeset
      || strcasecmp (lc->coll.checksum, db_coll->checksum) != 0)
    {
      check_tables = true;
      check_views = true;
      check_atts = true;
      check_triggers = true;
      check_func_index = true;
      is_obs_coll = true;
    }
      else if (strcmp (lc->coll.coll_name, db_coll->coll_name))
    {
      check_tables = true;
      check_views = true;
      check_triggers = true;
      is_obs_coll = true;
      check_func_index = true;
    }

      if (is_obs_coll)
    {
      (*db_obs_coll_cnt)++;
      fprintf (stdout, "----------------------------------------\n");
      fprintf (stdout, "----------------------------------------\n");
      fprintf (stdout, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_OBS_COLL),
           db_coll->coll_name, db_coll->coll_id);
    }

      if (check_tables)
    {
      db_status = synccoll_check_tables (db_coll, f_stmt, &need_manual_sync);
      if (db_status != NO_ERROR)
        {
          status = EXIT_FAILURE;
          goto exit;
        }
    }

      if (check_atts)
    {
      db_status = synccoll_check_foreign_keys (db_coll, f_stmt, &need_manual_sync);
      if (db_status != NO_ERROR)
        {
          status = EXIT_FAILURE;
          goto exit;
        }

      db_status = synccoll_check_attrs (db_coll, f_stmt, &need_manual_sync);
      if (db_status != NO_ERROR)
        {
          status = EXIT_FAILURE;
          goto exit;
        }
    }

      if (check_views)
    {
      db_status = synccoll_check_views (db_coll, f_stmt, &need_manual_sync);
      if (db_status != NO_ERROR)
        {
          status = EXIT_FAILURE;
          goto exit;
        }
    }

      if (check_triggers)
    {
      db_status = synccoll_check_triggers (db_coll, f_stmt, &need_manual_sync);
      if (db_status != NO_ERROR)
        {
          status = EXIT_FAILURE;
          goto exit;
        }
    }

      if (check_func_index)
    {
      db_status = synccoll_check_function_indexes (db_coll, f_stmt, &need_manual_sync);
      if (db_status != NO_ERROR)
        {
          status = EXIT_FAILURE;
          goto exit;
        }
    }
    }

  fprintf (stdout, "----------------------------------------\n");
  fprintf (stdout, "----------------------------------------\n");
  if (*db_obs_coll_cnt == 0)
    {
      fprintf (stdout,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_REPORT_DB_OBS_OK),
           db_name);
    }
  else
    {
      fprintf (stdout,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_REPORT_DB_OBS_NOK),
           *db_obs_coll_cnt);
      if (need_manual_sync)
    {
      fprintf (stdout,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_REPORT_SQL_FILE),
           f_stmt_name);
    }
    }

  if (!need_manual_sync)
    {
      if (f_stmt != NULL)
    {
      fclose (f_stmt);
      f_stmt = NULL;
    }
      remove (f_stmt_name);
    }

  if (lang_collation_count () != sys_coll_found_cnt)
    {
      fprintf (stdout,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_REPORT_NEW_COLL),
           lang_collation_count () - sys_coll_found_cnt);

      for (i = 0; i < LANG_MAX_COLLATIONS; i++)
    {
      if (sys_coll_found[i] == 1)
        {
          continue;
        }

      lc = lang_get_collation (i);
      if (lc->coll.coll_id == LANG_COLL_DEFAULT)
        {
          assert (i != 0);
          continue;
        }

      assert (sys_coll_found[i] == 0);
      /* system collation was not found in DB */
      fprintf (stdout, "%s\n", lc->coll.coll_name);
      (*new_sys_coll_cnt)++;
    }
      fprintf (stdout, "\n");
    }

  if (*db_obs_coll_cnt == 0 && *new_sys_coll_cnt == 0)
    {
      fprintf (stdout,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_REPORT_NOT_NEEDED));
    }
  else
    {
      fprintf (stdout,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_REPORT_SYNC_REQUIRED),
           db_name);
    }

  fprintf (stdout, "----------------------------------------\n");
  fprintf (stdout, "----------------------------------------\n");

exit:
  if (f_stmt != NULL)
    {
      fclose (f_stmt);
      f_stmt = NULL;
    }

  if (db_collations != NULL)
    {
      db_private_free (thread_p, db_collations);
    }

  return status;

#undef FILE_STMT_NAME
}

static int
synccoll_check_tables (const LANG_COLL_COMPAT * db_coll, FILE * f_stmt, bool * need_manual_sync)
{
#define QUERY_BUF_SIZE 1024

  char query[QUERY_BUF_SIZE] = { 0 };
  DB_QUERY_RESULT *query_result = NULL;
  DB_QUERY_ERROR query_error;
  DB_VALUE value;
  DB_VALUE class_name_val;
  DB_VALUE owner_name_val;
  int error = NO_ERROR;

  memset (&query_error, 0, sizeof (DB_QUERY_ERROR));

  db_make_null (&value);
  db_make_null (&class_name_val);
  db_make_null (&owner_name_val);

  /* get table names having collation; do not include partition sub-classes */

  // *INDENT-OFF*
  sprintf (query,
    "SELECT "
      "[c].[class_type] AS [class_type], "
      "[c].[is_system_class] AS [is_system_class], "
      "[c].[class_name] AS [class_name], "
      "LOWER ([c].[owner].[name]) AS [owner_name] "
    "FROM "
      "[_db_class] AS [c] "
      "LEFT OUTER JOIN [_db_partition] AS [p] "
        "ON [p].[class_of] = [c] AND [p].[pname] IS NOT NULL "
    "WHERE "
      "[c].[collation_id] = %d "
      "AND [p].[pname] IS NULL",
    db_coll->coll_id);
  // *INDENT-ON*

  error = db_compile_and_execute_local (query, &query_result, &query_error);
  if (error < 0)
    {
      goto exit;
    }

  error = db_query_first_tuple (query_result);
  if (error != DB_CURSOR_SUCCESS)
    {
      if (error == DB_CURSOR_END)
    {
      error = NO_ERROR;
    }
      else
    {
      ASSERT_ERROR ();
    }

      goto exit;
    }

  fprintf (stdout, "----------------------------------------\n");
  fprintf (stdout, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_CLASS_OBS_COLL),
       db_coll->coll_name);

  do
    {
      int class_type = SM_CLASS_CT;
      int is_system_class = 0;
      const char *class_name = NULL;
      const char *owner_name = NULL;

      /* class_type */
      error = db_query_get_tuple_value (query_result, 0, &value);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&value) == DB_TYPE_INTEGER);
      class_type = db_get_int (&value);
      db_value_clear (&value);

      if (class_type != SM_CLASS_CT)
    {
      continue;
    }

      /* is_system_class */
      error = db_query_get_tuple_value (query_result, 1, &value);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&value) == DB_TYPE_INTEGER);
      is_system_class = db_get_int (&value);
      db_value_clear (&value);

      /* class_name */
      error = db_query_get_tuple_value (query_result, 2, &class_name_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&class_name_val) == DB_TYPE_STRING);
      class_name = db_get_string (&class_name_val);

      /* owner_name */
      error = db_query_get_tuple_value (query_result, 3, &owner_name_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&owner_name_val) == DB_TYPE_STRING);
      owner_name = db_get_string (&owner_name_val);

      if (is_system_class)
    {
      fprintf (stdout, "%s\n", class_name);
      fprintf (f_stmt, "ALTER TABLE [%s] COLLATE utf8_bin;\n", class_name);
    }
      else
    {
      fprintf (stdout, "%s.%s\n", owner_name, class_name);
      fprintf (f_stmt, "ALTER TABLE [%s].[%s] COLLATE utf8_bin;\n", owner_name, class_name);
    }

      *need_manual_sync = true;

      db_value_clear (&class_name_val);
      db_value_clear (&owner_name_val);
    }
  while ((error = db_query_next_tuple (query_result)) == DB_CURSOR_SUCCESS);

  if (error == DB_CURSOR_END)
    {
      error = NO_ERROR;
    }
  else
    {
      ASSERT_ERROR ();
    }

exit:
  if (query_result != NULL)
    {
      db_query_end (query_result);
      query_result = NULL;
    }

  return error;

exit_on_error:
  db_value_clear (&class_name_val);
  db_value_clear (&owner_name_val);

  if (query_result != NULL)
    {
      db_query_end (query_result);
      query_result = NULL;
    }

  return error;

#undef QUERY_BUF_SIZE
}

static int
synccoll_check_foreign_keys (const LANG_COLL_COMPAT * db_coll, FILE * f_stmt, bool * need_manual_sync)
{
#define QUERY_BUF_SIZE 1024

  char query[QUERY_BUF_SIZE] = { 0 };
  DB_QUERY_RESULT *query_result = NULL;
  DB_QUERY_ERROR query_error;
  DB_VALUE value;
  DB_VALUE class_name_val;
  DB_VALUE owner_name_val;
  DB_VALUE index_name_val;

  int error = NO_ERROR;

  memset (&query_error, 0, sizeof (DB_QUERY_ERROR));

  db_make_null (&value);
  db_make_null (&class_name_val);
  db_make_null (&owner_name_val);
  db_make_null (&index_name_val);

  /* first drop foreign keys on attributes using collation; do not include partition sub-classes */

  // *INDENT-OFF*
  sprintf (query,
    "SELECT "
      "[a].[class_of].[is_system_class] AS [is_system_class], "
      "[a].[class_of].[class_name] AS [class_name], "
      "LOWER ([a].[class_of].[owner].[name]) AS [owner_name], "
      "[i].[index_name] AS [index_name] "
    "FROM "
      "[_db_attribute] AS [a] "
      "INNER JOIN [_db_domain] AS [d] ON [d].[object_of] = [a] "
      "INNER JOIN [_db_index] AS [i] ON [i].[class_of] = [a].[class_of] "
      "INNER JOIN [_db_index_key] AS [k] "
        "ON [k].[key_attr_name] = [a].[attr_name] AND [k].[index_of] = [i] "
      "LEFT OUTER JOIN [_db_partition] AS [p] "
        "ON [p].[class_of] = [a].[class_of] AND [p].[pname] IS NOT NULL "
    "WHERE "
      "[d].[collation_id] = %d "
      "AND [i].[is_foreign_key] = 1 "
      "AND [p].[pname] IS NULL "
    "GROUP BY "
      "[a].[class_of].[class_name], "
      "[i].[index_name], "
      "[a].[class_of].[owner].[name]",
    db_coll->coll_id);
  // *INDENT-ON*

  error = db_compile_and_execute_local (query, &query_result, &query_error);
  if (error < 0)
    {
      goto exit;
    }

  error = db_query_first_tuple (query_result);
  if (error != DB_CURSOR_SUCCESS)
    {
      if (error == DB_CURSOR_END)
    {
      error = NO_ERROR;
    }
      else
    {
      ASSERT_ERROR ();
    }

      goto exit;
    }

  fprintf (stdout, "----------------------------------------\n");
  fprintf (stdout, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_FK_OBS_COLL),
       db_coll->coll_name);

  do
    {
      int is_system_class = 0;
      const char *class_name = NULL;
      const char *owner_name = NULL;
      const char *index_name = NULL;

      /* is_system_class */
      error = db_query_get_tuple_value (query_result, 0, &value);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&value) == DB_TYPE_INTEGER);
      is_system_class = db_get_int (&value);
      db_value_clear (&value);

      /* class_name */
      error = db_query_get_tuple_value (query_result, 1, &class_name_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&class_name_val) == DB_TYPE_STRING);
      class_name = db_get_string (&class_name_val);

      /* owner_name */
      error = db_query_get_tuple_value (query_result, 2, &owner_name_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&owner_name_val) == DB_TYPE_STRING);
      owner_name = db_get_string (&owner_name_val);

      /* index_name */
      error = db_query_get_tuple_value (query_result, 3, &index_name_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&index_name_val) == DB_TYPE_STRING);
      index_name = db_get_string (&index_name_val);

      if (is_system_class)
    {
      fprintf (stdout, "%s | %s\n", class_name, index_name);
      fprintf (f_stmt, "ALTER TABLE [%s] DROP FOREIGN KEY [%s];\n", class_name, index_name);
    }
      else
    {
      fprintf (stdout, "%s.%s | %s\n", owner_name, class_name, index_name);
      fprintf (f_stmt, "ALTER TABLE [%s].[%s] DROP FOREIGN KEY [%s];\n", owner_name, class_name, index_name);
    }

      *need_manual_sync = true;

      db_value_clear (&class_name_val);
      db_value_clear (&owner_name_val);
      db_value_clear (&index_name_val);
    }
  while ((error = db_query_next_tuple (query_result)) == DB_CURSOR_SUCCESS);

  if (error == DB_CURSOR_END)
    {
      error = NO_ERROR;
    }
  else
    {
      ASSERT_ERROR ();
    }

exit:
  if (query_result != NULL)
    {
      db_query_end (query_result);
      query_result = NULL;
    }

  return error;

exit_on_error:
  db_value_clear (&class_name_val);
  db_value_clear (&owner_name_val);
  db_value_clear (&index_name_val);

  if (query_result != NULL)
    {
      db_query_end (query_result);
      query_result = NULL;
    }

  return error;

#undef QUERY_BUF_SIZE
}

static int
synccoll_check_attrs (const LANG_COLL_COMPAT * db_coll, FILE * f_stmt, bool * need_manual_sync)
{
#define QUERY_BUF_SIZE 2048
#define ARRAY_DEFAULT_SIZE 10

  char query[QUERY_BUF_SIZE] = { 0 };
  DB_QUERY_RESULT *query_result = NULL;
  DB_QUERY_ERROR query_error;
  DB_VALUE value;
  DB_VALUE unique_name_val;
  DB_VALUE class_name_val;
  DB_VALUE owner_name_val;
  DB_VALUE attr_name_val;
  DB_VALUE attr_data_type_val;
  dynamic_array *partition_array = NULL;
  int partition_array_size = 0;
  int i = 0;
  int error = NO_ERROR;

  memset (&query_error, 0, sizeof (DB_QUERY_ERROR));

  db_make_null (&value);
  db_make_null (&unique_name_val);
  db_make_null (&class_name_val);
  db_make_null (&owner_name_val);
  db_make_null (&attr_name_val);
  db_make_null (&attr_data_type_val);

  partition_array = da_create (ARRAY_DEFAULT_SIZE, DB_MAX_IDENTIFIER_LENGTH);
  if (partition_array == NULL)
    {
      ERROR_SET_ERROR (error, ER_OUT_OF_VIRTUAL_MEMORY);
      goto exit;
    }

  /* attributes having collation; do not include partition sub-classes */

  // *INDENT-OFF*
  sprintf (query,
    "SELECT "
      "[a].[class_of].[class_type] AS [class_type], "
      "[a].[class_of].[is_system_class] AS [is_system_class], "
      "[a].[class_of].[unique_name] AS [unique_name], "
      "[a].[class_of].[class_name] AS [class_name], "
      "LOWER ([a].[class_of].[owner].[name]) AS [owner_name], "
      "[a].[attr_name] AS [attr_name], "
      "CASE [d].[data_type] "
        /* VARCHAR */
        "WHEN 4 THEN IF ([d].[prec] < 0, 'VARCHAR', CONCAT ('VARCHAR(', [d].[prec], ')')) "
        /* CHAR */
        "WHEN 25 THEN CONCAT ('CHAR(', [d].[prec], ')') "
        /* ENUM */
        "WHEN 35 THEN ("
        "SELECT "
          /* e.g. ENUM ('A','B','C',...,'Z') */
          "CONCAT ('ENUM (''', GROUP_CONCAT ([e].[t] SEPARATOR ''','''), ''')') "
        "FROM "
          "TABLE ([d].[enumeration]) AS [e] ([t])"
          ") "
        "END AS [data_type], "
      "CASE "
        "WHEN LOCATE ("
        "[a].[attr_name], "
        /* 8 is the position after 'SELECT '. There is one empty string after 'SELECT'.
         * So the attribute name comes after at least position 8. */
        "TRIM (SUBSTRING ([p].[pexpr] FROM 8 FOR (POSITION (' FROM ' IN [p].[pexpr]) - 8)))"
          ") > 0 THEN 1 "
        "ELSE 0 "
        "END AS [has_partition] "
    "FROM "
      "[_db_attribute] AS [a] "
      "INNER JOIN [_db_domain] AS [d] ON [d].[object_of] = [a] "
      "LEFT OUTER JOIN [_db_partition] AS [p] ON [p].[class_of] = [a].[class_of] "
    "WHERE "
      "[d].[collation_id] = %d "
      "AND [p].[pname] IS NULL "
    "ORDER BY "
      "[a].[class_of].[unique_name], "
      "[a].[attr_name]",
    db_coll->coll_id);
  // *INDENT-ON*

  error = db_compile_and_execute_local (query, &query_result, &query_error);
  if (error < 0)
    {
      goto exit;
    }

  error = db_query_first_tuple (query_result);
  if (error != DB_CURSOR_SUCCESS)
    {
      if (error == DB_CURSOR_END)
    {
      error = NO_ERROR;
    }
      else
    {
      ASSERT_ERROR ();
    }

      goto exit;
    }

  fprintf (stdout, "----------------------------------------\n");
  fprintf (stdout, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_ATTR_OBS_COLL),
       db_coll->coll_name);

  do
    {
      int class_type = SM_CLASS_CT;
      int is_system_class = 0;
      const char *unique_name = NULL;
      const char *class_name = NULL;
      const char *owner_name = NULL;
      const char *attr_name = NULL;
      const char *attr_data_type = NULL;
      int has_partition = 0;

      /* class_type */
      error = db_query_get_tuple_value (query_result, 0, &value);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&value) == DB_TYPE_INTEGER);
      class_type = db_get_int (&value);
      db_value_clear (&value);

      /* is_system_class */
      error = db_query_get_tuple_value (query_result, 1, &value);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&value) == DB_TYPE_INTEGER);
      is_system_class = db_get_int (&value);
      db_value_clear (&value);

      /* unique_name */
      error = db_query_get_tuple_value (query_result, 2, &unique_name_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&unique_name_val) == DB_TYPE_STRING);
      unique_name = db_get_string (&unique_name_val);

      /* class_name */
      error = db_query_get_tuple_value (query_result, 3, &class_name_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&class_name_val) == DB_TYPE_STRING);
      class_name = db_get_string (&class_name_val);

      /* owner_name */
      error = db_query_get_tuple_value (query_result, 4, &owner_name_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&owner_name_val) == DB_TYPE_STRING);
      owner_name = db_get_string (&owner_name_val);

      /* attr_name */
      error = db_query_get_tuple_value (query_result, 5, &attr_name_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&attr_name_val) == DB_TYPE_STRING);
      attr_name = db_get_string (&attr_name_val);

      /* attr_data_type */
      error = db_query_get_tuple_value (query_result, 6, &attr_data_type_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&attr_data_type_val) == DB_TYPE_STRING);
      attr_data_type = db_get_string (&attr_data_type_val);

      /* has_partition */
      error = db_query_get_tuple_value (query_result, 7, &value);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&value) == DB_TYPE_INTEGER);
      has_partition = db_get_int (&value);
      db_value_clear (&value);

      fprintf (stdout, "%s | %s %s\n", unique_name, attr_name, attr_data_type);

      if (class_type == SM_CLASS_CT)
    {
      if (has_partition == 1)
        {
          /* class is partitioned, remove partition; we cannot change the collation of an attribute
           * having partitions */

          error = da_add (partition_array, unique_name);
          if (error != NO_ERROR)
        {
          ERROR_SET_ERROR (error, ER_OUT_OF_VIRTUAL_MEMORY);
          goto exit_on_error;
        }

          if (is_system_class)
        {
          fprintf (f_stmt, "ALTER TABLE [%s] REMOVE PARTITIONING;\n", class_name);
          fprintf (f_stmt, "ALTER TABLE [%s] MODIFY [%s] %s COLLATE utf8_bin;\n", class_name, attr_name,
               attr_data_type);
        }
          else
        {
          fprintf (f_stmt, "ALTER TABLE [%s].[%s] REMOVE PARTITIONING;\n", owner_name, class_name);
          fprintf (f_stmt, "ALTER TABLE [%s].[%s] MODIFY [%s] %s COLLATE utf8_bin;\n", owner_name, class_name,
               attr_name, attr_data_type);
        }
        }
      else
        {
          if (is_system_class)
        {
          fprintf (f_stmt, "ALTER TABLE [%s] MODIFY [%s] %s COLLATE utf8_bin;\n", class_name, attr_name,
               attr_data_type);
        }
          else
        {
          fprintf (f_stmt, "ALTER TABLE [%s].[%s] MODIFY [%s] %s COLLATE utf8_bin;\n", owner_name, class_name,
               attr_name, attr_data_type);
        }
        }
    }
      else
    {
      assert (class_type == SM_VCLASS_CT);

      if (is_system_class)
        {
          fprintf (f_stmt, "DROP VIEW [%s];\n", class_name);
        }
      else
        {
          fprintf (f_stmt, "DROP VIEW [%s].[%s];\n", owner_name, class_name);
        }
    }

      *need_manual_sync = true;

      db_value_clear (&unique_name_val);
      db_value_clear (&owner_name_val);
      db_value_clear (&class_name_val);
      db_value_clear (&attr_name_val);
      db_value_clear (&attr_data_type_val);
    }
  while ((error = db_query_next_tuple (query_result)) == DB_CURSOR_SUCCESS);

  if (error == DB_CURSOR_END)
    {
      error = NO_ERROR;
    }
  else
    {
      ASSERT_ERROR ();
    }

  partition_array_size = da_size (partition_array);
  if (partition_array_size > 0)
    {
      fprintf (stdout, "----------------------------------------\n");
      fprintf (stdout,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_PARTITION_OBS_COLL),
           db_coll->coll_name);

      for (i = 0; i < partition_array_size; i++)
    {
      char partition_name[DB_MAX_IDENTIFIER_LENGTH] = { 0 };

      error = da_get (partition_array, i, partition_name);
      if (error != NO_ERROR)
        {
          ERROR_SET_ERROR (error, ER_GENERIC_ERROR);
          goto exit_on_error;
        }

      printf ("%s\n", partition_name);
    }
    }

exit:
  da_destroy (partition_array);

  if (query_result != NULL)
    {
      db_query_end (query_result);
      query_result = NULL;
    }

  return error;

exit_on_error:
  db_value_clear (&unique_name_val);
  db_value_clear (&class_name_val);
  db_value_clear (&owner_name_val);
  db_value_clear (&attr_name_val);
  db_value_clear (&attr_data_type_val);

  da_destroy (partition_array);

  if (query_result != NULL)
    {
      db_query_end (query_result);
      query_result = NULL;
    }

  return error;

#undef QUERY_BUF_SIZE
#undef ARRAY_DEFAULT_SIZE
}

static int
synccoll_check_views (const LANG_COLL_COMPAT * db_coll, FILE * f_stmt, bool * need_manual_sync)
{
#define QUERY_BUF_SIZE 1024

  char query[QUERY_BUF_SIZE] = { 0 };
  DB_QUERY_RESULT *query_result = NULL;
  DB_QUERY_ERROR query_error;
  DB_VALUE value;
  DB_VALUE view_name_val;
  DB_VALUE owner_name_val;
  DB_VALUE query_spec_val;
  int error = NO_ERROR;

  memset (&query_error, 0, sizeof (DB_QUERY_ERROR));

  db_make_null (&value);
  db_make_null (&view_name_val);
  db_make_null (&owner_name_val);
  db_make_null (&query_spec_val);

  // *INDENT-OFF*
  sprintf (query,
    "SELECT "
      "[q].[class_of].[is_system_class] AS [is_system_class], "
      "[q].[class_of].[class_name] AS [view_name], "
      "LOWER ([q].[class_of].[owner].[name]) AS [owner_name], "
      "[q].[spec] AS [spec], "
      "CASE WHEN [a].[class_of] IS NULL THEN 1 ELSE 0 END AS [need_check] "
    "FROM "
      "[_db_query_spec] AS [q] "
      "LEFT OUTER JOIN ("
          "SELECT "
        "[a].[class_of] AS [class_of] "
          "FROM "
        "[_db_attribute] AS [a] "
        "INNER JOIN [_db_domain] AS [d] ON [d].[object_of] = [a] "
          "WHERE "
        "[d].[collation_id] = %d "
          "GROUP BY "
        "[a].[class_of] "
        ") AS [a] ON [a].[class_of] = [q].[class_of]"
    "WHERE "
      "LOCATE ('collate %s', [q].[spec]) > 0 "
      /* This is to distinguish between "collate utf8_de_exp" and "collate utf8_de_exp_ai_ci".
       * This is just one example, other collations could be the target. */
      "AND LOCATE ('collate %s', [q].[spec]) != LOCATE ('collate %s_', [q].[spec])",
    db_coll->coll_id,
    db_coll->coll_name,
    db_coll->coll_name,
    db_coll->coll_name);
  // *INDENT-ON*

  error = db_compile_and_execute_local (query, &query_result, &query_error);
  if (error < 0)
    {
      goto exit;
    }

  error = db_query_first_tuple (query_result);
  if (error != DB_CURSOR_SUCCESS)
    {
      if (error == DB_CURSOR_END)
    {
      error = NO_ERROR;
    }
      else
    {
      ASSERT_ERROR ();
    }

      goto exit;
    }

  fprintf (stdout, "----------------------------------------\n");
  fprintf (stdout, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_VIEW_OBS_COLL),
       db_coll->coll_name);

  do
    {
      int is_system_class = 0;
      const char *view_name = NULL;
      const char *owner_name = NULL;
      const char *query_spec = NULL;
      int need_check = 0;

      /* is_system_class */
      error = db_query_get_tuple_value (query_result, 0, &value);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&value) == DB_TYPE_INTEGER);
      is_system_class = db_get_int (&value);
      db_value_clear (&value);

      /* view_name */
      error = db_query_get_tuple_value (query_result, 1, &view_name_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&view_name_val) == DB_TYPE_STRING);
      view_name = db_get_string (&view_name_val);

      /* owner_name */
      error = db_query_get_tuple_value (query_result, 2, &owner_name_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&owner_name_val) == DB_TYPE_STRING);
      owner_name = db_get_string (&owner_name_val);

      /* query_spec */
      error = db_query_get_tuple_value (query_result, 3, &query_spec_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&query_spec_val) == DB_TYPE_STRING);
      query_spec = db_get_string (&query_spec_val);

      /* need_check */
      error = db_query_get_tuple_value (query_result, 4, &value);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&value) == DB_TYPE_INTEGER);
      need_check = db_get_int (&value);
      db_value_clear (&value);

      if (is_system_class)
    {
      fprintf (stdout, "%s | %s\n", view_name, query_spec);

      if (need_check == 1)
        {
          fprintf (f_stmt, "DROP VIEW [%s];\n", view_name);
        }
    }
      else
    {
      fprintf (stdout, "%s.%s | %s\n", owner_name, view_name, query_spec);

      if (need_check == 1)
        {
          fprintf (f_stmt, "DROP VIEW [%s].[%s];\n", owner_name, view_name);
        }
    }

      *need_manual_sync = true;

      db_value_clear (&view_name_val);
      db_value_clear (&owner_name_val);
      db_value_clear (&query_spec_val);
    }
  while ((error = db_query_next_tuple (query_result)) == DB_CURSOR_SUCCESS);

  if (error == DB_CURSOR_END)
    {
      error = NO_ERROR;
    }
  else
    {
      ASSERT_ERROR ();
    }

exit:
  if (query_result != NULL)
    {
      db_query_end (query_result);
      query_result = NULL;
    }

  return error;

exit_on_error:
  db_value_clear (&view_name_val);
  db_value_clear (&owner_name_val);
  db_value_clear (&query_spec_val);

  if (query_result != NULL)
    {
      db_query_end (query_result);
      query_result = NULL;
    }

  return error;

#undef QUERY_BUF_SIZE
}

static int
synccoll_check_triggers (const LANG_COLL_COMPAT * db_coll, FILE * f_stmt, bool * need_manual_sync)
{
#define QUERY_BUF_SIZE 1024

  char query[QUERY_BUF_SIZE] = { 0 };
  DB_QUERY_RESULT *query_result = NULL;
  DB_QUERY_ERROR query_error;
  DB_VALUE trigger_name_val;
  DB_VALUE owner_name_val;
  DB_VALUE trigger_cond_val;

  int error = NO_ERROR;

  memset (&query_error, 0, sizeof (DB_QUERY_ERROR));

  db_make_null (&trigger_name_val);
  db_make_null (&owner_name_val);
  db_make_null (&trigger_cond_val);

  // *INDENT-OFF*
  sprintf (query,
    "SELECT "
      "[t].[name] AS [trigger_name], "
      "LOWER ([t].[owner].[name]) AS [owner_name], "
      "[t].[condition] AS [condition] "
    "FROM "
      "[_db_trigger] AS [t] "
    "WHERE "
      "LOCATE ('collate %s', [t].[condition]) > 0",
    db_coll->coll_name);
  // *INDENT-ON*

  error = db_compile_and_execute_local (query, &query_result, &query_error);
  if (error < 0)
    {
      goto exit;
    }

  error = db_query_first_tuple (query_result);
  if (error != DB_CURSOR_SUCCESS)
    {
      if (error == DB_CURSOR_END)
    {
      error = NO_ERROR;
    }
      else
    {
      ASSERT_ERROR ();
    }

      goto exit;
    }

  fprintf (stdout, "----------------------------------------\n");
  fprintf (stdout, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_TRIG_OBS_COLL),
       db_coll->coll_name);

  do
    {
      const char *trigger_name = NULL;
      const char *owner_name = NULL;
      const char *trigger_cond = NULL;

      /* trigger_name */
      error = db_query_get_tuple_value (query_result, 0, &trigger_name_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&trigger_name_val) == DB_TYPE_STRING);
      trigger_name = db_get_string (&trigger_name_val);

      /* owner_name */
      error = db_query_get_tuple_value (query_result, 1, &owner_name_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&owner_name_val) == DB_TYPE_STRING);
      owner_name = db_get_string (&owner_name_val);
      assert (owner_name != NULL);

      /* trigger_cond */
      error = db_query_get_tuple_value (query_result, 2, &trigger_cond_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&trigger_cond_val) == DB_TYPE_STRING);
      trigger_cond = db_get_string (&trigger_cond_val);

      fprintf (stdout, "%s.%s | %s\n", owner_name, trigger_name, trigger_cond);
      fprintf (f_stmt, "DROP TRIGGER [%s].[%s];\n", owner_name, trigger_name);

      *need_manual_sync = true;

      db_value_clear (&trigger_name_val);
      db_value_clear (&owner_name_val);
      db_value_clear (&trigger_cond_val);
    }
  while ((error = db_query_next_tuple (query_result)) == DB_CURSOR_SUCCESS);

  if (error == DB_CURSOR_END)
    {
      error = NO_ERROR;
    }
  else
    {
      ASSERT_ERROR ();
    }

exit:
  if (query_result != NULL)
    {
      db_query_end (query_result);
      query_result = NULL;
    }

  return error;

exit_on_error:
  db_value_clear (&trigger_name_val);
  db_value_clear (&owner_name_val);
  db_value_clear (&trigger_cond_val);

  if (query_result != NULL)
    {
      db_query_end (query_result);
      query_result = NULL;
    }

  return error;

#undef QUERY_BUF_SIZE
}

static int
synccoll_check_function_indexes (const LANG_COLL_COMPAT * db_coll, FILE * f_stmt, bool * need_manual_sync)
{
#define QUERY_BUF_SIZE 1024

  char query[QUERY_BUF_SIZE] = { 0 };
  DB_QUERY_RESULT *query_result = NULL;
  DB_QUERY_ERROR query_error;
  DB_VALUE value;
  DB_VALUE class_name_val;
  DB_VALUE owner_name_val;
  DB_VALUE index_name_val;
  DB_VALUE index_func_expr_val;
  int error = NO_ERROR;

  memset (&query_error, 0, sizeof (DB_QUERY_ERROR));

  db_make_null (&value);
  db_make_null (&class_name_val);
  db_make_null (&owner_name_val);
  db_make_null (&index_name_val);
  db_make_null (&index_func_expr_val);

  /* Function indexes using collation; do not include partition sub-classes */

  /* The condition of "[p].[class_of] = [k].[index_of].[class_of]" cannot be used as a join condition
   * because a path expression is used. So, INNER JOIN of _db_index and _db_index_key is required. */

  // *INDENT-OFF*
  sprintf (query,
    "SELECT "
      "[k].[index_of].[class_of].[is_system_class] AS [is_system_class], "
      "[k].[index_of].[class_of].[class_name] AS [class_name], "
      "LOWER ([k].[index_of].[class_of].[owner].[name]) AS [owner_name], "
      "[k].[index_of].[index_name] AS [index_name], "
      "[k].[func] AS [func] "
    "FROM "
      "[_db_index] AS [i] "
      "INNER JOIN [_db_index_key] AS [k] ON [k].[index_of] = [i] "
      "LEFT OUTER JOIN [_db_partition] AS [p] "
        "ON [p].[class_of] = [i].[class_of] AND [p].[pname] IS NOT NULL "
    "WHERE "
      "LOCATE ('%s', [k].[func]) > 0 " /* Why not 'collate %s'? */
      "AND [p].[pname] IS NULL",
    db_coll->coll_name);
  // *INDENT-ON*

  error = db_compile_and_execute_local (query, &query_result, &query_error);
  if (error < 0)
    {
      goto exit;
    }

  error = db_query_first_tuple (query_result);
  if (error != DB_CURSOR_SUCCESS)
    {
      if (error == DB_CURSOR_END)
    {
      error = NO_ERROR;
    }
      else
    {
      ASSERT_ERROR ();
    }

      goto exit;
    }

  fprintf (stdout, "----------------------------------------\n");
  fprintf (stdout, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_SYNCCOLLDB, SYNCCOLLDB_MSG_FI_OBS_COLL),
       db_coll->coll_name);

  do
    {
      int is_system_class = 0;
      const char *class_name = NULL;
      const char *owner_name = NULL;
      const char *index_name = NULL;
      const char *index_func_expr = NULL;

      /* is_system_class */
      error = db_query_get_tuple_value (query_result, 0, &value);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&value) == DB_TYPE_INTEGER);
      is_system_class = db_get_int (&value);
      db_value_clear (&value);

      /* class_name */
      error = db_query_get_tuple_value (query_result, 1, &class_name_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&class_name_val) == DB_TYPE_STRING);
      class_name = db_get_string (&class_name_val);

      /* owner_name */
      error = db_query_get_tuple_value (query_result, 2, &owner_name_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&owner_name_val) == DB_TYPE_STRING);
      owner_name = db_get_string (&owner_name_val);

      /* index_name */
      error = db_query_get_tuple_value (query_result, 3, &index_name_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&index_name_val) == DB_TYPE_STRING);
      index_name = db_get_string (&index_name_val);

      /* index_func_expr */
      error = db_query_get_tuple_value (query_result, 4, &index_func_expr_val);
      if (error != NO_ERROR)
    {
      ASSERT_ERROR ();
      goto exit_on_error;
    }
      assert (DB_VALUE_TYPE (&index_func_expr_val) == DB_TYPE_STRING);
      index_func_expr = db_get_string (&index_func_expr_val);

      if (is_system_class)
    {
      fprintf (stdout, "%s | %s | %s\n", class_name, index_name, index_func_expr);
      fprintf (f_stmt, "ALTER TABLE [%s] DROP INDEX [%s];\n", class_name, index_name);
    }
      else
    {
      fprintf (stdout, "%s.%s | %s | %s\n", owner_name, class_name, index_name, index_func_expr);
      fprintf (f_stmt, "ALTER TABLE [%s].[%s] DROP INDEX [%s];\n", owner_name, class_name, index_name);
    }

      *need_manual_sync = true;

      db_value_clear (&class_name_val);
      db_value_clear (&owner_name_val);
      db_value_clear (&index_name_val);
      db_value_clear (&index_func_expr_val);
    }
  while ((error = db_query_next_tuple (query_result)) == DB_CURSOR_SUCCESS);

  if (error == DB_CURSOR_END)
    {
      error = NO_ERROR;
    }
  else
    {
      ASSERT_ERROR ();
    }

exit:
  if (query_result != NULL)
    {
      db_query_end (query_result);
      query_result = NULL;
    }

  return error;

exit_on_error:
  db_value_clear (&class_name_val);
  db_value_clear (&owner_name_val);
  db_value_clear (&index_name_val);
  db_value_clear (&index_func_expr_val);

  if (query_result != NULL)
    {
      db_query_end (query_result);
      query_result = NULL;
    }

  return error;

#undef QUERY_BUF_SIZE
}

/*
 * synccoll_force() - sync_collations force new collation into DB
 *   return: EXIT_SUCCESS/EXIT_FAILURE
 */
int
synccoll_force (void)
{
  DB_OBJECT *class_mop;
  int status = EXIT_SUCCESS;
  int au_save;

  class_mop = db_find_class (CT_COLLATION_NAME);
  if (class_mop == NULL)
    {
      status = EXIT_FAILURE;
      return status;
    }

  AU_DISABLE (au_save);
  if (db_truncate_class (class_mop, false) != NO_ERROR)
    {
      AU_ENABLE (au_save);
      status = EXIT_FAILURE;
      return status;
    }

  if (catcls_add_collations (class_mop) != NO_ERROR)
    {
      status = EXIT_FAILURE;
    }

  AU_ENABLE (au_save);
  return status;
}

/*
 * delete_all_ha_apply_info () - delete ha apply info
 *   return:
 */
static int
delete_all_ha_apply_info (void)
{
#define QUERY_BUF_SIZE      2048

  int res, au_save;
  DB_QUERY_RESULT *result;
  DB_QUERY_ERROR query_error;
  char query_buf[QUERY_BUF_SIZE];

  snprintf (query_buf, sizeof (query_buf), "DELETE FROM %s ;", CT_HA_APPLY_INFO_NAME);

  AU_DISABLE (au_save);

  res = db_execute (query_buf, &result, &query_error);
  if (res >= 0)
    {
      int error;

      error = db_query_end (result);
      if (error != NO_ERROR)
    {
      res = error;
    }
    }

  AU_ENABLE (au_save);

  return res;
#undef QUERY_BUF_SIZE
}

/*
 * insert_ha_apply_info () - insert ha apply info
 *   return:
 */
static int
insert_ha_apply_info (char *database_name, char *master_host_name, INT64 database_creation, INT64 pageid, int offset,
              INT64 committed_pageid, int committed_offset)
{
#define APPLY_INFO_VALUES   15
#define QUERY_BUF_SIZE      2048

  int i, res, au_save;
  int in_value_idx;
  char *copy_log_base;
  char copy_log_base_buf[PATH_MAX];
  char log_path[PATH_MAX];
  char query_buf[QUERY_BUF_SIZE];
  DB_VALUE in_value[APPLY_INFO_VALUES];
  DB_DATETIME db_creation;
  DB_QUERY_RESULT *result;
  DB_QUERY_ERROR query_error;

  db_localdatetime (&database_creation, &db_creation);
  copy_log_base = prm_get_string_value (PRM_ID_HA_COPY_LOG_BASE);
  if (copy_log_base == NULL || *copy_log_base == '\0')
    {
      copy_log_base = (char *) envvar_get ("DATABASES");
      if (copy_log_base == NULL)
    {
      return ER_FAILED;
    }
    }

  copy_log_base = realpath (copy_log_base, copy_log_base_buf);
  snprintf (log_path, PATH_MAX, "%s/%s_%s", copy_log_base, database_name, master_host_name);

  snprintf (query_buf, sizeof (query_buf), "INSERT INTO %s "    /* INSERT */
        "( db_name, "   /* 1 */
        "  db_creation_time, "  /* 2 */
        "  copied_log_path, "   /* 3 */
        "  committed_lsa_pageid, "  /* 4 */
        "  committed_lsa_offset, "  /* 5 */
        "  committed_rep_pageid, "  /* 6 */
        "  committed_rep_offset, "  /* 7 */
        "  append_lsa_pageid, " /* 8 */
        "  append_lsa_offset, " /* 9 */
        "  eof_lsa_pageid, "    /* 10 */
        "  eof_lsa_offset, "    /* 11 */
        "  final_lsa_pageid, "  /* 12 */
        "  final_lsa_offset, "  /* 13 */
        "  required_lsa_pageid, "   /* 14 */
        "  required_lsa_offset, "   /* 15 */
        "  log_record_time, "   /* 16 */
        "  log_commit_time, "   /* 17 */
        "  last_access_time, "  /* 18 */
        "  status, "    /* 19 */
        "  insert_counter, "    /* 20 */
        "  update_counter, "    /* 21 */
        "  delete_counter, "    /* 22 */
        "  schema_counter, "    /* 23 */
        "  commit_counter, "    /* 24 */
        "  fail_counter, "  /* 25 */
        "  start_time ) "   /* 26 */
        " VALUES ( ?, " /* 1. db_name */
        "   ?, "        /* 2. db_creation_time */
        "   ?, "        /* 3. copied_log_path */
        "   ?, "        /* 4. committed_lsa_pageid */
        "   ?, "        /* 5. committed_lsa_offset */
        "   ?, "        /* 6. committed_rep_pageid */
        "   ?, "        /* 7. committed_rep_offset */
        "   ?, "        /* 8. append_lsa_pageid */
        "   ?, "        /* 9. append_lsa_offset */
        "   ?, "        /* 10. eof_lsa_pageid */
        "   ?, "        /* 11. eof_lsa_offset */
        "   ?, "        /* 12. final_lsa_pageid */
        "   ?, "        /* 13. final_lsa_offset */
        "   ?, "        /* 14. required_lsa_pageid */
        "   ?, "        /* 15. required_lsa_offset */
        "   NULL, "     /* 16. log_record_time */
        "   NULL, "     /* 17. log_commit_time */
        "   NULL, "     /* 18. last_access_time */
        "   0, "        /* 19. status */
        "   0, "        /* 20. insert_counter */
        "   0, "        /* 21. update_counter */
        "   0, "        /* 22. delete_counter */
        "   0, "        /* 23. schema_counter */
        "   0, "        /* 24. commit_counter */
        "   0, "        /* 25. fail_counter */
        "   NULL "      /* 26. start_time */
        "   ) ;", CT_HA_APPLY_INFO_NAME);

  in_value_idx = 0;

  /* 1. db_name */
  db_make_varchar (&in_value[in_value_idx++], 255, database_name, strlen (database_name), LANG_SYS_CODESET,
           LANG_SYS_COLLATION);

  /* 2. db_creation time */
  db_make_datetime (&in_value[in_value_idx++], &db_creation);

  /* 3. copied_log_path */
  db_make_varchar (&in_value[in_value_idx++], 4096, log_path, strlen (log_path), LANG_SYS_CODESET, LANG_SYS_COLLATION);

  /* 4 ~ 5. committed lsa */
  db_make_bigint (&in_value[in_value_idx++], committed_pageid);
  db_make_int (&in_value[in_value_idx++], committed_offset);

  /* 6 ~ 15. lsa */
  for (i = 0; i < 5; i++)
    {
      db_make_bigint (&in_value[in_value_idx++], pageid);
      db_make_int (&in_value[in_value_idx++], offset);
    }

  assert_release (in_value_idx == APPLY_INFO_VALUES);

  AU_DISABLE (au_save);

  res = db_execute_with_values (query_buf, &result, &query_error, in_value_idx, &in_value[0]);
  if (res >= 0)
    {
      int error;

      error = db_query_end (result);
      if (error != NO_ERROR)
    {
      res = error;
    }
    }

  AU_ENABLE (au_save);

  for (i = 0; i < in_value_idx; i++)
    {
      db_value_clear (&in_value[i]);
    }

  return res;

#undef APPLY_INFO_VALUES
#undef QUERY_BUF_SIZE
}

/*
 * delete_all_slave_ha_apply_info () - delete slave ha apply info
 *   return:
 */
static int
delete_all_slave_ha_apply_info (char *database_name, char *master_host_name)
{
#define APPLY_INFO_VALUES   2
#define QUERY_BUF_SIZE      2048

  int res, au_save;
  int in_value_idx;
  char *copy_log_base;
  char copy_log_base_buf[PATH_MAX];
  char log_path[PATH_MAX];
  DB_VALUE in_value[APPLY_INFO_VALUES];
  DB_QUERY_RESULT *result;
  DB_QUERY_ERROR query_error;
  char query_buf[QUERY_BUF_SIZE];

  copy_log_base = prm_get_string_value (PRM_ID_HA_COPY_LOG_BASE);
  if (copy_log_base == NULL || *copy_log_base == '\0')
    {
      copy_log_base = (char *) envvar_get ("DATABASES");
      if (copy_log_base == NULL)
    {
      return ER_FAILED;
    }
    }

  copy_log_base = realpath (copy_log_base, copy_log_base_buf);
  snprintf (log_path, PATH_MAX, "%s/%s_%s", copy_log_base, database_name, master_host_name);

  snprintf (query_buf, sizeof (query_buf), "DELETE FROM %s " "WHERE db_name = ? and copied_log_path <> ?",
        CT_HA_APPLY_INFO_NAME);

  in_value_idx = 0;
  /* 1. db_name */
  db_make_varchar (&in_value[in_value_idx++], 255, database_name, strlen (database_name), LANG_SYS_CODESET,
           LANG_SYS_COLLATION);

  /* 2. copied_log_path */
  db_make_varchar (&in_value[in_value_idx++], 4096, log_path, strlen (log_path), LANG_SYS_CODESET, LANG_SYS_COLLATION);

  AU_DISABLE (au_save);

  res = db_execute_with_values (query_buf, &result, &query_error, in_value_idx, &in_value[0]);
  if (res >= 0)
    {
      int error;

      error = db_query_end (result);
      if (error != NO_ERROR)
    {
      res = error;
    }
    }

  AU_ENABLE (au_save);

  return res;
#undef APPLY_INFO_VALUES
#undef QUERY_BUF_SIZE
}

/*
 * check_ha_db_and_node_list () - check ha db list and ha node list
 *   return:
 */
static bool
check_ha_db_and_node_list (char *database_name, char *source_host_name)
{
  int i, j, status, num_nodes;
  char **dbs;
  HA_CONF ha_conf;
  HA_NODE_CONF *nc;

  memset ((void *) &ha_conf, 0, sizeof (HA_CONF));
  status = util_make_ha_conf (&ha_conf);
  if (status != NO_ERROR)
    {
      return false;
    }

  num_nodes = ha_conf.num_node_conf;
  dbs = ha_conf.db_names;
  nc = ha_conf.node_conf;

  for (i = 0; dbs[i] != NULL; i++)
    {
      if (strcmp (dbs[i], database_name) != 0)
    {
      continue;
    }

      for (j = 0; j < num_nodes; j++)
    {
      if (strcmp (nc[j].node_name, source_host_name) != 0)
        {
          continue;
        }

      if (util_is_localhost (nc[j].node_name))
        {
          continue;
        }

      util_free_ha_conf (&ha_conf);
      return true;
    }
    }

  util_free_ha_conf (&ha_conf);
  return false;
}

/*
 * restoreslave() - restoreslave main routine
 *   return: EXIT_SUCCESS/EXIT_FAILURE
 */
int
restoreslave (UTIL_FUNCTION_ARG * arg)
{
  UTIL_ARG_MAP *arg_map = arg->arg_map;
  DB_DATETIME datetime;
  bool init_ha_catalog;
  int status, error_code;
  char er_msg_file[PATH_MAX];
  char db_creation_time[LINE_MAX];
  char *database_name;
  char *source_state;
  char *master_host_name;
  const char *mk_path;
  BO_RESTART_ARG restart_arg;

  if (sysprm_load_and_init (NULL, NULL, SYSPRM_LOAD_ALL) != NO_ERROR)
    {
      util_log_write_errid (MSGCAT_UTIL_GENERIC_SERVICE_PROPERTY_FAIL);
      goto error_exit;
    }

  database_name = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 0);
  master_host_name = utility_get_option_string_value (arg_map, RESTORESLAVE_MASTER_HOST_NAME_S, 0);
  source_state = utility_get_option_string_value (arg_map, RESTORESLAVE_SOURCE_STATE_S, 0);

  if (master_host_name == NULL || source_state == NULL)
    {
      goto print_restoreslave_usage;
    }

  if (strcasecmp (source_state, "master") == 0)
    {
      init_ha_catalog = true;
    }
  else if (strcasecmp (source_state, "slave") == 0 || strcasecmp (source_state, "replica") == 0)
    {
      init_ha_catalog = false;
    }
  else
    {
      fprintf (stderr,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_RESTORESLAVE, RESTORESLAVE_MSG_INVAILD_STATE),
           source_state);
      goto error_exit;
    }

  restart_arg.restore_slave = true;
  restart_arg.printtoc = utility_get_option_bool_value (arg_map, RESTORESLAVE_LIST_S);
  restart_arg.backuppath = utility_get_option_string_value (arg_map, RESTORESLAVE_BACKUP_FILE_PATH_S, 0);
  restart_arg.level = 0;
  restart_arg.verbose_file = utility_get_option_string_value (arg_map, RESTORESLAVE_OUTPUT_FILE_S, 0);
  restart_arg.newvolpath = utility_get_option_bool_value (arg_map, RESTORESLAVE_USE_DATABASE_LOCATION_PATH_S);
  mk_path = utility_get_option_string_value (arg_map, RESTORE_KEYS_FILE_PATH_S, 0);
  restart_arg.restore_upto_bktime = false;
  restart_arg.stopat = time (NULL);
  restart_arg.is_restore_from_backup = false;

  if (mk_path != NULL)
    {
      memcpy (restart_arg.keys_file_path, mk_path, PATH_MAX);
    }
  else
    {
      restart_arg.keys_file_path[0] = '\0';
    }

  if (utility_get_option_string_table_size (arg_map) != 1)
    {
      goto print_restoreslave_usage;
    }

  if (check_ha_db_and_node_list (database_name, master_host_name) == false)
    {
      fprintf (stderr,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_RESTORESLAVE, RESTORESLAVE_MSG_INVAILD_OPTIONS));
      goto error_exit;
    }

  /* error message log file */
  snprintf (er_msg_file, sizeof (er_msg_file) - 1, "%s_%s.err", database_name, arg->command_name);
  er_init (er_msg_file, ER_NEVER_EXIT);

  if (restart_arg.printtoc)
    {
      error_code = print_backup_info (database_name, &restart_arg);
      if (error_code != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      fprintf (stderr,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_RESTORESLAVE, RESTORESLAVE_MSG_FAILURE));
      goto error_exit;
    }

      return EXIT_SUCCESS;
    }

  AU_DISABLE_PASSWORDS ();
  db_set_client_type (DB_CLIENT_TYPE_ADMIN_UTILITY);
  db_login ("DBA", NULL);

  status = boot_restart_from_backup (true, database_name, &restart_arg);
  if (status == NULL_TRAN_INDEX)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_RESTORESLAVE, RESTORESLAVE_MSG_FAILURE));
      goto error_exit;
    }
  else
    {
      boot_shutdown_server (ER_ALL_FINAL);
    }

  db_localdatetime (&restart_arg.db_creation, &datetime);
  db_datetime_to_string (db_creation_time, LINE_MAX, &datetime);

  if (db_restart (arg->command_name, TRUE, database_name) != NO_ERROR)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      fprintf (stderr,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_RESTORESLAVE, RESTORESLAVE_MSG_HA_CATALOG_FAIL),
           db_creation_time, restart_arg.restart_repl_lsa.pageid, restart_arg.restart_repl_lsa.offset);
      return EXIT_FAILURE;
    }

  if (init_ha_catalog)
    {
      error_code = delete_all_ha_apply_info ();
      if (error_code < 0)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      fprintf (stderr,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_RESTORESLAVE,
                   RESTORESLAVE_MSG_HA_CATALOG_FAIL), db_creation_time,
           restart_arg.restart_repl_lsa.pageid, restart_arg.restart_repl_lsa.offset);
      db_shutdown ();
      return EXIT_FAILURE;
    }

      error_code =
    insert_ha_apply_info (database_name, master_host_name, restart_arg.db_creation,
                  restart_arg.restart_repl_lsa.pageid, (int) restart_arg.restart_repl_lsa.offset,
                  restart_arg.restart_committed_lsa.pageid, (int) restart_arg.restart_committed_lsa.offset);
      if (error_code < 0)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      fprintf (stderr,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_RESTORESLAVE,
                   RESTORESLAVE_MSG_HA_CATALOG_FAIL), db_creation_time,
           restart_arg.restart_repl_lsa.pageid, restart_arg.restart_repl_lsa.offset);
      db_shutdown ();
      return EXIT_FAILURE;
    }
    }
  else
    {
      error_code = delete_all_slave_ha_apply_info (database_name, master_host_name);
      if (error_code < 0)
    {
      PRINT_AND_LOG_ERR_MSG ("%s\n", db_error_string (3));
      fprintf (stderr,
           msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_RESTORESLAVE,
                   RESTORESLAVE_MSG_HA_CATALOG_FAIL), db_creation_time,
           restart_arg.restart_repl_lsa.pageid, restart_arg.restart_repl_lsa.offset);
      db_shutdown ();
      return EXIT_FAILURE;
    }

    }
  db_commit_transaction ();
  db_shutdown ();

  return EXIT_SUCCESS;

print_restoreslave_usage:
  fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_RESTORESLAVE, RESTORESLAVE_MSG_USAGE),
       basename (arg->argv0));
  util_log_write_errid (MSGCAT_UTIL_GENERIC_INVALID_ARGUMENT);

error_exit:
  return EXIT_FAILURE;
}

/*
 * gen_tz() - generate time zone data as a C source file, to be compiled into
 *        a shared library (DLL/so) using included makefile/build script
 *   return: EXIT_SUCCESS/EXIT_FAILURE
 */
int
gen_tz (UTIL_FUNCTION_ARG * arg)
{
  UTIL_ARG_MAP *arg_map = NULL;
  char *input_path = NULL;
  char inputpath_local[PATH_MAX] = { 0 };
  char *tz_gen_mode = NULL;
  TZ_GEN_TYPE tz_gen_type = TZ_GEN_TYPE_NEW;
  int exit_status = EXIT_SUCCESS;
  char checksum[TZ_CHECKSUM_SIZE + 1];
  bool need_db_shutdown = false;
  bool er_inited = false;
  DB_INFO *dir = NULL;
  DB_INFO *db_info_p = NULL;
  char *db_name = NULL;
  char er_msg_file[PATH_MAX];

  assert (arg != NULL);
  arg_map = arg->arg_map;

  tz_gen_mode = utility_get_option_string_value (arg_map, GEN_TZ_MODE_S, 0);
  if (tz_gen_mode == NULL)
    {
      fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_GEN_TZ, GEN_TZ_MSG_USAGE),
           basename (arg->argv0), basename (arg->argv0));
      goto exit;
    }

  if (strcasecmp (tz_gen_mode, "new") == 0)
    {
      tz_gen_type = TZ_GEN_TYPE_NEW;
    }
  else if (strcasecmp (tz_gen_mode, "extend") == 0)
    {
      tz_gen_type = TZ_GEN_TYPE_EXTEND;

      db_name = utility_get_option_string_value (arg_map, OPTION_STRING_TABLE, 0);

#if !defined (WINDOWS)
      /* workaround for Linux: gen_tz process should be restarted after each database migration, since globals variables
       * from shared libcubrid.so are not properly reset at db_shutdown */
      if (db_name == NULL)
    {
      goto print_gen_tz_usage;
    }
#endif /* !WINDOWS */

      if (db_name != NULL && check_database_name (db_name) != NO_ERROR)
    {
      exit_status = EXIT_FAILURE;
      goto exit;
    }
    }
  else if (strcasecmp (tz_gen_mode, "update") == 0)
    {
      tz_gen_type = TZ_GEN_TYPE_UPDATE;

      /* This is a temporary fix to show usages until we have the update option.
       * Please remove the following when you are going to implement it.
       */
      fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_GEN_TZ, GEN_TZ_MSG_INVALID_MODE));
      goto print_gen_tz_usage;
    }
  else
    {
      fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_GEN_TZ, GEN_TZ_MSG_INVALID_MODE));
      goto print_gen_tz_usage;
    }

  input_path = utility_get_option_string_value (arg_map, GEN_TZ_INPUT_FOLDER_S, 0);

  if (input_path == NULL || strlen (input_path) == 0)
    {
      envvar_tzdata_dir_file (inputpath_local, sizeof (inputpath_local), "");
      input_path = inputpath_local;
    }

  /* error message log file */
  if (db_name != NULL)
    {
      snprintf (er_msg_file, sizeof (er_msg_file) - 1, "%s_%s.err", db_name, arg->command_name);
    }
  else
    {
      snprintf (er_msg_file, sizeof (er_msg_file) - 1, "%s.err", arg->command_name);
    }
  er_init (er_msg_file, ER_NEVER_EXIT);
  er_inited = true;

  memset (checksum, 0, sizeof (checksum));
  if (timezone_compile_data (input_path, tz_gen_type, db_name, NULL, checksum) != NO_ERROR)
    {
      exit_status = EXIT_FAILURE;
      goto exit;
    }

  if (tz_gen_type == TZ_GEN_TYPE_EXTEND && checksum[0] != '\0')
    {
      if (db_name != NULL)
    {
      dir = (DB_INFO *) calloc (1, sizeof (DB_INFO));
      if (dir == NULL)
        {
          er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (DB_INFO));
          exit_status = EXIT_FAILURE;
          goto exit;
        }
      dir->name = (char *) calloc (strlen (db_name) + 1, sizeof (char));
      if (dir->name == NULL)
        {
          er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, strlen (db_name) + 1);
          exit_status = EXIT_FAILURE;
          goto exit;
        }
      strcpy (dir->name, db_name);
      dir->next = NULL;
    }
      else if (cfg_read_directory (&dir, false) != NO_ERROR)
    {
      exit_status = EXIT_FAILURE;
      goto exit;
    }

      for (db_info_p = dir; db_info_p != NULL; db_info_p = db_info_p->next)
    {
      AU_DISABLE_PASSWORDS ();
      db_set_client_type (DB_CLIENT_TYPE_ADMIN_UTILITY);
      db_login ("DBA", NULL);

      if (db_restart (arg->command_name, TRUE, db_info_p->name) != NO_ERROR)
        {
          need_db_shutdown = true;
          exit_status = EXIT_FAILURE;
          goto exit;
        }
      if (put_timezone_checksum (checksum) != NO_ERROR)
        {
          need_db_shutdown = true;
          exit_status = EXIT_FAILURE;
          db_abort_transaction ();
          goto exit;
        }
      else
        {
          /* write the new checksum in the database */
          db_commit_transaction ();
        }
      db_shutdown ();
    }
    }

exit:
  if (dir != NULL)
    {
      cfg_free_directory (dir);
    }

  if (exit_status != EXIT_SUCCESS)
    {
      if (er_inited == true)
    {
      fprintf (stderr, "%s\n", db_error_string (3));
    }

      if (need_db_shutdown == true)
    {
      db_shutdown ();
      er_inited = false;
    }
    }

  if (er_inited == true)
    {
      er_final (ER_ALL_FINAL);
    }

  return exit_status;

print_gen_tz_usage:
  fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_GEN_TZ, GEN_TZ_MSG_USAGE),
       basename (arg->argv0), basename (arg->argv0));
  return EXIT_FAILURE;
}

/*
 * dump_tz() - display time zone data from CUBRID's timezone shared library
 *         or from the generated and embedded timezone_list.c file
 *   return: EXIT_SUCCESS/EXIT_FAILURE
 */
int
dump_tz (UTIL_FUNCTION_ARG * arg)
{
  long int zone_id = -1;
  UTIL_ARG_MAP *arg_map = NULL;
  int err_status = EXIT_SUCCESS;
  char *zone = NULL;
  char *str_next = NULL;
  bool is_dump_countries = false;
  bool is_dump_zone_list = false;
  bool is_dump_zone = false;
  bool is_dump_leap_sec = false;
  bool is_dump_summary = false;
  const TZ_DATA *tzd;

  assert (arg != NULL);
  arg_map = arg->arg_map;

  /* read and check arguments */
  is_dump_countries = utility_get_option_bool_value (arg_map, DUMP_TZ_COUNTRIES_S);
  is_dump_zone_list = utility_get_option_bool_value (arg_map, DUMP_TZ_ZONES_S);
  is_dump_leap_sec = utility_get_option_bool_value (arg_map, DUMP_TZ_LEAP_SEC_S);
  is_dump_summary = utility_get_option_bool_value (arg_map, DUMP_TZ_DUMP_SUM_S);
  zone = utility_get_option_string_value (arg_map, DUMP_TZ_ZONE_ID_S, 0);

  if ((zone == NULL) && (!is_dump_countries) && (!is_dump_zone_list) && (!is_dump_leap_sec) && (!is_dump_summary))
    {
      goto print_dump_tz_usage;
    }

  if (zone != NULL && *zone != '\0')
    {
      /* check if either a single zone or all zones should be dumped */
      if (strcasecmp (zone, "all") == 0)
    {
      zone_id = -1;
    }
      else
    {
      zone_id = strtol (zone, &str_next, 10);
      /* check zone_id, str_next, and errno */
      if (zone_id == 0 && *str_next != '\0')
        {
          goto print_dump_tz_usage;
        }
      if (errno == ERANGE)
        {
          er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ARG_OUT_OF_RANGE, 1, zone);
          fprintf (stderr,
               msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_DUMP_TZ, DUMP_TZ_MSG_ID_OUT_OF_RANGE));
          err_status = EXIT_FAILURE;
          goto exit;
        }
    }
      is_dump_zone = true;
    }

  if (tz_load () != NO_ERROR)
    {
      err_status = EXIT_FAILURE;
      goto exit;
    }
  tzd = tz_get_data ();
  assert (tzd != NULL);
  /* check if zone_id is valid for the loaded timezone library */
  if (is_dump_zone && zone_id < -1 && zone_id >= tzd->timezone_count)
    {
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ARG_OUT_OF_RANGE, 1, zone);
      fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_DUMP_TZ, DUMP_TZ_MSG_ID_OUT_OF_RANGE));
      err_status = EXIT_FAILURE;
      goto exit;
    }

  printf ("\nDump timezone data");

  if (!is_dump_countries && !is_dump_zone && !is_dump_zone_list && !is_dump_leap_sec)
    {
      tzc_dump_summary (tzd);
      goto exit;
    }

  if (is_dump_countries)
    {
      printf ("\n\nDumping countries...\n");
      tzc_dump_countries (tzd);
    }
  if (is_dump_zone_list)
    {
      printf ("\n\nDumping timezones...\n");
      tzc_dump_timezones (tzd);
    }
  if (is_dump_zone)
    {
      if (zone_id != -1)
    {
      tzc_dump_one_timezone (tzd, zone_id);
    }
      else
    {
      for (zone_id = 0; zone_id < tzd->timezone_count; zone_id++)
        {
          printf ("\n\n");
          tzc_dump_one_timezone (tzd, zone_id);
        }
    }
    }

  if (is_dump_leap_sec)
    {
      printf ("\n\nDumping leap seconds...\n");
      tzc_dump_leap_sec (tzd);
    }

exit:
  tz_unload ();

  return err_status;

print_dump_tz_usage:
  fprintf (stderr, msgcat_message (MSGCAT_CATALOG_UTILS, MSGCAT_UTIL_SET_DUMP_TZ, DUMP_TZ_MSG_USAGE),
       basename (arg->argv0));
  return err_status;
}