mirror of https://gitee.com/bigwinds/arangodb
JAN: more optimisation
This commit is contained in:
parent
496a55cdb1
commit
d913bd95b1
|
@ -208,6 +208,32 @@ QL_ast_node_type_group_e QLAstNodeGetTypeGroup (const QL_ast_node_type_e type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief get the reverse of a relational operator
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
QL_ast_node_type_e QLAstNodeGetReversedRelationalOperator (const QL_ast_node_type_e type) {
|
||||||
|
if (type == QLNodeBinaryOperatorIdentical ||
|
||||||
|
type == QLNodeBinaryOperatorEqual ||
|
||||||
|
type == QLNodeBinaryOperatorUnidentical ||
|
||||||
|
type == QLNodeBinaryOperatorUnequal) {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
if (type == QLNodeBinaryOperatorLess) {
|
||||||
|
return QLNodeBinaryOperatorGreaterEqual;
|
||||||
|
}
|
||||||
|
if (type == QLNodeBinaryOperatorLessEqual) {
|
||||||
|
return QLNodeBinaryOperatorGreater;
|
||||||
|
}
|
||||||
|
if (type == QLNodeBinaryOperatorGreater) {
|
||||||
|
return QLNodeBinaryOperatorLessEqual;
|
||||||
|
}
|
||||||
|
if (type == QLNodeBinaryOperatorGreaterEqual) {
|
||||||
|
return QLNodeBinaryOperatorLess;
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief get the label string for a unary operator
|
/// @brief get the label string for a unary operator
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -169,6 +169,12 @@ const char* QLAstNodeGetName (const QL_ast_node_type_e);
|
||||||
|
|
||||||
QL_ast_node_type_group_e QLAstNodeGetTypeGroup (const QL_ast_node_type_e);
|
QL_ast_node_type_group_e QLAstNodeGetTypeGroup (const QL_ast_node_type_e);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief get the reverse of a relational operator
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
QL_ast_node_type_e QLAstNodeGetReversedRelationalOperator (const QL_ast_node_type_e);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief get the label string for a unary operator
|
/// @brief get the label string for a unary operator
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -158,6 +158,22 @@ bool QLAstQueryIsValidAlias (QL_ast_query_t* query, const char* alias) {
|
||||||
return (0 != TRI_LookupByKeyAssociativePointer(&query->_from._collections, alias));
|
return (0 != TRI_LookupByKeyAssociativePointer(&query->_from._collections, alias));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief Return the collection name for its alias
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
char* QLAstQueryGetCollectionNameForAlias (QL_ast_query_t* query,
|
||||||
|
const char* alias) {
|
||||||
|
QL_ast_query_collection_t* collection;
|
||||||
|
|
||||||
|
collection = (QL_ast_query_collection_t*)
|
||||||
|
TRI_LookupByKeyAssociativePointer(&query->_from._collections, alias);
|
||||||
|
if (!collection) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return collection->_name;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief Add a collection to the query
|
/// @brief Add a collection to the query
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -214,6 +214,12 @@ void QLAstQueryAddRefCount (QL_ast_query_t*, const char*);
|
||||||
|
|
||||||
bool QLAstQueryIsValidAlias (QL_ast_query_t*, const char*);
|
bool QLAstQueryIsValidAlias (QL_ast_query_t*, const char*);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief Return the collection name for its alias
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
char* QLAstQueryGetCollectionNameForAlias (QL_ast_query_t*, const char*);
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief Add a collection to the query
|
/// @brief Add a collection to the query
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
135
QL/optimize.c
135
QL/optimize.c
|
@ -208,6 +208,46 @@ double QLOptimizeGetDouble (const QL_ast_node_t const* node) {
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief check if a document declaration is static or dynamic
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool QLOptimizeIsStaticDocument (QL_ast_node_t* node) {
|
||||||
|
bool result;
|
||||||
|
|
||||||
|
if (node->_next) {
|
||||||
|
while (node->_next) {
|
||||||
|
result = QLOptimizeIsStaticDocument(node->_next);
|
||||||
|
if (!result) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
node = node->_next;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node->_lhs) {
|
||||||
|
result = QLOptimizeIsStaticDocument(node->_lhs);
|
||||||
|
if (!result) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node->_rhs) {
|
||||||
|
result = QLOptimizeIsStaticDocument(node->_rhs);
|
||||||
|
if (!result) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (node->_type == QLNodeReferenceCollectionAlias ||
|
||||||
|
node->_type == QLNodeControlFunctionCall ||
|
||||||
|
node->_type == QLNodeControlTernary ||
|
||||||
|
node->_type == QLNodeContainerMemberAccess) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief convert a node to a null value node
|
/// @brief convert a node to a null value node
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -870,6 +910,10 @@ void QLOptimizeFreeRangeVector (TRI_vector_pointer_t* vector) {
|
||||||
if (range->_field) {
|
if (range->_field) {
|
||||||
TRI_Free(range->_field);
|
TRI_Free(range->_field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (range->_refValue._field) {
|
||||||
|
TRI_FreeString(range->_refValue._field);
|
||||||
|
}
|
||||||
TRI_Free(range);
|
TRI_Free(range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -922,9 +966,20 @@ static TRI_vector_pointer_t* QLOptimizeCombineRanges (const QL_ast_node_type_e t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
previous = QLOptimizeGetRangeByHash(range->_hash, vector);
|
previous = QLOptimizeGetRangeByHash(range->_hash, vector);
|
||||||
|
if (type == QLNodeBinaryOperatorOr) {
|
||||||
|
// only use logical || operator for same field. if field name differs, an ||
|
||||||
|
// effectively kills all ranges
|
||||||
|
if (vector->_length >0 && !previous) {
|
||||||
|
QLOptimizeFreeRangeVector(vector);
|
||||||
|
TRI_InitVectorPointer(vector);
|
||||||
|
goto EXIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!previous) {
|
if (!previous) {
|
||||||
// push range on stack
|
// push range into result vector
|
||||||
TRI_PushBackVectorPointer(vector, range);
|
TRI_PushBackVectorPointer(vector, range);
|
||||||
|
|
||||||
// remove range from original vector to avoid double freeing
|
// remove range from original vector to avoid double freeing
|
||||||
|
@ -1298,6 +1353,7 @@ static QL_optimize_range_t* QLOptimizeCreateRange (QL_ast_node_t* memberNode,
|
||||||
QL_optimize_range_t* range;
|
QL_optimize_range_t* range;
|
||||||
TRI_string_buffer_t* name;
|
TRI_string_buffer_t* name;
|
||||||
QL_ast_node_t* lhs;
|
QL_ast_node_t* lhs;
|
||||||
|
QL_javascript_conversion_t* documentJs;
|
||||||
|
|
||||||
// get the field name
|
// get the field name
|
||||||
name = QLOptimizeGetMemberNameString(memberNode, false);
|
name = QLOptimizeGetMemberNameString(memberNode, false);
|
||||||
|
@ -1313,6 +1369,9 @@ static QL_optimize_range_t* QLOptimizeCreateRange (QL_ast_node_t* memberNode,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
range->_refValue._field = NULL;
|
||||||
|
range->_refValue._collection = NULL;
|
||||||
|
|
||||||
// get value
|
// get value
|
||||||
if (valueNode->_type == QLNodeValueNumberDouble ||
|
if (valueNode->_type == QLNodeValueNumberDouble ||
|
||||||
valueNode->_type == QLNodeValueNumberDoubleString) {
|
valueNode->_type == QLNodeValueNumberDoubleString) {
|
||||||
|
@ -1323,6 +1382,12 @@ static QL_optimize_range_t* QLOptimizeCreateRange (QL_ast_node_t* memberNode,
|
||||||
// range is of type string
|
// range is of type string
|
||||||
range->_valueType = RANGE_TYPE_STRING;
|
range->_valueType = RANGE_TYPE_STRING;
|
||||||
}
|
}
|
||||||
|
else if (valueNode->_type == QLNodeValueDocument) {
|
||||||
|
range->_valueType = RANGE_TYPE_JSON;
|
||||||
|
}
|
||||||
|
else if (valueNode->_type == QLNodeContainerMemberAccess) {
|
||||||
|
range->_valueType = RANGE_TYPE_FIELD;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
}
|
||||||
|
@ -1340,7 +1405,17 @@ static QL_optimize_range_t* QLOptimizeCreateRange (QL_ast_node_t* memberNode,
|
||||||
if (type == QLNodeBinaryOperatorIdentical ||
|
if (type == QLNodeBinaryOperatorIdentical ||
|
||||||
type == QLNodeBinaryOperatorEqual) {
|
type == QLNodeBinaryOperatorEqual) {
|
||||||
// === and == , range is [ value (inc) ... value (inc) ]
|
// === and == , range is [ value (inc) ... value (inc) ]
|
||||||
if (range->_valueType == RANGE_TYPE_DOUBLE) {
|
if (range->_valueType == RANGE_TYPE_FIELD) {
|
||||||
|
range->_refValue._collection =
|
||||||
|
((QL_ast_node_t*) valueNode->_lhs)->_value._stringValue;
|
||||||
|
name = QLOptimizeGetMemberNameString(valueNode, false);
|
||||||
|
if (name) {
|
||||||
|
range->_refValue._field = TRI_DuplicateString(name->_buffer);
|
||||||
|
TRI_FreeStringBuffer(name);
|
||||||
|
TRI_Free(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (range->_valueType == RANGE_TYPE_DOUBLE) {
|
||||||
range->_minValue._doubleValue = QLOptimizeGetDouble(valueNode);
|
range->_minValue._doubleValue = QLOptimizeGetDouble(valueNode);
|
||||||
range->_maxValue._doubleValue = range->_minValue._doubleValue;
|
range->_maxValue._doubleValue = range->_minValue._doubleValue;
|
||||||
}
|
}
|
||||||
|
@ -1348,6 +1423,19 @@ static QL_optimize_range_t* QLOptimizeCreateRange (QL_ast_node_t* memberNode,
|
||||||
range->_minValue._stringValue = valueNode->_value._stringValue;
|
range->_minValue._stringValue = valueNode->_value._stringValue;
|
||||||
range->_maxValue._stringValue = range->_minValue._stringValue;
|
range->_maxValue._stringValue = range->_minValue._stringValue;
|
||||||
}
|
}
|
||||||
|
else if (range->_valueType == RANGE_TYPE_JSON) {
|
||||||
|
documentJs = QLJavascripterInit();
|
||||||
|
if (!documentJs) {
|
||||||
|
TRI_FreeStringBuffer(name);
|
||||||
|
TRI_Free(name);
|
||||||
|
TRI_Free(range);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
QLJavascripterConvert(documentJs, valueNode);
|
||||||
|
range->_minValue._stringValue = documentJs->_buffer->_buffer;
|
||||||
|
range->_maxValue._stringValue = range->_minValue._stringValue;
|
||||||
|
QLJavascripterFree(documentJs);
|
||||||
|
}
|
||||||
range->_minStatus = RANGE_VALUE_INCLUDED;
|
range->_minStatus = RANGE_VALUE_INCLUDED;
|
||||||
range->_maxStatus = RANGE_VALUE_INCLUDED;
|
range->_maxStatus = RANGE_VALUE_INCLUDED;
|
||||||
}
|
}
|
||||||
|
@ -1449,19 +1537,43 @@ TRI_vector_pointer_t* QLOptimizeCondition (QL_ast_node_t* node) {
|
||||||
type == QLNodeBinaryOperatorLessEqual ||
|
type == QLNodeBinaryOperatorLessEqual ||
|
||||||
type == QLNodeBinaryOperatorGreaterEqual) {
|
type == QLNodeBinaryOperatorGreaterEqual) {
|
||||||
// comparison operator
|
// comparison operator
|
||||||
|
|
||||||
if (lhs->_type == QLNodeContainerMemberAccess &&
|
if (lhs->_type == QLNodeContainerMemberAccess &&
|
||||||
|
rhs->_type == QLNodeContainerMemberAccess) {
|
||||||
|
// collection.attribute relop collection.attribute
|
||||||
|
return QLOptimizeMergeRangeVectors(
|
||||||
|
QLOptimizeCreateRangeVector(QLOptimizeCreateRange(lhs, rhs, type)),
|
||||||
|
QLOptimizeCreateRangeVector(QLOptimizeCreateRange(rhs, lhs, type))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (lhs->_type == QLNodeContainerMemberAccess &&
|
||||||
|
(type == QLNodeBinaryOperatorIdentical ||
|
||||||
|
type == QLNodeBinaryOperatorEqual) &&
|
||||||
|
rhs->_type == QLNodeValueDocument &&
|
||||||
|
QLOptimizeIsStaticDocument(rhs)) {
|
||||||
|
// collection.attribute == document
|
||||||
|
return QLOptimizeCreateRangeVector(QLOptimizeCreateRange(lhs, rhs, type));
|
||||||
|
}
|
||||||
|
else if (lhs->_type == QLNodeContainerMemberAccess &&
|
||||||
(rhs->_type == QLNodeValueNumberDouble ||
|
(rhs->_type == QLNodeValueNumberDouble ||
|
||||||
rhs->_type == QLNodeValueNumberDoubleString ||
|
rhs->_type == QLNodeValueNumberDoubleString ||
|
||||||
rhs->_type == QLNodeValueString)) {
|
rhs->_type == QLNodeValueString)) {
|
||||||
// collection.attrbiute relop value
|
// collection.attribute relop value
|
||||||
return QLOptimizeCreateRangeVector(QLOptimizeCreateRange(lhs, rhs, type));
|
return QLOptimizeCreateRangeVector(QLOptimizeCreateRange(lhs, rhs, type));
|
||||||
|
}
|
||||||
|
else if (rhs->_type == QLNodeContainerMemberAccess &&
|
||||||
|
(type == QLNodeBinaryOperatorIdentical ||
|
||||||
|
type == QLNodeBinaryOperatorEqual) &&
|
||||||
|
lhs->_type == QLNodeValueDocument &&
|
||||||
|
QLOptimizeIsStaticDocument(lhs)) {
|
||||||
|
// document == collection.attribute
|
||||||
|
return QLOptimizeCreateRangeVector(QLOptimizeCreateRange(rhs, lhs, type));
|
||||||
} else if (rhs->_type == QLNodeContainerMemberAccess &&
|
} else if (rhs->_type == QLNodeContainerMemberAccess &&
|
||||||
(lhs->_type == QLNodeValueNumberDouble ||
|
(lhs->_type == QLNodeValueNumberDouble ||
|
||||||
lhs->_type == QLNodeValueNumberDoubleString ||
|
lhs->_type == QLNodeValueNumberDoubleString ||
|
||||||
lhs->_type == QLNodeValueString)) {
|
lhs->_type == QLNodeValueString)) {
|
||||||
// value relop collection.attrbiute
|
// value relop collection.attrbiute
|
||||||
return QLOptimizeCreateRangeVector(QLOptimizeCreateRange(rhs, lhs, type));
|
return QLOptimizeCreateRangeVector(
|
||||||
|
QLOptimizeCreateRange(rhs, lhs, QLAstNodeGetReversedRelationalOperator(type)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1555,22 +1667,25 @@ void QLOptimizeDetermineIndexes (QL_ast_query_t* query) {
|
||||||
TRI_index_definition_t* indexDefinition;
|
TRI_index_definition_t* indexDefinition;
|
||||||
QL_ast_node_t* node;
|
QL_ast_node_t* node;
|
||||||
char* collectionName;
|
char* collectionName;
|
||||||
|
char* alias;
|
||||||
size_t i, j, k, matches;
|
size_t i, j, k, matches;
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
node = (QL_ast_node_t*) query->_from._base->_next;
|
node = (QL_ast_node_t*) query->_from._base->_next;
|
||||||
|
|
||||||
assert(node != 0);
|
assert(node != 0);
|
||||||
|
|
||||||
|
// enum all collections used in query
|
||||||
while (node != 0) {
|
while (node != 0) {
|
||||||
ranges = 0;
|
ranges = 0;
|
||||||
if (count++ == 0) {
|
if (count++ == 0) {
|
||||||
collectionName = ((QL_ast_node_t*) node->_lhs)->_value._stringValue;
|
collectionName = ((QL_ast_node_t*) node->_lhs)->_value._stringValue;
|
||||||
|
alias = ((QL_ast_node_t*) node->_rhs)->_value._stringValue;
|
||||||
ranges = QLOptimizeCondition(query->_where._base);
|
ranges = QLOptimizeCondition(query->_where._base);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
collectionName = ((QL_ast_node_t*) ((QL_ast_node_t*) node->_lhs)->_lhs)->_value._stringValue;
|
collectionName = ((QL_ast_node_t*) ((QL_ast_node_t*) node->_lhs)->_lhs)->_value._stringValue;
|
||||||
|
alias = ((QL_ast_node_t*) ((QL_ast_node_t*) node->_lhs)->_rhs)->_value._stringValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// accessType = TABLE_SCAN;
|
// accessType = TABLE_SCAN;
|
||||||
|
@ -1578,6 +1693,7 @@ return;
|
||||||
if (ranges) {
|
if (ranges) {
|
||||||
indexDefinitions = TRI_GetCollectionIndexes(query->_vocbase, collectionName);
|
indexDefinitions = TRI_GetCollectionIndexes(query->_vocbase, collectionName);
|
||||||
|
|
||||||
|
// enum all indexes
|
||||||
for (i = 0; i < indexDefinitions._length; i++) {
|
for (i = 0; i < indexDefinitions._length; i++) {
|
||||||
indexDefinition = (TRI_index_definition_t*) indexDefinitions._buffer[i];
|
indexDefinition = (TRI_index_definition_t*) indexDefinitions._buffer[i];
|
||||||
|
|
||||||
|
@ -1585,8 +1701,8 @@ return;
|
||||||
for (j = 0 ; j < indexDefinition->_fields._length; j++) {
|
for (j = 0 ; j < indexDefinition->_fields._length; j++) {
|
||||||
for (k = 0; k < ranges->_length; k++) {
|
for (k = 0; k < ranges->_length; k++) {
|
||||||
range = (QL_optimize_range_t*) ranges->_buffer[k];
|
range = (QL_optimize_range_t*) ranges->_buffer[k];
|
||||||
// check if collection is the same
|
// check if collection name matches
|
||||||
if (strcmp(range->_collection, collectionName) != 0) {
|
if (strcmp(range->_collection, alias) != 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1606,7 +1722,8 @@ return;
|
||||||
range->_minValue._doubleValue != range->_maxValue._doubleValue) {
|
range->_minValue._doubleValue != range->_maxValue._doubleValue) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (range->_valueType == RANGE_TYPE_STRING &&
|
if ((range->_valueType == RANGE_TYPE_STRING ||
|
||||||
|
range->_valueType == RANGE_TYPE_JSON) &&
|
||||||
strcmp(range->_minValue._stringValue, range->_maxValue._stringValue) != 0) {
|
strcmp(range->_minValue._stringValue, range->_maxValue._stringValue) != 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
#include "QL/ast-query.h"
|
#include "QL/ast-query.h"
|
||||||
#include "QL/parser-context.h"
|
#include "QL/parser-context.h"
|
||||||
#include "QL/formatter.h"
|
#include "QL/formatter.h"
|
||||||
|
#include "QL/javascripter.h"
|
||||||
#include "VocBase/index.h"
|
#include "VocBase/index.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -98,12 +99,16 @@ QL_optimize_range_type_e;
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief Range value types
|
/// @brief Range value types
|
||||||
///
|
///
|
||||||
/// Currently supported types are doubles (numbers) and strings
|
/// Currently supported types are collection attributes (fields), doubles
|
||||||
|
/// (numbers), strings, and JSON documents.
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RANGE_TYPE_DOUBLE = 0,
|
RANGE_TYPE_FIELD = 1,
|
||||||
RANGE_TYPE_STRING = 1
|
RANGE_TYPE_DOUBLE = 2,
|
||||||
|
RANGE_TYPE_STRING = 3,
|
||||||
|
RANGE_TYPE_JSON = 4
|
||||||
|
|
||||||
}
|
}
|
||||||
QL_optimize_range_value_type_e;
|
QL_optimize_range_value_type_e;
|
||||||
|
|
||||||
|
@ -146,6 +151,10 @@ typedef struct QL_optimize_range_s {
|
||||||
double _doubleValue;
|
double _doubleValue;
|
||||||
char* _stringValue;
|
char* _stringValue;
|
||||||
} _maxValue;
|
} _maxValue;
|
||||||
|
struct {
|
||||||
|
char* _collection;
|
||||||
|
char *_field;
|
||||||
|
} _refValue;
|
||||||
uint64_t _hash;
|
uint64_t _hash;
|
||||||
QL_optimize_range_type_e _minStatus;
|
QL_optimize_range_type_e _minStatus;
|
||||||
QL_optimize_range_type_e _maxStatus;
|
QL_optimize_range_type_e _maxStatus;
|
||||||
|
|
Loading…
Reference in New Issue