Re: Avoiding rewrite in ALTER TABLE ALTER TYPE - Mailing list pgsql-hackers
From | Noah Misch |
---|---|
Subject | Re: Avoiding rewrite in ALTER TABLE ALTER TYPE |
Date | |
Msg-id | 20101231013534.GA7521@tornado.leadboat.com Whole thread Raw |
In response to | Re: Avoiding rewrite in ALTER TABLE ALTER TYPE (Robert Haas <robertmhaas@gmail.com>) |
Responses |
Re: Avoiding rewrite in ALTER TABLE ALTER TYPE
Re: Avoiding rewrite in ALTER TABLE ALTER TYPE |
List | pgsql-hackers |
On Thu, Dec 30, 2010 at 12:57:45AM -0500, Robert Haas wrote: > On Thu, Dec 30, 2010 at 12:24 AM, Noah Misch <noah@leadboat.com> wrote: > > On Wed, Dec 29, 2010 at 11:14:37PM -0500, Robert Haas wrote: > >> I think for any pair of types (T1, T2) we should first determine > >> whether we can skip the scan altogether. ?If yes, we're done. ?If no, > >> then we should have a way of determining whether a verify-only scan is > >> guaranteed to be sufficient (in your terminology, the verification > >> scan is guaranteed to return either positive or error, not negative). > >> If yes, then we do a verification scan. ?If no, we do a rewrite. > > > > How would we answer the second question in general? > > I am not sure - I guess we'd need to design some sort of mechanism for that. Okay, here goes. Given a Var "varexpr" representing the column we're changing and an expression tree "expr" we need to answer two questions (argument lists simplified -- assume the same RTEs in all cases): always-noop: "Will datumIsEquals(ExecEvalExpr(varexpr), ExecEvalExpr(expr)) return true or yield an error for all possible tuples?" never-error: "Will ExecEvalExpr(expr) never throw an error?" Currently we're only interested in the second question when the first is also true; I'm not sure if there's something fundamental there, or just an artifact of current needs. To support answering these questions, extend the CREATE CAST changes from my earlier proposal, modifying the exemptor signature to return an int, a bitmask containing one bit for each of these two questions. Call the function in find_typmod_coercion_function. If its return value answers "yes" to both questions, return COERCION_PATH_NONE, resulting in omission of the length coercion node. For other verdicts, generate the FuncExpr as normal and insert the verdict in a new FuncExpr field "funcexempt". (That need not increase the size of FuncExpr, if that's a concern.) ATPrepAlterColumnType, having generated its transformation expression, will call a new function that recursively walks the tree to answer the two questions. The walker will apply these rules: 1. For a Var with the varno/varattno in question, intrinsically "yes" to both. 2. A RelabelType node inherits the answers of its sole argument. 3. A CoerceToDomain node inherits the always-noop answer of its sole argument. When GetDomainConstraints() == NIL, it also inherits the never-error answer. Otherwise, never-error becomes "no". 4. A FuncExpr node has answers given by the bitwise-AND of its funcexempt field and the answers from its first argument. 5. Any other node answers "no" to both questions. If the transformation expression root has "yes" to both questions, we're done with no scan. If only always-noop is true, we do a verification scan only. Otherwise, we optimize nothing and do a rewrite. Thoughts? Thanks, nm
pgsql-hackers by date: