My bad. Everything is OK. The problem was inside my tables.
It is a tricky query that DBeaver sends in order to get primitive types.

it turned out that pg_class table must not have a record with oid = 0,
otherwise c.relkind will never be NULL after LEFT JOIN

On Fri, Oct 28, 2022 at 5:46 AM Benchao Li <[email protected]> wrote:

> What do you mean by saying "bug"? Do you mean that "c.relkind IS NULL OR
> c.relkind = 'c'" should be pushed through the first join?
>
> Calcite could do this now in FilterJoinRule[1].
>
> [1]
>
> https://github.com/apache/calcite/blob/c945b7f49b99538748c871557f6ac80957be2b6e/core/src/main/java/org/apache/calcite/rel/rules/FilterJoinRule.java#L58
>
> Dmitry Sysolyatin <[email protected]> 于2022年10月28日周五 00:52写道:
>
> > Hi!
> >
> > I tried to execute query the following query against calcite:
> >
> > SELECT t.oid,t.*,c.relkind,format_type(nullif(t.typbasetype, 0),
> > t.typtypmod) as base_type_name, d.description
> > FROM pg_catalog.pg_type t
> > LEFT OUTER JOIN pg_catalog.pg_type et ON et.oid=t.typelem
> > LEFT OUTER JOIN pg_catalog.pg_class c ON c.oid=t.typrelid
> > LEFT OUTER JOIN pg_catalog.pg_description d ON t.oid=d.objoid
> > WHERE t.typname IS NOT NULL
> > AND (c.relkind IS NULL OR c.relkind = 'c') AND (et.typcategory IS NULL OR
> > et.typcategory <> 'C')
> >
> > For some reason, filtering by c.relkind is applied after joining.
> >
> > LogicalProject(oid=[$0], oid0=[$0], typname=[$1], typnamespace=[$2],
> > typowner=[$3], typlen=[$4], typbyval=[$5], typtype=[$6],
> typcategory=[$7],
> > typispreferred=[$8], typisdefined=[$9], typdelim=[$10], typrelid=[$11],
> > typelem=[$12], typarray=[$13], typinput=[$14], typoutput=[$15],
> > typreceive=[$16], typsend=[$17], typmodin=[$18], typmodout=[$19],
> > typanalyze=[$20], typalign=[$21], typstorage=[$22], typnotnull=[$23],
> > typbasetype=[$24], typtypmod=[$25], typndims=[$26], typcollation=[$27],
> > typdefaultbin=[$28], typdefault=[$29], typacl=[$30], relkind=[$78],
> > base_type_name=[format_type(CASE(=($24, 0), null:INTEGER, $24), $25)],
> > description=[$98])
> >   LogicalFilter(condition=[AND(IS NOT NULL($1), OR(IS NULL($78), =($78,
> > _UTF-16LE'c')), OR(IS NULL($38), <>($38, _UTF-16LE'C')))])
> >     LogicalJoin(condition=[=($0, $95)], joinType=[left])
> >       LogicalJoin(condition=[=($62, $11)], joinType=[left])
> >         LogicalJoin(condition=[=($31, $12)], joinType=[left])
> >           LogicalTableScan(table=[[default, pg_catalog, pg_type]])
> >           LogicalTableScan(table=[[default, pg_catalog, pg_type]])
> >         LogicalTableScan(table=[[default, pg_catalog, pg_class]])
> >       LogicalTableScan(table=[[default, pg_catalog, pg_description]])
> >
> >
> >
> > Postgres plan generates the following plan for the same query
> > Nested Loop Left Join  (cost=22.47..44.73 rows=1 width=322)
> >    ->  Nested Loop Left Join  (cost=22.18..43.94 rows=1 width=261)
> >          Filter: ((et.typcategory IS NULL) OR (et.typcategory <>
> > 'C'::"char"))
> >          ->  Hash Left Join  (cost=21.91..43.52 rows=1 width=261)
> >                Hash Cond: (t.typrelid = c.oid)
> >                Filter: (c.relkind IS NULL)
> >                ->  Seq Scan on pg_type t  (cost=0.00..20.01 rows=601
> > width=260)
> >                      Filter: (typname IS NOT NULL)
> >                ->  Hash  (cost=16.96..16.96 rows=396 width=5)
> >                      ->  Seq Scan on pg_class c  (cost=0.00..16.96
> rows=396
> > width=5)
> >          ->  Index Scan using pg_type_oid_index on pg_type et
> >  (cost=0.28..0.41 rows=1 width=5)
> >                Index Cond: (oid = t.typelem)
> >    ->  Index Scan using pg_description_o_c_o_index on pg_description d
> >  (cost=0.28..0.77 rows=1 width=29)
> >          Index Cond: (objoid = t.oid)
> > (14 rows)
> >
> > Is it a bug or maybe there is a setting that changes this behaviour ?
> >
>
>
> --
>
> Best,
> Benchao Li
>

Reply via email to