/** * Determines if a projection is simple. * * @param calcRel CalcRel containing the projection * @param projOrdinals if the projection is simple, returns the ordinals of the projection inputs * @return rowtype corresponding to the projection, provided it is simple; otherwise null is * returned */ private RelDataType isProjectSimple(CalcRel calcRel, List<Integer> projOrdinals) { // Loop through projection expressions. If we find a non-simple // projection expression, simply return. RexProgram program = calcRel.getProgram(); List<RexLocalRef> projList = program.getProjectList(); int nProjExprs = projList.size(); RelDataType[] types = new RelDataType[nProjExprs]; String[] fieldNames = new String[nProjExprs]; RelDataTypeField[] projFields = calcRel.getRowType().getFields(); for (int i = 0; i < nProjExprs; i++) { RexNode projExpr = program.expandLocalRef(projList.get(i)); if (projExpr instanceof RexInputRef) { projOrdinals.add(((RexInputRef) projExpr).getIndex()); types[i] = projExpr.getType(); fieldNames[i] = projFields[i].getName(); continue; } else if (!(projExpr instanceof RexCall)) { return null; } RexCall rexCall = (RexCall) projExpr; if (rexCall.getOperator() != SqlStdOperatorTable.castFunc) { return null; } RexNode castOperand = rexCall.getOperands()[0]; if (!(castOperand instanceof RexInputRef)) { return null; } RelDataType castType = projExpr.getType(); RelDataType origType = castOperand.getType(); if (isCastSimple(origType, castType)) { projOrdinals.add(((RexInputRef) castOperand).getIndex()); types[i] = castType; fieldNames[i] = projFields[i].getName(); } else { return null; } } // return the rowtype corresponding to the output of the projection return calcRel.getCluster().getTypeFactory().createStructType(types, fieldNames); }