1 | //===----------------------------------------------------------------------===// |
2 | // DuckDB |
3 | // |
4 | // duckdb/parser/transformer.hpp |
5 | // |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #pragma once |
10 | |
11 | #include "duckdb/common/constants.hpp" |
12 | #include "duckdb/common/enums/expression_type.hpp" |
13 | #include "duckdb/common/types.hpp" |
14 | #include "duckdb/common/unordered_map.hpp" |
15 | #include "duckdb/parser/qualified_name.hpp" |
16 | #include "duckdb/parser/tokens.hpp" |
17 | #include "duckdb/parser/parsed_data/create_info.hpp" |
18 | #include "duckdb/parser/group_by_node.hpp" |
19 | #include "duckdb/parser/query_node.hpp" |
20 | #include "duckdb/common/case_insensitive_map.hpp" |
21 | |
22 | #include "pg_definitions.hpp" |
23 | #include "nodes/parsenodes.hpp" |
24 | #include "nodes/primnodes.hpp" |
25 | |
26 | namespace duckdb { |
27 | |
28 | class ColumnDefinition; |
29 | class StackChecker; |
30 | struct OrderByNode; |
31 | struct CopyInfo; |
32 | struct CommonTableExpressionInfo; |
33 | struct GroupingExpressionMap; |
34 | class OnConflictInfo; |
35 | class UpdateSetInfo; |
36 | struct ParserOptions; |
37 | struct PivotColumn; |
38 | |
39 | //! The transformer class is responsible for transforming the internal Postgres |
40 | //! parser representation into the DuckDB representation |
41 | class Transformer { |
42 | friend class StackChecker; |
43 | |
44 | struct CreatePivotEntry { |
45 | string enum_name; |
46 | unique_ptr<SelectNode> base; |
47 | unique_ptr<ParsedExpression> column; |
48 | unique_ptr<QueryNode> subquery; |
49 | }; |
50 | |
51 | public: |
52 | explicit Transformer(ParserOptions &options); |
53 | explicit Transformer(Transformer &parent); |
54 | ~Transformer(); |
55 | |
56 | //! Transforms a Postgres parse tree into a set of SQL Statements |
57 | bool TransformParseTree(duckdb_libpgquery::PGList *tree, vector<unique_ptr<SQLStatement>> &statements); |
58 | string NodetypeToString(duckdb_libpgquery::PGNodeTag type); |
59 | |
60 | idx_t ParamCount() const; |
61 | |
62 | private: |
63 | optional_ptr<Transformer> parent; |
64 | //! Parser options |
65 | ParserOptions &options; |
66 | //! The current prepared statement parameter index |
67 | idx_t prepared_statement_parameter_index = 0; |
68 | //! Map from named parameter to parameter index; |
69 | case_insensitive_map_t<idx_t> named_param_map; |
70 | //! Holds window expressions defined by name. We need those when transforming the expressions referring to them. |
71 | unordered_map<string, duckdb_libpgquery::PGWindowDef *> window_clauses; |
72 | //! The set of pivot entries to create |
73 | vector<unique_ptr<CreatePivotEntry>> pivot_entries; |
74 | //! Sets of stored CTEs, if any |
75 | vector<CommonTableExpressionMap *> stored_cte_map; |
76 | //! Whether or not we are currently binding a window definition |
77 | bool in_window_definition = false; |
78 | |
79 | void Clear(); |
80 | bool InWindowDefinition(); |
81 | |
82 | Transformer &RootTransformer(); |
83 | const Transformer &RootTransformer() const; |
84 | void SetParamCount(idx_t new_count); |
85 | void SetNamedParam(const string &name, int32_t index); |
86 | bool GetNamedParam(const string &name, int32_t &index); |
87 | bool HasNamedParameters() const; |
88 | |
89 | void AddPivotEntry(string enum_name, unique_ptr<SelectNode> source, unique_ptr<ParsedExpression> column, |
90 | unique_ptr<QueryNode> subquery); |
91 | unique_ptr<SQLStatement> GenerateCreateEnumStmt(unique_ptr<CreatePivotEntry> entry); |
92 | bool HasPivotEntries(); |
93 | idx_t PivotEntryCount(); |
94 | vector<unique_ptr<CreatePivotEntry>> &GetPivotEntries(); |
95 | void PivotEntryCheck(const string &type); |
96 | void (CommonTableExpressionMap &cte_map); |
97 | |
98 | private: |
99 | //! Transforms a Postgres statement into a single SQL statement |
100 | unique_ptr<SQLStatement> TransformStatement(duckdb_libpgquery::PGNode &stmt); |
101 | //! Transforms a Postgres statement into a single SQL statement |
102 | unique_ptr<SQLStatement> TransformStatementInternal(duckdb_libpgquery::PGNode &stmt); |
103 | //===--------------------------------------------------------------------===// |
104 | // Statement transformation |
105 | //===--------------------------------------------------------------------===// |
106 | //! Transform a Postgres duckdb_libpgquery::T_PGSelectStmt node into a SelectStatement |
107 | unique_ptr<SelectStatement> TransformSelect(optional_ptr<duckdb_libpgquery::PGNode> node, bool is_select = true); |
108 | //! Transform a Postgres duckdb_libpgquery::T_PGSelectStmt node into a SelectStatement |
109 | unique_ptr<SelectStatement> TransformSelect(duckdb_libpgquery::PGSelectStmt &select, bool is_select = true); |
110 | //! Transform a Postgres T_AlterStmt node into a AlterStatement |
111 | unique_ptr<AlterStatement> TransformAlter(duckdb_libpgquery::PGAlterTableStmt &stmt); |
112 | //! Transform a Postgres duckdb_libpgquery::T_PGRenameStmt node into a RenameStatement |
113 | unique_ptr<AlterStatement> TransformRename(duckdb_libpgquery::PGRenameStmt &stmt); |
114 | //! Transform a Postgres duckdb_libpgquery::T_PGCreateStmt node into a CreateStatement |
115 | unique_ptr<CreateStatement> TransformCreateTable(duckdb_libpgquery::PGCreateStmt &node); |
116 | //! Transform a Postgres duckdb_libpgquery::T_PGCreateStmt node into a CreateStatement |
117 | unique_ptr<CreateStatement> TransformCreateTableAs(duckdb_libpgquery::PGCreateTableAsStmt &stmt); |
118 | //! Transform a Postgres node into a CreateStatement |
119 | unique_ptr<CreateStatement> TransformCreateSchema(duckdb_libpgquery::PGCreateSchemaStmt &stmt); |
120 | //! Transform a Postgres duckdb_libpgquery::T_PGCreateSeqStmt node into a CreateStatement |
121 | unique_ptr<CreateStatement> TransformCreateSequence(duckdb_libpgquery::PGCreateSeqStmt &node); |
122 | //! Transform a Postgres duckdb_libpgquery::T_PGViewStmt node into a CreateStatement |
123 | unique_ptr<CreateStatement> TransformCreateView(duckdb_libpgquery::PGViewStmt &node); |
124 | //! Transform a Postgres duckdb_libpgquery::T_PGIndexStmt node into CreateStatement |
125 | unique_ptr<CreateStatement> TransformCreateIndex(duckdb_libpgquery::PGIndexStmt &stmt); |
126 | //! Transform a Postgres duckdb_libpgquery::T_PGCreateFunctionStmt node into CreateStatement |
127 | unique_ptr<CreateStatement> TransformCreateFunction(duckdb_libpgquery::PGCreateFunctionStmt &stmt); |
128 | //! Transform a Postgres duckdb_libpgquery::T_PGCreateTypeStmt node into CreateStatement |
129 | unique_ptr<CreateStatement> TransformCreateType(duckdb_libpgquery::PGCreateTypeStmt &stmt); |
130 | //! Transform a Postgres duckdb_libpgquery::T_PGAlterSeqStmt node into CreateStatement |
131 | unique_ptr<AlterStatement> TransformAlterSequence(duckdb_libpgquery::PGAlterSeqStmt &stmt); |
132 | //! Transform a Postgres duckdb_libpgquery::T_PGDropStmt node into a Drop[Table,Schema]Statement |
133 | unique_ptr<SQLStatement> TransformDrop(duckdb_libpgquery::PGDropStmt &stmt); |
134 | //! Transform a Postgres duckdb_libpgquery::T_PGInsertStmt node into a InsertStatement |
135 | unique_ptr<InsertStatement> TransformInsert(duckdb_libpgquery::PGInsertStmt &stmt); |
136 | |
137 | //! Transform a Postgres duckdb_libpgquery::T_PGOnConflictClause node into a OnConflictInfo |
138 | unique_ptr<OnConflictInfo> TransformOnConflictClause(duckdb_libpgquery::PGOnConflictClause *node, |
139 | const string &relname); |
140 | //! Transform a ON CONFLICT shorthand into a OnConflictInfo |
141 | unique_ptr<OnConflictInfo> DummyOnConflictClause(duckdb_libpgquery::PGOnConflictActionAlias type, |
142 | const string &relname); |
143 | //! Transform a Postgres duckdb_libpgquery::T_PGCopyStmt node into a CopyStatement |
144 | unique_ptr<CopyStatement> TransformCopy(duckdb_libpgquery::PGCopyStmt &stmt); |
145 | void TransformCopyOptions(CopyInfo &info, optional_ptr<duckdb_libpgquery::PGList> options); |
146 | //! Transform a Postgres duckdb_libpgquery::T_PGTransactionStmt node into a TransactionStatement |
147 | unique_ptr<TransactionStatement> TransformTransaction(duckdb_libpgquery::PGTransactionStmt &stmt); |
148 | //! Transform a Postgres T_DeleteStatement node into a DeleteStatement |
149 | unique_ptr<DeleteStatement> TransformDelete(duckdb_libpgquery::PGDeleteStmt &stmt); |
150 | //! Transform a Postgres duckdb_libpgquery::T_PGUpdateStmt node into a UpdateStatement |
151 | unique_ptr<UpdateStatement> TransformUpdate(duckdb_libpgquery::PGUpdateStmt &stmt); |
152 | //! Transform a Postgres duckdb_libpgquery::T_PGPragmaStmt node into a PragmaStatement |
153 | unique_ptr<SQLStatement> TransformPragma(duckdb_libpgquery::PGPragmaStmt &stmt); |
154 | //! Transform a Postgres duckdb_libpgquery::T_PGExportStmt node into a ExportStatement |
155 | unique_ptr<ExportStatement> TransformExport(duckdb_libpgquery::PGExportStmt &stmt); |
156 | //! Transform a Postgres duckdb_libpgquery::T_PGImportStmt node into a PragmaStatement |
157 | unique_ptr<PragmaStatement> TransformImport(duckdb_libpgquery::PGImportStmt &stmt); |
158 | unique_ptr<ExplainStatement> TransformExplain(duckdb_libpgquery::PGExplainStmt &stmt); |
159 | unique_ptr<SQLStatement> TransformVacuum(duckdb_libpgquery::PGVacuumStmt &stmt); |
160 | unique_ptr<SQLStatement> TransformShow(duckdb_libpgquery::PGVariableShowStmt &stmt); |
161 | unique_ptr<ShowStatement> TransformShowSelect(duckdb_libpgquery::PGVariableShowSelectStmt &stmt); |
162 | unique_ptr<AttachStatement> TransformAttach(duckdb_libpgquery::PGAttachStmt &stmt); |
163 | unique_ptr<DetachStatement> TransformDetach(duckdb_libpgquery::PGDetachStmt &stmt); |
164 | unique_ptr<SetStatement> TransformUse(duckdb_libpgquery::PGUseStmt &stmt); |
165 | |
166 | unique_ptr<PrepareStatement> TransformPrepare(duckdb_libpgquery::PGPrepareStmt &stmt); |
167 | unique_ptr<ExecuteStatement> TransformExecute(duckdb_libpgquery::PGExecuteStmt &stmt); |
168 | unique_ptr<CallStatement> TransformCall(duckdb_libpgquery::PGCallStmt &stmt); |
169 | unique_ptr<DropStatement> TransformDeallocate(duckdb_libpgquery::PGDeallocateStmt &stmt); |
170 | unique_ptr<QueryNode> TransformPivotStatement(duckdb_libpgquery::PGSelectStmt &select); |
171 | unique_ptr<SQLStatement> CreatePivotStatement(unique_ptr<SQLStatement> statement); |
172 | PivotColumn TransformPivotColumn(duckdb_libpgquery::PGPivot &pivot); |
173 | vector<PivotColumn> TransformPivotList(duckdb_libpgquery::PGList &list); |
174 | |
175 | //===--------------------------------------------------------------------===// |
176 | // SetStatement Transform |
177 | //===--------------------------------------------------------------------===// |
178 | unique_ptr<SetStatement> TransformSet(duckdb_libpgquery::PGVariableSetStmt &set); |
179 | unique_ptr<SetStatement> TransformSetVariable(duckdb_libpgquery::PGVariableSetStmt &stmt); |
180 | unique_ptr<SetStatement> TransformResetVariable(duckdb_libpgquery::PGVariableSetStmt &stmt); |
181 | |
182 | unique_ptr<SQLStatement> TransformCheckpoint(duckdb_libpgquery::PGCheckPointStmt &stmt); |
183 | unique_ptr<LoadStatement> TransformLoad(duckdb_libpgquery::PGLoadStmt &stmt); |
184 | |
185 | //===--------------------------------------------------------------------===// |
186 | // Query Node Transform |
187 | //===--------------------------------------------------------------------===// |
188 | //! Transform a Postgres duckdb_libpgquery::T_PGSelectStmt node into a QueryNode |
189 | unique_ptr<QueryNode> TransformSelectNode(duckdb_libpgquery::PGSelectStmt &select); |
190 | unique_ptr<QueryNode> TransformSelectInternal(duckdb_libpgquery::PGSelectStmt &select); |
191 | void TransformModifiers(duckdb_libpgquery::PGSelectStmt &stmt, QueryNode &node); |
192 | |
193 | //===--------------------------------------------------------------------===// |
194 | // Expression Transform |
195 | //===--------------------------------------------------------------------===// |
196 | //! Transform a Postgres boolean expression into an Expression |
197 | unique_ptr<ParsedExpression> TransformBoolExpr(duckdb_libpgquery::PGBoolExpr &root); |
198 | //! Transform a Postgres case expression into an Expression |
199 | unique_ptr<ParsedExpression> TransformCase(duckdb_libpgquery::PGCaseExpr &root); |
200 | //! Transform a Postgres type cast into an Expression |
201 | unique_ptr<ParsedExpression> TransformTypeCast(duckdb_libpgquery::PGTypeCast &root); |
202 | //! Transform a Postgres coalesce into an Expression |
203 | unique_ptr<ParsedExpression> TransformCoalesce(duckdb_libpgquery::PGAExpr &root); |
204 | //! Transform a Postgres column reference into an Expression |
205 | unique_ptr<ParsedExpression> TransformColumnRef(duckdb_libpgquery::PGColumnRef &root); |
206 | //! Transform a Postgres constant value into an Expression |
207 | unique_ptr<ConstantExpression> TransformValue(duckdb_libpgquery::PGValue val); |
208 | //! Transform a Postgres operator into an Expression |
209 | unique_ptr<ParsedExpression> TransformAExpr(duckdb_libpgquery::PGAExpr &root); |
210 | unique_ptr<ParsedExpression> TransformAExprInternal(duckdb_libpgquery::PGAExpr &root); |
211 | //! Transform a Postgres abstract expression into an Expression |
212 | unique_ptr<ParsedExpression> TransformExpression(optional_ptr<duckdb_libpgquery::PGNode> node); |
213 | unique_ptr<ParsedExpression> TransformExpression(duckdb_libpgquery::PGNode &node); |
214 | //! Transform a Postgres function call into an Expression |
215 | unique_ptr<ParsedExpression> TransformFuncCall(duckdb_libpgquery::PGFuncCall &root); |
216 | //! Transform a Postgres boolean expression into an Expression |
217 | unique_ptr<ParsedExpression> TransformInterval(duckdb_libpgquery::PGIntervalConstant &root); |
218 | //! Transform a Postgres lambda node [e.g. (x, y) -> x + y] into a lambda expression |
219 | unique_ptr<ParsedExpression> TransformLambda(duckdb_libpgquery::PGLambdaFunction &node); |
220 | //! Transform a Postgres array access node (e.g. x[1] or x[1:3]) |
221 | unique_ptr<ParsedExpression> TransformArrayAccess(duckdb_libpgquery::PGAIndirection &node); |
222 | //! Transform a positional reference (e.g. #1) |
223 | unique_ptr<ParsedExpression> TransformPositionalReference(duckdb_libpgquery::PGPositionalReference &node); |
224 | unique_ptr<ParsedExpression> TransformStarExpression(duckdb_libpgquery::PGAStar &node); |
225 | unique_ptr<ParsedExpression> TransformBooleanTest(duckdb_libpgquery::PGBooleanTest &node); |
226 | |
227 | //! Transform a Postgres constant value into an Expression |
228 | unique_ptr<ParsedExpression> TransformConstant(duckdb_libpgquery::PGAConst &c); |
229 | unique_ptr<ParsedExpression> TransformGroupingFunction(duckdb_libpgquery::PGGroupingFunc &n); |
230 | unique_ptr<ParsedExpression> TransformResTarget(duckdb_libpgquery::PGResTarget &root); |
231 | unique_ptr<ParsedExpression> TransformNullTest(duckdb_libpgquery::PGNullTest &root); |
232 | unique_ptr<ParsedExpression> TransformParamRef(duckdb_libpgquery::PGParamRef &node); |
233 | unique_ptr<ParsedExpression> TransformNamedArg(duckdb_libpgquery::PGNamedArgExpr &root); |
234 | |
235 | unique_ptr<ParsedExpression> TransformSQLValueFunction(duckdb_libpgquery::PGSQLValueFunction &node); |
236 | |
237 | unique_ptr<ParsedExpression> TransformSubquery(duckdb_libpgquery::PGSubLink &root); |
238 | //===--------------------------------------------------------------------===// |
239 | // Constraints transform |
240 | //===--------------------------------------------------------------------===// |
241 | unique_ptr<Constraint> TransformConstraint(duckdb_libpgquery::PGListCell *cell); |
242 | |
243 | unique_ptr<Constraint> TransformConstraint(duckdb_libpgquery::PGListCell *cell, ColumnDefinition &column, |
244 | idx_t index); |
245 | |
246 | //===--------------------------------------------------------------------===// |
247 | // Update transform |
248 | //===--------------------------------------------------------------------===// |
249 | unique_ptr<UpdateSetInfo> TransformUpdateSetInfo(duckdb_libpgquery::PGList *target_list, |
250 | duckdb_libpgquery::PGNode *where_clause); |
251 | |
252 | //===--------------------------------------------------------------------===// |
253 | // Index transform |
254 | //===--------------------------------------------------------------------===// |
255 | vector<unique_ptr<ParsedExpression>> TransformIndexParameters(duckdb_libpgquery::PGList &list, |
256 | const string &relation_name); |
257 | |
258 | //===--------------------------------------------------------------------===// |
259 | // Collation transform |
260 | //===--------------------------------------------------------------------===// |
261 | unique_ptr<ParsedExpression> TransformCollateExpr(duckdb_libpgquery::PGCollateClause &collate); |
262 | |
263 | string TransformCollation(optional_ptr<duckdb_libpgquery::PGCollateClause> collate); |
264 | |
265 | ColumnDefinition TransformColumnDefinition(duckdb_libpgquery::PGColumnDef &cdef); |
266 | //===--------------------------------------------------------------------===// |
267 | // Helpers |
268 | //===--------------------------------------------------------------------===// |
269 | OnCreateConflict TransformOnConflict(duckdb_libpgquery::PGOnCreateConflict conflict); |
270 | string TransformAlias(duckdb_libpgquery::PGAlias *root, vector<string> &column_name_alias); |
271 | vector<string> TransformStringList(duckdb_libpgquery::PGList *list); |
272 | void TransformCTE(duckdb_libpgquery::PGWithClause &de_with_clause, CommonTableExpressionMap &cte_map); |
273 | unique_ptr<SelectStatement> TransformRecursiveCTE(duckdb_libpgquery::PGCommonTableExpr &cte, |
274 | CommonTableExpressionInfo &info); |
275 | |
276 | unique_ptr<ParsedExpression> TransformUnaryOperator(const string &op, unique_ptr<ParsedExpression> child); |
277 | unique_ptr<ParsedExpression> TransformBinaryOperator(string op, unique_ptr<ParsedExpression> left, |
278 | unique_ptr<ParsedExpression> right); |
279 | //===--------------------------------------------------------------------===// |
280 | // TableRef transform |
281 | //===--------------------------------------------------------------------===// |
282 | //! Transform a Postgres node into a TableRef |
283 | unique_ptr<TableRef> TransformTableRefNode(duckdb_libpgquery::PGNode &n); |
284 | //! Transform a Postgres FROM clause into a TableRef |
285 | unique_ptr<TableRef> TransformFrom(optional_ptr<duckdb_libpgquery::PGList> root); |
286 | //! Transform a Postgres table reference into a TableRef |
287 | unique_ptr<TableRef> TransformRangeVar(duckdb_libpgquery::PGRangeVar &root); |
288 | //! Transform a Postgres table-producing function into a TableRef |
289 | unique_ptr<TableRef> TransformRangeFunction(duckdb_libpgquery::PGRangeFunction &root); |
290 | //! Transform a Postgres join node into a TableRef |
291 | unique_ptr<TableRef> TransformJoin(duckdb_libpgquery::PGJoinExpr &root); |
292 | //! Transform a Postgres pivot node into a TableRef |
293 | unique_ptr<TableRef> TransformPivot(duckdb_libpgquery::PGPivotExpr &root); |
294 | //! Transform a table producing subquery into a TableRef |
295 | unique_ptr<TableRef> TransformRangeSubselect(duckdb_libpgquery::PGRangeSubselect &root); |
296 | //! Transform a VALUES list into a set of expressions |
297 | unique_ptr<TableRef> TransformValuesList(duckdb_libpgquery::PGList *list); |
298 | |
299 | //! Transform a range var into a (schema) qualified name |
300 | QualifiedName TransformQualifiedName(duckdb_libpgquery::PGRangeVar &root); |
301 | |
302 | //! Transform a Postgres TypeName string into a LogicalType |
303 | LogicalType TransformTypeName(duckdb_libpgquery::PGTypeName &name); |
304 | |
305 | //! Transform a Postgres GROUP BY expression into a list of Expression |
306 | bool TransformGroupBy(optional_ptr<duckdb_libpgquery::PGList> group, SelectNode &result); |
307 | void TransformGroupByNode(duckdb_libpgquery::PGNode &n, GroupingExpressionMap &map, SelectNode &result, |
308 | vector<GroupingSet> &result_sets); |
309 | void AddGroupByExpression(unique_ptr<ParsedExpression> expression, GroupingExpressionMap &map, GroupByNode &result, |
310 | vector<idx_t> &result_set); |
311 | void TransformGroupByExpression(duckdb_libpgquery::PGNode &n, GroupingExpressionMap &map, GroupByNode &result, |
312 | vector<idx_t> &result_set); |
313 | //! Transform a Postgres ORDER BY expression into an OrderByDescription |
314 | bool TransformOrderBy(duckdb_libpgquery::PGList *order, vector<OrderByNode> &result); |
315 | |
316 | //! Transform a Postgres SELECT clause into a list of Expressions |
317 | void TransformExpressionList(duckdb_libpgquery::PGList &list, vector<unique_ptr<ParsedExpression>> &result); |
318 | |
319 | //! Transform a Postgres PARTITION BY/ORDER BY specification into lists of expressions |
320 | void TransformWindowDef(duckdb_libpgquery::PGWindowDef &window_spec, WindowExpression &expr, |
321 | const char *window_name = nullptr); |
322 | //! Transform a Postgres window frame specification into frame expressions |
323 | void TransformWindowFrame(duckdb_libpgquery::PGWindowDef &window_spec, WindowExpression &expr); |
324 | |
325 | unique_ptr<SampleOptions> TransformSampleOptions(optional_ptr<duckdb_libpgquery::PGNode> options); |
326 | //! Returns true if an expression is only a star (i.e. "*", without any other decorators) |
327 | bool ExpressionIsEmptyStar(ParsedExpression &expr); |
328 | |
329 | OnEntryNotFound TransformOnEntryNotFound(bool missing_ok); |
330 | |
331 | Vector PGListToVector(optional_ptr<duckdb_libpgquery::PGList> column_list, idx_t &size); |
332 | vector<string> TransformConflictTarget(duckdb_libpgquery::PGList &list); |
333 | |
334 | private: |
335 | //! Current stack depth |
336 | idx_t stack_depth; |
337 | |
338 | void InitializeStackCheck(); |
339 | StackChecker StackCheck(idx_t = 1); |
340 | |
341 | public: |
342 | template <class T> |
343 | static T &PGCast(duckdb_libpgquery::PGNode &node) { |
344 | return reinterpret_cast<T &>(node); |
345 | } |
346 | template <class T> |
347 | static optional_ptr<T> PGPointerCast(void *ptr) { |
348 | return optional_ptr<T>(reinterpret_cast<T *>(ptr)); |
349 | } |
350 | }; |
351 | |
352 | class StackChecker { |
353 | public: |
354 | StackChecker(Transformer &transformer, idx_t stack_usage); |
355 | ~StackChecker(); |
356 | StackChecker(StackChecker &&) noexcept; |
357 | StackChecker(const StackChecker &) = delete; |
358 | |
359 | private: |
360 | Transformer &transformer; |
361 | idx_t stack_usage; |
362 | }; |
363 | |
364 | vector<string> ReadPgListToString(duckdb_libpgquery::PGList *column_list); |
365 | |
366 | } // namespace duckdb |
367 | |