@@ -34,7 +34,7 @@ import za.co.absa.standardization.schema.{MetadataKeys, MetadataValues, StdSchem
3434import za .co .absa .standardization .time .DateTimePattern
3535import za .co .absa .standardization .typeClasses .{DoubleLike , LongLike }
3636import za .co .absa .standardization .types .TypedStructField ._
37- import za .co .absa .standardization .types .parsers .{ DateTimeParser => DateTimeParserImpl }
37+ import za .co .absa .standardization .types .parsers .DateTimeParser
3838import za .co .absa .standardization .types .{ParseOutput , TypeDefaults , TypedStructField }
3939import za .co .absa .standardization .udf .{UDFBuilder , UDFNames }
4040
@@ -318,13 +318,13 @@ object TypeParser {
318318 }
319319
320320 private abstract class NumericParser [N : TypeTag ](override val field : NumericTypeStructField [N ])
321- (implicit defaults : TypeDefaults ) extends ScalarParser [N ] with InfinitySupport {
322- override protected val infMinusSymbol : Option [ String ] = metadata.getOptString( MetadataKeys . MinusInfinitySymbol )
323- override protected val infMinusValue : Option [ String ] = metadata.getOptString(MetadataKeys .MinusInfinityValue )
324- override protected val infPlusSymbol : Option [ String ] = metadata.getOptString(MetadataKeys .PlusInfinitySymbol )
325- override protected val infPlusValue : Option [ String ] = metadata.getOptString(MetadataKeys .PlusInfinityValue )
326- override protected def canParseInfValue ( value : String ) : Boolean = false
327- private val columnWithInfinityReplaced = replaceInfinitySymbols(column).cast( origType)
321+ (implicit defaults : TypeDefaults ) extends ScalarParser [N ] {
322+ private val infinitySupport = InfinitySupport (
323+ metadata.getOptString(MetadataKeys .MinusInfinitySymbol ),
324+ metadata.getOptString(MetadataKeys .MinusInfinityValue ),
325+ metadata.getOptString(MetadataKeys .PlusInfinitySymbol ),
326+ metadata.getOptString( MetadataKeys . PlusInfinityValue ),
327+ origType)
328328
329329 override protected def standardizeAfterCheck (stdConfig : StandardizationConfig )(implicit logger : Logger ): ParseOutput = {
330330 if (field.needsUdfParsing) {
@@ -345,9 +345,9 @@ object TypeParser {
345345 val columnWithProperDecimalSymbols : Column = if (replacements.nonEmpty) {
346346 val from = replacements.keys.mkString
347347 val to = replacements.values.mkString
348- translate(columnWithInfinityReplaced , from, to)
348+ infinitySupport.replaceInfinitySymbols(column, translate(_ , from, to) )
349349 } else {
350- columnWithInfinityReplaced
350+ infinitySupport.replaceInfinitySymbols(column)
351351 }
352352
353353 val columnToCast = if (field.allowInfinity && (decimalSymbols.infinityValue != InfinityStr )) {
@@ -504,28 +504,17 @@ object TypeParser {
504504 * Date | O | ->to_utc_timestamp->to_date
505505 * Other | ->String->to_date | ->String->to_timestamp->to_utc_timestamp->to_date
506506 */
507- private abstract class DateTimeParser [T ](implicit defaults : TypeDefaults ) extends PrimitiveParser [T ] with InfinitySupport {
507+ private abstract class DateTimeParser [T ](implicit defaults : TypeDefaults ) extends PrimitiveParser [T ] {
508508 override val field : DateTimeTypeStructField [T ]
509509 protected val pattern : DateTimePattern = field.pattern.get.get
510- override protected val infMinusSymbol : Option [String ] = metadata.getOptString(MetadataKeys .MinusInfinitySymbol )
511- override protected val infMinusValue : Option [String ] = metadata.getOptString(MetadataKeys .MinusInfinityValue )
512- override protected val infPlusSymbol : Option [String ] = metadata.getOptString(MetadataKeys .PlusInfinitySymbol )
513- override protected val infPlusValue : Option [String ] = metadata.getOptString(MetadataKeys .PlusInfinityValue )
514-
515-
516- private val IsoDatePattern = " yyyy-MM-dd"
517- private val IsoTimestampPattern = " yyyy-MM-dd HH:mm:ss"
518-
519- private lazy val dateTimeParser : DateTimeParserImpl = field.parser.get
520-
521- override protected def canParseInfValue (value : String ): Boolean = {
522- Try {
523- field.dataType match {
524- case DateType => dateTimeParser.parseDate(value)
525- case TimestampType => dateTimeParser.parseTimestamp(value)
526- }
527- }.isSuccess
528- }
510+ private val infinitySupport = InfinitySupportIso (
511+ metadata.getOptString(MetadataKeys .MinusInfinitySymbol ),
512+ metadata.getOptString(MetadataKeys .MinusInfinityValue ),
513+ metadata.getOptString(MetadataKeys .PlusInfinitySymbol ),
514+ metadata.getOptString(MetadataKeys .PlusInfinityValue ),
515+ origType,
516+ field.dataType
517+ )
529518
530519 protected val replaceCenturyUDF : UserDefinedFunction = udf((inputDate : String , centuryPattern : String ) => {
531520 val centuryIndex = centuryPattern.indexOf(DateTimePattern .patternCenturyChar)
@@ -538,45 +527,6 @@ object TypeParser {
538527 pendedInput.substring(0 , centuryIndex) + modifiedChar + pendedInput.substring(centuryIndex + 1 )
539528 })
540529
541- private val columnWithInfinityReplaced : Column = {
542- val replaced = replaceInfinitySymbols(column)
543-
544- val originalCastFunc : Column => Column = if (pattern.isEpoch) {
545- col => (col.cast(decimalType) / pattern.epochFactor).cast(TimestampType )
546- } else {
547- col => castStringColumn(col)
548- }
549-
550- val isoPattern = field.dataType match {
551- case DateType => IsoDatePattern
552- case TimestampType => IsoTimestampPattern
553- }
554- val isoCastFunc : Column => Column = col => field.dataType match {
555- case DateType => to_date(col,isoPattern)
556- case TimestampType => to_timestamp(col, isoPattern)
557- }
558-
559- infMinusSymbol.flatMap { minusSymbol =>
560- infMinusValue.map { minusValue =>
561- if (canParseInfValue(minusValue)){
562- originalCastFunc(replaced)
563- } else {
564- when(replaced === lit(minusValue), isoCastFunc(lit(minusValue))).otherwise(originalCastFunc(replaced))
565- }
566- }
567- }.getOrElse{
568- infPlusSymbol.flatMap{ plusSymbol =>
569- infPlusValue.map { plusValue=>
570- if (canParseInfValue(plusValue)){
571- originalCastFunc(replaced)
572- } else {
573- when(replaced === lit(plusValue), isoCastFunc(lit(plusValue))).otherwise(originalCastFunc(replaced))
574- }
575- }
576- }.getOrElse(originalCastFunc(replaced))
577- }
578- }
579-
580530 override protected def assemblePrimitiveCastLogic : Column = {
581531 if (pattern.isEpoch) {
582532 castEpoch()
@@ -598,20 +548,20 @@ object TypeParser {
598548 // underlyingType match {
599549 origType match {
600550 case _ : NullType => nullColumn
601- case _ : DateType => castDateColumn(columnWithInfinityReplaced )
602- case _ : TimestampType => castTimestampColumn(columnWithInfinityReplaced )
603- case _ : StringType => castStringColumn(columnWithInfinityReplaced )
551+ case _ : DateType => infinitySupport.replaceInfinitySymbols(column, castDateColumn )
552+ case _ : TimestampType => infinitySupport.replaceInfinitySymbols(column, castTimestampColumn )
553+ case _ : StringType => infinitySupport.replaceInfinitySymbols(column, castStringColumn )
604554 case ot : DoubleType =>
605555 // this case covers some IBM date format where it's represented as a double ddmmyyyy.hhmmss
606556 patternNeeded(ot)
607- castFractionalColumn(columnWithInfinityReplaced , ot)
557+ infinitySupport.replaceInfinitySymbols(column, castFractionalColumn(_ , ot) )
608558 case ot : FloatType =>
609559 // this case covers some IBM date format where it's represented as a double ddmmyyyy.hhmmss
610560 patternNeeded(ot)
611- castFractionalColumn(columnWithInfinityReplaced , ot)
561+ infinitySupport.replaceInfinitySymbols(column, castFractionalColumn(_ , ot) )
612562 case ot =>
613563 patternNeeded(ot)
614- castNonStringColumn(columnWithInfinityReplaced , ot)
564+ infinitySupport.replaceInfinitySymbols(column, castNonStringColumn(_ , ot) )
615565 }
616566 }
617567
@@ -633,7 +583,7 @@ object TypeParser {
633583 }
634584
635585 protected def castEpoch (): Column = {
636- (columnWithInfinityReplaced .cast(decimalType) / pattern.epochFactor).cast(TimestampType )
586+ infinitySupport.replaceInfinitySymbols(column, c => (c .cast(decimalType) / pattern.epochFactor).cast(TimestampType ) )
637587 }
638588
639589 protected def castStringColumn (stringColumn : Column ): Column
0 commit comments