laravel-nestedset
                                
                                 laravel-nestedset copied to clipboard
                                
                                    laravel-nestedset copied to clipboard
                            
                            
                            
                        withDepth causes Cardinality violation mysql error
Description
Using withDepth results in a mysql error caused by a superfluous * selector. Changing the library code like below solves the issue.
Versions:
kalnoy/nestedset: 6.0.0 laravel/framework: 8.48.1 php: 8.0
Reproducable using:
Unit::withDepth()->get();
Error:
Illuminate\Database\QueryException
SQLSTATE[21000]: Cardinality violation: 1241 Operand should contain 1 column(s) (SQL: select *, (select *, count(1) - 1 from `units` as `_d` where `units`.`deleted_at` is null and `units`.`_lft` between `_d`.`_lft` and `_d`.`_rgt`) as `depth` from `units` where `units`.`deleted_at` is null)
I isolated the problem to the subquery for the depth value. Laravel somehow adds a *-selector to the query. MySQL cannot match the subquery result to a single value in the main query. To get rid of the *-selector I tweaked the library code as stated below.
Malfunctioning library code
# vendor/kalnoy/nestedset/src/QueryBuilder.php
# line 411 and following
$query = $this->model
            ->newScopedQuery('_d')
            ->toBase()
            ->selectRaw('count(1) - 1') // <-- not working
            ->from($this->model->getTable().' as '.$alias)
            ->whereRaw("{$table}.{$lft} between {$wrappedAlias}.{$lft} and {$wrappedAlias}.{$rgt}");
Working library code
# vendor/kalnoy/nestedset/src/QueryBuilder.php
# line 411 and following
$query = $this->model
            ->newScopedQuery('_d')
            ->toBase()
            ->select(DB::raw('count(1) - 1')) // <-- works :)
            ->from($this->model->getTable().' as '.$alias)
            ->whereRaw("{$table}.{$lft} between {$wrappedAlias}.{$lft} and {$wrappedAlias}.{$rgt}");
I found my error. I had some left-over code in my default Eloquent query, that led to the superfluous *.
After removing this, the library works as desired:
static::addGlobalScope('order', function (Builder $builder) {
    if(is_null($builder->getQuery()->columns)) {
        $builder->addSelect('*'); // <-- this
    }
    $builder->addSelect(
        DB::raw(/* some complex mysql terms */),
    )->orderBy('hierarchy');
});
I am leaving this here for others who encounter the same problem.