on dev help sign in
Remove column name ambiguity in ON CONFLICT DO UPDATE clauses
e2c57b4Rhys
squeal-postgresql/src/Squeal/PostgreSQL/Manipulation.hs+21−13
@@ -124,11 +124,11 @@ let
124 (OnConflictDoUpdate
124 (OnConflictDoUpdate
125 (UniqueIndexOn #col1)
125 (UniqueIndexOn #col1)
126 (Set 2 `as` #col1 :* Same `as` #col2)
126 (Set 2 `as` #col1 :* Same `as` #col2)
127− [#col1 .== #col2])
127+ [#existing ! #col1 .== #excluded ! #col2])
128 (Returning $ (#col1 + #col2) `as` #sum)
128 (Returning $ (#col1 + #col2) `as` #sum)
129in printSQL manipulation
129in printSQL manipulation
130:}
130:}
131−INSERT INTO "tab" ("col1", "col2") VALUES (2, 4), (6, 8) ON CONFLICT ("col1") DO UPDATE SET "col1" = 2 WHERE ("col1" = "col2") RETURNING ("col1" + "col2") AS "sum"
131+INSERT INTO "tab" AS existing ("col1", "col2") VALUES (2, 4), (6, 8) ON CONFLICT ("col1") DO UPDATE SET "col1" = 2 WHERE ("existing"."col1" = "excluded"."col2") RETURNING ("col1" + "col2") AS "sum"
132
132
133query insert:
133query insert:
134
134
@@ -245,6 +245,7 @@ insertRows
245 -> Manipulation schema params results
245 -> Manipulation schema params results
246insertRows tab rw rws conflict returning = UnsafeManipulation $
246insertRows tab rw rws conflict returning = UnsafeManipulation $
247 "INSERT" <+> "INTO" <+> renderAlias tab
247 "INSERT" <+> "INTO" <+> renderAlias tab
248+ <> renderConflictAlias conflict
248 <+> parenthesized (renderCommaSeparated renderAliasPart rw)
249 <+> parenthesized (renderCommaSeparated renderAliasPart rw)
249 <+> "VALUES"
250 <+> "VALUES"
250 <+> commaSeparated
251 <+> commaSeparated
@@ -312,6 +313,7 @@ insertQuery
312 -> Manipulation schema params results
313 -> Manipulation schema params results
313insertQuery tab query conflict returning = UnsafeManipulation $
314insertQuery tab query conflict returning = UnsafeManipulation $
314 "INSERT" <+> "INTO" <+> renderAlias tab
315 "INSERT" <+> "INTO" <+> renderAlias tab
316+ <> renderConflictAlias conflict
315 <+> renderQuery query
317 <+> renderQuery query
316 <> renderConflictClause conflict
318 <> renderConflictClause conflict
317 <> renderReturningClause returning
319 <> renderReturningClause returning
@@ -334,15 +336,15 @@ insertQuery_ tab query =
334-- existing value in the row for an update.
336-- existing value in the row for an update.
335data ColumnValue
337data ColumnValue
336 (schema :: SchemaType)
338 (schema :: SchemaType)
337− (columns :: RowType)
339+ (tables :: FromType)
338 (params :: [NullityType])
340 (params :: [NullityType])
339 (ty :: ColumnType)
341 (ty :: ColumnType)
340 where
342 where
341− Same :: ColumnValue schema (column ': columns) params ty
343+ Same :: ColumnValue schema (table ': tables) params ty
342− Default :: ColumnValue schema columns params ('Def :=> ty)
344+ Default :: ColumnValue schema tables params ('Def :=> ty)
343 Set
345 Set
344− :: (forall table. Expression schema '[table ::: columns] 'Ungrouped params ty)
346+ :: Expression schema tables 'Ungrouped params ty
345− -> ColumnValue schema columns params (constraint :=> ty)
347+ -> ColumnValue schema tables params (constraint :=> ty)
346
348
347-- | A `ReturningClause` computes and return value(s) based
349-- | A `ReturningClause` computes and return value(s) based
348-- on each row actually inserted, updated or deleted. This is primarily
350-- on each row actually inserted, updated or deleted. This is primarily
@@ -391,12 +393,12 @@ data ConflictClause
391 OnConflictDoUpdate
393 OnConflictDoUpdate
392 :: (row ~ TableToRow table, columns ~ TableToColumns table)
394 :: (row ~ TableToRow table, columns ~ TableToColumns table)
393 => ConflictTarget table
395 => ConflictTarget table
394− -> NP (Aliased (ColumnValue schema row params)) columns
396+ -> NP (Aliased (ColumnValue schema '["existing" ::: row, "excluded" ::: row] params)) columns
395− -> [Condition schema '[t ::: row] 'Ungrouped params]
397+ -> [Condition schema '["existing" ::: row, "excluded" ::: row] 'Ungrouped params]
396 -> ConflictClause schema table params
398 -> ConflictClause schema table params
397
399
398−-- | A 'ConflictTarget' specifies the constraint violation that triggers an
400+-- | A `ConflictTarget` specifies the constraint violation that triggers an
399−-- 'OnConflictDoUpdate'.
401+-- `OnConflictDoUpdate`.
400data ConflictTarget (table :: TableType) where
402data ConflictTarget (table :: TableType) where
401 -- | An explicitly named constraint.
403 -- | An explicitly named constraint.
402 OnConstraint
404 OnConstraint
@@ -410,6 +412,12 @@ data ConflictTarget (table :: TableType) where
410 => NP Alias columnNames
412 => NP Alias columnNames
411 -> ConflictTarget '(constraints, columns)
413 -> ConflictTarget '(constraints, columns)
412
414
415+-- | Render any table alias required for a `ConflictClause`.
416+renderConflictAlias :: ConflictClause schema table params -> ByteString
417+renderConflictAlias = \case
418+ OnConflictDoUpdate _ _ _ -> " AS existing"
419+ _ -> ""
420+
413-- | Render a `ConflictClause`.
421-- | Render a `ConflictClause`.
414renderConflictClause
422renderConflictClause
415 :: SOP.SListI (TableToColumns table)
423 :: SOP.SListI (TableToColumns table)
@@ -458,7 +466,7 @@ update
458 , row ~ TableToRow table
466 , row ~ TableToRow table
459 , columns ~ TableToColumns table )
467 , columns ~ TableToColumns table )
460 => Alias tab -- ^ table to update
468 => Alias tab -- ^ table to update
461− -> NP (Aliased (ColumnValue schema row params)) columns
469+ -> (forall t. NP (Aliased (ColumnValue schema '[t ::: row] params)) columns)
462 -- ^ modified values to replace old values
470 -- ^ modified values to replace old values
463 -> (forall t. Condition schema '[t ::: row] 'Ungrouped params)
471 -> (forall t. Condition schema '[t ::: row] 'Ungrouped params)
464 -- ^ condition under which to perform update on a row
472 -- ^ condition under which to perform update on a row
@@ -489,7 +497,7 @@ update_
489 , row ~ TableToRow table
497 , row ~ TableToRow table
490 , columns ~ TableToColumns table )
498 , columns ~ TableToColumns table )
491 => Alias tab -- ^ table to update
499 => Alias tab -- ^ table to update
492− -> NP (Aliased (ColumnValue schema row params)) columns
500+ -> (forall t. NP (Aliased (ColumnValue schema '[t ::: row] params)) columns)
493 -- ^ modified values to replace old values
501 -- ^ modified values to replace old values
494 -> (forall t. Condition schema '[t ::: row] 'Ungrouped params)
502 -> (forall t. Condition schema '[t ::: row] 'Ungrouped params)
495 -- ^ condition under which to perform update on a row
503 -- ^ condition under which to perform update on a row