On Tue, Jan 6, 2015 at 10:51 PM, Kouhei Kaigai <kai...@ak.jp.nec.com> wrote:
> Jim, Thanks for your reviewing the patch. > > The attached patch is revised one according to your suggestion, > and also includes bug fix I could found. > > * Definitions of TIDXXXXOperator was moved to pg_operator.h > as other operator doing. > * Support the case of "ctid (operator) Param" expression. > * Add checks if commutator of TID was not found. > * Qualifiers gets extracted on plan stage, not path stage. > * Adjust cost estimation logic to fit SeqScan manner. > * Add some new test cases for regression test. > > > On 12/24/14, 7:54 PM, Kouhei Kaigai wrote: > > >>> On Mon, Dec 15, 2014 at 4:55 PM, Kouhei Kaigai > > >>> <kai...@ak.jp.nec.com> > > >> wrote: > > >>>> I'm not certain whether we should have this functionality in > > >>>> contrib from the perspective of workload that can help, but its > > >>>> major worth is for an example of custom-scan interface. > > >>> worker_spi is now in src/test/modules. We may add it there as well, > > no? > > >>> > > >> Hmm, it makes sense for me. Does it also make sense to add a > > >> test-case to the core regression test cases? > > >> > > > The attached patch adds ctidscan module at test/module instead of > contrib. > > > Basic portion is not changed from the previous post, but file > > > locations and test cases in regression test are changed. > > > > First, I'm glad for this. It will be VERY valuable for anyone trying to > > clean up the end of a majorly bloated table. > > > > Here's a partial review... > > > > +++ b/src/test/modules/ctidscan/ctidscan.c > > > > +/* missing declaration in pg_proc.h */ > > +#ifndef TIDGreaterOperator > > +#define TIDGreaterOperator 2800 > > ... > > If we're calling that out here, should we have a corresponding comment in > > pg_proc.h, in case these ever get renumbered? > > > It was a quick hack when I moved this module out of the tree. > Yep, I should revert when I submit this patch again. > > > +CTidQualFromExpr(Node *expr, int varno) > > ... > > + if (IsCTIDVar(arg1, varno)) > > + other = arg2; > > + else if (IsCTIDVar(arg2, varno)) > > + other = arg1; > > + else > > + return NULL; > > + if (exprType(other) != TIDOID) > > + return NULL; /* should not happen */ > > + /* The other argument must be a pseudoconstant */ > > + if (!is_pseudo_constant_clause(other)) > > + return NULL; > > > > I think this needs some additional blank lines... > > > OK. And, I also noticed the coding style around this function is > different from other built-in plans, so I redefined the role of > this function just to check whether the supplied RestrictInfo is > OpExpr that involves TID inequality operator, or not. > > Expression node shall be extracted when Plan node is created > from Path node. > > > + if (IsCTIDVar(arg1, varno)) > > + other = arg2; > > + else if (IsCTIDVar(arg2, varno)) > > + other = arg1; > > + else > > + return NULL; > > + > > + if (exprType(other) != TIDOID) > > + return NULL; /* should not happen */ > > + > > + /* The other argument must be a pseudoconstant */ > > + if (!is_pseudo_constant_clause(other)) > > + return NULL; > > > > + * CTidEstimateCosts > > + * > > + * It estimates cost to scan the target relation according to the given > > + * restriction clauses. Its logic to scan relations are almost same as > > + * SeqScan doing, because it uses regular heap_getnext(), except for > > + * the number of tuples to be scanned if restriction clauses work well. > > > > <grammar>That should read "same as what SeqScan is doing"... however, > what > > actual function are you talking about? I couldn't find > SeqScanEstimateCosts > > (or anything ending EstimateCosts). > > > It is cost_seqscan(). But I don't put a raw function name in the source > code comments in other portion, because nobody can guarantee it is up to > date in the future... > > > BTW, there's other grammar issues but it'd be best to handle those all at > > once after all the code stuff is done. > > > Yep. Help by native English speaker is very helpful for us. > > > + opno = get_commutator(op->opno); > > What happens if there's no commutator? Perhaps best to Assert(opno != > > InvalidOid) at the end of that if block. > > > Usually, commutator operator of TID is defined on initdb time, however, > nobody can guarantee a mad superuser doesn't drop it. > So, I added elog(ERROR,...) here. > > > > Though, it seems things will fall apart anyway if ctid_quals isn't > exactly > > what we're expecting; I don't know if that's OK or not. > > > No worry, it was already checked on planning stage. > > > + /* disk costs --- assume each tuple on a different page */ > > + run_cost += spc_random_page_cost * ntuples; > > Isn't that extremely pessimistic? > > > Probably. I follow the manner of SeqScan. > > > I'm not familiar enough with the custom-scan stuff to really comment past > > this point, and I could certainly be missing some details about planning > > and execution. > > > > I do have some concerns about the regression test, but perhaps I'm just > > being paranoid: > > > > - The EXPLAIN tests don't cover >. They do cover <= and >= via BETWEEN. > > - Nothing tests the case of '...'::tid op ctid; only lvalue cases are > tested. > > > Both are added. > > > Also, it seems that we don't handle joining on a ctid qual... is that > > intentional? > > > Yep. This module does not intend to handle joining, because custom-/ > foreign-join interface is still under the discussion. > https://commitfest.postgresql.org/action/patch_view?id=1653 > > Hanada-san makes an enhancement of postgres_fdw on this enhancement. > https://commitfest.postgresql.org/action/patch_view?id=1674 > > > I know that sounds silly, but you'd probably want to do that > > if you're trying to move tuples off the end of a bloated table. You could > > work around it by constructing a dynamic SQL string, but it'd be easier > > to do something like: > > > > UPDATE table1 SET ... > > WHERE ctid >= (SELECT '(' || relpages || ',0)' FROM pg_class WHERE oid > > = 'table1'::regclass) ; > > > This example noticed me that the previous version didn't support the case > of "ctid (operator) Param". > So, I enhanced to support above case, and update the regression test also. > Moved this patch to next CF 2015-02 because of lack of review(ers). -- Michael