You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pig.apache.org by da...@apache.org on 2014/02/03 20:56:03 UTC

svn commit: r1564034 - in /pig/trunk: CHANGES.txt contrib/piggybank/java/src/main/java/org/apache/pig/piggybank/evaluation/string/Stuff.java contrib/piggybank/java/src/test/java/org/apache/pig/piggybank/test/evaluation/string/TestStuff.java

Author: daijy
Date: Mon Feb  3 19:56:03 2014
New Revision: 1564034

URL: http://svn.apache.org/r1564034
Log:
PIG-3238: Pig current releases lack a UDF Stuff(). This UDF deletes a specified length of characters and inserts another set of characters at a specified starting point

Added:
    pig/trunk/contrib/piggybank/java/src/main/java/org/apache/pig/piggybank/evaluation/string/Stuff.java
    pig/trunk/contrib/piggybank/java/src/test/java/org/apache/pig/piggybank/test/evaluation/string/TestStuff.java
Modified:
    pig/trunk/CHANGES.txt

Modified: pig/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/pig/trunk/CHANGES.txt?rev=1564034&r1=1564033&r2=1564034&view=diff
==============================================================================
--- pig/trunk/CHANGES.txt (original)
+++ pig/trunk/CHANGES.txt Mon Feb  3 19:56:03 2014
@@ -30,6 +30,9 @@ PIG-2207: Support custom counters for ag
 
 IMPROVEMENTS
 
+PIG-3238: Pig current releases lack a UDF Stuff(). This UDF deletes a specified length of characters
+ and inserts another set of characters at a specified starting point (nezihyigitbasi via daijy)
+
 PIG-3299: Provide support for LazyOutputFormat to avoid creating empty files (lbendig via daijy)
 
 PIG-3642: Direct HDFS access for small jobs (fetch) (lbendig via cheolsoo)

Added: pig/trunk/contrib/piggybank/java/src/main/java/org/apache/pig/piggybank/evaluation/string/Stuff.java
URL: http://svn.apache.org/viewvc/pig/trunk/contrib/piggybank/java/src/main/java/org/apache/pig/piggybank/evaluation/string/Stuff.java?rev=1564034&view=auto
==============================================================================
--- pig/trunk/contrib/piggybank/java/src/main/java/org/apache/pig/piggybank/evaluation/string/Stuff.java (added)
+++ pig/trunk/contrib/piggybank/java/src/main/java/org/apache/pig/piggybank/evaluation/string/Stuff.java Mon Feb  3 19:56:03 2014
@@ -0,0 +1,117 @@
+/*
+ * 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.pig.piggybank.evaluation.string;
+
+import java.io.IOException;
+
+import org.apache.pig.EvalFunc;
+import org.apache.pig.PigWarning;
+import org.apache.pig.data.DataType;
+import org.apache.pig.data.Tuple;
+import org.apache.pig.impl.logicalLayer.schema.Schema;
+
+/**
+ * Given a string, this UDF replaces a substring given its starting index and
+ * length with the given replacement string. If the the last argument is null, the specified
+ * part of the string gets deleted. 
+ * 
+ * B = FOREACH A GENERATE Stuff($0, 10, 4, 'Pie')
+ * If $0 is "Chocolate Cake" then the UDF will return "Chocolate Pie"
+ * 
+ **/
+
+public class Stuff extends EvalFunc<String> {
+
+	public String exec(Tuple input) throws IOException {
+		int inputSize = input.size();
+
+		if (input == null || inputSize == 0 || input.get(0) == null) {
+			warn("Null input", PigWarning.UDF_WARNING_1);
+			return null;
+		}
+
+		if (inputSize != 4) {
+			throw new IOException("Stuff requires 4 arguments");
+		}
+
+		String inString = (String) input.get(0);
+		
+		Integer startIndex = null;
+		Object inStartIndex = input.get(1);
+		//handle Double and Float
+		if(inStartIndex instanceof Number){
+			startIndex = ((Number)inStartIndex).intValue();
+		}else{
+			warn("Specified startIndex is of type " + inStartIndex.getClass().getName() + ", only Numbers are supported", PigWarning.UDF_WARNING_1);
+			return null;
+		}
+		
+		Integer length = null;
+		Object inLength = input.get(2);
+		
+		//handle Double and Float
+		if(inLength instanceof Number){
+			length = ((Number)inLength).intValue();
+		}else{
+			warn("Specified length is of type " + inLength.getClass().getName() + ", only Numbers are supported", PigWarning.UDF_WARNING_1);
+			return null;
+		}
+
+		String replacementString = (String) input.get(3);
+
+		int strLength = inString.length();
+		if (startIndex < 0 || startIndex >= strLength) {
+			throw new IOException("Given startIndex " + startIndex
+					+ " is out of bounds: [0," + strLength + ")");
+		}
+
+		if (length < 0) {
+			throw new IOException(
+					"The number of characters to delete cannot be negative");
+		}
+
+		StringBuffer result = new StringBuffer();
+
+		int upperBound = (startIndex + length > strLength) ? strLength
+				: startIndex + length;
+
+		for (int i = 0; i < strLength;) {
+			// need to replace these characters
+			if (i >= startIndex && i < upperBound) {
+				if(replacementString != null)
+					result.append(replacementString);
+				i += length;
+			} else {
+				result.append(inString.charAt(i));
+				i++;
+			}
+		}
+
+		return result.toString();
+	}
+
+	/**
+	 * @param input
+	 *            , schema of the input data
+	 * @return output schema
+	 */
+	@Override
+	public Schema outputSchema(Schema input) {
+		return new Schema(new Schema.FieldSchema(null, DataType.CHARARRAY));
+	}
+}

Added: pig/trunk/contrib/piggybank/java/src/test/java/org/apache/pig/piggybank/test/evaluation/string/TestStuff.java
URL: http://svn.apache.org/viewvc/pig/trunk/contrib/piggybank/java/src/test/java/org/apache/pig/piggybank/test/evaluation/string/TestStuff.java?rev=1564034&view=auto
==============================================================================
--- pig/trunk/contrib/piggybank/java/src/test/java/org/apache/pig/piggybank/test/evaluation/string/TestStuff.java (added)
+++ pig/trunk/contrib/piggybank/java/src/test/java/org/apache/pig/piggybank/test/evaluation/string/TestStuff.java Mon Feb  3 19:56:03 2014
@@ -0,0 +1,124 @@
+/*
+ * 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.pig.piggybank.test.evaluation.string;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import java.io.IOException;
+
+import org.apache.pig.data.Tuple;
+import org.apache.pig.data.TupleFactory;
+import org.apache.pig.piggybank.evaluation.string.Stuff;
+import org.junit.Test;
+
+public class TestStuff {
+
+	Stuff udf = new Stuff();
+
+	@Test
+	public void test() throws IOException {
+		Tuple tupleWithNullElement = TupleFactory.getInstance().newTuple(1);
+		String result = udf.exec(tupleWithNullElement);
+		assertNull(result);
+
+		Tuple t = TupleFactory.getInstance().newTuple(4);
+		t.set(0, "Chocolate Cake");
+		t.set(1, 10);
+		t.set(2, 4);
+		t.set(3, "Pie");
+		result = udf.exec(t);
+		assertEquals("Chocolate Pie", result);
+
+		t.set(0, "Old Zealand");
+		t.set(1, 0);
+		t.set(2, 3);
+		t.set(3, "New");
+		result = udf.exec(t);
+		assertEquals("New Zealand", result);
+
+		t.set(0, "Take a look");
+		t.set(1, 5);
+		t.set(2, 1);
+		t.set(3, "b");
+		result = udf.exec(t);
+		assertEquals("Take b look", result);
+
+		t.set(0, "Take a look");
+		t.set(1, 5);
+		t.set(2, 6);// replace until the end
+		t.set(3, "b");
+		result = udf.exec(t);
+		assertEquals("Take b", result);
+
+		t.set(0, "Take a look");
+		t.set(1, 4);
+		t.set(2, 7);// replace until the end
+		t.set(3, null);// delete the specified portion
+		result = udf.exec(t);
+		assertEquals("Take", result);
+
+	}
+
+	@Test(expected = IOException.class)
+	public void testArgumentCountMismatch() throws IOException {
+		Tuple t = TupleFactory.getInstance().newTuple(1);
+		t.set(0, "some_val");
+		udf.exec(t);
+	}
+
+	@Test(expected = IOException.class)
+	public void testIndexOutOfBounds() throws IOException {
+		Tuple t = TupleFactory.getInstance().newTuple(4);
+		t.set(0, "Replace me now!");
+		t.set(1, -1);
+		t.set(2, 2);
+		t.set(3, "test");
+		udf.exec(t);
+	}
+
+	@Test(expected = IOException.class)
+	public void testNegativeNumCharsToDelete() throws IOException {
+		Tuple t = TupleFactory.getInstance().newTuple(4);
+		t.set(0, "Replace me now!");
+		t.set(1, 0);
+		t.set(2, -2);
+		t.set(3, "test");
+		udf.exec(t);
+	}
+
+	@Test
+	public void testWithOtherTypes() throws IOException {
+		Tuple t = TupleFactory.getInstance().newTuple(4);
+		t.set(0, "Replace me now!");
+		t.set(1, new Double(8));
+		t.set(2, 2);
+		t.set(3, "ZZ");
+		String result = udf.exec(t);
+		assertEquals("Replace ZZ now!", result);
+
+		t = TupleFactory.getInstance().newTuple(4);
+		t.set(0, "Replace me now!");
+		t.set(1, new Float(14));
+		t.set(2, 1);
+		t.set(3, ";");
+		result = udf.exec(t);
+		assertEquals("Replace me now;", result);
+	}
+}