def tab_join(ToMerge, keycols=None, nullvals=None, renamer=None,<EOL>returnrenaming=False, Names=None):
[Result, Renaming] = spreadsheet.join(ToMerge, keycols=keycols,<EOL>nullvals=nullvals, renamer=renamer, returnrenaming=True, Names=Names)<EOL>if isinstance(ToMerge, dict):<EOL><INDENT>Names = ToMerge.keys()<EOL><DEDENT>else:<EOL><INDENT>Names = range(len(ToMerge))<EOL><DEDENT>Colorings = dict([(k, ToMerge[k].coloring) if '<STR_LIT>' in dir(ToMerge[k])<EOL>else {} for k in Names])<EOL>for k in Names:<EOL><INDENT>if k in Renaming.keys():<EOL><INDENT>l = ToMerge[k]<EOL>Colorings[k] =dict([(g, [n if not n in Renaming[k].keys() else Renaming[k][n]<EOL>for n in l.coloring[g]]) for g in Colorings[k].keys()])<EOL><DEDENT><DEDENT>Coloring = {}<EOL>for k in Colorings.keys():<EOL><INDENT>for j in Colorings[k].keys():<EOL><INDENT>if j in Coloring.keys():<EOL><INDENT>Coloring[j] = utils.uniqify(Coloring[j] + Colorings[k][j])<EOL><DEDENT>else:<EOL><INDENT>Coloring[j] = utils.uniqify(Colorings[k][j])<EOL><DEDENT><DEDENT><DEDENT>Result = Result.view(tabarray)<EOL>Result.coloring = Coloring<EOL>if returnrenaming:<EOL><INDENT>return [Result, Renaming]<EOL><DEDENT>else:<EOL><INDENT>return Result<EOL><DEDENT>
Database-join for tabular arrays.

Wrapper for :func:`tabular.spreadsheet.join` that deals with the coloring 
and returns the result as a tabarray.

Method calls::

        data = tabular.spreadsheet.join