mirror of https://gitee.com/bigwinds/arangodb
Used the TraverserExpression in Local case for Edges. Right now it fails hardcoded.
This commit is contained in:
parent
a656182145
commit
f880592025
|
@ -256,6 +256,7 @@ add_executable(
|
|||
VocBase/shaped-json.cpp
|
||||
VocBase/Shaper.cpp
|
||||
VocBase/transaction.cpp
|
||||
VocBase/Traverser.cpp
|
||||
VocBase/vocbase.cpp
|
||||
VocBase/vocbase-defaults.cpp
|
||||
VocBase/VocShaper.cpp
|
||||
|
|
|
@ -218,6 +218,7 @@ arangod_libarangod_a_SOURCES = \
|
|||
arangod/VocBase/shaped-json.cpp \
|
||||
arangod/VocBase/Shaper.cpp \
|
||||
arangod/VocBase/transaction.cpp \
|
||||
arangod/VocBase/Traverser.cpp \
|
||||
arangod/VocBase/vocbase.cpp \
|
||||
arangod/VocBase/vocbase-defaults.cpp \
|
||||
arangod/VocBase/VocShaper.cpp \
|
||||
|
|
|
@ -843,15 +843,13 @@ void DepthFirstTraverser::_defInternalFunctions () {
|
|||
return VertexId(TRI_EXTRACT_MARKER_FROM_CID(&mptr), TRI_EXTRACT_MARKER_FROM_KEY(&mptr));
|
||||
};
|
||||
|
||||
auto direction = _opts.direction;
|
||||
auto edgeCols = _edgeCols;
|
||||
if (direction == TRI_EDGE_ANY) {
|
||||
_getEdge = [edgeCols] (VertexId& startVertex, std::vector<EdgeInfo>& edges, TRI_doc_mptr_copy_t*& last, size_t& eColIdx, bool& dir) {
|
||||
if (_opts.direction == TRI_EDGE_ANY) {
|
||||
_getEdge = [&] (VertexId& startVertex, std::vector<EdgeInfo>& edges, TRI_doc_mptr_copy_t*& last, size_t& eColIdx, bool& dir) {
|
||||
std::vector<TRI_doc_mptr_copy_t> tmp;
|
||||
TRI_ASSERT(eColIdx < edgeCols.size());
|
||||
TRI_ASSERT(eColIdx < _edgeCols.size());
|
||||
// TODO fill Statistics
|
||||
// TODO Self referencing edges
|
||||
triagens::arango::EdgeIndex* edgeIndex = edgeCols.at(eColIdx)->edgeIndex();
|
||||
triagens::arango::EdgeIndex* edgeIndex = _edgeCols.at(eColIdx)->edgeIndex();
|
||||
if (dir) {
|
||||
TRI_edge_index_iterator_t it(TRI_EDGE_OUT, startVertex.cid, startVertex.key);
|
||||
edgeIndex->lookup(&it, tmp, last, 1);
|
||||
|
@ -859,12 +857,12 @@ void DepthFirstTraverser::_defInternalFunctions () {
|
|||
// Switch back direction
|
||||
dir = false;
|
||||
++eColIdx;
|
||||
if (edgeCols.size() == eColIdx) {
|
||||
if (_edgeCols.size() == eColIdx) {
|
||||
// No more to do, stop here
|
||||
return;
|
||||
}
|
||||
TRI_edge_index_iterator_t it(TRI_EDGE_IN, startVertex.cid, startVertex.key);
|
||||
edgeIndex = edgeCols.at(eColIdx)->edgeIndex();
|
||||
edgeIndex = _edgeCols.at(eColIdx)->edgeIndex();
|
||||
edgeIndex->lookup(&it, tmp, last, 1);
|
||||
if (last == nullptr) {
|
||||
dir = true;
|
||||
|
@ -884,12 +882,12 @@ void DepthFirstTraverser::_defInternalFunctions () {
|
|||
// The other direction also has no further edges
|
||||
dir = false;
|
||||
++eColIdx;
|
||||
if (edgeCols.size() == eColIdx) {
|
||||
if (_edgeCols.size() == eColIdx) {
|
||||
// No more to do, stop here
|
||||
return;
|
||||
}
|
||||
TRI_edge_index_iterator_t it(TRI_EDGE_IN, startVertex.cid, startVertex.key);
|
||||
edgeIndex = edgeCols.at(eColIdx)->edgeIndex();
|
||||
edgeIndex = _edgeCols.at(eColIdx)->edgeIndex();
|
||||
edgeIndex->lookup(&it, tmp, last, 1);
|
||||
}
|
||||
}
|
||||
|
@ -897,39 +895,62 @@ void DepthFirstTraverser::_defInternalFunctions () {
|
|||
if (last != nullptr) {
|
||||
// sth is stored in tmp. Now push it on edges
|
||||
TRI_ASSERT(tmp.size() == 1);
|
||||
auto it = _expressions->find(edges.size());
|
||||
if (it != _expressions->end()) {
|
||||
auto shaper = _edgeCols.at(eColIdx)->getShaper();
|
||||
for (auto const& exp : it->second) {
|
||||
if (exp->isEdgeAccess && ! exp->matchesCheck(tmp.back(), shaper)) {
|
||||
// Retry with the next element
|
||||
_getEdge(startVertex, edges, last, eColIdx, dir);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
EdgeInfo e(
|
||||
edgeCols.at(eColIdx)->_info._cid,
|
||||
_edgeCols.at(eColIdx)->_info._cid,
|
||||
tmp.back()
|
||||
);
|
||||
edges.push_back(e);
|
||||
}
|
||||
};
|
||||
} else {
|
||||
_getEdge = [edgeCols, direction] (VertexId& startVertex, std::vector<EdgeInfo>& edges, TRI_doc_mptr_copy_t*& last, size_t& eColIdx, bool&) {
|
||||
_getEdge = [&] (VertexId& startVertex, std::vector<EdgeInfo>& edges, TRI_doc_mptr_copy_t*& last, size_t& eColIdx, bool& dir) {
|
||||
std::vector<TRI_doc_mptr_copy_t> tmp;
|
||||
TRI_ASSERT(eColIdx < edgeCols.size());
|
||||
TRI_ASSERT(eColIdx < _edgeCols.size());
|
||||
// Do not touch the bool parameter, as long as it is default the first encountered nullptr is final
|
||||
// TODO fill Statistics
|
||||
TRI_edge_index_iterator_t it(direction, startVertex.cid, startVertex.key);
|
||||
triagens::arango::EdgeIndex* edgeIndex = edgeCols.at(eColIdx)->edgeIndex();
|
||||
TRI_edge_index_iterator_t it(_opts.direction, startVertex.cid, startVertex.key);
|
||||
triagens::arango::EdgeIndex* edgeIndex = _edgeCols.at(eColIdx)->edgeIndex();
|
||||
edgeIndex->lookup(&it, tmp, last, 1);
|
||||
while (last == nullptr) {
|
||||
// This edge collection does not have any more edges for this vertex. Check the next one
|
||||
++eColIdx;
|
||||
if (edgeCols.size() == eColIdx) {
|
||||
if (_edgeCols.size() == eColIdx) {
|
||||
// No more to do, stop here
|
||||
return;
|
||||
}
|
||||
edgeIndex = edgeCols.at(eColIdx)->edgeIndex();
|
||||
edgeIndex = _edgeCols.at(eColIdx)->edgeIndex();
|
||||
edgeIndex->lookup(&it, tmp, last, 1);
|
||||
}
|
||||
if (last != nullptr) {
|
||||
// sth is stored in tmp. Now push it on edges
|
||||
TRI_ASSERT(tmp.size() == 1);
|
||||
edges.push_back(EdgeInfo(
|
||||
edgeCols.at(eColIdx)->_info._cid,
|
||||
auto it = _expressions->find(edges.size());
|
||||
if (it != _expressions->end()) {
|
||||
auto shaper = _edgeCols.at(eColIdx)->getShaper();
|
||||
for (auto const& exp : it->second) {
|
||||
if (exp->isEdgeAccess && ! exp->matchesCheck(tmp.back(), shaper)) {
|
||||
// Retry with the next element
|
||||
_getEdge(startVertex, edges, last, eColIdx, dir);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
EdgeInfo e(
|
||||
_edgeCols.at(eColIdx)->_info._cid,
|
||||
tmp.back()
|
||||
));
|
||||
);
|
||||
edges.push_back(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Traverser
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014-2015 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Michael Hackstein
|
||||
/// @author Copyright 2014-2015, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Traverser.h"
|
||||
|
||||
using TraverserExpression = triagens::arango::traverser::TraverserExpression;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief transforms the expression into json
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TraverserExpression::toJson (triagens::basics::Json& json,
|
||||
TRI_memory_zone_t* zone) const {
|
||||
auto op = triagens::aql::AstNode::Operators.find(comparisonType);
|
||||
|
||||
if (op == triagens::aql::AstNode::Operators.end()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_PARSE, "invalid operator for TraverserExpression");
|
||||
}
|
||||
std::string const operatorStr = op->second;
|
||||
|
||||
json("isEdgeAccess", triagens::basics::Json(isEdgeAccess))
|
||||
("comparisonType", triagens::basics::Json(operatorStr))
|
||||
("varAccess", varAccess->toJson(zone, true));
|
||||
if (compareTo != nullptr) {
|
||||
json("compareTo", *compareTo);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief evalutes if an element matches the given expression
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool TraverserExpression::matchesCheck (TRI_doc_mptr_t& element,
|
||||
VocShaper* shaper) const {
|
||||
return false;
|
||||
}
|
|
@ -70,21 +70,10 @@ namespace triagens {
|
|||
}
|
||||
|
||||
void toJson (triagens::basics::Json& json,
|
||||
TRI_memory_zone_t* zone) const {
|
||||
auto op = triagens::aql::AstNode::Operators.find(comparisonType);
|
||||
|
||||
if (op == triagens::aql::AstNode::Operators.end()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_PARSE, "invalid operator for TraverserExpression");
|
||||
}
|
||||
std::string const operatorStr = op->second;
|
||||
TRI_memory_zone_t* zone) const;
|
||||
|
||||
json("isEdgeAccess", triagens::basics::Json(isEdgeAccess))
|
||||
("comparisonType", triagens::basics::Json(operatorStr))
|
||||
("varAccess", varAccess->toJson(zone, true));
|
||||
if (compareTo != nullptr) {
|
||||
json("compareTo", *compareTo);
|
||||
}
|
||||
}
|
||||
bool matchesCheck (TRI_doc_mptr_t& element,
|
||||
VocShaper* shaper) const;
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue