percentile.test 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. # 2013-05-28
  2. #
  3. # The author disclaims copyright to this source code. In place of
  4. # a legal notice, here is a blessing:
  5. #
  6. # May you do good and not evil.
  7. # May you find forgiveness for yourself and forgive others.
  8. # May you share freely, never taking more than you give.
  9. #
  10. #***********************************************************************
  11. # This file implements regression tests for SQLite library. The
  12. # focus of this file is percentile.c extension
  13. #
  14. set testdir [file dirname $argv0]
  15. source $testdir/tester.tcl
  16. # Basic test of the percentile() function.
  17. #
  18. do_test percentile-1.0 {
  19. load_static_extension db percentile
  20. execsql {
  21. CREATE TABLE t1(x);
  22. INSERT INTO t1 VALUES(1),(4),(6),(7),(8),(9),(11),(11),(11);
  23. }
  24. execsql {SELECT percentile(x,0) FROM t1}
  25. } {1.0}
  26. foreach {in out} {
  27. 100 11.0
  28. 50 8.0
  29. 12.5 4.0
  30. 15 4.4
  31. 20 5.2
  32. 80 11.0
  33. 89 11.0
  34. } {
  35. do_test percentile-1.1.$in {
  36. execsql {SELECT percentile(x,$in) FROM t1}
  37. } $out
  38. }
  39. # Add some NULL values.
  40. #
  41. do_test percentile-1.2 {
  42. execsql {INSERT INTO t1 VALUES(NULL),(NULL);}
  43. } {}
  44. foreach {in out} {
  45. 100 11.0
  46. 50 8.0
  47. 12.5 4.0
  48. 15 4.4
  49. 20 5.2
  50. 80 11.0
  51. 89 11.0
  52. } {
  53. do_test percentile-1.3.$in {
  54. execsql {SELECT percentile(x,$in) FROM t1}
  55. } $out
  56. }
  57. # The second argument to percentile can change some, but not much.
  58. #
  59. do_test percentile-1.4 {
  60. catchsql {SELECT round(percentile(x, 15+0.000001*rowid),1) FROM t1}
  61. } {0 4.4}
  62. do_test percentile-1.5 {
  63. catchsql {SELECT round(percentile(x, 15+0.1*rowid),1) FROM t1}
  64. } {1 {2nd argument to percentile() is not the same for all input rows}}
  65. # Input values in a random order
  66. #
  67. do_test percentile-1.6 {
  68. execsql {
  69. CREATE TABLE t2(x);
  70. INSERT INTO t2 SELECT x+0.0 FROM t1 ORDER BY random();
  71. }
  72. } {}
  73. foreach {in out} {
  74. 100 11.0
  75. 50 8.0
  76. 12.5 4.0
  77. 15 4.4
  78. 20 5.2
  79. 80 11.0
  80. 89 11.0
  81. } {
  82. do_test percentile-1.7.$in {
  83. execsql {SELECT percentile(x,$in) FROM t2}
  84. } $out
  85. }
  86. # Wrong number of arguments
  87. #
  88. do_test percentile-1.8 {
  89. catchsql {SELECT percentile(x,0,1) FROM t1}
  90. } {1 {wrong number of arguments to function percentile()}}
  91. do_test percentile-1.9 {
  92. catchsql {SELECT percentile(x) FROM t1}
  93. } {1 {wrong number of arguments to function percentile()}}
  94. # Second argument must be numeric
  95. #
  96. do_test percentile-1.10 {
  97. catchsql {SELECT percentile(x,null) FROM t1}
  98. } {1 {2nd argument to percentile() is not a number between 0.0 and 100.0}}
  99. do_test percentile-1.11 {
  100. catchsql {SELECT percentile(x,'fifty') FROM t1}
  101. } {1 {2nd argument to percentile() is not a number between 0.0 and 100.0}}
  102. do_test percentile-1.12 {
  103. catchsql {SELECT percentile(x,x'3530') FROM t1}
  104. } {1 {2nd argument to percentile() is not a number between 0.0 and 100.0}}
  105. # Second argument is out of range
  106. #
  107. do_test percentile-1.13 {
  108. catchsql {SELECT percentile(x,-0.0000001) FROM t1}
  109. } {1 {2nd argument to percentile() is not a number between 0.0 and 100.0}}
  110. do_test percentile-1.14 {
  111. catchsql {SELECT percentile(x,100.0000001) FROM t1}
  112. } {1 {2nd argument to percentile() is not a number between 0.0 and 100.0}}
  113. # First argument is not NULL and is not NUMERIC
  114. #
  115. do_test percentile-1.15 {
  116. catchsql {
  117. BEGIN;
  118. UPDATE t1 SET x='50' WHERE x IS NULL;
  119. SELECT percentile(x, 50) FROM t1;
  120. }
  121. } {1 {1st argument to percentile() is not numeric}}
  122. do_test percentile-1.16 {
  123. catchsql {
  124. ROLLBACK;
  125. BEGIN;
  126. UPDATE t1 SET x=x'3530' WHERE x IS NULL;
  127. SELECT percentile(x, 50) FROM t1;
  128. }
  129. } {1 {1st argument to percentile() is not numeric}}
  130. do_test percentile-1.17 {
  131. catchsql {
  132. ROLLBACK;
  133. SELECT percentile(x, 50) FROM t1;
  134. }
  135. } {0 8.0}
  136. # No non-NULL entries.
  137. #
  138. do_test percentile-1.18 {
  139. execsql {
  140. UPDATE t1 SET x=NULL;
  141. SELECT ifnull(percentile(x, 50),'NULL') FROM t1
  142. }
  143. } {NULL}
  144. # Exactly one non-NULL entry
  145. #
  146. do_test percentile-1.19 {
  147. execsql {
  148. UPDATE t1 SET x=12345 WHERE rowid=5;
  149. SELECT percentile(x, 0), percentile(x, 50), percentile(x,100) FROM t1
  150. }
  151. } {12345.0 12345.0 12345.0}
  152. # Infinity as an input
  153. #
  154. do_test percentile-1.20 {
  155. catchsql {
  156. DELETE FROM t1;
  157. INSERT INTO t1 SELECT x+0.0 FROM t2;
  158. UPDATE t1 SET x=1.0e300*1.0e300 WHERE rowid=5;
  159. SELECT percentile(x,50) from t1;
  160. }
  161. } {1 {Inf input to percentile()}}
  162. do_test percentile-1.21 {
  163. catchsql {
  164. UPDATE t1 SET x=-1.0e300*1.0e300 WHERE rowid=5;
  165. SELECT percentile(x,50) from t1;
  166. }
  167. } {1 {Inf input to percentile()}}
  168. # Million-row Inputs
  169. #
  170. ifcapable vtab {
  171. do_test percentile-2.0 {
  172. load_static_extension db wholenumber
  173. execsql {
  174. CREATE VIRTUAL TABLE nums USING wholenumber;
  175. CREATE TABLE t3(x);
  176. INSERT INTO t3 SELECT value-1 FROM nums WHERE value BETWEEN 1 AND 500000;
  177. INSERT INTO t3 SELECT value*10 FROM nums
  178. WHERE value BETWEEN 500000 AND 999999;
  179. SELECT count(*) FROM t3;
  180. }
  181. } {1000000}
  182. foreach {in out} {
  183. 0 0.0
  184. 100 9999990.0
  185. 50 2749999.5
  186. 10 99999.9
  187. } {
  188. do_test percentile-2.1.$in {
  189. execsql {
  190. SELECT percentile(x, $in) from t3;
  191. }
  192. } $out
  193. }
  194. }
  195. finish_test