|
147 | 147 | import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_ROW_LEVEL_DELETE; |
148 | 148 | import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_ROW_TYPE; |
149 | 149 | import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_SET_COLUMN_TYPE; |
| 150 | +import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_SET_FIELD_TYPE; |
150 | 151 | import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_TOPN_PUSHDOWN; |
151 | 152 | import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_TRUNCATE; |
152 | 153 | import static io.trino.testing.TestingConnectorBehavior.SUPPORTS_UPDATE; |
@@ -3041,6 +3042,156 @@ protected void verifySetColumnTypeFailurePermissible(Throwable e) |
3041 | 3042 | throw new AssertionError("Unexpected set column type failure", e); |
3042 | 3043 | } |
3043 | 3044 |
|
| 3045 | + @Test |
| 3046 | + public void testSetFieldType() |
| 3047 | + { |
| 3048 | + skipTestUnless(hasBehavior(SUPPORTS_CREATE_TABLE_WITH_DATA) && hasBehavior(SUPPORTS_ROW_TYPE)); |
| 3049 | + |
| 3050 | + if (!hasBehavior(SUPPORTS_SET_FIELD_TYPE)) { |
| 3051 | + try (TestTable table = new TestTable(getQueryRunner()::execute, "test_set_field_type_", "(col row(field int))")) { |
| 3052 | + assertQueryFails( |
| 3053 | + "ALTER TABLE " + table.getName() + " ALTER COLUMN col.field SET DATA TYPE bigint", |
| 3054 | + "This connector does not support setting field types"); |
| 3055 | + } |
| 3056 | + return; |
| 3057 | + } |
| 3058 | + |
| 3059 | + try (TestTable table = new TestTable(getQueryRunner()::execute, "test_set_field_type_", "AS SELECT CAST(row(123) AS row(field integer)) AS col")) { |
| 3060 | + assertEquals(getColumnType(table.getName(), "col"), "row(field integer)"); |
| 3061 | + |
| 3062 | + assertUpdate("ALTER TABLE " + table.getName() + " ALTER COLUMN col.field SET DATA TYPE bigint"); |
| 3063 | + |
| 3064 | + assertEquals(getColumnType(table.getName(), "col"), "row(field bigint)"); |
| 3065 | + assertThat(query("SELECT * FROM " + table.getName())) |
| 3066 | + .skippingTypesCheck() |
| 3067 | + .matches("SELECT row(bigint '123')"); |
| 3068 | + } |
| 3069 | + } |
| 3070 | + |
| 3071 | + @Test(dataProvider = "setFieldTypesDataProvider") |
| 3072 | + public void testSetFieldTypes(SetColumnTypeSetup setup) |
| 3073 | + { |
| 3074 | + skipTestUnless(hasBehavior(SUPPORTS_SET_FIELD_TYPE) && hasBehavior(SUPPORTS_CREATE_TABLE_WITH_DATA)); |
| 3075 | + |
| 3076 | + TestTable table; |
| 3077 | + try { |
| 3078 | + table = new TestTable( |
| 3079 | + getQueryRunner()::execute, |
| 3080 | + "test_set_field_type_", |
| 3081 | + " AS SELECT CAST(row(" + setup.sourceValueLiteral + ") AS row(field " + setup.sourceColumnType + ")) AS col"); |
| 3082 | + } |
| 3083 | + catch (Exception e) { |
| 3084 | + verifyUnsupportedTypeException(e, setup.sourceColumnType); |
| 3085 | + throw new SkipException("Unsupported column type: " + setup.sourceColumnType); |
| 3086 | + } |
| 3087 | + try (table) { |
| 3088 | + Runnable setFieldType = () -> assertUpdate("ALTER TABLE " + table.getName() + " ALTER COLUMN col.field SET DATA TYPE " + setup.newColumnType); |
| 3089 | + if (setup.unsupportedType) { |
| 3090 | + assertThatThrownBy(setFieldType::run) |
| 3091 | + .satisfies(this::verifySetFieldTypeFailurePermissible); |
| 3092 | + return; |
| 3093 | + } |
| 3094 | + setFieldType.run(); |
| 3095 | + |
| 3096 | + assertEquals(getColumnType(table.getName(), "col"), "row(field " + setup.newColumnType + ")"); |
| 3097 | + assertThat(query("SELECT * FROM " + table.getName())) |
| 3098 | + .skippingTypesCheck() |
| 3099 | + .matches("SELECT row(" + setup.newValueLiteral + ")"); |
| 3100 | + } |
| 3101 | + } |
| 3102 | + |
| 3103 | + @DataProvider |
| 3104 | + public Object[][] setFieldTypesDataProvider() |
| 3105 | + { |
| 3106 | + return setColumnTypeSetupData().stream() |
| 3107 | + .map(this::filterSetFieldTypesDataProvider) |
| 3108 | + .flatMap(Optional::stream) |
| 3109 | + .collect(toDataProvider()); |
| 3110 | + } |
| 3111 | + |
| 3112 | + protected Optional<SetColumnTypeSetup> filterSetFieldTypesDataProvider(SetColumnTypeSetup setup) |
| 3113 | + { |
| 3114 | + return Optional.of(setup); |
| 3115 | + } |
| 3116 | + |
| 3117 | + @Test |
| 3118 | + public void testSetFieldTypeCaseSensitivity() |
| 3119 | + { |
| 3120 | + skipTestUnless(hasBehavior(SUPPORTS_SET_FIELD_TYPE) && hasBehavior(SUPPORTS_NOT_NULL_CONSTRAINT)); |
| 3121 | + |
| 3122 | + try (TestTable table = new TestTable(getQueryRunner()::execute, "test_set_field_type_case_", " AS SELECT CAST(row(1) AS row(\"UPPER\" integer)) col")) { |
| 3123 | + assertEquals(getColumnType(table.getName(), "col"), "row(UPPER integer)"); |
| 3124 | + |
| 3125 | + assertUpdate("ALTER TABLE " + table.getName() + " ALTER COLUMN col.upper SET DATA TYPE bigint"); |
| 3126 | + assertEquals(getColumnType(table.getName(), "col"), "row(UPPER bigint)"); |
| 3127 | + assertThat(query("SELECT * FROM " + table.getName())) |
| 3128 | + .matches("SELECT CAST(row(1) AS row(UPPER bigint))"); |
| 3129 | + } |
| 3130 | + } |
| 3131 | + |
| 3132 | + @Test |
| 3133 | + public void testSetFieldTypeWithNotNull() |
| 3134 | + { |
| 3135 | + skipTestUnless(hasBehavior(SUPPORTS_SET_FIELD_TYPE) && hasBehavior(SUPPORTS_NOT_NULL_CONSTRAINT)); |
| 3136 | + |
| 3137 | + try (TestTable table = new TestTable(getQueryRunner()::execute, "test_set_field_type_null_", "(col row(field int) NOT NULL)")) { |
| 3138 | + assertFalse(columnIsNullable(table.getName(), "col")); |
| 3139 | + |
| 3140 | + assertUpdate("ALTER TABLE " + table.getName() + " ALTER COLUMN col.field SET DATA TYPE bigint"); |
| 3141 | + assertFalse(columnIsNullable(table.getName(), "col")); |
| 3142 | + } |
| 3143 | + } |
| 3144 | + |
| 3145 | + @Test |
| 3146 | + public void testSetFieldTypeWithComment() |
| 3147 | + { |
| 3148 | + skipTestUnless(hasBehavior(SUPPORTS_SET_FIELD_TYPE) && hasBehavior(SUPPORTS_CREATE_TABLE_WITH_COLUMN_COMMENT)); |
| 3149 | + |
| 3150 | + try (TestTable table = new TestTable(getQueryRunner()::execute, "test_set_field_type_comment_", "(col row(field int) COMMENT 'test comment')")) { |
| 3151 | + assertEquals(getColumnComment(table.getName(), "col"), "test comment"); |
| 3152 | + |
| 3153 | + assertUpdate("ALTER TABLE " + table.getName() + " ALTER COLUMN col.field SET DATA TYPE bigint"); |
| 3154 | + assertEquals(getColumnComment(table.getName(), "col"), "test comment"); |
| 3155 | + } |
| 3156 | + } |
| 3157 | + |
| 3158 | + @Test |
| 3159 | + public void testSetFieldIncompatibleType() |
| 3160 | + { |
| 3161 | + skipTestUnless(hasBehavior(SUPPORTS_SET_FIELD_TYPE) && hasBehavior(SUPPORTS_CREATE_TABLE_WITH_DATA)); |
| 3162 | + |
| 3163 | + try (TestTable table = new TestTable( |
| 3164 | + getQueryRunner()::execute, |
| 3165 | + "test_set_invalid_field_type_", |
| 3166 | + "(row_col row(field varchar), nested_col row(field row(nested int)))")) { |
| 3167 | + assertThatThrownBy(() -> assertUpdate("ALTER TABLE " + table.getName() + " ALTER COLUMN row_col.field SET DATA TYPE row(nested integer)")) |
| 3168 | + .satisfies(this::verifySetFieldTypeFailurePermissible); |
| 3169 | + assertThatThrownBy(() -> assertUpdate("ALTER TABLE " + table.getName() + " ALTER COLUMN row_col.field SET DATA TYPE integer")) |
| 3170 | + .satisfies(this::verifySetFieldTypeFailurePermissible); |
| 3171 | + assertThatThrownBy(() -> assertUpdate("ALTER TABLE " + table.getName() + " ALTER COLUMN nested_col.field SET DATA TYPE integer")) |
| 3172 | + .satisfies(this::verifySetFieldTypeFailurePermissible); |
| 3173 | + } |
| 3174 | + } |
| 3175 | + |
| 3176 | + @Test |
| 3177 | + public void testSetFieldOutOfRangeType() |
| 3178 | + { |
| 3179 | + skipTestUnless(hasBehavior(SUPPORTS_SET_FIELD_TYPE) && hasBehavior(SUPPORTS_CREATE_TABLE_WITH_DATA)); |
| 3180 | + |
| 3181 | + try (TestTable table = new TestTable( |
| 3182 | + getQueryRunner()::execute, |
| 3183 | + "test_set_field_type_invalid_range_", |
| 3184 | + "AS SELECT CAST(row(9223372036854775807) AS row(field bigint)) AS col")) { |
| 3185 | + assertThatThrownBy(() -> assertUpdate("ALTER TABLE " + table.getName() + " ALTER COLUMN col.field SET DATA TYPE integer")) |
| 3186 | + .satisfies(this::verifySetFieldTypeFailurePermissible); |
| 3187 | + } |
| 3188 | + } |
| 3189 | + |
| 3190 | + protected void verifySetFieldTypeFailurePermissible(Throwable e) |
| 3191 | + { |
| 3192 | + throw new AssertionError("Unexpected set field type failure", e); |
| 3193 | + } |
| 3194 | + |
3044 | 3195 | protected String getColumnType(String tableName, String columnName) |
3045 | 3196 | { |
3046 | 3197 | return (String) computeScalar(format("SELECT data_type FROM information_schema.columns WHERE table_schema = CURRENT_SCHEMA AND table_name = '%s' AND column_name = '%s'", |
|
0 commit comments