Skip to content

Commit

Permalink
fix: explicitly forbid offset and limit in partitioned queries
Browse files Browse the repository at this point in the history
as there is no proper way to implement this that isn't very slow

Signed-off-by: Robin Appelman <[email protected]>
  • Loading branch information
icewind1991 committed Aug 12, 2024
1 parent 80aad73 commit 7f43c7d
Showing 1 changed file with 25 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
* 7. Update, delete and insert statements aren't allowed to contain cross-partition joins.
* 8. Queries that "GROUP BY" a column from the joined partition are not allowed.
* 9. Any `join` call needs to be made before any `where` call.
* 10. Queries that join cross-partition cannot use "LIMIT" or "OFFSET" in queries.
*
* [1]: A set of tables which can't be queried together with the rest of the tables, such as when sharding is used.
*/
Expand All @@ -113,6 +114,8 @@ class PartitionedQueryBuilder extends ShardedQueryBuilder {
private ?PartitionSplit $mainPartition = null;
private bool $hasPositionalParameter = false;
private QuoteHelper $quoteHelper;
private ?int $limit = null;
private ?int $offset = null;

public function __construct(
IQueryBuilder $builder,
Expand Down Expand Up @@ -397,6 +400,20 @@ public function delete($delete = null, $alias = null) {
return parent::delete($delete, $alias);
}

public function setMaxResults($maxResults) {
if ($maxResults > 0) {
$this->limit = (int)$maxResults;
}
return parent::setMaxResults($maxResults);
}

public function setFirstResult($firstResult) {
if ($firstResult > 0) {
$this->offset = (int)$firstResult;
}
return parent::setFirstResult($firstResult);
}

public function executeQuery(?IDBConnection $connection = null): IResult {
$this->applySelects();
if ($this->splitQueries && $this->hasPositionalParameter) {
Expand All @@ -405,6 +422,14 @@ public function executeQuery(?IDBConnection $connection = null): IResult {
foreach ($this->splitQueries as $split) {
$split->query->setParameters($this->getParameters(), $this->getParameterTypes());
}
if (count($this->splitQueries) > 0) {
if (is_int($this->limit)) {
throw new InvalidPartitionedQueryException("Limit is not allowed in partitioned queries");
}
if (is_int($this->offset)) {
throw new InvalidPartitionedQueryException("Offset is not allowed in partitioned queries");
}
}

$s = parent::getSQL();
$result = parent::executeQuery($connection);
Expand Down

0 comments on commit 7f43c7d

Please sign in to comment.