@@ -2200,6 +2200,149 @@ def test_execute_command_sets_complex_type_fields_correctly(
22002200 t_execute_statement_req .useArrowNativeTypes .intervalTypesAsArrow
22012201 )
22022202
2203+ def test_col_to_description_with_variant_type (self ):
2204+ # Test variant type detection from Arrow field metadata
2205+ col = ttypes .TColumnDesc (
2206+ columnName = "variant_col" ,
2207+ typeDesc = self ._make_type_desc (ttypes .TTypeId .STRING_TYPE ),
2208+ )
2209+
2210+ # Create a field with variant type in metadata
2211+ field = pyarrow .field (
2212+ "variant_col" ,
2213+ pyarrow .string (),
2214+ metadata = {b'Spark:DataType:SqlName' : b'VARIANT' }
2215+ )
2216+
2217+ result = ThriftBackend ._col_to_description (col , field )
2218+
2219+ # Verify the result has variant as the type
2220+ self .assertEqual (result [0 ], "variant_col" ) # Column name
2221+ self .assertEqual (result [1 ], "variant" ) # Type name (should be variant instead of string)
2222+ self .assertIsNone (result [2 ]) # No display size
2223+ self .assertIsNone (result [3 ]) # No internal size
2224+ self .assertIsNone (result [4 ]) # No precision
2225+ self .assertIsNone (result [5 ]) # No scale
2226+ self .assertIsNone (result [6 ]) # No null ok
2227+
2228+ def test_col_to_description_without_variant_type (self ):
2229+ # Test normal column without variant type
2230+ col = ttypes .TColumnDesc (
2231+ columnName = "normal_col" ,
2232+ typeDesc = self ._make_type_desc (ttypes .TTypeId .STRING_TYPE ),
2233+ )
2234+
2235+ # Create a normal field without variant metadata
2236+ field = pyarrow .field (
2237+ "normal_col" ,
2238+ pyarrow .string (),
2239+ metadata = {}
2240+ )
2241+
2242+ result = ThriftBackend ._col_to_description (col , field )
2243+
2244+ # Verify the result has string as the type (unchanged)
2245+ self .assertEqual (result [0 ], "normal_col" ) # Column name
2246+ self .assertEqual (result [1 ], "string" ) # Type name (should be string)
2247+ self .assertIsNone (result [2 ]) # No display size
2248+ self .assertIsNone (result [3 ]) # No internal size
2249+ self .assertIsNone (result [4 ]) # No precision
2250+ self .assertIsNone (result [5 ]) # No scale
2251+ self .assertIsNone (result [6 ]) # No null ok
2252+
2253+ def test_col_to_description_with_null_field (self ):
2254+ # Test handling of null field
2255+ col = ttypes .TColumnDesc (
2256+ columnName = "missing_field" ,
2257+ typeDesc = self ._make_type_desc (ttypes .TTypeId .STRING_TYPE ),
2258+ )
2259+
2260+ # Pass None as the field
2261+ result = ThriftBackend ._col_to_description (col , None )
2262+
2263+ # Verify the result has string as the type (unchanged)
2264+ self .assertEqual (result [0 ], "missing_field" ) # Column name
2265+ self .assertEqual (result [1 ], "string" ) # Type name (should be string)
2266+ self .assertIsNone (result [2 ]) # No display size
2267+ self .assertIsNone (result [3 ]) # No internal size
2268+ self .assertIsNone (result [4 ]) # No precision
2269+ self .assertIsNone (result [5 ]) # No scale
2270+ self .assertIsNone (result [6 ]) # No null ok
2271+
2272+ def test_hive_schema_to_description_with_arrow_schema (self ):
2273+ # Create a table schema with regular and variant columns
2274+ columns = [
2275+ ttypes .TColumnDesc (
2276+ columnName = "regular_col" ,
2277+ typeDesc = self ._make_type_desc (ttypes .TTypeId .STRING_TYPE ),
2278+ ),
2279+ ttypes .TColumnDesc (
2280+ columnName = "variant_col" ,
2281+ typeDesc = self ._make_type_desc (ttypes .TTypeId .STRING_TYPE ),
2282+ ),
2283+ ]
2284+ t_table_schema = ttypes .TTableSchema (columns = columns )
2285+
2286+ # Create an Arrow schema with one variant column
2287+ fields = [
2288+ pyarrow .field ("regular_col" , pyarrow .string ()),
2289+ pyarrow .field (
2290+ "variant_col" ,
2291+ pyarrow .string (),
2292+ metadata = {b'Spark:DataType:SqlName' : b'VARIANT' }
2293+ )
2294+ ]
2295+ arrow_schema = pyarrow .schema (fields )
2296+ schema_bytes = arrow_schema .serialize ().to_pybytes ()
2297+
2298+ # Get the description
2299+ description = ThriftBackend ._hive_schema_to_description (t_table_schema , schema_bytes )
2300+
2301+ # Verify regular column type
2302+ self .assertEqual (description [0 ][0 ], "regular_col" )
2303+ self .assertEqual (description [0 ][1 ], "string" )
2304+
2305+ # Verify variant column type
2306+ self .assertEqual (description [1 ][0 ], "variant_col" )
2307+ self .assertEqual (description [1 ][1 ], "variant" )
2308+
2309+ def test_hive_schema_to_description_with_null_schema_bytes (self ):
2310+ # Create a simple table schema
2311+ columns = [
2312+ ttypes .TColumnDesc (
2313+ columnName = "regular_col" ,
2314+ typeDesc = self ._make_type_desc (ttypes .TTypeId .STRING_TYPE ),
2315+ ),
2316+ ]
2317+ t_table_schema = ttypes .TTableSchema (columns = columns )
2318+
2319+ # Get the description with null schema_bytes
2320+ description = ThriftBackend ._hive_schema_to_description (t_table_schema , None )
2321+
2322+ # Verify column type remains unchanged
2323+ self .assertEqual (description [0 ][0 ], "regular_col" )
2324+ self .assertEqual (description [0 ][1 ], "string" )
2325+
2326+ def test_col_to_description_with_malformed_metadata (self ):
2327+ # Test handling of malformed metadata
2328+ col = ttypes .TColumnDesc (
2329+ columnName = "weird_field" ,
2330+ typeDesc = self ._make_type_desc (ttypes .TTypeId .STRING_TYPE ),
2331+ )
2332+
2333+ # Create a field with malformed metadata
2334+ field = pyarrow .field (
2335+ "weird_field" ,
2336+ pyarrow .string (),
2337+ metadata = {b'Spark:DataType:SqlName' : b'Some unexpected value' }
2338+ )
2339+
2340+ result = ThriftBackend ._col_to_description (col , field )
2341+
2342+ # Verify the type remains unchanged
2343+ self .assertEqual (result [0 ], "weird_field" ) # Column name
2344+ self .assertEqual (result [1 ], "string" ) # Type name (should remain string)
2345+
22032346
22042347if __name__ == "__main__" :
22052348 unittest .main ()
0 commit comments