Line data Source code
1 : #include "backend/engine/duckdb/transpiler/node_dispositions.h"
2 :
3 : #include <set>
4 :
5 : #include "absl/strings/string_view.h"
6 : #include "backend/engine/disposition.h"
7 : #include "gtest/gtest.h"
8 :
9 : namespace bigquery_emulator {
10 : namespace backend {
11 : namespace engine {
12 : namespace duckdb {
13 : namespace transpiler {
14 : namespace {
15 :
16 1 : TEST(NodeDispositionTableTest, LookupReturnsExpectedRows) {
17 1 : const auto* query_stmt = LookupNodeDisposition("ResolvedQueryStmt");
18 1 : ASSERT_NE(query_stmt, nullptr);
19 1 : EXPECT_EQ(query_stmt->disposition, Disposition::kDuckdbNative);
20 1 : EXPECT_FALSE(query_stmt->planned);
21 :
22 1 : const auto* explain_stmt = LookupNodeDisposition("ResolvedExplainStmt");
23 1 : ASSERT_NE(explain_stmt, nullptr);
24 1 : EXPECT_EQ(explain_stmt->disposition, Disposition::kUnsupported);
25 :
26 1 : const auto* make_struct = LookupNodeDisposition("ResolvedMakeStruct");
27 1 : ASSERT_NE(make_struct, nullptr);
28 1 : EXPECT_EQ(make_struct->disposition, Disposition::kDuckdbRewrite);
29 :
30 1 : const auto* create_table = LookupNodeDisposition("ResolvedCreateTableStmt");
31 1 : ASSERT_NE(create_table, nullptr);
32 1 : EXPECT_EQ(create_table->disposition, Disposition::kControlOp);
33 1 : EXPECT_FALSE(create_table->planned);
34 1 : }
35 :
36 1 : TEST(NodeDispositionTableTest, LookupUnknownReturnsNull) {
37 1 : EXPECT_EQ(LookupNodeDisposition("ResolvedTotallyMadeUpNode"), nullptr);
38 1 : EXPECT_EQ(LookupNodeDisposition("resolvedquerystmt"), nullptr);
39 1 : }
40 :
41 1 : TEST(NodeDispositionTableTest, EveryNodeApplicableDispositionIsReachable) {
42 1 : const std::set<Disposition> kNodeApplicable = {
43 1 : Disposition::kDuckdbNative,
44 1 : Disposition::kDuckdbRewrite,
45 1 : Disposition::kSemanticExecutor,
46 1 : Disposition::kControlOp,
47 1 : Disposition::kLocalStub,
48 1 : Disposition::kUnsupported,
49 1 : };
50 1 : std::set<Disposition> seen;
51 117 : for (const auto& view : internal::AllNodeDispositions()) {
52 117 : ASSERT_NE(view.entry, nullptr);
53 117 : seen.insert(view.entry->disposition);
54 117 : }
55 6 : for (Disposition d : kNodeApplicable) {
56 6 : SCOPED_TRACE(DispositionToString(d));
57 12 : EXPECT_NE(seen.find(d), seen.end())
58 12 : << "node_dispositions.yaml is missing a row for this disposition";
59 6 : }
60 2 : EXPECT_EQ(seen.find(Disposition::kDuckdbUdf), seen.end())
61 2 : << "kDuckdbUdf is per-function, not per-node-kind; tested via "
62 2 : "functions.yaml LookupPlannedDuckdbUdfFunction instead";
63 1 : }
64 :
65 1 : TEST(NodeDispositionTableTest, UnsupportedAndLocalStubRowsExist) {
66 1 : int unsupported_rows = 0;
67 1 : int local_stub_rows = 0;
68 117 : for (const auto& view : internal::AllNodeDispositions()) {
69 117 : ASSERT_NE(view.entry, nullptr);
70 117 : if (view.entry->disposition == Disposition::kUnsupported) {
71 29 : unsupported_rows++;
72 29 : }
73 117 : if (view.entry->disposition == Disposition::kLocalStub) {
74 4 : local_stub_rows++;
75 4 : }
76 117 : }
77 1 : EXPECT_GT(unsupported_rows, 0);
78 1 : EXPECT_GT(local_stub_rows, 0);
79 1 : }
80 :
81 1 : TEST(NodeDispositionTableTest, RegistryNonTrivial) {
82 2 : EXPECT_GT(internal::AllNodeDispositions().size(), 50u)
83 2 : << "node_dispositions.yaml should cover every SHAPE_TRACKER.md "
84 2 : "row (~80 entries today)";
85 1 : }
86 :
87 : } // namespace
88 : } // namespace transpiler
89 : } // namespace duckdb
90 : } // namespace engine
91 : } // namespace backend
92 : } // namespace bigquery_emulator
|