mechatroner / RBQL

🦜RBQL - Rainbow Query Language: SQL-like query engine for (not only) CSV file processing. Supports SQL queries with Python and JavaScript expressions.
https://rbql.org
MIT License
281 stars 13 forks source link

Add equivalent of LIKE operator #18

Closed mechatroner closed 4 years ago

mechatroner commented 4 years ago

Unfortunately it is not possible to implement LIKE as operator in RBQL. But it is possible to implement LIKE as a function or function-like class. Actually the fact that LIKE is an operator in traditional SQL doesn't make a lot of sense (apart from convenience of usage). LIKE is not part of relational algebra, it is just a traditional (and very primitive) function without any side effects. Possible implementation in Python can look like this:

class my_like:
    def __init__(self):
        self._cache = dict()

    def _like_to_regex(self, pattern):
        p = 0
        i = 0
        converted = ''
        while i < len(pattern):
            if pattern[i] in ['_', '%']:
                converted += re.escape(pattern[p:i])
                p = i + 1
                if pattern[i] == '_':
                    converted += '.'
                else:
                    converted += '.*'
            i += 1
        converted += re.escape(pattern[p:i])
        return '^' + converted + '$'

    def __call__(self, text, pattern):
        if pattern not in self._cache:
            rgx = self._like_to_regex(pattern)
            self._cache[pattern] = re.compile(rgx)
        return self._cache[pattern].match(text) is not None

like = my_like()
LIKE = like  

Queries would look a little less elegant than traditonal SQL equivalents: select * where like(a.notes, '%holiday%')

In case if user made an error by using the traditional syntax, e.g. select * where a.notes like '%holiday%' RBQL can catch the syntax error exception and show an appropirate error message with example of how to use the not-so-elegant RBQL-supported LIKE function.

mechatroner commented 4 years ago

LIKE() function was added to the master branch