Rules: 2nd patch - Mailing list pgsql-hackers
From | jwieck@debis.com (Jan Wieck) |
---|---|
Subject | Rules: 2nd patch |
Date | |
Msg-id | m0z95iD-000EBPC@orion.SAPserv.Hamburg.dsh.de Whole thread Raw |
Responses |
Rules and views (was Re: [HACKERS] Rules: 2nd patch)
|
List | pgsql-hackers |
Hi, here's the second patch for the rule system. It fixes the backend crashes that occur when using views/rules in the same session where they are created. The bug was that the new actions parsetrees and event qualifications, added to the relations rd_rules locks, where not copied to the cache memory context. In addition it prepares tcop/postgres.c to handle a zero length rewritten list returned by QueryRewrite() correctly (due to instead nothing). Next patch will allow instead nothing on select rules to return no tuples at all instead of one with all NULL fields (as it is now). Jan -- #======================================================================# # It's easier to get forgiveness for being wrong than for being right. # # Let's break this rule - forgive me. # #======================================== jwieck@debis.com (Jan Wieck) # diff -cr backend.orig/rewrite/rewriteSupport.c backend/rewrite/rewriteSupport.c *** backend.orig/rewrite/rewriteSupport.c Wed Aug 19 10:36:15 1998 --- backend/rewrite/rewriteSupport.c Wed Aug 19 10:55:03 1998 *************** *** 158,163 **** --- 158,167 ---- */ oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt); thisRule = (RewriteRule *) palloc(sizeof(RewriteRule)); + if (qual != NULL) + qual = copyObject(qual); + if (actions != NIL) + actions = copyObject(actions); MemoryContextSwitchTo(oldcxt); thisRule->ruleId = ruleId; diff -cr backend.orig/tcop/postgres.c backend/tcop/postgres.c *** backend.orig/tcop/postgres.c Fri Aug 7 11:05:41 1998 --- backend/tcop/postgres.c Wed Aug 19 10:51:50 1998 *************** *** 451,474 **** /* rewrite queries (retrieve, append, delete, replace) */ rewritten = QueryRewrite(querytree); ! /* ! * Rewrite the UNIONS. ! */ ! foreach(rewritten_list, rewritten) ! { ! Query *qry = (Query *) lfirst(rewritten_list); ! ! union_result = NIL; ! foreach(union_list, qry->unionClause) ! union_result = nconc(union_result, QueryRewrite((Query *) lfirst(union_list))); ! qry->unionClause = union_result; ! } ! ! if (rewritten != NULL) { int len, k; len = length(rewritten); if (len == 1) new_list->qtrees[j++] = (Query *) lfirst(rewritten); --- 451,474 ---- /* rewrite queries (retrieve, append, delete, replace) */ rewritten = QueryRewrite(querytree); ! if (rewritten != NIL) { int len, k; + /* + * Rewrite the UNIONS. + */ + foreach(rewritten_list, rewritten) + { + Query *qry = (Query *) lfirst(rewritten_list); + + union_result = NIL; + foreach(union_list, qry->unionClause) + union_result = nconc(union_result, QueryRewrite((Query *) lfirst(union_list))); + qry->unionClause = union_result; + } + len = length(rewritten); if (len == 1) new_list->qtrees[j++] = (Query *) lfirst(rewritten); *************** *** 487,492 **** --- 487,500 ---- } } + /* ---------- + * Due to rewriting, the new list could also have been + * shrunk (do instead nothing). Forget obsolete queries + * at the end. + * ---------- + */ + new_list->len = j; + /* we're done with the original lists, free it */ free(querytree_list->qtrees); free(querytree_list); *************** *** 530,536 **** elog(NOTICE, "(transaction aborted): %s", "queries ignored until END"); ! *queryListP = (QueryTreeList *) NULL; return (List *) NULL; } --- 538,547 ---- elog(NOTICE, "(transaction aborted): %s", "queries ignored until END"); ! free(querytree_list->qtrees); ! free(querytree_list); ! if (queryListP) ! *queryListP = (QueryTreeList *) NULL; return (List *) NULL; } *************** *** 571,576 **** --- 582,597 ---- else plan_list = lappend(plan_list, NULL); #endif + } + + /* ---------- + * Check if the rewriting had thrown away anything + * ---------- + */ + if (querytree_list->len == 0) { + free(querytree_list->qtrees); + free(querytree_list); + querytree_list = NULL; } if (queryListP)
pgsql-hackers by date: