@@ -26,7 +26,7 @@ use crate::error::DataFusionError;
2626use crate :: logical_plan:: dfschema:: DFSchemaRef ;
2727use crate :: sql:: parser:: FileType ;
2828use arrow:: datatypes:: { DataType , Field , Schema , SchemaRef } ;
29- use datafusion_common:: DFSchema ;
29+ use datafusion_common:: { DFField , DFSchema } ;
3030use std:: fmt:: Formatter ;
3131use std:: {
3232 collections:: HashSet ,
@@ -282,13 +282,16 @@ pub struct Subquery {
282282pub enum SubqueryType {
283283 /// Scalar (SELECT, WHERE) evaluating to one value
284284 Scalar ,
285- // This will be extended with `Exists` and `AnyAll` types.
285+ /// EXISTS(...) evaluating to true if at least one row was produced
286+ Exists ,
287+ // This will be extended with `AnyAll` type.
286288}
287289
288290impl Display for SubqueryType {
289291 fn fmt ( & self , f : & mut Formatter ) -> fmt:: Result {
290292 let subquery_type = match self {
291293 SubqueryType :: Scalar => "Scalar" ,
294+ SubqueryType :: Exists => "Exists" ,
292295 } ;
293296 write ! ( f, "{}" , subquery_type)
294297 }
@@ -315,15 +318,31 @@ impl Subquery {
315318 pub fn transform_dfschema ( schema : & DFSchema , typ : SubqueryType ) -> DFSchema {
316319 match typ {
317320 SubqueryType :: Scalar => schema. clone ( ) ,
318- // Schema will be transformed for `Exists` and `AnyAll`
321+ SubqueryType :: Exists => {
322+ let new_fields = schema
323+ . fields ( )
324+ . iter ( )
325+ . map ( |field| {
326+ let new_field = Subquery :: transform_field ( field. field ( ) , typ) ;
327+ if let Some ( qualifier) = field. qualifier ( ) {
328+ DFField :: from_qualified ( qualifier, new_field)
329+ } else {
330+ DFField :: from ( new_field)
331+ }
332+ } )
333+ . collect ( ) ;
334+ DFSchema :: new_with_metadata ( new_fields, schema. metadata ( ) . clone ( ) )
335+ . unwrap ( )
336+ } // Schema will be transformed for `AnyAll` as well
319337 }
320338 }
321339
322340 /// Transform Arrow field according to subquery type
323341 pub fn transform_field ( field : & Field , typ : SubqueryType ) -> Field {
324342 match typ {
325343 SubqueryType :: Scalar => field. clone ( ) ,
326- // Field will be transformed for `Exists` and `AnyAll`
344+ SubqueryType :: Exists => Field :: new ( field. name ( ) , DataType :: Boolean , false ) ,
345+ // Field will be transformed for `AnyAll` as well
327346 }
328347 }
329348}
0 commit comments