Hans Zeller created TRAFODION-2382:
--------------------------------------

             Summary: No plan produced when joining two TMUDFs
                 Key: TRAFODION-2382
                 URL: https://issues.apache.org/jira/browse/TRAFODION-2382
             Project: Apache Trafodion
          Issue Type: Bug
          Components: sql-cmp
    Affects Versions: 2.1-incubating
         Environment: any
            Reporter: Hans Zeller
            Assignee: Hans Zeller


This problem was reported by Gunnar Tapper and it uncovered three separate 
issues:

# The max cardinality for some TMUDFs is set to -1 and this causes the hash 
join implementation rule to trigger a condition that disables a hash join. This 
is intended for situations where the left/outer table has at most 1 row, which 
is not the case here.
# The merge join rule doesn't fire, because the CAST functions used here are 
not considered order-preserving expressions. This problem is not addressed as 
part of this JIRA.
# The nested join rule produces a filter, but we fail to push the filter 
predicate into the TMUDF, because the code uses the operator type to determine 
its arity, and the TMUDF uses the same operator type for different arities.

In the end, none of the three join algorithms can be applied, and we fail to 
produce a plan.

Here is how to reproduce the problem:

Put this Java code into file join_udr.java:

{code:java}
import org.trafodion.sql.udr.*;

class join_udf extends UDR {
        public join_udf() {}
        
        @Override
        public void describeParamsAndColumns(UDRInvocationInfo info)
         throws UDRException
        {
                // 1st param is vchar size desired
                int vSize = info.par().getInt(0);
                // this param needed when call is exec'd, but not info.out()'d
                info.addFormalParameter(info.par().getColumn(0));               
        

                // For each following param, create an output column
                // Params are json tag names - convert these to SQL column names
                // For output, cannot distinguish data types so everything is 
VARCHAR
        
                for (int i = 1; i < info.par().getNumColumns(); i++) {
                        // make formal param
                        info.addFormalParameter(info.par().getColumn(i));
                        // use input param string to create output param
                        info.out().addVarCharColumn(info.par().getString(i), 
vSize, true);
                } // for
                
                // set as Mapper so reading can be parallelized
                info.setFuncType(UDRInvocationInfo.FuncType.MAPPER);
        }
        
        @Override
        public void processData(UDRInvocationInfo info,
                                UDRPlanInfo plan)
                throws UDRException
        {
            // do nothing
        } // end processData
        
}
{code}

Compile the code:

{code}
javac join_udf.java
jar cvf join_udf.jar join_udf.class
{code}

Create the UDF and a source table, then try to compile the query (stay in the 
same directory and use the sqlci tool):

{code:sql}
drop function  join_udf;
drop library join_udf_lib;

create library join_udf_lib file
 'join_udf.jar';

create table_mapping function join_udf()
external name 'join_udf'
language java 
library join_udf_lib;

-- disable semijoin to join transformation, some more complex situations
-- show this error without this CQD, but we are using it here to keep the
-- test case simple
cqd SEMIJOIN_TO_INNERJOIN_TRANSFORMATION 'off';

create table join_udf_src(a integer);

prepare s from
--display
select a,b
from
( select
    -- Convert the string data to SQL data types.
    cast( a as char(4) ) as a
  , cast( b as date ) as b
  from udf
  ( join_udf(
        table( select * from join_udf_src )
      , 257
      , 'A'
      , 'B'
    )
  )
)
where ( a,b ) in
( select a,b
  from
  ( select
      cast( a as char(4) ) as a
    , cast( b as date ) as b
    from udf
    ( join_udf(
          257
        , 'A'
        , 'B'
      )
    )
  )
  where b between date '2016-01-01' and date '2016-02-28'
)
;
{code}

This will produce the following error:

{code}
*** ERROR[2235] Compiler Internal Error: Pass one skipped, but cannot produce a 
plan in pass two, originated from file ../optimizer/opt.cpp at line xxxx.

*** ERROR[8822] The statement was not prepared.
{code}




--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to