Skip to content

Commit

Permalink
finish range function
Browse files Browse the repository at this point in the history
  • Loading branch information
AEsir777 committed Sep 20, 2023
1 parent 6943574 commit 53e605e
Show file tree
Hide file tree
Showing 10 changed files with 265 additions and 19 deletions.
6 changes: 6 additions & 0 deletions src/common/types/types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,12 @@ std::vector<LogicalTypeID> LogicalTypeUtils::getNumericalLogicalTypeIDs() {
LogicalTypeID::SERIAL};
}

std::vector<LogicalType> LogicalTypeUtils::getIntegerLogicalTypes() {
return std::vector<LogicalType>{LogicalType{LogicalTypeID::INT64},
LogicalType{LogicalTypeID::INT32}, LogicalType{LogicalTypeID::INT16},
LogicalType{LogicalTypeID::INT8}, LogicalType{LogicalTypeID::SERIAL}};
}

std::vector<LogicalType> LogicalTypeUtils::getAllValidLogicTypes() {
// TODO(Ziyi): Add FIX_LIST,STRUCT,MAP type to allValidTypeID when we support functions on
// FIXED_LIST,STRUCT,MAP.
Expand Down
1 change: 1 addition & 0 deletions src/function/built_in_vector_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ void BuiltInVectorFunctions::registerCastFunctions() {

void BuiltInVectorFunctions::registerListFunctions() {
vectorFunctions.insert({LIST_CREATION_FUNC_NAME, ListCreationVectorFunction::getDefinitions()});
vectorFunctions.insert({LIST_RANGE_FUNC_NAME, ListRangeVectorFunction::getDefinitions()});
vectorFunctions.insert({LIST_LEN_FUNC_NAME, ListLenVectorFunction::getDefinitions()});
vectorFunctions.insert({LIST_EXTRACT_FUNC_NAME, ListExtractVectorFunction::getDefinitions()});
vectorFunctions.insert({LIST_ELEMENT_FUNC_NAME, ListExtractVectorFunction::getDefinitions()});
Expand Down
28 changes: 28 additions & 0 deletions src/function/vector_list_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "function/list/functions/list_len_function.h"
#include "function/list/functions/list_position_function.h"
#include "function/list/functions/list_prepend_function.h"
#include "function/list/functions/list_range_function.h"
#include "function/list/functions/list_reverse_sort_function.h"
#include "function/list/functions/list_slice_function.h"
#include "function/list/functions/list_sort_function.h"
Expand Down Expand Up @@ -94,6 +95,33 @@ vector_function_definitions ListCreationVectorFunction::getDefinitions() {
return result;
}

std::unique_ptr<FunctionBindData> ListRangeVectorFunction::bindFunc(
const binder::expression_vector& arguments, kuzu::function::FunctionDefinition* definition) {
assert(arguments[0]->dataType == arguments[1]->dataType);
auto varListTypeInfo = std::make_unique<VarListTypeInfo>(
std::make_unique<LogicalType>(arguments[0]->dataType.getLogicalTypeID()));
auto resultType = LogicalType{LogicalTypeID::VAR_LIST, std::move(varListTypeInfo)};
return std::make_unique<FunctionBindData>(resultType);
}

vector_function_definitions ListRangeVectorFunction::getDefinitions() {
vector_function_definitions result;
for (auto type : LogicalTypeUtils::getIntegerLogicalTypes()) {
// start, end
result.push_back(std::make_unique<VectorFunctionDefinition>(LIST_RANGE_FUNC_NAME,
std::vector<LogicalTypeID>{type.getLogicalTypeID(), type.getLogicalTypeID()},
LogicalTypeID::VAR_LIST, getBinaryListExecFunc<Range, list_entry_t>(type, true),
nullptr, bindFunc, false));
// start, end, step
result.push_back(std::make_unique<VectorFunctionDefinition>(LIST_RANGE_FUNC_NAME,
std::vector<LogicalTypeID>{
type.getLogicalTypeID(), type.getLogicalTypeID(), type.getLogicalTypeID()},
LogicalTypeID::VAR_LIST, getTernaryListExecFunc<Range, list_entry_t>(type, true),
nullptr, bindFunc, false));
}
return result;
}

Check warning on line 123 in src/function/vector_list_functions.cpp

View check run for this annotation

Codecov / codecov/patch

src/function/vector_list_functions.cpp#L123

Added line #L123 was not covered by tests

vector_function_definitions ListLenVectorFunction::getDefinitions() {
vector_function_definitions result;
auto execFunc = UnaryExecFunction<list_entry_t, int64_t, ListLen>;
Expand Down
1 change: 1 addition & 0 deletions src/include/common/expression_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ const std::string CAST_TO_BLOB_FUNC_NAME = "BLOB";

// list
const std::string LIST_CREATION_FUNC_NAME = "LIST_CREATION";
const std::string LIST_RANGE_FUNC_NAME = "RANGE";
const std::string LIST_EXTRACT_FUNC_NAME = "LIST_EXTRACT";
const std::string LIST_ELEMENT_FUNC_NAME = "LIST_ELEMENT";
const std::string LIST_LEN_FUNC_NAME = "LEN";
Expand Down
1 change: 1 addition & 0 deletions src/include/common/types/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ class LogicalTypeUtils {
static bool isNested(const LogicalType& dataType);
static std::vector<LogicalType> getAllValidComparableLogicalTypes();
static std::vector<LogicalTypeID> getNumericalLogicalTypeIDs();
static std::vector<LogicalType> getIntegerLogicalTypes();
static std::vector<LogicalType> getAllValidLogicTypes();

private:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ class VectorArithmeticFunction : public VectorFunction {
throw common::RuntimeException(
"Invalid input data types(" +
common::LogicalTypeUtils::dataTypeToString(operandTypeID) +
") for getUnaryExecFunc.");
") for getBinaryExecFunc.");
}
}
};
Expand Down
46 changes: 46 additions & 0 deletions src/include/function/list/functions/list_range_function.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#pragma once

#include "common/types/ku_list.h"

namespace kuzu {
namespace function {

struct Range {
public:
// range function:
// - include end
// - when start = end: there is only one element in result varlist
// - when end - start are of opposite sign of step, the result will be empty
// - default step = 1
template<typename T>
static inline void operation(T& start, T& end, common::list_entry_t& result,
common::ValueVector& leftVector, common::ValueVector& rightVector,
common::ValueVector& resultVector) {
// step = 1
T step = 1;
operation(start, end, step, result, leftVector, resultVector);
}

template<typename T>
static inline void operation(T& start, T& end, T& step, common::list_entry_t& result,
common::ValueVector& inputVector, common::ValueVector& resultVector) {
if (step == 0) {
throw common::RuntimeException("Step of range cannot be 0.");
}

// start, start + step, start + 2step, ..., end
T number = start;
auto size = (end - start) * 1.0 / step;
size < 0 ? size = 0 : size = (int64_t)(size + 1);

result = common::ListVector::addList(&resultVector, size);
auto resultDataVector = common::ListVector::getDataVector(&resultVector);
for (auto i = 0u; i < size; i++) {
resultDataVector->setValue(result.offset + i, number);
number += step;
}
}
};

} // namespace function
} // namespace kuzu
59 changes: 59 additions & 0 deletions src/include/function/list/vector_list_functions.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,59 @@ struct VectorListFunction : public VectorFunction {
}
return execFunc;
}

template<typename OPERATION, typename RESULT_TYPE>
static scalar_exec_func getBinaryListExecFunc(common::LogicalType rightType, bool noListInput) {
scalar_exec_func execFunc;
switch (rightType.getPhysicalType()) {
case common::PhysicalTypeID::INT64: {
execFunc = BinaryExecListStructFunction<int64_t, int64_t, RESULT_TYPE, OPERATION>;
} break;
case common::PhysicalTypeID::INT32: {
execFunc = BinaryExecListStructFunction<int32_t, int32_t, RESULT_TYPE, OPERATION>;
} break;

Check warning on line 78 in src/include/function/list/vector_list_functions.h

View check run for this annotation

Codecov / codecov/patch

src/include/function/list/vector_list_functions.h#L77-L78

Added lines #L77 - L78 were not covered by tests
case common::PhysicalTypeID::INT16: {
execFunc = BinaryExecListStructFunction<int16_t, int16_t, RESULT_TYPE, OPERATION>;
} break;
case common::PhysicalTypeID::INT8: {
execFunc = BinaryExecListStructFunction<int8_t, int8_t, RESULT_TYPE, OPERATION>;
} break;
default: {
throw common::NotImplementedException{
"VectorListFunctions::getBinaryListOperationDefinition"};
}
}
return execFunc;
}

template<typename OPERATION, typename RESULT_TYPE>
static scalar_exec_func getTernaryListExecFunc(
common::LogicalType rightType, bool noListInput) {
scalar_exec_func execFunc;
switch (rightType.getPhysicalType()) {
case common::PhysicalTypeID::INT64: {
execFunc =
TernaryExecListStructFunction<int64_t, int64_t, int64_t, RESULT_TYPE, OPERATION>;
} break;
case common::PhysicalTypeID::INT32: {

Check warning on line 102 in src/include/function/list/vector_list_functions.h

View check run for this annotation

Codecov / codecov/patch

src/include/function/list/vector_list_functions.h#L101-L102

Added lines #L101 - L102 were not covered by tests
execFunc =
TernaryExecListStructFunction<int32_t, int32_t, int32_t, RESULT_TYPE, OPERATION>;
} break;
case common::PhysicalTypeID::INT16: {
execFunc =
TernaryExecListStructFunction<int16_t, int16_t, int16_t, RESULT_TYPE, OPERATION>;
} break;
case common::PhysicalTypeID::INT8: {
execFunc =
TernaryExecListStructFunction<int8_t, int8_t, int8_t, RESULT_TYPE, OPERATION>;
} break;
default: {
throw common::NotImplementedException{
"VectorListFunctions::getTernaryListOperationDefinition"};
}
}
return execFunc;
}
};

struct ListCreationVectorFunction : public VectorListFunction {
Expand All @@ -75,6 +128,12 @@ struct ListCreationVectorFunction : public VectorListFunction {
common::ValueVector& result);
};

struct ListRangeVectorFunction : public VectorListFunction {

Check warning on line 131 in src/include/function/list/vector_list_functions.h

View check run for this annotation

Codecov / codecov/patch

src/include/function/list/vector_list_functions.h#L131

Added line #L131 was not covered by tests
static vector_function_definitions getDefinitions();
static std::unique_ptr<FunctionBindData> bindFunc(
const binder::expression_vector& arguments, FunctionDefinition* definition);
};

struct ListLenVectorFunction : public VectorListFunction {
static vector_function_definitions getDefinitions();
};
Expand Down
22 changes: 4 additions & 18 deletions test/test_files/tck/match/match4.test
Original file line number Diff line number Diff line change
Expand Up @@ -59,31 +59,17 @@
# Matching longer variable length paths
-CASE Scenario4
-SKIP
-STATEMENT CREATE NODE TABLE A(ID SERIAL, var STRING, PRIMARY KEY(ID));
-STATEMENT CREATE NODE TABLE A(ID SERIAL, var INT64, PRIMARY KEY(ID));
---- ok
-STATEMENT CREATE REL TABLE T(FROM A TO A);
---- ok
# indexing on varlist causes segmentaion fault
-STATEMENT CREATE (a {var: 'start'}), (b {var: 'end'})
WITH *
UNWIND ['0', '1', '2'] AS i
CREATE (n {var: i})
WITH a, b, collect(n) AS nodeList
UNWIND [0, 1] AS i
WITH nodeList[i] AS n1, nodeList[i+1] AS n2
CREATE (n1)-[:T]->(n2);
---- ok
-STATEMENT WITH collect(n) AS nodeList
UNWIND [0, 1] AS i
WITH nodeList[i] AS n1, nodeList[i+1] AS n2
CREATE (n1)-[:T]->(n2);
---- ok
-STATEMENT CREATE (a {var: 'start'}), (b {var: 'end'})
-STATEMENT CREATE (a {var: -2}), (b {var: 0})
WITH *
UNWIND range(1, 20) AS i
CREATE (n {var: i})
WITH a, b, [a] + collect(n) + [b] AS nodeList
UNWIND range(0, size(nodeList) - 2, 1) AS i
WITH a, b, list_cat(list_cat([a], collect(n)), [b]) AS nodeList
UNWIND range(0, len(nodeList) - 2, 1) AS i
WITH nodeList[i] AS n1, nodeList[i+1] AS n2
CREATE (n1)-[:T]->(n2);
---- ok
Expand Down
118 changes: 118 additions & 0 deletions test/test_files/tinysnb/function/range.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
-GROUP TinySnbReadTest
-DATASET CSV tck

--

-CASE Range
-STATEMENT CREATE NODE TABLE A(ID SERIAL, AGE INT64, NAME STRING, NUMBER INT32, PRIMARY KEY(ID));
---- ok
-STATEMENT CREATE REL TABLE T(FROM A TO A);
---- ok
-STATEMENT CREATE ({AGE: 1, NAME: "Alice", NUMBER: 1})-[]-({AGE: 2, NAME: "Alice", NUMBER: 2});
---- ok
-STATEMENT CREATE ({AGE: 0, NAME:"Alice", NUMBER:3});
---- ok
-STATEMENT MATCH (a) RETURN range(a.AGE, 3);
---- 3
[1,2,3]
[2,3]
[0,1,2,3]
-STATEMENT MATCH(a) RETURN range(1, a.AGE, 1);
---- 3
[1]
[1,2]
[]
-STATEMENT MATCH(a) RETURN range(a.ID, a.ID, 1);
---- 3
[0]
[1]
[2]
-STATEMENT MATCH (a)--() RETURN range(a.AGE, a.AGE, a.AGE);
---- 2
[1]
[2]
-STATEMENT MATCH (a)--() RETURN range(1, 5, a.AGE);
---- 2
[1,2,3,4,5]
[1,3,5]
-STATEMENT MATCH (a) RETURN range(a.NUMBER, a.AGE, -1);
---- 3
[1]
[2]
[3,2,1,0]
-STATEMENT MATCH (a) RETURN range(-4, a.AGE, a.NUMBER);
---- 3
[-4,-3,-2,-1,0,1]
[-4,-2,0,2]
[-4,-1]
-STATEMENT MATCH (b)--() RETURN range(b.AGE, 4, b.NUMBER);
---- 2
[1,2,3,4]
[2,4]
-STATEMENT MATCH (a) RETURN range(a.NUMBER, 5, a.AGE);
---- error
Runtime exception: Step of range cannot be 0.
-STATEMENT MATCH (a) RETURN range(a.NAME, 4, 1);
---- error
Binder exception: Cannot match a built-in function for given function RANGE(STRING,INT64,INT64). Supported inputs are
(INT64,INT64) -> VAR_LIST
(INT64,INT64,INT64) -> VAR_LIST
(INT32,INT32) -> VAR_LIST
(INT32,INT32,INT32) -> VAR_LIST
(INT16,INT16) -> VAR_LIST
(INT16,INT16,INT16) -> VAR_LIST
(INT8,INT8) -> VAR_LIST
(INT8,INT8,INT8) -> VAR_LIST
(SERIAL,SERIAL) -> VAR_LIST
(SERIAL,SERIAL,SERIAL) -> VAR_LIST
-STATEMENT RETURN range(4, 3);
---- 1
[]
-STATEMENT RETURN range(0, 0);
---- 1
[0]
-STATEMENT RETURN range(1, 5);
---- 1
[1,2,3,4,5]
-STATEMENT RETURN range(4, 4, 2);
---- 1
[4]
-STATEMENT RETURN range(4, 4, -2);
---- 1
[4]
-STATEMENT RETURN range(5, 1, -1);
---- 1
[5,4,3,2,1]
-STATEMENT RETURN range(5, 1, -2);
---- 1
[5,3,1]
-STATEMENT RETURN range(5, 1, -3);
---- 1
[5,2]
-STATEMENT RETURN range(6, 2, 2);
---- 1
[]
-STATEMENT RETURN range(3, 6, -5);
---- 1
[]
-STATEMENT RETURN range(3, 6, -1);
---- 1
[]
-STATEMENT RETURN range(0, -1, 9223372036854775807);
---- 1
[]
-STATEMENT RETURN range(TO_INT32(3), 8, 2);
---- 1
[3,5,7]
-STATEMENT RETURN range(TO_INT8(0), TO_INT16(-9), TO_INT8(-2));
---- 1
[0,-2,-4,-6,-8]
-STATEMENT RETURN range(TO_INT16(5), TO_INT16(6), TO_INT16(1));
---- 1
[5,6]
-STATEMENT RETURN range(TO_INT32(5), 25, TO_INT32(10));
---- 1
[5,15,25]
-STATEMENT RETURN range(3, 4, 0);
---- error
Runtime exception: Step of range cannot be 0.

0 comments on commit 53e605e

Please sign in to comment.