'Provide some completions for SQL
:param line: The current complete input line
:param token: The word readline is looking for matches
:param beg: Integer offset of token in line
:param end: Integer end of token in line
:return: A list of completions, or an empty list if none'

def complete_sql(self, line, token, beg, end):

    if (self._completion_cache is None):
        cur = self.db.cursor()
        collations = [row[1] for row in cur.execute('pragma    collation_list')]
        databases = [row[1] for row in cur.execute('pragma    database_list')]
        other = []
        for db in databases:
            if (db == 'temp'):
                master = 'sqlite_temp_master'
            else:
                master = ('[%s].sqlite_master' % (db,))
            for row in cur.execute(('select    *    from    ' + master)).fetchall():
                for col in (1, 2):
                    if ((row[col] not in other) and (not row[col].startswith('sqlite_'))):
                        other.append(row[col])
                if (row[0] == 'table'):
                    try:
                        for table in cur.execute(('pragma    [%s].table_info([%s])' % (db, row[1]))).fetchall():
                            if (table[1] not in other):
                                other.append(table[1])
                            for item in table[2].split():
                                if (item not in other):
                                    other.append(item)
                    except apsw.SQLError:
                        pass
        self._completion_cache = [self._sqlite_keywords, self._sqlite_functions, self._sqlite_special_names, collations, databases, other]
        for i in range(len(self._completion_cache)):
            self._completion_cache[i].sort()
    if ('pragma    ' in line.lower()):
        t = self._get_prev_tokens(line.lower(), end)
        if ((len(t) > 2) and (t[(-3)] == 'pragma')):
            for p in self._pragmas:
                if (p.replace('=', '') == t[(-2)]):
                    vals = self._pragmas[p]
                    if (not vals):
                        return []
                    return [(x + ';') for x in vals if x.startswith(token)]
        if ((len(t) > 1) and (t[(-2)] == 'pragma') and line[:end].replace('    ', '').endswith('=')):
            for p in self._pragmas:
                if (p.replace('=', '') == t[(-1)]):
                    vals = self._pragmas[p]
                    if (not vals):
                        return []
                    return vals
        if ((len(t) > 1) and (t[(-2)] == 'pragma')):
            res = [x for x in self._pragmas.keys() if x.startswith(token)]
            res.sort()
            return res
        if (len(t) and (t[(-1)] == 'pragma')):
            res = list(self._pragmas.keys())
            res.sort()
            return res
    res = []
    ut = token.upper()
    for corpus in self._completion_cache:
        for word in corpus:
            if word.upper().startswith(ut):
                if word.startswith(token):
                    if (word not in res):
                        res.append(word)
                elif word.lower().startswith(token):
                    if (word.lower() not in res):
                        res.append(word.lower())
                elif word.upper().startswith(token):
                    if (word.upper() not in res):
                        res.append(word.upper())
                else:
                    w = (token + word[len(token):])
                    if (w not in res):
                        res.append(w)
    return res
