@@ -475,20 +475,26 @@ protected function addTablePrefix($query, string $column): string
475
475
return $ column ;
476
476
}
477
477
478
- $ q = $ this ->getBaseQueryBuilder ($ query );
478
+ // Extract selected columns from the query
479
+ $ selects = $ this ->getSelectedColumns ($ query );
479
480
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
- $ match = preg_quote ($ column ).'\b| ' .preg_quote ($ this ->wrap ($ column ));
484
- if (preg_match ("/(\s)as(\s+)( $ match)/i " , $ sql )) {
485
- return $ column ;
486
- }
481
+ // We have a match
482
+ if (isset ($ selects ['columns ' ][$ column ])) {
483
+ return $ selects ['columns ' ][$ column ];
487
484
}
488
485
489
- $ prefix = $ this ->getTablePrefix ($ query );
486
+ // Multiple wildcards => Unable to determine prefix
487
+ if (in_array ('* ' , $ selects ['wildcards ' ]) || count (array_unique ($ selects ['wildcards ' ])) > 1 ) {
488
+ return $ column ;
489
+ }
490
490
491
- return $ prefix ? $ prefix .'. ' .$ column : $ column ;
491
+ // Use the only wildcard available
492
+ if (! empty ($ selects ['wildcards ' ])) {
493
+ return $ selects ['wildcards ' ][0 ].'. ' .$ column ;
494
+ }
495
+
496
+ // Fallback on table prefix
497
+ return ltrim ($ this ->getTablePrefix ($ query ).'. ' .$ column , '. ' );
492
498
}
493
499
494
500
/**
@@ -513,6 +519,49 @@ protected function getTablePrefix($query): ?string
513
519
return null ;
514
520
}
515
521
522
+ /**
523
+ * Get declared column names from the query.
524
+ *
525
+ * @param QueryBuilder|EloquentBuilder $query
526
+ */
527
+ protected function getSelectedColumns ($ query ): array
528
+ {
529
+ $ q = $ this ->getBaseQueryBuilder ($ query );
530
+
531
+ $ selects = [
532
+ 'wildcards ' => [],
533
+ 'columns ' => [],
534
+ ];
535
+
536
+ foreach ($ q ->columns ?? [] as $ select ) {
537
+ $ sql = trim ($ select instanceof Expression ? $ select ->getValue ($ this ->getConnection ()->getQueryGrammar ()) : $ select );
538
+ // Remove expressions
539
+ $ sql = preg_replace ('/\s*\w*\((?:[^()]*|(?R))*\)/ ' , '_ ' , $ sql );
540
+ // Remove multiple spaces
541
+ $ sql = preg_replace ('/\s+/ ' , ' ' , $ sql );
542
+ // Remove wrappers
543
+ $ sql = str_replace (['` ' , '" ' , '[ ' , '] ' ], '' , $ sql );
544
+ // Loop on select columns
545
+ foreach (explode (', ' , $ sql ) as $ column ) {
546
+ $ column = trim ($ column );
547
+ if (preg_match ('/[\w.]+\s+(?:as\s+)?([a-zA-Z0-9_]+)$/i ' , $ column , $ matches )) {
548
+ // Column with alias
549
+ $ selects ['columns ' ][$ matches [1 ]] = $ matches [1 ];
550
+ } elseif (preg_match ('/^([\w.]+)$/i ' , $ column )) {
551
+ // Column without alias
552
+ [$ table , $ name ] = str_contains ($ column , '. ' ) ? explode ('. ' , $ column ) : [null , $ column ];
553
+ if ($ name === '* ' ) {
554
+ $ selects ['wildcards ' ][] = $ table ?? '* ' ;
555
+ } else {
556
+ $ selects ['columns ' ][$ name ] = $ column ;
557
+ }
558
+ }
559
+ }
560
+ }
561
+
562
+ return $ selects ;
563
+ }
564
+
516
565
/**
517
566
* Prepare search keyword based on configurations.
518
567
*/
0 commit comments