1//===--------------------------------------------------------------------===//
2// null_operators.cpp
3// Description: This file contains the implementation of the
4// IS NULL/NOT IS NULL operators
5//===--------------------------------------------------------------------===//
6
7#include "duckdb/common/exception.hpp"
8#include "duckdb/common/vector_operations/vector_operations.hpp"
9
10using namespace duckdb;
11using namespace std;
12
13template <bool INVERSE> void is_null_loop(Vector &input, Vector &result, idx_t count) {
14 assert(result.type == TypeId::BOOL);
15
16 if (input.vector_type == VectorType::CONSTANT_VECTOR) {
17 result.vector_type = VectorType::CONSTANT_VECTOR;
18 auto result_data = ConstantVector::GetData<bool>(result);
19 *result_data = INVERSE ? !ConstantVector::IsNull(input) : ConstantVector::IsNull(input);
20 } else {
21 VectorData data;
22 input.Orrify(count, data);
23
24 result.vector_type = VectorType::FLAT_VECTOR;
25 auto result_data = FlatVector::GetData<bool>(result);
26 auto &nullmask = *data.nullmask;
27 for (idx_t i = 0; i < count; i++) {
28 auto idx = data.sel->get_index(i);
29 result_data[i] = INVERSE ? !nullmask[idx] : nullmask[idx];
30 }
31 }
32}
33
34void VectorOperations::IsNotNull(Vector &input, Vector &result, idx_t count) {
35 is_null_loop<true>(input, result, count);
36}
37
38void VectorOperations::IsNull(Vector &input, Vector &result, idx_t count) {
39 is_null_loop<false>(input, result, count);
40}
41
42bool VectorOperations::HasNotNull(Vector &input, idx_t count) {
43 if (count == 0) {
44 return false;
45 }
46 if (input.vector_type == VectorType::CONSTANT_VECTOR) {
47 return !ConstantVector::IsNull(input);
48 } else {
49 VectorData data;
50 input.Orrify(count, data);
51
52 if (data.nullmask->none()) {
53 return true;
54 }
55 for (idx_t i = 0; i < count; i++) {
56 auto idx = data.sel->get_index(i);
57 if (!(*data.nullmask)[idx]) {
58 return true;
59 }
60 }
61 return false;
62 }
63}
64
65bool VectorOperations::HasNull(Vector &input, idx_t count) {
66 if (count == 0) {
67 return false;
68 }
69 if (input.vector_type == VectorType::CONSTANT_VECTOR) {
70 return ConstantVector::IsNull(input);
71 } else {
72 VectorData data;
73 input.Orrify(count, data);
74
75 if (data.nullmask->none()) {
76 return false;
77 }
78 for (idx_t i = 0; i < count; i++) {
79 auto idx = data.sel->get_index(i);
80 if ((*data.nullmask)[idx]) {
81 return true;
82 }
83 }
84 return false;
85 }
86}
87