mirror of
https://github.com/valitydev/riak_test.git
synced 2024-11-06 16:45:29 +00:00
149 lines
5.5 KiB
Erlang
149 lines
5.5 KiB
Erlang
%% -------------------------------------------------------------------
|
|
%%
|
|
%% Copyright (c) 2015 Basho Technologies, Inc.
|
|
%%
|
|
%% This file is provided to you under the Apache License,
|
|
%% Version 2.0 (the "License"); you may not use this file
|
|
%% except in compliance with the License. You may obtain
|
|
%% a copy of the License at
|
|
%%
|
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
|
%%
|
|
%% Unless required by applicable law or agreed to in writing,
|
|
%% software distributed under the License is distributed on an
|
|
%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
%% KIND, either express or implied. See the License for the
|
|
%% specific language governing permissions and limitations
|
|
%% under the License.
|
|
%%
|
|
%% -------------------------------------------------------------------
|
|
%% A simple timeseries test to select along the IS [NOT] NULL predicates for
|
|
%% all various datatypes.
|
|
%%
|
|
%% The premise is that if it holds that neither set of IS NULL and IS NOT NULL
|
|
%% satisfying result sets are empty, then the count of rows in the sets combined
|
|
%% matching the count of rows in the set resulting from querying without the
|
|
%% NULL predicates proves that each predicate is correctly implemented.
|
|
|
|
-module(ts_simple_select_is_null).
|
|
|
|
-behavior(riak_test).
|
|
|
|
-export([confirm/0]).
|
|
|
|
-include_lib("eunit/include/eunit.hrl").
|
|
|
|
-define(SPANNING_STEP, (1000)).
|
|
-define(TEST_TYPE, normal).
|
|
|
|
confirm() ->
|
|
%% will fail if ts_simple_put_all_null_datatypes fails
|
|
DDL =
|
|
"CREATE TABLE GeoCheckin ("
|
|
" myfamily varchar not null,"
|
|
" myseries varchar not null,"
|
|
" time timestamp not null,"
|
|
" myvarchar varchar ,"
|
|
" myint sint64 ,"
|
|
" myfloat double ,"
|
|
" mybool boolean ,"
|
|
" mytimestamp timestamp ,"
|
|
" PRIMARY KEY ((myfamily, myseries, quantum(time, 15, 'm')),"
|
|
" myfamily, myseries, time))",
|
|
Family = <<"family1">>,
|
|
Series = <<"seriesX">>,
|
|
N = 11,
|
|
Data = make_data(N, Family, Series, []),
|
|
ClusterConn = ts_util:cluster_and_connect(single),
|
|
Got = ts_util:ts_put(ClusterConn, ?TEST_TYPE, DDL, Data),
|
|
?assertEqual(ok, Got),
|
|
Qry = "SELECT * FROM GeoCheckin WHERE"
|
|
" myfamily='" ++ binary_to_list(Family) ++ "'"
|
|
" AND myseries='" ++ binary_to_list(Series) ++ "'"
|
|
" AND time >= 1000 AND time <= " ++ integer_to_list(N * 1000) ++
|
|
" AND myvarchar IS NULL",
|
|
{ok, {_Fields, Rows}} = ts_util:ts_query(ClusterConn, ?TEST_TYPE, DDL, Data, Qry),
|
|
?assertNotEqual(0, length(Rows)),
|
|
NullableFields = [ "myvarchar", "myint", "myfloat", "mybool", "mytimestamp" ],
|
|
lists:foreach(fun (Field) ->
|
|
query_field(Field, ClusterConn, DDL, Data, Family, Series, N)
|
|
end, NullableFields),
|
|
pass.
|
|
|
|
query_field(Field, ClusterConn, DDL, Data, Family, Series, N) ->
|
|
RowsAll = query_all(ClusterConn, DDL, Data, Family, Series, N),
|
|
RowsIsNull = query_is_null(ClusterConn, DDL, Data, Family, Series, N, Field),
|
|
RowsIsNotNull = query_is_not_null(ClusterConn, DDL, Data, Family, Series, N, Field),
|
|
?assertEqual(RowsAll, RowsIsNull + RowsIsNotNull).
|
|
|
|
query_base(Family, Series, N) ->
|
|
"SELECT * FROM GeoCheckin WHERE"
|
|
" myfamily='" ++ binary_to_list(Family) ++ "'"
|
|
" AND myseries='" ++ binary_to_list(Series) ++ "'"
|
|
" AND time >= 1000 AND time <= " ++ integer_to_list(N * 1000 + ?SPANNING_STEP).
|
|
|
|
query_all(ClusterConn, DDL, Data, Family, Series, N) ->
|
|
Qry = query_base(Family, Series, N),
|
|
{ok, {_Fields, Rows}} = ts_util:ts_query(ClusterConn, ?TEST_TYPE, DDL, Data, Qry),
|
|
RowsN = length(Rows),
|
|
?assertNotEqual(0, RowsN),
|
|
RowsN.
|
|
|
|
query_is_null(ClusterConn, DDL, Data, Family, Series, N, Field) ->
|
|
Qry = query_base(Family, Series, N) ++
|
|
" AND " ++ Field ++ " IS NULL",
|
|
{ok, {_Fields, Rows}} = ts_util:ts_query(ClusterConn, ?TEST_TYPE, DDL, Data, Qry),
|
|
RowsN = length(Rows),
|
|
%% the number of NULL rows can be determined by any non-key field being NULL
|
|
RowsNull = lists:foldr(fun (El, Acc) ->
|
|
case element(4, El) of
|
|
[] -> Acc + 1;
|
|
_ -> Acc
|
|
end
|
|
end, 0, Data),
|
|
?assertEqual(RowsNull, RowsN),
|
|
RowsN.
|
|
|
|
query_is_not_null(ClusterConn, DDL, Data, Family, Series, N, Field) ->
|
|
Qry = query_base(Family, Series, N) ++
|
|
" AND " ++ Field ++ " IS NOT NULL",
|
|
{ok, {_Fields, Rows}} = ts_util:ts_query(ClusterConn, ?TEST_TYPE, DDL, Data, Qry),
|
|
RowsN = length(Rows),
|
|
%% the number of NULL rows can be determined by any non-key field being NULL
|
|
RowsNotNull = lists:foldr(fun (El, Acc) ->
|
|
case element(4, El) of
|
|
[] -> Acc;
|
|
_ -> Acc + 1
|
|
end
|
|
end, 0, Data),
|
|
?assertEqual(RowsNotNull, RowsN),
|
|
RowsN.
|
|
|
|
%% insert every even row as null
|
|
make_data(0, _, _, Acc) ->
|
|
Acc;
|
|
make_data(N, F, S, Acc) when is_integer(N) andalso N rem 2 =:= 1 ->
|
|
NewAcc = {
|
|
F,
|
|
S,
|
|
1 + N * ?SPANNING_STEP,
|
|
<<"">>, %%<< using empty string to stress the difference between NULL and <<"">>
|
|
N,
|
|
N * 1.0,
|
|
N rem 6 =:= 0,
|
|
N
|
|
},
|
|
make_data(N - 1, F, S, [NewAcc | Acc]);
|
|
make_data(N, F, S, Acc) when is_integer(N) ->
|
|
NewAcc = {
|
|
F,
|
|
S,
|
|
1 + N * ?SPANNING_STEP,
|
|
[],
|
|
[],
|
|
[],
|
|
[],
|
|
[]
|
|
},
|
|
make_data(N - 1, F, S, [NewAcc | Acc]).
|