@@ -146,7 +146,10 @@ type InsertBuilder struct {
146146 returning []string
147147 values [][]any
148148 conflict * conflict
149- isUpsert bool // YDB-specific: use UPSERT instead of INSERT
149+
150+ // YDB-specific:
151+ isUpsert bool // use UPSERT instead of INSERT
152+ isReplace bool // use REPLACE instead of INSERT
150153}
151154
152155// Insert creates a builder for the `INSERT INTO` statement.
@@ -174,6 +177,21 @@ func Upsert(table string) *InsertBuilder {
174177 return & InsertBuilder {table : table , isUpsert : true }
175178}
176179
180+ // Replace creates a builder for the `REPLACE INTO` statement.
181+ // REPLACE overwrites entire rows based on primary key comparison.
182+ // For existing rows, the entire row is replaced (unspecified columns get default values).
183+ // For missing rows, new rows are inserted.
184+ //
185+ // Replace("users").
186+ // Columns("id", "name", "age").
187+ // Values(1, "a8m", 10).
188+ // Values(2, "foo", 20)
189+ //
190+ // Note: REPLACE is only supported in YDB dialect.
191+ func Replace (table string ) * InsertBuilder {
192+ return & InsertBuilder {table : table , isReplace : true }
193+ }
194+
177195// Schema sets the database name for the insert table.
178196func (i * InsertBuilder ) Schema (name string ) * InsertBuilder {
179197 i .schema = name
@@ -454,17 +472,23 @@ func (i *InsertBuilder) Query() (string, []any) {
454472 return query , args
455473}
456474
457- // QueryErr returns query representation of an `INSERT INTO` or `UPSERT INTO`
458- // statement and any error occurred in building the statement.
475+ // QueryErr returns query representation of an `INSERT INTO`, `UPSERT INTO`,
476+ // or `REPLACE INTO` statement and any error occurred in building the statement.
459477func (i * InsertBuilder ) QueryErr () (string , []any , error ) {
460478 b := i .Builder .clone ()
461479
462480 if i .isUpsert {
463481 if ! b .ydb () {
464- b .AddError (fmt .Errorf ("UPSERT: unsupported dialect: %q" , b .dialect ))
482+ b .AddError (fmt .Errorf ("UPSERT INTO : unsupported dialect: %q" , b .dialect ))
465483 return "" , nil , b .Err ()
466484 }
467485 b .WriteString ("UPSERT INTO " )
486+ } else if i .isReplace {
487+ if ! b .ydb () {
488+ b .AddError (fmt .Errorf ("REPLACE INTO: unsupported dialect: %q" , b .dialect ))
489+ return "" , nil , b .Err ()
490+ }
491+ b .WriteString ("REPLACE INTO " )
468492 } else {
469493 b .WriteString ("INSERT INTO " )
470494 }
@@ -3657,6 +3681,19 @@ func (d *DialectBuilder) Upsert(table string) *InsertBuilder {
36573681 return b
36583682}
36593683
3684+ // Replace creates an InsertBuilder for the REPLACE statement with the configured dialect.
3685+ // REPLACE is only supported in YDB dialect.
3686+ //
3687+ // Dialect(dialect.YDB).
3688+ // Replace("users").
3689+ // Columns("id", "name", "age").
3690+ // Values(1, "a8m", 10)
3691+ func (d * DialectBuilder ) Replace (table string ) * InsertBuilder {
3692+ b := Replace (table )
3693+ b .SetDialect (d .dialect )
3694+ return b
3695+ }
3696+
36603697// Update creates a UpdateBuilder for the configured dialect.
36613698//
36623699// Dialect(dialect.Postgres).
0 commit comments