'Find all tables and fields to retrieve in the master query
@param dfields: the requested fields (S3ResourceFields)
@param vfields: the virtual filter fields
@param joined_tables: the tables joined in the master query
@param as_rows: whether to produce web2py Rows
@param groupby: the GROUPBY expression from the caller
@return: tuple (tables, fields, extract, groupby):
tables: the tables required to join
fields: the fields to retrieve
extract: the fields to extract from the result
groupby: the GROUPBY expression (resolved into Fields)'

def master_fields(self, dfields, vfields, joined_tables, as_rows=False, groupby=None):

    db = current.db
    tablename = self.resource.table._tablename
    tables = set()
    fields = {}
    extract = set()
    if groupby:
        items = self.resolve_expression(groupby)
        groupby = []
        groupby_append = groupby.append
        for item in items:
            tname = None
            if isinstance(item, Field):
                f = item
            elif isinstance(item, str):
                fn = item.strip()
                (tname, fn) = ([tablename] + fn.split('.', 1))[(-2):]
                try:
                    f = db[tname][fn]
                except (AttributeError, KeyError):
                    continue
            else:
                continue
            groupby_append(f)
            fname = str(f)
            if (not tname):
                tname = f.tablename
            fields[fname] = f
            if (tname == tablename):
                continue
            else:
                tnames = None
                for dfield in dfields:
                    if (dfield.colname == fname):
                        tnames = self.rfield_tables(dfield)
                        break
            if tnames:
                tables |= tnames
            else:
                tables.add(tname)
        extract = set(fields.keys())
    else:
        rfields = (dfields + vfields)
        for rfield in rfields:
            tname = rfield.tname
            joined = ((tname == tablename) or (tname in joined_tables))
            if (as_rows or joined):
                colname = rfield.colname
                if rfield.show:
                    extract.add(colname)
                if rfield.field:
                    fields[colname] = rfield.field
                if (not joined):
                    tables |= self.rfield_tables(rfield)
    return (tables, fields, extract, groupby)
