in velox/functions/prestosql/ArrayPosition.cpp [172:284]
void applyTypedWithInstance(
const SelectivityVector& rows,
DecodedVector& arrayDecoded,
const DecodedVector& elementsDecoded,
const DecodedVector& searchDecoded,
const DecodedVector& instanceDecoded,
FlatVector<int64_t>& flatResult) {
using T = typename TypeTraits<kind>::NativeType;
auto baseArray = arrayDecoded.base()->as<ArrayVector>();
auto rawSizes = baseArray->rawSizes();
auto rawOffsets = baseArray->rawOffsets();
auto indices = arrayDecoded.indices();
int startIndex;
int endIndex;
int step;
if (elementsDecoded.isIdentityMapping() && !elementsDecoded.mayHaveNulls() &&
searchDecoded.isConstantMapping() &&
instanceDecoded.isConstantMapping()) {
auto instance = instanceDecoded.valueAt<int64_t>(0);
VELOX_USER_CHECK_NE(
instance,
0,
"array_position cannot take a 0-valued instance argument.");
// Fast path for array vector of boolean.
if constexpr (std::is_same_v<bool, T>) {
auto rawElements = elementsDecoded.values<uint64_t>();
auto search = bits::isBitSet(searchDecoded.values<uint64_t>(), 0);
rows.applyToSelected([&](auto row) {
auto offset = rawOffsets[indices[row]];
getLoopBoundary(
rawSizes, indices, row, instance, startIndex, endIndex, step);
int i;
for (i = startIndex; i != endIndex; i += step) {
if (bits::isBitSet(rawElements, offset + i) == search) {
--instance;
if (instance == 0) {
flatResult.set(row, i + 1);
break;
}
}
}
if (i == endIndex) {
flatResult.set(row, 0);
}
});
return;
}
// Fast path for array vector of types other than boolean.
auto rawElements = elementsDecoded.values<T>();
auto search = searchDecoded.valueAt<T>(0);
rows.applyToSelected([&](auto row) {
auto offset = rawOffsets[indices[row]];
getLoopBoundary(
rawSizes, indices, row, instance, startIndex, endIndex, step);
int i;
for (i = startIndex; i != endIndex; i += step) {
if (rawElements[offset + i] == search) {
--instance;
if (instance == 0) {
flatResult.set(row, i + 1);
break;
}
}
}
if (i == endIndex) {
flatResult.set(row, 0);
}
});
return;
}
// Regular path where no assumption is made about the encodings of
// searchDecoded and elementsDecoded.
rows.applyToSelected([&](auto row) {
auto offset = rawOffsets[indices[row]];
auto search = searchDecoded.valueAt<T>(row);
auto instance = instanceDecoded.valueAt<int64_t>(row);
VELOX_USER_CHECK_NE(
instance,
0,
"array_position cannot take a 0-valued instance argument.");
getLoopBoundary(
rawSizes, indices, row, instance, startIndex, endIndex, step);
int i;
for (i = startIndex; i != endIndex; i += step) {
if (!elementsDecoded.isNullAt(offset + i) &&
elementsDecoded.valueAt<T>(offset + i) == search) {
--instance;
if (instance == 0) {
flatResult.set(row, i + 1);
break;
}
}
}
if (i == endIndex) {
flatResult.set(row, 0);
}
});
}