Skip to content

Commit 50af2d3

Browse files
committed
Fix invalid UPDATE stmt when none of the columns change
We need at least two columns to be able to skip a column if the value is the same in the old and new rows. Otherwise, we would end up with an invalid UPDATE statement like below: ``` UPDATE table SET WHERE "id" = 1; ``` Usually, the above could happen when REPLICA IDENTITY is set to FULL, and the UPDATE statement executed with the same values as the old ones. For e.g. ``` UPDATE table SET "id" = 1 WHERE "id" = 1; ``` Solution: Skip the update when all columns in SET clause is equal to the WHERE clause. Signed-off-by: Arunprasad Rajkumar <[email protected]>
1 parent 9031626 commit 50af2d3

File tree

5 files changed

+214
-128
lines changed

5 files changed

+214
-128
lines changed

src/bin/pgcopydb/ld_transform.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2227,12 +2227,15 @@ stream_write_update(FILE *out, LogicalMessageUpdate *update)
22272227
update->table.relname);
22282228
int pos = 0;
22292229

2230+
int skipColumnCount = 0;
2231+
22302232
for (int r = 0; r < new->values.count; r++)
22312233
{
22322234
LogicalMessageValues *values = &(new->values.array[r]);
22332235

22342236
bool first = true;
22352237

2238+
22362239
/* now loop over column values for this VALUES row */
22372240
for (int v = 0; v < values->cols; v++)
22382241
{
@@ -2273,7 +2276,11 @@ stream_write_update(FILE *out, LogicalMessageUpdate *update)
22732276
}
22742277
}
22752278

2276-
if (!skip)
2279+
if (skip)
2280+
{
2281+
++skipColumnCount;
2282+
}
2283+
else
22772284
{
22782285
if (attr->isgenerated)
22792286
{
@@ -2360,6 +2367,31 @@ stream_write_update(FILE *out, LogicalMessageUpdate *update)
23602367
return false;
23612368
}
23622369

2370+
/*
2371+
* When all column values in the SET clause are equal to those in the
2372+
* WHERE clause, we remove all columns from the SET clause. This results
2373+
* in an invalid UPDATE statement like the one shown below:
2374+
*
2375+
* UPDATE table SET WHERE "id" = 1;
2376+
*
2377+
* Usually, the above could happen when REPLICA IDENTITY is set to FULL,
2378+
* and the UPDATE statement executed with the same values as the old ones.
2379+
* For e.g.
2380+
* UPDATE table SET "id" = 1 WHERE "id" = 1;
2381+
*
2382+
* Skip the UPDATE statement in such cases.
2383+
*/
2384+
bool skipUpdate = (skipColumnCount == new->attributes.count);
2385+
2386+
if (skipUpdate)
2387+
{
2388+
log_warn("Skipping UPDATE statement as all columns are "
2389+
"the same as the old");
2390+
2391+
destroyPQExpBuffer(buf);
2392+
return true;
2393+
}
2394+
23632395
uint32_t hash = hashlittle(buf->data, buf->len, 5381);
23642396

23652397
FFORMAT(out, "PREPARE %x AS %s;\n", hash, buf->data);

0 commit comments

Comments
 (0)