@@ -1623,6 +1623,26 @@ impl Expr {
1623
1623
| Expr :: SimilarTo ( Like { expr, pattern, .. } ) => {
1624
1624
rewrite_placeholder ( pattern. as_mut ( ) , expr. as_ref ( ) , schema) ?;
1625
1625
}
1626
+ Expr :: InSubquery ( InSubquery {
1627
+ expr,
1628
+ subquery,
1629
+ negated : _,
1630
+ } ) => {
1631
+ let subquery_schema = subquery. subquery . schema ( ) ;
1632
+ let fields = subquery_schema. fields ( ) ;
1633
+
1634
+ // only supports subquery with exactly 1 field
1635
+ if let [ first_field] = & fields[ ..] {
1636
+ rewrite_placeholder (
1637
+ expr. as_mut ( ) ,
1638
+ & Expr :: Column ( Column {
1639
+ relation : None ,
1640
+ name : first_field. name ( ) . clone ( ) ,
1641
+ } ) ,
1642
+ schema,
1643
+ ) ?;
1644
+ }
1645
+ }
1626
1646
Expr :: Placeholder ( _) => {
1627
1647
has_placeholder = true ;
1628
1648
}
@@ -2801,7 +2821,8 @@ mod test {
2801
2821
use crate :: expr_fn:: col;
2802
2822
use crate :: {
2803
2823
case, lit, qualified_wildcard, wildcard, wildcard_with_options, ColumnarValue ,
2804
- ScalarFunctionArgs , ScalarUDF , ScalarUDFImpl , Volatility ,
2824
+ LogicalPlan , LogicalTableSource , Projection , ScalarFunctionArgs , ScalarUDF ,
2825
+ ScalarUDFImpl , TableScan , Volatility ,
2805
2826
} ;
2806
2827
use arrow:: datatypes:: { Field , Schema } ;
2807
2828
use sqlparser:: ast;
@@ -2863,6 +2884,86 @@ mod test {
2863
2884
}
2864
2885
}
2865
2886
2887
+ #[ test]
2888
+ fn infer_placeholder_in_subquery ( ) -> Result < ( ) > {
2889
+ // Schema for my_table: A (Int32), B (Int32)
2890
+ let schema = Arc :: new ( Schema :: new ( vec ! [
2891
+ Field :: new( "A" , DataType :: Int32 , true ) ,
2892
+ Field :: new( "B" , DataType :: Int32 , true ) ,
2893
+ ] ) ) ;
2894
+
2895
+ let source = Arc :: new ( LogicalTableSource :: new ( schema. clone ( ) ) ) ;
2896
+
2897
+ // Simulate: SELECT * FROM my_table WHERE $1 IN (SELECT A FROM my_table WHERE B > 3);
2898
+ let placeholder = Expr :: Placeholder ( Placeholder {
2899
+ id : "$1" . to_string ( ) ,
2900
+ data_type : None ,
2901
+ } ) ;
2902
+
2903
+ // Subquery: SELECT A FROM my_table WHERE B > 3
2904
+ let subquery_filter = Expr :: BinaryExpr ( BinaryExpr {
2905
+ left : Box :: new ( col ( "B" ) ) ,
2906
+ op : Operator :: Gt ,
2907
+ right : Box :: new ( Expr :: Literal ( ScalarValue :: Int32 ( Some ( 3 ) ) ) ) ,
2908
+ } ) ;
2909
+
2910
+ let subquery_scan = LogicalPlan :: TableScan ( TableScan {
2911
+ table_name : TableReference :: from ( "my_table" ) ,
2912
+ source,
2913
+ projected_schema : Arc :: new ( DFSchema :: try_from ( schema. clone ( ) ) ?) ,
2914
+ projection : None ,
2915
+ filters : vec ! [ subquery_filter. clone( ) ] ,
2916
+ fetch : None ,
2917
+ } ) ;
2918
+
2919
+ let projected_fields = vec ! [ Field :: new( "A" , DataType :: Int32 , true ) ] ;
2920
+ let projected_schema = Arc :: new ( DFSchema :: from_unqualified_fields (
2921
+ projected_fields. into ( ) ,
2922
+ Default :: default ( ) ,
2923
+ ) ?) ;
2924
+
2925
+ let subquery = Subquery {
2926
+ subquery : Arc :: new ( LogicalPlan :: Projection ( Projection {
2927
+ expr : vec ! [ col( "A" ) ] ,
2928
+ input : Arc :: new ( subquery_scan) ,
2929
+ schema : projected_schema,
2930
+ } ) ) ,
2931
+ outer_ref_columns : vec ! [ ] ,
2932
+ } ;
2933
+
2934
+ let in_subquery = Expr :: InSubquery ( InSubquery {
2935
+ expr : Box :: new ( placeholder) ,
2936
+ subquery,
2937
+ negated : false ,
2938
+ } ) ;
2939
+
2940
+ let df_schema = DFSchema :: try_from ( schema) ?;
2941
+
2942
+ let ( inferred_expr, contains_placeholder) =
2943
+ in_subquery. infer_placeholder_types ( & df_schema) ?;
2944
+
2945
+ assert ! (
2946
+ contains_placeholder,
2947
+ "Expression should contain a placeholder"
2948
+ ) ;
2949
+
2950
+ match inferred_expr {
2951
+ Expr :: InSubquery ( in_subquery) => match * in_subquery. expr {
2952
+ Expr :: Placeholder ( placeholder) => {
2953
+ assert_eq ! (
2954
+ placeholder. data_type,
2955
+ Some ( DataType :: Int32 ) ,
2956
+ "Placeholder $1 should infer Int32"
2957
+ ) ;
2958
+ }
2959
+ _ => panic ! ( "Expected Placeholder expression in InSubquery" ) ,
2960
+ } ,
2961
+ _ => panic ! ( "Expected InSubquery expression" ) ,
2962
+ }
2963
+
2964
+ Ok ( ( ) )
2965
+ }
2966
+
2866
2967
#[ test]
2867
2968
fn infer_placeholder_like_and_similar_to ( ) {
2868
2969
// name LIKE $1
0 commit comments