* If the given Query is an INSERT ... SELECT construct, extract and * return the sub-Query node that represents the SELECT part. Otherwise * return the given Query. * * If subquery_ptr is not NULL, then *subquery_ptr is set to the location * of the link to the SELECT subquery inside parsetree, or NULL if not an * INSERT ... SELECT. * * This is a hack needed because transformations on INSE
| 970 | * INSERT part. Perhaps this can be cleaned up with redesigned querytrees. |
| 971 | */ |
| 972 | Query * |
| 973 | getInsertSelectQuery(Query *parsetree, Query ***subquery_ptr) |
| 974 | { |
| 975 | Query *selectquery; |
| 976 | RangeTblEntry *selectrte; |
| 977 | RangeTblRef *rtr; |
| 978 | |
| 979 | if (subquery_ptr) |
| 980 | *subquery_ptr = NULL; |
| 981 | |
| 982 | if (parsetree == NULL) |
| 983 | return parsetree; |
| 984 | if (parsetree->commandType != CMD_INSERT) |
| 985 | return parsetree; |
| 986 | |
| 987 | /* |
| 988 | * Currently, this is ONLY applied to rule-action queries, and so we |
| 989 | * expect to find the OLD and NEW placeholder entries in the given query. |
| 990 | * If they're not there, it must be an INSERT/SELECT in which they've been |
| 991 | * pushed down to the SELECT. |
| 992 | */ |
| 993 | if (list_length(parsetree->rtable) >= 2 && |
| 994 | strcmp(rt_fetch(PRS2_OLD_VARNO, parsetree->rtable)->eref->aliasname, |
| 995 | "old") == 0 && |
| 996 | strcmp(rt_fetch(PRS2_NEW_VARNO, parsetree->rtable)->eref->aliasname, |
| 997 | "new") == 0) |
| 998 | return parsetree; |
| 999 | Assert(parsetree->jointree && IsA(parsetree->jointree, FromExpr)); |
| 1000 | if (list_length(parsetree->jointree->fromlist) != 1) |
| 1001 | elog(ERROR, "expected to find SELECT subquery"); |
| 1002 | rtr = (RangeTblRef *) linitial(parsetree->jointree->fromlist); |
| 1003 | if (!IsA(rtr, RangeTblRef)) |
| 1004 | elog(ERROR, "expected to find SELECT subquery"); |
| 1005 | selectrte = rt_fetch(rtr->rtindex, parsetree->rtable); |
| 1006 | if (!(selectrte->rtekind == RTE_SUBQUERY && |
| 1007 | selectrte->subquery && |
| 1008 | IsA(selectrte->subquery, Query) && |
| 1009 | selectrte->subquery->commandType == CMD_SELECT)) |
| 1010 | elog(ERROR, "expected to find SELECT subquery"); |
| 1011 | selectquery = selectrte->subquery; |
| 1012 | if (list_length(selectquery->rtable) >= 2 && |
| 1013 | strcmp(rt_fetch(PRS2_OLD_VARNO, selectquery->rtable)->eref->aliasname, |
| 1014 | "old") == 0 && |
| 1015 | strcmp(rt_fetch(PRS2_NEW_VARNO, selectquery->rtable)->eref->aliasname, |
| 1016 | "new") == 0) |
| 1017 | { |
| 1018 | if (subquery_ptr) |
| 1019 | *subquery_ptr = &(selectrte->subquery); |
| 1020 | return selectquery; |
| 1021 | } |
| 1022 | elog(ERROR, "could not find rule placeholders"); |
| 1023 | return NULL; /* not reached */ |
| 1024 | } |
| 1025 | |
| 1026 | |
| 1027 | /* |
no test coverage detected