// Condition(s) in the left join. Punt for now.
if ( opJoin.getExprs() != null )
return super.transform(opJoin, left, right) ;
SqlNode sqlLeft = ((OpSQL)left).getSqlNode() ;
SqlNode sqlRight = ((OpSQL)right).getSqlNode() ;
// Check for coalesce.
// Do optional variables on the right appear only as optional variables on the left?
Set<ScopeEntry> scopes = sqlLeft.getIdScope().findScopes() ;
// Find optional-on-left
Set<ScopeEntry> scopes2 = toSet(filter(scopes, ScopeEntry.OptionalFilter)) ;
Set<Var> leftOptVars = toSet(map(scopes2, ScopeEntry.ToVar)) ; // Vars from left optionals.
if ( false )
{
Iter<ScopeEntry> iter = Iter.iter(scopes) ;
Set<Var> leftOptVars_ = iter.filter(ScopeEntry.OptionalFilter).map(ScopeEntry.ToVar).toSet() ;
}
// Find optional-on-right (easier - it's all variables)
Set<Var> rightOptVars = sqlRight.getIdScope().getVars() ;
// And finally, calculate the intersection of the two.
// SetUtils extension - one side could be an iterator
Set<Var> coalesceVars = intersection(leftOptVars, rightOptVars) ;
// Future simplification : LeftJoinClassifier.nonLinearVars
// if ( ! coalesceVars.equals(LeftJoinClassifier.nonLinearVars( opJoin.getLeft(), opJoin.getRight() )) )
// { unexpected }
if ( coalesceVars.size() > 0 )
{
String alias = request.genId(AliasesSql.CoalesceAliasBase) ;
SqlNode sqlNode = SqlBuilder.leftJoinCoalesce(request, alias,
sqlLeft, sqlRight,
coalesceVars) ;
return new OpSQL(sqlNode, opJoin, request) ;
// Punt