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/shaped-json.cpp
|
||||||
VocBase/Shaper.cpp
|
VocBase/Shaper.cpp
|
||||||
VocBase/transaction.cpp
|
VocBase/transaction.cpp
|
||||||
|
VocBase/Traverser.cpp
|
||||||
VocBase/vocbase.cpp
|
VocBase/vocbase.cpp
|
||||||
VocBase/vocbase-defaults.cpp
|
VocBase/vocbase-defaults.cpp
|
||||||
VocBase/VocShaper.cpp
|
VocBase/VocShaper.cpp
|
||||||
|
|
|
@ -218,6 +218,7 @@ arangod_libarangod_a_SOURCES = \
|
||||||
arangod/VocBase/shaped-json.cpp \
|
arangod/VocBase/shaped-json.cpp \
|
||||||
arangod/VocBase/Shaper.cpp \
|
arangod/VocBase/Shaper.cpp \
|
||||||
arangod/VocBase/transaction.cpp \
|
arangod/VocBase/transaction.cpp \
|
||||||
|
arangod/VocBase/Traverser.cpp \
|
||||||
arangod/VocBase/vocbase.cpp \
|
arangod/VocBase/vocbase.cpp \
|
||||||
arangod/VocBase/vocbase-defaults.cpp \
|
arangod/VocBase/vocbase-defaults.cpp \
|
||||||
arangod/VocBase/VocShaper.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));
|
return VertexId(TRI_EXTRACT_MARKER_FROM_CID(&mptr), TRI_EXTRACT_MARKER_FROM_KEY(&mptr));
|
||||||
};
|
};
|
||||||
|
|
||||||
auto direction = _opts.direction;
|
if (_opts.direction == TRI_EDGE_ANY) {
|
||||||
auto edgeCols = _edgeCols;
|
_getEdge = [&] (VertexId& startVertex, std::vector<EdgeInfo>& edges, TRI_doc_mptr_copy_t*& last, size_t& eColIdx, bool& dir) {
|
||||||
if (direction == TRI_EDGE_ANY) {
|
|
||||||
_getEdge = [edgeCols] (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;
|
std::vector<TRI_doc_mptr_copy_t> tmp;
|
||||||
TRI_ASSERT(eColIdx < edgeCols.size());
|
TRI_ASSERT(eColIdx < _edgeCols.size());
|
||||||
// TODO fill Statistics
|
// TODO fill Statistics
|
||||||
// TODO Self referencing edges
|
// TODO Self referencing edges
|
||||||
triagens::arango::EdgeIndex* edgeIndex = edgeCols.at(eColIdx)->edgeIndex();
|
triagens::arango::EdgeIndex* edgeIndex = _edgeCols.at(eColIdx)->edgeIndex();
|
||||||
if (dir) {
|
if (dir) {
|
||||||
TRI_edge_index_iterator_t it(TRI_EDGE_OUT, startVertex.cid, startVertex.key);
|
TRI_edge_index_iterator_t it(TRI_EDGE_OUT, startVertex.cid, startVertex.key);
|
||||||
edgeIndex->lookup(&it, tmp, last, 1);
|
edgeIndex->lookup(&it, tmp, last, 1);
|
||||||
|
@ -859,12 +857,12 @@ void DepthFirstTraverser::_defInternalFunctions () {
|
||||||
// Switch back direction
|
// Switch back direction
|
||||||
dir = false;
|
dir = false;
|
||||||
++eColIdx;
|
++eColIdx;
|
||||||
if (edgeCols.size() == eColIdx) {
|
if (_edgeCols.size() == eColIdx) {
|
||||||
// No more to do, stop here
|
// No more to do, stop here
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TRI_edge_index_iterator_t it(TRI_EDGE_IN, startVertex.cid, startVertex.key);
|
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);
|
edgeIndex->lookup(&it, tmp, last, 1);
|
||||||
if (last == nullptr) {
|
if (last == nullptr) {
|
||||||
dir = true;
|
dir = true;
|
||||||
|
@ -884,12 +882,12 @@ void DepthFirstTraverser::_defInternalFunctions () {
|
||||||
// The other direction also has no further edges
|
// The other direction also has no further edges
|
||||||
dir = false;
|
dir = false;
|
||||||
++eColIdx;
|
++eColIdx;
|
||||||
if (edgeCols.size() == eColIdx) {
|
if (_edgeCols.size() == eColIdx) {
|
||||||
// No more to do, stop here
|
// No more to do, stop here
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TRI_edge_index_iterator_t it(TRI_EDGE_IN, startVertex.cid, startVertex.key);
|
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);
|
edgeIndex->lookup(&it, tmp, last, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -897,39 +895,62 @@ void DepthFirstTraverser::_defInternalFunctions () {
|
||||||
if (last != nullptr) {
|
if (last != nullptr) {
|
||||||
// sth is stored in tmp. Now push it on edges
|
// sth is stored in tmp. Now push it on edges
|
||||||
TRI_ASSERT(tmp.size() == 1);
|
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(
|
EdgeInfo e(
|
||||||
edgeCols.at(eColIdx)->_info._cid,
|
_edgeCols.at(eColIdx)->_info._cid,
|
||||||
tmp.back()
|
tmp.back()
|
||||||
);
|
);
|
||||||
edges.push_back(e);
|
edges.push_back(e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
} else {
|
} 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;
|
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
|
// Do not touch the bool parameter, as long as it is default the first encountered nullptr is final
|
||||||
// TODO fill Statistics
|
// TODO fill Statistics
|
||||||
TRI_edge_index_iterator_t it(direction, startVertex.cid, startVertex.key);
|
TRI_edge_index_iterator_t it(_opts.direction, startVertex.cid, startVertex.key);
|
||||||
triagens::arango::EdgeIndex* edgeIndex = edgeCols.at(eColIdx)->edgeIndex();
|
triagens::arango::EdgeIndex* edgeIndex = _edgeCols.at(eColIdx)->edgeIndex();
|
||||||
edgeIndex->lookup(&it, tmp, last, 1);
|
edgeIndex->lookup(&it, tmp, last, 1);
|
||||||
while (last == nullptr) {
|
while (last == nullptr) {
|
||||||
// This edge collection does not have any more edges for this vertex. Check the next one
|
// This edge collection does not have any more edges for this vertex. Check the next one
|
||||||
++eColIdx;
|
++eColIdx;
|
||||||
if (edgeCols.size() == eColIdx) {
|
if (_edgeCols.size() == eColIdx) {
|
||||||
// No more to do, stop here
|
// No more to do, stop here
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
edgeIndex = edgeCols.at(eColIdx)->edgeIndex();
|
edgeIndex = _edgeCols.at(eColIdx)->edgeIndex();
|
||||||
edgeIndex->lookup(&it, tmp, last, 1);
|
edgeIndex->lookup(&it, tmp, last, 1);
|
||||||
}
|
}
|
||||||
if (last != nullptr) {
|
if (last != nullptr) {
|
||||||
// sth is stored in tmp. Now push it on edges
|
// sth is stored in tmp. Now push it on edges
|
||||||
TRI_ASSERT(tmp.size() == 1);
|
TRI_ASSERT(tmp.size() == 1);
|
||||||
edges.push_back(EdgeInfo(
|
auto it = _expressions->find(edges.size());
|
||||||
edgeCols.at(eColIdx)->_info._cid,
|
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()
|
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,
|
void toJson (triagens::basics::Json& json,
|
||||||
TRI_memory_zone_t* zone) const {
|
TRI_memory_zone_t* zone) const;
|
||||||
auto op = triagens::aql::AstNode::Operators.find(comparisonType);
|
|
||||||
|
|
||||||
if (op == triagens::aql::AstNode::Operators.end()) {
|
bool matchesCheck (TRI_doc_mptr_t& element,
|
||||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_PARSE, "invalid operator for TraverserExpression");
|
VocShaper* shaper) const;
|
||||||
}
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue