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:
|
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)*:
|
- *DATE_TIMESTAMP(year, month, day, hour, minute, second, millisecond)*:
|
||||||
Same as before, but allows specifying the individual date components separately.
|
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:
|
The following other date functions are also available:
|
||||||
|
|
||||||
- *DATE_NOW()*: Returns the current time as a timestamp.
|
- *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
|
Note that this function is evaluated on every invocation and may return different
|
||||||
values when invoked multiple times in the same query.
|
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;
|
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)
|
/// @brief getClientId: get the number <clientId> (used internally)
|
||||||
/// corresponding to <shardId>
|
/// corresponding to <shardId>
|
||||||
|
@ -3824,6 +3841,9 @@ ClusterCommResult* RemoteBlock::sendRequest (
|
||||||
ClientTransactionID const clientTransactionId = "AQL";
|
ClientTransactionID const clientTransactionId = "AQL";
|
||||||
CoordTransactionID const coordTransactionId = 1;
|
CoordTransactionID const coordTransactionId = 1;
|
||||||
std::map<std::string, std::string> headers;
|
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";
|
std::cout << "SENDING REQUEST TO " << _server << ", URLPART: " << urlPart << ", QUERYID: " << _queryId << "\n";
|
||||||
return cc->syncRequest(clientTransactionId,
|
return cc->syncRequest(clientTransactionId,
|
||||||
|
|
|
@ -1629,6 +1629,12 @@ namespace triagens {
|
||||||
size_t skipSomeForShard (size_t atLeast, size_t atMost, std::string
|
size_t skipSomeForShard (size_t atLeast, size_t atMost, std::string
|
||||||
const& shardId);
|
const& shardId);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief skipForShard
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool skipForShard (size_t number, std::string const& shardId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -209,7 +209,7 @@ ExecutionNode::ExecutionNode (ExecutionPlan* plan,
|
||||||
_id(JsonHelper::checkAndGetNumericValue<size_t>(json.json(), "id")),
|
_id(JsonHelper::checkAndGetNumericValue<size_t>(json.json(), "id")),
|
||||||
_estimatedCost(0.0),
|
_estimatedCost(0.0),
|
||||||
_estimatedCostSet(false),
|
_estimatedCostSet(false),
|
||||||
_varUsageValid(false),
|
_varUsageValid(true),
|
||||||
_plan(plan),
|
_plan(plan),
|
||||||
_depth(JsonHelper::checkAndGetNumericValue<size_t>(json.json(), "depth")) {
|
_depth(JsonHelper::checkAndGetNumericValue<size_t>(json.json(), "depth")) {
|
||||||
|
|
||||||
|
@ -1854,6 +1854,7 @@ void ReturnNode::toJsonHelper (triagens::basics::Json& nodes,
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief clone ExecutionNode recursively
|
/// @brief clone ExecutionNode recursively
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
ExecutionNode* ReturnNode::clone (ExecutionPlan* plan,
|
ExecutionNode* ReturnNode::clone (ExecutionPlan* plan,
|
||||||
bool withDependencies,
|
bool withDependencies,
|
||||||
bool withProperties) const {
|
bool withProperties) const {
|
||||||
|
|
|
@ -488,6 +488,13 @@ void RestAqlHandler::getInfoQuery (std::string const& operation,
|
||||||
std::string const& idString) {
|
std::string const& idString) {
|
||||||
// the GET verb
|
// the GET verb
|
||||||
|
|
||||||
|
bool found;
|
||||||
|
std::string shardId;
|
||||||
|
char const* shardIdCharP = _request->header("shard-id", found);
|
||||||
|
if (found && shardIdCharP != nullptr) {
|
||||||
|
shardId = shardIdCharP;
|
||||||
|
}
|
||||||
|
|
||||||
QueryId qId;
|
QueryId qId;
|
||||||
Query* query = nullptr;
|
Query* query = nullptr;
|
||||||
if (findQuery(idString, qId, query)) {
|
if (findQuery(idString, qId, query)) {
|
||||||
|
@ -498,33 +505,69 @@ void RestAqlHandler::getInfoQuery (std::string const& operation,
|
||||||
|
|
||||||
TRI_ASSERT(query->engine() != nullptr);
|
TRI_ASSERT(query->engine() != nullptr);
|
||||||
|
|
||||||
int64_t number;
|
try {
|
||||||
if (operation == "count") {
|
int64_t number;
|
||||||
number = query->engine()->count();
|
if (operation == "count") {
|
||||||
if (number == -1) {
|
number = query->engine()->count();
|
||||||
answerBody("count", Json("unknown"));
|
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 {
|
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") {
|
catch (triagens::arango::Exception const& ex) {
|
||||||
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 {
|
|
||||||
_queryRegistry->close(_vocbase, qId);
|
_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);
|
_queryRegistry->close(_vocbase, qId);
|
||||||
|
@ -661,7 +704,7 @@ void RestAqlHandler::handleUseQuery (std::string const& operation,
|
||||||
bool found;
|
bool found;
|
||||||
std::string shardId;
|
std::string shardId;
|
||||||
char const* shardIdCharP = _request->header("shard-id", found);
|
char const* shardIdCharP = _request->header("shard-id", found);
|
||||||
if (shardIdCharP != nullptr) {
|
if (found && shardIdCharP != nullptr) {
|
||||||
shardId = shardIdCharP;
|
shardId = shardIdCharP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -706,7 +749,16 @@ std::cout << "ANSWERBODY: " << JsonHelper::toString(answerBody.json()) << "\n\n"
|
||||||
"atMost", ExecutionBlock::DefaultBatchSize);
|
"atMost", ExecutionBlock::DefaultBatchSize);
|
||||||
size_t skipped;
|
size_t skipped;
|
||||||
try {
|
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 (...) {
|
catch (...) {
|
||||||
generateError(HttpResponse::SERVER_ERROR, TRI_ERROR_HTTP_SERVER_ERROR,
|
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(),
|
auto number = JsonHelper::getNumericValue<uint64_t>(queryJson.json(),
|
||||||
"number", 1);
|
"number", 1);
|
||||||
try {
|
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))
|
answerBody("exhausted", Json(exhausted))
|
||||||
("error", Json(false));
|
("error", Json(false));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue