Bug: [QueryBuilder] select() TypeError: trim(): Argument #1 ($string) must be of type string, CodeIgniter\Database\RawSql given
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);
Expected Output
SELECT col1, `col2`
FROM `table`
Why do you want to use RawSql to only the first element?
Check this. #9009
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.
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()