Skip to content

Commit d1fad2e

Browse files
authored
Merge pull request #3227 from Seb33300/always-alias
fix: prevent ambiguous column names
2 parents f7c04c9 + 562552b commit d1fad2e

File tree

2 files changed

+42
-17
lines changed

2 files changed

+42
-17
lines changed

src/EloquentDataTable.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ protected function resolveRelationColumn(string $column): string
166166
$relation = str_replace('[]', '', implode('.', $parts));
167167

168168
if ($this->isNotEagerLoaded($relation)) {
169-
return $column;
169+
return parent::resolveRelationColumn($column);
170170
}
171171

172172
return $this->joinEagerLoadedColumn($relation, $columnName);
@@ -187,14 +187,14 @@ protected function joinEagerLoadedColumn($relation, $relationColumn)
187187
$lastQuery = $this->query;
188188
foreach (explode('.', $relation) as $eachRelation) {
189189
$model = $lastQuery->getRelation($eachRelation);
190-
$lastAlias = $tableAlias ?: $lastQuery->getModel()->getTable();
190+
$lastAlias = $tableAlias ?: $this->getTablePrefix($lastQuery);
191191
$tableAlias = $tableAlias.'_'.$eachRelation;
192192
$pivotAlias = $tableAlias.'_pivot';
193193
switch (true) {
194194
case $model instanceof BelongsToMany:
195195
$pivot = $model->getTable().' as '.$pivotAlias;
196196
$pivotPK = $pivotAlias.'.'.$model->getForeignPivotKeyName();
197-
$pivotFK = $lastAlias.'.'.$model->getParentKeyName();
197+
$pivotFK = ltrim($lastAlias.'.'.$model->getParentKeyName(), '.');
198198
$this->performJoin($pivot, $pivotPK, $pivotFK);
199199

200200
$related = $model->getRelated();
@@ -210,7 +210,7 @@ protected function joinEagerLoadedColumn($relation, $relationColumn)
210210
case $model instanceof HasOneThrough:
211211
$pivot = explode('.', $model->getQualifiedParentKeyName())[0].' as '.$pivotAlias; // extract pivot table from key
212212
$pivotPK = $pivotAlias.'.'.$model->getFirstKeyName();
213-
$pivotFK = $lastAlias.'.'.$model->getLocalKeyName();
213+
$pivotFK = ltrim($lastAlias.'.'.$model->getLocalKeyName(), '.');
214214
$this->performJoin($pivot, $pivotPK, $pivotFK);
215215

216216
$related = $model->getRelated();
@@ -226,12 +226,12 @@ protected function joinEagerLoadedColumn($relation, $relationColumn)
226226
case $model instanceof HasOneOrMany:
227227
$table = $model->getRelated()->getTable().' as '.$tableAlias;
228228
$foreign = $tableAlias.'.'.$model->getForeignKeyName();
229-
$other = $lastAlias.'.'.$model->getLocalKeyName();
229+
$other = ltrim($lastAlias.'.'.$model->getLocalKeyName(), '.');
230230
break;
231231

232232
case $model instanceof BelongsTo:
233233
$table = $model->getRelated()->getTable().' as '.$tableAlias;
234-
$foreign = $lastAlias.'.'.$model->getForeignKeyName();
234+
$foreign = ltrim($lastAlias.'.'.$model->getForeignKeyName(), '.');
235235
$other = $tableAlias.'.'.$model->getOwnerKeyName();
236236
break;
237237

src/QueryDataTable.php

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -388,7 +388,7 @@ public function getQuery(): QueryBuilder
388388
*/
389389
protected function resolveRelationColumn(string $column): string
390390
{
391-
return $column;
391+
return $this->addTablePrefix($this->query, $column);
392392
}
393393

394394
/**
@@ -451,7 +451,7 @@ protected function castColumn(string $column): string
451451
*/
452452
protected function compileQuerySearch($query, string $column, string $keyword, string $boolean = 'or'): void
453453
{
454-
$column = $this->addTablePrefix($query, $column);
454+
$column = $this->wrap($this->addTablePrefix($query, $column));
455455
$column = $this->castColumn($column);
456456
$sql = $column.' LIKE ?';
457457

@@ -470,20 +470,45 @@ protected function compileQuerySearch($query, string $column, string $keyword, s
470470
*/
471471
protected function addTablePrefix($query, string $column): string
472472
{
473-
if (! str_contains($column, '.')) {
474-
$q = $this->getBaseQueryBuilder($query);
475-
$from = $q->from ?? '';
473+
// Column is already prefixed
474+
if (str_contains($column, '.')) {
475+
return $column;
476+
}
476477

477-
if (! $from instanceof Expression) {
478-
if (str_contains((string) $from, ' as ')) {
479-
$from = explode(' as ', (string) $from)[1];
480-
}
478+
$q = $this->getBaseQueryBuilder($query);
479+
480+
// Column is an alias, no prefix required
481+
foreach ($q->columns ?? [] as $select) {
482+
$sql = trim($select instanceof Expression ? $select->getValue($this->getConnection()->getQueryGrammar()) : $select);
483+
if (str_ends_with($sql, ' as '.$column) || str_ends_with($sql, ' as '.$this->wrap($column))) {
484+
return $column;
485+
}
486+
}
487+
488+
// Add table prefix to column
489+
return $this->getTablePrefix($query).'.'.$column;
490+
}
481491

482-
$column = $from.'.'.$column;
492+
/**
493+
* Try to get the base table prefix.
494+
* To be used to prevent ambiguous field name.
495+
*
496+
* @param QueryBuilder|EloquentBuilder $query
497+
*/
498+
protected function getTablePrefix($query): ?string
499+
{
500+
$q = $this->getBaseQueryBuilder($query);
501+
$from = $q->from ?? '';
502+
503+
if (! $from instanceof Expression) {
504+
if (str_contains((string) $from, ' as ')) {
505+
$from = explode(' as ', (string) $from)[1];
483506
}
507+
508+
return $from;
484509
}
485510

486-
return $this->wrap($column);
511+
return null;
487512
}
488513

489514
/**

0 commit comments

Comments
 (0)