phalcon/cphalcon · error · InvalidSqlExpression
Invalid SQL expression
Error message
Invalid SQL expression
What it means
Phalcon\Db\Dialect::getSqlExpression() compiles intermediate-representation (IR) expression arrays - the nodes the PHQL compiler produces - into SQL. Every node must carry a 'type' discriminator naming its shape ('scalar', 'binary-op', 'functionCall', ...). An array without 'type' cannot be compiled and throws InvalidSqlExpression.
Source
Thrown at phalcon/Db/Dialect.zep:270
*/
if fetch columnAlias, columnExpression["sqlAlias"] || fetch columnAlias, columnExpression["alias"] {
return this->prepareColumnAlias(column, columnAlias, escapeChar);
}
return this->prepareColumnAlias(column, null, escapeChar);
}
/**
* Transforms an intermediate representation for an expression into a database system valid expression
*/
public function getSqlExpression( array expression, string escapeChar = null, array bindCounts = []) -> string
{
int i;
var type, times, postTimes, rawValue, value, nestedDefinition;
array placeholders;
if unlikely !fetch type, expression["type"] {
throw new InvalidSqlExpression();
}
switch type {
/**
* Resolve scalar column expressions
*/
case "scalar":
return this->getSqlExpressionScalar(
expression,
escapeChar,
bindCounts
);
/**
* Resolve object expressions
*/
case "object":
return this->getSqlExpressionObject(View on GitHub (pinned to b7419de9cd)
Solutions
- Give the node a valid 'type' key matching one of the cases in Dialect::getSqlExpression().
- Prefer Phalcon\Db\RawValue or PHQL itself instead of hand-crafting IR arrays.
- If you must build IR, wrap node construction in a helper that always sets 'type' first.
Example fix
// before
$sql = $dialect->getSqlExpression(['value' => 'robots.name']); // throws InvalidSqlExpression
// after
$sql = $dialect->getSqlExpression([
'type' => 'qualified',
'name' => 'name',
'domain' => 'robots',
]); Defensive patterns
Strategy: validation
Validate before calling
if (!isset($expression['type'])) {
throw new InvalidArgumentException('IR expression node requires a "type" discriminator');
}
$sql = $dialect->getSqlExpression($expression); Type guard
function isTypedExpressionNode(array $node): bool
{
return isset($node['type']) && is_string($node['type']);
} Prevention
- Avoid calling getSqlExpression directly - use PHQL or Phalcon\Db\RawValue.
- When debugging IR, dump the array and verify every nested node has 'type'.
- Centralize IR construction in tested helpers that set 'type' first.
When it happens
Trigger: Calling $dialect->getSqlExpression(['value' => 'x']) directly with no 'type' key; hand-built IR fed to the dialect or select builders; nested expression arrays where a sub-node lacks 'type'; middleware that mutates expression arrays and drops the key.
Common situations: Advanced usage extending the dialect or hand-building IR for expressions; debugging PHQL by inspecting and re-feeding compiled arrays; custom query builders that construct nodes without a type-first discipline.
Related errors
- Invalid SQL expression type '{}'
- ON CONFLICT requires at least one conflict-target column
- ON CONFLICT DO UPDATE requires at least one update column
- The 'dialectClass' '{className}' must implement Phalcon\Db\D
- Savepoints are not supported by this database adapter
AI-assisted analysis of phalcon/cphalcon@b7419de9cd (2026-08-21).
Data as JSON: /api/errors/427c8c2f2a1f0471.
Report an issue: GitHub.