Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Link C and C++ API tests against the API-restricted shared library #2153

Merged
merged 1 commit into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,8 @@ set(CMAKE_FIND_PACKAGE_RESOLVE_SYMLINKS TRUE)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
if (MSVC)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
endif()
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)

# Detect OS and architecture, copied from DuckDB
set(OS_NAME "unknown")
Expand Down Expand Up @@ -92,6 +90,9 @@ if(MSVC)
# Remove the default to avoid warnings
STRING(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
STRING(REPLACE "/EHs" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
# Store all libraries and binaries in the same directory so that kuzu_shared.dll is found at runtime
set(LIBRARY_OUTPUT_PATH "${CMAKE_BINARY_DIR}/src")
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_BINARY_DIR}/src")
endif()
if(CMAKE_BUILD_TYPE MATCHES Release)
if(MSVC)
Expand Down Expand Up @@ -152,6 +153,15 @@ function(add_kuzu_test TEST_NAME)
gtest_discover_tests(${TEST_NAME})
endfunction()

function(add_kuzu_api_test TEST_NAME)
set(SRCS ${ARGN})
add_executable(${TEST_NAME} ${SRCS})
target_link_libraries(${TEST_NAME} PRIVATE api_graph_test api_test_helper)
target_include_directories(${TEST_NAME} PRIVATE ${PROJECT_SOURCE_DIR}/test/include)
include(GoogleTest)
gtest_discover_tests(${TEST_NAME})
endfunction()

add_definitions(-DKUZU_ROOT_DIRECTORY="${PROJECT_SOURCE_DIR}")
add_definitions(-DKUZU_STORAGE_VERSION="${CMAKE_PROJECT_VERSION}")

Expand Down
1 change: 0 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ target_include_directories(kuzu_shared
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)

include(GenerateExportHeader)
generate_export_header(kuzu_shared BASE_NAME kuzu EXPORT_MACRO_NAME KUZU_API STATIC_DEFINE KUZU_STATIC_DEFINE)
target_include_directories(kuzu PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
target_include_directories(kuzu_shared PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
target_compile_definitions(kuzu PUBLIC KUZU_STATIC_DEFINE)
8 changes: 8 additions & 0 deletions src/common/types/types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,14 @@ void StructTypeInfo::serializeInternal(FileInfo* fileInfo, uint64_t& offset) con
SerDeser::serializeVectorOfPtrs(fields, fileInfo, offset);
}

LogicalType::LogicalType(LogicalTypeID typeID) : typeID{typeID}, extraTypeInfo{nullptr} {
setPhysicalType();
};
LogicalType::LogicalType(LogicalTypeID typeID, std::unique_ptr<ExtraTypeInfo> extraTypeInfo)
: typeID{typeID}, extraTypeInfo{std::move(extraTypeInfo)} {
setPhysicalType();
};

LogicalType::LogicalType(const LogicalType& other) {
typeID = other.typeID;
physicalType = other.physicalType;
Expand Down
36 changes: 20 additions & 16 deletions src/common/vector/value_vector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,22 +372,22 @@ void ArrowColumnVector::slice(ValueVector* vector, offset_t offset) {
setArrowColumn(vector, arrowColumnBuffer->column->Slice((int64_t)offset));
}

template void ValueVector::setValue<nodeID_t>(uint32_t pos, nodeID_t val);
template void ValueVector::setValue<bool>(uint32_t pos, bool val);
template void ValueVector::setValue<int64_t>(uint32_t pos, int64_t val);
template void ValueVector::setValue<int32_t>(uint32_t pos, int32_t val);
template void ValueVector::setValue<int16_t>(uint32_t pos, int16_t val);
template void ValueVector::setValue<int8_t>(uint32_t pos, int8_t val);
template void ValueVector::setValue<uint64_t>(uint32_t pos, uint64_t val);
template void ValueVector::setValue<uint32_t>(uint32_t pos, uint32_t val);
template void ValueVector::setValue<uint16_t>(uint32_t pos, uint16_t val);
template void ValueVector::setValue<uint8_t>(uint32_t pos, uint8_t val);
template void ValueVector::setValue<double_t>(uint32_t pos, double_t val);
template void ValueVector::setValue<float_t>(uint32_t pos, float_t val);
template void ValueVector::setValue<date_t>(uint32_t pos, date_t val);
template void ValueVector::setValue<timestamp_t>(uint32_t pos, timestamp_t val);
template void ValueVector::setValue<interval_t>(uint32_t pos, interval_t val);
template void ValueVector::setValue<list_entry_t>(uint32_t pos, list_entry_t val);
template KUZU_API void ValueVector::setValue<nodeID_t>(uint32_t pos, nodeID_t val);
template KUZU_API void ValueVector::setValue<bool>(uint32_t pos, bool val);
template KUZU_API void ValueVector::setValue<int64_t>(uint32_t pos, int64_t val);
template KUZU_API void ValueVector::setValue<int32_t>(uint32_t pos, int32_t val);
template KUZU_API void ValueVector::setValue<int16_t>(uint32_t pos, int16_t val);
template KUZU_API void ValueVector::setValue<int8_t>(uint32_t pos, int8_t val);
template KUZU_API void ValueVector::setValue<uint64_t>(uint32_t pos, uint64_t val);
template KUZU_API void ValueVector::setValue<uint32_t>(uint32_t pos, uint32_t val);
template KUZU_API void ValueVector::setValue<uint16_t>(uint32_t pos, uint16_t val);
template KUZU_API void ValueVector::setValue<uint8_t>(uint32_t pos, uint8_t val);
template KUZU_API void ValueVector::setValue<double_t>(uint32_t pos, double_t val);
template KUZU_API void ValueVector::setValue<float_t>(uint32_t pos, float_t val);
template KUZU_API void ValueVector::setValue<date_t>(uint32_t pos, date_t val);
template KUZU_API void ValueVector::setValue<timestamp_t>(uint32_t pos, timestamp_t val);
template KUZU_API void ValueVector::setValue<interval_t>(uint32_t pos, interval_t val);
template KUZU_API void ValueVector::setValue<list_entry_t>(uint32_t pos, list_entry_t val);

template<>
void ValueVector::setValue(uint32_t pos, ku_string_t val) {
Expand All @@ -398,6 +398,10 @@ void ValueVector::setValue(uint32_t pos, std::string val) {
StringVector::addString(this, pos, val.data(), val.length());
}

void ValueVector::setNull(uint32_t pos, bool isNull) {
nullMask->setNull(pos, isNull);
}

void StringVector::addString(ValueVector* vector, uint32_t vectorPos, ku_string_t& srcStr) {
assert(vector->dataType.getPhysicalType() == PhysicalTypeID::STRING);
auto stringBuffer = reinterpret_cast<StringAuxiliaryBuffer*>(vector->auxiliaryBuffer.get());
Expand Down
99 changes: 99 additions & 0 deletions src/function/vector_string_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,105 @@
namespace kuzu {
namespace function {

void BaseLowerUpperFunction::operation(common::ku_string_t& input, common::ku_string_t& result,
common::ValueVector& resultValueVector, bool isUpper) {
uint32_t resultLen = getResultLen((char*)input.getData(), input.len, isUpper);
result.len = resultLen;
if (resultLen <= common::ku_string_t::SHORT_STR_LENGTH) {
convertCase((char*)result.prefix, input.len, (char*)input.getData(), isUpper);
} else {
result.overflowPtr = reinterpret_cast<uint64_t>(
common::StringVector::getInMemOverflowBuffer(&resultValueVector)
->allocateSpace(result.len));
auto buffer = reinterpret_cast<char*>(result.overflowPtr);
convertCase(buffer, input.len, (char*)input.getData(), isUpper);
memcpy(result.prefix, buffer, common::ku_string_t::PREFIX_LENGTH);
}
}

void BaseStrOperation::operation(common::ku_string_t& input, common::ku_string_t& result,
common::ValueVector& resultValueVector, uint32_t (*strOperation)(char* data, uint32_t len)) {
if (input.len <= common::ku_string_t::SHORT_STR_LENGTH) {
memcpy(result.prefix, input.prefix, input.len);
result.len = strOperation((char*)result.prefix, input.len);
} else {
result.overflowPtr = reinterpret_cast<uint64_t>(

Check warning on line 48 in src/function/vector_string_functions.cpp

View check run for this annotation

Codecov / codecov/patch

src/function/vector_string_functions.cpp#L48

Added line #L48 was not covered by tests
common::StringVector::getInMemOverflowBuffer(&resultValueVector)
->allocateSpace(input.len));

Check warning on line 50 in src/function/vector_string_functions.cpp

View check run for this annotation

Codecov / codecov/patch

src/function/vector_string_functions.cpp#L50

Added line #L50 was not covered by tests
auto buffer = reinterpret_cast<char*>(result.overflowPtr);
memcpy(buffer, input.getData(), input.len);
result.len = strOperation(buffer, input.len);
memcpy(result.prefix, buffer,
result.len < common::ku_string_t::PREFIX_LENGTH ? result.len :

Check warning on line 55 in src/function/vector_string_functions.cpp

View check run for this annotation

Codecov / codecov/patch

src/function/vector_string_functions.cpp#L52-L55

Added lines #L52 - L55 were not covered by tests
common::ku_string_t::PREFIX_LENGTH);
}
}

void Concat::concat(const char* left, uint32_t leftLen, const char* right, uint32_t rightLen,
common::ku_string_t& result, common::ValueVector& resultValueVector) {
auto len = leftLen + rightLen;
if (len <= common::ku_string_t::SHORT_STR_LENGTH /* concat's result is short */) {
memcpy(result.prefix, left, leftLen);
memcpy(result.prefix + leftLen, right, rightLen);
} else {
result.overflowPtr = reinterpret_cast<uint64_t>(
common::StringVector::getInMemOverflowBuffer(&resultValueVector)->allocateSpace(len));
auto buffer = reinterpret_cast<char*>(result.overflowPtr);
memcpy(buffer, left, leftLen);
memcpy(buffer + leftLen, right, rightLen);
memcpy(result.prefix, buffer, common::ku_string_t::PREFIX_LENGTH);
}
result.len = len;
}

void Repeat::operation(common::ku_string_t& left, int64_t& right, common::ku_string_t& result,
common::ValueVector& resultValueVector) {
result.len = left.len * right;
if (result.len <= common::ku_string_t::SHORT_STR_LENGTH) {
repeatStr((char*)result.prefix, left.getAsString(), right);
} else {
result.overflowPtr = reinterpret_cast<uint64_t>(
common::StringVector::getInMemOverflowBuffer(&resultValueVector)
->allocateSpace(result.len));
auto buffer = reinterpret_cast<char*>(result.overflowPtr);
repeatStr(buffer, left.getAsString(), right);
memcpy(result.prefix, buffer, common::ku_string_t::PREFIX_LENGTH);
}
}

void Reverse::operation(common::ku_string_t& input, common::ku_string_t& result,
common::ValueVector& resultValueVector) {
bool isAscii = true;
std::string inputStr = input.getAsString();
for (uint32_t i = 0; i < input.len; i++) {
if (inputStr[i] & 0x80) {
isAscii = false;
break;
}
}
if (isAscii) {
BaseStrOperation::operation(input, result, resultValueVector, reverseStr);
} else {
result.len = input.len;
if (result.len > common::ku_string_t::SHORT_STR_LENGTH) {
result.overflowPtr = reinterpret_cast<uint64_t>(
common::StringVector::getInMemOverflowBuffer(&resultValueVector)
->allocateSpace(input.len));
}
auto resultBuffer = result.len <= common::ku_string_t::SHORT_STR_LENGTH ?
reinterpret_cast<char*>(result.prefix) :
reinterpret_cast<char*>(result.overflowPtr);
utf8proc::utf8proc_grapheme_callback(

Check warning on line 114 in src/function/vector_string_functions.cpp

View check run for this annotation

Codecov / codecov/patch

src/function/vector_string_functions.cpp#L114

Added line #L114 was not covered by tests
inputStr.c_str(), input.len, [&](size_t start, size_t end) {
memcpy(resultBuffer + input.len - end, input.getData() + start, end - start);
return true;
});
if (result.len > common::ku_string_t::SHORT_STR_LENGTH) {
memcpy(result.prefix, resultBuffer, common::ku_string_t::PREFIX_LENGTH);
}
}
}

vector_function_definitions ArrayExtractVectorFunction::getDefinitions() {
vector_function_definitions definitions;
definitions.emplace_back(make_unique<VectorFunctionDefinition>(ARRAY_EXTRACT_FUNC_NAME,
Expand Down
2 changes: 1 addition & 1 deletion src/include/common/data_chunk/sel_vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class SelectionVector {
}
inline sel_t* getSelectedPositionsBuffer() { return selectedPositionsBuffer.get(); }

static const sel_t INCREMENTAL_SELECTED_POS[DEFAULT_VECTOR_CAPACITY];
KUZU_API static const sel_t INCREMENTAL_SELECTED_POS[DEFAULT_VECTOR_CAPACITY];

public:
sel_t* selectedPositions;
Expand Down
9 changes: 2 additions & 7 deletions src/include/common/types/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,13 +249,8 @@ class LogicalType {

public:
KUZU_API LogicalType() : typeID{LogicalTypeID::ANY}, extraTypeInfo{nullptr} {};
KUZU_API explicit LogicalType(LogicalTypeID typeID) : typeID{typeID}, extraTypeInfo{nullptr} {
setPhysicalType();
};
KUZU_API LogicalType(LogicalTypeID typeID, std::unique_ptr<ExtraTypeInfo> extraTypeInfo)
: typeID{typeID}, extraTypeInfo{std::move(extraTypeInfo)} {
setPhysicalType();
};
explicit KUZU_API LogicalType(LogicalTypeID typeID);
KUZU_API LogicalType(LogicalTypeID typeID, std::unique_ptr<ExtraTypeInfo> extraTypeInfo);
// For deserialize only.
LogicalType(LogicalTypeID typeID, PhysicalTypeID physicalType,
std::unique_ptr<ExtraTypeInfo> extraTypeInfo)
Expand Down
8 changes: 4 additions & 4 deletions src/include/common/vector/value_vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class ValueVector {
assert(dataTypeID != LogicalTypeID::VAR_LIST);
}

~ValueVector() = default;
KUZU_API ~ValueVector() = default;

void setState(std::shared_ptr<DataChunkState> state_);

Expand All @@ -41,7 +41,7 @@ class ValueVector {
nullMask->setNullFromRange(startPos, len, false);
}
inline const uint64_t* getNullMaskData() { return nullMask->getData(); }
inline void setNull(uint32_t pos, bool isNull) { nullMask->setNull(pos, isNull); }
KUZU_API void setNull(uint32_t pos, bool isNull);
inline uint8_t isNull(uint32_t pos) const { return nullMask->isNull(pos); }
inline void setAsSingleNullEntry() {
state->selVector->selectedSize = 1;
Expand All @@ -59,7 +59,7 @@ class ValueVector {
return ((T*)valueBuffer.get())[pos];
}
template<typename T>
void setValue(uint32_t pos, T val);
KUZU_API void setValue(uint32_t pos, T val);
// copyFromRowData assumes rowData is non-NULL.
void copyFromRowData(uint32_t pos, const uint8_t* rowData);
// copyToRowData assumes srcVectorData is non-NULL.
Expand All @@ -83,7 +83,7 @@ class ValueVector {
inline void setSequential() { _isSequential = true; }
inline bool isSequential() const { return _isSequential; }

void resetAuxiliaryBuffer();
KUZU_API void resetAuxiliaryBuffer();

// If there is still non-null values after discarding, return true. Otherwise, return false.
// For an unflat vector, its selection vector is also updated to the resultSelVector.
Expand Down
18 changes: 3 additions & 15 deletions src/include/function/string/functions/base_lower_upper_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <cassert>
#include <cstring>

#include "common/api.h"
#include "common/types/ku_string.h"
#include "common/vector/value_vector.h"
#include "utf8proc.h"
Expand All @@ -12,21 +13,8 @@ namespace function {

struct BaseLowerUpperFunction {

static inline void operation(common::ku_string_t& input, common::ku_string_t& result,
common::ValueVector& resultValueVector, bool isUpper) {
uint32_t resultLen = getResultLen((char*)input.getData(), input.len, isUpper);
result.len = resultLen;
if (resultLen <= common::ku_string_t::SHORT_STR_LENGTH) {
convertCase((char*)result.prefix, input.len, (char*)input.getData(), isUpper);
} else {
result.overflowPtr = reinterpret_cast<uint64_t>(
common::StringVector::getInMemOverflowBuffer(&resultValueVector)
->allocateSpace(result.len));
auto buffer = reinterpret_cast<char*>(result.overflowPtr);
convertCase(buffer, input.len, (char*)input.getData(), isUpper);
memcpy(result.prefix, buffer, common::ku_string_t::PREFIX_LENGTH);
}
}
KUZU_API static void operation(common::ku_string_t& input, common::ku_string_t& result,
common::ValueVector& resultValueVector, bool isUpper);

private:
static uint32_t getResultLen(char* inputStr, uint32_t inputLen, bool isUpper);
Expand Down
22 changes: 3 additions & 19 deletions src/include/function/string/functions/base_str_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,16 @@
#include <cassert>
#include <cstring>

#include "common/api.h"
#include "common/types/ku_string.h"

namespace kuzu {
namespace function {

struct BaseStrOperation {
public:
static inline void operation(common::ku_string_t& input, common::ku_string_t& result,
common::ValueVector& resultValueVector,
uint32_t (*strOperation)(char* data, uint32_t len)) {
if (input.len <= common::ku_string_t::SHORT_STR_LENGTH) {
memcpy(result.prefix, input.prefix, input.len);
result.len = strOperation((char*)result.prefix, input.len);
} else {
result.overflowPtr = reinterpret_cast<uint64_t>(
common::StringVector::getInMemOverflowBuffer(&resultValueVector)
->allocateSpace(input.len));
auto buffer = reinterpret_cast<char*>(result.overflowPtr);
memcpy(buffer, input.getData(), input.len);
result.len = strOperation(buffer, input.len);
memcpy(result.prefix, buffer,
result.len < common::ku_string_t::PREFIX_LENGTH ?
result.len :
common::ku_string_t::PREFIX_LENGTH);
}
}
KUZU_API static void operation(common::ku_string_t& input, common::ku_string_t& result,
common::ValueVector& resultValueVector, uint32_t (*strOperation)(char* data, uint32_t len));
};

} // namespace function
Expand Down
20 changes: 3 additions & 17 deletions src/include/function/string/functions/concat_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <cassert>
#include <cstring>

#include "common/api.h"
#include "common/types/ku_string.h"
#include "common/vector/value_vector.h"

Expand All @@ -15,23 +16,8 @@ struct Concat {
assert(false);
}

static void concat(const char* left, uint32_t leftLen, const char* right, uint32_t rightLen,
common::ku_string_t& result, common::ValueVector& resultValueVector) {
auto len = leftLen + rightLen;
if (len <= common::ku_string_t::SHORT_STR_LENGTH /* concat's result is short */) {
memcpy(result.prefix, left, leftLen);
memcpy(result.prefix + leftLen, right, rightLen);
} else {
result.overflowPtr = reinterpret_cast<uint64_t>(
common::StringVector::getInMemOverflowBuffer(&resultValueVector)
->allocateSpace(len));
auto buffer = reinterpret_cast<char*>(result.overflowPtr);
memcpy(buffer, left, leftLen);
memcpy(buffer + leftLen, right, rightLen);
memcpy(result.prefix, buffer, common::ku_string_t::PREFIX_LENGTH);
}
result.len = len;
}
KUZU_API static void concat(const char* left, uint32_t leftLen, const char* right,
uint32_t rightLen, common::ku_string_t& result, common::ValueVector& resultValueVector);
};

template<>
Expand Down
Loading
Loading