Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Translate XOR, shift left, shift right #18952

Closed
wants to merge 1 commit into from
Closed

Translate XOR, shift left, shift right #18952

wants to merge 1 commit into from

Conversation

roji
Copy link
Member

@roji roji commented Nov 17, 2019

Closes #18795

Because it just had to be done.

@@ -179,6 +179,9 @@ private SqlExpression ApplyTypeMappingOnLike(LikeExpression likeExpression)
case ExpressionType.Coalesce:
case ExpressionType.And:
case ExpressionType.Or:
case ExpressionType.ExclusiveOr:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid a bug trail, we need to get a report on typeMapping characteristics on each of these operator on different databases. What are supported types. What are corresponding result types. etc

Copy link
Member Author

@roji roji Nov 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

edit: added MySQL info as well

XOR/AND/OR

On both SQL Server, PostgreSQL and MySQL, these always casts up to the wider integral operand (so TINYINT XOR BIGINT yields BIGINT). Regular arithmetic operators (e.g. Add) work the same way, all of the below return BIGINT:

SQL Server:

SELECT SQL_VARIANT_PROPERTY(CAST(8 AS SMALLINT) + CAST(1 AS BIGINT), 'BaseType');
SELECT SQL_VARIANT_PROPERTY(CAST(8 AS BIGINT) + CAST(1 AS SMALLINT), 'BaseType');

PostgreSQL:

SELECT pg_typeof(8::BIGINT + 1::SMALLINT);
SELECT pg_typeof(8::SMALLINT + 1::BIGINT);

MySQL:

CREATE TABLE types (tiny TINYINT, small SMALLINT, normal INT, big BIGINT); 
INSERT INTO types (tiny, small, normal, big) VALUES (8, 8, 8, 8);

CREATE TEMPORARY TABLE typeof AS SELECT tiny + big FROM types AS col;
DESCRIBE typeof;
DROP TABLE typeof;

Both return BIGINT. Our type inference doesn't match this: we just call ExpressionExtensions.InferTypeMapping on both sides. Did you have this on your radar, should I open an issue? Not sure if there's anything to check on Sqlite with its lack of real types.

SHL/SHR

Not supported on SQL Server.

On PostgreSQL the operation predictably returns the same type as the left operand. The right side can be SMALLINT or INT but not BIGINT. Modified the inference to simply apply the default mapping on the right-hand operand. Sqlite supports SHL/SHR but again no real typing so...

On MySQL the operation behaves like an arithmetic operator, taking the wider operand type:

CREATE TABLE types (tiny TINYINT, small SMALLINT, normal INT, big BIGINT); 
INSERT INTO types (tiny, small, normal, big) VALUES (8, 8, 8, 8);

CREATE TEMPORARY TABLE typeof AS SELECT tiny >> big FROM types AS col;
DESCRIBE typeof;
DROP TABLE typeof;

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm guessing that the mismatch above (arithmetic widening) doesn't actually manifest as a bug, because integer literals are identical, and even when sent as parameters there's implicit widening logic (either in the ADO.NET driver or in the database). But we may still want to fix this for correctness etc.

},
elementSorter: e => (e.e2.EmployeeID, e.o2.OrderID),
entryCount: 3))).Message);
await AssertQuery(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@smitpatel this testing for translation failure (because of the XOR operator), although the name and purpose logic don't seem to fit - removed the throws assertion and made it into a positive test.

Copy link
Contributor

@smitpatel smitpatel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type mapping inference is incorrect. TypeMapping inference needs to account for actual C# expression trees.

Tests should be written for following types for leftshift/rightshift s_SByte, s_Int16, s_Int32, s_Int64, s_Byte, s_UInt16, s_UInt32, s_UInt64
And for exclusive OR - s_SByte, s_Int16, s_Int32, s_Int64, s_Byte, s_UInt16, s_UInt32, s_UInt64, s_Boolean

}
break;

case ExpressionType.LeftShift:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is incorrect change

@roji roji marked this pull request as draft May 2, 2020 20:15
@roji
Copy link
Member Author

roji commented Jun 9, 2020

Closing this for now.

@roji roji closed this Jun 9, 2020
@smitpatel smitpatel deleted the MoreBitwise branch June 9, 2020 15:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support more bitwise operators
2 participants