All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.aliyun.odps.mapred.bridge.sqlgen.SqlGenerator Maven / Gradle / Ivy

There is a newer version: 0.52.1-public
Show newest version
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package com.aliyun.odps.mapred.bridge.sqlgen;

import java.io.StringWriter;
import java.util.Arrays;
import java.util.Map;
import java.util.Properties;

import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;

import com.aliyun.odps.OdpsException;
import com.aliyun.odps.data.VolumeInfo;
import com.aliyun.odps.mapred.bridge.MetaExplorer;
import com.aliyun.odps.mapred.conf.BridgeJobConf;
import com.aliyun.odps.mapred.conf.JobConf;
import com.aliyun.odps.mapred.conf.SessionState;
import com.aliyun.odps.mapred.utils.InputUtils;
import com.aliyun.odps.mapred.utils.OutputUtils;
import com.aliyun.odps.pipeline.Pipeline;


public class SqlGenerator {

  public static String generate(JobConf job, String id, MetaExplorer metaExplorer, Map aliasToTempResource) {
    createFunction((BridgeJobConf) job, id, aliasToTempResource);
    Properties p = new Properties();
    p.setProperty("resource.loader", "class");
    p.setProperty("class.resource.loader.class",
                  "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
    Velocity.init(p);

    VelocityContext context = new VelocityContext();

    Template template = null;

    try {
      String vm = "sql";
      Pipeline pipeline = null;
      if (job.isStreamJob()) {
        vm = "stream";
      } else if (job.isPipeline()) {
        pipeline = Pipeline.fromJobConf(job);
        assert pipeline != null;
        context.put("pipes", pipeline.getNodes());
        vm = "pl";
      }

      context.put("ctx", new SqlGenContext(job, id, pipeline));
      if (!job.getBoolean("odps.optimizer.cbo.remove.shuffle", false)) {
        job.setBoolean("odps.optimizer.cbo.remove.shuffle", false);
      }
      if (!job.getBoolean("odps.optimizer.cbo.enable.dynamic.parallelism", false)) {
        job.setBoolean("odps.optimizer.cbo.enable.dynamic.parallelism", false);
      }
      template = Velocity.getTemplate(String.format("%s.vm", vm));
    } catch (ResourceNotFoundException e) {
      // couldn't find the template
      throw new RuntimeException(e);
    } catch (ParseErrorException e) {
      // syntax error: problem parsing the template
      throw new RuntimeException(e);
    } catch (MethodInvocationException e) {
      // something invoked in the template
      // threw an exception
      throw new RuntimeException(e);
    }

    StringWriter sw = new StringWriter();
    template.merge(context, sw);
    return sw.toString();
  }

  static void createFunction(BridgeJobConf job, String jobId, Map aliasToTempResource) {
    StringBuilder resouceText = new StringBuilder();
    StringBuilder createText = new StringBuilder();
    for (String s :job.getFunctionResources()){
      resouceText.append(s).append(",");
    }
    if (job.isStreamJob()) {
      if (job.getResources() != null && aliasToTempResource != null) {
        for (String s : job.getResources()) {
          if (!aliasToTempResource.containsKey(s)) {
            resouceText.append(s).append(",");
          }
        }
      }
      resouceText.deleteCharAt(resouceText.lastIndexOf(","));
      createText.append(String.format("set %s=", SessionState.MR_EXECUTION_SESSION_RESOURCES));
      if (job.get(SessionState.MR_EXECUTION_SESSION_RESOURCES) != null) {
        createText.append(String.format("%s,", job.get(SessionState.MR_EXECUTION_SESSION_RESOURCES)));
      }
      createText.append(String.format("%s;\n", resouceText.toString()));
      job.setFunctionCreateText(createText.toString());
      return;
    }
    for (String s : job.getResources()) {
      if (!aliasToTempResource.keySet().contains(s)) {
        resouceText.append(s).append(",");
      }
    }
    resouceText.deleteCharAt(resouceText.lastIndexOf(","));
    if (job.isPipeline()) {
      int index = 0;
      Pipeline pipeline = Pipeline.fromJobConf(job);
      for (Pipeline.TransformNode node: pipeline.getNodes()) {
        if ("map".equals(node.getType())) {
          createText.append(String.format("create temporary function mr2sql_mapper_%s_%d  as 'com.aliyun.odps.mapred.bridge.LotMapperUDTF' using '%s';\n", jobId, index, resouceText.toString()));
        } else {
          createText.append(String.format("create temporary function mr2sql_reducer_%s_%d  as 'com.aliyun.odps.mapred.bridge.LotReducerUDTF' using '%s';\n", jobId, index, resouceText.toString()));
        }
        index ++ ;
      }
    } else {
      createText.append(String.format("create temporary function mr2sql_mapper_%s as 'com.aliyun.odps.mapred.bridge.LotMapperUDTF' using '%s';\n", jobId, resouceText.toString()));
      if (job.getNumReduceTasks() > 0) {
        createText.append(String.format("create temporary function mr2sql_reducer_%s as 'com.aliyun.odps.mapred.bridge.LotReducerUDTF' using '%s';\n", jobId, resouceText.toString()));
      }
    }
    job.setFunctionCreateText(createText.toString());

    for (String type : Arrays.asList("input", "output")) {
      VolumeInfo[] volumeInfos = type.equals("input") ?  InputUtils.getVolumes(job) : OutputUtils.getVolumes(job);
      if (volumeInfos != null && volumeInfos.length > 0) {
        StringBuilder vols = new StringBuilder();
        for (VolumeInfo vol : volumeInfos) {
          vols.append(vol.toString());
          if (vol.getLabel() != null) {
            vols.append(':').append(vol.getLabel());
          }
          vols.append(",");
        }
        vols.deleteCharAt(vols.lastIndexOf(","));
        job.set(String.format("odps.sql.volume.%s", type), vols.toString());
      }
    }
  }

  /**
   * 返回sql run模式
   *
   * @return true如果符合sql run模式
   */
  static boolean isSqlMode(JobConf job, MetaExplorer metaExplorer) {
    if (System.getProperty(SessionState.MR_EXECUTION_MODE, "lot").equalsIgnoreCase("sql")) {
      return true;
    }
    String mode = job.get(SessionState.MR_EXECUTION_MODE);
    if (mode != null) {
      if (mode.equalsIgnoreCase("lot")) {
        return false;
      } else {
        return true;
      }
    }
    try {
      mode = metaExplorer.getProjectProperty(SessionState.MR_EXECUTION_MODE);
      if (mode != null && (mode.equalsIgnoreCase("sql") || mode.equalsIgnoreCase("hybrid"))) {
        return true;
      }
    } catch (OdpsException e) {
      e.printStackTrace();
      return false;
    }
    return false;
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy