dropping the backing table drops the materialized view - postgresql

When dropping a backing table for a materialized view, is it normal for the materialized view to be also dropped? I understand that the materialized view is invalid without the presence of the backing table, but dropping the materialized view seems a bit unusual.
The materialized views is created as follows
create materialized view if not exists ea_master.geography_hierarchy
as
Select
parent.geography_id as parent_geography_id
,child.geography_id as child_geography_id
from ea_master.Geography parent
join ea_master.Polygon pParent on pParent.polygon_id = parent.polygon_id
join ea_master.Polygon pChild on ST_Contains(pParent.geometry, pChild.geometry)
join ea_master.Geography child on child.polygon_id = pChild.polygon_id
with no data;
The query used to drop the backing table: DROP TABLE ea_master.geography CASCADE;
Please note at some point the materialized view is refreshed with data before issuing the command to drop the backing table.

Thanks to #Raptélan on postgres-slack channel, who pointed to me the documentation for delete table with cascade parameter. As per the docs, it is expected behavior from the docs excerpt:
DROP TABLE always removes any indexes, rules, triggers, and constraints that exist
for the target table. However, to drop a table that is referenced by a view or a
foreign-key constraint of another table, CASCADE must be specified. (CASCADE will
remove a dependent view entirely, but in the foreign-key case it will only remove
the foreign-key constraint, not the other table entirely.)
Unfortunately looks like the cascade parameter is required to remove the backing table to ensure view is removed along with it. I will just have to recreate the view every time the backing table is deleted with the cascade option.
Also, I was conflating this cascade parameter to the foreign keys with on delete cascade parameter.

Related

Postgres View, after alter table to change table name, View still queries it?

Using Postgres database. I have an existing table, and several existing Views that query that table.
Call the table, 'contacts'.
I alter the table, changing the name to 'contacts_backup'. I then created a new table with the same name the older table used to have 'contacts'
Now it appears that if I query the existing views, the data is still retrieved from the renamed table, contacts_backup, and not the new table, 'contacts'.
Can this be? How can I update the Views to query the new table of the same name, and not the renamed contacts_backup?
My new table is actually a foreign table, but shouldn't the principle be the same? I was expecting the existing tables to query against the new table, not the old renamed one.
What is an efficient way to update the existing views to query from the new table?
This is because PostgreSQL does not store the view definition as an SQL string, but as a parsed query tree.
These parsed query trees don't contain the names of the referenced objects, but only their object identifier (oid), which does not change when you rename an object.
The same is true for table columns. This all holds for foreign tables as well.
When you examine the view definition, for example with pg_get_viewdef, the parse tree is rendered as text, so you will see the changed names.
If you want to change the table that a view is referring to, the only solution is to either DROP the view and CREATE it again, or you can use CREATE OR REPLACE VIEW.

How do I reload a table without deleting existing views?

I have a dataset that spans across many tables by date.
table_name_YYYY_MM_DD
There are many VIEWS created across these date range tables. However whenever I need to reload a table, I have to delete all these views to remove dependency constraints
DROP TABLE IF EXISTS table_name_YYYY_MM_DD cascade;
Is there a way to reload the table, as part of a transaction, to where the VIEWS don't need to be deleted. Eg create a new table, and swap their names, so that the transaction would guarantee the views don't need to be deleted.
Don't drop the table. Instead, truncate it:
truncate table table_name_YYYY_MM_DD
This removes all rows (quickly), but the table remains. So other dependencies are not affected.
Afterwards, you need to insert the data back into the table, rather than recreating the table.

How can I rename this table?

I Have a problem. I created a table using this :
CREATE TABLE MHS_KOTA2_1028(
NIM VARCHAR(15)PRIMARY KEY NOT NULL REFERENCES MAHASISWA_1028(NIM),
K_KOTA VARCHAR(9),
K_PROPINSI VARCHAR(9),
K_NEGARA VARCHAR(9),
FOREIGN KEY(K_KOTA,K_NEGARA,K_PROPINSI) REFERENCES
M_KOTA_1028(K_KOTA,K_NEGARA,K_PROPINSI), ALAMAT VARCHAR(100),KODE_POS VARCHAR(9));
when i rename the table using\
RENAME MHS_KOTA2_1028 TO MHS_KOTA_1028;
there was an error like this.
The source table cannot be renamed because it is referenced in a view,
materialized query table, trigger, SQL function, SQL method, check
constraint, referential constraint, or XSR object.. SQLCODE=-750,
SQLSTATE=42986, DRIVER=4.13.111
I try searching for its solution and i didn't get it. So how can we fix this?
The error tells you what to do.
The source table cannot be renamed because it is referenced in a view, materialized query table, trigger, SQL function, SQL method, check constraint, referential constraint, or XSR object.. SQLCODE=-750, SQLSTATE=42986, DRIVER=4.13.111
You have to check all of your views and tables for a reference to MHS_KOTA2_1028. If you find any, you have to first delete the views and / or tables with the reference, then do your rename, then add them back.

In DB2, are materialized query tables dropped if one of its source tables is dropped?

For example, I have a table GAME and PRICE, then I have an MQT called FPS_PRICE that is created using the following statement:
SELECT A.GAMENAME, B.GAMEPRICE
FROM GAME A, PRICE B
WHERE A.GAMEID=B.GAMEID
AND A.GAMETYPE='FPS';
If either the table GAME or PRICE gets dropped... does the MQT FPS_PRICE get dropped as well?
(I would test it out for myself,
but I don't have administrator access for the database in question)
Thanks!
Straight from Info Center:
All indexes, primary keys, foreign keys, check constraints,
materialized query tables, and staging tables referencing the table
are dropped. All views and triggers that reference the table are made
inoperative. (This includes both the table referenced in the ON clause
of the CREATE TRIGGER statement, and all tables referenced within the
triggered SQL statements.) All packages depending on any object
dropped or marked inoperative will be invalidated. This includes
packages dependent on any supertables above the subtable in the
hierarchy. Any reference columns for which the dropped table is
defined as the scope of the reference become unscoped.
The way to prevent it being dropped is to make it with a simple CREATE TABLE, rather than making it a materialized table.

Mysql workbench foreign key options [Restrict, Cascade, Set Null, No Action], what do they do?

In foreign key options on update and on delete.
What does each field [Restrict, Cascade, Set Null, No Action] do?
If you take one by one :
For both update and delete :
if you try to update / delete the parent row :
Restrict : Nothing gonna be delete if there is a child row
Cascade : the child row will be delete / update too
Set Null : the child column will be set to null if you delete the parent
No action : The child row will not be concern of the delete / update
The table containing the foreign key is called the referencing or child table, and the table containing the candidate key is called the referenced or parent table.
Set NULL : Sets the column value to NULL when you delete the parent table row.
CASCADE : CASCADE will propagate the change when the parent changes. If you delete a row, rows in constrained tables that reference that row will also be deleted, etc.
RESTRICT : RESTRICT causes you can not delete a given parent row if a child row exists that references the value for that parent row.
NO ACTION : NO ACTION and RESTRICT are very much alike. when an UPDATE or DELETE statement is executed on the referenced table, the DBMS verifies at the end of the statement execution that none of the referential relationships are violated. in short child row no concern if parent row delete or update.
When an UPDATE or DELETE operation affects a key value in the parent table that has matching rows in the child table, the result depends on the referential action specified using ON UPDATE and ON DELETE subclauses of the FOREIGN KEY clause. MySQL supports five options regarding the action to be taken, listed here:
CASCADE: Delete or update the row from the parent table, and automatically delete or update the matching rows in the child table. Both ON DELETE CASCADE and ON UPDATE CASCADE are supported. Between two tables, do not define several ON UPDATE CASCADE clauses that act on the same column in the parent table or in the child table.
SET NULL: Delete or update the row from the parent table, and set the foreign key column or columns in the child table to NULL. Both ON DELETE SET NULL and ON UPDATE SET NULL clauses are supported.
If you specify a SET NULL action, make sure that you have not declared the columns in the child table as NOT NULL.
RESTRICT: Rejects the delete or update operation for the parent table. Specifying RESTRICT (or NO ACTION) is the same as omitting the ON DELETE or ON UPDATE clause.
NO ACTION: A keyword from standard SQL. In MySQL, equivalent to RESTRICT. The MySQL Server rejects the delete or update operation for the parent table if there is a related foreign key value in the referenced table. Some database systems have deferred checks, and NO ACTION is a deferred check. In MySQL, foreign key constraints are checked immediately, so NO ACTION is the same as RESTRICT.
SET DEFAULT: This action is recognized by the MySQL parser, but InnoDB rejects table definitions containing ON DELETE SET DEFAULT or ON UPDATE SET DEFAULT clauses.
For an ON DELETE or ON UPDATE that is not specified, the default action is always RESTRICT.
Copied above text from:
https://dev.mysql.com/doc/refman/5.5/en/create-table-foreign-keys.html