mirror of
https://github.com/processone/ejabberd
synced 2025-10-06 03:50:15 +02:00
Use INSERT ... ON DUPLICATE KEY UPDATE for upsert on mysql
This can be used for all upsert expressions (where REPLACE INTO used previously were only possible to use for subset of queries), and may potentially help with deadlocks reported by mysql when we issues multiple querier for same key in quick succession.
This commit is contained in:
parent
a6101cc26d
commit
a89b1f332d
1 changed files with 52 additions and 45 deletions
|
@ -570,20 +570,6 @@ parse_upsert_field1([C | S], Acc, ParamPos, Loc) ->
|
|||
|
||||
make_sql_upsert(Table, ParseRes, Pos) ->
|
||||
check_upsert(ParseRes, Pos),
|
||||
HasInsertOnlyFields = lists:any(
|
||||
fun({_, {false}, _}) -> true;
|
||||
(_) -> false
|
||||
end, ParseRes),
|
||||
MySqlReplace = case HasInsertOnlyFields of
|
||||
false ->
|
||||
[erl_syntax:clause(
|
||||
[erl_syntax:atom(mysql), erl_syntax:underscore()],
|
||||
[],
|
||||
[make_sql_upsert_mysql(Table, ParseRes),
|
||||
erl_syntax:atom(ok)])];
|
||||
_ ->
|
||||
[]
|
||||
end,
|
||||
erl_syntax:fun_expr(
|
||||
[erl_syntax:clause(
|
||||
[erl_syntax:atom(pgsql), erl_syntax:variable("__Version")],
|
||||
|
@ -600,9 +586,13 @@ make_sql_upsert(Table, ParseRes, Pos) ->
|
|||
erl_syntax:operator('>='),
|
||||
erl_syntax:integer(90100))],
|
||||
[make_sql_upsert_pgsql901(Table, ParseRes),
|
||||
erl_syntax:atom(ok)])] ++
|
||||
MySqlReplace ++
|
||||
[erl_syntax:clause(
|
||||
erl_syntax:atom(ok)]),
|
||||
erl_syntax:clause(
|
||||
[erl_syntax:atom(mysql), erl_syntax:underscore()],
|
||||
[],
|
||||
[make_sql_upsert_mysql(Table, ParseRes),
|
||||
erl_syntax:atom(ok)]),
|
||||
erl_syntax:clause(
|
||||
[erl_syntax:underscore(), erl_syntax:underscore()],
|
||||
none,
|
||||
[make_sql_upsert_generic(Table, ParseRes)])
|
||||
|
@ -672,9 +662,6 @@ make_sql_upsert_update(Table, ParseRes) ->
|
|||
State.
|
||||
|
||||
make_sql_upsert_insert(Table, ParseRes) ->
|
||||
make_sql_upsert_insert_replace(Table, ParseRes, "INSERT").
|
||||
|
||||
make_sql_upsert_insert_replace(Table, ParseRes, Keyword) ->
|
||||
Vals =
|
||||
lists:map(
|
||||
fun({_Field, _, ST}) ->
|
||||
|
@ -687,7 +674,7 @@ make_sql_upsert_insert_replace(Table, ParseRes, Keyword) ->
|
|||
end, ParseRes),
|
||||
State =
|
||||
concat_states(
|
||||
[#state{'query' = [{str, Keyword ++" INTO "}, {str, Table}, {str, "("}]},
|
||||
[#state{'query' = [{str, "INSERT INTO "}, {str, Table}, {str, "("}]},
|
||||
join_states(Fields, ", "),
|
||||
#state{'query' = [{str, ") VALUES ("}]},
|
||||
join_states(Vals, ", "),
|
||||
|
@ -695,15 +682,35 @@ make_sql_upsert_insert_replace(Table, ParseRes, Keyword) ->
|
|||
]),
|
||||
State.
|
||||
|
||||
make_sql_upsert_replace(Table, ParseRes) ->
|
||||
make_sql_upsert_insert_replace(Table, ParseRes, "REPLACE").
|
||||
|
||||
make_sql_upsert_mysql(Table, ParseRes) ->
|
||||
Replace = make_sql_query(make_sql_upsert_replace(Table, ParseRes)),
|
||||
Vals =
|
||||
lists:map(
|
||||
fun({_Field, _, ST}) ->
|
||||
ST
|
||||
end, ParseRes),
|
||||
{Fields, Set} =
|
||||
lists:foldr(
|
||||
fun({Field, key, _ST}, {F, S}) ->
|
||||
{[#state{'query' = [{str, Field}]} | F], S};
|
||||
({Field, {false}, _ST}, {F, S}) ->
|
||||
{[#state{'query' = [{str, Field}]} | F], S};
|
||||
({Field, {true}, _ST}, {F, S}) ->
|
||||
{[#state{'query' = [{str, Field}]} | F],
|
||||
[#state{'query' = [{str, Field}, {str, "=VALUES("}, {str, Field}, {str, ")"}]} | S]}
|
||||
end, {[], []}, ParseRes),
|
||||
Insert =
|
||||
concat_states(
|
||||
[#state{'query' = [{str, "INSERT INTO "}, {str, Table}, {str, "("}]},
|
||||
join_states(Fields, ", "),
|
||||
#state{'query' = [{str, ") VALUES ("}]},
|
||||
join_states(Vals, ", "),
|
||||
#state{'query' = [{str, ") ON DUPLICATE KEY UPDATE "}]},
|
||||
join_states(Set, ", ")
|
||||
]),
|
||||
erl_syntax:application(
|
||||
erl_syntax:atom(ejabberd_sql),
|
||||
erl_syntax:atom(sql_query_t),
|
||||
[Replace]).
|
||||
[make_sql_query(Insert)]).
|
||||
|
||||
make_sql_upsert_pgsql901(Table, ParseRes0) ->
|
||||
ParseRes = lists:map(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue