protected void convertFrom(Blackboard bb,SqlNode from){
  if (from == null) {
    bb.setRoot(LogicalValues.createOneRow(cluster),false);
    return;
  }
  final SqlCall call;
  final SqlNode[] operands;
switch (from.getKind()) {
case AS:
    convertFrom(bb,((SqlCall)from).operand(0));
  return;
case WITH_ITEM:
convertFrom(bb,((SqlWithItem)from).query);
return;
case WITH:
convertFrom(bb,((SqlWith)from).body);
return;
case TABLESAMPLE:
operands=((SqlBasicCall)from).getOperands();
SqlSampleSpec sampleSpec=SqlLiteral.sampleValue(operands[1]);
if (sampleSpec instanceof SqlSampleSpec.SqlSubstitutionSampleSpec) {
String sampleName=((SqlSampleSpec.SqlSubstitutionSampleSpec)sampleSpec).getName();
datasetStack.push(sampleName);
convertFrom(bb,operands[0]);
datasetStack.pop();
}
 else if (sampleSpec instanceof SqlSampleSpec.SqlTableSampleSpec) {
SqlSampleSpec.SqlTableSampleSpec tableSampleSpec=(SqlSampleSpec.SqlTableSampleSpec)sampleSpec;
convertFrom(bb,operands[0]);
RelOptSamplingParameters params=new RelOptSamplingParameters(tableSampleSpec.isBernoulli(),tableSampleSpec.getSamplePercentage(),tableSampleSpec.isRepeatable(),tableSampleSpec.getRepeatableSeed());
bb.setRoot(new Sample(cluster,bb.root,params),false);
}
 else {
throw Util.newInternal("unknown TABLESAMPLE type: " + sampleSpec);
}
return;
case IDENTIFIER:
final SqlValidatorNamespace fromNamespace=validator.getNamespace(from).resolve();
if (fromNamespace.getNode() != null) {
convertFrom(bb,fromNamespace.getNode());
return;
}
final String datasetName=datasetStack.isEmpty() ? null : datasetStack.peek();
boolean[] usedDataset={false};
RelOptTable table=SqlValidatorUtil.getRelOptTable(fromNamespace,catalogReader,datasetName,usedDataset);
final RelNode tableRel;
if (shouldConvertTableAccess) {
tableRel=toRel(table);
}
 else {
tableRel=LogicalTableScan.create(cluster,table);
}
bb.setRoot(tableRel,true);
if (usedDataset[0]) {
bb.setDataset(datasetName);
}
return;
case JOIN:
final SqlJoin join=(SqlJoin)from;
final SqlValidatorScope scope=validator.getJoinScope(from);
final Blackboard fromBlackboard=createBlackboard(scope,null,false);
SqlNode left=join.getLeft();
SqlNode right=join.getRight();
final boolean isNatural=join.isNatural();
final JoinType joinType=join.getJoinType();
final SqlValidatorScope leftScope=Util.first(validator.getJoinScope(left),((DelegatingScope)bb.scope).getParent());
final Blackboard leftBlackboard=createBlackboard(leftScope,null,false);
final SqlValidatorScope rightScope=Util.first(validator.getJoinScope(right),((DelegatingScope)bb.scope).getParent());
final Blackboard rightBlackboard=createBlackboard(rightScope,null,false);
convertFrom(leftBlackboard,left);
RelNode leftRel=leftBlackboard.root;
convertFrom(rightBlackboard,right);
RelNode rightRel=rightBlackboard.root;
JoinRelType convertedJoinType=convertJoinType(joinType);
RexNode conditionExp;
final SqlValidatorNamespace leftNamespace=validator.getNamespace(left);
final SqlValidatorNamespace rightNamespace=validator.getNamespace(right);
if (isNatural) {
final RelDataType leftRowType=leftNamespace.getRowType();
final RelDataType rightRowType=rightNamespace.getRowType();
final List<String> columnList=SqlValidatorUtil.deriveNaturalJoinColumnList(leftRowType,rightRowType);
conditionExp=convertUsing(leftNamespace,rightNamespace,columnList);
}
 else {
conditionExp=convertJoinCondition(fromBlackboard,leftNamespace,rightNamespace,join.getCondition(),join.getConditionType(),leftRel,rightRel);
}
final RelNode joinRel=createJoin(fromBlackboard,leftRel,rightRel,conditionExp,convertedJoinType);
bb.setRoot(joinRel,false);
return;
case SELECT:
case INTERSECT:
case EXCEPT:
case UNION:
final RelNode rel=convertQueryRecursive(from,false,null).project();
bb.setRoot(rel,true);
return;
case VALUES:
convertValuesImpl(bb,(SqlCall)from,null);
return;
case UNNEST:
call=(SqlCall)from;
final List<SqlNode> nodes=call.getOperandList();
final SqlUnnestOperator operator=(SqlUnnestOperator)call.getOperator();
for (SqlNode node : nodes) {
replaceSubqueries(bb,node,RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
}
final List<RexNode> exprs=new ArrayList<>();
final List<String> fieldNames=new ArrayList<>();
for (Ord<SqlNode> node : Ord.zip(nodes)) {
exprs.add(bb.convertExpression(node.e));
fieldNames.add(validator.deriveAlias(node.e,node.i));
}
final RelNode input=RelOptUtil.createProject((null != bb.root) ? bb.root : LogicalValues.createOneRow(cluster),exprs,fieldNames,true);
Uncollect uncollect=new Uncollect(cluster,cluster.traitSetOf(Convention.NONE),input,operator.withOrdinality);
bb.setRoot(uncollect,true);
return;
case COLLECTION_TABLE:
call=(SqlCall)from;
assert call.getOperandList().size() == 1;
final SqlCall call2=call.operand(0);
convertCollectionTable(bb,call2);
return;
default :
throw Util.newInternal("not a join operator " + from);
}
}

protected void convertFrom ( Blackboard bb , SqlNode from ) { if ( from == null ) { bb . setRoot ( LogicalValues . createOneRow ( cluster ) , false ) ; return ; } final SqlCall call ; final SqlNode [ ] operands ; switch ( from . getKind ( ) ) { case AS : convertFrom ( bb , ( ( SqlCall ) from ) . operand ( 0 ) ) ; return ; case WITH_ITEM : convertFrom ( bb , ( ( SqlWithItem ) from ) . query ) ; return ; case WITH : convertFrom ( bb , ( ( SqlWith ) from ) . body ) ; return ; case TABLESAMPLE : operands = ( ( SqlBasicCall ) from ) . getOperands ( ) ; SqlSampleSpec sampleSpec = SqlLiteral . sampleValue ( operands [ 1 ] ) ; if ( sampleSpec instanceof SqlSampleSpec . SqlSubstitutionSampleSpec ) { String sampleName = ( ( SqlSampleSpec . SqlSubstitutionSampleSpec ) sampleSpec ) . getName ( ) ; datasetStack . push ( sampleName ) ; convertFrom ( bb , operands [ 0 ] ) ; datasetStack . pop ( ) ; } else if ( sampleSpec instanceof SqlSampleSpec . SqlTableSampleSpec ) { SqlSampleSpec . SqlTableSampleSpec tableSampleSpec = ( SqlSampleSpec . SqlTableSampleSpec ) sampleSpec ; convertFrom ( bb , operands [ 0 ] ) ; RelOptSamplingParameters params = new RelOptSamplingParameters ( tableSampleSpec . isBernoulli ( ) , tableSampleSpec . getSamplePercentage ( ) , tableSampleSpec . isRepeatable ( ) , tableSampleSpec . getRepeatableSeed ( ) ) ; bb . setRoot ( new Sample ( cluster , bb . root , params ) , false ) ; } else { throw Util . newInternal ( "unknown TABLESAMPLE type: " + sampleSpec ) ; } return ; case IDENTIFIER : final SqlValidatorNamespace fromNamespace = validator . getNamespace ( from ) . resolve ( ) ; if ( fromNamespace . getNode ( ) != null ) { convertFrom ( bb , fromNamespace . getNode ( ) ) ; return ; } final String datasetName = datasetStack . isEmpty ( ) ? null : datasetStack . peek ( ) ; boolean [ ] usedDataset = { false } ; RelOptTable table = SqlValidatorUtil . getRelOptTable ( fromNamespace , catalogReader , datasetName , usedDataset ) ; final RelNode tableRel ; if ( shouldConvertTableAccess ) { tableRel = toRel ( table ) ; } else { tableRel = LogicalTableScan . create ( cluster , table ) ; } bb . setRoot ( tableRel , true ) ; if ( usedDataset [ 0 ] ) { bb . setDataset ( datasetName ) ; } return ; case JOIN : final SqlJoin join = ( SqlJoin ) from ; final SqlValidatorScope scope = validator . getJoinScope ( from ) ; final Blackboard fromBlackboard = createBlackboard ( scope , null , false ) ; SqlNode left = join . getLeft ( ) ; SqlNode right = join . getRight ( ) ; final boolean isNatural = join . isNatural ( ) ; final JoinType joinType = join . getJoinType ( ) ; final SqlValidatorScope leftScope = Util . first ( validator . getJoinScope ( left ) , ( ( DelegatingScope ) bb . scope ) . getParent ( ) ) ; final Blackboard leftBlackboard = createBlackboard ( leftScope , null , false ) ; final SqlValidatorScope rightScope = Util . first ( validator . getJoinScope ( right ) , ( ( DelegatingScope ) bb . scope ) . getParent ( ) ) ; final Blackboard rightBlackboard = createBlackboard ( rightScope , null , false ) ; convertFrom ( leftBlackboard , left ) ; RelNode leftRel = leftBlackboard . root ; convertFrom ( rightBlackboard , right ) ; RelNode rightRel = rightBlackboard . root ; JoinRelType convertedJoinType = convertJoinType ( joinType ) ; RexNode conditionExp ; final SqlValidatorNamespace leftNamespace = validator . getNamespace ( left ) ; final SqlValidatorNamespace rightNamespace = validator . getNamespace ( right ) ; if ( isNatural ) { final RelDataType leftRowType = leftNamespace . getRowType ( ) ; final RelDataType rightRowType = rightNamespace . getRowType ( ) ; final List < String > columnList = SqlValidatorUtil . deriveNaturalJoinColumnList ( leftRowType , rightRowType ) ; conditionExp = convertUsing ( leftNamespace , rightNamespace , columnList ) ; } else { conditionExp = convertJoinCondition ( fromBlackboard , leftNamespace , rightNamespace , join . getCondition ( ) , join . getConditionType ( ) , leftRel , rightRel ) ; } final RelNode joinRel = createJoin ( fromBlackboard , leftRel , rightRel , conditionExp , convertedJoinType ) ; bb . setRoot ( joinRel , false ) ; return ; case SELECT : case INTERSECT : case EXCEPT : case UNION : final RelNode rel = convertQueryRecursive ( from , false , null ) . project ( ) ; bb . setRoot ( rel , true ) ; return ; case VALUES : convertValuesImpl ( bb , ( SqlCall ) from , null ) ; return ; case UNNEST : call = ( SqlCall ) from ; final List < SqlNode > nodes = call . getOperandList ( ) ; final SqlUnnestOperator operator = ( SqlUnnestOperator ) call . getOperator ( ) ; for ( SqlNode node : nodes ) { replaceSubqueries ( bb , node , RelOptUtil . Logic . TRUE_FALSE_UNKNOWN ) ; } final List < RexNode > exprs = new ArrayList < > ( ) ; final List < String > fieldNames = new ArrayList < > ( ) ; for ( Ord < SqlNode > node : Ord . zip ( nodes ) ) { exprs . add ( bb . convertExpression ( node . e ) ) ; fieldNames . add ( validator . deriveAlias ( node . e , node . i ) ) ; } final RelNode input = RelOptUtil . createProject ( ( null != bb . root ) ? bb . root : LogicalValues . createOneRow ( cluster ) , exprs , fieldNames , true ) ; Uncollect uncollect = new Uncollect ( cluster , cluster . traitSetOf ( Convention . NONE ) , input , operator . withOrdinality ) ; bb . setRoot ( uncollect , true ) ; return ; case COLLECTION_TABLE : call = ( SqlCall ) from ; assert call . getOperandList ( ) . size ( ) == 1 ; final SqlCall call2 = call . operand ( 0 ) ; convertCollectionTable ( bb , call2 ) ; return ; default : throw Util . newInternal ( "not a join operator " + from ) ; } }
converts a from clause into a relational expression .
