'Yields the values of attribute for a range of subjexts.
Args:
subject_prefix: Returns records for all subjects which begin with
subject_prefix.
attributes: A list of the attributes of interest.
after_urn: If set, restrict to records which come after.
max_records: The maximum number of values to return.
Yields:
Records of the form (subject, timestamp, value).'

def ScanAttributes(self, subject_prefix, attributes, after_urn=None, max_records=None):

    cursor = self.conn.cursor()
    cursor.execute('PRAGMA    synchronous    =    OFF')
    cursor.execute('PRAGMA    cache_size    =    10000')
    query = ('SELECT    t1.subject,    t1.predicate,    t1.timestamp,    t1.value\n                                                            FROM    tbl    AS    t1,\n                                                                                (SELECT    subject,    predicate,\n                                                                                                                MAX(timestamp)    AS    max_ts    FROM    tbl\n                                                                                            WHERE    subject    LIKE    ?    AND    subject    >    ?\n                                                                                                    AND    predicate    in    (%s)\n                                                                                            GROUP    BY    subject,    predicate)    AS    t2\n                                                            WHERE    t1.subject    =    t2.subject    AND\n                                                                                    t1.timestamp    =    t2.max_ts    AND\n                                                                                    t1.predicate    =    t2.predicate\n                                                            ORDER    BY    t1.subject\n                                                ' % ','.join(('?' * len(attributes))))
    subject_prefix = utils.SmartStr(subject_prefix)
    if after_urn:
        after_urn = utils.SmartStr(after_urn)
    else:
        after_urn = ''
    args = ([(subject_prefix + '%'), after_urn] + attributes)
    if max_records:
        query += '    LIMIT    ?'
        args.append((max_records * len(attributes)))
    cursor.execute(query, args)
    for r in cursor:
        (yield r)
