diff --git a/src/c_api/prepared_statement.cpp b/src/c_api/prepared_statement.cpp index f7c104ad416..13e3890939a 100644 --- a/src/c_api/prepared_statement.cpp +++ b/src/c_api/prepared_statement.cpp @@ -72,6 +72,36 @@ void kuzu_prepared_statement_bind_int16( kuzu_prepared_statement_bind_cpp_value(prepared_statement, param_name, value_ptr); } +void kuzu_prepared_statement_bind_int8( + kuzu_prepared_statement* prepared_statement, const char* param_name, int8_t value) { + auto value_ptr = std::make_shared(value); + kuzu_prepared_statement_bind_cpp_value(prepared_statement, param_name, value_ptr); +} + +void kuzu_prepared_statement_bind_uint64( + kuzu_prepared_statement* prepared_statement, const char* param_name, uint64_t value) { + auto value_ptr = std::make_shared(value); + kuzu_prepared_statement_bind_cpp_value(prepared_statement, param_name, value_ptr); +} + +void kuzu_prepared_statement_bind_uint32( + kuzu_prepared_statement* prepared_statement, const char* param_name, uint32_t value) { + auto value_ptr = std::make_shared(value); + kuzu_prepared_statement_bind_cpp_value(prepared_statement, param_name, value_ptr); +} + +void kuzu_prepared_statement_bind_uint16( + kuzu_prepared_statement* prepared_statement, const char* param_name, uint16_t value) { + auto value_ptr = std::make_shared(value); + kuzu_prepared_statement_bind_cpp_value(prepared_statement, param_name, value_ptr); +} + +void kuzu_prepared_statement_bind_uint8( + kuzu_prepared_statement* prepared_statement, const char* param_name, uint8_t value) { + auto value_ptr = std::make_shared(value); + kuzu_prepared_statement_bind_cpp_value(prepared_statement, param_name, value_ptr); +} + void kuzu_prepared_statement_bind_double( kuzu_prepared_statement* prepared_statement, const char* param_name, double value) { auto value_ptr = std::make_shared(value); diff --git a/src/c_api/value.cpp b/src/c_api/value.cpp index 6d565339358..855bdd3a16e 100644 --- a/src/c_api/value.cpp +++ b/src/c_api/value.cpp @@ -46,6 +46,12 @@ kuzu_value* kuzu_value_create_bool(bool val_) { return c_value; } +kuzu_value* kuzu_value_create_int8(int8_t val_) { + auto* c_value = (kuzu_value*)calloc(1, sizeof(kuzu_value)); + c_value->_value = new Value(val_); + return c_value; +} + kuzu_value* kuzu_value_create_int16(int16_t val_) { auto* c_value = (kuzu_value*)calloc(1, sizeof(kuzu_value)); c_value->_value = new Value(val_); @@ -64,6 +70,30 @@ kuzu_value* kuzu_value_create_int64(int64_t val_) { return c_value; } +kuzu_value* kuzu_value_create_uint8(uint8_t val_) { + auto* c_value = (kuzu_value*)calloc(1, sizeof(kuzu_value)); + c_value->_value = new Value(val_); + return c_value; +} + +kuzu_value* kuzu_value_create_uint16(uint16_t val_) { + auto* c_value = (kuzu_value*)calloc(1, sizeof(kuzu_value)); + c_value->_value = new Value(val_); + return c_value; +} + +kuzu_value* kuzu_value_create_uint32(uint32_t val_) { + auto* c_value = (kuzu_value*)calloc(1, sizeof(kuzu_value)); + c_value->_value = new Value(val_); + return c_value; +} + +kuzu_value* kuzu_value_create_uint64(uint64_t val_) { + auto* c_value = (kuzu_value*)calloc(1, sizeof(kuzu_value)); + c_value->_value = new Value(val_); + return c_value; +} + kuzu_value* kuzu_value_create_float(float val_) { auto* c_value = (kuzu_value*)calloc(1, sizeof(kuzu_value)); c_value->_value = new Value(val_); @@ -189,6 +219,10 @@ bool kuzu_value_get_bool(kuzu_value* value) { return static_cast(value->_value)->getValue(); } +int8_t kuzu_value_get_int8(kuzu_value* value) { + return static_cast(value->_value)->getValue(); +} + int16_t kuzu_value_get_int16(kuzu_value* value) { return static_cast(value->_value)->getValue(); } @@ -201,6 +235,22 @@ int64_t kuzu_value_get_int64(kuzu_value* value) { return static_cast(value->_value)->getValue(); } +uint8_t kuzu_value_get_uint8(kuzu_value* value) { + return static_cast(value->_value)->getValue(); +} + +uint16_t kuzu_value_get_uint16(kuzu_value* value) { + return static_cast(value->_value)->getValue(); +} + +uint32_t kuzu_value_get_uint32(kuzu_value* value) { + return static_cast(value->_value)->getValue(); +} + +uint64_t kuzu_value_get_uint64(kuzu_value* value) { + return static_cast(value->_value)->getValue(); +} + float kuzu_value_get_float(kuzu_value* value) { return static_cast(value->_value)->getValue(); } diff --git a/src/include/c_api/kuzu.h b/src/include/c_api/kuzu.h index f8f1e68a66b..c2673d5fe96 100644 --- a/src/include/c_api/kuzu.h +++ b/src/include/c_api/kuzu.h @@ -165,6 +165,11 @@ KUZU_C_API typedef enum { KUZU_INT64 = 23, KUZU_INT32 = 24, KUZU_INT16 = 25, + KUZU_INT8 = 26, + KUZU_UINT64 = 27, + KUZU_UINT32 = 28, + KUZU_UINT16 = 29, + KUZU_UINT8 = 30, KUZU_DOUBLE = 32, KUZU_FLOAT = 33, KUZU_DATE = 34, @@ -342,6 +347,46 @@ KUZU_C_API void kuzu_prepared_statement_bind_int32( */ KUZU_C_API void kuzu_prepared_statement_bind_int16( kuzu_prepared_statement* prepared_statement, const char* param_name, int16_t value); +/** + * @brief Binds the given int8_t value to the given parameter name in the prepared statement. + * @param prepared_statement The prepared statement instance to bind the value. + * @param param_name The parameter name to bind the value. + * @param value The int8_t value to bind. + */ +KUZU_C_API void kuzu_prepared_statement_bind_int8( + kuzu_prepared_statement* prepared_statement, const char* param_name, int8_t value); +/** + * @brief Binds the given uint64_t value to the given parameter name in the prepared statement. + * @param prepared_statement The prepared statement instance to bind the value. + * @param param_name The parameter name to bind the value. + */ +KUZU_C_API void kuzu_prepared_statement_bind_uint64( + kuzu_prepared_statement* prepared_statement, const char* param_name, uint64_t value); +/** + * @brief Binds the given uint32_t value to the given parameter name in the prepared statement. + * @param prepared_statement The prepared statement instance to bind the value. + * @param param_name The parameter name to bind the value. + * @param value The uint32_t value to bind. + */ +KUZU_C_API void kuzu_prepared_statement_bind_uint32( + kuzu_prepared_statement* prepared_statement, const char* param_name, uint32_t value); +/** + * @brief Binds the given uint16_t value to the given parameter name in the prepared statement. + * @param prepared_statement The prepared statement instance to bind the value. + * @param param_name The parameter name to bind the value. + * @param value The uint16_t value to bind. + */ +KUZU_C_API void kuzu_prepared_statement_bind_uint16( + kuzu_prepared_statement* prepared_statement, const char* param_name, uint16_t value); +/** + * @brief Binds the given int8_t value to the given parameter name in the prepared statement. + * @param prepared_statement The prepared statement instance to bind the value. + * @param param_name The parameter name to bind the value. + * @param value The int8_t value to bind. + */ +KUZU_C_API void kuzu_prepared_statement_bind_uint8( + kuzu_prepared_statement* prepared_statement, const char* param_name, uint8_t value); + /** * @brief Binds the given double value to the given parameter name in the prepared statement. * @param prepared_statement The prepared statement instance to bind the value. @@ -586,6 +631,12 @@ KUZU_C_API kuzu_value* kuzu_value_create_default(kuzu_logical_type* data_type); * @param val_ The bool value of the value to create. */ KUZU_C_API kuzu_value* kuzu_value_create_bool(bool val_); +/** + * @brief Creates a value with int8 type and the given int8 value. Caller is responsible for + * destroying the returned value. + * @param val_ The int8 value of the value to create. + */ +KUZU_C_API kuzu_value* kuzu_value_create_int8(int8_t val_); /** * @brief Creates a value with int16 type and the given int16 value. Caller is responsible for * destroying the returned value. @@ -604,6 +655,30 @@ KUZU_C_API kuzu_value* kuzu_value_create_int32(int32_t val_); * @param val_ The int64 value of the value to create. */ KUZU_C_API kuzu_value* kuzu_value_create_int64(int64_t val_); +/** + * @brief Creates a value with uint8 type and the given uint8 value. Caller is responsible for + * destroying the returned value. + * @param val_ The uint8 value of the value to create. + */ +KUZU_C_API kuzu_value* kuzu_value_create_uint8(uint8_t val_); +/** + * @brief Creates a value with uint16 type and the given uint16 value. Caller is responsible for + * destroying the returned value. + * @param val_ The uint16 value of the value to create. + */ +KUZU_C_API kuzu_value* kuzu_value_create_uint16(uint16_t val_); +/** + * @brief Creates a value with uint32 type and the given uint32 value. Caller is responsible for + * destroying the returned value. + * @param val_ The uint32 value of the value to create. + */ +KUZU_C_API kuzu_value* kuzu_value_create_uint32(uint32_t val_); +/** + * @brief Creates a value with uint64 type and the given uint64 value. Caller is responsible for + * destroying the returned value. + * @param val_ The uint64 value of the value to create. + */ +KUZU_C_API kuzu_value* kuzu_value_create_uint64(uint64_t val_); /** * @brief Creates a value with float type and the given float value. Caller is responsible for * destroying the returned value. @@ -715,6 +790,12 @@ KUZU_C_API kuzu_logical_type* kuzu_value_get_data_type(kuzu_value* value); * @param value The value to return. */ KUZU_C_API bool kuzu_value_get_bool(kuzu_value* value); + +/** + * @brief Returns the int8 value of the given value. The value must be of type INT8. + * @param value The value to return. + */ +KUZU_C_API int8_t kuzu_value_get_int8(kuzu_value* value); /** * @brief Returns the int16 value of the given value. The value must be of type INT16. * @param value The value to return. @@ -730,6 +811,26 @@ KUZU_C_API int32_t kuzu_value_get_int32(kuzu_value* value); * @param value The value to return. */ KUZU_C_API int64_t kuzu_value_get_int64(kuzu_value* value); +/** + * @brief Returns the uint8 value of the given value. The value must be of type UINT8. + * @param value The value to return. + */ +KUZU_C_API uint8_t kuzu_value_get_uint8(kuzu_value* value); +/** + * @brief Returns the uint16 value of the given value. The value must be of type UINT16. + * @param value The value to return. + */ +KUZU_C_API uint16_t kuzu_value_get_uint16(kuzu_value* value); +/** + * @brief Returns the uint32 value of the given value. The value must be of type UINT32. + * @param value The value to return. + */ +KUZU_C_API uint32_t kuzu_value_get_uint32(kuzu_value* value); +/** + * @brief Returns the uint64 value of the given value. The value must be of type UINT64. + * @param value The value to return. + */ +KUZU_C_API uint64_t kuzu_value_get_uint64(kuzu_value* value); /** * @brief Returns the float value of the given value. The value must be of type FLOAT. * @param value The value to return. diff --git a/test/c_api/value_test.cpp b/test/c_api/value_test.cpp index f9bb5d3d109..aadb3aec920 100644 --- a/test/c_api/value_test.cpp +++ b/test/c_api/value_test.cpp @@ -88,6 +88,15 @@ TEST_F(CApiValueTest, CreateBool) { kuzu_value_destroy(value); } +TEST_F(CApiValueTest, CreateInt8) { + kuzu_value* value = kuzu_value_create_int8(12); + ASSERT_FALSE(value->_is_owned_by_cpp); + auto cppValue = static_cast(value->_value); + ASSERT_EQ(cppValue->getDataType()->getLogicalTypeID(), LogicalTypeID::INT8); + ASSERT_EQ(cppValue->getValue(), 12); + kuzu_value_destroy(value); +} + TEST_F(CApiValueTest, CreateInt16) { kuzu_value* value = kuzu_value_create_int16(123); ASSERT_FALSE(value->_is_owned_by_cpp); @@ -115,6 +124,42 @@ TEST_F(CApiValueTest, CreateInt64) { kuzu_value_destroy(value); } +TEST_F(CApiValueTest, CreateUInt8) { + kuzu_value* value = kuzu_value_create_uint8(12); + ASSERT_FALSE(value->_is_owned_by_cpp); + auto cppValue = static_cast(value->_value); + ASSERT_EQ(cppValue->getDataType()->getLogicalTypeID(), LogicalTypeID::UINT8); + ASSERT_EQ(cppValue->getValue(), 12); + kuzu_value_destroy(value); +} + +TEST_F(CApiValueTest, CreateUInt16) { + kuzu_value* value = kuzu_value_create_uint16(123); + ASSERT_FALSE(value->_is_owned_by_cpp); + auto cppValue = static_cast(value->_value); + ASSERT_EQ(cppValue->getDataType()->getLogicalTypeID(), LogicalTypeID::UINT16); + ASSERT_EQ(cppValue->getValue(), 123); + kuzu_value_destroy(value); +} + +TEST_F(CApiValueTest, CreateUInt32) { + kuzu_value* value = kuzu_value_create_uint32(123); + ASSERT_FALSE(value->_is_owned_by_cpp); + auto cppValue = static_cast(value->_value); + ASSERT_EQ(cppValue->getDataType()->getLogicalTypeID(), LogicalTypeID::UINT32); + ASSERT_EQ(cppValue->getValue(), 123); + kuzu_value_destroy(value); +} + +TEST_F(CApiValueTest, CreateUInt64) { + kuzu_value* value = kuzu_value_create_uint64(123); + ASSERT_FALSE(value->_is_owned_by_cpp); + auto cppValue = static_cast(value->_value); + ASSERT_EQ(cppValue->getDataType()->getLogicalTypeID(), LogicalTypeID::UINT64); + ASSERT_EQ(cppValue->getValue(), 123); + kuzu_value_destroy(value); +} + TEST_F(CApiValueTest, CreateFloat) { kuzu_value* value = kuzu_value_create_float(123.456); ASSERT_FALSE(value->_is_owned_by_cpp); @@ -405,6 +450,22 @@ TEST_F(CApiValueTest, GetBool) { kuzu_query_result_destroy(result); } +TEST_F(CApiValueTest, GetInt8) { + auto connection = getConnection(); + auto result = kuzu_connection_query(connection, + (char*)"MATCH (a:person) -[r:studyAt]-> (b:organisation) RETURN r.level ORDER BY a.ID"); + ASSERT_TRUE(kuzu_query_result_is_success(result)); + ASSERT_TRUE(kuzu_query_result_has_next(result)); + auto flatTuple = kuzu_query_result_get_next(result); + auto value = kuzu_flat_tuple_get_value(flatTuple, 0); + ASSERT_TRUE(value->_is_owned_by_cpp); + ASSERT_FALSE(kuzu_value_is_null(value)); + ASSERT_EQ(kuzu_value_get_int8(value), 5); + kuzu_value_destroy(value); + kuzu_flat_tuple_destroy(flatTuple); + kuzu_query_result_destroy(result); +} + TEST_F(CApiValueTest, GetInt16) { auto connection = getConnection(); auto result = kuzu_connection_query(connection, @@ -453,6 +514,71 @@ TEST_F(CApiValueTest, GetInt64) { kuzu_query_result_destroy(result); } +TEST_F(CApiValueTest, GetUInt8) { + auto connection = getConnection(); + auto result = kuzu_connection_query(connection, + (char*)"MATCH (a:person) -[r:studyAt]-> (b:organisation) RETURN r.ulevel ORDER BY a.ID"); + ASSERT_TRUE(kuzu_query_result_is_success(result)); + ASSERT_TRUE(kuzu_query_result_has_next(result)); + auto flatTuple = kuzu_query_result_get_next(result); + auto value = kuzu_flat_tuple_get_value(flatTuple, 0); + ASSERT_TRUE(value->_is_owned_by_cpp); + ASSERT_FALSE(kuzu_value_is_null(value)); + ASSERT_EQ(kuzu_value_get_uint8(value), 15); + kuzu_value_destroy(value); + kuzu_flat_tuple_destroy(flatTuple); + kuzu_query_result_destroy(result); +} + +TEST_F(CApiValueTest, GetUInt16) { + auto connection = getConnection(); + auto result = kuzu_connection_query(connection, + (char*)"MATCH (a:person) -[r:studyAt]-> (b:organisation) RETURN r.ulength ORDER BY a.ID"); + ASSERT_TRUE(kuzu_query_result_is_success(result)); + ASSERT_TRUE(kuzu_query_result_has_next(result)); + auto flatTuple = kuzu_query_result_get_next(result); + auto value = kuzu_flat_tuple_get_value(flatTuple, 0); + ASSERT_TRUE(value->_is_owned_by_cpp); + ASSERT_FALSE(kuzu_value_is_null(value)); + ASSERT_EQ(kuzu_value_get_uint16(value), 120); + kuzu_value_destroy(value); + kuzu_flat_tuple_destroy(flatTuple); + kuzu_query_result_destroy(result); +} + +TEST_F(CApiValueTest, GetUInt32) { + auto connection = getConnection(); + auto result = + kuzu_connection_query(connection, (char*)"MATCH (a:person) -[r:studyAt]-> (b:organisation) " + "RETURN r.temprature ORDER BY a.ID"); + ASSERT_TRUE(kuzu_query_result_is_success(result)); + ASSERT_TRUE(kuzu_query_result_has_next(result)); + auto flatTuple = kuzu_query_result_get_next(result); + auto value = kuzu_flat_tuple_get_value(flatTuple, 0); + ASSERT_TRUE(value->_is_owned_by_cpp); + ASSERT_FALSE(kuzu_value_is_null(value)); + ASSERT_EQ(kuzu_value_get_uint32(value), 35); + kuzu_value_destroy(value); + kuzu_flat_tuple_destroy(flatTuple); + kuzu_query_result_destroy(result); +} + +TEST_F(CApiValueTest, GetUInt64) { + auto connection = getConnection(); + auto result = kuzu_connection_query(connection, + (char*)"MATCH (a:person) -[r:studyAt]-> (b:organisation) RETURN r.code ORDER BY a.ID"); + ASSERT_TRUE(kuzu_query_result_is_success(result)); + ASSERT_TRUE(kuzu_query_result_has_next(result)); + auto flatTuple = kuzu_query_result_get_next(result); + auto value = kuzu_flat_tuple_get_value(flatTuple, 0); + ASSERT_TRUE(value->_is_owned_by_cpp); + ASSERT_FALSE(kuzu_value_is_null(value)); + ASSERT_EQ(kuzu_value_get_uint64(value), 6556); + kuzu_value_destroy(value); + kuzu_flat_tuple_destroy(flatTuple); + kuzu_query_result_destroy(result); +} + TEST_F(CApiValueTest, GetFloat) { auto connection = getConnection(); auto result = diff --git a/tools/java_api/src/jni/kuzu_java.cpp b/tools/java_api/src/jni/kuzu_java.cpp index d31e49212f1..64ccaa1601e 100644 --- a/tools/java_api/src/jni/kuzu_java.cpp +++ b/tools/java_api/src/jni/kuzu_java.cpp @@ -841,6 +841,41 @@ JNIEXPORT jobject JNICALL Java_com_kuzudb_KuzuNative_kuzu_1value_1get_1value( jobject ret = env->NewObject(retClass, ctor, val); return ret; } + case LogicalTypeID::INT8: { + jclass retClass = env->FindClass("java/lang/Byte"); + jmethodID ctor = env->GetMethodID(retClass, "", "(B)V"); + jbyte val = static_cast(v->getValue()); + jobject ret = env->NewObject(retClass, ctor, val); + return ret; + } + case LogicalTypeID::UINT64: { + jclass retClass = env->FindClass("java/lang/Long"); + jmethodID ctor = env->GetMethodID(retClass, "", "(J)V"); + jlong val = static_cast(v->getValue()); + jobject ret = env->NewObject(retClass, ctor, val); + return ret; + } + case LogicalTypeID::UINT32: { + jclass retClass = env->FindClass("java/lang/Integer"); + jmethodID ctor = env->GetMethodID(retClass, "", "(I)V"); + jint val = static_cast(v->getValue()); + jobject ret = env->NewObject(retClass, ctor, val); + return ret; + } + case LogicalTypeID::UINT16: { + jclass retClass = env->FindClass("java/lang/Short"); + jmethodID ctor = env->GetMethodID(retClass, "", "(S)V"); + jshort val = static_cast(v->getValue()); + jobject ret = env->NewObject(retClass, ctor, val); + return ret; + } + case LogicalTypeID::UINT8: { + jclass retClass = env->FindClass("java/lang/Byte"); + jmethodID ctor = env->GetMethodID(retClass, "", "(B)V"); + jbyte val = static_cast(v->getValue()); + jobject ret = env->NewObject(retClass, ctor, val); + return ret; + } case LogicalTypeID::DOUBLE: { jclass retClass = env->FindClass("java/lang/Double"); jmethodID ctor = env->GetMethodID(retClass, "", "(D)V"); diff --git a/tools/java_api/src/main/java/com/kuzudb/KuzuDataTypeID.java b/tools/java_api/src/main/java/com/kuzudb/KuzuDataTypeID.java index 0d92262fc77..78ac3f897cf 100644 --- a/tools/java_api/src/main/java/com/kuzudb/KuzuDataTypeID.java +++ b/tools/java_api/src/main/java/com/kuzudb/KuzuDataTypeID.java @@ -13,6 +13,11 @@ public enum KuzuDataTypeID { INT64(23), INT32(24), INT16(25), + INT8(26), + UINT64(27), + UINT32(28), + UINT16(29), + UINT8(30), DOUBLE(32), FLOAT(33), DATE(34), diff --git a/tools/java_api/src/test/java/com/kuzudb/test/ValueTest.java b/tools/java_api/src/test/java/com/kuzudb/test/ValueTest.java index 66693e0837e..d6c64ce4d42 100644 --- a/tools/java_api/src/test/java/com/kuzudb/test/ValueTest.java +++ b/tools/java_api/src/test/java/com/kuzudb/test/ValueTest.java @@ -5,6 +5,7 @@ import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.*; +import java.math.BigInteger; import java.time.LocalDate; import java.time.Duration; @@ -102,6 +103,16 @@ void ValueCreateBool() throws KuzuObjectRefDestroyedException { value.destroy(); } + @Test + void ValueCreateINT8() throws KuzuObjectRefDestroyedException { + // INT8 + KuzuValue value = new KuzuValue((byte) 42); + assertFalse(value.isOwnedByCPP()); + assertEquals(value.getDataType().getID(), KuzuDataTypeID.INT8); + assertTrue(value.getValue().equals((byte) 42)); + value.destroy(); + } + @Test void ValueCreateINT16() throws KuzuObjectRefDestroyedException { // INT16 @@ -132,6 +143,46 @@ void ValueCreateINT64() throws KuzuObjectRefDestroyedException { value.destroy(); } + @Test + void ValueCreateUINT8() throws KuzuObjectRefDestroyedException { + // UINT8 + KuzuValue value = new KuzuValue((short) 255); // Assuming UINT8 maximum value + assertFalse(value.isOwnedByCPP()); + assertEquals(value.getDataType().getID(), KuzuDataTypeID.UINT8); + assertTrue(value.getValue().equals((short) 255)); + value.destroy(); + } + + @Test + void ValueCreateUINT16() throws KuzuObjectRefDestroyedException { + // UINT16 + KuzuValue value = new KuzuValue((int) 65535); // Assuming UINT16 maximum value + assertFalse(value.isOwnedByCPP()); + assertEquals(value.getDataType().getID(), KuzuDataTypeID.UINT16); + assertTrue(value.getValue().equals((int) 65535)); + value.destroy(); + } + + @Test + void ValueCreateUINT32() throws KuzuObjectRefDestroyedException { + // UINT32 + KuzuValue value = new KuzuValue((long) 4294967295L); // Assuming UINT32 maximum value + assertFalse(value.isOwnedByCPP()); + assertEquals(value.getDataType().getID(), KuzuDataTypeID.UINT32); + assertTrue(value.getValue().equals((long) 4294967295L)); + value.destroy(); + } + + @Test + void ValueCreateUINT64() throws KuzuObjectRefDestroyedException { + // UINT64 + KuzuValue value = new KuzuValue(new BigInteger("18446744073709551615")); // Assuming UINT64 maximum value + assertFalse(value.isOwnedByCPP()); + assertEquals(value.getDataType().getID(), KuzuDataTypeID.UINT64); + assertTrue(value.getValue().equals(new BigInteger("18446744073709551615"))); + value.destroy(); + } + @Test void ValueCreateFloat() throws KuzuObjectRefDestroyedException { // float diff --git a/tools/python_api/src_cpp/py_connection.cpp b/tools/python_api/src_cpp/py_connection.cpp index f4767e7c452..63b710998e7 100644 --- a/tools/python_api/src_cpp/py_connection.cpp +++ b/tools/python_api/src_cpp/py_connection.cpp @@ -186,6 +186,7 @@ Value PyConnection::transformPythonValue(py::handle val) { return Value::createValue(val.cast()); } else if (py::isinstance(val)) { return Value::createValue(val.cast()); + } else if (py::isinstance(val)) { return Value::createValue(val.cast()); } else if (py::isinstance(val)) { diff --git a/tools/python_api/src_py/database.py b/tools/python_api/src_py/database.py index 7f89b64d8a5..9fb1ca80261 100644 --- a/tools/python_api/src_py/database.py +++ b/tools/python_api/src_py/database.py @@ -148,26 +148,6 @@ def _scan_node_table(self, table_name, prop_name, prop_type, dim, indices, num_t result = np.empty(len(indices) * dim, dtype=np.int16) self._database.scan_node_table_as_int16( table_name, prop_name, indices_cast, result, num_threads) - if prop_type == Type.INT8.value: - result = np.empty(len(indices) * dim, dtype=np.int8) - self._database.scan_node_table_as_int8( - table_name, prop_name, indices_cast, result, num_threads) - if prop_type == Type.UINT64.value: - result = np.empty(len(indices) * dim, dtype=np.uint64) - self._database.scan_node_table_as_uint64( - table_name, prop_name, indices_cast, result, num_threads) - if prop_type == Type.UINT32.value: - result = np.empty(len(indices) * dim, dtype=np.uint32) - self._database.scan_node_table_as_uint32( - table_name, prop_name, indices_cast, result, num_threads) - if prop_type == Type.UINT16.value: - result = np.empty(len(indices) * dim, dtype=np.uint16) - self._database.scan_node_table_as_uint16( - table_name, prop_name, indices_cast, result, num_threads) - if prop_type == Type.UINT8.value: - result = np.empty(len(indices) * dim, dtype=np.uint8) - self._database.scan_node_table_as_uint8( - table_name, prop_name, indices_cast, result, num_threads) if prop_type == Type.DOUBLE.value: result = np.empty(len(indices) * dim, dtype=np.float64) self._database.scan_node_table_as_double( diff --git a/tools/rust_api/src/ffi.rs b/tools/rust_api/src/ffi.rs index 6981bb7dc99..0f42ea89bf3 100644 --- a/tools/rust_api/src/ffi.rs +++ b/tools/rust_api/src/ffi.rs @@ -22,6 +22,11 @@ pub(crate) mod ffi { INT64 = 23, INT32 = 24, INT16 = 25, + INT8 = 26, + UINT64 = 27, + UINT32 = 28, + UINT16 = 29, + UINT8 = 30, DOUBLE = 32, FLOAT = 33, DATE = 34, @@ -229,12 +234,22 @@ pub(crate) mod ffi { #[rust_name = "get_value_bool"] fn getValue(&self) -> bool; + #[rust_name = "get_value_i8"] + fn getValue(&self) -> i8; #[rust_name = "get_value_i16"] fn getValue(&self) -> i16; #[rust_name = "get_value_i32"] fn getValue(&self) -> i32; #[rust_name = "get_value_i64"] fn getValue(&self) -> i64; + #[rust_name = "get_value_u8"] + fn getValue(&self) -> u8; + #[rust_name = "get_value_u16"] + fn getValue(&self) -> u16; + #[rust_name = "get_value_u32"] + fn getValue(&self) -> u32; + #[rust_name = "get_value_u64"] + fn getValue(&self) -> u64; #[rust_name = "get_value_float"] fn getValue(&self) -> f32; #[rust_name = "get_value_double"] @@ -257,12 +272,22 @@ pub(crate) mod ffi { #[rust_name = "create_value_bool"] fn create_value(value: bool) -> UniquePtr; + #[rust_name = "create_value_i8"] + fn create_value(value: i8) -> UniquePtr; #[rust_name = "create_value_i16"] fn create_value(value: i16) -> UniquePtr; #[rust_name = "create_value_i32"] fn create_value(value: i32) -> UniquePtr; #[rust_name = "create_value_i64"] fn create_value(value: i64) -> UniquePtr; + #[rust_name = "create_value_u8"] + fn create_value(value: u8) -> UniquePtr; + #[rust_name = "create_value_u16"] + fn create_value(value: u16) -> UniquePtr; + #[rust_name = "create_value_u32"] + fn create_value(value: u32) -> UniquePtr; + #[rust_name = "create_value_u64"] + fn create_value(value: u64) -> UniquePtr; #[rust_name = "create_value_float"] fn create_value(value: f32) -> UniquePtr; #[rust_name = "create_value_double"] diff --git a/tools/rust_api/src/logical_type.rs b/tools/rust_api/src/logical_type.rs index 876bb8fa860..32c54c06c9b 100644 --- a/tools/rust_api/src/logical_type.rs +++ b/tools/rust_api/src/logical_type.rs @@ -18,6 +18,16 @@ pub enum LogicalType { Int32, /// Correponds to [Value::Int16](crate::value::Value::Int16) Int16, + /// Correponds to [Value::Int8](crate::value::Value::Int8) + Int8, + /// Correponds to [Value::UInt64](crate::value::Value::UInt64) + UInt64, + /// Correponds to [Value::UInt32](crate::value::Value::UInt32) + UInt32, + /// Correponds to [Value::UInt16](crate::value::Value::UInt16) + UInt16, + /// Correponds to [Value::UInt8](crate::value::Value::UInt8) + UInt8, /// Correponds to [Value::Double](crate::value::Value::Double) Double, /// Correponds to [Value::Float](crate::value::Value::Float) @@ -67,9 +77,14 @@ impl From<&ffi::LogicalType> for LogicalType { LogicalTypeID::ANY => LogicalType::Any, LogicalTypeID::BOOL => LogicalType::Bool, LogicalTypeID::SERIAL => LogicalType::Serial, + LogicalTypeID::INT8 => LogicalType::Int8, LogicalTypeID::INT16 => LogicalType::Int16, LogicalTypeID::INT32 => LogicalType::Int32, LogicalTypeID::INT64 => LogicalType::Int64, + LogicalTypeID::UINT8 => LogicalType::UInt8, + LogicalTypeID::UINT16 => LogicalType::UInt16, + LogicalTypeID::UINT32 => LogicalType::UInt32, + LogicalTypeID::UINT64 => LogicalType::UInt64, LogicalTypeID::FLOAT => LogicalType::Float, LogicalTypeID::DOUBLE => LogicalType::Double, LogicalTypeID::STRING => LogicalType::String, @@ -118,6 +133,11 @@ impl From<&LogicalType> for cxx::UniquePtr { | LogicalType::Int64 | LogicalType::Int32 | LogicalType::Int16 + | LogicalType::Int8 + | LogicalType::UInt64 + | LogicalType::UInt32 + | LogicalType::UInt16 + | LogicalType::UInt8 | LogicalType::Float | LogicalType::Double | LogicalType::Date @@ -156,9 +176,14 @@ impl LogicalType { LogicalType::Any => LogicalTypeID::ANY, LogicalType::Bool => LogicalTypeID::BOOL, LogicalType::Serial => LogicalTypeID::SERIAL, + LogicalType::Int8 => LogicalTypeID::INT8, LogicalType::Int16 => LogicalTypeID::INT16, LogicalType::Int32 => LogicalTypeID::INT32, LogicalType::Int64 => LogicalTypeID::INT64, + LogicalType::UInt8 => LogicalTypeID::UINT8, + LogicalType::UInt16 => LogicalTypeID::UINT16, + LogicalType::UInt32 => LogicalTypeID::UINT32, + LogicalType::UInt64 => LogicalTypeID::UINT64, LogicalType::Float => LogicalTypeID::FLOAT, LogicalType::Double => LogicalTypeID::DOUBLE, LogicalType::String => LogicalTypeID::STRING, diff --git a/tools/rust_api/src/value.rs b/tools/rust_api/src/value.rs index 913804e16cf..67cd6db77cb 100644 --- a/tools/rust_api/src/value.rs +++ b/tools/rust_api/src/value.rs @@ -196,6 +196,11 @@ pub enum Value { Int64(i64), Int32(i32), Int16(i16), + Int8(i8), + UInt64(u64), + UInt32(u32), + UInt16(u16), + UInt8(u8), Double(f64), Float(f32), /// Stored internally as the number of days since 1970-01-01 as a 32-bit signed integer, which @@ -257,9 +262,14 @@ impl std::fmt::Display for Value { match self { Value::Bool(true) => write!(f, "True"), Value::Bool(false) => write!(f, "False"), + Value::Int8(x) => write!(f, "{x}"), Value::Int16(x) => write!(f, "{x}"), Value::Int32(x) => write!(f, "{x}"), Value::Int64(x) => write!(f, "{x}"), + Value::UInt8(x) => write!(f, "{x}"), + Value::UInt16(x) => write!(f, "{x}"), + Value::UInt32(x) => write!(f, "{x}"), + Value::UInt64(x) => write!(f, "{x}"), Value::Date(x) => write!(f, "{x}"), Value::String(x) => write!(f, "{x}"), Value::Blob(x) => write!(f, "{x:x?}"), @@ -299,9 +309,14 @@ impl From<&Value> for LogicalType { fn from(value: &Value) -> Self { match value { Value::Bool(_) => LogicalType::Bool, + Value::Int8(_) => LogicalType::Int8, Value::Int16(_) => LogicalType::Int16, Value::Int32(_) => LogicalType::Int32, Value::Int64(_) => LogicalType::Int64, + Value::UInt8(_) => LogicalType::UInt8, + Value::UInt16(_) => LogicalType::UInt16, + Value::UInt32(_) => LogicalType::UInt32, + Value::UInt64(_) => LogicalType::UInt64, Value::Float(_) => LogicalType::Float, Value::Double(_) => LogicalType::Double, Value::Date(_) => LogicalType::Date, @@ -345,9 +360,14 @@ impl TryFrom<&ffi::Value> for Value { match ffi::value_get_data_type_id(value) { LogicalTypeID::ANY => unimplemented!(), LogicalTypeID::BOOL => Ok(Value::Bool(value.get_value_bool())), + LogicalTypeID::INT8 => Ok(Value::Int8(value.get_value_i8())), LogicalTypeID::INT16 => Ok(Value::Int16(value.get_value_i16())), LogicalTypeID::INT32 => Ok(Value::Int32(value.get_value_i32())), LogicalTypeID::INT64 => Ok(Value::Int64(value.get_value_i64())), + LogicalTypeID::UINT8 => Ok(Value::UInt8(value.get_value_u8())), + LogicalTypeID::UINT16 => Ok(Value::UInt16(value.get_value_u16())), + LogicalTypeID::UINT32 => Ok(Value::UInt32(value.get_value_u32())), + LogicalTypeID::UINT64 => Ok(Value::UInt64(value.get_value_u64())), LogicalTypeID::FLOAT => Ok(Value::Float(value.get_value_float())), LogicalTypeID::DOUBLE => Ok(Value::Double(value.get_value_double())), LogicalTypeID::STRING => Ok(Value::String(ffi::value_get_string(value).to_string())), @@ -503,9 +523,14 @@ impl TryInto> for Value { match self { Value::Null(typ) => Ok(ffi::create_value_null((&typ).into())), Value::Bool(value) => Ok(ffi::create_value_bool(value)), + Value::Int8(value) => Ok(ffi::create_value_i8(value)), Value::Int16(value) => Ok(ffi::create_value_i16(value)), Value::Int32(value) => Ok(ffi::create_value_i32(value)), Value::Int64(value) => Ok(ffi::create_value_i64(value)), + Value::UInt8(value) => Ok(ffi::create_value_u8(value)), + Value::UInt16(value) => Ok(ffi::create_value_u16(value)), + Value::UInt32(value) => Ok(ffi::create_value_u32(value)), + Value::UInt64(value) => Ok(ffi::create_value_u64(value)), Value::Float(value) => Ok(ffi::create_value_float(value)), Value::Double(value) => Ok(ffi::create_value_double(value)), Value::String(value) => Ok(ffi::create_value_string( @@ -594,6 +619,12 @@ impl TryInto> for Value { } } +impl From for Value { + fn from(item: i8) -> Self { + Value::Int8(item) + } +} + impl From for Value { fn from(item: i16) -> Self { Value::Int16(item) @@ -612,6 +643,30 @@ impl From for Value { } } +impl From for Value { + fn from(item: u8) -> Self { + Value::UInt8(item) + } +} + +impl From for Value { + fn from(item: u16) -> Self { + Value::UInt16(item) + } +} + +impl From for Value { + fn from(item: u32) -> Self { + Value::UInt32(item) + } +} + +impl From for Value { + fn from(item: u64) -> Self { + Value::UInt64(item) + } +} + impl From for Value { fn from(item: f32) -> Self { Value::Float(item) @@ -738,9 +793,14 @@ mod tests { type_tests! { convert_var_list_type: LogicalType::VarList { child_type: Box::new(LogicalType::String) }, convert_fixed_list_type: LogicalType::FixedList { child_type: Box::new(LogicalType::Int64), num_elements: 3 }, + convert_int8_type: LogicalType::Int8, convert_int16_type: LogicalType::Int16, convert_int32_type: LogicalType::Int32, convert_int64_type: LogicalType::Int64, + convert_uint8_type: LogicalType::UInt8, + convert_uint16_type: LogicalType::UInt16, + convert_uint32_type: LogicalType::UInt32, + convert_uint64_type: LogicalType::UInt64, convert_float_type: LogicalType::Float, convert_double_type: LogicalType::Double, convert_timestamp_type: LogicalType::Timestamp, @@ -760,9 +820,14 @@ mod tests { convert_var_list: Value::VarList(LogicalType::String, vec!["Alice".into(), "Bob".into()]), convert_var_list_empty: Value::VarList(LogicalType::String, vec![]), convert_fixed_list: Value::FixedList(LogicalType::String, vec!["Alice".into(), "Bob".into()]), + convert_int8: Value::Int8(0), convert_int16: Value::Int16(1), convert_int32: Value::Int32(2), convert_int64: Value::Int64(3), + convert_uint8: Value::UInt8(0), + convert_uint16: Value::UInt16(1), + convert_uint32: Value::UInt32(2), + convert_uint64: Value::UInt64(3), convert_float: Value::Float(4.), convert_double: Value::Double(5.), convert_timestamp: Value::Timestamp(datetime!(2023-06-13 11:25:30 UTC)), @@ -782,9 +847,14 @@ mod tests { display_var_list: Value::VarList(LogicalType::String, vec!["Alice".into(), "Bob".into()]), display_var_list_empty: Value::VarList(LogicalType::String, vec![]), display_fixed_list: Value::FixedList(LogicalType::String, vec!["Alice".into(), "Bob".into()]), + display_int8: Value::Int8(0), display_int16: Value::Int16(1), display_int32: Value::Int32(2), display_int64: Value::Int64(3), + display_uint8: Value::UInt8(0), + display_uint16: Value::UInt16(1), + display_uint32: Value::UInt32(2), + display_uint64: Value::UInt64(3), // Float, double, interval and timestamp have display differences which we probably don't want to // reconcile display_date: Value::Date(date!(2023-06-13)), @@ -813,9 +883,14 @@ mod tests { // }), "INT16[3][]", // db_var_list_string: Value::VarList(LogicalType::String, vec!["Alice".into(), "Bob".into()]), "STRING[]", // db_var_list_int: Value::VarList(LogicalType::Int64, vec![0i64.into(), 1i64.into(), 2i64.into()]), "INT64[]", + db_int8: Value::Int8(0), "INT8", db_int16: Value::Int16(1), "INT16", db_int32: Value::Int32(2), "INT32", db_int64: Value::Int64(3), "INT64", + db_uint8: Value::UInt8(0), "UINT8", + db_uint16: Value::UInt16(1), "UINT16", + db_uint32: Value::UInt32(2), "UINT32", + db_uint64: Value::UInt64(3), "UINT64", db_float: Value::Float(4.), "FLOAT", db_double: Value::Double(5.), "DOUBLE", db_timestamp: Value::Timestamp(datetime!(2023-06-13 11:25:30 UTC)), "TIMESTAMP",