示例#1
0
    def select(self, p):
        select = p.select
        if select.offset is not None:
            raise ParsingException(f'OFFSET already specified for this query')
        ensure_select_keyword_order(select, 'OFFSET')
        if not isinstance(p.constant.value, int):
            raise ParsingException(
                f'OFFSET must be an integer value, got: {p.constant.value}')

        select.offset = p.constant
        return select
示例#2
0
 def result_column(self, p):
     col = p.result_column
     if col.alias:
         raise ParsingException(
             f'Attempt to provide two aliases for {str(col)}')
     col.alias = p.identifier
     return col
示例#3
0
 def select(self, p):
     select = p.select
     ensure_select_keyword_order(select, 'LIMIT')
     if not isinstance(p.constant.value, int):
         raise ParsingException(
             f'LIMIT must be an integer value, got: {p.constant.value}')
     select.limit = p.constant
     return select
示例#4
0
    def __init__(self, name, url, *args, **kwargs):
        super().__init__(*args, **kwargs)

        url_ = urlparse(url)
        if url_.scheme not in ('http', 'https'):
            raise ParsingException(f'Wrong url scheme: {url_.scheme}')
        self.url = url
        self.name = name
示例#5
0
    def delete(self, p):
        where = getattr(p, 'expr', None)

        if where is not None and not isinstance(where, Operation):
            raise ParsingException(
                f"WHERE must contain an operation that evaluates to a boolean, got: {str(where)}"
            )

        return Delete(table=p.from_table, where=where)
示例#6
0
 def select(self, p):
     select = p.select
     ensure_select_keyword_order(select, 'WHERE')
     where_expr = p.expr
     if not isinstance(where_expr, Operation):
         raise ParsingException(
             f"WHERE must contain an operation that evaluates to a boolean, got: {str(where_expr)}"
         )
     select.where = where_expr
     return select
示例#7
0
 def select(self, p):
     select = p.select
     ensure_select_keyword_order(select, 'HAVING')
     having = p.expr
     if not isinstance(having, Operation):
         raise ParsingException(
             f"HAVING must contain an operation that evaluates to a boolean, got: {str(having)}"
         )
     select.having = having
     return select
示例#8
0
 def result_column(self, p):
     col = p.result_column
     if col.alias:
         raise ParsingException(
             f'Attempt to provide two aliases for {str(col)}')
     if hasattr(p, 'dquote_string'):
         alias = Identifier(p.dquote_string)
     else:
         alias = p.identifier
     col.alias = alias
     return col
示例#9
0
 def select(self, p):
     select = p.select
     ensure_select_keyword_order(select, 'LIMIT')
     if not isinstance(p.constant0.value, int) or not isinstance(
             p.constant1.value, int):
         raise ParsingException(
             f'LIMIT must have integer arguments, got: {p.constant0.value}, {p.constant1.value}'
         )
     select.offset = p.constant0
     select.limit = p.constant1
     return select
示例#10
0
def ensure_select_keyword_order(select, operation):
    op_to_attr = {
        'FROM': select.from_table,
        'WHERE': select.where,
        'GROUP BY': select.group_by,
        'HAVING': select.having,
        'ORDER BY': select.order_by,
        'LIMIT': select.limit,
        'OFFSET': select.offset,
        'MODE': select.mode,
    }

    requirements = {
        'WHERE': ['FROM'],
        'GROUP BY': ['FROM'],
        'ORDER BY': ['FROM'],
        # 'HAVING': ['GROUP BY'],
    }

    precedence = [
        'FROM', 'WHERE', 'GROUP BY', 'HAVING', 'ORDER BY', 'LIMIT', 'OFFSET',
        'MODE'
    ]

    if op_to_attr[operation]:
        raise ParsingException(
            f"Duplicate {operation} clause. Only one {operation} allowed per SELECT."
        )

    op_requires = requirements.get(operation, [])

    for req in op_requires:
        if not op_to_attr[req]:
            raise ParsingException(f"{operation} requires {req}")

    op_precedence_pos = precedence.index(operation)

    for next_op in precedence[op_precedence_pos:]:
        if op_to_attr[next_op]:
            raise ParsingException(f"{operation} must go after {next_op}")
示例#11
0
def get_lexer_parser(dialect):
    if dialect == 'sqlite':
        from mindsdb_sql.parser.lexer import SQLLexer
        from mindsdb_sql.parser.parser import SQLParser
        lexer, parser = SQLLexer(), SQLParser()
    elif dialect == 'mysql':
        from mindsdb_sql.parser.dialects.mysql.lexer import MySQLLexer
        from mindsdb_sql.parser.dialects.mysql.parser import MySQLParser
        lexer, parser = MySQLLexer(), MySQLParser()
    elif dialect == 'mindsdb':
        from mindsdb_sql.parser.dialects.mindsdb.lexer import MindsDBLexer
        from mindsdb_sql.parser.dialects.mindsdb.parser import MindsDBParser
        lexer, parser = MindsDBLexer(), MindsDBParser()
    else:
        raise ParsingException(f'Unknown dialect {dialect}. Available options are: sqlite, mysql.')
    return lexer, parser
示例#12
0
    def set(self, p):
        if not p.id.lower() == 'names':
            raise ParsingException(f'Expected "SET names", got "SET {p.id}"')
        if isinstance(p[2], Constant):
            arg = Identifier(p[2].value)
        else:
            # is identifier
            arg = p[2]

        params = {}
        if hasattr(p, 'COLLATE'):
            if isinstance(p[4], Constant):
                val = p[4]
            else:
                val = SpecialConstant('DEFAULT')
            params['COLLATE'] = val

        return Set(category=p.id.lower(), arg=arg, params=params)
示例#13
0
 def error(self, p):
     if p:
         raise ParsingException(
             f"Syntax error at token {p.type}: \"{p.value}\"")
     else:
         raise ParsingException("Syntax error at EOF")
示例#14
0
 def set(self, p):
     if not p.id.lower() == 'names':
         raise ParsingException(f'Expected "SET names", got "SET {p.id}"')
     return Set(category=p.id.lower(), arg=p.identifier)