File sp_code.cpp¶
File List > cubrid > src > sp > sp_code.cpp
Go to the documentation of this file
/*
*
* 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.
*
*/
//
// sp_code.cpp
//
#include "sp_code.hpp"
#include <unordered_map>
#include <string>
#include "dbtype.h"
#include "heap_file.h"
#include "object_representation_sr.h"
#include "sp_constants.hpp"
// XXX: SHOULD BE THE LAST INCLUDE HEADER
#include "memory_wrapper.hpp"
ATTR_ID spcode_Attrs_id[NUM_SP_CODE_ATTR];
int spcode_Num_attrs = -1;
static int sp_load_sp_code_attribute_info (THREAD_ENTRY *thread_p);
static void sp_code_attr_init ();
static int sp_get_attrid (THREAD_ENTRY *thread_p, int attr_index, ATTR_ID &attrid);
static int sp_get_attr_idx (const std::string &attr_name);
using sp_code_attr_map_type = std::unordered_map <std::string, int>;
static sp_code_attr_map_type attr_idx_map;
static void
sp_code_attr_init ()
{
#define MAP_LIST_ITEM(item) attr_idx_map [SP_CODE_ATTR_##item] = INDEX_SP_CODE_ATTR_##item;
SP_CODE_ATTR_LIST
#undef MAP_LIST_ITEM
}
static int
sp_get_attr_idx (const std::string &attr_name)
{
if (attr_idx_map.size () == 0)
{
sp_code_attr_init ();
}
auto idx_it = attr_idx_map.find (attr_name);
if (idx_it == attr_idx_map.end ())
{
return -1;
}
else
{
return idx_it->second;
}
}
int
sp_get_code_attr (THREAD_ENTRY *thread_p, const std::string &attr_name, const OID *sp_oidp, DB_VALUE *result)
{
int ret = NO_ERROR;
HEAP_SCANCACHE scan_cache;
SCAN_CODE scan;
RECDES recdesc = RECDES_INITIALIZER;
HEAP_CACHE_ATTRINFO attr_info, *attr_info_p = NULL;
ATTR_ID attrid;
DB_VALUE *cur_val;
OID *sp_class_oid = oid_Sp_code_class_oid;
int idx = -1;
heap_scancache_quick_start_with_class_oid (thread_p, &scan_cache, sp_class_oid);
/* get record into record desc */
scan = heap_get_visible_version (thread_p, sp_oidp, sp_class_oid, &recdesc, &scan_cache, PEEK, NULL_CHN);
if (scan != S_SUCCESS)
{
if (er_errid () == ER_PB_BAD_PAGEID)
{
er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_HEAP_UNKNOWN_OBJECT, 3, sp_oidp->volid, sp_oidp->pageid,
sp_oidp->slotid);
}
else
{
er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_QPROC_CANNOT_FETCH_SERIAL, 0);
}
goto exit_on_error;
}
/* retrieve attribute */
idx = sp_get_attr_idx (attr_name);
if (idx == -1)
{
goto exit_on_error;
}
if (sp_get_attrid (thread_p, idx, attrid) != NO_ERROR)
{
goto exit_on_error;
}
assert (attrid != -1);
ret = heap_attrinfo_start (thread_p, sp_class_oid, 1, &attrid, &attr_info);
if (ret != NO_ERROR)
{
goto exit_on_error;
}
attr_info_p = &attr_info;
ret = heap_attrinfo_read_dbvalues (thread_p, sp_oidp, &recdesc, attr_info_p);
if (ret != NO_ERROR)
{
goto exit_on_error;
}
cur_val = heap_attrinfo_access (attrid, attr_info_p);
db_value_clone (cur_val, result);
heap_attrinfo_end (thread_p, attr_info_p);
heap_scancache_end (thread_p, &scan_cache);
return NO_ERROR;
exit_on_error:
if (attr_info_p != NULL)
{
heap_attrinfo_end (thread_p, attr_info_p);
}
heap_scancache_end (thread_p, &scan_cache);
ret = (ret == NO_ERROR && (ret = er_errid ()) == NO_ERROR) ? ER_FAILED : ret;
return ret;
}
static int
sp_get_attrid (THREAD_ENTRY *thread_p, int attr_index, ATTR_ID &attrid)
{
attrid = -1; // NOT FOUND
if (spcode_Num_attrs < 0)
{
int error = sp_load_sp_code_attribute_info (thread_p);
if (error != NO_ERROR)
{
ASSERT_ERROR ();
return error;
}
}
if (attr_index >= 0 && attr_index <= spcode_Num_attrs)
{
attrid = spcode_Attrs_id[attr_index];
}
return NO_ERROR;
}
static int
sp_load_sp_code_attribute_info (THREAD_ENTRY *thread_p)
{
HEAP_SCANCACHE scan;
RECDES class_record;
HEAP_CACHE_ATTRINFO attr_info;
int i, error = NO_ERROR;
char *attr_name_p, *string = NULL;
int alloced_string = 0;
int attr_idx = -1;
if (spcode_Num_attrs != -1)
{
// already retrived
return error;
}
OID *sp_code_oid_class = oid_Sp_code_class_oid;
spcode_Num_attrs = -1;
if (heap_scancache_quick_start_with_class_oid (thread_p, &scan, sp_code_oid_class) != NO_ERROR)
{
return ER_FAILED;
}
if (heap_get_class_record (thread_p, sp_code_oid_class, &class_record, &scan, PEEK) != S_SUCCESS)
{
heap_scancache_end (thread_p, &scan);
return ER_FAILED;
}
error = heap_attrinfo_start (thread_p, sp_code_oid_class, -1, NULL, &attr_info);
if (error != NO_ERROR)
{
(void) heap_scancache_end (thread_p, &scan);
return error;
}
for (i = 0; i < attr_info.num_values; i++)
{
string = NULL;
alloced_string = 0;
error = or_get_attrname (&class_record, i, &string, &alloced_string);
if (error != NO_ERROR)
{
ASSERT_ERROR ();
goto exit_on_error;
}
attr_name_p = string;
if (attr_name_p == NULL)
{
error = ER_FAILED;
goto exit_on_error;
}
attr_idx = sp_get_attr_idx (attr_name_p);
if (attr_idx != -1)
{
spcode_Attrs_id [attr_idx] = i;
}
if (string != NULL && alloced_string)
{
db_private_free_and_init (NULL, string);
}
}
spcode_Num_attrs = attr_info.num_values;
heap_attrinfo_end (thread_p, &attr_info);
error = heap_scancache_end (thread_p, &scan);
return error;
exit_on_error:
heap_attrinfo_end (thread_p, &attr_info);
(void) heap_scancache_end (thread_p, &scan);
return error;
}