/* * bh_create () - create an empty heap * return : heap or NULL * max_capacity (in): maximum capacity of the heap * cmp_func (in) : pointer to the comparison function * cmp_arg (in) : argument to be passed to the comparison function * * Note: this implementation considers the heap to be a MAX heap (i.e.: the * root of the heap is the "largest" element). To use the heap as a MIN * heap, callers can use the comparison function to inverse the comparison */ BINARY_HEAP * bh_create (THREAD_ENTRY * thread_p, int max_capacity, bh_key_comparator cmp_func, BH_CMP_ARG cmp_arg) { BINARY_HEAP *heap = NULL; heap = (BINARY_HEAP *) db_private_alloc (thread_p, sizeof (BINARY_HEAP)); if (heap == NULL) { return NULL; } heap->members = (BH_ELEM *) db_private_alloc (thread_p, max_capacity * sizeof (BH_ELEM)); if (heap->members == NULL) { db_private_free (thread_p, heap); return NULL; } memset (heap->members, 0, max_capacity * sizeof (BH_ELEM)); heap->max_capacity = max_capacity; heap->cmp_func = cmp_func; heap->cmp_arg = cmp_arg; heap->element_count = 0; heap->state = BH_HEAP_CONSISTENT; return heap; }
/* * str_to_hex() - convert a string to its hexadecimal expreesion string * return: * thread_p(in): * src(in): * src_len(in): * dest_p(out): * dest_len_p(out): * Note: */ static char * str_to_hex (THREAD_ENTRY * thread_p, const char *src, int src_len, char **dest_p, int *dest_len_p) { static const char hextable[] = "0123456789ABCDEF"; int dest_len = 2 * src_len; int i = 0; unsigned char item_num = 0; char *dest; assert (src != NULL); if (thread_p == NULL) { thread_p = thread_get_thread_entry_info (); } dest = (char *) db_private_alloc (thread_p, dest_len * sizeof (char)); if (dest == NULL) { return NULL; } while (i < src_len) { item_num = (unsigned char) src[i]; dest[2 * i] = hextable[item_num / 16]; dest[2 * i + 1] = hextable[item_num % 16]; i++; } *dest_p = dest; *dest_len_p = dest_len; return dest; }
/* * process_object - process an object * return: 1 - object has changed * 0 - object has not changed * -1 - object failed * upd_scancache(in): * attr_info(in): * oid(in): the oid of the object to process */ static int process_object (THREAD_ENTRY * thread_p, HEAP_SCANCACHE * upd_scancache, HEAP_CACHE_ATTRINFO * attr_info, OID * oid) { int i, result = 0; int updated_flag = 0; HEAP_ATTRVALUE *value = NULL; int force_count = 0, updated_n_attrs_id = 0; int *atts_id = NULL; if (upd_scancache == NULL || attr_info == NULL || oid == NULL) { return -1; } atts_id = (int *) db_private_alloc (thread_p, attr_info->num_values * sizeof (int)); if (atts_id == NULL) { return -1; } for (i = 0, value = attr_info->values; i < attr_info->num_values; i++, value++) { if (process_value (&value->dbvalue)) { value->state = HEAP_WRITTEN_ATTRVALUE; atts_id[updated_n_attrs_id] = value->attrid; updated_n_attrs_id++; } } if ((updated_n_attrs_id > 0) || (attr_info->read_classrepr != NULL && attr_info->last_classrepr != NULL && attr_info->read_classrepr->id != attr_info->last_classrepr->id)) { if (locator_attribute_info_force (thread_p, &upd_scancache->hfid, oid, 0, attr_info, atts_id, updated_n_attrs_id, LC_FLUSH_UPDATE, SINGLE_ROW_UPDATE, upd_scancache, &force_count, false, REPL_INFO_TYPE_STMT_NORMAL) != NO_ERROR) { result = -1; } result = 1; } if (atts_id) { db_private_free (thread_p, atts_id); atts_id = NULL; } return result; }
/* * crypt_sha_one() - * return: * thread_p(in): * src(in): * src_len(in): * dest_len_p(out): * Note: */ int crypt_sha_one (THREAD_ENTRY * thread_p, const char *src, int src_len, char **dest_p, int *dest_len_p) { int hash_length; char *dest = NULL; char *dest_hex = NULL; int dest_len; int dest_hex_len; int error_status = NO_ERROR; assert (src != NULL); if (thread_p == NULL) { thread_p = thread_get_thread_entry_info (); } *dest_p = NULL; if (init_gcrypt () != NO_ERROR) { return ER_ENCRYPTION_LIB_FAILED; } hash_length = gcry_md_get_algo_dlen (GCRY_MD_SHA1); dest = (char *) db_private_alloc (thread_p, hash_length); if (dest == NULL) { error_status = ER_OUT_OF_VIRTUAL_MEMORY; goto exit_and_free; } dest_len = hash_length; gcry_md_hash_buffer (GCRY_MD_SHA1, dest, src, src_len); dest_hex = str_to_hex (thread_p, dest, dest_len, &dest_hex, &dest_hex_len); if (dest_hex == NULL) { error_status = ER_OUT_OF_VIRTUAL_MEMORY; goto exit_and_free; } *dest_p = dest_hex; *dest_len_p = dest_hex_len; exit_and_free: if (dest != NULL) { db_private_free_and_init (thread_p, dest); } return error_status; }
/* * crypt_crc32() - * return: error code * thread_p(in): * src(in): original message * src_len(in): length of original message * dest(out): crc32 result * Note: */ int crypt_crc32 (THREAD_ENTRY * thread_p, const char *src, int src_len, int *dest) { int hash_length; char *hash_result; int error_status = NO_ERROR; assert (src != NULL); if (thread_p == NULL) { thread_p = thread_get_thread_entry_info (); } if (init_gcrypt () != NO_ERROR) { return ER_ENCRYPTION_LIB_FAILED; } hash_length = gcry_md_get_algo_dlen (GCRY_MD_CRC32); hash_result = (char *) db_private_alloc (thread_p, hash_length); if (hash_result == NULL) { error_status = ER_OUT_OF_VIRTUAL_MEMORY; goto exit_and_free; } gcry_md_hash_buffer (GCRY_MD_CRC32, hash_result, src, src_len); *dest = htonl (*(UINT32 *) hash_result); exit_and_free: if (hash_result != NULL) { db_private_free_and_init (thread_p, hash_result); } return error_status; }
/* * qst_get_class_list () - Build the list of OIDs of classes * return: NO_ERROR or error code * key(in): next class OID to be added to the list * val(in): data value associated with the class id on the ext. hash entry * args(in): class list being built * * Note: This function builds the next node of the class id list. It is passed * to the ehash_map function to be called once on each item kept on the * extendible hashing structure used by the catalog manager. */ static int stats_get_class_list (THREAD_ENTRY * thread_p, void *key, void *val, void *args) { CLASS_ID_LIST *class_id_item_p, **p; p = (CLASS_ID_LIST **) args; class_id_item_p = (CLASS_ID_LIST *) db_private_alloc (thread_p, sizeof (CLASS_ID_LIST)); if (class_id_item_p == NULL) { return ER_OUT_OF_VIRTUAL_MEMORY; } class_id_item_p->class_id.volid = ((OID *) key)->volid; class_id_item_p->class_id.pageid = ((OID *) key)->pageid; class_id_item_p->class_id.slotid = ((OID *) key)->slotid; class_id_item_p->next = *p; *p = class_id_item_p; return NO_ERROR; }
/* remote_execute_delete_query_by_host() - reorganize sub-XASL for specified host to execute * return: rc * * local_xasl(in): original XASL * db_vals_p(in): * dbval_count(in): * flag (in): * remote_host (in): specified host */ static int remote_execute_delete_query_by_host (THREAD_ENTRY * thread_p, XASL_NODE * local_xasl, const DB_VALUE * dbvals_p, int dbval_count, QUERY_FLAG flag, int remote_host, QFILE_LIST_ID ** list_id_p) { int rc = ER_FAILED; int no_classes = 0; int i, j, size, status = ER_FAILED; XASL_NODE *remote_xasl = NULL; ACCESS_SPEC_TYPE *remote_spec_list = NULL, *local_spec_list = NULL; ACCESS_SPEC_TYPE *remote_spec = NULL, *tmp_spec = NULL; OID *remote_oid = NULL; HFID *remote_hfid = NULL; int remote_spec_cnt = 0; int *remote_node_ids = NULL; char *remote_stream = NULL; int node_id; remote_xasl = (XASL_NODE *) db_private_alloc (thread_p, sizeof (XASL_NODE)); if (remote_xasl == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (XASL_NODE)); goto end; } memcpy (remote_xasl, local_xasl, sizeof (XASL_NODE)); remote_xasl->proc.delete_.no_classes = 0; /* save original XASL spec list */ local_spec_list = local_xasl->aptr_list->spec_list; no_classes = local_xasl->proc.delete_.no_classes; remote_oid = (OID *) db_private_alloc (thread_p, no_classes * sizeof (OID)); if (remote_oid == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (OID)); goto end; } remote_hfid = (HFID *) db_private_alloc (thread_p, no_classes * sizeof (HFID)); if (remote_hfid == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (HFID)); goto end; } remote_node_ids = (int *) db_private_alloc (thread_p, no_classes * sizeof (int)); if (remote_node_ids == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (int)); goto end; } memset (remote_node_ids, 0, no_classes * sizeof (int)); remote_xasl->proc.delete_.class_oid = remote_oid; remote_xasl->proc.delete_.class_hfid = remote_hfid; /* step1: find out spec and oid/hfid to reorgnize sub-XASL for specified host */ for (i = 0; i < no_classes; i++) { node_id = local_xasl->proc.delete_.node_ids[i]; if (node_id != remote_host) { continue; } /* for remote spec */ tmp_spec = local_spec_list; j = no_classes - i - 1; while (j--) { tmp_spec = tmp_spec->next; } remote_spec = (ACCESS_SPEC_TYPE *) db_private_alloc (thread_p, sizeof (ACCESS_SPEC_TYPE)); if (remote_spec == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (ACCESS_SPEC_TYPE)); goto end; } memcpy (remote_spec, tmp_spec, sizeof (ACCESS_SPEC_TYPE)); tmp_spec = remote_spec_list; if (remote_spec_list) { j = remote_spec_cnt - 1; while (j--) { tmp_spec = tmp_spec->next; } tmp_spec->next = remote_spec; } remote_spec->s.cls_node.node_id = 0; /* for remote delete proc */ remote_oid[remote_spec_cnt] = local_xasl->proc.delete_.class_oid[i]; remote_hfid[remote_spec_cnt] = local_xasl->proc.delete_.class_hfid[i]; remote_spec_cnt++; remote_xasl->proc.delete_.no_classes++; if (remote_spec_cnt == 1) { remote_spec_list = remote_spec; } } i = remote_spec_cnt - 1; tmp_spec = remote_spec_list; while (i--) { tmp_spec = tmp_spec->next; } tmp_spec->next = NULL; remote_xasl->proc.delete_.no_classes = remote_spec_cnt; remote_xasl->proc.delete_.no_logging = local_xasl->proc.delete_.no_logging; remote_xasl->proc.delete_.node_ids = remote_node_ids; remote_xasl->proc.delete_.release_lock = local_xasl->proc.delete_.release_lock; remote_xasl->proc.delete_.waitsecs = local_xasl->proc.delete_.waitsecs; remote_xasl->aptr_list->spec_list = remote_spec_list; /* step 2: send to remote host */ if (NO_ERROR != xts_map_xasl_to_stream (thread_p, remote_xasl, &remote_stream, &size)) { goto end; } if (NO_ERROR != remote_prepare_and_execute_query (thread_p, remote_host, remote_stream, size, dbvals_p, dbval_count, flag, list_id_p)) { goto end; } /* step3: end query for remote host */ remote_end_query (thread_p, remote_host, (*list_id_p)->query_id, &status); if (NO_ERROR != status) { rc = ER_FAILED; er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_REMOTE_SERVER_END_FAIL, 1, node_id); goto end; } local_xasl->aptr_list->spec_list = local_spec_list; rc = NO_ERROR; end: db_private_free_and_init (thread_p, remote_stream); db_private_free_and_init (thread_p, remote_xasl); while (remote_spec_list) { remote_spec = remote_spec_list->next; db_private_free_and_init (thread_p, remote_spec_list); remote_spec_list = remote_spec; } db_private_free_and_init (thread_p, remote_oid); db_private_free_and_init (thread_p, remote_hfid); db_private_free_and_init (thread_p, remote_node_ids); return rc; }
static int remote_generate_count_star_xasl (THREAD_ENTRY * thread_p, XASL_NODE ** target, XASL_NODE * src, ACCESS_SPEC_TYPE * spec) { int rc = ER_FAILED; if (src == NULL) { return rc; } *target = (XASL_NODE *) db_private_alloc (thread_p, sizeof (XASL_NODE)); if ((*target) == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (XASL_NODE)); return rc; } memcpy (*target, src, sizeof (XASL_NODE)); (*target)->n_oid_list = 0; (*target)->outptr_list = (*target)->outptr_list; (*target)->remote_outptr_list = NULL; (*target)->spec_list = NULL; (*target)->curr_spec = NULL; (*target)->scan_ptr = NULL; (*target)->aptr_list = NULL; (*target)->next = NULL; (*target)->after_iscan_list = NULL; (*target)->ordbynum_flag = 0; (*target)->ordbynum_pred = NULL; (*target)->ordbynum_val = NULL; (*target)->orderby_list = NULL; (*target)->instnum_pred = NULL; (*target)->instnum_val = NULL; (*target)->list_id = (QFILE_LIST_ID *) db_private_alloc (thread_p, sizeof (QFILE_LIST_ID)); if ((*target)->list_id == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (XASL_NODE)); return rc; } QFILE_CLEAR_LIST_ID ((*target)->list_id); (*target)->spec_list = (ACCESS_SPEC_TYPE *) db_private_alloc (thread_p, sizeof (ACCESS_SPEC_TYPE)); if ((*target)->spec_list == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (ACCESS_SPEC_TYPE)); return rc; } memcpy ((*target)->spec_list, spec, sizeof (ACCESS_SPEC_TYPE)); (*target)->spec_list->s.cls_node.node_id = DB_CLUSTER_NODE_LOCAL; (*target)->spec_list->next = NULL; rc = NO_ERROR; return rc; }
static int remote_generate_remote_xasl_by_host (THREAD_ENTRY * thread_p, XASL_NODE ** target, XASL_NODE * src, int node_id) { int rc = ER_FAILED; ACCESS_SPEC_TYPE *src_spec = NULL, *tar_spec = NULL, *tmp_spec = NULL; if (src == NULL) { return rc; } *target = (XASL_NODE *) db_private_alloc (thread_p, sizeof (XASL_NODE)); if ((*target) == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (XASL_NODE)); return rc; } memcpy (*target, src, sizeof (XASL_NODE)); (*target)->n_oid_list = 0; if (src->type == BUILDVALUE_PROC && src->proc.buildvalue.agg_list->function == PT_COUNT_STAR) { /* nothing */ /* temp code */ } else { (*target)->outptr_list = (*target)->remote_outptr_list; (*target)->remote_outptr_list = NULL; } (*target)->spec_list = NULL; (*target)->curr_spec = NULL; (*target)->scan_ptr = NULL; (*target)->aptr_list = NULL; (*target)->next = NULL; (*target)->after_iscan_list = NULL; (*target)->ordbynum_flag = 0; (*target)->ordbynum_pred = NULL; (*target)->ordbynum_val = NULL; (*target)->orderby_list = NULL; (*target)->instnum_pred = NULL; (*target)->instnum_val = NULL; (*target)->list_id = (QFILE_LIST_ID *) db_private_alloc (thread_p, sizeof (QFILE_LIST_ID)); if ((*target)->list_id == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (XASL_NODE)); return rc; } QFILE_CLEAR_LIST_ID ((*target)->list_id); src_spec = src->spec_list; while (src_spec) { if (src_spec->s.cls_node.node_id == node_id) { tar_spec = (ACCESS_SPEC_TYPE *) db_private_alloc (thread_p, sizeof (ACCESS_SPEC_TYPE)); if (tar_spec == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (ACCESS_SPEC_TYPE)); return rc; } memcpy (tar_spec, src_spec, sizeof (ACCESS_SPEC_TYPE)); tar_spec->s.cls_node.node_id = DB_CLUSTER_NODE_LOCAL; tar_spec->next = NULL; if (!(*target)->spec_list) { (*target)->spec_list = tar_spec; } else { tmp_spec = (*target)->spec_list; while (tmp_spec->next) { tmp_spec = tmp_spec->next; } tmp_spec->next = tar_spec; } XASL_SET_FLAG (src_spec, XASL_SPEC_VISITED); } src_spec = src_spec->next; } if ((*target)->type == BUILDVALUE_PROC) { BUILDLIST_PROC_NODE *bl_proc = &((*target)->proc.buildlist); (*target)->type = BUILDLIST_PROC; memset (bl_proc, 0, sizeof (BUILDLIST_PROC_NODE)); } rc = NO_ERROR; return rc; }
/* remote_count_star_scan() : - * thread_p(in): * xasl(in/out): * spec(in): * direction(in): */ static SCAN_CODE remote_count_star_scan (THREAD_ENTRY * thread_p, XASL_NODE * xasl, ACCESS_SPEC_TYPE * spec, int direction, bool count_star_with_iscan_opt) { int size = 0, status, error; SCAN_CODE retval = S_ERROR; char *spec_stream = NULL; QUERY_EXEC_PARM *query_parm = QPARM_PTR (thread_p); XASL_NODE *remote_xasl = NULL; QFILE_LIST_ID *list_id = NULL; DB_VALUE *tmp_ptr = NULL; QUERY_FLAG remote_flag = QPARM_PTR (thread_p)->flag; /* stage 1: remote scan and open list can. */ if (!XASL_IS_FLAGED (spec, XASL_SPEC_VISITED)) { error = remote_generate_count_star_xasl (thread_p, &remote_xasl, xasl, spec); if (NO_ERROR != error) { goto end; } error = xts_map_xasl_to_stream (thread_p, remote_xasl, &spec_stream, &size); if (NO_ERROR != error) { goto end; } if (IS_ASYNC_EXEC_MODE (remote_flag)) { remote_flag &= ~ASYNC_EXEC; } error = remote_prepare_and_execute_query (thread_p, spec->s.cls_node. node_id, spec_stream, size, query_parm-> xasl_state->vd. dbval_ptr, query_parm-> xasl_state->vd. dbval_cnt, remote_flag, &list_id); if (error != NO_ERROR) { goto end; } list_id->remote_node_id = spec->s.cls_node.node_id; spec->s_id.scan_id = db_private_alloc (thread_p, sizeof (QFILE_LIST_SCAN_ID)); if (spec->s_id.scan_id == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (QFILE_LIST_SCAN_ID)); goto end; } if (qfile_open_list_scan (list_id, spec->s_id.scan_id) != NO_ERROR) { goto end; } XASL_SET_FLAG (spec, XASL_SPEC_VISITED); retval = qfile_to_val_list (thread_p, spec->s_id.scan_id, xasl->val_list); if (retval == S_ERROR) { goto end; } spec->s_id.scan_id->position = S_AFTER; spec->s_id.scan_id->curr_vpid.pageid = NULL_PAGEID; } if (db_get_int (xasl->val_list->valp->val) > 0) { if (count_star_with_iscan_opt) { (&xasl->curr_spec->s_id)->s.isid.oid_list.oid_cnt = db_get_int (xasl->val_list->valp->val); db_make_int (xasl->val_list->valp->val, 0); } else { db_make_int (xasl->val_list->valp->val, db_get_int (xasl->val_list->valp->val) - 1); } return S_SUCCESS; } else { retval = S_END; remote_end_query (thread_p, spec->s_id.scan_id->list_id.remote_node_id, spec->s_id.scan_id->list_id.query_id, &status); if (NO_ERROR != status) { retval = S_ERROR; er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_REMOTE_SERVER_END_FAIL, 1, spec->s.cls_node.node_id); } } end: if (spec->s_id.scan_id) { if (spec->s_id.scan_id->curr_pgptr) { free_and_init (spec->s_id.scan_id->curr_pgptr); } qfile_close_scan (thread_p, spec->s_id.scan_id); db_private_free_and_init (thread_p, spec->s_id.scan_id); } if (remote_xasl) { db_private_free_and_init (thread_p, remote_xasl->list_id); db_private_free_and_init (thread_p, remote_xasl->spec_list); } db_private_free_and_init (thread_p, remote_xasl); db_private_free_and_init (thread_p, spec_stream); if (list_id) { qfile_free_list_id (list_id); list_id = NULL; } return retval; }
/* remote_scan_next_scan() : - * thread_p(in): * xasl(in/out): * spec(in): * direction(in): */ static SCAN_CODE remote_scan_next_scan (THREAD_ENTRY * thread_p, XASL_NODE * xasl, ACCESS_SPEC_TYPE * spec, int direction) { int size = 0, status, error; SCAN_CODE retval = S_ERROR; char *spec_stream = NULL; QUERY_EXEC_PARM *query_parm = QPARM_PTR (thread_p); XASL_NODE *remote_xasl = NULL; QFILE_LIST_ID *list_id = NULL; DB_VALUE *tmp_ptr = NULL; QUERY_FLAG remote_flag = QPARM_PTR (thread_p)->flag; ACCESS_SPEC_TYPE *tmp_spec = NULL; /* stage 1: remote scan and open list can. */ if (spec->s_id.scan_id == NULL) { if (XASL_IS_FLAGED (spec, XASL_SPEC_VISITED)) { return S_END; } error = remote_generate_remote_xasl_by_host (thread_p, &remote_xasl, xasl, spec->s.cls_node.node_id); if (NO_ERROR != error) { goto end; } if (xasl->type == BUILDVALUE_PROC && xasl->val_list->valp == NULL) { remote_xasl->val_list->valp = db_private_alloc (thread_p, sizeof (QPROC_DB_VALUE_LIST)); remote_xasl->val_list->valp->val = remote_xasl->outptr_list->valptrp->value.value.dbvalptr; remote_xasl->val_list->valp->next = NULL; remote_xasl->val_list->val_cnt = 1; } QEXEC_REMOTE_OUTPTR_LIST (remote_xasl, &tmp_ptr); error = xts_map_xasl_to_stream (thread_p, remote_xasl, &spec_stream, &size); if (NO_ERROR != error) { goto end; } QEXEC_LOCAL_OUTPTR_LIST (remote_xasl, tmp_ptr); if (IS_ASYNC_EXEC_MODE (remote_flag)) { remote_flag &= ~ASYNC_EXEC; } error = remote_prepare_and_execute_query (thread_p, spec->s.cls_node. node_id, spec_stream, size, query_parm-> xasl_state->vd. dbval_ptr, query_parm-> xasl_state->vd. dbval_cnt, remote_flag, &list_id); if (error != NO_ERROR) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_REMOTE_SERVER_SCAN_FAIL, 1, spec->s.cls_node.node_id); qmgr_set_query_error (thread_p, query_parm->xasl_state->query_id); goto end; } list_id->remote_node_id = spec->s.cls_node.node_id; spec->s_id.scan_id = db_private_alloc (thread_p, sizeof (QFILE_LIST_SCAN_ID)); if (spec->s_id.scan_id == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, sizeof (QFILE_LIST_SCAN_ID)); goto end; } if (qfile_open_list_scan (list_id, spec->s_id.scan_id) != NO_ERROR) { goto end; } XASL_SET_FLAG (spec, XASL_SPEC_VISITED); } /* stage 2 : do next scan */ retval = qfile_to_val_list (thread_p, spec->s_id.scan_id, xasl->val_list); /* stage 3 : close scan and send NET_SERVER_QM_QUERY_END to service node */ if (retval == S_SUCCESS) { return retval; } else if (retval == S_END) { remote_end_query (thread_p, spec->s_id.scan_id->list_id.remote_node_id, spec->s_id.scan_id->list_id.query_id, &status); if (NO_ERROR != status) { retval = S_ERROR; er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_REMOTE_SERVER_END_FAIL, 1, spec->s.cls_node.node_id); } } end: if (spec->s_id.scan_id) { qfile_close_scan (thread_p, spec->s_id.scan_id); db_private_free_and_init (thread_p, spec->s_id.scan_id); } if (remote_xasl) { db_private_free_and_init (thread_p, remote_xasl->list_id); while (remote_xasl->spec_list) { tmp_spec = remote_xasl->spec_list->next; db_private_free_and_init (thread_p, remote_xasl->spec_list); remote_xasl->spec_list = tmp_spec; } } db_private_free_and_init (thread_p, remote_xasl); db_private_free_and_init (thread_p, spec_stream); if (list_id) { qfile_free_list_id (list_id); list_id = NULL; } return retval; }
/* * xlogwr_get_log_pages - * * return: * * thread_p(in): * first_pageid(in): * mode(in): * * Note: */ int xlogwr_get_log_pages (THREAD_ENTRY * thread_p, PAGEID first_pageid, int mode) { LOGWR_ENTRY *entry; char *logpg_area; int logpg_used_size; PAGEID next_fpageid; LOGWR_MODE next_mode; int status; int rv; int error_code; bool check_cs_own = false; LOGWR_INFO *writer_info = &log_Gl.writer_info; logpg_used_size = 0; logpg_area = db_private_alloc (thread_p, PRM_LOG_NBUFFERS * LOG_PAGESIZE); if (logpg_area == NULL) { error_code = ER_OUT_OF_VIRTUAL_MEMORY; er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, PRM_LOG_NBUFFERS * LOG_PAGESIZE); return ER_OUT_OF_VIRTUAL_MEMORY; } if (thread_p->conn_entry) { thread_p->conn_entry->stop_phase = THREAD_WORKER_STOP_PHASE_1; } while (true) { er_log_debug (ARG_FILE_LINE, "[tid:%ld] xlogwr_get_log_pages, fpageid(%d), mode(%s)\n", thread_p->tid, first_pageid, (mode == LOGWR_MODE_SYNC ? "sync" : (mode == LOGWR_MODE_ASYNC ? "async" : "semisync"))); /* Register the writer at the list and wait until LFT start to work */ LOG_MUTEX_LOCK (rv, writer_info->flush_start_mutex); error_code = logwr_register_writer_entry (&entry, thread_p, first_pageid, mode); if (error_code != NO_ERROR) { LOG_MUTEX_UNLOCK (writer_info->flush_start_mutex); status = LOGWR_STATUS_ERROR; goto error; } if (entry->status == LOGWR_STATUS_WAIT) { bool continue_checking = true; thread_suspend_with_other_mutex (thread_p, &writer_info->flush_start_mutex, INF_WAIT, NULL, THREAD_LOGWR_SUSPENDED); LOG_MUTEX_UNLOCK (writer_info->flush_start_mutex); if (logtb_is_interrupted (thread_p, false, &continue_checking) || thread_p->resume_status == THREAD_RESUME_DUE_TO_INTERRUPT) { /* interrupted, shutdown or connection has gone. */ error_code = ER_INTERRUPTED; er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0); status = LOGWR_STATUS_ERROR; goto error; } else if (thread_p->resume_status != THREAD_LOGWR_RESUMED) { error_code = ER_FAILED; status = LOGWR_STATUS_ERROR; goto error; } } else { assert (entry->status == LOGWR_STATUS_DELAY); LOG_MUTEX_UNLOCK (writer_info->flush_start_mutex); LOG_CS_ENTER (thread_p); check_cs_own = true; } /* Send the log pages to be flushed until now */ error_code = logwr_pack_log_pages (thread_p, logpg_area, &logpg_used_size, &status, entry); if (error_code != NO_ERROR) { status = LOGWR_STATUS_ERROR; goto error; } error_code = xlog_send_log_pages_to_client (thread_p, logpg_area, logpg_used_size, mode); if (error_code != NO_ERROR) { status = LOGWR_STATUS_ERROR; goto error; } /* In case of async mode, unregister the writer and wakeup LFT to finish */ /* The result mode is the following. transition \ req mode | req_sync req_async ----------------------------------------- delay -> delay | n/a ASYNC delay -> done | n/a SYNC wait -> delay | SYNC ASYNC wait -> done | SYNC ASYNC */ if (mode == LOGWR_MODE_ASYNC && (entry->status != LOGWR_STATUS_DELAY || (entry->status == LOGWR_STATUS_DELAY && status != LOGWR_STATUS_DONE))) { if (check_cs_own) { check_cs_own = false; LOG_CS_EXIT (); } LOG_MUTEX_LOCK (rv, writer_info->flush_end_mutex); if (logwr_unregister_writer_entry (entry, status)) { COND_SIGNAL (writer_info->flush_end_cond); } LOG_MUTEX_UNLOCK (writer_info->flush_end_mutex); } /* Get the next request from the client and reset the arguments */ error_code = xlog_get_page_request_with_reply (thread_p, &next_fpageid, &next_mode); if (error_code != NO_ERROR) { status = LOGWR_STATUS_ERROR; goto error; } /* In case of sync mode, unregister the writer and wakeup LFT to finish */ if (mode != LOGWR_MODE_ASYNC || (entry->status == LOGWR_STATUS_DELAY && status == LOGWR_STATUS_DONE)) { if (check_cs_own) { check_cs_own = false; LOG_CS_EXIT (); } LOG_MUTEX_LOCK (rv, writer_info->flush_end_mutex); if (logwr_unregister_writer_entry (entry, status)) { COND_SIGNAL (writer_info->flush_end_cond); } LOG_MUTEX_UNLOCK (writer_info->flush_end_mutex); } /* Reset the arguments for the next request */ first_pageid = next_fpageid; mode = next_mode; } db_private_free_and_init (thread_p, logpg_area); return NO_ERROR; error: er_log_debug (ARG_FILE_LINE, "[tid:%ld] xlogwr_get_log_pages, error(%d)\n", thread_p->tid, error_code); if (check_cs_own) { LOG_CS_EXIT (); } LOG_MUTEX_LOCK (rv, writer_info->flush_end_mutex); if (entry != NULL && logwr_unregister_writer_entry (entry, status)) { COND_SIGNAL (writer_info->flush_end_cond); } LOG_MUTEX_UNLOCK (writer_info->flush_end_mutex); db_private_free_and_init (thread_p, logpg_area); return error_code; }
/* * db_private_realloc () - call re-allocation function for current private heap * return: allocated memory pointer * thrd(in): thread conext if it is server, otherwise NULL * ptr(in): memory pointer to reallocate * size(in): size to allocate */ void * db_private_realloc (void *thrd, void *ptr, size_t size) { void *new_ptr = NULL; #if defined (CS_MODE) return db_ws_realloc (ptr, size); #elif defined (SERVER_MODE) HL_HEAPID heap_id; if (size <= 0) { return NULL; } heap_id = (thrd ? ((THREAD_ENTRY *) thrd)->private_heap_id : css_get_private_heap (NULL)); if (heap_id) { new_ptr = hl_lea_realloc (heap_id, ptr, size); } else { new_ptr = realloc (ptr, size); if (new_ptr == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, size); } } return new_ptr; #else /* SA_MODE */ if (ptr == NULL) { return db_private_alloc (thrd, size); } if (!db_on_server) { return db_ws_realloc (ptr, size); } else { if (private_heap_id) { PRIVATE_MALLOC_HEADER *h; h = private_user2hl_ptr (ptr); if (h->magic != PRIVATE_MALLOC_HEADER_MAGIC) { return NULL; } if (h->alloc_type == PRIVATE_ALLOC_TYPE_LEA) { PRIVATE_MALLOC_HEADER *new_h; size_t req_sz; req_sz = private_request_size (size); new_h = hl_lea_realloc (private_heap_id, h, req_sz); if (new_h == NULL) { return NULL; } return private_hl2user_ptr (new_h); } else if (h->alloc_type == PRIVATE_ALLOC_TYPE_WS) { return db_ws_realloc (ptr, size); } else { return NULL; } } else { new_ptr = realloc (ptr, size); if (new_ptr == NULL) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, size); } return new_ptr; } } #endif /* SA_MODE */ }
/* * crypt_sha_two() - * return: * thread_p(in): * src(in): * src_len(in): * need_hash_len(in): * dest_p(out) * dest_len_p(out): * Note: */ int crypt_sha_two (THREAD_ENTRY * thread_p, const char *src, int src_len, int need_hash_len, char **dest_p, int *dest_len_p) { int hash_length; int algo; char *dest = NULL; int dest_len; char *dest_hex = NULL; int dest_hex_len; int error_status = NO_ERROR; assert (src != NULL); if (thread_p == NULL) { thread_p = thread_get_thread_entry_info (); } *dest_p = NULL; switch (need_hash_len) { case 0: case 256: algo = GCRY_MD_SHA256; break; case 224: algo = GCRY_MD_SHA224; break; case 384: algo = GCRY_MD_SHA384; break; case 512: algo = GCRY_MD_SHA512; break; default: return NO_ERROR; } if (init_gcrypt () != NO_ERROR) { return ER_ENCRYPTION_LIB_FAILED; } hash_length = gcry_md_get_algo_dlen (algo); dest_len = hash_length; dest = (char *) db_private_alloc (thread_p, hash_length); if (dest == NULL) { error_status = ER_OUT_OF_VIRTUAL_MEMORY; goto exit_and_free; } gcry_md_hash_buffer (algo, dest, src, src_len); dest_hex = str_to_hex (thread_p, dest, dest_len, &dest_hex, &dest_hex_len); if (dest_hex == NULL) { error_status = ER_OUT_OF_VIRTUAL_MEMORY; goto exit_and_free; } *dest_p = dest_hex; *dest_len_p = dest_hex_len; exit_and_free: if (dest != NULL) { db_private_free_and_init (thread_p, dest); } return error_status; }
/* * crypt_aes_default_decrypt() - like mysql's aes_decrypt. Use AES-128/ECB/PKCS7 method. * return: * thread_p(in): * src(in): source string * src_len(in): the length of source string * key(in): the encrypt key * key_len(in): the length of the key * dest_p(out): the encrypted data. The pointer has to be free by db_private_free * dest_len_p(out): * Note: */ int crypt_aes_default_decrypt (THREAD_ENTRY * thread_p, const char *src, int src_len, const char *key, int key_len, char **dest_p, int *dest_len_p) { gcry_error_t i_gcrypt_err; gcry_cipher_hd_t aes_ctx; char *dest = NULL; int dest_len = 0; char new_key[AES128_KEY_LEN]; int pad, pad_len; int i; int error_status = NO_ERROR; assert (src != NULL); assert (key != NULL); if (thread_p == NULL) { thread_p = thread_get_thread_entry_info (); } *dest_p = NULL; *dest_len_p = 0; /* src is not a string encrypted by aes_default_encrypt, return NULL */ if (src_len % AES128_BLOCK_LEN) { return NO_ERROR; } if (init_gcrypt () != NO_ERROR) { return ER_ENCRYPTION_LIB_FAILED; } i_gcrypt_err = gcry_cipher_open (&aes_ctx, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0); if (i_gcrypt_err != GPG_ERR_NO_ERROR) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ENCRYPTION_LIB_FAILED, 1, crypt_lib_fail_info[CRYPT_LIB_OPEN_CIPHER_ERR]); return ER_ENCRYPTION_LIB_FAILED; } dest = (char *) db_private_alloc (thread_p, src_len * sizeof (char)); if (dest == NULL) { error_status = ER_OUT_OF_VIRTUAL_MEMORY; goto error_and_free; } aes_default_gen_key (key, key_len, new_key, AES128_KEY_LEN); i_gcrypt_err = gcry_cipher_setkey (aes_ctx, new_key, AES128_KEY_LEN); if (i_gcrypt_err != GPG_ERR_NO_ERROR) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ENCRYPTION_LIB_FAILED, 1, crypt_lib_fail_info[CRYPT_LIB_SET_KEY_ERR]); error_status = ER_ENCRYPTION_LIB_FAILED; goto error_and_free; } i_gcrypt_err = gcry_cipher_decrypt (aes_ctx, dest, src_len, src, src_len); if (i_gcrypt_err != GPG_ERR_NO_ERROR) { error_status = ER_ENCRYPTION_LIB_FAILED; er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ENCRYPTION_LIB_FAILED, 1, crypt_lib_fail_info[CRYPT_LIB_CRYPT_ERR]); goto error_and_free; } /* PKCS7 */ if (src_len != 0) { pad = dest[src_len - 1]; if (pad > AES128_BLOCK_LEN) { /* src is not a string encrypted by aes_default_encrypt, return NULL */ if (dest != NULL) { db_private_free_and_init (thread_p, dest); } goto error_and_free; } i = src_len - 2; pad_len = 1; while ((i >= 0) && (dest[i] == pad)) { pad_len++; i--; } if ((pad_len >= pad)) { pad_len = pad; dest_len = src_len - pad_len; } else { /* src is not a string encrypted by aes_default_encrypt, return NULL */ if (dest != NULL) { db_private_free_and_init (thread_p, dest); } goto error_and_free; } } *dest_p = dest; *dest_len_p = dest_len; error_and_free: if ((dest != NULL) && (error_status != NO_ERROR)) { db_private_free_and_init (thread_p, dest); } gcry_cipher_close (aes_ctx); return error_status; }
/* * crypt_aes_default_encrypt() - like mysql's aes_encrypt. Use AES-128/ECB/PKCS7 method. * return: * thread_p(in): * src(in): source string * src_len(in): the length of source string * key(in): the encrypt key * key_len(in): the length of the key * dest_p(out): the encrypted data. The pointer has to be free by db_private_free * dest_len_p(out): * Note: */ int crypt_aes_default_encrypt (THREAD_ENTRY * thread_p, const char *src, int src_len, const char *key, int key_len, char **dest_p, int *dest_len_p) { gcry_error_t i_gcrypt_err; gcry_cipher_hd_t aes_ctx; char new_key[AES128_KEY_LEN]; int pad; int padding_src_len; char *padding_src = NULL; char *dest = NULL; int error_status = NO_ERROR; assert (src != NULL); assert (key != NULL); if (thread_p == NULL) { thread_p = thread_get_thread_entry_info (); } *dest_p = NULL; *dest_len_p = 0; if (init_gcrypt () != NO_ERROR) { return ER_ENCRYPTION_LIB_FAILED; } i_gcrypt_err = gcry_cipher_open (&aes_ctx, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB, 0); if (i_gcrypt_err != GPG_ERR_NO_ERROR) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ENCRYPTION_LIB_FAILED, 1, crypt_lib_fail_info[CRYPT_LIB_OPEN_CIPHER_ERR]); return ER_ENCRYPTION_LIB_FAILED; } /* PKCS7 */ if ((src_len % AES128_BLOCK_LEN) == 0) { pad = AES128_BLOCK_LEN; padding_src_len = src_len + pad; } else { padding_src_len = ceil ((double) src_len / AES128_BLOCK_LEN) * AES128_BLOCK_LEN; pad = padding_src_len - src_len; } padding_src = (char *) db_private_alloc (thread_p, padding_src_len); if (padding_src == NULL) { error_status = ER_OUT_OF_VIRTUAL_MEMORY; goto exit_and_free; } memcpy (padding_src, src, src_len); memset (padding_src + src_len, pad, pad); aes_default_gen_key (key, key_len, new_key, AES128_KEY_LEN); i_gcrypt_err = gcry_cipher_setkey (aes_ctx, new_key, AES128_KEY_LEN); if (i_gcrypt_err != GPG_ERR_NO_ERROR) { error_status = ER_ENCRYPTION_LIB_FAILED; er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ENCRYPTION_LIB_FAILED, 1, crypt_lib_fail_info[CRYPT_LIB_SET_KEY_ERR]); goto exit_and_free; } dest = (char *) db_private_alloc (thread_p, padding_src_len); if (dest == NULL) { error_status = ER_OUT_OF_VIRTUAL_MEMORY; goto exit_and_free; } i_gcrypt_err = gcry_cipher_encrypt (aes_ctx, dest, padding_src_len, padding_src, padding_src_len); if (i_gcrypt_err != GPG_ERR_NO_ERROR) { er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_ENCRYPTION_LIB_FAILED, 1, crypt_lib_fail_info[CRYPT_LIB_CRYPT_ERR]); error_status = ER_ENCRYPTION_LIB_FAILED; goto exit_and_free; } *dest_len_p = padding_src_len; *dest_p = dest; exit_and_free: if (padding_src != NULL) { db_private_free_and_init (thread_p, padding_src); } if ((dest != NULL) && (error_status != NO_ERROR)) { db_private_free_and_init (thread_p, dest); } gcry_cipher_close (aes_ctx); return error_status; }