Skip to content

File stream_to_xasl.c

File List > cubrid > src > query > stream_to_xasl.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.
 *
 */

/*
 * stream_to_xasl.c - XASL tree restorer
 */

#ident "$Id$"

#include "config.h"

#include <assert.h>
#include <cstring>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

#include "stream_to_xasl.h"

#include "dbtype.h"
#include "error_manager.h"
#include "query_aggregate.hpp"
#include "xasl.h"
#include "xasl_aggregate.hpp"
#include "xasl_analytic.hpp"
#include "xasl_predicate.hpp"
#include "xasl_stream.hpp"
#include "xasl_unpack_info.hpp"
#include "pl_signature.hpp"

// XXX: SHOULD BE THE LAST INCLUDE HEADER
#include "memory_wrapper.hpp"

static ACCESS_SPEC_TYPE *stx_restore_access_spec_type (THREAD_ENTRY * thread_p, char **ptr, void *arg);
static AGGREGATE_TYPE *stx_restore_aggregate_type (THREAD_ENTRY * thread_p, char *ptr);
static SP_TYPE *stx_restore_sp_type (THREAD_ENTRY * thread_p, char *ptr);
static FUNCTION_TYPE *stx_restore_function_type (THREAD_ENTRY * thread_p, char *ptr);
static ANALYTIC_TYPE *stx_restore_analytic_type (THREAD_ENTRY * thread_p, char *ptr);
static ANALYTIC_EVAL_TYPE *stx_restore_analytic_eval_type (THREAD_ENTRY * thread_p, char *ptr);
static QFILE_SORTED_LIST_ID *stx_restore_srlist_id (THREAD_ENTRY * thread_p, char *ptr);
static QFILE_LIST_ID *stx_restore_list_id (THREAD_ENTRY * thread_p, char *ptr);
static ARITH_TYPE *stx_restore_arith_type (THREAD_ENTRY * thread_p, char *ptr);
static INDX_INFO *stx_restore_indx_info (THREAD_ENTRY * thread_p, char *ptr);
static OUTPTR_LIST *stx_restore_outptr_list (THREAD_ENTRY * thread_p, char *ptr);
static SELUPD_LIST *stx_restore_selupd_list (THREAD_ENTRY * thread_p, char *ptr);
static UPDDEL_CLASS_INFO *stx_restore_update_class_info_array (THREAD_ENTRY * thread_p, char *ptr, int num_classes);
static UPDATE_ASSIGNMENT *stx_restore_update_assignment_array (THREAD_ENTRY * thread_p, char *ptr, int num_assigns);
static ODKU_INFO *stx_restore_odku_info (THREAD_ENTRY * thread_p, char *ptr);
static PRED_EXPR *stx_restore_pred_expr (THREAD_ENTRY * thread_p, char *ptr);
static REGU_VARIABLE *stx_restore_regu_variable (THREAD_ENTRY * thread_p, char *ptr);
static REGU_VARIABLE_LIST stx_restore_regu_variable_list (THREAD_ENTRY * thread_p, char *ptr);
static REGU_VARLIST_LIST stx_restore_regu_varlist_list (THREAD_ENTRY * thread_p, char *ptr);
static SORT_LIST *stx_restore_sort_list (THREAD_ENTRY * thread_p, char *ptr);
static VAL_LIST *stx_restore_val_list (THREAD_ENTRY * thread_p, char *ptr);
static DB_VALUE *stx_restore_db_value (THREAD_ENTRY * thread_p, char *ptr);
#if defined(ENABLE_UNUSED_FUNCTION)
static QPROC_DB_VALUE_LIST stx_restore_db_value_list (THREAD_ENTRY * thread_p, char *ptr);
#endif
static XASL_NODE *stx_restore_xasl_node (THREAD_ENTRY * thread_p, char *ptr);
static PRED_EXPR_WITH_CONTEXT *stx_restore_filter_pred_node (THREAD_ENTRY * thread_p, char *ptr);
static FUNC_PRED *stx_restore_func_pred (THREAD_ENTRY * thread_p, char *ptr);
static HEAP_CACHE_ATTRINFO *stx_restore_cache_attrinfo (THREAD_ENTRY * thread_p, char *ptr);
static DB_VALUE **stx_restore_db_value_array_extra (THREAD_ENTRY * thread_p, char *ptr, int size, int total_size);
static int *stx_restore_int_array (THREAD_ENTRY * thread_p, char *ptr, int size);
static OID *stx_restore_OID_array (THREAD_ENTRY * thread_p, char *ptr, int size);

static PL_SIGNATURE_ARRAY_TYPE *stx_restore_pl_sig_array (THREAD_ENTRY * thread_p, char *ptr);
static PL_SIGNATURE_TYPE *stx_restore_pl_sig (THREAD_ENTRY * thread_p, char *ptr);

static KEY_RANGE *stx_restore_key_range_array (THREAD_ENTRY * thread_p, char *ptr, int size);

static char *stx_build_xasl_node (THREAD_ENTRY * thread_p, char *tmp, XASL_NODE * ptr);
static char *stx_build_xasl_header (THREAD_ENTRY * thread_p, char *ptr, XASL_NODE_HEADER * xasl_header);
static char *stx_build_filter_pred_node (THREAD_ENTRY * thread_p, char *ptr, PRED_EXPR_WITH_CONTEXT * pred);
static char *stx_build_func_pred (THREAD_ENTRY * thread_p, char *tmp, FUNC_PRED * ptr);
static char *stx_build_cache_attrinfo (char *tmp);
static char *stx_build_list_id (THREAD_ENTRY * thread_p, char *tmp, QFILE_LIST_ID * ptr);
static char *stx_build_sub_xasl_id (THREAD_ENTRY * thread_p, char *tmp, XASL_ID * ptr);

static char *stx_build_pl_sig (THREAD_ENTRY * thread_p, char *ptr, PL_SIGNATURE_TYPE * sig);
static char *stx_build_pl_sig_array (THREAD_ENTRY * thread_p, char *ptr, PL_SIGNATURE_ARRAY_TYPE * sig_array);

static char *stx_build_union_proc (THREAD_ENTRY * thread_p, char *tmp, UNION_PROC_NODE * ptr);
static char *stx_build_fetch_proc (THREAD_ENTRY * thread_p, char *tmp, FETCH_PROC_NODE * ptr);
static char *stx_build_buildlist_proc (THREAD_ENTRY * thread_p, char *tmp, BUILDLIST_PROC_NODE * ptr);
static char *stx_build_buildvalue_proc (THREAD_ENTRY * thread_p, char *tmp, BUILDVALUE_PROC_NODE * ptr);
static char *stx_build_mergelist_proc (THREAD_ENTRY * thread_p, char *tmp, MERGELIST_PROC_NODE * ptr);
static char *stx_build_hashjoin_proc (THREAD_ENTRY * thread_p, char *ptr, HASHJOIN_PROC_NODE * node_p);
static char *stx_build_ls_merge_info (THREAD_ENTRY * thread_p, char *tmp, QFILE_LIST_MERGE_INFO * ptr);
static char *stx_build_update_class_info (THREAD_ENTRY * thread_p, char *tmp, UPDDEL_CLASS_INFO * ptr);
static char *stx_build_update_assignment (THREAD_ENTRY * thread_p, char *tmp, UPDATE_ASSIGNMENT * ptr);
static char *stx_build_update_proc (THREAD_ENTRY * thread_p, char *tmp, UPDATE_PROC_NODE * ptr);
static char *stx_build_delete_proc (THREAD_ENTRY * thread_p, char *tmp, DELETE_PROC_NODE * ptr);
static char *stx_build_insert_proc (THREAD_ENTRY * thread_p, char *tmp, INSERT_PROC_NODE * ptr);
static char *stx_build_merge_proc (THREAD_ENTRY * thread_p, char *tmp, MERGE_PROC_NODE * ptr);
static char *stx_build_cte_proc (THREAD_ENTRY * thread_p, char *tmp, CTE_PROC_NODE * ptr);
static char *stx_build_outptr_list (THREAD_ENTRY * thread_p, char *tmp, OUTPTR_LIST * ptr);
static char *stx_build_selupd_list (THREAD_ENTRY * thread_p, char *tmp, SELUPD_LIST * ptr);
static char *stx_build_pred_expr (THREAD_ENTRY * thread_p, char *tmp, PRED_EXPR * ptr);
static char *stx_build_pred (THREAD_ENTRY * thread_p, char *tmp, PRED * ptr);
static char *stx_build_eval_term (THREAD_ENTRY * thread_p, char *tmp, EVAL_TERM * ptr);
static char *stx_build_comp_eval_term (THREAD_ENTRY * thread_p, char *tmp, COMP_EVAL_TERM * ptr);
static char *stx_build_alsm_eval_term (THREAD_ENTRY * thread_p, char *tmp, ALSM_EVAL_TERM * ptr);
static char *stx_build_like_eval_term (THREAD_ENTRY * thread_p, char *tmp, LIKE_EVAL_TERM * ptr);
static char *stx_build_rlike_eval_term (THREAD_ENTRY * thread_p, char *tmp, RLIKE_EVAL_TERM * ptr);
static char *stx_build_access_spec_type (THREAD_ENTRY * thread_p, char *tmp, ACCESS_SPEC_TYPE * ptr, void *arg);
static char *stx_build_indx_info (THREAD_ENTRY * thread_p, char *tmp, INDX_INFO * ptr);
static char *stx_build_key_info (THREAD_ENTRY * thread_p, char *tmp, KEY_INFO * ptr);
static char *stx_build_cls_spec_type (THREAD_ENTRY * thread_p, char *tmp, CLS_SPEC_TYPE * ptr);
static char *stx_build_list_spec_type (THREAD_ENTRY * thread_p, char *tmp, LIST_SPEC_TYPE * ptr);
static char *stx_build_showstmt_spec_type (THREAD_ENTRY * thread_p, char *ptr, SHOWSTMT_SPEC_TYPE * spec);
static char *stx_build_rlist_spec_type (THREAD_ENTRY * thread_p, char *ptr, REGUVAL_LIST_SPEC_TYPE * spec,
                    OUTPTR_LIST * outptr_list);
static char *stx_build_set_spec_type (THREAD_ENTRY * thread_p, char *tmp, SET_SPEC_TYPE * ptr);
static char *stx_build_method_spec_type (THREAD_ENTRY * thread_p, char *tmp, METHOD_SPEC_TYPE * ptr);
static char *stx_build_dblink_spec_type (THREAD_ENTRY * thread_p, char *ptr, DBLINK_SPEC_TYPE * dblink_spec);
static char *stx_build_val_list (THREAD_ENTRY * thread_p, char *tmp, VAL_LIST * ptr);
#if defined(ENABLE_UNUSED_FUNCTION)
static char *stx_build_db_value_list (THREAD_ENTRY * thread_p, char *tmp, QPROC_DB_VALUE_LIST ptr);
#endif
static char *stx_build_regu_variable (THREAD_ENTRY * thread_p, char *tmp, REGU_VARIABLE * ptr);
static char *stx_unpack_regu_variable_value (THREAD_ENTRY * thread_p, char *tmp, REGU_VARIABLE * ptr);
static char *stx_build_attr_descr (THREAD_ENTRY * thread_p, char *tmp, ATTR_DESCR * ptr);
static char *stx_build_pos_descr (char *tmp, QFILE_TUPLE_VALUE_POSITION * ptr);
static char *stx_build_arith_type (THREAD_ENTRY * thread_p, char *tmp, ARITH_TYPE * ptr);
static char *stx_build_aggregate_type (THREAD_ENTRY * thread_p, char *tmp, AGGREGATE_TYPE * ptr);
static char *stx_build_function_type (THREAD_ENTRY * thread_p, char *tmp, FUNCTION_TYPE * ptr);
static char *stx_build_analytic_type (THREAD_ENTRY * thread_p, char *tmp, ANALYTIC_TYPE * ptr);
static char *stx_build_analytic_eval_type (THREAD_ENTRY * thread_p, char *tmp, ANALYTIC_EVAL_TYPE * ptr);
static char *stx_build_srlist_id (THREAD_ENTRY * thread_p, char *tmp, QFILE_SORTED_LIST_ID * ptr);
static char *stx_build_sort_list (THREAD_ENTRY * thread_p, char *tmp, SORT_LIST * ptr);
static char *stx_build_connectby_proc (THREAD_ENTRY * thread_p, char *tmp, CONNECTBY_PROC_NODE * ptr);
static char *stx_build_sq_cache (THREAD_ENTRY * thread_p, char *ptr, SQ_CACHE ** sq_cache_p);
static char *stx_build_sp_type (THREAD_ENTRY * thread_p, char *tmp, SP_TYPE * ptr);

static REGU_VALUE_LIST *stx_regu_value_list_alloc_and_init (THREAD_ENTRY * thread_p);
static REGU_VALUE_ITEM *stx_regu_value_item_alloc_and_init (THREAD_ENTRY * thread_p);
static char *stx_build_regu_value_list (THREAD_ENTRY * thread_p, char *ptr, REGU_VALUE_LIST * regu_value_list,
                    TP_DOMAIN * domain);
static void stx_init_regu_variable (REGU_VARIABLE * regu);

static char *stx_build_regu_variable_list (THREAD_ENTRY * thread_p, char *ptr, REGU_VARIABLE_LIST * regu_var_list);

#if defined(ENABLE_UNUSED_FUNCTION)
static char *stx_unpack_char (char *tmp, char *ptr);
static char *stx_unpack_long (char *tmp, long *ptr);
#endif

/*
 * stx_map_stream_to_xasl_node_header () - Obtain xasl node header from xasl
 *                     stream.
 *
 * return          : error code.
 * thread_p (in)       : thread entry.
 * xasl_header_p (out) : pointer to xasl node header.
 * xasl_stream (in)    : xasl stream.
 */
int
stx_map_stream_to_xasl_node_header (THREAD_ENTRY * thread_p, xasl_node_header * xasl_header_p, char *xasl_stream)
{
  int xasl_stream_header_size = 0, offset = 0;
  char *ptr = NULL;

  if (xasl_stream == NULL || xasl_header_p == NULL)
    {
      assert (0);
      return ER_FAILED;
    }
  (void) or_unpack_int (xasl_stream, &xasl_stream_header_size);
  offset = OR_INT_SIZE +    /* xasl stream header size */
    xasl_stream_header_size +   /* xasl stream header data */
    OR_INT_SIZE;        /* xasl stream body size */
  offset = xasl_stream_make_align (offset);
  ptr = xasl_stream + offset;
  OR_UNPACK_XASL_NODE_HEADER (ptr, xasl_header_p);
  return NO_ERROR;
}

/*
 * stx_map_stream_to_xasl () -
 *   return: if successful, return 0, otherwise non-zero error code
 *   xasl_tree(in)      : pointer to where to return the
 *                        root of the unpacked XASL tree
 *   use_xasl_clone(in) : true, if XASL clone is used
 *   xasl_stream(in)    : pointer to xasl stream
 *   xasl_stream_size(in)       : # of bytes in xasl_stream
 *   xasl_unpack_info_ptr(in)   : pointer to where to return the pack info
 *
 * Note: map the linear byte stream in disk representation to an XASL tree.
 *
 * Note: the caller is responsible for freeing the memory of
 * xasl_unpack_info_ptr. The free function is free_xasl_unpack_info().
 */
int
stx_map_stream_to_xasl (THREAD_ENTRY * thread_p, xasl_node ** xasl_tree, bool use_xasl_clone, char *xasl_stream,
            int xasl_stream_size, XASL_UNPACK_INFO ** xasl_unpack_info_ptr)
{
  XASL_NODE *xasl;
  char *p;
  int header_size;
  int offset;
  XASL_UNPACK_INFO *unpack_info_p = NULL;
  XASL_UNPACK_INFO *unpack_info_p_orig = thread_p->xasl_unpack_info_ptr;

  if (!xasl_tree || !xasl_stream || !xasl_unpack_info_ptr || xasl_stream_size <= 0)
    {
      return ER_QPROC_INVALID_XASLNODE;
    }

  stx_set_xasl_errcode (thread_p, NO_ERROR);
  stx_init_xasl_unpack_info (thread_p, xasl_stream, xasl_stream_size);
  unpack_info_p = get_xasl_unpack_info_ptr (thread_p);
  unpack_info_p->use_xasl_clone = use_xasl_clone;
  unpack_info_p->track_allocated_bufers = 1;

  /* calculate offset to XASL tree in the stream buffer */
  p = or_unpack_int (xasl_stream, &header_size);
  offset = sizeof (int)     /* [size of header data] */
    + header_size       /* [header data] */
    + sizeof (int);     /* [size of body data] */
  offset = xasl_stream_make_align (offset);

  /* restore XASL tree from body data of the stream buffer */
  xasl = stx_restore_xasl_node (thread_p, xasl_stream + offset);
  if (xasl == NULL)
    {
      free_xasl_unpack_info (thread_p, unpack_info_p);
      goto end;
    }

  /* set result */
  *xasl_tree = xasl;
  *xasl_unpack_info_ptr = get_xasl_unpack_info_ptr (thread_p);

  /* restore header data of new XASL format */
  p = or_unpack_int (p, &xasl->dbval_cnt);
  OID_SET_NULL (&xasl->creator_oid);
  xasl->n_oid_list = 0;
  xasl->class_oid_list = NULL;
  xasl->class_locks = NULL;
  xasl->tcard_list = NULL;
  xasl->px_executor = NULL;
  xasl->memoize_storage = NULL;
  xasl->executed_parallelism = 0;

  /* initialize the query in progress flag to FALSE.  Note that this flag is not packed/unpacked.  It is strictly a
   * server side flag. */
  xasl->query_in_progress = false;
end:
  stx_free_visited_ptrs (thread_p);
#if defined(SERVER_MODE)
  set_xasl_unpack_info_ptr (thread_p, unpack_info_p_orig);
#endif /* SERVER_MODE */

  return stx_get_xasl_errcode (thread_p);
}

/*
 * stx_map_stream_to_filter_pred () -
 *   return: if successful, return 0, otherwise non-zero error code
 *   pred(in): pointer to where to return the root of the unpacked
 *             filter predicate tree
 *   pred_stream(in): pointer to predicate stream
 *   pred_stream_size(in): # of bytes in predicate stream
 *   pred_unpack_info_ptr(in): pointer to where to return the pack info
 *
 * Note: map the linear byte stream in disk representation to an predicate
 *       with context. The caller is responsible for freeing the memory of
 *       (*pred)->unpack_info by calling free_xasl_unpack_info().
 *       *pred is private_alloced separatedly of (*pred)->unpack_info and
 *       needs to be freed after it
 */
int
stx_map_stream_to_filter_pred (THREAD_ENTRY * thread_p, pred_expr_with_context ** pred, char *pred_stream,
                   int pred_stream_size)
{
  PRED_EXPR_WITH_CONTEXT *pwc = NULL;
  char *p = NULL;
  int header_size;
  int offset;
  XASL_UNPACK_INFO *unpack_info_p = NULL;
  XASL_UNPACK_INFO *unpack_info_p_orig = thread_p->xasl_unpack_info_ptr;

  if (!pred || !pred_stream || pred_stream_size <= 0)
    {
      return ER_QPROC_INVALID_XASLNODE;
    }

  stx_set_xasl_errcode (thread_p, NO_ERROR);
  stx_init_xasl_unpack_info (thread_p, pred_stream, pred_stream_size);
  unpack_info_p = get_xasl_unpack_info_ptr (thread_p);
  unpack_info_p->use_xasl_clone = true;
  unpack_info_p->track_allocated_bufers = 1;

  /* calculate offset to filter predicate in the stream buffer */
  p = or_unpack_int (pred_stream, &header_size);
  offset = sizeof (int)     /* [size of header data] */
    + header_size       /* [header data] */
    + sizeof (int);     /* [size of body data] */
  offset = xasl_stream_make_align (offset);

  /* restore XASL tree from body data of the stream buffer */
  pwc = stx_restore_filter_pred_node (thread_p, pred_stream + offset);
  if (pwc == NULL)
    {
      free_xasl_unpack_info (thread_p, unpack_info_p);
      goto end;
    }

  /* set result */
  pwc->unpack_info = unpack_info_p;
  *pred = pwc;

end:
  stx_free_visited_ptrs (thread_p);
#if defined(SERVER_MODE)
  set_xasl_unpack_info_ptr (thread_p, unpack_info_p_orig);
#endif /* SERVER_MODE */

  return stx_get_xasl_errcode (thread_p);
}

/*
 * stx_map_stream_to_func_pred () -
 *   return: if successful, return 0, otherwise non-zero error code
 *   xasl(in)      : pointer to where to return the unpacked FUNC_PRED
 *   xasl_stream(in)    : pointer to xasl stream
 *   xasl_stream_size(in)       : # of bytes in xasl_stream
 *   xasl_unpack_info_ptr(in)   : pointer to where to return the pack info
 */
int
stx_map_stream_to_func_pred (THREAD_ENTRY * thread_p, func_pred ** xasl, char *xasl_stream, int xasl_stream_size,
                 XASL_UNPACK_INFO ** xasl_unpack_info_ptr)
{
  FUNC_PRED *p_xasl = NULL;
  char *p = NULL;
  int header_size;
  int offset;
  XASL_UNPACK_INFO *unpack_info_p = NULL;
  XASL_UNPACK_INFO *unpack_info_p_orig = thread_p->xasl_unpack_info_ptr;

  if (!xasl || !xasl_stream || !xasl_unpack_info_ptr || xasl_stream_size <= 0)
    {
      return ER_QPROC_INVALID_XASLNODE;
    }

  stx_set_xasl_errcode (thread_p, NO_ERROR);
  stx_init_xasl_unpack_info (thread_p, xasl_stream, xasl_stream_size);
  unpack_info_p = get_xasl_unpack_info_ptr (thread_p);
  unpack_info_p->use_xasl_clone = false;
  unpack_info_p->track_allocated_bufers = 1;

  /* calculate offset to expr XASL in the stream buffer */
  p = or_unpack_int (xasl_stream, &header_size);
  offset = sizeof (int)     /* [size of header data] */
    + header_size       /* [header data] */
    + sizeof (int);     /* [size of body data] */
  offset = xasl_stream_make_align (offset);

  /* restore XASL tree from body data of the stream buffer */
  p_xasl = stx_restore_func_pred (thread_p, xasl_stream + offset);
  if (p_xasl == NULL)
    {
      free_xasl_unpack_info (thread_p, unpack_info_p);
      goto end;
    }

  /* set result */
  *xasl = p_xasl;
  *xasl_unpack_info_ptr = unpack_info_p;

end:
  stx_free_visited_ptrs (thread_p);
#if defined(SERVER_MODE)
  set_xasl_unpack_info_ptr (thread_p, unpack_info_p_orig);
#endif /* SERVER_MODE */

  return stx_get_xasl_errcode (thread_p);
}

/*
 * stx_restore_func_postfix () -
 *   return: if successful, return the offset of position
 *           in disk object where the node is stored, otherwise
 *           return ER_FAILED and error code is set to xasl_errcode.
 *   ptr(in): pointer to an XASL tree node whose type is return type
 *
 * Note: store the XASL tree node pointed by 'ptr' into disk
 * object with the help of stx_build_func_postfix to process
 * the members of the node.
 */

static AGGREGATE_TYPE *
stx_restore_aggregate_type (THREAD_ENTRY * thread_p, char *ptr)
{
  AGGREGATE_TYPE *aggregate;

  if (ptr == NULL)
    {
      return NULL;
    }

  aggregate = (AGGREGATE_TYPE *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (aggregate != NULL)
    {
      return aggregate;
    }

  aggregate = (AGGREGATE_TYPE *) stx_alloc_struct (thread_p, sizeof (*aggregate));
  if (aggregate == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, aggregate) == ER_FAILED
      || stx_build_aggregate_type (thread_p, ptr, aggregate) == NULL)
    {
      return NULL;
    }

  return aggregate;
}

static SP_TYPE *
stx_restore_sp_type (THREAD_ENTRY * thread_p, char *ptr)
{
  SP_TYPE *sp;

  if (ptr == NULL)
    {
      return NULL;
    }

  sp = (SP_TYPE *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (sp != NULL)
    {
      return sp;
    }

  sp = (SP_TYPE *) stx_alloc_struct (thread_p, sizeof (*sp));
  if (sp == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, sp) == ER_FAILED || stx_build_sp_type (thread_p, ptr, sp) == NULL)
    {
      return NULL;
    }

  return sp;
}

static FUNCTION_TYPE *
stx_restore_function_type (THREAD_ENTRY * thread_p, char *ptr)
{
  FUNCTION_TYPE *function;

  if (ptr == NULL)
    {
      return NULL;
    }

  function = (FUNCTION_TYPE *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (function != NULL)
    {
      return function;
    }

  function = (FUNCTION_TYPE *) stx_alloc_struct (thread_p, sizeof (*function));
  if (function == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, function) == ER_FAILED
      || stx_build_function_type (thread_p, ptr, function) == NULL)
    {
      return NULL;
    }

  return function;
}

static ANALYTIC_TYPE *
stx_restore_analytic_type (THREAD_ENTRY * thread_p, char *ptr)
{
  ANALYTIC_TYPE *analytic;

  if (ptr == NULL)
    {
      return NULL;
    }

  analytic = (ANALYTIC_TYPE *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (analytic != NULL)
    {
      return analytic;
    }

  analytic = (ANALYTIC_TYPE *) stx_alloc_struct (thread_p, sizeof (*analytic));
  if (analytic == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, analytic) == ER_FAILED
      || stx_build_analytic_type (thread_p, ptr, analytic) == NULL)
    {
      return NULL;
    }

  analytic->init ();

  return analytic;
}

static ANALYTIC_EVAL_TYPE *
stx_restore_analytic_eval_type (THREAD_ENTRY * thread_p, char *ptr)
{
  ANALYTIC_EVAL_TYPE *analytic_eval;

  if (ptr == NULL)
    {
      return NULL;
    }

  analytic_eval = (ANALYTIC_EVAL_TYPE *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (analytic_eval != NULL)
    {
      return analytic_eval;
    }

  analytic_eval = (ANALYTIC_EVAL_TYPE *) stx_alloc_struct (thread_p, sizeof (*analytic_eval));
  if (analytic_eval == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, analytic_eval) == ER_FAILED
      || stx_build_analytic_eval_type (thread_p, ptr, analytic_eval) == NULL)
    {
      return NULL;
    }

  return analytic_eval;
}

static QFILE_SORTED_LIST_ID *
stx_restore_srlist_id (THREAD_ENTRY * thread_p, char *ptr)
{
  QFILE_SORTED_LIST_ID *sort_list_id;

  if (ptr == NULL)
    {
      return NULL;
    }

  sort_list_id = (QFILE_SORTED_LIST_ID *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (sort_list_id != NULL)
    {
      return sort_list_id;
    }

  sort_list_id = (QFILE_SORTED_LIST_ID *) stx_alloc_struct (thread_p, sizeof (*sort_list_id));
  if (sort_list_id == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, sort_list_id) == ER_FAILED
      || stx_build_srlist_id (thread_p, ptr, sort_list_id) == NULL)
    {
      return NULL;
    }

  return sort_list_id;
}

static ARITH_TYPE *
stx_restore_arith_type (THREAD_ENTRY * thread_p, char *ptr)
{
  ARITH_TYPE *arithmetic;

  if (ptr == NULL)
    {
      return NULL;
    }

  arithmetic = (ARITH_TYPE *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (arithmetic != NULL)
    {
      return arithmetic;
    }

  arithmetic = (ARITH_TYPE *) stx_alloc_struct (thread_p, sizeof (*arithmetic));
  if (arithmetic == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, arithmetic) == ER_FAILED
      || stx_build_arith_type (thread_p, ptr, arithmetic) == NULL)
    {
      return NULL;
    }

  return arithmetic;
}

static INDX_INFO *
stx_restore_indx_info (THREAD_ENTRY * thread_p, char *ptr)
{
  INDX_INFO *indx_info;

  if (ptr == NULL)
    {
      return NULL;
    }

  indx_info = (INDX_INFO *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (indx_info != NULL)
    {
      return indx_info;
    }

  indx_info = (INDX_INFO *) stx_alloc_struct (thread_p, sizeof (*indx_info));
  if (indx_info == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, indx_info) == ER_FAILED
      || stx_build_indx_info (thread_p, ptr, indx_info) == NULL)
    {
      return NULL;
    }

  return indx_info;
}

static OUTPTR_LIST *
stx_restore_outptr_list (THREAD_ENTRY * thread_p, char *ptr)
{
  OUTPTR_LIST *outptr_list;

  if (ptr == NULL)
    {
      return NULL;
    }

  outptr_list = (OUTPTR_LIST *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (outptr_list != NULL)
    {
      return outptr_list;
    }

  outptr_list = (OUTPTR_LIST *) stx_alloc_struct (thread_p, sizeof (*outptr_list));
  if (outptr_list == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, outptr_list) == ER_FAILED
      || stx_build_outptr_list (thread_p, ptr, outptr_list) == NULL)
    {
      return NULL;
    }

  return outptr_list;
}

static SELUPD_LIST *
stx_restore_selupd_list (THREAD_ENTRY * thread_p, char *ptr)
{
  SELUPD_LIST *selupd_list;

  if (ptr == NULL)
    {
      return NULL;
    }

  selupd_list = (SELUPD_LIST *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (selupd_list != NULL)
    {
      return selupd_list;
    }

  selupd_list = (SELUPD_LIST *) stx_alloc_struct (thread_p, sizeof (*selupd_list));
  if (selupd_list == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, selupd_list) == ER_FAILED
      || stx_build_selupd_list (thread_p, ptr, selupd_list) == NULL)
    {
      return NULL;
    }

  return selupd_list;
}

static PRED_EXPR *
stx_restore_pred_expr (THREAD_ENTRY * thread_p, char *ptr)
{
  PRED_EXPR *pred_expr;

  if (ptr == NULL)
    {
      return NULL;
    }

  pred_expr = (PRED_EXPR *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (pred_expr != NULL)
    {
      return pred_expr;
    }

  pred_expr = (PRED_EXPR *) stx_alloc_struct (thread_p, sizeof (*pred_expr));
  if (pred_expr == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, pred_expr) == ER_FAILED
      || stx_build_pred_expr (thread_p, ptr, pred_expr) == NULL)
    {
      return NULL;
    }

  return pred_expr;
}

static REGU_VARIABLE *
stx_restore_regu_variable (THREAD_ENTRY * thread_p, char *ptr)
{
  REGU_VARIABLE *regu_var;

  if (ptr == NULL)
    {
      return NULL;
    }

  regu_var = (REGU_VARIABLE *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (regu_var != NULL)
    {
      return regu_var;
    }

  regu_var = (REGU_VARIABLE *) stx_alloc_struct (thread_p, sizeof (*regu_var));
  if (regu_var == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, regu_var) == ER_FAILED
      || stx_build_regu_variable (thread_p, ptr, regu_var) == NULL)
    {
      return NULL;
    }

  return regu_var;
}

static SORT_LIST *
stx_restore_sort_list (THREAD_ENTRY * thread_p, char *ptr)
{
  SORT_LIST *sort_list;

  if (ptr == NULL)
    {
      return NULL;
    }

  sort_list = (SORT_LIST *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (sort_list != NULL)
    {
      return sort_list;
    }

  sort_list = (SORT_LIST *) stx_alloc_struct (thread_p, sizeof (*sort_list));
  if (sort_list == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, sort_list) == ER_FAILED
      || stx_build_sort_list (thread_p, ptr, sort_list) == NULL)
    {
      return NULL;
    }

  return sort_list;
}

static VAL_LIST *
stx_restore_val_list (THREAD_ENTRY * thread_p, char *ptr)
{
  VAL_LIST *val_list;

  if (ptr == NULL)
    {
      return NULL;
    }

  val_list = (VAL_LIST *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (val_list != NULL)
    {
      return val_list;
    }

  val_list = (VAL_LIST *) stx_alloc_struct (thread_p, sizeof (*val_list));
  if (val_list == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, val_list) == ER_FAILED
      || stx_build_val_list (thread_p, ptr, val_list) == NULL)
    {
      return NULL;
    }

  return val_list;
}

static DB_VALUE *
stx_restore_db_value (THREAD_ENTRY * thread_p, char *ptr)
{
  DB_VALUE *value;

  if (ptr == NULL)
    {
      return NULL;
    }

  value = (DB_VALUE *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (value != NULL)
    {
      return value;
    }

  value = (DB_VALUE *) stx_alloc_struct (thread_p, sizeof (*value));
  if (value == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, value) == ER_FAILED || stx_build_db_value (thread_p, ptr, value) == NULL)
    {
      return NULL;
    }

  return value;
}

#if defined(ENABLE_UNUSED_FUNCTION)
static QPROC_DB_VALUE_LIST
stx_restore_db_value_list (THREAD_ENTRY * thread_p, char *ptr)
{
  QPROC_DB_VALUE_LIST value_list;

  if (ptr == NULL)
    {
      return NULL;
    }

  value_list = (QPROC_DB_VALUE_LIST) stx_get_struct_visited_ptr (thread_p, ptr);
  if (value_list != NULL)
    {
      return value_list;
    }

  value_list = (QPROC_DB_VALUE_LIST) stx_alloc_struct (thread_p, sizeof (*value_list));
  if (value_list == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, value_list) == ER_FAILED
      || stx_build_db_value_list (thread_p, ptr, value_list) == NULL)
    {
      return NULL;
    }

  return value_list;
}
#endif

static XASL_NODE *
stx_restore_xasl_node (THREAD_ENTRY * thread_p, char *ptr)
{
  XASL_NODE *xasl;

  if (ptr == NULL)
    {
      return NULL;
    }

  xasl = (XASL_NODE *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (xasl != NULL)
    {
      return xasl;
    }

  xasl = (XASL_NODE *) stx_alloc_struct (thread_p, sizeof (*xasl));
  if (xasl == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, xasl) == ER_FAILED || stx_build_xasl_node (thread_p, ptr, xasl) == NULL)
    {
      return NULL;
    }

  return xasl;
}

/*
 * stx_restore_filter_pred_node () -
 *   return: unpacked pred_expr_with_context
 *   thread_entry(in):
 *   ptr(in): pointer to stream
 *
 * Note: returned pred is private_alloced and should be freed separately after
 *       pred->unpack_info.
 */
static PRED_EXPR_WITH_CONTEXT *
stx_restore_filter_pred_node (THREAD_ENTRY * thread_p, char *ptr)
{
  PRED_EXPR_WITH_CONTEXT *pred = NULL;

  if (ptr == NULL)
    {
      return NULL;
    }

  pred = (PRED_EXPR_WITH_CONTEXT *) db_private_alloc (thread_p, sizeof (*pred));
  if (pred == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_build_filter_pred_node (thread_p, ptr, pred) == NULL)
    {
      return NULL;
    }

  return pred;
}

static FUNC_PRED *
stx_restore_func_pred (THREAD_ENTRY * thread_p, char *ptr)
{
  FUNC_PRED *func_pred = NULL;

  if (ptr == NULL)
    {
      return NULL;
    }

  func_pred = (FUNC_PRED *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (func_pred != NULL)
    {
      return func_pred;
    }

  func_pred = (FUNC_PRED *) stx_alloc_struct (thread_p, sizeof (*func_pred));
  if (func_pred == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, func_pred) == ER_FAILED
      || stx_build_func_pred (thread_p, ptr, func_pred) == NULL)
    {
      return NULL;
    }

  return func_pred;
}

static HEAP_CACHE_ATTRINFO *
stx_restore_cache_attrinfo (THREAD_ENTRY * thread_p, char *ptr)
{
  HEAP_CACHE_ATTRINFO *cache_attrinfo;

  if (ptr == NULL)
    {
      return NULL;
    }

  cache_attrinfo = (HEAP_CACHE_ATTRINFO *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (cache_attrinfo != NULL)
    {
      return cache_attrinfo;
    }

  cache_attrinfo = (HEAP_CACHE_ATTRINFO *) stx_alloc_struct (thread_p, sizeof (*cache_attrinfo));
  if (cache_attrinfo == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, cache_attrinfo) == ER_FAILED || stx_build_cache_attrinfo (ptr) == NULL)
    {
      return NULL;
    }

  return cache_attrinfo;
}

#if 0
/* there are currently no pointers to these type of structures in xasl
 * so there is no need to have a separate restore function.
 */

static MERGELIST_PROC_NODE *
stx_restore_merge_list_info (char *ptr)
{
  MERGELIST_PROC_NODE *merge_list_info;

  if (ptr == NULL)
    {
      return NULL;
    }

  merge_list_info = stx_get_struct_visited_ptr (thread_p, ptr);
  if (merge_list_info != NULL)
    {
      return merge_list_info;
    }

  merge_list_info = (MERGELIST_PROC_NODE *) stx_alloc_struct (sizeof (*merge_list_info));
  if (merge_list_info == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (ptr, merge_list_info) == ER_FAILED
      || stx_build_merge_list_info (ptr, merge_list_info) == NULL)
    {
      return NULL;
    }

  return merge_list_info;
}

static QFILE_LIST_MERGE_INFO *
stx_restore_ls_merge_info (char *ptr)
{
  QFILE_LIST_MERGE_INFO *list_merge_info;

  if (ptr == NULL)
    {
      return NULL;
    }

  list_merge_info = stx_get_struct_visited_ptr (thread_p, ptr);
  if (list_merge_info != NULL)
    {
      return list_merge_info;
    }

  list_merge_info = (QFILE_LIST_MERGE_INFO *) stx_alloc_struct (sizeof (*list_merge_info));
  if (list_merge_info == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (ptr, list_merge_info) == ER_FAILED
      || stx_build_ls_merge_info (ptr, list_merge_info) == NULL)
    {
      return NULL;
    }

  return list_merge_info;
}

static UPDATE_PROC_NODE *
stx_restore_update_info (char *ptr)
{
  UPDATE_PROC_NODE *update_info;

  if (ptr == NULL)
    {
      return NULL;
    }

  update_info = stx_get_struct_visited_ptr (thread_p, ptr);
  if (update_info != NULL)
    {
      return update_info;
    }

  update_info = (UPDATE_PROC_NODE *) stx_alloc_struct (sizeof (*update_info));
  if (update_info == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (ptr, update_info) == ER_FAILED || stx_build_update_info (ptr, update_info) == NULL)
    {
      return NULL;
    }

  return update_info;
}

static DELETE_PROC_NODE *
stx_restore_delete_info (char *ptr)
{
  DELETE_PROC_NODE *delete_info;

  if (ptr == NULL)
    {
      return NULL;
    }

  delete_info = stx_get_struct_visited_ptr (thread_p, ptr);
  if (delete_info != NULL)
    {
      return delete_info;
    }

  delete_info = (DELETE_PROC_NODE *) stx_alloc_struct (sizeof (*delete_info));
  if (delete_info == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (ptr, delete_info) == ER_FAILED || stx_build_delete_info (ptr, delete_info) == NULL)
    {
      return NULL;
    }

  return delete_info;
}

static INSERT_PROC_NODE *
stx_restore_insert_info (char *ptr)
{
  INSERT_PROC_NODE *insert_info;

  if (ptr == NULL)
    {
      return NULL;
    }

  insert_info = stx_get_struct_visited_ptr (thread_p, ptr);
  if (insert_info != NULL)
    {
      return insert_info;
    }

  insert_info = (INSERT_PROC_NODE *) stx_alloc_struct (sizeof (*insert_info));
  if (insert_info == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (ptr, insert_info) == ER_FAILED || stx_build_insert_info (ptr, insert_info) == NULL)
    {
      return NULL;
    }

  return insert_info;
}
#endif /* 0 */

static QFILE_LIST_ID *
stx_restore_list_id (THREAD_ENTRY * thread_p, char *ptr)
{
  QFILE_LIST_ID *list_id;

  if (ptr == NULL)
    {
      return NULL;
    }

  list_id = (QFILE_LIST_ID *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (list_id != NULL)
    {
      return list_id;
    }

  list_id = (QFILE_LIST_ID *) stx_alloc_struct (thread_p, sizeof (QFILE_LIST_ID));
  if (list_id == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
  if (stx_mark_struct_visited (thread_p, ptr, list_id) == ER_FAILED
      || stx_build_list_id (thread_p, ptr, list_id) == NULL)
    {
      return NULL;
    }

  return list_id;
}

/*
 * stx_restore_pl_sig () -
 *
 */
static PL_SIGNATURE_TYPE *
stx_restore_pl_sig (THREAD_ENTRY * thread_p, char *ptr)
{
  PL_SIGNATURE_TYPE *sig = NULL;

  if (ptr == NULL)
    {
      return NULL;
    }

  sig = (PL_SIGNATURE_TYPE *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (sig != NULL)
    {
      return sig;
    }

#if defined(MMON_DEBUG_LEVEL)
  sig = new PL_SIGNATURE_TYPE;
#else
  sig = new (std::nothrow) PL_SIGNATURE_TYPE;
#endif

  if (stx_mark_struct_visited (thread_p, ptr, sig) == ER_FAILED || stx_build_pl_sig (thread_p, ptr, sig) == NULL)
    {
      return NULL;
    }

  return sig;
}

/*
 * stx_restore_pl_sig_array () -
 *
 */
static PL_SIGNATURE_ARRAY_TYPE *
stx_restore_pl_sig_array (THREAD_ENTRY * thread_p, char *ptr)
{
  PL_SIGNATURE_ARRAY_TYPE *sig_array = NULL;

  if (ptr == NULL)
    {
      return NULL;
    }

  sig_array = (PL_SIGNATURE_ARRAY_TYPE *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (sig_array != NULL)
    {
      return sig_array;
    }

#if defined(MMON_DEBUG_LEVEL)
  sig_array = new PL_SIGNATURE_ARRAY_TYPE;
#else
  sig_array = new (std::nothrow) PL_SIGNATURE_ARRAY_TYPE;
#endif

  if (stx_mark_struct_visited (thread_p, ptr, sig_array) == ER_FAILED ||
      stx_build_pl_sig_array (thread_p, ptr, sig_array) == NULL)
    {
      return NULL;
    }

  return sig_array;
}

static DB_VALUE **
stx_restore_db_value_array_extra (THREAD_ENTRY * thread_p, char *ptr, int nelements, int total_nelements)
{
  DB_VALUE **value_array;
  int *ints;
  int i;
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  value_array = (DB_VALUE **) stx_alloc_struct (thread_p, sizeof (DB_VALUE *) * total_nelements);
  if (value_array == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
  ints = stx_restore_int_array (thread_p, ptr, nelements);
  if (ints == NULL)
    {
      return NULL;
    }

  for (i = 0; i < nelements; i++)
    {
      offset = ints[i];
      value_array[i] = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (value_array[i] == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
      assert (value_array[i]->need_clear == false);
    }

  for (; i < total_nelements; ++i)
    {
      value_array[i] = NULL;
    }
  return value_array;
}

#if defined(ENABLE_UNUSED_FUNCTION)
static TP_DOMAIN **
stx_restore_domain_array (THREAD_ENTRY * thread_p, char *ptr, int nelements)
{
  int i;
  TP_DOMAIN **domains;

  domains = (TP_DOMAIN **) stx_alloc_struct (thread_p, nelements * sizeof (TP_DOMAIN *));
  if (domains == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
  for (i = 0; i < nelements; ++i)
    {
      ptr = or_unpack_domain (ptr, &domains[i], NULL);
    }

  return domains;
}
#endif

static int *
stx_restore_int_array (THREAD_ENTRY * thread_p, char *ptr, int nelements)
{
  int *int_array;
  int i;

  int_array = (int *) stx_alloc_struct (thread_p, sizeof (int) * nelements);
  if (int_array == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
  for (i = 0; i < nelements; ++i)
    {
      ptr = or_unpack_int (ptr, &int_array[i]);
    }

  return int_array;
}

static HFID *
stx_restore_hfid_array (THREAD_ENTRY * thread_p, char *ptr, int nelements)
{
  HFID *hfid_array;
  int i;

  hfid_array = (HFID *) stx_alloc_struct (thread_p, sizeof (HFID) * nelements);
  if (hfid_array == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
  for (i = 0; i < nelements; ++i)
    {
      ptr = or_unpack_hfid (ptr, &hfid_array[i]);
    }

  return hfid_array;
}

static OID *
stx_restore_OID_array (THREAD_ENTRY * thread_p, char *ptr, int nelements)
{
  OID *oid_array;
  int i;

  oid_array = (OID *) stx_alloc_struct (thread_p, sizeof (OID) * nelements);
  if (oid_array == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
  for (i = 0; i < nelements; i++)
    {
      ptr = or_unpack_oid (ptr, &oid_array[i]);
    }

  return oid_array;
}

static XASL_ID *
stx_restore_sub_xasl_id (THREAD_ENTRY * thread_p, char *ptr)
{
  int i, offset;
  XASL_ID *sub_xasl_id;

  if (ptr == NULL)
    {
      return NULL;
    }

  sub_xasl_id = (XASL_ID *) stx_get_struct_visited_ptr (thread_p, ptr);
  if (sub_xasl_id != NULL)
    {
      return sub_xasl_id;
    }

  sub_xasl_id = (XASL_ID *) stx_alloc_struct (thread_p, sizeof (XASL_ID));
  if (sub_xasl_id == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  if (stx_mark_struct_visited (thread_p, ptr, sub_xasl_id) == ER_FAILED
      || stx_build_sub_xasl_id (thread_p, ptr, sub_xasl_id) == NULL)
    {
      return NULL;
    }

  return sub_xasl_id;
}

static KEY_VAL_RANGE *
stx_restore_key_val_array (THREAD_ENTRY * thread_p, char *ptr, int nelements)
{
  KEY_VAL_RANGE *key_val_array;
  int i;

  key_val_array = (KEY_VAL_RANGE *) stx_alloc_struct (thread_p, sizeof (KEY_VAL_RANGE) * nelements);
  if (key_val_array == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
  for (i = 0; i < nelements; i++)
    {
      ptr = or_unpack_key_val_range (ptr, &key_val_array[i]);
    }

  return key_val_array;
}

#if defined(ENABLE_UNUSED_FUNCTION)
static char *
stx_restore_input_vals (THREAD_ENTRY * thread_p, char *ptr, int nelements)
{
  char *input_vals;

  input_vals = stx_alloc_struct (thread_p, nelements);
  if (input_vals == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
  memmove (input_vals, ptr, nelements);

  return input_vals;
}
#endif

/*
 * Restore the regu_variable_list as an array to avoid recursion in the server.
 * The array size is restored first, then the array.
 */
static REGU_VARIABLE_LIST
stx_restore_regu_variable_list (THREAD_ENTRY * thread_p, char *ptr)
{
  REGU_VARIABLE_LIST regu_var_list;
  int offset;
  int total;
  int i;
  char *ptr2;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  regu_var_list = (REGU_VARIABLE_LIST) stx_get_struct_visited_ptr (thread_p, ptr);
  if (regu_var_list != NULL)
    {
      return regu_var_list;
    }

  ptr2 = or_unpack_int (ptr, &total);
  regu_var_list = (REGU_VARIABLE_LIST) stx_alloc_struct (thread_p, sizeof (struct regu_variable_list_node) * total);
  if (regu_var_list == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
  if (stx_mark_struct_visited (thread_p, ptr, regu_var_list) == ER_FAILED)
    {
      return NULL;
    }

  ptr = ptr2;
  for (i = 0; i < total; i++)
    {
      ptr = or_unpack_int (ptr, &offset);
      if (stx_build_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset], &regu_var_list[i].value) == NULL)
    {
      return NULL;
    }

      if (i < total - 1)
    {
      regu_var_list[i].next = (struct regu_variable_list_node *) &regu_var_list[i + 1];
    }
      else
    {
      regu_var_list[i].next = NULL;
    }
    }

  return regu_var_list;
}

static REGU_VARLIST_LIST
stx_restore_regu_varlist_list (THREAD_ENTRY * thread_p, char *ptr)
{
  REGU_VARLIST_LIST regu_var_list_list;
  int offset;
  int total;
  int i;
  char *ptr2;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  regu_var_list_list = (REGU_VARLIST_LIST) stx_get_struct_visited_ptr (thread_p, ptr);
  if (regu_var_list_list != NULL)
    {
      return regu_var_list_list;
    }

  ptr2 = or_unpack_int (ptr, &total);
  regu_var_list_list = (REGU_VARLIST_LIST) stx_alloc_struct (thread_p, sizeof (struct regu_varlist_list_node) * total);
  if (regu_var_list_list == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
  if (stx_mark_struct_visited (thread_p, ptr, regu_var_list_list) == ER_FAILED)
    {
      return NULL;
    }

  ptr = ptr2;
  for (i = 0; i < total; i++)
    {
      ptr = or_unpack_int (ptr, &offset);
      regu_var_list_list[i].list = stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (i < total - 1)
    {
      regu_var_list_list[i].next = (REGU_VARLIST_LIST) (&regu_var_list_list[i + 1]);
    }
      else
    {
      regu_var_list_list[i].next = NULL;
    }
    }

  return regu_var_list_list;
}

static KEY_RANGE *
stx_restore_key_range_array (THREAD_ENTRY * thread_p, char *ptr, int nelements)
{
  KEY_RANGE *key_range_array;
  int *ints;
  int i, j, offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  key_range_array = (KEY_RANGE *) stx_alloc_struct (thread_p, sizeof (KEY_RANGE) * nelements);
  if (key_range_array == NULL)
    {
      goto error;
    }

  ints = stx_restore_int_array (thread_p, ptr, 3 * nelements);
  if (ints == NULL)
    {
      return NULL;
    }

  for (i = 0, j = 0; i < nelements; i++, j++)
    {
      key_range_array[i].range = (RANGE) ints[j];

      offset = ints[++j];
      if (offset)
    {
      key_range_array[i].key1 = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (key_range_array[i].key1 == NULL)
        {
          goto error;
        }
    }
      else
    {
      key_range_array[i].key1 = NULL;
    }

      offset = ints[++j];
      if (offset)
    {
      key_range_array[i].key2 = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (key_range_array[i].key2 == NULL)
        {
          goto error;
        }
    }
      else
    {
      key_range_array[i].key2 = NULL;
    }
    }

  return key_range_array;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

/*
 * Restore access spec type list as an array to avoid recursion in the server.
 * The array size is restored first, then the array.
 */
static ACCESS_SPEC_TYPE *
stx_restore_access_spec_type (THREAD_ENTRY * thread_p, char **ptr, void *arg)
{
  ACCESS_SPEC_TYPE *access_spec_type = NULL;
  int total, i;

  *ptr = or_unpack_int (*ptr, &total);
  if (total > 0)
    {
      access_spec_type = (ACCESS_SPEC_TYPE *) stx_alloc_struct (thread_p, sizeof (ACCESS_SPEC_TYPE) * total);
      if (access_spec_type == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  for (i = 0; i < total; i++)
    {
      *ptr = stx_build_access_spec_type (thread_p, *ptr, &access_spec_type[i], arg);
      if (*ptr == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
      if (i < total - 1)
    {
      access_spec_type[i].next = (ACCESS_SPEC_TYPE *) (&access_spec_type[i + 1]);
    }
      else
    {
      access_spec_type[i].next = NULL;
    }
    }

  return access_spec_type;
}

/*
 * stx_build_xasl_header () - Unpack XASL node header from buffer.
 *
 * return        : buffer pointer after the unpacked XASL node header
 * thread_p (in)     : thread entry
 * ptr (in)      : buffer pointer where XASL node header is packed
 * xasl_header (out) : Unpacked XASL node header
 */
static char *
stx_build_xasl_header (THREAD_ENTRY * thread_p, char *ptr, XASL_NODE_HEADER * xasl_header)
{
  if (ptr == NULL)
    {
      return NULL;
    }
  ASSERT_ALIGN (ptr, INT_ALIGNMENT);

  OR_UNPACK_XASL_NODE_HEADER (ptr, xasl_header);
  return ptr;
}

static char *
stx_build_xasl_node (THREAD_ENTRY * thread_p, char *ptr, XASL_NODE * xasl)
{
  int offset;
  int tmp, i;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  /* initialize query_in_progress flag */
  xasl->query_in_progress = false;

  /* XASL node header is packed first */
  ptr = stx_build_xasl_header (thread_p, ptr, &xasl->header);

  ptr = or_unpack_int (ptr, &tmp);
  xasl->type = (PROC_TYPE) tmp;

  ptr = or_unpack_int (ptr, &xasl->flag);

  /* initialize xasl status */
  xasl->status = XASL_BUILD;
  /* ************************************************************************** 
   *  === Status transition diagram   
   *       |------------------>----------------------------------|
   *  XASL_BUILD -> XASL_SUCCESS/XASL_FAILURE -> XASL_INITIALIZED/XASL_CLEARED  
   *                            |--------------<-----------------|
   *  
   * 1. When you first create an XASL, it starts with the XASL_BUILD status.
   * 2. If the created XASL is executed successfully, it becomes XASL_SUCCESS, and if an error occurs, it becomes XASL_FAILURE.
   *    When an error occurs, the status of XASLs that have not yet been executed does not change.
   * 3. When the task execution is completed, whether successful or failed, 
   *    it changes to XASL_INITIALIZED or XASL_CLEARED through qexec_clear_xasl().
   * 4. If the XASL is cached and reused, steps 2 and 3 are repeated.
   ************************************************************************** */

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->list_id = NULL;
    }
  else
    {
      xasl->list_id = stx_restore_list_id (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->list_id == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->after_iscan_list = NULL;
    }
  else
    {
      xasl->after_iscan_list = stx_restore_sort_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->after_iscan_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->orderby_list = NULL;
    }
  else
    {
      xasl->orderby_list = stx_restore_sort_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->orderby_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->ordbynum_pred = NULL;
    }
  else
    {
      xasl->ordbynum_pred = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->ordbynum_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->ordbynum_val = NULL;
    }
  else
    {
      xasl->ordbynum_val = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->ordbynum_val == NULL)
    {
      goto error;
    }
      assert (xasl->ordbynum_val->need_clear == false);
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->orderby_limit = NULL;
    }
  else
    {
      xasl->orderby_limit = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->orderby_limit == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, (int *) &xasl->ordbynum_flag);

  xasl->topn_items = NULL;

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->limit_offset = NULL;
    }
  else
    {
      xasl->limit_offset = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->limit_offset == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->limit_row_count = NULL;
    }
  else
    {
      xasl->limit_row_count = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->limit_row_count == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->single_tuple = NULL;
    }
  else
    {
      xasl->single_tuple = stx_restore_val_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->single_tuple == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &xasl->is_single_tuple);

  ptr = or_unpack_int (ptr, &tmp);
  xasl->option = (QUERY_OPTIONS) tmp;

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->outptr_list = NULL;
    }
  else
    {
      xasl->outptr_list = stx_restore_outptr_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->outptr_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->selected_upd_list = NULL;
    }
  else
    {
      xasl->selected_upd_list = stx_restore_selupd_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->selected_upd_list == NULL)
    {
      goto error;
    }
    }

  xasl->spec_list = stx_restore_access_spec_type (thread_p, &ptr, (void *) xasl->outptr_list);

  xasl->merge_spec = stx_restore_access_spec_type (thread_p, &ptr, NULL);
  if (ptr == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_QPROC_INVALID_XASLNODE);
      return NULL;
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->val_list = NULL;
    }
  else
    {
      xasl->val_list = stx_restore_val_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->val_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->merge_val_list = NULL;
    }
  else
    {
      xasl->merge_val_list = stx_restore_val_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->merge_val_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->aptr_list = NULL;
    }
  else
    {
      xasl->aptr_list = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->aptr_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->bptr_list = NULL;
    }
  else
    {
      xasl->bptr_list = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->bptr_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->dptr_list = NULL;
    }
  else
    {
      xasl->dptr_list = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->dptr_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->during_join_pred = NULL;
    }
  else
    {
      xasl->during_join_pred = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->during_join_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->after_join_pred = NULL;
    }
  else
    {
      xasl->after_join_pred = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->after_join_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->if_pred = NULL;
    }
  else
    {
      xasl->if_pred = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->if_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->instnum_pred = NULL;
    }
  else
    {
      xasl->instnum_pred = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->instnum_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->instnum_val = NULL;
    }
  else
    {
      xasl->instnum_val = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->instnum_val == NULL)
    {
      goto error;
    }
      assert (xasl->instnum_val->need_clear == false);
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->save_instnum_val = NULL;
    }
  else
    {
      xasl->save_instnum_val = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->save_instnum_val == NULL)
    {
      goto error;
    }
      assert (xasl->save_instnum_val->need_clear == false);
    }

  ptr = or_unpack_int (ptr, (int *) &xasl->instnum_flag);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->fptr_list = NULL;
    }
  else
    {
      xasl->fptr_list = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->fptr_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->scan_ptr = NULL;
    }
  else
    {
      xasl->scan_ptr = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->scan_ptr == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->connect_by_ptr = NULL;
    }
  else
    {
      xasl->connect_by_ptr = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->connect_by_ptr == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->level_val = NULL;
    }
  else
    {
      xasl->level_val = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->level_val == NULL)
    {
      goto error;
    }
      assert (xasl->level_val->need_clear == false);
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->level_regu = NULL;
    }
  else
    {
      xasl->level_regu = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->level_regu == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->isleaf_val = NULL;
    }
  else
    {
      xasl->isleaf_val = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->isleaf_val == NULL)
    {
      goto error;
    }
      assert (xasl->isleaf_val->need_clear == false);
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->isleaf_regu = NULL;
    }
  else
    {
      xasl->isleaf_regu = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->isleaf_regu == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->iscycle_val = NULL;
    }
  else
    {
      xasl->iscycle_val = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->iscycle_val == NULL)
    {
      goto error;
    }
      assert (xasl->iscycle_val->need_clear == false);
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->iscycle_regu = NULL;
    }
  else
    {
      xasl->iscycle_regu = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->iscycle_regu == NULL)
    {
      goto error;
    }
    }

  xasl->curr_spec = stx_restore_access_spec_type (thread_p, &ptr, NULL);

  ptr = or_unpack_int (ptr, &tmp);
  xasl->scan_op_type = (SCAN_OPERATION_TYPE) tmp;

  ptr = or_unpack_int (ptr, &xasl->upd_del_class_cnt);

  ptr = or_unpack_int (ptr, &xasl->mvcc_reev_extra_cls_cnt);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->sub_xasl_id = NULL;
    }
  else
    {
      xasl->sub_xasl_id = stx_restore_sub_xasl_id (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->sub_xasl_id == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &xasl->sub_host_var_count);
  if (xasl->sub_host_var_count > 0)
    {
      xasl->sub_host_var_index = (int *) malloc (sizeof (int) * xasl->sub_host_var_count);
      for (i = 0; i < xasl->sub_host_var_count; i++)
    {
      ptr = or_unpack_int (ptr, &xasl->sub_host_var_index[i]);
    }
    }

#if defined (ENABLE_COMPOSITE_LOCK)
  /*
   * Note that the composite lock block is strictly a server side block
   * and was not packed.  We'll simply clear the memory.
   */
  memset (&xasl->composite_lock, 0, sizeof (LK_COMPOSITE_LOCK));
#endif /* defined (ENABLE_COMPOSITE_LOCK) */

  switch (xasl->type)
    {
    case CONNECTBY_PROC:
      ptr = stx_build_connectby_proc (thread_p, ptr, &xasl->proc.connect_by);
      break;

    case BUILDLIST_PROC:
      ptr = stx_build_buildlist_proc (thread_p, ptr, &xasl->proc.buildlist);
      break;

    case BUILDVALUE_PROC:
      ptr = stx_build_buildvalue_proc (thread_p, ptr, &xasl->proc.buildvalue);
      break;

    case MERGELIST_PROC:
      ptr = stx_build_mergelist_proc (thread_p, ptr, &xasl->proc.mergelist);
      break;

    case HASHJOIN_PROC:
      ptr = stx_build_hashjoin_proc (thread_p, ptr, &xasl->proc.hashjoin);
      break;

    case UPDATE_PROC:
      ptr = stx_build_update_proc (thread_p, ptr, &xasl->proc.update);
      break;

    case DELETE_PROC:
      ptr = stx_build_delete_proc (thread_p, ptr, &xasl->proc.delete_);
      break;

    case INSERT_PROC:
      ptr = stx_build_insert_proc (thread_p, ptr, &xasl->proc.insert);
      break;

    case UNION_PROC:
    case DIFFERENCE_PROC:
    case INTERSECTION_PROC:
      ptr = stx_build_union_proc (thread_p, ptr, &xasl->proc.union_);
      break;

    case OBJFETCH_PROC:
      ptr = stx_build_fetch_proc (thread_p, ptr, &xasl->proc.fetch);
      break;

    case SCAN_PROC:
      break;

    case DO_PROC:
      break;

    case BUILD_SCHEMA_PROC:
      break;

    case MERGE_PROC:
      ptr = stx_build_merge_proc (thread_p, ptr, &xasl->proc.merge);
      break;

    case CTE_PROC:
      ptr = stx_build_cte_proc (thread_p, ptr, &xasl->proc.cte);
      break;

    default:
      stx_set_xasl_errcode (thread_p, ER_QPROC_INVALID_XASLNODE);
      return NULL;
    }

  if (ptr == NULL)
    {
      return NULL;
    }

  /* Prevent faults when qdump_print_xasl is called. */
  xasl->n_oid_list = 0;

  ptr = or_unpack_int (ptr, &tmp);
  xasl->iscan_oid_order = (bool) tmp;

  xasl->query_alias = stx_restore_string (thread_p, ptr);
  assert (xasl->query_alias != NULL);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      xasl->next = NULL;
    }
  else
    {
      xasl->next = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (xasl->next == NULL)
    {
      goto error;
    }
    }
  ptr = stx_build_sq_cache (thread_p, ptr, &xasl->sq_cache);
  if (ptr == NULL)
    {
      goto error;
    }

  ptr = or_unpack_int (ptr, &xasl->parallelism);

  memset (&xasl->orderby_stats, 0, sizeof (xasl->orderby_stats));
  memset (&xasl->groupby_stats, 0, sizeof (xasl->groupby_stats));
  memset (&xasl->xasl_stats, 0, sizeof (xasl->xasl_stats));
  memset (&xasl->func_stats, 0, sizeof (xasl->func_stats));
  xasl->analytic_stats = NULL;
  xasl->max_iterations = -1;
  xasl->px_executor = NULL;
  xasl->memoize_storage = NULL;
  xasl->executed_parallelism = 0;
  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_filter_pred_node (THREAD_ENTRY * thread_p, char *ptr, PRED_EXPR_WITH_CONTEXT * pred)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      pred->pred = NULL;
    }
  else
    {
      pred->pred = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (pred->pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &pred->num_attrs_pred);
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || pred->num_attrs_pred == 0)
    {
      pred->attrids_pred = NULL;
    }
  else
    {
      pred->attrids_pred =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], pred->num_attrs_pred);
      if (pred->attrids_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      pred->cache_pred = NULL;
    }
  else
    {
      pred->cache_pred = stx_restore_cache_attrinfo (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (pred->cache_pred == NULL)
    {
      goto error;
    }
    }

  return ptr;
error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_func_pred (THREAD_ENTRY * thread_p, char *ptr, FUNC_PRED * func_pred)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      func_pred->func_regu = NULL;
    }
  else
    {
      func_pred->func_regu = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (func_pred->func_regu == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      func_pred->cache_attrinfo = NULL;
    }
  else
    {
      func_pred->cache_attrinfo = stx_restore_cache_attrinfo (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (func_pred->cache_attrinfo == NULL)
    {
      goto error;
    }
    }

  return ptr;
error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_cache_attrinfo (char *ptr)
{
  int dummy;

  /* unpack the zero int that is sent mainly as a placeholder */
  ptr = or_unpack_int (ptr, &dummy);

  return ptr;
}

static char *
stx_build_sub_xasl_id (THREAD_ENTRY * thread_p, char *ptr, XASL_ID * sub_xasl_id)
{
  int i;

  ptr = or_unpack_sha1 (ptr, &sub_xasl_id->sha1);

  sub_xasl_id->cache_flag = OR_GET_INT (ptr);
  ptr += OR_INT_SIZE;

  sub_xasl_id->time_stored.sec = OR_GET_INT (ptr);
  ptr += OR_INT_SIZE;

  sub_xasl_id->time_stored.usec = OR_GET_INT (ptr);
  ptr += OR_INT_SIZE;

  return ptr;
}

static char *
stx_build_sq_cache (THREAD_ENTRY * thread_p, char *ptr, SQ_CACHE ** sq_cache_p)
{
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);
  SQ_CACHE *new_sq_cache = NULL;
  int n_elements, offset;

  *sq_cache_p = NULL;
  ptr = or_unpack_int (ptr, &n_elements);
  ptr = or_unpack_int (ptr, &offset);

  if (n_elements > 0)
    {
      new_sq_cache = (SQ_CACHE *) stx_alloc_struct (thread_p, sizeof (SQ_CACHE));
      if (new_sq_cache == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
      memset (new_sq_cache, 0, sizeof (SQ_CACHE));

      new_sq_cache->sq_key_struct = (SQ_KEY *) stx_alloc_struct (thread_p, sizeof (SQ_KEY));
      new_sq_cache->sq_key_struct->dbv_array =
    stx_restore_db_value_array_extra (thread_p, &xasl_unpack_info->packed_xasl[offset], n_elements, n_elements);
      if (new_sq_cache->sq_key_struct->dbv_array == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

      new_sq_cache->sq_key_struct->n_elements = n_elements;
      *sq_cache_p = new_sq_cache;
    }

  return ptr;
}

static char *
stx_build_list_id (THREAD_ENTRY * thread_p, char *ptr, QFILE_LIST_ID * listid)
{
  ptr = or_unpack_listid (ptr, listid);

  if (listid->type_list.type_cnt < 0)
    {
      goto error;
    }

  assert_release (listid->type_list.type_cnt == 0);
  assert_release (listid->type_list.domp == NULL);

#if 0               /* DEAD CODE - for defense code */
  if (listid->type_list.type_cnt > 0)
    {
      int count, i;

      count = listid->type_list.type_cnt;

      /* TODO - need to replace with stx_alloc_struct to make tracking */
      listid->type_list.domp = (TP_DOMAIN **) db_private_alloc (thread_p, sizeof (TP_DOMAIN *) * count);

      if (listid->type_list.domp == NULL)
    {
      goto error;
    }

      for (i = 0; i < count; i++)
    {
      ptr = or_unpack_domain (ptr, &listid->type_list.domp[i], NULL);
    }
    }
#endif

  return ptr;
error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

// FIXME: use template
static char *
stx_build_pl_sig (THREAD_ENTRY * thread_p, char *ptr, PL_SIGNATURE_TYPE * sig)
{
  int size, offset;

  ptr = or_unpack_int (ptr, (int *) &size);
  packing_unpacker unpacker (ptr, size);
  unpacker.unpack_all (*sig);

  return (char *) unpacker.get_curr_ptr ();
}

// FIXME: use template
static char *
stx_build_pl_sig_array (THREAD_ENTRY * thread_p, char *ptr, PL_SIGNATURE_ARRAY_TYPE * sig_array)
{
  int size, offset;

  ptr = or_unpack_int (ptr, (int *) &size);
  packing_unpacker unpacker (ptr, size);
  unpacker.unpack_all (*sig_array);

  return (char *) unpacker.get_curr_ptr ();
}

static char *
stx_build_union_proc (THREAD_ENTRY * thread_p, char *ptr, UNION_PROC_NODE * union_proc)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      union_proc->left = NULL;
    }
  else
    {
      union_proc->left = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (union_proc->left == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      union_proc->right = NULL;
    }
  else
    {
      union_proc->right = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (union_proc->right == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  return ptr;
}

static char *
stx_build_fetch_proc (THREAD_ENTRY * thread_p, char *ptr, FETCH_PROC_NODE * obj_set_fetch_proc)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);
  int i;

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      obj_set_fetch_proc->arg = NULL;
    }
  else
    {
      obj_set_fetch_proc->arg = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (obj_set_fetch_proc->arg == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
      assert (obj_set_fetch_proc->arg->need_clear == false);
    }

  ptr = or_unpack_int (ptr, &i);
  obj_set_fetch_proc->fetch_res = (bool) i;

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      obj_set_fetch_proc->set_pred = NULL;
    }
  else
    {
      obj_set_fetch_proc->set_pred = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (obj_set_fetch_proc->set_pred == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  ptr = or_unpack_int (ptr, &i);
  obj_set_fetch_proc->ql_flag = (bool) i;

  return ptr;
}

static char *
stx_build_buildlist_proc (THREAD_ENTRY * thread_p, char *ptr, BUILDLIST_PROC_NODE * stx_build_list_proc)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  stx_build_list_proc->output_columns = (DB_VALUE **) 0;
  stx_build_list_proc->upddel_oid_locator_ehids = NULL;

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->eptr_list = NULL;
    }
  else
    {
      stx_build_list_proc->eptr_list = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->eptr_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->groupby_list = NULL;
    }
  else
    {
      stx_build_list_proc->groupby_list = stx_restore_sort_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->groupby_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->after_groupby_list = NULL;
    }
  else
    {
      stx_build_list_proc->after_groupby_list =
    stx_restore_sort_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->after_groupby_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->push_list_id = NULL;
    }
  else
    {
      stx_build_list_proc->push_list_id = stx_restore_list_id (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->push_list_id == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->g_outptr_list = NULL;
    }
  else
    {
      stx_build_list_proc->g_outptr_list = stx_restore_outptr_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->g_outptr_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->g_regu_list = NULL;
    }
  else
    {
      stx_build_list_proc->g_regu_list =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->g_regu_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->g_val_list = NULL;
    }
  else
    {
      stx_build_list_proc->g_val_list = stx_restore_val_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->g_val_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->g_having_pred = NULL;
    }
  else
    {
      stx_build_list_proc->g_having_pred = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->g_having_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->g_grbynum_pred = NULL;
    }
  else
    {
      stx_build_list_proc->g_grbynum_pred = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->g_grbynum_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->g_grbynum_val = NULL;
    }
  else
    {
      stx_build_list_proc->g_grbynum_val = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->g_grbynum_val == NULL)
    {
      goto error;
    }
      assert (stx_build_list_proc->g_grbynum_val->need_clear == false);
    }

  ptr = or_unpack_int (ptr, (int *) &stx_build_list_proc->g_hash_eligible);
  stx_build_list_proc->agg_hash_context =
    (AGGREGATE_HASH_CONTEXT *) stx_alloc_struct (thread_p, sizeof (*stx_build_list_proc->agg_hash_context));
  std::memset (stx_build_list_proc->agg_hash_context, 0, sizeof (*stx_build_list_proc->agg_hash_context));

  ptr = or_unpack_int (ptr, (int *) &stx_build_list_proc->g_output_first_tuple);
  ptr = or_unpack_int (ptr, (int *) &stx_build_list_proc->g_hkey_size);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->g_hk_scan_regu_list = NULL;
    }
  else
    {
      stx_build_list_proc->g_hk_scan_regu_list =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->g_hk_scan_regu_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->g_hk_sort_regu_list = NULL;
    }
  else
    {
      stx_build_list_proc->g_hk_sort_regu_list =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->g_hk_sort_regu_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->g_scan_regu_list = NULL;
    }
  else
    {
      stx_build_list_proc->g_scan_regu_list =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->g_scan_regu_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, (int *) &stx_build_list_proc->g_func_count);
  ptr = or_unpack_int (ptr, (int *) &stx_build_list_proc->g_grbynum_flag);
  ptr = or_unpack_int (ptr, (int *) &stx_build_list_proc->g_with_rollup);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->g_agg_list = NULL;
    }
  else
    {
      stx_build_list_proc->g_agg_list = stx_restore_aggregate_type (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->g_agg_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->a_eval_list = NULL;
    }
  else
    {
      stx_build_list_proc->a_eval_list =
    stx_restore_analytic_eval_type (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->a_eval_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->a_regu_list = NULL;
    }
  else
    {
      stx_build_list_proc->a_regu_list =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->a_regu_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->a_scan_regu_list = NULL;
    }
  else
    {
      stx_build_list_proc->a_scan_regu_list =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->a_scan_regu_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->a_outptr_list = NULL;
    }
  else
    {
      stx_build_list_proc->a_outptr_list = stx_restore_outptr_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->a_outptr_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->a_outptr_list_ex = NULL;
    }
  else
    {
      stx_build_list_proc->a_outptr_list_ex =
    stx_restore_outptr_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->a_outptr_list_ex == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->a_outptr_list_interm = NULL;
    }
  else
    {
      stx_build_list_proc->a_outptr_list_interm =
    stx_restore_outptr_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->a_outptr_list_interm == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_list_proc->a_val_list = NULL;
    }
  else
    {
      stx_build_list_proc->a_val_list = stx_restore_val_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_list_proc->a_val_list == NULL)
    {
      goto error;
    }
    }

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_buildvalue_proc (THREAD_ENTRY * thread_p, char *ptr, BUILDVALUE_PROC_NODE * stx_build_value_proc)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_value_proc->having_pred = NULL;
    }
  else
    {
      stx_build_value_proc->having_pred = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_value_proc->having_pred == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_value_proc->grbynum_val = NULL;
    }
  else
    {
      stx_build_value_proc->grbynum_val = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_value_proc->grbynum_val == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
      assert (stx_build_value_proc->grbynum_val->need_clear == false);
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_value_proc->agg_list = NULL;
    }
  else
    {
      stx_build_value_proc->agg_list = stx_restore_aggregate_type (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_value_proc->agg_list == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_build_value_proc->outarith_list = NULL;
    }
  else
    {
      stx_build_value_proc->outarith_list = stx_restore_arith_type (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_build_value_proc->outarith_list == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  ptr = or_unpack_int (ptr, &stx_build_value_proc->is_always_false);

  return ptr;
}

static char *
stx_build_mergelist_proc (THREAD_ENTRY * thread_p, char *ptr, MERGELIST_PROC_NODE * merge_list_info)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      merge_list_info->outer_xasl = NULL;
    }
  else
    {
      merge_list_info->outer_xasl = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (merge_list_info->outer_xasl == NULL)
    {
      goto error;
    }
    }

  merge_list_info->outer_spec_list = stx_restore_access_spec_type (thread_p, &ptr, NULL);
  if (ptr == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_QPROC_INVALID_XASLNODE);
      return NULL;
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      merge_list_info->outer_val_list = NULL;
    }
  else
    {
      merge_list_info->outer_val_list = stx_restore_val_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (merge_list_info->outer_val_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      merge_list_info->inner_xasl = NULL;
    }
  else
    {
      merge_list_info->inner_xasl = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (merge_list_info->inner_xasl == NULL)
    {
      goto error;
    }
    }

  merge_list_info->inner_spec_list = stx_restore_access_spec_type (thread_p, &ptr, NULL);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      merge_list_info->inner_val_list = NULL;
    }
  else
    {
      merge_list_info->inner_val_list = stx_restore_val_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (merge_list_info->inner_val_list == NULL)
    {
      goto error;
    }
    }

  ptr = stx_build_ls_merge_info (thread_p, ptr, &merge_list_info->ls_merge);

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

/*
 * stx_build_hashjoin_proc () -
 *   return: The buffer pointer after the unpacked XASL node.
 *   thread_p(in): The current thread entry.
 *   ptr(in): The buffer pointer where the XASL node is packed.
 *   node_p(in): The pointer to the unpacked XASL node.
 */
static char *
stx_build_hashjoin_proc (THREAD_ENTRY * thread_p, char *ptr, HASHJOIN_PROC_NODE * node_p)
{
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);
  TP_DOMAIN **all_domains = NULL;
  int domain_cnt;
  int offset;

  int error = NO_ERROR;

  memset (node_p, 0, sizeof (HASHJOIN_PROC_NODE));

  /* outer */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      error = ER_QPROC_INVALID_XASLNODE;
      stx_set_xasl_errcode (thread_p, error);
      goto exit_on_error;
    }
  else
    {
      node_p->outer.xasl = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (node_p->outer.xasl == NULL)
    {
      goto exit_on_error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      node_p->outer.regu_list_pred = NULL;
    }
  else
    {
      node_p->outer.regu_list_pred = stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (node_p->outer.regu_list_pred == NULL)
    {
      goto exit_on_error;
    }
    }

  /* inner */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      error = ER_QPROC_INVALID_XASLNODE;
      stx_set_xasl_errcode (thread_p, error);
      goto exit_on_error;
    }
  else
    {
      node_p->inner.xasl = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (node_p->inner.xasl == NULL)
    {
      goto exit_on_error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      node_p->inner.regu_list_pred = NULL;
    }
  else
    {
      node_p->inner.regu_list_pred = stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (node_p->inner.regu_list_pred == NULL)
    {
      goto exit_on_error;
    }
    }

  /* merge_info */
  ptr = stx_build_ls_merge_info (thread_p, ptr, &node_p->merge_info);
  if (ptr == NULL)
    {
      goto exit_on_error;
    }
  assert (node_p->merge_info.single_fetch == QPROC_NO_SINGLE_INNER);    /* Unused */

  /* domain_info */
  domain_cnt = node_p->merge_info.ls_column_cnt;
  if (domain_cnt == 0)
    {
      error = ER_QPROC_INVALID_XASLNODE;
      stx_set_xasl_errcode (thread_p, error);
      goto exit_on_error;
    }
  else
    {
      all_domains = (TP_DOMAIN **) stx_alloc_struct (thread_p, sizeof (TP_DOMAIN *) * domain_cnt * 3);
      if (all_domains == NULL)
    {
      er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (TP_DOMAIN *) * domain_cnt * 3);
      goto exit_on_error;
    }

      /* It is initialized before execution, so initialization here is unnecessary. */
      node_p->domain_info.outer.domains = all_domains;
      node_p->domain_info.inner.domains = all_domains + domain_cnt;
      node_p->domain_info.coerce_domains = all_domains + domain_cnt * 2;

      node_p->domain_info.outer.value_indexes = node_p->merge_info.ls_outer_column;
      node_p->domain_info.inner.value_indexes = node_p->merge_info.ls_inner_column;
    }

  return ptr;

exit_on_error:
  if (error == NO_ERROR)
    {
      error = stx_get_xasl_errcode (thread_p);
      if (error == NO_ERROR)
    {
      stx_set_xasl_errcode (thread_p, ER_QPROC_INVALID_XASLNODE);
    }
    }

  return NULL;
}

static char *
stx_build_ls_merge_info (THREAD_ENTRY * thread_p, char *ptr, QFILE_LIST_MERGE_INFO * list_merge_info)
{
  int tmp, offset;
  int single_fetch;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &tmp);
  list_merge_info->join_type = (JOIN_TYPE) tmp;

  ptr = or_unpack_int (ptr, &single_fetch);
  list_merge_info->single_fetch = (QPROC_SINGLE_FETCH) single_fetch;

  ptr = or_unpack_int (ptr, &list_merge_info->ls_column_cnt);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || list_merge_info->ls_column_cnt == 0)
    {
      list_merge_info->ls_outer_column = NULL;
    }
  else
    {
      list_merge_info->ls_outer_column =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], list_merge_info->ls_column_cnt);
      if (list_merge_info->ls_outer_column == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || list_merge_info->ls_column_cnt == 0)
    {
      list_merge_info->ls_outer_unique = NULL;
    }
  else
    {
      list_merge_info->ls_outer_unique =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], list_merge_info->ls_column_cnt);
      if (list_merge_info->ls_outer_unique == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || list_merge_info->ls_column_cnt == 0)
    {
      list_merge_info->ls_inner_column = NULL;
    }
  else
    {
      list_merge_info->ls_inner_column =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], list_merge_info->ls_column_cnt);
      if (list_merge_info->ls_inner_column == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if ((offset == 0) || (list_merge_info->ls_column_cnt == 0))
    {
      list_merge_info->ls_inner_unique = NULL;
    }
  else
    {
      list_merge_info->ls_inner_unique =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], list_merge_info->ls_column_cnt);
      if (list_merge_info->ls_inner_unique == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &list_merge_info->ls_pos_cnt);

  ptr = or_unpack_int (ptr, &offset);
  if ((offset == 0) || (list_merge_info->ls_pos_cnt == 0))
    {
      list_merge_info->ls_pos_list = NULL;
    }
  else
    {
      list_merge_info->ls_pos_list =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], list_merge_info->ls_pos_cnt);
      if (list_merge_info->ls_pos_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || list_merge_info->ls_pos_cnt == 0)
    {
      list_merge_info->ls_outer_inner_list = NULL;
    }
  else
    {
      list_merge_info->ls_outer_inner_list =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], list_merge_info->ls_pos_cnt);
      if (list_merge_info->ls_outer_inner_list == NULL)
    {
      goto error;
    }
    }

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_update_class_info (THREAD_ENTRY * thread_p, char *ptr, UPDDEL_CLASS_INFO * upd_cls)
{
  int offset = 0;
  int i;
  char *p;

  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  /* num_subclasses */
  ptr = or_unpack_int (ptr, &upd_cls->num_subclasses);

  /* class_oid */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || upd_cls->num_subclasses == 0)
    {
      upd_cls->class_oid = NULL;
    }
  else
    {
      upd_cls->class_oid =
    stx_restore_OID_array (thread_p, &xasl_unpack_info->packed_xasl[offset], upd_cls->num_subclasses);
      if (upd_cls->class_oid == NULL)
    {
      return NULL;
    }
    }

  /* class_hfid */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || upd_cls->num_subclasses == 0)
    {
      upd_cls->class_hfid = NULL;
    }
  else
    {
      upd_cls->class_hfid =
    stx_restore_hfid_array (thread_p, &xasl_unpack_info->packed_xasl[offset], upd_cls->num_subclasses);
      if (upd_cls->class_hfid == NULL)
    {
      return NULL;
    }
    }

  /* num_attrs & att_id */
  ptr = or_unpack_int (ptr, &upd_cls->num_attrs);
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || upd_cls->num_attrs == 0)
    {
      upd_cls->att_id = NULL;
    }
  else
    {
      upd_cls->att_id =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset],
                   upd_cls->num_attrs * upd_cls->num_subclasses);
      if (upd_cls->att_id == NULL)
    {
      return NULL;
    }
    }

  /* partition pruning info */
  ptr = or_unpack_int (ptr, &upd_cls->needs_pruning);
  /* has_uniques */
  ptr = or_unpack_int (ptr, &upd_cls->has_uniques);

  /* num_lob_attrs */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || upd_cls->num_subclasses == 0)
    {
      upd_cls->num_lob_attrs = NULL;
    }
  else
    {
      upd_cls->num_lob_attrs =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], upd_cls->num_subclasses);
      if (upd_cls->num_lob_attrs == NULL)
    {
      return NULL;
    }
    }
  /* lob_attr_ids */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || upd_cls->num_subclasses == 0)
    {
      upd_cls->lob_attr_ids = NULL;
    }
  else
    {
      upd_cls->lob_attr_ids = (int **) stx_alloc_struct (thread_p, upd_cls->num_subclasses * sizeof (int *));
      if (!upd_cls->lob_attr_ids)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
      p = &xasl_unpack_info->packed_xasl[offset];
      for (i = 0; i < upd_cls->num_subclasses; i++)
    {
      p = or_unpack_int (p, &offset);
      if (offset == 0 || upd_cls->num_lob_attrs[i] == 0)
        {
          upd_cls->lob_attr_ids[i] = NULL;
        }
      else
        {
          upd_cls->lob_attr_ids[i] =
        stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], upd_cls->num_lob_attrs[i]);
          if (upd_cls->lob_attr_ids[i] == NULL)
        {
          return NULL;
        }
        }
    }
    }
  /* make sure num_lob_attrs and lob_attr_ids are both NULL or are both not NULL */
  assert ((upd_cls->num_lob_attrs && upd_cls->lob_attr_ids) || (!upd_cls->num_lob_attrs && !upd_cls->lob_attr_ids));

  /* num_extra_assign_reev & mvcc_extra_assign_reev */
  ptr = or_unpack_int (ptr, &upd_cls->num_extra_assign_reev);
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || upd_cls->num_extra_assign_reev == 0)
    {
      upd_cls->mvcc_extra_assign_reev = NULL;
    }
  else
    {
      upd_cls->mvcc_extra_assign_reev =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], upd_cls->num_extra_assign_reev);
      if (upd_cls->mvcc_extra_assign_reev == NULL)
    {
      return NULL;
    }
    }

  return ptr;
}

static UPDDEL_CLASS_INFO *
stx_restore_update_class_info_array (THREAD_ENTRY * thread_p, char *ptr, int num_classes)
{
  int idx;
  UPDDEL_CLASS_INFO *classes = NULL;

  classes = (UPDDEL_CLASS_INFO *) stx_alloc_struct (thread_p, sizeof (*classes) * num_classes);
  if (classes == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  for (idx = 0; idx < num_classes; idx++)
    {
      ptr = stx_build_update_class_info (thread_p, ptr, &classes[idx]);
      if (ptr == NULL)
    {
      return NULL;
    }
    }

  return classes;
}

static char *
stx_build_update_assignment (THREAD_ENTRY * thread_p, char *ptr, UPDATE_ASSIGNMENT * assign)
{
  int offset = 0;
  XASL_UNPACK_INFO *xasl_unpack_info_p = get_xasl_unpack_info_ptr (thread_p);

  /* cls_idx */
  ptr = or_unpack_int (ptr, &assign->cls_idx);

  /* att_idx */
  ptr = or_unpack_int (ptr, &assign->att_idx);

  /* constant */
  assign->clear_value_at_clone_decache = false;
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      assign->constant = NULL;
    }
  else
    {
      assign->constant = stx_restore_db_value (thread_p, &xasl_unpack_info_p->packed_xasl[offset]);
      if (assign->constant == NULL)
    {
      return NULL;
    }
      if (xasl_unpack_info_p->use_xasl_clone && !db_value_is_null (assign->constant))
    {
      assign->clear_value_at_clone_decache = true;
    }
    }

  /* regu_var */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      assign->regu_var = NULL;
    }
  else
    {
      assign->regu_var = stx_restore_regu_variable (thread_p, &xasl_unpack_info_p->packed_xasl[offset]);
      if (assign->regu_var == NULL)
    {
      return NULL;
    }
    }

  return ptr;
}

static UPDATE_ASSIGNMENT *
stx_restore_update_assignment_array (THREAD_ENTRY * thread_p, char *ptr, int num_assigns)
{
  int idx;
  UPDATE_ASSIGNMENT *assigns = NULL;

  assigns = (UPDATE_ASSIGNMENT *) stx_alloc_struct (thread_p, sizeof (*assigns) * num_assigns);
  if (assigns == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  for (idx = 0; idx < num_assigns; idx++)
    {
      ptr = stx_build_update_assignment (thread_p, ptr, &assigns[idx]);
      if (ptr == NULL)
    {
      return NULL;
    }
    }

  return assigns;
}

static ODKU_INFO *
stx_restore_odku_info (THREAD_ENTRY * thread_p, char *ptr)
{
  ODKU_INFO *odku_info = NULL;
  int offset;

  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  odku_info = (ODKU_INFO *) stx_alloc_struct (thread_p, sizeof (ODKU_INFO));
  if (odku_info == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }

  /* num_assigns */
  ptr = or_unpack_int (ptr, &odku_info->num_assigns);

  /* attr_ids */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      odku_info->attr_ids = NULL;
    }
  else
    {
      odku_info->attr_ids =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], odku_info->num_assigns);
      if (odku_info->attr_ids == NULL)
    {
      return NULL;
    }
    }

  /* assignments */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      odku_info->assignments = NULL;
    }
  else
    {
      odku_info->assignments =
    stx_restore_update_assignment_array (thread_p, &xasl_unpack_info->packed_xasl[offset], odku_info->num_assigns);
      if (odku_info->assignments == NULL)
    {
      return NULL;
    }
    }

  /* constraint predicate */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      odku_info->cons_pred = NULL;
    }
  else
    {
      odku_info->cons_pred = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (odku_info->cons_pred == NULL)
    {
      return NULL;
    }
    }

  /* cache attr info */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      odku_info->attr_info = NULL;
    }
  else
    {
      odku_info->attr_info = stx_restore_cache_attrinfo (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (odku_info->attr_info == NULL)
    {
      return NULL;
    }
    }

  return odku_info;
}

static char *
stx_build_update_proc (THREAD_ENTRY * thread_p, char *ptr, UPDATE_PROC_NODE * update_info)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  /* classes */
  ptr = or_unpack_int (ptr, &update_info->num_classes);
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || update_info->num_classes == 0)
    {
      stx_set_xasl_errcode (thread_p, ER_GENERIC_ERROR);
      return NULL;
    }
  else
    {
      update_info->classes =
    stx_restore_update_class_info_array (thread_p, &xasl_unpack_info->packed_xasl[offset],
                         update_info->num_classes);
      if (update_info->classes == NULL)
    {
      goto error;
    }
    }

  /* assigns */
  ptr = or_unpack_int (ptr, &update_info->num_assigns);
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || update_info->num_classes == 0)
    {
      update_info->assigns = NULL;
    }
  else
    {
      update_info->assigns =
    stx_restore_update_assignment_array (thread_p, &xasl_unpack_info->packed_xasl[offset],
                         update_info->num_assigns);
      if (update_info->assigns == NULL)
    {
      goto error;
    }
    }

  /* cons_pred */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      update_info->cons_pred = NULL;
    }
  else
    {
      update_info->cons_pred = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (update_info->cons_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &update_info->wait_msecs);
  ptr = or_unpack_int (ptr, &update_info->no_logging);
  ptr = or_unpack_int (ptr, &update_info->no_supplemental_log);
  ptr = or_unpack_int (ptr, &update_info->num_orderby_keys);

  /* restore MVCC condition reevaluation data */
  ptr = or_unpack_int (ptr, &update_info->num_assign_reev_classes);
  ptr = or_unpack_int (ptr, &update_info->num_reev_classes);
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || update_info->num_reev_classes == 0)
    {
      update_info->mvcc_reev_classes = NULL;
    }
  else
    {
      update_info->mvcc_reev_classes =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], update_info->num_reev_classes);
      if (update_info->mvcc_reev_classes == NULL)
    {
      goto error;
    }
    }

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_delete_proc (THREAD_ENTRY * thread_p, char *ptr, DELETE_PROC_NODE * delete_info)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &delete_info->num_classes);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || delete_info->num_classes == 0)
    {
      delete_info->classes = NULL;
    }
  else
    {
      delete_info->classes =
    stx_restore_update_class_info_array (thread_p, &xasl_unpack_info->packed_xasl[offset],
                         delete_info->num_classes);
      if (delete_info->classes == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &delete_info->wait_msecs);
  ptr = or_unpack_int (ptr, &delete_info->no_logging);
  ptr = or_unpack_int (ptr, &delete_info->no_supplemental_log);

  /* restore MVCC condition reevaluation data */
  ptr = or_unpack_int (ptr, &delete_info->num_reev_classes);
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || delete_info->num_reev_classes == 0)
    {
      delete_info->mvcc_reev_classes = NULL;
    }
  else
    {
      delete_info->mvcc_reev_classes =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], delete_info->num_reev_classes);
      if (delete_info->mvcc_reev_classes == NULL)
    {
      goto error;
    }
    }

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_insert_proc (THREAD_ENTRY * thread_p, char *ptr, INSERT_PROC_NODE * insert_info)
{
  int offset;
  int i;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_oid (ptr, &insert_info->class_oid);

  ptr = or_unpack_hfid (ptr, &insert_info->class_hfid);

  ptr = or_unpack_int (ptr, &insert_info->num_vals);

  ptr = or_unpack_int (ptr, &insert_info->num_default_expr);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || insert_info->num_vals == 0)
    {
      insert_info->att_id = NULL;
    }
  else
    {
      insert_info->att_id =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], insert_info->num_vals);
      if (insert_info->att_id == NULL)
    {
      goto error;
    }
    }

  /* Make space for the subquery values. */
  insert_info->vals = (DB_VALUE **) stx_alloc_struct (thread_p, sizeof (DB_VALUE *) * insert_info->num_vals);
  if (insert_info->num_vals)
    {
      if (insert_info->vals == NULL)
    {
      goto error;
    }
      for (i = 0; i < insert_info->num_vals; ++i)
    {
      insert_info->vals[i] = (DB_VALUE *) 0;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      insert_info->cons_pred = NULL;
    }
  else
    {
      insert_info->cons_pred = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (insert_info->cons_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &insert_info->has_uniques);
  ptr = or_unpack_int (ptr, &insert_info->wait_msecs);
  ptr = or_unpack_int (ptr, &insert_info->no_logging);
  ptr = or_unpack_int (ptr, &insert_info->do_replace);
  ptr = or_unpack_int (ptr, &insert_info->pruning_type);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      insert_info->odku = NULL;
    }
  else
    {
      insert_info->odku = stx_restore_odku_info (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (insert_info->odku == NULL)
    {
      return NULL;
    }
    }

  ptr = or_unpack_int (ptr, &insert_info->num_val_lists);
  if (insert_info->num_val_lists == 0)
    {
      insert_info->valptr_lists = NULL;
    }
  else
    {
      assert (insert_info->num_val_lists > 0);

      insert_info->valptr_lists =
    (OUTPTR_LIST **) stx_alloc_struct (thread_p, sizeof (OUTPTR_LIST *) * insert_info->num_val_lists);
      if (insert_info->valptr_lists == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
      for (i = 0; i < insert_info->num_val_lists; i++)
    {
      ptr = or_unpack_int (ptr, &offset);
      if (ptr == 0)
        {
          assert (0);
          return NULL;
        }
      else
        {
          insert_info->valptr_lists[i] = stx_restore_outptr_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
          if (insert_info->valptr_lists[i] == NULL)
        {
          return NULL;
        }
        }
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      insert_info->obj_oid = NULL;
    }
  else
    {
      insert_info->obj_oid = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (insert_info->obj_oid == NULL)
    {
      return NULL;
    }
      assert (insert_info->obj_oid->need_clear == false);
    }

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_merge_proc (THREAD_ENTRY * thread_p, char *ptr, MERGE_PROC_NODE * merge_info)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);
  int tmp;

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      merge_info->update_xasl = NULL;
    }
  else
    {
      merge_info->update_xasl = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (merge_info->update_xasl == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      merge_info->insert_xasl = NULL;
    }
  else
    {
      merge_info->insert_xasl = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (merge_info->insert_xasl == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &tmp);
  merge_info->has_delete = (bool) tmp;

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_cte_proc (THREAD_ENTRY * thread_p, char *ptr, CTE_PROC_NODE * cte_info)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      cte_info->non_recursive_part = NULL;  /* may have false_where */
    }
  else
    {
      cte_info->non_recursive_part = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);

      if (cte_info->non_recursive_part == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      cte_info->recursive_part = NULL;
    }
  else
    {
      cte_info->recursive_part = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (cte_info->recursive_part == NULL)
    {
      goto error;
    }
    }

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_outptr_list (THREAD_ENTRY * thread_p, char *ptr, OUTPTR_LIST * outptr_list)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &outptr_list->valptr_cnt);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      outptr_list->valptrp = NULL;
    }
  else
    {
      outptr_list->valptrp = stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (outptr_list->valptrp == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  return ptr;
}

static char *
stx_build_selupd_list (THREAD_ENTRY * thread_p, char *ptr, SELUPD_LIST * selupd_list)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_oid (ptr, &selupd_list->class_oid);
  ptr = or_unpack_hfid (ptr, &selupd_list->class_hfid);
  ptr = or_unpack_int (ptr, &selupd_list->select_list_size);
  ptr = or_unpack_int (ptr, &selupd_list->wait_msecs);

  ptr = or_unpack_int (ptr, &offset);
  selupd_list->select_list = stx_restore_regu_varlist_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      selupd_list->next = NULL;
    }
  else
    {
      selupd_list->next = stx_restore_selupd_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (selupd_list->next == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  return ptr;
}

static char *
stx_build_pred_expr (THREAD_ENTRY * thread_p, char *ptr, PRED_EXPR * pred_expr)
{
  int tmp, offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &tmp);
  pred_expr->type = (TYPE_PRED_EXPR) tmp;

  switch (pred_expr->type)
    {
    case T_PRED:
      ptr = stx_build_pred (thread_p, ptr, &pred_expr->pe.m_pred);
      break;

    case T_EVAL_TERM:
      ptr = stx_build_eval_term (thread_p, ptr, &pred_expr->pe.m_eval_term);
      break;

    case T_NOT_TERM:
      ptr = or_unpack_int (ptr, &offset);
      if (offset == 0)
    {
      pred_expr->pe.m_not_term = NULL;
    }
      else
    {
      pred_expr->pe.m_not_term = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (pred_expr->pe.m_not_term == NULL)
        {
          stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
          return NULL;
        }
    }
      break;

    default:
      stx_set_xasl_errcode (thread_p, ER_QPROC_INVALID_XASLNODE);
      return NULL;
    }

  return ptr;
}

static char *
stx_build_pred (THREAD_ENTRY * thread_p, char *ptr, PRED * pred)
{
  int tmp, offset;
  int rhs_type;
  PRED_EXPR *rhs;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  /* lhs */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      pred->lhs = NULL;
    }
  else
    {
      pred->lhs = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (pred->lhs == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &tmp);
  pred->bool_op = (BOOL_OP) tmp;

  ptr = or_unpack_int (ptr, &rhs_type); /* rhs-type */

  /* Traverse right-linear chains of AND/OR terms */
  while (rhs_type == T_PRED)
    {
      pred->rhs = (PRED_EXPR *) stx_alloc_struct (thread_p, sizeof (PRED_EXPR));
      if (pred->rhs == NULL)
    {
      goto error;
    }

      rhs = pred->rhs;

      rhs->type = T_PRED;

      pred = &rhs->pe.m_pred;

      /* lhs */
      ptr = or_unpack_int (ptr, &offset);
      if (offset == 0)
    {
      pred->lhs = NULL;
    }
      else
    {
      pred->lhs = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (pred->lhs == NULL)
        {
          goto error;
        }
    }

      ptr = or_unpack_int (ptr, &tmp);
      pred->bool_op = (BOOL_OP) tmp;    /* bool_op */

      ptr = or_unpack_int (ptr, &rhs_type); /* rhs-type */
    }

  /* rhs */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      pred->rhs = NULL;
    }
  else
    {
      pred->rhs = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (pred->rhs == NULL)
    {
      goto error;
    }
    }

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_eval_term (THREAD_ENTRY * thread_p, char *ptr, EVAL_TERM * eval_term)
{
  int tmp;

  ptr = or_unpack_int (ptr, &tmp);
  eval_term->et_type = (TYPE_EVAL_TERM) tmp;

  switch (eval_term->et_type)
    {
    case T_COMP_EVAL_TERM:
      ptr = stx_build_comp_eval_term (thread_p, ptr, &eval_term->et.et_comp);
      break;

    case T_ALSM_EVAL_TERM:
      ptr = stx_build_alsm_eval_term (thread_p, ptr, &eval_term->et.et_alsm);
      break;

    case T_LIKE_EVAL_TERM:
      ptr = stx_build_like_eval_term (thread_p, ptr, &eval_term->et.et_like);
      break;

    case T_RLIKE_EVAL_TERM:
      ptr = stx_build_rlike_eval_term (thread_p, ptr, &eval_term->et.et_rlike);
      break;

    default:
      stx_set_xasl_errcode (thread_p, ER_QPROC_INVALID_XASLNODE);
      return NULL;
    }

  return ptr;
}

static char *
stx_build_comp_eval_term (THREAD_ENTRY * thread_p, char *ptr, COMP_EVAL_TERM * comp_eval_term)
{
  int tmp, offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      comp_eval_term->lhs = NULL;
    }
  else
    {
      comp_eval_term->lhs = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (comp_eval_term->lhs == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      comp_eval_term->rhs = NULL;
    }
  else
    {
      comp_eval_term->rhs = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (comp_eval_term->rhs == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  ptr = or_unpack_int (ptr, &tmp);
  comp_eval_term->rel_op = (REL_OP) tmp;

  ptr = or_unpack_int (ptr, &tmp);
  comp_eval_term->type = (DB_TYPE) tmp;

  return ptr;
}

static char *
stx_build_alsm_eval_term (THREAD_ENTRY * thread_p, char *ptr, ALSM_EVAL_TERM * alsm_eval_term)
{
  int tmp, offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      alsm_eval_term->elem = NULL;
    }
  else
    {
      alsm_eval_term->elem = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (alsm_eval_term->elem == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      alsm_eval_term->elemset = NULL;
    }
  else
    {
      alsm_eval_term->elemset = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (alsm_eval_term->elemset == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  ptr = or_unpack_int (ptr, &tmp);
  alsm_eval_term->eq_flag = (QL_FLAG) tmp;

  ptr = or_unpack_int (ptr, &tmp);
  alsm_eval_term->rel_op = (REL_OP) tmp;

  ptr = or_unpack_int (ptr, &tmp);
  alsm_eval_term->item_type = (DB_TYPE) tmp;

  return ptr;
}

static char *
stx_build_like_eval_term (THREAD_ENTRY * thread_p, char *ptr, LIKE_EVAL_TERM * like_eval_term)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      like_eval_term->src = NULL;
    }
  else
    {
      like_eval_term->src = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (like_eval_term->src == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      like_eval_term->pattern = NULL;
    }
  else
    {
      like_eval_term->pattern = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (like_eval_term->pattern == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      like_eval_term->esc_char = NULL;
    }
  else
    {
      like_eval_term->esc_char = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (like_eval_term->esc_char == NULL)
    {
      goto error;
    }
    }

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_rlike_eval_term (THREAD_ENTRY * thread_p, char *ptr, RLIKE_EVAL_TERM * rlike_eval_term)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      rlike_eval_term->src = NULL;
    }
  else
    {
      rlike_eval_term->src = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (rlike_eval_term->src == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      rlike_eval_term->pattern = NULL;
    }
  else
    {
      rlike_eval_term->pattern = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (rlike_eval_term->pattern == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      rlike_eval_term->case_sensitive = NULL;
    }
  else
    {
      rlike_eval_term->case_sensitive = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (rlike_eval_term->case_sensitive == NULL)
    {
      goto error;
    }
    }

  /* initialize regex object pointer */
  rlike_eval_term->compiled_regex = NULL;

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}


static char *
stx_build_access_spec_type (THREAD_ENTRY * thread_p, char *ptr, ACCESS_SPEC_TYPE * access_spec, void *arg)
{
  int tmp, offset;
  int val;
  OUTPTR_LIST *outptr_list = NULL;

  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &tmp);
  access_spec->type = (TARGET_TYPE) tmp;

  ptr = or_unpack_int (ptr, &tmp);
  access_spec->access = (ACCESS_METHOD) tmp;

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      access_spec->indexptr = NULL;
    }
  else
    {
      access_spec->indexptr = stx_restore_indx_info (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (access_spec->indexptr == NULL)
    {
      goto error;
    }
      /* backup index id */
      access_spec->btid = access_spec->indexptr->btid;
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      access_spec->where_key = NULL;
    }
  else
    {
      access_spec->where_key = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (access_spec->where_key == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      access_spec->where_pred = NULL;
    }
  else
    {
      access_spec->where_pred = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (access_spec->where_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      access_spec->where_range = NULL;
    }
  else
    {
      access_spec->where_range = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (access_spec->where_range == NULL)
    {
      goto error;
    }
    }

  switch (access_spec->type)
    {
    case TARGET_CLASS:
    case TARGET_CLASS_ATTR:
      ptr = stx_build_cls_spec_type (thread_p, ptr, &ACCESS_SPEC_CLS_SPEC (access_spec));
      break;

    case TARGET_LIST:
      ptr = stx_build_list_spec_type (thread_p, ptr, &ACCESS_SPEC_LIST_SPEC (access_spec));
      break;

    case TARGET_SHOWSTMT:
      ptr = stx_build_showstmt_spec_type (thread_p, ptr, &ACCESS_SPEC_SHOWSTMT_SPEC (access_spec));
      break;

    case TARGET_REGUVAL_LIST:
      /* only for the customized type, arg is valid for the transition of customized outptr info */
      outptr_list = (OUTPTR_LIST *) arg;
      ptr = stx_build_rlist_spec_type (thread_p, ptr, &ACCESS_SPEC_RLIST_SPEC (access_spec), outptr_list);
      break;

    case TARGET_SET:
      ptr = stx_build_set_spec_type (thread_p, ptr, &ACCESS_SPEC_SET_SPEC (access_spec));
      break;

    case TARGET_METHOD:
      ptr = stx_build_method_spec_type (thread_p, ptr, &ACCESS_SPEC_METHOD_SPEC (access_spec));
      break;

    case TARGET_JSON_TABLE:
      ptr = stx_build (thread_p, ptr, ACCESS_SPEC_JSON_TABLE_SPEC (access_spec));
      break;

    case TARGET_DBLINK:
      ptr = stx_build_dblink_spec_type (thread_p, ptr, &ACCESS_SPEC_DBLINK_SPEC (access_spec));
      break;

    default:
      stx_set_xasl_errcode (thread_p, ER_QPROC_INVALID_XASLNODE);
      return NULL;
    }

  if (ptr == NULL)
    {
      return NULL;
    }

  /* access_spec_type->s_id not sent to server */
  memset (&access_spec->s_id, '\0', sizeof (SCAN_ID));
  if (access_spec->type == TARGET_METHOD)
    {
      access_spec->s_id.s.msid.constructor ();
    }

  access_spec->s_id.status = S_CLOSED;

  if (access_spec->type == TARGET_JSON_TABLE)
    {
      // also initialize scan part; it is enough to call it once here, not on each query execution
      // since we initialize the json table here, we also have to initialize s_id.type
      access_spec->s_id.type = S_JSON_TABLE_SCAN;
      access_spec->s_id.s.jtid.init (access_spec->s.json_table_node);
    }

  access_spec->grouped_scan = false;
  access_spec->fixed_scan = false;

  ptr = or_unpack_int (ptr, &tmp);
  access_spec->single_fetch = (QPROC_SINGLE_FETCH) tmp;

  ptr = or_unpack_int (ptr, &access_spec->pruning_type);
  access_spec->parts = NULL;
  access_spec->curent = NULL;
  access_spec->pruned = false;

  access_spec->clear_value_at_clone_decache = xasl_unpack_info->use_xasl_clone;
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      access_spec->s_dbval = NULL;
    }
  else
    {
      access_spec->s_dbval = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (access_spec->s_dbval == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &val);
  access_spec->flags = val;

  ptr = or_unpack_int (ptr, &val);
  access_spec->num_parallel_threads = val;

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_indx_info (THREAD_ENTRY * thread_p, char *ptr, INDX_INFO * indx_info)
{
  int tmp, offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_btid (ptr, &indx_info->btid);

  ptr = or_unpack_int (ptr, &indx_info->coverage);

  ptr = or_unpack_int (ptr, &tmp);
  indx_info->range_type = (RANGE_TYPE) tmp;

  ptr = stx_build_key_info (thread_p, ptr, &indx_info->key_info);
  if (ptr == NULL)
    {
      return NULL;
    }

  ptr = or_unpack_int (ptr, &indx_info->orderby_desc);

  ptr = or_unpack_int (ptr, &indx_info->groupby_desc);

  ptr = or_unpack_int (ptr, &indx_info->use_desc_index);

  ptr = or_unpack_int (ptr, &indx_info->orderby_skip);

  ptr = or_unpack_int (ptr, &indx_info->groupby_skip);

  ptr = or_unpack_int (ptr, &indx_info->use_iss);

  ptr = or_unpack_int (ptr, &indx_info->ils_prefix_len);

  ptr = or_unpack_int (ptr, &indx_info->func_idx_col_id);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      indx_info->cov_list_id = NULL;
    }
  else
    {
      indx_info->cov_list_id = stx_restore_list_id (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (indx_info->cov_list_id == NULL)
    {
      return NULL;
    }
    }

  if (indx_info->use_iss)
    {
      ptr = or_unpack_int (ptr, &tmp);
      indx_info->iss_range.range = (RANGE) tmp;

      ptr = or_unpack_int (ptr, &offset);
      if (offset == 0)
    {
      /* can't go on without correct range */
      return NULL;
    }
      else
    {
      indx_info->iss_range.key1 = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (indx_info->iss_range.key1 == NULL)
        {
          stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
          return NULL;
        }
    }

      indx_info->iss_range.key2 = NULL;
    }

  return ptr;
}

static char *
stx_build_key_info (THREAD_ENTRY * thread_p, char *ptr, KEY_INFO * key_info)
{
  int offset;
  int i;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &key_info->key_cnt);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || key_info->key_cnt == 0)
    {
      key_info->key_ranges = NULL;
    }
  else
    {
      key_info->key_ranges =
    stx_restore_key_range_array (thread_p, &xasl_unpack_info->packed_xasl[offset], key_info->key_cnt);
      if (key_info->key_ranges == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || key_info->key_cnt == 0)
    {
      key_info->key_vals = NULL;
    }
  else
    {
      key_info->key_vals =
    stx_restore_key_val_array (thread_p, &xasl_unpack_info->packed_xasl[offset], key_info->key_cnt);
      if (key_info->key_vals == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  ptr = or_unpack_int (ptr, &i);
  key_info->is_constant = (bool) i;

  ptr = or_unpack_int (ptr, &i);
  key_info->key_limit_reset = (bool) i;

  ptr = or_unpack_int (ptr, &i);
  key_info->is_user_given_keylimit = (bool) i;

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      key_info->key_limit_l = NULL;
    }
  else
    {
      key_info->key_limit_l = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (key_info->key_limit_l == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      key_info->key_limit_u = NULL;
    }
  else
    {
      key_info->key_limit_u = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (key_info->key_limit_u == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  return ptr;
}

static char *
stx_build_cls_spec_type (THREAD_ENTRY * thread_p, char *ptr, CLS_SPEC_TYPE * cls_spec)
{
  int tmp, offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_hfid (ptr, &cls_spec->hfid);
  ptr = or_unpack_oid (ptr, &cls_spec->cls_oid);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      cls_spec->cls_regu_list_key = NULL;
    }
  else
    {
      cls_spec->cls_regu_list_key = stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (cls_spec->cls_regu_list_key == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      cls_spec->cls_regu_list_pred = NULL;
    }
  else
    {
      cls_spec->cls_regu_list_pred = stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (cls_spec->cls_regu_list_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      cls_spec->cls_regu_list_rest = NULL;
    }
  else
    {
      cls_spec->cls_regu_list_rest = stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (cls_spec->cls_regu_list_rest == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      cls_spec->cls_regu_list_range = NULL;
    }
  else
    {
      cls_spec->cls_regu_list_range = stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (cls_spec->cls_regu_list_range == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      cls_spec->cls_output_val_list = NULL;
    }
  else
    {
      cls_spec->cls_output_val_list = stx_restore_outptr_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (cls_spec->cls_output_val_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      cls_spec->cls_regu_val_list = NULL;
    }
  else
    {
      cls_spec->cls_regu_val_list = stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (cls_spec->cls_regu_val_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &cls_spec->num_attrs_key);
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || cls_spec->num_attrs_key == 0)
    {
      cls_spec->attrids_key = NULL;
    }
  else
    {
      cls_spec->attrids_key =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], cls_spec->num_attrs_key);
      if (cls_spec->attrids_key == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      cls_spec->cache_key = NULL;
    }
  else
    {
      cls_spec->cache_key = stx_restore_cache_attrinfo (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (cls_spec->cache_key == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &cls_spec->num_attrs_pred);
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || cls_spec->num_attrs_pred == 0)
    {
      cls_spec->attrids_pred = NULL;
    }
  else
    {
      cls_spec->attrids_pred =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], cls_spec->num_attrs_pred);
      if (cls_spec->attrids_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      cls_spec->cache_pred = NULL;
    }
  else
    {
      cls_spec->cache_pred = stx_restore_cache_attrinfo (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (cls_spec->cache_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &cls_spec->num_attrs_rest);
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || cls_spec->num_attrs_rest == 0)
    {
      cls_spec->attrids_rest = NULL;
    }
  else
    {
      cls_spec->attrids_rest =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], cls_spec->num_attrs_rest);
      if (cls_spec->attrids_rest == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      cls_spec->cache_rest = NULL;
    }
  else
    {
      cls_spec->cache_rest = stx_restore_cache_attrinfo (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (cls_spec->cache_rest == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &tmp);
  cls_spec->schema_type = (ACCESS_SCHEMA_TYPE) tmp;

  ptr = or_unpack_int (ptr, &cls_spec->num_attrs_reserved);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      cls_spec->cache_reserved = NULL;
    }
  else
    {
      cls_spec->cache_reserved =
    stx_restore_db_value_array_extra (thread_p, &xasl_unpack_info->packed_xasl[offset],
                      cls_spec->num_attrs_reserved, cls_spec->num_attrs_reserved);
      if (cls_spec->cache_reserved == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      cls_spec->cls_regu_list_reserved = NULL;
    }
  else
    {
      cls_spec->cls_regu_list_reserved =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (cls_spec->cls_regu_list_reserved == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &cls_spec->num_attrs_range);
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0 || cls_spec->num_attrs_range == 0)
    {
      cls_spec->attrids_range = NULL;
    }
  else
    {
      cls_spec->attrids_range =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], cls_spec->num_attrs_range);
      if (cls_spec->attrids_range == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      cls_spec->cache_range = NULL;
    }
  else
    {
      cls_spec->cache_range = stx_restore_cache_attrinfo (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (cls_spec->cache_range == NULL)
    {
      goto error;
    }
    }

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_list_spec_type (THREAD_ENTRY * thread_p, char *ptr, LIST_SPEC_TYPE * list_spec_type)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      list_spec_type->xasl_node = NULL;
    }
  else
    {
      list_spec_type->xasl_node = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (list_spec_type->xasl_node == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      list_spec_type->list_regu_list_pred = NULL;
    }
  else
    {
      list_spec_type->list_regu_list_pred =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (list_spec_type->list_regu_list_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      list_spec_type->list_regu_list_rest = NULL;
    }
  else
    {
      list_spec_type->list_regu_list_rest =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (list_spec_type->list_regu_list_rest == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      list_spec_type->list_regu_list_build = NULL;
    }
  else
    {
      list_spec_type->list_regu_list_build =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (list_spec_type->list_regu_list_build == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      list_spec_type->list_regu_list_probe = NULL;
    }
  else
    {
      list_spec_type->list_regu_list_probe =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (list_spec_type->list_regu_list_probe == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, (int *) &list_spec_type->hash_list_scan_yn);

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_showstmt_spec_type (THREAD_ENTRY * thread_p, char *ptr, SHOWSTMT_SPEC_TYPE * showstmt_spec_type)
{
  int offset;
  int val;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &val);
  showstmt_spec_type->show_type = (SHOWSTMT_TYPE) val;

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      showstmt_spec_type->arg_list = NULL;
    }
  else
    {
      showstmt_spec_type->arg_list = stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (showstmt_spec_type->arg_list == NULL)
    {
      goto error;
    }
    }

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_rlist_spec_type (THREAD_ENTRY * thread_p, char *ptr, REGUVAL_LIST_SPEC_TYPE * spec, OUTPTR_LIST * outptr_list)
{
  assert (ptr != NULL && spec != NULL);

  if (outptr_list == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_QPROC_INVALID_XASLNODE);
      return NULL;
    }
  spec->valptr_list = outptr_list;

  return ptr;
}

static char *
stx_build_set_spec_type (THREAD_ENTRY * thread_p, char *ptr, SET_SPEC_TYPE * set_spec)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      set_spec->set_ptr = NULL;
    }
  else
    {
      set_spec->set_ptr = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (set_spec->set_ptr == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      set_spec->set_regu_list = NULL;
    }
  else
    {
      set_spec->set_regu_list = stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (set_spec->set_regu_list == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  return ptr;
}

static char *
stx_build_method_spec_type (THREAD_ENTRY * thread_p, char *ptr, METHOD_SPEC_TYPE * method_spec)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      method_spec->xasl_node = NULL;
    }
  else
    {
      method_spec->xasl_node = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (method_spec->xasl_node == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      method_spec->method_regu_list = NULL;
    }
  else
    {
      method_spec->method_regu_list = stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (method_spec->method_regu_list == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      method_spec->sig_array = NULL;
    }
  else
    {
      method_spec->sig_array = stx_restore_pl_sig_array (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (method_spec->sig_array == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  return ptr;
}

static char *
stx_build_dblink_spec_type (THREAD_ENTRY * thread_p, char *ptr, DBLINK_SPEC_TYPE * dblink_spec)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      dblink_spec->dblink_regu_list_pred = NULL;
    }
  else
    {
      dblink_spec->dblink_regu_list_pred =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (dblink_spec->dblink_regu_list_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      dblink_spec->dblink_regu_list_rest = NULL;
    }
  else
    {
      dblink_spec->dblink_regu_list_rest =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (dblink_spec->dblink_regu_list_rest == NULL)
    {
      goto error;
    }
    }

  /* host variable count */
  ptr = or_unpack_int (ptr, &dblink_spec->host_var_count);
  if (dblink_spec->host_var_count > 0)
    {
      ptr = or_unpack_int (ptr, &offset);
      dblink_spec->host_var_index =
    stx_restore_int_array (thread_p, &xasl_unpack_info->packed_xasl[offset], dblink_spec->host_var_count);
      if (dblink_spec->host_var_index == NULL)
    {
      goto error;
    }
    }

  dblink_spec->conn_url = stx_restore_string (thread_p, ptr);
  dblink_spec->conn_user = stx_restore_string (thread_p, ptr);
  dblink_spec->conn_password = stx_restore_string (thread_p, ptr);
  dblink_spec->conn_sql = stx_restore_string (thread_p, ptr);

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_val_list (THREAD_ENTRY * thread_p, char *ptr, VAL_LIST * val_list)
{
  int offset, i;
  QPROC_DB_VALUE_LIST value_list = NULL;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &val_list->val_cnt);

  value_list =
    (QPROC_DB_VALUE_LIST) stx_alloc_struct (thread_p, sizeof (struct qproc_db_value_list) * val_list->val_cnt);
  if (val_list->val_cnt)
    {
      if (value_list == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  for (i = 0; i < val_list->val_cnt; i++)
    {
      ptr = or_unpack_int (ptr, &offset);
      if (offset == 0)
    {
      value_list[i].val = NULL;
    }
      else
    {
      value_list[i].val = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (value_list[i].val == NULL)
        {
          stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
          return NULL;
        }
      assert (value_list[i].val->need_clear == false);
    }

      ptr = or_unpack_domain (ptr, &value_list[i].dom, NULL);
      if (value_list[i].dom == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
      value_list[i].dom = tp_domain_cache (value_list[i].dom);

      if (i < val_list->val_cnt - 1)
    {
      value_list[i].next = (QPROC_DB_VALUE_LIST) (&value_list[i + 1]);
    }
      else
    {
      value_list[i].next = NULL;
    }
    }

  val_list->valp = value_list;

  return ptr;
}

#if defined(ENABLE_UNUSED_FUNCTION)
static char *
stx_build_db_value_list (THREAD_ENTRY * thread_p, char *ptr, QPROC_DB_VALUE_LIST value_list)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = stx_get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      value_list->next = NULL;
    }
  else
    {
      value_list->next = stx_restore_db_value_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (value_list->next == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      value_list->val = NULL;
    }
  else
    {
      value_list->val = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (value_list->val == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  return ptr;
}
#endif

static char *
stx_build_regu_variable (THREAD_ENTRY * thread_p, char *ptr, REGU_VARIABLE * regu_var)
{
  int tmp, offset;

  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_domain (ptr, &regu_var->domain, NULL);
  /* save the original domain */
  regu_var->original_domain = regu_var->domain;

  ptr = or_unpack_int (ptr, &tmp);
  regu_var->type = (REGU_DATATYPE) tmp;

  ptr = or_unpack_int (ptr, &regu_var->flags);
  assert (!REGU_VARIABLE_IS_FLAGED (regu_var, REGU_VARIABLE_FETCH_ALL_CONST));
  assert (!REGU_VARIABLE_IS_FLAGED (regu_var, REGU_VARIABLE_FETCH_NOT_CONST));

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      regu_var->vfetch_to = NULL;
    }
  else
    {
      regu_var->vfetch_to = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (regu_var->vfetch_to == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      regu_var->xasl = NULL;
    }
  else
    {
      regu_var->xasl = stx_restore_xasl_node (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (regu_var->xasl == NULL)
    {
      goto error;
    }
    }

  ptr = stx_unpack_regu_variable_value (thread_p, ptr, regu_var);

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_unpack_regu_variable_value (THREAD_ENTRY * thread_p, char *ptr, REGU_VARIABLE * regu_var)
{
  REGU_VALUE_LIST *regu_list;
  REGU_VARIABLE_LIST regu_var_list = NULL;
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info_p = get_xasl_unpack_info_ptr (thread_p);

  assert (ptr != NULL && regu_var != NULL);

  switch (regu_var->type)
    {
    case TYPE_REGU_VAR_LIST:
      ptr = stx_build_regu_variable_list (thread_p, ptr, &regu_var_list);
      if (ptr == NULL)
    {
      goto error;
    }
      regu_var->value.regu_var_list = regu_var_list;
      break;

    case TYPE_REGUVAL_LIST:
      regu_list = stx_regu_value_list_alloc_and_init (thread_p);

      if (regu_list == NULL)
    {
      goto error;
    }

      ptr = stx_build_regu_value_list (thread_p, ptr, regu_list, regu_var->domain);
      if (ptr == NULL)
    {
      goto error;
    }

      regu_var->value.reguval_list = regu_list;
      break;

    case TYPE_DBVAL:
      ptr = stx_build_db_value (thread_p, ptr, &regu_var->value.dbval);
      if (xasl_unpack_info_p->use_xasl_clone && !db_value_is_null (&regu_var->value.dbval))
    {
      REGU_VARIABLE_SET_FLAG (regu_var, REGU_VARIABLE_CLEAR_AT_CLONE_DECACHE);
    }
      break;

    case TYPE_CONSTANT:
    case TYPE_ORDERBY_NUM:
      ptr = or_unpack_int (ptr, &offset);
      if (offset == 0)
    {
      regu_var->value.dbvalptr = NULL;
    }
      else
    {
      regu_var->value.dbvalptr = stx_restore_db_value (thread_p, &xasl_unpack_info_p->packed_xasl[offset]);
      if (regu_var->value.dbvalptr == NULL)
        {
          goto error;
        }
      if (xasl_unpack_info_p->use_xasl_clone && regu_var->value.dbvalptr->need_clear)
        {
          REGU_VARIABLE_SET_FLAG (regu_var, REGU_VARIABLE_CLEAR_AT_CLONE_DECACHE);
        }
    }
      break;

    case TYPE_INARITH:
    case TYPE_OUTARITH:
      ptr = or_unpack_int (ptr, &offset);
      if (offset == 0)
    {
      regu_var->value.arithptr = NULL;
    }
      else
    {
      regu_var->value.arithptr = stx_restore_arith_type (thread_p, &xasl_unpack_info_p->packed_xasl[offset]);
      if (regu_var->value.arithptr == NULL)
        {
          goto error;
        }
    }
      break;

    case TYPE_FUNC:
      ptr = or_unpack_int (ptr, &offset);
      if (offset == 0)
    {
      regu_var->value.funcp = NULL;
    }
      else
    {
      regu_var->value.funcp = stx_restore_function_type (thread_p, &xasl_unpack_info_p->packed_xasl[offset]);
      if (regu_var->value.funcp == NULL)
        {
          goto error;
        }
    }
      break;

    case TYPE_SP:
      ptr = or_unpack_int (ptr, &offset);
      if (offset == 0)
    {
      regu_var->value.sp_ptr = NULL;
    }
      else
    {
      regu_var->value.sp_ptr = stx_restore_sp_type (thread_p, &xasl_unpack_info_p->packed_xasl[offset]);
      if (regu_var->value.sp_ptr == NULL)
        {
          goto error;
        }
    }
      break;

    case TYPE_ATTR_ID:
    case TYPE_SHARED_ATTR_ID:
    case TYPE_CLASS_ATTR_ID:
      ptr = stx_build_attr_descr (thread_p, ptr, &regu_var->value.attr_descr);
      break;

    case TYPE_LIST_ID:
      ptr = or_unpack_int (ptr, &offset);
      if (offset == 0)
    {
      regu_var->value.srlist_id = NULL;
    }
      else
    {
      regu_var->value.srlist_id = stx_restore_srlist_id (thread_p, &xasl_unpack_info_p->packed_xasl[offset]);
      if (regu_var->value.srlist_id == NULL)
        {
          goto error;
        }
    }
      break;

    case TYPE_POSITION:
      ptr = stx_build_pos_descr (ptr, &regu_var->value.pos_descr);
      break;

    case TYPE_POS_VALUE:
      ptr = or_unpack_int (ptr, &regu_var->value.val_pos);
      break;

    case TYPE_OID:
    case TYPE_CLASSOID:
      break;

    default:
      stx_set_xasl_errcode (thread_p, ER_QPROC_INVALID_XASLNODE);
      return NULL;
    }

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_attr_descr (THREAD_ENTRY * thread_p, char *ptr, ATTR_DESCR * attr_descr)
{
  int tmp, offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &tmp);
  attr_descr->id = (CL_ATTR_ID) tmp;

  ptr = or_unpack_int (ptr, &tmp);
  attr_descr->type = (DB_TYPE) tmp;

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      attr_descr->cache_attrinfo = NULL;
    }
  else
    {
      attr_descr->cache_attrinfo = stx_restore_cache_attrinfo (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (attr_descr->cache_attrinfo == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  attr_descr->cache_dbvalp = NULL;

  return ptr;
}

static char *
stx_build_pos_descr (char *ptr, QFILE_TUPLE_VALUE_POSITION * position_descr)
{
  ptr = or_unpack_int (ptr, &position_descr->pos_no);
  ptr = or_unpack_domain (ptr, &position_descr->dom, NULL);
  position_descr->original_domain = position_descr->dom;

  return ptr;
}

static char *
stx_build_arith_type (THREAD_ENTRY * thread_p, char *ptr, ARITH_TYPE * arith_type)
{
  int tmp, offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_domain (ptr, &arith_type->domain, NULL);
  /* save the original domain */
  arith_type->original_domain = arith_type->domain;

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      arith_type->value = NULL;
    }
  else
    {
      arith_type->value = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (arith_type->value == NULL)
    {
      goto error;
    }
      assert (arith_type->value->need_clear == false);
    }

  ptr = or_unpack_int (ptr, &tmp);
  arith_type->opcode = (OPERATOR_TYPE) tmp;

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      arith_type->leftptr = NULL;
    }
  else
    {
      arith_type->leftptr = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (arith_type->leftptr == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      arith_type->rightptr = NULL;
    }
  else
    {
      arith_type->rightptr = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (arith_type->rightptr == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      arith_type->thirdptr = NULL;
    }
  else
    {
      arith_type->thirdptr = stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (arith_type->thirdptr == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &tmp);
  arith_type->misc_operand = (MISC_OPERAND) tmp;

  if (arith_type->opcode == T_CASE || arith_type->opcode == T_DECODE || arith_type->opcode == T_PREDICATE
      || arith_type->opcode == T_IF)
    {
      ptr = or_unpack_int (ptr, &offset);
      if (offset == 0)
    {
      arith_type->pred = NULL;
    }
      else
    {
      arith_type->pred = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (arith_type->pred == NULL)
        {
          goto error;
        }
    }
    }
  else
    {
      arith_type->pred = NULL;
    }

  /* This member is only used on server internally. */
  arith_type->rand_seed = NULL;

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_aggregate_type (THREAD_ENTRY * thread_p, char *ptr, AGGREGATE_TYPE * aggregate)
{
  int offset, flagint = 0;
  int tmp;
  XASL_UNPACK_INFO *xasl_unpack_info_p = get_xasl_unpack_info_ptr (thread_p);

  assert (ptr != NULL && aggregate != NULL);

  /* domain */
  ptr = or_unpack_domain (ptr, &aggregate->domain, NULL);
  aggregate->original_domain = aggregate->domain;

  /* accumulator */
  aggregate->accumulator.clear_value_at_clone_decache = false;
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      aggregate->accumulator.value = NULL;
    }
  else
    {
      aggregate->accumulator.value = stx_restore_db_value (thread_p, &xasl_unpack_info_p->packed_xasl[offset]);
      if (aggregate->accumulator.value == NULL)
    {
      goto error;
    }
      if (xasl_unpack_info_p->use_xasl_clone && !db_value_is_null (aggregate->accumulator.value))
    {
      aggregate->accumulator.clear_value_at_clone_decache = true;
    }
    }

  aggregate->accumulator.clear_value2_at_clone_decache = false;
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      aggregate->accumulator.value2 = NULL;
    }
  else
    {
      aggregate->accumulator.value2 = stx_restore_db_value (thread_p, &xasl_unpack_info_p->packed_xasl[offset]);
      if (aggregate->accumulator.value2 == NULL)
    {
      goto error;
    }
      if (xasl_unpack_info_p->use_xasl_clone && !db_value_is_null (aggregate->accumulator.value2))
    {
      aggregate->accumulator.clear_value2_at_clone_decache = true;
    }
    }

  ptr = or_unpack_int64 (ptr, &aggregate->accumulator.curr_cnt);

  /* next */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      aggregate->next = NULL;
    }
  else
    {
      aggregate->next = stx_restore_aggregate_type (thread_p, &xasl_unpack_info_p->packed_xasl[offset]);
      if (aggregate->next == NULL)
    {
      goto error;
    }
    }

  /* function */
  ptr = or_unpack_int (ptr, &tmp);
  aggregate->function = (FUNC_CODE) tmp;

  /* option */
  ptr = or_unpack_int (ptr, &tmp);
  aggregate->option = (QUERY_OPTIONS) tmp;

  /* opr_dbtype */
  ptr = or_unpack_int (ptr, &tmp);
  aggregate->opr_dbtype = (DB_TYPE) tmp;
  aggregate->original_opr_dbtype = aggregate->opr_dbtype;

  ptr = stx_build_regu_variable_list (thread_p, ptr, &aggregate->operands);
  if (ptr == NULL)
    {
      return NULL;
    }

  /* list_id */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      aggregate->list_id = NULL;
    }
  else
    {
      aggregate->list_id = stx_restore_list_id (thread_p, &xasl_unpack_info_p->packed_xasl[offset]);
      if (aggregate->list_id == NULL)
    {
      goto error;
    }
    }

  /* btid */
  ptr = or_unpack_btid (ptr, &aggregate->btid);

  /* sort_list */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      aggregate->sort_list = NULL;
    }
  else
    {
      aggregate->sort_list = stx_restore_sort_list (thread_p, &xasl_unpack_info_p->packed_xasl[offset]);
      if (aggregate->sort_list == NULL)
    {
      goto error;
    }
    }

  /* info */
  if (aggregate->function == PT_PERCENTILE_CONT || aggregate->function == PT_PERCENTILE_DISC)
    {
      ptr = or_unpack_int (ptr, &offset);
      if (offset > 0)
    {
      aggregate->info.percentile.percentile_reguvar =
        stx_restore_regu_variable (thread_p, &xasl_unpack_info_p->packed_xasl[offset]);
      if (aggregate->info.percentile.percentile_reguvar == NULL)
        {
          goto error;
        }
    }
      else
    {
      goto error;
    }
    }
  else if (aggregate->function == PT_CUME_DIST || aggregate->function == PT_PERCENT_RANK)
    {
      /* init info.dist_percent */
      aggregate->info.dist_percent.const_array = NULL;
      aggregate->info.dist_percent.list_len = 0;
      aggregate->info.dist_percent.nlargers = 0;
    }
  else
    {
      /* Other functions need specific variables if any in the future */
      ;
    }

  /* is_min_max_optimized */
  ptr = or_unpack_int (ptr, &flagint);
  aggregate->flag.agg_optimized = (flagint & (1 << 0)) != 0;
  aggregate->flag.min_max_optimized = (flagint & (1 << 1)) != 0;
  aggregate->flag.part_key_descending = (flagint & (1 << 2)) != 0;
  aggregate->flag.dummy = (flagint & (1 << 3)) != 0;
  /* is_ended */
  ptr = or_unpack_int (ptr, &offset);
  aggregate->is_ended = false;

  /* accumulator_domain */
  aggregate->accumulator_domain.value_dom = NULL;
  aggregate->accumulator_domain.value2_dom = NULL;

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}


static char *
stx_build_sp_type (THREAD_ENTRY * thread_p, char *ptr, SP_TYPE * sp)
{
  int tmp, offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      sp->value = NULL;
    }
  else
    {
      sp->value = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (sp->value == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
      assert (sp->value->need_clear == false);
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      sp->args = NULL;
    }
  else
    {
      sp->args = stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (sp->args == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      sp->sig = NULL;
    }
  else
    {
      sp->sig = stx_restore_pl_sig (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (sp->sig == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  return ptr;
}

static char *
stx_build_function_type (THREAD_ENTRY * thread_p, char *ptr, FUNCTION_TYPE * function)
{
  int tmp, offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      function->value = NULL;
    }
  else
    {
      function->value = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (function->value == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
      assert (function->value->need_clear == false);
    }

  ptr = or_unpack_int (ptr, &tmp);
  function->ftype = (FUNC_CODE) tmp;

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      function->operand = NULL;
    }
  else
    {
      function->operand = stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (function->operand == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  function->tmp_obj = NULL;

  return ptr;
}

static char *
stx_build_analytic_type (THREAD_ENTRY * thread_p, char *ptr, ANALYTIC_TYPE * analytic)
{
  int offset;
  int tmp_i;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  assert (ptr != NULL && analytic != NULL);

  /* domain */
  ptr = or_unpack_domain (ptr, &analytic->domain, NULL);
  analytic->original_domain = analytic->domain;

  /* value */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      analytic->value = NULL;
    }
  else
    {
      analytic->value = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (analytic->value == NULL)
    {
      goto error;
    }
      assert (analytic->value->need_clear == false);
    }

  /* value2 */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      analytic->value2 = NULL;
    }
  else
    {
      analytic->value2 = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (analytic->value2 == NULL)
    {
      goto error;
    }
      assert (analytic->value2->need_clear == false);
    }

  /* out_value */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      analytic->out_value = NULL;
    }
  else
    {
      analytic->out_value = stx_restore_db_value (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (analytic->out_value == NULL)
    {
      goto error;
    }
      assert (analytic->out_value->need_clear == false);
    }

  /* offset_idx */
  ptr = or_unpack_int (ptr, &analytic->offset_idx);

  /* default_idx */
  ptr = or_unpack_int (ptr, &analytic->default_idx);

  /* next */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      analytic->next = NULL;
    }
  else
    {
      analytic->next = stx_restore_analytic_type (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (analytic->next == NULL)
    {
      goto error;
    }
    }

  /* function */
  ptr = or_unpack_int (ptr, &tmp_i);
  analytic->function = (FUNC_CODE) tmp_i;

  /* option */
  ptr = or_unpack_int (ptr, &tmp_i);
  analytic->option = (QUERY_OPTIONS) tmp_i;

  /* opr_dbtype */
  ptr = or_unpack_int (ptr, &tmp_i);
  analytic->opr_dbtype = (DB_TYPE) tmp_i;
  analytic->original_opr_dbtype = analytic->opr_dbtype;

  /* operand */
  ptr = stx_build_regu_variable (thread_p, ptr, &analytic->operand);
  if (ptr == NULL)
    {
      return NULL;
    }

  /* list_id */
  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      analytic->list_id = NULL;
    }
  else
    {
      analytic->list_id = stx_restore_list_id (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (analytic->list_id == NULL)
    {
      goto error;
    }
    }

  /* sort_prefix_size */
  ptr = or_unpack_int (ptr, &analytic->sort_prefix_size);

  /* sort_list_size */
  ptr = or_unpack_int (ptr, &analytic->sort_list_size);

  /* flag */
  ptr = or_unpack_int (ptr, &analytic->flag);

  /* from_last */
  ptr = or_unpack_int (ptr, &tmp_i);
  analytic->from_last = (bool) tmp_i;

  /* ignore_nulls */
  ptr = or_unpack_int (ptr, &tmp_i);
  analytic->ignore_nulls = (bool) tmp_i;

  /* is_const_operand */
  ptr = or_unpack_int (ptr, &tmp_i);
  analytic->is_const_operand = (bool) tmp_i;

  if (analytic->function == PT_PERCENTILE_CONT || analytic->function == PT_PERCENTILE_DISC)
    {
      ptr = or_unpack_int (ptr, &offset);

      if (offset > 0)
    {
      analytic->info.percentile.percentile_reguvar =
        stx_restore_regu_variable (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (analytic->info.percentile.percentile_reguvar == NULL)
        {
          goto error;
        }
    }
      else
    {
      goto error;
    }
    }
  else
    {
      /* Other functions need specific variables if any in the future */
      ;
    }

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_analytic_eval_type (THREAD_ENTRY * thread_p, char *ptr, ANALYTIC_EVAL_TYPE * analytic_eval)
{
  int offset, tmp_i;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);

  assert (offset != 0);     /* head should exist */

  analytic_eval->head = stx_restore_analytic_type (thread_p, &xasl_unpack_info->packed_xasl[offset]);
  if (analytic_eval->head == NULL)
    {
      goto error;
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      analytic_eval->sort_list = NULL;
    }
  else
    {
      analytic_eval->sort_list = stx_restore_sort_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (analytic_eval->sort_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      analytic_eval->next = NULL;
    }
  else
    {
      analytic_eval->next = stx_restore_analytic_eval_type (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (analytic_eval->next == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &tmp_i);
  analytic_eval->sort_list_size = tmp_i;

  analytic_eval->covered_size = 0;  /* not serialized; only used at XASL build time */

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

static char *
stx_build_srlist_id (THREAD_ENTRY * thread_p, char *ptr, QFILE_SORTED_LIST_ID * sort_list_id)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &sort_list_id->sorted);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      sort_list_id->list_id = NULL;
    }
  else
    {
      sort_list_id->list_id = stx_restore_list_id (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (sort_list_id->list_id == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  return ptr;
}

static char *
stx_build_sort_list (THREAD_ENTRY * thread_p, char *ptr, SORT_LIST * sort_list)
{
  int tmp, offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      sort_list->next = NULL;
    }
  else
    {
      sort_list->next = stx_restore_sort_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (sort_list->next == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
      return NULL;
    }
    }

  ptr = stx_build_pos_descr (ptr, &sort_list->pos_descr);
  if (ptr == NULL)
    {
      return NULL;
    }

  ptr = or_unpack_int (ptr, &tmp);
  sort_list->s_order = (SORT_ORDER) tmp;

  ptr = or_unpack_int (ptr, &tmp);
  sort_list->s_nulls = (SORT_NULLS) tmp;

  return ptr;
}

static char *
stx_build_connectby_proc (THREAD_ENTRY * thread_p, char *ptr, CONNECTBY_PROC_NODE * stx_connectby_proc)
{
  int offset;
  int tmp;

  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_connectby_proc->start_with_pred = NULL;
    }
  else
    {
      stx_connectby_proc->start_with_pred = stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_connectby_proc->start_with_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_connectby_proc->after_connect_by_pred = NULL;
    }
  else
    {
      stx_connectby_proc->after_connect_by_pred =
    stx_restore_pred_expr (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_connectby_proc->after_connect_by_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_connectby_proc->input_list_id = NULL;
    }
  else
    {
      stx_connectby_proc->input_list_id = stx_restore_list_id (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_connectby_proc->input_list_id == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_connectby_proc->start_with_list_id = NULL;
    }
  else
    {
      stx_connectby_proc->start_with_list_id = stx_restore_list_id (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_connectby_proc->start_with_list_id == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_connectby_proc->regu_list_pred = NULL;
    }
  else
    {
      stx_connectby_proc->regu_list_pred =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_connectby_proc->regu_list_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_connectby_proc->regu_list_rest = NULL;
    }
  else
    {
      stx_connectby_proc->regu_list_rest =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_connectby_proc->regu_list_rest == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_connectby_proc->prior_val_list = NULL;
    }
  else
    {
      stx_connectby_proc->prior_val_list = stx_restore_val_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_connectby_proc->prior_val_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_connectby_proc->prior_outptr_list = NULL;
    }
  else
    {
      stx_connectby_proc->prior_outptr_list =
    stx_restore_outptr_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_connectby_proc->prior_outptr_list == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_connectby_proc->prior_regu_list_pred = NULL;
    }
  else
    {
      stx_connectby_proc->prior_regu_list_pred =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_connectby_proc->prior_regu_list_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_connectby_proc->prior_regu_list_rest = NULL;
    }
  else
    {
      stx_connectby_proc->prior_regu_list_rest =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_connectby_proc->prior_regu_list_rest == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_connectby_proc->after_cb_regu_list_pred = NULL;
    }
  else
    {
      stx_connectby_proc->after_cb_regu_list_pred =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_connectby_proc->after_cb_regu_list_pred == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      stx_connectby_proc->after_cb_regu_list_rest = NULL;
    }
  else
    {
      stx_connectby_proc->after_cb_regu_list_rest =
    stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (stx_connectby_proc->after_cb_regu_list_rest == NULL)
    {
      goto error;
    }
    }

  ptr = or_unpack_int (ptr, &tmp);
  stx_connectby_proc->single_table_opt = (bool) tmp;
  stx_connectby_proc->curr_tuple = NULL;

  return ptr;

error:
  stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
  return NULL;
}

/* stx_regu_value_list_alloc_and_init () -
 *   return:
 *   thread_p(in)
 */
static REGU_VALUE_LIST *
stx_regu_value_list_alloc_and_init (THREAD_ENTRY * thread_p)
{
  REGU_VALUE_LIST *regu_value_list = NULL;

  regu_value_list = (REGU_VALUE_LIST *) stx_alloc_struct (thread_p, sizeof (REGU_VALUE_LIST));

  if (regu_value_list == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
    }
  else
    {
      regu_value_list->count = 0;
      regu_value_list->current_value = NULL;
      regu_value_list->regu_list = NULL;
    }

  return regu_value_list;
}

/* stx_regu_value_item_alloc_and_init () -
 *   return:
 *   thread_p(in)
 */
static REGU_VALUE_ITEM *
stx_regu_value_item_alloc_and_init (THREAD_ENTRY * thread_p)
{
  REGU_VALUE_ITEM *regu_value_item = NULL;

  regu_value_item = (REGU_VALUE_ITEM *) stx_alloc_struct (thread_p, sizeof (REGU_VALUE_ITEM));

  if (regu_value_item == NULL)
    {
      stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
    }
  else
    {
      regu_value_item->next = NULL;
      regu_value_item->value = NULL;
    }

  return regu_value_item;
}

/* stx_build_regu_value_list () -
 *   return:
 *   thread_p(in)
 *   tmp(in)    :
 *   ptr(in)    : pointer to REGU_VALUE_LIST
 */
static char *
stx_build_regu_value_list (THREAD_ENTRY * thread_p, char *ptr, REGU_VALUE_LIST * regu_value_list, TP_DOMAIN * domain)
{
  int i, count, tmp;
  REGU_VALUE_ITEM *list_node;
  REGU_VARIABLE *regu;

  assert (ptr != NULL && regu_value_list != NULL);

  ptr = or_unpack_int (ptr, &count);
  if (count <= 0)
    {
      stx_set_xasl_errcode (thread_p, ER_QPROC_INVALID_XASLNODE);
      goto error;
    }

  for (i = 0; i < count; ++i)
    {
      list_node = stx_regu_value_item_alloc_and_init (thread_p);
      if (list_node == NULL)
    {
      goto error;
    }

      regu = (REGU_VARIABLE *) stx_get_struct_visited_ptr (thread_p, ptr);
      if (regu == NULL)
    {
      regu = (REGU_VARIABLE *) stx_alloc_struct (thread_p, sizeof (REGU_VARIABLE));
      if (regu == NULL)
        {
          stx_set_xasl_errcode (thread_p, ER_OUT_OF_VIRTUAL_MEMORY);
          goto error;
        }

      if (stx_mark_struct_visited (thread_p, ptr, regu) == ER_FAILED)
        {
          goto error;
        }
    }

      /* Now, we got a REGU_VARIABLE successfully */
      stx_init_regu_variable (regu);
      list_node->value = regu;

      if (regu_value_list->current_value == NULL)
    {
      regu_value_list->regu_list = list_node;
    }
      else
    {
      regu_value_list->current_value->next = list_node;
    }

      regu_value_list->current_value = list_node;

      ptr = or_unpack_int (ptr, &tmp);
      regu->type = (REGU_DATATYPE) tmp;
      regu->domain = domain;
      /* save te original domain */
      regu->original_domain = domain;

      if (regu->type != TYPE_DBVAL && regu->type != TYPE_INARITH && regu->type != TYPE_POS_VALUE)
    {
      stx_set_xasl_errcode (thread_p, ER_QPROC_INVALID_XASLNODE);
      goto error;
    }
      ptr = stx_unpack_regu_variable_value (thread_p, ptr, regu);
      if (ptr == NULL)
    {
      goto error;
    }

      regu_value_list->count += 1;
    }
  regu_value_list->current_value = regu_value_list->regu_list;

  return ptr;

error:
  return NULL;
}

/* stx_build_regu_variable_list () -
 *   return:
 *   thread_p(in)
 *   ptr(out):
 *   regu_var_list(in): pointer to REGU_VARIABLE_LIST
 */
static char *
stx_build_regu_variable_list (THREAD_ENTRY * thread_p, char *ptr, REGU_VARIABLE_LIST * regu_var_list)
{
  int offset;
  XASL_UNPACK_INFO *xasl_unpack_info = get_xasl_unpack_info_ptr (thread_p);

  assert (ptr != NULL && regu_var_list != NULL);

  ptr = or_unpack_int (ptr, &offset);
  if (offset == 0)
    {
      *regu_var_list = NULL;
    }
  else
    {
      *regu_var_list = stx_restore_regu_variable_list (thread_p, &xasl_unpack_info->packed_xasl[offset]);
      if (*regu_var_list == NULL)
    {
      return NULL;
    }
    }

  return ptr;
}

/*
 * init_regu_variable () -
 *   return:
 *   regu(in):    :
 */
static void
stx_init_regu_variable (REGU_VARIABLE * regu)
{
  assert (regu);

  regu->type = TYPE_POS_VALUE;
  regu->flags = 0;
  regu->value.val_pos = 0;
  regu->vfetch_to = NULL;
  regu->domain = NULL;
  regu->xasl = NULL;
}

#if defined(ENABLE_UNUSED_FUNCTION)
/*
 * stx_unpack_char () -
 *   return:
 *   tmp(in)    :
 *   ptr(in)    :
 */
static char *
stx_unpack_char (char *tmp, char *ptr)
{
  int i;

  tmp = or_unpack_int (tmp, &i);
  *ptr = i;

  return tmp;
}

/*
 * stx_unpack_long () -
 *   return:
 *   tmp(in)    :
 *   ptr(in)    :
 */
static char *
stx_unpack_long (char *tmp, long *ptr)
{
  int i;

  tmp = or_unpack_int (tmp, &i);
  *ptr = i;

  return tmp;
}
#endif

char *
stx_build (THREAD_ENTRY * thread_p, char *ptr, regu_variable_node & reguvar)
{
  return stx_build_regu_variable (thread_p, ptr, &reguvar);
}