Merge pull request #378 from asarhaddon/test-macro-not-changing-function
[jackhill/mal.git] / plsql / env.sql
1 -- ---------------------------------------------------------
2 -- env.sql
3
4 CREATE OR REPLACE TYPE env_item FORCE AS OBJECT (
5 key varchar2(256),
6 val integer
7 ) FINAL;
8 /
9
10 CREATE OR REPLACE TYPE env_data FORCE IS TABLE OF env_item;
11 /
12
13 CREATE OR REPLACE TYPE env_T FORCE AS OBJECT (
14 idx integer,
15 outer_idx integer,
16 data env_data
17 );
18 /
19
20 CREATE OR REPLACE TYPE env_mem_T FORCE IS TABLE OF env_T;
21 /
22
23 CREATE OR REPLACE PACKAGE env_pkg IS
24 TYPE env_entry IS TABLE OF integer INDEX BY varchar2(256);
25 TYPE env_entry_table IS TABLE OF env_entry;
26
27 FUNCTION env_new(M IN OUT NOCOPY types.mal_table,
28 eeT IN OUT NOCOPY env_entry_table,
29 outer_idx integer DEFAULT NULL)
30 RETURN integer;
31 FUNCTION env_new(M IN OUT NOCOPY types.mal_table,
32 eeT IN OUT NOCOPY env_entry_table,
33 outer_idx integer,
34 binds integer,
35 exprs mal_vals)
36 RETURN integer;
37 FUNCTION env_set(M IN OUT NOCOPY types.mal_table,
38 eeT IN OUT NOCOPY env_entry_table,
39 eidx integer,
40 key integer,
41 val integer) RETURN integer;
42 FUNCTION env_find(M IN OUT NOCOPY types.mal_table,
43 eeT env_entry_table,
44 eidx integer,
45 key integer) RETURN integer;
46 FUNCTION env_get(M IN OUT NOCOPY types.mal_table,
47 eeT env_entry_table,
48 eidx integer,
49 key integer) RETURN integer;
50 END env_pkg;
51 /
52 show errors;
53
54
55 CREATE OR REPLACE PACKAGE BODY env_pkg IS
56
57 FUNCTION env_new(M IN OUT NOCOPY types.mal_table,
58 eeT IN OUT NOCOPY env_entry_table,
59 outer_idx integer DEFAULT NULL)
60 RETURN integer IS
61 eidx integer;
62 BEGIN
63 eeT.EXTEND();
64 eidx := eeT.COUNT();
65 eeT(eidx)('**OUTER**') := outer_idx;
66 RETURN eidx;
67 END;
68
69 FUNCTION env_new(M IN OUT NOCOPY types.mal_table,
70 eeT IN OUT NOCOPY env_entry_table,
71 outer_idx integer,
72 binds integer,
73 exprs mal_vals)
74 RETURN integer IS
75 eidx integer;
76 i integer;
77 bs mal_vals;
78 BEGIN
79 eeT.EXTEND();
80 eidx := eeT.COUNT();
81 eeT(eidx)('**OUTER**') := outer_idx;
82 IF binds IS NOT NULL THEN
83 bs := TREAT(M(binds) AS mal_seq_T).val_seq;
84 FOR i IN 1..bs.COUNT LOOP
85 IF TREAT(M(bs(i)) AS mal_str_T).val_str = '&' THEN
86 eeT(eidx)(TREAT(M(bs(i+1)) AS mal_str_T).val_str) :=
87 types.slice(M, exprs, i-1);
88 EXIT;
89 ELSE
90 eeT(eidx)(TREAT(M(bs(i)) AS mal_str_T).val_str) :=
91 exprs(i);
92 END IF;
93 END LOOP;
94 END IF;
95 RETURN eidx;
96 END;
97
98 FUNCTION env_set(M IN OUT NOCOPY types.mal_table,
99 eeT IN OUT NOCOPY env_entry_table,
100 eidx integer,
101 key integer,
102 val integer) RETURN integer IS
103 k varchar2(256);
104 i integer;
105 cnt integer;
106 BEGIN
107 k := TREAT(M(key) AS mal_str_T).val_str;
108 eeT(eidx)(k) := val;
109 RETURN val;
110 END;
111
112 FUNCTION env_find(M IN OUT NOCOPY types.mal_table,
113 eeT env_entry_table,
114 eidx integer,
115 key integer) RETURN integer IS
116 k varchar2(256);
117 cnt integer;
118 BEGIN
119 k := TREAT(M(key) AS mal_str_T).val_str;
120 IF eeT(eidx).EXISTS(k) THEN
121 RETURN eidx;
122 ELSIF eeT(eidx)('**OUTER**') IS NOT NULL THEN
123 RETURN env_find(M, eeT, eeT(eidx)('**OUTER**'), key);
124 ELSE
125 RETURN NULL;
126 END IF;
127 END;
128
129 FUNCTION env_get(M IN OUT NOCOPY types.mal_table,
130 eeT env_entry_table,
131 eidx integer,
132 key integer) RETURN integer IS
133 found integer;
134 k varchar2(256);
135 BEGIN
136 found := env_find(M, eeT, eidx, key);
137 k := TREAT(M(key) AS mal_str_T).val_str;
138 IF found IS NOT NULL THEN
139 RETURN eeT(found)(k);
140 ELSE
141 raise_application_error(-20005,
142 '''' || k || ''' not found', TRUE);
143 END IF;
144 END;
145
146 END env_pkg;
147 /
148 show errors;