-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
sql: INSERT..ON CONFLICT updates columns not in UPDATE clause #13962
Comments
This seems to fix the issue, but I don't know what else this might break: diff --git a/pkg/sql/tablewriter.go b/pkg/sql/tablewriter.go
index 5b34be0..bf1e828 100644
--- a/pkg/sql/tablewriter.go
+++ b/pkg/sql/tablewriter.go
@@ -227,6 +227,7 @@ func (tu *tableUpserter) init(txn *client.Txn) error {
tu.indexKeyPrefix = sqlbase.MakeIndexKeyPrefix(tu.tableDesc, tu.tableDesc.PrimaryIndex.ID)
allColsIdentityExpr := len(tu.ri.insertCols) == len(tu.tableDesc.Columns) &&
+ len(tu.updateCols) == len(tu.tableDesc.Columns) &&
tu.evaler != nil && tu.evaler.isIdentityEvaler()
// When adding or removing a column in a schema change (mutation), the user
// can't specify it, which means we need to do a lookup and so we can't use |
Just took a look at this; this query definitely shouldn't be fast pathed. Your fix seems to me like the correct one, but I want to briefly remind myself how it worked when I wrote it (before the various intervening refactors) before I commit to that. |
This was always broken, thanks for tracking it down, @cuongdo! I'm sending a fix shortly |
The fast path was incorrectly taken when all columns in the DO UPDATE clause were of the form `x = excluded.x` but not every column was in the clause. This led to a correctness issue. Closes cockroachdb#13962.
This is happening again as of 1758050. Same repro as above. |
#14034 was included in the draft release notes in cockroachdb/docs#1214. Does it need to be removed from the release notes for this week? |
Ah, I see. The |
Yes, it is a little strange, but unfortunately, generated queries such as those from ORMs do have some oddities. |
The Postgres dialect for Sequelize uses a stored procedure to implement upserts, for compatibility with PostgreSQL before 9.5. CockroachDB has upsert but no stored procedures, so this monkey patch for the built-in Sequelize dialect replaces Sequelize's Model.upsert() with a version that uses `INSERT ... ON CONFLICT DO UPDATE SET`, which CockroachDB does support. require()ing the package multiple times should be fine, as `index.js` is idempotent. Note that tests will not pass until cockroachdb/cockroach#13962 is fixed. Resolves cockroachdb/cockroach#12120
The previous implementation was getting confused because it only looked for the correct number of columns in the ON CONFLICT clause. cockroachdb#13962 was broken because it included a conflict index column in the ON CONFLICT clause (which doesn't make sense for a manually written query, but some ORMs will do this). Closes cockroachdb#13962.
`INSERT .. ON CONFLICT ..` is temporarily no longer eligible for fast path. The fast path is currently only enabled when the UPSERT alias is explicitly selected by the user. It's possible to fast path some queries of the form INSERT ... ON CONFLICT, but the utility is low and there are lots of edge cases (that caused real correctness bugs cockroachdb#13437 cockroachdb#13962). As a result, we've decided to remove this until after 1.0 and re-enable it then. See cockroachdb#14482. Closes cockroachdb#13962.
Repro:
createdAt
:SHA: e66b654
Actual: both
createdAt
andupdatedAt
are updatedExpected: only
updatedAt
is updatedI've traced the issue to this line:
https://github.com/cockroachdb/cockroach/blob/master/pkg/sql/tablewriter.go#L235
(*tableUpserter).init()
is terminating very early. When I remove that wholeif
block, the upsert works correctly. There are several things I don't understand here, so assigning this to @danhhz.Also, this scenario needs a logic test.
The text was updated successfully, but these errors were encountered: