diff --git a/bin/interpreter.sh b/bin/interpreter.sh
index a81c8f21067..4fb4b269265 100755
--- a/bin/interpreter.sh
+++ b/bin/interpreter.sh
@@ -149,6 +149,28 @@ elif [[ "${INTERPRETER_ID}" == "hbase" ]]; then
else
echo "HBASE_HOME and HBASE_CONF_DIR are not set, configuration might not be loaded"
fi
+elif [[ "${INTERPRETER_ID}" == "pig" ]]; then
+ # autodetect HADOOP_CONF_HOME by heuristic
+ if [[ -n "${HADOOP_HOME}" ]] && [[ -z "${HADOOP_CONF_DIR}" ]]; then
+ if [[ -d "${HADOOP_HOME}/etc/hadoop" ]]; then
+ export HADOOP_CONF_DIR="${HADOOP_HOME}/etc/hadoop"
+ elif [[ -d "/etc/hadoop/conf" ]]; then
+ export HADOOP_CONF_DIR="/etc/hadoop/conf"
+ fi
+ fi
+
+ if [[ -n "${HADOOP_CONF_DIR}" ]] && [[ -d "${HADOOP_CONF_DIR}" ]]; then
+ ZEPPELIN_INTP_CLASSPATH+=":${HADOOP_CONF_DIR}"
+ fi
+
+ # autodetect TEZ_CONF_DIR
+ if [[ -n "${TEZ_CONF_DIR}" ]]; then
+ ZEPPELIN_INTP_CLASSPATH+=":${TEZ_CONF_DIR}"
+ elif [[ -d "/etc/tez/conf" ]]; then
+ ZEPPELIN_INTP_CLASSPATH+=":/etc/tez/conf"
+ else
+ echo "TEZ_CONF_DIR is not set, configuration might not be loaded"
+ fi
fi
addJarInDirForIntp "${LOCAL_INTERPRETER_REPO}"
diff --git a/conf/interpreter-list b/conf/interpreter-list
index 098b3c6c188..38cb386d8cd 100644
--- a/conf/interpreter-list
+++ b/conf/interpreter-list
@@ -32,6 +32,7 @@ kylin org.apache.zeppelin:zeppelin-kylin:0.6.1 Kylin in
lens org.apache.zeppelin:zeppelin-lens:0.6.1 Lens interpreter
livy org.apache.zeppelin:zeppelin-livy:0.6.1 Livy interpreter
md org.apache.zeppelin:zeppelin-markdown:0.6.1 Markdown support
+pig org.apache.zeppelin:zeppelin-pig:0.6.1 Pig interpreter
postgresql org.apache.zeppelin:zeppelin-postgresql:0.6.1 Postgresql interpreter
python org.apache.zeppelin:zeppelin-python:0.6.1 Python interpreter
shell org.apache.zeppelin:zeppelin-shell:0.6.1 Shell command
diff --git a/conf/zeppelin-site.xml.template b/conf/zeppelin-site.xml.template
index 05bd7195277..c4b369c301c 100755
--- a/conf/zeppelin-site.xml.template
+++ b/conf/zeppelin-site.xml.template
@@ -190,7 +190,7 @@
| Property | +Default | +Description | +
|---|---|---|
| zeppelin.pig.execType | +mapreduce | +Execution mode for pig runtime. local | mapreduce | tez | +
| zeppelin.pig.includeJobStats | +false | +whether display jobStats info in %pig.script |
+
| zeppelin.pig.maxResult | +1000 | +max row number displayed in %pig.query |
+
+ * 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 org.apache.zeppelin.pig; + +import org.apache.commons.io.IOUtils; +import org.apache.zeppelin.interpreter.InterpreterContext; +import org.apache.zeppelin.interpreter.InterpreterResult; +import org.apache.zeppelin.interpreter.InterpreterResult.Code; +import org.apache.zeppelin.interpreter.InterpreterResult.Type; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class PigInterpreterTest { + + private PigInterpreter pigInterpreter; + private InterpreterContext context; + + @Before + public void setUp() { + Properties properties = new Properties(); + properties.put("zeppelin.pig.execType", "local"); + pigInterpreter = new PigInterpreter(properties); + pigInterpreter.open(); + context = new InterpreterContext(null, "paragraph_id", null, null, null, null, null, null, null, + null, null); + } + + @After + public void tearDown() { + pigInterpreter.close(); + } + + @Test + public void testBasics() throws IOException { + String content = "1\tandy\n" + + "2\tpeter\n"; + File tmpFile = File.createTempFile("zeppelin", "test"); + FileWriter writer = new FileWriter(tmpFile); + IOUtils.write(content, writer); + writer.close(); + + // simple pig script using dump + String pigscript = "a = load '" + tmpFile.getAbsolutePath() + "';" + + "dump a;"; + InterpreterResult result = pigInterpreter.interpret(pigscript, context); + assertEquals(Type.TEXT, result.type()); + assertEquals(Code.SUCCESS, result.code()); + assertTrue(result.message().contains("(1,andy)\n(2,peter)")); + + // describe + pigscript = "a = load '" + tmpFile.getAbsolutePath() + "' as (id: int, name: bytearray);" + + "describe a;"; + result = pigInterpreter.interpret(pigscript, context); + assertEquals(Type.TEXT, result.type()); + assertEquals(Code.SUCCESS, result.code()); + assertTrue(result.message().contains("a: {id: int,name: bytearray}")); + + // syntax error (compilation error) + pigscript = "a = loa '" + tmpFile.getAbsolutePath() + "';" + + "describe a;"; + result = pigInterpreter.interpret(pigscript, context); + assertEquals(Type.TEXT, result.type()); + assertEquals(Code.ERROR, result.code()); + assertTrue(result.message().contains("Syntax error, unexpected symbol at or near 'a'")); + + // execution error + pigscript = "a = load 'invalid_path';" + + "dump a;"; + result = pigInterpreter.interpret(pigscript, context); + assertEquals(Type.TEXT, result.type()); + assertEquals(Code.ERROR, result.code()); + assertTrue(result.message().contains("Input path does not exist")); + } + + + @Test + public void testIncludeJobStats() throws IOException { + Properties properties = new Properties(); + properties.put("zeppelin.pig.execType", "local"); + properties.put("zeppelin.pig.includeJobStats", "true"); + pigInterpreter = new PigInterpreter(properties); + pigInterpreter.open(); + + String content = "1\tandy\n" + + "2\tpeter\n"; + File tmpFile = File.createTempFile("zeppelin", "test"); + FileWriter writer = new FileWriter(tmpFile); + IOUtils.write(content, writer); + writer.close(); + + // simple pig script using dump + String pigscript = "a = load '" + tmpFile.getAbsolutePath() + "';" + + "dump a;"; + InterpreterResult result = pigInterpreter.interpret(pigscript, context); + assertEquals(Type.TEXT, result.type()); + assertEquals(Code.SUCCESS, result.code()); + assertTrue(result.message().contains("Counters:")); + assertTrue(result.message().contains("(1,andy)\n(2,peter)")); + + // describe + pigscript = "a = load '" + tmpFile.getAbsolutePath() + "' as (id: int, name: bytearray);" + + "describe a;"; + result = pigInterpreter.interpret(pigscript, context); + assertEquals(Type.TEXT, result.type()); + assertEquals(Code.SUCCESS, result.code()); + // no job is launched, so no jobStats + assertTrue(!result.message().contains("Counters:")); + assertTrue(result.message().contains("a: {id: int,name: bytearray}")); + + // syntax error (compilation error) + pigscript = "a = loa '" + tmpFile.getAbsolutePath() + "';" + + "describe a;"; + result = pigInterpreter.interpret(pigscript, context); + assertEquals(Type.TEXT, result.type()); + assertEquals(Code.ERROR, result.code()); + // no job is launched, so no jobStats + assertTrue(!result.message().contains("Counters:")); + assertTrue(result.message().contains("Syntax error, unexpected symbol at or near 'a'")); + + // execution error + pigscript = "a = load 'invalid_path';" + + "dump a;"; + result = pigInterpreter.interpret(pigscript, context); + assertEquals(Type.TEXT, result.type()); + assertEquals(Code.ERROR, result.code()); + assertTrue(result.message().contains("Counters:")); + assertTrue(result.message().contains("Input path does not exist")); + } +} diff --git a/pig/src/test/java/org/apache/zeppelin/pig/PigQueryInterpreterTest.java b/pig/src/test/java/org/apache/zeppelin/pig/PigQueryInterpreterTest.java new file mode 100644 index 00000000000..00ece440542 --- /dev/null +++ b/pig/src/test/java/org/apache/zeppelin/pig/PigQueryInterpreterTest.java @@ -0,0 +1,153 @@ +/** + * 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 org.apache.zeppelin.pig;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.zeppelin.interpreter.Interpreter;
+import org.apache.zeppelin.interpreter.InterpreterContext;
+import org.apache.zeppelin.interpreter.InterpreterGroup;
+import org.apache.zeppelin.interpreter.InterpreterResult;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ *
+ */
+public class PigQueryInterpreterTest {
+
+ private PigInterpreter pigInterpreter;
+ private PigQueryInterpreter pigQueryInterpreter;
+ private InterpreterContext context;
+
+ @Before
+ public void setUp() {
+ Properties properties = new Properties();
+ properties.put("zeppelin.pig.execType", "local");
+ properties.put("zeppelin.pig.maxResult", "20");
+
+ pigInterpreter = new PigInterpreter(properties);
+ pigQueryInterpreter = new PigQueryInterpreter(properties);
+ List