How to show all invalid objects in PostgresQL - postgresql

Looking for the view I can list up all 'invalid' objects in PostgreSQL.
In Oracle, we can use dab_objects.status column but I'm not sure if there is a simple way to do such a thing in PostgreSQL.
Maybe, I can check the invalid indexes with below code.
How can I do that for other objects?
SELECT pg_class.relname
FROM pg_class, pg_index
WHERE pg_index.indisvalid = false
AND pg_index.indexrelid = pg_class.oid;

I don't think that you have to check anything else, since other objects cannot become invalid in PostgreSQL.
Oracle and PostgreSQL work quite differently in that respect:
In Oracle, you can always ALTER an object (for example a table) even if there are dependent objects (for example views). The dependent objects then become invalid and have to be recompiled.
In PostgreSQL, you cannot ALTER an object that has dependend objects in a way that renders these dependent objects invalid. You have to drop and recreate the dependent objects.
Invalid indexes can be left behind by a failed CREATE INDEX command.

Related

How to create a synonym for a table in PostgreSQL

I am migrating this Oracle command to PostgreSQL:
CREATE SYNONYM &user..emp FOR &schema..emp;
Please suggest to me how I can migrate the above command.
PostgreSQL does not support SYNOSYM or ALIAS. Synonym is a non SQL 2003 feature implemented by Microsoft SQL 2005 (I think). While it does provide an interesting abstraction, but due to lack of relational integrity, it can be considered a risk.
That is, you can create a synonym, advertise it to you programmers, the code is written around it, including stored procedures, then one day the backend of this synonym (or link or pointer) is changed/deleted/etc leading to a run time error. I don't even think a prepare would catch that.
It is the same trap as the symbolic links in unix and null pointers in C/C++.
But rather create a DB view and it is already updateable as long as it contains one table select only.
CREATE VIEW schema_name.synonym_name AS SELECT * FROM schema_name.table_name;
You don't need synonyms.
There are two approaches:
using the schema search path:
ALTER DATABASE xyz SET search_path = schema1, schema2, ...;
Put the schema that holds the table on the search_path of the database (or user), then it can be used without schema qualification.
using a view:
CREATE VIEW dest_schema.tab AS SELECT * FROM source_schema.tab;
The first approach is good if you have a lot of synonyms for objects in the same schema.

Is it possible to have database-wide table aliases?

I am about to model a PostgreSQL database, based on an Oracle database. The latter is old and its tables have been named after a 3-letter-scheme.
E.g. a table that holds parameters for tasks would be named TSK_PAR.
As I model the new database, I'd like to rename those tables to a more descriptive name using actual words. My problem is, that some parts of the software might rely on these old names until they're rewritten and adapted to the new scheme.
Is it possible to create something like an alias that's being used for the whole database?
E.g. I create a new task_parameters database, but add a TSK_PAR alias to it, so if a SELECT * FROM TSK_PAR is being used, it automatically refers to the new name?
Postgres has no synonyms like Oracle.
But for your intended use case, views should do just fine. A view that simply does select * from taks_parameters is automatically updateable (see here for an online example).
If you don't want to clutter your default schema (usually public) with all those views, you can create them in a different schema, and then adjust the user's search path to include that "synonym schema".
For example:
create schema synonyms;
create table public.task_parameters (
id integer primary key,
....
);
create view synonyms.task_par
as
select *
from public.task_parameters;
However, that approach has one annoying drawback: if a table is used by a view, the allowed DDL statements on it are limited, e.g. you can't drop a column or rename it.
As we manage our schema migrations using Liquibase, we always drop all views before applying "normal" migrations, then once everything is done, we simply re-create all views (by running the SQL scripts stored in Git). With that approach, ALTER TABLE statements never fail because there are not views using the tables. As creating a view is really quick, it doesn't add overhead when deploying a migration.

DB2 equivalent for CREATE FORCE VIEW

I am in process of migration MaxDB database to DB2. I need to recreate all views, but their definitions contain references to other views and have the same create date and time, so I'm unable to create them in correct order.
Does the DB2 support somehow the CREATE FORCE VIEW statement?
How can I recreate the views in correct order (without creating SQL parser - because I have just String definition of views from Data Dictionary from MAXDB)?
SELECT for MaxDB:
select vd.*, t.createdate, t.createtime from viewdefs vd
join tables t on vd.viewname = t.tablename and vd.owner = t.owner
order by t.createdate, t.createtime
MaxDB Data Dictionary
You don't indicate what DB2 platform you're using. DB2 for LUW has the database configuration parameter auto_reval, which, when set to deferred (default) or deferred_force, allows you to create dependent objects in any order. With deferred_force in effect objects (including views) that cannot be validated at creation time because of missing dependencies will be created "with error" and revalidated when they are first used in a SQL statement.
You can also explicitly revalidate all invalid objects after you create them by calling the system stored procedure SYSPROC.ADMIN_REVALIDATE_DB_OBJECTS().

Postgres GRANT not applied on parent

I'm in trouble with grant in postgresql (version 9.3).
I'm trying to restrict a ROLE 'client_1'. I want it to be able to do only select for one table. But there is inheritance between tables.
Here is my table structure:
CREATE TABLE public.table_a (...);
CREATE TABLE table_a_partitions.child_1 (...) INHERITS (public.table_a);
CREATE TABLE table_a_partitions.child_2 (...) INHERITS (public.table_a);
GRANT SELECT ON table_a_child_1 TO client_1;
It's okay when I do a select on child_2, there is an error, but if I do a SELECT * FROM table_a; for example it also reads the forbidden table child_2. I would my client access only child_1 (and some other in the future) results when he does SELECT * FROM table_a;.
Is there a simple way to solve this problem ?
Thank you
You would need to use a VIEW in PostgreSQL 9.3 to solve this problem. If you upgrade to 9.5, however, you could use row-level security.
As a note as to why, the grant check only occurs on the level of the initial relation queried. This means if you query a view, you need access to the view's contents, but the view owner (NOT YOU) needs access to the underlying relations. This allows a view to be useful for information hiding. Similarly with inheritance, this structure allows you to forbid rows to be inserted or queried directly from partitions of a table, but to allow different queries via the parent table. So this is a consequence of design priorities, not a bug.
Before row-level security, you would basically create a view and fold in user privilege criteria into the view (with partitioning/inheritance this is also a good idea for other reasons since your insert/update/delete triggers can return exactly what the db would do even though it cannot on a table).
As for row-level security, PostgreSQL 9.5 does allow you to specify row-level policies (conditions that get appended to insert/select/update/delete queries) and that provides something a little more manageable in some cases than the view approach.

Alter column ignoring dependent views

I have column column with character varying(20) type, i want to increase it to 50
ALTER TABLE table ALTER COLUMN column TYPE character varying(50);
I get an error that view view_name depends on column "column". I wonder how can i alter column without dropping and recreating about 10 depending views?
The answer to your question can be found on this blog
PostgreSQL is very restrictive when it comes to modifying existing
objects. Very often when you try to ALTER TABLE or REPLACE VIEW it
tells you that you cannot do it, because there's another object
(typically a view or materialized view), which depends on the one you
want to modify. It seems that the only solution is to DROP dependent
objects, make desired changes to the target object and then recreate
dropped objects.
It is tedious and cumbersome, because those dependent objects can have
further dependencies, which also may have other dependencies and so
on. I created utility functions which can help in such situations.
The usage is very simple - you just have to call:
select deps_save_and_drop_dependencies(p_schema_name, p_object_name);
You
have to pass two arguments: the name of the schema and the name of the
object in that schema. This object can be a table, a view or a
materialized view. The function will drop all views and materialized
views dependent on p_schema_name.p_object_name and save DDL which
restores them in a helper table.
When you want to restore those dropped objects (for example when you
are done modyfing p_schema_name.p_object_name), you just need to make
another simple call:
select deps_restore_dependencies(p_schema_name,p_object_name);
and the dropped objects will be recreated.
These functions take care about:
dependencies hierarchy
proper order of dropping and creating views/materialized views across hierarchy
restoring comments and grants on views/materialized views
Click here
for a working sqlfiddle example or check this gist for a complete
source code
It's not possible, but a TODO feature. You should create a script that is able to handle such a thing as simple view creations.