@@ -113,7 +113,9 @@ def cast_ibis_value(
113
113
114
114
Raises:
115
115
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 :
117
119
return value
118
120
# casts that just work
119
121
# TODO(bmil): add to this as more casts are verified
@@ -189,52 +191,39 @@ def cast_ibis_value(
189
191
ibis_dtypes .multipolygon : (IBIS_GEO_TYPE ,),
190
192
}
191
193
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 ]:
195
196
return value .try_cast (to_type ) if safe else value .cast (to_type )
196
197
else :
197
198
# this should never happen
198
199
raise TypeError (
199
- f"Unexpected value type { value . type () } . { constants .FEEDBACK_LINK } "
200
+ f"Unexpected value type { value_type } . { constants .FEEDBACK_LINK } "
200
201
)
201
202
202
203
# casts that need some encouragement
203
204
204
205
# BigQuery casts bools to lower case strings. Capitalize the result to match Pandas
205
206
# 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 :
207
208
if safe :
208
209
return cast (ibis_types .StringValue , value .try_cast (to_type )).capitalize ()
209
210
else :
210
211
return cast (ibis_types .StringValue , value .cast (to_type )).capitalize ()
211
212
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 :
213
214
if safe :
214
215
return value .try_cast (ibis_dtypes .int64 ).try_cast (ibis_dtypes .float64 )
215
216
else :
216
217
return value .cast (ibis_dtypes .int64 ).cast (ibis_dtypes .float64 )
217
218
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 :
219
220
return value != ibis_types .literal (0 )
220
221
221
222
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 } "
223
224
)
224
225
225
226
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
-
238
227
def bigframes_dtype_to_ibis_dtype (
239
228
bigframes_dtype : bigframes .dtypes .Dtype ,
240
229
) -> ibis_dtypes .DataType :
0 commit comments