duckdb 0.3.3-dev1217.0 → 0.3.3-dev1232.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/src/duckdb.cpp CHANGED
@@ -5307,15 +5307,19 @@ int ResultArrowArrayStreamWrapper::MyStreamGetNext(struct ArrowArrayStream *stre
5307
5307
  out->release = nullptr;
5308
5308
  return 0;
5309
5309
  }
5310
- while (chunk_result->size() < my_stream->batch_size) {
5310
+ unique_ptr<DataChunk> agg_chunk_result = make_unique<DataChunk>();
5311
+ agg_chunk_result->Initialize(chunk_result->GetTypes());
5312
+ agg_chunk_result->Append(*chunk_result, true);
5313
+
5314
+ while (agg_chunk_result->size() < my_stream->batch_size) {
5311
5315
  auto new_chunk = result.Fetch();
5312
5316
  if (!new_chunk) {
5313
5317
  break;
5314
5318
  } else {
5315
- chunk_result->Append(*new_chunk, true);
5319
+ agg_chunk_result->Append(*new_chunk, true);
5316
5320
  }
5317
5321
  }
5318
- chunk_result->ToArrowArray(out);
5322
+ agg_chunk_result->ToArrowArray(out);
5319
5323
  return 0;
5320
5324
  }
5321
5325
 
@@ -26367,17 +26371,20 @@ template <class OP, bool NO_MATCH_SEL>
26367
26371
  static void TemplatedMatchNested(Vector &col, Vector &rows, const idx_t vcount, SelectionVector &sel, idx_t &count,
26368
26372
  const idx_t col_offset, const idx_t col_no, SelectionVector *no_match,
26369
26373
  idx_t &no_match_count) {
26370
- // Gather a scattered Vector containing the column values being matched
26374
+ // Gather a dense Vector containing the column values being matched
26371
26375
  Vector key(col.GetType());
26372
- RowOperations::Gather(rows, sel, key, sel, count, col_offset, col_no);
26376
+ RowOperations::Gather(rows, sel, key, *FlatVector::IncrementalSelectionVector(), count, col_offset, col_no);
26377
+
26378
+ // Densify the input column
26379
+ Vector sliced(col, sel, count);
26373
26380
 
26374
26381
  if (NO_MATCH_SEL) {
26375
26382
  SelectionVector no_match_sel_offset(no_match->data() + no_match_count);
26376
- auto match_count = SelectComparison<OP>(col, key, vcount, sel, count, &sel, &no_match_sel_offset);
26383
+ auto match_count = SelectComparison<OP>(sliced, key, count, sel, count, &sel, &no_match_sel_offset);
26377
26384
  no_match_count += count - match_count;
26378
26385
  count = match_count;
26379
26386
  } else {
26380
- count = SelectComparison<OP>(col, key, vcount, sel, count, &sel, nullptr);
26387
+ count = SelectComparison<OP>(sliced, key, count, sel, count, &sel, nullptr);
26381
26388
  }
26382
26389
  }
26383
26390
 
@@ -43436,9 +43443,13 @@ static idx_t DistinctSelect(Vector &left, Vector &right, idx_t vcount, const Sel
43436
43443
  }
43437
43444
 
43438
43445
  template <class OP>
43439
- static idx_t DistinctSelectNotNull(VectorData &lvdata, VectorData &rvdata, const idx_t count, idx_t &true_count,
43440
- const SelectionVector &sel, SelectionVector &maybe_vec, OptionalSelection &true_vec,
43441
- OptionalSelection &false_vec) {
43446
+ static idx_t DistinctSelectNotNull(Vector &left, Vector &right, const idx_t count, idx_t &true_count,
43447
+ const SelectionVector &sel, SelectionVector &maybe_vec, OptionalSelection &true_opt,
43448
+ OptionalSelection &false_opt) {
43449
+ VectorData lvdata, rvdata;
43450
+ left.Orrify(count, lvdata);
43451
+ right.Orrify(count, rvdata);
43452
+
43442
43453
  auto &lmask = lvdata.validity;
43443
43454
  auto &rmask = rvdata.validity;
43444
43455
 
@@ -43452,39 +43463,39 @@ static idx_t DistinctSelectNotNull(VectorData &lvdata, VectorData &rvdata, const
43452
43463
  return remaining;
43453
43464
  }
43454
43465
 
43466
+ // Slice the Vectors down to the rows that are not determined (i.e., neither is NULL)
43467
+ SelectionVector slicer(count);
43468
+ true_count = 0;
43455
43469
  idx_t false_count = 0;
43456
43470
  for (idx_t i = 0; i < count; ++i) {
43457
- const auto idx = sel.get_index(i);
43458
- const auto lidx = lvdata.sel->get_index(idx);
43459
- const auto ridx = rvdata.sel->get_index(idx);
43471
+ const auto result_idx = sel.get_index(i);
43472
+ const auto lidx = lvdata.sel->get_index(i);
43473
+ const auto ridx = rvdata.sel->get_index(i);
43460
43474
  const auto lnull = !lmask.RowIsValid(lidx);
43461
43475
  const auto rnull = !rmask.RowIsValid(ridx);
43462
43476
  if (lnull || rnull) {
43463
43477
  // If either is NULL then we can major distinguish them
43464
43478
  if (!OP::Operation(false, false, lnull, rnull)) {
43465
- false_vec.Append(false_count, idx);
43479
+ false_opt.Append(false_count, result_idx);
43466
43480
  } else {
43467
- true_vec.Append(true_count, idx);
43481
+ true_opt.Append(true_count, result_idx);
43468
43482
  }
43469
43483
  } else {
43470
43484
  // Neither is NULL, distinguish values.
43471
- maybe_vec.set_index(remaining++, idx);
43485
+ slicer.set_index(remaining, i);
43486
+ maybe_vec.set_index(remaining++, result_idx);
43472
43487
  }
43473
43488
  }
43474
- true_vec.Advance(true_count);
43475
- false_vec.Advance(false_count);
43476
43489
 
43477
- return remaining;
43478
- }
43490
+ true_opt.Advance(true_count);
43491
+ false_opt.Advance(false_count);
43479
43492
 
43480
- template <bool DENSE>
43481
- static inline void ScatterSelection(SelectionVector *target, const idx_t count, const SelectionVector &sel,
43482
- const SelectionVector &dense_vec) {
43483
- if (DENSE && target) {
43484
- for (idx_t i = 0; i < count; ++i) {
43485
- target->set_index(i, sel.get_index(dense_vec.get_index(i)));
43486
- }
43493
+ if (remaining && remaining < count) {
43494
+ left.Slice(slicer, remaining);
43495
+ right.Slice(slicer, remaining);
43487
43496
  }
43497
+
43498
+ return remaining;
43488
43499
  }
43489
43500
 
43490
43501
  struct PositionComparator {
@@ -43616,26 +43627,70 @@ static StructEntries &StructVectorGetSlicedEntries(Vector &parent, StructEntries
43616
43627
  return children;
43617
43628
  }
43618
43629
 
43630
+ static void ExtractNestedSelection(const SelectionVector &slice_sel, const idx_t count, const SelectionVector &sel,
43631
+ OptionalSelection &opt) {
43632
+
43633
+ for (idx_t i = 0; i < count;) {
43634
+ const auto slice_idx = slice_sel.get_index(i);
43635
+ const auto result_idx = sel.get_index(slice_idx);
43636
+ opt.Append(i, result_idx);
43637
+ }
43638
+ opt.Advance(count);
43639
+ }
43640
+
43641
+ static void DensifyNestedSelection(const SelectionVector &dense_sel, const idx_t count, SelectionVector &slice_sel) {
43642
+ for (idx_t i = 0; i < count; ++i) {
43643
+ slice_sel.set_index(i, dense_sel.get_index(i));
43644
+ }
43645
+ }
43646
+
43619
43647
  template <class OP>
43620
- static idx_t DistinctSelectStruct(Vector &left, Vector &right, idx_t vcount, VectorData &lvdata, VectorData &rvdata,
43621
- idx_t count, SelectionVector &maybe_vec, OptionalSelection &true_opt,
43622
- OptionalSelection &false_opt) {
43648
+ static idx_t DistinctSelectStruct(Vector &left, Vector &right, idx_t count, const SelectionVector &sel,
43649
+ OptionalSelection &true_opt, OptionalSelection &false_opt) {
43650
+ if (count == 0) {
43651
+ return 0;
43652
+ }
43653
+
43623
43654
  // Avoid allocating in the 99% of the cases where we don't need to.
43624
43655
  StructEntries lsliced, rsliced;
43625
- auto &lchildren = StructVectorGetSlicedEntries(left, lsliced, vcount);
43626
- auto &rchildren = StructVectorGetSlicedEntries(right, rsliced, vcount);
43656
+ auto &lchildren = StructVectorGetSlicedEntries(left, lsliced, count);
43657
+ auto &rchildren = StructVectorGetSlicedEntries(right, rsliced, count);
43627
43658
  D_ASSERT(lchildren.size() == rchildren.size());
43628
43659
 
43660
+ // In order to reuse the comparators, we have to track what passed and failed internally.
43661
+ // To do that, we need local SVs that we then merge back into the real ones after every pass.
43662
+ const auto vcount = count;
43663
+ SelectionVector slice_sel(count);
43664
+ for (idx_t i = 0; i < count; ++i) {
43665
+ slice_sel.set_index(i, i);
43666
+ }
43667
+
43668
+ SelectionVector true_sel(count);
43669
+ SelectionVector false_sel(count);
43670
+
43629
43671
  idx_t match_count = 0;
43630
43672
  for (idx_t col_no = 0; col_no < lchildren.size(); ++col_no) {
43631
- auto &lchild = *lchildren[col_no];
43632
- auto &rchild = *rchildren[col_no];
43673
+ // Slice the children to maintain density
43674
+ Vector lchild(*lchildren[col_no]);
43675
+ lchild.Normalify(vcount);
43676
+ lchild.Slice(slice_sel, count);
43677
+
43678
+ Vector rchild(*rchildren[col_no]);
43679
+ rchild.Normalify(vcount);
43680
+ rchild.Slice(slice_sel, count);
43633
43681
 
43634
43682
  // Find everything that definitely matches
43635
43683
  auto true_count =
43636
- PositionComparator::Definite<OP>(lchild, rchild, vcount, maybe_vec, count, true_opt, maybe_vec);
43684
+ PositionComparator::Definite<OP>(lchild, rchild, count, slice_sel, count, &true_sel, false_sel);
43637
43685
  if (true_count > 0) {
43638
- true_opt.Advance(true_count);
43686
+ auto false_count = count - true_count;
43687
+
43688
+ // Extract the definite matches into the true result
43689
+ ExtractNestedSelection(false_count ? true_sel : slice_sel, true_count, sel, true_opt);
43690
+
43691
+ // Remove the definite matches from the slicing vector
43692
+ DensifyNestedSelection(false_sel, false_count, slice_sel);
43693
+
43639
43694
  match_count += true_count;
43640
43695
  count -= true_count;
43641
43696
  }
@@ -43643,12 +43698,28 @@ static idx_t DistinctSelectStruct(Vector &left, Vector &right, idx_t vcount, Vec
43643
43698
  if (col_no != lchildren.size() - 1) {
43644
43699
  // Find what might match on the next position
43645
43700
  true_count =
43646
- PositionComparator::Possible<OP>(lchild, rchild, vcount, maybe_vec, count, maybe_vec, false_opt);
43701
+ PositionComparator::Possible<OP>(lchild, rchild, count, slice_sel, count, true_sel, &false_sel);
43647
43702
  auto false_count = count - true_count;
43648
- false_opt.Advance(false_count);
43703
+
43704
+ // Extract the definite failures into the false result
43705
+ ExtractNestedSelection(true_count ? false_sel : slice_sel, false_count, sel, false_opt);
43706
+
43707
+ // Remove any definite failures from the slicing vector
43708
+ if (false_count) {
43709
+ DensifyNestedSelection(true_sel, true_count, slice_sel);
43710
+ }
43711
+
43649
43712
  count = true_count;
43650
43713
  } else {
43651
- true_count = PositionComparator::Final<OP>(lchild, rchild, vcount, maybe_vec, count, true_opt, false_opt);
43714
+ true_count = PositionComparator::Final<OP>(lchild, rchild, count, slice_sel, count, &true_sel, &false_sel);
43715
+ auto false_count = count - true_count;
43716
+
43717
+ // Extract the definite matches into the true result
43718
+ ExtractNestedSelection(false_count ? true_sel : slice_sel, true_count, sel, true_opt);
43719
+
43720
+ // Extract the definite failures into the false result
43721
+ ExtractNestedSelection(true_count ? false_sel : slice_sel, false_count, sel, false_opt);
43722
+
43652
43723
  match_count += true_count;
43653
43724
  }
43654
43725
  }
@@ -43657,28 +43728,27 @@ static idx_t DistinctSelectStruct(Vector &left, Vector &right, idx_t vcount, Vec
43657
43728
  }
43658
43729
 
43659
43730
  static void PositionListCursor(SelectionVector &cursor, VectorData &vdata, const idx_t pos,
43660
- const SelectionVector &maybe_vec, const idx_t count) {
43731
+ const SelectionVector &slice_sel, const idx_t count) {
43661
43732
  const auto data = (const list_entry_t *)vdata.data;
43662
43733
  for (idx_t i = 0; i < count; ++i) {
43663
- const auto idx = maybe_vec.get_index(i);
43734
+ const auto slice_idx = slice_sel.get_index(i);
43664
43735
 
43665
- const auto lidx = vdata.sel->get_index(idx);
43736
+ const auto lidx = vdata.sel->get_index(slice_idx);
43666
43737
  const auto &entry = data[lidx];
43667
- cursor.set_index(idx, entry.offset + pos);
43738
+ cursor.set_index(i, entry.offset + pos);
43668
43739
  }
43669
43740
  }
43670
43741
 
43671
43742
  template <class OP>
43672
- static idx_t DistinctSelectList(Vector &left, Vector &right, idx_t vcount, VectorData &lvdata, VectorData &rvdata,
43673
- idx_t count, SelectionVector &maybe_vec, OptionalSelection &true_opt,
43674
- OptionalSelection &false_opt) {
43743
+ static idx_t DistinctSelectList(Vector &left, Vector &right, idx_t count, const SelectionVector &sel,
43744
+ OptionalSelection &true_opt, OptionalSelection &false_opt) {
43675
43745
  if (count == 0) {
43676
43746
  return count;
43677
43747
  }
43678
43748
 
43679
- // We use them to create dictionary views of the children so we can vectorise the positional comparisons.
43680
- SelectionVector lcursor(vcount);
43681
- SelectionVector rcursor(vcount);
43749
+ // Create dictionary views of the children so we can vectorise the positional comparisons.
43750
+ SelectionVector lcursor(count);
43751
+ SelectionVector rcursor(count);
43682
43752
 
43683
43753
  Vector lchild(ListVector::GetEntry(left), lcursor, count);
43684
43754
  Vector rchild(ListVector::GetEntry(right), rcursor, count);
@@ -43696,105 +43766,137 @@ static idx_t DistinctSelectList(Vector &left, Vector &right, idx_t vcount, Vecto
43696
43766
  // ++left, ++right;
43697
43767
  // }
43698
43768
  // }
43769
+
43770
+ // Get pointers to the list entries
43771
+ VectorData lvdata;
43772
+ left.Orrify(count, lvdata);
43699
43773
  const auto ldata = (const list_entry_t *)lvdata.data;
43774
+
43775
+ VectorData rvdata;
43776
+ right.Orrify(count, rvdata);
43700
43777
  const auto rdata = (const list_entry_t *)rvdata.data;
43701
43778
 
43779
+ // In order to reuse the comparators, we have to track what passed and failed internally.
43780
+ // To do that, we need local SVs that we then merge back into the real ones after every pass.
43781
+ SelectionVector slice_sel(count);
43782
+ for (idx_t i = 0; i < count; ++i) {
43783
+ slice_sel.set_index(i, i);
43784
+ }
43785
+
43786
+ SelectionVector true_sel(count);
43787
+ SelectionVector false_sel(count);
43788
+
43702
43789
  idx_t match_count = 0;
43703
43790
  for (idx_t pos = 0; count > 0; ++pos) {
43704
43791
  // Set up the cursors for the current position
43705
- PositionListCursor(lcursor, lvdata, pos, maybe_vec, count);
43706
- PositionListCursor(rcursor, rvdata, pos, maybe_vec, count);
43792
+ PositionListCursor(lcursor, lvdata, pos, slice_sel, count);
43793
+ PositionListCursor(rcursor, rvdata, pos, slice_sel, count);
43707
43794
 
43708
43795
  // Tie-break the pairs where one of the LISTs is exhausted.
43709
43796
  idx_t true_count = 0;
43710
43797
  idx_t false_count = 0;
43711
43798
  idx_t maybe_count = 0;
43712
43799
  for (idx_t i = 0; i < count; ++i) {
43713
- const auto idx = maybe_vec.get_index(i);
43714
- const auto lidx = lvdata.sel->get_index(idx);
43800
+ const auto slice_idx = slice_sel.get_index(i);
43801
+ const auto lidx = lvdata.sel->get_index(slice_idx);
43715
43802
  const auto &lentry = ldata[lidx];
43716
- const auto ridx = rvdata.sel->get_index(idx);
43803
+ const auto ridx = rvdata.sel->get_index(slice_idx);
43717
43804
  const auto &rentry = rdata[ridx];
43718
43805
  if (lentry.length == pos || rentry.length == pos) {
43806
+ const auto idx = sel.get_index(slice_idx);
43719
43807
  if (PositionComparator::TieBreak<OP>(lentry.length, rentry.length)) {
43720
43808
  true_opt.Append(true_count, idx);
43721
43809
  } else {
43722
43810
  false_opt.Append(false_count, idx);
43723
43811
  }
43724
43812
  } else {
43725
- maybe_vec.set_index(maybe_count++, idx);
43813
+ true_sel.set_index(maybe_count++, slice_idx);
43726
43814
  }
43727
43815
  }
43728
43816
  true_opt.Advance(true_count);
43729
43817
  false_opt.Advance(false_count);
43730
- count = maybe_count;
43731
43818
  match_count += true_count;
43732
43819
 
43820
+ // Redensify the list cursors
43821
+ if (maybe_count < count) {
43822
+ count = maybe_count;
43823
+ DensifyNestedSelection(true_sel, count, slice_sel);
43824
+ PositionListCursor(lcursor, lvdata, pos, slice_sel, count);
43825
+ PositionListCursor(rcursor, rvdata, pos, slice_sel, count);
43826
+ }
43827
+
43733
43828
  // Find everything that definitely matches
43734
- true_count = PositionComparator::Definite<OP>(lchild, rchild, vcount, maybe_vec, count, true_opt, maybe_vec);
43735
- true_opt.Advance(true_count);
43736
- match_count += true_count;
43737
- count -= true_count;
43829
+ true_count = PositionComparator::Definite<OP>(lchild, rchild, count, slice_sel, count, &true_sel, false_sel);
43830
+ if (true_count) {
43831
+ false_count = count - true_count;
43832
+ ExtractNestedSelection(false_count ? true_sel : slice_sel, true_count, sel, true_opt);
43833
+ match_count += true_count;
43834
+
43835
+ // Redensify the list cursors
43836
+ count -= true_count;
43837
+ DensifyNestedSelection(false_sel, count, slice_sel);
43838
+ PositionListCursor(lcursor, lvdata, pos, slice_sel, count);
43839
+ PositionListCursor(rcursor, rvdata, pos, slice_sel, count);
43840
+ }
43738
43841
 
43739
43842
  // Find what might match on the next position
43740
- maybe_count = PositionComparator::Possible<OP>(lchild, rchild, vcount, maybe_vec, count, maybe_vec, false_opt);
43741
- false_count = count - maybe_count;
43742
- false_opt.Advance(false_count);
43743
- count = maybe_count;
43843
+ true_count = PositionComparator::Possible<OP>(lchild, rchild, count, slice_sel, count, true_sel, &false_sel);
43844
+ false_count = count - true_count;
43845
+ ExtractNestedSelection(true_count ? false_sel : slice_sel, false_count, sel, false_opt);
43846
+
43847
+ if (false_count) {
43848
+ DensifyNestedSelection(true_sel, true_count, slice_sel);
43849
+ }
43850
+ count = true_count;
43744
43851
  }
43745
43852
 
43746
43853
  return match_count;
43747
43854
  }
43748
43855
 
43749
- template <class OP, bool DENSE, class OPNESTED>
43750
- static idx_t DistinctSelectNested(Vector &left, Vector &right, idx_t vcount, const SelectionVector *sel, idx_t count,
43856
+ template <class OP, class OPNESTED>
43857
+ static idx_t DistinctSelectNested(Vector &left, Vector &right, const SelectionVector *sel, const idx_t count,
43751
43858
  SelectionVector *true_sel, SelectionVector *false_sel) {
43752
- // We need multiple, real selections
43859
+ // The Select operations all use a dense pair of input vectors to partition
43860
+ // a selection vector in a single pass. But to implement progressive comparisons,
43861
+ // we have to make multiple passes, so we need to keep track of the original input positions
43862
+ // and then scatter the output selections when we are done.
43753
43863
  SelectionVector owned_sel;
43754
43864
  if (!sel) {
43755
43865
  sel = FlatVector::IncrementalSelectionVector(count, owned_sel);
43756
43866
  }
43757
43867
 
43758
- SelectionVector true_vec;
43759
- SelectionVector false_vec;
43760
- if (DENSE) {
43761
- true_vec.Initialize(vcount);
43762
- false_vec.Initialize(vcount);
43763
- }
43868
+ // Make buffered selections for progressive comparisons
43869
+ // TODO: Remove unnecessary allocations
43870
+ SelectionVector true_vec(count);
43871
+ OptionalSelection true_opt(&true_vec);
43764
43872
 
43765
- OptionalSelection true_opt(DENSE ? &true_vec : true_sel);
43766
- OptionalSelection false_opt(DENSE ? &false_vec : false_sel);
43873
+ SelectionVector false_vec(count);
43874
+ OptionalSelection false_opt(&false_vec);
43767
43875
 
43768
- // Handle NULL STRUCTs
43769
- VectorData lvdata, rvdata;
43770
- left.Orrify(vcount, lvdata);
43771
- right.Orrify(vcount, rvdata);
43876
+ SelectionVector maybe_vec(count);
43877
+
43878
+ // Handle NULL nested values
43879
+ Vector l_not_null(left);
43880
+ Vector r_not_null(right);
43772
43881
 
43773
- sel_t maybe_one;
43774
- SelectionVector maybe_vec(&maybe_one);
43775
- if (count > 1) {
43776
- maybe_vec.Initialize(count);
43777
- }
43778
43882
  idx_t match_count = 0;
43779
- idx_t no_match_count = count;
43780
- count = DistinctSelectNotNull<OP>(lvdata, rvdata, count, match_count, *sel, maybe_vec, true_opt, false_opt);
43781
- no_match_count -= (count + match_count);
43883
+ auto unknown =
43884
+ DistinctSelectNotNull<OP>(l_not_null, r_not_null, count, match_count, *sel, maybe_vec, true_opt, false_opt);
43782
43885
 
43783
- idx_t true_count = 0;
43784
43886
  if (PhysicalType::LIST == left.GetType().InternalType()) {
43785
- true_count =
43786
- DistinctSelectList<OPNESTED>(left, right, vcount, lvdata, rvdata, count, maybe_vec, true_opt, false_opt);
43887
+ match_count += DistinctSelectList<OPNESTED>(l_not_null, r_not_null, unknown, maybe_vec, true_opt, false_opt);
43787
43888
  } else {
43788
- true_count =
43789
- DistinctSelectStruct<OPNESTED>(left, right, vcount, lvdata, rvdata, count, maybe_vec, true_opt, false_opt);
43889
+ match_count += DistinctSelectStruct<OPNESTED>(l_not_null, r_not_null, unknown, maybe_vec, true_opt, false_opt);
43790
43890
  }
43791
43891
 
43792
- auto false_count = count - true_count;
43793
- match_count += true_count;
43794
- no_match_count += false_count;
43892
+ // Copy the buffered selections to the output selections
43893
+ if (true_sel) {
43894
+ DensifyNestedSelection(true_vec, match_count, *true_sel);
43895
+ }
43795
43896
 
43796
- ScatterSelection<DENSE>(true_sel, match_count, *sel, true_vec);
43797
- ScatterSelection<DENSE>(false_sel, no_match_count, *sel, false_vec);
43897
+ if (false_sel) {
43898
+ DensifyNestedSelection(false_vec, count - match_count, *false_sel);
43899
+ }
43798
43900
 
43799
43901
  return match_count;
43800
43902
  }
@@ -43896,7 +43998,7 @@ static idx_t TemplatedDistinctSelectOperation(Vector &left, Vector &right, idx_t
43896
43998
  case PhysicalType::MAP:
43897
43999
  case PhysicalType::STRUCT:
43898
44000
  case PhysicalType::LIST:
43899
- return DistinctSelectNested<OP, DENSE, OPNESTED>(left, right, vcount, sel, count, true_sel, false_sel);
44001
+ return DistinctSelectNested<OP, OPNESTED>(left, right, sel, count, true_sel, false_sel);
43900
44002
  default:
43901
44003
  throw InternalException("Invalid type for distinct selection");
43902
44004
  }
@@ -44004,38 +44106,38 @@ idx_t VectorOperations::DistinctLessThanEquals(Vector &left, Vector &right, cons
44004
44106
  // true := A != B with nulls being equal, inputs selected
44005
44107
  idx_t VectorOperations::NestedNotEquals(Vector &left, Vector &right, idx_t vcount, const SelectionVector &sel,
44006
44108
  idx_t count, SelectionVector *true_sel, SelectionVector *false_sel) {
44007
- return TemplatedDistinctSelectOperation<duckdb::DistinctFrom, false>(left, right, vcount, &sel, count, true_sel,
44008
- false_sel);
44109
+ return TemplatedDistinctSelectOperation<duckdb::DistinctFrom, true>(left, right, vcount, &sel, count, true_sel,
44110
+ false_sel);
44009
44111
  }
44010
44112
  // true := A == B with nulls being equal, inputs selected
44011
44113
  idx_t VectorOperations::NestedEquals(Vector &left, Vector &right, idx_t vcount, const SelectionVector &sel, idx_t count,
44012
44114
  SelectionVector *true_sel, SelectionVector *false_sel) {
44013
- return TemplatedDistinctSelectOperation<duckdb::NotDistinctFrom, false>(left, right, vcount, &sel, count, true_sel,
44014
- false_sel);
44115
+ return TemplatedDistinctSelectOperation<duckdb::NotDistinctFrom, true>(left, right, vcount, &sel, count, true_sel,
44116
+ false_sel);
44015
44117
  }
44016
44118
  // true := A > B with nulls being maximal, inputs selected
44017
44119
  idx_t VectorOperations::NestedGreaterThan(Vector &left, Vector &right, idx_t vcount, const SelectionVector &sel,
44018
44120
  idx_t count, SelectionVector *true_sel, SelectionVector *false_sel) {
44019
- return TemplatedDistinctSelectOperation<duckdb::DistinctGreaterThan, false>(left, right, vcount, &sel, count,
44020
- true_sel, false_sel);
44121
+ return TemplatedDistinctSelectOperation<duckdb::DistinctGreaterThan, true>(left, right, vcount, &sel, count,
44122
+ true_sel, false_sel);
44021
44123
  }
44022
44124
  // true := A >= B with nulls being maximal, inputs selected
44023
44125
  idx_t VectorOperations::NestedGreaterThanEquals(Vector &left, Vector &right, idx_t vcount, const SelectionVector &sel,
44024
44126
  idx_t count, SelectionVector *true_sel, SelectionVector *false_sel) {
44025
- return TemplatedDistinctSelectOperation<duckdb::DistinctGreaterThanEquals, false>(left, right, vcount, &sel, count,
44026
- true_sel, false_sel);
44127
+ return TemplatedDistinctSelectOperation<duckdb::DistinctGreaterThanEquals, true>(left, right, vcount, &sel, count,
44128
+ true_sel, false_sel);
44027
44129
  }
44028
44130
  // true := A < B with nulls being maximal, inputs selected
44029
44131
  idx_t VectorOperations::NestedLessThan(Vector &left, Vector &right, idx_t vcount, const SelectionVector &sel,
44030
44132
  idx_t count, SelectionVector *true_sel, SelectionVector *false_sel) {
44031
- return TemplatedDistinctSelectOperation<duckdb::DistinctLessThan, false>(left, right, vcount, &sel, count, true_sel,
44032
- false_sel);
44133
+ return TemplatedDistinctSelectOperation<duckdb::DistinctLessThan, true>(left, right, vcount, &sel, count, true_sel,
44134
+ false_sel);
44033
44135
  }
44034
44136
  // true := A <= B with nulls being maximal, inputs selected
44035
44137
  idx_t VectorOperations::NestedLessThanEquals(Vector &left, Vector &right, idx_t vcount, const SelectionVector &sel,
44036
44138
  idx_t count, SelectionVector *true_sel, SelectionVector *false_sel) {
44037
- return TemplatedDistinctSelectOperation<duckdb::DistinctLessThanEquals, false>(left, right, vcount, &sel, count,
44038
- true_sel, false_sel);
44139
+ return TemplatedDistinctSelectOperation<duckdb::DistinctLessThanEquals, true>(left, right, vcount, &sel, count,
44140
+ true_sel, false_sel);
44039
44141
  }
44040
44142
 
44041
44143
  } // namespace duckdb
@@ -48171,45 +48273,63 @@ idx_t NestedSelector::Select<duckdb::GreaterThanEquals>(Vector &left, Vector &ri
48171
48273
  return VectorOperations::NestedGreaterThanEquals(left, right, vcount, sel, count, true_sel, false_sel);
48172
48274
  }
48173
48275
 
48174
- static inline idx_t SelectNotNull(VectorData &lvdata, VectorData &rvdata, const idx_t count,
48175
- OptionalSelection &false_vec, SelectionVector &maybe_vec) {
48276
+ static inline idx_t SelectNotNull(Vector &left, Vector &right, const idx_t count, const SelectionVector &sel,
48277
+ SelectionVector &maybe_vec, OptionalSelection &false_opt) {
48278
+
48279
+ VectorData lvdata, rvdata;
48280
+ left.Orrify(count, lvdata);
48281
+ right.Orrify(count, rvdata);
48282
+
48283
+ auto &lmask = lvdata.validity;
48284
+ auto &rmask = rvdata.validity;
48176
48285
 
48177
48286
  // For top-level comparisons, NULL semantics are in effect,
48178
48287
  // so filter out any NULLs
48179
- if (!lvdata.validity.AllValid() || !rvdata.validity.AllValid()) {
48180
- idx_t true_count = 0;
48181
- idx_t false_count = 0;
48288
+ idx_t remaining = 0;
48289
+ if (lmask.AllValid() && rmask.AllValid()) {
48290
+ // None are NULL, distinguish values.
48182
48291
  for (idx_t i = 0; i < count; ++i) {
48183
- const auto lidx = lvdata.sel->get_index(i);
48184
- const auto ridx = rvdata.sel->get_index(i);
48185
- if (!lvdata.validity.RowIsValid(lidx) || !rvdata.validity.RowIsValid(ridx)) {
48186
- false_vec.Append(false_count, i);
48187
- } else {
48188
- maybe_vec.set_index(true_count++, i);
48189
- }
48292
+ const auto idx = sel.get_index(i);
48293
+ maybe_vec.set_index(remaining++, idx);
48190
48294
  }
48191
- false_vec.Advance(false_count);
48295
+ return remaining;
48296
+ }
48192
48297
 
48193
- return true_count;
48194
- } else {
48195
- for (idx_t i = 0; i < count; ++i) {
48196
- maybe_vec.set_index(i, i);
48298
+ // Slice the Vectors down to the rows that are not determined (i.e., neither is NULL)
48299
+ SelectionVector slicer(count);
48300
+ idx_t false_count = 0;
48301
+ for (idx_t i = 0; i < count; ++i) {
48302
+ const auto result_idx = sel.get_index(i);
48303
+ const auto lidx = lvdata.sel->get_index(i);
48304
+ const auto ridx = rvdata.sel->get_index(i);
48305
+ if (!lmask.RowIsValid(lidx) || !rmask.RowIsValid(ridx)) {
48306
+ false_opt.Append(false_count, result_idx);
48307
+ } else {
48308
+ // Neither is NULL, distinguish values.
48309
+ slicer.set_index(remaining, i);
48310
+ maybe_vec.set_index(remaining++, result_idx);
48197
48311
  }
48198
- return count;
48199
48312
  }
48313
+ false_opt.Advance(false_count);
48314
+
48315
+ if (remaining && remaining < count) {
48316
+ left.Slice(slicer, remaining);
48317
+ right.Slice(slicer, remaining);
48318
+ }
48319
+
48320
+ return remaining;
48200
48321
  }
48201
48322
 
48202
- static void ScatterSelection(SelectionVector *target, const idx_t count, const SelectionVector *sel,
48203
- const SelectionVector &dense_vec) {
48323
+ static void ScatterSelection(SelectionVector *target, const idx_t count, const SelectionVector &dense_vec) {
48204
48324
  if (target) {
48205
48325
  for (idx_t i = 0; i < count; ++i) {
48206
- target->set_index(i, sel->get_index(dense_vec.get_index(i)));
48326
+ target->set_index(i, dense_vec.get_index(i));
48207
48327
  }
48208
48328
  }
48209
48329
  }
48210
48330
 
48211
48331
  template <typename OP>
48212
- static idx_t NestedSelectOperation(Vector &left, Vector &right, const SelectionVector *sel, idx_t vcount,
48332
+ static idx_t NestedSelectOperation(Vector &left, Vector &right, const SelectionVector *sel, idx_t count,
48213
48333
  SelectionVector *true_sel, SelectionVector *false_sel) {
48214
48334
  // The Select operations all use a dense pair of input vectors to partition
48215
48335
  // a selection vector in a single pass. But to implement progressive comparisons,
@@ -48217,47 +48337,34 @@ static idx_t NestedSelectOperation(Vector &left, Vector &right, const SelectionV
48217
48337
  // and then scatter the output selections when we are done.
48218
48338
  SelectionVector owned_sel;
48219
48339
  if (!sel) {
48220
- sel = FlatVector::IncrementalSelectionVector(vcount, owned_sel);
48340
+ sel = FlatVector::IncrementalSelectionVector(count, owned_sel);
48221
48341
  }
48222
48342
 
48223
- VectorData lvdata, rvdata;
48224
- left.Orrify(vcount, lvdata);
48225
- right.Orrify(vcount, rvdata);
48226
-
48227
- // Make real selections for progressive comparisons
48228
- SelectionVector true_vec(vcount);
48343
+ // Make buffered selections for progressive comparisons
48344
+ // TODO: Remove unnecessary allocations
48345
+ SelectionVector true_vec(count);
48229
48346
  OptionalSelection true_opt(&true_vec);
48230
48347
 
48231
- SelectionVector false_vec(vcount);
48348
+ SelectionVector false_vec(count);
48232
48349
  OptionalSelection false_opt(&false_vec);
48233
48350
 
48234
- SelectionVector maybe_vec(vcount);
48235
- auto count = SelectNotNull(lvdata, rvdata, vcount, false_opt, maybe_vec);
48236
- auto no_match_count = vcount - count;
48351
+ SelectionVector maybe_vec(count);
48237
48352
 
48238
- // If everything was NULL, fill in false_sel with sel
48239
- if (count == 0) {
48240
- SelectionVector owned_flat_sel;
48241
- auto flat_sel = FlatVector::IncrementalSelectionVector(vcount, owned_sel);
48242
- ScatterSelection(false_sel, no_match_count, sel, *flat_sel);
48243
- return count;
48244
- }
48353
+ // Handle NULL nested values
48354
+ Vector l_not_null(left);
48355
+ Vector r_not_null(right);
48356
+
48357
+ auto match_count = SelectNotNull(l_not_null, r_not_null, count, *sel, maybe_vec, false_opt);
48358
+ auto no_match_count = count - match_count;
48359
+ count = match_count;
48245
48360
 
48246
48361
  // Now that we have handled the NULLs, we can use the recursive nested comparator for the rest.
48247
- auto match_count = NestedSelector::Select<OP>(left, right, vcount, maybe_vec, count, true_opt, false_opt);
48362
+ match_count = NestedSelector::Select<OP>(l_not_null, r_not_null, count, maybe_vec, count, true_opt, false_opt);
48248
48363
  no_match_count += (count - match_count);
48249
48364
 
48250
- // Sort the optional selections if we would overwrite.
48251
- if (true_sel == sel) {
48252
- std::sort(true_vec.data(), true_vec.data() + match_count);
48253
- }
48254
- if (false_sel == sel) {
48255
- std::sort(false_vec.data(), false_vec.data() + no_match_count);
48256
- }
48257
-
48258
- // Scatter the original selection to the output selections
48259
- ScatterSelection(true_sel, match_count, sel, true_vec);
48260
- ScatterSelection(false_sel, no_match_count, sel, false_vec);
48365
+ // Copy the buffered selections to the output selections
48366
+ ScatterSelection(true_sel, match_count, true_vec);
48367
+ ScatterSelection(false_sel, no_match_count, false_vec);
48261
48368
 
48262
48369
  return match_count;
48263
48370
  }
@@ -97377,8 +97484,7 @@ void ArrowTableFunction::ArrowToDuckDB(ArrowScanState &scan_state,
97377
97484
  if (array.length != scan_state.chunk->arrow_array.length) {
97378
97485
  throw InvalidInputException("arrow_scan: array length mismatch");
97379
97486
  }
97380
- output.data[idx].GetBuffer()->SetAuxiliaryData(make_unique<ArrowAuxiliaryData>(scan_state.chunk),
97381
- VectorAuxiliaryDataType::ARROW_AUXILIARY);
97487
+ output.data[idx].GetBuffer()->SetAuxiliaryData(make_unique<ArrowAuxiliaryData>(scan_state.chunk));
97382
97488
  if (array.dictionary) {
97383
97489
  ColumnArrowToDuckDBDictionary(output.data[idx], array, scan_state, output.size(), arrow_convert_data,
97384
97490
  col_idx, arrow_convert_idx);
@@ -104250,6 +104356,10 @@ duckdb_logical_type duckdb_create_logical_type(duckdb_type type) {
104250
104356
  return new duckdb::LogicalType(duckdb::ConvertCTypeToCPP(type));
104251
104357
  }
104252
104358
 
104359
+ duckdb_logical_type duckdb_create_decimal_type(uint8_t width, uint8_t scale) {
104360
+ return new duckdb::LogicalType(duckdb::LogicalType::DECIMAL(width, scale));
104361
+ }
104362
+
104253
104363
  duckdb_type duckdb_get_type_id(duckdb_logical_type type) {
104254
104364
  if (!type) {
104255
104365
  return DUCKDB_TYPE_INVALID;
@@ -105222,12 +105332,15 @@ struct CTableInitData : public FunctionOperatorData {
105222
105332
  };
105223
105333
 
105224
105334
  struct CTableInternalInitInfo {
105225
- CTableInternalInitInfo(CTableBindData &bind_data, CTableInitData &init_data)
105226
- : bind_data(bind_data), init_data(init_data), success(true) {
105335
+ CTableInternalInitInfo(CTableBindData &bind_data, CTableInitData &init_data, const vector<column_t> &column_ids,
105336
+ TableFilterCollection *filters)
105337
+ : bind_data(bind_data), init_data(init_data), column_ids(column_ids), filters(filters), success(true) {
105227
105338
  }
105228
105339
 
105229
105340
  CTableBindData &bind_data;
105230
105341
  CTableInitData &init_data;
105342
+ const vector<column_t> &column_ids;
105343
+ TableFilterCollection *filters;
105231
105344
  bool success;
105232
105345
  string error;
105233
105346
  };
@@ -105264,7 +105377,7 @@ unique_ptr<FunctionOperatorData> CTableFunctionInit(ClientContext &context, cons
105264
105377
  auto &bind_data = (CTableBindData &)*bind_data_p;
105265
105378
  auto result = make_unique<CTableInitData>();
105266
105379
 
105267
- CTableInternalInitInfo init_info(bind_data, *result);
105380
+ CTableInternalInitInfo init_info(bind_data, *result, column_ids, filters);
105268
105381
  bind_data.info->init(&init_info);
105269
105382
  if (!init_info.success) {
105270
105383
  throw Exception(init_info.error);
@@ -105358,6 +105471,14 @@ void duckdb_table_function_set_function(duckdb_table_function table_function, du
105358
105471
  info->function = function;
105359
105472
  }
105360
105473
 
105474
+ void duckdb_table_function_supports_projection_pushdown(duckdb_table_function table_function, bool pushdown) {
105475
+ if (!table_function) {
105476
+ return;
105477
+ }
105478
+ auto tf = (duckdb::TableFunction *)table_function;
105479
+ tf->projection_pushdown = pushdown;
105480
+ }
105481
+
105361
105482
  duckdb_state duckdb_register_table_function(duckdb_connection connection, duckdb_table_function function) {
105362
105483
  if (!connection || !function) {
105363
105484
  return DuckDBError;
@@ -105469,6 +105590,25 @@ void duckdb_init_set_error(duckdb_init_info info, const char *error) {
105469
105590
  function_info->success = false;
105470
105591
  }
105471
105592
 
105593
+ idx_t duckdb_init_get_column_count(duckdb_init_info info) {
105594
+ if (!info) {
105595
+ return 0;
105596
+ }
105597
+ auto function_info = (duckdb::CTableInternalInitInfo *)info;
105598
+ return function_info->column_ids.size();
105599
+ }
105600
+
105601
+ idx_t duckdb_init_get_column_index(duckdb_init_info info, idx_t column_index) {
105602
+ if (!info) {
105603
+ return 0;
105604
+ }
105605
+ auto function_info = (duckdb::CTableInternalInitInfo *)info;
105606
+ if (column_index >= function_info->column_ids.size()) {
105607
+ return 0;
105608
+ }
105609
+ return function_info->column_ids[column_index];
105610
+ }
105611
+
105472
105612
  //===--------------------------------------------------------------------===//
105473
105613
  // Function Interface
105474
105614
  //===--------------------------------------------------------------------===//