Skip to content

Commit

Permalink
[CUBVEC-24] Convert CHAR types to DB Vector in tp_value_cast (#5771)
Browse files Browse the repository at this point in the history
http://jira.cubrid.org/browse/CUBVEC-24

* feat(object_domain, db_set): coerce str to vector

* feat(object_domain): function tp_str_to_vector

* style(object_domain): fix style

* refactor(object_domain): no magic number for sizes

* fix(object_domain): 63 instead of 64 for null terminator

* replace intl_skip_spaces to plain c impl

* rename tp_str_to_vector to tp_atovector

* add db_vector.cpp, db_vector.hpp with db_string_to_vector function

* convert db_string_to_vector to cpp style

* improve readability

* more readability

* feat!(db_vector.cpp): use rapidjson parser

* style: format and isnan check
  • Loading branch information
vimkim authored Feb 3, 2025
1 parent e9c2db6 commit 1928adb
Show file tree
Hide file tree
Showing 8 changed files with 252 additions and 0 deletions.
2 changes: 2 additions & 0 deletions cs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ set(COMPAT_SOURCES
${COMPAT_DIR}/db_temp.c
${COMPAT_DIR}/db_value_printer.cpp
${COMPAT_DIR}/db_vdb.c
${COMPAT_DIR}/db_vector.cpp
${COMPAT_DIR}/db_virt.c
${COMPAT_DIR}/dbtype_function.c
)
Expand All @@ -79,6 +80,7 @@ set (COMPAT_HEADERS
${COMPAT_DIR}/dbtype_function.h
${COMPAT_DIR}/dbtype_function.i
${COMPAT_DIR}/db_admin.h
${COMPAT_DIR}/db_vector.hpp
)

set(BASE_SOURCES
Expand Down
2 changes: 2 additions & 0 deletions cubrid/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ set(COMPAT_SOURCES
${COMPAT_DIR}/db_macro.c
${COMPAT_DIR}/db_set.c
${COMPAT_DIR}/db_value_printer.cpp
${COMPAT_DIR}/db_vector.cpp
)
set (COMPAT_HEADERS
${COMPAT_DIR}/dbtype_def.h
Expand All @@ -40,6 +41,7 @@ set (COMPAT_HEADERS
${COMPAT_DIR}/db_set.h
${COMPAT_DIR}/db_set_function.h
${COMPAT_DIR}/dbtype_function.i
${COMPAT_DIR}/db_vector.hpp
)

set(THREAD_SOURCES
Expand Down
1 change: 1 addition & 0 deletions sa/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ set(COMPAT_SOURCES
${COMPAT_DIR}/db_temp.c
${COMPAT_DIR}/db_value_printer.cpp
${COMPAT_DIR}/db_vdb.c
${COMPAT_DIR}/db_vector.cpp
${COMPAT_DIR}/db_virt.c
${COMPAT_DIR}/dbtype_function.c
)
Expand Down
60 changes: 60 additions & 0 deletions src/compat/db_set.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,66 @@ db_seq_create (MOP classop, const char *name, int size)
return (set);
}

/*
* db_vec_create() - This function creates an empty vector. The class and
* name arguments can be set to NULL. If values are supplied, a check will
* be made to make sure that the attribute was defined with the vector
* domain.
* return : a set (vector) descriptor
* classop(in): class or instance
* name(in): attribute name
* size(in): initial size
*
* note : The new set will not be attached to any object, so you must use the
* db_put( ) function to assign it as the value of an attribute. If the size
* is not known, it is permissible to pass zero.
*/
DB_SET *
db_vec_create (MOP classop, const char *name, int size)
{
DB_SET *set;
#if !defined(SERVER_MODE)
int error = NO_ERROR;
#endif

CHECK_CONNECT_NULL ();

set = NULL;
if (classop == NULL || name == NULL)
{
set = set_create_vector (size);
}
else
{
#if !defined(SERVER_MODE)
SM_CLASS *class_;
SM_ATTRIBUTE *att;

if (au_fetch_class (classop, &class_, AU_FETCH_READ, AU_SELECT) == NO_ERROR)
{
att = classobj_find_attribute (class_, name, 0);
if (att == NULL)
{
ERROR_SET1 (error, ER_OBJ_INVALID_ATTRIBUTE, name);
}
else
{
if (att->type->id == DB_TYPE_VECTOR)
{
set = set_create_vector (size);
}
else
{
ERROR_SET1 (error, ER_OBJ_DOMAIN_CONFLICT, name);
}
}
}
#endif
}

return (set);
}

/*
* db_set_free() - This function frees a set handle. If the set is owned by an
* object, the contents of the set are not freed, only the set handle is
Expand Down
1 change: 1 addition & 0 deletions src/compat/db_set_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ extern "C"
extern DB_COLLECTION *db_set_create_basic (DB_OBJECT * classobj, const char *name);
extern DB_COLLECTION *db_set_create_multi (DB_OBJECT * classobj, const char *name);
extern DB_COLLECTION *db_seq_create (DB_OBJECT * classobj, const char *name, int size);
extern DB_COLLECTION *db_vec_create (DB_OBJECT * classobj, const char *name, int size);
extern int db_set_free (DB_COLLECTION * set);
extern int db_set_filter (DB_COLLECTION * set);
extern int db_set_add (DB_COLLECTION * set, DB_VALUE * value);
Expand Down
87 changes: 87 additions & 0 deletions src/compat/db_vector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* 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.
*
*/

/*
* @file db_vector.cpp
* @brief Implements string to vector conversion functionality
*/

#include "error_code.h"
#include <cmath>
#include <limits>
#include "rapidjson/document.h"
// XXX: SHOULD BE THE LAST INCLUDE HEADER
#include "memory_wrapper.hpp"


int db_string_to_vector (
const char *p,
int str_len,
float *vector,
int *p_count
)
{
// Validate input parameters
if (!p || !vector || !p_count || str_len <= 0)
{
return ER_FAILED;
}

// Parse without modifying the length (fixes const assignment error)
rapidjson::Document doc;
rapidjson::ParseResult result = doc.Parse (p, static_cast<size_t> (str_len));
if (!result)
{
return ER_FAILED;
}

// Check if root is an array
if (!doc.IsArray())
{
return ER_FAILED;
}

// Check array size
size_t size = doc.Size();
if (size > static_cast<size_t> (std::numeric_limits<int>::max()))
{
return ER_FAILED;
}

// Convert each element to float
for (size_t i = 0; i < size; i++)
{
if (!doc[i].IsNumber())
{
return ER_FAILED;
}

float num = doc[i].GetFloat();

if (std::isinf (num) || std::isnan (num))
{
return ER_FAILED;
}

vector[i] = num;

}

*p_count = static_cast<int> (size);
return NO_ERROR;
}
30 changes: 30 additions & 0 deletions src/compat/db_vector.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* 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.
*
*/

/*
* db_vector.hpp - Definitions for the vector utilities.
*/

#ifndef _DB_VECTOR_HPP_
#define _DB_VECTOR_HPP_

#ident "$Id$"

extern int db_string_to_vector (const char *p, int str_len, float * vector, int * count);

#endif /* _DB_VECTOR_HPP_ */
69 changes: 69 additions & 0 deletions src/object/object_domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include "db_json.hpp"
#include "string_buffer.hpp"
#include "db_value_printer.hpp"
#include "db_vector.hpp"

#if !defined (SERVER_MODE)
#include "work_space.h"
Expand Down Expand Up @@ -581,6 +582,7 @@ static int tp_atodatetimetz (const DB_VALUE * src, DB_DATETIMETZ * temp);
static int tp_atonumeric (const DB_VALUE * src, DB_VALUE * temp);
static int tp_atof (const DB_VALUE * src, double *num_value, DB_DATA_STATUS * data_stat);
static int tp_atobi (const DB_VALUE * src, DB_BIGINT * num_value, DB_DATA_STATUS * data_stat);
static int tp_atovector (DB_VALUE const *src, DB_VALUE * result);
#if defined(ENABLE_UNUSED_FUNCTION)
static char *tp_itoa (int value, char *string, int radix);
#endif
Expand Down Expand Up @@ -4994,6 +4996,55 @@ tp_atof (const DB_VALUE * src, double *num_value, DB_DATA_STATUS * data_stat)
return status;
}

/*
* tp_str_to_vector - Coerce a string to a vector.
* return: NO_ERROR or error code.
* src(in): string DB_VALUE
* result(out): vector DB_VALUE
* Note:
* Accepts strings that are not null terminated. Don't call this unless
* src is a string db_value.
*/
static int
tp_atovector (const DB_VALUE * src, DB_VALUE * result)
{
const char *p = db_get_string (src);
const char *end = p + db_get_string_size (src);
int count = 0;
const int number_buffer_size = 64;
char number_buffer[number_buffer_size];
int buffer_idx;
const int max_vector_size = 2000;
float float_array[max_vector_size];
DB_SET *vec = NULL;
DB_VALUE e_val;

int error = db_string_to_vector(p, db_get_string_size(src), float_array, &count);
if (error != NO_ERROR) {
return ER_FAILED;
}

// Create vector and populate it
vec = db_vec_create (NULL, NULL, 0);
if (vec == NULL)
{
assert (er_errid () != NO_ERROR);
return er_errid ();
}

db_make_vector (result, vec);
for (int i = 0; i < count; ++i)
{
db_make_float (&e_val, float_array[i]);
if (db_seq_put (db_get_set (result), i, &e_val) != NO_ERROR)
{
return ER_FAILED;
}
}

return NO_ERROR;
}

/*
* tp_atobi - Coerce a string to a bigint.
* return: NO_ERROR or error code
Expand Down Expand Up @@ -9125,6 +9176,24 @@ tp_value_cast_internal (const DB_VALUE * src, DB_VALUE * dest, const TP_DOMAIN *
}
break;

case DB_TYPE_VECTOR:
switch (original_type)
{
case DB_TYPE_CHAR:
case DB_TYPE_VARCHAR:
case DB_TYPE_NCHAR:
case DB_TYPE_VARNCHAR:
{

err = tp_atovector (src, target);
break;

}
default:
status = DOMAIN_INCOMPATIBLE;
break;
}
break;
case DB_TYPE_VOBJ:
if (original_type == DB_TYPE_VOBJ)
{
Expand Down

0 comments on commit 1928adb

Please sign in to comment.