@@ -113,7 +113,9 @@ def cast_ibis_value(
113113
114114 Raises:
115115 TypeError: if the type cast cannot be executed"""
116- if value .type () == to_type :
116+ # normalize to nullable, which doesn't impact compatibility
117+ value_type = value .type ().copy (nullable = True )
118+ if value_type == to_type :
117119 return value
118120 # casts that just work
119121 # TODO(bmil): add to this as more casts are verified
@@ -189,52 +191,39 @@ def cast_ibis_value(
189191 ibis_dtypes .multipolygon : (IBIS_GEO_TYPE ,),
190192 }
191193
192- value = ibis_value_to_canonical_type (value )
193- if value .type () in good_casts :
194- if to_type in good_casts [value .type ()]:
194+ if value_type in good_casts :
195+ if to_type in good_casts [value_type ]:
195196 return value .try_cast (to_type ) if safe else value .cast (to_type )
196197 else :
197198 # this should never happen
198199 raise TypeError (
199- f"Unexpected value type { value . type () } . { constants .FEEDBACK_LINK } "
200+ f"Unexpected value type { value_type } . { constants .FEEDBACK_LINK } "
200201 )
201202
202203 # casts that need some encouragement
203204
204205 # BigQuery casts bools to lower case strings. Capitalize the result to match Pandas
205206 # TODO(bmil): remove this workaround after fixing Ibis
206- if value . type () == ibis_dtypes .bool and to_type == ibis_dtypes .string :
207+ if value_type == ibis_dtypes .bool and to_type == ibis_dtypes .string :
207208 if safe :
208209 return cast (ibis_types .StringValue , value .try_cast (to_type )).capitalize ()
209210 else :
210211 return cast (ibis_types .StringValue , value .cast (to_type )).capitalize ()
211212
212- if value . type () == ibis_dtypes .bool and to_type == ibis_dtypes .float64 :
213+ if value_type == ibis_dtypes .bool and to_type == ibis_dtypes .float64 :
213214 if safe :
214215 return value .try_cast (ibis_dtypes .int64 ).try_cast (ibis_dtypes .float64 )
215216 else :
216217 return value .cast (ibis_dtypes .int64 ).cast (ibis_dtypes .float64 )
217218
218- if value . type () == ibis_dtypes .float64 and to_type == ibis_dtypes .bool :
219+ if value_type == ibis_dtypes .float64 and to_type == ibis_dtypes .bool :
219220 return value != ibis_types .literal (0 )
220221
221222 raise TypeError (
222- f"Unsupported cast { value . type () } to { to_type } . { constants .FEEDBACK_LINK } "
223+ f"Unsupported cast { value_type } to { to_type } . { constants .FEEDBACK_LINK } "
223224 )
224225
225226
226- def ibis_value_to_canonical_type (value : ibis_types .Value ) -> ibis_types .Value :
227- """Converts an Ibis expression to canonical type.
228-
229- This is useful in cases where multiple types correspond to the same BigFrames dtype.
230- """
231- ibis_type = value .type ()
232- name = value .get_name ()
233- # Allow REQUIRED fields to be joined with NULLABLE fields.
234- nullable_type = ibis_type .copy (nullable = True )
235- return value .cast (nullable_type ).name (name )
236-
237-
238227def bigframes_dtype_to_ibis_dtype (
239228 bigframes_dtype : bigframes .dtypes .Dtype ,
240229) -> ibis_dtypes .DataType :
0 commit comments