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

Commit7bff4c5

Browse files
committed
Now we are able to CREATE PROCEDURAL LANGUAGE (Thanks, Jan).
1 parent9db2992 commit7bff4c5

File tree

16 files changed

+638
-145
lines changed

16 files changed

+638
-145
lines changed

‎src/backend/commands/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# Makefile for commands
55
#
66
# IDENTIFICATION
7-
# $Header: /cvsroot/pgsql/src/backend/commands/Makefile,v 1.4 1997/08/31 11:40:12 vadim Exp $
7+
# $Header: /cvsroot/pgsql/src/backend/commands/Makefile,v 1.5 1997/10/28 14:54:43 vadim Exp $
88
#
99
#-------------------------------------------------------------------------
1010

@@ -19,7 +19,7 @@ CFLAGS+=$(INCLUDE_OPT)
1919

2020
OBJS = async.o creatinh.o command.o copy.o defind.o define.o\
2121
purge.o remove.o rename.o vacuum.o version.o view.o cluster.o\
22-
recipe.o explain.o sequence.o trigger.o
22+
recipe.o explain.o sequence.o trigger.o proclang.o
2323

2424
all: SUBSYS.o
2525

‎src/backend/commands/define.c

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.16 1997/09/08 21:42:38 momjian Exp $
12+
* $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.17 1997/10/28 14:54:46 vadim Exp $
1313
*
1414
* DESCRIPTION
1515
* The "DefineFoo" routines take the parse tree and pick out the
@@ -45,6 +45,7 @@
4545
#include<catalog/pg_operator.h>
4646
#include<catalog/pg_proc.h>
4747
#include<catalog/pg_type.h>
48+
#include<catalog/pg_language.h>
4849
#include<utils/syscache.h>
4950
#include<fmgr.h>/* for fmgr */
5051
#include<utils/builtins.h>/* prototype for textin() */
@@ -239,6 +240,8 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
239240
boolcanCache;
240241
boolreturnsSet;
241242

243+
boollanisPL= false;
244+
242245
/* The function returns a set of values, as opposed to a singleton. */
243246

244247

@@ -262,19 +265,59 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
262265
}
263266
else
264267
{
265-
elog(WARN,
268+
HeapTuplelanguageTuple;
269+
Form_pg_languagelanguageStruct;
270+
271+
/* Lookup the language in the system cache */
272+
languageTuple=SearchSysCacheTuple(LANNAME,
273+
PointerGetDatum(languageName),
274+
0,0,0);
275+
276+
if (!HeapTupleIsValid(languageTuple)) {
277+
278+
elog(WARN,
266279
"Unrecognized language specified in a CREATE FUNCTION: "
267-
"'%s'. Recognized languages are sql, C, and internal.",
280+
"'%s'. Recognized languages are sql, C, internal "
281+
"and the created procedural languages.",
268282
languageName);
283+
}
284+
285+
/* Check that this language is a PL */
286+
languageStruct= (Form_pg_language)GETSTRUCT(languageTuple);
287+
if (!(languageStruct->lanispl)) {
288+
elog(WARN,
289+
"Language '%s' isn't defined as PL",languageName);
290+
}
291+
292+
/*
293+
* Functions in untrusted procedural languages are
294+
* restricted to be defined by postgres superusers only
295+
*/
296+
if (languageStruct->lanpltrusted== false&& !superuser()) {
297+
elog(WARN,"Only users with Postgres superuser privilege "
298+
"are permitted to create a function in the '%s' "
299+
"language.",
300+
languageName);
301+
}
302+
303+
lanisPL= true;
304+
305+
/*
306+
* These are meaningless
307+
*/
308+
perbyte_cpu=percall_cpu=0;
309+
byte_pct=outin_ratio=100;
310+
canCache= false;
269311
}
270312

271313
interpret_AS_clause(languageName,stmt->as,&prosrc_str,&probin_str);
272314

273-
if (strcmp(languageName,"sql")!=0&& !superuser())
315+
if (strcmp(languageName,"sql")!=0&&lanisPL== false&&!superuser())
274316
elog(WARN,
275317
"Only users with Postgres superuser privilege are permitted "
276318
"to create a function "
277-
"in the '%s' language. Others may use the 'sql' language.",
319+
"in the '%s' language. Others may use the 'sql' language "
320+
"or the created procedural languages.",
278321
languageName);
279322
/* Above does not return. */
280323
else

‎src/backend/commands/proclang.c

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
/*-------------------------------------------------------------------------
2+
*
3+
* proclang.c--
4+
* PostgreSQL PROCEDURAL LANGUAGE support code.
5+
*
6+
*-------------------------------------------------------------------------
7+
*/
8+
#include<ctype.h>
9+
#include<string.h>
10+
#include"postgres.h"
11+
12+
#include"access/heapam.h"
13+
#include"catalog/catname.h"
14+
#include"catalog/pg_user.h"
15+
#include"catalog/pg_proc.h"
16+
#include"catalog/pg_language.h"
17+
#include"utils/syscache.h"
18+
#include"commands/proclang.h"
19+
#include"fmgr.h"
20+
21+
22+
staticvoid
23+
case_translate_language_name(constchar*input,char*output)
24+
{
25+
/*-------------------------------------------------------------------------
26+
Translate the input language name to lower case, except if it's C,
27+
translate to upper case.
28+
--------------------------------------------------------------------------*/
29+
inti;
30+
31+
for (i=0;i<NAMEDATALEN&&input[i]!='\0';++i)
32+
output[i]=tolower(input[i]);
33+
34+
output[i]='\0';
35+
36+
if (strcmp(output,"c")==0)
37+
output[0]='C';
38+
}
39+
40+
41+
/* ---------------------------------------------------------------------
42+
* CREATE PROCEDURAL LANGUAGE
43+
* ---------------------------------------------------------------------
44+
*/
45+
void
46+
CreateProceduralLanguage(CreatePLangStmt*stmt)
47+
{
48+
charlanguageName[NAMEDATALEN];
49+
HeapTuplelangTup;
50+
HeapTupleprocTup;
51+
52+
Oidtypev[8];
53+
charnulls[Natts_pg_language];
54+
Datumvalues[Natts_pg_language];
55+
Relationrdesc;
56+
HeapTupletup;
57+
TupleDesctupDesc;
58+
59+
inti;
60+
61+
/* ----------------
62+
* Check permission
63+
* ----------------
64+
*/
65+
if (!superuser())
66+
{
67+
elog(WARN,"Only users with Postgres superuser privilege are "
68+
"permitted to create procedural languages");
69+
}
70+
71+
/* ----------------
72+
* Translate the language name and check that
73+
* this language doesn't already exist
74+
* ----------------
75+
*/
76+
case_translate_language_name(stmt->plname,languageName);
77+
78+
langTup=SearchSysCacheTuple(LANNAME,
79+
PointerGetDatum(languageName),
80+
0,0,0);
81+
if (HeapTupleIsValid(langTup))
82+
{
83+
elog(WARN,"Language %s already exists",languageName);
84+
}
85+
86+
/* ----------------
87+
* Lookup the PL handler function and check that it is
88+
* of return type Opaque
89+
* ----------------
90+
*/
91+
memset(typev,0,sizeof(typev));
92+
procTup=SearchSysCacheTuple(PRONAME,
93+
PointerGetDatum(stmt->plhandler),
94+
UInt16GetDatum(0),
95+
PointerGetDatum(typev),
96+
0);
97+
if (!HeapTupleIsValid(procTup))
98+
{
99+
elog(WARN,"PL handler function %s() doesn't exist",
100+
stmt->plhandler);
101+
}
102+
if (((Form_pg_proc)GETSTRUCT(procTup))->prorettype!=InvalidOid)
103+
{
104+
elog(WARN,"PL handler function %s() isn't of return type Opaque",
105+
stmt->plhandler);
106+
}
107+
108+
/* ----------------
109+
* Insert the new language into pg_language
110+
* ----------------
111+
*/
112+
for (i=0;i<Natts_pg_language;i++)
113+
{
114+
nulls[i]=' ';
115+
values[i]= (Datum)NULL;
116+
}
117+
118+
i=0;
119+
values[i++]=PointerGetDatum(languageName);
120+
values[i++]=Int8GetDatum((bool)1);
121+
values[i++]=Int8GetDatum(stmt->pltrusted);
122+
values[i++]=ObjectIdGetDatum(procTup->t_oid);
123+
values[i++]= (Datum)fmgr(TextInRegProcedure,stmt->plcompiler);
124+
125+
rdesc=heap_openr(LanguageRelationName);
126+
127+
tupDesc=rdesc->rd_att;
128+
tup=heap_formtuple(tupDesc,values,nulls);
129+
130+
heap_insert(rdesc,tup);
131+
132+
heap_close(rdesc);
133+
return;
134+
}
135+
136+
137+
/* ---------------------------------------------------------------------
138+
* DROP PROCEDURAL LANGUAGE
139+
* ---------------------------------------------------------------------
140+
*/
141+
void
142+
DropProceduralLanguage(DropPLangStmt*stmt)
143+
{
144+
charlanguageName[NAMEDATALEN];
145+
HeapTuplelangTup;
146+
147+
Relationrdesc;
148+
HeapScanDescscanDesc;
149+
ScanKeyDatascanKeyData;
150+
HeapTupletup;
151+
152+
/* ----------------
153+
* Check permission
154+
* ----------------
155+
*/
156+
if (!superuser())
157+
{
158+
elog(WARN,"Only users with Postgres superuser privilege are "
159+
"permitted to drop procedural languages");
160+
}
161+
162+
/* ----------------
163+
* Translate the language name, check that
164+
* this language exist and is a PL
165+
* ----------------
166+
*/
167+
case_translate_language_name(stmt->plname,languageName);
168+
169+
langTup=SearchSysCacheTuple(LANNAME,
170+
PointerGetDatum(languageName),
171+
0,0,0);
172+
if (!HeapTupleIsValid(langTup))
173+
{
174+
elog(WARN,"Language %s doesn't exist",languageName);
175+
}
176+
177+
if (!((Form_pg_language)GETSTRUCT(langTup))->lanispl)
178+
{
179+
elog(WARN,"Language %s isn't a created procedural language",
180+
languageName);
181+
}
182+
183+
/* ----------------
184+
* Now scan pg_language and delete the PL tuple
185+
* ----------------
186+
*/
187+
rdesc=heap_openr(LanguageRelationName);
188+
189+
ScanKeyEntryInitialize(&scanKeyData,0,Anum_pg_language_lanname,
190+
F_NAMEEQ,PointerGetDatum(languageName));
191+
192+
scanDesc=heap_beginscan(rdesc,0,NowTimeQual,1,&scanKeyData);
193+
194+
tup=heap_getnext(scanDesc,0, (Buffer*)NULL);
195+
196+
if (!HeapTupleIsValid(tup))
197+
{
198+
elog(WARN,"Language with name '%s' not found",languageName);
199+
}
200+
201+
heap_delete(rdesc,&(tup->t_ctid));
202+
203+
heap_endscan(scanDesc);
204+
heap_close(rdesc);
205+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp