Skip to content

Commit

Permalink
Fix python prepared statement uuid binding
Browse files Browse the repository at this point in the history
  • Loading branch information
acquamarin committed Feb 21, 2024
1 parent 89aba2f commit ebfff70
Show file tree
Hide file tree
Showing 16 changed files with 90 additions and 74 deletions.
2 changes: 1 addition & 1 deletion src/common/arrow/arrow_row_batch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ template<>
void ArrowRowBatch::templateCopyNonNullValue<LogicalTypeID::UUID>(
ArrowVector* vector, const main::DataTypeInfo& /*typeInfo*/, Value* value, std::int64_t pos) {
auto offsets = (std::uint32_t*)vector->data.data();
auto str = uuid_t::toString(value->val.int128Val);
auto str = UUID::toString(value->val.int128Val);
auto strLength = str.length();
offsets[pos + 1] = offsets[pos] + strLength;
vector->overflow.resize(offsets[pos + 1]);
Expand Down
8 changes: 3 additions & 5 deletions src/common/type_utils.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
#include "common/type_utils.h"

#include "common/types/blob.h"
#include "common/types/uuid.h"
#include "common/vector/value_vector.h"

namespace kuzu {
Expand Down Expand Up @@ -64,7 +62,7 @@ static std::string entryToString(
case LogicalTypeID::UNION:
return TypeUtils::toString(*reinterpret_cast<const union_entry_t*>(value), valueVector);
case LogicalTypeID::UUID:
return TypeUtils::toString(*reinterpret_cast<const uuid_t*>(value));
return TypeUtils::toString(*reinterpret_cast<const ku_uuid_t*>(value));
case LogicalTypeID::NODE:
return TypeUtils::nodeToString(
*reinterpret_cast<const struct_entry_t*>(value), valueVector);
Expand Down Expand Up @@ -160,8 +158,8 @@ std::string TypeUtils::toString(const blob_t& val, void* /*valueVector*/) {
}

template<>
std::string TypeUtils::toString(const uuid_t& val, void* /*valueVector*/) {
return val.toString();
std::string TypeUtils::toString(const ku_uuid_t& val, void* /*valueVector*/) {
return UUID::toString(val);
}

template<>
Expand Down
38 changes: 31 additions & 7 deletions src/common/types/uuid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
namespace kuzu {
namespace common {

void uuid_t::byteToHex(char byteVal, char* buf, uint64_t& pos) {
void UUID::byteToHex(char byteVal, char* buf, uint64_t& pos) {
buf[pos++] = HEX_DIGITS[(byteVal >> 4) & 0xf];
buf[pos++] = HEX_DIGITS[byteVal & 0xf];
}

unsigned char uuid_t::hex2Char(char ch) {
unsigned char UUID::hex2Char(char ch) {
if (ch >= '0' && ch <= '9') {
return ch - '0';
}
Expand All @@ -21,9 +21,13 @@ unsigned char uuid_t::hex2Char(char ch) {
return 10 + ch - 'A';
}
return 0;
};
}

bool UUID::isHex(char ch) {
return (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F');
}

bool uuid_t::fromString(std::string str, int128_t& result) {
bool UUID::fromString(std::string str, int128_t& result) {
if (str.empty()) {
return false;
}
Expand Down Expand Up @@ -59,7 +63,17 @@ bool uuid_t::fromString(std::string str, int128_t& result) {
return count == 32;
}

void uuid_t::toString(int128_t input, char* buf) {
int128_t UUID::fromString(std::string str) {
int128_t result;
fromString(str, result);
return result;
}

int128_t UUID::fromCString(const char* str, uint64_t len) {
return fromString(std::string(str, len));
}

void UUID::toString(int128_t input, char* buf) {
// Flip back before convert to string
int64_t high = input.high ^ (int64_t(1) << 63);
uint64_t pos = 0;
Expand All @@ -85,7 +99,17 @@ void uuid_t::toString(int128_t input, char* buf) {
byteToHex(input.low & 0xFF, buf, pos);
}

uuid_t uuid_t::generateRandomUUID(RandomEngine* engine) {
std::string UUID::toString(int128_t input) {
char buff[UUID_STRING_LENGTH];
toString(input, buff);
return std::string(buff, UUID_STRING_LENGTH);
}

std::string UUID::toString(ku_uuid_t val) {
return toString(val.value);
}

ku_uuid_t UUID::generateRandomUUID(RandomEngine* engine) {
uint8_t bytes[16];
for (int i = 0; i < 16; i += 4) {
*reinterpret_cast<uint32_t*>(bytes + i) = engine->nextRandomInteger();
Expand Down Expand Up @@ -116,7 +140,7 @@ uuid_t uuid_t::generateRandomUUID(RandomEngine* engine) {
result.low |= ((uint64_t)bytes[13] << 16);
result.low |= ((uint64_t)bytes[14] << 8);
result.low |= bytes[15];
return uuid_t{result};
return ku_uuid_t{result};
}

} // namespace common
Expand Down
8 changes: 4 additions & 4 deletions src/common/types/value/value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ Value::Value(int128_t val_) : isNull_{false} {
val.int128Val = val_;
}

Value::Value(uuid_t val_) : isNull_{false} {
Value::Value(ku_uuid_t val_) : isNull_{false} {
dataType = LogicalType::UUID();
val.int128Val = val_.value;
}
Expand Down Expand Up @@ -323,8 +323,8 @@ void Value::copyValueFrom(const uint8_t* value) {
strVal = ((blob_t*)value)->value.getAsString();
} break;
case LogicalTypeID::UUID: {
val.int128Val = ((uuid_t*)value)->value;
strVal = uuid_t::toString(val.int128Val);
val.int128Val = ((ku_uuid_t*)value)->value;
strVal = UUID::toString(*((ku_uuid_t*)value));
} break;
case LogicalTypeID::STRING: {
strVal = ((ku_string_t*)value)->getAsString();
Expand Down Expand Up @@ -472,7 +472,7 @@ std::string Value::toString() const {
case LogicalTypeID::BLOB:
return Blob::toString(reinterpret_cast<const uint8_t*>(strVal.c_str()), strVal.length());
case LogicalTypeID::UUID:
return uuid_t::toString(val.int128Val);
return UUID::toString(val.int128Val);
case LogicalTypeID::STRING:
return strVal;
case LogicalTypeID::RDF_VARIANT: {
Expand Down
12 changes: 6 additions & 6 deletions src/function/cast_from_string_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,16 +161,16 @@ void CastStringHelper::cast(const char* input, uint64_t len, blob_t& /*result*/,

//---------------------- cast String to UUID ------------------------------ //
template<>
void CastString::operation(const ku_string_t& input, uuid_t& result, ValueVector* /*result_vector*/,
uint64_t /*rowToAdd*/, const CSVOption* /*option*/) {
result.value = uuid_t::fromString(input.getAsString());
void CastString::operation(const ku_string_t& input, ku_uuid_t& result,
ValueVector* /*result_vector*/, uint64_t /*rowToAdd*/, const CSVOption* /*option*/) {
result.value = UUID::fromString(input.getAsString());
}

// LCOV_EXCL_START
template<>
void CastStringHelper::cast(const char* input, uint64_t len, uuid_t& result,
void CastStringHelper::cast(const char* input, uint64_t len, ku_uuid_t& result,
ValueVector* /*vector*/, uint64_t /*rowToAdd*/, const CSVOption* /*option*/) {
result.value = uuid_t::fromCString(input, len);
result.value = UUID::fromCString(input, len);
}
// LCOV_EXCL_STOP

Expand Down Expand Up @@ -886,7 +886,7 @@ void CastString::copyStringToVector(
CastStringHelper::cast(strVal.data(), strVal.length(), val, vector, rowToAdd, option);
} break;
case LogicalTypeID::UUID: {
uuid_t val;
ku_uuid_t val;
CastStringHelper::cast(strVal.data(), strVal.length(), val);
vector->setValue(rowToAdd, val.value);
} break;
Expand Down
7 changes: 4 additions & 3 deletions src/function/vector_cast_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ static std::unique_ptr<ScalarFunction> bindCastFromStringFunction(
ScalarFunction::UnaryCastStringExecFunction<ku_string_t, blob_t, CastString, EXECUTOR>;
} break;
case LogicalTypeID::UUID: {
execFunc =
ScalarFunction::UnaryCastStringExecFunction<ku_string_t, uuid_t, CastString, EXECUTOR>;
execFunc = ScalarFunction::UnaryCastStringExecFunction<ku_string_t, ku_uuid_t, CastString,
EXECUTOR>;
} break;
case LogicalTypeID::STRING: {
execFunc =
Expand Down Expand Up @@ -456,7 +456,8 @@ static std::unique_ptr<ScalarFunction> bindCastToStringFunction(
func = ScalarFunction::UnaryCastExecFunction<blob_t, ku_string_t, CastToString, EXECUTOR>;
} break;
case LogicalTypeID::UUID: {
func = ScalarFunction::UnaryCastExecFunction<uuid_t, ku_string_t, CastToString, EXECUTOR>;
func =
ScalarFunction::UnaryCastExecFunction<ku_uuid_t, ku_string_t, CastToString, EXECUTOR>;
} break;
case LogicalTypeID::VAR_LIST: {
func = ScalarFunction::UnaryCastExecFunction<list_entry_t, ku_string_t, CastToString,
Expand Down
2 changes: 1 addition & 1 deletion src/function/vector_uuid_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ function_set GenRandomUUIDFunction::getFunctionSet() {
function_set definitions;
definitions.push_back(
make_unique<ScalarFunction>(GEN_RANDOM_UUID_FUNC_NAME, std::vector<LogicalTypeID>{},
LogicalTypeID::UUID, ScalarFunction::PoniterExecFunction<uuid_t, GenRandomUUID>));
LogicalTypeID::UUID, ScalarFunction::PoniterExecFunction<ku_uuid_t, GenRandomUUID>));
return definitions;
}

Expand Down
6 changes: 2 additions & 4 deletions src/include/common/type_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ namespace kuzu {
namespace common {

class ValueVector;
struct blob_t;
struct uuid_t;

template<class... Funcs>
struct overload : Funcs... {
Expand Down Expand Up @@ -178,7 +176,7 @@ class TypeUtils {
case LogicalTypeID::BLOB:
return func(blob_t());
case LogicalTypeID::UUID:
return func(uuid_t());
return func(ku_uuid_t());
case LogicalTypeID::VAR_LIST:
return func(list_entry_t());
case LogicalTypeID::MAP:
Expand Down Expand Up @@ -276,7 +274,7 @@ std::string TypeUtils::toString(const ku_string_t& val, void* valueVector);
template<>
std::string TypeUtils::toString(const blob_t& val, void* valueVector);
template<>
std::string TypeUtils::toString(const uuid_t& val, void* valueVector);
std::string TypeUtils::toString(const ku_uuid_t& val, void* valueVector);
template<>
std::string TypeUtils::toString(const list_entry_t& val, void* valueVector);
template<>
Expand Down
50 changes: 15 additions & 35 deletions src/include/common/types/uuid.h
Original file line number Diff line number Diff line change
@@ -1,53 +1,33 @@
#pragma once
// pragma once doesn't appear to work properly on MSVC for this file
#ifndef KUZU_COMMON_TYPES_UUID
#define KUZU_COMMON_TYPES_UUID

#include "common/types/int128_t.h"
#include "int128_t.h"

namespace kuzu {
namespace common {

class RandomEngine;

struct uuid_t {
constexpr static uint8_t UUID_STRING_LENGTH = 36;
constexpr static char HEX_DIGITS[] = "0123456789abcdef";
// Note: uuid_t is a reserved keyword in MSVC, we have to use ku_uuid_t instead.
struct ku_uuid_t {
int128_t value;
};

struct UUID {
static constexpr const uint8_t UUID_STRING_LENGTH = 36;
static constexpr const char HEX_DIGITS[] = "0123456789abcdef";
static void byteToHex(char byteVal, char* buf, uint64_t& pos);
static unsigned char hex2Char(char ch);
static inline bool isHex(char ch) {
return (ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'f') || (ch >= 'A' && ch <= 'F');
}

// Convert a uuid string to a int128_t object
static bool isHex(char ch);
static bool fromString(std::string str, int128_t& result);

static inline int128_t fromString(std::string str) {
int128_t result;
fromString(str, result);
return result;
}

static inline int128_t fromCString(const char* str, uint64_t len) {
return fromString(std::string(str, len));
}

// Convert a int128_t object to a uuid style string
static int128_t fromString(std::string str);
static int128_t fromCString(const char* str, uint64_t len);
static void toString(int128_t input, char* buf);
static std::string toString(int128_t input);
static std::string toString(ku_uuid_t val);

static inline std::string toString(int128_t input) {
char buff[UUID_STRING_LENGTH];
toString(input, buff);
return std::string(buff, UUID_STRING_LENGTH);
}
inline std::string toString() const { return toString(value); }

int128_t value;

// generate a random uuid object
static uuid_t generateRandomUUID(RandomEngine* engine);
static ku_uuid_t generateRandomUUID(RandomEngine* engine);
};

} // namespace common
} // namespace kuzu
#endif
3 changes: 2 additions & 1 deletion src/include/common/types/value/value.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class Value {
/**
* @param val_ the UUID value to set.
*/
KUZU_API explicit Value(uuid_t val_);
KUZU_API explicit Value(ku_uuid_t val_);
/**
* @param val_ the double value to set.
*/
Expand Down Expand Up @@ -218,6 +218,7 @@ class Value {
static Value createValue(T /*value*/) {
throw std::runtime_error("Unimplemented template for Value::createValue()");
}

/**
* @return a copy of the current value.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ void CastString::operation(const ku_string_t& input, blob_t& result, ValueVector
uint64_t rowToAdd, const CSVOption* option);

template<>
void CastString::operation(const ku_string_t& input, uuid_t& result, ValueVector* result_vector,
void CastString::operation(const ku_string_t& input, ku_uuid_t& result, ValueVector* result_vector,
uint64_t rowToAdd, const CSVOption* option);

template<>
Expand Down
6 changes: 3 additions & 3 deletions src/include/function/uuid/functions/gen_random_uuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@ class ClientContext;
}

namespace common {
struct uuid_t;
struct ku_uuid_t;
} // namespace common

namespace function {

struct GenRandomUUID {
static inline void operation(common::ValueVector& result, void* dataPtr) {
KU_ASSERT(result.state->isFlat());
auto resultValues = (common::uuid_t*)result.getData();
auto resultValues = (common::ku_uuid_t*)result.getData();
auto idx = result.state->selVector->selectedPositions[0];
KU_ASSERT(idx == 0);
resultValues[idx] = common::uuid_t::generateRandomUUID(
resultValues[idx] = common::UUID::generateRandomUUID(
reinterpret_cast<main::ClientContext*>(dataPtr)->getRandomEngine());
}
};
Expand Down
8 changes: 8 additions & 0 deletions tools/python_api/src_cpp/py_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "main/connection.h"
#include "pandas/pandas_scan.h"
#include "processor/result/factorized_table.h"
#include "common/types/uuid.h"

using namespace kuzu::common;

Expand Down Expand Up @@ -179,6 +180,7 @@ Value transformPythonValue(py::handle val) {
auto datetime_datetime = datetime_mod.attr("datetime");
auto time_delta = datetime_mod.attr("timedelta");
auto datetime_date = datetime_mod.attr("date");
auto uuid = py::module::import("uuid").attr("UUID");
if (py::isinstance<py::bool_>(val)) {
return Value::createValue<bool>(val.cast<bool>());
} else if (py::isinstance<py::int_>(val)) {
Expand Down Expand Up @@ -215,6 +217,12 @@ Value transformPythonValue(py::handle val) {
Interval::addition(interval, seconds, "seconds");
Interval::addition(interval, microseconds, "microseconds");
return Value::createValue<interval_t>(interval);
} else if (py::isinstance(val, uuid)) {
auto strVal = py::str(val).cast<std::string>();
auto uuidVal = UUID::fromString(strVal);
ku_uuid_t uuidToAppend;
uuidToAppend.value = uuidVal;
return Value{uuidToAppend};
} else {
throw std::runtime_error(
"Unknown parameter type " + py::str(val.get_type()).cast<std::string>());
Expand Down
2 changes: 1 addition & 1 deletion tools/python_api/src_cpp/py_query_result.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ py::object PyQueryResult::convertValueToPyObject(const Value& value) {
}
case LogicalTypeID::UUID: {
kuzu::common::int128_t result = value.getValue<kuzu::common::int128_t>();
std::string uuidString = kuzu::common::uuid_t::toString(result);
std::string uuidString = kuzu::common::UUID::toString(result);
py::object UUID = py::module_::import("uuid").attr("UUID");
return UUID(uuidString);
}
Expand Down
Loading

0 comments on commit ebfff70

Please sign in to comment.