]> granicus.if.org Git - ejabberd/commitdiff
Fix some LIMIT related problems with MSSQL
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Thu, 24 Mar 2016 12:03:19 +0000 (15:03 +0300)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Tue, 29 Mar 2016 08:34:00 +0000 (11:34 +0300)
src/ejabberd_odbc.erl
src/mod_mam.erl
src/node_flat_odbc.erl

index e98665862b9e16726ce670ba8c0b4dc973e5f19a..f595933a1f452b81a9c5474d864d3890e13074eb 100644 (file)
@@ -269,6 +269,7 @@ connecting(connect, #state{host = Host} = State) ->
                   [mysql | Args] -> apply(fun mysql_connect/5, Args);
            [pgsql | Args] -> apply(fun pgsql_connect/5, Args);
            [sqlite | Args] -> apply(fun sqlite_connect/1, Args);
+                  [mssql | Args] -> apply(fun odbc_connect/1, Args);
                   [odbc | Args] -> apply(fun odbc_connect/1, Args)
                 end,
     {_, PendingRequests} = State#state.pending_requests,
@@ -505,6 +506,8 @@ sql_query_internal(#sql_query{} = Query) ->
             case State#state.db_type of
                 odbc ->
                     generic_sql_query(Query);
+               mssql ->
+                   generic_sql_query(Query);
                 pgsql ->
                     Key = {?PREPARE_KEY, Query#sql_query.hash},
                     case get(Key) of
@@ -554,7 +557,10 @@ sql_query_internal(Query) ->
     ?DEBUG("SQL: \"~s\"", [Query]),
     Res = case State#state.db_type of
            odbc ->
-               to_odbc(odbc:sql_query(State#state.db_ref, Query,
+               to_odbc(odbc:sql_query(State#state.db_ref, [Query],
+                                       (?TRANSACTION_TIMEOUT) - 1000));
+           mssql ->
+               to_odbc(odbc:sql_query(State#state.db_ref, [Query],
                                        (?TRANSACTION_TIMEOUT) - 1000));
            pgsql ->
                pgsql_to_odbc(pgsql:squery(State#state.db_ref, Query));
@@ -898,8 +904,8 @@ db_opts(Host) ->
                                               <<"">>),
            case Type of
                mssql ->
-                   [odbc, <<"DSN=", Host/binary, ";UID=", User/binary,
-                            ";PWD=", Pass/binary>>];
+                   [mssql, <<"DSN=", Host/binary, ";UID=", User/binary,
+                             ";PWD=", Pass/binary>>];
                _ ->
                    [Type, Server, Port, DB, User, Pass]
            end
index 38642c0c6abd31c81af55703dbd7888e59caccc4..d212f63c67c1d92020e012b37936c771614d7007 100644 (file)
@@ -1260,7 +1260,7 @@ make_matchspec(LUser, LServer, Start, End, none) ->
              Msg
       end).
 
-make_sql_query(User, _LServer, Start, End, With, RSM) ->
+make_sql_query(User, LServer, Start, End, With, RSM) ->
     {Max, Direction, ID} = case RSM of
        #rsm_in{} ->
            {RSM#rsm_in.max,
@@ -1269,11 +1269,19 @@ make_sql_query(User, _LServer, Start, End, With, RSM) ->
        none ->
            {none, none, <<>>}
     end,
-    LimitClause = if is_integer(Max), Max >= 0 ->
+    ODBCType = ejabberd_config:get_option(
+                {odbc_type, LServer},
+                ejabberd_odbc:opt_type(odbc_type)),
+    LimitClause = if is_integer(Max), Max >= 0, ODBCType /= mssql ->
                          [<<" limit ">>, jlib:integer_to_binary(Max+1)];
                     true ->
                          []
                  end,
+    TopClause = if is_integer(Max), Max >= 0, ODBCType == mssql ->
+                         [<<" TOP ">>, jlib:integer_to_binary(Max+1)];
+                    true ->
+                         []
+                 end,
     WithClause = case With of
                     {text, <<>>} ->
                         [];
@@ -1320,7 +1328,7 @@ make_sql_query(User, _LServer, Start, End, With, RSM) ->
                end,
     SUser = ejabberd_odbc:escape(User),
 
-    Query = [<<"SELECT timestamp, xml, peer, kind, nick"
+    Query = [<<"SELECT ">>, TopClause, <<" timestamp, xml, peer, kind, nick"
              " FROM archive WHERE username='">>,
             SUser, <<"'">>, WithClause, StartClause, EndClause,
             PageClause],
index e3c57938274718a1e7a5f8abefdfef52c90b3a34..5aeb973d123d4309e42fc8bb0e1ee1028eea6ea8 100644 (file)
@@ -697,12 +697,21 @@ get_items(Nidx, _From,
        {selected, [_], [[C]]} -> C;
        _ -> <<"0">>
     end,
-    case catch
-       ejabberd_odbc:sql_query_t([<<"select itemid, publisher, creation, modification, payload "
-                   "from pubsub_item where nodeid='">>, Nidx,
-               <<"' and ">>, AttrName, <<" ">>, Way, <<" ">>, Id, <<" order by ">>,
-               AttrName, <<" ">>, Order, <<" limit ">>, jlib:i2l(Max), <<" ;">>])
-    of
+    Query = fun(mssql, _) ->
+                   ejabberd_odbc:sql_query_t(
+                     [<<"select top ">>, jlib:i2l(Max),
+                      <<" itemid, publisher, creation, modification, payload "
+                        "from pubsub_item where nodeid='">>, Nidx,
+                      <<"' and ">>, AttrName, <<" ">>, Way, <<" ">>, Id, <<" order by ">>,
+                      AttrName, <<" ">>, Order, <<";">>]);
+              (_, _) ->
+                   ejabberd_odbc:sql_query_t(
+                     [<<"select itemid, publisher, creation, modification, payload "
+                        "from pubsub_item where nodeid='">>, Nidx,
+                      <<"' and ">>, AttrName, <<" ">>, Way, <<" ">>, Id, <<" order by ">>,
+                      AttrName, <<" ">>, Order, <<" limit ">>, jlib:i2l(Max), <<" ;">>])
+           end,
+    case catch ejabberd_odbc:sql_query_t(Query) of
        {selected,
                    [<<"itemid">>, <<"publisher">>, <<"creation">>, <<"modification">>, <<"payload">>], RItems} ->
            case RItems of
@@ -760,11 +769,20 @@ get_items(Nidx, JID, AccessModel, PresenceSubscription, RosterGroup, _SubId, RSM
     end.
 
 get_last_items(Nidx, _From, Count) ->
-    case catch
-       ejabberd_odbc:sql_query_t([<<"select itemid, publisher, creation, modification, payload "
-                   "from pubsub_item where nodeid='">>, Nidx,
-               <<"' order by modification desc limit ">>, jlib:i2l(Count), <<";">>])
-    of
+    Limit = jlib:i2l(Count),
+    Query = fun(mssql, _) ->
+                   ejabberd_odbc:sql_query_t(
+                     [<<"select top ">>, Limit,
+                      <<" itemid, publisher, creation, modification, payload "
+                        "from pubsub_item where nodeid='">>, Nidx,
+                      <<"' order by modification desc ;">>]);
+              (_, _) ->
+                   ejabberd_odbc:sql_query_t(
+                     [<<"select itemid, publisher, creation, modification, payload "
+                        "from pubsub_item where nodeid='">>, Nidx,
+                      <<"' order by modification desc limit ">>, Limit, <<";">>])
+           end,
+    case catch ejabberd_odbc:sql_query_t(Query) of
        {selected,
                    [<<"itemid">>, <<"publisher">>, <<"creation">>, <<"modification">>, <<"payload">>], RItems} ->
            {result, [raw_to_item(Nidx, RItem) || RItem <- RItems]};