--- dict-sql-private.h.orig 2019-05-19 19:00:12.395887496 +0200 +++ dict-sql-private.h 2019-05-19 19:04:00.147601310 +0200 @@ -13,6 +13,7 @@ HASH_TABLE(const char *, struct sql_prepared_statement *) prep_stmt_hash; bool has_on_duplicate_key:1; + bool has_on_conflict_do_update:1; }; #endif --- dict-sql.c.orig 2019-05-19 18:58:02.435194691 +0200 +++ dict-sql.c 2019-05-19 19:17:52.613253822 +0200 @@ -105,8 +105,10 @@ i_zero(&sql_set); sql_set.driver = driver->name; sql_set.connect_string = dict->set->connect; - /* currently pgsql and sqlite don't support "ON DUPLICATE KEY" */ + /* pgsql and sqlite don't support "ON DUPLICATE KEY" */ + /* mysql and sqlite don't support "ON CONFLICT DO UPDATE" */ dict->has_on_duplicate_key = strcmp(driver->name, "mysql") == 0; + dict->has_on_conflict_do_update = strcmp(driver->name, "pgsql") == 0; if (sql_db_cache_new(dict_sql_db_cache, &sql_set, &dict->db, error_r) < 0) { pool_unref(&pool); @@ -1108,12 +1110,15 @@ str_append_str(prefix, suffix); str_append_c(prefix, ')'); - if (!dict->has_on_duplicate_key) { + if (dict->has_on_duplicate_key ) { + str_append(prefix, " ON DUPLICATE KEY UPDATE "); + } else if(dict->has_on_conflict_do_update) { + str_append(prefix, " ON CONFLICT DO UPDATE SET "); + } else { *stmt_r = sql_dict_transaction_stmt_init(ctx, str_c(prefix), ¶ms); return 0; } - str_append(prefix, " ON DUPLICATE KEY UPDATE "); for (i = 0; i < field_count; i++) { const char *first_value_field = t_strcut(fields[i].map->value_field, ',');