@@ -129,7 +129,13 @@ pub trait Visitor<'a> {
129129 fn parameter_substitution ( & mut self ) -> Result ;
130130
131131 /// What to use to substitute a list of parameters of variable length
132- fn visit_parameterized_row ( & mut self , value : Value < ' a > ) -> Result ;
132+ fn visit_parameterized_row (
133+ & mut self ,
134+ value : Value < ' a > ,
135+ item_prefix : impl Into < Cow < ' static , str > > ,
136+ separator : impl Into < Cow < ' static , str > > ,
137+ item_suffix : impl Into < Cow < ' static , str > > ,
138+ ) -> Result ;
133139
134140 /// What to use to aggregate an array of values into a string
135141 fn visit_aggregate_to_string ( & mut self , value : Expression < ' a > ) -> Result ;
@@ -618,7 +624,7 @@ pub trait Visitor<'a> {
618624 ExpressionKind :: ConditionTree ( tree) => self . visit_conditions ( tree) ?,
619625 ExpressionKind :: Compare ( compare) => self . visit_compare ( compare) ?,
620626 ExpressionKind :: Parameterized ( val) => self . visit_parameterized ( val) ?,
621- ExpressionKind :: ParameterizedRow ( val) => self . visit_parameterized_row ( val) ?,
627+ ExpressionKind :: ParameterizedRow ( val) => self . visit_parameterized_row ( val, "" , "," , "" ) ?,
622628 ExpressionKind :: RawValue ( val) => self . visit_raw_value ( val. 0 ) ?,
623629 ExpressionKind :: Column ( column) => self . visit_column ( * column) ?,
624630 ExpressionKind :: Row ( row) => self . visit_row ( row) ?,
@@ -877,15 +883,13 @@ pub trait Visitor<'a> {
877883 kind : ExpressionKind :: Row ( mut cols) ,
878884 ..
879885 } ,
880- Expression {
881- kind : ExpressionKind :: ParameterizedRow ( value ) ,
886+ rhs @ Expression {
887+ kind : ExpressionKind :: ParameterizedRow ( _ ) ,
882888 ..
883889 } ,
884890 ) if cols. len ( ) == 1 => {
885891 let col = cols. pop ( ) . unwrap ( ) ;
886- self . visit_expression ( col) ?;
887- self . write ( " IN " ) ?;
888- self . visit_parameterized_row ( value)
892+ self . visit_compare ( Compare :: In ( Box :: new ( col) , Box :: new ( rhs) ) )
889893 }
890894
891895 // expr IN (?, ?, ..., ?)
@@ -898,7 +902,36 @@ pub trait Visitor<'a> {
898902 ) => {
899903 self . visit_expression ( left) ?;
900904 self . write ( " IN " ) ?;
901- self . visit_parameterized_row ( value)
905+ self . visit_parameterized_row ( value, "" , "," , "" )
906+ }
907+
908+ // expr IN (CALL(?), CALL(?), ..., CALL(?))
909+ (
910+ left,
911+ Expression {
912+ kind : ExpressionKind :: Function ( value) ,
913+ ..
914+ } ,
915+ ) if value. typ_ . arguments ( ) . len ( ) == 1
916+ && value
917+ . typ_
918+ . arguments ( )
919+ . iter ( )
920+ . all ( |arg| matches ! ( arg. kind, ExpressionKind :: ParameterizedRow ( _) ) ) =>
921+ {
922+ self . visit_expression ( left) ?;
923+ self . write ( " IN " ) ?;
924+
925+ let Some ( ExpressionKind :: ParameterizedRow ( val) ) =
926+ value. typ_ . arguments ( ) . first ( ) . map ( |arg| & arg. kind )
927+ else {
928+ unreachable ! ( )
929+ } ;
930+ let Some ( function_name) = & value. typ_ . name ( ) else {
931+ panic ! ( "function call against a row of expressions must have a name" )
932+ } ;
933+
934+ self . visit_parameterized_row ( val. clone ( ) , format ! ( "{function_name}(" ) , "," , ")" )
902935 }
903936
904937 (
@@ -979,15 +1012,13 @@ pub trait Visitor<'a> {
9791012 kind : ExpressionKind :: Row ( mut cols) ,
9801013 ..
9811014 } ,
982- Expression {
983- kind : ExpressionKind :: ParameterizedRow ( value ) ,
1015+ rhs @ Expression {
1016+ kind : ExpressionKind :: ParameterizedRow ( _ ) ,
9841017 ..
9851018 } ,
9861019 ) if cols. len ( ) == 1 => {
9871020 let col = cols. pop ( ) . unwrap ( ) ;
988- self . visit_expression ( col) ?;
989- self . write ( " NOT IN " ) ?;
990- self . visit_parameterized_row ( value)
1021+ self . visit_compare ( Compare :: NotIn ( Box :: new ( col) , Box :: new ( rhs) ) )
9911022 }
9921023
9931024 // expr NOT IN (?, ?, ..., ?)
@@ -1000,7 +1031,7 @@ pub trait Visitor<'a> {
10001031 ) => {
10011032 self . visit_expression ( left) ?;
10021033 self . write ( " NOT IN " ) ?;
1003- self . visit_parameterized_row ( value)
1034+ self . visit_parameterized_row ( value, "" , "," , "" )
10041035 }
10051036
10061037 (
@@ -1014,6 +1045,35 @@ pub trait Visitor<'a> {
10141045 } ,
10151046 ) => self . visit_multiple_tuple_comparison ( row, * values, true ) ,
10161047
1048+ // expr NOT IN (CALL(?), CALL(?), ..., CALL(?))
1049+ (
1050+ left,
1051+ Expression {
1052+ kind : ExpressionKind :: Function ( value) ,
1053+ ..
1054+ } ,
1055+ ) if value. typ_ . arguments ( ) . len ( ) == 1
1056+ && value
1057+ . typ_
1058+ . arguments ( )
1059+ . iter ( )
1060+ . all ( |arg| matches ! ( arg. kind, ExpressionKind :: ParameterizedRow ( _) ) ) =>
1061+ {
1062+ self . visit_expression ( left) ?;
1063+ self . write ( " NOT IN " ) ?;
1064+
1065+ let Some ( ExpressionKind :: ParameterizedRow ( val) ) =
1066+ value. typ_ . arguments ( ) . first ( ) . map ( |arg| & arg. kind )
1067+ else {
1068+ unreachable ! ( )
1069+ } ;
1070+ let Some ( function_name) = & value. typ_ . name ( ) else {
1071+ panic ! ( "function call against a row of expressions must have a name" )
1072+ } ;
1073+
1074+ self . visit_parameterized_row ( val. clone ( ) , format ! ( "{function_name}(" ) , "," , ")" )
1075+ }
1076+
10171077 // expr IN (..)
10181078 ( left, right) => {
10191079 self . visit_expression ( left) ?;
0 commit comments