コード例 #1
0
static char* makeWindowsArgs (TRI_external_t* external) {
  TRI_string_buffer_t* buf;
  size_t i;
  int err = TRI_ERROR_NO_ERROR;
  char* res;

  buf = TRI_CreateStringBuffer(TRI_UNKNOWN_MEM_ZONE);
  if (buf == NULL) {
    return NULL;
  }
  TRI_ReserveStringBuffer(buf, 1024);
  err = appendQuotedArg(buf, external->_executable);
  if (err != TRI_ERROR_NO_ERROR) {
    TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buf);
    return NULL;
  }
  for (i = 1;i < external->_numberArguments;i++) {
    err = TRI_AppendCharStringBuffer(buf, ' ');
    if (err != TRI_ERROR_NO_ERROR) {
      TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buf);
      return NULL;
    }
    err = appendQuotedArg(buf, external->_arguments[i]);
  }
  res = TRI_StealStringBuffer(buf);
  TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buf);
  return res;
}
コード例 #2
0
static void LogIndexString (const char* const what,
                            TRI_index_t const* idx,
                            char const* collectionName) {
  TRI_string_buffer_t* buffer = TRI_CreateStringBuffer(TRI_UNKNOWN_MEM_ZONE);
  size_t i;

  if (buffer == NULL) {
    return;
  }

  for (i = 0; i < idx->_fields._length; i++) {
    if (i > 0) {
      TRI_AppendStringStringBuffer(buffer, ", ");
    }

    TRI_AppendStringStringBuffer(buffer, idx->_fields._buffer[i]);
  }

  LOG_TRACE("%s %s index (%s) for '%s'",
            what,
            TRI_TypeNameIndex(idx->_type),
            buffer->_buffer,
            collectionName);

  TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
}
コード例 #3
0
void TRI_FreeQueryJavascript (TRI_query_javascript_converter_t* converter) {
  assert(converter);
  assert(converter->_buffer);
  
  TRI_FreeStringBuffer(converter->_buffer);
  TRI_Free(converter->_buffer);
  TRI_Free(converter);
}
コード例 #4
0
ファイル: ahuacatl-optimiser.c プロジェクト: luxyer/ArangoDB
static TRI_string_buffer_t* RelationCode (const char* const name, 
                                          const TRI_aql_node_t* const lhs,
                                          const TRI_aql_node_t* const rhs) {
  TRI_string_buffer_t* buffer = TRI_CreateStringBuffer(TRI_UNKNOWN_MEM_ZONE);

  if (!lhs || !rhs) {
    return NULL;
  }
  
  if (TRI_AppendStringStringBuffer(buffer, "(function(){return AHUACATL_RELATIONAL_") != TRI_ERROR_NO_ERROR) {
    TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
    return NULL;
  }

  if (TRI_AppendStringStringBuffer(buffer, name) != TRI_ERROR_NO_ERROR) {
    TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
    return NULL;
  }
  
  if (TRI_AppendStringStringBuffer(buffer, "(") != TRI_ERROR_NO_ERROR) {
    TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
    return NULL;
  }
    
  if (!TRI_NodeJavascriptAql(buffer, lhs)) {
    TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
    return NULL;
  }
      
  if (TRI_AppendCharStringBuffer(buffer, ',') != TRI_ERROR_NO_ERROR) {
    TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
    return NULL;
  }
  
  if (!TRI_NodeJavascriptAql(buffer, rhs)) {
    TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
    return NULL;
  }

  if (TRI_AppendStringStringBuffer(buffer, ");})") != TRI_ERROR_NO_ERROR) {
    TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
    return NULL;
  }

  return buffer;
}
コード例 #5
0
ファイル: ahuacatl-optimiser.c プロジェクト: luxyer/ArangoDB
static TRI_string_buffer_t* FcallCode (const char* const name, 
                                       const TRI_aql_node_t* const args) {
  TRI_string_buffer_t* buffer = TRI_CreateStringBuffer(TRI_UNKNOWN_MEM_ZONE);
  size_t i;
  size_t n;

  if (!buffer) {
    return NULL;
  }
  
  if (TRI_AppendStringStringBuffer(buffer, "(function(){return AHUACATL_FCALL(") != TRI_ERROR_NO_ERROR) {
    TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
    return NULL;
  }
  
  if (TRI_AppendStringStringBuffer(buffer, name) != TRI_ERROR_NO_ERROR) {
    TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
    return NULL;
  }

  if (TRI_AppendStringStringBuffer(buffer, ",[") != TRI_ERROR_NO_ERROR) {
    TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
    return NULL;
  }

  n = args->_members._length;
  for (i = 0; i < n; ++i) {
    TRI_aql_node_t* arg = (TRI_aql_node_t*) args->_members._buffer[i];
    if (i > 0) {
      if (TRI_AppendCharStringBuffer(buffer, ',') != TRI_ERROR_NO_ERROR) {
        TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
        return NULL;
      }
    }

    if (!TRI_NodeJavascriptAql(buffer, arg)) {
      TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
      return NULL;
    }
  }

  if (TRI_AppendStringStringBuffer(buffer, "]);})") != TRI_ERROR_NO_ERROR) {
    TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
    return NULL;
  }

  return buffer;
}
コード例 #6
0
TRI_json_t* TRI_GetJsonCollectionHintAql (TRI_aql_collection_hint_t* const hint) {
  TRI_json_t* result;

  if (hint == NULL) {
    return NULL;
  }

  result = TRI_CreateArrayJson(TRI_UNKNOWN_MEM_ZONE);

  if (result == NULL) {
    return NULL;
  }

  if (hint->_index == NULL) {
    // full table scan
    TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                         result,
                         "accessType",
                         TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, "all"));
  }
  else {
    // index usage
    TRI_index_t* idx = hint->_index->_idx;
    TRI_json_t* indexDescription;

    TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                         result,
                         "accessType",
                         TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, "index"));

    indexDescription = TRI_CreateArrayJson(TRI_UNKNOWN_MEM_ZONE);
    if (indexDescription != NULL) {
      TRI_string_buffer_t* buffer;
      char* idString = GetIndexIdString(hint);

      // index id
      if (idString != NULL) {
        TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                             indexDescription,
                             "id",
                             TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, idString));

        TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, idString);
      }

      // index type
      TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                           indexDescription,
                           "type",
                           TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, idx->typeName(idx)));

      // index attributes
      buffer = TRI_CreateStringBuffer(TRI_UNKNOWN_MEM_ZONE);
      if (buffer != NULL) {
        size_t i;

        for (i = 0; i < idx->_fields._length; i++) {
          if (i > 0) {
            TRI_AppendStringStringBuffer(buffer, ", ");
          }
          TRI_AppendStringStringBuffer(buffer, idx->_fields._buffer[i]);
        }

        TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                             indexDescription,
                             "attributes",
                             TRI_CreateStringCopyJson(TRI_UNKNOWN_MEM_ZONE, buffer->_buffer));

        TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, buffer);
      }

    }

    TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                         result,
                         "index",
                         indexDescription);
  }

  if (hint->_limit._status == TRI_AQL_LIMIT_USE) {
    TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE,
                         result,
                         "limit",
                         TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, (double) hint->_limit._offset + (double) hint->_limit._limit));
  }

  return result;
}
コード例 #7
0
ファイル: ahuacatl-optimiser.c プロジェクト: luxyer/ArangoDB
static TRI_aql_node_t* OptimiseBinaryRelationalOperation (TRI_aql_context_t* const context,
                                                          TRI_aql_node_t* node) {
  TRI_aql_node_t* lhs = TRI_AQL_NODE_MEMBER(node, 0);
  TRI_aql_node_t* rhs = TRI_AQL_NODE_MEMBER(node, 1);
  TRI_js_exec_context_t* execContext;
  TRI_string_buffer_t* code;
  TRI_json_t* json;
  char* func;
  
  if (!lhs || !TRI_IsConstantValueNodeAql(lhs) || !rhs || !TRI_IsConstantValueNodeAql(rhs)) {
    return node;
  } 
  
  if (node->_type == TRI_AQL_NODE_OPERATOR_BINARY_EQ) {
    func = "EQUAL";
  }
  else if (node->_type == TRI_AQL_NODE_OPERATOR_BINARY_NE) {
    func = "UNEQUAL";
  }
  else if (node->_type == TRI_AQL_NODE_OPERATOR_BINARY_GT) {
    func = "GREATER";
  }
  else if (node->_type == TRI_AQL_NODE_OPERATOR_BINARY_GE) {
    func = "GREATEREQUAL";
  }
  else if (node->_type == TRI_AQL_NODE_OPERATOR_BINARY_LT) {
    func = "LESS";
  }
  else if (node->_type == TRI_AQL_NODE_OPERATOR_BINARY_LE) {
    func = "LESSEQUAL";
  }
  else if (node->_type == TRI_AQL_NODE_OPERATOR_BINARY_IN) {
    func = "IN";
  }
  else {
    // not what we expected, however, simply continue
    return node;
  }
  
  code = RelationCode(func, lhs, rhs); 
  if (!code) {
    TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
    return node;
  }
    
  // execute the function code
  execContext = TRI_CreateExecutionContext(code->_buffer);
  TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, code);

  if (!execContext) {
    TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
    return node;
  }

  json = TRI_ExecuteResultContext(execContext);
  TRI_FreeExecutionContext(execContext);
  if (!json) {
    TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_SCRIPT, NULL);
    return NULL;
  }
  
  // use the constant values instead of the function call node
  node = TRI_JsonNodeAql(context, json);
  if (!node) {
    TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
  }
    
  LOG_TRACE("optimised away binary relational operation");

  TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);

  return node;
}
コード例 #8
0
ファイル: ahuacatl-optimiser.c プロジェクト: luxyer/ArangoDB
static TRI_aql_node_t* OptimiseFcall (TRI_aql_context_t* const context,
                                      TRI_aql_node_t* node) {
  TRI_aql_node_t* args = TRI_AQL_NODE_MEMBER(node, 0);
  TRI_aql_function_t* function;
  TRI_js_exec_context_t* execContext;
  TRI_string_buffer_t* code;
  TRI_json_t* json;
  size_t i;
  size_t n;

  function = (TRI_aql_function_t*) TRI_AQL_NODE_DATA(node);
  assert(function);

  // check if function is deterministic
  if (!function->_isDeterministic) {
    return node;
  }

  // check if function call arguments are deterministic
  n = args->_members._length;
  for (i = 0; i < n; ++i) {
    TRI_aql_node_t* arg = (TRI_aql_node_t*) args->_members._buffer[i];

    if (!arg || !TRI_IsConstantValueNodeAql(arg)) {
      return node;
    }
  }
 
  // all arguments are constants
  // create the function code
  code = FcallCode(function->_internalName, args);
  if (!code) {
    TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
    return node;
  }
    
  // execute the function code
  execContext = TRI_CreateExecutionContext(code->_buffer);
  TRI_FreeStringBuffer(TRI_UNKNOWN_MEM_ZONE, code);

  if (!execContext) {
    TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
    return node;
  }

  json = TRI_ExecuteResultContext(execContext);
  TRI_FreeExecutionContext(execContext);
  if (!json) {
    // cannot optimise the function call due to an internal error

    // TODO: check whether we can validate the arguments here already and return an error early
    // TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_SCRIPT, "function optimisation");
    return node;
  }

  // use the constant values instead of the function call node
  node = TRI_JsonNodeAql(context, json);
  if (!node) {
    TRI_SetErrorContextAql(context, TRI_ERROR_OUT_OF_MEMORY, NULL);
  }

  TRI_FreeJson(TRI_UNKNOWN_MEM_ZONE, json);
  
  LOG_TRACE("optimised function call");

  return node;
}