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

Remove run first column #2769

Merged
merged 11 commits into from
Jan 30, 2023
Merged

Conversation

angrykoala
Copy link
Member

Description

Removes runFirstColumn from the @cypher directive, forcing the directive to be used with the columnName option.

Updates all tests to comply with this new requirement

Complexity

Complexity: Medium

@changeset-bot
Copy link

changeset-bot bot commented Jan 23, 2023

🦋 Changeset detected

Latest commit: f2bd09c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 8 packages
Name Type
@neo4j/graphql Major
@neo4j/graphql-toolbox Patch
@neo4j/graphql-ogm Major
neo-place Patch
neo-push-server Patch
apollo-suscriptions-server Patch
yoga-subscriptions-server Patch
@neo4j/graphql-plugin-subscriptions-amqp Major

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@CLAassistant
Copy link

CLAassistant commented Jan 23, 2023

CLA assistant check
All committers have signed the CLA.

@neo4j-team-graphql
Copy link
Collaborator

neo4j-team-graphql commented Jan 23, 2023

Performance Report

name dbHits old dbHits time (ms) old time (ms) maxRows
🟥 connections.ConnectionWithSortAndCypher 14278 2277 116 445 2174
🟥 cypher-directive.TopLevelCypherDirective 127994 99525 388 865 10168
🟥 sorting.SortMultipleTypesWithCypherWithCypher 13424 1439 127 312 2174
🟥 sorting.SortWithTopLevelCypher 14120 2119 58 211 2174

🟥 - Performance worsened (dbHits)
🟩 - Performance improved (dbHits)
🟦 - New test

Show Full Table
name dbHits old dbHits time (ms) old time (ms) maxRows
aggregations.TopLevelAggregate 3403 3403 44 52 1134
aggregations.NestedAggregation 13514 13514 103 126 2174
aggregations.AggregationWithWhere 10942 10942 87 124 2174
aggregations.NestedCountFromMovieToActors 8694 8694 81 105 2174
aggregations.NestedCountFromActorsToMovie 8900 8900 81 126 2174
aggregations.DeeplyNestedCount 10054408 10054408 5157 5394 2008534
batch-create.BatchCreate 3600 3600 163 126 600
connect.createAndConnect 12419 12419 194 268 3003
connections.Connection 13042 13042 232 150 2174
connections.NestedConnection 33883 33883 136 171 4516
connections.ConnectionWithSort 2277 2277 71 84 1040
🟥 connections.ConnectionWithSortAndCypher 14278 2277 116 445 2174
create.SimpleMutation 6 6 32 51 1
🟥 cypher-directive.TopLevelCypherDirective 127994 99525 388 865 10168
delete.SimpleDelete 18361 18361 275 386 1040
delete.NestedDeleteInUpdate 16779 16779 187 158 2040
query.SimpleQuery 14120 14120 180 123 2174
query.QueryWhere 12971 12993 40 59 2161
query.SimpleQueryWithNestedWhere 13142 13164 70 87 2161
query.Nested 10084290 10084290 10738 11263 2008534
query.NestedWithFilter 38198 38198 144 138 4511
query.OrFilterOnRelationships 52737 50559 202 294 2139
query.OrFilterOnRelationshipsAndNested 40319 37664 240 394 2139
query.QueryWithNestedIn 14436 15315 70 97 1157
query.NestedConnectionWhere 13182 13182 64 70 2174
query.DeeplyNestedConnectionWhere 13186 13342 88 95 2174
query.DeeplyNestedWithRelationshipFilters 6913 6913 153 172 1134
query.DeeplyNestedWithRelationshipSingleFilters 15438 15438 102 120 2174
query.Fulltext 96 96 44 39 16
query.FulltextWithNestedQuery 571 571 49 55 84
sorting.SortMultipleTypes 2493 2493 82 81 1040
🟥 sorting.SortMultipleTypesWithCypherWithCypher 13424 1439 127 312 2174
sorting.SortOnNestedFields 13042 13042 106 102 2174
sorting.SortDeeplyNestedFields 38965 38965 190 227 4516
🟥 sorting.SortWithTopLevelCypher 14120 2119 58 211 2174
unions.SimpleUnionQuery 321 321 66 92 35
unions.SimpleUnionQueryWithMissingFields 293 293 64 84 35
unions.NestedUnion 398553 398553 341 364 33033
unions.NestedUnionWithMissingFields 372527 372527 288 341 33033
update.NestedUpdate 2117 2117 50 70 1040

Old Schema Generation: 35.521s
Schema Generation: 35.888s

@angrykoala angrykoala marked this pull request as ready for review January 24, 2023 14:10
@Liam-Doodson
Copy link
Contributor

I've not had a chance to properly look over this yet but a general observation is that I think this could do with some updates to the documentation for the @cypher directive. Currently, most of the examples there do not use columnName.

The 4.0.0 migration guide also probably needs an update to make clear that at the point this is released, columnName will be required

@angrykoala
Copy link
Member Author

Yeah, these will be added as a separate PR to reduce the size of these for review

Copy link
Contributor

@Liam-Doodson Liam-Doodson left a comment

Choose a reason for hiding this comment

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

This is looking good, especially the performance improvement! Just a couple of typos in the updated tests and some edge cases that I'm not clear on the expected behaviour (mainly because I didn't see the first stage of this) and could possibly benefit from tests

"apoc.cypher.runFirstColumnMany",
"apoc.date.convertFormat",
];
export const REQUIRED_APOC_FUNCTIONS = ["apoc.util.validatePredicate", "apoc.date.convertFormat"];
Copy link
Contributor

Choose a reason for hiding this comment

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

🥳

@@ -79,7 +79,8 @@ describe("cypher", () => {
statement: """
MATCH (m:${Movie} {title: $title})
RETURN m
"""
""",
columnName: "m"
Copy link
Contributor

Choose a reason for hiding this comment

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

I wouldn't say these are blockers but it'd be interesting to see what the expected behaviour/error is if columnName is not provided now.
It'd also be interesting to see the behaviour if the wrong column name is provided.

Are there any tests that show either of these cases?

Copy link
Contributor

Choose a reason for hiding this comment

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

columnName is now be a mandatory field in the directive definition, so it will literally fail type definition validation if it isn't passed in.

shippingCost: Float
@cypher(
statement: "MATCH (this)-[:SHIPS_TO]->(a:Address) RETURN round(0.01 * distance(a.location, Point({latitude: 40.7128, longitude: -74.0060})) / 1000, 2)"
statement: "MATCH (this)-[:SHIPS_TO]->(a:Address) RETURN round(0.01 * distance(a.location, Point({latitude: 40.7128, longitude: -74.0060})) / 1000, 2) as result"
columnName: "resul"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
columnName: "resul"
columnName: "result"

@@ -402,6 +411,7 @@ describe("validateDocument", () => {
currentWeather: Weather
@cypher(
statement: "CALL apoc.load.json('https://www.7timer.info/bin/civil.php?lon=' + this.location.longitude + '&lat=' + this.location.latitude + '&ac=0&unit=metric&output=json&tzshift=0') YIELD value WITH value.dataseries[0] as weather RETURN {temperature: weather.temp2m, windSpeed: weather.wind10m.speed, windDirection: weather.wind10m.direction, precipitation: weather.prec_type, summary: weather.weather} AS conditions"
columnName: "condition"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
columnName: "condition"
columnName: "conditions"

@@ -435,6 +445,7 @@ describe("validateDocument", () => {
ORDER BY jaccard DESC
RETURN b LIMIT 1
"""
columnName: "jaccard"
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
columnName: "jaccard"
columnName: "b"

Copy link
Member Author

Choose a reason for hiding this comment

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

good catch!

});
cypherStrs.push(...legacyCypherStatement);
}
const experimentalCypherStatement = createCypherDirectiveSubquery({
Copy link
Contributor

Choose a reason for hiding this comment

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

This probably shouldn't be called experimental anymore

Suggested change
const experimentalCypherStatement = createCypherDirectiveSubquery({
const cypherStatement = createCypherDirectiveSubquery({

const experimentalCypherStatement = createCypherDirectiveSubquery({
field,
});
cypherStrs.push(...experimentalCypherStatement);
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
cypherStrs.push(...experimentalCypherStatement);
cypherStrs.push(...cypherStatement);

@@ -79,7 +79,8 @@ describe("cypher", () => {
statement: """
MATCH (m:${Movie} {title: $title})
RETURN m
"""
""",
columnName: "m"
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Also not a blocker but I'm not clear what should happen if a user tried to return multiple columns in their cypher statement. Are there any tests for this?

Copy link
Member Author

Choose a reason for hiding this comment

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

it would get ignored, as columnName is used in with

@@ -1,115 +0,0 @@
/*
Copy link
Contributor

Choose a reason for hiding this comment

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

Why has this been deleted? Is it not possible to use columnName in this test?

Copy link
Member Author

Choose a reason for hiding this comment

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

This test is no longer relevant, as this is only caused when a cypher query does not return anything, which is no longer supported

Copy link
Contributor

@darrellwarde darrellwarde left a comment

Choose a reason for hiding this comment

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

The changes are good! You are going to have to remind me, why is it that we decided against running EXPLAIN on the queries? I'm still really not 100% a fan of this approach, it feels somewhat like we're pinning our shortcomings onto our users.

@@ -182,7 +182,7 @@ describe("makeAugmentedSchema", () => {
}

type Query {
movies: [Movie!]! @cypher(statement: "")
movies: [Movie!]! @cypher(statement: "RETURN 5 as a", columnName: "a")
Copy link
Contributor

Choose a reason for hiding this comment

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

The examples in this file upset me, I really wish there was a way we could have Cypher queries like this without the aliasing.

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 agree, but none we could find :(

@angrykoala
Copy link
Member Author

answering to you @darrellwarde

EXPLAIN has a lots of gotchas and pitfalls in its implementation, but most importantly, not all of the RETURN cases are covered, as explain does not really produce a consistent list of returned columns, with several cases requiring flaky custom parsing, and other cases simply not providing the variables.

I have the same concerns, and I feel that we could even keep providing a version without columnName using APOC, even if not recommended.

Another alternative could be trying to do some parsing if columnName is not provided. Even if this alternative does not work for all cases, columnName will always be available there to custom configure.

I'm happy to keep this PR open a bit longer if we want to keep this discussion going before merging

@angrykoala angrykoala merged commit 92bf74f into neo4j:4.0.0 Jan 30, 2023
@angrykoala angrykoala deleted the remove-run-first-column branch January 30, 2023 14:36
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.

5 participants