duckdb 0.4.1-dev104.0 → 0.4.1-dev108.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/duckdb.cpp +344 -318
- package/src/duckdb.hpp +581 -563
- package/src/parquet-amalgamation.cpp +36759 -36759
package/src/duckdb.hpp
CHANGED
|
@@ -11,8 +11,8 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
|
|
11
11
|
#pragma once
|
|
12
12
|
#define DUCKDB_AMALGAMATION 1
|
|
13
13
|
#define DUCKDB_AMALGAMATION_EXTENDED 1
|
|
14
|
-
#define DUCKDB_SOURCE_ID "
|
|
15
|
-
#define DUCKDB_VERSION "v0.4.1-
|
|
14
|
+
#define DUCKDB_SOURCE_ID "d3b4eba6a"
|
|
15
|
+
#define DUCKDB_VERSION "v0.4.1-dev108"
|
|
16
16
|
//===----------------------------------------------------------------------===//
|
|
17
17
|
// DuckDB
|
|
18
18
|
//
|
|
@@ -7553,362 +7553,6 @@ public:
|
|
|
7553
7553
|
|
|
7554
7554
|
|
|
7555
7555
|
|
|
7556
|
-
//===----------------------------------------------------------------------===//
|
|
7557
|
-
// DuckDB
|
|
7558
|
-
//
|
|
7559
|
-
// duckdb/common/vector_operations/aggregate_executor.hpp
|
|
7560
|
-
//
|
|
7561
|
-
//
|
|
7562
|
-
//===----------------------------------------------------------------------===//
|
|
7563
|
-
|
|
7564
|
-
|
|
7565
|
-
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
|
|
7569
|
-
|
|
7570
|
-
|
|
7571
|
-
namespace duckdb {
|
|
7572
|
-
struct FunctionData;
|
|
7573
|
-
typedef std::pair<idx_t, idx_t> FrameBounds;
|
|
7574
|
-
|
|
7575
|
-
class AggregateExecutor {
|
|
7576
|
-
private:
|
|
7577
|
-
template <class STATE_TYPE, class OP>
|
|
7578
|
-
static inline void NullaryFlatLoop(STATE_TYPE **__restrict states, FunctionData *bind_data, idx_t count) {
|
|
7579
|
-
for (idx_t i = 0; i < count; i++) {
|
|
7580
|
-
OP::template Operation<STATE_TYPE, OP>(states[i], bind_data, i);
|
|
7581
|
-
}
|
|
7582
|
-
}
|
|
7583
|
-
|
|
7584
|
-
template <class STATE_TYPE, class OP>
|
|
7585
|
-
static inline void NullaryScatterLoop(STATE_TYPE **__restrict states, FunctionData *bind_data,
|
|
7586
|
-
const SelectionVector &ssel, idx_t count) {
|
|
7587
|
-
|
|
7588
|
-
for (idx_t i = 0; i < count; i++) {
|
|
7589
|
-
auto sidx = ssel.get_index(i);
|
|
7590
|
-
OP::template Operation<STATE_TYPE, OP>(states[sidx], bind_data, sidx);
|
|
7591
|
-
}
|
|
7592
|
-
}
|
|
7593
|
-
|
|
7594
|
-
template <class STATE_TYPE, class INPUT_TYPE, class OP>
|
|
7595
|
-
static inline void UnaryFlatLoop(INPUT_TYPE *__restrict idata, FunctionData *bind_data,
|
|
7596
|
-
STATE_TYPE **__restrict states, ValidityMask &mask, idx_t count) {
|
|
7597
|
-
if (!mask.AllValid()) {
|
|
7598
|
-
idx_t base_idx = 0;
|
|
7599
|
-
auto entry_count = ValidityMask::EntryCount(count);
|
|
7600
|
-
for (idx_t entry_idx = 0; entry_idx < entry_count; entry_idx++) {
|
|
7601
|
-
auto validity_entry = mask.GetValidityEntry(entry_idx);
|
|
7602
|
-
idx_t next = MinValue<idx_t>(base_idx + ValidityMask::BITS_PER_VALUE, count);
|
|
7603
|
-
if (!OP::IgnoreNull() || ValidityMask::AllValid(validity_entry)) {
|
|
7604
|
-
// all valid: perform operation
|
|
7605
|
-
for (; base_idx < next; base_idx++) {
|
|
7606
|
-
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[base_idx], bind_data, idata, mask,
|
|
7607
|
-
base_idx);
|
|
7608
|
-
}
|
|
7609
|
-
} else if (ValidityMask::NoneValid(validity_entry)) {
|
|
7610
|
-
// nothing valid: skip all
|
|
7611
|
-
base_idx = next;
|
|
7612
|
-
continue;
|
|
7613
|
-
} else {
|
|
7614
|
-
// partially valid: need to check individual elements for validity
|
|
7615
|
-
idx_t start = base_idx;
|
|
7616
|
-
for (; base_idx < next; base_idx++) {
|
|
7617
|
-
if (ValidityMask::RowIsValid(validity_entry, base_idx - start)) {
|
|
7618
|
-
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[base_idx], bind_data, idata, mask,
|
|
7619
|
-
base_idx);
|
|
7620
|
-
}
|
|
7621
|
-
}
|
|
7622
|
-
}
|
|
7623
|
-
}
|
|
7624
|
-
} else {
|
|
7625
|
-
for (idx_t i = 0; i < count; i++) {
|
|
7626
|
-
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[i], bind_data, idata, mask, i);
|
|
7627
|
-
}
|
|
7628
|
-
}
|
|
7629
|
-
}
|
|
7630
|
-
|
|
7631
|
-
template <class STATE_TYPE, class INPUT_TYPE, class OP>
|
|
7632
|
-
static inline void UnaryScatterLoop(INPUT_TYPE *__restrict idata, FunctionData *bind_data,
|
|
7633
|
-
STATE_TYPE **__restrict states, const SelectionVector &isel,
|
|
7634
|
-
const SelectionVector &ssel, ValidityMask &mask, idx_t count) {
|
|
7635
|
-
if (OP::IgnoreNull() && !mask.AllValid()) {
|
|
7636
|
-
// potential NULL values and NULL values are ignored
|
|
7637
|
-
for (idx_t i = 0; i < count; i++) {
|
|
7638
|
-
auto idx = isel.get_index(i);
|
|
7639
|
-
auto sidx = ssel.get_index(i);
|
|
7640
|
-
if (mask.RowIsValid(idx)) {
|
|
7641
|
-
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[sidx], bind_data, idata, mask, idx);
|
|
7642
|
-
}
|
|
7643
|
-
}
|
|
7644
|
-
} else {
|
|
7645
|
-
// quick path: no NULL values or NULL values are not ignored
|
|
7646
|
-
for (idx_t i = 0; i < count; i++) {
|
|
7647
|
-
auto idx = isel.get_index(i);
|
|
7648
|
-
auto sidx = ssel.get_index(i);
|
|
7649
|
-
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[sidx], bind_data, idata, mask, idx);
|
|
7650
|
-
}
|
|
7651
|
-
}
|
|
7652
|
-
}
|
|
7653
|
-
|
|
7654
|
-
template <class STATE_TYPE, class INPUT_TYPE, class OP>
|
|
7655
|
-
static inline void UnaryFlatUpdateLoop(INPUT_TYPE *__restrict idata, FunctionData *bind_data,
|
|
7656
|
-
STATE_TYPE *__restrict state, idx_t count, ValidityMask &mask) {
|
|
7657
|
-
idx_t base_idx = 0;
|
|
7658
|
-
auto entry_count = ValidityMask::EntryCount(count);
|
|
7659
|
-
for (idx_t entry_idx = 0; entry_idx < entry_count; entry_idx++) {
|
|
7660
|
-
auto validity_entry = mask.GetValidityEntry(entry_idx);
|
|
7661
|
-
idx_t next = MinValue<idx_t>(base_idx + ValidityMask::BITS_PER_VALUE, count);
|
|
7662
|
-
if (!OP::IgnoreNull() || ValidityMask::AllValid(validity_entry)) {
|
|
7663
|
-
// all valid: perform operation
|
|
7664
|
-
for (; base_idx < next; base_idx++) {
|
|
7665
|
-
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(state, bind_data, idata, mask, base_idx);
|
|
7666
|
-
}
|
|
7667
|
-
} else if (ValidityMask::NoneValid(validity_entry)) {
|
|
7668
|
-
// nothing valid: skip all
|
|
7669
|
-
base_idx = next;
|
|
7670
|
-
continue;
|
|
7671
|
-
} else {
|
|
7672
|
-
// partially valid: need to check individual elements for validity
|
|
7673
|
-
idx_t start = base_idx;
|
|
7674
|
-
for (; base_idx < next; base_idx++) {
|
|
7675
|
-
if (ValidityMask::RowIsValid(validity_entry, base_idx - start)) {
|
|
7676
|
-
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(state, bind_data, idata, mask, base_idx);
|
|
7677
|
-
}
|
|
7678
|
-
}
|
|
7679
|
-
}
|
|
7680
|
-
}
|
|
7681
|
-
}
|
|
7682
|
-
|
|
7683
|
-
template <class STATE_TYPE, class INPUT_TYPE, class OP>
|
|
7684
|
-
static inline void UnaryUpdateLoop(INPUT_TYPE *__restrict idata, FunctionData *bind_data,
|
|
7685
|
-
STATE_TYPE *__restrict state, idx_t count, ValidityMask &mask,
|
|
7686
|
-
const SelectionVector &__restrict sel_vector) {
|
|
7687
|
-
if (OP::IgnoreNull() && !mask.AllValid()) {
|
|
7688
|
-
// potential NULL values and NULL values are ignored
|
|
7689
|
-
for (idx_t i = 0; i < count; i++) {
|
|
7690
|
-
auto idx = sel_vector.get_index(i);
|
|
7691
|
-
if (mask.RowIsValid(idx)) {
|
|
7692
|
-
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(state, bind_data, idata, mask, idx);
|
|
7693
|
-
}
|
|
7694
|
-
}
|
|
7695
|
-
} else {
|
|
7696
|
-
// quick path: no NULL values or NULL values are not ignored
|
|
7697
|
-
for (idx_t i = 0; i < count; i++) {
|
|
7698
|
-
auto idx = sel_vector.get_index(i);
|
|
7699
|
-
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(state, bind_data, idata, mask, idx);
|
|
7700
|
-
}
|
|
7701
|
-
}
|
|
7702
|
-
}
|
|
7703
|
-
|
|
7704
|
-
template <class STATE_TYPE, class A_TYPE, class B_TYPE, class OP>
|
|
7705
|
-
static inline void BinaryScatterLoop(A_TYPE *__restrict adata, FunctionData *bind_data, B_TYPE *__restrict bdata,
|
|
7706
|
-
STATE_TYPE **__restrict states, idx_t count, const SelectionVector &asel,
|
|
7707
|
-
const SelectionVector &bsel, const SelectionVector &ssel,
|
|
7708
|
-
ValidityMask &avalidity, ValidityMask &bvalidity) {
|
|
7709
|
-
if (OP::IgnoreNull() && (!avalidity.AllValid() || !bvalidity.AllValid())) {
|
|
7710
|
-
// potential NULL values and NULL values are ignored
|
|
7711
|
-
for (idx_t i = 0; i < count; i++) {
|
|
7712
|
-
auto aidx = asel.get_index(i);
|
|
7713
|
-
auto bidx = bsel.get_index(i);
|
|
7714
|
-
auto sidx = ssel.get_index(i);
|
|
7715
|
-
if (avalidity.RowIsValid(aidx) && bvalidity.RowIsValid(bidx)) {
|
|
7716
|
-
OP::template Operation<A_TYPE, B_TYPE, STATE_TYPE, OP>(states[sidx], bind_data, adata, bdata,
|
|
7717
|
-
avalidity, bvalidity, aidx, bidx);
|
|
7718
|
-
}
|
|
7719
|
-
}
|
|
7720
|
-
} else {
|
|
7721
|
-
// quick path: no NULL values or NULL values are not ignored
|
|
7722
|
-
for (idx_t i = 0; i < count; i++) {
|
|
7723
|
-
auto aidx = asel.get_index(i);
|
|
7724
|
-
auto bidx = bsel.get_index(i);
|
|
7725
|
-
auto sidx = ssel.get_index(i);
|
|
7726
|
-
OP::template Operation<A_TYPE, B_TYPE, STATE_TYPE, OP>(states[sidx], bind_data, adata, bdata, avalidity,
|
|
7727
|
-
bvalidity, aidx, bidx);
|
|
7728
|
-
}
|
|
7729
|
-
}
|
|
7730
|
-
}
|
|
7731
|
-
|
|
7732
|
-
template <class STATE_TYPE, class A_TYPE, class B_TYPE, class OP>
|
|
7733
|
-
static inline void BinaryUpdateLoop(A_TYPE *__restrict adata, FunctionData *bind_data, B_TYPE *__restrict bdata,
|
|
7734
|
-
STATE_TYPE *__restrict state, idx_t count, const SelectionVector &asel,
|
|
7735
|
-
const SelectionVector &bsel, ValidityMask &avalidity, ValidityMask &bvalidity) {
|
|
7736
|
-
if (OP::IgnoreNull() && (!avalidity.AllValid() || !bvalidity.AllValid())) {
|
|
7737
|
-
// potential NULL values and NULL values are ignored
|
|
7738
|
-
for (idx_t i = 0; i < count; i++) {
|
|
7739
|
-
auto aidx = asel.get_index(i);
|
|
7740
|
-
auto bidx = bsel.get_index(i);
|
|
7741
|
-
if (avalidity.RowIsValid(aidx) && bvalidity.RowIsValid(bidx)) {
|
|
7742
|
-
OP::template Operation<A_TYPE, B_TYPE, STATE_TYPE, OP>(state, bind_data, adata, bdata, avalidity,
|
|
7743
|
-
bvalidity, aidx, bidx);
|
|
7744
|
-
}
|
|
7745
|
-
}
|
|
7746
|
-
} else {
|
|
7747
|
-
// quick path: no NULL values or NULL values are not ignored
|
|
7748
|
-
for (idx_t i = 0; i < count; i++) {
|
|
7749
|
-
auto aidx = asel.get_index(i);
|
|
7750
|
-
auto bidx = bsel.get_index(i);
|
|
7751
|
-
OP::template Operation<A_TYPE, B_TYPE, STATE_TYPE, OP>(state, bind_data, adata, bdata, avalidity,
|
|
7752
|
-
bvalidity, aidx, bidx);
|
|
7753
|
-
}
|
|
7754
|
-
}
|
|
7755
|
-
}
|
|
7756
|
-
|
|
7757
|
-
public:
|
|
7758
|
-
template <class STATE_TYPE, class OP>
|
|
7759
|
-
static void NullaryScatter(Vector &states, FunctionData *bind_data, idx_t count) {
|
|
7760
|
-
if (states.GetVectorType() == VectorType::CONSTANT_VECTOR) {
|
|
7761
|
-
auto sdata = ConstantVector::GetData<STATE_TYPE *>(states);
|
|
7762
|
-
OP::template ConstantOperation<STATE_TYPE, OP>(*sdata, bind_data, count);
|
|
7763
|
-
} else if (states.GetVectorType() == VectorType::FLAT_VECTOR) {
|
|
7764
|
-
auto sdata = FlatVector::GetData<STATE_TYPE *>(states);
|
|
7765
|
-
NullaryFlatLoop<STATE_TYPE, OP>(sdata, bind_data, count);
|
|
7766
|
-
} else {
|
|
7767
|
-
VectorData sdata;
|
|
7768
|
-
states.Orrify(count, sdata);
|
|
7769
|
-
NullaryScatterLoop<STATE_TYPE, OP>((STATE_TYPE **)sdata.data, bind_data, *sdata.sel, count);
|
|
7770
|
-
}
|
|
7771
|
-
}
|
|
7772
|
-
|
|
7773
|
-
template <class STATE_TYPE, class OP>
|
|
7774
|
-
static void NullaryUpdate(data_ptr_t state, FunctionData *bind_data, idx_t count) {
|
|
7775
|
-
OP::template ConstantOperation<STATE_TYPE, OP>((STATE_TYPE *)state, bind_data, count);
|
|
7776
|
-
}
|
|
7777
|
-
|
|
7778
|
-
template <class STATE_TYPE, class INPUT_TYPE, class OP>
|
|
7779
|
-
static void UnaryScatter(Vector &input, Vector &states, FunctionData *bind_data, idx_t count) {
|
|
7780
|
-
if (input.GetVectorType() == VectorType::CONSTANT_VECTOR &&
|
|
7781
|
-
states.GetVectorType() == VectorType::CONSTANT_VECTOR) {
|
|
7782
|
-
if (OP::IgnoreNull() && ConstantVector::IsNull(input)) {
|
|
7783
|
-
// constant NULL input in function that ignores NULL values
|
|
7784
|
-
return;
|
|
7785
|
-
}
|
|
7786
|
-
// regular constant: get first state
|
|
7787
|
-
auto idata = ConstantVector::GetData<INPUT_TYPE>(input);
|
|
7788
|
-
auto sdata = ConstantVector::GetData<STATE_TYPE *>(states);
|
|
7789
|
-
OP::template ConstantOperation<INPUT_TYPE, STATE_TYPE, OP>(*sdata, bind_data, idata,
|
|
7790
|
-
ConstantVector::Validity(input), count);
|
|
7791
|
-
} else if (input.GetVectorType() == VectorType::FLAT_VECTOR &&
|
|
7792
|
-
states.GetVectorType() == VectorType::FLAT_VECTOR) {
|
|
7793
|
-
auto idata = FlatVector::GetData<INPUT_TYPE>(input);
|
|
7794
|
-
auto sdata = FlatVector::GetData<STATE_TYPE *>(states);
|
|
7795
|
-
UnaryFlatLoop<STATE_TYPE, INPUT_TYPE, OP>(idata, bind_data, sdata, FlatVector::Validity(input), count);
|
|
7796
|
-
} else {
|
|
7797
|
-
VectorData idata, sdata;
|
|
7798
|
-
input.Orrify(count, idata);
|
|
7799
|
-
states.Orrify(count, sdata);
|
|
7800
|
-
UnaryScatterLoop<STATE_TYPE, INPUT_TYPE, OP>((INPUT_TYPE *)idata.data, bind_data, (STATE_TYPE **)sdata.data,
|
|
7801
|
-
*idata.sel, *sdata.sel, idata.validity, count);
|
|
7802
|
-
}
|
|
7803
|
-
}
|
|
7804
|
-
|
|
7805
|
-
template <class STATE_TYPE, class INPUT_TYPE, class OP>
|
|
7806
|
-
static void UnaryUpdate(Vector &input, FunctionData *bind_data, data_ptr_t state, idx_t count) {
|
|
7807
|
-
switch (input.GetVectorType()) {
|
|
7808
|
-
case VectorType::CONSTANT_VECTOR: {
|
|
7809
|
-
if (OP::IgnoreNull() && ConstantVector::IsNull(input)) {
|
|
7810
|
-
return;
|
|
7811
|
-
}
|
|
7812
|
-
auto idata = ConstantVector::GetData<INPUT_TYPE>(input);
|
|
7813
|
-
OP::template ConstantOperation<INPUT_TYPE, STATE_TYPE, OP>((STATE_TYPE *)state, bind_data, idata,
|
|
7814
|
-
ConstantVector::Validity(input), count);
|
|
7815
|
-
break;
|
|
7816
|
-
}
|
|
7817
|
-
case VectorType::FLAT_VECTOR: {
|
|
7818
|
-
auto idata = FlatVector::GetData<INPUT_TYPE>(input);
|
|
7819
|
-
UnaryFlatUpdateLoop<STATE_TYPE, INPUT_TYPE, OP>(idata, bind_data, (STATE_TYPE *)state, count,
|
|
7820
|
-
FlatVector::Validity(input));
|
|
7821
|
-
break;
|
|
7822
|
-
}
|
|
7823
|
-
default: {
|
|
7824
|
-
VectorData idata;
|
|
7825
|
-
input.Orrify(count, idata);
|
|
7826
|
-
UnaryUpdateLoop<STATE_TYPE, INPUT_TYPE, OP>((INPUT_TYPE *)idata.data, bind_data, (STATE_TYPE *)state, count,
|
|
7827
|
-
idata.validity, *idata.sel);
|
|
7828
|
-
break;
|
|
7829
|
-
}
|
|
7830
|
-
}
|
|
7831
|
-
}
|
|
7832
|
-
|
|
7833
|
-
template <class STATE_TYPE, class A_TYPE, class B_TYPE, class OP>
|
|
7834
|
-
static void BinaryScatter(FunctionData *bind_data, Vector &a, Vector &b, Vector &states, idx_t count) {
|
|
7835
|
-
VectorData adata, bdata, sdata;
|
|
7836
|
-
|
|
7837
|
-
a.Orrify(count, adata);
|
|
7838
|
-
b.Orrify(count, bdata);
|
|
7839
|
-
states.Orrify(count, sdata);
|
|
7840
|
-
|
|
7841
|
-
BinaryScatterLoop<STATE_TYPE, A_TYPE, B_TYPE, OP>((A_TYPE *)adata.data, bind_data, (B_TYPE *)bdata.data,
|
|
7842
|
-
(STATE_TYPE **)sdata.data, count, *adata.sel, *bdata.sel,
|
|
7843
|
-
*sdata.sel, adata.validity, bdata.validity);
|
|
7844
|
-
}
|
|
7845
|
-
|
|
7846
|
-
template <class STATE_TYPE, class A_TYPE, class B_TYPE, class OP>
|
|
7847
|
-
static void BinaryUpdate(FunctionData *bind_data, Vector &a, Vector &b, data_ptr_t state, idx_t count) {
|
|
7848
|
-
VectorData adata, bdata;
|
|
7849
|
-
|
|
7850
|
-
a.Orrify(count, adata);
|
|
7851
|
-
b.Orrify(count, bdata);
|
|
7852
|
-
|
|
7853
|
-
BinaryUpdateLoop<STATE_TYPE, A_TYPE, B_TYPE, OP>((A_TYPE *)adata.data, bind_data, (B_TYPE *)bdata.data,
|
|
7854
|
-
(STATE_TYPE *)state, count, *adata.sel, *bdata.sel,
|
|
7855
|
-
adata.validity, bdata.validity);
|
|
7856
|
-
}
|
|
7857
|
-
|
|
7858
|
-
template <class STATE_TYPE, class OP>
|
|
7859
|
-
static void Combine(Vector &source, Vector &target, FunctionData *bind_data, idx_t count) {
|
|
7860
|
-
D_ASSERT(source.GetType().id() == LogicalTypeId::POINTER && target.GetType().id() == LogicalTypeId::POINTER);
|
|
7861
|
-
auto sdata = FlatVector::GetData<const STATE_TYPE *>(source);
|
|
7862
|
-
auto tdata = FlatVector::GetData<STATE_TYPE *>(target);
|
|
7863
|
-
|
|
7864
|
-
for (idx_t i = 0; i < count; i++) {
|
|
7865
|
-
OP::template Combine<STATE_TYPE, OP>(*sdata[i], tdata[i], bind_data);
|
|
7866
|
-
}
|
|
7867
|
-
}
|
|
7868
|
-
|
|
7869
|
-
template <class STATE_TYPE, class RESULT_TYPE, class OP>
|
|
7870
|
-
static void Finalize(Vector &states, FunctionData *bind_data, Vector &result, idx_t count, idx_t offset) {
|
|
7871
|
-
if (states.GetVectorType() == VectorType::CONSTANT_VECTOR) {
|
|
7872
|
-
result.SetVectorType(VectorType::CONSTANT_VECTOR);
|
|
7873
|
-
|
|
7874
|
-
auto sdata = ConstantVector::GetData<STATE_TYPE *>(states);
|
|
7875
|
-
auto rdata = ConstantVector::GetData<RESULT_TYPE>(result);
|
|
7876
|
-
OP::template Finalize<RESULT_TYPE, STATE_TYPE>(result, bind_data, *sdata, rdata,
|
|
7877
|
-
ConstantVector::Validity(result), 0);
|
|
7878
|
-
} else {
|
|
7879
|
-
D_ASSERT(states.GetVectorType() == VectorType::FLAT_VECTOR);
|
|
7880
|
-
result.SetVectorType(VectorType::FLAT_VECTOR);
|
|
7881
|
-
|
|
7882
|
-
auto sdata = FlatVector::GetData<STATE_TYPE *>(states);
|
|
7883
|
-
auto rdata = FlatVector::GetData<RESULT_TYPE>(result);
|
|
7884
|
-
for (idx_t i = 0; i < count; i++) {
|
|
7885
|
-
OP::template Finalize<RESULT_TYPE, STATE_TYPE>(result, bind_data, sdata[i], rdata,
|
|
7886
|
-
FlatVector::Validity(result), i + offset);
|
|
7887
|
-
}
|
|
7888
|
-
}
|
|
7889
|
-
}
|
|
7890
|
-
|
|
7891
|
-
template <class STATE, class INPUT_TYPE, class RESULT_TYPE, class OP>
|
|
7892
|
-
static void UnaryWindow(Vector &input, const ValidityMask &ifilter, FunctionData *bind_data, data_ptr_t state,
|
|
7893
|
-
const FrameBounds &frame, const FrameBounds &prev, Vector &result, idx_t rid, idx_t bias) {
|
|
7894
|
-
|
|
7895
|
-
auto idata = FlatVector::GetData<const INPUT_TYPE>(input) - bias;
|
|
7896
|
-
const auto &ivalid = FlatVector::Validity(input);
|
|
7897
|
-
OP::template Window<STATE, INPUT_TYPE, RESULT_TYPE>(idata, ifilter, ivalid, bind_data, (STATE *)state, frame,
|
|
7898
|
-
prev, result, rid, bias);
|
|
7899
|
-
}
|
|
7900
|
-
|
|
7901
|
-
template <class STATE_TYPE, class OP>
|
|
7902
|
-
static void Destroy(Vector &states, idx_t count) {
|
|
7903
|
-
auto sdata = FlatVector::GetData<STATE_TYPE *>(states);
|
|
7904
|
-
for (idx_t i = 0; i < count; i++) {
|
|
7905
|
-
OP::template Destroy<STATE_TYPE>(sdata[i]);
|
|
7906
|
-
}
|
|
7907
|
-
}
|
|
7908
|
-
};
|
|
7909
|
-
|
|
7910
|
-
} // namespace duckdb
|
|
7911
|
-
|
|
7912
7556
|
|
|
7913
7557
|
|
|
7914
7558
|
//===----------------------------------------------------------------------===//
|
|
@@ -8857,56 +8501,241 @@ class LogicalWindow;
|
|
|
8857
8501
|
} // namespace duckdb
|
|
8858
8502
|
|
|
8859
8503
|
|
|
8860
|
-
#include <functional>
|
|
8504
|
+
#include <functional>
|
|
8505
|
+
|
|
8506
|
+
namespace duckdb {
|
|
8507
|
+
//! The LogicalOperatorVisitor is an abstract base class that implements the
|
|
8508
|
+
//! Visitor pattern on LogicalOperator.
|
|
8509
|
+
class LogicalOperatorVisitor {
|
|
8510
|
+
public:
|
|
8511
|
+
virtual ~LogicalOperatorVisitor() {};
|
|
8512
|
+
|
|
8513
|
+
virtual void VisitOperator(LogicalOperator &op);
|
|
8514
|
+
virtual void VisitExpression(unique_ptr<Expression> *expression);
|
|
8515
|
+
|
|
8516
|
+
static void EnumerateExpressions(LogicalOperator &op,
|
|
8517
|
+
const std::function<void(unique_ptr<Expression> *child)> &callback);
|
|
8518
|
+
|
|
8519
|
+
protected:
|
|
8520
|
+
//! Automatically calls the Visit method for LogicalOperator children of the current operator. Can be overloaded to
|
|
8521
|
+
//! change this behavior.
|
|
8522
|
+
void VisitOperatorChildren(LogicalOperator &op);
|
|
8523
|
+
//! Automatically calls the Visit method for Expression children of the current operator. Can be overloaded to
|
|
8524
|
+
//! change this behavior.
|
|
8525
|
+
void VisitOperatorExpressions(LogicalOperator &op);
|
|
8526
|
+
|
|
8527
|
+
// The VisitExpressionChildren method is called at the end of every call to VisitExpression to recursively visit all
|
|
8528
|
+
// expressions in an expression tree. It can be overloaded to prevent automatically visiting the entire tree.
|
|
8529
|
+
virtual void VisitExpressionChildren(Expression &expression);
|
|
8530
|
+
|
|
8531
|
+
virtual unique_ptr<Expression> VisitReplace(BoundAggregateExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
8532
|
+
virtual unique_ptr<Expression> VisitReplace(BoundBetweenExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
8533
|
+
virtual unique_ptr<Expression> VisitReplace(BoundCaseExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
8534
|
+
virtual unique_ptr<Expression> VisitReplace(BoundCastExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
8535
|
+
virtual unique_ptr<Expression> VisitReplace(BoundColumnRefExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
8536
|
+
virtual unique_ptr<Expression> VisitReplace(BoundComparisonExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
8537
|
+
virtual unique_ptr<Expression> VisitReplace(BoundConjunctionExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
8538
|
+
virtual unique_ptr<Expression> VisitReplace(BoundConstantExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
8539
|
+
virtual unique_ptr<Expression> VisitReplace(BoundDefaultExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
8540
|
+
virtual unique_ptr<Expression> VisitReplace(BoundFunctionExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
8541
|
+
virtual unique_ptr<Expression> VisitReplace(BoundOperatorExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
8542
|
+
virtual unique_ptr<Expression> VisitReplace(BoundReferenceExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
8543
|
+
virtual unique_ptr<Expression> VisitReplace(BoundSubqueryExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
8544
|
+
virtual unique_ptr<Expression> VisitReplace(BoundParameterExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
8545
|
+
virtual unique_ptr<Expression> VisitReplace(BoundWindowExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
8546
|
+
virtual unique_ptr<Expression> VisitReplace(BoundUnnestExpression &expr, unique_ptr<Expression> *expr_ptr);
|
|
8547
|
+
};
|
|
8548
|
+
} // namespace duckdb
|
|
8549
|
+
|
|
8550
|
+
//===----------------------------------------------------------------------===//
|
|
8551
|
+
// DuckDB
|
|
8552
|
+
//
|
|
8553
|
+
// duckdb/planner/column_binding.hpp
|
|
8554
|
+
//
|
|
8555
|
+
//
|
|
8556
|
+
//===----------------------------------------------------------------------===//
|
|
8557
|
+
|
|
8558
|
+
|
|
8559
|
+
|
|
8560
|
+
|
|
8561
|
+
#include <functional>
|
|
8562
|
+
|
|
8563
|
+
namespace duckdb {
|
|
8564
|
+
|
|
8565
|
+
struct ColumnBinding {
|
|
8566
|
+
idx_t table_index;
|
|
8567
|
+
idx_t column_index;
|
|
8568
|
+
|
|
8569
|
+
ColumnBinding() : table_index(DConstants::INVALID_INDEX), column_index(DConstants::INVALID_INDEX) {
|
|
8570
|
+
}
|
|
8571
|
+
ColumnBinding(idx_t table, idx_t column) : table_index(table), column_index(column) {
|
|
8572
|
+
}
|
|
8573
|
+
|
|
8574
|
+
bool operator==(const ColumnBinding &rhs) const {
|
|
8575
|
+
return table_index == rhs.table_index && column_index == rhs.column_index;
|
|
8576
|
+
}
|
|
8577
|
+
};
|
|
8578
|
+
|
|
8579
|
+
} // namespace duckdb
|
|
8580
|
+
|
|
8581
|
+
|
|
8582
|
+
#include <functional>
|
|
8583
|
+
#include <algorithm>
|
|
8584
|
+
|
|
8585
|
+
namespace duckdb {
|
|
8586
|
+
|
|
8587
|
+
//! LogicalOperator is the base class of the logical operators present in the
|
|
8588
|
+
//! logical query tree
|
|
8589
|
+
class LogicalOperator {
|
|
8590
|
+
public:
|
|
8591
|
+
explicit LogicalOperator(LogicalOperatorType type) : type(type) {
|
|
8592
|
+
}
|
|
8593
|
+
LogicalOperator(LogicalOperatorType type, vector<unique_ptr<Expression>> expressions)
|
|
8594
|
+
: type(type), expressions(move(expressions)) {
|
|
8595
|
+
}
|
|
8596
|
+
virtual ~LogicalOperator() {
|
|
8597
|
+
}
|
|
8598
|
+
|
|
8599
|
+
//! The type of the logical operator
|
|
8600
|
+
LogicalOperatorType type;
|
|
8601
|
+
//! The set of children of the operator
|
|
8602
|
+
vector<unique_ptr<LogicalOperator>> children;
|
|
8603
|
+
//! The set of expressions contained within the operator, if any
|
|
8604
|
+
vector<unique_ptr<Expression>> expressions;
|
|
8605
|
+
//! The types returned by this logical operator. Set by calling LogicalOperator::ResolveTypes.
|
|
8606
|
+
vector<LogicalType> types;
|
|
8607
|
+
//! Estimated Cardinality
|
|
8608
|
+
idx_t estimated_cardinality = 0;
|
|
8609
|
+
|
|
8610
|
+
public:
|
|
8611
|
+
virtual vector<ColumnBinding> GetColumnBindings() {
|
|
8612
|
+
return {ColumnBinding(0, 0)};
|
|
8613
|
+
}
|
|
8614
|
+
static vector<ColumnBinding> GenerateColumnBindings(idx_t table_idx, idx_t column_count);
|
|
8615
|
+
static vector<LogicalType> MapTypes(const vector<LogicalType> &types, const vector<idx_t> &projection_map);
|
|
8616
|
+
static vector<ColumnBinding> MapBindings(const vector<ColumnBinding> &types, const vector<idx_t> &projection_map);
|
|
8617
|
+
|
|
8618
|
+
//! Resolve the types of the logical operator and its children
|
|
8619
|
+
void ResolveOperatorTypes();
|
|
8620
|
+
|
|
8621
|
+
virtual string GetName() const;
|
|
8622
|
+
virtual string ParamsToString() const;
|
|
8623
|
+
virtual string ToString() const;
|
|
8624
|
+
DUCKDB_API void Print();
|
|
8625
|
+
//! Debug method: verify that the integrity of expressions & child nodes are maintained
|
|
8626
|
+
virtual void Verify();
|
|
8627
|
+
|
|
8628
|
+
void AddChild(unique_ptr<LogicalOperator> child) {
|
|
8629
|
+
children.push_back(move(child));
|
|
8630
|
+
}
|
|
8631
|
+
|
|
8632
|
+
virtual idx_t EstimateCardinality(ClientContext &context) {
|
|
8633
|
+
// simple estimator, just take the max of the children
|
|
8634
|
+
idx_t max_cardinality = 0;
|
|
8635
|
+
for (auto &child : children) {
|
|
8636
|
+
max_cardinality = MaxValue(child->EstimateCardinality(context), max_cardinality);
|
|
8637
|
+
}
|
|
8638
|
+
return max_cardinality;
|
|
8639
|
+
}
|
|
8640
|
+
|
|
8641
|
+
protected:
|
|
8642
|
+
//! Resolve types for this specific operator
|
|
8643
|
+
virtual void ResolveTypes() = 0;
|
|
8644
|
+
};
|
|
8645
|
+
} // namespace duckdb
|
|
8646
|
+
|
|
8647
|
+
|
|
8648
|
+
namespace duckdb {
|
|
8649
|
+
|
|
8650
|
+
struct BoundStatement {
|
|
8651
|
+
unique_ptr<LogicalOperator> plan;
|
|
8652
|
+
vector<LogicalType> types;
|
|
8653
|
+
vector<string> names;
|
|
8654
|
+
};
|
|
8655
|
+
|
|
8656
|
+
} // namespace duckdb
|
|
8657
|
+
|
|
8658
|
+
|
|
8659
|
+
|
|
8861
8660
|
|
|
8862
8661
|
namespace duckdb {
|
|
8863
|
-
|
|
8864
|
-
//!
|
|
8865
|
-
class
|
|
8662
|
+
|
|
8663
|
+
//! A ResultModifier
|
|
8664
|
+
class BoundResultModifier {
|
|
8866
8665
|
public:
|
|
8867
|
-
|
|
8666
|
+
explicit BoundResultModifier(ResultModifierType type);
|
|
8667
|
+
virtual ~BoundResultModifier();
|
|
8868
8668
|
|
|
8869
|
-
|
|
8870
|
-
|
|
8669
|
+
ResultModifierType type;
|
|
8670
|
+
};
|
|
8871
8671
|
|
|
8872
|
-
|
|
8873
|
-
|
|
8672
|
+
struct BoundOrderByNode {
|
|
8673
|
+
public:
|
|
8674
|
+
BoundOrderByNode(OrderType type, OrderByNullType null_order, unique_ptr<Expression> expression);
|
|
8675
|
+
BoundOrderByNode(OrderType type, OrderByNullType null_order, unique_ptr<Expression> expression,
|
|
8676
|
+
unique_ptr<BaseStatistics> stats);
|
|
8874
8677
|
|
|
8875
|
-
|
|
8876
|
-
|
|
8877
|
-
|
|
8878
|
-
|
|
8879
|
-
//! Automatically calls the Visit method for Expression children of the current operator. Can be overloaded to
|
|
8880
|
-
//! change this behavior.
|
|
8881
|
-
void VisitOperatorExpressions(LogicalOperator &op);
|
|
8678
|
+
OrderType type;
|
|
8679
|
+
OrderByNullType null_order;
|
|
8680
|
+
unique_ptr<Expression> expression;
|
|
8681
|
+
unique_ptr<BaseStatistics> stats;
|
|
8882
8682
|
|
|
8883
|
-
|
|
8884
|
-
|
|
8885
|
-
|
|
8683
|
+
public:
|
|
8684
|
+
BoundOrderByNode Copy() const;
|
|
8685
|
+
string ToString() const;
|
|
8686
|
+
};
|
|
8886
8687
|
|
|
8887
|
-
|
|
8888
|
-
|
|
8889
|
-
|
|
8890
|
-
|
|
8891
|
-
|
|
8892
|
-
|
|
8893
|
-
|
|
8894
|
-
|
|
8895
|
-
|
|
8896
|
-
|
|
8897
|
-
|
|
8898
|
-
|
|
8899
|
-
|
|
8900
|
-
|
|
8901
|
-
|
|
8902
|
-
|
|
8688
|
+
class BoundLimitModifier : public BoundResultModifier {
|
|
8689
|
+
public:
|
|
8690
|
+
BoundLimitModifier();
|
|
8691
|
+
|
|
8692
|
+
//! LIMIT
|
|
8693
|
+
int64_t limit_val = NumericLimits<int64_t>::Maximum();
|
|
8694
|
+
//! OFFSET
|
|
8695
|
+
int64_t offset_val = 0;
|
|
8696
|
+
//! Expression in case limit is not constant
|
|
8697
|
+
unique_ptr<Expression> limit;
|
|
8698
|
+
//! Expression in case limit is not constant
|
|
8699
|
+
unique_ptr<Expression> offset;
|
|
8700
|
+
};
|
|
8701
|
+
|
|
8702
|
+
class BoundOrderModifier : public BoundResultModifier {
|
|
8703
|
+
public:
|
|
8704
|
+
BoundOrderModifier();
|
|
8705
|
+
|
|
8706
|
+
//! List of order nodes
|
|
8707
|
+
vector<BoundOrderByNode> orders;
|
|
8708
|
+
};
|
|
8709
|
+
|
|
8710
|
+
class BoundDistinctModifier : public BoundResultModifier {
|
|
8711
|
+
public:
|
|
8712
|
+
BoundDistinctModifier();
|
|
8713
|
+
|
|
8714
|
+
//! list of distinct on targets (if any)
|
|
8715
|
+
vector<unique_ptr<Expression>> target_distincts;
|
|
8716
|
+
};
|
|
8717
|
+
|
|
8718
|
+
class BoundLimitPercentModifier : public BoundResultModifier {
|
|
8719
|
+
public:
|
|
8720
|
+
BoundLimitPercentModifier();
|
|
8721
|
+
|
|
8722
|
+
//! LIMIT %
|
|
8723
|
+
double limit_percent = 100.0;
|
|
8724
|
+
//! OFFSET
|
|
8725
|
+
int64_t offset_val = 0;
|
|
8726
|
+
//! Expression in case limit is not constant
|
|
8727
|
+
unique_ptr<Expression> limit;
|
|
8728
|
+
//! Expression in case limit is not constant
|
|
8729
|
+
unique_ptr<Expression> offset;
|
|
8903
8730
|
};
|
|
8731
|
+
|
|
8904
8732
|
} // namespace duckdb
|
|
8905
8733
|
|
|
8734
|
+
|
|
8906
8735
|
//===----------------------------------------------------------------------===//
|
|
8907
8736
|
// DuckDB
|
|
8908
8737
|
//
|
|
8909
|
-
// duckdb/
|
|
8738
|
+
// duckdb/common/vector_operations/aggregate_executor.hpp
|
|
8910
8739
|
//
|
|
8911
8740
|
//
|
|
8912
8741
|
//===----------------------------------------------------------------------===//
|
|
@@ -8914,196 +8743,382 @@ protected:
|
|
|
8914
8743
|
|
|
8915
8744
|
|
|
8916
8745
|
|
|
8917
|
-
|
|
8746
|
+
|
|
8747
|
+
|
|
8918
8748
|
|
|
8919
8749
|
namespace duckdb {
|
|
8920
8750
|
|
|
8921
|
-
struct
|
|
8922
|
-
idx_t table_index;
|
|
8923
|
-
idx_t column_index;
|
|
8751
|
+
struct AggregateInputData;
|
|
8924
8752
|
|
|
8925
|
-
|
|
8753
|
+
typedef std::pair<idx_t, idx_t> FrameBounds;
|
|
8754
|
+
|
|
8755
|
+
class AggregateExecutor {
|
|
8756
|
+
private:
|
|
8757
|
+
template <class STATE_TYPE, class OP>
|
|
8758
|
+
static inline void NullaryFlatLoop(STATE_TYPE **__restrict states, AggregateInputData &aggr_input_data,
|
|
8759
|
+
idx_t count) {
|
|
8760
|
+
for (idx_t i = 0; i < count; i++) {
|
|
8761
|
+
OP::template Operation<STATE_TYPE, OP>(states[i], aggr_input_data, i);
|
|
8762
|
+
}
|
|
8926
8763
|
}
|
|
8927
|
-
|
|
8764
|
+
|
|
8765
|
+
template <class STATE_TYPE, class OP>
|
|
8766
|
+
static inline void NullaryScatterLoop(STATE_TYPE **__restrict states, AggregateInputData &aggr_input_data,
|
|
8767
|
+
const SelectionVector &ssel, idx_t count) {
|
|
8768
|
+
|
|
8769
|
+
for (idx_t i = 0; i < count; i++) {
|
|
8770
|
+
auto sidx = ssel.get_index(i);
|
|
8771
|
+
OP::template Operation<STATE_TYPE, OP>(states[sidx], aggr_input_data, sidx);
|
|
8772
|
+
}
|
|
8773
|
+
}
|
|
8774
|
+
|
|
8775
|
+
template <class STATE_TYPE, class INPUT_TYPE, class OP>
|
|
8776
|
+
static inline void UnaryFlatLoop(INPUT_TYPE *__restrict idata, AggregateInputData &aggr_input_data,
|
|
8777
|
+
STATE_TYPE **__restrict states, ValidityMask &mask, idx_t count) {
|
|
8778
|
+
if (!mask.AllValid()) {
|
|
8779
|
+
idx_t base_idx = 0;
|
|
8780
|
+
auto entry_count = ValidityMask::EntryCount(count);
|
|
8781
|
+
for (idx_t entry_idx = 0; entry_idx < entry_count; entry_idx++) {
|
|
8782
|
+
auto validity_entry = mask.GetValidityEntry(entry_idx);
|
|
8783
|
+
idx_t next = MinValue<idx_t>(base_idx + ValidityMask::BITS_PER_VALUE, count);
|
|
8784
|
+
if (!OP::IgnoreNull() || ValidityMask::AllValid(validity_entry)) {
|
|
8785
|
+
// all valid: perform operation
|
|
8786
|
+
for (; base_idx < next; base_idx++) {
|
|
8787
|
+
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[base_idx], aggr_input_data, idata,
|
|
8788
|
+
mask, base_idx);
|
|
8789
|
+
}
|
|
8790
|
+
} else if (ValidityMask::NoneValid(validity_entry)) {
|
|
8791
|
+
// nothing valid: skip all
|
|
8792
|
+
base_idx = next;
|
|
8793
|
+
continue;
|
|
8794
|
+
} else {
|
|
8795
|
+
// partially valid: need to check individual elements for validity
|
|
8796
|
+
idx_t start = base_idx;
|
|
8797
|
+
for (; base_idx < next; base_idx++) {
|
|
8798
|
+
if (ValidityMask::RowIsValid(validity_entry, base_idx - start)) {
|
|
8799
|
+
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[base_idx], aggr_input_data, idata,
|
|
8800
|
+
mask, base_idx);
|
|
8801
|
+
}
|
|
8802
|
+
}
|
|
8803
|
+
}
|
|
8804
|
+
}
|
|
8805
|
+
} else {
|
|
8806
|
+
for (idx_t i = 0; i < count; i++) {
|
|
8807
|
+
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[i], aggr_input_data, idata, mask, i);
|
|
8808
|
+
}
|
|
8809
|
+
}
|
|
8810
|
+
}
|
|
8811
|
+
|
|
8812
|
+
template <class STATE_TYPE, class INPUT_TYPE, class OP>
|
|
8813
|
+
static inline void UnaryScatterLoop(INPUT_TYPE *__restrict idata, AggregateInputData &aggr_input_data,
|
|
8814
|
+
STATE_TYPE **__restrict states, const SelectionVector &isel,
|
|
8815
|
+
const SelectionVector &ssel, ValidityMask &mask, idx_t count) {
|
|
8816
|
+
if (OP::IgnoreNull() && !mask.AllValid()) {
|
|
8817
|
+
// potential NULL values and NULL values are ignored
|
|
8818
|
+
for (idx_t i = 0; i < count; i++) {
|
|
8819
|
+
auto idx = isel.get_index(i);
|
|
8820
|
+
auto sidx = ssel.get_index(i);
|
|
8821
|
+
if (mask.RowIsValid(idx)) {
|
|
8822
|
+
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[sidx], aggr_input_data, idata, mask, idx);
|
|
8823
|
+
}
|
|
8824
|
+
}
|
|
8825
|
+
} else {
|
|
8826
|
+
// quick path: no NULL values or NULL values are not ignored
|
|
8827
|
+
for (idx_t i = 0; i < count; i++) {
|
|
8828
|
+
auto idx = isel.get_index(i);
|
|
8829
|
+
auto sidx = ssel.get_index(i);
|
|
8830
|
+
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(states[sidx], aggr_input_data, idata, mask, idx);
|
|
8831
|
+
}
|
|
8832
|
+
}
|
|
8833
|
+
}
|
|
8834
|
+
|
|
8835
|
+
template <class STATE_TYPE, class INPUT_TYPE, class OP>
|
|
8836
|
+
static inline void UnaryFlatUpdateLoop(INPUT_TYPE *__restrict idata, AggregateInputData &aggr_input_data,
|
|
8837
|
+
STATE_TYPE *__restrict state, idx_t count, ValidityMask &mask) {
|
|
8838
|
+
idx_t base_idx = 0;
|
|
8839
|
+
auto entry_count = ValidityMask::EntryCount(count);
|
|
8840
|
+
for (idx_t entry_idx = 0; entry_idx < entry_count; entry_idx++) {
|
|
8841
|
+
auto validity_entry = mask.GetValidityEntry(entry_idx);
|
|
8842
|
+
idx_t next = MinValue<idx_t>(base_idx + ValidityMask::BITS_PER_VALUE, count);
|
|
8843
|
+
if (!OP::IgnoreNull() || ValidityMask::AllValid(validity_entry)) {
|
|
8844
|
+
// all valid: perform operation
|
|
8845
|
+
for (; base_idx < next; base_idx++) {
|
|
8846
|
+
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(state, aggr_input_data, idata, mask, base_idx);
|
|
8847
|
+
}
|
|
8848
|
+
} else if (ValidityMask::NoneValid(validity_entry)) {
|
|
8849
|
+
// nothing valid: skip all
|
|
8850
|
+
base_idx = next;
|
|
8851
|
+
continue;
|
|
8852
|
+
} else {
|
|
8853
|
+
// partially valid: need to check individual elements for validity
|
|
8854
|
+
idx_t start = base_idx;
|
|
8855
|
+
for (; base_idx < next; base_idx++) {
|
|
8856
|
+
if (ValidityMask::RowIsValid(validity_entry, base_idx - start)) {
|
|
8857
|
+
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(state, aggr_input_data, idata, mask,
|
|
8858
|
+
base_idx);
|
|
8859
|
+
}
|
|
8860
|
+
}
|
|
8861
|
+
}
|
|
8862
|
+
}
|
|
8863
|
+
}
|
|
8864
|
+
|
|
8865
|
+
template <class STATE_TYPE, class INPUT_TYPE, class OP>
|
|
8866
|
+
static inline void UnaryUpdateLoop(INPUT_TYPE *__restrict idata, AggregateInputData &aggr_input_data,
|
|
8867
|
+
STATE_TYPE *__restrict state, idx_t count, ValidityMask &mask,
|
|
8868
|
+
const SelectionVector &__restrict sel_vector) {
|
|
8869
|
+
if (OP::IgnoreNull() && !mask.AllValid()) {
|
|
8870
|
+
// potential NULL values and NULL values are ignored
|
|
8871
|
+
for (idx_t i = 0; i < count; i++) {
|
|
8872
|
+
auto idx = sel_vector.get_index(i);
|
|
8873
|
+
if (mask.RowIsValid(idx)) {
|
|
8874
|
+
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(state, aggr_input_data, idata, mask, idx);
|
|
8875
|
+
}
|
|
8876
|
+
}
|
|
8877
|
+
} else {
|
|
8878
|
+
// quick path: no NULL values or NULL values are not ignored
|
|
8879
|
+
for (idx_t i = 0; i < count; i++) {
|
|
8880
|
+
auto idx = sel_vector.get_index(i);
|
|
8881
|
+
OP::template Operation<INPUT_TYPE, STATE_TYPE, OP>(state, aggr_input_data, idata, mask, idx);
|
|
8882
|
+
}
|
|
8883
|
+
}
|
|
8884
|
+
}
|
|
8885
|
+
|
|
8886
|
+
template <class STATE_TYPE, class A_TYPE, class B_TYPE, class OP>
|
|
8887
|
+
static inline void BinaryScatterLoop(A_TYPE *__restrict adata, AggregateInputData &aggr_input_data,
|
|
8888
|
+
B_TYPE *__restrict bdata, STATE_TYPE **__restrict states, idx_t count,
|
|
8889
|
+
const SelectionVector &asel, const SelectionVector &bsel,
|
|
8890
|
+
const SelectionVector &ssel, ValidityMask &avalidity,
|
|
8891
|
+
ValidityMask &bvalidity) {
|
|
8892
|
+
if (OP::IgnoreNull() && (!avalidity.AllValid() || !bvalidity.AllValid())) {
|
|
8893
|
+
// potential NULL values and NULL values are ignored
|
|
8894
|
+
for (idx_t i = 0; i < count; i++) {
|
|
8895
|
+
auto aidx = asel.get_index(i);
|
|
8896
|
+
auto bidx = bsel.get_index(i);
|
|
8897
|
+
auto sidx = ssel.get_index(i);
|
|
8898
|
+
if (avalidity.RowIsValid(aidx) && bvalidity.RowIsValid(bidx)) {
|
|
8899
|
+
OP::template Operation<A_TYPE, B_TYPE, STATE_TYPE, OP>(states[sidx], aggr_input_data, adata, bdata,
|
|
8900
|
+
avalidity, bvalidity, aidx, bidx);
|
|
8901
|
+
}
|
|
8902
|
+
}
|
|
8903
|
+
} else {
|
|
8904
|
+
// quick path: no NULL values or NULL values are not ignored
|
|
8905
|
+
for (idx_t i = 0; i < count; i++) {
|
|
8906
|
+
auto aidx = asel.get_index(i);
|
|
8907
|
+
auto bidx = bsel.get_index(i);
|
|
8908
|
+
auto sidx = ssel.get_index(i);
|
|
8909
|
+
OP::template Operation<A_TYPE, B_TYPE, STATE_TYPE, OP>(states[sidx], aggr_input_data, adata, bdata,
|
|
8910
|
+
avalidity, bvalidity, aidx, bidx);
|
|
8911
|
+
}
|
|
8912
|
+
}
|
|
8928
8913
|
}
|
|
8929
8914
|
|
|
8930
|
-
|
|
8931
|
-
|
|
8915
|
+
template <class STATE_TYPE, class A_TYPE, class B_TYPE, class OP>
|
|
8916
|
+
static inline void BinaryUpdateLoop(A_TYPE *__restrict adata, AggregateInputData &aggr_input_data,
|
|
8917
|
+
B_TYPE *__restrict bdata, STATE_TYPE *__restrict state, idx_t count,
|
|
8918
|
+
const SelectionVector &asel, const SelectionVector &bsel,
|
|
8919
|
+
ValidityMask &avalidity, ValidityMask &bvalidity) {
|
|
8920
|
+
if (OP::IgnoreNull() && (!avalidity.AllValid() || !bvalidity.AllValid())) {
|
|
8921
|
+
// potential NULL values and NULL values are ignored
|
|
8922
|
+
for (idx_t i = 0; i < count; i++) {
|
|
8923
|
+
auto aidx = asel.get_index(i);
|
|
8924
|
+
auto bidx = bsel.get_index(i);
|
|
8925
|
+
if (avalidity.RowIsValid(aidx) && bvalidity.RowIsValid(bidx)) {
|
|
8926
|
+
OP::template Operation<A_TYPE, B_TYPE, STATE_TYPE, OP>(state, aggr_input_data, adata, bdata,
|
|
8927
|
+
avalidity, bvalidity, aidx, bidx);
|
|
8928
|
+
}
|
|
8929
|
+
}
|
|
8930
|
+
} else {
|
|
8931
|
+
// quick path: no NULL values or NULL values are not ignored
|
|
8932
|
+
for (idx_t i = 0; i < count; i++) {
|
|
8933
|
+
auto aidx = asel.get_index(i);
|
|
8934
|
+
auto bidx = bsel.get_index(i);
|
|
8935
|
+
OP::template Operation<A_TYPE, B_TYPE, STATE_TYPE, OP>(state, aggr_input_data, adata, bdata, avalidity,
|
|
8936
|
+
bvalidity, aidx, bidx);
|
|
8937
|
+
}
|
|
8938
|
+
}
|
|
8932
8939
|
}
|
|
8933
|
-
};
|
|
8934
|
-
|
|
8935
|
-
} // namespace duckdb
|
|
8936
|
-
|
|
8937
|
-
|
|
8938
|
-
#include <functional>
|
|
8939
|
-
#include <algorithm>
|
|
8940
|
-
|
|
8941
|
-
namespace duckdb {
|
|
8942
8940
|
|
|
8943
|
-
//! LogicalOperator is the base class of the logical operators present in the
|
|
8944
|
-
//! logical query tree
|
|
8945
|
-
class LogicalOperator {
|
|
8946
8941
|
public:
|
|
8947
|
-
|
|
8948
|
-
|
|
8949
|
-
|
|
8950
|
-
|
|
8951
|
-
|
|
8952
|
-
|
|
8942
|
+
template <class STATE_TYPE, class OP>
|
|
8943
|
+
static void NullaryScatter(Vector &states, AggregateInputData &aggr_input_data, idx_t count) {
|
|
8944
|
+
if (states.GetVectorType() == VectorType::CONSTANT_VECTOR) {
|
|
8945
|
+
auto sdata = ConstantVector::GetData<STATE_TYPE *>(states);
|
|
8946
|
+
OP::template ConstantOperation<STATE_TYPE, OP>(*sdata, aggr_input_data, count);
|
|
8947
|
+
} else if (states.GetVectorType() == VectorType::FLAT_VECTOR) {
|
|
8948
|
+
auto sdata = FlatVector::GetData<STATE_TYPE *>(states);
|
|
8949
|
+
NullaryFlatLoop<STATE_TYPE, OP>(sdata, aggr_input_data, count);
|
|
8950
|
+
} else {
|
|
8951
|
+
VectorData sdata;
|
|
8952
|
+
states.Orrify(count, sdata);
|
|
8953
|
+
NullaryScatterLoop<STATE_TYPE, OP>((STATE_TYPE **)sdata.data, aggr_input_data, *sdata.sel, count);
|
|
8954
|
+
}
|
|
8953
8955
|
}
|
|
8954
8956
|
|
|
8955
|
-
|
|
8956
|
-
|
|
8957
|
-
|
|
8958
|
-
vector<unique_ptr<LogicalOperator>> children;
|
|
8959
|
-
//! The set of expressions contained within the operator, if any
|
|
8960
|
-
vector<unique_ptr<Expression>> expressions;
|
|
8961
|
-
//! The types returned by this logical operator. Set by calling LogicalOperator::ResolveTypes.
|
|
8962
|
-
vector<LogicalType> types;
|
|
8963
|
-
//! Estimated Cardinality
|
|
8964
|
-
idx_t estimated_cardinality = 0;
|
|
8965
|
-
|
|
8966
|
-
public:
|
|
8967
|
-
virtual vector<ColumnBinding> GetColumnBindings() {
|
|
8968
|
-
return {ColumnBinding(0, 0)};
|
|
8957
|
+
template <class STATE_TYPE, class OP>
|
|
8958
|
+
static void NullaryUpdate(data_ptr_t state, AggregateInputData &aggr_input_data, idx_t count) {
|
|
8959
|
+
OP::template ConstantOperation<STATE_TYPE, OP>((STATE_TYPE *)state, aggr_input_data, count);
|
|
8969
8960
|
}
|
|
8970
|
-
static vector<ColumnBinding> GenerateColumnBindings(idx_t table_idx, idx_t column_count);
|
|
8971
|
-
static vector<LogicalType> MapTypes(const vector<LogicalType> &types, const vector<idx_t> &projection_map);
|
|
8972
|
-
static vector<ColumnBinding> MapBindings(const vector<ColumnBinding> &types, const vector<idx_t> &projection_map);
|
|
8973
|
-
|
|
8974
|
-
//! Resolve the types of the logical operator and its children
|
|
8975
|
-
void ResolveOperatorTypes();
|
|
8976
8961
|
|
|
8977
|
-
|
|
8978
|
-
|
|
8979
|
-
|
|
8980
|
-
|
|
8981
|
-
|
|
8982
|
-
|
|
8983
|
-
|
|
8984
|
-
|
|
8985
|
-
|
|
8962
|
+
template <class STATE_TYPE, class INPUT_TYPE, class OP>
|
|
8963
|
+
static void UnaryScatter(Vector &input, Vector &states, AggregateInputData &aggr_input_data, idx_t count) {
|
|
8964
|
+
if (input.GetVectorType() == VectorType::CONSTANT_VECTOR &&
|
|
8965
|
+
states.GetVectorType() == VectorType::CONSTANT_VECTOR) {
|
|
8966
|
+
if (OP::IgnoreNull() && ConstantVector::IsNull(input)) {
|
|
8967
|
+
// constant NULL input in function that ignores NULL values
|
|
8968
|
+
return;
|
|
8969
|
+
}
|
|
8970
|
+
// regular constant: get first state
|
|
8971
|
+
auto idata = ConstantVector::GetData<INPUT_TYPE>(input);
|
|
8972
|
+
auto sdata = ConstantVector::GetData<STATE_TYPE *>(states);
|
|
8973
|
+
OP::template ConstantOperation<INPUT_TYPE, STATE_TYPE, OP>(*sdata, aggr_input_data, idata,
|
|
8974
|
+
ConstantVector::Validity(input), count);
|
|
8975
|
+
} else if (input.GetVectorType() == VectorType::FLAT_VECTOR &&
|
|
8976
|
+
states.GetVectorType() == VectorType::FLAT_VECTOR) {
|
|
8977
|
+
auto idata = FlatVector::GetData<INPUT_TYPE>(input);
|
|
8978
|
+
auto sdata = FlatVector::GetData<STATE_TYPE *>(states);
|
|
8979
|
+
UnaryFlatLoop<STATE_TYPE, INPUT_TYPE, OP>(idata, aggr_input_data, sdata, FlatVector::Validity(input),
|
|
8980
|
+
count);
|
|
8981
|
+
} else {
|
|
8982
|
+
VectorData idata, sdata;
|
|
8983
|
+
input.Orrify(count, idata);
|
|
8984
|
+
states.Orrify(count, sdata);
|
|
8985
|
+
UnaryScatterLoop<STATE_TYPE, INPUT_TYPE, OP>((INPUT_TYPE *)idata.data, aggr_input_data,
|
|
8986
|
+
(STATE_TYPE **)sdata.data, *idata.sel, *sdata.sel,
|
|
8987
|
+
idata.validity, count);
|
|
8988
|
+
}
|
|
8986
8989
|
}
|
|
8987
8990
|
|
|
8988
|
-
|
|
8989
|
-
|
|
8990
|
-
|
|
8991
|
-
|
|
8992
|
-
|
|
8991
|
+
template <class STATE_TYPE, class INPUT_TYPE, class OP>
|
|
8992
|
+
static void UnaryUpdate(Vector &input, AggregateInputData &aggr_input_data, data_ptr_t state, idx_t count) {
|
|
8993
|
+
switch (input.GetVectorType()) {
|
|
8994
|
+
case VectorType::CONSTANT_VECTOR: {
|
|
8995
|
+
if (OP::IgnoreNull() && ConstantVector::IsNull(input)) {
|
|
8996
|
+
return;
|
|
8997
|
+
}
|
|
8998
|
+
auto idata = ConstantVector::GetData<INPUT_TYPE>(input);
|
|
8999
|
+
OP::template ConstantOperation<INPUT_TYPE, STATE_TYPE, OP>((STATE_TYPE *)state, aggr_input_data, idata,
|
|
9000
|
+
ConstantVector::Validity(input), count);
|
|
9001
|
+
break;
|
|
9002
|
+
}
|
|
9003
|
+
case VectorType::FLAT_VECTOR: {
|
|
9004
|
+
auto idata = FlatVector::GetData<INPUT_TYPE>(input);
|
|
9005
|
+
UnaryFlatUpdateLoop<STATE_TYPE, INPUT_TYPE, OP>(idata, aggr_input_data, (STATE_TYPE *)state, count,
|
|
9006
|
+
FlatVector::Validity(input));
|
|
9007
|
+
break;
|
|
9008
|
+
}
|
|
9009
|
+
default: {
|
|
9010
|
+
VectorData idata;
|
|
9011
|
+
input.Orrify(count, idata);
|
|
9012
|
+
UnaryUpdateLoop<STATE_TYPE, INPUT_TYPE, OP>((INPUT_TYPE *)idata.data, aggr_input_data, (STATE_TYPE *)state,
|
|
9013
|
+
count, idata.validity, *idata.sel);
|
|
9014
|
+
break;
|
|
9015
|
+
}
|
|
8993
9016
|
}
|
|
8994
|
-
return max_cardinality;
|
|
8995
9017
|
}
|
|
8996
9018
|
|
|
8997
|
-
|
|
8998
|
-
|
|
8999
|
-
|
|
9000
|
-
};
|
|
9001
|
-
} // namespace duckdb
|
|
9002
|
-
|
|
9003
|
-
|
|
9004
|
-
namespace duckdb {
|
|
9005
|
-
|
|
9006
|
-
struct BoundStatement {
|
|
9007
|
-
unique_ptr<LogicalOperator> plan;
|
|
9008
|
-
vector<LogicalType> types;
|
|
9009
|
-
vector<string> names;
|
|
9010
|
-
};
|
|
9011
|
-
|
|
9012
|
-
} // namespace duckdb
|
|
9013
|
-
|
|
9014
|
-
|
|
9015
|
-
|
|
9016
|
-
|
|
9017
|
-
namespace duckdb {
|
|
9019
|
+
template <class STATE_TYPE, class A_TYPE, class B_TYPE, class OP>
|
|
9020
|
+
static void BinaryScatter(AggregateInputData &aggr_input_data, Vector &a, Vector &b, Vector &states, idx_t count) {
|
|
9021
|
+
VectorData adata, bdata, sdata;
|
|
9018
9022
|
|
|
9019
|
-
|
|
9020
|
-
|
|
9021
|
-
|
|
9022
|
-
explicit BoundResultModifier(ResultModifierType type);
|
|
9023
|
-
virtual ~BoundResultModifier();
|
|
9023
|
+
a.Orrify(count, adata);
|
|
9024
|
+
b.Orrify(count, bdata);
|
|
9025
|
+
states.Orrify(count, sdata);
|
|
9024
9026
|
|
|
9025
|
-
|
|
9026
|
-
|
|
9027
|
+
BinaryScatterLoop<STATE_TYPE, A_TYPE, B_TYPE, OP>((A_TYPE *)adata.data, aggr_input_data, (B_TYPE *)bdata.data,
|
|
9028
|
+
(STATE_TYPE **)sdata.data, count, *adata.sel, *bdata.sel,
|
|
9029
|
+
*sdata.sel, adata.validity, bdata.validity);
|
|
9030
|
+
}
|
|
9027
9031
|
|
|
9028
|
-
|
|
9029
|
-
|
|
9030
|
-
|
|
9031
|
-
BoundOrderByNode(OrderType type, OrderByNullType null_order, unique_ptr<Expression> expression,
|
|
9032
|
-
unique_ptr<BaseStatistics> stats);
|
|
9032
|
+
template <class STATE_TYPE, class A_TYPE, class B_TYPE, class OP>
|
|
9033
|
+
static void BinaryUpdate(AggregateInputData &aggr_input_data, Vector &a, Vector &b, data_ptr_t state, idx_t count) {
|
|
9034
|
+
VectorData adata, bdata;
|
|
9033
9035
|
|
|
9034
|
-
|
|
9035
|
-
|
|
9036
|
-
unique_ptr<Expression> expression;
|
|
9037
|
-
unique_ptr<BaseStatistics> stats;
|
|
9036
|
+
a.Orrify(count, adata);
|
|
9037
|
+
b.Orrify(count, bdata);
|
|
9038
9038
|
|
|
9039
|
-
|
|
9040
|
-
|
|
9041
|
-
|
|
9042
|
-
}
|
|
9039
|
+
BinaryUpdateLoop<STATE_TYPE, A_TYPE, B_TYPE, OP>((A_TYPE *)adata.data, aggr_input_data, (B_TYPE *)bdata.data,
|
|
9040
|
+
(STATE_TYPE *)state, count, *adata.sel, *bdata.sel,
|
|
9041
|
+
adata.validity, bdata.validity);
|
|
9042
|
+
}
|
|
9043
9043
|
|
|
9044
|
-
class
|
|
9045
|
-
|
|
9046
|
-
|
|
9044
|
+
template <class STATE_TYPE, class OP>
|
|
9045
|
+
static void Combine(Vector &source, Vector &target, AggregateInputData &aggr_input_data, idx_t count) {
|
|
9046
|
+
D_ASSERT(source.GetType().id() == LogicalTypeId::POINTER && target.GetType().id() == LogicalTypeId::POINTER);
|
|
9047
|
+
auto sdata = FlatVector::GetData<const STATE_TYPE *>(source);
|
|
9048
|
+
auto tdata = FlatVector::GetData<STATE_TYPE *>(target);
|
|
9047
9049
|
|
|
9048
|
-
|
|
9049
|
-
|
|
9050
|
-
|
|
9051
|
-
|
|
9052
|
-
//! Expression in case limit is not constant
|
|
9053
|
-
unique_ptr<Expression> limit;
|
|
9054
|
-
//! Expression in case limit is not constant
|
|
9055
|
-
unique_ptr<Expression> offset;
|
|
9056
|
-
};
|
|
9050
|
+
for (idx_t i = 0; i < count; i++) {
|
|
9051
|
+
OP::template Combine<STATE_TYPE, OP>(*sdata[i], tdata[i], aggr_input_data);
|
|
9052
|
+
}
|
|
9053
|
+
}
|
|
9057
9054
|
|
|
9058
|
-
class
|
|
9059
|
-
|
|
9060
|
-
|
|
9055
|
+
template <class STATE_TYPE, class RESULT_TYPE, class OP>
|
|
9056
|
+
static void Finalize(Vector &states, AggregateInputData &aggr_input_data, Vector &result, idx_t count,
|
|
9057
|
+
idx_t offset) {
|
|
9058
|
+
if (states.GetVectorType() == VectorType::CONSTANT_VECTOR) {
|
|
9059
|
+
result.SetVectorType(VectorType::CONSTANT_VECTOR);
|
|
9061
9060
|
|
|
9062
|
-
|
|
9063
|
-
|
|
9064
|
-
|
|
9061
|
+
auto sdata = ConstantVector::GetData<STATE_TYPE *>(states);
|
|
9062
|
+
auto rdata = ConstantVector::GetData<RESULT_TYPE>(result);
|
|
9063
|
+
OP::template Finalize<RESULT_TYPE, STATE_TYPE>(result, aggr_input_data, *sdata, rdata,
|
|
9064
|
+
ConstantVector::Validity(result), 0);
|
|
9065
|
+
} else {
|
|
9066
|
+
D_ASSERT(states.GetVectorType() == VectorType::FLAT_VECTOR);
|
|
9067
|
+
result.SetVectorType(VectorType::FLAT_VECTOR);
|
|
9065
9068
|
|
|
9066
|
-
|
|
9067
|
-
|
|
9068
|
-
|
|
9069
|
+
auto sdata = FlatVector::GetData<STATE_TYPE *>(states);
|
|
9070
|
+
auto rdata = FlatVector::GetData<RESULT_TYPE>(result);
|
|
9071
|
+
for (idx_t i = 0; i < count; i++) {
|
|
9072
|
+
OP::template Finalize<RESULT_TYPE, STATE_TYPE>(result, aggr_input_data, sdata[i], rdata,
|
|
9073
|
+
FlatVector::Validity(result), i + offset);
|
|
9074
|
+
}
|
|
9075
|
+
}
|
|
9076
|
+
}
|
|
9069
9077
|
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
|
|
9078
|
+
template <class STATE, class INPUT_TYPE, class RESULT_TYPE, class OP>
|
|
9079
|
+
static void UnaryWindow(Vector &input, const ValidityMask &ifilter, AggregateInputData &aggr_input_data,
|
|
9080
|
+
data_ptr_t state, const FrameBounds &frame, const FrameBounds &prev, Vector &result,
|
|
9081
|
+
idx_t rid, idx_t bias) {
|
|
9073
9082
|
|
|
9074
|
-
|
|
9075
|
-
|
|
9076
|
-
|
|
9083
|
+
auto idata = FlatVector::GetData<const INPUT_TYPE>(input) - bias;
|
|
9084
|
+
const auto &ivalid = FlatVector::Validity(input);
|
|
9085
|
+
OP::template Window<STATE, INPUT_TYPE, RESULT_TYPE>(idata, ifilter, ivalid, aggr_input_data, (STATE *)state,
|
|
9086
|
+
frame, prev, result, rid, bias);
|
|
9087
|
+
}
|
|
9077
9088
|
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
|
|
9081
|
-
|
|
9082
|
-
|
|
9083
|
-
|
|
9084
|
-
|
|
9085
|
-
unique_ptr<Expression> offset;
|
|
9089
|
+
template <class STATE_TYPE, class OP>
|
|
9090
|
+
static void Destroy(Vector &states, idx_t count) {
|
|
9091
|
+
auto sdata = FlatVector::GetData<STATE_TYPE *>(states);
|
|
9092
|
+
for (idx_t i = 0; i < count; i++) {
|
|
9093
|
+
OP::template Destroy<STATE_TYPE>(sdata[i]);
|
|
9094
|
+
}
|
|
9095
|
+
}
|
|
9086
9096
|
};
|
|
9087
9097
|
|
|
9088
9098
|
} // namespace duckdb
|
|
9089
9099
|
|
|
9090
9100
|
|
|
9091
|
-
|
|
9092
9101
|
namespace duckdb {
|
|
9093
9102
|
|
|
9094
9103
|
class BoundAggregateExpression;
|
|
9095
9104
|
|
|
9105
|
+
struct AggregateInputData {
|
|
9106
|
+
AggregateInputData(FunctionData *bind_data_p) : bind_data(bind_data_p) {};
|
|
9107
|
+
FunctionData *bind_data;
|
|
9108
|
+
};
|
|
9109
|
+
|
|
9096
9110
|
//! The type used for sizing hashed aggregate function states
|
|
9097
9111
|
typedef idx_t (*aggregate_size_t)();
|
|
9098
9112
|
//! The type used for initializing hashed aggregate function states
|
|
9099
9113
|
typedef void (*aggregate_initialize_t)(data_ptr_t state);
|
|
9100
9114
|
//! The type used for updating hashed aggregate functions
|
|
9101
|
-
typedef void (*aggregate_update_t)(Vector inputs[],
|
|
9102
|
-
idx_t count);
|
|
9115
|
+
typedef void (*aggregate_update_t)(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count,
|
|
9116
|
+
Vector &state, idx_t count);
|
|
9103
9117
|
//! The type used for combining hashed aggregate states
|
|
9104
|
-
typedef void (*aggregate_combine_t)(Vector &state, Vector &combined,
|
|
9118
|
+
typedef void (*aggregate_combine_t)(Vector &state, Vector &combined, AggregateInputData &aggr_input_data, idx_t count);
|
|
9105
9119
|
//! The type used for finalizing hashed aggregate function payloads
|
|
9106
|
-
typedef void (*aggregate_finalize_t)(Vector &state,
|
|
9120
|
+
typedef void (*aggregate_finalize_t)(Vector &state, AggregateInputData &aggr_input_data, Vector &result, idx_t count,
|
|
9121
|
+
idx_t offset);
|
|
9107
9122
|
//! The type used for propagating statistics in aggregate functions (optional)
|
|
9108
9123
|
typedef unique_ptr<BaseStatistics> (*aggregate_statistics_t)(ClientContext &context, BoundAggregateExpression &expr,
|
|
9109
9124
|
FunctionData *bind_data,
|
|
@@ -9116,14 +9131,15 @@ typedef unique_ptr<FunctionData> (*bind_aggregate_function_t)(ClientContext &con
|
|
|
9116
9131
|
typedef void (*aggregate_destructor_t)(Vector &state, idx_t count);
|
|
9117
9132
|
|
|
9118
9133
|
//! The type used for updating simple (non-grouped) aggregate functions
|
|
9119
|
-
typedef void (*aggregate_simple_update_t)(Vector inputs[],
|
|
9120
|
-
idx_t count);
|
|
9134
|
+
typedef void (*aggregate_simple_update_t)(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count,
|
|
9135
|
+
data_ptr_t state, idx_t count);
|
|
9121
9136
|
|
|
9122
9137
|
//! The type used for updating complex windowed aggregate functions (optional)
|
|
9123
9138
|
typedef std::pair<idx_t, idx_t> FrameBounds;
|
|
9124
|
-
typedef void (*aggregate_window_t)(Vector inputs[], const ValidityMask &filter_mask,
|
|
9125
|
-
idx_t input_count, data_ptr_t state,
|
|
9126
|
-
const FrameBounds &prev, Vector &result, idx_t rid,
|
|
9139
|
+
typedef void (*aggregate_window_t)(Vector inputs[], const ValidityMask &filter_mask,
|
|
9140
|
+
AggregateInputData &aggr_input_data, idx_t input_count, data_ptr_t state,
|
|
9141
|
+
const FrameBounds &frame, const FrameBounds &prev, Vector &result, idx_t rid,
|
|
9142
|
+
idx_t bias);
|
|
9127
9143
|
|
|
9128
9144
|
class AggregateFunction : public BaseScalarFunction {
|
|
9129
9145
|
public:
|
|
@@ -9262,64 +9278,66 @@ public:
|
|
|
9262
9278
|
}
|
|
9263
9279
|
|
|
9264
9280
|
template <class STATE, class OP>
|
|
9265
|
-
static void NullaryScatterUpdate(Vector inputs[],
|
|
9266
|
-
idx_t count) {
|
|
9281
|
+
static void NullaryScatterUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count,
|
|
9282
|
+
Vector &states, idx_t count) {
|
|
9267
9283
|
D_ASSERT(input_count == 0);
|
|
9268
|
-
AggregateExecutor::NullaryScatter<STATE, OP>(states,
|
|
9284
|
+
AggregateExecutor::NullaryScatter<STATE, OP>(states, aggr_input_data, count);
|
|
9269
9285
|
}
|
|
9270
9286
|
|
|
9271
9287
|
template <class STATE, class OP>
|
|
9272
|
-
static void NullaryUpdate(Vector inputs[],
|
|
9288
|
+
static void NullaryUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, data_ptr_t state,
|
|
9273
9289
|
idx_t count) {
|
|
9274
9290
|
D_ASSERT(input_count == 0);
|
|
9275
|
-
AggregateExecutor::NullaryUpdate<STATE, OP>(state,
|
|
9291
|
+
AggregateExecutor::NullaryUpdate<STATE, OP>(state, aggr_input_data, count);
|
|
9276
9292
|
}
|
|
9277
9293
|
|
|
9278
9294
|
template <class STATE, class T, class OP>
|
|
9279
|
-
static void UnaryScatterUpdate(Vector inputs[],
|
|
9280
|
-
idx_t count) {
|
|
9295
|
+
static void UnaryScatterUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count,
|
|
9296
|
+
Vector &states, idx_t count) {
|
|
9281
9297
|
D_ASSERT(input_count == 1);
|
|
9282
|
-
AggregateExecutor::UnaryScatter<STATE, T, OP>(inputs[0], states,
|
|
9298
|
+
AggregateExecutor::UnaryScatter<STATE, T, OP>(inputs[0], states, aggr_input_data, count);
|
|
9283
9299
|
}
|
|
9284
9300
|
|
|
9285
9301
|
template <class STATE, class INPUT_TYPE, class OP>
|
|
9286
|
-
static void UnaryUpdate(Vector inputs[],
|
|
9302
|
+
static void UnaryUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, data_ptr_t state,
|
|
9287
9303
|
idx_t count) {
|
|
9288
9304
|
D_ASSERT(input_count == 1);
|
|
9289
|
-
AggregateExecutor::UnaryUpdate<STATE, INPUT_TYPE, OP>(inputs[0],
|
|
9305
|
+
AggregateExecutor::UnaryUpdate<STATE, INPUT_TYPE, OP>(inputs[0], aggr_input_data, state, count);
|
|
9290
9306
|
}
|
|
9291
9307
|
|
|
9292
9308
|
template <class STATE, class INPUT_TYPE, class RESULT_TYPE, class OP>
|
|
9293
|
-
static void UnaryWindow(Vector inputs[], const ValidityMask &filter_mask,
|
|
9309
|
+
static void UnaryWindow(Vector inputs[], const ValidityMask &filter_mask, AggregateInputData &aggr_input_data,
|
|
9294
9310
|
idx_t input_count, data_ptr_t state, const FrameBounds &frame, const FrameBounds &prev,
|
|
9295
9311
|
Vector &result, idx_t rid, idx_t bias) {
|
|
9296
9312
|
D_ASSERT(input_count == 1);
|
|
9297
|
-
AggregateExecutor::UnaryWindow<STATE, INPUT_TYPE, RESULT_TYPE, OP>(inputs[0], filter_mask,
|
|
9298
|
-
frame, prev, result, rid, bias);
|
|
9313
|
+
AggregateExecutor::UnaryWindow<STATE, INPUT_TYPE, RESULT_TYPE, OP>(inputs[0], filter_mask, aggr_input_data,
|
|
9314
|
+
state, frame, prev, result, rid, bias);
|
|
9299
9315
|
}
|
|
9300
9316
|
|
|
9301
9317
|
template <class STATE, class A_TYPE, class B_TYPE, class OP>
|
|
9302
|
-
static void BinaryScatterUpdate(Vector inputs[],
|
|
9303
|
-
idx_t count) {
|
|
9318
|
+
static void BinaryScatterUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count,
|
|
9319
|
+
Vector &states, idx_t count) {
|
|
9304
9320
|
D_ASSERT(input_count == 2);
|
|
9305
|
-
AggregateExecutor::BinaryScatter<STATE, A_TYPE, B_TYPE, OP>(
|
|
9321
|
+
AggregateExecutor::BinaryScatter<STATE, A_TYPE, B_TYPE, OP>(aggr_input_data, inputs[0], inputs[1], states,
|
|
9322
|
+
count);
|
|
9306
9323
|
}
|
|
9307
9324
|
|
|
9308
9325
|
template <class STATE, class A_TYPE, class B_TYPE, class OP>
|
|
9309
|
-
static void BinaryUpdate(Vector inputs[],
|
|
9326
|
+
static void BinaryUpdate(Vector inputs[], AggregateInputData &aggr_input_data, idx_t input_count, data_ptr_t state,
|
|
9310
9327
|
idx_t count) {
|
|
9311
9328
|
D_ASSERT(input_count == 2);
|
|
9312
|
-
AggregateExecutor::BinaryUpdate<STATE, A_TYPE, B_TYPE, OP>(
|
|
9329
|
+
AggregateExecutor::BinaryUpdate<STATE, A_TYPE, B_TYPE, OP>(aggr_input_data, inputs[0], inputs[1], state, count);
|
|
9313
9330
|
}
|
|
9314
9331
|
|
|
9315
9332
|
template <class STATE, class OP>
|
|
9316
|
-
static void StateCombine(Vector &source, Vector &target,
|
|
9317
|
-
AggregateExecutor::Combine<STATE, OP>(source, target,
|
|
9333
|
+
static void StateCombine(Vector &source, Vector &target, AggregateInputData &aggr_input_data, idx_t count) {
|
|
9334
|
+
AggregateExecutor::Combine<STATE, OP>(source, target, aggr_input_data, count);
|
|
9318
9335
|
}
|
|
9319
9336
|
|
|
9320
9337
|
template <class STATE, class RESULT_TYPE, class OP>
|
|
9321
|
-
static void StateFinalize(Vector &states,
|
|
9322
|
-
|
|
9338
|
+
static void StateFinalize(Vector &states, AggregateInputData &aggr_input_data, Vector &result, idx_t count,
|
|
9339
|
+
idx_t offset) {
|
|
9340
|
+
AggregateExecutor::Finalize<STATE, RESULT_TYPE, OP>(states, aggr_input_data, result, count, offset);
|
|
9323
9341
|
}
|
|
9324
9342
|
|
|
9325
9343
|
template <class STATE, class OP>
|