3939#include " Logger/LogMacros.h"
4040#include " VocBase/LogicalCollection.h"
4141
42+ #if USE_ENTERPRISE
43+ #include " Enterprise/VocBase/VirtualClusterSmartEdgeCollection.h"
44+ #endif
45+
4246using namespace arangodb ;
4347using namespace arangodb ::aql;
4448using namespace arangodb ::containers;
@@ -164,6 +168,13 @@ bool selectivityIsLowEnough(IndexNode const& in) {
164168
165169 double requiredSelectivity;
166170 if (ServerState::instance ()->isSingleServer ()) {
171+ if (numberOfItems == 1 ) {
172+ // log(1) is 0 so we are dividing by zero here
173+ // IEEE-754 defines division-by-zero to lead to NaN, +Inf or -Inf
174+ // 1.0 / 0.0 should by definition lead to +Inf, so we skip the calculation
175+ // and return directly.
176+ return true ;
177+ }
167178 requiredSelectivity = 1 . / log (numberOfItems);
168179 } else {
169180 // in cluster mode, we use the same equation as an approximation, although
@@ -175,8 +186,36 @@ bool selectivityIsLowEnough(IndexNode const& in) {
175186 // TODO compare the total costs of executing the optimized vs. the
176187 // non-optimized execution node, which involves getting the selectivity
177188 // estimate of each shard separately
178- requiredSelectivity =
179- 1 . / log (numberOfItems / index->collection ().numberOfShards ());
189+ auto numberOfShards = index->collection ().numberOfShards ();
190+ if (numberOfShards == 0 ) {
191+ #if USE_ENTERPRISE
192+ // In case of smart edge collections we do have 0 shards,
193+ // this would lead to a SIGFPE(FPE_INTDIV) and crash.
194+ // So we get the number of shards of the underlying collections
195+ // e.g. _local
196+ try {
197+ auto & virtualEdgeCol = dynamic_cast <VirtualClusterSmartEdgeCollection&>(
198+ index->collection ());
199+ numberOfShards = virtualEdgeCol.numberOfUnderlyingShards ();
200+ } catch (std::bad_cast&) {
201+ }
202+ #endif // USE_ENTERPRISE
203+ if (numberOfShards == 0 ) {
204+ LOG_RULE << " IndexNode " << in.id ()
205+ << " detected a node with zero shards,"
206+ << " which is not a virtual smart edge collection" ;
207+ return false ;
208+ }
209+ }
210+
211+ if (numberOfItems == numberOfShards) {
212+ // log(1) is 0 so we are dividing by zero here
213+ // IEEE-754 defines division-by-zero to lead to NaN, +Inf or -Inf
214+ // 1.0 / 0.0 should by definition lead to +Inf, so we skip the calculation
215+ // and return directly.
216+ return true ;
217+ }
218+ requiredSelectivity = 1 . / log (numberOfItems / numberOfShards);
180219 }
181220
182221 if (index_selectivity > requiredSelectivity) {
0 commit comments