@@ -30,7 +30,7 @@ use crate::logical_plan::Subquery;
3030use crate :: Volatility ;
3131use crate :: { udaf, ExprSchemable , Operator , Signature , WindowFrame , WindowUDF } ;
3232
33- use arrow:: datatypes:: { DataType , FieldRef } ;
33+ use arrow:: datatypes:: { DataType , Field , FieldRef } ;
3434use datafusion_common:: cse:: { HashNode , NormalizeEq , Normalizeable } ;
3535use datafusion_common:: tree_node:: {
3636 Transformed , TransformedResult , TreeNode , TreeNodeContainer , TreeNodeRecursion ,
@@ -284,8 +284,8 @@ pub enum Expr {
284284 Column ( Column ) ,
285285 /// A named reference to a variable in a registry.
286286 ScalarVariable ( DataType , Vec < String > ) ,
287- /// A constant value along with associated metadata
288- Literal ( ScalarValue , Option < BTreeMap < String , String > > ) ,
287+ /// A constant value along with associated [`FieldMetadata`].
288+ Literal ( ScalarValue , Option < FieldMetadata > ) ,
289289 /// A binary expression such as "age > 21"
290290 BinaryExpr ( BinaryExpr ) ,
291291 /// LIKE expression
@@ -413,6 +413,116 @@ impl<'a> TreeNodeContainer<'a, Self> for Expr {
413413 }
414414}
415415
416+ /// Literal metadata
417+ ///
418+ /// This structure is used to store metadata associated with a literal expressions
419+ /// and is designed to be cheap to `clone`.
420+ ///
421+ /// This structure is used to store metadata associated with a literal expression, and it
422+ /// corresponds to the `metadata` field on [`FieldRef`].
423+ #[ derive( Clone , PartialEq , Eq , PartialOrd , Hash , Debug ) ]
424+ pub struct FieldMetadata {
425+ /// The inner metadata of a literal expression, which is a map of string
426+ /// keys to string values.
427+ ///
428+ /// Note this is not a `HashMap because `HashMap` does not provide
429+ /// implementations for traits like `Debug` and `Hash`.
430+ inner : Arc < BTreeMap < String , String > > ,
431+ }
432+
433+ impl FieldMetadata {
434+ /// Create a new empty metadata instance.
435+ pub fn new_empty ( ) -> Self {
436+ Self {
437+ inner : Arc :: new ( BTreeMap :: new ( ) ) ,
438+ }
439+ }
440+
441+ /// Create a new metadata instance from a `Field`'s metadata.
442+ pub fn new_from_field ( field : & Field ) -> Self {
443+ let inner = field
444+ . metadata ( )
445+ . iter ( )
446+ . map ( |( k, v) | ( k. to_string ( ) , v. to_string ( ) ) )
447+ . collect ( ) ;
448+ Self {
449+ inner : Arc :: new ( inner) ,
450+ }
451+ }
452+
453+ /// Create a new metadata instance from a map of string keys to string values.
454+ pub fn new ( inner : BTreeMap < String , String > ) -> Self {
455+ Self {
456+ inner : Arc :: new ( inner) ,
457+ }
458+ }
459+
460+ /// Get the inner metadata as a reference to a `BTreeMap`.
461+ pub fn inner ( & self ) -> & BTreeMap < String , String > {
462+ & self . inner
463+ }
464+
465+ /// Return the inner metadata
466+ pub fn into_inner ( self ) -> Arc < BTreeMap < String , String > > {
467+ self . inner
468+ }
469+
470+ /// Adds metadata from `other` into `self`, overwriting any existing keys.
471+ pub fn extend ( & mut self , other : Self ) {
472+ let other = Arc :: unwrap_or_clone ( other. into_inner ( ) ) ;
473+ Arc :: make_mut ( & mut self . inner ) . extend ( other) ;
474+ }
475+
476+ /// Returns true if the metadata is empty.
477+ pub fn is_empty ( & self ) -> bool {
478+ self . inner . is_empty ( )
479+ }
480+
481+ /// Returns the number of key-value pairs in the metadata.
482+ pub fn len ( & self ) -> usize {
483+ self . inner . len ( )
484+ }
485+
486+ /// Updates the metadata on the Field with this metadata
487+ pub fn add_to_field ( & self , field : Field ) -> Field {
488+ field. with_metadata (
489+ self . inner
490+ . iter ( )
491+ . map ( |( k, v) | ( k. clone ( ) , v. clone ( ) ) )
492+ . collect ( ) ,
493+ )
494+ }
495+ }
496+
497+ impl From < & Field > for FieldMetadata {
498+ fn from ( field : & Field ) -> Self {
499+ Self :: new_from_field ( field)
500+ }
501+ }
502+
503+ impl From < BTreeMap < String , String > > for FieldMetadata {
504+ fn from ( inner : BTreeMap < String , String > ) -> Self {
505+ Self :: new ( inner)
506+ }
507+ }
508+
509+ impl From < std:: collections:: HashMap < String , String > > for FieldMetadata {
510+ fn from ( map : std:: collections:: HashMap < String , String > ) -> Self {
511+ Self :: new ( map. into_iter ( ) . collect ( ) )
512+ }
513+ }
514+
515+ /// From reference
516+ impl From < & std:: collections:: HashMap < String , String > > for FieldMetadata {
517+ fn from ( map : & std:: collections:: HashMap < String , String > ) -> Self {
518+ let inner = map
519+ . iter ( )
520+ . map ( |( k, v) | ( k. to_string ( ) , v. to_string ( ) ) )
521+ . collect ( ) ;
522+ Self :: new ( inner)
523+ }
524+ }
525+
416526/// UNNEST expression.
417527#[ derive( Clone , PartialEq , Eq , PartialOrd , Hash , Debug ) ]
418528pub struct Unnest {
0 commit comments