@@ -34,11 +34,11 @@ namespace {
34
34
35
35
auto doNothingVisitor = [](AstNode const *) {};
36
36
37
- bool accessesSearchVariableViaReference (AstNode const * current, Variable const * searchVariable) {
37
+ bool isTargetVariable (AstNode const * const current, Variable const * const searchVariable) {
38
38
if (current->type == NODE_TYPE_INDEXED_ACCESS) {
39
39
auto sub = current->getMemberUnchecked (0 );
40
40
if (sub->type == NODE_TYPE_REFERENCE) {
41
- Variable const * v = static_cast <Variable const *>(sub->getData ());
41
+ auto const v = static_cast <Variable const *>(sub->getData ());
42
42
if (v->id == searchVariable->id ) {
43
43
return true ;
44
44
}
@@ -57,7 +57,7 @@ bool accessesSearchVariableViaReference(AstNode const* current, Variable const*
57
57
if (sub1->type != NODE_TYPE_VARIABLE || sub2->type != NODE_TYPE_REFERENCE) {
58
58
return false ;
59
59
}
60
- Variable const * v = static_cast <Variable const *>(sub2->getData ());
60
+ auto const v = static_cast <Variable const *>(sub2->getData ());
61
61
if (v->id == searchVariable->id ) {
62
62
return true ;
63
63
}
@@ -66,113 +66,34 @@ bool accessesSearchVariableViaReference(AstNode const* current, Variable const*
66
66
return false ;
67
67
};
68
68
69
- bool isTargetVariable (AstNode const * node,
70
- ::arangodb::containers::SmallVector<Variable const *>& searchVariables,
71
- bool & isSafeForOptimization) {
72
- TRI_ASSERT (!searchVariables.empty ());
73
-
74
- // given and expression like g3[0].`g2`[0].`g1`[0].`item1`.`_id`
75
- // this loop resolves subtrees of the form: .`g2`[0].`g1`[0]
76
- // search variables should equal [g1, g2, g3]. Therefor we need not match the
77
- // variable names from the vector with those in the expression while going
78
- // forward in the vector the we go backward in the expression
79
-
80
- auto current = node;
81
- for (auto varIt = searchVariables.begin ();
82
- varIt != std::prev (searchVariables.end ()); ++varIt) {
83
- AstNode* next = nullptr ;
84
- if (current->type == NODE_TYPE_INDEXED_ACCESS) {
85
- next = current->getMemberUnchecked (0 );
86
- } else if (current->type == NODE_TYPE_EXPANSION) {
87
- if (current->numMembers () < 2 ) {
88
- return false ;
89
- }
90
-
91
- auto it = current->getMemberUnchecked (0 );
92
- TRI_ASSERT (it);
93
-
94
- // The expansion is at the very end
95
- if (it->type == NODE_TYPE_ITERATOR && it->numMembers () == 2 ) {
96
- if (it->getMember (0 )->type != NODE_TYPE_VARIABLE) {
97
- return false ;
98
- }
99
-
100
- auto attributeAccess = it->getMember (1 );
101
- TRI_ASSERT (attributeAccess);
102
-
103
- if (std::next (varIt) != searchVariables.end () &&
104
- attributeAccess->type == NODE_TYPE_ATTRIBUTE_ACCESS) {
105
- next = attributeAccess;
106
- } else {
107
- return false ;
108
- }
109
-
110
- } else {
111
- // The expansion is not at the very end! we are unable to check if the
112
- // variable will be accessed checking nested expansions is really crazy
113
- // and would probably be best done in a recursive way. If the expansion
114
- // is in the middle, then it would be still the very first node in the
115
- // AST, having 2 subtrees that contain the other search variables
116
- isSafeForOptimization = false ; // could be an access - we can not tell
117
- return false ;
118
- }
119
- } else {
120
- return false ;
121
- }
122
-
123
- if (varIt == searchVariables.end ()) {
124
- return false ;
125
- }
126
-
127
- if (next && next->type == NODE_TYPE_ATTRIBUTE_ACCESS &&
128
- next->getString () == (*varIt)->name ) {
129
- current = next->getMemberUnchecked (0 );
130
- } else if (next && next->type == NODE_TYPE_EXPANSION) {
131
- isSafeForOptimization = false ;
132
- return false ;
133
- } else {
134
- return false ;
135
- }
136
- } // for nodes but last
137
-
138
- if (!current) {
139
- return false ;
140
- }
141
-
142
- return accessesSearchVariableViaReference (current, searchVariables.back ());
143
- }
144
-
145
69
} // namespace
146
70
147
- std::unordered_set<std::string> arangodb::aql::ast::getReferencedAttributesForKeep (
148
- const AstNode* node, ::arangodb::containers::SmallVector<const Variable*, 64 > searchVariables,
149
- bool & isSafeForOptimization) {
150
- std::unordered_set<std::string> result;
71
+ auto arangodb::aql::ast::getReferencedAttributesForKeep (AstNode const * const node,
72
+ Variable const * const searchVariable,
73
+ bool & isSafeForOptimization)
74
+ -> std::vector<std::string> {
75
+ auto result = std::vector<std::string>();
151
76
isSafeForOptimization = true ;
152
77
153
- std::function<bool (AstNode const *)> visitor = [&isSafeForOptimization, &result,
154
- &searchVariables](AstNode const * node) {
155
- if (!isSafeForOptimization) {
156
- return false ;
157
- }
158
-
78
+ auto const visitor = [&isSafeForOptimization, &result,
79
+ &searchVariable](AstNode const * node) -> bool {
159
80
if (node->type == NODE_TYPE_ATTRIBUTE_ACCESS) {
160
81
while (node->getMemberUnchecked (0 )->type == NODE_TYPE_ATTRIBUTE_ACCESS) {
161
82
node = node->getMemberUnchecked (0 );
162
83
}
163
- if (isTargetVariable (node->getMemberUnchecked (0 ), searchVariables, isSafeForOptimization )) {
164
- result.emplace (node->getString ());
84
+ if (isTargetVariable (node->getMemberUnchecked (0 ), searchVariable )) {
85
+ result.emplace_back (node->getString ());
165
86
// do not descend further
166
87
return false ;
167
88
}
168
89
} else if (node->type == NODE_TYPE_REFERENCE) {
169
- Variable const * v = static_cast <Variable const *>(node->getData ());
170
- if (v->id == searchVariables. front () ->id ) {
90
+ auto const v = static_cast <Variable const *>(node->getData ());
91
+ if (v->id == searchVariable ->id ) {
171
92
isSafeForOptimization = false ; // the expression references the searched variable
172
93
return false ;
173
94
}
174
95
} else if (node->type == NODE_TYPE_EXPANSION) {
175
- if (isTargetVariable (node, searchVariables, isSafeForOptimization )) {
96
+ if (isTargetVariable (node, searchVariable )) {
176
97
auto sub = node->getMemberUnchecked (1 );
177
98
if (sub->type == NODE_TYPE_EXPANSION) {
178
99
sub = sub->getMemberUnchecked (0 )->getMemberUnchecked (1 );
@@ -181,16 +102,16 @@ std::unordered_set<std::string> arangodb::aql::ast::getReferencedAttributesForKe
181
102
while (sub->getMemberUnchecked (0 )->type == NODE_TYPE_ATTRIBUTE_ACCESS) {
182
103
sub = sub->getMemberUnchecked (0 );
183
104
}
184
- result.emplace (sub->getString ());
105
+ result.emplace_back (sub->getString ());
185
106
// do not descend further
186
107
return false ;
187
108
}
188
109
}
189
110
} else if (node->type == NODE_TYPE_INDEXED_ACCESS) {
190
111
auto sub = node->getMemberUnchecked (0 );
191
112
if (sub->type == NODE_TYPE_REFERENCE) {
192
- Variable const * v = static_cast <Variable const *>(sub->getData ());
193
- if (v->id == searchVariables. back () ->id ) {
113
+ auto const v = static_cast <Variable const *>(sub->getData ());
114
+ if (v->id == searchVariable ->id ) {
194
115
isSafeForOptimization = false ;
195
116
return false ;
196
117
}
0 commit comments