Files
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

478 lines
19 KiB
C++

// Copyright (c) Advanced Micro Devices, Inc.
// SPDX-License-Identifier: MIT
#include "query_common.hpp"
#include "select/table_select_query.hpp"
#include <gtest/gtest.h>
#include <string>
namespace
{
using namespace profiler_hub::queries::select;
using profiler_hub::queries::sort_order;
class table_select_query_test : public ::testing::Test
{
protected:
table_select_query m_query;
};
TEST_F(table_select_query_test, simple_select_all)
{
auto query_string = m_query.select_all().from("users").get_query_string();
EXPECT_EQ(query_string, "SELECT * FROM users");
}
TEST_F(table_select_query_test, select_specific_columns)
{
auto query_string =
m_query.select("id", "name", "email").from("users").get_query_string();
EXPECT_EQ(query_string, "SELECT id, name, email FROM users");
}
TEST_F(table_select_query_test, select_with_table_alias)
{
auto query_string =
m_query.select("u.id", "u.name").from("users", "u").get_query_string();
EXPECT_EQ(query_string, "SELECT u.id, u.name FROM users u");
}
TEST_F(table_select_query_test, select_distinct)
{
auto query_string =
m_query.distinct().select("name").from("users").get_query_string();
EXPECT_EQ(query_string, "SELECT DISTINCT name FROM users");
}
TEST_F(table_select_query_test, select_with_where)
{
auto query_string =
m_query.select("id", "name").from("users").where("active = ?").get_query_string();
EXPECT_EQ(query_string, "SELECT id, name FROM users WHERE active = ?");
}
TEST_F(table_select_query_test, select_with_multiple_where_conditions)
{
auto query_string = m_query.select("id", "name")
.from("users")
.where("active = ?")
.and_where("age > ?")
.or_where("role = ?")
.get_query_string();
EXPECT_EQ(query_string,
"SELECT id, name FROM users WHERE active = ? AND age > ? OR role = ?");
}
TEST_F(table_select_query_test, select_with_inner_join)
{
auto query_string = m_query.select("u.id", "o.total")
.from("users", "u")
.inner_join("orders", "o", "u.id = o.user_id")
.get_query_string();
EXPECT_EQ(
query_string,
"SELECT u.id, o.total FROM users u INNER JOIN orders AS o ON u.id = o.user_id");
}
TEST_F(table_select_query_test, select_with_left_join)
{
auto query_string = m_query.select("users.id", "orders.total")
.from("users")
.left_join("orders", "users.id = orders.user_id")
.get_query_string();
EXPECT_EQ(query_string,
"SELECT users.id, orders.total FROM users LEFT JOIN orders ON users.id = "
"orders.user_id");
}
TEST_F(table_select_query_test, select_with_right_join_and_alias)
{
auto query_string = m_query.select("u.id", "o.total")
.from("users", "u")
.right_join("orders", "o", "u.id = o.user_id")
.get_query_string();
EXPECT_EQ(
query_string,
"SELECT u.id, o.total FROM users u RIGHT JOIN orders AS o ON u.id = o.user_id");
}
TEST_F(table_select_query_test, select_with_order_by)
{
auto query_string = m_query.select("id", "name")
.from("users")
.order_by("name", sort_order::ascending)
.get_query_string();
EXPECT_EQ(query_string, "SELECT id, name FROM users ORDER BY name ASC");
}
TEST_F(table_select_query_test, select_with_order_by_desc)
{
auto query_string = m_query.select("id", "created_at")
.from("users")
.order_by("created_at", sort_order::descending)
.get_query_string();
EXPECT_EQ(query_string, "SELECT id, created_at FROM users ORDER BY created_at DESC");
}
TEST_F(table_select_query_test, select_with_multiple_order_by)
{
auto query_string = m_query.select("id", "name", "age")
.from("users")
.order_by("name", sort_order::ascending)
.order_by("age", sort_order::descending)
.get_query_string();
EXPECT_EQ(query_string,
"SELECT id, name, age FROM users ORDER BY name ASC, age DESC");
}
TEST_F(table_select_query_test, select_with_limit)
{
auto query_string =
m_query.select("id", "name").from("users").limit(10).get_query_string();
EXPECT_EQ(query_string, "SELECT id, name FROM users LIMIT 10");
}
TEST_F(table_select_query_test, select_with_limit_and_offset)
{
auto query_string = m_query.select("id", "name")
.from("users")
.limit(10)
.offset(20)
.get_query_string();
EXPECT_EQ(query_string, "SELECT id, name FROM users LIMIT 10 OFFSET 20");
}
TEST_F(table_select_query_test, select_with_group_by)
{
auto query_string = m_query.select("customer_id", "COUNT(*)")
.from("orders")
.group_by("customer_id")
.get_query_string();
EXPECT_EQ(query_string,
"SELECT customer_id, COUNT(*) FROM orders GROUP BY customer_id");
}
TEST_F(table_select_query_test, select_with_group_by_and_having)
{
auto query_string = m_query.select("customer_id", "COUNT(*)")
.from("orders")
.group_by("customer_id")
.having("COUNT(*) > ?")
.get_query_string();
EXPECT_EQ(query_string,
"SELECT customer_id, COUNT(*) FROM orders GROUP BY customer_id HAVING "
"COUNT(*) > ?");
}
TEST_F(table_select_query_test, complex_query)
{
auto query_string = m_query.select("u.id", "u.name", "COUNT(o.id)")
.from("users", "u")
.left_join("orders", "o", "u.id = o.user_id")
.where("u.active = ?")
.group_by("u.id", "u.name")
.having("COUNT(o.id) > ?")
.order_by("u.name", sort_order::ascending)
.limit(100)
.get_query_string();
EXPECT_EQ(query_string,
"SELECT u.id, u.name, COUNT(o.id) FROM users u"
" LEFT JOIN orders AS o ON u.id = o.user_id"
" WHERE u.active = ?"
" GROUP BY u.id, u.name"
" HAVING COUNT(o.id) > ?"
" ORDER BY u.name ASC"
" LIMIT 100");
}
TEST_F(table_select_query_test, reuse_query_builder)
{
auto query1 = m_query.select("id").from("users").get_query_string();
auto query2 = m_query.select("id", "total")
.from("orders")
.where("total > ?")
.get_query_string();
EXPECT_EQ(query1, "SELECT id FROM users");
EXPECT_EQ(query2, "SELECT id, total FROM orders WHERE total > ?");
}
TEST_F(table_select_query_test, select_all_with_where_and_limit)
{
auto query_string = m_query.select_all()
.from("products")
.where("price > ?")
.limit(50)
.get_query_string();
EXPECT_EQ(query_string, "SELECT * FROM products WHERE price > ? LIMIT 50");
}
TEST_F(table_select_query_test, select_distinct_with_order_by_and_limit)
{
auto query_string = m_query.distinct()
.select("name")
.from("categories")
.order_by("name", sort_order::ascending)
.limit(100)
.get_query_string();
EXPECT_EQ(query_string,
"SELECT DISTINCT name FROM categories ORDER BY name ASC LIMIT 100");
}
TEST_F(table_select_query_test, multiple_joins)
{
auto query_string = m_query.select("o.id", "c.name", "p.title")
.from("orders", "o")
.inner_join("customers", "c", "o.customer_id = c.id")
.left_join("products", "p", "o.product_id = p.id")
.get_query_string();
EXPECT_EQ(query_string,
"SELECT o.id, c.name, p.title FROM orders o"
" INNER JOIN customers AS c ON o.customer_id = c.id"
" LEFT JOIN products AS p ON o.product_id = p.id");
}
TEST_F(table_select_query_test, multiple_joins_with_where)
{
auto query_string = m_query.select("o.id", "c.name", "p.title", "o.total")
.from("orders", "o")
.inner_join("customers", "c", "o.customer_id = c.id")
.left_join("products", "p", "o.product_id = p.id")
.where("o.status = ?")
.and_where("o.total > ?")
.get_query_string();
EXPECT_EQ(query_string,
"SELECT o.id, c.name, p.title, o.total FROM orders o"
" INNER JOIN customers AS c ON o.customer_id = c.id"
" LEFT JOIN products AS p ON o.product_id = p.id"
" WHERE o.status = ? AND o.total > ?");
}
TEST_F(table_select_query_test, join_with_group_by_having_order_limit)
{
auto query_string = m_query.select("s.product_id", "p.name", "SUM(s.amount)")
.from("sales", "s")
.inner_join("products", "p", "s.product_id = p.id")
.group_by("s.product_id", "p.name")
.having("SUM(s.amount) > ?")
.order_by("SUM(s.amount)", sort_order::descending)
.limit(10)
.get_query_string();
EXPECT_EQ(query_string,
"SELECT s.product_id, p.name, SUM(s.amount) FROM sales s"
" INNER JOIN products AS p ON s.product_id = p.id"
" GROUP BY s.product_id, p.name"
" HAVING SUM(s.amount) > ?"
" ORDER BY SUM(s.amount) DESC"
" LIMIT 10");
}
TEST_F(table_select_query_test, distinct_with_join_and_where)
{
auto query_string = m_query.distinct()
.select("c.country")
.from("orders", "o")
.left_join("customers", "c", "o.customer_id = c.id")
.where("o.year = ?")
.get_query_string();
EXPECT_EQ(query_string,
"SELECT DISTINCT c.country FROM orders o"
" LEFT JOIN customers AS c ON o.customer_id = c.id"
" WHERE o.year = ?");
}
TEST_F(table_select_query_test, where_with_or_conditions_and_order_by)
{
auto query_string = m_query.select("id", "name", "role")
.from("users")
.where("role = ?")
.or_where("role = ?")
.or_where("role = ?")
.order_by("name", sort_order::ascending)
.get_query_string();
EXPECT_EQ(query_string,
"SELECT id, name, role FROM users"
" WHERE role = ? OR role = ? OR role = ?"
" ORDER BY name ASC");
}
TEST_F(table_select_query_test, group_by_multiple_columns_with_having)
{
auto query_string = m_query.select("region", "product", "SUM(quantity)")
.from("sales")
.group_by("region", "product")
.having("SUM(quantity) >= ?")
.get_query_string();
EXPECT_EQ(query_string,
"SELECT region, product, SUM(quantity) FROM sales"
" GROUP BY region, product"
" HAVING SUM(quantity) >= ?");
}
TEST_F(table_select_query_test, offset_without_order_by)
{
auto query_string = m_query.select("id", "message", "timestamp")
.from("logs")
.limit(100)
.offset(500)
.get_query_string();
EXPECT_EQ(query_string,
"SELECT id, message, timestamp FROM logs LIMIT 100 OFFSET 500");
}
TEST_F(table_select_query_test, multiple_order_by_with_limit_offset)
{
auto query_string = m_query.select("id", "name", "department", "salary")
.from("employees")
.order_by("department", sort_order::ascending)
.order_by("salary", sort_order::descending)
.order_by("name", sort_order::ascending)
.limit(25)
.offset(50)
.get_query_string();
EXPECT_EQ(query_string,
"SELECT id, name, department, salary FROM employees"
" ORDER BY department ASC, salary DESC, name ASC"
" LIMIT 25 OFFSET 50");
}
TEST_F(table_select_query_test, full_query_all_clauses)
{
auto query_string = m_query.distinct()
.select("t.account_id", "a.name", "SUM(t.amount)", "COUNT(*)")
.from("transactions", "t")
.inner_join("accounts", "a", "t.account_id = a.id")
.left_join("account_types", "at", "a.type_id = at.id")
.where("t.date >= ?")
.and_where("t.date <= ?")
.and_where("at.category = ?")
.group_by("t.account_id", "a.name")
.having("SUM(t.amount) > ?")
.having("COUNT(*) >= ?")
.order_by("SUM(t.amount)", sort_order::descending)
.order_by("a.name", sort_order::ascending)
.limit(100)
.offset(0)
.get_query_string();
EXPECT_EQ(query_string,
"SELECT DISTINCT t.account_id, a.name, SUM(t.amount), COUNT(*)"
" FROM transactions t"
" INNER JOIN accounts AS a ON t.account_id = a.id"
" LEFT JOIN account_types AS at ON a.type_id = at.id"
" WHERE t.date >= ? AND t.date <= ? AND at.category = ?"
" GROUP BY t.account_id, a.name"
" HAVING SUM(t.amount) > ?"
" HAVING COUNT(*) >= ?"
" ORDER BY SUM(t.amount) DESC, a.name ASC"
" LIMIT 100 OFFSET 0");
}
TEST_F(table_select_query_test, join_without_alias)
{
auto query_string = m_query.select("users.id", "users.name", "orders.total")
.from("users")
.inner_join("orders", "users.id = orders.user_id")
.get_query_string();
EXPECT_EQ(query_string,
"SELECT users.id, users.name, orders.total FROM users"
" INNER JOIN orders ON users.id = orders.user_id");
}
TEST_F(table_select_query_test, right_join_full_query)
{
auto query_string = m_query.select("d.name", "COUNT(e.id)")
.from("departments", "d")
.right_join("employees", "e", "d.id = e.department_id")
.group_by("d.name")
.order_by("COUNT(e.id)", sort_order::descending)
.get_query_string();
EXPECT_EQ(query_string,
"SELECT d.name, COUNT(e.id) FROM departments d"
" RIGHT JOIN employees AS e ON d.id = e.department_id"
" GROUP BY d.name"
" ORDER BY COUNT(e.id) DESC");
}
TEST_F(table_select_query_test, skip_optional_clauses_where_directly_to_order)
{
auto query_string = m_query.select("id", "name", "price")
.from("products")
.order_by("price", sort_order::ascending)
.limit(10)
.get_query_string();
EXPECT_EQ(query_string,
"SELECT id, name, price FROM products ORDER BY price ASC LIMIT 10");
}
TEST_F(table_select_query_test, skip_optional_clauses_where_directly_to_limit)
{
auto query_string =
m_query.select("id", "name").from("events").limit(5).get_query_string();
EXPECT_EQ(query_string, "SELECT id, name FROM events LIMIT 5");
}
TEST_F(table_select_query_test, having_without_group_by)
{
// Note: This is semantically invalid SQL but syntactically allowed by builder
auto query_string = m_query.select("category", "total")
.from("stats")
.having("total > ?")
.get_query_string();
EXPECT_EQ(query_string, "SELECT category, total FROM stats HAVING total > ?");
}
TEST_F(table_select_query_test, kernel_dispatch_timeline_event_query)
{
auto query_string =
m_query.select("K.id", "K.start", "K.end", "E.category_id", "KS.display_name")
.from("rocpd_kernel_dispatch", "K")
.inner_join("rocpd_event", "E", "E.id = event_id")
.inner_join("rocpd_info_kernel_symbol", "KS", "KS.id = kernel_id")
.get_query_string();
EXPECT_EQ(
query_string,
"SELECT K.id, K.start, K.end, E.category_id, KS.display_name FROM "
"rocpd_kernel_dispatch K INNER JOIN rocpd_event AS E ON E.id = event_id INNER "
"JOIN rocpd_info_kernel_symbol AS KS ON KS.id = kernel_id");
}
TEST_F(table_select_query_test, query_reusability)
{
auto query_builder = m_query.select("id", "name").from("users");
EXPECT_EQ(query_builder.get_query_string(), "SELECT id, name FROM users");
auto query1 = query_builder.where("age > ?").get_query_string();
EXPECT_EQ(query1, "SELECT id, name FROM users WHERE age > ?");
auto query2 = query_builder.where("name LIKE '?'").get_query_string();
EXPECT_EQ(query2, "SELECT id, name FROM users WHERE name LIKE '?'");
}
TEST_F(table_select_query_test, query_reusability_with_join)
{
auto query_builder = m_query.select("id", "name")
.from("users")
.inner_join("orders", "users.id = orders.user_id");
EXPECT_EQ(
query_builder.get_query_string(),
"SELECT id, name FROM users INNER JOIN orders ON users.id = orders.user_id");
auto query1 = query_builder.where("age > ?").get_query_string();
EXPECT_EQ(query1,
"SELECT id, name FROM users INNER JOIN orders ON users.id = orders.user_id "
"WHERE age > ?");
auto query2 = query_builder.where("name LIKE '?'").get_query_string();
EXPECT_EQ(query2,
"SELECT id, name FROM users INNER JOIN orders ON users.id = orders.user_id "
"WHERE name LIKE '?'");
}
} // namespace