Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQL is constructed incorrectly when using groupBy() to make Query Builder #184

Open
CarterZhou opened this issue Dec 30, 2014 · 3 comments
Labels

Comments

@CarterZhou
Copy link

The package may have a bug when it constructs SQL that uses group by.

I have two models: Channel and Program, and a Channel could have many Programs.
Use case: Display how many programs each channel has in channel list.

A very common way to achieve this is to use count() and group by in SQL.

So in php I define a query builder as follows:

$channels = Channel::select(
            array(
                'channels.id',
                'channels.name_en',
                'channels.name',
                DB::raw('COUNT(programs.id) AS number_of_programs')
            )
        )
        ->leftJoin('programs','programs.channel_id','=','channels.id')
        ->groupBy('channels.id');

And then let the package to generate JSON for us:

return Datatables::of($channels)->make(true);

On the surface it works well, my view showing number of programs of each channel as expected.
However, when I typed in search box, like 'sport', Datatables.js complains that there is something wrong when it fetched data and did not render the table.

I dug into laravel.log to see what exactly happened. It turns out that bllim constructed the SQL incorrectly like so:

select count(*) 
as aggregate from 
(select '1' as row from `channels` 
left join `programs` on `programs`.`channel_id` = `channels`.`id` 
where `channels`.`deleted_at` is null 
and 
LOWER(channels.id) LIKE %sport% or LOWER(channels.name_en) LIKE %sport% or LOWER(channels.name) LIKE %sport% or LOWER(COUNT(programs.id)) LIKE %sport%
group by `channels`.`id`) 
AS count_row_table

where all those LIKE operators did not compare with strings, let alone it even generates something is syntax error, like LOWER(COUNT(programs.id)) LIKE %sport%.

Next I did some searching in program list view. The underlying program query builder is simpler without groupBy():

$programs = Program::select(
            array(
                'programs.id',
                'programs.name',
                'programs.name_en',
                'channels.name as channel_name',
                'programs.start_date',
                'programs.end_date',
            )
        )->leftJoin('channels','channels.id','=','programs.channel_id');

This time Datatables.js rendered view correctly.
Again, I checked laravel.log and I found no syntax error in the SQL constructed:

select count(*) as aggregate 
from (select '1' as row from `programs` 
left join `channels` on `channels`.`id` = `programs`.`channel_id` 
where `programs`.`deleted_at` is null and (LOWER(programs.id) LIKE '%ebert%' or LOWER(programs.name) LIKE '%ebert%' or LOWER(programs.name_en) LIKE '%ebert%' or LOWER(channels.name) LIKE '%ebert%' or LOWER(programs.start_date) LIKE '%ebert%' or LOWER(programs.end_date) LIKE '%ebert%')) 
AS count_row_table

where term ebert was properly quoted.

@straube
Copy link

straube commented Mar 5, 2015

+1

@Ardakilic
Copy link

+1, having same issue, too

@MarkVaughn
Copy link
Contributor

as noted on the main git readme page, anyone who is willing to make a pull request please do

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants