Skip to content

Commit 6949364

Browse files
committed
Inline Limit/Offset/Quantifier into Select, simplify GroupBy
Eliminate three single-purpose Part wrapper objects (Limit, Offset, Quantifier) by inlining their logic directly into Select. This removes object allocation overhead, virtual method dispatch, and unnecessary class files. GroupBy no longer wraps columns in ColumnRef, storing ArgumentInterface|ExpressionInterface directly instead.
1 parent 4ac0bf5 commit 6949364

File tree

9 files changed

+59
-190
lines changed

9 files changed

+59
-190
lines changed

src/Sql/Argument/Value.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
* @param null|string|int|float|bool $value Scalar value, or null
1414
*/
1515
public function __construct(
16-
public null|string|int|float|bool $value
16+
public null|string|int|float|bool $value,
17+
public ?string $typeHint = null,
1718
) {
1819
}
1920

src/Sql/Part/GroupBy.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@
66

77
use PhpDb\Sql\Argument\Identifier;
88
use PhpDb\Sql\ArgumentInterface;
9+
use PhpDb\Sql\ExpressionInterface;
910
use PhpDb\Sql\Platform\AbstractSqlRenderer;
1011

1112
use function implode;
1213
use function is_array;
14+
use function is_string;
1315
use function str_replace;
1416

1517
class GroupBy extends AbstractPart
1618
{
17-
/** @var ColumnRef[]|null */
19+
/** @var list<ArgumentInterface|ExpressionInterface>|null */
1820
private ?array $group = null;
1921

2022
public function toSql(AbstractSqlRenderer $renderer, string $paramPrefix = '', int &$paramIndex = 0): ?string
@@ -25,9 +27,7 @@ public function toSql(AbstractSqlRenderer $renderer, string $paramPrefix = '', i
2527

2628
$groups = [];
2729

28-
foreach ($this->group as $ref) {
29-
$column = $ref->column;
30-
30+
foreach ($this->group as $column) {
3131
if ($column instanceof Identifier) {
3232
$groups[] = $renderer->qo . str_replace('.', $renderer->qs, $column->identifier) . $renderer->qc;
3333
} elseif ($column instanceof ArgumentInterface) {
@@ -50,10 +50,10 @@ public function add(mixed $group): static
5050
{
5151
if (is_array($group)) {
5252
foreach ($group as $g) {
53-
$this->group[] = new ColumnRef(0, $g);
53+
$this->group[] = is_string($g) ? new Identifier($g) : $g;
5454
}
5555
} else {
56-
$this->group[] = new ColumnRef(0, $group);
56+
$this->group[] = is_string($group) ? new Identifier($group) : $group;
5757
}
5858
return $this;
5959
}
@@ -65,10 +65,10 @@ public function get(): ?array
6565
}
6666

6767
$result = [];
68-
foreach ($this->group as $ref) {
69-
$result[] = $ref->column instanceof ArgumentInterface
70-
? $ref->column->getValue()
71-
: $ref->column;
68+
foreach ($this->group as $column) {
69+
$result[] = $column instanceof ArgumentInterface
70+
? $column->getValue()
71+
: $column;
7272
}
7373
return $result;
7474
}

src/Sql/Part/Limit.php

Lines changed: 0 additions & 41 deletions
This file was deleted.

src/Sql/Part/Offset.php

Lines changed: 0 additions & 41 deletions
This file was deleted.

src/Sql/Part/Quantifier.php

Lines changed: 0 additions & 57 deletions
This file was deleted.

src/Sql/Platform/AbstractSqlRenderer.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ public function renderArgument(
208208
$argument instanceof NullValue => 'NULL',
209209
$argument instanceof Parameter => $this->bindParameter($argument),
210210
$argument instanceof Value => $this->parameterContainer !== null
211-
? $this->bindValue($argument->value, $paramPrefix, $paramIndex)
211+
? $this->bindValue($argument->value, $paramPrefix, $paramIndex, $argument->typeHint)
212212
: $this->platform->quoteValue((string) $argument->value),
213213
$argument instanceof SelectArgument => $argument->select instanceof Select
214214
? '(' . $this->processSubSelect($argument->select) . ')'
@@ -235,9 +235,10 @@ public function bindValue(
235235
int|float|string|bool $value,
236236
string $paramPrefix,
237237
int &$paramIndex,
238+
?string $typeHint = null,
238239
): string {
239240
$name = $paramPrefix . $paramIndex++;
240-
$this->parameterContainer->offsetSet($name, $value);
241+
$this->parameterContainer->offsetSet($name, $value, $typeHint);
241242

242243
return $this->driver->formatParameterName($name);
243244
}

src/Sql/Select.php

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66

77
use Closure;
88
use Override;
9+
use PhpDb\Adapter\ParameterContainer;
10+
use PhpDb\Sql\Argument\Literal;
11+
use PhpDb\Sql\Argument\Select as SelectArgument;
12+
use PhpDb\Sql\Argument\Value;
913
use PhpDb\Sql\Part\Combine as CombinePart;
1014
use PhpDb\Sql\Part\GroupBy;
11-
use PhpDb\Sql\Part\Limit;
12-
use PhpDb\Sql\Part\Offset;
1315
use PhpDb\Sql\Part\OrderBy;
14-
use PhpDb\Sql\Part\Quantifier;
1516
use PhpDb\Sql\Part\Table;
1617
use PhpDb\Sql\Platform\AbstractSqlRenderer;
1718
use PhpDb\Sql\Predicate\PredicateInterface;
@@ -96,7 +97,7 @@ class Select extends AbstractPreparableSql
9697

9798
protected Table $table;
9899

99-
protected ?Quantifier $quantifier = null;
100+
protected Literal|SelectArgument|null $quantifier = null;
100101

101102
protected ?Where $where = null;
102103

@@ -106,9 +107,9 @@ class Select extends AbstractPreparableSql
106107

107108
protected ?OrderBy $orderBy = null;
108109

109-
protected ?Limit $limit = null;
110+
protected ?Value $limitValue = null;
110111

111-
protected ?Offset $offset = null;
112+
protected ?Value $offsetValue = null;
112113

113114
protected ?CombinePart $combine = null;
114115

@@ -154,7 +155,9 @@ public function from(array|string|TableIdentifier $table): static
154155
*/
155156
public function quantifier(ExpressionInterface|string $quantifier): static
156157
{
157-
($this->quantifier ??= new Quantifier())->set($quantifier);
158+
$this->quantifier = $quantifier instanceof ExpressionInterface
159+
? new SelectArgument($quantifier)
160+
: new Literal($quantifier);
158161
return $this;
159162
}
160163

@@ -256,7 +259,7 @@ public function limit(int|string $limit): static
256259
));
257260
}
258261

259-
($this->limit ??= new Limit())->set($limit);
262+
$this->limitValue = new Value($limit, ParameterContainer::TYPE_INTEGER);
260263
return $this;
261264
}
262265

@@ -273,7 +276,7 @@ public function offset(int|string $offset): static
273276
));
274277
}
275278

276-
($this->offset ??= new Offset())->set($offset);
279+
$this->offsetValue = new Value($offset, ParameterContainer::TYPE_INTEGER);
277280
return $this;
278281
}
279282

@@ -326,10 +329,10 @@ public function reset(string $part): static
326329
$this->having = null;
327330
break;
328331
case self::LIMIT:
329-
$this->limit = null;
332+
$this->limitValue = null;
330333
break;
331334
case self::OFFSET:
332-
$this->offset = null;
335+
$this->offsetValue = null;
333336
break;
334337
case self::ORDER:
335338
$this->orderBy = null;
@@ -346,15 +349,15 @@ public function getRawState(?string $key = null): mixed
346349
{
347350
$rawState = [
348351
self::TABLE => $this->table->getFrom(),
349-
self::QUANTIFIER => $this->quantifier?->get(),
352+
self::QUANTIFIER => $this->quantifier?->getValue(),
350353
self::COLUMNS => $this->table->getColumns(),
351354
self::JOINS => $this->table->joins() ?? new Join(),
352355
self::WHERE => $this->where ??= new Where(),
353356
self::ORDER => $this->orderBy?->get() ?? [],
354357
self::GROUP => $this->groupBy?->get() ?? [],
355358
self::HAVING => $this->having ??= new Having(),
356-
self::LIMIT => $this->limit?->get(),
357-
self::OFFSET => $this->offset?->get(),
359+
self::LIMIT => $this->limitValue?->value,
360+
self::OFFSET => $this->offsetValue?->value,
358361
self::COMBINE => $this->combine?->get() ?? [],
359362
];
360363
return $key !== null && array_key_exists($key, $rawState) ? $rawState[$key] : $rawState;
@@ -380,8 +383,10 @@ public function buildSqlString(AbstractSqlRenderer $renderer): string
380383

381384
$sql = 'SELECT';
382385

383-
if (($part = $this->quantifier?->toSql($renderer)) !== null) {
384-
$sql .= " $part";
386+
if ($this->quantifier !== null) {
387+
$sql .= $this->quantifier instanceof Literal
388+
? ' ' . $this->quantifier->literal
389+
: ' ' . $renderer->render($this->quantifier->getValue(), 'quantifier');
385390
}
386391

387392
$sql .= ' ' . $this->table->columns()->toSql($renderer);
@@ -404,11 +409,21 @@ public function buildSqlString(AbstractSqlRenderer $renderer): string
404409
if (($part = $this->orderBy?->toSql($renderer)) !== null) {
405410
$sql .= " $part";
406411
}
407-
if (($part = $this->limit?->toSql($renderer)) !== null) {
408-
$sql .= " $part";
412+
if ($this->limitValue !== null) {
413+
$pi = 0;
414+
$sql .= ' LIMIT ' . $renderer->renderArgument(
415+
$this->limitValue,
416+
$renderer->getParamPrefix() . 'limit',
417+
$pi,
418+
);
409419
}
410-
if (($part = $this->offset?->toSql($renderer)) !== null) {
411-
$sql .= " $part";
420+
if ($this->offsetValue !== null) {
421+
$pi = 0;
422+
$sql .= ' OFFSET ' . $renderer->renderArgument(
423+
$this->offsetValue,
424+
$renderer->getParamPrefix() . 'offset',
425+
$pi,
426+
);
412427
}
413428

414429
$combine = $this->combine?->toSql($renderer);
@@ -448,9 +463,6 @@ public function __get(string $name): Where|Join|Having
448463
public function __clone()
449464
{
450465
$this->table = clone $this->table;
451-
if ($this->quantifier !== null) {
452-
$this->quantifier = clone $this->quantifier;
453-
}
454466
if ($this->where !== null) {
455467
$this->where = clone $this->where;
456468
}
@@ -463,12 +475,6 @@ public function __clone()
463475
if ($this->orderBy !== null) {
464476
$this->orderBy = clone $this->orderBy;
465477
}
466-
if ($this->limit !== null) {
467-
$this->limit = clone $this->limit;
468-
}
469-
if ($this->offset !== null) {
470-
$this->offset = clone $this->offset;
471-
}
472478
if ($this->combine !== null) {
473479
$this->combine = clone $this->combine;
474480
}

0 commit comments

Comments
 (0)