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
- 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 '#>>'
- Switch the adapter to the dialect that supports the operator (Postgresql) if you truly need JSONB semantics
- Branch the operator per adapter: check $adapter->getDialect()->supportedOperators (or getDialect() instanceof Postgresql) before building the expression
- 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
- Feature-check operators against the dialect before building expressions
- Keep JSONB/array operators behind a PostgreSQL-only code path
- Run your test suite against every adapter you deploy
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
- Materialized views are not supported by this dialect
- RETURNING clauses are not supported by this dialect
- The index 'tables' is required in the definition array
- The index 'columns' is required in the definition array
- Invalid SQL-GROUP-BY expression
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/20086cdd8eeb9d06.
Report an issue: GitHub.