@@ -725,6 +725,164 @@ async fn test_interval_expressions() -> Result<()> {
725725 Ok ( ( ) )
726726}
727727
728+ #[ tokio:: test]
729+ async fn test_interval_mul_div_float ( ) -> Result < ( ) > {
730+ macro_rules! test_mul {
731+ ( $L: expr, $R: expr, $EXPECTED: expr) => {
732+ test_expression!( format!( "({}) * ({})" , $L, $R) , $EXPECTED) ;
733+ test_expression!( format!( "({}) * ({})" , $R, $L) , $EXPECTED) ;
734+ } ;
735+ }
736+
737+ test_mul ! (
738+ "0.5" ,
739+ "interval '1 month'" ,
740+ "0 years 0 mons 15 days 0 hours 0 mins 0.000000000 secs"
741+ ) ;
742+ test_mul ! (
743+ "1.0" ,
744+ "interval '1 month'" ,
745+ "0 years 1 mons 0 days 0 hours 0 mins 0.000000000 secs"
746+ ) ;
747+ test_mul ! (
748+ "1.5" ,
749+ "interval '1 month'" ,
750+ "0 years 1 mons 15 days 0 hours 0 mins 0.000000000 secs"
751+ ) ;
752+ test_mul ! (
753+ "2.0" ,
754+ "interval '1 month'" ,
755+ "0 years 2 mons 0 days 0 hours 0 mins 0.000000000 secs"
756+ ) ;
757+ test_mul ! (
758+ "-1.5" ,
759+ "interval '1 month'" ,
760+ "0 years -1 mons -15 days 0 hours 0 mins 0.000000000 secs"
761+ ) ;
762+ test_expression ! (
763+ "1.5 * (interval '1 month') / 1.5" ,
764+ "0 years 0 mons 30 days 0 hours 0 mins 0.000000000 secs"
765+ ) ;
766+
767+ test_mul ! (
768+ "0.5" ,
769+ "interval '1 day'" ,
770+ "0 years 0 mons 0 days 12 hours 0 mins 0.000000000 secs"
771+ ) ;
772+ test_mul ! (
773+ "1.0" ,
774+ "interval '1 day'" ,
775+ "0 years 0 mons 1 days 0 hours 0 mins 0.000000000 secs"
776+ ) ;
777+ test_mul ! (
778+ "1.5" ,
779+ "interval '1 day'" ,
780+ "0 years 0 mons 1 days 12 hours 0 mins 0.000000000 secs"
781+ ) ;
782+ test_mul ! (
783+ "2.0" ,
784+ "interval '1 day'" ,
785+ "0 years 0 mons 2 days 0 hours 0 mins 0.000000000 secs"
786+ ) ;
787+ test_mul ! (
788+ "-1.5" ,
789+ "interval '1 day'" ,
790+ "0 years 0 mons -1 days -12 hours 0 mins 0.000000000 secs"
791+ ) ;
792+ test_expression ! (
793+ "1.5 * (interval '1 day') / 1.5" ,
794+ "0 years 0 mons 0 days 24 hours 0 mins 0.000000000 secs"
795+ ) ;
796+
797+ test_mul ! (
798+ "0.5" ,
799+ "interval '1 second'" ,
800+ "0 years 0 mons 0 days 0 hours 0 mins 0.500000000 secs"
801+ ) ;
802+ test_mul ! (
803+ "1.0" ,
804+ "interval '1 second'" ,
805+ "0 years 0 mons 0 days 0 hours 0 mins 1.000000000 secs"
806+ ) ;
807+ test_mul ! (
808+ "1.5" ,
809+ "interval '1 second'" ,
810+ "0 years 0 mons 0 days 0 hours 0 mins 1.500000000 secs"
811+ ) ;
812+ test_mul ! (
813+ "2.0" ,
814+ "interval '1 second'" ,
815+ "0 years 0 mons 0 days 0 hours 0 mins 2.000000000 secs"
816+ ) ;
817+ // This test prints as -1.-500000000 secs, that looks like a bug in printing
818+ // TODO fix it
819+ // test_mul!(
820+ // "-1.5",
821+ // "interval '1 second'",
822+ // "0 years 0 mons 0 days 0 hours 0 mins -1.500000000 secs"
823+ // );
824+ test_expression ! (
825+ "1.5 * (interval '1 second') / 1.5" ,
826+ "0 years 0 mons 0 days 0 hours 0 mins 1.000000000 secs"
827+ ) ;
828+
829+ // Carry-over cases
830+ test_mul ! (
831+ "1.5" ,
832+ "interval '1 month 1 day'" ,
833+ "0 years 1 mons 16 days 12 hours 0 mins 0.000000000 secs"
834+ ) ;
835+ test_mul ! (
836+ "1.5" ,
837+ "interval '1 month 1 second'" ,
838+ "0 years 1 mons 15 days 0 hours 0 mins 1.500000000 secs"
839+ ) ;
840+ test_mul ! (
841+ "1.5" ,
842+ "interval '1 day 1 second'" ,
843+ "0 years 0 mons 1 days 12 hours 0 mins 1.500000000 secs"
844+ ) ;
845+
846+ Ok ( ( ) )
847+ }
848+
849+ #[ tokio:: test]
850+ async fn test_interval_mul_bad_float ( ) -> Result < ( ) > {
851+ macro_rules! test_expr_error {
852+ ( $SQL: expr, $EXPECTED: expr) => {
853+ let ctx = SessionContext :: new( ) ;
854+ let sql = format!( "SELECT {}" , $SQL) ;
855+ let actual_err = plan_and_collect( & ctx, sql. as_str( ) ) . await . unwrap_err( ) ;
856+ assert_eq!( actual_err. to_string( ) , $EXPECTED) ;
857+ } ;
858+ }
859+ macro_rules! test_mul_error {
860+ ( $L: expr, $R: expr, $EXPECTED: expr) => {
861+ test_expr_error!( format!( "({}) * ({})" , $L, $R) , $EXPECTED) ;
862+ test_expr_error!( format!( "({}) * ({})" , $R, $L) , $EXPECTED) ;
863+ } ;
864+ }
865+
866+ // This behaviour was checked on PostgreSQL 15.7
867+ test_mul_error ! (
868+ "cast('NaN' as double precision)" ,
869+ "interval '1 month'" ,
870+ "Execution error: interval out of range (float)"
871+ ) ;
872+ test_mul_error ! (
873+ "cast('inf' as double precision)" ,
874+ "interval '1 month'" ,
875+ "Execution error: interval out of range (float)"
876+ ) ;
877+ test_mul_error ! (
878+ "cast('-inf' as double precision)" ,
879+ "interval '1 month'" ,
880+ "Execution error: interval out of range (float)"
881+ ) ;
882+
883+ Ok ( ( ) )
884+ }
885+
728886#[ cfg( feature = "unicode_expressions" ) ]
729887#[ tokio:: test]
730888async fn test_substring_expr ( ) -> Result < ( ) > {
0 commit comments