Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit11b5847

Browse files
committed
Add an OR REPLACE option to CREATE LANGUAGE.
This operates in the same way as other CREATE OR REPLACE commands, ie,it replaces everything but the ownership and ACL lists of an existingentry, and requires the caller to have owner privileges for that entry.While modifying an existing language has some use in development scenarios,in typical usage all the "replaced" values come from pg_pltemplate so therewill be no actual change in the language definition. The reason for addingthis is mainly to allow programs to ensure that a language exists withouttriggering an error if it already does exist.This commit just adds and documents the new option. A followon patchwill use it to clean up some unpleasant cases in pg_dump and pg_regress.
1 parentc4fc082 commit11b5847

File tree

6 files changed

+102
-46
lines changed

6 files changed

+102
-46
lines changed

‎doc/src/sgml/ref/create_language.sgml

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/ref/create_language.sgml,v 1.48 2009/12/19 01:49:02 tgl Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/ref/create_language.sgml,v 1.49 2010/02/23 22:51:42 tgl Exp $
33
PostgreSQL documentation
44
-->
55

@@ -21,8 +21,8 @@ PostgreSQL documentation
2121

2222
<refsynopsisdiv>
2323
<synopsis>
24-
CREATE [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">name</replaceable>
25-
CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">name</replaceable>
24+
CREATE [OR REPLACE ] [PROCEDURAL ] LANGUAGE <replaceable class="parameter">name</replaceable>
25+
CREATE [OR REPLACE ] [TRUSTED ] [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">name</replaceable>
2626
HANDLER <replaceable class="parameter">call_handler</replaceable> [ INLINE <replaceable class="parameter">inline_handler</replaceable> ] [ VALIDATOR <replaceable>valfunction</replaceable> ]
2727
</synopsis>
2828
</refsynopsisdiv>
@@ -31,18 +31,17 @@ CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">name</
3131
<title>Description</title>
3232

3333
<para>
34-
Using <command>CREATE LANGUAGE</command>, a
35-
<productname>PostgreSQL</productname> user can register a new
34+
<command>CREATE LANGUAGE</command> registers a new
3635
procedural language with a <productname>PostgreSQL</productname>
3736
database. Subsequently, functions and trigger procedures can be
3837
defined in this new language.
3938
</para>
4039

4140
<para>
4241
<command>CREATE LANGUAGE</command> effectively associates the
43-
language name witha callhandler thatis responsible for executing
42+
language name with handlerfunction(s)thatare responsible for executing
4443
functions written in the language. Refer to <xref linkend="plhandler">
45-
for more information about languagecallhandlers.
44+
for more information about language handlers.
4645
</para>
4746

4847
<para>
@@ -77,6 +76,23 @@ CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">name</
7776
The creator of a language becomes its owner and can later
7877
drop it, rename it, or assign it to a new owner.
7978
</para>
79+
80+
<para>
81+
<command>CREATE OR REPLACE LANGUAGE</command> will either create a
82+
new language, or replace an existing definition. If the language
83+
already exists, its parameters are updated according to the values
84+
specified or taken from <structname>pg_pltemplate</structname>,
85+
but the language's ownership and permissions settings do not change,
86+
and any existing functions written in the language are assumed to still
87+
be valid. In addition to the normal privilege requirements for creating
88+
a language, the user must be superuser or owner of the existing language.
89+
The <literal>REPLACE</> case is mainly meant to be used to
90+
ensure that the language exists. If the language has a
91+
<structname>pg_pltemplate</structname> entry then <literal>REPLACE</>
92+
will not actually change anything about an existing definition, except in
93+
the unusual case where the <structname>pg_pltemplate</structname> entry
94+
has been modified since the language was created.
95+
</para>
8096
</refsect1>
8197

8298
<refsect1 id="sql-createlanguage-parameters">
@@ -88,7 +104,7 @@ CREATE [ TRUSTED ] [ PROCEDURAL ] LANGUAGE <replaceable class="parameter">name</
88104

89105
<listitem>
90106
<para>
91-
<literal>TRUSTED</literal> specifies that the call handler for
107+
<literal>TRUSTED</literal> specifies that
92108
the language is safe, that is, it does not offer an
93109
unprivileged user any functionality to bypass access
94110
restrictions. If this key word is omitted when registering the

‎src/backend/commands/proclang.c

Lines changed: 59 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/commands/proclang.c,v 1.89 2010/02/14 18:42:14 rhaas Exp $
10+
* $PostgreSQL: pgsql/src/backend/commands/proclang.c,v 1.90 2010/02/23 22:51:42 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -17,7 +17,6 @@
1717
#include"access/heapam.h"
1818
#include"catalog/dependency.h"
1919
#include"catalog/indexing.h"
20-
#include"catalog/pg_authid.h"
2120
#include"catalog/pg_language.h"
2221
#include"catalog/pg_namespace.h"
2322
#include"catalog/pg_pltemplate.h"
@@ -49,7 +48,7 @@ typedef struct
4948
char*tmpllibrary;/* path of shared library */
5049
}PLTemplate;
5150

52-
staticvoidcreate_proc_lang(constchar*languageName,
51+
staticvoidcreate_proc_lang(constchar*languageName,boolreplace,
5352
OidlanguageOwner,OidhandlerOid,OidinlineOid,
5453
OidvalOid,booltrusted);
5554
staticPLTemplate*find_language_template(constchar*languageName);
@@ -73,16 +72,10 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
7372
Oidfuncargtypes[1];
7473

7574
/*
76-
* Translate the language name and check that this language doesn't
77-
* already exist
75+
* Translate the language name to lower case
7876
*/
7977
languageName=case_translate_language_name(stmt->plname);
8078

81-
if (SearchSysCacheExists1(LANGNAME,PointerGetDatum(languageName)))
82-
ereport(ERROR,
83-
(errcode(ERRCODE_DUPLICATE_OBJECT),
84-
errmsg("language \"%s\" already exists",languageName)));
85-
8679
/*
8780
* If we have template information for the language, ignore the supplied
8881
* parameters (if any) and use the template information.
@@ -232,7 +225,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
232225
valOid=InvalidOid;
233226

234227
/* ok, create it */
235-
create_proc_lang(languageName,GetUserId(),handlerOid,inlineOid,
228+
create_proc_lang(languageName,stmt->replace,GetUserId(),
229+
handlerOid,inlineOid,
236230
valOid,pltemplate->tmpltrusted);
237231
}
238232
else
@@ -306,7 +300,8 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
306300
valOid=InvalidOid;
307301

308302
/* ok, create it */
309-
create_proc_lang(languageName,GetUserId(),handlerOid,inlineOid,
303+
create_proc_lang(languageName,stmt->replace,GetUserId(),
304+
handlerOid,inlineOid,
310305
valOid,stmt->pltrusted);
311306
}
312307
}
@@ -315,27 +310,29 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
315310
* Guts of language creation.
316311
*/
317312
staticvoid
318-
create_proc_lang(constchar*languageName,
313+
create_proc_lang(constchar*languageName,boolreplace,
319314
OidlanguageOwner,OidhandlerOid,OidinlineOid,
320315
OidvalOid,booltrusted)
321316
{
322317
Relationrel;
323318
TupleDesctupDesc;
324319
Datumvalues[Natts_pg_language];
325320
boolnulls[Natts_pg_language];
321+
boolreplaces[Natts_pg_language];
326322
NameDatalangname;
323+
HeapTupleoldtup;
327324
HeapTupletup;
325+
boolis_update;
328326
ObjectAddressmyself,
329327
referenced;
330328

331-
/*
332-
* Insert the new language into pg_language
333-
*/
334329
rel=heap_open(LanguageRelationId,RowExclusiveLock);
335-
tupDesc=rel->rd_att;
330+
tupDesc=RelationGetDescr(rel);
336331

332+
/* Prepare data to be inserted */
337333
memset(values,0,sizeof(values));
338334
memset(nulls, false,sizeof(nulls));
335+
memset(replaces, true,sizeof(replaces));
339336

340337
namestrcpy(&langname,languageName);
341338
values[Anum_pg_language_lanname-1]=NameGetDatum(&langname);
@@ -347,24 +344,62 @@ create_proc_lang(const char *languageName,
347344
values[Anum_pg_language_lanvalidator-1]=ObjectIdGetDatum(valOid);
348345
nulls[Anum_pg_language_lanacl-1]= true;
349346

350-
tup=heap_form_tuple(tupDesc,values,nulls);
347+
/* Check for pre-existing definition */
348+
oldtup=SearchSysCache1(LANGNAME,PointerGetDatum(languageName));
351349

352-
simple_heap_insert(rel,tup);
350+
if (HeapTupleIsValid(oldtup))
351+
{
352+
/* There is one; okay to replace it? */
353+
if (!replace)
354+
ereport(ERROR,
355+
(errcode(ERRCODE_DUPLICATE_OBJECT),
356+
errmsg("language \"%s\" already exists",languageName)));
357+
if (!pg_language_ownercheck(HeapTupleGetOid(oldtup),languageOwner))
358+
aclcheck_error(ACLCHECK_NOT_OWNER,ACL_KIND_LANGUAGE,
359+
languageName);
353360

361+
/*
362+
* Do not change existing ownership or permissions. Note
363+
* dependency-update code below has to agree with this decision.
364+
*/
365+
replaces[Anum_pg_language_lanowner-1]= false;
366+
replaces[Anum_pg_language_lanacl-1]= false;
367+
368+
/* Okay, do it... */
369+
tup=heap_modify_tuple(oldtup,tupDesc,values,nulls,replaces);
370+
simple_heap_update(rel,&tup->t_self,tup);
371+
372+
ReleaseSysCache(oldtup);
373+
is_update= true;
374+
}
375+
else
376+
{
377+
/* Creating a new language */
378+
tup=heap_form_tuple(tupDesc,values,nulls);
379+
simple_heap_insert(rel,tup);
380+
is_update= false;
381+
}
382+
383+
/* Need to update indexes for either the insert or update case */
354384
CatalogUpdateIndexes(rel,tup);
355385

356386
/*
357-
* Create dependencies for language
387+
* Create dependencies for the new language. If we are updating an
388+
* existing language, first delete any existing pg_depend entries.
389+
* (However, since we are not changing ownership or permissions, the
390+
* shared dependencies do *not* need to change, and we leave them alone.)
358391
*/
359392
myself.classId=LanguageRelationId;
360393
myself.objectId=HeapTupleGetOid(tup);
361394
myself.objectSubId=0;
362395

396+
if (is_update)
397+
deleteDependencyRecordsFor(myself.classId,myself.objectId);
398+
363399
/* dependency on owner of language */
364-
referenced.classId=AuthIdRelationId;
365-
referenced.objectId=languageOwner;
366-
referenced.objectSubId=0;
367-
recordSharedDependencyOn(&myself,&referenced,SHARED_DEPENDENCY_OWNER);
400+
if (!is_update)
401+
recordDependencyOnOwner(myself.classId,myself.objectId,
402+
languageOwner);
368403

369404
/* dependency on the PL handler function */
370405
referenced.classId=ProcedureRelationId;

‎src/backend/nodes/copyfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.462 2010/02/16 22:34:43 tgl Exp $
18+
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.463 2010/02/23 22:51:42 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -3237,6 +3237,7 @@ _copyCreatePLangStmt(CreatePLangStmt *from)
32373237
{
32383238
CreatePLangStmt*newnode=makeNode(CreatePLangStmt);
32393239

3240+
COPY_SCALAR_FIELD(replace);
32403241
COPY_STRING_FIELD(plname);
32413242
COPY_NODE_FIELD(plhandler);
32423243
COPY_NODE_FIELD(plinline);

‎src/backend/nodes/equalfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* Portions Copyright (c) 1994, Regents of the University of California
2323
*
2424
* IDENTIFICATION
25-
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.383 2010/02/16 22:34:43 tgl Exp $
25+
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.384 2010/02/23 22:51:42 tgl Exp $
2626
*
2727
*-------------------------------------------------------------------------
2828
*/
@@ -1710,6 +1710,7 @@ _equalDropPropertyStmt(DropPropertyStmt *a, DropPropertyStmt *b)
17101710
staticbool
17111711
_equalCreatePLangStmt(CreatePLangStmt*a,CreatePLangStmt*b)
17121712
{
1713+
COMPARE_SCALAR_FIELD(replace);
17131714
COMPARE_STRING_FIELD(plname);
17141715
COMPARE_NODE_FIELD(plhandler);
17151716
COMPARE_NODE_FIELD(plinline);

‎src/backend/parser/gram.y

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.710 2010/02/17 04:19:39 tgl Exp $
14+
* $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.711 2010/02/23 22:51:42 tgl Exp $
1515
*
1616
* HISTORY
1717
* AUTHORDATEMAJOR EVENT
@@ -2882,32 +2882,34 @@ NumericOnly:
28822882
/*****************************************************************************
28832883
*
28842884
*QUERIES :
2885-
*CREATE PROCEDURAL LANGUAGE ...
2886-
*DROP PROCEDURAL LANGUAGE ...
2885+
*CREATE[OR REPLACE] [TRUSTED] [PROCEDURAL] LANGUAGE ...
2886+
*DROP[PROCEDURAL] LANGUAGE ...
28872887
*
28882888
*****************************************************************************/
28892889

28902890
CreatePLangStmt:
2891-
CREATEopt_trustedopt_proceduralLANGUAGEColId_or_Sconst
2891+
CREATEopt_or_replaceopt_trustedopt_proceduralLANGUAGEColId_or_Sconst
28922892
{
28932893
CreatePLangStmt *n = makeNode(CreatePLangStmt);
2894-
n->plname =$5;
2894+
n->replace =$2;
2895+
n->plname =$6;
28952896
/* parameters are all to be supplied by system*/
28962897
n->plhandler = NIL;
28972898
n->plinline = NIL;
28982899
n->plvalidator = NIL;
28992900
n->pltrusted =false;
29002901
$$ = (Node *)n;
29012902
}
2902-
|CREATEopt_trustedopt_proceduralLANGUAGEColId_or_Sconst
2903+
|CREATEopt_or_replaceopt_trustedopt_proceduralLANGUAGEColId_or_Sconst
29032904
HANDLERhandler_nameopt_inline_handleropt_validator
29042905
{
29052906
CreatePLangStmt *n = makeNode(CreatePLangStmt);
2906-
n->plname =$5;
2907-
n->plhandler =$7;
2908-
n->plinline =$8;
2909-
n->plvalidator =$9;
2910-
n->pltrusted =$2;
2907+
n->replace =$2;
2908+
n->plname =$6;
2909+
n->plhandler =$8;
2910+
n->plinline =$9;
2911+
n->plvalidator =$10;
2912+
n->pltrusted =$3;
29112913
$$ = (Node *)n;
29122914
}
29132915
;

‎src/include/nodes/parsenodes.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
1414
* Portions Copyright (c) 1994, Regents of the University of California
1515
*
16-
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.430 2010/02/16 22:34:57 tgl Exp $
16+
* $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.431 2010/02/23 22:51:43 tgl Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -1623,6 +1623,7 @@ typedef struct CreateTrigStmt
16231623
typedefstructCreatePLangStmt
16241624
{
16251625
NodeTagtype;
1626+
boolreplace;/* T => replace if already exists */
16261627
char*plname;/* PL name */
16271628
List*plhandler;/* PL call handler function (qual. name) */
16281629
List*plinline;/* optional inline function (qual. name) */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp