@@ -16,10 +16,23 @@ static void exitHook(int code, Datum arg);
1616
1717void * serializePlanState (FdwPlanState * state );
1818FdwExecState * initializeExecState (void * internalstate );
19+
20+ static void
21+ steampipe_fdw_ProcessUtility (PlannedStmt * pstmt ,
22+ const char * queryString ,
23+ bool readOnlyTree ,
24+ ProcessUtilityContext context ,
25+ ParamListInfo params ,
26+ QueryEnvironment * queryEnv ,
27+ DestReceiver * dest ,
28+ QueryCompletion * qc );
29+
1930// Required by postgres, doing basic checks to ensure compatibility,
2031// such as being compiled against the correct major version.
2132PG_MODULE_MAGIC ;
2233
34+ static ProcessUtility_hook_type next_ProcessUtility_hook = NULL ;
35+
2336// Define the handler function for signal 16
2437void signal_handler (int sig ) {
2538// elog(NOTICE, "Caught signal %d", sig);
@@ -63,6 +76,9 @@ void _PG_init(void)
6376 on_proc_exit (& exitHook , PointerGetDatum (NULL ));
6477 RegisterXactCallback (pgfdw_xact_callback , NULL );
6578
79+ /* Hook ProcessUtility for adding comments to foreign tables */
80+ next_ProcessUtility_hook = ProcessUtility_hook ;
81+ ProcessUtility_hook = steampipe_fdw_ProcessUtility ;
6682}
6783
6884/*
@@ -88,6 +104,65 @@ void exitHook(int code, Datum arg)
88104 goFdwShutdown ();
89105}
90106
107+ static void
108+ steampipe_fdw_ProcessUtility (PlannedStmt * pstmt ,
109+ const char * queryString ,
110+ bool readOnlyTree ,
111+ ProcessUtilityContext context ,
112+ ParamListInfo params ,
113+ QueryEnvironment * queryEnv ,
114+ DestReceiver * dest ,
115+ QueryCompletion * qc ) {
116+ List * cmd_list = NULL ;
117+ if (IsA (pstmt -> utilityStmt , CreateForeignTableStmt ) && context == PROCESS_UTILITY_SUBCOMMAND && dest == None_Receiver ) {
118+ const CreateForeignTableStmt * cstmt = (const CreateForeignTableStmt * )pstmt -> utilityStmt ;
119+ cmd_list = goFdwGetForeignTableComments (cstmt -> servername , cstmt -> base .relation -> schemaname , cstmt -> base .relation -> relname );
120+ }
121+
122+ if (next_ProcessUtility_hook ) {
123+ next_ProcessUtility_hook (pstmt , queryString , readOnlyTree , context , params , queryEnv , dest , qc );
124+ } else {
125+ standard_ProcessUtility (pstmt , queryString , readOnlyTree , context , params , queryEnv , dest , qc );
126+ }
127+
128+ if (cmd_list != NULL ) {
129+ ListCell * lc ;
130+ foreach (lc , cmd_list ) {
131+ char * cmd = (char * )lfirst (lc );
132+ List * raw_parsetree_list = pg_parse_query (cmd );
133+
134+ ListCell * lc2 ;
135+ foreach (lc2 , raw_parsetree_list ) {
136+ RawStmt * rs = lfirst_node (RawStmt , lc2 );
137+ CommentStmt * comment_stmt = (CommentStmt * )rs -> stmt ;
138+
139+ if (!IsA (comment_stmt , CommentStmt )) {
140+ elog (ERROR , "unexpected statement type %d where CommentStmt expected" , (int )nodeTag (comment_stmt ));
141+ }
142+
143+ #if PG_VERSION_NUM < 120000
144+ // Be sure to advance the command counter between subcommands
145+ // Not needed in PG 12+ because standard_ProcessUtility already does this
146+ CommandCounterIncrement ();
147+ #endif
148+
149+ pstmt = makeNode (PlannedStmt );
150+ pstmt -> commandType = CMD_UTILITY ;
151+ pstmt -> canSetTag = false;
152+ pstmt -> utilityStmt = (Node * ) comment_stmt ;
153+ pstmt -> stmt_location = rs -> stmt_location ;
154+ pstmt -> stmt_len = rs -> stmt_len ;
155+
156+ /* Execute statement */
157+ ProcessUtility (pstmt , cmd , false,
158+ PROCESS_UTILITY_SUBCOMMAND , NULL , NULL ,
159+ None_Receiver , NULL );
160+ }
161+ }
162+
163+ }
164+ }
165+
91166static bool fdwIsForeignScanParallelSafe (PlannerInfo * root , RelOptInfo * rel , RangeTblEntry * rte ) {
92167 return getenv ("STEAMPIPE_FDW_PARALLEL_SAFE" ) != NULL ;
93168}
0 commit comments