Bug #93834 Unexpected results with shift operators
Submitted: 7 Jan 12:21 Modified: 7 Jan 12:22
Reporter: Rui Quelhas Email Updates:
Status: Verified Impact on me:
None 
Category:Connector for Node.js Severity:S3 (Non-critical)
Version:8.0.13 OS:Any
Assigned to: Rui Quelhas CPU Architecture:Any

[7 Jan 12:21] Rui Quelhas
Description:
As a user, I expect an expression like "8 >> 1 >> 1" to yield the same results both in a CRUD context (such as in a field projection) or in plain SQL.

In this case, the following should happen:

session.sql('SELECT 8 >> 1 >> 1 AS shifting')
  .execute(console.log) // [2]

collection.find()
  .fields('8 >> 1 >> 1 AS shifting')
  .execute(console.log) { shifting: 2 }

The plain SQL example seems to yield the expected the result but the CRUD example does not.

How to repeat:
Assuming the existence of a `mySchema.myCollection` collection which contains a single document.

mysqxl.getSession(config)
  .then(session => {
    var collection = session.getSchema('mySchema').getCollection('myCollection')
    return collection.find()
      .fields('8 >> 1 >> 1 AS shifting')
      .execute(console.log) // { shifting: 8 }
  })

Suggested fix:
The expression parser seems to be using right associativity.

> mysqlx.expr('8 >> 1 >> 1')
{
    "type": 5,
    "operator": {
        "name": ">>",
        "paramList": [
            {
                "type": 2,
                "literal": {
                    "type": 2,
                    "vUnsignedInt": 8
                }
            },
            {
                "type": 5,
                "operator": {
                    "name": ">>",
                    "paramList": [
                        {
                            "type": 2,
                            "literal": {
                                "type": 2,
                                "vUnsignedInt": 1
                            }
                        },
                        {
                            "type": 2,
                            "literal": {
                                "type": 2,
                                "vUnsignedInt": 1
                            }
                        }
                    ]
                }
            }
        ]
    }
}

It can be changed to use left associativity instead.

> mysqlx.expr('8 >> 1 >> 1')
{
    "type": 5,
    "operator": {
        "name": ">>",
        "paramList": [
            {
                "operator": {
                    "name": ">>",
                    "paramList": [
                        {
                            "type": 2,
                            "literal": {
                                "type": 2,
                                "vUnsignedInt": 8
                            }
                        },
                        {
                            "type": 2,
                            "literal": {
                                "type": 2,
                                "vUnsignedInt": 1
                            }
                        }
                    ]
                }
            },
            {
                "type": 2,
                "literal": {
                    "type": 2,
                    "vUnsignedInt": 1
                }
            }
        ]
    }
}