<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def get_query_rows(self, job_id, offset=None, limit=None, timeout=0):
 """Retrieve a list of rows from a query table by job id. This method will append results from multiple pages together. If you want to manually page through results, you can use `get_query_results` method directly. Parameters job_id : str The job id that references a BigQuery query. offset : int, optional The offset of the rows to pull from BigQuery limit : int, optional The number of rows to retrieve from a query table. timeout : float, optional Timeout in seconds. Returns ------- list A ``list`` of ``dict`` objects that represent table rows. """


        # Get query results
        query_reply = self.get_query_results(job_id, offset=offset,
                                             limit=limit, timeout=timeout)
        if not query_reply['jobComplete']:
            logger.warning('BigQuery job %s not complete' % job_id)
            raise UnfinishedQueryException()

        schema = query_reply["schema"]["fields"]
        rows = query_reply.get('rows', [])
        page_token = query_reply.get("pageToken")
        records = [self._transform_row(row, schema) for row in rows]

        # Append to records if there are multiple pages for query results
        while page_token and (not limit or len(records) < limit):
            query_reply = self.get_query_results(
                job_id, offset=offset, limit=limit, page_token=page_token,
                timeout=timeout)
            page_token = query_reply.get("pageToken")
            rows = query_reply.get('rows', [])
            records += [self._transform_row(row, schema) for row in rows]
        return records[:limit] if limit else records