Esempio n. 1
0
  void operator()(VPackSlice const& v, std::vector<VPackSlice>& resEdges,
                  std::vector<VPackSlice>& neighbors) {
    int res = TRI_ERROR_NO_ERROR;
    for (auto const& edgeCollection : _block->_collectionInfos) {
      VPackBuilder result;
      TRI_ASSERT(edgeCollection != nullptr);
      if (_isReverse) {
        res = edgeCollection->getReverseEdgesCoordinator(v, result);
      } else {
        res = edgeCollection->getEdgesCoordinator(v, result);
      }

      if (res != TRI_ERROR_NO_ERROR) {
        THROW_ARANGO_EXCEPTION(res);
      }

      VPackSlice edges = result.slice().get("edges");
      for (auto const& edge : VPackArrayIterator(edges)) {
        VPackSlice from = arangodb::Transaction::extractFromFromDocument(edge);
        if (from == v) {
          VPackSlice to = arangodb::Transaction::extractToFromDocument(edge);
          if (to != v) {
            resEdges.emplace_back(edge);
            neighbors.emplace_back(to);
          }
        } else {
          resEdges.emplace_back(edge);
          neighbors.emplace_back(from);
        }
      }
      // Make sure the data Slices are pointing to is not running out of scope.
      // This is not thread-safe!
      _block->_coordinatorCache.emplace_back(result.steal());
    }
  }
Esempio n. 2
0
arangodb::traverser::TraverserOptions::LookupInfo::LookupInfo(
    arangodb::aql::Query* query, VPackSlice const& info, VPackSlice const& shards) {
  TRI_ASSERT(shards.isArray());
  idxHandles.reserve(shards.length());

  conditionNeedUpdate = arangodb::basics::VelocyPackHelper::getBooleanValue(
      info, "condNeedUpdate", false);
  conditionMemberToUpdate =
      arangodb::basics::VelocyPackHelper::getNumericValue<size_t>(
          info, "condMemberToUpdate", 0);
  
  VPackSlice read = info.get("handle");
  if (!read.isObject()) {
    THROW_ARANGO_EXCEPTION_MESSAGE(
        TRI_ERROR_BAD_PARAMETER,
        "Each lookup requires handle to be an object");
  }

  read = read.get("id");
  if (!read.isString()) {
    THROW_ARANGO_EXCEPTION_MESSAGE(
        TRI_ERROR_BAD_PARAMETER,
        "Each handle requires id to be a string");
  }
  std::string idxId = read.copyString();
  auto trx = query->trx();

  for (auto const& it : VPackArrayIterator(shards)) {
    if (!it.isString()) {
      THROW_ARANGO_EXCEPTION_MESSAGE(
          TRI_ERROR_BAD_PARAMETER,
          "Shards have to be a list of strings");
    }
    idxHandles.emplace_back(trx->getIndexByIdentifier(it.copyString(), idxId));
  }

  read = info.get("expression");
  if (!read.isObject()) {
    THROW_ARANGO_EXCEPTION_MESSAGE(
        TRI_ERROR_BAD_PARAMETER,
        "Each lookup requires expression to be an object");
  }


  expression = new aql::Expression(query->ast(), read);

  read = info.get("condition");
  if (!read.isObject()) {
    THROW_ARANGO_EXCEPTION_MESSAGE(
        TRI_ERROR_BAD_PARAMETER,
        "Each lookup requires condition to be an object");
  }
  indexCondition = new aql::AstNode(query->ast(), read); 
}
Esempio n. 3
0
  void operator()(VPackSlice const& source,
                  std::vector<ArangoDBPathFinder::Step*>& result) {
    int res = TRI_ERROR_NO_ERROR;
    for (auto const& edgeCollection : _block->_collectionInfos) {
      TRI_ASSERT(edgeCollection != nullptr);
      VPackBuilder edgesBuilder;
      if (_reverse) {
        res = edgeCollection->getReverseEdgesCoordinator(source, edgesBuilder);
      } else {
        res = edgeCollection->getEdgesCoordinator(source, edgesBuilder);
      }

      if (res != TRI_ERROR_NO_ERROR) {
        THROW_ARANGO_EXCEPTION(res);
      }

      std::unordered_map<VPackSlice, size_t> candidates;

      auto inserter = [&](VPackSlice const& s, VPackSlice const& t,
                          double currentWeight, VPackSlice const& edge) {
        auto cand = candidates.find(t);
        if (cand == candidates.end()) {
          // Add weight
          auto step = std::make_unique<ArangoDBPathFinder::Step>(
              t, s, currentWeight, std::move(edge));
          result.emplace_back(step.release());
          candidates.emplace(t, result.size() - 1);
        } else {
          // Compare weight
          auto old = result[cand->second];
          auto oldWeight = old->weight();
          if (currentWeight < oldWeight) {
            old->setWeight(currentWeight);
            old->_predecessor = s;
            old->_edge = edge;
          }
        }
      };

      VPackSlice edges = edgesBuilder.slice().get("edges");
      for (auto const& edge : VPackArrayIterator(edges)) {
        VPackSlice from = arangodb::Transaction::extractFromFromDocument(edge);
        VPackSlice to = arangodb::Transaction::extractToFromDocument(edge);
        double currentWeight = edgeCollection->weightEdge(edge);
        if (from == source) {
          inserter(from, to, currentWeight, edge);
        } else {
          inserter(to, from, currentWeight, edge);
        }
      }
      _block->_coordinatorCache.emplace_back(edgesBuilder.steal());
    }
  }
Esempio n. 4
0
bool Node::handle<PREPEND>(VPackSlice const& slice) {
  if (!slice.hasKey("new")) {
    LOG_TOPIC(WARN, Logger::AGENCY)
        << "Operator prepend without new value: " << slice.toJson();
    return false;
  }
  Builder tmp;
  tmp.openArray();
  tmp.add(slice.get("new"));
  if (this->slice().isArray()) {
    for (auto const& old : VPackArrayIterator(this->slice())) tmp.add(old);
  }
  tmp.close();
  *this = tmp.slice();
  return true;
}
Esempio n. 5
0
void VelocyPackHelper::SanitizeExternals(VPackSlice const input, VPackBuilder& output) {
  if (input.isExternal()) {
    output.add(input.resolveExternal());
  } else if (input.isObject()) {
    output.openObject();
    for (auto const& it : VPackObjectIterator(input)) {
      output.add(VPackValue(it.key.copyString()));
      SanitizeExternals(it.value, output);
    }
    output.close();
  } else if (input.isArray()) {
    output.openArray();
    for (auto const& it : VPackArrayIterator(input)) {
      SanitizeExternals(it, output);
    }
    output.close();
  } else {
    output.add(input);
  }
}
Esempio n. 6
0
bool TraverserExpression::matchesCheck(arangodb::Transaction* trx,
                                       VPackSlice const& element) const {
  TRI_ASSERT(trx != nullptr);
  VPackSlice base = arangodb::basics::VelocyPackHelper::EmptyObjectValue();

  VPackSlice value = element.resolveExternal(); 
  
  // initialize compare value to Null
  VPackSlice result = arangodb::basics::VelocyPackHelper::NullValue();
  // perform recursive check. this may modify value
  if (recursiveCheck(varAccess, value, base)) {
    result = value;
  }

  // hack for _id attribute
  TransactionBuilderLeaser builder(trx);
  if (result.isCustom() && base.isObject()) {
    builder->add(VPackValue(trx->extractIdString(base)));
    result = builder->slice();
  }

  TRI_ASSERT(compareTo != nullptr);
  VPackOptions* options = trx->transactionContext()->getVPackOptions();

  switch (comparisonType) {
    case arangodb::aql::NODE_TYPE_OPERATOR_BINARY_EQ:
      return arangodb::basics::VelocyPackHelper::compare(result, compareTo->slice(), false, options) == 0; 
    case arangodb::aql::NODE_TYPE_OPERATOR_BINARY_NE:
      return arangodb::basics::VelocyPackHelper::compare(result, compareTo->slice(), false, options) != 0; 
    case arangodb::aql::NODE_TYPE_OPERATOR_BINARY_LT:
      return arangodb::basics::VelocyPackHelper::compare(result, compareTo->slice(), true, options) < 0; 
    case arangodb::aql::NODE_TYPE_OPERATOR_BINARY_LE:
      return arangodb::basics::VelocyPackHelper::compare(result, compareTo->slice(), true, options) <= 0; 
    case arangodb::aql::NODE_TYPE_OPERATOR_BINARY_GE:
      return arangodb::basics::VelocyPackHelper::compare(result, compareTo->slice(), true, options) >= 0; 
    case arangodb::aql::NODE_TYPE_OPERATOR_BINARY_GT:
      return arangodb::basics::VelocyPackHelper::compare(result, compareTo->slice(), true, options) > 0;
    case arangodb::aql::NODE_TYPE_OPERATOR_BINARY_IN: {
      // In means any of the elements in compareTo is identical
      VPackSlice compareArray = compareTo->slice();
      for (auto const& cmp : VPackArrayIterator(compareArray)) {
        if (arangodb::basics::VelocyPackHelper::compare(result, cmp, false, options) == 0) {
          // One is identical
          return true;
        }
      }
      // If we get here non is identical
      return false;
    }
    case arangodb::aql::NODE_TYPE_OPERATOR_BINARY_NIN: {
      // NIN means none of the elements in compareTo is identical
      VPackSlice compareArray = compareTo->slice();
      for (auto const& cmp : VPackArrayIterator(compareArray)) {
        if (arangodb::basics::VelocyPackHelper::compare(result, cmp, false, options) == 0) {
          // One is identical
          return false;
        }
      }
      // If we get here non is identical
      return true;
    }
    default:
      TRI_ASSERT(false);
  }
  return false;
}