/* * QueryRewrite - * Primary entry point to the query rewriter. * Rewrite one query via query rewrite system, possibly returning 0 * or many queries. * * NOTE: the parsetree must either have come straight from the parser, * or have been scanned by AcquireRewriteLocks to acquire suitable locks. */ List * QueryRewrite(Query *parsetree) { uint64 input_query_id = parsetree->queryId; List *querylist; List *results; ListCell *l; CmdType origCmdType; bool foundOriginalQuery; Query *lastInstead;
/* * This function is only applied to top-level original queries */ Assert(parsetree->querySource == QSRC_ORIGINAL); Assert(parsetree->canSetTag);
/* * Step 1 * * Apply all non-SELECT rules possibly getting 0 or many queries */ querylist = RewriteQuery(parsetree, NIL, 0);
/* * Step 2 * * Apply all the RIR rules on each query * * This is also a handy place to mark each query with the original queryId */ results = NIL; foreach(l, querylist) { Query *query = (Query *) lfirst(l);
query = fireRIRrules(query, NIL);
query->queryId = input_query_id;
results = lappend(results, query); }
/* * Step 3 * * Determine which, if any, of the resulting queries is supposed to set * the command-result tag; and update the canSetTag fields accordingly. * * If the original query is still in the list, it sets the command tag. * Otherwise, the last INSTEAD query of the same kind as the original is * allowed to set the tag. (Note these rules can leave us with no query * setting the tag. The tcop code has to cope with this by setting up a * default tag based on the original un-rewritten query.) * * The Asserts verify that at most one query in the result list is marked * canSetTag. If we aren't checking asserts, we can fall out of the loop * as soon as we find the original query. */ origCmdType = parsetree->commandType; foundOriginalQuery = false; lastInstead = NULL;