{"record":{"id":"78bb0af32b46fc58","repo":"prestodb/presto","slug":"invalid-table-property","errorCode":"INVALID_TABLE_PROPERTY","errorMessage":"Key/value types of a MAP column must be plain types","messagePattern":"Key/value types of a MAP column must be plain types","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-accumulo/src/main/java/com/facebook/presto/accumulo/AccumuloClient.java","lineNumber":181,"sourceCode":"        validateColumns(meta);\n        validateLocalityGroups(meta);\n        if (!AccumuloTableProperties.isExternal(meta.getProperties())) {\n            validateInternalTable(meta);\n        }\n    }\n\n    private static void validateColumns(ConnectorTableMetadata meta)\n    {\n        // Check all the column types, and throw an exception if the types of a map are complex\n        // While it is a rare case, this is not supported by the Accumulo connector\n        ImmutableSet.Builder<String> columnNameBuilder = ImmutableSet.builder();\n        for (ColumnMetadata column : meta.getColumns()) {\n            if (Types.isMapType(column.getType())) {\n                if (Types.isMapType(Types.getKeyType(column.getType()))\n                        || Types.isMapType(Types.getValueType(column.getType()))\n                        || Types.isArrayType(Types.getKeyType(column.getType()))\n                        || Types.isArrayType(Types.getValueType(column.getType()))) {\n                    throw new PrestoException(INVALID_TABLE_PROPERTY, \"Key/value types of a MAP column must be plain types\");\n                }\n            }\n\n            columnNameBuilder.add(column.getName().toLowerCase(Locale.ENGLISH));\n        }\n\n        // Validate the columns are distinct\n        if (columnNameBuilder.build().size() != meta.getColumns().size()) {\n            throw new PrestoException(INVALID_TABLE_PROPERTY, \"Duplicate column names are not supported\");\n        }\n\n        Optional<Map<String, Pair<String, String>>> columnMapping = AccumuloTableProperties.getColumnMapping(meta.getProperties());\n        if (columnMapping.isPresent()) {\n            // Validate there are no duplicates in the column mapping\n            long distinctMappings = columnMapping.get().values().stream().distinct().count();\n            if (distinctMappings != columnMapping.get().size()) {\n                throw new PrestoException(INVALID_TABLE_PROPERTY, \"Duplicate column family/qualifier pair detected in column mapping, check the value of \" + AccumuloTableProperties.COLUMN_MAPPING);\n            }","sourceCodeStart":163,"sourceCodeEnd":199,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-accumulo/src/main/java/com/facebook/presto/accumulo/AccumuloClient.java#L163-L199","documentation":"Presto's TRUNCATE TABLE statement only works on real base tables. In TruncateTableTask.execute, the metadata resolver is asked whether the target qualifiesName refers to a materialized view; if so, a SemanticException with code NOT_SUPPORTED is thrown because truncating a materialized view would invalidate its refresh semantics and is not implemented by the engine.","triggerScenarios":"Running `TRUNCATE TABLE <name>` where <name> resolves to an existing materialized view (metadataResolver.isMaterializedView returns true) and the schema itself exists.","commonSituations":"Developers assuming materialized views can be reset like tables to force a full recompute; migration scripts that blindly truncate a list of relations; automation that iterates information_schema without distinguishing views/matviews from tables.","solutions":["Identify the object via `SHOW CREATE TABLE <name>` or system metadata; if it is a materialized view, drop and recreate it instead of truncating.","If the goal is a full refresh, run `REFRESH MATERIALIZED VIEW <name>` (or drop/recreate) rather than TRUNCATE.","If you intended to truncate an underlying storage table, truncate that base table, not the materialized view that reads from it.","If you are the connector author needing truncate support, override the view/matview rejection by routing the statement to the base table handle in your connector rather than the matview name."],"exampleFix":"-- before\nTRUNCATE TABLE analytics.daily_sales_mv;\n-- after\nCALL system.runtime.refresh_materialized_view('analytics', 'daily_sales_mv');\n-- or: DROP MATERIALIZED VIEW analytics.daily_sales_mv; then recreate","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":["presto","sql","materialized-view","not-supported"],"backgroundTag":"operation-not-supported-on-view","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}