CodeIgniter4 icon indicating copy to clipboard operation
CodeIgniter4 copied to clipboard

Bug: [QueryBuilder] select() TypeError: trim(): Argument #1 ($string) must be of type string, CodeIgniter\Database\RawSql given

Open maniaba opened this issue 1 year ago • 4 comments

PHP Version

8.1

CodeIgniter4 Version

4.5.3

CodeIgniter4 Installation Method

Composer (as dependency to an existing project)

Which operating systems have you tested for this bug?

Windows, Linux

Which server did you use?

apache

Database

MySQL (ver. 8.3.0)

What happened?

I encountered a TypeError when running a test that involves selecting columns using RawSql in combination with string column names. The error message indicates that the trim() function is receiving a CodeIgniter\Database\RawSql object instead of a string.

TypeError: trim(): Argument #1 ($string) must be of type string, CodeIgniter\Database\RawSql given

/vendor/codeigniter4/framework/system/Database/BaseBuilder.php:415
/vendor/codeigniter4/framework/system/Model.php:930

Steps to Reproduce


$query = model(Model::class)
->select([
    new RawSql('col1'),
    'col2'
])->builder()->getCompiledSelect();

print_r($query);

Expected Output

SELECT `col1`, `col2`
FROM `table`

Anything else?

If only RawSql objects are passed to the select method, it works fine. However, when combining RawSql objects with strings, the error occurs.

I temporarily resolved the issue by chaining the select method calls separately for RawSql and string columns:


$query = model(Model::class)
->select(new RawSql('col1'))
->select('col2')
->builder()->getCompiledSelect();

print_r($query);

maniaba avatar Jun 27 '24 10:06 maniaba

Expected Output

SELECT col1, `col2`
FROM `table`

Why do you want to use RawSql to only the first element?

kenjis avatar Jun 27 '24 21:06 kenjis

Check this. #9009

kenjis avatar Jun 28 '24 00:06 kenjis

Expected Output

SELECT col1, `col2`
FROM `table`

Why do you want to use RawSql to only the first element?

I have developed a custom library that dynamically constructs queries and passes the columns to the select method. Depending on the complexity of the query, this library automatically determines whether to return an instance of RawSql or a string. This approach is necessary to handle complex SQL scenarios where parts of the query may need to be constructed using raw SQL expressions.

maniaba avatar Jun 28 '24 05:06 maniaba

Check this. #9009

@kenjis

Still not fixed

Try to reverse the order in tests :

        $builder->select([
            new RawSql("IF(salary > 5000, 'High', 'Low') AS salary_level"),
            'employee_id',
        ]);

I think the problem is the method: BaseBuilder::compileSelect()

maniaba avatar Jun 28 '24 10:06 maniaba