Skip to content

Commit 26dab63

Browse files
laylatichygitbutler-client
authored andcommitted
refactor(database): only alias when duplicate target tables detected
Instead of aliasing all root-level relations (which broke whereRaw with bare table names), detect duplicate target tables in the query builder and only alias those via withPropertyNameAlias(). Single-relation cases keep bare table names, preserving backward compatibility. Remove getOwnerTableAlias (now a no-op), revert FieldStatement/ JoinStatement/doc changes that were only needed for universal aliasing.
1 parent d555e2b commit 26dab63

16 files changed

Lines changed: 65 additions & 53 deletions

File tree

docs/1-essentials/03-database.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ The `through` parameter specifies the intermediate model class. The target model
272272

273273
```sql
274274
LEFT JOIN profiles ON profiles.author_id = authors.id
275-
LEFT JOIN addresses AS address ON address.profile_id = profiles.id
275+
LEFT JOIN addresses ON addresses.profile_id = profiles.id
276276
```
277277

278278
When conventions don't match, optional parameters can override the join fields:

packages/database/src/BelongsTo.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ public function getJoinStatement(): JoinStatement
105105
? sprintf('%s AS %s', $tableName, $tableAlias)
106106
: $tableName;
107107

108-
// LEFT JOIN authors AS author ON author.id = books.author_id
108+
// LEFT JOIN authors ON authors.id = books.author_id
109109
return new JoinStatement(sprintf(
110110
'LEFT JOIN %s ON %s = %s',
111111
$tableRef,
@@ -171,7 +171,7 @@ private function isSelfReferencing(): bool
171171
private function getOwnerJoin(ModelInspector $ownerModel): string
172172
{
173173
$ownerJoin = $this->ownerJoin;
174-
$ownerTable = $this->getOwnerTableAlias(ownerTableName: $ownerModel->getTableName());
174+
$ownerTable = $ownerModel->getTableName();
175175

176176
if ($ownerJoin && ! strpos($ownerJoin, '.')) {
177177
$ownerJoin = sprintf('%s.%s', $ownerTable, $ownerJoin);

packages/database/src/BelongsToMany.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ private function resolveOwnerJoin(
247247
private function resolveRelationJoin(ModelInspector $ownerModel): string
248248
{
249249
$relationJoin = $this->relationJoin;
250-
$ownerTable = $this->getOwnerTableAlias(ownerTableName: $ownerModel->getTableName());
250+
$ownerTable = $ownerModel->getTableName();
251251

252252
if (
253253
$relationJoin

packages/database/src/Builder/QueryBuilders/SelectQueryBuilder.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,27 @@ public function getResolvedRelations(): array
500500
$relations = [...$relations, ...$resolvedRelations];
501501
}
502502

503+
return $this->shouldUsePropertyNameAlias($relations);
504+
}
505+
506+
/**
507+
* @param Relation[] $relations
508+
*
509+
* @return Relation[]
510+
*/
511+
private function shouldUsePropertyNameAlias(array $relations): array
512+
{
513+
$rootTables = arr(input: $relations)
514+
->filter(filter: fn (Relation $_, string $path) => ! str_contains(haystack: $path, needle: '.'))
515+
->map(map: fn (Relation $relation) => inspect(model: $relation)->getTableName())
516+
->toArray();
517+
518+
$counts = array_count_values(array: $rootTables);
519+
520+
arr(input: $rootTables)
521+
->filter(filter: fn (string $table) => $counts[$table] > 1)
522+
->each(each: fn (string $_, string $path) => $relations[$path]->withPropertyNameAlias());
523+
503524
return $relations;
504525
}
505526

packages/database/src/HasMany.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ private function isSelfReferencing(): bool
189189
private function getRelationJoin(ModelInspector $relationModel): string
190190
{
191191
$relationJoin = $this->relationJoin;
192-
$ownerTable = $this->getOwnerTableAlias(ownerTableName: $relationModel->getTableName());
192+
$ownerTable = $relationModel->getTableName();
193193

194194
if ($relationJoin && ! strpos($relationJoin, '.')) {
195195
$relationJoin = sprintf(

packages/database/src/HasManyThrough.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ private function resolveOwnerJoin(
216216
private function resolveRelationJoin(ModelInspector $ownerModel): string
217217
{
218218
$relationJoin = $this->relationJoin;
219-
$ownerTable = $this->getOwnerTableAlias(ownerTableName: $ownerModel->getTableName());
219+
$ownerTable = $ownerModel->getTableName();
220220

221221
if (
222222
$relationJoin

packages/database/src/HasOne.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ private function isSelfReferencing(): bool
159159
private function getRelationJoin(ModelInspector $relationModel): string
160160
{
161161
$relationJoin = $this->relationJoin;
162-
$ownerTable = $this->getOwnerTableAlias(ownerTableName: $relationModel->getTableName());
162+
$ownerTable = $relationModel->getTableName();
163163

164164
if ($relationJoin && ! strpos($relationJoin, '.')) {
165165
$relationJoin = sprintf(

packages/database/src/HasOneThrough.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ private function resolveOwnerJoin(
173173
private function resolveRelationJoin(ModelInspector $ownerModel): string
174174
{
175175
$relationJoin = $this->relationJoin;
176-
$ownerTable = $this->getOwnerTableAlias(ownerTableName: $ownerModel->getTableName());
176+
$ownerTable = $ownerModel->getTableName();
177177

178178
if (
179179
$relationJoin

packages/database/src/HasTableAlias.php

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,25 @@
88

99
trait HasTableAlias
1010
{
11+
public bool $withPropertyNameAlias = false;
12+
13+
public function withPropertyNameAlias(): self
14+
{
15+
$this->withPropertyNameAlias = true;
16+
17+
return $this;
18+
}
19+
1120
private function getTableAlias(string $tableName): string
1221
{
1322
if ($this->parent === null) {
1423
return $tableName;
1524
}
1625

1726
if ($this->parent === '') {
18-
$alias = $this->property->getName();
19-
20-
return $alias === $tableName
21-
? $tableName
22-
: str(string: $alias)->wrap('`')->toString();
27+
return $this->withPropertyNameAlias
28+
? $this->property->getName()
29+
: $tableName;
2330
}
2431

2532
return str(string: $this->parent)
@@ -31,22 +38,6 @@ private function getTableAlias(string $tableName): string
3138
'_',
3239
$this->property->getName(),
3340
)
34-
->wrap('`')
35-
->toString();
36-
}
37-
38-
private function getOwnerTableAlias(string $ownerTableName): string
39-
{
40-
if ($this->parent === null || $this->parent === '') {
41-
return $ownerTableName;
42-
}
43-
44-
return str(string: $this->parent)
45-
->replace(
46-
search: '.',
47-
replace: '_',
48-
)
49-
->wrap('`')
5041
->toString();
5142
}
5243

packages/database/src/QueryStatements/FieldStatement.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ function (string $part) use ($dialect) {
4545
return $part;
4646
}
4747

48-
return match ($dialect) {
49-
DatabaseDialect::SQLITE => $part,
50-
DatabaseDialect::POSTGRESQL => sprintf('"%s"', $part),
51-
default => sprintf('`%s`', $part),
52-
};
48+
if ($dialect === DatabaseDialect::SQLITE) {
49+
return $part;
50+
}
51+
52+
return sprintf('`%s`', $part);
5353
},
5454
)
5555
->implode('.');

0 commit comments

Comments
 (0)