def _get_limit_with_offset(self, index, value_begin_position, value, is_paramter_for_value, select_satement): offset_begin_position = self.lexer_engine.get_current_token( ).end_position offset_index = -1 is_paramter_for_offset = False if self.lexer_engine.equal_any(Literals.INT): offset_value = int(self.lexer_engine.get_current_token().literals) offset_begin_position -= len(str(offset_value)) elif self.lexer_engine.equal_any(Symbol.QUESTION): offset_index = select_satement.parameters_index if index == -1 else index + 1 offset_value = -1 offset_begin_position -= 1 is_paramter_for_offset = True else: raise SQLParsingException(self.lexer_engine) self.lexer_engine.next_token() if is_paramter_for_offset: select_satement.increase_parameters_index() else: select_satement.sql_tokens.append( OffsetToken(offset_begin_position, offset_value)) if is_paramter_for_value: select_satement.increase_parameters_index() else: select_satement.sql_tokens.append( RowCountToken(value_begin_position, value)) return Limit(DatabaseType.MySQL, LimitValue(offset_value, offset_index, True), LimitValue(value, index, False))
def _parse_select_order_by_item(self, select_statement): sql_expr = self.basic_expression_parser.parse(select_statement) order_by_type = OrderDirection.ASC if self.lexer_engine.skip_if_equal(DefaultKeyword.ASC): order_by_type = OrderDirection.ASC elif self.lexer_engine.skip_if_equal(DefaultKeyword.DESC): order_by_type = OrderDirection.DESC if isinstance(sql_expr, SQLNumberExpression): return OrderItem(None, None, order_by_type, OrderDirection.ASC, None, sql_expr.number) if isinstance(sql_expr, SQLIdentifierExpression): return OrderItem(None, sqlutil.get_exactly_value(sql_expr.name), order_by_type, OrderDirection.ASC, select_statement.get_alias(sqlutil.get_exactly_value(sql_expr.name))) if isinstance(sql_expr, SQLPropertyExpression): return OrderItem(sqlutil.get_exactly_value(sql_expr.owner.name), sqlutil.get_exactly_value(sql_expr.name), order_by_type, OrderDirection.ASC, select_statement.get_alias( sqlutil.get_exactly_value(sql_expr.owner.name) + '.' + sqlutil.get_exactly_value( sql_expr.name))) if isinstance(sql_expr, SQLIgnoreExpression): return OrderItem(None, sqlutil.get_exactly_value(sql_expr.expression), order_by_type, OrderDirection.ASC, select_statement.get_alias(sql_expr.expression)) raise SQLParsingException(self.lexer_engine)
def _fill(self, parameters): _offset = 0 if self.offset: _offset = self._get_offset_value( ) if self.offset.index == -1 else parameters[self.offset.index] self.offset.value = _offset _row_count = 0 if self.row_count: _row_count = self._get_row_count_value( ) if self.row_count.index == -1 else parameters[ self.row_count.index] self.row_count.value = _row_count if _offset < 0 or _row_count < 0: raise SQLParsingException( 'LIMIT offset and row count can not be a negative value.')
def parse(self, insert_statement): if not self.lexer_engine.skip_if_equal(*self.get_customized_insert_keywords()): return self.lexer_engine.accept(DefaultKeyword.DUPLICATE) self.lexer_engine.accept(DefaultKeyword.KEY) self.lexer_engine.accept(DefaultKeyword.UPDATE) while True: column = Column(self.lexer_engine.get_current_token().literals, insert_statement.tables.get_single_table_name()) if self.sharding_rule.is_sharding_column(column): raise SQLParsingException( 'INSERT INTO .... ON DUPLICATE KEY UPDATE can not support on sharding column: {}'.format( column.name)) self.lexer_engine.skip_until(Symbol.COMMA, Assist.END) if not self.lexer_engine.skip_if_equal(Symbol.COMMA): break
def parse(self, select_satement): if not self.lexer_engine.skip_if_equal(MySQLKeyword.LIMIT): return value_index = -1 value_begin_position = self.lexer_engine.get_current_token( ).end_position is_paramter_for_value = False if self.lexer_engine.equal_any(Literals.INT): value = int(self.lexer_engine.get_current_token().literals) value_begin_position = value_begin_position - len(str(value)) elif self.lexer_engine.equal_any(Symbol.QUESTION): value_index = select_satement.parameters_index value = -1 value_begin_position -= 1 is_paramter_for_value = True else: raise SQLParsingException(self.lexer_engine) self.lexer_engine.next_token() if self.lexer_engine.skip_if_equal(Symbol.COMMA): select_satement.limit = self._get_limit_with_comma( value_index, value_begin_position, value, is_paramter_for_value, select_satement) return if self.lexer_engine.skip_if_equal(MySQLKeyword.OFFSET): select_satement.limit = self._get_limit_with_offset( value_index, value_begin_position, value, is_paramter_for_value, select_satement) return if is_paramter_for_value: select_satement.increase_parameters_index() else: select_satement.sql_tokens.append( RowCountToken(value_begin_position, value)) select_satement.limit = Limit(DatabaseType.MySQL, None, LimitValue(value, value_index, False))
def next_token(self): self._skip_ignored_token() if self.is_variable_begin(): self.current_token = self.tokenizer.scan_variable() elif self._is_n_char_begin(): self.offset += 1 self.tokenizer.advance(1) self.current_token = self.tokenizer.scan_chars() elif self._is_identifier_begin(): self.current_token = self.tokenizer.scan_identifier() elif self._is_hex_decimal_begin(): self.current_token = self.tokenizer.scan_hex_decimal() elif self._is_number_begin(): self.current_token = self.tokenizer.scan_number() elif self._is_symbol_begin(): self.current_token = self.tokenizer.scan_symbol() elif self._is_char_begin(): self.current_token = self.tokenizer.scan_chars() elif self._is_end(): self.current_token = Token(Assist.END, "", self.offset) else: raise SQLParsingException(self, Assist.ERROR) self.offset = self.current_token.end_position
def accept(self, token_type): if self.lexer.get_current_token().token_type != token_type: raise SQLParsingException(self.lexer, token_type) self.lexer.next_token()