Ryan, your fix implementation looks ok, except that copyFixups I would change to:
private static void copyFixups(List<Fixup> fixups, Symbol[] out, int outPos, Symbol[] toCopy) { final int nrFixups = fixups.size(); for (int i = 0; i < nrFixups; i++) { Fixup fixup = fixups.get(i); if (fixup.symbols == toCopy) { fixups.add(new Fixup(out, fixup.pos + outPos)); } } } this should be less error prone and slightly faster. let me know if you have any questions. —Z > On Mar 7, 2016, at 11:46 AM, Ryan Blue (JIRA) <j...@apache.org> wrote: > > > [ > https://issues.apache.org/jira/browse/AVRO-1667?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15183246#comment-15183246 > ] > > Ryan Blue commented on AVRO-1667: > --------------------------------- > > We just need a fixup that applies to a production that gets copied twice. I > think a recursive binary tree structure would do it, where each node has > optional left and right child nodes. > >> Parser symbol tree flattening is broken for recursive schemas >> ------------------------------------------------------------- >> >> Key: AVRO-1667 >> URL: https://issues.apache.org/jira/browse/AVRO-1667 >> Project: Avro >> Issue Type: Bug >> Affects Versions: 1.7.7 >> Reporter: Zoltan Farkas >> Attachments: AVRO-1667.2.patch, avro-1667.patch >> >> >> Here is a unit test to reproduce: >> {noformat} >> package org.apache.avro.io.parsing; >> import java.io.IOException; >> import java.util.HashMap; >> import java.util.HashSet; >> import java.util.Set; >> import junit.framework.Assert; >> import org.apache.avro.Schema; >> import org.junit.Test; >> public class SymbolTest { >> private static final String SCHEMA = >> "{\"type\":\"record\",\"name\":\"SampleNode\"," >> + "\"namespace\":\"org.spf4j.ssdump2.avro\",\n" + >> " \"fields\":[\n" + >> " {\"name\":\"count\",\"type\":\"int\",\"default\":0},\n" + >> " {\"name\":\"subNodes\",\"type\":\n" + >> " {\"type\":\"array\",\"items\":{\n" + >> " \"type\":\"record\",\"name\":\"SamplePair\",\n" + >> " \"fields\":[\n" + >> " {\"name\":\"method\",\"type\":\n" + >> " {\"type\":\"record\",\"name\":\"Method\",\n" + >> " \"fields\":[\n" + >> " >> {\"name\":\"declaringClass\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},\n" >> + >> " >> {\"name\":\"methodName\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}}\n" >> + >> " ]}},\n" + >> " {\"name\":\"node\",\"type\":\"SampleNode\"}]}}}]}"; >> @Test >> public void testSomeMethod() throws IOException { >> Schema schema = new Schema.Parser().parse(SCHEMA); >> Symbol root = Symbol.root(new ResolvingGrammarGenerator() >> .generate(schema, schema, new >> HashMap<ValidatingGrammarGenerator.LitS, Symbol>())); >> validateNonNull(root, new HashSet<Symbol>()); >> } >> private static void validateNonNull(final Symbol symb, Set<Symbol> seen) { >> if (seen.contains(symb)) { >> return; >> } else { >> seen.add(symb); >> } >> if (symb.production != null) { >> for (Symbol s : symb.production) { >> if (s == null) { >> Assert.fail("invalid parsing tree should not contain >> nulls"); >> } >> if (s.kind != Symbol.Kind.ROOT) { >> validateNonNull(s, seen);; >> } >> } >> } >> } >> } >> {noformat} > > > > -- > This message was sent by Atlassian JIRA > (v6.3.4#6332)