phalcon/cphalcon · error · UnsupportedOperator

Operator '{}' is not supported by this SQL dialect

Error message

Operator '{}' is not supported by this SQL dialect

What it means

getSqlExpressionBinaryOperations() throws UnsupportedOperator when a binary-op expression uses an operator from the dialect's guardedOperators list (['@@','@>','<@','&&','||','->','->>','#>','#>>']) that the current dialect does not support. Support is per-dialect: MySQL only allows '->' and '->>', SQLite allows '||','->','->>', PostgreSQL allows all of them. The guard exists so dialect-specific operators (mostly PostgreSQL JSONB/array ones) fail loudly instead of silently emitting SQL the server will reject.

Source

Thrown at phalcon/Db/Dialect.zep:929

    }

    /**
     * Resolve binary operations expressions
     *
     * @param array expression
     * @param string|null escapeChar
     * @param array bindCounts
     *
     * @return string
     */
    final protected function getSqlExpressionBinaryOperations( array expression, string escapeChar = null,  array bindCounts = []) -> string
    {
        var left, right, operator;

        let operator = expression["op"];

        if in_array(operator, this->guardedOperators) && !in_array(operator, this->supportedOperators) {
            throw new UnsupportedOperator(operator);
        }

        let left  = this->getSqlExpression(
            expression["left"],
            escapeChar,
            bindCounts
        );

        let right = this->getSqlExpression(
            expression["right"],
            escapeChar,
            bindCounts
        );

        return left . " " . operator . " " . right;
    }

    /**

View on GitHub (pinned to b7419de9cd)

Solutions

  1. Replace the guarded operator with syntax the current dialect supports, e.g. MySQL JSON extraction with '->' / '->>' or JSON_EXTRACT()/JSON_UNQUOTE(JSON_EXTRACT(...)) instead of '@>' or '#>>'
  2. Switch the adapter to the dialect that supports the operator (Postgresql) if you truly need JSONB semantics
  3. Branch the operator per adapter: check $adapter->getDialect()->supportedOperators (or getDialect() instanceof Postgresql) before building the expression
  4. As a last resort use a RawValue / hand-written SQL string for the dialect-specific part

Example fix

// before (MySQL adapter)
$expr = [
    'type'  => 'binary-op',
    'op'    => '@>',
    'left'  => ['type' => 'qualified', 'name' => 'meta'],
    'right' => ['type' => 'literal', 'value' => '"tags"'],
];

// after (MySQL: JSON_CONTAINS)
$expr = new RawValue("JSON_CONTAINS(meta, '\"tags\"')");
Defensive patterns

Strategy: type-guard

Validate before calling

const GUARDED = ['@@','@>','<@','&&','||','->','->>','#>','#>>'];
$supported = ['mysql' => ['->','->>'], 'sqlite' => ['||','->','->>'], 'postgresql' => GUARDED];
if (in_array($operator, GUARDED, true) && !in_array($operator, $supported[$driver], true)) {
    throw new InvalidArgumentException("Operator {$operator} not supported by {$driver}");
}

Type guard

/** @param array|string $dialect dialect name or Dialect instance */
function supportsOperator(string $driver, string $op): bool
{
    $map = [
        'mysql'      => ['->', '->>'],
        'sqlite'     => ['||', '->', '->>'],
        'postgresql' => ['@@','@>','<@','&&','||','->','->>','#>','#>>'],
    ];
    return in_array($op, $map[$driver] ?? [], true);
}

Try / catch

try {
    $sql = $dialect->select($definition);
} catch (\Phalcon\Db\Exceptions\UnsupportedOperator $e) {
    // fall back to dialect-specific raw SQL for this predicate
    $sql = $dialect->select($definitionWithoutOp) . ' /* unsupported op */';
}

Prevention

When it happens

Trigger: Compiling a raw expression with type 'binary-op' whose 'op' is e.g. '@>' or '#>>' while the adapter's dialect is Mysql or Sqlite; using dialect-agnostic query code with hardcoded JSONB operators on a MySQL connection; PHQL/RawValue expressions containing guarded operators on the wrong adapter.

Common situations: Porting an application from PostgreSQL to MySQL (or SQLite) while keeping JSONB/array operator expressions; shared model code deployed against different database backends; upgrading Phalcon to a version that added this guard, where previously the operator passed through unvalidated.

Related errors


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