[12.x] feat: query builder aliases for expressions#58436
[12.x] feat: query builder aliases for expressions#58436taylorotwell merged 1 commit intolaravel:12.xfrom
Conversation
4bebe0e to
d97f59b
Compare
d97f59b to
38ccfa0
Compare
|
The failing static analysis check is because of some blade compiler stuff. Not touched that part. |
Double aliasing in MySQL when using an existing associative array of selects with column aliasesThis looks like a really useful feature, but it caused a problem in our test suite in a very specific scenario: If you already have an existing associative array of selects with your own column aliases, and then pass it to Example:$selects = [
'conference_registration_id' => 'conference_registrations.id AS conference_registration_id',
'user_id' => 'conference_registrations.user_id',
];
-Model::select($selects)->get();
+Model::select(array_values($selects))->get();A user can work around this by applying Could this feature be opt-in? Otherwise, Laravel may automatically create aliases in users' queries, potentially causing issues, whether through double aliasing or the addition of unintended aliases. |
|
@u01jmg3 I did only change the behaviour when an DB::table('example')->select([
'conference_registration_id' => 'conference_registrations.id AS conference_registration_id',
'user_id' => 'conference_registrations.user_id',
])->dd();
// Laravel 12.47.0:
// select
// "conference_registrations"."id" as "conference_registration_id",
// "conference_registrations"."user_id"
// from "example
// Laravel 12.48.0:
// select
// "conference_registrations"."id" as "conference_registration_id",
// "conference_registrations"."user_id"
// from "exampleSo honestly, I don't understand your issue and how it relates to my pr. You must provide more information. Like how the sql was before/after to understand the impact. |
PHP/**
* Combine necessary tables to return Conference Attendee data.
*
* @param Conference $conference
* @param array $excludedColumns
* @param boolean $withHtml
* @return \Illuminate\Database\Eloquent\Collection
*/
public static function getAttendees(Conference $conference, array $excludedColumns = [], $withHtml = true)
{
$selects = [
'conference_registration_id' => 'conference_registrations.id AS conference_registration_id',
'conference_id' => 'conference_registrations.conference_id',
'user_id' => 'conference_registrations.user_id',
'ars_membership_no' => 'ars_membership_no',
'ars_validated' => 'ars_validated',
'email' => 'email',
'requirements' => \DB::raw('IF(conference_registration_categories.id IS NULL, IF(includes_accommodation = "yes" AND includes_dinner = "yes", "Accommodation and Dinner", IF(includes_accommodation = "yes", "Accommodation only", IF(includes_dinner = "yes", "Dinner only", "-"))), CONCAT(conference_fees.text, IF(includes_dinner = "yes", " + with dinner", ""))) AS requirements'),
'dietary' => \DB::raw('COALESCE(IF(STRCMP(dietary_requirements.text, "Other"), dietary_requirements.text, dietary_other), "-") AS dietary'),
'work_info' => \DB::raw('COALESCE(CONCAT(IF(conference_registration_categories.id IS NULL, "Guest Speaker", conference_registration_categories.text), IF(workplaces.id IS NULL, "", CONCAT(" // ", IF(STRCMP(workplaces.text, "Other"), workplaces.text, workplace_other)))), "-") AS work_info'),
'conference_registration_categories_id' => 'conference_registration_categories.id AS conference_registration_categories_id',
'conference_fee_id' => 'conference_fees.id AS conference_fee_id',
'updated_at' => 'conference_registrations.updated_at',
'updated_by' => 'conference_registrations.updated_by',
'invoice_id' => 'conference_registrations.invoice_id',
'stripe_payment_intent_id' => 'conference_registrations.stripe_payment_intent_id',
'is_ars_member' => 'conference_registrations.is_ars_member',
];
if ($excludedColumns) {
$excludedColumns = array_flip($excludedColumns);
$selects = array_diff_key($selects, $excludedColumns);
}
if (!$withHtml) {
$selects = ['name' => \DB::raw('CONCAT(users.forename, " ", users.surname) AS name')] + $selects;
}
return self::select($selects)
->where('conference_registrations.conference_id', $conference->id)
->wherePaid('yes')
->withConferenceFees('leftJoin')
->withConferenceRegistrationCategories('leftJoin')
->withDietaryRequirements()
->withUsers()
->withWorkplaces()
->orderBy('surname')
->get();
}SQLSELECT
conference_registrations.id AS conference_registration_id,
conference_registrations.conference_id,
conference_registrations.user_id,
ars_membership_no,
ars_validated,
email,
(
IF(
conference_registration_categories.id IS NULL,
IF(
includes_accommodation = "yes"
AND includes_dinner = "yes",
"Accommodation and Dinner",
IF(
includes_accommodation = "yes",
"Accommodation only",
IF(
includes_dinner = "yes",
"Dinner only",
"-"
)
)
),
CONCAT(
conference_fees.text,
IF(includes_dinner = "yes", " + with dinner", "")
)
) AS requirements
) AS requirements,
(
COALESCE(
IF(
STRCMP(dietary_requirements.text, "Other"),
dietary_requ |
|
Thats a completely different code than you initially provided. I see no way to fix this in code. You basically used the select() function in a very special way. Because you provided array keys which don't have any effect at all. Didn't have before. There are two options from here:
|
|
My apologies - I only shared a shortened snippet of the first few entries in my Using an associative array in my code is not anything special - it is a practical way to dynamically include or exclude columns, which I suspect is a fairly common use case. Prior to this change, it caused no issues with MySQL. To work around this, I'll use
If you're asking me to raise the issue, does that mean you think my use case isn't valid and the current behaviour should remain as is? |
Currently, you can add subqueries to a query builder with an alias.
But the same is not yet possible for expressions There's just no way to define an alias. This PR fixes this
So this PR changes:
selectExpression(likeselectSub)selectaddSelectselectandaddSelectwhich was not covered yet