fix(db): Fix JSON handling in WHERE statements for postgres

Signed-off-by: Joas Schilling <coding@schilljs.com>
pull/56504/head
Joas Schilling 2025-11-18 08:38:56 +07:00
parent b19e81428f
commit fb8caecbb0
No known key found for this signature in database
GPG Key ID: F72FA5B49FFA96B0
3 changed files with 50 additions and 1 deletions

@ -26,7 +26,7 @@ class Version33000Date20251106131209 extends SimpleMigrationStep {
$qb->update('share')
->set('attributes', $qb->createNamedParameter('[["permissions","download",true]]'))
->where($qb->expr()->eq('share_type', $qb->createNamedParameter(IShare::TYPE_CIRCLE, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->eq('attributes', $qb->createNamedParameter('[["permissions","download",null]]', IQueryBuilder::PARAM_STR)));
->andWhere($qb->expr()->eq('attributes', $qb->createNamedParameter('[["permissions","download",null]]'), IQueryBuilder::PARAM_JSON));
$qb->executeStatement();
}
}

@ -8,6 +8,8 @@
namespace OC\DB\QueryBuilder\ExpressionBuilder;
use OC\DB\QueryBuilder\QueryFunction;
use OCP\DB\QueryBuilder\ILiteral;
use OCP\DB\QueryBuilder\IParameter;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\DB\QueryBuilder\IQueryFunction;
@ -25,12 +27,24 @@ class PgSqlExpressionBuilder extends ExpressionBuilder {
case IQueryBuilder::PARAM_INT:
return new QueryFunction('CAST(' . $this->helper->quoteColumnName($column) . ' AS BIGINT)');
case IQueryBuilder::PARAM_STR:
case IQueryBuilder::PARAM_JSON:
return new QueryFunction('CAST(' . $this->helper->quoteColumnName($column) . ' AS TEXT)');
default:
return parent::castColumn($column, $type);
}
}
/**
* @inheritdoc
*/
protected function prepareColumn($column, $type) {
if ($type === IQueryBuilder::PARAM_JSON && !is_array($column) && !($column instanceof IParameter) && !($column instanceof ILiteral)) {
$column = $this->castColumn($column, $type);
}
return parent::prepareColumn($column, $type);
}
/**
* @inheritdoc
*/

@ -141,6 +141,41 @@ class ExpressionBuilderDBTest extends TestCase {
self::assertEquals('myvalue', $entries[0]['configvalue']);
}
public function testJson(): void {
$appId = $this->getUniqueID('testing');
$query = $this->connection->getQueryBuilder();
$query->insert('share')
->values([
'uid_owner' => $query->createNamedParameter('uid_owner'),
'item_type' => $query->createNamedParameter('item_type'),
'permissions' => $query->createNamedParameter(0),
'stime' => $query->createNamedParameter(0),
'accepted' => $query->createNamedParameter(0),
'mail_send' => $query->createNamedParameter(0),
'share_type' => $query->createNamedParameter(0),
'share_with' => $query->createNamedParameter($appId),
'attributes' => $query->createNamedParameter('[["permissions","before"]]'),
])
->executeStatement();
$query = $this->connection->getQueryBuilder();
$query->update('share')
->set('attributes', $query->createNamedParameter('[["permissions","after"]]'))
->where($query->expr()->eq('attributes', $query->createNamedParameter('[["permissions","before"]]'), IQueryBuilder::PARAM_JSON));
$query->executeStatement();
$query = $this->connection->getQueryBuilder();
$query->select('attributes')
->from('share')
->where($query->expr()->eq('share_with', $query->createNamedParameter($appId)));
$result = $query->executeQuery();
$entries = $result->fetchAll();
$result->closeCursor();
self::assertCount(1, $entries);
self::assertEquals('[["permissions","after"]]', $entries[0]['attributes']);
}
public function testDateTimeEquals(): void {
$dateTime = new \DateTime('2023-01-01');
$insert = $this->connection->getQueryBuilder();