Skip to content
This repository was archived by the owner on Oct 10, 2025. It is now read-only.

Commit 0071140

Browse files
committed
Add test for all required list function except for list_zip, modify list_insersect and list_where to make them act similar to those in duckdb
1 parent 375bc44 commit 0071140

File tree

3 files changed

+100
-10
lines changed

3 files changed

+100
-10
lines changed

src/function/list/list_select_function.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,23 @@ struct ListSelect {
2424
auto rightDataVector = common::ListVector::getDataVector(&rightVector);
2525
auto rightPos = right.offset;
2626
for (auto i=0u; i < right.size; i++) {
27-
auto leftIndexPos=rightDataVector->getValue<long long>(rightPos+i);
27+
auto leftIndexPos=rightDataVector->getValue<long long>(rightPos+i)-1;
2828
if ((leftIndexPos<0)||(leftIndexPos>=left.size)) {
29-
throw BinderException(stringFormat("LIST_SELECTION encounters index out of range : {} , min: {}, max: {}", leftIndexPos, 0, left.size-1));
29+
// append null to result if out of index
30+
resultDataVector->setNull(resultPos++, true);
31+
} else {
32+
resultDataVector->copyFromVectorData(resultPos++, leftDataVector, leftIndexPos);
3033
}
31-
resultDataVector->copyFromVectorData(resultPos++, leftDataVector, leftIndexPos);
3234
}
3335
}
3436
};
3537
static std::unique_ptr<FunctionBindData> bindFunc(const ScalarBindFuncInput& input) {
3638
std::vector<LogicalType> types;
3739
types.push_back(input.arguments[0]->getDataType().copy());
3840
types.push_back(input.arguments[1]->getDataType().copy());
41+
if (types[0].getPhysicalType()!=PhysicalTypeID::LIST) {
42+
throw BinderException("LIST_SELECT expecting argument type: LIST of ANY, LIST of INT");
43+
}
3944
if (types[1].getPhysicalType()!=PhysicalTypeID::LIST) {
4045
throw BinderException(ExceptionMessage::listFunctionIncompatibleChildrenType(
4146
ListIntersectFunction::name, types[0].toString(), types[1].toString()));

src/function/list/list_where_function.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,34 @@ struct ListWhere {
1717
static void operation(common::list_entry_t& left, common::list_entry_t& right,
1818
common::list_entry_t& result, common::ValueVector& leftVector,
1919
common::ValueVector& rightVector, common::ValueVector& resultVector) {
20-
if (right.size!=left.size) {
21-
throw BinderException(stringFormat("LIST_WHERE expecting lists of same size, receiving size {} and size {}", left.size, left.size));
22-
}
2320
auto leftDataVector = common::ListVector::getDataVector(&leftVector);
2421
auto leftPos = left.offset;
2522
auto rightDataVector = common::ListVector::getDataVector(&rightVector);
2623
auto rightPos = right.offset;
2724
list_size_t resultSize=0;
2825
std::vector<bool> maskListBools;
2926
for (auto i=0u; i < right.size; i++) {
27+
if (rightDataVector->isNull(rightPos+i)) {
28+
throw BinderException("NULLs are not allowed as list elements in the second input parameter.");
29+
}
3030
auto maskBool=rightDataVector->getValue<bool>(rightPos+i);
31-
maskListBools.push_back(maskBool);
32-
if (maskBool) {
31+
if (maskBool){
3332
resultSize++;
3433
}
34+
maskListBools.push_back(maskBool);
3535
}
3636
result = common::ListVector::addList(&resultVector, resultSize);
3737
auto resultDataVector = common::ListVector::getDataVector(&resultVector);
3838
auto resultPos = result.offset;
3939
for (auto i=0u; i < right.size; i++) {
4040
auto maskBool=maskListBools.at(i);
4141
if (maskBool) {
42-
resultDataVector->copyFromVectorData(resultPos++, leftDataVector, leftPos+i);
42+
if (leftPos+i<left.size) {
43+
resultDataVector->copyFromVectorData(resultPos++, leftDataVector, leftPos+i);
44+
} else {
45+
resultDataVector->setNull(resultPos++,true);
46+
}
47+
4348
}
4449
}
4550
}
@@ -48,14 +53,17 @@ static std::unique_ptr<FunctionBindData> bindFunc(const ScalarBindFuncInput& inp
4853
std::vector<LogicalType> types;
4954
types.push_back(input.arguments[0]->getDataType().copy());
5055
types.push_back(input.arguments[1]->getDataType().copy());
56+
if (types[0].getPhysicalType()!=PhysicalTypeID::LIST) {
57+
throw BinderException("LIST_WHERE expecting argument type: LIST of ANY, LIST of BOOL");
58+
}
5159
if (types[1].getPhysicalType()!=PhysicalTypeID::LIST) {
5260
throw BinderException(ExceptionMessage::listFunctionIncompatibleChildrenType(
5361
ListIntersectFunction::name, types[0].toString(), types[1].toString()));
5462
} else {
5563
auto thisExtraTypeInfo=types[1].getExtraTypeInfo();
5664
auto thisListTypeInfo=ku_dynamic_cast<const ListTypeInfo*>(thisExtraTypeInfo);
5765
if (thisListTypeInfo->getChildType().getPhysicalType()!=PhysicalTypeID::BOOL) {
58-
throw BinderException("LIST_SELECT expecting argument type: LIST of ANY, LIST of BOOL");
66+
throw BinderException("LIST_WHERE expecting argument type: LIST of ANY, LIST of BOOL");
5967
}
6068
}
6169
return std::make_unique<FunctionBindData>(std::move(types), types[0].copy());

test/test_files/function/list.test

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2306,3 +2306,80 @@ False
23062306
---- 1
23072307
[False]
23082308

2309+
-CASE ListSelect
2310+
-STATEMENT RETURN list_select([1,2,3,4,5],[1,2,3])
2311+
---- 1
2312+
[1,2,3]
2313+
2314+
-STATEMENT RETURN list_select(['s','t','d','u','e','f','~'],[2,2,3,4,5])
2315+
---- 1
2316+
[t,t,d,u,e]
2317+
2318+
-STATEMENT RETURN list_select([1,2,3,4,5],[1.0,2.0,3.0,5.0])
2319+
---- error
2320+
Binder exception: LIST_SELECT expecting argument type: LIST of ANY, LIST of INT
2321+
2322+
-STATEMENT RETURN list_select([[1],[2,3],[2,3,4],[1,2,3],[1]],[1,2,3,4,2,3,2])
2323+
---- 1
2324+
[[1],[2,3],[2,3,4],[1,2,3],[2,3],[2,3,4],[2,3]]
2325+
2326+
-STATEMENT Return list_select([1,2,3,4,5],[0,1,2,3,4,5,6])
2327+
---- 1
2328+
[,1,2,3,4,5,]
2329+
2330+
-STATEMENT Return list_select([1,2,3,4,5],[null])
2331+
---- 1
2332+
[]
2333+
2334+
-STATEMENT Return list_select([1,2,3,4,5],null)
2335+
---- error
2336+
Binder exception: Cannot bind LIST_INTERSECT with parameter type INT64[] and ANY.
2337+
2338+
-STATEMENT Return list_select(null,[0,1,2,3,4,5])
2339+
---- error
2340+
Binder exception: LIST_SELECT expecting argument type: LIST of ANY, LIST of INT
2341+
2342+
-STATEMENT RETURN list_select([{q:1, p:2},{q:2, p:3},{a: 3, q: 4}],[1,2,2,1])
2343+
---- 1
2344+
[{a: 1, q: 2},{a: 2, q: 3},{a: 2, q: 3},{a: 1, q: 2}]
2345+
2346+
-STATEMENT RETURN list_select([1,2,3,4,5],[null, 2, null, 4, 5])
2347+
---- 1
2348+
[,2,,4,5]
2349+
2350+
-CASE ListWhere
2351+
-STATEMENT RETURN list_where([1,2,3,4,5],[true, false, true, true, false])
2352+
---- 1
2353+
[1,3,4]
2354+
2355+
-STATEMENT RETURN list_where([{a:2, b:3},{a:3, b:5},{a:4, c:1},{a:21, u:33}],[true, false, true, true, false])
2356+
---- 1
2357+
[{a: 2, u: 3},{a: 4, u: 1},{a: 21, u: 33}]
2358+
2359+
-STATEMENT RETURN list_where([1,2,3,4,null],[true, false, true, true, true])
2360+
---- 1
2361+
[1,3,4,]
2362+
2363+
-STATEMENT RETURN list_where([1,2,3,4],[true, false, true])
2364+
---- 1
2365+
[1,3]
2366+
2367+
-STATEMENT RETURN list_where([1,2,3,4],[true, false, true,false, true, true])
2368+
---- 1
2369+
[1,3,,]
2370+
2371+
-STATEMENT RETURN list_where(['a','b','c','6','r'],[false, false, true,false, true])
2372+
---- 1
2373+
[c,r]
2374+
2375+
-STATEMENT RETURN list_where(null,[false, false, true,false, true])
2376+
---- error
2377+
Binder exception: LIST_WHERE expecting argument type: LIST of ANY, LIST of BOOL
2378+
2379+
-STATEMENT RETURN list_where([1,2,3,4],null)
2380+
---- error
2381+
Binder exception: Cannot bind LIST_INTERSECT with parameter type INT64[] and ANY.
2382+
2383+
-STATEMENT RETURN list_where([1,2,3,4],[true, false, null, true])
2384+
---- error
2385+
Binder exception: NULLs are not allowed as list elements in the second input parameter.

0 commit comments

Comments
 (0)