Skip to content

Commit d262058

Browse files
committed
BUG23568207: Fix default aliases for projection fields
An error is thrown when an operator or a function is present in the projection which is used without an alias. Example: a + b, sum($.age) This patch fixes the alias parsing by using the entire projection field as an alias. Tests added for regression.
1 parent 19ef27b commit d262058

File tree

3 files changed

+42
-4
lines changed

3 files changed

+42
-4
lines changed

lib/mysqlx/expr.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -784,9 +784,21 @@ def parse_table_insert_field(self):
784784
def parse_table_update_field(self):
785785
return self.column_identifier().identifier
786786

787+
def _table_fields(self):
788+
fields = []
789+
temp = self.string.split(",")
790+
temp.reverse()
791+
while temp:
792+
field = temp.pop()
793+
while field.count("(") != field.count(")"):
794+
field = "{0}{1}".format(temp.pop(), field)
795+
fields.append(field.strip())
796+
return fields
797+
787798
def parse_table_select_projection(self):
788799
project_expr = []
789800
first = True
801+
fields = self._table_fields()
790802
while self.pos < len(self.tokens):
791803
if not first:
792804
self.consume_token(TokenType.COMMA)
@@ -795,10 +807,14 @@ def parse_table_select_projection(self):
795807
if self.cur_token_type_is(TokenType.AS):
796808
self.consume_token(TokenType.AS)
797809
projection["alias"] = self.consume_token(TokenType.IDENT)
798-
else:
810+
elif projection["source"]["type"] is \
811+
mysqlxpb_enum("Mysqlx.Expr.Expr.Type.IDENT"):
799812
self.pos -= 1
800813
projection["alias"] = self.consume_token(TokenType.IDENT)
814+
else:
815+
projection["alias"] = fields[len(project_expr)]
801816
project_expr.append(projection.get_message())
817+
802818
return project_expr
803819

804820
def parse_order_spec(self):

lib/mysqlx/result.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,11 @@ def set_from_protobuf(payload):
147147
def decimal_from_protobuf(payload):
148148
digits = []
149149
sign = None
150-
scale = ord(payload[0])
150+
scale = payload[0] if isinstance(payload[0], int) else ord(payload[0])
151151
payload = payload[1:]
152152

153153
for c in payload:
154-
ch = ord(c)
154+
ch = c if isinstance(c, int) else ord(c)
155155
high_bcd = (ch & 0xf0) >> 4
156156
low_bcd = ch & 0x0f
157157
if high_bcd < 0x0a:

tests/test_mysqlx_crud.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- coding: utf-8 -*-
22
# MySQL Connector/Python - MySQL driver written in Python.
3-
# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3+
# Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
44

55
# MySQL Connector/Python is licensed under the terms of the GPLv2
66
# <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
@@ -495,6 +495,17 @@ def test_find(self):
495495
docs = result.fetch_all()
496496
self.assertEqual(2, len(docs))
497497

498+
# test aggregation functions without alias
499+
result = collection.find().fields("sum($.age)").execute()
500+
docs = result.fetch_all()
501+
self.assertTrue("sum($.age)" in docs[0].keys())
502+
self.assertEqual(158, docs[0]["sum($.age)"])
503+
504+
# test operators without alias
505+
result = collection.find().fields("$.age + 100").execute()
506+
docs = result.fetch_all()
507+
self.assertTrue("$.age + 100" in docs[0].keys())
508+
498509
self.schema.drop_collection(collection_name)
499510

500511
def test_modify(self):
@@ -733,6 +744,17 @@ def test_select(self):
733744
rows = result.fetch_all()
734745
self.assertEqual(2, len(rows))
735746

747+
# test aggregation functions
748+
result = table.select("sum(age)").execute()
749+
rows = result.fetch_all()
750+
self.assertTrue("sum(age)" == result.columns[0].get_column_name())
751+
self.assertEqual(158, rows[0]["sum(age)"])
752+
753+
# test operators without alias
754+
result = table.select("age + 100").execute()
755+
rows = result.fetch_all()
756+
self.assertTrue("age + 100" == result.columns[0].get_column_name())
757+
736758
self.schema.drop_table("test")
737759

738760
def test_having(self):

0 commit comments

Comments
 (0)