aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexey Shchepin <alexey@process-one.net>2021-09-19 05:59:12 +0300
committerAlexey Shchepin <alexey@process-one.net>2021-09-19 06:20:20 +0300
commit32cf44827d5bd47c1918250c86104f6331a4f15e (patch)
tree5044fe151fd4fd2b6aed4792202dd95a96f70f8c /src
parentFix SQL_UPSERT in mod_push_sql:store_session (diff)
Use INSERT ... ON CONFLICT in SQL_UPSERT for PostgreSQL >= 9.5
Diffstat (limited to 'src')
-rw-r--r--src/ejabberd_sql_pt.erl77
1 files changed, 68 insertions, 9 deletions
diff --git a/src/ejabberd_sql_pt.erl b/src/ejabberd_sql_pt.erl
index 130228fe1..d131570f7 100644
--- a/src/ejabberd_sql_pt.erl
+++ b/src/ejabberd_sql_pt.erl
@@ -564,15 +564,23 @@ make_sql_upsert(Table, ParseRes, Pos) ->
[]
end,
erl_syntax:fun_expr(
- [erl_syntax:clause(
- [erl_syntax:atom(pgsql), erl_syntax:variable("__Version")],
- [erl_syntax:infix_expr(
- erl_syntax:variable("__Version"),
- erl_syntax:operator('>='),
- erl_syntax:integer(90100))],
- [make_sql_upsert_pgsql901(Table, ParseRes),
- erl_syntax:atom(ok)])] ++
- MySqlReplace ++
+ [erl_syntax:clause(
+ [erl_syntax:atom(pgsql), erl_syntax:variable("__Version")],
+ [erl_syntax:infix_expr(
+ erl_syntax:variable("__Version"),
+ erl_syntax:operator('>='),
+ erl_syntax:integer(90500))],
+ [make_sql_upsert_pgsql905(Table, ParseRes),
+ erl_syntax:atom(ok)]),
+ erl_syntax:clause(
+ [erl_syntax:atom(pgsql), erl_syntax:variable("__Version")],
+ [erl_syntax:infix_expr(
+ erl_syntax:variable("__Version"),
+ erl_syntax:operator('>='),
+ erl_syntax:integer(90100))],
+ [make_sql_upsert_pgsql901(Table, ParseRes),
+ erl_syntax:atom(ok)])] ++
+ MySqlReplace ++
[erl_syntax:clause(
[erl_syntax:underscore(), erl_syntax:underscore()],
none,
@@ -713,6 +721,57 @@ make_sql_upsert_pgsql901(Table, ParseRes0) ->
erl_syntax:atom(sql_query_t),
[Upsert]).
+make_sql_upsert_pgsql905(Table, ParseRes0) ->
+ ParseRes = lists:map(
+ fun({"family", A2, A3}) -> {"\"family\"", A2, A3};
+ (Other) -> Other
+ end, ParseRes0),
+ Vals =
+ lists:map(
+ fun({_Field, _, ST}) ->
+ ST
+ end, ParseRes),
+ Fields =
+ lists:map(
+ fun({Field, _, _ST}) ->
+ #state{'query' = [{str, Field}]}
+ end, ParseRes),
+ SPairs =
+ lists:flatmap(
+ fun({_Field, key, _ST}) ->
+ [];
+ ({_Field, {false}, _ST}) ->
+ [];
+ ({Field, {true}, ST}) ->
+ [ST#state{
+ 'query' = [{str, Field}, {str, "="}] ++ ST#state.'query'
+ }]
+ end, ParseRes),
+ Set = join_states(SPairs, ", "),
+ KeyFields =
+ lists:flatmap(
+ fun({Field, key, _ST}) ->
+ [#state{'query' = [{str, Field}]}];
+ ({_Field, _, _ST}) ->
+ []
+ end, ParseRes),
+ State =
+ concat_states(
+ [#state{'query' = [{str, "INSERT INTO "}, {str, Table}, {str, "("}]},
+ join_states(Fields, ", "),
+ #state{'query' = [{str, ") VALUES ("}]},
+ join_states(Vals, ", "),
+ #state{'query' = [{str, ") ON CONFLICT ("}]},
+ join_states(KeyFields, ", "),
+ #state{'query' = [{str, ") DO UPDATE SET "}]},
+ Set
+ ]),
+ Upsert = make_sql_query(State),
+ erl_syntax:application(
+ erl_syntax:atom(ejabberd_sql),
+ erl_syntax:atom(sql_query_t),
+ [Upsert]).
+
check_upsert(ParseRes, Pos) ->
Set =