{"record":{"id":"4be6e7b506f9c80e","repo":"phalcon/cphalcon","slug":"materialized-views-are-not-supported-by-this-diale","errorCode":null,"errorMessage":"Materialized views are not supported by this dialect","messagePattern":"Materialized views are not supported by this dialect","errorType":"exception","errorClass":"MaterializedViewsNotSupported","httpStatus":null,"severity":"error","filePath":"phalcon/Db/Dialect.zep","lineNumber":514,"sourceCode":"\n    /**\n     * Registers custom SQL functions\n     */\n    public function registerCustomFunction(string name, callable customFunction) -> <static>\n    {\n        let this->customFunctions[name] = customFunction;\n\n        return this;\n    }\n\n    /**\n     * Generates SQL to create a materialized view. Supported by PostgreSQL\n     * (`CREATE MATERIALIZED VIEW name AS <sql>`). Other dialects inherit\n     * this throw - MySQL and SQLite have no materialized-view concept.\n     */\n    public function createMaterializedView( string viewName,  array definition, string schemaName = null) -> string\n    {\n        throw new MaterializedViewsNotSupported();\n    }\n\n    /**\n     * Generates SQL to drop a materialized view. Supported by PostgreSQL.\n     */\n    public function dropMaterializedView( string viewName, string schemaName = null, bool ifExists = true) -> string\n    {\n        throw new MaterializedViewsNotSupported();\n    }\n\n    /**\n     * Generates SQL to refresh a materialized view. Supported by\n     * PostgreSQL. Pass `concurrent = true` for `REFRESH MATERIALIZED VIEW\n     * CONCURRENTLY ...`, which avoids blocking concurrent SELECTs (requires\n     * the view to have a unique index).\n     */\n    public function refreshMaterializedView( string viewName, string schemaName = null, bool concurrent = false) -> string\n    {","sourceCodeStart":496,"sourceCodeEnd":532,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Db/Dialect.zep#L496-L532","documentation":"The base Phalcon\\Db\\Dialect implements createMaterializedView() as an unconditional throw: materialized views are a PostgreSQL feature (`CREATE MATERIALIZED VIEW ... AS`), so only the Postgresql dialect overrides it. Calling it on a Mysql or Sqlite dialect/adapter raises MaterializedViewsNotSupported instead of emitting invalid SQL. The dialect exposes supportsMaterializedViews() (false on the base class) to probe this.","triggerScenarios":"Calling $connection->createMaterializedView(...) on a Pdo\\Mysql or Pdo\\Sqlite connection; generic migration code running the same DDL against every configured adapter; feature-probing by direct call instead of supportsMaterializedViews().","commonSituations":"Multi-database apps running a shared migration set; CI matrices (mysql + pgsql) where a PostgreSQL-only migration leaks into the MySQL run; code ported from a Postgres-centric project to adapters without matviews.","solutions":["Guard the call: if ($connection->getDialect()->supportsMaterializedViews()) { ... }.","On MySQL, emulate with a regular table plus INSERT ... SELECT refresh (cron/EVENT) - MySQL has no matview concept.","On SQLite, use a normal view or a shadow table refreshed in a transaction.","Move PostgreSQL-only DDL into driver-specific migration files."],"exampleFix":"// before\n$connection->createMaterializedView('sales_mv', [\n    'sql' => 'SELECT product_id, SUM(qty) FROM sales GROUP BY product_id',\n]); // throws MaterializedViewsNotSupported on MySQL/SQLite\n\n// after\nif ($connection->getDialect()->supportsMaterializedViews()) {\n    $connection->createMaterializedView('sales_mv', [\n        'sql' => 'SELECT product_id, SUM(qty) FROM sales GROUP BY product_id',\n    ]);\n} else {\n    $connection->execute(\n        'CREATE TABLE sales_mv AS SELECT product_id, SUM(qty) FROM sales GROUP BY product_id'\n    );\n}","handlingStrategy":"validation","validationCode":"if (!$connection->getDialect()->supportsMaterializedViews()) {\n    throw new RuntimeException('This database does not support materialized views');\n}\n$connection->createMaterializedView('sales_mv', ['sql' => $query]);","typeGuard":null,"tryCatchPattern":"use Phalcon\\Db\\Exceptions\\MaterializedViewsNotSupported;\n\ntry {\n    $connection->createMaterializedView('sales_mv', ['sql' => $query]);\n} catch (MaterializedViewsNotSupported $e) {\n    // Non-PostgreSQL connection - fall back to a plain table\n    $connection->execute(\"CREATE TABLE sales_mv AS {$query}\");\n}","preventionTips":["Gate driver-specific DDL with the dialect supports*() checks.","Split migrations per adapter instead of running one shared set.","Test migrations against every adapter in your support matrix."],"tags":["materialized-view","dialect","postgresql","mysql","sqlite","unsupported-feature"],"backgroundTag":"unsupported-dialect-feature","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}