Json AqlValue::extractObjectMember (triagens::arango::AqlTransaction* trx, TRI_document_collection_t const* document, char const* name, bool copy, triagens::basics::StringBuffer& buffer) const { switch (_type) { case JSON: { TRI_ASSERT(_json != nullptr); TRI_json_t const* json = _json->json(); if (TRI_IsObjectJson(json)) { TRI_json_t const* found = TRI_LookupObjectJson(json, name); if (found != nullptr) { if (copy) { // return a copy of the value auto c = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, found); if (c == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } return Json(TRI_UNKNOWN_MEM_ZONE, c, triagens::basics::Json::AUTOFREE); } // return a pointer to the original value, without asking for its ownership return Json(TRI_UNKNOWN_MEM_ZONE, found, triagens::basics::Json::NOFREE); } } // attribute does not exist or something went wrong - fall-through to returning null below return Json(Json::Null); } case SHAPED: { TRI_ASSERT(document != nullptr); TRI_ASSERT(_marker != nullptr); // look for the attribute name in the shape if (*name == '_' && name[1] != '\0') { if (name[1] == 'k' && strcmp(name, TRI_VOC_ATTRIBUTE_KEY) == 0) { // _key value is copied into JSON return Json(TRI_UNKNOWN_MEM_ZONE, TRI_EXTRACT_MARKER_KEY(_marker)); } if (name[1] == 'i' && strcmp(name, TRI_VOC_ATTRIBUTE_ID) == 0) { // _id buffer.reset(); trx->resolver()->getCollectionName(document->_info._cid, buffer); buffer.appendChar('/'); buffer.appendText(TRI_EXTRACT_MARKER_KEY(_marker)); return Json(TRI_UNKNOWN_MEM_ZONE, buffer.c_str(), buffer.length()); } if (name[1] == 'r' && strcmp(name, TRI_VOC_ATTRIBUTE_REV) == 0) { // _rev TRI_voc_rid_t rid = TRI_EXTRACT_MARKER_RID(_marker); buffer.reset(); buffer.appendInteger(rid); return Json(TRI_UNKNOWN_MEM_ZONE, buffer.c_str(), buffer.length()); } if (name[1] == 'f' && strcmp(name, TRI_VOC_ATTRIBUTE_FROM) == 0 && (_marker->_type == TRI_DOC_MARKER_KEY_EDGE || _marker->_type == TRI_WAL_MARKER_EDGE)) { buffer.reset(); trx->resolver()->getCollectionNameCluster(TRI_EXTRACT_MARKER_FROM_CID(_marker), buffer); buffer.appendChar('/'); buffer.appendText(TRI_EXTRACT_MARKER_FROM_KEY(_marker)); return Json(TRI_UNKNOWN_MEM_ZONE, buffer.c_str(), buffer.length()); } if (name[1] == 't' && strcmp(name, TRI_VOC_ATTRIBUTE_TO) == 0 && (_marker->_type == TRI_DOC_MARKER_KEY_EDGE || _marker->_type == TRI_WAL_MARKER_EDGE)) { buffer.reset(); trx->resolver()->getCollectionNameCluster(TRI_EXTRACT_MARKER_TO_CID(_marker), buffer); buffer.appendChar('/'); buffer.appendText(TRI_EXTRACT_MARKER_TO_KEY(_marker)); return Json(TRI_UNKNOWN_MEM_ZONE, buffer.c_str(), buffer.length()); } } auto shaper = document->getShaper(); TRI_shape_pid_t pid = shaper->lookupAttributePathByName(name); if (pid != 0) { // attribute exists TRI_shaped_json_t document; TRI_EXTRACT_SHAPED_JSON_MARKER(document, _marker); TRI_shaped_json_t json; TRI_shape_t const* shape; bool ok = shaper->extractShapedJson(&document, 0, pid, &json, &shape); if (ok && shape != nullptr) { auto v = TRI_JsonShapedJson(shaper, &json); if (v == nullptr) { THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY); } return Json(TRI_UNKNOWN_MEM_ZONE, v); } } // attribute does not exist or something went wrong - fall-through to returning null break; } case DOCVEC: case RANGE: case EMPTY: { break; } } return Json(Json::Null); }