{"record":{"id":"8860f294f08e5181","repo":"phalcon/cphalcon","slug":"the-index-sql-is-required-in-the-definition-arra-8860f2","errorCode":null,"errorMessage":"The index 'sql' is required in the definition array","messagePattern":"The index 'sql' is required in the definition array","errorType":"exception","errorClass":"MissingDefinitionKey","httpStatus":null,"severity":"error","filePath":"phalcon/Db/Dialect/Postgresql.zep","lineNumber":319,"sourceCode":"        }\n        if tableComment {\n            let indexSqlAfterCreate .= \" COMMENT ON TABLE \" . table . \" IS '\" . str_replace(\"'\", \"''\", tableComment) . \"';\";\n        }\n\n        let sql .= \";\" . indexSqlAfterCreate;\n\n        return sql;\n    }\n\n    /**\n     * Generates SQL to create a materialized view.\n     */\n    public function createMaterializedView( string viewName,  array definition, string schemaName = null) -> string\n    {\n        var viewSql;\n\n        if unlikely !fetch viewSql, definition[\"sql\"] {\n            throw new MissingDefinitionKey(\"sql\");\n        }\n\n        return \"CREATE MATERIALIZED VIEW \"\n            . this->prepareTable(viewName, schemaName)\n            . \" AS \" . viewSql;\n    }\n\n    /**\n     * Generates SQL to create a view\n     */\n    public function createView( string viewName,  array definition, string schemaName = null) -> string\n    {\n        var viewSql;\n\n        if unlikely !fetch viewSql, definition[\"sql\"] {\n            throw new MissingDefinitionKey(\"sql\");\n        }\n","sourceCodeStart":301,"sourceCodeEnd":337,"githubUrl":"https://github.com/phalcon/cphalcon/blob/b7419de9cd0a8a3f48441ead84c9f8415d463e25/phalcon/Db/Dialect/Postgresql.zep#L301-L337","documentation":"The PostgreSQL dialect's createMaterializedView() throws MissingDefinitionKey when the definition array has no 'sql' key. A materialized view is just CREATE MATERIALIZED VIEW name AS <query>, so the underlying SELECT under 'sql' is the only required element.","triggerScenarios":"Calling $adapter->createMaterializedView('mv_stats', []) or with the query under a different key ('query', 'select'); helper-generated definitions where the SQL body key is missing for empty materialized views.","commonSituations":"Report/aggregate pipeline code creating materialized views from templates; refactoring view creation helpers shared between CREATE VIEW and CREATE MATERIALIZED VIEW paths.","solutions":["Pass the SELECT under 'sql': $adapter->createMaterializedView('mv_stats', ['sql' => 'SELECT ... GROUP BY ...'])","Verify the key name if the definition comes from YAML/JSON config"],"exampleFix":"// before\n$connection->createMaterializedView('mv_stats', ['query' => 'SELECT count(*) FROM logs']);\n\n// after\n$connection->createMaterializedView('mv_stats', ['sql' => 'SELECT count(*) FROM logs']);","handlingStrategy":"validation","validationCode":"if (!isset($definition['sql']) || trim($definition['sql']) === '') {\n    throw new InvalidArgumentException('createMaterializedView requires the query under \"sql\"');\n}","typeGuard":"function isCreatableViewDefinition(array $definition): bool\n{\n    return isset($definition['sql']) && is_string($definition['sql']) && trim($definition['sql']) !== '';\n}","tryCatchPattern":"try {\n    $connection->createMaterializedView($name, $definition);\n} catch (\\Phalcon\\Db\\Exceptions\\MissingDefinitionKey $e) {\n    throw new RuntimeException(\"Cannot create materialized view {$name}: \" . $e->getMessage(), 0, $e);\n}","preventionTips":["Build materialized-view definitions through a single helper that enforces the 'sql' key","Add REFRESH logic separately; do not overload the definition array with extra keys expecting defaults"],"tags":["phalcon","postgresql","ddl","materialized-view","definition-array"],"backgroundTag":"missing-definition-key","analyzedSha":"b7419de9cd0a8a3f48441ead84c9f8415d463e25","analyzedAt":"2026-08-21T06:21:18.811Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}