Postgresql: create view and use of default tablespace? - postgresql

When I try to create a view in PostgreSQL 13 I get an error saying: "permission denied for tablespace tbs_dft". As you can see I've changed the system default tablespace. The problem is easy to fix by granting create on tablespace 'tbs_dft'. But my question is: why does it need to access the 'default tablespace' when creating a view containing a simple select statement? Although this is not a practical issue I am trying to learn Postgresql having come from Oracle and hence I'm not sure what it is I don't understand about the way View creation works in Postgresql.
Any information gratefully received.

The reason is that this check is done whenever a relation is created (in DefineRelation in src/backend/commands/tablecmds.c). A relation is anything stored in pg_class: a table, an index, a sequence, a composite type, a view or a materialized view.
Now views or composite types do not have data files, so the check could be skipped in this case. If that is important for you, get in touch with development on the pgsql-hackers mailing list. This could be improved in my opinion.
Here is the code in question:
/* Check permissions except when using database's default */
if (OidIsValid(tablespaceId) && tablespaceId != MyDatabaseTableSpace)
{
AclResult aclresult;
aclresult = pg_tablespace_aclcheck(tablespaceId, GetUserId(),
ACL_CREATE);
if (aclresult != ACLCHECK_OK)
aclcheck_error(aclresult, OBJECT_TABLESPACE,
get_tablespace_name(tablespaceId));
}

Related

How do I generate a list of views dependent on a certain table in postgresql?

I need to update a mapping table in postgresql, but of course it won't allow me to replace/drop the original table as there are dependencies.
The error message details does list the dependent views, but I'd like to generate a list programmatically so that I can make temp views while I drop my original mapping table and migrate the views back afterwards.
Prefer not to do this in SQL Shell incidentally. Any pointers would be much appreciated.

How to maintain CREATE VIEW script in postgres rather than VIEW DEFINITION

I am using Postgres Version 9.1 and am having some trouble reviewing past VIEWS that I have created.
Once I create a VIEW, Postgres jumbles up the CREATE VIEW text so it is very unreadable.
For instance, I might create a simple VIEW as:
create view some_view as
select *
from some_table
where some_column = 'some_value';
This then turns into something way more complicated as:
select [all columns...]
from some_table
where (((some_column = 'some_value')));
Now, this is a simple example - however when you get into multiple JOINS and WHERE clauses or SUBQUERIES it gets nearly impossible to read so as to edit the VIEW at a later date.
(The exact location the VIEWS are stored is in information_schema.pg_views if anybody cares to look.)
For that reason I save my CREATE VIEW scripts as a separate .sql file, however this can get taxing and is obviously has the liability of not being sync'd with the current VIEW in the Postgres Database (if you update the VIEW but don't update the .sql file for instance).
It would be MUCH more simple if the plain text of the CREATE VIEW was saved.
When I create a FUNCTION, it saves the script entirely as is with all white-space, etc.
This makes it very simple, at a later date, to review it and see if it needs to be fixed up or spot possible errors.
So my question is if there is some place in the Postgres database where the actual plain-text is saved of the CREATE VIEW statement for later review/editing.
Thank you.
As found, the correct answer is to:
a) Maintain your SQL Scripts in separate files
b) Have a proper versioning system (Git, etc.)
c) Deploy from the versioning system
Done Deal.

How to apply new changes without dropping current data in the db.(Playframework evaluations)

I'm using play 2.2.1 with scala. And I have a managing database evaluations. When I run my application with changes on the database, it'll drop all my datas.
At this moment evaluationplugin = disabled is comment in. If I comment out, it does not apply my changes.
For example. I have a users table and there are id, f_name, l_name
User
id f_name l_name
1. khazo rasp
And I want to add age field to this table without losing data. I've added this field in scala files.It works properly. I'm assuming I need to write script in 1.sql for some alter command, but I don't want to write script.
How to apply new changes without dropping current data in the db. I've read this documentation. Thanks in advance.
I've added this field in scala files
In slick (you have the tag play-slick), you can specify a default value in your Table
See the documentation here, under Tables:
Default[T](defaultValue: T)
Specify a default value for inserting data the table without this column. This information is only used for creating DDL statements so that the database can fill in the missing information.
I am not sure if it gets translated to ALTER statement if the table already exists . You will have to test it.

Dynamic auditing of data with PostgreSQL trigger

I'm interested in using the following audit mechanism in an existing PostgreSQL database.
http://wiki.postgresql.org/wiki/Audit_trigger
but, would like (if possible) to make one modification. I would also like to log the primary_key's value where it could be queried later. So, I would like to add a field named something like "record_id" to the "logged_actions" table. The problem is that every table in the existing database has a different primary key fieldname. The good news is that the database has a very consistent naming convention. It's always, _id. So, if a table was named "employee", the primary key is "employee_id".
Is there anyway to do this? basically, I need something like OLD.FieldByName(x) or OLD[x] to get value out of the id field to put into the record_id field in the new audit record.
I do understand that I could just create a separate, custom trigger for each table that I want to keep track of, but it would be nice to have it be generic.
edit: I also understand that the key value does get logged in either the old/new data fields. But, what I would like would be to make querying for the history easier and more efficient. In other words,
select * from audit.logged_actions where table_name = 'xxxx' and record_id = 12345;
another edit: I'm using PostgreSQL 9.1
Thanks!
You didn't mention your version of PostgreSQL, which is very important when writing answers to questions like this.
If you're running PostgreSQL 9.0 or newer (or able to upgrade) you can use this approach as documented by Pavel:
http://okbob.blogspot.com/2009/10/dynamic-access-to-record-fields-in.html
In general, what you want is to reference a dynamically named field in a record-typed PL/PgSQL variable like 'NEW' or 'OLD'. This has historically been annoyingly hard, and is still awkward but is at least possible in 9.0.
Your other alternative - which may be simpler - is to write your audit triggers in plperlu, where dynamic field references are trivial.

Microsoft Access ADP UPDATE Query does NOT update

I have a (very simple and standard) UPDATE statement which works fine either directly in Query Analyser, or executed as a stored procedure in Query Analyser.
UPDATE A
SET
A.field1 = B.col1
, A.field2 = B.col2
FROM
tblA AS A INNER JOIN tblB AS B
ON A.pk1 = B.pk1 AND A.pk2 = B.pk2
Problem is when i execute the same stored proc via microsoft ADP (by double-clicking on the sproc name or using the Run option), it says "query ran successfully but did not return records" AND does NOT update the records when i inspect the tables directly.
Before anyone even says "syntax of MS-Access is different than SQLServer T-SQL", remember that with ADP everything happens on the server and one is actually passing thru to T-SQL.
Any bright ideas from any ADP gurus out there?
Gotcha. Responding to my own question for the benefit of anyone else.
Tools / Options / Advanced / Client-Server Settings / Default max records is set at 10,000 (presumably this is the default). Change this to 0 for unlimited.
My table had 100,000+ rows and whatever set of 10,000 it was updating was difficult to find ( among a sea of 90,000+ un-updated rows ). Hence the update did not work fully as expected.
Try and see whether the query gets executed on the SQL Server using SQL profiler.
Also, I think you might need to close the linked table & re-open it to see the updated records.
Does that work?
Run the query with SQL PRofiler running. Before you start the trace add in all the error events. This will give you any errors that the SQL Server is generating that the Access ADP might not be showing correctly (or at all).
Feel free to post them here.
Just as a reference, here's a paper I wrote on Update Queries that discusses some of the issues associated with when the fail.
http://www.fmsinc.com/microsoftaccess/query/snytax/update-query.html
I seem to remember that I always got the "didn't return any rows" message and had to simply turn off the messaging. It's because it isn't returning any rows!
as for the other - sometimes there's a primary key issue. Does the table being updated have a primary key in SQLServer? If so, check the view of the table in Access - sometimes that link doesn't come through. It's been a while, so I could be wrong, but I think you may need to look at the design view of the table while in access and add the primary key there.
EDIT: Additional thought:
in your debugging, try throwing in print statements to see what the values of your inputs are. Is it actually picking up the data from the table as you expect when you execute from access?