
/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * 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.
 */

#include "src/trace_processor/sqlite/db_sqlite_table.h"

#include "test/gtest_and_gmock.h"

namespace perfetto {
namespace trace_processor {
namespace {

Table::Schema CreateSchema() {
  Table::Schema schema;
  schema.columns.push_back({"id", SqlValue::Type::kLong, true /* is_id */,
                            true /* is_sorted */, false /* is_hidden */,
                            false /* is_set_id */});
  schema.columns.push_back({"type", SqlValue::Type::kLong, false /* is_id */,
                            false /* is_sorted */, false /* is_hidden */,
                            false /* is_set_id */});
  schema.columns.push_back({"test1", SqlValue::Type::kLong, false /* is_id */,
                            true /* is_sorted */, false /* is_hidden */,
                            false /* is_set_id */});
  schema.columns.push_back({"test2", SqlValue::Type::kLong, false /* is_id */,
                            false /* is_sorted */, false /* is_hidden */,
                            false /* is_set_id */});
  schema.columns.push_back({"test3", SqlValue::Type::kLong, false /* is_id */,
                            false /* is_sorted */, false /* is_hidden */,
                            false /* is_set_id */});
  return schema;
}

TEST(DbSqliteTable, IdEqCheaperThanOtherEq) {
  auto schema = CreateSchema();
  constexpr uint32_t kRowCount = 1234;

  QueryConstraints id_eq;
  id_eq.AddConstraint(0u, SQLITE_INDEX_CONSTRAINT_EQ, 0u);

  auto id_cost = DbSqliteTable::EstimateCost(schema, kRowCount, id_eq);

  QueryConstraints a_eq;
  a_eq.AddConstraint(1u, SQLITE_INDEX_CONSTRAINT_EQ, 1u);

  auto a_cost = DbSqliteTable::EstimateCost(schema, kRowCount, a_eq);

  ASSERT_LT(id_cost.cost, a_cost.cost);
  ASSERT_LT(id_cost.rows, a_cost.rows);
}

TEST(DbSqliteTable, IdEqCheaperThatOtherConstraint) {
  auto schema = CreateSchema();
  constexpr uint32_t kRowCount = 1234;

  QueryConstraints id_eq;
  id_eq.AddConstraint(0u, SQLITE_INDEX_CONSTRAINT_EQ, 0u);

  auto id_cost = DbSqliteTable::EstimateCost(schema, kRowCount, id_eq);

  QueryConstraints a_eq;
  a_eq.AddConstraint(1u, SQLITE_INDEX_CONSTRAINT_LT, 1u);

  auto a_cost = DbSqliteTable::EstimateCost(schema, kRowCount, a_eq);

  ASSERT_LT(id_cost.cost, a_cost.cost);
  ASSERT_LT(id_cost.rows, a_cost.rows);
}

TEST(DbSqliteTable, SingleEqCheaperThanMultipleConstraint) {
  auto schema = CreateSchema();
  constexpr uint32_t kRowCount = 1234;

  QueryConstraints single_eq;
  single_eq.AddConstraint(1u, SQLITE_INDEX_CONSTRAINT_EQ, 0u);

  auto single_cost = DbSqliteTable::EstimateCost(schema, kRowCount, single_eq);

  QueryConstraints multi_eq;
  multi_eq.AddConstraint(1u, SQLITE_INDEX_CONSTRAINT_EQ, 0u);
  multi_eq.AddConstraint(2u, SQLITE_INDEX_CONSTRAINT_EQ, 1u);

  auto multi_cost = DbSqliteTable::EstimateCost(schema, kRowCount, multi_eq);

  // The cost of the single filter should be cheaper (because of our special
  // handling of single equality). But the number of rows should be greater.
  ASSERT_LT(single_cost.cost, multi_cost.cost);
  ASSERT_GT(single_cost.rows, multi_cost.rows);
}

TEST(DbSqliteTable, MultiSortedEqCheaperThanMultiUnsortedEq) {
  auto schema = CreateSchema();
  constexpr uint32_t kRowCount = 1234;

  QueryConstraints sorted_eq;
  sorted_eq.AddConstraint(2u, SQLITE_INDEX_CONSTRAINT_EQ, 0u);
  sorted_eq.AddConstraint(3u, SQLITE_INDEX_CONSTRAINT_EQ, 0u);

  auto sorted_cost = DbSqliteTable::EstimateCost(schema, kRowCount, sorted_eq);

  QueryConstraints unsorted_eq;
  unsorted_eq.AddConstraint(3u, SQLITE_INDEX_CONSTRAINT_EQ, 0u);
  unsorted_eq.AddConstraint(4u, SQLITE_INDEX_CONSTRAINT_EQ, 0u);

  auto unsorted_cost =
      DbSqliteTable::EstimateCost(schema, kRowCount, unsorted_eq);

  // The number of rows should be the same but the cost of the sorted
  // query should be less.
  ASSERT_LT(sorted_cost.cost, unsorted_cost.cost);
  ASSERT_EQ(sorted_cost.rows, unsorted_cost.rows);
}

TEST(DbSqliteTable, EmptyTableCosting) {
  auto schema = CreateSchema();

  QueryConstraints id_eq;
  id_eq.AddConstraint(0u, SQLITE_INDEX_CONSTRAINT_EQ, 0u);

  auto id_cost = DbSqliteTable::EstimateCost(schema, 0, id_eq);

  QueryConstraints a_eq;
  a_eq.AddConstraint(1u, SQLITE_INDEX_CONSTRAINT_LT, 1u);

  auto a_cost = DbSqliteTable::EstimateCost(schema, 0, a_eq);

  ASSERT_DOUBLE_EQ(id_cost.cost, a_cost.cost);
  ASSERT_EQ(id_cost.rows, a_cost.rows);
}

TEST(DbSqliteTable, OrderByOnSortedCheaper) {
  auto schema = CreateSchema();
  constexpr uint32_t kRowCount = 1234;

  QueryConstraints a_qc;
  a_qc.AddOrderBy(1u, false);

  auto a_cost = DbSqliteTable::EstimateCost(schema, kRowCount, a_qc);

  // On an ordered column, the constraint for sorting would get pruned so
  // we would end up with an empty constraint set.
  QueryConstraints sorted_qc;
  auto sorted_cost = DbSqliteTable::EstimateCost(schema, kRowCount, sorted_qc);

  ASSERT_LT(sorted_cost.cost, a_cost.cost);
  ASSERT_EQ(sorted_cost.rows, a_cost.rows);
}

}  // namespace
}  // namespace trace_processor
}  // namespace perfetto
