-
Notifications
You must be signed in to change notification settings - Fork 254
Cube support (revamped) #3651
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
Cube support (revamped) #3651
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kirkbrauer this is great, thanks - I wish I had more contributions were this high-quality.
See below for questions/suggestions, but I think this is quite close to being mergeable.
src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCubeTranslator.cs
Outdated
Show resolved
Hide resolved
src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCubeTranslator.cs
Outdated
Show resolved
Hide resolved
src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCubeTranslator.cs
Outdated
Show resolved
Hide resolved
| break; | ||
| } | ||
|
|
||
| case PgExpressionType.CubeNthCoordinate: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an alternative to these, I think you should be able to simply set the returned type mapping (double) directly in the method translator, no? In fact, that's usually better, since we know at the point of translation exactly what type the method returns (it's documented) - the return type isn't sensitive to context and shouldn't get inferred.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wanting to make sure that this code fragment is actually needed, as you're now setting the returned type mapping in the method translator (basically my comment above). It might be possible to remove this altogether.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding is that MakePostgresBinary doesn't have a case for these operators so the return type would be NpgsqlCube instead of double. Here, ApplyTypeMappingOnPostgresBinary is basically patching this problem.
As a simplification, we could just add cases to MakePostgresBinary instead to handle this scenario.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I think I see where I wasn't clear... In the translator, you can simply construct a PgBinaryExpression directly, rather than going through the SqlExpressionFactory. Since the translator basically knows everything about the expression it's going to produce (i.e. it's exact return type), I don't think the expression factory is required here (and it would allow you to remove all this cube-specific custom stuff).
The factory is useful mainly when the same expression kind might be constructed from various places and with different operand types; this allows us to factor the knowledge on what type is returned given what operands (and operator) in a single place (the factory). But since the only place that would ever construct cube-related operators is this translator, we may as well just keep all the logic there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a note that this is still pending.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I've removed the cube-specific logic here and migrated it back to the cube type mapper. I think this should follow your suggestion above.
src/EFCore.PG/Storage/Internal/Mapping/NpgsqlCubeTypeMapping.cs
Outdated
Show resolved
Hide resolved
test/EFCore.PG.FunctionalTests/Query/Translations/CubeTranslationsTest.cs
Outdated
Show resolved
Hide resolved
… of indexes as used by the cube subset function
src/EFCore.PG/Query/Internal/NpgsqlSqlTranslatingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
src/EFCore.PG/Query/Internal/NpgsqlSqlTranslatingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCubeTranslator.cs
Outdated
Show resolved
Hide resolved
src/EFCore.PG/Query/Expressions/Internal/PgIndexesArrayExpression.cs
Outdated
Show resolved
Hide resolved
…exesArray type and expression, fix constructor handling and nullability
src/EFCore.PG/Query/Internal/NpgsqlSqlTranslatingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
src/EFCore.PG/Query/Internal/NpgsqlSqlTranslatingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
src/EFCore.PG/Query/Internal/NpgsqlSqlTranslatingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCubeTranslator.cs
Outdated
Show resolved
Hide resolved
src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCubeTranslator.cs
Outdated
Show resolved
Hide resolved
src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCubeTranslator.cs
Outdated
Show resolved
Hide resolved
src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCubeTranslator.cs
Outdated
Show resolved
Hide resolved
src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCubeTranslator.cs
Outdated
Show resolved
Hide resolved
src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCubeTranslator.cs
Outdated
Show resolved
Hide resolved
src/EFCore.PG/Query/Expressions/Internal/PgIndexesArrayExpression.cs
Outdated
Show resolved
Hide resolved
src/EFCore.PG/Storage/Internal/Mapping/NpgsqlCubeTypeMapping.cs
Outdated
Show resolved
Hide resolved
src/EFCore.PG/Storage/Internal/Mapping/NpgsqlCubeTypeMapping.cs
Outdated
Show resolved
Hide resolved
roji
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Took another look, and this all looks - the only thing remaining is the custom expression for the indices which should ideally not be needed. Am happy to merge once that's done (and also to help with that task).
src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCubeTranslator.cs
Outdated
Show resolved
Hide resolved
| break; | ||
| } | ||
|
|
||
| case PgExpressionType.CubeNthCoordinate: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wanting to make sure that this code fragment is actually needed, as you're now setting the returned type mapping in the method translator (basically my comment above). It might be possible to remove this altogether.
|
@roji Can we merge npgsql/npgsql#6295? I think it should be ready now. |
…ve binary expr handling
src/EFCore.PG/Query/Internal/NpgsqlSqlTranslatingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
…, construct binary expressions directly
roji
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kirkbrauer here's a (likely last) review - this seems almost ready to merge, see the remaining unresolved comments.
src/EFCore.PG/Query/ExpressionTranslators/Internal/NpgsqlCubeTranslator.cs
Show resolved
Hide resolved
src/EFCore.PG/Query/Internal/NpgsqlSqlTranslatingExpressionVisitor.cs
Outdated
Show resolved
Hide resolved
| break; | ||
| } | ||
|
|
||
| case PgExpressionType.CubeNthCoordinate: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a note that this is still pending.
roji
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @kirkbrauer - all looks good, am approving and will merge this for 10.0.
Thanks again for the very high-quality work, and for the patience to work through all my comments! It was a pleasure to review your work and get it merged.
|
@kirkbrauer note the small refinement in #3664, which automatically detects if any property in the EF model uses cube, and automatically installs the extension if so. Regardless, am finalizing the 10 release. Are you interesting in submitting docs on the various translations cube supports on this page (source)? If you don't like this kinda work no worries at all - just let me know and I'll do it. |
|
Hi @roji, I took a stab at it, I'll make a PR soon with the docs. I created a new cube.md page as there are a few details or we can just put it in the main translations.md for simplicity. |
|
@kirkbrauer I say let's put it in its own section inside translations.md, that's what we do for most other things. |
This PR extends the original PR #2808 by @Jimmacle and is updated for the latest version of EFCore.PG.
Continues implementation of npgsql/npgsql#3867.
cube && cubebool Overlaps(this NpgsqlCube a, NpgsqlCube b)cube @> cubebool Contains(this NpgsqlCube a, NpgsqlCube b)cube <@ cubebool ContainedBy(this NpgsqlCube a, NpgsqlCube b)cube -> integerdouble NthCoordinate(this NpgsqlCube cube, int n)cube ~> integerdouble NthCoordinateKnn(this NpgsqlCube cube, int n)cube <-> cubedouble Distance(this NpgsqlCube a, NpgsqlCube b)cube <#> cubedouble DistanceTaxicab(this NpgsqlCube a, NpgsqlCube b)cube <=> cubedouble DistanceChebyshev(this NpgsqlCube a, NpgsqlCube b)cube_union(cube, cube)NpgsqlCube Union(this NpgsqlCube a, NpgsqlCube b)cube_inter(cube, cube)NpgsqlCube Intersect(this NpgsqlCube a, NpgsqlCube b)cube_enlarge(c cube, r double, n integer)NpgsqlCube Enlarge(this NpgsqlCube cube, double r, int n)cube_dim(cube)int Dimensionscube_ll_coord(cube, integer)double LlCoord(int n)cube_ur_coord(cube, integer)double UrCoord(int n)cube_is_point(cube)bool IsPointcube_subset(cube, integer[])NpgsqlCube ToSubset(params int[] indexes)A few design notes here that need to be discussed:
NthCoordinate2toNthCoordinateKnnas this describes the fact this operator uses K-nearest neighbor (KNN).IReadOnlyList<double>is being indexed for theLowerLeftandUpperRightlists, I have retained theLlCoordandUrCoordextension methods. Trying to index the lists directly throws anInvalidOperationExceptionexception.LlCoordandUrCoordmethods as mentioned by @Jimmacle instead?ConvertToPostgresIndexmethod every time to increment by one either as a literal or by creating an addition expression.I also noticed that the
ToString()method of theNpgsqlCubetype does not produce fullG17floating-point representations, we should probably make a follow-up PR to that repository to fix this so I can remove the custom serialization code in this repo.