Beispiel #1
0
ResultType TrafficCop::ExecuteStatement(
    const std::string &query, std::vector<StatementResult> &result,
    std::vector<FieldInfo> &tuple_descriptor, int &rows_changed,
    std::string &error_message,
    const size_t thread_id UNUSED_ATTRIBUTE) {
  LOG_TRACE("Received %s", query.c_str());

  // Prepare the statement
  std::string unnamed_statement = "unnamed";
  auto statement = PrepareStatement(unnamed_statement, query, error_message);

  if (statement.get() == nullptr) {
    return ResultType::FAILURE;
  }

  // Then, execute the statement
  bool unnamed = true;
  std::vector<int> result_format(statement->GetTupleDescriptor().size(), 0);
  std::vector<type::Value> params;
  auto status =
      ExecuteStatement(statement, params, unnamed, nullptr, result_format,
                       result, rows_changed, error_message, thread_id);

  if (status == ResultType::SUCCESS) {
    LOG_TRACE("Execution succeeded!");
    tuple_descriptor = std::move(statement->GetTupleDescriptor());
  } else {
    LOG_TRACE("Execution failed!");
  }

  return status;
}
void StatsTestsUtil::ShowTable(std::string database_name,
                               std::string table_name) {
  catalog::Catalog::GetInstance()->GetTableWithName(database_name, table_name);
  std::unique_ptr<Statement> statement;
  auto &peloton_parser = parser::Parser::GetInstance();
  std::vector<common::Value> params;
  std::vector<ResultType> result;
  std::string sql = "SELECT * FROM " + database_name + "." + table_name;
  statement.reset(new Statement("SELECT", sql));
  auto select_stmt = peloton_parser.BuildParseTree(sql);
  statement->SetPlanTree(
      optimizer::SimpleOptimizer::BuildPelotonPlanTree(select_stmt));
  bridge::PlanExecutor::PrintPlan(statement->GetPlanTree().get(), "Plan");
  std::vector<int> result_format(statement->GetTupleDescriptor().size(), 0);
  bridge::PlanExecutor::ExecutePlan(statement->GetPlanTree().get(), params,
                                    result, result_format);
}
Beispiel #3
0
// The Simple Query Protocol
// Fix mis-split bug: Previously, this function assumes there are multiple
// queries in the string and split it by ';', which would cause one containing
// ';' being split into multiple queries.
// However, the multi-statement queries has been split by the psql client and
// there is no need to split the query again.
void PacketManager::ExecQueryMessage(InputPacket *pkt, const size_t thread_id) {
  std::string query;
  PacketGetString(pkt, pkt->len, query);

  // pop out the last character if it is ';'
  if (query.back() == ';') {
    query.pop_back();
  }
  boost::trim(query);

  if (!query.empty()) {
    std::vector<StatementResult> result;
    std::vector<FieldInfo> tuple_descriptor;
    std::string error_message;
    int rows_affected = 0;

    std::string query_type_string_;
    Statement::ParseQueryTypeString(query, query_type_string_);

    QueryType query_type;
    Statement::MapToQueryType(query_type_string_, query_type);
    std::stringstream stream(query_type_string_);

    switch (query_type) {
      case QueryType::QUERY_PREPARE:
      {
        std::string statement_name;
        stream >> statement_name;
        std::size_t pos = query.find("AS");
        std::string statement_query = query.substr(pos + 3);
        boost::trim(statement_query);

        // Prepare statement
        std::shared_ptr<Statement> statement(nullptr);

        LOG_DEBUG("PrepareStatement[%s] => %s", statement_name.c_str(),
                statement_query.c_str());

        statement = traffic_cop_->PrepareStatement(statement_name, statement_query,
                                                 error_message);
        if (statement.get() == nullptr) {
          skipped_stmt_ = true;
          SendErrorResponse(
              {{NetworkMessageType::HUMAN_READABLE_ERROR, error_message}});
          LOG_TRACE("ExecQuery Error");
          return;
        }

        auto entry = std::make_pair(statement_name, statement);
        statement_cache_.insert(entry);
        for (auto table_id : statement->GetReferencedTables()) {
          table_statement_cache_[table_id].push_back(statement.get());
        }
        break;
      }
      case QueryType::QUERY_EXECUTE:
      {
        std::string statement_name;
        std::shared_ptr<Statement> statement;
        std::vector<type::Value> param_values;
        bool unnamed = false;
        std::vector<std::string> tokens;

        boost::split(tokens, query, boost::is_any_of("(), "));

        statement_name = tokens.at(1);
        auto statement_cache_itr = statement_cache_.find(statement_name);
        if (statement_cache_itr != statement_cache_.end()) {
          statement = *statement_cache_itr;
        }
        // Did not find statement with same name
        else {
          std::string error_message = "The prepared statement does not exist";
          LOG_ERROR("%s", error_message.c_str());
          SendErrorResponse(
              {{NetworkMessageType::HUMAN_READABLE_ERROR, error_message}});
          SendReadyForQuery(NetworkTransactionStateType::IDLE);
          return;
        }

        std::vector<int> result_format(statement->GetTupleDescriptor().size(), 0);

        for (std::size_t idx = 2; idx < tokens.size(); idx++) {
          std::string param_str = tokens.at(idx);
          boost::trim(param_str);
          if (param_str.empty()) {
            continue;
          }
          param_values.push_back(type::ValueFactory::GetVarcharValue(param_str));
        }

        if (param_values.size() > 0) {
          statement->GetPlanTree()->SetParameterValues(&param_values);
        }

        auto status =
                traffic_cop_->ExecuteStatement(statement, param_values, unnamed, nullptr, result_format,
                             result, rows_affected, error_message, thread_id);

        if (status == ResultType::SUCCESS) {
          tuple_descriptor = statement->GetTupleDescriptor();
        } else {
          SendErrorResponse(
                {{NetworkMessageType::HUMAN_READABLE_ERROR, error_message}});
          SendReadyForQuery(NetworkTransactionStateType::IDLE);
          return;
        }
      	break;
      }
      default:
      {
        // execute the query using tcop
        auto status = traffic_cop_->ExecuteStatement(
            query, result, tuple_descriptor, rows_affected, error_message,
            thread_id);

      // check status
        if (status == ResultType::FAILURE) {
          SendErrorResponse(
            {{NetworkMessageType::HUMAN_READABLE_ERROR, error_message}});
          SendReadyForQuery(NetworkTransactionStateType::IDLE);
          return;
        }
      }
    }

    // send the attribute names
    PutTupleDescriptor(tuple_descriptor);

    // send the result rows
    SendDataRows(result, tuple_descriptor.size(), rows_affected);

    // The response to the SimpleQueryCommand is the query string.
    CompleteCommand(query, query_type, rows_affected);
  } else {
Beispiel #4
0
/**
 * @return true on success, false otherwise.
 */
bool CopyExecutor::DExecute() {
  // skip if we're done
  if (done) {
    return false;
  }

  while (children_[0]->Execute() == true) {
    // Get input a tile
    std::unique_ptr<LogicalTile> logical_tile(children_[0]->GetOutput());
    LOG_DEBUG("Looping over the output tile..");

    // Get physical schema of the tile
    std::unique_ptr<catalog::Schema> output_schema(
        logical_tile->GetPhysicalSchema());

    // vectors for prepared statement parameters
    int num_params = 0;
    std::vector<std::pair<type::TypeId, std::string>> bind_parameters;
    std::vector<type::Value> param_values;
    std::vector<int16_t> formats;
    std::vector<int32_t> types;

    // Construct result format as varchar
    auto col_count = output_schema->GetColumnCount();
    std::vector<std::vector<std::string>> answer_tuples;
    std::vector<int> result_format(col_count, 0);
    answer_tuples =
        logical_tile->GetAllValuesAsStrings(result_format, true);

    // Loop over the returned results
    for (auto &tuple : answer_tuples) {
      // Loop over the columns
      for (unsigned int col_index = 0; col_index < col_count; col_index++) {
        auto val = tuple[col_index];
        auto origin_col_id =
            logical_tile->GetColumnInfo(col_index).origin_column_id;
        int len = val.length();

        if (origin_col_id == num_param_col_id) {
          // num_param column
          num_params = std::stoi(val);
          Copy(val.c_str(), val.length(), false);

        } else if (origin_col_id == param_type_col_id) {
          // param_types column
          PELOTON_ASSERT(output_schema->GetColumn(col_index).GetType() ==
                    type::TypeId::VARBINARY);

          network::InputPacket packet(len, val);

          // Read param types
          types.resize(num_params);
          //TODO: Instead of passing packet to executor, some data structure more generic is need
          network::PostgresProtocolHandler::ReadParamType(&packet, num_params, types);

          // Write all the types to output file
          for (int i = 0; i < num_params; i++) {
            std::string type_str = std::to_string(types[i]);
            Copy(type_str.c_str(), type_str.length(), false);
          }
        } else if (origin_col_id == param_format_col_id) {
          // param_formats column
          PELOTON_ASSERT(output_schema->GetColumn(col_index).GetType() ==
                    type::TypeId::VARBINARY);

          network::InputPacket packet(len, val);

          // Read param formats
          formats.resize(num_params);
          //TODO: Instead of passing packet to executor, some data structure more generic is need
          network::PostgresProtocolHandler::ReadParamFormat(&packet, num_params, formats);

        } else if (origin_col_id == param_val_col_id) {
          // param_values column
          PELOTON_ASSERT(output_schema->GetColumn(col_index).GetType() ==
                    type::TypeId::VARBINARY);

          network::InputPacket packet(len, val);
          bind_parameters.resize(num_params);
          param_values.resize(num_params);
          //TODO: Instead of passing packet to executor, some data structure more generic is need
          network::PostgresProtocolHandler::ReadParamValue(&packet, num_params, types,
                                              bind_parameters, param_values,
                                              formats);

          // Write all the values to output file
          for (int i = 0; i < num_params; i++) {
            auto param_value = param_values[i];
            LOG_TRACE("param_value.GetTypeId(): %s",
                      TypeIdToString(param_value.GetTypeId()).c_str());
            // Avoid extra copy for varlen types
            if (param_value.GetTypeId() == type::TypeId::VARBINARY) {
              const char *data = param_value.GetData();
              Copy(data, param_value.GetLength(), false);
            } else if (param_value.GetTypeId() == type::TypeId::VARCHAR) {
              const char *data = param_value.GetData();
              // Don't write the NULL character for varchar
              Copy(data, param_value.GetLength() - 1, false);
            } else {
              // Convert integer / double types to string before copying
              auto param_str = param_value.ToString();
              Copy(param_str.c_str(), param_str.length(), false);
            }
          }
        } else {
          // For other columns, just copy the content to local buffer
          bool end_of_line = col_index == col_count - 1;
          Copy(val.c_str(), val.length(), end_of_line);
        }
      }
    }
    LOG_DEBUG("Done writing to csv file for this tile");
  }
  LOG_INFO("Done copying all logical tiles");
  FlushBuffer();
  FFlushFsync();
  // Sync and close
  fclose(file_handle_.file);

  done = true;
  return true;
}