PIG-4880: Overlapping of parameter substitution names inside&outside a macro fails with NPE (knoguchi)
git-svn-id: https://svn.apache.org/repos/asf/pig/trunk@1743527 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/CHANGES.txt b/CHANGES.txt
index 16a5301..cfc219c 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -119,6 +119,8 @@
BUG FIXES
+PIG-4880: Overlapping of parameter substitution names inside&outside a macro fails with NPE (knoguchi)
+
PIG-4881: TestBuiltin.testUniqueID failing on hadoop-1.x (knoguchi)
PIG-4888: Line number off when reporting syntax error inside a macro (knoguchi)
diff --git a/src/org/apache/pig/parser/PigMacro.java b/src/org/apache/pig/parser/PigMacro.java
index dc277ab..1f84af4 100644
--- a/src/org/apache/pig/parser/PigMacro.java
+++ b/src/org/apache/pig/parser/PigMacro.java
@@ -168,14 +168,9 @@
Map<String, String> paramVal = pc.getParamVal();
for (Map.Entry<String, String> e : pigContext.getParamVal().entrySet()) {
- if (paramVal.containsKey(e.getKey())) {
- throw new ParserException(
- "Macro contains argument or return value " + e.getKey() + " which conflicts " +
- "with a Pig parameter of the same name."
- );
- } else {
- paramVal.put(e.getKey(), e.getValue());
- }
+ // overwrite=false since macro parameters should have precedence
+ // over commandline parameters (if keys overlap)
+ pc.processOrdLine(e.getKey(), e.getValue(), false);
}
ParameterSubstitutionPreprocessor psp = new ParameterSubstitutionPreprocessor(pc);
diff --git a/test/org/apache/pig/test/TestMacroExpansion.java b/test/org/apache/pig/test/TestMacroExpansion.java
index 99c405a..0328b07 100644
--- a/test/org/apache/pig/test/TestMacroExpansion.java
+++ b/test/org/apache/pig/test/TestMacroExpansion.java
@@ -2280,6 +2280,135 @@
verify(script, expected);
}
+ // When declare-in-macro, macro param and command-line param contain the
+ // same name, last declare wins
+ @Test
+ public void testParamOverLap1() throws Exception {
+ String macro =
+ "DEFINE mygroupby(REL, key, number) RETURNS G {\n" +
+ " %declare number 333;\n" +
+ " $G = GROUP $REL by $key parallel $number;\n" +
+ "};";
+ createFile("my_macro.pig", macro);
+
+ String script =
+ "%declare number 111;\n" +
+ "IMPORT 'my_macro.pig';\n" +
+ "data = LOAD '1234.txt' USING PigStorage() AS (i: int);\n" +
+ "result = mygroupby(data, i, 222);\n" +
+ "STORE result INTO 'test.out' USING PigStorage();";
+
+ String expected =
+ "data = LOAD '1234.txt' USING PigStorage() AS i:int;\n" +
+ "result = GROUP data by (i) parallel 333;\n" +
+ "STORE result INTO 'test.out' USING PigStorage();\n";
+
+ verify(script, expected);
+ }
+
+ // When default-in-macro, macro param and command-line param contain the
+ // same name, then default should be ignored and macro param to be taken
+ @Test
+ public void testParamOverLap2() throws Exception {
+ String macro =
+ "DEFINE mygroupby(REL, key, number) RETURNS G {\n" +
+ " %default number 333;\n" +
+ " $G = GROUP $REL by $key parallel $number;\n" +
+ "};";
+ createFile("my_macro.pig", macro);
+
+ String script =
+ "%declare number 111;\n" +
+ "IMPORT 'my_macro.pig';\n" +
+ "data = LOAD '1234.txt' USING PigStorage() AS (i: int);\n" +
+ "result = mygroupby(data, i, 222);\n" +
+ "STORE result INTO 'test.out' USING PigStorage();";
+
+ String expected =
+ "data = LOAD '1234.txt' USING PigStorage() AS i:int;\n" +
+ "result = GROUP data by (i) parallel 222;\n" +
+ "STORE result INTO 'test.out' USING PigStorage();\n";
+
+ verify(script, expected);
+ }
+
+ // Overlapping of macro param and command-line param used to be disallowed.
+ // Now, simply taking the macro param when this happens
+ @Test
+ public void testParamOverLap3() throws Exception {
+ String macro =
+ "DEFINE mygroupby(REL, key, number) RETURNS G {\n" +
+ " $G = GROUP $REL by $key parallel $number;\n" +
+ "};";
+ createFile("my_macro.pig", macro);
+
+ String script =
+ "%default number 111;\n" +
+ "IMPORT 'my_macro.pig';\n" +
+ "data = LOAD '1234.txt' USING PigStorage() AS (i: int);\n" +
+ "result = mygroupby(data, i, 222);\n" +
+ "STORE result INTO 'test.out' USING PigStorage();";
+
+ String expected =
+ "data = LOAD '1234.txt' USING PigStorage() AS i:int;\n" +
+ "result = GROUP data by (i) parallel 222;\n" +
+ "STORE result INTO 'test.out' USING PigStorage();\n";
+
+ verify(script, expected);
+ }
+
+ // Testing inline declare and commandline param overlap.
+ // testParamOverLap1 should cover this case as well but creating a specific
+ // case since this pair used to fail with NPE
+ @Test
+ public void testParamOverLap4() throws Exception {
+ String macro =
+ "DEFINE mygroupby(REL, key) RETURNS G {\n" +
+ " %declare number 333;\n" +
+ " $G = GROUP $REL by $key parallel $number;\n" +
+ "};";
+ createFile("my_macro.pig", macro);
+
+ String script =
+ "%default number 111;\n" +
+ "IMPORT 'my_macro.pig';\n" +
+ "data = LOAD '1234.txt' USING PigStorage() AS (i: int);\n" +
+ "result = mygroupby(data, i);\n" +
+ "STORE result INTO 'test.out' USING PigStorage();";
+
+ String expected =
+ "data = LOAD '1234.txt' USING PigStorage() AS i:int;\n" +
+ "result = GROUP data by (i) parallel 333;\n" +
+ "STORE result INTO 'test.out' USING PigStorage();\n";
+
+ verify(script, expected);
+ }
+
+ // default-in-macro should yield to command-line param
+ @Test
+ public void testParamOverLap5() throws Exception {
+ String macro =
+ "DEFINE mygroupby(REL, key) RETURNS G {\n" +
+ " %default number 333;\n" +
+ " $G = GROUP $REL by $key parallel $number;\n" +
+ "};";
+ createFile("my_macro.pig", macro);
+
+ String script =
+ "%declare number 111;\n" +
+ "IMPORT 'my_macro.pig';\n" +
+ "data = LOAD '1234.txt' USING PigStorage() AS (i: int);\n" +
+ "result = mygroupby(data, i);\n" +
+ "STORE result INTO 'test.out' USING PigStorage();";
+
+ String expected =
+ "data = LOAD '1234.txt' USING PigStorage() AS i:int;\n" +
+ "result = GROUP data by (i) parallel 111;\n" +
+ "STORE result INTO 'test.out' USING PigStorage();\n";
+
+ verify(script, expected);
+ }
+
//-------------------------------------------------------------------------
private void testMacro(String content) throws Exception {