Skip to content

Commit 6f3e6e3

Browse files
committed
fix: unify PostgreSQL reviewed node cases
1 parent 1d127af commit 6f3e6e3

3 files changed

Lines changed: 140 additions & 98 deletions

File tree

tests/pg_compat/statement_type_cases.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ void test_grant_and_revoke_mappings() {
222222
}
223223

224224
void test_oracle_node_names() {
225-
const NameCase cases[] = {
225+
constexpr NameCase cases[] = {
226226
{PG_QUERY__NODE__NODE_SELECT_STMT, "PG_QUERY__NODE__NODE_SELECT_STMT"},
227227
{PG_QUERY__NODE__NODE_INSERT_STMT, "PG_QUERY__NODE__NODE_INSERT_STMT"},
228228
{PG_QUERY__NODE__NODE_UPDATE_STMT, "PG_QUERY__NODE__NODE_UPDATE_STMT"},
@@ -271,6 +271,10 @@ void test_oracle_node_names() {
271271
{PG_QUERY__NODE__NODE_GRANT_ROLE_STMT, "PG_QUERY__NODE__NODE_GRANT_ROLE_STMT"},
272272
};
273273

274+
constexpr std::size_t case_count = sizeof(cases) / sizeof(cases[0]);
275+
static_assert(case_count == 46);
276+
assert(case_count == pg_compat::reviewed_node_case_count());
277+
274278
for (const auto& test_case : cases) {
275279
const char* actual = pg_compat::oracle_node_name(test_case.node_case);
276280
assert(std::strcmp(actual, "UNMAPPED_NODE_CASE") != 0);

tools/pg_compat/statement_type_map.cpp

Lines changed: 132 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -2,123 +2,158 @@
22

33
namespace pg_compat {
44

5-
#define PG_COMPAT_SIMPLE_STATEMENT_TYPE_MAPPINGS(X) \
6-
X(PG_QUERY__NODE__NODE_SELECT_STMT, Equivalent, SELECT) \
7-
X(PG_QUERY__NODE__NODE_INSERT_STMT, Equivalent, INSERT) \
8-
X(PG_QUERY__NODE__NODE_UPDATE_STMT, Equivalent, UPDATE) \
9-
X(PG_QUERY__NODE__NODE_DELETE_STMT, Equivalent, DELETE_STMT) \
10-
X(PG_QUERY__NODE__NODE_VARIABLE_SET_STMT, Equivalent, SET) \
11-
X(PG_QUERY__NODE__NODE_VARIABLE_SHOW_STMT, Equivalent, SHOW) \
12-
X(PG_QUERY__NODE__NODE_PREPARE_STMT, Equivalent, PREPARE) \
13-
X(PG_QUERY__NODE__NODE_EXECUTE_STMT, Equivalent, EXECUTE) \
14-
X(PG_QUERY__NODE__NODE_DEALLOCATE_STMT, Equivalent, DEALLOCATE) \
15-
X(PG_QUERY__NODE__NODE_EXPLAIN_STMT, Equivalent, EXPLAIN) \
16-
X(PG_QUERY__NODE__NODE_CALL_STMT, Equivalent, CALL) \
17-
X(PG_QUERY__NODE__NODE_DO_STMT, Equivalent, DO_STMT) \
18-
X(PG_QUERY__NODE__NODE_TRUNCATE_STMT, Equivalent, TRUNCATE) \
19-
X(PG_QUERY__NODE__NODE_LOCK_STMT, Equivalent, LOCK) \
20-
X(PG_QUERY__NODE__NODE_CREATE_STMT, Equivalent, CREATE) \
21-
X(PG_QUERY__NODE__NODE_CREATE_SCHEMA_STMT, Equivalent, CREATE) \
22-
X(PG_QUERY__NODE__NODE_CREATE_TABLE_AS_STMT, Equivalent, CREATE) \
23-
X(PG_QUERY__NODE__NODE_INDEX_STMT, Equivalent, CREATE) \
24-
X(PG_QUERY__NODE__NODE_CREATE_FUNCTION_STMT, Equivalent, CREATE) \
25-
X(PG_QUERY__NODE__NODE_CREATE_ROLE_STMT, Equivalent, CREATE) \
26-
X(PG_QUERY__NODE__NODE_CREATE_SEQ_STMT, Equivalent, CREATE) \
27-
X(PG_QUERY__NODE__NODE_CREATE_DOMAIN_STMT, Equivalent, CREATE) \
28-
X(PG_QUERY__NODE__NODE_CREATE_ENUM_STMT, Equivalent, CREATE) \
29-
X(PG_QUERY__NODE__NODE_CREATE_RANGE_STMT, Equivalent, CREATE) \
30-
X(PG_QUERY__NODE__NODE_CREATEDB_STMT, Equivalent, CREATE) \
31-
X(PG_QUERY__NODE__NODE_ALTER_TABLE_STMT, Equivalent, ALTER) \
32-
X(PG_QUERY__NODE__NODE_ALTER_FUNCTION_STMT, Equivalent, ALTER) \
33-
X(PG_QUERY__NODE__NODE_ALTER_ROLE_STMT, Equivalent, ALTER) \
34-
X(PG_QUERY__NODE__NODE_ALTER_SEQ_STMT, Equivalent, ALTER) \
35-
X(PG_QUERY__NODE__NODE_ALTER_DOMAIN_STMT, Equivalent, ALTER) \
36-
X(PG_QUERY__NODE__NODE_ALTER_ENUM_STMT, Equivalent, ALTER) \
37-
X(PG_QUERY__NODE__NODE_ALTER_DATABASE_STMT, Equivalent, ALTER) \
38-
X(PG_QUERY__NODE__NODE_RENAME_STMT, Equivalent, ALTER) \
39-
X(PG_QUERY__NODE__NODE_DROP_STMT, Equivalent, DROP) \
40-
X(PG_QUERY__NODE__NODE_DROPDB_STMT, Equivalent, DROP) \
41-
X(PG_QUERY__NODE__NODE_DROP_ROLE_STMT, Equivalent, DROP) \
42-
X(PG_QUERY__NODE__NODE_DROP_TABLE_SPACE_STMT, Equivalent, DROP) \
43-
X(PG_QUERY__NODE__NODE_COPY_STMT, NoEquivalent, UNKNOWN) \
44-
X(PG_QUERY__NODE__NODE_MERGE_STMT, NoEquivalent, UNKNOWN) \
45-
X(PG_QUERY__NODE__NODE_VACUUM_STMT, NoEquivalent, UNKNOWN) \
46-
X(PG_QUERY__NODE__NODE_NOTIFY_STMT, NoEquivalent, UNKNOWN) \
47-
X(PG_QUERY__NODE__NODE_LISTEN_STMT, NoEquivalent, UNKNOWN) \
48-
X(PG_QUERY__NODE__NODE_UNLISTEN_STMT, NoEquivalent, UNKNOWN)
5+
#define PG_COMPAT_REVIEWED_NODE_CASES(SIMPLE, PAYLOAD) \
6+
SIMPLE(PG_QUERY__NODE__NODE_SELECT_STMT, Equivalent, SELECT) \
7+
SIMPLE(PG_QUERY__NODE__NODE_INSERT_STMT, Equivalent, INSERT) \
8+
SIMPLE(PG_QUERY__NODE__NODE_UPDATE_STMT, Equivalent, UPDATE) \
9+
SIMPLE(PG_QUERY__NODE__NODE_DELETE_STMT, Equivalent, DELETE_STMT) \
10+
SIMPLE(PG_QUERY__NODE__NODE_VARIABLE_SET_STMT, Equivalent, SET) \
11+
SIMPLE(PG_QUERY__NODE__NODE_VARIABLE_SHOW_STMT, Equivalent, SHOW) \
12+
SIMPLE(PG_QUERY__NODE__NODE_PREPARE_STMT, Equivalent, PREPARE) \
13+
SIMPLE(PG_QUERY__NODE__NODE_EXECUTE_STMT, Equivalent, EXECUTE) \
14+
SIMPLE(PG_QUERY__NODE__NODE_DEALLOCATE_STMT, Equivalent, DEALLOCATE) \
15+
SIMPLE(PG_QUERY__NODE__NODE_EXPLAIN_STMT, Equivalent, EXPLAIN) \
16+
SIMPLE(PG_QUERY__NODE__NODE_CALL_STMT, Equivalent, CALL) \
17+
SIMPLE(PG_QUERY__NODE__NODE_DO_STMT, Equivalent, DO_STMT) \
18+
SIMPLE(PG_QUERY__NODE__NODE_TRUNCATE_STMT, Equivalent, TRUNCATE) \
19+
SIMPLE(PG_QUERY__NODE__NODE_LOCK_STMT, Equivalent, LOCK) \
20+
SIMPLE(PG_QUERY__NODE__NODE_CREATE_STMT, Equivalent, CREATE) \
21+
SIMPLE(PG_QUERY__NODE__NODE_CREATE_SCHEMA_STMT, Equivalent, CREATE) \
22+
SIMPLE(PG_QUERY__NODE__NODE_CREATE_TABLE_AS_STMT, Equivalent, CREATE) \
23+
SIMPLE(PG_QUERY__NODE__NODE_INDEX_STMT, Equivalent, CREATE) \
24+
SIMPLE(PG_QUERY__NODE__NODE_CREATE_FUNCTION_STMT, Equivalent, CREATE) \
25+
SIMPLE(PG_QUERY__NODE__NODE_CREATE_ROLE_STMT, Equivalent, CREATE) \
26+
SIMPLE(PG_QUERY__NODE__NODE_CREATE_SEQ_STMT, Equivalent, CREATE) \
27+
SIMPLE(PG_QUERY__NODE__NODE_CREATE_DOMAIN_STMT, Equivalent, CREATE) \
28+
SIMPLE(PG_QUERY__NODE__NODE_CREATE_ENUM_STMT, Equivalent, CREATE) \
29+
SIMPLE(PG_QUERY__NODE__NODE_CREATE_RANGE_STMT, Equivalent, CREATE) \
30+
SIMPLE(PG_QUERY__NODE__NODE_CREATEDB_STMT, Equivalent, CREATE) \
31+
SIMPLE(PG_QUERY__NODE__NODE_ALTER_TABLE_STMT, Equivalent, ALTER) \
32+
SIMPLE(PG_QUERY__NODE__NODE_ALTER_FUNCTION_STMT, Equivalent, ALTER) \
33+
SIMPLE(PG_QUERY__NODE__NODE_ALTER_ROLE_STMT, Equivalent, ALTER) \
34+
SIMPLE(PG_QUERY__NODE__NODE_ALTER_SEQ_STMT, Equivalent, ALTER) \
35+
SIMPLE(PG_QUERY__NODE__NODE_ALTER_DOMAIN_STMT, Equivalent, ALTER) \
36+
SIMPLE(PG_QUERY__NODE__NODE_ALTER_ENUM_STMT, Equivalent, ALTER) \
37+
SIMPLE(PG_QUERY__NODE__NODE_ALTER_DATABASE_STMT, Equivalent, ALTER) \
38+
SIMPLE(PG_QUERY__NODE__NODE_RENAME_STMT, Equivalent, ALTER) \
39+
SIMPLE(PG_QUERY__NODE__NODE_DROP_STMT, Equivalent, DROP) \
40+
SIMPLE(PG_QUERY__NODE__NODE_DROPDB_STMT, Equivalent, DROP) \
41+
SIMPLE(PG_QUERY__NODE__NODE_DROP_ROLE_STMT, Equivalent, DROP) \
42+
SIMPLE(PG_QUERY__NODE__NODE_DROP_TABLE_SPACE_STMT, Equivalent, DROP) \
43+
SIMPLE(PG_QUERY__NODE__NODE_COPY_STMT, NoEquivalent, UNKNOWN) \
44+
SIMPLE(PG_QUERY__NODE__NODE_MERGE_STMT, NoEquivalent, UNKNOWN) \
45+
SIMPLE(PG_QUERY__NODE__NODE_VACUUM_STMT, NoEquivalent, UNKNOWN) \
46+
SIMPLE(PG_QUERY__NODE__NODE_NOTIFY_STMT, NoEquivalent, UNKNOWN) \
47+
SIMPLE(PG_QUERY__NODE__NODE_LISTEN_STMT, NoEquivalent, UNKNOWN) \
48+
SIMPLE(PG_QUERY__NODE__NODE_UNLISTEN_STMT, NoEquivalent, UNKNOWN) \
49+
PAYLOAD(PG_QUERY__NODE__NODE_TRANSACTION_STMT, map_transaction_stmt) \
50+
PAYLOAD(PG_QUERY__NODE__NODE_GRANT_STMT, map_grant_stmt) \
51+
PAYLOAD(PG_QUERY__NODE__NODE_GRANT_ROLE_STMT, map_grant_role_stmt)
52+
53+
namespace {
54+
55+
StatementTypeMapping map_transaction_stmt(const PgQuery__Node& node) {
56+
using sql_parser::StmtType;
57+
58+
if (node.transaction_stmt == nullptr) {
59+
return {};
60+
}
61+
switch (node.transaction_stmt->kind) {
62+
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_BEGIN:
63+
return {MappingKind::Equivalent, StmtType::BEGIN};
64+
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_START:
65+
return {MappingKind::Equivalent, StmtType::START_TRANSACTION};
66+
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_COMMIT:
67+
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_COMMIT_PREPARED:
68+
return {MappingKind::Equivalent, StmtType::COMMIT};
69+
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_ROLLBACK:
70+
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_ROLLBACK_TO:
71+
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_ROLLBACK_PREPARED:
72+
return {MappingKind::Equivalent, StmtType::ROLLBACK};
73+
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_SAVEPOINT:
74+
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_RELEASE:
75+
return {MappingKind::Equivalent, StmtType::SAVEPOINT};
76+
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_PREPARE:
77+
return {MappingKind::Equivalent, StmtType::PREPARE};
78+
default:
79+
return {};
80+
}
81+
}
82+
83+
StatementTypeMapping map_grant_stmt(const PgQuery__Node& node) {
84+
using sql_parser::StmtType;
85+
86+
if (node.grant_stmt == nullptr) {
87+
return {};
88+
}
89+
return {
90+
MappingKind::Equivalent,
91+
node.grant_stmt->is_grant ? StmtType::GRANT : StmtType::REVOKE,
92+
};
93+
}
94+
95+
StatementTypeMapping map_grant_role_stmt(const PgQuery__Node& node) {
96+
using sql_parser::StmtType;
97+
98+
if (node.grant_role_stmt == nullptr) {
99+
return {};
100+
}
101+
return {
102+
MappingKind::Equivalent,
103+
node.grant_role_stmt->is_grant ? StmtType::GRANT : StmtType::REVOKE,
104+
};
105+
}
106+
107+
} // namespace
49108

50109
StatementTypeMapping expected_stmt_type(const PgQuery__Node& node) {
51110
using sql_parser::StmtType;
52111

53112
switch (node.node_case) {
54-
#define PG_COMPAT_MAPPING_CASE(node_case, mapping_kind, stmt_type) \
113+
#define PG_COMPAT_SIMPLE_MAPPING_CASE(node_case, mapping_kind, stmt_type) \
55114
case node_case: \
56115
return {MappingKind::mapping_kind, StmtType::stmt_type};
57-
PG_COMPAT_SIMPLE_STATEMENT_TYPE_MAPPINGS(PG_COMPAT_MAPPING_CASE)
58-
#undef PG_COMPAT_MAPPING_CASE
59-
case PG_QUERY__NODE__NODE_TRANSACTION_STMT:
60-
if (node.transaction_stmt == nullptr) {
61-
return {};
62-
}
63-
switch (node.transaction_stmt->kind) {
64-
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_BEGIN:
65-
return {MappingKind::Equivalent, StmtType::BEGIN};
66-
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_START:
67-
return {MappingKind::Equivalent, StmtType::START_TRANSACTION};
68-
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_COMMIT:
69-
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_COMMIT_PREPARED:
70-
return {MappingKind::Equivalent, StmtType::COMMIT};
71-
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_ROLLBACK:
72-
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_ROLLBACK_TO:
73-
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_ROLLBACK_PREPARED:
74-
return {MappingKind::Equivalent, StmtType::ROLLBACK};
75-
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_SAVEPOINT:
76-
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_RELEASE:
77-
return {MappingKind::Equivalent, StmtType::SAVEPOINT};
78-
case PG_QUERY__TRANSACTION_STMT_KIND__TRANS_STMT_PREPARE:
79-
return {MappingKind::Equivalent, StmtType::PREPARE};
80-
default:
81-
return {};
82-
}
83-
case PG_QUERY__NODE__NODE_GRANT_STMT:
84-
if (node.grant_stmt == nullptr) {
85-
return {};
86-
}
87-
return {
88-
MappingKind::Equivalent,
89-
node.grant_stmt->is_grant ? StmtType::GRANT : StmtType::REVOKE,
90-
};
91-
case PG_QUERY__NODE__NODE_GRANT_ROLE_STMT:
92-
if (node.grant_role_stmt == nullptr) {
93-
return {};
94-
}
95-
return {
96-
MappingKind::Equivalent,
97-
node.grant_role_stmt->is_grant ? StmtType::GRANT : StmtType::REVOKE,
98-
};
116+
#define PG_COMPAT_PAYLOAD_MAPPING_CASE(node_case, helper) \
117+
case node_case: \
118+
return helper(node);
119+
PG_COMPAT_REVIEWED_NODE_CASES(
120+
PG_COMPAT_SIMPLE_MAPPING_CASE,
121+
PG_COMPAT_PAYLOAD_MAPPING_CASE)
122+
#undef PG_COMPAT_PAYLOAD_MAPPING_CASE
123+
#undef PG_COMPAT_SIMPLE_MAPPING_CASE
99124
default:
100125
return {};
101126
}
102127
}
103128

104129
const char* oracle_node_name(PgQuery__Node__NodeCase node_case) {
105130
switch (node_case) {
106-
#define PG_COMPAT_NODE_NAME_CASE(node_case, mapping_kind, stmt_type) \
131+
#define PG_COMPAT_SIMPLE_NODE_NAME_CASE(node_case, mapping_kind, stmt_type) \
107132
case node_case: \
108133
return #node_case;
109-
PG_COMPAT_SIMPLE_STATEMENT_TYPE_MAPPINGS(PG_COMPAT_NODE_NAME_CASE)
110-
#undef PG_COMPAT_NODE_NAME_CASE
111-
case PG_QUERY__NODE__NODE_TRANSACTION_STMT:
112-
return "PG_QUERY__NODE__NODE_TRANSACTION_STMT";
113-
case PG_QUERY__NODE__NODE_GRANT_STMT:
114-
return "PG_QUERY__NODE__NODE_GRANT_STMT";
115-
case PG_QUERY__NODE__NODE_GRANT_ROLE_STMT:
116-
return "PG_QUERY__NODE__NODE_GRANT_ROLE_STMT";
134+
#define PG_COMPAT_PAYLOAD_NODE_NAME_CASE(node_case, helper) \
135+
case node_case: \
136+
return #node_case;
137+
PG_COMPAT_REVIEWED_NODE_CASES(
138+
PG_COMPAT_SIMPLE_NODE_NAME_CASE,
139+
PG_COMPAT_PAYLOAD_NODE_NAME_CASE)
140+
#undef PG_COMPAT_PAYLOAD_NODE_NAME_CASE
141+
#undef PG_COMPAT_SIMPLE_NODE_NAME_CASE
117142
default:
118143
return "UNMAPPED_NODE_CASE";
119144
}
120145
}
121146

147+
std::size_t reviewed_node_case_count() {
148+
#define PG_COMPAT_SIMPLE_NODE_COUNT(node_case, mapping_kind, stmt_type) + 1
149+
#define PG_COMPAT_PAYLOAD_NODE_COUNT(node_case, helper) + 1
150+
return 0 PG_COMPAT_REVIEWED_NODE_CASES(
151+
PG_COMPAT_SIMPLE_NODE_COUNT,
152+
PG_COMPAT_PAYLOAD_NODE_COUNT);
153+
#undef PG_COMPAT_PAYLOAD_NODE_COUNT
154+
#undef PG_COMPAT_SIMPLE_NODE_COUNT
155+
}
156+
122157
const char* stmt_type_name(sql_parser::StmtType type) {
123158
using sql_parser::StmtType;
124159

@@ -197,6 +232,6 @@ const char* stmt_type_name(sql_parser::StmtType type) {
197232
return "OTHER";
198233
}
199234

200-
#undef PG_COMPAT_SIMPLE_STATEMENT_TYPE_MAPPINGS
235+
#undef PG_COMPAT_REVIEWED_NODE_CASES
201236

202237
} // namespace pg_compat

tools/pg_compat/statement_type_map.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
#include "protobuf/pg_query.pb-c.h"
77

8+
#include <cstddef>
9+
810
namespace pg_compat {
911

1012
enum class MappingKind {
@@ -20,6 +22,7 @@ struct StatementTypeMapping {
2022

2123
StatementTypeMapping expected_stmt_type(const PgQuery__Node& node);
2224
const char* oracle_node_name(PgQuery__Node__NodeCase node_case);
25+
std::size_t reviewed_node_case_count();
2326
const char* stmt_type_name(sql_parser::StmtType type);
2427

2528
} // namespace pg_compat

0 commit comments

Comments
 (0)