Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
06a9974e
Commit
06a9974e
authored
Dec 08, 2021
by
Alex Pooley
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Wrap ancestor scopes in CTE
parent
8fe0036d
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
44 additions
and
3 deletions
+44
-3
app/models/namespaces/traversal/linear_scopes.rb
app/models/namespaces/traversal/linear_scopes.rb
+22
-3
ee/spec/lib/gitlab/group_plans_preloader_spec.rb
ee/spec/lib/gitlab/group_plans_preloader_spec.rb
+3
-0
spec/support/shared_examples/namespaces/traversal_scope_examples.rb
...rt/shared_examples/namespaces/traversal_scope_examples.rb
+19
-0
No files found.
app/models/namespaces/traversal/linear_scopes.rb
View file @
06a9974e
...
...
@@ -25,15 +25,20 @@ module Namespaces
def
self_and_ancestors
(
include_self:
true
,
hierarchy_order:
nil
)
return
super
unless
use_traversal_ids_for_ancestor_scopes?
ancestors_cte
,
base_cte
=
ancestor_ctes
namespaces
=
Arel
::
Table
.
new
(
:namespaces
)
records
=
unscoped
.
where
(
id:
select
(
'unnest(traversal_ids)'
))
.
with
(
base_cte
.
to_arel
,
ancestors_cte
.
to_arel
)
.
distinct
.
from
([
ancestors_cte
.
table
,
namespaces
])
.
where
(
namespaces
[
:id
].
eq
(
ancestors_cte
.
table
[
:ancestor_id
]))
.
order_by_depth
(
hierarchy_order
)
.
normal_select
if
include_self
records
else
records
.
where
.
not
(
id:
all
.
as_ids
)
records
.
where
(
ancestors_cte
.
table
[
:base_id
].
not_eq
(
ancestors_cte
.
table
[
:ancestor_id
])
)
end
end
...
...
@@ -150,6 +155,20 @@ module Namespaces
records
.
where
(
'namespaces.id <> base.id'
)
end
end
def
ancestor_ctes
base_scope
=
all
.
select
(
'namespaces.id'
,
'namespaces.traversal_ids'
)
base_cte
=
Gitlab
::
SQL
::
CTE
.
new
(
:base_ancestors_cte
,
base_scope
)
# We have to alias id with 'AS' to avoid ambiguous column references by calling methods.
ancestors_scope
=
unscoped
.
unscope
(
where:
[
:type
])
.
select
(
'id as base_id'
,
'unnest(traversal_ids) as ancestor_id'
)
.
from
(
base_cte
.
table
)
ancestors_cte
=
Gitlab
::
SQL
::
CTE
.
new
(
:ancestors_cte
,
ancestors_scope
)
[
ancestors_cte
,
base_cte
]
end
end
end
end
...
...
ee/spec/lib/gitlab/group_plans_preloader_spec.rb
View file @
06a9974e
...
...
@@ -21,6 +21,9 @@ RSpec.describe Gitlab::GroupPlansPreloader, :saas do
shared_examples
'preloading cases'
do
it
'only executes three SQL queries to preload the data'
do
# Pre-cache `select VERSION()` query to avoid counting.
Gitlab
::
Database
::
AsWithMaterialized
.
materialized_supported?
amount
=
ActiveRecord
::
QueryRecorder
.
new
{
preloaded_groups
}
.
count
...
...
spec/support/shared_examples/namespaces/traversal_scope_examples.rb
View file @
06a9974e
...
...
@@ -124,6 +124,12 @@ RSpec.shared_examples 'namespace traversal scopes' do
it
{
expect
(
subject
[
0
,
2
]).
to
contain_exactly
(
group_1
,
group_2
)
}
it
{
expect
(
subject
[
2
,
2
]).
to
contain_exactly
(
nested_group_1
,
nested_group_2
)
}
end
context
'with offset and limit'
do
subject
{
described_class
.
where
(
id:
[
deep_nested_group_1
,
deep_nested_group_2
]).
offset
(
1
).
limit
(
1
).
self_and_ancestors
}
it
{
is_expected
.
to
contain_exactly
(
group_2
,
nested_group_2
,
deep_nested_group_2
)
}
end
end
describe
'.self_and_ancestors'
do
...
...
@@ -168,6 +174,19 @@ RSpec.shared_examples 'namespace traversal scopes' do
it
{
is_expected
.
to
contain_exactly
(
group_1
.
id
,
group_2
.
id
)
}
end
context
'with offset and limit'
do
subject
do
described_class
.
where
(
id:
[
deep_nested_group_1
,
deep_nested_group_2
])
.
limit
(
1
)
.
offset
(
1
)
.
self_and_ancestor_ids
.
pluck
(
:id
)
end
it
{
is_expected
.
to
contain_exactly
(
group_2
.
id
,
nested_group_2
.
id
,
deep_nested_group_2
.
id
)
}
end
end
describe
'.self_and_ancestor_ids'
do
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment