there's been some discussion about this: http://issues.apache.org/jira/browse/THRIFT-409
On Sun, Apr 12, 2009 at 2:40 PM, Debacker <[email protected]> wrote: > Hi, > > I recently came across a problem which could be nicely implemented if union > were supported. Let's suppose that you want to create a method to query > objects based on several fields. The problem is that for string fields for > example, you may want to do a range query, or a fulltext search query. Thus > you would created the following two structs to represent that: > > struct StringRangeFilter { string minValue, string maxValue } > struct StringSearchFilter { string expression } > > The problem is that the caller need to use only one, not both. What I > propose would be this: > > union StringFilter { > 1:StringRangeFilter rangeFilter, > 2:StringSearchFilter searchFilter, > } > > When sending such an object over the wire, we could write the id number > first, followed by the binary form of the field that is used. With unions, > the method signature could be: > > query(1:StringFilter nameFilter, 2:StringFilter descriptionFilter) > > The binary format would be efficient (more efficient than sending two > structs, and using only one at least). But still we would need a nice API > for client and server. > > What we could do for Java-like languages is: > > class StringFilter { > int id; > Object data; > > void setRangeFilter(StringRangeFilter rangeFilter) { id = 1; data = > rangeFilter; } > void setSearchFilter(StringSearchFilter searchFilter) { id = 2; data = > searchFilter; } > > int getID() { return id; } > > StringRangeFilter getRangeFilter() { > if(id != 1) throw .... > return (StringRangeFilter)data; > } > > StringSearchFilter getSearchFilter() { > if(id != 2) throw .... > return (StringSearchFilter)data; > } > } > > The reader can use the getID method to know the data type. If we don't want > the developer to care about the ID, we could use the visitor pattern: > > interface StringFilterVisitor { > void visitStringRangeFilter(StringRangeFilter rangeFilter); > void visitStringSearchFilter(StringSearchFilter searchFilter); > void other(); > } > > and add the following method to StringFilter: > > void accept(StringFilterVisitor visitor) { > switch(id) { > case 1: visitor.visitStringRangeFilter((StringRangeFilter)data); > break; > case 2: visitor.visitStringSearchFilter((StringSearchFilter)data); > break; > default: visitor.other(); break; > } > } > > I think that the ID use fits nicely with the style of Thrift. However, I > understand that not many poeple would be willing to change the binary > protocol. But I would like to start the debate :) > > Laurent Debacker. >
