Check if the query string represents a pure SELECT statement (not CTAS, INSERT, etc.)
| 1215 | |
| 1216 | // Check if the query string represents a pure SELECT statement (not CTAS, INSERT, etc.) |
| 1217 | static bool is_pure_select_statement(const char* query_string) |
| 1218 | { |
| 1219 | if (query_string == nullptr) { |
| 1220 | return false; |
| 1221 | } |
| 1222 | |
| 1223 | // Use PG_TRY to catch parse errors from invalid SQL (e.g., expression fragments |
| 1224 | // from plpgsql functions during constant folding) |
| 1225 | bool result = false; |
| 1226 | PG_TRY(); |
| 1227 | { |
| 1228 | List* raw_parsetree_list = raw_parser(query_string, RAW_PARSE_DEFAULT); |
| 1229 | if (raw_parsetree_list != NIL) { |
| 1230 | RawStmt* raw_stmt = linitial_node(RawStmt, raw_parsetree_list); |
| 1231 | result = nodeTag(raw_stmt->stmt) == T_SelectStmt; |
| 1232 | } |
| 1233 | } |
| 1234 | PG_CATCH(); |
| 1235 | { |
| 1236 | // Parse failed - not a valid SQL statement (e.g., expression fragment) |
| 1237 | FlushErrorState(); |
| 1238 | result = false; |
| 1239 | } |
| 1240 | PG_END_TRY(); |
| 1241 | |
| 1242 | return result; |
| 1243 | } |
| 1244 | |
| 1245 | static PlannedStmt* |
| 1246 | deeplake_planner(Query* parse, const char* query_string, int32_t cursorOptions, ParamListInfo boundParams) |