Thanks for your comments.

Tom Lane <t...@sss.pgh.pa.us> writes: 
> Tomas Vondra <tomas.von...@enterprisedb.com> writes:
> > I honestly don't know if this is the correct solution. It seems to me
> > handling this at the EXPLAIN level might just mask the issue - it's
> > not clear to me why adding "indexqualorig" would remove the ambiguity
> > (if there's one). Perhaps it might be better to find why the
> > ruleutils.c code thinks the OPERATOR() is necessary, and then improve/fix 
> > that?
> 
> As Masahiro-san already said, the root cause is that the planner removes the
> RelabelType that is on the indexed variable.  So ruleutils sees that the 
> operator is not
> the one that would be chosen by the parser given those input expressions (cf
> generate_operator_name) and it concludes it'd better schema-qualify the 
> operator.
> While that doesn't really make any difference in this particular case, it is 
> the right thing
> in typical rule-deparsing cases.

Yes.

The plan of index scan has a "RELABELTYPE" node, and it has "resulttype" so that
generate_operator_name() gets "operid =1054("="), arg1=1042(bpchar from 
resulttype),
arg2=1042(bpchar)". The plan of index only scan is removed it so that
generate_operator_name() gets "operid =1054("="), arg1=25(*text*), 
arg2=1042(bpchar)". 

Though there is no entry "operid=1054("="), arg1=25(*text*), arg2=1042(bpchar)" 
in
pg_operator, it decided to check with the operator "=" for (text, text) because 
it is
coercion-compatible and preferred than operator "=" for (bpchar, bpchar). 

But since the caller expected to use operator "=" for (bpchar, bpchar), it plus
OPERATOR() decoration sadly.

# the partial output of Index Scan plan
              :indexqualorig (
                 {OPEXPR 
                 :opno 1054                -- "=" operator
                 :opfuncid 1048 
                 :opresulttype 16 
                 :opretset false 
                 :opcollid 0 
                 :inputcollid 950 
                 :args (
                    {RELABELTYPE 
                    :arg 
                       {VAR 
                       :varno 1
                       :varattno 1 
                       :vartype 25           -- text. But it will be evaluated 
as 1042(bpchar) from resulttype
                       :vartypmod -1 
                       :varcollid 950 
                       :varnullingrels (b)
                       :varlevelsup 0 
                       :varnosyn 1 
                       :varattnosyn 1 
                       :location 33
                       }
                    :resulttype 1042        -- bpchar
                    :resulttypmod -1 
                    :resultcollid 950 
                    :relabelformat 1 
                    :location 35
                    }
                    {CONST 
                    :consttype 1042        -- bpchar
                    :consttypmod -1 
                    :constcollid 100 
                    :constlen -1 
                    :constbyval false 
                    :constisnull false 
                    :location 46 
                    :constvalue 7 [ 28 0 0 0 102 111 111 ]
                    }
                 ) 

# the partial output of Index Only Scan plan
              :indexqual (
                 {OPEXPR 
                 :opno 1054               -- "=" operator
                 :opfuncid 1048 
                 :opresulttype 16 
                 :opretset false 
                 :opcollid 0 
                 :inputcollid 950 
                 :args (
                    {VAR 
                    :varno -3
                    :varattno 1 
                    :vartype 25      -- text
                    :vartypmod -1 
                    :varcollid 950 
                    :varnullingrels (b)
                    :varlevelsup 0 
                    :varnosyn 1 
                    :varattnosyn 1 
                    :location 33
                    }
                    {CONST 
                    :consttype 1042   -- bpchar
                    :consttypmod -1 
                    :constcollid 100 
                    :constlen -1 
                    :constbyval false 
                    :constisnull false 
                    :location 46 
                    :constvalue 7 [ 28 0 0 0 102 111 111 ]
                    }
                 )
                 :location 44
                 }
              )

> I don't think this output is really wrong, and I'm not in favor of adding 
> nontrivial overhead
> to make it better, so I don't like the proposed patch.  Maybe 
> generate_operator_name
> could use some other heuristic, but I'm unsure what.  The case it wants to 
> cover is that
> the operator is in the search path but is masked by some operator in an 
> earlier schema,
> so simply testing if the operator's schema is in the path at all would be 
> insufficient.

Yes, that's one of my concerns. 

IIUC, the above case is not related to the search path but the arguments don't 
match. If so,
I think there are two ways to solve the issue.

1. make callers of generate_operator_name() check the arguments first.
The callers (e.g., get_oper_expr()) of generate_operator_name() decide whether 
they
should/can cast the arguments. The planner already decided what operator should 
be used
so that get_oper_expr() can cast always on the explain context if the arguments 
don't match
the operator's one, doesn't it?

2. make generate_operator_name() checks all operator candidate.
Currently generate_operator_name() checks only one operator which matches the 
operator's name
even if although there are other candidates (e.g., to call 
oper()->oper_select_candidate()). 
func_select_candidate() selects operator "=" for (text, text) in the above case 
because "=" for
(btchar, btchar) is typispreferred=false. So, it seems to me that it can solve 
the issue 
if generate_operator_name() checks all candidates.

I think the second solution is better because callers might expect to use 
specified operator 
even if there are other candidates' operator which can handle the arguments.

Regards,
--
Masahiro Ikeda
NTT DATA CORPORATION


Reply via email to