mirror of https://gitee.com/bigwinds/arangodb
1st steps for reference access optimisations
This commit is contained in:
parent
2d7505a598
commit
3cb8b653cd
|
@ -49,6 +49,8 @@ static char* AccessName (const TRI_aql_access_e type) {
|
|||
switch (type) {
|
||||
case TRI_AQL_ACCESS_ALL:
|
||||
return "all";
|
||||
case TRI_AQL_ACCESS_REFERENCE:
|
||||
return "reference";
|
||||
case TRI_AQL_ACCESS_IMPOSSIBLE:
|
||||
return "impossible";
|
||||
case TRI_AQL_ACCESS_EXACT:
|
||||
|
@ -59,9 +61,10 @@ static char* AccessName (const TRI_aql_access_e type) {
|
|||
return "single range";
|
||||
case TRI_AQL_ACCESS_RANGE_DOUBLE:
|
||||
return "double range";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
assert(false);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -94,17 +97,21 @@ static void FreeAccessMembers (TRI_aql_field_access_t* const fieldAccess) {
|
|||
|
||||
switch (fieldAccess->_type) {
|
||||
case TRI_AQL_ACCESS_EXACT:
|
||||
case TRI_AQL_ACCESS_LIST:
|
||||
case TRI_AQL_ACCESS_LIST: {
|
||||
if (fieldAccess->_value._value) {
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, fieldAccess->_value._value);
|
||||
}
|
||||
break;
|
||||
case TRI_AQL_ACCESS_RANGE_SINGLE:
|
||||
}
|
||||
|
||||
case TRI_AQL_ACCESS_RANGE_SINGLE: {
|
||||
if (fieldAccess->_value._singleRange._value) {
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, fieldAccess->_value._singleRange._value);
|
||||
}
|
||||
break;
|
||||
case TRI_AQL_ACCESS_RANGE_DOUBLE:
|
||||
}
|
||||
|
||||
case TRI_AQL_ACCESS_RANGE_DOUBLE: {
|
||||
if (fieldAccess->_value._between._lower._value) {
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, fieldAccess->_value._between._lower._value);
|
||||
}
|
||||
|
@ -112,11 +119,19 @@ static void FreeAccessMembers (TRI_aql_field_access_t* const fieldAccess) {
|
|||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, fieldAccess->_value._between._upper._value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TRI_AQL_ACCESS_REFERENCE: {
|
||||
if (fieldAccess->_value._value) {
|
||||
TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, fieldAccess->_value._value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TRI_AQL_ACCESS_ALL:
|
||||
case TRI_AQL_ACCESS_IMPOSSIBLE:
|
||||
default: {
|
||||
case TRI_AQL_ACCESS_IMPOSSIBLE: {
|
||||
// nada
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -198,6 +213,23 @@ static TRI_aql_field_access_t* MergeAndAll (TRI_aql_context_t* const context,
|
|||
return rhs;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief merge two access structures using a logical AND
|
||||
///
|
||||
/// left hand operand is a reference, so it will always be returned
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_aql_field_access_t* MergeAndReference (TRI_aql_context_t* const context,
|
||||
TRI_aql_field_access_t* lhs,
|
||||
TRI_aql_field_access_t* rhs) {
|
||||
assert(lhs->_type == TRI_AQL_ACCESS_REFERENCE);
|
||||
|
||||
// reference always wins
|
||||
TRI_FreeAccessAql(rhs);
|
||||
|
||||
return lhs;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief merge two access structures using a logical AND
|
||||
///
|
||||
|
@ -808,6 +840,35 @@ static TRI_aql_field_access_t* MergeOrAll (TRI_aql_context_t* const context,
|
|||
return lhs;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief merge two access structures using a logical OR
|
||||
///
|
||||
/// left hand operand is reference access
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static TRI_aql_field_access_t* MergeOrReference (TRI_aql_context_t* const context,
|
||||
TRI_aql_field_access_t* lhs,
|
||||
TRI_aql_field_access_t* rhs) {
|
||||
assert(lhs->_type == TRI_AQL_ACCESS_REFERENCE);
|
||||
|
||||
if (rhs->_type == TRI_AQL_ACCESS_REFERENCE) {
|
||||
// if rhs is also a reference, we can keep it if both refer to the same value
|
||||
if (TRI_EqualString(lhs->_value._value->_value._string.data, rhs->_value._value->_value._string.data)) {
|
||||
TRI_FreeAccessAql(rhs);
|
||||
|
||||
return lhs;
|
||||
}
|
||||
}
|
||||
|
||||
// for everything else, we have to use the ALL range unfortunately
|
||||
|
||||
TRI_FreeAccessAql(rhs);
|
||||
FreeAccessMembers(lhs);
|
||||
lhs->_type = TRI_AQL_ACCESS_ALL;
|
||||
|
||||
return lhs;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief merge two access structures using a logical OR
|
||||
///
|
||||
|
@ -1131,6 +1192,8 @@ static TRI_aql_field_access_t* MergeAttributeAccessAnd (TRI_aql_context_t* const
|
|||
return MergeAndImpossible(context, lhs, rhs);
|
||||
case TRI_AQL_ACCESS_ALL:
|
||||
return MergeAndAll(context, lhs, rhs);
|
||||
case TRI_AQL_ACCESS_REFERENCE:
|
||||
return MergeAndReference(context, lhs, rhs);
|
||||
case TRI_AQL_ACCESS_EXACT:
|
||||
return MergeAndExact(context, lhs, rhs);
|
||||
case TRI_AQL_ACCESS_LIST:
|
||||
|
@ -1172,6 +1235,8 @@ static TRI_aql_field_access_t* MergeAttributeAccessOr (TRI_aql_context_t* const
|
|||
return MergeOrImpossible(context, lhs, rhs);
|
||||
case TRI_AQL_ACCESS_ALL:
|
||||
return MergeOrAll(context, lhs, rhs);
|
||||
case TRI_AQL_ACCESS_REFERENCE:
|
||||
return MergeOrReference(context, lhs, rhs);
|
||||
case TRI_AQL_ACCESS_EXACT:
|
||||
return MergeOrExact(context, lhs, rhs);
|
||||
case TRI_AQL_ACCESS_LIST:
|
||||
|
@ -1451,6 +1516,7 @@ static TRI_aql_field_access_t* CreateAccessForNode (TRI_aql_context_t* const con
|
|||
if (fieldAccess == NULL) {
|
||||
// OOM
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1458,6 +1524,7 @@ static TRI_aql_field_access_t* CreateAccessForNode (TRI_aql_context_t* const con
|
|||
if (fieldAccess->_fullName == NULL) {
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||
TRI_Free(TRI_UNKNOWN_MEM_ZONE, fieldAccess);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
SetNameLength(fieldAccess);
|
||||
|
@ -1465,13 +1532,15 @@ static TRI_aql_field_access_t* CreateAccessForNode (TRI_aql_context_t* const con
|
|||
if (operator == TRI_AQL_NODE_OPERATOR_BINARY_NE) {
|
||||
// create an all items access, and we're done
|
||||
fieldAccess->_type = TRI_AQL_ACCESS_ALL;
|
||||
|
||||
return fieldAccess;
|
||||
}
|
||||
|
||||
// all other operation types require a value...
|
||||
value = TRI_NodeJsonAql(context, node);
|
||||
if (!value) {
|
||||
if (value == NULL) {
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -1859,14 +1928,16 @@ TRI_aql_field_access_t* TRI_CloneAccessAql (TRI_aql_context_t* const context,
|
|||
|
||||
switch (source->_type) {
|
||||
case TRI_AQL_ACCESS_EXACT:
|
||||
case TRI_AQL_ACCESS_LIST:
|
||||
case TRI_AQL_ACCESS_LIST: {
|
||||
fieldAccess->_value._value = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, source->_value._value);
|
||||
if (fieldAccess->_value._value == NULL) {
|
||||
// OOM
|
||||
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||
}
|
||||
break;
|
||||
case TRI_AQL_ACCESS_RANGE_SINGLE:
|
||||
}
|
||||
|
||||
case TRI_AQL_ACCESS_RANGE_SINGLE: {
|
||||
fieldAccess->_value._singleRange._type = source->_value._singleRange._type;
|
||||
fieldAccess->_value._singleRange._value = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, source->_value._singleRange._value);
|
||||
if (fieldAccess->_value._singleRange._value == NULL) {
|
||||
|
@ -1874,7 +1945,9 @@ TRI_aql_field_access_t* TRI_CloneAccessAql (TRI_aql_context_t* const context,
|
|||
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||
}
|
||||
break;
|
||||
case TRI_AQL_ACCESS_RANGE_DOUBLE:
|
||||
}
|
||||
|
||||
case TRI_AQL_ACCESS_RANGE_DOUBLE: {
|
||||
fieldAccess->_value._between._lower._type = source->_value._between._lower._type;
|
||||
fieldAccess->_value._between._upper._type = source->_value._between._upper._type;
|
||||
fieldAccess->_value._between._lower._value = TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, source->_value._between._lower._value);
|
||||
|
@ -1885,12 +1958,19 @@ TRI_aql_field_access_t* TRI_CloneAccessAql (TRI_aql_context_t* const context,
|
|||
TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TRI_AQL_ACCESS_REFERENCE: {
|
||||
// TODO
|
||||
break;
|
||||
}
|
||||
|
||||
case TRI_AQL_ACCESS_ALL:
|
||||
case TRI_AQL_ACCESS_IMPOSSIBLE:
|
||||
default:
|
||||
case TRI_AQL_ACCESS_IMPOSSIBLE: {
|
||||
// nada
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return fieldAccess;
|
||||
}
|
||||
|
|
|
@ -68,12 +68,13 @@ TRI_aql_logical_e;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef enum {
|
||||
TRI_AQL_ACCESS_IMPOSSIBLE, // no values must be accessed
|
||||
TRI_AQL_ACCESS_EXACT, // one value must be accessed
|
||||
TRI_AQL_ACCESS_LIST, // a list of values must be accessed
|
||||
TRI_AQL_ACCESS_RANGE_SINGLE, // a range with one bound must be accessed
|
||||
TRI_AQL_ACCESS_RANGE_DOUBLE, // a two bounded range must be accessed
|
||||
TRI_AQL_ACCESS_ALL // all values must be accessed
|
||||
TRI_AQL_ACCESS_IMPOSSIBLE, // no value needs to be accessed (impossible range)
|
||||
TRI_AQL_ACCESS_EXACT, // one value is accessed
|
||||
TRI_AQL_ACCESS_LIST, // a list of values is accessed
|
||||
TRI_AQL_ACCESS_RANGE_SINGLE, // a range with one boundary is accessed
|
||||
TRI_AQL_ACCESS_RANGE_DOUBLE, // a two bounded range is accessed
|
||||
TRI_AQL_ACCESS_REFERENCE, // a reference can be used for access (a.x == b.x)
|
||||
TRI_AQL_ACCESS_ALL // all values must be accessed (full scan)
|
||||
}
|
||||
TRI_aql_access_e;
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Ahuacatl/ahuacatl-explain.h"
|
||||
#include "Ahuacatl/ahuacatl-collections.h"
|
||||
#include "Ahuacatl/ahuacatl-conversions.h"
|
||||
#include "Ahuacatl/ahuacatl-scope.h"
|
||||
#include "Ahuacatl/ahuacatl-statement-walker.h"
|
||||
|
|
Loading…
Reference in New Issue