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
9afed290
Commit
9afed290
authored
Mar 27, 2019
by
Heinrich Lee Yu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Prevent infinite loops in ObjectHierarchy
parent
3b591ffe
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
34 additions
and
7 deletions
+34
-7
ee/db/migrate/20190327085945_remove_cyclic_hierarchies_in_epics.rb
...rate/20190327085945_remove_cyclic_hierarchies_in_epics.rb
+2
-0
ee/spec/migrations/remove_cyclic_hierarchies_in_epics_spec.rb
...pec/migrations/remove_cyclic_hierarchies_in_epics_spec.rb
+9
-3
lib/gitlab/object_hierarchy.rb
lib/gitlab/object_hierarchy.rb
+23
-4
No files found.
ee/db/migrate/20190327085945_remove_cyclic_hierarchies_in_epics.rb
View file @
9afed290
...
...
@@ -30,6 +30,8 @@ class RemoveCyclicHierarchiesInEpics < ActiveRecord::Migration[5.0]
# We only need to update the first epic of the loop to break the cycle
epic_ids_to_update
=
epics_grouped_by_loop
.
map
{
|
path
,
epics
|
epics
.
first
[
'id'
]
}
# rubocop:disable Lint/UnneededCopDisableDirective
# rubocop:disable Migration/UpdateColumnInBatches
update_column_in_batches
(
:epics
,
:parent_id
,
nil
)
do
|
table
,
query
|
query
.
where
(
table
[
:id
].
in
(
epic_ids_to_update
)
...
...
ee/spec/migrations/remove_cyclic_hierarchies_in_epics_spec.rb
View file @
9afed290
...
...
@@ -11,7 +11,15 @@ describe RemoveCyclicHierarchiesInEpics, :migration, :postgresql do
def
create_epic_with_defaults!
(
attributes
=
{})
@last_iid
+=
1
epics
.
create!
({
iid:
@last_iid
,
group_id:
group
.
id
,
author_id:
user
.
id
,
title:
"Epic"
,
title_html:
"Epic"
}.
merge
(
attributes
))
epics
.
create!
(
attributes
.
reverse_merge
(
iid:
@last_iid
,
group_id:
group
.
id
,
author_id:
user
.
id
,
title:
"Epic"
,
title_html:
"Epic"
)
)
end
let!
(
:epic_self_loop
)
{
create_epic_with_defaults!
}
...
...
@@ -53,5 +61,3 @@ describe RemoveCyclicHierarchiesInEpics, :migration, :postgresql do
expect
(
epic_not_in_loop
.
reload
.
parent_id
).
not_to
be_nil
end
end
lib/gitlab/object_hierarchy.rb
View file @
9afed290
...
...
@@ -144,7 +144,7 @@ module Gitlab
cte
=
SQL
::
RecursiveCTE
.
new
(
:base_and_ancestors
)
base_query
=
ancestors_base
.
except
(
:order
)
base_query
=
base_query
.
select
(
"1 as
#{
DEPTH_COLUMN
}
"
,
objects_table
[
Arel
.
star
])
if
hierarchy_order
base_query
=
base_query
.
select
(
"1 as
#{
DEPTH_COLUMN
}
"
,
"ARRAY[id] AS tree_path"
,
"false AS tree_cycle"
,
objects_table
[
Arel
.
star
])
if
hierarchy_order
cte
<<
base_query
...
...
@@ -154,7 +154,17 @@ module Gitlab
.
where
(
objects_table
[
:id
].
eq
(
cte
.
table
[
:parent_id
]))
.
except
(
:order
)
parent_query
=
parent_query
.
select
(
cte
.
table
[
DEPTH_COLUMN
]
+
1
,
objects_table
[
Arel
.
star
])
if
hierarchy_order
if
hierarchy_order
quoted_objects_table_name
=
model
.
connection
.
quote_table_name
(
objects_table
.
name
)
parent_query
=
parent_query
.
select
(
cte
.
table
[
DEPTH_COLUMN
]
+
1
,
"tree_path ||
#{
quoted_objects_table_name
}
.id"
,
"
#{
quoted_objects_table_name
}
.id = ANY(tree_path)"
,
objects_table
[
Arel
.
star
]
).
where
(
cte
.
table
[
:tree_cycle
].
eq
(
false
))
end
parent_query
=
parent_query
.
where
(
cte
.
table
[
:parent_id
].
not_eq
(
stop_id
))
if
stop_id
cte
<<
parent_query
...
...
@@ -167,7 +177,7 @@ module Gitlab
cte
=
SQL
::
RecursiveCTE
.
new
(
:base_and_descendants
)
base_query
=
descendants_base
.
except
(
:order
)
base_query
=
base_query
.
select
(
"1
as
#{
DEPTH_COLUMN
}
"
,
objects_table
[
Arel
.
star
])
if
with_depth
base_query
=
base_query
.
select
(
"1
AS
#{
DEPTH_COLUMN
}
"
,
"ARRAY[id] AS tree_path"
,
"false AS tree_cycle
"
,
objects_table
[
Arel
.
star
])
if
with_depth
cte
<<
base_query
...
...
@@ -177,7 +187,16 @@ module Gitlab
.
where
(
objects_table
[
:parent_id
].
eq
(
cte
.
table
[
:id
]))
.
except
(
:order
)
descendants_query
=
descendants_query
.
select
(
cte
.
table
[
DEPTH_COLUMN
]
+
1
,
objects_table
[
Arel
.
star
])
if
with_depth
if
with_depth
quoted_objects_table_name
=
model
.
connection
.
quote_table_name
(
objects_table
.
name
)
descendants_query
=
descendants_query
.
select
(
cte
.
table
[
DEPTH_COLUMN
]
+
1
,
"tree_path ||
#{
quoted_objects_table_name
}
.id"
,
"
#{
quoted_objects_table_name
}
.id = ANY(tree_path)"
,
objects_table
[
Arel
.
star
]
).
where
(
cte
.
table
[
:tree_cycle
].
eq
(
false
))
end
cte
<<
descendants_query
cte
...
...
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