mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel
This commit is contained in:
commit
f63e90e08b
|
@ -193,7 +193,9 @@ a numeric timestamp to a string representation and vice versa.
|
|||
|
||||
There are two date functions in AQL to create dates for further use:
|
||||
|
||||
- *DATE_TIMESTAMP(date)*: Creates a UTC timestamp value from *date*.
|
||||
- *DATE_TIMESTAMP(date)*: Creates a UTC timestamp value from *date*. The return
|
||||
value has millisecond precision. To convert the return value to seconds, divide
|
||||
it by 1000.
|
||||
|
||||
- *DATE_TIMESTAMP(year, month, day, hour, minute, second, millisecond)*:
|
||||
Same as before, but allows specifying the individual date components separately.
|
||||
|
@ -294,6 +296,8 @@ The following date functions can be used with dates created by *DATE_TIMESTAMP*
|
|||
The following other date functions are also available:
|
||||
|
||||
- *DATE_NOW()*: Returns the current time as a timestamp.
|
||||
The return value has millisecond precision. To convert the return value to seconds,
|
||||
divide it by 1000.
|
||||
|
||||
Note that this function is evaluated on every invocation and may return different
|
||||
values when invoked multiple times in the same query.
|
||||
|
|
|
@ -3758,6 +3758,23 @@ size_t ScatterBlock::skipSomeForShard (size_t atLeast, size_t atMost, std::strin
|
|||
return skipped;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief skipForShard
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool ScatterBlock::skipForShard (size_t number, std::string const& shardId) {
|
||||
size_t skipped = skipSomeForShard(number, number, shardId);
|
||||
size_t nr = skipped;
|
||||
while ( nr != 0 && skipped < number ){
|
||||
nr = skipSomeForShard(number - skipped, number - skipped, shardId);
|
||||
skipped += nr;
|
||||
}
|
||||
if (nr == 0) {
|
||||
return true;
|
||||
}
|
||||
return ! hasMoreForShard(shardId);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief getClientId: get the number <clientId> (used internally)
|
||||
/// corresponding to <shardId>
|
||||
|
@ -3824,6 +3841,9 @@ ClusterCommResult* RemoteBlock::sendRequest (
|
|||
ClientTransactionID const clientTransactionId = "AQL";
|
||||
CoordTransactionID const coordTransactionId = 1;
|
||||
std::map<std::string, std::string> headers;
|
||||
if (! _ownName.empty()) {
|
||||
headers.insert(make_pair("Shard-Id", _ownName));
|
||||
}
|
||||
|
||||
std::cout << "SENDING REQUEST TO " << _server << ", URLPART: " << urlPart << ", QUERYID: " << _queryId << "\n";
|
||||
return cc->syncRequest(clientTransactionId,
|
||||
|
|
|
@ -1629,6 +1629,12 @@ namespace triagens {
|
|||
size_t skipSomeForShard (size_t atLeast, size_t atMost, std::string
|
||||
const& shardId);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief skipForShard
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool skipForShard (size_t number, std::string const& shardId);
|
||||
|
||||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -209,7 +209,7 @@ ExecutionNode::ExecutionNode (ExecutionPlan* plan,
|
|||
_id(JsonHelper::checkAndGetNumericValue<size_t>(json.json(), "id")),
|
||||
_estimatedCost(0.0),
|
||||
_estimatedCostSet(false),
|
||||
_varUsageValid(false),
|
||||
_varUsageValid(true),
|
||||
_plan(plan),
|
||||
_depth(JsonHelper::checkAndGetNumericValue<size_t>(json.json(), "depth")) {
|
||||
|
||||
|
@ -1854,6 +1854,7 @@ void ReturnNode::toJsonHelper (triagens::basics::Json& nodes,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief clone ExecutionNode recursively
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExecutionNode* ReturnNode::clone (ExecutionPlan* plan,
|
||||
bool withDependencies,
|
||||
bool withProperties) const {
|
||||
|
|
|
@ -488,6 +488,13 @@ void RestAqlHandler::getInfoQuery (std::string const& operation,
|
|||
std::string const& idString) {
|
||||
// the GET verb
|
||||
|
||||
bool found;
|
||||
std::string shardId;
|
||||
char const* shardIdCharP = _request->header("shard-id", found);
|
||||
if (found && shardIdCharP != nullptr) {
|
||||
shardId = shardIdCharP;
|
||||
}
|
||||
|
||||
QueryId qId;
|
||||
Query* query = nullptr;
|
||||
if (findQuery(idString, qId, query)) {
|
||||
|
@ -498,33 +505,69 @@ void RestAqlHandler::getInfoQuery (std::string const& operation,
|
|||
|
||||
TRI_ASSERT(query->engine() != nullptr);
|
||||
|
||||
int64_t number;
|
||||
if (operation == "count") {
|
||||
number = query->engine()->count();
|
||||
if (number == -1) {
|
||||
answerBody("count", Json("unknown"));
|
||||
try {
|
||||
int64_t number;
|
||||
if (operation == "count") {
|
||||
number = query->engine()->count();
|
||||
if (number == -1) {
|
||||
answerBody("count", Json("unknown"));
|
||||
}
|
||||
else {
|
||||
answerBody("count", Json(static_cast<double>(number)));
|
||||
}
|
||||
}
|
||||
else if (operation == "remaining") {
|
||||
// FIXME:
|
||||
// Do the !shardId.empty() case once the ScatterBlock has remainingForShard
|
||||
number = query->engine()->remaining();
|
||||
if (number == -1) {
|
||||
answerBody("remaining", Json("unknown"));
|
||||
}
|
||||
else {
|
||||
answerBody("remaining", Json(static_cast<double>(number)));
|
||||
}
|
||||
}
|
||||
else if (operation == "hasMore") {
|
||||
bool hasMore;
|
||||
if (shardId.empty()) {
|
||||
hasMore = query->engine()->hasMore();
|
||||
}
|
||||
else {
|
||||
auto scatter = static_cast<ScatterBlock*>(query->engine()->root());
|
||||
if (scatter->getPlanNode()->getType() != ExecutionNode::SCATTER) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
}
|
||||
hasMore = scatter->hasMoreForShard(shardId);
|
||||
}
|
||||
|
||||
answerBody("hasMore", Json(hasMore));
|
||||
}
|
||||
else {
|
||||
answerBody("count", Json(static_cast<double>(number)));
|
||||
_queryRegistry->close(_vocbase, qId);
|
||||
generateError(HttpResponse::NOT_FOUND, TRI_ERROR_HTTP_NOT_FOUND);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (operation == "remaining") {
|
||||
number = query->engine()->remaining();
|
||||
if (number == -1) {
|
||||
answerBody("remaining", Json("unknown"));
|
||||
}
|
||||
else {
|
||||
answerBody("remaining", Json(static_cast<double>(number)));
|
||||
}
|
||||
}
|
||||
else if (operation == "hasMore") {
|
||||
bool hasMore = query->engine()->hasMore();
|
||||
answerBody("hasMore", Json(hasMore));
|
||||
}
|
||||
else {
|
||||
catch (triagens::arango::Exception const& ex) {
|
||||
_queryRegistry->close(_vocbase, qId);
|
||||
generateError(HttpResponse::NOT_FOUND, TRI_ERROR_HTTP_NOT_FOUND);
|
||||
return;
|
||||
|
||||
generateError(HttpResponse::SERVER_ERROR,
|
||||
ex.code(),
|
||||
ex.message());
|
||||
}
|
||||
catch (std::exception const& ex) {
|
||||
_queryRegistry->close(_vocbase, qId);
|
||||
|
||||
generateError(HttpResponse::SERVER_ERROR,
|
||||
TRI_ERROR_HTTP_SERVER_ERROR,
|
||||
ex.what());
|
||||
}
|
||||
catch (...) {
|
||||
_queryRegistry->close(_vocbase, qId);
|
||||
|
||||
generateError(HttpResponse::SERVER_ERROR,
|
||||
TRI_ERROR_HTTP_SERVER_ERROR,
|
||||
"an unknown exception occurred");
|
||||
}
|
||||
|
||||
_queryRegistry->close(_vocbase, qId);
|
||||
|
@ -661,7 +704,7 @@ void RestAqlHandler::handleUseQuery (std::string const& operation,
|
|||
bool found;
|
||||
std::string shardId;
|
||||
char const* shardIdCharP = _request->header("shard-id", found);
|
||||
if (shardIdCharP != nullptr) {
|
||||
if (found && shardIdCharP != nullptr) {
|
||||
shardId = shardIdCharP;
|
||||
}
|
||||
|
||||
|
@ -706,7 +749,16 @@ std::cout << "ANSWERBODY: " << JsonHelper::toString(answerBody.json()) << "\n\n"
|
|||
"atMost", ExecutionBlock::DefaultBatchSize);
|
||||
size_t skipped;
|
||||
try {
|
||||
skipped = query->engine()->skipSome(atLeast, atMost);
|
||||
if (shardId.empty()) {
|
||||
skipped = query->engine()->skipSome(atLeast, atMost);
|
||||
}
|
||||
else {
|
||||
auto scatter = static_cast<ScatterBlock*>(query->engine()->root());
|
||||
if (scatter->getPlanNode()->getType() != ExecutionNode::SCATTER) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
}
|
||||
skipped = scatter->skipSomeForShard(atLeast, atMost, shardId);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
generateError(HttpResponse::SERVER_ERROR, TRI_ERROR_HTTP_SERVER_ERROR,
|
||||
|
@ -720,7 +772,18 @@ std::cout << "ANSWERBODY: " << JsonHelper::toString(answerBody.json()) << "\n\n"
|
|||
auto number = JsonHelper::getNumericValue<uint64_t>(queryJson.json(),
|
||||
"number", 1);
|
||||
try {
|
||||
bool exhausted = query->engine()->skip(number);
|
||||
bool exhausted;
|
||||
if (shardId.empty()) {
|
||||
exhausted = query->engine()->skip(number);
|
||||
}
|
||||
else {
|
||||
auto scatter = static_cast<ScatterBlock*>(query->engine()->root());
|
||||
if (scatter->getPlanNode()->getType() != ExecutionNode::SCATTER) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
}
|
||||
exhausted = scatter->skipForShard(number, shardId);
|
||||
}
|
||||
|
||||
answerBody("exhausted", Json(exhausted))
|
||||
("error", Json(false));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue