12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811 |
- # Copyright Materialize, Inc. and contributors. All rights reserved.
- #
- # Use of this software is governed by the Business Source License
- # included in the LICENSE file at the root of this repository.
- #
- # As of the Change Date specified in that file, in accordance with
- # the Business Source License, use of this software will be governed
- # by the Apache License, Version 2.0.
- mode cockroach
- # Setup
- statement ok
- CREATE TABLE t (a int, b int)
- statement ok
- INSERT INTO t VALUES (1, 2), (3, 4), (5, 6)
- statement ok
- CREATE CLUSTER other REPLICAS (r1 (SIZE '1'), r2 (SIZE '2-2'))
- # Test: Materialized view can be created.
- statement ok
- CREATE MATERIALIZED VIEW mv AS SELECT 1
- # Test: Materialized view can be replaced.
- statement ok
- CREATE OR REPLACE MATERIALIZED VIEW mv AS SELECT 2
- query I
- SELECT * FROM mv
- ----
- 2
- # Test: Materialized view creation can be skipped if a materialized view already exists.
- statement error materialized view "materialize.public.mv" already exists
- CREATE MATERIALIZED VIEW mv AS SELECT 1
- statement ok
- CREATE MATERIALIZED VIEW IF NOT EXISTS mv AS SELECT 1
- query I
- SELECT * FROM mv
- ----
- 2
- # Test: Materialized view can have explicit column names.
- statement ok
- CREATE OR REPLACE MATERIALIZED VIEW mv (name, age) AS SELECT 'jon', 12
- query TI colnames
- SELECT * FROM mv
- ----
- name age
- jon 12
- # Test: Explicit column names must have the right cardinality.
- statement error materialized view .+ definition names 2 columns, but materialized view .+ has 1 column
- CREATE MATERIALIZED VIEW error (name, age) AS SELECT 'jon'
- # Test: Materialized view can be created in another cluster.
- statement ok
- CREATE MATERIALIZED VIEW other_mv IN CLUSTER other AS SELECT 1
- query TTT colnames,rowsort
- SHOW MATERIALIZED VIEWS
- ----
- name cluster comment
- mv quickstart (empty)
- other_mv other (empty)
- statement ok
- DROP MATERIALIZED VIEW other_mv
- # Test: Materialized view can not be created in a non-existing cluster.
- statement error unknown cluster 'doesnotexist'
- CREATE MATERIALIZED VIEW error IN CLUSTER doesnotexist AS SELECT 1
- # Test: Materialized view data is accessible from the same cluster.
- statement ok
- CREATE OR REPLACE MATERIALIZED VIEW mv AS SELECT a + b FROM t
- query I rowsort
- SELECT * FROM mv
- ----
- 3
- 7
- 11
- # Test: Materialized view data is accessible from other clusters.
- statement ok
- SET cluster = other
- query I rowsort
- SELECT * FROM mv
- ----
- 3
- 7
- 11
- statement ok
- RESET cluster
- # Test: Materialized view reflects input data changes.
- statement ok
- INSERT INTO t VALUES (7, 8)
- query I rowsort
- SELECT * FROM mv
- ----
- 3
- 7
- 11
- 15
- statement ok
- DELETE FROM t WHERE a = 1
- query I rowsort
- SELECT * FROM mv
- ----
- 7
- 11
- 15
- # Test: Query errors are propagated through materialized views.
- statement ok
- CREATE OR REPLACE MATERIALIZED VIEW mv AS SELECT 100 / a FROM t
- query I rowsort
- SELECT * FROM mv
- ----
- 14
- 20
- 33
- statement ok
- INSERT INTO t VALUES (0, 0)
- query error Evaluation error: division by zero
- SELECT * FROM mv
- statement ok
- DELETE FROM t WHERE a = 0
- query I rowsort
- SELECT * FROM mv
- ----
- 14
- 20
- 33
- # Test: Materialized views can be nested.
- statement ok
- CREATE MATERIALIZED VIEW mv2 AS SELECT count(*) FROM mv
- query I
- SELECT * FROM mv2
- ----
- 3
- statement ok
- DROP MATERIALIZED VIEW mv2
- # Test: Materialized views can have indexes on top.
- statement ok
- CREATE DEFAULT INDEX ON mv;
- # Test: Materialized views can be dropped.
- statement ok
- CREATE OR REPLACE MATERIALIZED VIEW mv AS SELECT 1
- statement ok
- DROP MATERIALIZED VIEW mv
- # Test: Materialized views can not be dropped if they have dependants.
- statement ok
- CREATE MATERIALIZED VIEW mv AS SELECT 1
- statement ok
- CREATE VIEW v AS SELECT * FROM mv
- statement error cannot drop materialized view "mv": still depended upon by view "v"
- DROP MATERIALIZED VIEW mv
- # Test: Materialized views with dependants can be dropped with CASCADE.
- statement ok
- DROP MATERIALIZED VIEW mv CASCADE
- query error unknown catalog item 'v'
- SELECT * FROM v
- # Test: a view on a materialized view that optimizes to the empty set
- # still prevents the underlying view from being dropped.
- # See: https://github.com/MaterializeInc/database-issues/issues/6101
- statement ok
- CREATE VIEW v AS SELECT 1 AS c
- statement ok
- CREATE MATERIALIZED VIEW mv AS SELECT * FROM v WHERE c IS NULL
- statement error cannot drop view "v": still depended upon by materialized view "mv"
- DROP VIEW v
- statement ok
- DROP VIEW v CASCADE
- query I
- SELECT count(*) FROM mz_materialized_views WHERE name = 'mv'
- ----
- 0
- # mz_scheduling_elapsed_raw, a log source, is optimized away, but should still count as a dependency
- query error db error: ERROR: materialized view objects cannot depend on log sources
- CREATE MATERIALIZED VIEW mv AS SELECT (SELECT 1 FROM mz_introspection.mz_scheduling_elapsed_raw WHERE FALSE);
- simple conn=mz_system,user=mz_system
- ALTER SYSTEM SET unsafe_enable_table_keys = true
- ----
- COMPLETE 0
- statement ok
- CREATE TABLE t1 (f1 INTEGER NOT NULL PRIMARY KEY);
- statement ok
- CREATE TABLE t2 (f1 INTEGER NOT NULL PRIMARY KEY);
- # Folds to Constant, t1 is optimized away but must still be counted as a dependency
- statement ok
- CREATE MATERIALIZED VIEW mv AS SELECT * FROM t1 WHERE FALSE;
- statement error db error: ERROR: cannot drop table "t1": still depended upon by materialized view "mv"
- DROP TABLE t1
- statement ok
- DROP MATERIALIZED VIEW mv
- # In the cases below, t2 is optimized away but should still be present as a dependency
- statement ok
- CREATE MATERIALIZED VIEW mv AS SELECT t1.* FROM t1 LEFT JOIN t2 ON (t1.f1 = t2.f1);
- statement error db error: ERROR: cannot drop table "t2": still depended upon by materialized view "mv"
- DROP TABLE t2
- statement ok
- DROP MATERIALIZED VIEW mv
- statement ok
- CREATE MATERIALIZED VIEW mv AS SELECT * FROM t1 WHERE FALSE AND EXISTS (SELECT * FROM t2);
- statement error db error: ERROR: cannot drop table "t2": still depended upon by materialized view "mv"
- DROP TABLE t2
- statement ok
- DROP MATERIALIZED VIEW mv
- statement ok
- CREATE MATERIALIZED VIEW mv AS SELECT * FROM t1 WHERE TRUE OR EXISTS (SELECT * FROM t2);
- statement error db error: ERROR: cannot drop table "t2": still depended upon by materialized view "mv"
- DROP TABLE t2
- statement ok
- DROP MATERIALIZED VIEW mv
- statement ok
- CREATE MATERIALIZED VIEW mv AS SELECT (SELECT f1 FROM t2 WHERE FALSE) FROM t1;
- statement error db error: ERROR: cannot drop table "t2": still depended upon by materialized view "mv"
- DROP TABLE t2
- statement ok
- DROP MATERIALIZED VIEW mv
- # No need to evaluate second argument of COALESCE if first is non-null
- statement ok
- CREATE MATERIALIZED VIEW mv AS SELECT COALESCE(1, (SELECT * FROM t2 LIMIT 1)) FROM t1;
- statement error db error: ERROR: cannot drop table "t2": still depended upon by materialized view "mv"
- DROP TABLE t2
- statement ok
- DROP MATERIALIZED VIEW mv
- statement ok
- CREATE TYPE int4_list AS LIST (ELEMENT TYPE = int4);
- # Mention of int4_list is optimized away
- statement ok
- CREATE MATERIALIZED VIEW mv AS SELECT * FROM t1 WHERE NULL::int4_list IS NOT NULL;
- statement error db error: ERROR: cannot drop type "int4_list": still depended upon by materialized view "mv"
- DROP TYPE int4_list
- statement ok
- DROP MATERIALIZED VIEW mv
- statement ok
- DROP TYPE int4_list
- statement ok
- DROP TABLE t1
- statement ok
- DROP TABLE t2
- # Test: Materialized view prevents dropping its cluster.
- statement ok
- CREATE CLUSTER to_drop REPLICAS ()
- statement ok
- CREATE MATERIALIZED VIEW to_drop_mv IN CLUSTER to_drop AS SELECT 1
- statement error cannot drop cluster "to_drop" because other objects depend on it
- DROP CLUSTER to_drop
- # Test: Cluster with dependent materialized view can be dropped with CASCADE.
- statement ok
- DROP CLUSTER to_drop CASCADE
- query error unknown catalog item 'to_drop_mv'
- SELECT * FROM to_drop_mv
- # Test: SHOW CREATE MATERIALIZED VIEW
- statement ok
- CREATE MATERIALIZED VIEW mv AS SELECT 1
- query TT colnames
- SHOW CREATE MATERIALIZED VIEW mv
- ----
- name create_sql
- materialize.public.mv CREATE␠MATERIALIZED␠VIEW␠materialize.public.mv⏎␠␠␠␠IN␠CLUSTER␠quickstart⏎␠␠␠␠WITH␠(REFRESH␠=␠ON␠COMMIT)⏎␠␠␠␠AS␠SELECT␠1;
- # Test: SHOW CREATE MATERIALIZED VIEW as mz_support
- simple multiline,conn=mz_catalog_server,user=mz_support
- SELECT create_sql FROM (SHOW CREATE MATERIALIZED VIEW mv);
- ----
- CREATE MATERIALIZED VIEW materialize.public.mv
- IN CLUSTER quickstart
- WITH (REFRESH = ON COMMIT)
- AS SELECT 1;
- EOF
- COMPLETE 1
- # Test: SHOW MATERIALIZED VIEWS
- statement ok
- CREATE MATERIALIZED VIEW other_mv IN CLUSTER other AS SELECT 1
- query TTT colnames,rowsort
- SHOW MATERIALIZED VIEWS
- ----
- name cluster comment
- mv quickstart (empty)
- other_mv other (empty)
- query TTT colnames,rowsort
- SHOW MATERIALIZED VIEWS IN CLUSTER other
- ----
- name cluster comment
- other_mv other (empty)
- statement ok
- DROP MATERIALIZED VIEW other_mv
- # Test: Materialized view can be renamed.
- statement ok
- ALTER MATERIALIZED VIEW mv RENAME TO mv2
- query I
- SELECT * FROM mv2
- ----
- 1
- statement ok
- DROP MATERIALIZED VIEW mv2
- # Test: Materialized views show up in mz_materialized_views.
- statement ok
- CREATE MATERIALIZED VIEW mv AS SELECT 1
- query TT colnames
- SELECT name, definition FROM mz_materialized_views
- ----
- name definition
- mv SELECT␠1;
- statement ok
- DROP MATERIALIZED VIEW mv
- query I
- SELECT count(*) FROM mz_materialized_views
- ----
- 0
- # Test: Materialized views show in `SHOW OBJECTS`.
- statement ok
- CREATE MATERIALIZED VIEW mv AS SELECT 1
- mode standard
- query TTT colnames,rowsort
- SHOW OBJECTS
- ----
- name type comment
- mv
- materialized-view
- (empty)
- t
- table
- (empty)
- mode cockroach
- # Test: Indexes on materialized views show in `SHOW INDEXES`.
- statement ok
- CREATE DEFAULT INDEX ON mv
- query TTTTT colnames
- SHOW INDEXES ON mv
- ----
- name on cluster key comment
- mv_primary_idx mv quickstart {?column?} (empty)
- # Test: Creating materialized views that depend on log sources is forbidden.
- statement error materialized view objects cannot depend on log sources
- CREATE OR REPLACE MATERIALIZED VIEW mv AS SELECT id, name FROM mz_introspection.mz_dataflow_operators;
- # Test: Attempting to use view commands on materialized views gives helpful errors.
- statement error mv is not a view\nHINT: Use DROP MATERIALIZED VIEW to remove a materialized view\.
- DROP VIEW mv
- statement error mv is not a view\nHINT: Use SHOW CREATE MATERIALIZED VIEW to show a materialized view\.
- SHOW CREATE VIEW mv
- statement error mv is not a view\nHINT: Use ALTER MATERIALIZED VIEW to rename a materialized view\.
- ALTER VIEW mv RENAME TO mv2
- # We should not be able to create materialized views on top of 'SHOW' commands.
- statement error SHOW commands are not allowed in views
- CREATE MATERIALIZED VIEW mat_clusters AS SELECT name FROM (SHOW CLUSTERS);
- statement error SHOW commands are not allowed in views
- CREATE MATERIALIZED VIEW mat_cluster_replicas AS SELECT cluster, replica, size, ready FROM (SHOW CLUSTER REPLICAS);
- statement error SHOW commands are not allowed in views
- CREATE MATERIALIZED VIEW mat_columns AS SELECT name, nullable, type FROM (SHOW COLUMNS FROM mz_tables);
- statement error SHOW commands are not allowed in views
- CREATE MATERIALIZED VIEW mat_connections AS SELECT name, type FROM (SHOW CONNECTIONS);
- statement error SHOW commands are not allowed in views
- CREATE MATERIALIZED VIEW mat_databases AS SELECT name FROM (SHOW DATABASES);
- statement error SHOW commands are not allowed in views
- CREATE MATERIALIZED VIEW mat_indexes AS SELECT name, on, cluster, key FROM (SHOW INDEXES);
- statement error SHOW commands are not allowed in views
- CREATE MATERIALIZED VIEW mat_mat_views AS SELECT name, cluster FROM (SHOW MATERIALIZED VIEWS);
- statement error SHOW commands are not allowed in views
- CREATE MATERIALIZED VIEW mat_objects AS SELECT name FROM (SHOW OBJECTS);
- statement error SHOW commands are not allowed in views
- CREATE MATERIALIZED VIEW mat_schemas AS SELECT name FROM (SHOW SCHEMAS);
- statement error SHOW commands are not allowed in views
- CREATE MATERIALIZED VIEW mat_secrets AS SELECT name FROM (SHOW SECRETS);
- statement error SHOW commands are not allowed in views
- CREATE MATERIALIZED VIEW mat_sinks AS SELECT name, type FROM (SHOW SINKS);
- statement error SHOW commands are not allowed in views
- CREATE MATERIALIZED VIEW mat_sources AS SELECT name, type FROM (SHOW SOURCES);
- statement error SHOW commands are not allowed in views
- CREATE MATERIALIZED VIEW mat_tables AS SELECT name FROM (SHOW TABLES);
- statement error SHOW commands are not allowed in views
- CREATE MATERIALIZED VIEW mat_views AS SELECT name FROM (SHOW VIEWS);
- # LIMIT in materialized view
- statement ok
- CREATE MATERIALIZED VIEW mv_limited AS
- SELECT a
- FROM t
- ORDER BY a DESC, a+b
- LIMIT 3;
- query I
- SELECT * FROM mv_limited;
- ----
- 3
- 5
- 7
- statement ok
- DELETE FROM t WHERE a = 5;
- query I
- SELECT * FROM mv_limited;
- ----
- 3
- 7
- query I
- SELECT * FROM mv_limited
- ORDER BY a
- LIMIT 1;
- ----
- 3
- # Cleanup
- statement ok
- DROP TABLE t CASCADE
- statement ok
- DROP CLUSTER other CASCADE
- statement ok
- CREATE TABLE t2 (x int, y int, z int);
- statement ok
- INSERT INTO t2 VALUES (NULL, 2, 3), (4, NULL, 6), (7, 8, NULL);
- statement ok
- CREATE MATERIALIZED VIEW mv_no_assertions AS SELECT * FROM t2;
- query III
- SELECT * FROM mv_no_assertions ORDER BY x;
- ----
- 4 NULL 6
- 7 8 NULL
- NULL 2 3
- statement ok
- CREATE MATERIALIZED VIEW mv_assertion_at_begin WITH (ASSERT NOT NULL x) AS SELECT * FROM t2;
- statement error column "x" must not be null
- SELECT * FROM mv_assertion_at_begin;
- statement ok
- CREATE MATERIALIZED VIEW mv_assertion_at_end WITH (ASSERT NOT NULL z) AS SELECT * FROM t2;
- statement error column "z" must not be null
- SELECT * FROM mv_assertion_at_end;
- statement ok
- CREATE MATERIALIZED VIEW mv_two_assertions WITH (ASSERT NOT NULL x, ASSERT NOT NULL z) AS SELECT * FROM t2;
- statement error column "x" must not be null
- SELECT * FROM mv_two_assertions;
- statement ok
- CREATE MATERIALIZED VIEW mv_misordered_assertions WITH (ASSERT NOT NULL z, ASSERT NOT NULL y) AS SELECT * FROM t2;
- statement error must not be null
- SELECT * FROM mv_misordered_assertions
- statement error duplicate column "y" in non-null assertions
- CREATE MATERIALIZED VIEW mv_duplicate_assertions WITH (ASSERT NOT NULL y, ASSERT NOT NULL y) AS SELECT * FROM t2;
- statement error column "x" in ASSERT NOT NULL option not found
- CREATE MATERIALIZED VIEW mv_bad_assertion_on_renamed_column (a, b, c) WITH (ASSERT NOT NULL x) AS SELECT * FROM t2;
- statement ok
- CREATE MATERIALIZED VIEW mv_good_assertion_on_renamed_column (a, b, c) WITH (ASSERT NOT NULL b) AS SELECT * FROM t2;
- statement error column "b" must not be null
- SELECT * FROM mv_good_assertion_on_renamed_column;
- statement ok
- UPDATE t2 SET x=1 WHERE x IS NULL;
- query III
- SELECT * FROM mv_assertion_at_begin ORDER BY x;
- ----
- 1 2 3
- 4 NULL 6
- 7 8 NULL
- # ------------------------------------------------------------------
- # REFRESH options (see also in materialized-view-refresh-options.td)
- # ------------------------------------------------------------------
- # Planning/parsing errors
- simple conn=mz_system,user=mz_system
- ALTER SYSTEM SET enable_refresh_every_mvs = false
- ----
- COMPLETE 0
- # Should be disabled
- query error db error: ERROR: REFRESH EVERY and REFRESH AT materialized views is not available
- CREATE MATERIALIZED VIEW mv_bad WITH (ASSERT NOT NULL x, REFRESH EVERY '8 seconds') AS SELECT * FROM t2;
- simple conn=mz_system,user=mz_system
- ALTER SYSTEM SET enable_refresh_every_mvs = true
- ----
- COMPLETE 0
- query error Expected one of ON or AT or EVERY, found number "5"
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH 5) AS SELECT 1;
- query error db error: ERROR: REFRESH ON COMMIT cannot be specified multiple times
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH ON COMMIT, REFRESH ON COMMIT) AS SELECT 1;
- query error db error: ERROR: REFRESH ON COMMIT is not compatible with any of the other REFRESH options
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH ON COMMIT, REFRESH EVERY '1 day') AS SELECT 1;
- query error db error: ERROR: REFRESH AT does not support casting from record\(f1: integer,f2: integer\) to mz_timestamp
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH AT row(1,2)) AS SELECT 1;
- query error db error: ERROR: REFRESH AT argument must be an expression that can be simplified and/or cast to a constant whose type is mz_timestamp
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH AT 'aaaa') AS SELECT 1;
- query error db error: ERROR: column "ccc" does not exist
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH AT ccc) AS SELECT 1 as ccc;
- query error db error: ERROR: REFRESH AT argument must be an expression that can be simplified and/or cast to a constant whose type is mz_timestamp
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH AT now()) AS SELECT 1;
- query error db error: ERROR: REFRESH AT argument must be an expression that can be simplified and/or cast to a constant whose type is mz_timestamp
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH AT now()::mz_timestamp) AS SELECT 1;
- query error db error: ERROR: greatest types mz_timestamp and timestamp with time zone cannot be matched
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH AT greatest(mz_now(), now())) AS SELECT 1;
- query error db error: ERROR: REFRESH AT argument must be an expression that can be simplified and/or cast to a constant whose type is mz_timestamp
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH AT greatest(mz_now(), now()::mz_timestamp)) AS SELECT 1;
- query error db error: ERROR: aggregate functions are not allowed in REFRESH AT \(function pg_catalog\.sum\)
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH AT sum(5)) AS SELECT 1;
- query error db error: ERROR: REFRESH AT does not allow subqueries
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH AT (SELECT 1)) AS SELECT 1;
- query error db error: ERROR: window functions are not allowed in REFRESH AT \(function pg_catalog\.lag\)
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH AT lag(7) OVER ()) AS SELECT 1;
- query error Expected literal string, found number "42"
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH EVERY 42) AS SELECT 1;
- query error db error: ERROR: invalid input syntax for type interval: unknown units dayy: "1 dayy"
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH EVERY '1 dayy') AS SELECT 1;
- query error Expected literal string, found INTERVAL
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH EVERY INTERVAL '1 day') AS SELECT 1;
- query error db error: ERROR: REFRESH interval must be positive; got: \-00:01:00
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH EVERY '-1 minutes') AS SELECT 1;
- query error db error: ERROR: REFRESH interval must not involve units larger than days
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH EVERY '1 month') AS SELECT 1;
- query error db error: ERROR: REFRESH interval must not involve units larger than days
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH EVERY '1 year') AS SELECT 1;
- query error db error: ERROR: REFRESH EVERY \.\.\. ALIGNED TO argument must be an expression that can be simplified and/or cast to a constant whose type is mz_timestamp
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH EVERY '1 day' ALIGNED TO now()) AS SELECT 1;
- query error db error: ERROR: REFRESH EVERY \.\.\. ALIGNED TO argument must be an expression that can be simplified and/or cast to a constant whose type is mz_timestamp
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH EVERY '1 day' ALIGNED TO now()::mz_timestamp) AS SELECT 1;
- query error db error: ERROR: greatest types mz_timestamp and timestamp with time zone cannot be matched
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH EVERY '1 day' ALIGNED TO greatest(mz_now(), now())) AS SELECT 1;
- query error db error: ERROR: REFRESH EVERY \.\.\. ALIGNED TO argument must be an expression that can be simplified and/or cast to a constant whose type is mz_timestamp
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH EVERY '1 day' ALIGNED TO greatest(mz_now(), now()::mz_timestamp)) AS SELECT 1;
- query error db error: ERROR: aggregate functions are not allowed in REFRESH EVERY \.\.\. ALIGNED TO \(function pg_catalog\.sum\)
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH EVERY '1 day' ALIGNED TO sum(5)) AS SELECT 1;
- query error db error: ERROR: REFRESH EVERY \.\.\. ALIGNED TO does not allow subqueries
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH EVERY '1 day' ALIGNED TO (SELECT 1)) AS SELECT 1;
- query error db error: ERROR: window functions are not allowed in REFRESH EVERY \.\.\. ALIGNED TO \(function pg_catalog\.lag\)
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH EVERY '1 day' ALIGNED TO lag(7) OVER ()) AS SELECT 1;
- query error Expected literal string, found right parenthesis
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH EVERY) AS SELECT * FROM t2;
- query error Expected literal string, found comma
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH EVERY, ASSERT NOT NULL x) AS SELECT * FROM t2;
- query error Expected right parenthesis, found REFRESH
- CREATE MATERIALIZED VIEW mv_bad WITH (ASSERT NOT NULL x REFRESH EVERY '8 seconds') AS SELECT * FROM t2;
- query error Expected literal string, found ASSERT
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH EVERY ASSERT NOT NULL x) AS SELECT * FROM t2;
- query error db error: ERROR: invalid input syntax for type interval: Overflows maximum days; cannot exceed 2147483647/\-2147483648 days: "213503982001"
- CREATE MATERIALIZED VIEW mv_bad WITH (REFRESH EVERY '213503982001' days) AS SELECT * FROM t2;
- # This tests that we don't forget to purify EXPLAIN CREATE MATERIALIZED VIEW
- statement ok
- EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR CREATE MATERIALIZED VIEW mv_explain WITH (REFRESH EVERY '2 seconds') AS SELECT * FROM t2;
- statement ok
- CREATE MATERIALIZED VIEW mv_on_commit WITH (REFRESH ON COMMIT) AS SELECT * FROM t2;
- query III rowsort
- SELECT 1000*x, 1000*y, 1000*z
- FROM mv_on_commit;
- ----
- 7000 8000 NULL
- 4000 NULL 6000
- 1000 2000 3000
- # Test that we call `transform_ast::transform`. (This has an `Expr::Nested`, which needs to be desugared, or we panic.)
- statement ok
- CREATE MATERIALIZED VIEW mv_desugar1 WITH (REFRESH AT (mz_now())) AS SELECT * FROM t2;
- # Same with ALIGNED TO
- statement ok
- CREATE MATERIALIZED VIEW mv_desugar2 WITH (REFRESH EVERY '1 day' ALIGNED TO (mz_now())) AS SELECT * FROM t2;
- ## REFRESH options together with ASSERT NOT NULL options
- statement ok
- INSERT INTO t2 VALUES (10, 11, 12);
- statement ok
- CREATE MATERIALIZED VIEW mv_assertion_plus_refresh_every WITH (ASSERT NOT NULL x, REFRESH EVERY '8 seconds') AS SELECT * FROM t2;
- # There should be a refresh immediately when creating the MV. This refresh should already see what we just inserted.
- query III
- SELECT * FROM mv_assertion_plus_refresh_every ORDER BY x;
- ----
- 1 2 3
- 4 NULL 6
- 7 8 NULL
- 10 11 12
- statement ok
- INSERT INTO t2 VALUES (NULL, -1, -2);
- # This insert shouldn't be visible yet.
- query III
- SELECT * FROM mv_assertion_plus_refresh_every ORDER BY x;
- ----
- 1 2 3
- 4 NULL 6
- 7 8 NULL
- 10 11 12
- # Sleep for the refresh interval, so that we get a refresh.
- # Actually, we sleep a bit more than the refresh interval, because we don't have real-time recency guarantees:
- # When we query the MV at a particular wall clock time `t`, there is no guarantee that we see a refresh that
- # happened at, say, `t - 1ms`. Note that the test was actually failing sometimes when it was sleeping for only 8s or 9s.
- # A proper solution might be to add `AS OF now()` to the following SELECT, but calling `now()` seems to not be currently
- # allowed in `AS OF`.
- statement ok
- SELECT mz_unsafe.mz_sleep(8+2);
- # Now we should see the NULL that should error out the MV.
- query error db error: ERROR: Evaluation error: column "x" must not be null
- SELECT * FROM mv_assertion_plus_refresh_every ORDER BY x;
- ## Check `REFRESH AT greatest(<past time>, mz_now())`, because this is an idiom that we are recommending to users.
- # Insert something into the underlying table.
- statement ok
- INSERT INTO t2 VALUES (30, 30, 30);
- statement ok
- CREATE MATERIALIZED VIEW mv_greatest
- WITH (REFRESH AT greatest('1990-01-04 11:00', mz_now()))
- AS SELECT * FROM t2;
- query III rowsort
- SELECT * FROM mv_greatest;
- ----
- NULL -1 -2
- 4 NULL 6
- 7 8 NULL
- 1 2 3
- 10 11 12
- 30 30 30
- ## If there is no creation refresh, then a query should block until the first refresh.
- # Save the current time.
- statement ok
- CREATE TABLE start_time(t timestamp);
- statement ok
- INSERT INTO start_time VALUES (now());
- # Create an MV whose first refresh is 5 sec after its creation.
- statement ok
- CREATE MATERIALIZED VIEW mv_no_creation_refresh
- WITH (REFRESH EVERY '100000 sec' ALIGNED TO mz_now()::string::int8 + 5000)
- AS SELECT * FROM t2;
- # Insert something into the underlying table.
- statement ok
- INSERT INTO t2 VALUES (100, 100, 100);
- # Query it.
- # - The query should block until the first refresh.
- # - The newly inserted stuff should be visible.
- query III rowsort
- SELECT * FROM mv_no_creation_refresh;
- ----
- NULL -1 -2
- 4 NULL 6
- 7 8 NULL
- 1 2 3
- 10 11 12
- 30 30 30
- 100 100 100
- # Verify that at least 5 seconds have passed.
- query B
- SELECT now() - (SELECT * from start_time) >= INTERVAL '5 sec';
- ----
- true
- ## Check ALIGNED TO in the far past
- # Save the current time.
- statement ok
- DELETE FROM start_time;
- statement ok
- INSERT INTO start_time VALUES (now());
- statement ok
- CREATE MATERIALIZED VIEW mv_aligned_to_past
- WITH (REFRESH EVERY '10000 ms' ALIGNED TO mz_now()::text::int8 - 10*10000 + 3000)
- AS SELECT * FROM t2;
- query III rowsort
- SELECT * FROM mv_aligned_to_past;
- ----
- NULL -1 -2
- 4 NULL 6
- 7 8 NULL
- 1 2 3
- 10 11 12
- 30 30 30
- 100 100 100
- # Verify that at least 3 seconds have passed.
- query B
- SELECT now() - (SELECT * from start_time) >= INTERVAL '3 sec';
- ----
- true
- ## Check ALIGNED TO in the far future
- # Save the current time.
- statement ok
- DELETE FROM start_time;
- statement ok
- INSERT INTO start_time VALUES (now());
- statement ok
- CREATE MATERIALIZED VIEW mv_aligned_to_future
- WITH (REFRESH EVERY '10000 ms' ALIGNED TO mz_now()::text::int8 + 10*10000 + 3000)
- AS SELECT * FROM t2;
- query III rowsort
- SELECT * FROM mv_aligned_to_future;
- ----
- NULL -1 -2
- 4 NULL 6
- 7 8 NULL
- 1 2 3
- 10 11 12
- 30 30 30
- 100 100 100
- # Verify that at least 3 seconds have passed.
- query B
- SELECT now() - (SELECT * from start_time) >= INTERVAL '3 sec';
- ----
- true
- ## Constant query in an MV with REFRESH options
- statement ok
- CREATE MATERIALIZED VIEW const_mv
- WITH (REFRESH EVERY '1 day')
- AS SELECT 1;
- query I
- SELECT * FROM const_mv
- ----
- 1
- ## We should be able to immediately query a constant MV under serializable isolation even if the
- ## first refresh is in the future. The since will be advanced to [3000-01-01 23:59] and the upper
- ## will be advanced to [].
- statement ok
- CREATE MATERIALIZED VIEW const_mv2
- WITH (REFRESH AT '3000-01-01 23:59')
- AS SELECT 2;
- statement ok
- SET transaction_isolation = 'serializable'
- query I
- SELECT * FROM const_mv2
- ----
- 2
- statement ok
- SET transaction_isolation = 'strict serializable'
- ## MV that has refreshes only in the past
- query error db error: ERROR: REFRESH AT requested for a time where not all the inputs are readable
- CREATE MATERIALIZED VIEW mv_no_refresh
- WITH (REFRESH AT '2000-01-01 10:00')
- AS SELECT * FROM t2;
- ## Query MV after the last refresh
- statement ok
- CREATE MATERIALIZED VIEW mv3
- WITH (REFRESH AT mz_now()::text::int8 + 2000, REFRESH AT mz_now()::text::int8 + 4000)
- AS SELECT * FROM t2;
- # Wait until the first refresh
- query III rowsort
- SELECT * FROM mv3;
- ----
- NULL -1 -2
- 4 NULL 6
- 7 8 NULL
- 1 2 3
- 10 11 12
- 30 30 30
- 100 100 100
- # Wait until we are past the second refresh, which is the last one.
- # (See the explanation for the `+2` above at a similar `mz_sleep`.)
- statement ok
- SELECT mz_unsafe.mz_sleep(2+2);
- # This insert will happen after the last refresh.
- statement ok
- INSERT INTO t2 VALUES (70, 70, 70);
- # We should be able to query the MV after the last refresh, and the newly inserted data shouldn't be visible.
- query III rowsort
- SELECT * FROM mv3;
- ----
- NULL -1 -2
- 4 NULL 6
- 7 8 NULL
- 1 2 3
- 10 11 12
- 30 30 30
- 100 100 100
- # Regression test for https://github.com/MaterializeInc/database-issues/issues/7265
- # The sleep makes _optimization_ take a few seconds, so we need to grab read holds in purification right away after
- # choosing a timestamp for mz_now.
- simple conn=mz_system,user=mz_system
- ALTER SYSTEM SET unsafe_enable_unstable_dependencies = true
- ----
- COMPLETE 0
- statement ok
- create materialized view mv4 with (refresh at creation) as
- select * from
- (select mz_unsafe.mz_sleep(3)),
- (select * from t2);
- # EXPLAIN and EXPLAIN TIMESTAMP on an MV that hasn't had its first refresh yet shouldn't block
- # See also `test_explain_timestamp_blocking`
- statement ok
- CREATE MATERIALIZED VIEW mv5 WITH (REFRESH AT mz_now()::text::int8 + 1000000) AS
- SELECT x+y+z from t2;
- statement ok
- EXPLAIN OPTIMIZED PLAN WITH (humanized expressions) AS VERBOSE TEXT FOR SELECT * FROM mv5;
- statement ok
- EXPLAIN TIMESTAMP FOR SELECT * FROM mv5;
- ## Stacked REFRESH MVs -- both have their first and only refresh in the future, at similar times
- statement ok
- CREATE MATERIALIZED VIEW mv6 WITH (REFRESH AT mz_now()::text::int8 + 3000) AS
- SELECT x-y+z from t2;
- statement ok
- CREATE MATERIALIZED VIEW mv7 WITH (REFRESH AT mz_now()::text::int8 + 3000) AS
- SELECT * from mv6;
- query I rowsort
- SELECT * FROM mv7
- ----
- NULL
- NULL
- NULL
- 2
- 11
- 30
- 70
- 100
- # We now insert something into the underlying table. This shouldn't be visible in mv6, because mv6's refresh shouldn't
- # be later than mv7's refresh.
- statement ok
- INSERT INTO t2 VALUES (0, 0, 0);
- query I rowsort
- SELECT * FROM mv6
- ----
- NULL
- NULL
- NULL
- 2
- 11
- 30
- 70
- 100
- ## REFRESH AT CREATION + REFRESH EVERY ALIGNED TO
- ## We create an MV that would be first refreshed only much later, if it were not for the REFRESH AT CREATION.
- statement ok
- CREATE MATERIALIZED VIEW mv_multiple_refresh_options WITH (
- REFRESH AT CREATION,
- REFRESH EVERY '1 day' ALIGNED TO mz_now()::text::int8 + 1000000
- ) AS
- SELECT DISTINCT 5*x FROM t2;
- # Should return quickly due to the creation refresh.
- query I rowsort
- SELECT * FROM mv_multiple_refresh_options;
- ----
- NULL
- 0
- 5
- 20
- 35
- 50
- 150
- 350
- 500
- ## EXPLAIN shouldn't try to grab read holds in `create_materialized_view_validate`
- statement ok
- CREATE TABLE t3(x int);
- statement ok
- INSERT INTO t3 VALUES (5), (6);
- statement ok
- CREATE MATERIALIZED VIEW mv8 WITH (REFRESH AT CREATION) AS
- SELECT DISTINCT x-x FROM t3;
- # Sleep until we could no longer grab read holds at the original creation time.
- statement ok
- SELECT mz_unsafe.mz_sleep(2);
- # This would fail to get read holds if it attempted to do so.
- statement ok
- EXPLAIN REPLAN MATERIALIZED VIEW mv8;
- ## Indexes on REFRESH MVs
- statement ok
- CREATE MATERIALIZED VIEW mvi1 WITH (REFRESH EVERY '8s' ALIGNED TO mz_now()::string::int8 + 2000) AS
- SELECT 5*x FROM t3;
- statement ok
- CREATE DEFAULT INDEX on mvi1;
- query I
- SELECT * FROM mvi1;
- ----
- 25
- 30
- query I
- (SELECT * FROM mvi1)
- UNION ALL
- (SELECT * FROM t3);
- ----
- 5
- 6
- 25
- 30
- statement ok
- INSERT INTO t3 values (7);
- # Not visible yet.
- query I
- SELECT * FROM mvi1;
- ----
- 25
- 30
- query I
- (SELECT * FROM mvi1)
- UNION ALL
- (SELECT * FROM t3);
- ----
- 5
- 6
- 7
- 25
- 30
- statement ok
- SELECT mz_unsafe.mz_sleep(8+2);
- # Visible now.
- query I rowsort
- SELECT * FROM mvi1;
- ----
- 25
- 30
- 35
- query I
- (SELECT * FROM mvi1)
- UNION ALL
- (SELECT * FROM t3);
- ----
- 5
- 6
- 7
- 25
- 30
- 35
- # First refresh immediately, next one much later.
- statement ok
- CREATE MATERIALIZED VIEW mvi2 WITH (REFRESH EVERY '10 hours') AS
- SELECT DISTINCT x+x+x FROM t3;
- statement ok
- CREATE DEFAULT INDEX on mvi2;
- query I rowsort
- SELECT * FROM mvi2;
- ----
- 15
- 18
- 21
- query I
- (SELECT * FROM mvi2)
- UNION ALL
- (SELECT * FROM t3);
- ----
- 5
- 6
- 7
- 15
- 18
- 21
- # There is a last refresh.
- statement ok
- CREATE MATERIALIZED VIEW mvi3 WITH (REFRESH AT CREATION, REFRESH AT mz_now()::string::int8 + 2000) AS
- SELECT DISTINCT 5*x FROM t3;
- statement ok
- CREATE DEFAULT INDEX ON mvi3;
- query I rowsort
- SELECT * FROM mvi3
- ----
- 25
- 30
- 35
- query I
- (SELECT * FROM mvi3)
- UNION ALL
- (SELECT * FROM t3);
- ----
- 5
- 6
- 7
- 25
- 30
- 35
- # Check that it's still queryable after the last refresh, but new input changes are not taken into account.
- statement ok
- SELECT mz_unsafe.mz_sleep(2+2);
- statement ok
- INSERT INTO t3 VALUES (-1);
- query I rowsort
- SELECT * FROM mvi3
- ----
- 25
- 30
- 35
- query I
- (SELECT * FROM mvi3)
- UNION ALL
- (SELECT * FROM t3);
- ----
- -1
- 5
- 6
- 7
- 25
- 30
- 35
- # ----------------------------------------
- # Automated cluster scheduling for REFRESH
- # ----------------------------------------
- simple conn=mz_system,user=mz_system
- ALTER SYSTEM SET enable_cluster_schedule_refresh = false
- ----
- COMPLETE 0
- # Should be disabled
- query error db error: ERROR: `SCHEDULE = ON REFRESH` cluster option is not available
- CREATE CLUSTER c_schedule_0 (SIZE = '1', SCHEDULE = ON REFRESH);
- simple conn=mz_system,user=mz_system
- ALTER SYSTEM SET enable_cluster_schedule_refresh = true
- ----
- COMPLETE 0
- # Let's not complicate things with `cluster_refresh_mv_compaction_estimate` at first.
- simple conn=mz_system,user=mz_system
- ALTER SYSTEM SET cluster_refresh_mv_compaction_estimate = 0
- ----
- COMPLETE 0
- statement error db error: ERROR: Expected one of MANUAL or ON, found identifier "aaaaaaaa"
- CREATE CLUSTER c_schedule_0 (SIZE = '1', SCHEDULE = AAAAAAAA);
- statement error db error: ERROR: Expected one of MANUAL or ON, found number "42"
- CREATE CLUSTER c_schedule_0 (SIZE = '1', SCHEDULE = 42);
- statement error db error: ERROR: Expected one of MANUAL or ON, found REFRESH
- CREATE CLUSTER c_schedule_0 (SIZE = '1', SCHEDULE = REFRESH);
- statement error db error: ERROR: REPLICATION FACTOR cannot be given together with any SCHEDULE other than MANUAL
- CREATE CLUSTER c_schedule_0 (SIZE = '1', SCHEDULE = ON REFRESH, REPLICATION FACTOR = 1);
- statement ok
- CREATE CLUSTER c_schedule_1 (SIZE = '1', SCHEDULE = MANUAL);
- statement ok
- CREATE CLUSTER c_schedule_2 (SIZE = '1', SCHEDULE MANUAL);
- statement ok
- CREATE CLUSTER c_schedule_3 (SIZE = '1', SCHEDULE = ON REFRESH);
- statement error db error: ERROR: REPLICATION FACTOR cannot be set if the cluster SCHEDULE is anything other than MANUAL
- ALTER CLUSTER c_schedule_3 SET (REPLICATION FACTOR = 1);
- statement ok
- ALTER CLUSTER c_schedule_1 RESET (SCHEDULE);
- statement error db error: ERROR: REPLICATION FACTOR cannot be given together with any SCHEDULE other than MANUAL
- ALTER CLUSTER c_schedule_1 SET (REPLICATION FACTOR = 1, SCHEDULE = ON REFRESH);
- statement ok
- ALTER CLUSTER c_schedule_1 SET (SCHEDULE = MANUAL);
- statement ok
- ALTER CLUSTER c_schedule_1 SET (SCHEDULE = ON REFRESH);
- statement ok
- SELECT mz_unsafe.mz_sleep(3+2);
- # Should turn off.
- query I
- SELECT replication_factor FROM mz_catalog.mz_clusters WHERE name = 'c_schedule_1';
- ----
- 0
- statement error db error: ERROR: cluster schedules other than MANUAL are not supported for unmanaged clusters
- ALTER CLUSTER c_schedule_1 SET (MANAGED = false, SCHEDULE = ON REFRESH);
- # The SCHEDULE shouldn't simply "fall off" when switching to unmanaged,
- statement error db error: ERROR: when switching a cluster to unmanaged, if the managed cluster's SCHEDULE is anything other than MANUAL, you have to explicitly set the SCHEDULE to MANUAL
- ALTER CLUSTER c_schedule_1 SET (MANAGED = false);
- # ... but can be explicitly set to MANUAL in the same command.
- statement ok
- ALTER CLUSTER c_schedule_1 SET (MANAGED = false, SCHEDULE = MANUAL);
- statement ok
- ALTER CLUSTER c_schedule_1 SET (MANAGED = true, SIZE = '1');
- statement ok
- ALTER CLUSTER c_schedule_1 SET (SCHEDULE = ON REFRESH (HYDRATION TIME ESTIMATE = '0 seconds'));
- # Setting some other cluster option in ALTER CLUSTER shouldn't change the SCHEDULE.
- # (The sleep is needed so that if the following ALTER erroneously sets the SCHEDULE to MANUAL, then we should be in a
- # turned off state at that moment to trigger errors in later tests.)
- statement ok
- SELECT mz_unsafe.mz_sleep(3);
- statement ok
- ALTER CLUSTER c_schedule_1 SET (INTROSPECTION DEBUGGING = TRUE);
- statement ok
- ALTER CLUSTER c_schedule_1 RESET (INTROSPECTION DEBUGGING);
- statement ok
- CREATE CLUSTER unmanaged1 (SCHEDULE = MANUAL, REPLICAS (r1 (SIZE '1')))
- statement ok
- ALTER cluster unmanaged1 SET (SCHEDULE = MANUAL);
- statement error db error: ERROR: cluster schedules other than MANUAL are not supported for unmanaged clusters
- ALTER cluster unmanaged1 SET (SCHEDULE = ON REFRESH);
- statement error db error: ERROR: REPLICATION FACTOR cannot be given together with any SCHEDULE other than MANUAL
- ALTER cluster unmanaged1 SET (managed = true, SCHEDULE = ON REFRESH, REPLICATION FACTOR = 1, SIZE = '1');
- statement error db error: ERROR: cluster schedules other than MANUAL are not supported for unmanaged clusters
- CREATE CLUSTER unmanaged2 (SCHEDULE = ON REFRESH, REPLICAS (r1 (SIZE '1')))
- statement ok
- CREATE CLUSTER c_schedule_5 (SIZE = '1');
- statement error db error: ERROR: Expected one of OWNER or RENAME or RESET or SET or SWAP, found left parenthesis
- ALTER CLUSTER c_schedule_5 (MANAGED = false, SCHEDULE = REFRESH);
- statement ok
- CREATE MATERIALIZED VIEW mv9
- IN CLUSTER c_schedule_1
- WITH (REFRESH = EVERY '8 sec')
- AS SELECT sum(x*y*z) + count(*) FROM t2;
- query I
- SELECT * FROM mv9;
- ----
- 1371335
- statement ok
- INSERT INTO t2 VALUES (1, 0, 1);
- statement ok
- SELECT mz_unsafe.mz_sleep(8+2);
- query I
- SELECT * FROM mv9;
- ----
- 1371336
- statement ok
- CREATE MATERIALIZED VIEW mv10
- IN CLUSTER c_schedule_1
- WITH (REFRESH AT CREATION)
- AS SELECT count(*) FROM t2;
- query I
- SELECT * FROM mv10
- ----
- 10
- # The other refresh cluster should be off, because there is no refresh MV on it yet.
- query I
- SELECT replication_factor FROM mz_catalog.mz_clusters WHERE name = 'c_schedule_3';
- ----
- 0
- # A `REFRESH AT CREATION` MV alone on a cluster should make the cluster turn on.
- statement ok
- CREATE MATERIALIZED VIEW mv11
- IN CLUSTER c_schedule_3
- WITH (REFRESH AT CREATION)
- AS SELECT count(*) FROM t2;
- query I
- SELECT * FROM mv11
- ----
- 10
- ## Very short refresh interval.
- statement ok
- CREATE CLUSTER c_schedule_4 (SIZE = '1', SCHEDULE = ON REFRESH);
- statement ok
- CREATE MATERIALIZED VIEW mv12
- IN CLUSTER c_schedule_4
- WITH (REFRESH EVERY '1 millisecond')
- AS SELECT count(*) FROM t2;
- query I
- SELECT * FROM mv12
- ----
- 10
- statement ok
- INSERT INTO t2 VALUES (1, 1, 10);
- query I
- SELECT * FROM mv12
- ----
- 11
- # This should set the schedule back to manual.
- statement ok
- ALTER CLUSTER c_schedule_4 RESET (SCHEDULE);
- statement ok
- ALTER CLUSTER c_schedule_4 SET (REPLICATION FACTOR = 0);
- statement ok
- SELECT mz_unsafe.mz_sleep(3);
- # Should stay off, because it was reset to manual.
- query I
- SELECT replication_factor FROM mz_catalog.mz_clusters WHERE name = 'c_schedule_4';
- ----
- 0
- ## HYDRATION TIME ESTIMATE
- statement error db error: ERROR: Expected literal string, found number "0"
- CREATE CLUSTER c_bad (SIZE = '1', SCHEDULE = ON REFRESH (HYDRATION TIME ESTIMATE = 0));
- statement error db error: ERROR: HYDRATION TIME ESTIMATE must be non\-negative; got: \-01:00:00
- CREATE CLUSTER c_bad (SIZE = '1', SCHEDULE = ON REFRESH (HYDRATION TIME ESTIMATE = '-1 hour'));
- statement error db error: ERROR: invalid input syntax for type interval: unknown units aaaa: "1 aaaa"
- CREATE CLUSTER c_bad (SIZE = '1', SCHEDULE = ON REFRESH (HYDRATION TIME ESTIMATE = '1 aaaa'));
- statement error db error: ERROR: HYDRATION TIME ESTIMATE must not involve units larger than days
- CREATE CLUSTER c_bad (SIZE = '1', SCHEDULE = ON REFRESH (HYDRATION TIME ESTIMATE = '1 month'));
- statement error db error: ERROR: invalid input syntax for type interval: Overflows maximum days; cannot exceed 2147483647/\-2147483648 days: "1000000000000 days"
- CREATE CLUSTER c_bad (SIZE = '1', SCHEDULE = ON REFRESH (HYDRATION TIME ESTIMATE = '1000000000000 days'));
- # ----------------------------------------
- # Introspection
- # ----------------------------------------
- query TTTBB
- SELECT
- name,
- type,
- interval,
- now() - aligned_to < INTERVAL '30 minutes',
- now() - at < INTERVAL '30 minutes'
- FROM mz_internal.mz_materialized_view_refresh_strategies mvrs, mz_catalog.mz_materialized_views mv
- WHERE mv.id = mvrs.materialized_view_id
- ORDER BY name;
- ----
- const_mv every 24:00:00 true NULL
- const_mv2 at NULL NULL true
- mv on-commit NULL NULL NULL
- mv10 at NULL NULL true
- mv11 at NULL NULL true
- mv12 every 00:00:00.001 true NULL
- mv3 at NULL NULL true
- mv3 at NULL NULL true
- mv4 at NULL NULL true
- mv5 at NULL NULL true
- mv6 at NULL NULL true
- mv7 at NULL NULL true
- mv8 at NULL NULL true
- mv9 every 00:00:08 true NULL
- mv_aligned_to_future every 00:00:10 true NULL
- mv_aligned_to_past every 00:00:10 true NULL
- mv_assertion_at_begin on-commit NULL NULL NULL
- mv_assertion_at_end on-commit NULL NULL NULL
- mv_assertion_plus_refresh_every every 00:00:08 true NULL
- mv_desugar1 at NULL NULL true
- mv_desugar2 every 24:00:00 true NULL
- mv_good_assertion_on_renamed_column on-commit NULL NULL NULL
- mv_greatest at NULL NULL true
- mv_misordered_assertions on-commit NULL NULL NULL
- mv_multiple_refresh_options at NULL NULL true
- mv_multiple_refresh_options every 24:00:00 true NULL
- mv_no_assertions on-commit NULL NULL NULL
- mv_no_creation_refresh every 27:46:40 true NULL
- mv_on_commit on-commit NULL NULL NULL
- mv_two_assertions on-commit NULL NULL NULL
- mvi1 every 00:00:08 true NULL
- mvi2 every 10:00:00 true NULL
- mvi3 at NULL NULL true
- mvi3 at NULL NULL true
- statement ok
- CREATE CLUSTER c_schedule_hydration_time_estimate (SIZE = '1', SCHEDULE = ON REFRESH (HYDRATION TIME ESTIMATE = '995 seconds'));
- # Make the above cluster turn on, so that we can test how the HYDRATION TIME ESTIMATE looks in `mz_audit_events`.
- statement ok
- CREATE MATERIALIZED VIEW mv_rte
- IN CLUSTER c_schedule_hydration_time_estimate
- WITH (REFRESH EVERY '1 sec') AS SELECT * FROM t2;
- query TTT
- SELECT name, cs.type, cs.refresh_hydration_time_estimate
- FROM mz_internal.mz_cluster_schedules cs, mz_catalog.mz_clusters c
- WHERE c.id = cs.cluster_id
- AND name LIKE 'c_schedule_%'
- ORDER BY name;
- ----
- c_schedule_1 on-refresh 00:00:00
- c_schedule_2 manual NULL
- c_schedule_3 on-refresh 00:00:00
- c_schedule_4 manual NULL
- c_schedule_5 manual NULL
- c_schedule_hydration_time_estimate on-refresh 00:16:35
- statement ok
- SELECT mz_unsafe.mz_sleep(4);
- query TTTTBT rowsort
- SELECT DISTINCT
- event_type,
- object_type,
- (details->'cluster_name')::text,
- (details->'reason')::text,
- (details->'scheduling_policies') IS NULL,
- regexp_replace((details->'scheduling_policies'->'on_refresh')::text, '\["u.*"\]', '["uXXX"]')
- FROM mz_audit_events
- WHERE
- event_type IN ('create', 'drop') AND
- object_type = 'cluster-replica' AND
- ((details->'cluster_name')::text LIKE '"c_schedule_%"' OR (details->'cluster_name')::text = '"other"');
- ----
- drop cluster-replica "other" "manual" true NULL
- create cluster-replica "other" "manual" true NULL
- drop cluster-replica "c_schedule_4" "manual" true NULL
- create cluster-replica "c_schedule_1" "manual" true NULL
- create cluster-replica "c_schedule_2" "manual" true NULL
- create cluster-replica "c_schedule_5" "manual" true NULL
- drop cluster-replica "c_schedule_1" "schedule" false {"decision":"off","hydration_time_estimate":"00:00:00","objects_needing_compaction":[],"objects_needing_refresh":[]}
- drop cluster-replica "c_schedule_3" "schedule" false {"decision":"off","hydration_time_estimate":"00:00:00","objects_needing_compaction":[],"objects_needing_refresh":[]}
- create cluster-replica "c_schedule_1" "schedule" false {"decision":"on","hydration_time_estimate":"00:00:00","objects_needing_compaction":[],"objects_needing_refresh":["uXXX"]}
- create cluster-replica "c_schedule_3" "schedule" false {"decision":"on","hydration_time_estimate":"00:00:00","objects_needing_compaction":[],"objects_needing_refresh":["uXXX"]}
- create cluster-replica "c_schedule_4" "schedule" false {"decision":"on","hydration_time_estimate":"00:00:00","objects_needing_compaction":[],"objects_needing_refresh":["uXXX"]}
- create cluster-replica "c_schedule_hydration_time_estimate" "schedule" false {"decision":"on","hydration_time_estimate":"00:16:35","objects_needing_compaction":[],"objects_needing_refresh":["uXXX"]}
- ## Now test `cluster_refresh_mv_compaction_estimate`.
- ## (This would make the above audit test flaky, so it should be after that.)
- simple conn=mz_system,user=mz_system
- ALTER SYSTEM SET cluster_refresh_mv_compaction_estimate = 1200000
- ----
- COMPLETE 0
- statement ok
- CREATE CLUSTER c_schedule_6 (SIZE = '1', SCHEDULE = ON REFRESH);
- query I
- SELECT replication_factor FROM mz_catalog.mz_clusters WHERE name = 'c_schedule_6';
- ----
- 0
- statement ok
- CREATE MATERIALIZED VIEW mv13
- IN CLUSTER c_schedule_6
- WITH (REFRESH AT CREATION)
- AS SELECT sum(x*y) - count(*) AS r FROM t2;
- # Wait until the first refresh is complete.
- query I
- SELECT r+r FROM mv13;
- ----
- 31916
- # We'd turn it off at the next scheduling decision if it were not for `cluster_refresh_mv_compaction_estimate`
- statement ok
- SELECT mz_unsafe.mz_sleep(3+1+1);
- query I
- SELECT replication_factor FROM mz_catalog.mz_clusters WHERE name = 'c_schedule_6';
- ----
- 1
- simple conn=mz_system,user=mz_system
- ALTER SYSTEM SET cluster_refresh_mv_compaction_estimate = 0
- ----
- COMPLETE 0
- # Should turn off at the next scheduling decision.
- statement ok
- SELECT mz_unsafe.mz_sleep(3+1+1);
- query I
- SELECT replication_factor FROM mz_catalog.mz_clusters WHERE name = 'c_schedule_6';
- ----
- 0
- simple conn=mz_system,user=mz_system
- ALTER SYSTEM SET cluster_refresh_mv_compaction_estimate = 120000
- ----
- COMPLETE 0
- # Should turn on at the next scheduling decision.
- statement ok
- SELECT mz_unsafe.mz_sleep(3+1+1);
- query I
- SELECT replication_factor FROM mz_catalog.mz_clusters WHERE name = 'c_schedule_6';
- ----
- 1
- # The audit events should now have a row that has a non-empty `objects_needing_compaction`.
- query TTTTBT rowsort
- SELECT DISTINCT
- event_type,
- object_type,
- (details->'cluster_name')::text,
- (details->'reason')::text,
- (details->'scheduling_policies') IS NULL,
- regexp_replace((details->'scheduling_policies'->'on_refresh')::text, '\["u.*"\]', '["uXXX"]')
- FROM mz_audit_events
- WHERE
- event_type IN ('create', 'drop') AND
- object_type = 'cluster-replica' AND
- (details->'cluster_name')::text = '"c_schedule_6"';
- ----
- drop cluster-replica "c_schedule_6" "schedule" false {"decision":"off","hydration_time_estimate":"00:00:00","objects_needing_compaction":[],"objects_needing_refresh":[]}
- create cluster-replica "c_schedule_6" "schedule" false {"decision":"on","hydration_time_estimate":"00:00:00","objects_needing_compaction":["uXXX"],"objects_needing_refresh":[]}
- create cluster-replica "c_schedule_6" "schedule" false {"decision":"on","hydration_time_estimate":"00:00:00","objects_needing_compaction":[],"objects_needing_refresh":["uXXX"]}
- simple conn=mz_system,user=mz_system
- ALTER SYSTEM SET cluster_refresh_mv_compaction_estimate = 0
- ----
- COMPLETE 0
- ## EXPLAIN FILTER PUSHDOWN can be run on materialized views in this file
- simple conn=mz_system,user=mz_system
- ALTER SYSTEM SET enable_explain_pushdown = true
- ----
- COMPLETE 0
- # Pulling stats for refresh-every and similar MVs can time out,
- # since data may not yet be available...
- statement ok
- SET statement_timeout = '1s'
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW const_mv;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW const_mv2;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv3;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv5;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv8;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv9;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv12;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv_aligned_to_future;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv_aligned_to_past;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv_assertion_at_begin;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv_assertion_at_end;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv_assertion_plus_refresh_every;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv_desugar1;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv_desugar2;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv_good_assertion_on_renamed_column;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv_greatest;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv_misordered_assertions;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv_multiple_refresh_options;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv_multiple_refresh_options;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv_no_assertions;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv_no_creation_refresh;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv_on_commit;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv_two_assertions;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mvi1;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mvi2;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mvi3;
- statement ok
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mvi3;
- # Attempting to explain MVs which are not readable at the current time can block
- statement error db error: ERROR: canceling statement due to statement timeout
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv4;
- statement error db error: ERROR: canceling statement due to statement timeout
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv10;
- statement error db error: ERROR: canceling statement due to statement timeout
- EXPLAIN FILTER PUSHDOWN FOR MATERIALIZED VIEW mv11;
- simple conn=mz_system,user=mz_system
- ALTER SYSTEM SET enable_explain_pushdown = false
- ----
- COMPLETE 0
- query T multiline
- SELECT regexp_replace(create_sql, 'AT \d+', 'XXX', 'g') FROM (SHOW CREATE MATERIALIZED VIEW mvi3);
- ----
- CREATE MATERIALIZED VIEW materialize.public.mvi3
- IN CLUSTER quickstart
- WITH (
- REFRESH = XXX::mz_catalog.mz_timestamp,
- REFRESH = XXX::mz_catalog.mz_timestamp::pg_catalog.text::pg_catalog.int8 + 2000
- )
- AS SELECT DISTINCT 5 * x FROM materialize.public.t3;
- EOF
|