public String generateSql() {
    SqlDialect dialect = getJdbcDialect();
    final HiveJdbcImplementor jdbcImplementor =
        new HiveJdbcImplementor(dialect,
            (JavaTypeFactory) getCluster().getTypeFactory());
    Project topProject;
    if (getInput() instanceof Project) {
      topProject = (Project) getInput();
    } else {
      // If it is not a project operator, we add it on top of the input
      // to force generating the column names instead of * while
      // translating to SQL
      RelNode nodeToTranslate = getInput();
      RexBuilder builder = getCluster().getRexBuilder();
      List<RexNode> projects = new ArrayList<>(
          nodeToTranslate.getRowType().getFieldList().size());
      for (int i = 0; i < nodeToTranslate.getRowType().getFieldCount(); i++) {
        projects.add(builder.makeInputRef(nodeToTranslate, i));
      }
      topProject = new JdbcProject(nodeToTranslate.getCluster(),
          nodeToTranslate.getTraitSet(), nodeToTranslate,
          projects, nodeToTranslate.getRowType());
    }
    final HiveJdbcImplementor.Result result =
        jdbcImplementor.visitRoot(topProject);
    return result.asStatement().toSqlString(dialect).getSql();
  }
This is a designated RelNode that splits the Hive operators and the Jdbc operators,
every successor of this node will be Jdbc operator.
ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/reloperators/jdbc/HiveJdbcConverter.java