@@ -36,7 +36,7 @@ class CSVTypeCastSuite extends SparkFunSuite {
3636
3737 stringValues.zip(decimalValues).foreach { case (strVal, decimalVal) =>
3838 val decimalValue = new BigDecimal (decimalVal.toString)
39- assert(CSVTypeCast .castTo(strVal, decimalType) ===
39+ assert(CSVTypeCast .castTo(strVal, " _1 " , decimalType) ===
4040 Decimal (decimalValue, decimalType.precision, decimalType.scale))
4141 }
4242 }
@@ -67,97 +67,108 @@ class CSVTypeCastSuite extends SparkFunSuite {
6767
6868 test(" Nullable types are handled" ) {
6969 assertNull(
70- CSVTypeCast .castTo(" -" , ByteType , nullable = true , CSVOptions (" nullValue" , " -" )))
70+ CSVTypeCast .castTo(" -" , " _1 " , ByteType , nullable = true , CSVOptions (" nullValue" , " -" )))
7171 assertNull(
72- CSVTypeCast .castTo(" -" , ShortType , nullable = true , CSVOptions (" nullValue" , " -" )))
72+ CSVTypeCast .castTo(" -" , " _1 " , ShortType , nullable = true , CSVOptions (" nullValue" , " -" )))
7373 assertNull(
74- CSVTypeCast .castTo(" -" , IntegerType , nullable = true , CSVOptions (" nullValue" , " -" )))
74+ CSVTypeCast .castTo(" -" , " _1 " , IntegerType , nullable = true , CSVOptions (" nullValue" , " -" )))
7575 assertNull(
76- CSVTypeCast .castTo(" -" , LongType , nullable = true , CSVOptions (" nullValue" , " -" )))
76+ CSVTypeCast .castTo(" -" , " _1 " , LongType , nullable = true , CSVOptions (" nullValue" , " -" )))
7777 assertNull(
78- CSVTypeCast .castTo(" -" , FloatType , nullable = true , CSVOptions (" nullValue" , " -" )))
78+ CSVTypeCast .castTo(" -" , " _1 " , FloatType , nullable = true , CSVOptions (" nullValue" , " -" )))
7979 assertNull(
80- CSVTypeCast .castTo(" -" , DoubleType , nullable = true , CSVOptions (" nullValue" , " -" )))
80+ CSVTypeCast .castTo(" -" , " _1 " , DoubleType , nullable = true , CSVOptions (" nullValue" , " -" )))
8181 assertNull(
82- CSVTypeCast .castTo(" -" , BooleanType , nullable = true , CSVOptions (" nullValue" , " -" )))
82+ CSVTypeCast .castTo(" -" , " _1 " , BooleanType , nullable = true , CSVOptions (" nullValue" , " -" )))
8383 assertNull(
84- CSVTypeCast .castTo(" -" , DecimalType .DoubleDecimal , true , CSVOptions (" nullValue" , " -" )))
84+ CSVTypeCast .castTo(" -" , " _1 " , DecimalType .DoubleDecimal , true , CSVOptions (" nullValue" , " -" )))
8585 assertNull(
86- CSVTypeCast .castTo(" -" , TimestampType , nullable = true , CSVOptions (" nullValue" , " -" )))
86+ CSVTypeCast .castTo(" -" , " _1 " , TimestampType , nullable = true , CSVOptions (" nullValue" , " -" )))
8787 assertNull(
88- CSVTypeCast .castTo(" -" , DateType , nullable = true , CSVOptions (" nullValue" , " -" )))
88+ CSVTypeCast .castTo(" -" , " _1 " , DateType , nullable = true , CSVOptions (" nullValue" , " -" )))
8989 assertNull(
90- CSVTypeCast .castTo(" -" , StringType , nullable = true , CSVOptions (" nullValue" , " -" )))
90+ CSVTypeCast .castTo(" -" , " _1" , StringType , nullable = true , CSVOptions (" nullValue" , " -" )))
91+ assertNull(
92+ CSVTypeCast .castTo(null , " _1" , IntegerType , nullable = true , CSVOptions (" nullValue" , " -" )))
93+
94+ // casting a null to not nullable field should throw an exception.
95+ var message = intercept[RuntimeException ] {
96+ CSVTypeCast .castTo(null , " _1" , IntegerType , nullable = false , CSVOptions (" nullValue" , " -" ))
97+ }.getMessage
98+ assert(message.contains(" null value found but field _1 is not nullable." ))
99+
100+ message = intercept[RuntimeException ] {
101+ CSVTypeCast .castTo(" -" , " _1" , StringType , nullable = false , CSVOptions (" nullValue" , " -" ))
102+ }.getMessage
103+ assert(message.contains(" null value found but field _1 is not nullable." ))
91104 }
92105
93106 test(" String type should also respect `nullValue`" ) {
94107 assertNull(
95- CSVTypeCast .castTo(" " , StringType , nullable = true , CSVOptions ()))
96- assert(
97- CSVTypeCast .castTo(" " , StringType , nullable = false , CSVOptions ()) ==
98- UTF8String .fromString(" " ))
108+ CSVTypeCast .castTo(" " , " _1" , StringType , nullable = true , CSVOptions ()))
99109
100110 assert(
101- CSVTypeCast .castTo(" " , StringType , nullable = true , CSVOptions (" nullValue" , " null" )) ==
111+ CSVTypeCast .castTo(" " , " _1 " , StringType , nullable = true , CSVOptions (" nullValue" , " null" )) ==
102112 UTF8String .fromString(" " ))
103113 assert(
104- CSVTypeCast .castTo(" " , StringType , nullable = false , CSVOptions (" nullValue" , " null" )) ==
114+ CSVTypeCast .castTo(" " , " _1 " , StringType , nullable = false , CSVOptions (" nullValue" , " null" )) ==
105115 UTF8String .fromString(" " ))
106116
107117 assertNull(
108- CSVTypeCast .castTo(null , StringType , nullable = true , CSVOptions (" nullValue" , " null" )))
118+ CSVTypeCast .castTo(null , " _1 " , StringType , nullable = true , CSVOptions (" nullValue" , " null" )))
109119 }
110120
111121 test(" Throws exception for empty string with non null type" ) {
112- val exception = intercept[NumberFormatException ]{
113- CSVTypeCast .castTo(" " , IntegerType , nullable = false , CSVOptions ())
122+ val exception = intercept[RuntimeException ]{
123+ CSVTypeCast .castTo(" " , " _1 " , IntegerType , nullable = false , CSVOptions ())
114124 }
115- assert(exception.getMessage.contains(" For input string: \"\" " ))
125+ assert(exception.getMessage.contains(" null value found but field _1 is not nullable. " ))
116126 }
117127
118128 test(" Types are cast correctly" ) {
119- assert(CSVTypeCast .castTo(" 10" , ByteType ) == 10 )
120- assert(CSVTypeCast .castTo(" 10" , ShortType ) == 10 )
121- assert(CSVTypeCast .castTo(" 10" , IntegerType ) == 10 )
122- assert(CSVTypeCast .castTo(" 10" , LongType ) == 10 )
123- assert(CSVTypeCast .castTo(" 1.00" , FloatType ) == 1.0 )
124- assert(CSVTypeCast .castTo(" 1.00" , DoubleType ) == 1.0 )
125- assert(CSVTypeCast .castTo(" true" , BooleanType ) == true )
129+ assert(CSVTypeCast .castTo(" 10" , " _1 " , ByteType ) == 10 )
130+ assert(CSVTypeCast .castTo(" 10" , " _1 " , ShortType ) == 10 )
131+ assert(CSVTypeCast .castTo(" 10" , " _1 " , IntegerType ) == 10 )
132+ assert(CSVTypeCast .castTo(" 10" , " _1 " , LongType ) == 10 )
133+ assert(CSVTypeCast .castTo(" 1.00" , " _1 " , FloatType ) == 1.0 )
134+ assert(CSVTypeCast .castTo(" 1.00" , " _1 " , DoubleType ) == 1.0 )
135+ assert(CSVTypeCast .castTo(" true" , " _1 " , BooleanType ) == true )
126136
127137 val timestampsOptions = CSVOptions (" timestampFormat" , " dd/MM/yyyy hh:mm" )
128138 val customTimestamp = " 31/01/2015 00:00"
129139 val expectedTime = timestampsOptions.timestampFormat.parse(customTimestamp).getTime
130140 val castedTimestamp =
131- CSVTypeCast .castTo(customTimestamp, TimestampType , nullable = true , timestampsOptions)
141+ CSVTypeCast .castTo(customTimestamp, " _1 " , TimestampType , nullable = true , timestampsOptions)
132142 assert(castedTimestamp == expectedTime * 1000L )
133143
134144 val customDate = " 31/01/2015"
135145 val dateOptions = CSVOptions (" dateFormat" , " dd/MM/yyyy" )
136146 val expectedDate = dateOptions.dateFormat.parse(customDate).getTime
137- val castedDate = CSVTypeCast .castTo(customTimestamp, DateType , nullable = true , dateOptions)
147+ val castedDate =
148+ CSVTypeCast .castTo(customTimestamp, " _1" , DateType , nullable = true , dateOptions)
138149 assert(castedDate == DateTimeUtils .millisToDays(expectedDate))
139150
140151 val timestamp = " 2015-01-01 00:00:00"
141- assert(CSVTypeCast .castTo(timestamp, TimestampType ) ==
152+ assert(CSVTypeCast .castTo(timestamp, " _1 " , TimestampType ) ==
142153 DateTimeUtils .stringToTime(timestamp).getTime * 1000L )
143- assert(CSVTypeCast .castTo(" 2015-01-01" , DateType ) ==
154+ assert(CSVTypeCast .castTo(" 2015-01-01" , " _1 " , DateType ) ==
144155 DateTimeUtils .millisToDays(DateTimeUtils .stringToTime(" 2015-01-01" ).getTime))
145156 }
146157
147158 test(" Float and Double Types are cast without respect to platform default Locale" ) {
148159 val originalLocale = Locale .getDefault
149160 try {
150161 Locale .setDefault(new Locale (" fr" , " FR" ))
151- assert(CSVTypeCast .castTo(" 1,00" , FloatType ) == 100.0 ) // Would parse as 1.0 in fr-FR
152- assert(CSVTypeCast .castTo(" 1,00" , DoubleType ) == 100.0 )
162+ assert(CSVTypeCast .castTo(" 1,00" , " _1 " , FloatType ) == 100.0 ) // Would parse as 1.0 in fr-FR
163+ assert(CSVTypeCast .castTo(" 1,00" , " _1 " , DoubleType ) == 100.0 )
153164 } finally {
154165 Locale .setDefault(originalLocale)
155166 }
156167 }
157168
158169 test(" Float NaN values are parsed correctly" ) {
159170 val floatVal : Float = CSVTypeCast .castTo(
160- " nn" , FloatType , nullable = true , CSVOptions (" nanValue" , " nn" )).asInstanceOf [Float ]
171+ " nn" , " _1 " , FloatType , nullable = true , CSVOptions (" nanValue" , " nn" )).asInstanceOf [Float ]
161172
162173 // Java implements the IEEE-754 floating point standard which guarantees that any comparison
163174 // against NaN will return false (except != which returns true)
@@ -166,32 +177,32 @@ class CSVTypeCastSuite extends SparkFunSuite {
166177
167178 test(" Double NaN values are parsed correctly" ) {
168179 val doubleVal : Double = CSVTypeCast .castTo(
169- " -" , DoubleType , nullable = true , CSVOptions (" nanValue" , " -" )).asInstanceOf [Double ]
180+ " -" , " _1 " , DoubleType , nullable = true , CSVOptions (" nanValue" , " -" )).asInstanceOf [Double ]
170181
171182 assert(doubleVal.isNaN)
172183 }
173184
174185 test(" Float infinite values can be parsed" ) {
175186 val floatVal1 = CSVTypeCast .castTo(
176- " max" , FloatType , nullable = true , CSVOptions (" negativeInf" , " max" )).asInstanceOf [Float ]
187+ " max" , " _1 " , FloatType , nullable = true , CSVOptions (" negativeInf" , " max" )).asInstanceOf [Float ]
177188
178189 assert(floatVal1 == Float .NegativeInfinity )
179190
180191 val floatVal2 = CSVTypeCast .castTo(
181- " max" , FloatType , nullable = true , CSVOptions (" positiveInf" , " max" )).asInstanceOf [Float ]
192+ " max" , " _1 " , FloatType , nullable = true , CSVOptions (" positiveInf" , " max" )).asInstanceOf [Float ]
182193
183194 assert(floatVal2 == Float .PositiveInfinity )
184195 }
185196
186197 test(" Double infinite values can be parsed" ) {
187198 val doubleVal1 = CSVTypeCast .castTo(
188- " max" , DoubleType , nullable = true , CSVOptions (" negativeInf" , " max" )
199+ " max" , " _1 " , DoubleType , nullable = true , CSVOptions (" negativeInf" , " max" )
189200 ).asInstanceOf [Double ]
190201
191202 assert(doubleVal1 == Double .NegativeInfinity )
192203
193204 val doubleVal2 = CSVTypeCast .castTo(
194- " max" , DoubleType , nullable = true , CSVOptions (" positiveInf" , " max" )
205+ " max" , " _1 " , DoubleType , nullable = true , CSVOptions (" positiveInf" , " max" )
195206 ).asInstanceOf [Double ]
196207
197208 assert(doubleVal2 == Double .PositiveInfinity )
0 commit comments