Monday, September 1, 2008

[JDBC] UPDATE ... CURRENT OF cursorname

I looking for an explination of how named cursor updates actually
work. For example from the following link:
http://java.sun.com/javase/6/docs/technotes/guides/jdbc/getstart/resultset.html


the code seems to imply that all rows from a name cursor will be update.

...
stmt.setCursorName("x");
ResultSet rs = stmt.executeQuery(
"SELECT . . . FROM . . . WHERE . . . FOR UPDATE . . .")
String cursorName = rs.getCursorName;
int updateCount = stmt2.executeUpdate(
"UPDATE . . . WHERE CURRENT OF " + cursorName);
...

However from the postgresql manual, the verbase seems to indicate that
only the record currently pointed to in the cursor is updated.
http://www.postgresql.org/docs/8.3/interactive/sql-update.html

...
cursor_name
The name of the cursor to use in a WHERE CURRENT OF condition. The
->row<- to be updated is the one most recently fetched from this
cursor.
...

--
Regards,
Richard Broersma Jr.

Visit the Los Angeles PostgreSQL Users Group (LAPUG)
http://pugs.postgresql.org/lapug

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

Re: [BUGS] BUG #4389: FATAL: could not reattach to shared memory (key=1804, addr=018E0000): 487

could not reattach to shared memory napsal(a):
> The following bug has been logged online:
>
> Bug reference: 4389
> Logged by: could not reattach to shared memory
> Email address: diesel_den@ukr.net
> PostgreSQL version: 8.3.3-1
> Operating system: any 8.3.*
> Description: FATAL: could not reattach to shared memory (key=1804,
> addr=018E0000): 487
> Details:
>
> This error came week ago.
> From that 'black' day I can not use Postgre.
> I have reinstalled several 8.3.* versions (including last version with
> vcredist_x86.exe) and nothing helps me.
>

try to remove postgesql.pid file in the data directory.

Zdenek

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

Re: [pgsql-es-ayuda] Cómo cambio el plan de ejecución de un query

"Carlos Beltrán V." escribió:

> Alvaro, como realmente los selects de este tipo, se están usando en
> muchos scripts y son planos, ¿debo agruparlos como está el ejemplo o
> podría existir otra opción?

¿Probaste a darle un COST a la función?

> Y por último ¿Cuál fue la motivación para que implementaran este nuevo
> comportamiento en la versión 8.3.3?

Mejorar el optimizador.

--
Alvaro Herrera http://www.amazon.com/gp/registry/CTMLCN8V17R4
Renaming ReiserFS to NinaFS is such an amazingly stupid suggestion, in so many
ways, that it ought to qualify for some kind of award. Or perhaps we should
name an award after it: the "NinaFS award" for outstanding crassness.
(edmundo, http://lwn.net/Articles/203846/)
--
TIP 1: para suscribirte y desuscribirte, visita http://archives.postgresql.org/pgsql-es-ayuda

Re: [pgsql-es-ayuda] Problema insertando datos (TIME)

Cuando t ocurren esos problemas deberias dar una vuelta para que despejes la mente.. xD


--
Joseph Cesar Mena S.
+51 (1) 991526548
L1nuX R3g1$t3r3d U53r #412302
.~.
( 0 0 )
/ V \
// \\
/(( _ ))\

[pgsql-es-ayuda] Exprimir a Postgre

Amigos como estan, acudo ante ustedes para pedirles sus consejos, estoy desarrollando una aplicacion con punto net en windows forms y  postgre, ahora mi idea es explotar todas las virtudes de la base de dtos, ya que necesito hacer la aplicacion lo mas rapido posible, porque estamos migrando de un sistenma antiguo hecho en fox  a la nueva base y lenguaje, entonces quisiera que me ayuden con que cosas tengo que tener en consideracion para sacarle el jugo a la base de datos y hacer mi aplicacion lo mas rapido posible,  tambien necesito manejar replicas, y grandes volumenes de informacion, de pronto como deberia manejar las conexiones, si el crear indices, y llaves me ayudara, donde deberia manejar la concurrencia, la integridad referencial en punto net o directo con las llaves en postgre, bueno como veran soy nuevo en esto ahi que espero me puedas dar sus consejos segun las experieancias que han tenido.

De antemano agradesco cualquier ayuda que me puedan dar,

Saludos


Get more from your digital life. Find out how.

Re: [pgadmin-support] Table Constraints Bug

Matthew Arp a écrit :
> pgAdminIII will not allow you to add a self-referential constraint while
> using the GUI table editor, see the below example:
>
> CREATE TABLE "role"
> (
> uid integer NOT NULL,
> "name" character varying(32) NOT NULL,
> parent integer NOT NULL DEFAULT 1,
> CONSTRAINT role_pkey PRIMARY KEY (uid),
> CONSTRAINT role_parent_fkey FOREIGN KEY (parent)
> REFERENCES "role" (uid) MATCH SIMPLE
> ON UPDATE NO ACTION ON DELETE RESTRICT
> )
> WITH (OIDS=FALSE);
> ALTER TABLE "role" OWNER TO glasshook_admin;

Can we have more details? because I can add a foreign key which refers
to the same table with the GUI table editor.


--
Guillaume.
http://www.postgresqlfr.org
http://dalibo.com

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

[GENERAL] immutable functions and enumerate type casts in indexes

Hello,

I have a problem with enumerated types in functions parameters.

my enumerated type is (this is a subset)
CREATE TYPE hibridation AS ENUM('none','genus','specie');

function declaration
CREATE FUNCTION ename(text,boolean,text,text RETURNS text AS
'funzioniGDB.so' LANGUAGE C IMMUTABLE;

index creation (the type of ibrido is hibridation)
CREATE INDEX i_specie_nome_specie ON specie
(esterna_nome(ibrido::text,proParte,genere,specie));

the result is
ERROR: functions in index expression must be marked IMMUTABLE

Searching on google I found some explanation: the problem arises with
"non immutable" typea as "data" but I can't figure the problem (or
better, the solution) with enumerate types.

What can I do?

thank you
Edoardo

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

Re: [BUGS] Bug in RETURN QUERY

"Pavel Stehule" <pavel.stehule@gmail.com> writes:
> 2008/9/1 Oleg Serov <serovov@gmail.com>:
>> ERROR: structure of query does not match function result type
>> CONTEXT: PL/pgSQL function "buggy_procedure" line 3 at RETURN QUERY*/

> this isn't bug, it's feature.

No, it's a bug, and it's not related to plan caching at all --- even if
you start a fresh session the error persists. The problem is that
plpgsql isn't very good at dealing with rowtypes that contain dropped
columns. Unfortunately Oleg shouldn't hold his breath waiting for a
fix, because it's not trivial. In this example, the function would need
to return a three-column tuple (id, dropped-column, buggy_enum_field)
but the SELECT is only giving it two columns. There isn't anything in
plpgsql that has the ability to convert a tuple to add dropped columns
in the right places. I think we'd consider adding such functionality
as a new feature not a back-patchable bug fix.

The best near-term workaround would be to handle changes like this by
means of ALTER COLUMN TYPE rather than dropping and re-adding columns.

regards, tom lane

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

Re: [pgsql-www] Download links

On Mon, Sep 1, 2008 at 4:54 PM, Chander Ganesan <chander@otg-nc.com> wrote:

> All I'm saying is that there is a major decrease in usability of the site
> when it's not clearly documented where someone can get the latest patch
> version for their release.

It never has been clearly documented, nor was it ever particularly
usable due to the large number of places and ways that people get
their upgrades, most of which didn't actually come from us. What is
there now is designed to help people drill down to the distribution
that is right for them (which the old method failed to do completely
unless they ran Windows or built from source), from where they can
find the distribution-specific upgrade path.

For example, If you run Solaris, you Click Downloads -> Solaris ->
Download and then pick the version number and architecture you need.

If you run Debian, you click Downloads -> Linux where you'll see a
section for Debian/APT, with links to the Debian website and Debian
packages database.

Just to re-iterate, some time back I did ask for contributions to
improve the wording for each platform/distro. Iirc, Devrim and Peter
both kindly helped out. Further suggestions are welcome.

--
Dave Page
EnterpriseDB UK: http://www.enterprisedb.com

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

Re: [BUGS] Bug with FOR ... LOOP and composite types

"Pavel Stehule" <pavel.stehule@gmail.com> writes:
> 2008/9/1 Oleg Serov <serovov@gmail.com>:
>> Seems there is an error when I try to use a table with one field - composite
>> type, when SELECT QUERY in FOR ... LOOP instruction returns empty result.

> ROWTYPE is problem.

I think it actually is a bug. exec_for_query tries to set the target to
null this way:

exec_move_row(estate, rec, row, NULL, tuptab->tupdesc);

and exec_move_row thinks it doesn't have to present a valid "valtype"
to exec_assign_value when it's assigning a made-up null, and that fails
when the target is of PLPGSQL_DTYPE_ROW type (looks like it'd fail for
REC type too, but ROW is the case here).

We could work around the particular issue by moving the
type_is_rowtype() tests down so they're not done for a null source
value, but I think that's just a hack. A cleaner fix would be to teach
exec_move_row to present the correct column type in all cases.

regards, tom lane

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

Re: [pgsql-es-ayuda] default current_time

José Fermín Francisco Ferreras escribió:
>
> Hola, como muchos d ustedes saben soy d República Dominicana, y
> necesito ver insertar la hora en un camo de una tabla.
>
> Este ejemplito :
>
> create table tabla
> (
> codigo integer primary key,
> hora time default current_time
> );

El problema seguramente no es el DEFAULT, sino que current_time no está
retornando la hora correcta. Prueba haciendo lo siguiente:

select current_time;

y fíjate si la hora concuerda con la del sistema o no.

--
Alvaro Herrera http://www.amazon.com/gp/registry/CTMLCN8V17R4
"El día que dejes de cambiar dejarás de vivir"
--
TIP 5: ¿Has leído nuestro extenso FAQ?
http://www.postgresql.org/docs/faqs.FAQ.html

Re: [pgsql-www] Download links

Alvaro Herrera wrote:
>> I had to spend a bit of time hunting around to find the latest release
>> of 8.2.x, in fact, it's not really "indicated" anywhere that "old"
>> versions are there. Looking at the /download page, I cannot find a
>> single reference to older versions (the big advantage to the old
>> format). One has to hunt around until they find the "source code" link
>> to locate an older version of postgresql.
>>
>
> There's no usefulness whatsoever to the old versions, so why should they
> be linked to?
>
>
There are many organizations that have PostgreSQL's older versions
deployed, and have yet to upgrade to the latest major release...but
still have need to download the latest patch release to upgrade their
installation. IMHO, for this reason the older versions are extremely
important. Hence the need to link to them.

All I'm saying is that there is a major decrease in usability of the
site when it's not clearly documented where someone can get the latest
patch version for their release.

--
Chander Ganesan
Open Technology Group, Inc.
One Copley Parkway, Suite 210
Morrisville, NC 27560
919-463-0999/877-258-8987
http://www.otg-nc.com


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

Re: [GENERAL] refcursor

mike stanton escribió:
>
> Hello all,
> I've got a problem I can't get round. I want to declare a refcursor variable in a C program and call a function which returns a refcursor portal to the main C program.
> When I compile the C program, I get a refcursor doesn´t exist message.
> Has anyone got a C program which uses a refcursor variable?

Make sure the C program opens a transaction before calling the function,
otherwise the cursor is automatically closed as soon as the function ends.

--
Alvaro Herrera Valdivia, Chile Geotag: -39,815 -73,257
"Ah, spring... when a young penguin's fancy lightly turns to thoughts of ...
Beta testing!" (Fedora 9 beta announcement)

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

Re: [pgsql-es-ayuda] Manual Postgresql 8.x

Lo ideal sería que leas la documentación oficial, es la más actual y completa al momento, lamentablemente no esta disponible en español.

Saludos

On Sun, Aug 31, 2008 at 3:45 PM, Matias Parodi <mparodilabs@gmail.com> wrote:
Hola! acabo de registrarme en la lista.

Hace algunos días busco un manual reciente de Postgresql en español, todo lo que he conseguido es de versiones anteriores a la 8. Podrían recomendarme o indicarme algo para empezar ? no quiero entrar a leer la documentación oficial sin antes tener una base.

Gracias. Matías.



--

Casiva Agustin

Mail/Msn: casivaagustin@gmail.com
http://www.casivaagustin.com.ar

Re: [SQL] MAY I HAVE YOUR ASSISTANCE

> -----Mensaje original-----
> De: pgsql-sql-owner@postgresql.org
> [mailto:pgsql-sql-owner@postgresql.org] En nombre de Gary Chambers
> Enviado el: Lunes, 01 de Septiembre de 2008 11:31
> Para: D'Arcy J.M. Cain
> CC: jameskitambara@yahoo.co.uk; pgsql-sql@postgresql.org
> Asunto: Re: [SQL] MAY I HAVE YOUR ASSISTANCE
>
> >> I have one problem with the user table. I want to hide the
> password for the users.
>
> Here's what I did, which requires using the contrib/pgcrypto
> extension:
>
> CREATE FUNCTION encryptpw() RETURNS TRIGGER AS $encryptpw$ BEGIN
> NEW.password = CRYPT(NEW.password, GEN_SALT('md5'));
> RETURN NEW;
> END;
> $encryptpw$
>
> CREATE TRIGGER trg_encryptpw BEFORE INSERT OR UPDATE ON
> assignees FOR EACH ROW EXECUTE PROCEDURE encryptpw();
>
> Comments, suggestions, criticisms?
>
> -- Gary Chambers
>

The weakness of this solution is that your password might be send in the
clear through the network as the encription ocurrs in the database. I
suggest the encryption be enforced at the application or secure the
connection with ssl.


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

Re: [pgsql-es-ayuda] traduccion documentacion

Alvaro Herrera escribió:
> Calabaza escribió:
>
>
>> Bueno, les cuento lo que hice, empecé a investigar sobre docbook
>> (porque no tengo ni la más pálida idea de que es), me baje algunos
>> tutoriales, agregue unos tantos links a los marcadores, y luego me
>> baje el código fuente de postgres del 8.3.3, para revisar en que
>> formato esta la documentación, que esta en sgml, hasta ahí todo bien,
>> ahora la pregunta es en que versión de docbook esta?
>>
>
> Uff ... y vamos reinventando la rueda *otra vez*.
>
> Les cuento que ya tenemos una plataforma para pasar de docbook a POT, y
> una aplicacion web para apoyar la traduccion de POTs. Incluso tenemos
> bastante gente que aportó a esa traducción. El conjunto está en un
> proyecto en pgfoundry.org/projects/webtranslator (la instalación que
> estaba funcionando antes ya no está al aire, pero confío en que Mario
> tenga un respaldo de la base de datos por ahí)
>
> Lo que nos hace falta es alguien que se haga cargo de administrar y
> mantener eso funcionando.
>
>
Me ofresco como voluntario para mantener...

--
TIP 9: visita nuestro canal de IRC #postgresql-es en irc.freenode.net

Re: [pgsql-es-ayuda] Linea de Comandos

Hola, Gracias por responder...

Yo veo que tengo el paquete "libreadline.so.5" en   "/lib", pero creo que el postgres no fue compilado con ella pq en la linea de comandos no me funciona...

Sé que tengo que revisar el ./configure (pero no se por donde lo encuentro) y sé que eventualmente tengo que volver a compilar el portgres (pero no se como hacerlo)...  te agradeceria si me puedes dar unas indicaciones...

Mauricio




 

2008/7/25 Alvaro Herrera <alvherre@alvh.no-ip.org>
Mauricio Lopez escribió:
> Mandrake 7

Uhhhhh eso es mas viejo que los calzones que tejía mi abuela ...  ¿No
tienes algo mas moderno?

Debería funcionar.  Imagino que lo estás compilando tú mismo.  En ese
caso lo único que debes asegurarte es que al hacer el "./configure" no
le des el --disable-readline.

A todo esto, ¿qué versión de Postgres estás usando?

--
Alvaro Herrera                         http://www.flickr.com/photos/alvherre/
"I must say, I am absolutely impressed with what pgsql's implementation of
VALUES allows me to do. It's kind of ridiculous how much "work" goes away in
my code.  Too bad I can't do this at work (Oracle 8/9)."       (Tom Allison)
          http://archives.postgresql.org/pgsql-general/2007-06/msg00016.php



[BUGS] BUG #4389: FATAL: could not reattach to shared memory (key=1804, addr=018E0000): 487

The following bug has been logged online:

Bug reference: 4389
Logged by: could not reattach to shared memory
Email address: diesel_den@ukr.net
PostgreSQL version: 8.3.3-1
Operating system: any 8.3.*
Description: FATAL: could not reattach to shared memory (key=1804,
addr=018E0000): 487
Details:

This error came week ago.
From that 'black' day I can not use Postgre.
I have reinstalled several 8.3.* versions (including last version with
vcredist_x86.exe) and nothing helps me.

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

[JDBC] Table Alias posing problem in Update statements

Hi experts,

I am facing a problem using a Alias on a table while updating that table.

I am trying something like

UPDATE Table1 T1 SET = (SELECT DISTINCT col2 FROM Table2 T2 WHERE
T2.col3 = T1.col1)

T1 and T2 are table aliases.

Here I am trying to update a column in all the rows in table "Table1"
depending on value of another column for the same row.
But the query is not working. It is not allowing alias in the update
query (i.e. alias T1 on table "Table1").

Am I making a mistake somewhere in the syntax? Or, is it just not
supported in postgresql?
I am using postgreSQL version 8.2.

I have observed similar problems with delete statements also.
But these types of queries run successfully on Oracle.

Thanks in advance.
Pushker Chaubey


The information contained in this electronic message and any attachments to this message are intended for the exclusive use of the addressee(s) and may contain proprietary, confidential or privileged information. If you are not the intended recipient, you should not disseminate, distribute or copy this e-mail. Please notify the sender immediately and destroy the original message all copies of this message and any attachments.
WARNING: Computer viruses can be transmitted via email. The recipient should check this email and any attachments for the presence of viruses. The company accepts no liability for any damage caused by any virus transmitted by this email.

Please do not print this email unless it is absolutely necessary.

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

Re: [GENERAL] Oracle and Postgresql

On Mon, Sep 01, 2008 at 04:39:09PM +0200, Thomas Kellerer wrote:
> David Fetter, 01.09.2008 16:08:
>>> because we are making extensive usage of Oracle's windowing
>>> functions
>>
>> http://umitanuki.net/pgsql/wfv04/design.html
>
> I knew there was work going on regarding this, but I didn't know how
> definite the decision was to integrate that into 8.4
>
> It's too bad lead(), lag() won't make it

It's not certain they won't make it, only that they're not in the
current patch.

>> It's even more fun with CTEs.
>> <http://wiki.postgresql.org/wiki/CTEReadme>
>
> Recursive CTE are quite cool, and a valid "replacement" for CONNECT
> BY. I've used it already with SQL Server 2005 and once you get the
> idea it's really nice.

It's also standard, where Oracle's syntax is proprietary. In
PostgreSQL, when there's a choice between the two, the standard wins.

>> Those will both be fixed, at least to a large degree, in 8.4 :)
>
> What exactly means "large degree" :)

It means we may not get everything the SQL:2008 standard specifies for
CTEs and windowing functions on the first pass.

Cheers,
David.
--
David Fetter <david@fetter.org> http://fetter.org/
Phone: +1 415 235 3778 AIM: dfetter666 Yahoo!: dfetter
Skype: davidfetter XMPP: david.fetter@gmail.com

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate

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

Re: [pgsql-es-ayuda] Consulta función

Ana Smail escribió:
> Tengo un problemita que creo se debe al casteo de tipos , esto:
> select ENCODE(DIGEST('admin', 'md5'),'hex');
> Funciona bien en la versión 8.2, pero ya no funciona en la 8.3 y no puedo
> corregir el problema.

Mi bola de cristal dice: La funcion digest() no está instalada. Instala
el modulo pgcrypto.

--
Alvaro Herrera http://www.advogato.org/person/alvherre
"El número de instalaciones de UNIX se ha elevado a 10,
y se espera que este número aumente" (UPM, 1972)
--
TIP 9: visita nuestro canal de IRC #postgresql-es en irc.freenode.net

Re: [pgsql-es-ayuda] Consulta función



On Mon, Sep 1, 2008 at 9:45 AM, Ana Smail <anasmail@unnoba.edu.ar> wrote:
Tengo un problemita que creo se debe al casteo de tipos , esto:
select ENCODE(DIGEST('admin', 'md5'),'hex');
Funciona bien en la versión 8.2, pero ya no funciona en la 8.3 y no puedo
corregir el problema.

ANA

--
TIP 3: Si encontraste la respuesta a tu problema, publícala, otros te lo agradecerán

Pues a mi me funciono bien desde PgAdmin, tengo la 8.3.3.

--
Joseph Cesar Mena S.
+51 (1) 991526548
L1nuX R3g1$t3r3d U53r #412302
.~.
( 0 0 )
/ V \
// \\
/(( _ ))\

[pgsql-es-ayuda] Consulta función

Tengo un problemita que creo se debe al casteo de tipos , esto:
select ENCODE(DIGEST('admin', 'md5'),'hex');
Funciona bien en la versión 8.2, pero ya no funciona en la 8.3 y no puedo
corregir el problema.

ANA

--
TIP 3: Si encontraste la respuesta a tu problema, publícala, otros te lo agradecerán

Re: [PERFORM] limit clause breaks query planner?

Thanks for your suggestion but the result is the same.

Here is the explain analyse output from different queries.
Select * from my_table where A is null and B = '21' limit 15

"Limit (cost=0.00..3.68 rows=15 width=128) (actual time=85837.043..85896.140 rows=15 loops=1)"
" -> Seq Scan on my_table this_ (cost=0.00..258789.88 rows=1055580 width=128) (actual time=85837.038..85896.091 rows=15 loops=1)"
" Filter: ((A IS NULL) AND ((B)::text = '21'::text))"
"Total runtime: 85896.214 ms"

As you can see the estimated cost was 3.68: a long way from the true value.

Doing 'set enable_seqscan=false' and repeating the select:
"Limit (cost=0.00..5.58 rows=15 width=128) (actual time=4426.438..4426.834 rows=15 loops=1)"
" -> Index Scan using idx_A on my_table this_ (cost=0.00..392956.76 rows=1055970 width=128) (actual time=4426.433..4426.768 rows=15 loops=1)"
" Index Cond: (A IS NULL)"
" Filter: ((B)::text = '21'::text)"
"Total runtime: 4426.910 ms"

Probably some caching made this query faster, but it's still too slow, and using the wrong index.

Deleting index A gives:
"Limit (cost=0.00..56.47 rows=15 width=128) (actual time=10.298..10.668 rows=15 loops=1)"
" -> Index Scan using idx_B on my_table this_ (cost=0.00..3982709.15 rows=1057960 width=128) (actual time=10.293..10.618 rows=15 loops=1)"
" Index Cond: ((B)::text = '21'::text)"
" Filter: (A IS NULL)"
"Total runtime: 10.735 ms"
Much better. However I need index A for another query so I can't just delete it.

Looking at the estimated cost, you can see why it's choosing the order that it is choosing, but it just doesn't seem to reflect reality at all.

Now here's the result of the query, with both indexes in place and sequential scan enabled
Select * from my_table where A is null and B = '21'
"Bitmap Heap Scan on my_table this_ (cost=20412.89..199754.37 rows=1060529 width=128) (actual time=470.772..7432.062 rows=1020062 loops=1)"
" Recheck Cond: ((B)::text = '21'::text)"
" Filter: (A IS NULL)"
" -> Bitmap Index Scan on idx_B (cost=0.00..20147.76 rows=1089958 width=0) (actual time=466.545..466.545 rows=1020084 loops=1)"
" Index Cond: ((B)::text = '21'::text)"
"Total runtime: 8940.119 ms"

In this case it goes for the correct index. It appears that the query planner makes very simplistic assumptions when it comes to LIMIT?

Thanks
David

-----Original Message-----
From: Pavel Stehule [mailto:pavel.stehule@gmail.com]
Sent: 01 September 2008 13:53
To: David West
Cc: pgsql-performance@postgresql.org
Subject: Re: [PERFORM] limit clause breaks query planner?

Hello

you should partial index

create index foo(b) on mytable where a is null;

regards
Pavel Stehule

2008/9/1 David West <david.west@cusppoint.com>:
> Hi,
>
>
>
> I have a single table with about 10 million rows, and two indexes. Index A
> is on a column A with 95% null values. Index B is on a column B with about
> 10 values, ie. About a million rows of each value.
>
>
>
> When I do a simple query on the table (no joins) with the following
> condition:
>
> A is null AND
>
> B = '21'
>
>
>
> it uses the correct index, index B. However, when I add a limit clause of
> 15, postgres decides to do a sequential scan :s. Looking at the results
> from explain:
>
>
>
> "Limit (cost=0.00..3.69 rows=15 width=128)"
>
> " -> Seq Scan on my_table this_ (cost=0.00..252424.24 rows=1025157
> width=128)"
>
> " Filter: ((A IS NULL) AND ((B)::text = '21'::text))"
>
>
>
> It appears that postgres is (very incorrectly) assuming that it will only
> have to retrieve 15 rows on a sequential scan, and gives a total cost of
> 3.69. In reality, it has to scan many rows forward until it finds the
> correct value, yielding very poor performance for my table.
>
>
>
> If I disable sequential scan (set enable_seqscan=false) it then incorrectly
> uses the index A that has 95% null values: it seems to incorrectly apply the
> same logic again that it will only have to retrieve 15 rows with the limit
> clause, and thinks that the index scan using A is faster than index scan B.
>
>
>
> Only by deleting the index on A and disabling sequential scan will it use
> the correct index, which is of course by far the fastest.
>
>
>
> Is there an assumption in the planner that a limit of 15 will mean that
> postgres will only have to read 15 rows? If so is this a bad assumption?
> If a particular query is faster without a limit, then surely it will also be
> faster with the limit.
>
>
>
> Any workarounds for this?
>
>
>
> Thanks
>
> David


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

Re: [GENERAL] Oracle and Postgresql

David Fetter, 01.09.2008 16:08:
>> because we are making extensive usage of Oracle's windowing
>> functions
>
> http://umitanuki.net/pgsql/wfv04/design.html

I knew there was work going on regarding this, but I didn't know how definite the decision was to integrate that into 8.4

It's too bad lead(), lag() won't make it

> It's even more fun with CTEs.
> <http://wiki.postgresql.org/wiki/CTEReadme>

Recursive CTE are quite cool, and a valid "replacement" for CONNECT BY.
I've used it already with SQL Server 2005 and once you get the idea it's really nice.

> Those will both be fixed, at least to a large degree, in 8.4 :)

What exactly means "large degree" :)


Regards
Thomas


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

Re: [pgsql-es-ayuda] Linea de Comandos Postgres

Mauricio Lopez escribió:
> Hola...
>
> Alguien me puede decir de donde se puede descargar la libreria libreadline,
> para poder usar el autocompletar en la linea de comandos de postgres...
>
> Uso Linux Mandriva

urpmi readline5-devel

(o algo por el estilo ... la version seguramente es distinta, y el
nombre exacto del paquete. Pero lo importante es que tienes que usar la
herramienta de paquetes de la distribucion)

--
Alvaro Herrera http://www.amazon.com/gp/registry/CTMLCN8V17R4
"A wizard is never late, Frodo Baggins, nor is he early.
He arrives precisely when he means to." (Gandalf, en LoTR FoTR)
--
TIP 10: no uses HTML en tu pregunta, seguro que quien responda no podrá leerlo

Re: [PERFORM] too many clog files

Duan Ligong wrote:
> Hi, there.
>
> I have encountered an issue that there are too many
> clog file under the .../pg_clog/ directory. Some of them
> were even produced one month ago.

If you're going to repost a question, it is only polite that you link to
the answers already provided. Particularly so when some of your
questions were already answered.

--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

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

[pgsql-es-ayuda] Linea de Comandos Postgres

Hola...

Alguien me puede decir de donde se puede descargar la libreria libreadline, para poder usar el autocompletar en la linea de comandos de postgres...

Uso Linux Mandriva

Gracias

 Mauricio López Benítez

[GENERAL] refcursor

 
Hello all,
I've got a problem I can't get round. I want to declare a refcursor variable in a  C program and call a function which returns a refcursor portal to the main C program.
When I compile the C program, I get a refcursor doesn´t exist message. Has anyone got a  C program which uses a refcursor variable?
Hope you can help.
 
Cheers
Mike Stanton, Santiago Chile
 
 
 
 
Michael Stanton W.
Depto. Informática

Re: [SQL] MAY I HAVE YOUR ASSISTANCE

>> I have one problem with the user table. I want to hide the password for the users.

Here's what I did, which requires using the contrib/pgcrypto extension:

CREATE FUNCTION encryptpw() RETURNS TRIGGER AS
$encryptpw$
BEGIN
NEW.password = CRYPT(NEW.password, GEN_SALT('md5'));
RETURN NEW;
END;
$encryptpw$

CREATE TRIGGER trg_encryptpw BEFORE INSERT OR UPDATE ON assignees
FOR EACH ROW EXECUTE PROCEDURE encryptpw();

Comments, suggestions, criticisms?

-- Gary Chambers

/* Nothing fancy and nothing Microsoft! */

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

Re: [GENERAL] Oracle and Postgresql

On Mon, Sep 01, 2008 at 10:31:25AM +0200, Thomas Kellerer wrote:
> Scott Marlowe, 31.08.2008 22:44:
>> I think some of it is inertia. We've always used Oracle, let's
>> just keep on using it. The more conservative the IT department is,
>> the less likely they are to take chances with new technology.
>>
>> It used to be there was about an 80/20 split between what things
>> you could do with either postgresql or oracle, and the other 20%
>> was oracle only land. I think that number is dropping quickly, and
>> we're into the 1 or 2% club of what Oracle can do that PostgreSQL
>> isn't fast enough for.
>
> For me (personally) the ratio is more like 70/30,

It's about to increase :)

> because we are making extensive usage of Oracle's windowing
> functions

http://umitanuki.net/pgsql/wfv04/design.html

> (and ability to easily deal with hierarchical data using CONNECT BY).

It's even more fun with CTEs.
<http://wiki.postgresql.org/wiki/CTEReadme>

> The lack of windowing functions is a bit frustrating as I'm
> otherwise a big Postgres fan!

Those will both be fixed, at least to a large degree, in 8.4 :)

Cheers,
David.
--
David Fetter <david@fetter.org> http://fetter.org/
Phone: +1 415 235 3778 AIM: dfetter666 Yahoo!: dfetter
Skype: davidfetter XMPP: david.fetter@gmail.com

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate

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

Re: [SQL] MAY I HAVE YOUR ASSISTANCE

On Mon, 1 Sep 2008 07:03:51 +0000 (GMT)
James Kitambara <jameskitambara@yahoo.co.uk> wrote:
>  
> Please members of the PGSQL-SQL,
>  
> I have one problem with the user table. I want to hide the password for the users.

Look in the contrib directory for the chkpass type. It uses DES
encryption but if you need MD5 or Blowfish it wouldn't be very hard to
modify the code.

--
D'Arcy J.M. Cain <darcy@druid.net> | Democracy is three wolves
http://www.druid.net/darcy/ | and a sheep voting on
+1 416 425 1212 (DoD#0082) (eNTP) | what's for dinner.

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

Re: [pgsql-es-ayuda] traduccion documentacion

Calabaza escribió:

> Bueno, les cuento lo que hice, empecé a investigar sobre docbook
> (porque no tengo ni la más pálida idea de que es), me baje algunos
> tutoriales, agregue unos tantos links a los marcadores, y luego me
> baje el código fuente de postgres del 8.3.3, para revisar en que
> formato esta la documentación, que esta en sgml, hasta ahí todo bien,
> ahora la pregunta es en que versión de docbook esta?

Uff ... y vamos reinventando la rueda *otra vez*.

Les cuento que ya tenemos una plataforma para pasar de docbook a POT, y
una aplicacion web para apoyar la traduccion de POTs. Incluso tenemos
bastante gente que aportó a esa traducción. El conjunto está en un
proyecto en pgfoundry.org/projects/webtranslator (la instalación que
estaba funcionando antes ya no está al aire, pero confío en que Mario
tenga un respaldo de la base de datos por ahí)

Lo que nos hace falta es alguien que se haga cargo de administrar y
mantener eso funcionando.

--
Alvaro Herrera http://www.PlanetPostgreSQL.org/
"It takes less than 2 seconds to get to 78% complete; that's a good sign.
A few seconds later it's at 90%, but it seems to have stuck there. Did
somebody make percentages logarithmic while I wasn't looking?"
http://smylers.hates-software.com/2005/09/08/1995c749.html
--
TIP 5: ¿Has leído nuestro extenso FAQ?
http://www.postgresql.org/docs/faqs.FAQ.html

Re: [pgsql-es-ayuda] Consulta sobre rules

>
>
>Hola todos!
>Mi consulta es conceptual, para que usan las rules en postgresql, puedo
>implementar triggers con rules; cuál es la diferencia entra ambos?
>
>Gracias por su ayuda
>

Los triggers se ejecutan una acción antes o despues de una operación con la
DB. Las reglas MODIFICAN el plan de ejecucción original para incluir la
regla que definiste. Por ejemplo si realizas un update que va a modificar
1000 registros, el trigger se ejecuta por cada uno de esos 1000 registros.
En cambio la regla se va a ejecutar una única vez (con un plan modificado).

Atentamente,

RAUL DUQUE
Bogotá, Colombia

>ANA
>
>--
>TIP 2: puedes desuscribirte de todas las listas simultáneamente
> (envía "unregister TuDirecciónDeCorreo" a majordomo@postgresql.org)

--
TIP 9: visita nuestro canal de IRC #postgresql-es en irc.freenode.net

Re: [BUGS] Bug in RETURN QUERY

Hello

2008/9/1 Oleg Serov <serovov@gmail.com>:
> Hello all SQL BUG CODE:
> BEGIN;
> SELECT version(); -- "PostgreSQL 8.3.3 on i686-redhat-linux-gnu, compiled by
> GCC gcc (GCC) 4.1.2 20070626 (Red Hat 4.1.2-14)"
> CREATE TYPE "buggy_enum_first" AS ENUM ( 'bug1', 'bug2', 'bug3' );
>
> CREATE TABLE "bug_table" (
> "id" BIGINT NOT NULL,
> "buggy_enum_field" "buggy_enum_first" DEFAULT 'bug1'::buggy_enum_first NOT
> NULL,
> CONSTRAINT "test_table_pkey" PRIMARY KEY("id")
> ) WITHOUT OIDS;
>
>
> CREATE FUNCTION buggy_procedure() RETURNS SETOF bug_table
> AS $$
> BEGIN
> -- @todo hide password
> RETURN QUERY (
> SELECT *
> FROM bug_table
> );
> END;
> $$
> LANGUAGE plpgsql STRICT SECURITY DEFINER;
>
> SELECT * FROM buggy_procedure(); -- All Okey
> DROP TYPE buggy_enum_first CASCADE;
> CREATE TYPE "buggy_enum_second" AS ENUM ( 'bug1', 'bug2', 'bug3' );
> ALTER TABLE bug_table ADD COLUMN buggy_enum_field buggy_enum_second;
> SELECT * FROM buggy_procedure(); -- Bug
> ROLLBACK;
> /*NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index
> "test_table_pkey" for table "bug_table"
>
> NOTICE: drop cascades to default for table bug_table column
> buggy_enum_fieldNOTICE: drop cascades to table bug_table column
> buggy_enum_field
> ERROR: structure of query does not match function result type
> CONTEXT: PL/pgSQL function "buggy_procedure" line 3 at RETURN QUERY*/

this isn't bug, it's feature. Informations stored in execution plan
are broken, when some references to removed objects are stored in plan
- objects aren't stored by name, but by object id. So, when you drop
any object, then you have to finish session. Note: actually only drop
of table emits plan cache invalidation signal.

Regards
Pavel Stehule

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

Re: [NOVICE] Max OID

See below.
I'm at a loss here.
I've checked the lo_import / lo_export and I think that I am doing all this correctly.

The original import uses the server side lo_import in an sql statement. The large object appears to have been created ok and the oid value inserted into the document field below. All good so far. The users could then get the large object out - this used a call to psql and a \lo_export to get that OID referred to by the document field. This has been working fine for 2-3 years.
On saturday the live server crashed and was replaced with the backup server. The live data was pg_dump'd (from an 8.0.3 database) prior to the crash and pg_restored (into 8.0.8) onto the backup server. Again all seemed well - no errors reported into the restore and the data looked good. BUT the document field now contains values of >2billion. Is it possible that the dump or the restore 'altered' not only the document field, but also the actual OID of the large object? The data all looks good, in as much as say the document field points to large object 3123456789 and large object oid 3123456789 is correct (ie it does tie up to that record). The problem being is that the program that handles the exporting of the object has never handled OID's bigger than 2billion - so the document field and its related large object would have to hve been <=2billion prior to the dump/restore. Does that make sense and is that feasible?

I have also restored the data into an 8.1.10 database and I see the same results, ie the document field contains values only >3billion - but they do seem to correctly correlate to the large objects as retrieved by \lo_export.

On Mon, 2008-09-01 at 11:01 +0100, Steve T wrote:
I have a table that is used to control documents:
recno                | integer                | not null default nextval('document_recno_seq'::regclass)
foreigntablename     | character varying(255) | not null
foreignrecno         | integer                | not null
docforeigntablename  | character varying(255) | not null
docforeignrecno      | integer                | not null
docforeigntext       | character varying(255) | not null
documenttyperecno    | integer                | not null
version              | character varying(20)  | not null
loadeddate           | date                   | not null
loadedtime           | time without time zone | not null
usersrecno           | integer                | not null
title                | character varying(40)  | not null
description          | character varying(255) |
doculookupcodesrecno | integer                | not null
document             | oid                    | not null
suffix               | character varying(255) |

Each document is loaded using the large object commands and the OID of the load then inserted as a ref number on the document table.
This has been working fine, but I had a major crash on the server and it had to be rebuilt.
The database had been exported  (pg_dump) - so I reimported (pg_restore) the database.
If I now look at the oid (ie document.document) of the blob on the numbers are in the range:
3159553408
3159553409
3159553410
3159553411
3159553412
3159553413
3159553414
3159553415
these numbers are above the field I use for the OID in the code (ie an Integer - catering for 2 billion) - so the program no longer finds the document to export.
Any ideas as to why did these OID's become so large after reimporting (I am assuming here that they must have been under 2 billion before or else the process could not have worked before)? And what limit is ther then on this OID?

[PHP] pg_query_params and SQL injection

Hi all
I am just doing some playing around with PHP to learn how to avoid SQL injection attacks.
It has been mentioned in a few places that pg_query_params is supposed to protect from sql injection without needing to mess around escaping quotes and things.

However, I was still able to get it to drop a table by feeding in this input "1; drop table results" to the following statement:
$r = pg_query_params($p, 'select * from results where res_id = $1', array($input));

Everyone keeps repeating the same "pg_query_params is safe from SQL injection", but surely someone else must have actually tried it? Where am I going wrong?

I am using Postgresql 8.3 for OS X on 10.5.2, and MAMP which has PHP Version 5.2.5.

Thanks
Kevin


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

Re: [HACKERS] Extending grant insert on tables to sequences

* Jaime Casanova (jcasanov@systemguards.com.ec) wrote:
> On Fri, Aug 22, 2008 at 10:19 PM, Bruce Momjian <bruce@momjian.us> wrote:
> >
> > Added to September commit fest.
> >
>
> updating the patch with one that only extends inserts. though, i
> haven't look at the col level privs patch yet.

At least initially I wasn't planning to support column-level privileges
for sequences, so I don't think it will affect you much. Do people
think it makes sense to try and support that?

As your patch appears more ready-for-commit than the column-level
privileges patch, I wouldn't worry about what code might have to move
around, that'll be for me to deal with in a re-sync with HEAD once your
patch is committed.

Thanks,

Stephen

Re: [GENERAL] ERROR: relation . . . does not exist

Albretch Mueller wrote:
>> PostgreSQL has 60+ types and many look like eachother. How do you propose to differentiate?
> ~
> Data Types are basically about value ranges (how many bits do you
> need to hold the value) and formatting.

That is exactly wrong, at least in the PostgreSQL approach to the type
system. Data types are about functions and operators associated with
them. So it is not about what the data looks like, but what kind of
processing you want to do with it. Guessing that information from a
dump of data seems pretty much impossible.


--
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] determining existence of database and language

Chris Sano wrote:
> I'm trying to build a SQL script that will create a database if it
> doesn't already exist. I've looked everywhere and haven't been able to
> find anything. Am I missing something? Thanks.

SELECT * FROM pg_database will tell you what databases exist.


--
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] SQL optimization - WHERE SomeField STARTING WITH ...

Bill wrote:
> The SQL database servers I have worked with cannot use and index for a
> SELECT of the form
>
> SELECT * FROM ATABLE
> WHERE AFIELD LIKE ?
>
> because there is no way to know the location of the wild card until the
> parameter value is known. InterBase and Firebird allow
>
> SELECT * FROM ATABLE
> WHERE AFIELD STARTING WITH ?
>
> which is equivalent to LIKE 'ABC%' and will use an index on AFIELD. Is
> there a similar syntax in PostgreSQL?

One workaround might be to rewrite the query using some string function
(substring, position, or write your own) and index over that function.


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

Re: [HACKERS] [PATCH] Cleanup of GUC units code

diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 4ca25dc..b10be22 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -4182,7 +4182,7 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg)
#error XLOG_BLCKSZ must be between 1KB and 1MB
#endif

- if (strncmp(endptr, "kB", 2) == 0)
+ if (pg_strncasecmp(endptr, "kB", 2) == 0)
{
endptr += 2;
switch (flags & GUC_UNIT_MEMORY)
@@ -4195,7 +4195,7 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg)
break;
}
}
- else if (strncmp(endptr, "MB", 2) == 0)
+ else if (pg_strncasecmp(endptr, "MB", 2) == 0)
{
endptr += 2;
switch (flags & GUC_UNIT_MEMORY)
@@ -4211,7 +4211,7 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg)
break;
}
}
- else if (strncmp(endptr, "GB", 2) == 0)
+ else if (pg_strncasecmp(endptr, "GB", 2) == 0)
{
endptr += 2;
switch (flags & GUC_UNIT_MEMORY)
@@ -4234,7 +4234,7 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg)
if (hintmsg)
*hintmsg = gettext_noop("Valid units for this parameter are \"ms\", \"s\", \"min\", \"h\", and \"d\".");

- if (strncmp(endptr, "ms", 2) == 0)
+ if (pg_strncasecmp(endptr, "ms", 2) == 0)
{
endptr += 2;
switch (flags & GUC_UNIT_TIME)
@@ -4247,7 +4247,7 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg)
break;
}
}
- else if (strncmp(endptr, "s", 1) == 0)
+ else if (pg_strncasecmp(endptr, "s", 1) == 0)
{
endptr += 1;
switch (flags & GUC_UNIT_TIME)
@@ -4260,7 +4260,7 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg)
break;
}
}
- else if (strncmp(endptr, "min", 3) == 0)
+ else if (pg_strncasecmp(endptr, "min", 3) == 0)
{
endptr += 3;
switch (flags & GUC_UNIT_TIME)
@@ -4273,7 +4273,7 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg)
break;
}
}
- else if (strncmp(endptr, "h", 1) == 0)
+ else if (pg_strncasecmp(endptr, "h", 1) == 0)
{
endptr += 1;
switch (flags & GUC_UNIT_TIME)
@@ -4289,7 +4289,7 @@ parse_int(const char *value, int *result, int flags, const char **hintmsg)
break;
}
}
- else if (strncmp(endptr, "d", 1) == 0)
+ else if (pg_strncasecmp(endptr, "d", 1) == 0)
{
endptr += 1;
switch (flags & GUC_UNIT_TIME)
On 9/1/08, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Marko Kreen <markokr@gmail.com> writes:
> > - In attempt to preserve maximum range of values for INT64_IS_BUSTED
> > systems, the code is written rather non-obvious way.
>
> I do not personally object a bit to making the units comparisons
> case-insensitive (I think it's mainly Peter who wants to be strict
> about it). I don't think there are any other good ideas in this
> patch, however, and exposing ourselves to intermediate overflows in
> the name of simplicity is definitely not one.

For all practical purposes, the overflow is insignificant when int64
works. I'll look if I can avoid it on INT64_IS_BUSTED case.

In the meantime, here is simple patch for case-insensivity.

--
marko

Re: [GENERAL] indexes on functions and create or replace function

Matthew Dennis wrote:
> Given table T(c1 int) and function F(arg int) create an index on T using
> F(c1). It appears that if you execute "create or replace function F"
> and provide a different implementation that the index still contains the
> results from the original implementation, thus if you execute something
> like "select * from T where F(c1)" after replacing the function that it
> now misses rows that should be returned. In other words, the index
> isn't aware the function is now returning different values. That's not
> the correct/expected behavior is it? I would have expected that
> replacing the function would have caused any indexes that depend on that
> function to be reindexed/recreated with the new function implementation.

I have added a Todo item about this. But as you see, the problem is
quite large and involved.

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

Re: [HACKERS] [PATCH] Make gram.y use palloc/pfree for memory management

First a correction, overriding malloc/free seems dangerous they
seems to leak out, so correct would be to use YYMALLOC/YYFREE.
This leaves 1.875 potentially leaking, but danger seems small.

On 9/1/08, Tom Lane <tgl@sss.pgh.pa.us> wrote:
> Marko Kreen <markokr@gmail.com> writes:
> > This means gram.y can leak memory if error is throws in
> > the middle of parsing.
>
> Please offer some evidence for that claim.

The leak occurs when
1. bison does allocation.
2. error is thrown.

Now, normally bison does not do allocation as it has initially 200-item
stack allocated in stack. When this is full it does allocate.

But I'm not familial enough with bison internals and Postgres parser
structure, on how cause the stack fill up. It may be that Postgres
parser avoids recursive stack allocations, thus in practice the
leak cannot occur.

--
marko

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

[pgsql-es-ayuda] Consulta sobre rules

Hola todos!
Mi consulta es conceptual, para que usan las rules en postgresql, puedo
implementar triggers con rules; cuál es la diferencia entra ambos?

Gracias por su ayuda

ANA

--
TIP 2: puedes desuscribirte de todas las listas simultáneamente
(envía "unregister TuDirecciónDeCorreo" a majordomo@postgresql.org)

Re: [BUGS] libpq does not manage SSL callbacks properly when other libraries are involved.

Russell Smith wrote:
> Alvaro Herrera wrote:
> > PoolSnoopy wrote:
> >
> >> this bug is really some annoyance if you use automatic build environments.
> >> I'm using phpunit to run tests and as soon as postgres is involved the php
> >> cli environment segfaults at the end. this can be worked around by disabling
> >> ssl but it would be great if the underlying bug got fixed.
> >>
> >
> > This is PHP's bug, isn't it? Why are you complaining here
> No, this is a problem with the callback/exit functions used by
> PostgreSQL. We setup callback functions when we use SSL, if somebody
> else uses SSL we can create a problem.

Ok, so it seems you're correct; there is more evidence to be found by
searching other projects' mailing lists, for example as a starting point
http://markmail.org/search/?q=+CRYPTO_set_locking_callback%28NULL%29

--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

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

Re: [PERFORM] Best hardware/cost tradoff?

> -----Mensaje original-----
> De: pgsql-performance-owner@postgresql.org
> [mailto:pgsql-performance-owner@postgresql.org] En nombre de cluster
> Enviado el: Sábado, 30 de Agosto de 2008 07:21
> Para: pgsql-performance@postgresql.org
> Asunto: Re: [PERFORM] Best hardware/cost tradoff?
>
> We are now leaning towards just buying 4 SAS disks.
>
> So should I just make one large RAID-10 partition or make two
> RAID-1's having the log on one RAID and everything else on
> the second RAID?
> How can I get the best read/write performance out of these four disks?
> (Remember, that it is a combined web-/database server).
>

Make a single RAID 10. It´s simpler and it will provide you better write
performance which is where your bottleneck will be. I think you should
minimize the web server role in this equation as it should mostly work on
cached data.


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

[BUGS] Bug in RETURN QUERY

Hello all SQL BUG CODE:
BEGIN;
SELECT version(); -- "PostgreSQL 8.3.3 on i686-redhat-linux-gnu, compiled by GCC gcc (GCC) 4.1.2 20070626 (Red Hat 4.1.2-14)"
CREATE TYPE "buggy_enum_first" AS ENUM ( 'bug1', 'bug2', 'bug3' );

CREATE TABLE "bug_table" (
  "id" BIGINT NOT NULL,
  "buggy_enum_field" "buggy_enum_first" DEFAULT 'bug1'::buggy_enum_first NOT NULL,
  CONSTRAINT "test_table_pkey" PRIMARY KEY("id")
) WITHOUT OIDS;


CREATE FUNCTION buggy_procedure() RETURNS SETOF bug_table
    AS $$
BEGIN
    -- @todo hide password
    RETURN QUERY (
        SELECT *
        FROM bug_table
    );
END;
$$
    LANGUAGE plpgsql STRICT SECURITY DEFINER;

SELECT * FROM buggy_procedure(); -- All Okey
DROP TYPE buggy_enum_first CASCADE;
CREATE TYPE "buggy_enum_second" AS ENUM ( 'bug1', 'bug2', 'bug3' );
ALTER TABLE bug_table ADD COLUMN buggy_enum_field buggy_enum_second;
SELECT * FROM buggy_procedure(); -- Bug
ROLLBACK;
/*NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "test_table_pkey" for table "bug_table"

NOTICE:  drop cascades to default for table bug_table column buggy_enum_fieldNOTICE:  drop cascades to table bug_table column buggy_enum_field
ERROR:  structure of query does not match function result type
CONTEXT:  PL/pgSQL function "buggy_procedure" line 3 at RETURN QUERY*/

Re: [HACKERS] Is this really really as designed or defined in some standard

On Mon, 2008-09-01 at 11:15 +0200, Pavel Stehule wrote:
> 2008/9/1 Magnus Hagander <magnus@hagander.net>:
> > Pavel Stehule wrote:
> >> Hello
> >>
> >> 2008/8/31 Hannu Krosing <hannu@2ndquadrant.com>:

> >>>
> >>> hannu=# create or replace function ffa(a int, a int) returns int
> >>> language plpgsql as $$begin return a + a; end;$$;
> >>> CREATE FUNCTION
> >>> hannu=# select ffa(1,2);
> >>> ffa
> >>> -----
> >>> 2
> >>> (1 row)
> >>>
> >>> Is this defined by some standard or just an oversight ?
> >>>
> >>
> >> what is problem? You have two diferent functions. I don't see anything wrong.
> >
> > Take a look at the second function again. It's certainly not behaviour
> > that I would expect :-) (I would expect a syntax error)
>
> I see it now - it's really bug

There are a few places, where repeating labels are allowed, for example
select can produce such record

hannu=# select 1 as a, 2 as a;
a | a
---+---
1 | 2
(1 row)

But it is not allowed in TYPE or table definitions

hannu=# create type aa as (a int, a int);
ERROR: column "a" specified more than once

hannu=# create table aa (a int, a int);
ERROR: column "a" specified more than once

It probably is also not allowed in function/procedure argument list, but
I was not sure that any standard would not require it.

So, should this be fixed at calling / SQL side (by not allowing
repeating argument names) or at pl side for each pl separately ?

--------------
Hannu

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

Re: [pgsql-es-ayuda] traduccion documentacion

> Bueno, les cuento lo que hice, empecé a investigar sobre docbook
> (porque no tengo ni la más pálida idea de que es), me baje algunos
> tutoriales, agregue unos tantos links a los marcadores, y luego me
> baje el código fuente de postgres del 8.3.3, para revisar en que
> formato esta la documentación, que esta en sgml, hasta ahí todo bien,
> ahora la pregunta es en que versión de docbook esta?
> urgando por el archivo: reference.ced
> en una parte dice:
> (sgml-saved-dtd-version 7)
> ("/usr/share/sgml/docbook/sgml-dtd-3.1/dbgenent.mod"
>
> Según las especificaciones de docbook.org[2] va por la version 5 así
> que no entiendo porque el dtd es version 7, pero bueno, luego veo que
> abajo dice smgl-dtd-3.1 o sea version del dtd 3.1 y en qué quedamos?
> [2] http://www.docbook.org/specs/
>
> Realmente puedo empezar a pelearme con los archivos sgml pero creo que
> alguno que haya trabajado con estos documentos puede tener alguna
> herramienta que haga más fácil la vida?
>
> Y luego también esta el problema de quién hace qué...
>
> Vi algunos editores que interpretan los códigos del dtd para hacerlo
> más visual, de todos modos creo que casi ninguna etiqueta voy a
> modificar, pero bueno, alguien me da alguna iluminación sobre que
> herramienta utilizar para editar los sgml?
>
> Mi SO es un WinXP, posiblemente lo haga con pspad y su soporte de xml,
> pero preferiría algo más visual, ah! he visto que se puede hacer
> también con openoffice, mientras tanto seguiré investigando.
>

Hasta donde he leido no hay una herramienta WYSWYG para docbook. Pensaba que
se seguía utilizando Latex para documentación técnica :-(

Encontré este link que habla de cómo utilizar docbook sobre windows, pero
parece que para la edición lo máximo que vas a tener es un buen editor XML.

http://www.codeproject.com/KB/winhelp/docbook_howto.aspx

Atetamente,

RAUL DUQUE
Bogotá, Colombia


> Al que le interese aquí hay tutoriales para mirar:
> http://wiki.docbook.org/topic/DocBookTutorials#head-b6bf09ce90154dbda12d6c4e7a2d856c461baafa
>
> Hasta mañana amigos, revisaré el correo por la noche, así que no se
> molesten conmigo si no contesto rápido, :)
>
> Un abrazo.
> --
> §~^Calabaza^~§ from Villa Elisa, Paraguay
> --
> TIP 3: Si encontraste la respuesta a tu problema, publícala, otros te lo
> agradecerán
>
> __________ Information from ESET Smart Security, version of virus
> signature database 3401 (20080829) __________
>
> The message was checked by ESET Smart Security.
>
> http://www.eset.com
>
>
--
TIP 3: Si encontraste la respuesta a tu problema, publícala, otros te lo agradecerán

Sunday, August 31, 2008

[HACKERS] [PATCH] In case module has wrong magic, report exact problem

*** a/src/backend/utils/fmgr/dfmgr.c
--- b/src/backend/utils/fmgr/dfmgr.c
***************
*** 19,28 ****
--- 19,29 ----
#ifndef WIN32_ONLY_COMPILER
#include "dynloader.h"
#else
#include "port/dynloader/win32.h"
#endif
+ #include "lib/stringinfo.h"
#include "miscadmin.h"
#include "utils/dynamic_loader.h"
#include "utils/hsearch.h"


*************** PGFunction
*** 163,172 ****
--- 164,213 ----
lookup_external_function(void *filehandle, char *funcname)
{
return (PGFunction) pg_dlsym(filehandle, funcname);
}

+ /*
+ * Detailed error report when module incompatibility is detected.
+ */
+
+ #define MAGIC_FIELD_TEST(field) do { \
+ if (srv->field != mod->field) { \
+ if (det->len) \
+ appendStringInfo(det, ", "); \
+ appendStringInfo(det, "%s: %d != %d", #field, mod->field, srv->field); \
+ } \
+ } while (0)
+
+ static void
+ module_incompat_error(const Pg_magic_struct *mod, const Pg_magic_struct *srv, const char *libname)
+ {
+ StringInfo det;
+
+ if (mod->version != srv->version)
+ ereport(ERROR,
+ (errmsg("incompatible library \"%s\": version mismatch",
+ libname),
+ errdetail("Server is version %d.%d, library is version %d.%d.",
+ srv->version / 100,
+ srv->version % 100,
+ mod->version / 100,
+ mod->version % 100)));
+
+ det = makeStringInfo();
+
+ MAGIC_FIELD_TEST(funcmaxargs);
+ MAGIC_FIELD_TEST(indexmaxkeys);
+ MAGIC_FIELD_TEST(namedatalen);
+ MAGIC_FIELD_TEST(float4byval);
+ MAGIC_FIELD_TEST(float8byval);
+
+ ereport(ERROR,
+ (errmsg("incompatible library \"%s\": magic block mismatch: %s",
+ libname, det->data)));
+ }
+ #undef MAGIC_FIELD_TEST

/*
* Load the specified dynamic-link library file, unless it already is
* loaded. Return the pg_dl* handle for the file.
*
*************** internal_load_library(const char *libnam
*** 255,281 ****

/* try to unlink library */
pg_dlclose(file_scanner->handle);
free((char *) file_scanner);

! /*
! * Report suitable error. It's probably not worth writing a
! * separate error message for each field; only the most common
! * case of wrong major version gets its own message.
! */
! if (module_magic_data.version != magic_data.version)
! ereport(ERROR,
! (errmsg("incompatible library \"%s\": version mismatch",
! libname),
! errdetail("Server is version %d.%d, library is version %d.%d.",
! magic_data.version / 100,
! magic_data.version % 100,
! module_magic_data.version / 100,
! module_magic_data.version % 100)));
! ereport(ERROR,
! (errmsg("incompatible library \"%s\": magic block mismatch",
! libname)));
}
}
else
{
/* try to unlink library */
--- 296,306 ----

/* try to unlink library */
pg_dlclose(file_scanner->handle);
free((char *) file_scanner);

! module_incompat_error(&module_magic_data, &magic_data, libname);
}
}
else
{
/* try to unlink library */
In case module and server magic blocks do not match
report exact parameters that differ.

It is quite cumbersome problem to track down unless
user already knows the cause.

As we want to encourage module use, such situations
can happen more often.

Re: [HACKERS] WIP patch: Collation support

Radek Strnad escribió:

> - when creating database with different collation than database cluster, the
> database has to be reindexed. Any idea how to do it? Function
> ReindexDatabase works only when database is opened.

We have this Todo item:

Set proper permissions on non-system schemas during db creation
Currently all schemas are owned by the super-user because they are
copied from the template1 database. However, since all objects are
inherited from the template database, it is not clear that setting
schemas to the db owner is correct.

When this was discussed years ago, one proposed idea was that on the
first connection the backend should, as a first task, ensure that
certain administrative chores be done. The first of those was changing
the ownership of schemas. It sounds like this reindexing you propose
falls into the same category.

--
Alvaro Herrera http://www.CommandPrompt.com/
PostgreSQL Replication, Consulting, Custom Development, 24x7 support

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

[HACKERS] Is this really really as designed or defined in some standard

It seems that we allow several function arguments to have same
name (or is it label :)

hannu=# create or replace function ff(a int, a int) returns int language
plpgsql as $$begin return $1+$2; end;$$;
CREATE FUNCTION
hannu=# select ff(1,1);
ff
----
2
(1 row)

hannu=# select ff(1,2);
ff
----
3
(1 row)

hannu=# create or replace function ffa(a int, a int) returns int
language plpgsql as $$begin return a + a; end;$$;
CREATE FUNCTION
hannu=# select ffa(1,2);
ffa
-----
2
(1 row)

Is this defined by some standard or just an oversight ?

----------------------
Hannu

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

[HACKERS] Prototype: In-place upgrade

Attached patch is prototype of in-place upgrade as was presented on PGCon this year.

Main idea is to learn postgres to handle different version of page and tuple
structures.

1) page - Patch contains new page API and all code access page through this API.
Functions check page version and return correct data to caller. It is mostly
complete now. Only ItemId flags need finish.

2) tuple - HeapTuple structure has been extended with t_ver attribute which
contains page layout version and direct access to HeapTupleHeader is forbidden.
It is possible now only through HeapTuple* functions (see htup.c).
(HeapTupleHeader access still stays in a several functions like heap_form_tuple).

This patch version still does not allow to read old database, but it shows how
it should work. Main disadvantage of this approach is performance penalty.

Please, let me know your opinion about this approach.

Future work:
1) learn WAL to process different tuple structure version
2) tuple conversion to new version and put it into executor (ExecStoreTuple)
3) multiversion MaxItemSize constant

thanks for your comments Zdenek


--
Zdenek Kotala Sun Microsystems
Prague, Czech Republic http://sun.com/postgresql

[HACKERS] WIP patch: Collation support

Index: backend/parser/keywords.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/keywords.c,v
retrieving revision 1.199
diff -c -r1.199 keywords.c
*** backend/parser/keywords.c 16 Jul 2008 01:30:22 -0000 1.199
--- backend/parser/keywords.c 31 Aug 2008 19:21:08 -0000
***************
*** 45,50 ****
--- 45,51 ----
/* name, value, category */
{"abort", ABORT_P, UNRESERVED_KEYWORD},
{"absolute", ABSOLUTE_P, UNRESERVED_KEYWORD},
+ {"accent", ACCENT, UNRESERVED_KEYWORD},
{"access", ACCESS, UNRESERVED_KEYWORD},
{"action", ACTION, UNRESERVED_KEYWORD},
{"add", ADD_P, UNRESERVED_KEYWORD},
***************
*** 94,99 ****
--- 95,101 ----
{"cluster", CLUSTER, UNRESERVED_KEYWORD},
{"coalesce", COALESCE, COL_NAME_KEYWORD},
{"collate", COLLATE, RESERVED_KEYWORD},
+ {"collation", COLLATION, UNRESERVED_KEYWORD},
{"column", COLUMN, RESERVED_KEYWORD},
{"comment", COMMENT, UNRESERVED_KEYWORD},
{"commit", COMMIT, UNRESERVED_KEYWORD},
***************
*** 220,225 ****
--- 222,229 ----
{"language", LANGUAGE, UNRESERVED_KEYWORD},
{"large", LARGE_P, UNRESERVED_KEYWORD},
{"last", LAST_P, UNRESERVED_KEYWORD},
+ {"lccollate", LCCOLLATE, UNRESERVED_KEYWORD},
+ {"lcctype", LCCTYPE, UNRESERVED_KEYWORD},
{"leading", LEADING, RESERVED_KEYWORD},
{"least", LEAST, COL_NAME_KEYWORD},
{"left", LEFT, TYPE_FUNC_NAME_KEYWORD},
***************
*** 284,289 ****
--- 288,294 ----
{"overlay", OVERLAY, COL_NAME_KEYWORD},
{"owned", OWNED, UNRESERVED_KEYWORD},
{"owner", OWNER, UNRESERVED_KEYWORD},
+ {"pad", PAD, UNRESERVED_KEYWORD},
{"parser", PARSER, UNRESERVED_KEYWORD},
{"partial", PARTIAL, UNRESERVED_KEYWORD},
{"password", PASSWORD, UNRESERVED_KEYWORD},
***************
*** 331,336 ****
--- 336,342 ----
{"second", SECOND_P, UNRESERVED_KEYWORD},
{"security", SECURITY, UNRESERVED_KEYWORD},
{"select", SELECT, RESERVED_KEYWORD},
+ {"sensitive", SENSITIVE, UNRESERVED_KEYWORD},
{"sequence", SEQUENCE, UNRESERVED_KEYWORD},
{"serializable", SERIALIZABLE, UNRESERVED_KEYWORD},
{"session", SESSION, UNRESERVED_KEYWORD},
***************
*** 343,348 ****
--- 349,355 ----
{"simple", SIMPLE, UNRESERVED_KEYWORD},
{"smallint", SMALLINT, COL_NAME_KEYWORD},
{"some", SOME, RESERVED_KEYWORD},
+ {"space", SPACE, UNRESERVED_KEYWORD},
{"stable", STABLE, UNRESERVED_KEYWORD},
{"standalone", STANDALONE_P, UNRESERVED_KEYWORD},
{"start", START, UNRESERVED_KEYWORD},
***************
*** 351,356 ****
--- 358,364 ----
{"stdin", STDIN, UNRESERVED_KEYWORD},
{"stdout", STDOUT, UNRESERVED_KEYWORD},
{"storage", STORAGE, UNRESERVED_KEYWORD},
+ {"strcolfn", STRCOLFN, UNRESERVED_KEYWORD},
{"strict", STRICT_P, UNRESERVED_KEYWORD},
{"strip", STRIP_P, UNRESERVED_KEYWORD},
{"substring", SUBSTRING, COL_NAME_KEYWORD},
Index: backend/parser/gram.y
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/parser/gram.y,v
retrieving revision 2.618
diff -c -r2.618 gram.y
*** backend/parser/gram.y 18 Jul 2008 03:32:52 -0000 2.618
--- backend/parser/gram.y 31 Aug 2008 19:21:08 -0000
***************
*** 155,174 ****
}

%type <node> stmt schema_stmt
! AlterDatabaseStmt AlterDatabaseSetStmt AlterDomainStmt AlterGroupStmt
! AlterObjectSchemaStmt AlterOwnerStmt AlterSeqStmt AlterTableStmt
! AlterUserStmt AlterUserSetStmt AlterRoleStmt AlterRoleSetStmt
! AnalyzeStmt ClosePortalStmt ClusterStmt CommentStmt
! ConstraintsSetStmt CopyStmt CreateAsStmt CreateCastStmt
! CreateDomainStmt CreateGroupStmt CreateOpClassStmt
! CreateOpFamilyStmt AlterOpFamilyStmt CreatePLangStmt
CreateSchemaStmt CreateSeqStmt CreateStmt CreateTableSpaceStmt
CreateAssertStmt CreateTrigStmt CreateUserStmt CreateRoleStmt
! CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt DiscardStmt
! DropGroupStmt DropOpClassStmt DropOpFamilyStmt DropPLangStmt DropStmt
! DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt DropRoleStmt
! DropUserStmt DropdbStmt DropTableSpaceStmt ExplainStmt FetchStmt
! GrantStmt GrantRoleStmt IndexStmt InsertStmt ListenStmt LoadStmt
LockStmt NotifyStmt ExplainableStmt PreparableStmt
CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt
RemoveFuncStmt RemoveOperStmt RenameStmt RevokeStmt RevokeRoleStmt
--- 155,173 ----
}

%type <node> stmt schema_stmt
! AlterDatabaseStmt AlterDatabaseSetStmt AlterDomainStmt AlterGroupStmt
! AlterObjectSchemaStmt AlterOwnerStmt AlterSeqStmt AlterTableStmt
! AlterUserStmt AlterUserSetStmt AlterRoleStmt AlterRoleSetStmt AnalyzeStmt
! ClosePortalStmt ClusterStmt CommentStmt ConstraintsSetStmt CopyStmt
! CreateAsStmt CreateCastStmt CreateCollationStmt CreateDomainStmt
! CreateGroupStmt CreateOpClassStmt CreateOpFamilyStmt AlterOpFamilyStmt CreatePLangStmt
CreateSchemaStmt CreateSeqStmt CreateStmt CreateTableSpaceStmt
CreateAssertStmt CreateTrigStmt CreateUserStmt CreateRoleStmt
! CreatedbStmt DeclareCursorStmt DefineStmt DeleteStmt DiscardStmt
! DropCollationStmt DropGroupStmt DropOpClassStmt DropOpFamilyStmt
! DropPLangStmt DropStmt DropAssertStmt DropTrigStmt DropRuleStmt DropCastStmt
! DropRoleStmt DropUserStmt DropdbStmt DropTableSpaceStmt ExplainStmt
! FetchStmt GrantStmt GrantRoleStmt IndexStmt InsertStmt ListenStmt LoadStmt
LockStmt NotifyStmt ExplainableStmt PreparableStmt
CreateFunctionStmt AlterFunctionStmt ReindexStmt RemoveAggrStmt
RemoveFuncStmt RemoveOperStmt RenameStmt RevokeStmt RevokeRoleStmt
***************
*** 296,301 ****
--- 295,303 ----
%type <list> OptSeqOptList SeqOptList
%type <defelt> SeqOptElem

+ %type <list> OptCollationList
+ %type <defelt> OptCollationElem
+
%type <istmt> insert_rest

%type <vsetstmt> set_rest SetResetClause
***************
*** 372,378 ****
*/

/* ordinary key words in alphabetical order */
! %token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER
AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION

--- 374,380 ----
*/

/* ordinary key words in alphabetical order */
! %token <keyword> ABORT_P ABSOLUTE_P ACCENT ACCESS ACTION ADD_P ADMIN AFTER
AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION

***************
*** 381,387 ****

CACHE CALLED CASCADE CASCADED CASE CAST CHAIN CHAR_P
CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
! CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS
CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE
--- 383,389 ----

CACHE CALLED CASCADE CASCADED CASE CAST CHAIN CHAR_P
CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
! CLUSTER COALESCE COLLATE COLLATION COLUMN COMMENT COMMIT
COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS
CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE
***************
*** 401,416 ****

HANDLER HAVING HEADER_P HOLD HOUR_P

! IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P
! INCLUDING INCREMENT INDEX INDEXES INHERIT INHERITS INITIALLY
! INNER_P INOUT INPUT_P INSENSITIVE INSERT INSTEAD INT_P INTEGER
! INTERSECT INTERVAL INTO INVOKER IS ISNULL ISOLATION

JOIN

KEY

! LANCOMPILER LANGUAGE LARGE_P LAST_P LEADING LEAST LEFT LEVEL
LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION
LOCK_P LOGIN_P

--- 403,418 ----

HANDLER HAVING HEADER_P HOLD HOUR_P

! IDENTITY_P IF_P ILIKE IMMEDIATE IMMUTABLE IMPLICIT_P IN_P INCLUDING INCREMENT
! INDEX INDEXES INHERIT INHERITS INITIALLY INNER_P INOUT INPUT_P
! INSENSITIVE INSERT INSTEAD INT_P INTEGER INTERSECT
! INTERVAL INTO INVOKER IS ISNULL ISOLATION

JOIN

KEY

! LANCOMPILER LANGUAGE LARGE_P LAST_P LCCOLLATE LCCTYPE LEADING LEAST LEFT LEVEL
LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION
LOCK_P LOGIN_P

***************
*** 423,429 ****
OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR
ORDER OUT_P OUTER_P OVERLAPS OVERLAY OWNED OWNER

! PARSER PARTIAL PASSWORD PLACING PLANS POSITION
PRECISION PRESERVE PREPARE PREPARED PRIMARY
PRIOR PRIVILEGES PROCEDURAL PROCEDURE

--- 425,431 ----
OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR
ORDER OUT_P OUTER_P OVERLAPS OVERLAY OWNED OWNER

! PAD PARSER PARTIAL PASSWORD PLACING PLANS POSITION
PRECISION PRESERVE PREPARE PREPARED PRIMARY
PRIOR PRIVILEGES PROCEDURAL PROCEDURE

***************
*** 433,443 ****
REPEATABLE REPLACE REPLICA RESET RESTART RESTRICT RETURNING RETURNS REVOKE
RIGHT ROLE ROLLBACK ROW ROWS RULE

! SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE
! SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
! SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE_P START STATEMENT
! STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P SUBSTRING SUPERUSER_P
! SYMMETRIC SYSID SYSTEM_P

TABLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP
TO TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
--- 435,445 ----
REPEATABLE REPLACE REPLICA RESET RESTART RESTRICT RETURNING RETURNS REVOKE
RIGHT ROLE ROLLBACK ROW ROWS RULE

! SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SENSITIVE
! SEQUENCE SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
! SHOW SIMILAR SIMPLE SMALLINT SOME SPACE STABLE STANDALONE_P START STATEMENT
! STATISTICS STDIN STDOUT STORAGE STRCOLFN STRICT_P STRIP_P SUBSTRING
! SUPERUSER_P SYMMETRIC SYSID SYSTEM_P

TABLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP
TO TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P
***************
*** 559,564 ****
--- 561,567 ----
| CreateAsStmt
| CreateAssertStmt
| CreateCastStmt
+ | CreateCollationStmt
| CreateConversionStmt
| CreateDomainStmt
| CreateFunctionStmt
***************
*** 582,587 ****
--- 585,591 ----
| DiscardStmt
| DropAssertStmt
| DropCastStmt
+ | DropCollationStmt
| DropGroupStmt
| DropOpClassStmt
| DropOpFamilyStmt
***************
*** 2421,2426 ****
--- 2425,2508 ----
}
;

+ /*****************************************************************************
+ *
+ * QUERY :
+ *
+ * CREATE COLLATION <collation name> FOR <character set specification>
+ * FROM <existing collation name> [STRCOLFN <fn name>]
+ * [ <pad characteristic> ] [ <case sensitive> ] [ <accent sensitive> ]
+ * [ LCCOLLATE <lc_collate> ] [ LCCTYPE <lc_ctype> ]
+ *
+ * DROP COLLATION <collation name>
+ *
+ *****************************************************************************/
+
+ CreateCollationStmt:
+ CREATE COLLATION name FOR name FROM name OptCollationList
+ {
+ CreateCollationStmt *n = makeNode(CreateCollationStmt);
+ n->name = $3;
+ n->for_charset = $5;
+ n->parent_collation = $7;
+ n->options = $8;
+ $$ = (Node *)n;
+ }
+ ;
+
+ OptCollationList:
+ OptCollationList OptCollationElem { $$ = lappend($1, $2); }
+ | /*EMPTY*/ { $$ = NIL; }
+ ;
+
+ OptCollationElem:
+ NO PAD
+ {
+ $$ = makeDefElem("pad_characteristic", (Node *)makeInteger(FALSE));
+ }
+ | PAD SPACE
+ {
+ $$ = makeDefElem("pad_characteristic", (Node *)makeInteger(TRUE));
+ }
+ | CASE SENSITIVE
+ {
+ $$ = makeDefElem("case_sensitive", (Node *)makeInteger(TRUE));
+ }
+ | CASE INSENSITIVE
+ {
+ $$ = makeDefElem("case_sensitive", (Node *)makeInteger(FALSE));
+ }
+ | ACCENT SENSITIVE
+ {
+ $$ = makeDefElem("accent_sensitive", (Node *)makeInteger(TRUE));
+ }
+ | ACCENT INSENSITIVE
+ {
+ $$ = makeDefElem("accent_sensitive", (Node *)makeInteger(FALSE));
+ }
+ | LCCOLLATE name
+ {
+ $$ = makeDefElem("lc_collate_name", (Node *)makeString($2));
+ }
+ | LCCTYPE name
+ {
+ $$ = makeDefElem("lc_ctype_name", (Node *)makeString($2));
+ }
+ | STRCOLFN name
+ {
+ $$ = makeDefElem("str_col_function", (Node *)makeInteger(1));
+ }
+ ;
+
+ DropCollationStmt:
+ DROP COLLATION name
+ {
+ DropCollationStmt *n = makeNode(DropCollationStmt);
+ n->name = $3;
+ $$ = (Node *)n;
+ }
+ ;
+

/*****************************************************************************
*
***************
*** 5432,5437 ****
--- 5514,5527 ----
{
$$ = makeDefElem("encoding", NULL);
}
+ | COLLATE opt_equal name
+ {
+ $$ = makeDefElem("collate", (Node *)makeString($3));
+ }
+ | COLLATE opt_equal DEFAULT
+ {
+ $$ = makeDefElem("collate", NULL);
+ }
| CONNECTION LIMIT opt_equal SignedIconst
{
$$ = makeDefElem("connectionlimit", (Node *)makeInteger($4));
***************
*** 9044,9049 ****
--- 9134,9140 ----
unreserved_keyword:
ABORT_P
| ABSOLUTE_P
+ | ACCENT
| ACCESS
| ACTION
| ADD_P
***************
*** 9070,9075 ****
--- 9161,9167 ----
| CLASS
| CLOSE
| CLUSTER
+ | COLLATION
| COMMENT
| COMMIT
| COMMITTED
***************
*** 9151,9156 ****
--- 9243,9250 ----
| LANGUAGE
| LARGE_P
| LAST_P
+ | LCCOLLATE
+ | LCCTYPE
| LEVEL
| LISTEN
| LOAD
***************
*** 9187,9192 ****
--- 9281,9287 ----
| OPTION
| OWNED
| OWNER
+ | PAD
| PARSER
| PARTIAL
| PASSWORD
***************
*** 9224,9229 ****
--- 9319,9325 ----
| SEARCH
| SECOND_P
| SECURITY
+ | SENSITIVE
| SEQUENCE
| SERIALIZABLE
| SESSION
***************
*** 9231,9236 ****
--- 9327,9333 ----
| SHARE
| SHOW
| SIMPLE
+ | SPACE
| STABLE
| STANDALONE_P
| START
***************
*** 9239,9244 ****
--- 9336,9342 ----
| STDIN
| STDOUT
| STORAGE
+ | STRCOLFN
| STRICT_P
| STRIP_P
| SUPERUSER_P
Index: backend/utils/cache/syscache.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/cache/syscache.c,v
retrieving revision 1.117
diff -c -r1.117 syscache.c
*** backend/utils/cache/syscache.c 19 Jun 2008 00:46:05 -0000 1.117
--- backend/utils/cache/syscache.c 31 Aug 2008 19:21:08 -0000
***************
*** 28,33 ****
--- 28,35 ----
#include "catalog/pg_auth_members.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_cast.h"
+ #include "catalog/pg_charset.h"
+ #include "catalog/pg_collation.h"
#include "catalog/pg_constraint.h"
#include "catalog/pg_conversion.h"
#include "catalog/pg_database.h"
***************
*** 257,262 ****
--- 259,288 ----
},
256
},
+ {CharsetRelationId, /* CHARSETNAME */
+ CharsetNameIndexId,
+ 0,
+ 1,
+ {
+ Anum_pg_charset_charsetname,
+ 0,
+ 0,
+ 0
+ },
+ 64
+ },
+ {CharsetRelationId, /* CHARSETOID */
+ CharsetOidIndexId,
+ 0,
+ 1,
+ {
+ ObjectIdAttributeNumber,
+ 0,
+ 0,
+ 0
+ },
+ 64
+ },
{OperatorClassRelationId, /* CLAAMNAMENSP */
OpclassAmNameNspIndexId,
0,
***************
*** 281,286 ****
--- 307,336 ----
},
64
},
+ {CollationRelationId, /* COLLNAME */
+ CollationNameIndexId,
+ 0,
+ 1,
+ {
+ Anum_pg_collation_colname,
+ 0,
+ 0,
+ 0
+ },
+ 64
+ },
+ {CollationRelationId, /* COLLOID */
+ CollationOidIndexId,
+ 0,
+ 1,
+ {
+ ObjectIdAttributeNumber,
+ 0,
+ 0,
+ 0
+ },
+ 64
+ },
{ConversionRelationId, /* CONDEFAULT */
ConversionDefaultIndexId,
0,
Index: include/utils/pg_locale.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/utils/pg_locale.h,v
retrieving revision 1.25
diff -c -r1.25 pg_locale.h
*** include/utils/pg_locale.h 19 May 2008 18:08:16 -0000 1.25
--- include/utils/pg_locale.h 31 Aug 2008 19:21:10 -0000
***************
*** 30,35 ****
--- 30,39 ----
extern char *localized_full_months[];


+ extern const char *locale_collate_assign(const char *value,
+ bool doit, GucSource source);
+ extern const char *locale_ctype_assign(const char *value,
+ bool doit, GucSource source);
extern const char *locale_messages_assign(const char *value,
bool doit, GucSource source);
extern const char *locale_monetary_assign(const char *value,
Index: include/utils/syscache.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/utils/syscache.h,v
retrieving revision 1.72
diff -c -r1.72 syscache.h
*** include/utils/syscache.h 7 May 2008 01:04:49 -0000 1.72
--- include/utils/syscache.h 31 Aug 2008 19:21:10 -0000
***************
*** 42,49 ****
--- 42,53 ----
AUTHNAME,
AUTHOID,
CASTSOURCETARGET,
+ CHARSETNAME,
+ CHARSETOID,
CLAAMNAMENSP,
CLAOID,
+ COLLNAME,
+ COLLOID,
CONDEFAULT,
CONNAMENSP,
CONSTROID,
Index: interfaces/ecpg/preproc/preproc.y
===================================================================
RCS file: /projects/cvsroot/pgsql/src/interfaces/ecpg/preproc/preproc.y,v
retrieving revision 1.371
diff -c -r1.371 preproc.y
*** interfaces/ecpg/preproc/preproc.y 20 Aug 2008 14:09:16 -0000 1.371
--- interfaces/ecpg/preproc/preproc.y 31 Aug 2008 19:21:10 -0000
***************
*** 416,422 ****
%token TYPECAST

/* ordinary key words in alphabetical order */
! %token <keyword> ABORT_P ABSOLUTE_P ACCESS ACTION ADD_P ADMIN AFTER
AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION

--- 416,422 ----
%token TYPECAST

/* ordinary key words in alphabetical order */
! %token <keyword> ABORT_P ABSOLUTE_P ACCENT ACCESS ACTION ADD_P ADMIN AFTER
AGGREGATE ALL ALSO ALTER ALWAYS ANALYSE ANALYZE AND ANY ARRAY AS ASC
ASSERTION ASSIGNMENT ASYMMETRIC AT AUTHORIZATION

***************
*** 425,431 ****

CACHE CALLED CASCADE CASCADED CASE CAST CHAIN CHAR_P
CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
! CLUSTER COALESCE COLLATE COLUMN COMMENT COMMIT
COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS
CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE
--- 425,431 ----

CACHE CALLED CASCADE CASCADED CASE CAST CHAIN CHAR_P
CHARACTER CHARACTERISTICS CHECK CHECKPOINT CLASS CLOSE
! CLUSTER COALESCE COLLATE COLLATION COLUMN COMMENT COMMIT
COMMITTED CONCURRENTLY CONFIGURATION CONNECTION CONSTRAINT CONSTRAINTS
CONTENT_P CONTINUE_P CONVERSION_P COPY COST CREATE CREATEDB
CREATEROLE CREATEUSER CROSS CSV CURRENT_P CURRENT_DATE CURRENT_ROLE
***************
*** 454,462 ****

KEY

! LANCOMPILER LANGUAGE LARGE_P LAST_P LEADING LEAST LEFT LEVEL
! LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP LOCATION
! LOCK_P LOGIN_P

MAPPING MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE

--- 454,462 ----

KEY

! LANCOMPILER LANGUAGE LARGE_P LAST_P LCCOLLATE LCCTYPE LEADING LEAST
! LEFT LEVEL LIKE LIMIT LISTEN LOAD LOCAL LOCALTIME LOCALTIMESTAMP
! LOCATION LOCK_P LOGIN_P

MAPPING MATCH MAXVALUE MINUTE_P MINVALUE MODE MONTH_P MOVE

***************
*** 467,473 ****
OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR ORDER
OUT_P OUTER_P OVERLAPS OVERLAY OWNED OWNER

! PARSER PARTIAL PASSWORD PLACING PLANS POSITION
PRECISION PRESERVE PREPARE PREPARED PRIMARY
PRIOR PRIVILEGES PROCEDURAL PROCEDURE

--- 467,473 ----
OBJECT_P OF OFF OFFSET OIDS OLD ON ONLY OPERATOR OPTION OR ORDER
OUT_P OUTER_P OVERLAPS OVERLAY OWNED OWNER

! PAD PARSER PARTIAL PASSWORD PLACING PLANS POSITION
PRECISION PRESERVE PREPARE PREPARED PRIMARY
PRIOR PRIVILEGES PROCEDURAL PROCEDURE

***************
*** 477,487 ****
REPEATABLE REPLACE REPLICA RESET RESTART RESTRICT RETURNING RETURNS REVOKE
RIGHT ROLE ROLLBACK ROW ROWS RULE

! SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE
SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
! SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE_P START STATEMENT
! STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P SUBSTRING SUPERUSER_P
! SYMMETRIC SYSID SYSTEM_P

TABLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP TO
TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P TRUNCATE TRUSTED TYPE_P
--- 477,487 ----
REPEATABLE REPLACE REPLICA RESET RESTART RESTRICT RETURNING RETURNS REVOKE
RIGHT ROLE ROLLBACK ROW ROWS RULE

! SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SENSITIVE SEQUENCE
SERIALIZABLE SESSION SESSION_USER SET SETOF SHARE
! SHOW SIMILAR SIMPLE SMALLINT SOME SPACE STABLE STANDALONE_P START STATEMENT
! STATISTICS STDIN STDOUT STORAGE STRCOLFN STRICT_P STRIP_P SUBSTRING
! SUPERUSER_P SYMMETRIC SYSID SYSTEM_P

TABLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP TO
TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P TRUNCATE TRUSTED TYPE_P
Index: bin/psql/tab-complete.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/tab-complete.c,v
retrieving revision 1.171
diff -c -r1.171 tab-complete.c
*** bin/psql/tab-complete.c 16 Aug 2008 01:36:35 -0000 1.171
--- bin/psql/tab-complete.c 31 Aug 2008 19:21:09 -0000
***************
*** 514,520 ****
{"AGGREGATE", NULL, &Query_for_list_of_aggregates},
{"CAST", NULL, NULL}, /* Casts have complex structures for names, so
* skip it */
!
/*
* CREATE CONSTRAINT TRIGGER is not supported here because it is designed
* to be used only by pg_dump.
--- 514,520 ----
{"AGGREGATE", NULL, &Query_for_list_of_aggregates},
{"CAST", NULL, NULL}, /* Casts have complex structures for names, so
* skip it */
! {"COLLATION", NULL, NULL}, /* TODO eventually change */
/*
* CREATE CONSTRAINT TRIGGER is not supported here because it is designed
* to be used only by pg_dump.
***************
*** 1199,1205 ****
pg_strcasecmp(prev2_wd, "DATABASE") == 0)
{
static const char *const list_DATABASE[] =
! {"OWNER", "TEMPLATE", "ENCODING", "TABLESPACE", "CONNECTION LIMIT",
NULL};

COMPLETE_WITH_LIST(list_DATABASE);
--- 1199,1205 ----
pg_strcasecmp(prev2_wd, "DATABASE") == 0)
{
static const char *const list_DATABASE[] =
! {"OWNER", "TEMPLATE", "ENCODING", "LCCOLLATE", "LCCTYPE", "TABLESPACE", "CONNECTION LIMIT",
NULL};

COMPLETE_WITH_LIST(list_DATABASE);
***************
*** 1462,1468 ****

/* DROP object with CASCADE / RESTRICT */
else if ((pg_strcasecmp(prev3_wd, "DROP") == 0 &&
! (pg_strcasecmp(prev2_wd, "CONVERSION") == 0 ||
pg_strcasecmp(prev2_wd, "DOMAIN") == 0 ||
pg_strcasecmp(prev2_wd, "FUNCTION") == 0 ||
pg_strcasecmp(prev2_wd, "INDEX") == 0 ||
--- 1462,1469 ----

/* DROP object with CASCADE / RESTRICT */
else if ((pg_strcasecmp(prev3_wd, "DROP") == 0 &&
! (pg_strcasecmp(prev2_wd, "COLLATION") == 0 ||
! pg_strcasecmp(prev2_wd, "CONVERSION") == 0 ||
pg_strcasecmp(prev2_wd, "DOMAIN") == 0 ||
pg_strcasecmp(prev2_wd, "FUNCTION") == 0 ||
pg_strcasecmp(prev2_wd, "INDEX") == 0 ||
Index: bin/psql/describe.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/psql/describe.c,v
retrieving revision 1.184
diff -c -r1.184 describe.c
*** bin/psql/describe.c 18 Jul 2008 04:20:24 -0000 1.184
--- bin/psql/describe.c 31 Aug 2008 19:21:09 -0000
***************
*** 462,467 ****
--- 462,476 ----
gettext_noop("Access Privileges"));
if (verbose && pset.sversion >= 80200)
appendPQExpBuffer(&buf,
+ ",\n d.datcollate as \"%s\"",
+ _("LC_COLLATE"));
+ if (verbose && pset.sversion >= 80200)
+ appendPQExpBuffer(&buf,
+ ",\n d.datctype as \"%s\"",
+ _("LC_CTYPE"));
+
+ if (verbose && pset.sversion >= 80200)
+ appendPQExpBuffer(&buf,
",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
" THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
" ELSE 'No Access'\n"
Index: backend/commands/Makefile
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/Makefile,v
retrieving revision 1.38
diff -c -r1.38 Makefile
*** backend/commands/Makefile 19 Feb 2008 10:30:07 -0000 1.38
--- backend/commands/Makefile 31 Aug 2008 19:21:07 -0000
***************
*** 13,19 ****
include $(top_builddir)/src/Makefile.global

OBJS = aggregatecmds.o alter.o analyze.o async.o cluster.o comment.o \
! conversioncmds.o copy.o \
dbcommands.o define.o discard.o explain.o functioncmds.o \
indexcmds.o lockcmds.o operatorcmds.o opclasscmds.o \
portalcmds.o prepare.o proclang.o \
--- 13,19 ----
include $(top_builddir)/src/Makefile.global

OBJS = aggregatecmds.o alter.o analyze.o async.o cluster.o comment.o \
! collation.o conversioncmds.o copy.o \
dbcommands.o define.o discard.o explain.o functioncmds.o \
indexcmds.o lockcmds.o operatorcmds.o opclasscmds.o \
portalcmds.o prepare.o proclang.o \
Index: backend/commands/dbcommands.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/commands/dbcommands.c,v
retrieving revision 1.210
diff -c -r1.210 dbcommands.c
*** backend/commands/dbcommands.c 4 Aug 2008 18:03:46 -0000 1.210
--- backend/commands/dbcommands.c 31 Aug 2008 19:21:07 -0000
***************
*** 19,24 ****
--- 19,28 ----
*/
#include "postgres.h"

+ #ifdef HAVE_LANGINFO_H
+ #include <langinfo.h>
+ #endif
+
#include <fcntl.h>
#include <locale.h>
#include <unistd.h>
***************
*** 32,37 ****
--- 36,42 ----
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/pg_authid.h"
+ #include "catalog/pg_collation.h"
#include "catalog/pg_database.h"
#include "catalog/pg_tablespace.h"
#include "commands/comment.h"
***************
*** 53,58 ****
--- 58,64 ----
#include "utils/fmgroids.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"
+ #include "utils/pg_locale.h"
#include "utils/syscache.h"
#include "utils/tqual.h"

***************
*** 69,75 ****
Oid *dbIdP, Oid *ownerIdP,
int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
Oid *dbLastSysOidP, TransactionId *dbFrozenXidP,
! Oid *dbTablespace);
static bool have_createdb_privilege(void);
static void remove_dbtablespaces(Oid db_id);
static bool check_db_file_conflict(Oid db_id);
--- 75,81 ----
Oid *dbIdP, Oid *ownerIdP,
int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
Oid *dbLastSysOidP, TransactionId *dbFrozenXidP,
! Oid *dbTablespace, Oid *dbCollation);
static bool have_createdb_privilege(void);
static void remove_dbtablespaces(Oid db_id);
static bool check_db_file_conflict(Oid db_id);
***************
*** 86,92 ****
--- 92,101 ----
Relation rel;
Oid src_dboid;
Oid src_owner;
+ Oid src_collationoid;
int src_encoding;
+ char *src_collate;
+ char *src_ctype;
bool src_istemplate;
bool src_allowconn;
Oid src_lastsysoid;
***************
*** 95,113 ****
--- 104,127 ----
volatile Oid dst_deftablespace;
Relation pg_database_rel;
HeapTuple tuple;
+ HeapTuple coltuple;
Datum new_record[Natts_pg_database];
char new_record_nulls[Natts_pg_database];
Oid dboid;
Oid datdba;
+ Oid datcollationoid;
ListCell *option;
DefElem *dtablespacename = NULL;
DefElem *downer = NULL;
DefElem *dtemplate = NULL;
DefElem *dencoding = NULL;
+ DefElem *dcollation = NULL;
DefElem *dconnlimit = NULL;
char *dbname = stmt->dbname;
char *dbowner = NULL;
const char *dbtemplate = NULL;
+ char *lc_collate = NULL;
+ char *lc_ctype = NULL;
int encoding = -1;
int dbconnlimit = -1;
int ctype_encoding;
***************
*** 152,157 ****
--- 166,179 ----
errmsg("conflicting or redundant options")));
dencoding = defel;
}
+ else if (strcmp(defel->defname, "collate") == 0)
+ {
+ if (dcollation)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("conflicting or redundant options")));
+ dcollation = defel;
+ }
else if (strcmp(defel->defname, "connectionlimit") == 0)
{
if (dconnlimit)
***************
*** 205,210 ****
--- 227,256 ----
elog(ERROR, "unrecognized node type: %d",
nodeTag(dencoding->arg));
}
+ /*
+ if (dlc_collate && dlc_collate->arg) {
+ lc_collate = strVal(dlc_collate->arg);
+ if ((locale_collate_assign(lc_collate, false, (GucSource)NULL)) == NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("%s is not a valid LC_COLLATE name",
+ lc_collate)));
+ }
+ */
+
+ if (dcollation && dcollation->arg) {
+ coltuple = SearchSysCache(COLLNAME,
+ CStringGetDatum(strVal(dcollation->arg)),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(coltuple))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("%s is not a valid COLLATION name",
+ strVal(dcollation->arg))));
+ datcollationoid = HeapTupleGetOid(coltuple);
+ ReleaseSysCache(coltuple);
+ }
+
if (dconnlimit && dconnlimit->arg)
dbconnlimit = intVal(dconnlimit->arg);

***************
*** 243,249 ****
if (!get_db_info(dbtemplate, ShareLock,
&src_dboid, &src_owner, &src_encoding,
&src_istemplate, &src_allowconn, &src_lastsysoid,
! &src_frozenxid, &src_deftablespace))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("template database \"%s\" does not exist",
--- 289,295 ----
if (!get_db_info(dbtemplate, ShareLock,
&src_dboid, &src_owner, &src_encoding,
&src_istemplate, &src_allowconn, &src_lastsysoid,
! &src_frozenxid, &src_deftablespace, &src_collationoid))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("template database \"%s\" does not exist",
***************
*** 369,374 ****
--- 415,427 ----
/* Note there is no additional permission check in this path */
}

+ /*
+ * If collation is specified for database, use it, otherwise inherit database
+ * cluster's collation.
+ */
+ datcollationoid = OidIsValid(datcollationoid) ? datcollationoid : src_collationoid;
+
+
/*
* Check for db name conflict. This is just to give a more friendly error
* message than "unique index violation". There's a race condition but
***************
*** 414,419 ****
--- 467,473 ----
*/

/* Form tuple */
+
MemSet(new_record, 0, sizeof(new_record));
MemSet(new_record_nulls, ' ', sizeof(new_record_nulls));

***************
*** 421,426 ****
--- 475,481 ----
DirectFunctionCall1(namein, CStringGetDatum(dbname));
new_record[Anum_pg_database_datdba - 1] = ObjectIdGetDatum(datdba);
new_record[Anum_pg_database_encoding - 1] = Int32GetDatum(encoding);
+ new_record[Anum_pg_database_datcollation - 1] = ObjectIdGetDatum(datcollationoid);
new_record[Anum_pg_database_datistemplate - 1] = BoolGetDatum(false);
new_record[Anum_pg_database_datallowconn - 1] = BoolGetDatum(true);
new_record[Anum_pg_database_datconnlimit - 1] = Int32GetDatum(dbconnlimit);
***************
*** 583,588 ****
--- 638,659 ----
* space but is not in pg_database, which is not good.
*/
database_file_update_needed();
+
+ /*
+ * Message about reindexing new database
+ */
+ if (lc_collate != src_collate || lc_ctype != src_ctype)
+ ereport(NOTICE,
+ (errmsg("database \"%s\" need to be reindexed manually (REINDEX DATABASE)",
+ dbname)));
+
+ /* {
+ * ereport(NOTICE,
+ * (errmsg("database \"%s\" is reindexed automaticly",
+ * dbname)));
+ * ReindexDatabase(dbname, true, true);
+ *}
+ */
}
PG_END_ENSURE_ERROR_CLEANUP(createdb_failure_callback,
PointerGetDatum(&fparms));
***************
*** 629,635 ****
pgdbrel = heap_open(DatabaseRelationId, RowExclusiveLock);

if (!get_db_info(dbname, AccessExclusiveLock, &db_id, NULL, NULL,
! &db_istemplate, NULL, NULL, NULL, NULL))
{
if (!missing_ok)
{
--- 700,706 ----
pgdbrel = heap_open(DatabaseRelationId, RowExclusiveLock);

if (!get_db_info(dbname, AccessExclusiveLock, &db_id, NULL, NULL,
! &db_istemplate, NULL, NULL, NULL, NULL, NULL))
{
if (!missing_ok)
{
***************
*** 781,787 ****
rel = heap_open(DatabaseRelationId, RowExclusiveLock);

if (!get_db_info(oldname, AccessExclusiveLock, &db_id, NULL, NULL,
! NULL, NULL, NULL, NULL, NULL))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database \"%s\" does not exist", oldname)));
--- 852,858 ----
rel = heap_open(DatabaseRelationId, RowExclusiveLock);

if (!get_db_info(oldname, AccessExclusiveLock, &db_id, NULL, NULL,
! NULL, NULL, NULL, NULL, NULL, NULL))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_DATABASE),
errmsg("database \"%s\" does not exist", oldname)));
***************
*** 1168,1174 ****
Oid *dbIdP, Oid *ownerIdP,
int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
Oid *dbLastSysOidP, TransactionId *dbFrozenXidP,
! Oid *dbTablespace)
{
bool result = false;
Relation relation;
--- 1239,1245 ----
Oid *dbIdP, Oid *ownerIdP,
int *encodingP, bool *dbIsTemplateP, bool *dbAllowConnP,
Oid *dbLastSysOidP, TransactionId *dbFrozenXidP,
! Oid *dbTablespace, Oid *dbCollation)
{
bool result = false;
Relation relation;
***************
*** 1259,1264 ****
--- 1330,1338 ----
/* default tablespace for this database */
if (dbTablespace)
*dbTablespace = dbform->dattablespace;
+ /* default locale settings for this database */
+ if (dbCollation)
+ *dbCollation = dbform->datcollation;
ReleaseSysCache(tuple);
result = true;
break;
Index: include/nodes/parsenodes.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/nodes/parsenodes.h,v
retrieving revision 1.371
diff -c -r1.371 parsenodes.h
*** include/nodes/parsenodes.h 7 Aug 2008 01:11:51 -0000 1.371
--- include/nodes/parsenodes.h 31 Aug 2008 19:21:10 -0000
***************
*** 1224,1229 ****
--- 1224,1249 ----
bool skip_validation; /* skip validation of existing rows? */
} FkConstraint;

+ /* ----------------------
+ * Create/Drop Collation Statements
+ * ----------------------
+ */
+
+ typedef struct CreateCollationStmt
+ {
+ NodeTag type;
+ char *name;
+ char *for_charset;
+ char *parent_collation;
+ List *options;
+ } CreateCollationStmt;
+
+ typedef struct DropCollationStmt
+ {
+ NodeTag type;
+ char *name;
+
+ } DropCollationStmt;

/* ----------------------
* Create/Drop Table Space Statements
Index: include/nodes/nodes.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/nodes/nodes.h,v
retrieving revision 1.209
diff -c -r1.209 nodes.h
*** include/nodes/nodes.h 22 Aug 2008 00:16:04 -0000 1.209
--- include/nodes/nodes.h 31 Aug 2008 19:21:09 -0000
***************
*** 315,320 ****
--- 315,322 ----
T_CreateEnumStmt,
T_AlterTSDictionaryStmt,
T_AlterTSConfigurationStmt,
+ T_CreateCollationStmt,
+ T_DropCollationStmt,

/*
* TAGS FOR PARSE TREE NODES (parsenodes.h)
Index: backend/access/transam/xlog.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/access/transam/xlog.c,v
retrieving revision 1.317
diff -c -r1.317 xlog.c
*** backend/access/transam/xlog.c 11 Aug 2008 11:05:10 -0000 1.317
--- backend/access/transam/xlog.c 31 Aug 2008 19:21:07 -0000
***************
*** 3832,3850 ****
#endif
ControlFile->float4ByVal = FLOAT4PASSBYVAL;
ControlFile->float8ByVal = FLOAT8PASSBYVAL;
!
! ControlFile->localeBuflen = LOCALE_NAME_BUFLEN;
! localeptr = setlocale(LC_COLLATE, NULL);
! if (!localeptr)
! ereport(PANIC,
! (errmsg("invalid LC_COLLATE setting")));
! StrNCpy(ControlFile->lc_collate, localeptr, LOCALE_NAME_BUFLEN);
! localeptr = setlocale(LC_CTYPE, NULL);
! if (!localeptr)
! ereport(PANIC,
! (errmsg("invalid LC_CTYPE setting")));
! StrNCpy(ControlFile->lc_ctype, localeptr, LOCALE_NAME_BUFLEN);
!
/* Contents are protected with a CRC */
INIT_CRC32(ControlFile->crc);
COMP_CRC32(ControlFile->crc,
--- 3832,3838 ----
#endif
ControlFile->float4ByVal = FLOAT4PASSBYVAL;
ControlFile->float8ByVal = FLOAT8PASSBYVAL;
!
/* Contents are protected with a CRC */
INIT_CRC32(ControlFile->crc);
COMP_CRC32(ControlFile->crc,
***************
*** 4083,4116 ****
" but the server was compiled without USE_FLOAT8_BYVAL."),
errhint("It looks like you need to recompile or initdb.")));
#endif
-
- if (ControlFile->localeBuflen != LOCALE_NAME_BUFLEN)
- ereport(FATAL,
- (errmsg("database files are incompatible with server"),
- errdetail("The database cluster was initialized with LOCALE_NAME_BUFLEN %d,"
- " but the server was compiled with LOCALE_NAME_BUFLEN %d.",
- ControlFile->localeBuflen, LOCALE_NAME_BUFLEN),
- errhint("It looks like you need to recompile or initdb.")));
- if (pg_perm_setlocale(LC_COLLATE, ControlFile->lc_collate) == NULL)
- ereport(FATAL,
- (errmsg("database files are incompatible with operating system"),
- errdetail("The database cluster was initialized with LC_COLLATE \"%s\","
- " which is not recognized by setlocale().",
- ControlFile->lc_collate),
- errhint("It looks like you need to initdb or install locale support.")));
- if (pg_perm_setlocale(LC_CTYPE, ControlFile->lc_ctype) == NULL)
- ereport(FATAL,
- (errmsg("database files are incompatible with operating system"),
- errdetail("The database cluster was initialized with LC_CTYPE \"%s\","
- " which is not recognized by setlocale().",
- ControlFile->lc_ctype),
- errhint("It looks like you need to initdb or install locale support.")));
-
- /* Make the fixed locale settings visible as GUC variables, too */
- SetConfigOption("lc_collate", ControlFile->lc_collate,
- PGC_INTERNAL, PGC_S_OVERRIDE);
- SetConfigOption("lc_ctype", ControlFile->lc_ctype,
- PGC_INTERNAL, PGC_S_OVERRIDE);
}

void
--- 4071,4076 ----
Index: backend/catalog/Makefile
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/catalog/Makefile,v
retrieving revision 1.66
diff -c -r1.66 Makefile
*** backend/catalog/Makefile 19 Feb 2008 10:30:07 -0000 1.66
--- backend/catalog/Makefile 31 Aug 2008 19:21:07 -0000
***************
*** 11,18 ****
include $(top_builddir)/src/Makefile.global

OBJS = catalog.o dependency.o heap.o index.o indexing.o namespace.o aclchk.o \
! pg_aggregate.o pg_constraint.o pg_conversion.o pg_depend.o pg_enum.o \
! pg_largeobject.o pg_namespace.o pg_operator.o pg_proc.o pg_shdepend.o \
pg_type.o toasting.o

BKIFILES = postgres.bki postgres.description postgres.shdescription
--- 11,18 ----
include $(top_builddir)/src/Makefile.global

OBJS = catalog.o dependency.o heap.o index.o indexing.o namespace.o aclchk.o \
! pg_aggregate.o pg_collation.o pg_charset.o pg_constraint.o pg_conversion.o pg_depend.o \
! pg_enum.o pg_largeobject.o pg_namespace.o pg_operator.o pg_proc.o pg_shdepend.o \
pg_type.o toasting.o

BKIFILES = postgres.bki postgres.description postgres.shdescription
***************
*** 27,34 ****

POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\
pg_proc.h pg_type.h pg_attribute.h pg_class.h pg_autovacuum.h \
! pg_attrdef.h pg_constraint.h pg_inherits.h pg_index.h pg_operator.h \
! pg_opfamily.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
pg_enum.h pg_namespace.h pg_conversion.h pg_depend.h \
--- 27,34 ----

POSTGRES_BKI_SRCS = $(addprefix $(top_srcdir)/src/include/catalog/,\
pg_proc.h pg_type.h pg_attribute.h pg_class.h pg_autovacuum.h \
! pg_attrdef.h pg_charset.h pg_collation.h pg_constraint.h pg_inherits.h pg_index.h \
! pg_operator.h pg_opfamily.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h pg_cast.h \
pg_enum.h pg_namespace.h pg_conversion.h pg_depend.h \
Index: backend/utils/adt/pg_locale.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/pg_locale.c,v
retrieving revision 1.41
diff -c -r1.41 pg_locale.c
*** backend/utils/adt/pg_locale.c 19 May 2008 18:08:16 -0000 1.41
--- backend/utils/adt/pg_locale.c 31 Aug 2008 19:21:08 -0000
***************
*** 228,233 ****
--- 228,245 ----
return value;
}

+ const char *
+ locale_collate_assign(const char *value, bool doit, GucSource source)
+ {
+ return locale_xxx_assign(LC_COLLATE, value, doit, source);
+ }
+
+ const char *
+ locale_ctype_assign(const char *value, bool doit, GucSource source)
+ {
+ return locale_xxx_assign(LC_CTYPE, value, doit, source);
+ }
+

const char *
locale_monetary_assign(const char *value, bool doit, GucSource source)
Index: include/catalog/pg_control.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_control.h,v
retrieving revision 1.41
diff -c -r1.41 pg_control.h
*** include/catalog/pg_control.h 21 Apr 2008 00:26:47 -0000 1.41
--- include/catalog/pg_control.h 31 Aug 2008 19:21:09 -0000
***************
*** 144,154 ****
bool float4ByVal; /* float4 pass-by-value? */
bool float8ByVal; /* float8, int8, etc pass-by-value? */

- /* active locales */
- uint32 localeBuflen;
- char lc_collate[LOCALE_NAME_BUFLEN];
- char lc_ctype[LOCALE_NAME_BUFLEN];
-
/* CRC of all above ... MUST BE LAST! */
pg_crc32 crc;
} ControlFileData;
--- 144,149 ----
Index: include/catalog/pg_database.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/pg_database.h,v
retrieving revision 1.47
diff -c -r1.47 pg_database.h
*** include/catalog/pg_database.h 27 Mar 2008 03:57:34 -0000 1.47
--- include/catalog/pg_database.h 31 Aug 2008 19:21:09 -0000
***************
*** 33,38 ****
--- 33,39 ----
NameData datname; /* database name */
Oid datdba; /* owner of database */
int4 encoding; /* character encoding */
+ Oid datcollation; /* collation */
bool datistemplate; /* allowed as CREATE DATABASE template? */
bool datallowconn; /* new connections allowed? */
int4 datconnlimit; /* max connections allowed (-1=no limit) */
***************
*** 54,73 ****
* compiler constants for pg_database
* ----------------
*/
! #define Natts_pg_database 11
#define Anum_pg_database_datname 1
#define Anum_pg_database_datdba 2
#define Anum_pg_database_encoding 3
! #define Anum_pg_database_datistemplate 4
! #define Anum_pg_database_datallowconn 5
! #define Anum_pg_database_datconnlimit 6
! #define Anum_pg_database_datlastsysoid 7
! #define Anum_pg_database_datfrozenxid 8
! #define Anum_pg_database_dattablespace 9
! #define Anum_pg_database_datconfig 10
! #define Anum_pg_database_datacl 11

! DATA(insert OID = 1 ( template1 PGUID ENCODING t t -1 0 0 1663 _null_ _null_ ));
SHDESCR("default template database");
#define TemplateDbOid 1

--- 55,75 ----
* compiler constants for pg_database
* ----------------
*/
! #define Natts_pg_database 12
#define Anum_pg_database_datname 1
#define Anum_pg_database_datdba 2
#define Anum_pg_database_encoding 3
! #define Anum_pg_database_datcollation 4
! #define Anum_pg_database_datistemplate 5
! #define Anum_pg_database_datallowconn 6
! #define Anum_pg_database_datconnlimit 7
! #define Anum_pg_database_datlastsysoid 8
! #define Anum_pg_database_datfrozenxid 9
! #define Anum_pg_database_dattablespace 10
! #define Anum_pg_database_datconfig 11
! #define Anum_pg_database_datacl 12

! DATA(insert OID = 1 ( template1 PGUID ENCODING 2988 t t -1 0 0 1663 _null_ _null_ ));
SHDESCR("default template database");
#define TemplateDbOid 1

Index: include/catalog/indexing.h
===================================================================
RCS file: /projects/cvsroot/pgsql/src/include/catalog/indexing.h,v
retrieving revision 1.103
diff -c -r1.103 indexing.h
*** include/catalog/indexing.h 19 Jun 2008 00:46:06 -0000 1.103
--- include/catalog/indexing.h 31 Aug 2008 19:21:09 -0000
***************
*** 105,115 ****
--- 105,125 ----
DECLARE_UNIQUE_INDEX(pg_cast_source_target_index, 2661, on pg_cast using btree(castsource oid_ops, casttarget oid_ops));
#define CastSourceTargetIndexId 2661

+ DECLARE_UNIQUE_INDEX(pg_charset_name_index, 2179, on pg_charset using btree(charsetname name_ops));
+ #define CharsetNameIndexId 2179
+ DECLARE_UNIQUE_INDEX(pg_charset_oid_index, 2316, on pg_charset using btree(oid oid_ops));
+ #define CharsetOidIndexId 2316
+
DECLARE_UNIQUE_INDEX(pg_class_oid_index, 2662, on pg_class using btree(oid oid_ops));
#define ClassOidIndexId 2662
DECLARE_UNIQUE_INDEX(pg_class_relname_nsp_index, 2663, on pg_class using btree(relname name_ops, relnamespace oid_ops));
#define ClassNameNspIndexId 2663

+ DECLARE_UNIQUE_INDEX(pg_collation_name_index, 2181, on pg_collation using btree(colname name_ops));
+ #define CollationNameIndexId 2181
+ DECLARE_UNIQUE_INDEX(pg_collation_oid_index, 2232, on pg_collation using btree(oid oid_ops));
+ #define CollationOidIndexId 2232
+
/* This following index is not used for a cache and is not unique */
DECLARE_INDEX(pg_constraint_conname_nsp_index, 2664, on pg_constraint using btree(conname name_ops, connamespace oid_ops));
#define ConstraintNameNspIndexId 2664
Index: backend/utils/init/postinit.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/utils/init/postinit.c,v
retrieving revision 1.184
diff -c -r1.184 postinit.c
*** backend/utils/init/postinit.c 12 May 2008 00:00:52 -0000 1.184
--- backend/utils/init/postinit.c 31 Aug 2008 19:21:08 -0000
***************
*** 23,28 ****
--- 23,30 ----
#include "catalog/catalog.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.h"
+ #include "catalog/pg_collation.h"
+ #include "catalog/pg_charset.h"
#include "catalog/pg_database.h"
#include "catalog/pg_tablespace.h"
#include "libpq/hba.h"
***************
*** 156,164 ****
static void
CheckMyDatabase(const char *name, bool am_superuser)
{
! HeapTuple tup;
! Form_pg_database dbform;
!
/* Fetch our real pg_database row */
tup = SearchSysCache(DATABASEOID,
ObjectIdGetDatum(MyDatabaseId),
--- 158,173 ----
static void
CheckMyDatabase(const char *name, bool am_superuser)
{
! HeapTuple tup;
! HeapTuple localetup;
! Form_pg_database dbform;
! Form_pg_charset dbcharset;
! Form_pg_collation dbcollation;
! Oid collationoid;
! Oid charsetoid;
! char *collate;
! char *ctype;
!
/* Fetch our real pg_database row */
tup = SearchSysCache(DATABASEOID,
ObjectIdGetDatum(MyDatabaseId),
***************
*** 239,244 ****
--- 248,295 ----
/* If we have no other source of client_encoding, use server encoding */
SetConfigOption("client_encoding", GetDatabaseEncodingName(),
PGC_BACKEND, PGC_S_DEFAULT);
+ /* Get database collation oid */
+ collationoid = dbform->datcollation;
+ /* Fetch pg_collation record */
+ localetup = SearchSysCache(COLLOID,
+ ObjectIdGetDatum(collationoid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(localetup))
+ elog(ERROR, "cache lookup failed for collation %u", collationoid);
+ dbcollation = (Form_pg_collation) GETSTRUCT(localetup);
+ ReleaseSysCache(localetup);
+ /* Fetch pg_charset record */
+ charsetoid = dbcollation->colcharset;
+ localetup = SearchSysCache(CHARSETOID,
+ ObjectIdGetDatum(charsetoid),
+ 0, 0, 0);
+ if (!HeapTupleIsValid(tup))
+ elog(ERROR, "cache lookup failed for charset %u", charsetoid);
+ dbcharset = (Form_pg_charset) GETSTRUCT(localetup);
+ ReleaseSysCache(localetup);
+
+ /* assign locale variables */
+ collate = NameStr(dbcollation->colcollate);
+ ctype = NameStr(dbcharset->charsettype);
+
+ if (setlocale(LC_COLLATE, collate) == NULL)
+ ereport(FATAL,
+ (errmsg("database local is incompatible with OS"),
+ errdetail("The database was initialized with LC_COLLATE \"%s\", "
+ " which is not recognized by setlocale().", collate),
+ errhint("Try to recreate the database or install locale support.")));
+
+ if (setlocale(LC_CTYPE, ctype) == NULL)
+ ereport(FATAL,
+ (errmsg("database local is incompatible with OS"),
+ errdetail("The database was initialized with LC_CTYPE \"%s\", "
+ " which is not recognized by setlocale().", ctype),
+ errhint("Try to recreate the database or install locale support.")));
+
+ /* Record it as a GUC internal option, too */
+
+ SetConfigOption("lc_collate", collate, PGC_INTERNAL, PGC_S_DATABASE);
+ SetConfigOption("lc_ctype", ctype, PGC_INTERNAL, PGC_S_DATABASE);

/*
* Lastly, set up any database-specific configuration variables.
Index: bin/initdb/initdb.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/initdb/initdb.c,v
retrieving revision 1.159
diff -c -r1.159 initdb.c
*** bin/initdb/initdb.c 5 Aug 2008 12:09:30 -0000 1.159
--- bin/initdb/initdb.c 31 Aug 2008 19:21:08 -0000
***************
*** 1171,1176 ****
--- 1171,1184 ----
conflines = replace_token(conflines, "#port = 5432", repltok);
#endif

+ snprintf(repltok, sizeof(repltok), "lc_collate = '%s'",
+ escape_quotes(lc_collate));
+ conflines = replace_token(conflines, "#lc_collate = 'C'", repltok);
+
+ snprintf(repltok, sizeof(repltok), "lc_ctype = '%s'",
+ escape_quotes(lc_collate));
+ conflines = replace_token(conflines, "#lc_ctype = 'C'", repltok);
+
snprintf(repltok, sizeof(repltok), "lc_messages = '%s'",
escape_quotes(lc_messages));
conflines = replace_token(conflines, "#lc_messages = 'C'", repltok);
***************
*** 1353,1358 ****
--- 1361,1370 ----

bki_lines = replace_token(bki_lines, "ENCODING", encodingid);

+ bki_lines = replace_token(bki_lines, "LC_COLLATE", lc_collate);
+
+ bki_lines = replace_token(bki_lines, "LC_CTYPE", lc_ctype);
+
/*
* Pass correct LC_xxx environment to bootstrap.
*
***************
*** 2806,2815 ****
strcmp(lc_ctype, lc_numeric) == 0 &&
strcmp(lc_ctype, lc_monetary) == 0 &&
strcmp(lc_ctype, lc_messages) == 0)
! printf(_("The database cluster will be initialized with locale %s.\n"), lc_ctype);
else
{
! printf(_("The database cluster will be initialized with locales\n"
" COLLATE: %s\n"
" CTYPE: %s\n"
" MESSAGES: %s\n"
--- 2818,2827 ----
strcmp(lc_ctype, lc_numeric) == 0 &&
strcmp(lc_ctype, lc_monetary) == 0 &&
strcmp(lc_ctype, lc_messages) == 0)
! printf(_("The database template1 will be initialized with locale %s.\n"), lc_ctype);
else
{
! printf(_("The database template1 will be initialized with locales\n"
" COLLATE: %s\n"
" CTYPE: %s\n"
" MESSAGES: %s\n"
Index: bin/scripts/createdb.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/scripts/createdb.c,v
retrieving revision 1.26
diff -c -r1.26 createdb.c
*** bin/scripts/createdb.c 1 Jan 2008 19:45:56 -0000 1.26
--- bin/scripts/createdb.c 31 Aug 2008 19:21:09 -0000
***************
*** 32,37 ****
--- 32,39 ----
{"tablespace", required_argument, NULL, 'D'},
{"template", required_argument, NULL, 'T'},
{"encoding", required_argument, NULL, 'E'},
+ {"lc-collate", required_argument, NULL, 1},
+ {"lc-ctype", required_argument, NULL, 2},
{NULL, 0, NULL, 0}
};

***************
*** 50,55 ****
--- 52,59 ----
char *tablespace = NULL;
char *template = NULL;
char *encoding = NULL;
+ char *lc_collate = NULL;
+ char *lc_ctype = NULL;

PQExpBufferData sql;

***************
*** 95,100 ****
--- 99,110 ----
case 'E':
encoding = optarg;
break;
+ case 1:
+ lc_collate = optarg;
+ break;
+ case 2:
+ lc_ctype = optarg;
+ break;
default:
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
exit(1);
***************
*** 152,159 ****
appendPQExpBuffer(&sql, " ENCODING '%s'", encoding);
if (template)
appendPQExpBuffer(&sql, " TEMPLATE %s", fmtId(template));
appendPQExpBuffer(&sql, ";\n");
!
conn = connectDatabase(strcmp(dbname, "postgres") == 0 ? "template1" : "postgres",
host, port, username, password, progname);

--- 162,174 ----
appendPQExpBuffer(&sql, " ENCODING '%s'", encoding);
if (template)
appendPQExpBuffer(&sql, " TEMPLATE %s", fmtId(template));
+ if (lc_collate)
+ appendPQExpBuffer(&sql, " LCCOLLATE %s", fmtId(lc_collate));
+ if (lc_ctype)
+ appendPQExpBuffer(&sql, " LCCTYPE %s", fmtId(lc_ctype));
+
appendPQExpBuffer(&sql, ";\n");
!
conn = connectDatabase(strcmp(dbname, "postgres") == 0 ? "template1" : "postgres",
host, port, username, password, progname);

***************
*** 207,224 ****
printf(_("Usage:\n"));
printf(_(" %s [OPTION]... [DBNAME] [DESCRIPTION]\n"), progname);
printf(_("\nOptions:\n"));
! printf(_(" -D, --tablespace=TABLESPACE default tablespace for the database\n"));
! printf(_(" -E, --encoding=ENCODING encoding for the database\n"));
! printf(_(" -O, --owner=OWNER database user to own the new database\n"));
! printf(_(" -T, --template=TEMPLATE template database to copy\n"));
! printf(_(" -e, --echo show the commands being sent to the server\n"));
! printf(_(" --help show this help, then exit\n"));
! printf(_(" --version output version information, then exit\n"));
printf(_("\nConnection options:\n"));
! printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
! printf(_(" -p, --port=PORT database server port\n"));
! printf(_(" -U, --username=USERNAME user name to connect as\n"));
! printf(_(" -W, --password force password prompt\n"));
printf(_("\nBy default, a database with the same name as the current user is created.\n"));
printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
}
--- 222,240 ----
printf(_("Usage:\n"));
printf(_(" %s [OPTION]... [DBNAME] [DESCRIPTION]\n"), progname);
printf(_("\nOptions:\n"));
! printf(_(" -D, --tablespace=TABLESPACE default tablespace for the database\n"));
! printf(_(" -E, --encoding=ENCODING encoding for the database\n"));
! printf(_(" --lc-collate, --lc-ctype=LOCALE locale for the database\n"));
! printf(_(" -O, --owner=OWNER database user to own the new database\n"));
! printf(_(" -T, --template=TEMPLATE template database to copy\n"));
! printf(_(" -e, --echo show the commands being sent to the server\n"));
! printf(_(" --help show this help, then exit\n"));
! printf(_(" --version output version information, then exit\n"));
printf(_("\nConnection options:\n"));
! printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
! printf(_(" -p, --port=PORT database server port\n"));
! printf(_(" -U, --username=USERNAME user name to connect as\n"));
! printf(_(" -W, --password force password prompt\n"));
printf(_("\nBy default, a database with the same name as the current user is created.\n"));
printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
}
Index: bin/pg_controldata/pg_controldata.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/pg_controldata/pg_controldata.c,v
retrieving revision 1.39
diff -c -r1.39 pg_controldata.c
*** bin/pg_controldata/pg_controldata.c 21 Apr 2008 00:26:46 -0000 1.39
--- bin/pg_controldata/pg_controldata.c 31 Aug 2008 19:21:08 -0000
***************
*** 220,231 ****
(ControlFile.float4ByVal ? _("by value") : _("by reference")));
printf(_("Float8 argument passing: %s\n"),
(ControlFile.float8ByVal ? _("by value") : _("by reference")));
- printf(_("Maximum length of locale name: %u\n"),
- ControlFile.localeBuflen);
- printf(_("LC_COLLATE: %s\n"),
- ControlFile.lc_collate);
- printf(_("LC_CTYPE: %s\n"),
- ControlFile.lc_ctype);
-
return 0;
}
--- 220,224 ----
Index: backend/tcop/utility.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/backend/tcop/utility.c,v
retrieving revision 1.296
diff -c -r1.296 utility.c
*** backend/tcop/utility.c 13 Aug 2008 00:07:50 -0000 1.296
--- backend/tcop/utility.c 31 Aug 2008 19:21:08 -0000
***************
*** 24,29 ****
--- 24,30 ----
#include "commands/alter.h"
#include "commands/async.h"
#include "commands/cluster.h"
+ #include "commands/collation.h"
#include "commands/comment.h"
#include "commands/conversioncmds.h"
#include "commands/copy.h"
***************
*** 166,171 ****
--- 167,173 ----
case T_CommentStmt:
case T_DefineStmt:
case T_CreateCastStmt:
+ case T_CreateCollationStmt:
case T_CreateConversionStmt:
case T_CreatedbStmt:
case T_CreateDomainStmt:
***************
*** 1023,1028 ****
--- 1025,1038 ----
AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
break;

+ case T_CreateCollationStmt:
+ DefineCollation((CreateCollationStmt *) parsetree);
+ break;
+
+ case T_DropCollationStmt:
+ DropCollation((DropCollationStmt *) parsetree);
+ break;
+
default:
elog(ERROR, "unrecognized node type: %d",
(int) nodeTag(parsetree));
Index: bin/pg_resetxlog/pg_resetxlog.c
===================================================================
RCS file: /projects/cvsroot/pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v
retrieving revision 1.65
diff -c -r1.65 pg_resetxlog.c
*** bin/pg_resetxlog/pg_resetxlog.c 21 Apr 2008 00:26:46 -0000 1.65
--- bin/pg_resetxlog/pg_resetxlog.c 31 Aug 2008 19:21:08 -0000
***************
*** 493,514 ****
#endif
ControlFile.float4ByVal = FLOAT4PASSBYVAL;
ControlFile.float8ByVal = FLOAT8PASSBYVAL;
- ControlFile.localeBuflen = LOCALE_NAME_BUFLEN;
-
- localeptr = setlocale(LC_COLLATE, "");
- if (!localeptr)
- {
- fprintf(stderr, _("%s: invalid LC_COLLATE setting\n"), progname);
- exit(1);
- }
- strlcpy(ControlFile.lc_collate, localeptr, sizeof(ControlFile.lc_collate));
- localeptr = setlocale(LC_CTYPE, "");
- if (!localeptr)
- {
- fprintf(stderr, _("%s: invalid LC_CTYPE setting\n"), progname);
- exit(1);
- }
- strlcpy(ControlFile.lc_ctype, localeptr, sizeof(ControlFile.lc_ctype));

/*
* XXX eventually, should try to grovel through old XLOG to develop more
--- 493,498 ----
***************
*** 584,595 ****
(ControlFile.float4ByVal ? _("by value") : _("by reference")));
printf(_("Float8 argument passing: %s\n"),
(ControlFile.float8ByVal ? _("by value") : _("by reference")));
- printf(_("Maximum length of locale name: %u\n"),
- ControlFile.localeBuflen);
- printf(_("LC_COLLATE: %s\n"),
- ControlFile.lc_collate);
- printf(_("LC_CTYPE: %s\n"),
- ControlFile.lc_ctype);
}


--- 568,573 ----
Index: src/include/catalog/pg_collation.h
===================================================================
RCS file: src/include/catalog/pg_collation.h
diff -N src/include/catalog/pg_collation.h
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- src/include/catalog/pg_collation.h 1 Jan 1970 00:00:00 -0000
***************
*** 0 ****
--- 1,115 ----
+ /*-------------------------------------------------------------------------
+ *
+ * pg_collation.h
+ * definition of the system "collation" relation (pg_collation)
+ * along with the relation's initial contents.
+ *
+ *
+ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $PostgreSQL:
+ *
+ * NOTES
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
+ *
+ *-------------------------------------------------------------------------
+ */
+ #ifndef PG_COLLATION_H
+ #define PG_COLLATION_H
+
+ #include "catalog/genbki.h"
+
+ /* ----------------------------------------------------------------
+ * pg_collation definition.
+ *
+ * cpp turns this into typedef struct FormData_pg_collation
+ *
+ * colname collation name
+ * colschema collation schema
+ * colencoding encoding name
+ * colpadattribute pad attribute
+ * colcasesensitive case sensitive
+ * colcollate lc_collate
+ * colcharset collation charset
+ * colfunc used collation function
+ *
+ * ----------------------------------------------------------------
+ */
+
+ #define CollationRelationId 2328
+
+
+ enum {
+ PAD_CHARACTERISTIC_NO_PAD = 0,
+ PAD_CHARACTERISTIC_PAD_SPACE = 1
+
+ } CollationPadCharacteristic;
+
+ enum {
+ CASE_INSENSITIVE = 0,
+ CASE_SENSITIVE = 1
+ } CollationCaseSensitive;
+
+ enum {
+ FUNCTION_BUILTIN = 0,
+ FUNCTION_SYSTEM = 1
+ } CollationFunction;
+
+ CATALOG(pg_collation,2328)
+ {
+ NameData colname;
+ Oid colschema;
+ bool colpadattribute;
+ bool colcasesensitive;
+ NameData colcollate;
+ Oid colcharset;
+ int2 colfunc;
+ } FormData_pg_collation;
+
+ /* ----------------
+ * Form_pg_collation corresponds to a pointer to a tuple with
+ * the format of pg_collation relation.
+ * ----------------
+ */
+ typedef FormData_pg_collation *Form_pg_collation;
+
+ /* ----------------
+ * compiler constants for pg_collation
+ * ----------------
+ */
+ #define Natts_pg_collation 7
+ #define Anum_pg_collation_colname 1
+ #define Anum_pg_collation_colschema 2
+ #define Anum_pg_collation_colpadattribute 3
+ #define Anum_pg_collation_colcasesensitive 4
+ #define Anum_pg_collation_colcollate 5
+ #define Anum_pg_collation_colcharset 6
+ #define Anum_pg_collation_colfunc 7
+
+ /* ----------------
+ * initial contents of pg_collation
+ * ----------------
+ */
+
+ DATA(insert OID = 2982 ( "LATIN1" PGNSP t t "C" 2182 1));
+ DATA(insert OID = 2983 ( "ISO8BIT" PGNSP t t "C" 2183 1));
+ DATA(insert OID = 2984 ( "UNICODE" PGNSP t t "C" 2184 1));
+ DATA(insert OID = 2988 ( "DEFAULT" PGNSP t t "LC_COLLATE" 2185 1));
+
+ /* ----------------
+ * prototypes for functions in pg_collation.c
+ * ----------------
+ */
+ extern Oid CollationCreateEntry(const char *collationName,
+ Oid collationSchema,
+ bool padAttribute,
+ bool caseSensitive,
+ const char *collate,
+ Oid charset,
+ int8 collationFunction);
+
+ extern void CollationDeleteEntry(const char *collationName);
+
+ #endif /* PG_COLLATION_H */
Index: src/interfaces/ecpg/include/ecpg_config.h
===================================================================
RCS file: src/interfaces/ecpg/include/ecpg_config.h
diff -N src/interfaces/ecpg/include/ecpg_config.h
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- src/interfaces/ecpg/include/ecpg_config.h 1 Jan 1970 00:00:00 -0000
***************
*** 0 ****
--- 1,18 ----
+ /* src/interfaces/ecpg/include/ecpg_config.h. Generated by configure. */
+ /* Define to 1 if the system has the type `int64'. */
+ /* #undef HAVE_INT64 */
+
+ /* Define to 1 if `long int' works and is 64 bits. */
+ /* #undef HAVE_LONG_INT_64 */
+
+ /* Define to 1 if `long long int' works and is 64 bits. */
+ #define HAVE_LONG_LONG_INT_64
+
+ /* Define to 1 if you want 64-bit integer timestamp and interval support.
+ (--enable-integer-datetimes) */
+ /* #undef USE_INTEGER_DATETIMES */
+
+ /* Define to 1 to build client libraries as thread-safe code.
+ * (--enable-thread-safety) */
+ /* #undef ENABLE_THREAD_SAFETY */
+
Index: src/backend/catalog/pg_collation.c
===================================================================
RCS file: src/backend/catalog/pg_collation.c
diff -N src/backend/catalog/pg_collation.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- src/backend/catalog/pg_collation.c 1 Jan 1970 00:00:00 -0000
***************
*** 0 ****
--- 1,138 ----
+ /*-------------------------------------------------------------------------
+ *
+ * pg_collation.c
+ * routines to support manipulation of the pg_collation relation
+ *
+ * Copyright (c) 2006-2008, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL:
+ *
+ *-------------------------------------------------------------------------
+ */
+ #include "postgres.h"
+
+ #include "access/genam.h"
+ #include "access/heapam.h"
+ #include "access/htup.h"
+ #include "access/relscan.h"
+ #include "access/skey.h"
+ #include "catalog/catalog.h"
+ #include "catalog/indexing.h"
+ #include "catalog/pg_collation.h"
+ #include "utils/acl.h"
+ #include "utils/builtins.h"
+ #include "utils/fmgroids.h"
+ #include "utils/rel.h"
+ #include "utils/syscache.h"
+ #include "utils/tqual.h"
+
+
+ Oid
+ CollationCreateEntry(const char *collationName,
+ Oid collationSchema,
+ bool padAttribute,
+ bool caseSensitive,
+ const char *collate,
+ Oid charset,
+ int8 collationFunction)
+ {
+
+ Relation pg_collation;
+ HeapTuple tup;
+ TupleDesc tupDesc;
+ Datum values[Natts_pg_collation];
+ char nulls[Natts_pg_collation];
+ Oid oid;
+ Oid collOid;
+ NameData cname;
+ NameData ccollate;
+
+
+ /* ereport(WARNING, (errcode(ERRCODE_WARNING),
+ * errmsg("DEBUG (create collation): collation name - '%s', collate - '%s', padattribute - '%d', coll fn - '%d'",
+ * collationName,
+ * collate,
+ * padAttribute,
+ * collationFunction
+ * )));
+ *
+ * ereport(WARNING, (errcode(ERRCODE_WARNING),
+ * errmsg("TEST")));
+ */
+ Assert(collationName);
+ namestrcpy(&cname, collationName);
+
+ Assert(collate);
+ namestrcpy(&ccollate, collate);
+
+ pg_collation = heap_open(CollationRelationId, RowExclusiveLock);
+
+ /* check uniqueness */
+ if (HeapTupleIsValid(SearchSysCache(COLLNAME,
+ CStringGetDatum(collationName),
+ 0, 0, 0)))
+ ereport(ERROR,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("collation \"%s\" already exists",
+ collationName)));
+
+ /* allocate new oid */
+ oid = GetNewOid(pg_collation);
+ if (!OidIsValid(oid))
+ ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
+ errmsg("Can't allocate new pg_collation oid.")));
+
+ tupDesc = RelationGetDescr(pg_collation);
+
+ /* prepare entries */
+ memset(nulls, ' ', sizeof(nulls));
+
+ values[Anum_pg_collation_colname - 1] = NameGetDatum(&cname);
+ values[Anum_pg_collation_colschema - 1] = ObjectIdGetDatum(collationSchema);
+ values[Anum_pg_collation_colpadattribute - 1] = BoolGetDatum(padAttribute);
+ values[Anum_pg_collation_colcasesensitive - 1] = BoolGetDatum(caseSensitive);
+ values[Anum_pg_collation_colcollate - 1] = NameGetDatum(&ccollate);
+ values[Anum_pg_collation_colcharset - 1] = ObjectIdGetDatum(charset);
+ values[Anum_pg_collation_colfunc - 1] = Int8GetDatum(collationFunction);
+
+ tup = heap_formtuple(tupDesc, values, nulls);
+ /* HeapTupleSetOid(tup, oid); */
+
+ collOid = simple_heap_insert(pg_collation, tup);
+
+ CatalogUpdateIndexes(pg_collation, tup);
+
+ heap_freetuple(tup);
+
+ heap_close(pg_collation, RowExclusiveLock);
+
+ return collOid;
+ }
+
+ void
+ CollationDeleteEntry(const char *collationName)
+ {
+ Relation pg_collation;
+ HeapTuple tup;
+
+ Assert(collationName);
+
+ pg_collation = heap_open(CollationRelationId, RowExclusiveLock);
+
+ tup = SearchSysCache(COLLNAME, CStringGetDatum(collationName), 0, 0, 0);
+
+ if (HeapTupleIsValid(tup))
+ simple_heap_delete(pg_collation, &tup->t_self);
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("collation \"%s\" does not exist",
+ collationName)));
+
+ ReleaseSysCache(tup);
+
+ heap_close(pg_collation, RowExclusiveLock);
+ }
+
Index: src/include/commands/collation.h
===================================================================
RCS file: src/include/commands/collation.h
diff -N src/include/commands/collation.h
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- src/include/commands/collation.h 1 Jan 1970 00:00:00 -0000
***************
*** 0 ****
--- 1,21 ----
+ /*-------------------------------------------------------------------------
+ *
+ * collation.h
+ * prototypes for commands/collation.c
+ *
+ *
+ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $PostgreSQL: pgsql/src/include/commands/collation.h,v 1.1 2008/01/01 19:45:57 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+ #ifndef COLLATION_H
+ #define COLLATION_H
+
+ #include "nodes/parsenodes.h"
+
+ extern void DefineCollation(CreateCollationStmt *stmt);
+
+ #endif /* COLLATION_H */
Index: src/backend/commands/collation.c
===================================================================
RCS file: src/backend/commands/collation.c
diff -N src/backend/commands/collation.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- src/backend/commands/collation.c 1 Jan 1970 00:00:00 -0000
***************
*** 0 ****
--- 1,195 ----
+ /*-------------------------------------------------------------------------
+ *
+ * collation.c
+ * the Postgres collation support
+ *
+ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL:
+ *
+ *-------------------------------------------------------------------------
+ */
+ #include "postgres.h"
+ #include "c.h"
+
+ #include "access/genam.h"
+ #include "access/heapam.h"
+ #include "access/htup.h"
+ #include "access/skey.h"
+ #include "access/xact.h"
+ #include "access/xlogutils.h"
+ #include "catalog/catalog.h"
+ #include "catalog/dependency.h"
+ #include "catalog/indexing.h"
+ #include "catalog/pg_charset.h"
+ #include "catalog/pg_collation.h"
+ #include "catalog/pg_namespace.h"
+ #include "commands/defrem.h"
+ #include "utils/builtins.h"
+ #include "utils/fmgroids.h"
+ #include "utils/pg_locale.h"
+ #include "utils/syscache.h"
+ #include "utils/tqual.h"
+
+ /*
+ * CREATE COLLATION
+ */
+ void
+ DefineCollation(CreateCollationStmt *stmt)
+ {
+ const char *collationname = stmt->name;
+ const char *charsetname = stmt->for_charset;
+ const char *parentcollationname = stmt->parent_collation;
+ char *charsetctype = NULL;
+ char *collationcollate = NULL;
+ Oid schemaid;
+ Oid charsetid;
+ HeapTuple coltuple;
+ HeapTuple chartuple;
+ Form_pg_collation parentcollation;
+ ListCell *option;
+
+ /* debug stuff */
+
+ /* ereport(WARNING, (errcode(ERRCODE_WARNING),
+ errmsg("DEBUG: collation name - '%s', parent collation - '%s', charset for - '%s'",
+ collationname, parentcollationname, charsetname))); */
+
+ /* retrieve parent collation and copy parameters */
+
+ /* colrel = heap_open(CollationRelationId, RowShareLock);
+ *
+ * ScanKeyInit(&colkey[0],
+ * Anum_pg_collation_colname,
+ * BTEqualStrategyNumber, F_NAMEEQ,
+ * NameGetDatum(parentcollationname));
+ *
+ * scan = systable_beginscan(colrel, CollationRelationId, true,
+ * SnapshotNow, 1, colkey);
+ *
+ * coltuple = systable_getnext(scan);
+ *
+ */
+
+ coltuple = SearchSysCache(COLLNAME,
+ CStringGetDatum(parentcollationname),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(coltuple))
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("parent collation \"%s\" does not exist",
+ parentcollationname)));
+
+ parentcollation = (Form_pg_collation) GETSTRUCT(coltuple);
+
+ ReleaseSysCache(coltuple);
+
+ /* TODO sanity checks (duplicate options values etc.) */
+
+ /* override parent collation with new option values */
+
+ foreach(option, stmt->options)
+ {
+ DefElem *defel = (DefElem *) lfirst(option);
+
+ if (strcmp(defel->defname, "pad_characteristic") == 0)
+ {
+ if (defGetNumeric(defel) == FALSE)
+ parentcollation->colpadattribute = PAD_CHARACTERISTIC_NO_PAD;
+ else
+ parentcollation->colpadattribute = PAD_CHARACTERISTIC_PAD_SPACE;
+ }
+ else if (strcmp(defel->defname, "case_sensitive") == 0)
+ {
+ if (defGetNumeric(defel) == FALSE)
+ parentcollation->colcasesensitive = CASE_INSENSITIVE;
+ else
+ parentcollation->colcasesensitive = CASE_SENSITIVE;
+ }
+ else if (strcmp(defel->defname, "lc_collate_name") == 0)
+ {
+ if (defel->arg != NULL)
+ {
+ collationcollate = (char *)palloc((strlen(defGetString(defel)) + 1) * sizeof(char));
+ strcpy(collationcollate, defGetString(defel));
+ }
+ }
+ else if (strcmp(defel->defname, "lc_ctype_name") == 0)
+ {
+ if (defel->arg != NULL)
+ {
+ charsetctype = (char *)palloc((strlen(defGetString(defel)) + 1) * sizeof(char));
+ strcpy(charsetctype, defGetString(defel));
+ }
+ }
+ else if (strcmp(defel->defname, "str_col_function") == 0)
+ {
+ parentcollation->colfunc = defGetNumeric(defel);
+ }
+
+ }
+
+ if (collationcollate == NULL)
+ {
+ collationcollate = (char *)palloc((strlen((char *)parentcollation->colcollate.data) + 1) * sizeof(char));
+ strcpy(collationcollate, (char *)parentcollation->colcollate.data);
+ }
+
+ /* get character OID */
+ chartuple = SearchSysCache(CHARSETNAME,
+ CStringGetDatum(charsetname),
+ 0, 0, 0);
+
+ if (!HeapTupleIsValid(chartuple))
+ {
+
+ /* create record in pg_charset */
+ if (charsetctype != NULL)
+ {
+ charsetid = CharsetCreateEntry(charsetname, PG_PUBLIC_NAMESPACE, charsetctype);
+ ereport(WARNING, (errcode(ERRCODE_WARNING),
+ errmsg("DEBUG (create charset): charset name - '%s', charset namespace - '%d', LC_CTYPE - '%s'",
+ charsetname,
+ PG_PUBLIC_NAMESPACE,
+ charsetctype
+ )));
+ }
+ else
+ ereport(ERROR,
+ (errcode(ERRCODE_UNDEFINED_OBJECT),
+ errmsg("LCCTYPE not specified")));
+
+ /* TODO check duplicite names */
+ }
+ else
+ {
+
+ /* all good */
+ charsetid = HeapTupleGetOid(chartuple);
+ ReleaseSysCache(chartuple);
+ }
+
+ /* create catalog record */
+ CollationCreateEntry(collationname,
+ PG_PUBLIC_NAMESPACE,
+ parentcollation->colpadattribute,
+ parentcollation->colcasesensitive,
+ collationcollate,
+ charsetid,
+ 1);
+
+
+ if (collationcollate != NULL) pfree(collationcollate);
+ if (charsetctype != NULL) pfree(charsetctype);
+
+ }
+
+ void
+ DropCollation(DropCollationStmt *stmt)
+ {
+ CollationDeleteEntry(stmt->name);
+ }
Index: src/backend/catalog/pg_charset.c
===================================================================
RCS file: src/backend/catalog/pg_charset.c
diff -N src/backend/catalog/pg_charset.c
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- src/backend/catalog/pg_charset.c 1 Jan 1970 00:00:00 -0000
***************
*** 0 ****
--- 1,83 ----
+ /*-------------------------------------------------------------------------
+ *
+ * pg_charset.c
+ * routines to support manipulation of the pg_collation relation
+ *
+ * Copyright (c) 2006-2008, PostgreSQL Global Development Group
+ *
+ *
+ * IDENTIFICATION
+ * $PostgreSQL:
+ *
+ *-------------------------------------------------------------------------
+ */
+
+ #include "postgres.h"
+
+ #include "access/genam.h"
+ #include "access/heapam.h"
+ #include "catalog/catalog.h"
+ #include "catalog/indexing.h"
+ #include "catalog/pg_charset.h"
+ #include "utils/builtins.h"
+ #include "utils/rel.h"
+ #include "utils/syscache.h"
+ #include "utils/tqual.h"
+
+ Oid CharsetCreateEntry(const char *charsetName,
+ Oid charsetSchema,
+ const char *charsetType)
+ {
+ Relation pg_charset;
+ HeapTuple tup;
+ TupleDesc tupDesc;
+ Datum values[Natts_pg_charset];
+ char nulls[Natts_pg_charset];
+ Oid oid;
+ Oid charOid;
+ NameData chName;
+ NameData chType;
+
+ Assert(charsetName);
+ namestrcpy(&chName, charsetName);
+
+ Assert(charsetType);
+ namestrcpy(&chType, charsetType);
+
+ pg_charset = heap_open(CharsetRelationId, RowExclusiveLock);
+
+ /* check uniqueness */
+ if (HeapTupleIsValid(SearchSysCache(CHARSETNAME,
+ CStringGetDatum(charsetName),
+ 0, 0, 0)))
+ ereport(ERROR,
+ (errcode(ERRCODE_DUPLICATE_OBJECT),
+ errmsg("charset \"%s\" already exists",
+ charsetName)));
+
+ /* allocate new oid */
+ oid = GetNewOid(pg_charset);
+ if (!OidIsValid(oid))
+ ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_RESOURCES),
+ errmsg("Can't allocate new pg_charset oid.")));
+
+ tupDesc = RelationGetDescr(pg_charset);
+
+ /* prepare entries */
+ memset(nulls, ' ', sizeof(nulls));
+
+ values[Anum_pg_charset_charsetname - 1] = NameGetDatum(&chName);
+ values[Anum_pg_charset_charsetschema - 1] = ObjectIdGetDatum(charsetSchema);
+ values[Anum_pg_charset_charsettype - 1] = NameGetDatum(&chType);
+
+ tup = heap_formtuple(tupDesc, values, nulls);
+ /* HeapTupleSetOid(tup, oid); */
+
+ charOid = simple_heap_insert(pg_charset, tup);
+ CatalogUpdateIndexes(pg_charset, tup);
+ heap_freetuple(tup);
+
+ heap_close(pg_charset, RowExclusiveLock);
+
+ return charOid;
+ }
Index: src/include/catalog/pg_charset.h
===================================================================
RCS file: src/include/catalog/pg_charset.h
diff -N src/include/catalog/pg_charset.h
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- src/include/catalog/pg_charset.h 1 Jan 1970 00:00:00 -0000
***************
*** 0 ****
--- 1,82 ----
+ /*-------------------------------------------------------------------------
+ *
+ * pg_charset.h
+ * definition of the system "pg_charset" relation (pg_charset)
+ * along with the relation's initial contents.
+ *
+ *
+ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * $PostgreSQL:
+ *
+ * NOTES
+ * the genbki.sh script reads this file and generates .bki
+ * information from the DATA() statements.
+ *
+ *-------------------------------------------------------------------------
+ */
+ #ifndef PG_CHARSET_H
+ #define PG_CHARSET_H
+
+ #include "catalog/genbki.h"
+
+ /* ----------------------------------------------------------------
+ * pg_charset definition.
+ *
+ * cpp turns this into typedef struct FormData_pg_charset
+ *
+ * charsetname character set name
+ * charsetschema character set schema
+ * charsettype character set type
+ * charsetfunc character set function
+ * (sets the charset)
+ *
+ * ----------------------------------------------------------------
+ */
+
+ #define CharsetRelationId 2981
+
+ CATALOG(pg_charset,2981)
+ {
+ NameData charsetname;
+ Oid charsetschema;
+ NameData charsettype;
+ } FormData_pg_charset;
+
+ /* ----------------
+ * Form_pg_charset corresponds to a pointer to a tuple with
+ * the format of pg_collation relation.
+ * ----------------
+ */
+ typedef FormData_pg_charset *Form_pg_charset;
+
+ /* ----------------
+ * compiler constants for pg_collation
+ * ----------------
+ */
+ #define Natts_pg_charset 3
+ #define Anum_pg_charset_charsetname 1
+ #define Anum_pg_charset_charsetschema 2
+ #define Anum_pg_charset_charsettype 3
+
+ /* ----------------
+ * initial contents of pg_charset
+ * ----------------
+ */
+
+ DATA(insert OID = 2182 ( "LATIN1" PGNSP "C" ));
+ DATA(insert OID = 2183 ( "ISO8BIT" PGNSP "C" ));
+ DATA(insert OID = 2184 ( "UTF-8" PGNSP "C" ));
+ DATA(insert OID = 2185 ( "DEFAULT" PGNSP "LC_CTYPE" ));
+
+ /* ----------------
+ * prototypes for functions in pg_charset.c
+ * ----------------
+ */
+
+ extern Oid CharsetCreateEntry(const char *charsetName,
+ Oid charsetSchema,
+ const char *charsetType);
+
+ #endif /* PG_CHARSET_H */
I'm implementing collation support. Proposal can be found at http://archives.postgresql.org/pgsql-hackers/2008-07/msg00557.php

Progress so far:
- created catalogs pg_collation a pg_charset which are filled with three standard collations
- initdb changes rows called "DEFAULT" in both catalogs during the bki bootstrap phase with current system LC_COLLATE and LC_CTYPE or those set by command line.
- new collations can be defined with command CREATE COLLATION <collation name> FOR <character set specification>  FROM <existing collation name> [STRCOLFN <fn name>]
[ <pad characteristic> ] [ <case sensitive> ] [ LCCOLLATE <lc_collate> ] [ LCCTYPE <lc_ctype> ]
- because of pg_collation and pg_charset are catalogs individual for each database, if you want to create a database with collation other than specified, create it in template1 and then create database
- when connecting to database, it retrieves locales from pg_database and sets them

Design & functionality changes left:
- move retrieveing collation from pg_database to pg_type
- get case sensitivity and pad characteristic working
- wrap locale setting and text comparison into functions that will be referenced from pg_collation as regproc (make the code nice)
- when creating database with different collation than database cluster, the database has to be reindexed. Any idea how to do it? Function ReindexDatabase works only when database is opened.
- minor tweaks & fixes

Ideas? Comments?

Regards

Radek Strnad