[GENERAL] Is auto-analyze as thorough as manual analyze?

2017-09-23 Thread Jack Christensen
Just had an issue where a prepared query would occasionally choose a 
very bad plan in production. The same data set in a different 
environment consistently would choose the index scan. As would be 
expected, running analyze on that table in production resolved the issue.


However, before I ran the analyze I checked pg_stat_user_tables to see 
last_autoanalyze for that table. It had run today. But the problem 
existed before that. I would have expected that the auto-analyze would 
have corrected this (or prevented it entirely if run enough).


So that leaves me wondering: is an auto-analyze the same as manually 
running analyze or is a manual analyze more thorough? This is running 
version 9.6.3 on Heroku.


Thanks,

Jack




--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [GENERAL] Custom shuffle function stopped working in 9.6

2017-02-11 Thread Jack Christensen

On 02/11/2017 11:36 AM, Adrian Klaver wrote:

On 02/11/2017 09:17 AM, Alexander Farber wrote:

I think ORDER BY RANDOM() has stopped working in 9.6.2:

words=> select unnest(ARRAY['a','b','c','d','e','f']) order by random();
  unnest

  a
  b
  c
  d
  e
  f
(6 rows)


postgres=> select version();
version
-
  PostgreSQL 9.6.1 on x86_64-pc-linux-gnu, compiled by gcc (SUSE Linux) 4.8.5, 
64-bit
(1 row)

postgres=> select * from  unnest(ARRAY['a','b','c','d','e','f']) order by 
random();
  unnest

  d
  c
  a
  f
  e
  b
(6 rows)

postgres=> select * from  unnest(ARRAY['a','b','c','d','e','f']) order by 
random();
  unnest

  b
  d
  e
  c
  a
  f
(6 rows)





I can duplicate issue on 9.6.2.

jack=# select version();
 version
--
 PostgreSQL 9.6.2 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 
5.3.1-14ubuntu2) 5.3.1 20160413, 64-bit
(1 row)

jack=# select unnest(ARRAY['a','b','c','d','e','f']) order by random();
 unnest

 a
 b
 c
 d
 e
 f
(6 rows)

jack=# select unnest(ARRAY['a','b','c','d','e','f']) order by random();
 unnest

 a
 b
 c
 d
 e
 f
(6 rows)

Jack



--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [GENERAL] Permissions, "soft read failure" - wishful thinking?

2015-12-14 Thread Jack Christensen

On 12/14/2015 11:55 AM, Benjamin Smith wrote:

Is there a way to set PG field-level read permissions so that a deny doesn't
cause the query to bomb, but the fields for which permission is denied to be
nullified?

In our web-based app, we have a request to implement granular permissions:
table/field level permissions. EG: userX can't read customers.socialsecurity in
any circumstance. We'd like to implement DB-level permissions; so far, we've
been using an ORM to manage CRUD permissions.

This is old hat, but our system has a large number of complex queries that
immediately break if *any* field permission fails. So, implementing this for
customers could be *very* painful

Is that there is a way to let the query succeed, but nullify any fields where
read permissions fail? (crossing fingers) We'd be watching the PG logs to
identify problem queries in this case.


If userX is a real database user you create a customers view in the 
userX schema that selects from the real customers table and either omits 
the field entirely or nullifies it. Permissions could be used to deny 
access to the underlying table, and search_path could be used to avoid 
most if not all application level changes.


Jack



--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


[GENERAL] Text to interval conversion can silently truncate data

2015-07-01 Thread Jack Christensen

jack=# select '1.51 years'::interval = '1.52 years'::interval;
 ?column?
--
 t
(1 row)

This is surprising. Once I looked at the C code for Interval it makes 
more sense given that it cannot represent fractional years, months, or 
days. Wouldn't it make more sense to raise an invalid input error than 
to silently truncate data?


Jack



[GENERAL] log_statement = 'mod' does not log all data modifying statements

2015-06-12 Thread Jack Christensen
I was recently surprised by changes that were not logged by 
log_statement = 'mod'. After changing log_statement to 'all', I found 
that the changes were occurring in a writable CTE.


Is there a way to log all statements that update data?

Jack



--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [GENERAL] moving to PostgreSQL from MS-SQL and from Oracle, looking for feature comparison information

2015-05-09 Thread Jack Christensen

On 05/09/2015 06:33 AM, Stephen Frost wrote:
Temporary tables will be in memory unless they overflow work_mem and 
we do support unlogged tables and tablespaces which you could stick 
out on a ramdisk if you want.
I would suggest not putting a table space on a ramdisk. According to the 
docs this risks corrupting the entire cluster.


http://www.postgresql.org/docs/9.4/static/manage-ag-tablespaces.html

Jack



--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


[GENERAL] PLV8 for PostgreSQL 9.4 on Ubuntu 14.04

2014-12-19 Thread Jack Christensen
With PostgreSQL 9.3 I installed plv8 from apt.postgresql.org 
(http://www.postgresql.org/download/linux/ubuntu/). It doesn't appear 
that it is available for 9.4. Is this no longer offered or has it just 
not available yet?


Thanks.

Jack



--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [GENERAL] Forcing materialize in the planner

2013-08-16 Thread Jack Christensen
Have you tried putting those components in a common table expression? 
I'm not sure if it absolutely forces the materialization or not, but in 
practice that has been my experience.


Robert James wrote:

I have a query which, when I materialize by hand some of its
components, runs 10x faster (including the time needed to
materialize).  Is there any way to force Postgres to do that? Or do I
need to do this by hand using temp tables?





--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


[GENERAL] Possible bug with row_to_json

2013-08-05 Thread Jack Christensen
When using a subquery as a source for row_to_json, depending on the 
order of arguments it may ignore renaming a column.


jack=# create table player(
jack(#   player_id serial primary key,
jack(#   name varchar not null unique
jack(# );
NOTICE:  CREATE TABLE will create implicit sequence 
player_player_id_seq for serial column player.player_id
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index 
player_pkey for table player
NOTICE:  CREATE TABLE / UNIQUE will create implicit index 
player_name_key for table player

CREATE TABLE
jack=# insert into player(name) values('Jack');
INSERT 0 1
jack=# select row_to_json(t)
jack-# from (
jack(#   select player_id as renamed, name
jack(#   from player
jack(#   order by name
jack(# ) t;
  row_to_json
---
 {player_id:1,name:Jack}
(1 row)


It ignored the rename.


jack=# select row_to_json(t)
from (
  select name, player_id as renamed
  from player
  order by name
) t;
 row_to_json
-
 {name:Jack,renamed:1}
(1 row)

But here it didn't.

Is this a bug?

Jack Christensen


Re: [GENERAL] Avoiding duplication of code via views -- slower? How do people typically do this?

2013-02-15 Thread Jack Christensen



Joe Van Dyk wrote:


Perhaps I fat-fingered something somewhere... I tried that and I got 
this: 
https://gist.github.com/joevandyk/4958906/raw/5561f95ef2b5d82f81ab14913c4d36f6aac3ee0a/gistfile1.txt


The with_filters view uses a different plan.
Interesting. It is avoiding the hash join, but it is still evaluating 
the exists column even when it is not referenced at all in the select. I 
would have expected the optimizer to remove it entirely.



--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [GENERAL] Avoiding duplication of code via views -- slower? How do people typically do this?

2013-02-14 Thread Jack Christensen

Joe Van Dyk wrote:
See 
https://gist.github.com/joevandyk/4957646/raw/86d55472ff8b5a4a6740d9c673d18a7005738467/gistfile1.txt 
for the code.


I have promotions(id, end_at, quantity) and 
promotion_usages(promotion_id).


I have a couple of things I typically want to retrieve, and I'd like 
those things to be composable.  In this case, finding recently-expired 
promotions, finding promotions that have a quantity of one, and 
finding promotions that were used.


My approach is to put these conditions into views, then I can join 
against each one. But that approach is much slower than inlining all 
the code.


How is this typically done?

Thanks,
Joe


From your first example on the gist I extracted this. It should avoid 
the multiple scans and hash join the the join of the two views suffers 
from.


create view promotions_with_filters as (
  select *,
end_at  now() - '30 days'::interval as recently_expired,
quantity = 1 as one_time_use,
exists(select 1 from promotion_usages pu on pu.promotion_id = p.id) 
as used

  from promotions
);

select count(*) from promotions_with_filters where recently_expired and 
one_time_use;



--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [GENERAL] Picking the first of an order in an aggregate query

2012-12-31 Thread Jack Christensen

On 12/31/2012 8:33 AM, Robert James wrote:

I have a query

   SELECT grouping_field, MIN(field_a), MIN(field_b)
   FROM ...
   GROUP BY grouping_field

But, instead of picking the MIN field_a and MIN field_b, I'd like to
pick field_a and field_b from the first record, according to an order
I'll specify.  In pseudo-SQL, it would be something like this:

   SELECT grouping_field, FIRST(field_a), FIRST(field_b)
   FROM ...
   ORDER BY field_c DESC, field_d ASC, myfunc(field_e) ASC
   GROUP BY grouping_field

How can I do that with Postgres?



select distinct on (grouping_field), field_a, field_b
from ...
order by grouping_field, field_a asc, field_b asc


http://www.postgresql.org/docs/9.2/static/sql-select.html#SQL-DISTINCT

--
Jack Christensen
http://jackchristensen.com/



--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [GENERAL] Complex database infrastructure - how to?

2012-06-30 Thread Jack Christensen

On 6/30/2012 9:25 AM, Edson Richter wrote:
I've a plan that will need a complex database infra-structure using 
PostgreSQL 9.1.
I've seen similar setups using MS SQL Server and other databases, but 
all of them support cross database queries (also easy to implement 
with materialized views).


- Administrative database: have few tables, used to administer the 
infrastructure. This database have some tables like users, groups, 
permissions, etc.

- Application databases: have app specific data.

1) One main Administrative application that will have read/write 
permissions over the Administrative database.
2) Each application will have to access the application database (for 
read/write), and the administrative database (for read only - mainly 
to maintain the record references to the users that created objects, 
and so on).

3) All applications are written in Java, using JPA for persistence.
4) All databases are running on same server, and all of them have same 
encoding.


What I've tried so far:
1) Copy tables from Administrative to Application: this approach would 
work, but I have trouble with the foreign keys. I'll have to disable 
(or drop) them, then copy data, then activate (or recreate them 
again). Could lead to problems?
2) dblink: I can't use foreign key to foreign tables. Also, it is very 
hard to implement with JPA.
3) odbc_fdw: along with unstability, difficult to build/deploy, it is 
too slow (why? - don't know)
4) JPA spacific multi-database approach: not really working, and can't 
provide database integrity


My next try will be using triggers in Administrative database to send 
data to Application databases using dblink.


Is there any ohter way to do that? Please, adivce!

Edson.


Consider using one database with multiple schemas. You can separate your 
applications into their own schemas, and you can have cross-schema 
foreign keys.


--
Jack Christensen
http://jackchristensen.com/


--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [GENERAL] Subselect with incorrect column not a syntax error?

2012-04-13 Thread Jack Christensen

On 4/13/2012 11:39 AM, Mike Blackwell wrote:

Could someone please explain to me why the following select does not
result in a syntax error?  (9.0.3)

begin;

create table x( c1 integer , c2 integer);
create table y( c3 integer, c4 integer);

select * from x where c2 in ( select c2 from y where c4 = 2 );


rollback;

Mike

Your subquery is correlated with the outer query. So the c2 in the 
subquery is referring to table x.


--
Jack Christensen
ja...@hylesanderson.edu


--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [GENERAL] Optimise PostgreSQL for fast testing

2012-02-23 Thread Jack Christensen

On 2/23/2012 9:22 AM, Simon Riggs wrote:

On Thu, Feb 23, 2012 at 5:13 AM, Dmytrii Nagirniakdna...@gmail.com  wrote:


I wonder if you can suggest me how to speed-up PG when running specs.
I asked it at SO here:

http://stackoverflow.com/questions/9407442/optimise-postgresql-for-fast-testing

But briefly. PG specs are2x slower than SQLite.
I want it to be on par (don't care about reliability or anything, just need
fast specs).

Would appreciate some suggestions.

You really need to explain why this matters...

You mention a typical Ruby on Rails app and then discuss SQLite.
Well, typical web apps have more than 1 user, so fairly obviously
using SQLite isn't appropriate. If SQLite isn't appropriate, why are
you testing with it? How does a test run on a database you aren't
using in production tell you anything about the success or otherwise
of your program. It doesn't, so saying it runs quicker is irrelevant,
surely?

Perhaps just run half the test, that would make it twice as quick and
still just as valid.

If Postgres tests run in ~1 minute, what benefit have you gained from
saving 30 seconds? How often are you running tests?

So please explain a little more.

As another Rails developer using PostgreSQL I think I can explain the 
use case. In standard Rails usage, the ORM handles all SQL query 
generation and thus the application is database agnostic. It is typical 
to use SQLite in development and testing and MySQL or PostgreSQL in 
production. However, if any PostgreSQL specific functionality is used 
then obviously PostgreSQL must also be used in development and testing.


Another common practice is test-driven development. So the test suite 
for the application may run scores or hundreds of times per day per 
developer. So the speed of the test suite is of vital importance to 
developers. A 30 second difference 100's of times per day really can add 
up.


--
Jack Christensen
ja...@hylesanderson.edu


--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


[GENERAL] Set returning functions in select column list

2012-02-16 Thread Jack Christensen
* Apologies if anyone receives this twice. I previously sent it from 
another address and it did not appear to go through.


Can someone explain how set returning functions in a select clause work?

It seems that it is doing some sort of implicit cross join.

deliverance_development=# select id, generate_series(1, 3) from users;
 id | generate_series
+-
  0 |   1
  0 |   2
  0 |   3
  1 |   1
  1 |   2
  1 |   3
(6 rows)

But if multiple set returning functions that return the same number of 
rows are in the same select it doesn't further cross join it.


deliverance_development=# select id, generate_series(1, 3), 
generate_series(4, 6) from users;

 id | generate_series | generate_series
+-+-
  0 |   1 |   4
  0 |   2 |   5
  0 |   3 |   6
  1 |   1 |   4
  1 |   2 |   5
  1 |   3 |   6
(6 rows)


But if the set returning functions return a different number of rows 
then it goes back to a cross join.


deliverance_development=# select id, generate_series(1, 3), 
generate_series(4, 5) from users;

 id | generate_series | generate_series
+-+-
  0 |   1 |   4
  0 |   2 |   5
  0 |   3 |   4
  0 |   1 |   5
  0 |   2 |   4
  0 |   3 |   5
  1 |   1 |   4
  1 |   2 |   5
  1 |   3 |   4
  1 |   1 |   5
  1 |   2 |   4
  1 |   3 |   5
(12 rows)


I really don't understand what is going on here. I have checked Google 
and the PostgreSQL docs, but it appears either I do not know the key 
words to search for or it is sparsely documented.


Jack

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


[GENERAL] Functions that return a set in select column list

2012-02-16 Thread Jack Christensen
* Apologies if anyone receives this multiple times. I previously sent it 
with a subject that started with Set and it triggered some sort of 
admin filter.


Can someone explain how set returning functions in a select clause work?

It seems that it is doing some sort of implicit cross join.

deliverance_development=# select id, generate_series(1, 3) from users;
 id | generate_series
+-
  0 |   1
  0 |   2
  0 |   3
  1 |   1
  1 |   2
  1 |   3
(6 rows)

But if multiple set returning functions that return the same number of 
rows are in the same select it doesn't further cross join it.


deliverance_development=# select id, generate_series(1, 3), 
generate_series(4, 6) from users;

 id | generate_series | generate_series
+-+-
  0 |   1 |   4
  0 |   2 |   5
  0 |   3 |   6
  1 |   1 |   4
  1 |   2 |   5
  1 |   3 |   6
(6 rows)


But if the set returning functions return a different number of rows 
then it goes back to a cross join.


deliverance_development=# select id, generate_series(1, 3), 
generate_series(4, 5) from users;

 id | generate_series | generate_series
+-+-
  0 |   1 |   4
  0 |   2 |   5
  0 |   3 |   4
  0 |   1 |   5
  0 |   2 |   4
  0 |   3 |   5
  1 |   1 |   4
  1 |   2 |   5
  1 |   3 |   4
  1 |   1 |   5
  1 |   2 |   4
  1 |   3 |   5
(12 rows)


I really don't understand what is going on here. I have checked Google 
and the PostgreSQL docs, but it appears either I do not know the key 
words to search for or it is sparsely documented.


Jack

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


[GENERAL] Set returning functions in select column list

2012-02-16 Thread Jack Christensen

Can someone explain how set returning functions in a select clause work?

It seems that it is doing some sort of implicit cross join.

deliverance_development=# select id, generate_series(1, 3) from users;
 id | generate_series
+-
  0 |   1
  0 |   2
  0 |   3
  1 |   1
  1 |   2
  1 |   3
(6 rows)

But if multiple set returning functions that return the same number of 
rows are in the same select it doesn't further cross join it.


deliverance_development=# select id, generate_series(1, 3), 
generate_series(4, 6) from users;

 id | generate_series | generate_series
+-+-
  0 |   1 |   4
  0 |   2 |   5
  0 |   3 |   6
  1 |   1 |   4
  1 |   2 |   5
  1 |   3 |   6
(6 rows)


But if the set returning functions return a different number of rows 
then it goes back to a cross join.


deliverance_development=# select id, generate_series(1, 3), 
generate_series(4, 5) from users;

 id | generate_series | generate_series
+-+-
  0 |   1 |   4
  0 |   2 |   5
  0 |   3 |   4
  0 |   1 |   5
  0 |   2 |   4
  0 |   3 |   5
  1 |   1 |   4
  1 |   2 |   5
  1 |   3 |   4
  1 |   1 |   5
  1 |   2 |   4
  1 |   3 |   5
(12 rows)


I really don't understand what is going on here. I have checked Google 
and the PostgreSQL docs, but it appears either I do not know the key 
words to search for or it is sparsely documented.


--
Jack Christensen
ja...@hylesanderson.edu

--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [GENERAL] Why does aggregate query allow select of non-group by or aggregate values?

2011-12-10 Thread Jack Christensen

On 12/9/2011 4:57 PM, David Johnston wrote:

Functions are evaluated once for each row that it generated by the
surrounding query.  This is particularly useful if the function in question
takes an aggregate as an input:

SELECT col1,  array_processing_function( ARRAY_AGG( col2 ) )
FROM table
GROUP BY col1;

Without this particular behavior you would need to sub-query.

 From a layman's perspective the reason why you cannot use non-aggregates
outside of GROUP BY it that it is ambiguous as to what value to output; with
an uncorrelated function call that is not the case.

David J.




Thanks. This makes sense now. I also went back to the original query 
that provoked this question. It had a correlated subquery in the select 
statement. I thought that this could yield ambiguous results. But when I 
examined it closely, all the correlated fields were included in the 
group by of the outer query, and when I tried to use a non-grouped 
column from the outer query I correctly got a ERROR: subquery uses 
ungrouped column foo from outer query


Thanks again.

--
Jack Christensen
ja...@hylesanderson.edu


--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


[GENERAL] Why does aggregate query allow select of non-group by or aggregate values?

2011-12-09 Thread Jack Christensen

CREATE TABLE people(
  id serial PRIMARY KEY,
  name varchar NOT NULL
);

INSERT INTO people(name) VALUES('Adam'), ('Adam'), ('Adam'), ('Bill'), 
('Sam'), ('Joe'), ('Joe');


SELECT name, count(*), random()
FROM people
GROUP BY name;


I would expect this query to cause an error because of random(). I ran 
into this using an array produced by a subquery as a column in the 
select of an aggregate query, but I was able to boil it down to this 
contrived example. Shouldn't any expression that is not in the group by 
or an aggregate function be rejected?


What am I not understanding?

Thanks.

--
Jack Christensen
ja...@hylesanderson.edu


--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [GENERAL] Failure controlling PG 9.1 service on Ubuntu 10.04 32-bit

2011-10-10 Thread Jack Christensen

On 10/8/2011 1:21 AM, Craig Ringer wrote:

On 10/08/2011 02:23 AM, Jack Christensen wrote:

Just upgraded a machine from PostgreSQL 9.0 to 9.1. I uninstalled the
old version then installed the new one.

Whenever I try to run a service command to start, stop, or restart the
server it fails.

jackc@lizard:~$ sudo service postgresql stop
* Stopping PostgreSQL 9.1 database server
* Error: Could not open /proc/2193/comm
[fail]

It seems to be happening in /usr/share/postgresql-common/PgCommon.pm:542


The Upstart scripts and packaging are part of Ubuntu and maintained 
separately to PostgreSQL. I suggest you file a bug on Launchpad, 
providing as much detail as you can to assist in identifying why the 
issue arose.
It looks like you were right. There was another update released over the 
weekend that resolved the problem.


--
Craig Ringer




--
Jack Christensen
ja...@hylesanderson.edu


--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


[GENERAL] Failure controlling PG 9.1 service on Ubuntu 10.04 32-bit

2011-10-07 Thread Jack Christensen
Just upgraded a machine from PostgreSQL 9.0 to 9.1. I uninstalled the 
old version then installed the new one.


Whenever I try to run a service command to start, stop, or restart the 
server it fails.


jackc@lizard:~$ sudo service postgresql stop
 * Stopping PostgreSQL 9.1 database server
 * Error: Could not open /proc/2193/comm
 [fail]

It seems to be happening in /usr/share/postgresql-common/PgCommon.pm:542

PostgreSQL is actually running fine, but the only way I can make any 
changes is to reboot the server (or kill all the postgres processes I 
suppose).


--
Jack Christensen
ja...@hylesanderson.edu


--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [GENERAL] WITH x AS (...) and visibility in UPDATE

2011-07-27 Thread Jack Christensen

On 7/27/2011 4:22 PM, Peter V wrote:
I want to apply updates on a copy of a row, instead on the row itself. 
The queries are above were simplied to demonstrate the problem.

So basically I want to do:

1) create the copy of the row and return the identifier
2) apply updates on the new row identified by the identifier returned in step 1

If possible, I want to write this in a single command, to avoid overhead and 
mistakes.

I tried writing a rewrite rule or before trigger, but it becomes quickly a mess 
to avoid infinite loops.

Any ideas are welcome. Thanks.

Maybe I'm totally missing something, but why insert a copy and then 
update instead of directly insert a mutated copy?


Something like:
INSERT INTO t (foo, bar) SELECT 'my new foo', t.bar FROM t WHERE id=123;

Wouldn't the above construction let you make a new row with some new 
values and some copied values?


--
Jack Christensen
ja...@hylesanderson.edu


--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [GENERAL] implementing check-in/check-out of an items table

2011-05-20 Thread Jack Christensen

On 5/20/2011 8:41 AM, Seb wrote:

Hi,

I'm trying to implementing the checking in and checking out of items in
a table, whereby an item cannot be checked out if it's not checked-in.
I've searched for schemas for public libraries where this is a key
requirement, but haven't managed to hit the right keywords to get
relevant results.

Thanks,

Use a loans table with unique partial index to ensure that only one 
unreturned loan per item can exist at a time.


CREATE TABLE items(
  item_id SERIAL PRIMARY KEY,
  ...
);

CREATE TABLE loans(
  loan_id SERIAL,
  item_id integer NOT NULL REFERENCES items,
  start_time timestamptz NOT NULL,
  end_time timestamptz
  ...
);

CREATE UNIQUE INDEX ON loans(item_id) WHERE end_time IS NULL;

--
Jack Christensen
ja...@hylesanderson.edu


--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [GENERAL] implementing check-in/check-out of an items table

2011-05-20 Thread Jack Christensen

On 5/20/2011 10:15 AM, Seb wrote:

On Fri, 20 May 2011 09:48:45 -0500,
Jack Christensenja...@hylesanderson.edu  wrote:

Use a loans table with unique partial index to ensure that only one
unreturned loan per item can exist at a time.

[...]

Thanks, this certainly avoids loaning an item before it's returned, but
it doesn't protect against having loans that overlap in time.  For
example, an item can have a start_time that is between start_time and
end_time of a previous loan for that same item.  My first thought was to
have some CHECK constraint with a query, but this doesn't seem to be
supported by postgresql.


In a similar project I worked on start time for a loan was always the 
current time so overlaps weren't an issue. I don't have any firsthand 
experience with them, but it sounds like what you want are exclusion 
constraints.


http://www.depesz.com/index.php/2010/01/03/waiting-for-8-5-exclusion-constraints/

--
Jack Christensen
ja...@hylesanderson.edu


--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [GENERAL] Multiple table relationship constraints

2011-05-09 Thread Jack Christensen

On 5/5/2011 3:26 PM, Rick Genter wrote:


Hm. I think the way I would handle this is to put the business logic 
for inserting/updating into the room_assignments table into one or 
more functions and have a special user that owns the tables and owns 
the functions and declare the functions to be SECURITY DEFINER. Revoke 
INSERT/UPDATE/DELETE access to the tables from all other users. Then 
you grant your regular users EXECUTE access to the functions. The 
functions run as the user that created them, so they will have direct 
INSERT/UPDATE/DELETE access to the tables while your regular users won't.


Thanks everyone for your advice. I think this type of approach will be 
very helpful.


--
Jack Christensen
ja...@hylesanderson.edu


--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


[GENERAL] Multiple table relationship constraints

2011-05-05 Thread Jack Christensen
What is the best way to handle multiple table relationships where 
attributes of the tables at the ends of the chain must match?


Example:

CREATE TABLE achievements(
achievement_id serial PRIMARY KEY,
...
);

CREATE TABLE achievement_versions(
achievement_version_id serial PRIMARY KEY,
achievement_id integer NOT NULL REFERENCES achievements,
...
);

CREATE TABLE achievement_attempts(
achievement_attempt_id serial PRIMARY KEY,
achievement_version_id integer NOT NULL REFERENCES achievement_versions,
...
);

CREATE TABLE actions(
action_id serial PRIMARY KEY,
...
)

CREATE TABLE achievement_attempt_actions(
achievement_attempt_id integer NOT NULL REFERENCES achievement_attempts,
action_id integer NOT NULL REFERENCES actions,
PRIMARY KEY( achievement_attempt_id, action_id)
);


The achievement_attempt_actions table links actions to 
achievement_attempts. For a link to be valid a number of attributes of 
actions must match attributes of achievements and achievement_attempts. 
This means an update to any of these 5 tables could invalidate the 
chain. How can I eliminate the possibility for this type of erroneous data?


I have come up with 4 possibilities.

1. Composite keys -- I could include all the attributes that must match 
on all the tables through the chain and let foreign key constraints 
handle it. This could work but it feels wrong to be duplicating 
attributes. It also is inconvenient (but possible) with my ORM.


2. Triggers -- I can use triggers to check every change on all 5 tables 
that could possibly cause an invalid chain. I have done this before and 
it does work -- but it can be error prone.


3. Check a materialized view -- Add triggers to all 5 tables to keep a 
materialized view up to date. Check constraints could validate the 
materialized view.


4. Validate application side -- this can work well, but it leaves the 
hole of a bug in the application or a direct SQL statement going bad.



Anyone have any advice on the best way to handle this?

--
Jack Christensen
ja...@hylesanderson.edu


--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [GENERAL] Multiple table relationship constraints

2011-05-05 Thread Jack Christensen

On 5/5/2011 2:28 PM, Rick Genter wrote:
On Thu, May 5, 2011 at 3:20 PM, Jack Christensen 
ja...@hylesanderson.edu mailto:ja...@hylesanderson.edu wrote:


What is the best way to handle multiple table relationships where
attributes of the tables at the ends of the chain must match?

Example:

CREATE TABLE achievements(
achievement_id serial PRIMARY KEY,
...
);

CREATE TABLE achievement_versions(
achievement_version_id serial PRIMARY KEY,
achievement_id integer NOT NULL REFERENCES achievements,
...
);

CREATE TABLE achievement_attempts(
achievement_attempt_id serial PRIMARY KEY,
achievement_version_id integer NOT NULL REFERENCES
achievement_versions,
...
);

CREATE TABLE actions(
action_id serial PRIMARY KEY,
...
)

CREATE TABLE achievement_attempt_actions(
achievement_attempt_id integer NOT NULL REFERENCES
achievement_attempts,
action_id integer NOT NULL REFERENCES actions,
PRIMARY KEY( achievement_attempt_id, action_id)
);


The achievement_attempt_actions table links actions to
achievement_attempts. For a link to be valid a number of
attributes of actions must match attributes of achievements and
achievement_attempts. This means an update to any of these 5
tables could invalidate the chain. How can I eliminate the
possibility for this type of erroneous data?


I might not be understanding your question, but isn't that what your 
foreign key references do? For example, you can't update 
achievement_attempt_id in the achievement_attempt table if there is an 
achievement_attempt_actions record that refers to it since that would 
break the reference. (Not that you want to be updating primary key 
values in the first place...)
The trick is there are additional attributes of actions and achievements 
such as a category that must match for the link to be valid. These 
attributes are not part of the primary key of either record and can and 
do change.

--
Rick Genter
rick.gen...@gmail.com mailto:rick.gen...@gmail.com




--
Jack Christensen
ja...@hylesanderson.edu



Re: [GENERAL] Multiple table relationship constraints

2011-05-05 Thread Jack Christensen

On 5/5/2011 2:53 PM, Rick Genter wrote:
On Thu, May 5, 2011 at 3:50 PM, Jack Christensen 
ja...@hylesanderson.edu mailto:ja...@hylesanderson.edu wrote:


The trick is there are additional attributes of actions and
achievements such as a category that must match for the link to be
valid. These attributes are not part of the primary key of either
record and can and do change.


So your data is denormalized? (The category appears in 2 tables?) 
Don't do that. Create a view that joins your two tables together 
instead if you need a single entity that contains data from multiple 
sources. Then you won't have any of the data integrity issues you're 
worried about.
It's not denormalized. It is an attribute that both tables have that 
have to match for it to be a valid link.


Here's a contrived example:

CREATE TABLE dorms(
  dorm_id serial PRIMARY KEY,
  gender varchar NOT NULL,
  ...
);

CREATE TABLE people(
  person_id serial PRIMARY KEY,
  gender varchar NOT NULL,
  ...
);

CREATE TABLE room_assignments(
  person_id integer NOT NULL REFERENCES people,
  dorm_id integer NOT NULL REFERENCES dorms,
  ...
);

Men should only be assignable to men's dorms and women should only be 
assignable to women's dorms. On occasion a person's or dorm's gender 
needs to be updated. I want to make sure that doesn't cause a room 
assignment to become invalid. In this example, adding gender to 
room_assignments and using composite foreign keys is fairly straight 
forward -- but in my actual domain I have 5+ tables and 2+ attributes 
involved in the relationship.


--
Rick Genter
rick.gen...@gmail.com mailto:rick.gen...@gmail.com




--
Jack Christensen
ja...@hylesanderson.edu



[GENERAL] Deferred foreign key constraint downsides

2011-04-08 Thread Jack Christensen
I recently had cause to use a deferred foreign key constraint for the 
first time. I like it. It seems it could make life simpler, especially 
when an obstinate ORM insists on doing things in the wrong order.


The only downside I can see is it may be harder to track down where a 
violation occurred since the error won't be raised until commit.


Are there any other downsides to just setting all my foreign keys to 
initially deferred?


Thanks.

--
Jack Christensen
ja...@hylesanderson.edu


--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


Re: [GENERAL] What is the name pseudo column

2010-12-16 Thread Jack Christensen

On 12/15/2010 5:43 PM, Adrian Klaver wrote:

On Wednesday 15 December 2010 1:27:19 pm David Fetter wrote:

On Wed, Dec 15, 2010 at 01:50:54PM -0600, Jack Christensen wrote:

I was just surprised when accidentally selecting a non-existent name
column there was no error -- instead something came back.

select accounts.name from accounts limit 1 -
(1,65522,1,0.00,,2010-07-22 09:57:26.281172-05,2)

It appears it tries to return the entire row in an array (but longer
rows get truncated).

I've searched Google and the PG docs but I haven't had any luck.

What happened here is that you ran into PostgreSQL's charming habit
of using the argument.function notation, so you called the name
function, i.e. the one that casts to name, on the entire row from your
accounts table.

Cheers,
David.


In the for what is worth department that behavior is going away in 9.1. See here
for a detailed explanation:
http://www.depesz.com/index.php/2010/11/08/waiting-for-9-1-removed-autocast-footgun/#more-1908
It makes sense now what's happening -- but glad to see that feature is 
going away.


Thanks.

--
Jack Christensen
ja...@hylesanderson.edu


--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general


[GENERAL] What is the name pseudo column

2010-12-15 Thread Jack Christensen
I was just surprised when accidentally selecting a non-existent name 
column there was no error -- instead something came back.


select accounts.name from accounts limit 1 - 
(1,65522,1,0.00,,2010-07-22 09:57:26.281172-05,2)


It appears it tries to return the entire row in an array (but longer 
rows get truncated).


I've searched Google and the PG docs but I haven't had any luck.

--
Jack Christensen
ja...@hylesanderson.edu


--
Sent via pgsql-general mailing list (pgsql-general@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general