temporal.slt 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. # Copyright Materialize, Inc. and contributors. All rights reserved.
  2. #
  3. # Use of this software is governed by the Business Source License
  4. # included in the LICENSE file at the root of this repository.
  5. #
  6. # As of the Change Date specified in that file, in accordance with
  7. # the Business Source License, use of this software will be governed
  8. # by the Apache License, Version 2.0.
  9. # Test temporal filtering operators
  10. mode cockroach
  11. # Two columns here represent a validity interval [a, b].
  12. # These values must be castable to mz_timestamp, otherwise the BETWEEN will error.
  13. statement ok
  14. CREATE VIEW intervals (a, b) AS VALUES (1, 10), (1, 2), (2, 13), (3, 1), (0, 10), (5, 18446744073709551614)
  15. # Select out rows when each are valid.
  16. statement ok
  17. CREATE MATERIALIZED VIEW valid AS
  18. SELECT *
  19. FROM intervals
  20. WHERE mz_now() BETWEEN a AND b;
  21. query II rowsort
  22. select * from valid AS OF 2;
  23. ----
  24. 0 10
  25. 1 10
  26. 1 2
  27. 2 13
  28. query II rowsort
  29. select * from valid AS OF 3;
  30. ----
  31. 0 10
  32. 1 10
  33. 2 13
  34. query II rowsort
  35. select * from valid AS OF 11;
  36. ----
  37. 2 13
  38. 5 18446744073709551614
  39. query II rowsort
  40. select * from valid AS OF 14;
  41. ----
  42. 5 18446744073709551614
  43. # Test that rows are not dropped just before the end of time.
  44. # That big number there should be u64::MAX.
  45. query II rowsort
  46. select * from valid AS OF 18446744073709551614;
  47. ----
  48. 5 18446744073709551614
  49. # We don't currently support specifying the max timestamp due to a limitation in linear.rs and the step_mz_timestamp internal function.
  50. # That big number there should be u64::MAX.
  51. statement ok
  52. CREATE VIEW intervals_max (a, b) AS VALUES (0, 18446744073709551615)
  53. statement ok
  54. CREATE MATERIALIZED VIEW valid_max AS
  55. SELECT *
  56. FROM intervals_max
  57. WHERE mz_now() BETWEEN a AND b
  58. query error step mz_timestamp overflow
  59. select * from valid_max AS OF 0
  60. #
  61. # Regression test for database-issues#2066
  62. #
  63. statement ok
  64. CREATE TABLE events (
  65. content text,
  66. insert_ts numeric,
  67. delete_ts numeric
  68. );
  69. statement ok
  70. CREATE MATERIALIZED VIEW valid_events AS
  71. SELECT content, count(*)
  72. FROM events
  73. WHERE mz_now() >= insert_ts
  74. AND mz_now() < delete_ts
  75. GROUP BY content;
  76. query TI rowsort
  77. select * from valid_events;
  78. ----
  79. statement error mz_logical_timestamp\(\) has been renamed to mz_now\(\)
  80. CREATE VIEW mlt AS SELECT 1 WHERE mz_logical_timestamp() = 0;
  81. # Regression test for view visitation order.
  82. statement ok
  83. CREATE SCHEMA dev_fy2023;
  84. statement ok
  85. CREATE SCHEMA dev_warm;
  86. statement ok
  87. CREATE SCHEMA dev;
  88. statement ok
  89. CREATE VIEW dev.mock_data_days AS
  90. WITH
  91. days AS (
  92. SELECT generate_series(
  93. CAST('2023-12-01 11:00:00' AS timestamp),
  94. CAST('2024-01-06' AS timestamp),
  95. CAST('1 day' AS interval)
  96. ) AS "day"
  97. UNION ALL
  98. SELECT generate_series(
  99. CAST('10000-12-01 11:00:00' AS timestamp),
  100. CAST('10001-01-01' AS timestamp),
  101. CAST('1 day' AS interval)
  102. ) AS "day"
  103. )
  104. SELECT
  105. "day" AS ts,
  106. datediff('hour', CAST('2020-01-01' AS timestamp), "day") AS id
  107. FROM days;
  108. statement ok
  109. CREATE VIEW dev_warm.stg_data_days AS
  110. SELECT *
  111. FROM dev.mock_data_days
  112. WHERE
  113. TIMESTAMP '2024-12-21' <= date_trunc('year', ts + CAST('1 year' AS interval)) AND
  114. ts + CAST('7 days' AS interval) - CAST('1 month' AS interval) < TIMESTAMP '2024-12-21';
  115. statement ok
  116. CREATE VIEW dev_warm.count_by_day AS
  117. SELECT
  118. date_trunc('day', ts) AS "day",
  119. count(*) AS cnt
  120. FROM dev_warm.stg_data_days
  121. GROUP BY 1
  122. HAVING
  123. NOT (TIMESTAMP '2024-12-21' <= date_trunc('day', ts) + CAST('7 days' AS interval)) AND
  124. TIMESTAMP '2024-12-21' <= date_trunc('year', date_trunc('day', ts) + CAST('1 year' AS interval));
  125. statement ok
  126. CREATE VIEW dev_fy2023.stg_data_days AS
  127. SELECT *
  128. FROM dev.mock_data_days
  129. WHERE
  130. CAST('2023-01-01' AS timestamp) <= ts AND
  131. ts - CAST('1 month' AS interval) < CAST('2024-01-01' AS timestamp) AND
  132. ts - CAST('0 month' AS interval) < CAST('2025-01-01' AS timestamp);
  133. statement ok
  134. CREATE VIEW dev_fy2023.count_by_day AS
  135. SELECT
  136. date_trunc('day', ts) AS "day",
  137. count(*) AS cnt
  138. FROM dev_fy2023.stg_data_days
  139. GROUP BY 1
  140. HAVING
  141. NOT (CAST('2024-01-01' AS timestamp) <= date_trunc('day', ts)) AND
  142. CAST('2023-01-01' AS timestamp) <= date_trunc('day', ts);
  143. query TIT
  144. SELECT *, 'fy2023' AS origin FROM dev_fy2023.count_by_day
  145. UNION ALL
  146. SELECT *, 'warm' AS origin FROM dev_warm.count_by_day
  147. ORDER BY day DESC;
  148. ----
  149. 2024-01-05␠00:00:00 1 warm
  150. 2024-01-04␠00:00:00 1 warm
  151. 2024-01-03␠00:00:00 1 warm
  152. 2024-01-02␠00:00:00 1 warm
  153. 2024-01-01␠00:00:00 1 warm
  154. 2023-12-31␠00:00:00 1 fy2023
  155. 2023-12-30␠00:00:00 1 fy2023
  156. 2023-12-29␠00:00:00 1 fy2023
  157. 2023-12-28␠00:00:00 1 fy2023
  158. 2023-12-27␠00:00:00 1 fy2023
  159. 2023-12-26␠00:00:00 1 fy2023
  160. 2023-12-25␠00:00:00 1 fy2023
  161. 2023-12-24␠00:00:00 1 fy2023
  162. 2023-12-23␠00:00:00 1 fy2023
  163. 2023-12-22␠00:00:00 1 fy2023
  164. 2023-12-21␠00:00:00 1 fy2023
  165. 2023-12-20␠00:00:00 1 fy2023
  166. 2023-12-19␠00:00:00 1 fy2023
  167. 2023-12-18␠00:00:00 1 fy2023
  168. 2023-12-17␠00:00:00 1 fy2023
  169. 2023-12-16␠00:00:00 1 fy2023
  170. 2023-12-15␠00:00:00 1 fy2023
  171. 2023-12-14␠00:00:00 1 fy2023
  172. 2023-12-13␠00:00:00 1 fy2023
  173. 2023-12-12␠00:00:00 1 fy2023
  174. 2023-12-11␠00:00:00 1 fy2023
  175. 2023-12-10␠00:00:00 1 fy2023
  176. 2023-12-09␠00:00:00 1 fy2023
  177. 2023-12-08␠00:00:00 1 fy2023
  178. 2023-12-07␠00:00:00 1 fy2023
  179. 2023-12-06␠00:00:00 1 fy2023
  180. 2023-12-05␠00:00:00 1 fy2023
  181. 2023-12-04␠00:00:00 1 fy2023
  182. 2023-12-03␠00:00:00 1 fy2023
  183. 2023-12-02␠00:00:00 1 fy2023
  184. 2023-12-01␠00:00:00 1 fy2023
  185. # Constant queries should have a timestamp near the current time (instead of, e.g., u64::MAX)
  186. query B
  187. select mz_now() < '3000-01-01';
  188. ----
  189. true
  190. # Regression test for https://github.com/MaterializeInc/database-issues/issues/7560
  191. query B
  192. with v as (select mz_now() < '3000-01-01') select * from v;
  193. ----
  194. true
  195. # Make sure that we find temporal expressions also in referenced views.
  196. statement ok
  197. create view v as select mz_now() as x;
  198. query B
  199. select x < '3000-01-01' from v;
  200. ----
  201. true
  202. statement ok
  203. SELECT *
  204. FROM events
  205. WHERE insert_ts + 30 >= mz_now();
  206. query error db error: ERROR: WHERE clause error: operator does not exist: mz_timestamp \- integer
  207. SELECT *
  208. FROM events
  209. WHERE insert_ts >= mz_now() - 30;
  210. statement ok
  211. CREATE TABLE t2(ts timestamp, x int);
  212. statement ok
  213. SELECT *
  214. FROM t2
  215. WHERE ts + INTERVAL '30' minutes >= mz_now();
  216. statement ok
  217. CREATE MATERIALIZED VIEW mv1 AS
  218. SELECT *
  219. FROM t2
  220. WHERE ts + INTERVAL '30' minutes >= mz_now();
  221. query error db error: ERROR: WHERE clause error: operator does not exist: mz_timestamp \- interval
  222. SELECT *
  223. FROM t2
  224. WHERE ts >= mz_now() - INTERVAL '30' minutes;
  225. query error db error: ERROR: WHERE clause error: operator does not exist: mz_timestamp \- interval
  226. CREATE MATERIALIZED VIEW mv_err AS
  227. SELECT *
  228. FROM t2
  229. WHERE ts >= mz_now() - INTERVAL '30' minutes;
  230. statement ok
  231. SELECT *
  232. FROM t2
  233. WHERE
  234. ts + INTERVAL '30' minutes >= mz_now()
  235. OR ts IS NULL;
  236. query error db error: ERROR: Unsupported temporal predicate\. Note: `mz_now\(\)` must be directly compared to a non\-temporal expression of mz_timestamp\-castable type\. Expression found: \(\(#0\{ts\}\) IS NULL OR \(timestamp_to_mz_timestamp\(\(#0\{ts\} \+ 00:30:00\)\) >= mz_now\(\)\)\)
  237. CREATE MATERIALIZED VIEW mv_err AS
  238. SELECT *
  239. FROM t2
  240. WHERE
  241. ts + INTERVAL '30' minutes >= mz_now()
  242. OR ts IS NULL;
  243. # This view will only work in one-off queries.
  244. statement ok
  245. CREATE VIEW v_one_off AS
  246. SELECT *
  247. FROM t2
  248. WHERE
  249. ts + INTERVAL '30' minutes >= mz_now()
  250. OR ts IS NULL;
  251. statement ok
  252. SELECT * FROM v_one_off;
  253. query error db error: ERROR: Unsupported temporal predicate\. Note: `mz_now\(\)` must be directly compared to a non\-temporal expression of mz_timestamp\-castable type\. Expression found: \(\(#0\{ts\}\) IS NULL OR \(timestamp_to_mz_timestamp\(\(#0\{ts\} \+ 00:30:00\)\) >= mz_now\(\)\)\)
  254. CREATE DEFAULT INDEX ON v_one_off;
  255. query error db error: ERROR: Unsupported temporal predicate\. Note: `mz_now\(\)` must be directly compared to a non\-temporal expression of mz_timestamp\-castable type\. Expression found: \(\(#0\{ts\}\) IS NULL OR \(timestamp_to_mz_timestamp\(\(#0\{ts\} \+ 00:30:00\)\) >= mz_now\(\)\)\)
  256. CREATE MATERIALIZED VIEW mv_err AS
  257. SELECT * FROM v_one_off;
  258. query error db error: ERROR: Unsupported temporal predicate\. Note: `mz_now\(\)` must be directly compared to a non\-temporal expression of mz_timestamp\-castable type\. Expression found: \(\(#0\{ts\}\) IS NULL OR \(timestamp_to_mz_timestamp\(\(#0\{ts\} \+ 00:30:00\)\) >= mz_now\(\)\)\)
  259. SUBSCRIBE v_one_off;
  260. # This view will work also in maintained dataflows.
  261. statement ok
  262. CREATE VIEW v_maintained AS
  263. SELECT *
  264. FROM t2
  265. WHERE
  266. ts + INTERVAL '30' minutes >= mz_now();
  267. statement ok
  268. SELECT * FROM v_one_off;
  269. statement ok
  270. CREATE DEFAULT INDEX ON v_maintained;
  271. statement ok
  272. CREATE MATERIALIZED VIEW mv2 AS
  273. SELECT * FROM v_maintained;
  274. simple
  275. DECLARE c CURSOR FOR SUBSCRIBE v_maintained;
  276. FETCH 0 c;
  277. ----
  278. COMPLETE 0
  279. COMPLETE 0
  280. # Valid temporal expression remains valid if ANDed with a non-temporal expression
  281. statement ok
  282. CREATE MATERIALIZED VIEW mv3 AS
  283. SELECT *
  284. FROM t2
  285. WHERE
  286. ts + INTERVAL '30' minutes >= mz_now()
  287. AND x != 7;
  288. # UNION ALL workaround for OR
  289. query error db error: ERROR: Unsupported temporal predicate\. Note: `mz_now\(\)` must be directly compared to a non\-temporal expression of mz_timestamp\-castable type\. Expression found: \(\(#1\{x\} = 7\) OR \(timestamp_to_mz_timestamp\(\(#0\{ts\} \+ 00:30:00\)\) >= mz_now\(\)\)\)
  290. CREATE MATERIALIZED VIEW mv_err AS
  291. SELECT *
  292. FROM t2
  293. WHERE
  294. x = 7
  295. OR ts + INTERVAL '30' minutes >= mz_now();
  296. statement ok
  297. CREATE MATERIALIZED VIEW mv4 AS
  298. (
  299. SELECT *
  300. FROM t2
  301. WHERE x = 7
  302. )
  303. UNION ALL
  304. (
  305. SELECT *
  306. FROM t2
  307. WHERE
  308. ts + INTERVAL '30' minutes >= mz_now()
  309. AND x != 7
  310. );