|
17 | 17 | from sqlalchemy.sql.schema import Column, MetaData, Table |
18 | 18 | from sqlalchemy.sql.selectable import TextualSelect |
19 | 19 |
|
20 | | -from pyathena.sqlalchemy.types import TINYINT, AthenaStruct, Tinyint |
| 20 | +from pyathena.sqlalchemy.types import TINYINT, AthenaArray, AthenaMap, AthenaStruct, Tinyint |
21 | 21 | from tests.pyathena.conftest import ENV |
22 | 22 |
|
23 | 23 |
|
@@ -1997,3 +1997,145 @@ def test_compile_temporal_query_by_timestamp_with_hint(self, engine): |
1997 | 1997 | f"SELECT count({ENV.schema}.{table_name}.col_1) AS count_1 \n" |
1998 | 1998 | f"FROM {ENV.schema}.{table_name} FOR VERSION AS OF '{timestamp}'" |
1999 | 1999 | ) |
| 2000 | + |
| 2001 | + def test_create_table_with_array_types(self, engine): |
| 2002 | + """Test DDL compilation for ARRAY types.""" |
| 2003 | + engine, conn = engine |
| 2004 | + table_name = "test_create_table_with_array_types" |
| 2005 | + table = Table( |
| 2006 | + table_name, |
| 2007 | + MetaData(schema=ENV.schema), |
| 2008 | + Column("id", types.Integer), |
| 2009 | + Column("tags", AthenaArray(types.String)), |
| 2010 | + Column("scores", AthenaArray(types.Integer)), |
| 2011 | + Column("nested_arrays", AthenaArray(AthenaArray(types.String))), |
| 2012 | + Column( |
| 2013 | + "struct_array", |
| 2014 | + AthenaArray(AthenaStruct(("name", types.String), ("age", types.Integer))), |
| 2015 | + ), |
| 2016 | + awsathena_location=f"{ENV.s3_staging_dir}{ENV.schema}/{table_name}/", |
| 2017 | + awsathena_file_format="PARQUET", |
| 2018 | + ) |
| 2019 | + |
| 2020 | + # Test DDL compilation |
| 2021 | + create_ddl = CreateTable(table).compile(dialect=engine.dialect) |
| 2022 | + ddl_string = str(create_ddl) |
| 2023 | + |
| 2024 | + # Verify ARRAY types are correctly compiled |
| 2025 | + assert "tags ARRAY<STRING>" in ddl_string |
| 2026 | + assert "scores ARRAY<INTEGER>" in ddl_string |
| 2027 | + assert "nested_arrays ARRAY<ARRAY<STRING>>" in ddl_string |
| 2028 | + assert "struct_array ARRAY<ROW(name STRING, age INTEGER)>" in ddl_string |
| 2029 | + |
| 2030 | + def test_create_table_with_map_types(self, engine): |
| 2031 | + """Test DDL compilation for MAP types.""" |
| 2032 | + engine, conn = engine |
| 2033 | + table_name = "test_create_table_with_map_types" |
| 2034 | + table = Table( |
| 2035 | + table_name, |
| 2036 | + MetaData(schema=ENV.schema), |
| 2037 | + Column("id", types.Integer), |
| 2038 | + Column("attributes", AthenaMap(types.String, types.String)), |
| 2039 | + Column("metrics", AthenaMap(types.String, types.Integer)), |
| 2040 | + Column( |
| 2041 | + "complex_map", |
| 2042 | + AthenaMap( |
| 2043 | + types.String, AthenaStruct(("value", types.String), ("count", types.Integer)) |
| 2044 | + ), |
| 2045 | + ), |
| 2046 | + Column("nested_map", AthenaMap(types.String, AthenaArray(types.String))), |
| 2047 | + awsathena_location=f"{ENV.s3_staging_dir}{ENV.schema}/{table_name}/", |
| 2048 | + awsathena_file_format="PARQUET", |
| 2049 | + ) |
| 2050 | + |
| 2051 | + # Test DDL compilation |
| 2052 | + create_ddl = CreateTable(table).compile(dialect=engine.dialect) |
| 2053 | + ddl_string = str(create_ddl) |
| 2054 | + |
| 2055 | + # Verify MAP types are correctly compiled |
| 2056 | + assert "attributes MAP<STRING, STRING>" in ddl_string |
| 2057 | + assert "metrics MAP<STRING, INTEGER>" in ddl_string |
| 2058 | + assert "complex_map MAP<STRING, ROW(value STRING, count INTEGER)>" in ddl_string |
| 2059 | + assert "nested_map MAP<STRING, ARRAY<STRING>>" in ddl_string |
| 2060 | + |
| 2061 | + def test_create_table_with_struct_types(self, engine): |
| 2062 | + """Test DDL compilation for STRUCT types.""" |
| 2063 | + engine, conn = engine |
| 2064 | + table_name = "test_create_table_with_struct_types" |
| 2065 | + table = Table( |
| 2066 | + table_name, |
| 2067 | + MetaData(schema=ENV.schema), |
| 2068 | + Column("id", types.Integer), |
| 2069 | + Column( |
| 2070 | + "user_info", |
| 2071 | + AthenaStruct( |
| 2072 | + ("name", types.String), ("age", types.Integer), ("email", types.String) |
| 2073 | + ), |
| 2074 | + ), |
| 2075 | + Column( |
| 2076 | + "nested_struct", |
| 2077 | + AthenaStruct( |
| 2078 | + ( |
| 2079 | + "personal", |
| 2080 | + AthenaStruct(("first_name", types.String), ("last_name", types.String)), |
| 2081 | + ), |
| 2082 | + ("preferences", AthenaMap(types.String, types.String)), |
| 2083 | + ), |
| 2084 | + ), |
| 2085 | + Column( |
| 2086 | + "struct_with_array", |
| 2087 | + AthenaStruct( |
| 2088 | + ("tags", AthenaArray(types.String)), ("scores", AthenaArray(types.Integer)) |
| 2089 | + ), |
| 2090 | + ), |
| 2091 | + awsathena_location=f"{ENV.s3_staging_dir}{ENV.schema}/{table_name}/", |
| 2092 | + awsathena_file_format="PARQUET", |
| 2093 | + ) |
| 2094 | + |
| 2095 | + # Test DDL compilation |
| 2096 | + create_ddl = CreateTable(table).compile(dialect=engine.dialect) |
| 2097 | + ddl_string = str(create_ddl) |
| 2098 | + |
| 2099 | + # Verify STRUCT types are correctly compiled |
| 2100 | + assert "user_info ROW(name STRING, age INTEGER, email STRING)" in ddl_string |
| 2101 | + assert ( |
| 2102 | + "nested_struct ROW(personal ROW(first_name STRING, last_name STRING), " |
| 2103 | + "preferences MAP<STRING, STRING>)" in ddl_string |
| 2104 | + ) |
| 2105 | + assert "struct_with_array ROW(tags ARRAY<STRING>, scores ARRAY<INTEGER>)" in ddl_string |
| 2106 | + |
| 2107 | + def test_create_table_with_complex_nested_types(self, engine): |
| 2108 | + """Test DDL compilation for complex nested combinations of ARRAY, MAP, and STRUCT.""" |
| 2109 | + engine, conn = engine |
| 2110 | + table_name = "test_create_table_with_complex_nested_types" |
| 2111 | + table = Table( |
| 2112 | + table_name, |
| 2113 | + MetaData(schema=ENV.schema), |
| 2114 | + Column("id", types.Integer), |
| 2115 | + Column( |
| 2116 | + "data", |
| 2117 | + AthenaArray( |
| 2118 | + AthenaMap( |
| 2119 | + types.String, |
| 2120 | + AthenaStruct( |
| 2121 | + ("value", types.String), |
| 2122 | + ("metadata", AthenaMap(types.String, types.String)), |
| 2123 | + ("tags", AthenaArray(types.String)), |
| 2124 | + ), |
| 2125 | + ) |
| 2126 | + ), |
| 2127 | + ), |
| 2128 | + awsathena_location=f"{ENV.s3_staging_dir}{ENV.schema}/{table_name}/", |
| 2129 | + awsathena_file_format="PARQUET", |
| 2130 | + ) |
| 2131 | + |
| 2132 | + # Test DDL compilation |
| 2133 | + create_ddl = CreateTable(table).compile(dialect=engine.dialect) |
| 2134 | + ddl_string = str(create_ddl) |
| 2135 | + |
| 2136 | + # Verify complex nested type is correctly compiled |
| 2137 | + expected_type = ( |
| 2138 | + "data ARRAY<MAP<STRING, ROW(value STRING, metadata MAP<STRING, STRING>, " |
| 2139 | + "tags ARRAY<STRING>)>>" |
| 2140 | + ) |
| 2141 | + assert expected_type in ddl_string |
0 commit comments