Skip to content

Commit 05da8ad

Browse files
authored
Merge pull request IvorySQL#1194 from pierreforstmann/dbms_lock
feature: add DBMS_LOCK
2 parents 3594725 + a4aa874 commit 05da8ad

7 files changed

Lines changed: 699 additions & 1 deletion

File tree

contrib/ivorysql_ora/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ OBJS = \
3030
src/merge/ora_merge.o \
3131
src/sysview/sysview_functions.o \
3232
src/xml_functions/ora_xml_functions.o \
33-
src/builtin_packages/dbms_utility/dbms_utility.o
33+
src/builtin_packages/dbms_utility/dbms_utility.o \
34+
src/builtin_packages/dbms_lock/dbms_lock.o
3435

3536
EXTENSION = ivorysql_ora
3637

@@ -76,6 +77,7 @@ ORA_REGRESS = \
7677
dbms_utility \
7778
ora_dbms_output \
7879
ora_ascii \
80+
dbms_lock \
7981
utl_file
8082

8183
SHLIB_LINK += -lxml2
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
--
2+
-- dbms_lock.sql
3+
--
4+
-- tests for DBMS_LOCK
5+
--
6+
call dbms_lock.sleep(1);
7+
create table handle(h text);
8+
--
9+
-- test DBMS_LOCK.S
10+
--
11+
begin;
12+
declare
13+
v_lockname varchar2(10) = 'LOCKS';
14+
v_handle text;
15+
v_rc int;
16+
begin
17+
dbms_lock.allocate_unique(v_lockname, v_handle);
18+
v_rc := dbms_lock.request(v_handle, dbms_lock.s_mode, 0);
19+
raise notice 'request rc=%', v_rc;
20+
assert v_rc = 0, format('DBMS_LOCK.request failed: rc=%s', v_rc);
21+
insert into handle values(v_handle);
22+
end;
23+
/
24+
NOTICE: request rc=0
25+
do
26+
$$
27+
declare
28+
v_lockmode text;
29+
begin
30+
select mode into v_lockmode from pg_locks where pid = pg_backend_pid() and locktype ='advisory' and mode = 'ShareLock';
31+
if not found then
32+
v_lockmode := 'not found';
33+
end if;
34+
raise notice 'mode=%', v_lockmode;
35+
end
36+
$$;
37+
NOTICE: mode=ShareLock
38+
--
39+
declare
40+
v_rc int;
41+
v_handle text;
42+
begin
43+
select h into v_handle from handle;
44+
v_rc := dbms_lock.release(v_handle);
45+
raise notice 'release rc=%', v_rc;
46+
assert v_rc = 0, format('DBMS_LOCK.release failed: rc=%s', v_rc);
47+
delete from handle;
48+
end;
49+
/
50+
NOTICE: release rc=0
51+
do
52+
$$
53+
declare
54+
v_lockmode text;
55+
begin
56+
select mode into v_lockmode from pg_locks where pid = pg_backend_pid() and locktype ='advisory' and mode = 'ShareLock';
57+
if not found then
58+
v_lockmode := 'not found';
59+
end if;
60+
raise notice 'mode=%', v_lockmode;
61+
end
62+
$$;
63+
NOTICE: mode=not found
64+
--
65+
commit;
66+
--
67+
-- test DBMS_LOCK.X
68+
--
69+
begin;
70+
declare
71+
v_lockname varchar2(10) = 'LOCKX';
72+
v_handle text;
73+
v_rc int;
74+
begin
75+
dbms_lock.allocate_unique(v_lockname, v_handle);
76+
v_rc := dbms_lock.request(v_handle, dbms_lock.x_mode, 0);
77+
raise notice 'request rc=%', v_rc;
78+
assert v_rc = 0, format('DBMS_LOCK.request failed: rc=%s', v_rc);
79+
insert into handle values(v_handle);
80+
end;
81+
/
82+
NOTICE: request rc=0
83+
do
84+
$$
85+
declare
86+
v_lockmode text;
87+
begin
88+
select mode into v_lockmode from pg_locks where pid = pg_backend_pid() and locktype='advisory' and mode = 'ExclusiveLock';
89+
if not found then
90+
v_lockmode := 'not found';
91+
end if;
92+
raise notice 'mode=%', v_lockmode;
93+
end
94+
$$;
95+
NOTICE: mode=ExclusiveLock
96+
--
97+
declare
98+
v_rc int;
99+
v_handle text;
100+
begin
101+
select h into v_handle from handle;
102+
v_rc := dbms_lock.release(v_handle);
103+
raise notice 'release rc=%', v_rc;
104+
assert v_rc = 0, format('DBMS_LOCK.release failed: rc=%s', v_rc);
105+
delete from handle;
106+
end;
107+
/
108+
NOTICE: release rc=0
109+
do
110+
$$
111+
declare
112+
v_lockmode text ;
113+
begin
114+
select mode into v_lockmode from pg_locks where pid = pg_backend_pid() and locktype = 'advisory' and mode = 'ExclusiveLock';
115+
if not found then
116+
v_lockmode := 'not found';
117+
end if;
118+
raise notice 'mode=%', v_lockmode;
119+
end
120+
$$;
121+
NOTICE: mode=not found
122+
commit;

contrib/ivorysql_ora/ivorysql_ora_merge_sqls

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ src/builtin_packages/utl_file/utl_file
55
src/sysview/sysview
66
src/xml_functions/xml_functions
77
src/builtin_packages/dbms_utility/dbms_utility
8+
src/builtin_packages/dbms_lock/dbms_lock

contrib/ivorysql_ora/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ ivorysql_ora_sources = files(
2929
'src/sysview/sysview_functions.c',
3030
'src/xml_functions/ora_xml_functions.c',
3131
'src/builtin_packages/dbms_utility/dbms_utility.c',
32+
'src/builtin_packages/dbms_lock/dbms_lock.c'
3233
)
3334

3435
if host_system == 'windows'
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
--
2+
-- dbms_lock.sql
3+
--
4+
-- tests for DBMS_LOCK
5+
--
6+
call dbms_lock.sleep(1);
7+
create table handle(h text);
8+
--
9+
-- test DBMS_LOCK.S
10+
--
11+
begin;
12+
declare
13+
v_lockname varchar2(10) = 'LOCKS';
14+
v_handle text;
15+
v_rc int;
16+
begin
17+
dbms_lock.allocate_unique(v_lockname, v_handle);
18+
v_rc := dbms_lock.request(v_handle, dbms_lock.s_mode, 0);
19+
raise notice 'request rc=%', v_rc;
20+
assert v_rc = 0, format('DBMS_LOCK.request failed: rc=%s', v_rc);
21+
insert into handle values(v_handle);
22+
end;
23+
/
24+
do
25+
$$
26+
declare
27+
v_lockmode text;
28+
begin
29+
select mode into v_lockmode from pg_locks where pid = pg_backend_pid() and locktype ='advisory' and mode = 'ShareLock';
30+
if not found then
31+
v_lockmode := 'not found';
32+
end if;
33+
raise notice 'mode=%', v_lockmode;
34+
end
35+
$$;
36+
--
37+
declare
38+
v_rc int;
39+
v_handle text;
40+
begin
41+
select h into v_handle from handle;
42+
v_rc := dbms_lock.release(v_handle);
43+
raise notice 'release rc=%', v_rc;
44+
assert v_rc = 0, format('DBMS_LOCK.release failed: rc=%s', v_rc);
45+
delete from handle;
46+
end;
47+
/
48+
do
49+
$$
50+
declare
51+
v_lockmode text;
52+
begin
53+
select mode into v_lockmode from pg_locks where pid = pg_backend_pid() and locktype ='advisory' and mode = 'ShareLock';
54+
if not found then
55+
v_lockmode := 'not found';
56+
end if;
57+
raise notice 'mode=%', v_lockmode;
58+
end
59+
$$;
60+
--
61+
commit;
62+
--
63+
-- test DBMS_LOCK.X
64+
--
65+
begin;
66+
declare
67+
v_lockname varchar2(10) = 'LOCKX';
68+
v_handle text;
69+
v_rc int;
70+
begin
71+
dbms_lock.allocate_unique(v_lockname, v_handle);
72+
v_rc := dbms_lock.request(v_handle, dbms_lock.x_mode, 0);
73+
raise notice 'request rc=%', v_rc;
74+
assert v_rc = 0, format('DBMS_LOCK.request failed: rc=%s', v_rc);
75+
insert into handle values(v_handle);
76+
end;
77+
/
78+
do
79+
$$
80+
declare
81+
v_lockmode text;
82+
begin
83+
select mode into v_lockmode from pg_locks where pid = pg_backend_pid() and locktype='advisory' and mode = 'ExclusiveLock';
84+
if not found then
85+
v_lockmode := 'not found';
86+
end if;
87+
raise notice 'mode=%', v_lockmode;
88+
end
89+
$$;
90+
--
91+
declare
92+
v_rc int;
93+
v_handle text;
94+
begin
95+
select h into v_handle from handle;
96+
v_rc := dbms_lock.release(v_handle);
97+
raise notice 'release rc=%', v_rc;
98+
assert v_rc = 0, format('DBMS_LOCK.release failed: rc=%s', v_rc);
99+
delete from handle;
100+
end;
101+
/
102+
do
103+
$$
104+
declare
105+
v_lockmode text ;
106+
begin
107+
select mode into v_lockmode from pg_locks where pid = pg_backend_pid() and locktype = 'advisory' and mode = 'ExclusiveLock';
108+
if not found then
109+
v_lockmode := 'not found';
110+
end if;
111+
raise notice 'mode=%', v_lockmode;
112+
end
113+
$$;
114+
commit;
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/***************************************************************
2+
*
3+
* DBMS_LOCK Package
4+
*
5+
***************************************************************
6+
*/
7+
8+
CREATE FUNCTION sys.dbms_lock_allocate_unique(text)
9+
RETURNS text
10+
AS 'MODULE_PATHNAME', 'ivorysql_dbms_lock_allocate_unique'
11+
LANGUAGE C STRICT;
12+
13+
CREATE FUNCTION sys.dbms_lock_request(text, int, int)
14+
RETURNS int
15+
AS 'MODULE_PATHNAME', 'ivorysql_dbms_lock_request'
16+
LANGUAGE C STRICT;
17+
18+
CREATE FUNCTION sys.dbms_lock_release(text)
19+
RETURNS int
20+
AS 'MODULE_PATHNAME', 'ivorysql_dbms_lock_release'
21+
LANGUAGE C STRICT;
22+
23+
CREATE FUNCTION sys.dbms_lock_sleep(float8)
24+
returns void
25+
AS 'MODULE_PATHNAME', 'ivorysql_dbms_lock_sleep'
26+
LANGUAGE C STRICT;
27+
28+
-- PL/iSQL package wrapper
29+
CREATE PACKAGE dbms_lock AS
30+
31+
-- lock modes
32+
s_mode CONSTANT INTEGER := 4;
33+
x_mode CONSTANT INTEGER := 6;
34+
35+
-- return codes
36+
success CONSTANT INTEGER := 0;
37+
timeout CONSTANT INTEGER := 1;
38+
deadlock CONSTANT INTEGER := 2;
39+
parameter_error CONSTANT INTEGER := 3;
40+
already_owned CONSTANT INTEGER := 4;
41+
illegal_handle CONSTANT INTEGER := 5;
42+
43+
44+
PROCEDURE allocate_unique(lockname text, lockname_handle OUT text);
45+
46+
FUNCTION request(lockname_handle text, mode integer, timeout integer)
47+
RETURN int;
48+
49+
FUNCTION release(lockname_handle text)
50+
RETURN int;
51+
52+
PROCEDURE sleep(seconds double precision);
53+
54+
END;
55+
56+
CREATE PACKAGE BODY dbms_lock AS
57+
58+
PROCEDURE allocate_unique(lockname text, lockname_handle OUT text) IS
59+
v_handle text;
60+
BEGIN
61+
v_handle := dbms_lock_allocate_unique(lockname);
62+
lockname_handle := v_handle;
63+
END;
64+
65+
FUNCTION request(lockname_handle text, mode integer, timeout integer)
66+
RETURN int IS
67+
BEGIN
68+
RETURN dbms_lock_request(lockname_handle, mode, timeout);
69+
END;
70+
71+
FUNCTION release(lockname_handle text)
72+
RETURN int IS
73+
BEGIN
74+
RETURN dbms_lock_release(lockname_handle);
75+
END;
76+
77+
PROCEDURE sleep(seconds double precision) IS
78+
BEGIN
79+
PERFORM dbms_lock_sleep(seconds);
80+
END;
81+
82+
END;

0 commit comments

Comments
 (0)