mirror of https://gitee.com/bigwinds/arangodb
241 lines
8.8 KiB
C
241 lines
8.8 KiB
C
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief AST query declarations
|
|
///
|
|
/// @file
|
|
///
|
|
/// DISCLAIMER
|
|
///
|
|
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
|
///
|
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|
/// you may not use this file except in compliance with the License.
|
|
/// You may obtain a copy of the License at
|
|
///
|
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
|
///
|
|
/// Unless required by applicable law or agreed to in writing, software
|
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
/// See the License for the specific language governing permissions and
|
|
/// limitations under the License.
|
|
///
|
|
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
|
///
|
|
/// @author Jan Steemann
|
|
/// @author Copyright 2012, triagens GmbH, Cologne, Germany
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "QL/ast-query.h"
|
|
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// --SECTION-- private functions
|
|
// -----------------------------------------------------------------------------
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @addtogroup QL
|
|
/// @{
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Hash function used to hash collection aliases
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
static uint64_t HashKey (TRI_associative_pointer_t* array, void const* key) {
|
|
char const* k = (char const*) key;
|
|
|
|
return TRI_FnvHashString(k);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Hash function used to hash elements in the collection
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
static uint64_t HashElement (TRI_associative_pointer_t* array, void const* element) {
|
|
QL_ast_query_collection_t *collection = (QL_ast_query_collection_t*) element;
|
|
|
|
return TRI_FnvHashString(collection->_alias);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Comparison function used to determine hash key equality
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
static bool EqualKeyElement (TRI_associative_pointer_t* array, void const* key, void const* element) {
|
|
char const* k = (char const*) key;
|
|
QL_ast_query_collection_t *collection = (QL_ast_query_collection_t*) element;
|
|
|
|
return TRI_EqualString(k, collection->_alias);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @}
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// --SECTION-- public functions
|
|
// -----------------------------------------------------------------------------
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @addtogroup QL
|
|
/// @{
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Initialize data structures for a query
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void QLAstQueryInit (const TRI_vocbase_t* vocbase, QL_ast_query_t* query) {
|
|
query->_vocbase = vocbase;
|
|
query->_type = QLQueryTypeUndefined;
|
|
query->_from._base = 0;
|
|
query->_where._base = 0;
|
|
query->_order._base = 0;
|
|
query->_limit._isUsed = false;
|
|
|
|
TRI_InitAssociativePointer(&query->_from._collections,
|
|
HashKey,
|
|
HashElement,
|
|
EqualKeyElement,
|
|
0);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief De-allocate data structures for a query
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void QLAstQueryFree (QL_ast_query_t* query) {
|
|
size_t i;
|
|
void* ptr;
|
|
|
|
// destroy all elements in collection array
|
|
for (i = 0; i < query->_from._collections._nrAlloc; i++) {
|
|
ptr = query->_from._collections._table[i];
|
|
|
|
if (ptr != 0) {
|
|
TRI_Free(ptr);
|
|
}
|
|
}
|
|
|
|
// destroy array itself
|
|
TRI_DestroyAssociativePointer(&query->_from._collections);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief get the ref count for a collection
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
size_t QLAstQueryGetRefCount (QL_ast_query_t* query, const char* alias) {
|
|
QL_ast_query_collection_t* collection = (QL_ast_query_collection_t*)
|
|
TRI_LookupByKeyAssociativePointer(&query->_from._collections, alias);
|
|
|
|
if (collection != 0) {
|
|
return collection->_refCount;
|
|
}
|
|
|
|
// return a number > 0 if collection not found so nothing happens with it
|
|
return 1;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Increment ref count for a collection
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
void QLAstQueryAddRefCount (QL_ast_query_t* query, const char* alias) {
|
|
QL_ast_query_collection_t* collection = (QL_ast_query_collection_t*)
|
|
TRI_LookupByKeyAssociativePointer(&query->_from._collections, alias);
|
|
|
|
if (collection != 0) {
|
|
++collection->_refCount;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief Check if a collection was defined in a query
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool QLAstQueryIsValidAlias (QL_ast_query_t* query, const char* 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
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
bool QLAstQueryAddCollection (QL_ast_query_t* query,
|
|
const char* name,
|
|
const char* alias) {
|
|
QL_ast_query_collection_t* collection;
|
|
QL_ast_query_collection_t* previous;
|
|
|
|
previous = (QL_ast_query_collection_t*)
|
|
TRI_LookupByKeyAssociativePointer (&query->_from._collections, alias);
|
|
|
|
if (previous != 0) {
|
|
// element is already present - return an error
|
|
return false;
|
|
}
|
|
|
|
collection = (QL_ast_query_collection_t *) TRI_Allocate(sizeof(QL_ast_query_collection_t));
|
|
if (collection == 0) {
|
|
return false;
|
|
}
|
|
|
|
collection->_name = (char*) name;
|
|
collection->_alias = (char*) alias;
|
|
// first collection added is always the primary collection
|
|
collection->_isPrimary = (&query->_from._collections._nrUsed == 0);
|
|
collection->_refCount = 0; // will be used later when optimizing joins
|
|
|
|
TRI_InsertKeyAssociativePointer(&query->_from._collections,
|
|
collection->_alias,
|
|
collection,
|
|
true);
|
|
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief get the alias of the primary collection used in the query
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
char* QLAstQueryGetPrimaryAlias (const QL_ast_query_t* query) {
|
|
size_t i;
|
|
QL_ast_query_collection_t *collection;
|
|
|
|
for (i = 0; i < query->_from._collections._nrAlloc; i++) {
|
|
collection = query->_from._collections._table[i];
|
|
if (collection != 0 && collection->_isPrimary) {
|
|
return collection->_alias;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @}
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Local Variables:
|
|
// mode: outline-minor
|
|
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
|
|
// End:
|
|
|