DBA Data[Home] [Help]

PACKAGE BODY: SYS.STANDARD

Source


1 package body STANDARD is         -- careful on this line; SED edit occurs!
2 
3 subtype Cursor_Handle is binary_integer range 0..255;
4 
5 INVALID_USERENV_PARAMETER exception;
6 pragma EXCEPTION_INIT(INVALID_USERENV_PARAMETER, -2003);
7 
8 -- This exception is used by several sped-up STANDARD functions' ICDs to
9 -- indicate that the ICD is unable to compute the result, and that SQL should
10 -- be used to do the computation.
11 ICD_UNABLE_TO_COMPUTE exception;
12 pragma EXCEPTION_INIT(ICD_UNABLE_TO_COMPUTE, -6594);
13 
14 -- icds
15 
16   function pesxlt(ch VARCHAR2 CHARACTER SET ANY_CS,
17                   cpy VARCHAR2 CHARACTER SET ch%CHARSET,
18                   frm VARCHAR2 CHARACTER SET ch%CHARSET,
19                   too VARCHAR2 CHARACTER SET ch%CHARSET)
20         return VARCHAR2 CHARACTER SET ch%CHARSET;
21     pragma interface (c,pesxlt);
22 
23 -- trig fns
24   function pesxco(c VARCHAR2 CHARACTER SET ANY_CS, format VARCHAR2) return raw;
25     pragma interface (c,pesxco);
26 
27   function pesxup(ch VARCHAR2 CHARACTER SET ANY_CS, format VARCHAR2)
28         return VARCHAR2 CHARACTER SET ch%CHARSET;
29     pragma interface (c,pesxup);
30 
31   function pesxlo(ch VARCHAR2 CHARACTER SET ANY_CS, format VARCHAR2)
32         return VARCHAR2 CHARACTER SET ch%CHARSET;
33     pragma interface (c,pesxlo);
34 
35   function pesxcp(ch VARCHAR2 CHARACTER SET ANY_CS, format VARCHAR2)
36         return VARCHAR2 CHARACTER SET ch%CHARSET;
37     pragma interface (c,pesxcp);
38 
39 -- end of NLS icds
40 
41 -- begin trusted icds
42 -- Comparisons
43 -- Conversions
44 --  function peslts(label MLSLABEL,format VARCHAR2) return VARCHAR2;
45 --    pragma interface (c,peslts);
46 --  function pesstl(label varchar2,format VARCHAR2) return MLSLABEL;
47 --    pragma interface (c,pesstl);
48 -- end trusted icds
49 -----------------------------------------------------------
50 
51   function sqlerrm return varchar2 is
52     n1 number;
53   begin
54     n1 := sqlcode;
55     return sqlerrm(n1);
56   end sqlerrm;
57 
58   function pessdx (ch VARCHAR2 CHARACTER SET ANY_CS)
59         return VARCHAR2 CHARACTER SET ch%CHARSET;
60     pragma interface (c,pessdx);
61 
62   -- Special: if the ICD raises ICD_UNABLE_TO_COMPUTE, that means we should do
63   -- the old 'select soundex(...) from dual;' thing.  This allows us to do the
64   -- SELECT from PL/SQL rather than having to do it from C (within the ICD.)
65   function SOUNDEX(ch VARCHAR2 CHARACTER SET ANY_CS)
66         return VARCHAR2 CHARACTER SET ch%CHARSET is
67     c VARCHAR2(2000) CHARACTER SET ch%CHARSET;
68   begin
69     c := pessdx(ch);
70     return c;
71   exception
72     when ICD_UNABLE_TO_COMPUTE then
73       select soundex(ch) into c from sys.dual;
74       return c;
75   end SOUNDEX;
76 
77   function TRANSLATE(STR1 VARCHAR2 CHARACTER SET ANY_CS,
78                      SRC VARCHAR2 CHARACTER SET STR1%CHARSET,
79                      DEST VARCHAR2 CHARACTER SET STR1%CHARSET)
80         return VARCHAR2 CHARACTER SET STR1%CHARSET is
81   begin
82     if str1 is null then return str1; else
83         -- The substr and concat in arg list to pesxlt is done to
84         -- allocate a modifiable COPY of the first arg, STR1. This
85         -- operation is a complete cheat, because we pass the copy
86         -- as an IN parm, and modify it on the sly.
87     return pesxlt(STR1, substr(str1,1,1) || substr(str1,2),
88                            SRC, DEST);
89     end if;
90   end TRANSLATE;
91 
92   function 'REM' (LEFT NUMBER, RIGHT NUMBER) return NUMBER is
93   begin
94     return (LEFT - (trunc(LEFT / RIGHT) * RIGHT));
95   end;
96 
97   function 'REM' (LEFT BINARY_FLOAT, RIGHT BINARY_FLOAT)
98     return BINARY_FLOAT is
99   begin
100     return (LEFT - (trunc(LEFT / RIGHT) * RIGHT));
101   end;
102 
103   function 'REM' (LEFT BINARY_DOUBLE, RIGHT BINARY_DOUBLE)
104     return BINARY_DOUBLE is
105   begin
106     return (LEFT - (trunc(LEFT / RIGHT) * RIGHT));
107   end;
108 
109 -- Just call the other to_char with a null format string.
110 -- Perhaps this can be done more intelligently in the future. JEM 3/14/90.
111 --  function TO_CHAR(LEFT NUMBER)        return varchar2 is
112 --  begin
113 --    return TO_CHAR(LEFT, '');
114 --  end TO_CHAR;
115 
116 -- Added 3/16/90 by JEM.
117  function TO_NUMBER(LEFT NUMBER) return NUMBER is
118  begin
119    return(LEFT);
120  end to_number;
121 
122  function TO_BINARY_FLOAT (LEFT BINARY_FLOAT) return BINARY_FLOAT is
123  begin
124    return(LEFT);
125  end TO_BINARY_FLOAT;
126 
127  function TO_BINARY_DOUBLE(LEFT BINARY_DOUBLE) return BINARY_DOUBLE is
128  begin
129    return(LEFT);
130  end TO_BINARY_DOUBLE;
131 
132  function 'IS NAN' (N NUMBER) RETURN BOOLEAN is
133  begin
134    if N IS NULL then
135      return NULL;
136    else
137      return FALSE;
138    end if;
139  end 'IS NAN';
140 
141  function 'IS NOT NAN' (N NUMBER) RETURN BOOLEAN is
142  begin
143    if N IS NULL then
144      return NULL;
145    else
146      return TRUE;
147    end if;
148  end 'IS NOT NAN';
149 
150  function NANVL(n1 NUMBER, n2 NUMBER) return NUMBER is
151  begin
152    return (n1);
153  end NANVL;
154 
155  function NANVL(f1 BINARY_FLOAT, f2 BINARY_FLOAT) return BINARY_FLOAT is
156  begin
157    if f1 is nan then return (f2); else return (f1); end if;
158  end NANVL;
159 
160  function NANVL(d1 BINARY_DOUBLE, d2 BINARY_DOUBLE) return BINARY_DOUBLE is
161  begin
162    if d1 is nan then return (d2); else return (d1); end if;
163  end NANVL;
164 
165  function TO_DATE(LEFT NUMBER, RIGHT VARCHAR2) return DATE IS
166  begin
167    return (TO_DATE(TO_char(LEFT), RIGHT));
168  end TO_DATE;
169 
170   function UID return PLS_INTEGER is
171   i pls_integer;
172   begin
173         select uid into i from sys.dual;
174         return i;
175   end;
176 
177   function USER return varchar2 is
178   c varchar2(255);
179   begin
180         select user into c from sys.dual;
181         return c;
182   end;
183 
184 
185   function pesuen(envstr VARCHAR2) return VARCHAR2;
186     pragma interface (c,pesuen);
187 
188   -- Special: if the ICD raises ICD_UNABLE_TO_COMPUTE, that means we should do
189   -- the old 'select userenv(...) from dual;' thing.  This allows us to do the
190   -- select from PL/SQL rather than having to do it from C (within the ICD.)
191   function USERENV (envstr varchar2) return varchar2 is
192   c varchar2(255);
193   begin
194     c := upper(envstr);
195 
196     -- Gaak: we can't replace the following with a single block of code based
197     -- around 'USERENV(c)' because passing USERENV() anything but a string
198     -- literal parameter result in ORA-2003: Invalid USERENV parameter!  This
199     -- also means that we must manually update this file whenever RDBMS adds a
200     -- new option.
201     if c = 'COMMITSCN' then
202       raise USERENV_COMMITSCN_ERROR;
203     elsif c = 'TERMINAL' then
204       begin
205         c := pesuen(c);
206       exception
207         when ICD_UNABLE_TO_COMPUTE then
208           select userenv('TERMINAL') into c from sys.dual;
209       end;
210     elsif c = 'ENTRYID' then
211       begin
212         c := pesuen(c);
213       exception
214         when ICD_UNABLE_TO_COMPUTE then
215           select userenv('ENTRYID') into c from sys.dual;
216       end;
217     elsif c = 'SESSIONID' then
218       begin
219         c := pesuen(c);
220       exception
221         when ICD_UNABLE_TO_COMPUTE then
222           select userenv('SESSIONID') into c from sys.dual;
223       end;
224     elsif c = 'LANGUAGE' then
225       begin
226         c := pesuen(c);
227       exception
228         when ICD_UNABLE_TO_COMPUTE then
229           select userenv('LANGUAGE') into c from sys.dual;
230       end;
231     elsif c = 'LANG' then
232       begin
233         c := pesuen(c);
234       exception
235         when ICD_UNABLE_TO_COMPUTE then
236           select userenv('LANG') into c from sys.dual;
237       end;
238     elsif c = 'INSTANCE' then
239       begin
240         c := pesuen(c);
241       exception
242         when ICD_UNABLE_TO_COMPUTE then
243           select userenv('INSTANCE') into c from sys.dual;
244       end;
245     elsif c = 'CLIENT_INFO' then
246       begin
247         c := pesuen(c);
248       exception
249         when ICD_UNABLE_TO_COMPUTE then
250           select userenv('CLIENT_INFO') into c from sys.dual;
251       end;
252     elsif c = 'ISDBA' then
253       begin
254         c := pesuen(c);
255       exception
256         when ICD_UNABLE_TO_COMPUTE then
257           select userenv('ISDBA') into c from sys.dual;
258       end;
259     elsif c = 'SCHEMAID' then
260       begin
261         c := pesuen(c);
262       exception
263         when ICD_UNABLE_TO_COMPUTE then
264           select userenv('SCHEMAID') into c from sys.dual;
265       end;
266     elsif c = 'SID' then
267       begin
268         c := pesuen(c);
269       exception
270         when ICD_UNABLE_TO_COMPUTE then
271           select userenv('SID') into c from sys.dual;
272       end;
273     elsif c = 'PID' then
274       begin
275         c := pesuen(c);
276       exception
277         when ICD_UNABLE_TO_COMPUTE then
278           select userenv('PID') into c from sys.dual;
279       end;
280     else
281       raise INVALID_USERENV_PARAMETER;
282     end if;
283     return c;
284   end;
285 
286 -- Trusted*Oracle additions
287 
288   Function ROWLABEL return MLSLABEL is
289         begin return null; end;
290 -- removed - now builtin's
291 
292 --  Function TO_CHAR(label MLSLABEL, format varchar2 := '')
293 --       return VARCHAR2 is
294 --    begin return peslts(label,format); end;
295 --
296 --  Function TO_LABEL(label varchar2, format varchar2 := '')
297 --       return MLSLABEL is
298 --    begin return pesstl(label,format); end;
299 
300 -- group functions
301   Function LUB (label MLSLABEL) return MLSLABEL is
302         begin return null; end;
303   Function GLB (label MLSLABEL) return MLSLABEL is
304         begin return null; end;
305 
306 -- end of Trusted*Oracle additions
307 
308 
309 -- beginning of NLS routines
310 -- replaced with new versions 6/3/92 JEM
311 
312   function NLSSORT(c VARCHAR2 CHARACTER SET ANY_CS) return RAW is
313   begin
314     return pesxco(c,'');
315   end NLSSORT;
316 
317   function NLS_UPPER(ch VARCHAR2 CHARACTER SET ANY_CS)
318         return VARCHAR2 CHARACTER SET ch%CHARSET is
319   begin
320     return pesxup(ch,'');
321   end NLS_UPPER;
322 
323   function NLS_LOWER(ch VARCHAR2 CHARACTER SET ANY_CS)
324         return VARCHAR2 CHARACTER SET ch%CHARSET is
325   begin
326     return pesxlo(ch,'');
327   end NLS_LOWER;
328 
329   function NLS_INITCAP(ch VARCHAR2 CHARACTER SET ANY_CS)
330         return VARCHAR2 CHARACTER SET ch%CHARSET is
331   begin
332     return pesxcp(ch,'');
333   end NLS_INITCAP;
334 
335   function NLS_CHARSET_NAME(csetid PLS_INTEGER)
336     return VARCHAR2 is
337    v varchar2(2000);
338   begin
339    select nls_charset_name(csetid) into v from sys.dual;
340    return v;
341   end NLS_CHARSET_NAME;
342 
343   function NLS_CHARSET_ID(csetname VARCHAR2)
344     return PLS_INTEGER is
345    i PLS_INTEGER;
346   begin
347    select nls_charset_id(csetname) into i from sys.dual;
348    return i;
349   end NLS_CHARSET_ID;
350 
351   function NLS_CHARSET_DECL_LEN(bytecnt NUMBER, csetid NUMBER)
352     return PLS_INTEGER is
353    i PLS_INTEGER;
354   begin
355    select nls_charset_decl_len(bytecnt, csetid) into i from sys.dual;
356    return i;
357   end NLS_CHARSET_DECL_LEN;
358 -- end of NLS routines
359 
360 
361 -- DUMP and VSIZE are now not allowed in non-sql plsql, has code to forbid
362 -- it there, and is defined as a builtin in stdspc. The body will not be
363 -- called in plsql.
364 --- CMB
365 ----
366 -- dump
367 -- dump( expr [,display_format[,start_pos[,length]]]) return varchar2
368 -- how large should the plsql varchar2 string be
369 --
370 
371 -- why do we need these dummy bodies for LEVEL and ROWNUM?
372 
373   function LEVEL return NUMBER is
374         begin return 0.0; end;
375 
376   function ROWNUM return NUMBER is
377         begin return 0.0; end;
378 
379 --
380 -- ACOS, ASIN, ATAN, ATAN2
381 --   These functions return NULL if any of the inputs are NULL
382 --
383   function pesacos(n NUMBER) return NUMBER;
384     pragma interface (c,pesacos);
385 
386   function pesasin(n NUMBER) return NUMBER;
387     pragma interface (c,pesasin);
388 
389   function pesatn2(x NUMBER, y NUMBER) return NUMBER;
390     pragma interface (c,pesatn2);
391 
392   function ACOS(n NUMBER) return NUMBER is
393   begin
394     if (n > 1) or (n < -1) then raise VALUE_ERROR; end if;
395     return pesacos(n);
396   end ACOS;
397 
398   function ASIN(n NUMBER) return NUMBER is
399   begin
400     if (n > 1) or (n < -1) then raise VALUE_ERROR; end if;
401     return pesasin(n);
402   end ASIN;
403 
404   function ATAN2(x NUMBER, y NUMBER) return NUMBER is
405   begin
406     if ((x = 0) and (y = 0)) then raise VALUE_ERROR; end if;
407     return pesatn2(x, y);
408   end ATAN2;
409 
410 --****************************************************************
411 
412   -- This body is required, and will be called
413   function NVL (B1 "<REF_CURSOR_1>", B2 "<REF_CURSOR_1>")
414         return "<REF_CURSOR_1>" is
415   begin
416     if (B1 IS NULL) then return(B2); else return(B1); end if;
417   end NVL;
418 
419   /* these are special internal functions
420      they are potential dangerous and not to be used by customers */
421   function "SYS$LOB_REPLICATION" (x in blob) return blob
422         is begin return x; end;
423   function "SYS$LOB_REPLICATION" (x in clob character set any_cs)
424     return clob character set x%charset
425   is begin return x; end;
426 
427   --  Generic SQL DDL routine
428   --
429   --  This used to use plzopn, plzosq, etc. declared above;  now we use a
430   --  single bundled call.  Move these defs here so new ICD will not disturb
431   --  the ordering of the list.
432 
433   FUNCTION plzsql(stmt VARCHAR2) RETURN binary_integer;
434   PRAGMA interface (c,plzsql);
435 
436   procedure SQL_DDL(Stmt VARCHAR2) is
437          rc Binary_Integer;
438          DDL_ERROR exception;
439   Begin
440          rc := plzsql(Stmt);
441          if ( rc IS NOT NULL ) then
442                 RAISE DDL_ERROR;
443          end if;
444   End;
445 
446   --  SQL Transaction routines
447 
448   procedure SET_TRANSACTION_USE (vc varchar2) is
449   Begin
450          SQL_DDL('SET TRANSACTION USE ROLLBACK SEGMENT ' || vc);
451   End;
452 
453   procedure COMMIT is
454   Begin
455          SQL_DDL('COMMIT');
456   End;
457 
458   procedure COMMIT_CM (vc varchar2) is
459   Begin
460     -- bug13944958:
461     -- COMMIT_CM procedure takes the input argument "vs" as the comment string
462     -- to execute the SQL DDL "COMMIT work comment 'vc'" statement.
463     -- The input comment string to the COMMIT statement is vulnerable to
464     -- SQL injection because it may contain single-quotes.
465     -- Before we manually quote the comment string, we need to escape any
466     -- embedded quotes first.
470 
467     SQL_DDL('COMMIT work comment ' || '''' ||
468             replace(vc, '''', '''''') || '''');
469   End;
471   procedure ROLLBACK_NR is
472   Begin
473          SQL_DDL('ROLLBACK');
474   End;
475 
476   procedure ROLLBACK_SV(Save_Point CHAR) is
477   Begin
478          SQL_DDL('ROLLBACK TO ' || Save_Point);
479   End;
480 
481   procedure SAVEPOINT(Save_Point CHAR) is
482   begin
483          SQL_DDL('SAVEPOINT ' || Save_Point);
484   end;
485 
486 
487 ------ Datetime code starts here ------
488 
489 
490 -- functions to create intervals from constituent parts.
491 
492   function pesn2ymi(numerator number, units number)
493     return yminterval_unconstrained;
494   pragma interface (c,pesn2ymi);
495   function pesn2dsi(numerator number, units number)
496      return dsinterval_unconstrained;
497   pragma interface (c,pesn2dsi);
498 
499   function NUMTOYMINTERVAL(numerator number, units number)
500      return yminterval_unconstrained
501      is begin return pesn2ymi(numerator,units); end;
502   function NUMTODSINTERVAL(numerator number, units number)
503      return dsinterval_unconstrained
504      is begin return pesn2dsi(numerator,units); end;
505 
506  function NUMTOYMINTERVAL(numerator number, units varchar2 character set any_cs)
507      return yminterval_unconstrained
508      IS unitno NUMBER := 0;
509         unitstr VARCHAR2(5) character set units%charset := upper(trim(units));
510      begin
511      IF (unitstr = 'YEAR')  THEN unitno := 1;
512      elsif (unitstr = 'MONTH') THEN unitno := 2;
513      END IF;
514      return pesn2ymi(numerator,unitno);
515      -- IF unitno := 0 core will RAISE correct error
516      end;
517 
518  function NUMTODSINTERVAL(numerator number, units varchar2 character set any_cs)
519      return dsinterval_unconstrained
520      IS unitno NUMBER := 0;
521         unitstr VARCHAR2(6) character set units%charset := upper(trim(units));
522      begin
523      IF (unitstr = 'DAY') THEN  unitno := 1;
524      elsif (unitstr = 'HOUR') THEN unitno := 2;
525      elsif (unitstr = 'MINUTE') THEN  unitno := 3;
526      elsif (unitstr = 'SECOND') THEN unitno := 4;
527      END IF;
528      return pesn2dsi(numerator,unitno);
529      -- IF unitno = 0 core will RAISE correct error
530      end;
531 
532   function pessdt return DATE;
533     pragma interface (c,pessdt);
534 
535   -- Bug 1287775: back to calling ICD.
536   -- Special: if the ICD raises ICD_UNABLE_TO_COMPUTE, that means we should do
537   -- the old 'SELECT SYSDATE FROM DUAL;' thing.  This allows us to do the
538   -- SELECT from PL/SQL rather than having to do it from C (within the ICD.)
539   function sysdate return date is
540     d date;
541   begin
542     d := pessdt;
543     return d;
544   exception
545     when ICD_UNABLE_TO_COMPUTE then
546       select sysdate into d from sys.dual;
547       return d;
548   end;
549 
550   function pesguid return RAW;
551     pragma interface (c,pesguid);
552 
553   function SYS_GUID return raw is
554     c raw(16);
555   begin
556     c := pesguid;
557     return c;
558   exception
559     when ICD_UNABLE_TO_COMPUTE then
560         select sys_guid() into c from sys.dual;
561         return c;
562   end;
563 
564   function pessysctx2(namespace varchar2, attribute varchar2) return varchar2;
565     pragma interface (c,pessysctx2);
566 
567   -- Special: if the ICD raises ICD_UNABLE_TO_COMPUTE, that means we should do
568   -- the old 'select sys_context(...) from dual;' thing.  This allows us to do
569   -- the select from PL/SQL rather than having to do it from C (within the ICD.)
570   function SYS_CONTEXT(namespace varchar2, attribute varchar2)
571     return varchar2 is
572   c varchar2(4000);
573   BEGIN
574     c := pessysctx2(namespace, attribute);
575     return c;
576   exception
577     when ICD_UNABLE_TO_COMPUTE then
578       select sys_context(namespace,attribute) into c from sys.dual;
579       return c;
580   end;
581 
582 -- time zone functions
583 
584   function pessts return timestamp_tz_unconstrained;
585     pragma interface (c,pessts);
586 
587   -- Special: if the ICD raises ICD_UNABLE_TO_COMPUTE, that means we should do
588   -- the old 'SELECT systimestamp FROM dual;' thing.  This allows us to do the
589   -- SELECT from PL/SQL rather than having to do it from C (within the ICD.)
590   FUNCTION systimestamp RETURN timestamp_tz_unconstrained
591   IS  t timestamp_tz_unconstrained;
592   BEGIN
593     t := pessts;
594     RETURN t;
595   EXCEPTION
596     WHEN ICD_UNABLE_TO_COMPUTE THEN
597       SELECT systimestamp INTO t FROM sys.dual;
598       RETURN t;
599   END;
600 
601   function pesdbtz return varchar2;
602     pragma interface (c,pesdbtz);
603 
604   -- Special: if the ICD raises ICD_UNABLE_TO_COMPUTE, that means we should do
605   -- the old 'SELECT dbtimezone FROM dual;' thing.  This allows us to do the
606   -- SELECT from PL/SQL rather than having to do it from C (within the ICD.)
607   FUNCTION dbtimezone RETURN varchar2
608   IS  t VARCHAR2(75);                                -- == TZNMSTRLEN [2213965]
609   BEGIN
610     t := pesdbtz;
611     RETURN t;
612   EXCEPTION
616   END;
613     WHEN ICD_UNABLE_TO_COMPUTE THEN
614       SELECT dbtimezone INTO t FROM sys.dual;
615       RETURN t;
617 
618   FUNCTION localtimestamp RETURN timestamp_unconstrained
619   IS t timestamp_tz_unconstrained := current_timestamp;
620   BEGIN
621    RETURN (cast(t AS timestamp_unconstrained));
622   END;
623 
624   FUNCTION localtime RETURN time_unconstrained
625   IS t time_tz_unconstrained := current_time;
626   BEGIN
627    RETURN (cast(t AS time_unconstrained));
628   END;
629 
630   function pessysctx3(namespace varchar2, attribute varchar2,
631                       newoptional varchar2) return varchar2;
632     pragma interface (c,pessysctx3);
633 
634   -- Special: if the ICD raises ICD_UNABLE_TO_COMPUTE, that means we should do
635   -- the old 'select sys_context(...) from dual;' thing.  This allows us to do
636   -- the select from PL/SQL rather than having to do it from C (within the ICD.)
637   function SYS_CONTEXT(namespace varchar2, attribute varchar2,
638                        newoptional varchar2)
639     return varchar2 is
640   c varchar2(4000);
641   BEGIN
642     c := pessysctx3(namespace, attribute, newoptional);
643     return c;
644   exception
645     when ICD_UNABLE_TO_COMPUTE then
646       select sys_context(namespace,attribute,newoptional) into c from sys.dual;
647       return c;
648   end;
649 
650   function TO_NCLOB(cl CLOB CHARACTER SET ANY_CS) return NCLOB is
651   begin
652     return cl;
653   end;
654   function TO_CLOB(cl CLOB CHARACTER SET ANY_CS) return CLOB is
655   begin
656     return cl;
657   end;
658 
659   function NCHR(n INTEGER) return NVARCHAR2 is
660   begin
661     return CHR(n using NCHAR_CS);
662   end;
663 
664 -- REFs of opaque types are not yet supported.
665 --  function NVL (B1 REF "<OPAQUE_1>", B2 REF "<OPAQUE_1>")
666 --         return REF "<OPAQUE_1>" is
667 --  begin
668 --    if (B1 IS NULL) then return(B2); else return(B1); end if;
669 --  end NVL;
670 
671 
672 -- END OF PACKAGE standard
673 end;
674 
675