You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hello! I've found a bug with the .with CTE functionality.
When a relation has a CTE added, and that relation attempts to use .with to add another CTE of itself, it enters an infinite loop that results in a SystemStackError.
Reproduction steps:
# Note: The models don't matter here. I used some that are present in the spec/support/models.rb file for easy reproduction.# Initial Relationinitial_relation=User.all# Add CTE to User Relationcte_relation=Group.allinitial_relation_with_cte=initial_relation.with('first_cte'=>cte_relation)# When a relation with a CTE adds itself as another CTE a SystemStackError is raisedinitial_relation_with_self_cte=initial_relation_with_cte.with('self_cte'=>initial_relation_with_cte)initial_relation_with_self_cte.to_sql# .arel also triggers the loop
I've spent a couple of days looking into this. Here is the infinite loop.
build_arel method is called by rails, and since the relation has a CTE, build_with is called.
.to_sql of an ActiveRecord::Relation calls build_arel again in step 1.
Notes:
I've found that it is only an issue when a relation already has a CTE and you try to add that same relation as a CTE.
The construct of the relation doesn't seem to matter. I was able to recreate the bug with complex relations as well as simple ones (like the reproduction steps).
Workaround:
If I .dup the relation and the associated .cte, the relation behaves as expected.
# Initial Relationinitial_relation=User.all# Add CTE to User Relationcte_relation=Group.allinitial_relation_with_cte=initial_relation.with('first_cte'=>cte_relation)# duplicate the relation and the cteself_cte=initial_relation_with_cte.dupself_cte.cte=initial_relation_with_cte.cte.dup# use duplicated relationinitial_relation_with_self_cte=initial_relation_with_cte.with('self_cte'=>self_cte)initial_relation_with_self_cte.to_sql# works as expected
The text was updated successfully, but these errors were encountered:
Hello! I've found a bug with the
.with
CTE functionality.When a relation has a CTE added, and that relation attempts to use
.with
to add another CTE of itself, it enters an infinite loop that results in aSystemStackError
.Reproduction steps:
I've spent a couple of days looking into this. Here is the infinite loop.
build_arel
method is called by rails, and since the relation has a CTE,build_with
is called.build_with
method callsgenerate_grouping
which callsto_arel_sql
.to_arel_sql
calls.to_sql
in theActiveRecord::Relation
branch..to_sql
of anActiveRecord::Relation
callsbuild_arel
again in step 1.Notes:
Workaround:
If I
.dup
the relation and the associated.cte
, the relation behaves as expected.The text was updated successfully, but these errors were encountered: