]> granicus.if.org Git - postgresql/blob - src/bin/scripts/createlang.sh
Privileges on functions and procedural languages
[postgresql] / src / bin / scripts / createlang.sh
1 #! /bin/sh
2 #-------------------------------------------------------------------------
3 #
4 # createlang --
5 #   Install a procedural language in a database
6 #
7 # Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
8 # Portions Copyright (c) 1994, Regents of the University of California
9 #
10 # $Header: /cvsroot/pgsql/src/bin/scripts/Attic/createlang.sh,v 1.34 2002/02/18 23:11:30 petere Exp $
11 #
12 #-------------------------------------------------------------------------
13
14 CMDNAME=`basename "$0"`
15 PATHNAME=`echo $0 | sed "s,$CMDNAME\$,,"`
16
17 PSQLOPT=
18 dbname=
19 langname=
20 list=
21 showsql=
22 PGLIB=
23
24 # Check for echo -n vs echo \c
25
26 if echo '\c' | grep -s c >/dev/null 2>&1
27 then
28     ECHO_N="echo -n"
29     ECHO_C=""
30 else
31     ECHO_N="echo"
32     ECHO_C='\c'
33 fi
34
35
36
37 # ----------
38 # Get options, language name and dbname
39 # ----------
40 while [ "$#" -gt 0 ]
41 do
42     case "$1" in 
43         --help|-\?)
44                 usage=t
45                 break
46                 ;;
47         --list|-l)
48                 list=t
49                 ;;
50 # options passed on to psql
51         --host|-h)
52                 PSQLOPT="$PSQLOPT -h $2"
53                 shift;;
54         -h*)
55                 PSQLOPT="$PSQLOPT $1"
56                 ;;
57         --host=*)
58                 PSQLOPT="$PSQLOPT -h "`echo $1 | sed 's/^--host=//'`
59                 ;;
60         --port|-p)
61                 PSQLOPT="$PSQLOPT -p $2"
62                 shift;;
63         -p*)
64                 PSQLOPT="$PSQLOPT $1"
65                 ;;
66         --port=*)
67                 PSQLOPT="$PSQLOPT -p "`echo $1 | sed 's/^--port=//'`
68                 ;;
69         --username|-U)
70                 PSQLOPT="$PSQLOPT -U $2"
71                 shift;;
72         -U*)
73                 PSQLOPT="$PSQLOPT $1"
74                 ;;
75         --username=*)
76                 PSQLOPT="$PSQLOPT -U "`echo $1 | sed 's/^--username=//'`
77                 ;;
78         --password|-W)
79                 PSQLOPT="$PSQLOPT -W"
80                 ;;
81         --dbname|-d)
82                 dbname="$2"
83                 shift;;
84         -d*)
85                 dbname=`echo "$1" | sed 's/^-d//'`
86                 ;;
87         --dbname=*)
88                 dbname=`echo "$1" | sed 's/^--dbname=//'`
89                 ;;
90 # misc options
91         --pglib|-L)
92                 PGLIB="$2"
93                 shift;;
94         -L*)
95                 PGLIB=`echo "$1" | sed 's/^-L//'`
96                 ;;
97         --pglib=*)
98                 PGLIB=`echo "$1" | sed 's/^--pglib=//'`
99                 ;;
100         --echo|-e)
101                 showsql=yes
102                 ;;
103
104         -*)
105                 echo "$CMDNAME: invalid option: $1" 1>&2
106                 echo "Try '$CMDNAME --help' for more information." 1>&2
107                 exit 1
108                 ;;
109          *)
110                 if [ "$list" != "t" ]
111                 then    langname="$1"
112                         if [ "$2" ]
113                         then
114                                 shift
115                                 dbname="$1"
116                         fi
117                 else    dbname="$1"
118                 fi
119                 if [ "$#" -ne 1 ]; then
120                         echo "$CMDNAME: invalid option: $2" 1>&2
121                         echo "Try '$CMDNAME --help' for more information." 1>&2
122                         exit 1
123                 fi
124                 ;;
125     esac
126     shift
127 done
128
129 if [ -n "$usage" ]; then        
130         echo "$CMDNAME installs a procedural language into a PostgreSQL database."
131         echo
132         echo "Usage:"
133         echo "  $CMDNAME [options] langname [dbname]"
134         echo
135         echo "Options:"
136         echo "  -h, --host=HOSTNAME             Database server host"
137         echo "  -p, --port=PORT                 Database server port"
138         echo "  -U, --username=USERNAME         Username to connect as"
139         echo "  -W, --password                  Prompt for password"
140         echo "  -d, --dbname=DBNAME             Database to install language in"
141         echo "  -L, --pglib=DIRECTORY           Find language interpreter file in DIRECTORY"
142         echo "  -l, --list                      Show a list of currently installed languages"
143         echo
144         echo "Report bugs to <pgsql-bugs@postgresql.org>."
145         exit 0
146 fi
147
148
149 if [ -z "$dbname" ]; then
150         if [ "$PGUSER" ]; then
151                 dbname="$PGUSER"
152         else
153                 dbname=`${PATHNAME}pg_id -u -n`
154         fi
155         [ "$?" -ne 0 ] && exit 1
156 fi
157
158
159 # ----------
160 # List option, doesn't need langname
161 # ----------
162 if [ "$list" ]; then
163         sqlcmd="SELECT lanname as \"Name\", lanpltrusted as \"Trusted?\" FROM pg_language WHERE lanispl = TRUE;"
164         if [ "$showsql" = yes ]; then
165                 echo "$sqlcmd"
166         fi
167         ${PATHNAME}psql $PSQLOPT -d "$dbname" -P 'title=Procedural languages' -c "$sqlcmd"
168         exit $?
169 fi
170
171
172 # ----------
173 # We can't go any farther without a langname
174 # ----------
175 if [ -z "$langname" ]; then
176         echo "$CMDNAME: missing required argument language name" 1>&2
177         echo "Try '$CMDNAME --help' for help." 1>&2
178         exit 1
179 fi
180
181 # ----------
182 # Check that we have PGLIB
183 # ----------
184 if [ -z "$PGLIB" ]; then
185         PGLIB='$libdir'
186 fi
187
188 # ----------
189 # Check if supported and set related values
190 # ----------
191
192 langname=`echo "$langname" | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
193
194 case "$langname" in
195         plpgsql)
196                 trusted="TRUSTED "
197                 handler="plpgsql_call_handler"
198                 object="plpgsql"
199                 ;;
200         pltcl)
201                 trusted="TRUSTED "
202                 handler="pltcl_call_handler"
203                 object="pltcl"
204                 ;;
205         pltclu)
206                 trusted=""
207                 handler="pltclu_call_handler"
208                 object="pltcl"
209                 ;;
210         plperl)
211                 trusted="TRUSTED "
212                 handler="plperl_call_handler"
213                 object="plperl"
214                 ;;
215         plperlu)
216                 trusted=""
217                 handler="plperl_call_handler"
218                 object="plperl"
219                 ;;
220         plpython)
221                 trusted="TRUSTED "
222                 handler="plpython_call_handler"
223                 object="plpython"
224                 ;;
225         *)
226                 echo "$CMDNAME: unsupported language \"$langname\"" 1>&2
227                 echo "Supported languages are plpgsql, pltcl, pltclu, plperl, plperlu, and plpython." 1>&2
228                 exit 1
229         ;;
230 esac
231
232
233 PSQL="${PATHNAME}psql -A -t -q $PSQLOPT -d $dbname -c"
234
235 # ----------
236 # Make sure the language isn't already installed
237 # ----------
238 sqlcmd="SELECT oid FROM pg_language WHERE lanname = '$langname';"
239 if [ "$showsql" = yes ]; then
240         echo "$sqlcmd"
241 fi
242 res=`$PSQL "$sqlcmd"`
243 if [ "$?" -ne 0 ]; then
244         echo "$CMDNAME: external error" 1>&2
245         exit 1
246 fi
247 if [ -n "$res" ]; then
248         echo "$CMDNAME: language \"$langname\" is already installed in database $dbname" 1>&2
249         # separate exit status for "already installed"
250         exit 2
251 fi
252
253 # ----------
254 # Check whether the call handler exists
255 # ----------
256 sqlcmd="SELECT oid FROM pg_proc WHERE proname = '$handler' AND prorettype = 0 AND pronargs = 0;"
257 if [ "$showsql" = yes ]; then
258         echo "$sqlcmd"
259 fi
260 res=`$PSQL "$sqlcmd"`
261 if [ -n "$res" ]; then
262         handlerexists=yes
263 else
264         handlerexists=no
265 fi
266
267 # ----------
268 # Create the call handler and the language
269 # ----------
270 if [ "$handlerexists" = no ]; then
271         sqlcmd="CREATE FUNCTION \"$handler\" () RETURNS OPAQUE AS '$PGLIB/${object}' LANGUAGE C;"
272         if [ "$showsql" = yes ]; then
273                 echo "$sqlcmd"
274         fi
275         $PSQL "$sqlcmd"
276         if [ "$?" -ne 0 ]; then
277                 echo "$CMDNAME: language installation failed" 1>&2
278                 exit 1
279         fi
280 fi
281
282 sqlcmd="CREATE ${trusted}LANGUAGE \"$langname\" HANDLER \"$handler\";"
283 if [ "$showsql" = yes ]; then
284         echo "$sqlcmd"
285 fi
286 $PSQL "$sqlcmd"
287 if [ "$?" -ne 0 ]; then
288         echo "$CMDNAME: language installation failed" 1>&2
289         exit 1
290 fi
291
292 if test -n "$trusted"; then
293     sqlcmd="GRANT USAGE ON LANGUAGE \"$langname\" TO PUBLIC;"
294     if [ "$showsql" = yes ]; then
295         echo "$sqlcmd"
296     fi
297     $PSQL "$sqlcmd"
298     if [ "$?" -ne 0 ]; then
299         echo "$CMDNAME: language installation failed" 1>&2
300         exit 1
301     fi
302 fi
303 exit 0