1
0
Fork 0

Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel

This commit is contained in:
Willi Goesgens 2014-10-02 10:41:12 +02:00
commit f63e90e08b
5 changed files with 121 additions and 27 deletions

View File

@ -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.

View File

@ -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,

View File

@ -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:
////////////////////////////////////////////////////////////////////////////////

View File

@ -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 {

View File

@ -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));
}