@@ -558,7 +558,7 @@ BuilderExpr BuilderExpr::approxCountDist() const {
558
558
559
559
BuilderExpr BuilderExpr::approxQuantile (double val) const {
560
560
if (!expr_->type ()->isNumber ()) {
561
- throw InvalidQueryError () << " Unsupported type for sum aggregate: "
561
+ throw InvalidQueryError () << " Unsupported type for ApproxQuantile aggregate: "
562
562
<< expr_->type ()->toString ();
563
563
}
564
564
if (val < 0.0 || val > 1.0 ) {
@@ -613,6 +613,33 @@ BuilderExpr BuilderExpr::bottomK(int count) const {
613
613
return topK (-count);
614
614
}
615
615
616
+ BuilderExpr BuilderExpr::quantile (double val, Interpolation interpolation) const {
617
+ if (!expr_->type ()->isNumber () && !expr_->type ()->isDateTime () &&
618
+ !expr_->type ()->isInterval ()) {
619
+ throw InvalidQueryError () << " Unsupported type for quantile aggregate: "
620
+ << expr_->type ()->toString ();
621
+ }
622
+ if (val < 0.0 || val > 1.0 ) {
623
+ throw InvalidQueryError () << " Quantile expects argument between 0.0 and 1.0 but got "
624
+ << val;
625
+ }
626
+ Datum d;
627
+ d.doubleval = val;
628
+ auto cst = makeExpr<Constant>(builder_->ctx_ .fp64 (), false , d);
629
+ auto res_type = expr_->type ();
630
+ if (interpolation == Interpolation::kMidpoint ||
631
+ interpolation == Interpolation::kLinear ) {
632
+ if (res_type->isInteger ()) {
633
+ res_type = builder_->ctx_ .fp64 ();
634
+ }
635
+ }
636
+ res_type = res_type->canonicalize ();
637
+ auto agg =
638
+ makeExpr<AggExpr>(res_type, AggType::kQuantile , expr_, false , cst, interpolation);
639
+ auto name = name_.empty () ? " quantile" : name_ + " _quantile" ;
640
+ return {builder_, agg, name, true };
641
+ }
642
+
616
643
BuilderExpr BuilderExpr::stdDev () const {
617
644
if (!expr_->type ()->isNumber ()) {
618
645
throw InvalidQueryError () << " Non-numeric type " << expr_->type ()->toString ()
@@ -704,6 +731,7 @@ BuilderExpr BuilderExpr::agg(const std::string& agg_str, BuilderExpr arg) const
704
731
{" top_k" , AggType::kTopK },
705
732
{" bottomk" , AggType::kTopK },
706
733
{" bottom_k" , AggType::kTopK },
734
+ {" quantile" , AggType::kQuantile },
707
735
{" stddev" , AggType::kStdDevSamp },
708
736
{" stddev_samp" , AggType::kStdDevSamp },
709
737
{" stddev samp" , AggType::kStdDevSamp },
@@ -716,8 +744,8 @@ BuilderExpr BuilderExpr::agg(const std::string& agg_str, BuilderExpr arg) const
716
744
}
717
745
718
746
auto kind = agg_names.at (agg_str_lower);
719
- if (kind == AggType::kApproxQuantile && !arg.expr ()) {
720
- throw InvalidQueryError (" Missing argument for approximate quantile aggregate." );
747
+ if (( kind == AggType::kApproxQuantile || kind == AggType:: kQuantile ) && !arg.expr ()) {
748
+ throw InvalidQueryError (" Missing argument for quantile aggregate." );
721
749
}
722
750
if (kind == AggType::kTopK ) {
723
751
if (!arg.expr ()) {
@@ -751,8 +779,10 @@ BuilderExpr BuilderExpr::agg(AggType agg_kind, const BuilderExpr& arg) const {
751
779
return agg (agg_kind, false , arg);
752
780
}
753
781
754
- BuilderExpr BuilderExpr::agg (AggType agg_kind, double val) const {
755
- return agg (agg_kind, false , val);
782
+ BuilderExpr BuilderExpr::agg (AggType agg_kind,
783
+ double val,
784
+ Interpolation interpolation) const {
785
+ return agg (agg_kind, false , val, interpolation);
756
786
}
757
787
758
788
BuilderExpr BuilderExpr::agg (AggType agg_kind, int val) const {
@@ -761,21 +791,21 @@ BuilderExpr BuilderExpr::agg(AggType agg_kind, int val) const {
761
791
762
792
BuilderExpr BuilderExpr::agg (AggType agg_kind,
763
793
bool is_distinct,
764
- const BuilderExpr& arg) const {
794
+ const BuilderExpr& arg,
795
+ Interpolation interpolation) const {
765
796
if (is_distinct && agg_kind != AggType::kCount ) {
766
797
throw InvalidQueryError () << " Distinct property cannot be set to true for "
767
798
<< agg_kind << " aggregate." ;
768
799
}
769
800
if (arg.expr () && agg_kind != AggType::kApproxQuantile && agg_kind != AggType::kCorr &&
770
- agg_kind != AggType::kTopK ) {
801
+ agg_kind != AggType::kTopK && agg_kind != AggType:: kQuantile ) {
771
802
throw InvalidQueryError () << " Aggregate argument is supported for approximate "
772
803
" quantile and corr only but provided for "
773
804
<< agg_kind;
774
805
}
775
- if (agg_kind == AggType::kApproxQuantile ) {
806
+ if (agg_kind == AggType::kApproxQuantile || agg_kind == AggType:: kQuantile ) {
776
807
if (!arg.expr ()->is <Constant>() || !arg.type ()->isFloatingPoint ()) {
777
- throw InvalidQueryError () << " Expected fp constant argumnt for approximate "
778
- " quantile. Provided: "
808
+ throw InvalidQueryError () << " Expected fp constant argumnt for quantile. Provided: "
779
809
<< arg.expr ()->toString ();
780
810
}
781
811
}
@@ -808,6 +838,8 @@ BuilderExpr BuilderExpr::agg(AggType agg_kind,
808
838
return singleValue ();
809
839
case AggType::kTopK :
810
840
return topK (arg.expr ()->as <Constant>()->intVal ());
841
+ case AggType::kQuantile :
842
+ return quantile (arg.expr ()->as <Constant>()->fpVal (), interpolation);
811
843
case AggType::kStdDevSamp :
812
844
return stdDev ();
813
845
case AggType::kCorr :
@@ -818,12 +850,15 @@ BuilderExpr BuilderExpr::agg(AggType agg_kind,
818
850
throw InvalidQueryError () << " Unsupported aggregate type: " << agg_kind;
819
851
}
820
852
821
- BuilderExpr BuilderExpr::agg (AggType agg_kind, bool is_distinct, double val) const {
853
+ BuilderExpr BuilderExpr::agg (AggType agg_kind,
854
+ bool is_distinct,
855
+ double val,
856
+ Interpolation interpolation) const {
822
857
BuilderExpr arg;
823
858
if (val != HUGE_VAL) {
824
859
arg = builder_->cst (val);
825
860
}
826
- return agg (agg_kind, is_distinct, arg);
861
+ return agg (agg_kind, is_distinct, arg, interpolation );
827
862
}
828
863
829
864
BuilderExpr BuilderExpr::extract (DateExtractField field) const {
0 commit comments