phalcon/cphalcon · error · Phalcon\Db\Exceptions\MissingDefinitionKey

The index 'sql' is required in the definition array

Error message

The index 'sql' is required in the definition array

What it means

Phalcon\Db\Dialect\Sqlite::createView() requires the $definition array to contain a 'sql' key holding the SELECT statement for the view; otherwise MissingDefinitionKey('sql') is thrown. The dialect only wraps the supplied query in "CREATE VIEW ... AS <sql>", so with the key missing there is nothing to create.

Source

Thrown at phalcon/Db/Dialect/Sqlite.zep:294

            for check in checks {
                let createLines[] = this->getCheckClause(check, "`");
            }
        }

        let sql .= join(",\n\t", createLines) . "\n)";

        return sql;
    }

    /**
     * Generates SQL to create a view
     */
    public function createView( string viewName,  array definition, string schemaName = null) -> string
    {
        var viewSql;

        if unlikely !fetch viewSql, definition["sql"] {
            throw new MissingDefinitionKey("sql");
        }

        return "CREATE VIEW " . this->prepareTable(viewName, schemaName) . " AS " . viewSql;
    }

    /**
     * Generates SQL describing a table
     *
     * ```php
     * print_r(
     *     $dialect->describeColumns("posts")
     * );
     * ```
     */
    public function describeColumns( string table, string schema = null) -> string
    {
        /**
         * `table_xinfo` mirrors `table_info` but exposes the `hidden` column:

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Pass the query inside the array: $dialect->createView('v_active', ['sql' => 'SELECT * FROM posts WHERE active = 1'])
  2. Validate isset($definition['sql']) && is_string($definition['sql']) && $definition['sql'] !== '' before calling createView()
  3. Check the config/migration source that produced the definition and fix the missing view query

Example fix

// before
$sql = $dialect->createView('v_active', 'SELECT * FROM posts WHERE active = 1');

// after
$sql = $dialect->createView('v_active', ['sql' => 'SELECT * FROM posts WHERE active = 1']);
Defensive patterns

Strategy: validation

Validate before calling

if (!isset($definition['sql']) || !is_string($definition['sql']) || '' === trim($definition['sql'])) {
    throw new InvalidArgumentException("createView definition requires a non-empty 'sql' string");
}
$sql = $dialect->createView('v_active', $definition);

Try / catch

try {
    $sql = $dialect->createView('v_active', $definition);
} catch (\Phalcon\Db\Exceptions\MissingDefinitionKey $e) {
    throw new InvalidArgumentException('Invalid view definition for v_active: ' . $e->getMessage(), 0, $e);
}

Prevention

When it happens

Trigger: Calling createView('v_active', 'SELECT ...') and passing the query string directly instead of an array; createView('v_active', []) with an empty definition; definitions assembled from config where the 'sql' entry was lost or renamed.

Common situations: Copy-pasting the raw SELECT as the second argument instead of wrapping it in ['sql' => ...]; view migrations generated by tools that emit the query under a different key; empty definitions produced when a config lookup fails silently.

Related errors


AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21). Data as JSON: /api/errors/8bb15dd46d553408. Report an issue: GitHub.