yiisoft/yii2 · error · yii\base\NotSupportedException

yii\db\mssql\conditions\InConditionBuilder::buildSubqueryInC

Error message

yii\db\mssql\conditions\InConditionBuilder::buildSubqueryInCondition is not supported by MSSQL.

What it means

yii\db\mssql\conditions\InConditionBuilder::buildSubqueryInCondition() (framework/db/mssql/conditions/InConditionBuilder.php:29) overrides the base builder to reject composite IN conditions where $columns is an array and $values is a Query — e.g. ['in', ['col1','col2'], $subquery]. SQL Server does not support row-value (tuple) comparisons like (a,b) IN (SELECT x,y ...), so Yii throws NotSupportedException instead of emitting invalid SQL. A single column with a subquery falls through to the parent implementation and works.

Source

Thrown at framework/db/mssql/conditions/InConditionBuilder.php:29

use yii\base\NotSupportedException;
use yii\db\Expression;

/**
 * {@inheritdoc}
 *
 * @author Dmytro Naumenko <d.naumenko.a@gmail.com>
 * @since 2.0.14
 */
class InConditionBuilder extends \yii\db\conditions\InConditionBuilder
{
    /**
     * {@inheritdoc}
     * @throws NotSupportedException if `$columns` is an array
     */
    protected function buildSubqueryInCondition($operator, $columns, $values, &$params)
    {
        if (is_array($columns)) {
            throw new NotSupportedException(__METHOD__ . ' is not supported by MSSQL.');
        }

        return parent::buildSubqueryInCondition($operator, $columns, $values, $params);
    }

    /**
     * {@inheritdoc}
     */
    protected function buildCompositeInCondition($operator, $columns, $values, &$params)
    {
        $quotedColumns = [];
        foreach ($columns as $i => $column) {
            if ($column instanceof Expression) {
                $column = $column->expression;
            }
            $quotedColumns[$i] = strpos($column, '(') === false ? $this->queryBuilder->db->quoteColumnName($column) : $column;
        }
        $vss = [];

View on GitHub (pinned to 66f00d18a2)

Solutions

  1. Rewrite as a correlated EXISTS: ->andWhere(['exists', (new Query())->select('1')->from('selected s')->where('s.o = t.order_id AND s.l = t.line')])
  2. Replace IN-subquery with a JOIN against the subquery and DISTINCT selection
  3. If the composite key can be reduced to one expression (e.g. a computed key), filter on that single column instead

Example fix

// before (works on MySQL/PG, throws NotSupportedException on MSSQL)
$query->andWhere(['in', ['order_id', 'line'], (new Query())->select(['order_id', 'line'])->from('selected_rows')]);

// after (portable)
$query->andWhere(['exists', (new Query())
    ->select('1')
    ->from('selected_rows sr')
    ->where('sr.order_id = t.order_id AND sr.line = t.line'),
]);
Defensive patterns

Strategy: validation

Validate before calling

function isMssqlCompositeInSubquery($columns, $values, string $driverName): bool
{
    return $driverName === 'sqlsrv'
        && is_array($columns)
        && $values instanceof \yii\db\Query;
}

if (isMssqlCompositeInSubquery($columns, $values, $db->driverName)) {
    throw new \RuntimeException('Composite IN with subquery is not supported by MSSQL — use EXISTS.');
}
$query->andWhere(['in', $columns, $values]);

Type guard

function isCompositeColumns($columns): bool
{
    return is_array($columns) && count($columns) > 1;
}

Try / catch

try {
    $rows = $query->all();
} catch (\yii\db\NotSupportedException $e) {
    // composite IN + subquery on MSSQL — rewrite as EXISTS
    \Yii::error($e->getMessage(), __METHOD__);
    throw new \RuntimeException('Rewrite this IN-subquery as EXISTS for SQL Server.', 0, $e);
}

Prevention

When it happens

Trigger: ->where(['in', ['order_id','line'], (new Query())->select(['o','l'])->from('selected')]) on a SQL Server connection; queries written and tested on MySQL/PostgreSQL (whose builders support composite IN with subqueries) then executed on MSSQL; composite-key matching against junction tables.

Common situations: Cross-DBMS applications where dev uses MySQL and production SQL Server; composite primary keys on junction/mapping tables; upgrading a project to run on MSSQL without auditing IN conditions.

Related errors


AI-assisted analysis of yiisoft/yii2@66f00d18a2 (2026-08-17). Data as JSON: /api/errors/a79c03025c8caf43. Report an issue: GitHub.