CodeIgniter4: Bug: QueryBuilder inconsistent behaviour with multiple `set()`s
PHP Version
8.1
CodeIgniter4 Version
4.3.1
CodeIgniter4 Installation Method
Composer (using codeigniter4/appstarter
)
Which operating systems have you tested for this bug?
macOS
Which server did you use?
apache
Database
MySQL 8
What happened?
Using multiple set()
s with RawSql
doesn’t produce consistent sql statements.
Working SQL (1):
INSERT INTO `auth_bearer` (`jti`, `proctorID`, `token_type`, `expires`) VALUES ('jti', 12, 'handover', DATE_ADD(NOW(), INTERVAL 2 HOUR))
Working SQL (2):
INSERT INTO `auth_bearer` (`jti`, `proctorID`, `token_type`, `expires`) VALUES ('jti', 12, 'handover', DATE_ADD(NOW(), INTERVAL 2 HOUR))
Working SQL (3):
INSERT INTO `auth_bearer` (`jti`, `proctorID`, `token_type`, `expires`) VALUES ('jti', 12, 'handover', DATE_ADD(NOW(), INTERVAL 2 HOUR))
Generates bad SQL:
INSERT INTO `auth_bearer` (`jti`, `proctorID`, `token_type`, expires = DATE_ADD(NOW(), INTERVAL 2 HOUR)) VALUES ('jti', 12, 'handover', )
Silently failing SQL:
INSERT INTO `auth_bearer` (`jti`, `proctorID`, `token_type`) VALUES ('jti', '12', 'handover')
Failing with exception: You must use the "set" method to insert an entry.
Steps to Reproduce
The following code produce different sql statements, some working and some not working:
$db = db_connect();
CLI::write('Working SQL (1):', 'green');
CLI::write($db->table('auth_bearer')
->set([
'jti' => 'jti',
'proctorID' => 12,
'token_type' => 'handover',
])
->set('expires', 'DATE_ADD(NOW(), INTERVAL 2 HOUR)', false)
->getCompiledInsert(true));
CLI::write('Working SQL (2):', 'green');
CLI::write($db->table('auth_bearer')
->set([
'jti' => 'jti',
'proctorID' => 12,
'token_type' => 'handover',
'expires' => new RawSql('DATE_ADD(NOW(), INTERVAL 2 HOUR)')
])
->getCompiledInsert(true));
CLI::write('Working SQL (3):', 'green');
CLI::write($db->table('auth_bearer')
->set('jti', 'jti')
->set('proctorID', 12)
->set('token_type', 'handover')
->set('expires', 'DATE_ADD(NOW(), INTERVAL 2 HOUR)', false)
->getCompiledInsert(true));
CLI::write('Generates bad SQL:', 'red');
CLI::write($db->table('auth_bearer')
->set([
'jti' => 'jti',
'proctorID' => 12,
'token_type' => 'handover',
])
->set('expires = DATE_ADD(NOW(), INTERVAL 2 HOUR)', null, false)
->getCompiledInsert(true));
CLI::write('Silently failing SQL:', 'red');
CLI::write($db->table('auth_bearer')
->set([
'jti' => 'jti',
'proctorID' => '12',
'token_type' => 'handover',
])
->set(new RawSql('expires = DATE_ADD(NOW(), INTERVAL 2 HOUR)'))
->getCompiledInsert(true));
try {
CLI::write($db->table('auth_bearer')
->set(new RawSql('expires = DATE_ADD(NOW(), INTERVAL 2 HOUR)'))
->getCompiledInsert(true));
}
catch (DatabaseException $e) {
CLI::write('Failing with exception: ' . $e->getMessage(), 'red');
}
Expected Output
Same statements in all valid cases.
Anything else?
No response
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 15 (15 by maintainers)
I sent a PR to fix Silently failing SQL https://github.com/codeigniter4/CodeIgniter4/issues/7143#issuecomment-1385258336 See #7148
@tangix I submitted a PR to fix the functionality of
where()
so that it behaves the same wayset()
does.You can set both key and value to use RawSql.
You can include an operator in the key or leave it out for =
You can also use only RawSql for key and leave value null.
If the PR is merged you can replace the whereHaving() in system/Database/BaseBuilder.php with the one from the PR to patch until next release.
https://github.com/codeigniter4/CodeIgniter4/pull/7147