Guest User

Untitled

a guest
Sep 13th, 2025
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PL/SQL 12.81 KB | None | 0 0
  1. CREATE ROLE test
  2.     NOSUPERUSER NOCREATEDB NOCREATEROLE INHERIT LOGIN
  3.     PASSWORD 'test'
  4. ;
  5.  
  6. -- SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES, TRIGGER, ALL PRIVILEGES
  7. ALTER DEFAULT PRIVILEGES IN SCHEMA PUBLIC
  8.    GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO test;
  9.  
  10. -- USAGE, SELECT, UPDATE, ALTER, ALL PRIVILEGES
  11. ALTER DEFAULT PRIVILEGES IN SCHEMA PUBLIC
  12.     GRANT USAGE, SELECT, UPDATE ON SEQUENCES TO test;
  13.  
  14. CREATE OR REPLACE FUNCTION rls_guard_out( OUT org_id INT, OUT unit_id INT, OUT user_id INT )
  15. AS $$
  16. SELECT
  17.   current_setting( 'app.org_id',  TRUE )::int,
  18.   current_setting( 'app.unit_id', TRUE )::int,
  19.   current_setting( 'app.user_id', TRUE )::int;
  20. $$ LANGUAGE SQL STABLE;
  21.  
  22. CREATE OR REPLACE FUNCTION rls_guard_table()
  23. RETURNS TABLE( org_id INT, unit_id INT, user_id INT ) AS $$
  24. SELECT
  25.   current_setting( 'app.org_id',  TRUE )::int,
  26.   current_setting( 'app.unit_id', TRUE )::int,
  27.   current_setting( 'app.user_id', TRUE )::int;
  28. $$ LANGUAGE SQL STABLE;
  29.  
  30. -- define a composite type once
  31. CREATE TYPE tenant_ctx AS (
  32.   org_id int,
  33.   unit_id int,
  34.   user_id int
  35. );
  36.  
  37. -- function that always returns a single composite row
  38. CREATE OR REPLACE FUNCTION rls_guard_composite()
  39. RETURNS tenant_ctx
  40. LANGUAGE SQL STABLE AS $$
  41.   SELECT
  42.     current_setting('app.org_id',  TRUE)::int,
  43.     current_setting('app.unit_id', TRUE)::int,
  44.     current_setting('app.user_id', TRUE)::int;
  45. $$;
  46.  
  47.  
  48.  
  49.  
  50. CREATE TABLE rls_test_out (
  51.   id SERIAL,
  52.   org_id  INT NOT NULL DEFAULT current_setting( 'app.org_id',   TRUE )::int,
  53.   unit_id INT NOT NULL DEFAULT current_setting( 'app.unit_id',  TRUE )::int,
  54.   user_id INT NOT NULL DEFAULT current_setting( 'app.user_id',  TRUE )::int
  55. );
  56.  
  57. INSERT INTO rls_test_out ( org_id, unit_id, user_id ) VALUES
  58. ( 1, 1, 1 ),
  59. ( 1, 1, 2 ),
  60. ( 1, 1, 3 ),
  61. ( 1, 2, 1 ),
  62. ( 1, 2, 3 ),
  63. ( 1, 3, 2 ),
  64. ( 2, 1, 1 ),
  65. ( 1, 1, 1 ),
  66. ( 1, 1, 2 ),
  67. ( 1, 1, 3 ),
  68. ( 1, 2, 1 ),
  69. ( 1, 2, 3 ),
  70. ( 1, 3, 2 ),
  71. ( 2, 1, 1 ),
  72. ( 1, 1, 1 ),
  73. ( 1, 1, 2 ),
  74. ( 1, 1, 3 ),
  75. ( 1, 2, 1 ),
  76. ( 1, 2, 3 ),
  77. ( 1, 3, 2 ),
  78. ( 2, 1, 1 ),
  79. ( 1, 1, 1 ),
  80. ( 1, 1, 2 ),
  81. ( 1, 1, 3 ),
  82. ( 1, 2, 1 ),
  83. ( 1, 2, 3 ),
  84. ( 1, 3, 2 ),
  85. ( 2, 1, 1 ),
  86. ( 1, 1, 1 ),
  87. ( 1, 1, 2 ),
  88. ( 1, 1, 3 ),
  89. ( 1, 2, 1 ),
  90. ( 1, 2, 3 ),
  91. ( 1, 3, 2 ),
  92. ( 2, 1, 1 ),
  93. ( 1, 1, 1 ),
  94. ( 1, 1, 2 ),
  95. ( 1, 1, 3 ),
  96. ( 1, 2, 1 ),
  97. ( 1, 2, 3 ),
  98. ( 1, 3, 2 ),
  99. ( 2, 1, 1 );
  100.  
  101. ALTER TABLE rls_test_out FORCE  ROW LEVEL SECURITY;
  102. ALTER TABLE rls_test_out ENABLE ROW LEVEL SECURITY;
  103.  
  104. -- If table has RESTRICTIVE rules it must have at least one permissive rule
  105. -- https://www.postgresql.org/docs/current/sql-createpolicy.html#id-1.9.3.75.6
  106. CREATE POLICY db_tenant_allow_any ON rls_test_out USING( TRUE );
  107.  
  108. CREATE POLICY db_tenant_by ON rls_test_out AS RESTRICTIVE
  109. USING( (org_id, unit_id, user_id) = rls_guard_out() );
  110.  
  111.  
  112.  
  113.  
  114. CREATE TABLE rls_test_table (
  115.   id SERIAL,
  116.   org_id  INT NOT NULL DEFAULT current_setting( 'app.org_id',   TRUE )::int,
  117.   unit_id INT NOT NULL DEFAULT current_setting( 'app.unit_id',  TRUE )::int,
  118.   user_id INT NOT NULL DEFAULT current_setting( 'app.user_id',  TRUE )::int
  119. );
  120.  
  121. INSERT INTO rls_test_table ( org_id, unit_id, user_id ) VALUES
  122. ( 1, 1, 1 ),
  123. ( 1, 1, 2 ),
  124. ( 1, 1, 3 ),
  125. ( 1, 2, 1 ),
  126. ( 1, 2, 3 ),
  127. ( 1, 3, 2 ),
  128. ( 2, 1, 1 ),
  129. ( 1, 1, 1 ),
  130. ( 1, 1, 2 ),
  131. ( 1, 1, 3 ),
  132. ( 1, 2, 1 ),
  133. ( 1, 2, 3 ),
  134. ( 1, 3, 2 ),
  135. ( 2, 1, 1 ),
  136. ( 1, 1, 1 ),
  137. ( 1, 1, 2 ),
  138. ( 1, 1, 3 ),
  139. ( 1, 2, 1 ),
  140. ( 1, 2, 3 ),
  141. ( 1, 3, 2 ),
  142. ( 2, 1, 1 ),
  143. ( 1, 1, 1 ),
  144. ( 1, 1, 2 ),
  145. ( 1, 1, 3 ),
  146. ( 1, 2, 1 ),
  147. ( 1, 2, 3 ),
  148. ( 1, 3, 2 ),
  149. ( 2, 1, 1 ),
  150. ( 1, 1, 1 ),
  151. ( 1, 1, 2 ),
  152. ( 1, 1, 3 ),
  153. ( 1, 2, 1 ),
  154. ( 1, 2, 3 ),
  155. ( 1, 3, 2 ),
  156. ( 2, 1, 1 ),
  157. ( 1, 1, 1 ),
  158. ( 1, 1, 2 ),
  159. ( 1, 1, 3 ),
  160. ( 1, 2, 1 ),
  161. ( 1, 2, 3 ),
  162. ( 1, 3, 2 ),
  163. ( 2, 1, 1 );
  164.  
  165. ALTER TABLE rls_test_table FORCE  ROW LEVEL SECURITY;
  166. ALTER TABLE rls_test_table ENABLE ROW LEVEL SECURITY;
  167.  
  168. -- If table has RESTRICTIVE rules it must have at least one permissive rule
  169. -- https://www.postgresql.org/docs/current/sql-createpolicy.html#id-1.9.3.75.6
  170. CREATE POLICY db_tenant_allow_any ON rls_test_table USING( TRUE );
  171.  
  172. CREATE POLICY db_tenant_by ON rls_test_table AS RESTRICTIVE
  173. USING( (org_id, unit_id, user_id) = (SELECT (rls_guard_table()).*) );
  174.  
  175.  
  176.  
  177. CREATE TABLE rls_test_composite (
  178.   id SERIAL,
  179.     branch tenant_ctx
  180. );
  181.  
  182. INSERT INTO rls_test_composite ( branch ) VALUES
  183. (( 1, 1, 1 )),
  184. (( 1, 1, 2 )),
  185. (( 1, 1, 3 )),
  186. (( 1, 2, 1 )),
  187. (( 1, 2, 3 )),
  188. (( 1, 3, 2 )),
  189. (( 2, 1, 1 )),
  190. (( 1, 1, 1 )),
  191. (( 1, 1, 2 )),
  192. (( 1, 1, 3 )),
  193. (( 1, 2, 1 )),
  194. (( 1, 2, 3 )),
  195. (( 1, 3, 2 )),
  196. (( 2, 1, 1 )),
  197. (( 1, 1, 1 )),
  198. (( 1, 1, 2 )),
  199. (( 1, 1, 3 )),
  200. (( 1, 2, 1 )),
  201. (( 1, 2, 3 )),
  202. (( 1, 3, 2 )),
  203. (( 2, 1, 1 )),
  204. (( 1, 1, 1 )),
  205. (( 1, 1, 2 )),
  206. (( 1, 1, 3 )),
  207. (( 1, 2, 1 )),
  208. (( 1, 2, 3 )),
  209. (( 1, 3, 2 )),
  210. (( 2, 1, 1 )),
  211. (( 1, 1, 1 )),
  212. (( 1, 1, 2 )),
  213. (( 1, 1, 3 )),
  214. (( 1, 2, 1 )),
  215. (( 1, 2, 3 )),
  216. (( 1, 3, 2 )),
  217. (( 2, 1, 1 )),
  218. (( 1, 1, 1 )),
  219. (( 1, 1, 2 )),
  220. (( 1, 1, 3 )),
  221. (( 1, 2, 1 )),
  222. (( 1, 2, 3 )),
  223. (( 1, 3, 2 )),
  224. (( 2, 1, 1 ));
  225.  
  226. ALTER TABLE rls_test_composite FORCE  ROW LEVEL SECURITY;
  227. ALTER TABLE rls_test_composite ENABLE ROW LEVEL SECURITY;
  228.  
  229. -- If table has RESTRICTIVE rules it must have at least one permissive rule
  230. -- https://www.postgresql.org/docs/current/sql-createpolicy.html#id-1.9.3.75.6
  231. CREATE POLICY db_tenant_allow_any ON rls_test_composite USING( TRUE );
  232.  
  233. CREATE POLICY db_tenant_by ON rls_test_composite AS RESTRICTIVE
  234. USING( branch = rls_guard_composite() );
  235.  
  236.  
  237.  
  238. \timing
  239.  
  240. BEGIN;
  241. SET SESSION AUTHORIZATION test;
  242. SELECT current_user;
  243. SELECT set_config( 'app.user_id', '3', TRUE );
  244. SELECT set_config( 'app.unit_id', '2', TRUE );
  245. SELECT set_config( 'app.org_id',  '1', TRUE );
  246.  
  247. SELECT * FROM rls_guard_out();
  248. SELECT * FROM rls_guard_table();
  249. SELECT * FROM rls_guard_composite();
  250.  
  251. SELECT * FROM rls_test_out;
  252. SELECT * FROM rls_test_table;
  253. SELECT * FROM rls_test_composite;
  254.  
  255.  
  256. DO $$
  257. DECLARE
  258.   i int;
  259.   t0 timestamptz;
  260.   t1 INTERVAL;
  261. BEGIN
  262.   t0 := clock_timestamp();
  263.   FOR i IN 1..100000 LOOP
  264.     PERFORM * FROM rls_test_out;
  265.   END LOOP;
  266.   t1 := clock_timestamp() - t0;
  267.  
  268.   -- Return the elapsed ms as a one-row result
  269.   PERFORM set_config('app.elapsed_ms', (EXTRACT(MILLISECOND FROM t1))::text, TRUE);
  270. END $$;
  271.  
  272. SELECT current_setting('app.elapsed_ms') AS elapsed_ms;
  273.  
  274.  
  275.  
  276. DO $$
  277. DECLARE
  278.   i int;
  279.   t0 timestamptz;
  280.   t1 INTERVAL;
  281. BEGIN
  282.   t0 := clock_timestamp();
  283.   FOR i IN 1..100000 LOOP
  284.     PERFORM * FROM rls_test_table;
  285.   END LOOP;
  286.   t1 := clock_timestamp() - t0;
  287.  
  288.   -- Return the elapsed ms as a one-row result
  289.   PERFORM set_config('app.elapsed_ms', (EXTRACT(MILLISECOND FROM t1))::text, TRUE);
  290. END $$;
  291.  
  292. SELECT current_setting('app.elapsed_ms') AS elapsed_ms;
  293.  
  294.  
  295.  
  296. DO $$
  297. DECLARE
  298.   i int;
  299.   t0 timestamptz;
  300.   t1 INTERVAL;
  301. BEGIN
  302.   t0 := clock_timestamp();
  303.   FOR i IN 1..100000 LOOP
  304.     PERFORM * FROM rls_test_composite;
  305.   END LOOP;
  306.   t1 := clock_timestamp() - t0;
  307.  
  308.   -- Return the elapsed ms as a one-row result
  309.   PERFORM set_config('app.elapsed_ms', (EXTRACT(MILLISECOND FROM t1))::text, TRUE);
  310. END $$;
  311.  
  312. SELECT current_setting('app.elapsed_ms') AS elapsed_ms;
  313.  
  314.  
  315.  
  316.  
  317. DO $$
  318. DECLARE
  319.   i int;
  320. BEGIN
  321.   FOR i IN 1..1000000 LOOP
  322.     PERFORM rls_guard_out();
  323.   END LOOP;
  324. END $$;
  325.  
  326.  
  327. DO $$
  328. DECLARE
  329.   i int;
  330. BEGIN
  331.   FOR i IN 1..1000000 LOOP
  332.     PERFORM * FROM rls_test_out;
  333.   END LOOP;
  334. END $$;
  335.  
  336.  
  337.  
  338.  
  339. DO $$
  340. DECLARE
  341.   i int;
  342. BEGIN
  343.   FOR i IN 1..1000000 LOOP
  344.     PERFORM rls_guard_table();
  345.   END LOOP;
  346. END $$;
  347.  
  348.  
  349. DO $$
  350. DECLARE
  351.   i int;
  352. BEGIN
  353.   FOR i IN 1..1000000 LOOP
  354.     PERFORM * FROM rls_test_table;
  355.   END LOOP;
  356. END $$;
  357.  
  358.  
  359.  
  360.  
  361. DO $$
  362. DECLARE
  363.   i int;
  364. BEGIN
  365.   FOR i IN 1..1000000 LOOP
  366.     PERFORM rls_guard_composite();
  367.   END LOOP;
  368. END $$;
  369.  
  370.  
  371. DO $$
  372. DECLARE
  373.   i int;
  374. BEGIN
  375.   FOR i IN 1..1000000 LOOP
  376.     PERFORM * FROM rls_test_composite;
  377.   END LOOP;
  378. END $$;
  379.  
  380.  
  381. ROLLBACK;
  382.  
  383. RESET SESSION AUTHORIZATION;
  384.  
  385. DROP TABLE rls_test_composite;
  386. DROP TABLE rls_test_table;
  387. DROP TABLE rls_test_out;
  388.  
  389. DROP FUNCTION rls_guard_composite();
  390. DROP FUNCTION rls_guard_table();
  391. DROP FUNCTION rls_guard_out();
  392.  
  393.  
  394. ALTER DEFAULT PRIVILEGES IN SCHEMA PUBLIC
  395.     REVOKE ALL PRIVILEGES ON TABLES FROM test;
  396. ALTER DEFAULT PRIVILEGES IN SCHEMA PUBLIC
  397.     REVOKE ALL PRIVILEGES ON SEQUENCES FROM test;
  398. DROP ROLE test;
  399.  
  400. /*
  401.  
  402. psql -d test -U postgres -p 15435 -h 127.0.0.1 -f t/module/db/sql/manual.sql
  403. CREATE ROLE
  404. ALTER DEFAULT PRIVILEGES
  405. ALTER DEFAULT PRIVILEGES
  406. CREATE FUNCTION
  407. CREATE FUNCTION
  408. psql:t/module/db/sql/manual.sql:35: ERROR:  type "tenant_ctx" already exists
  409. CREATE FUNCTION
  410. CREATE TABLE
  411. INSERT 0 7
  412. ALTER TABLE
  413. ALTER TABLE
  414. CREATE POLICY
  415. CREATE POLICY
  416. CREATE TABLE
  417. INSERT 0 7
  418. ALTER TABLE
  419. ALTER TABLE
  420. CREATE POLICY
  421. CREATE POLICY
  422. CREATE TABLE
  423. INSERT 0 7
  424. ALTER TABLE
  425. ALTER TABLE
  426. CREATE POLICY
  427. CREATE POLICY
  428. Timing is on.
  429. BEGIN
  430. Time: 0,029 ms
  431. SET
  432. Time: 0,028 ms
  433.  current_user
  434. --------------
  435.  test
  436. (1 row)
  437.  
  438. Time: 0,046 ms
  439.  set_config
  440. ------------
  441.  3
  442. (1 row)
  443.  
  444. Time: 0,069 ms
  445.  set_config
  446. ------------
  447.  2
  448. (1 row)
  449.  
  450. Time: 0,022 ms
  451.  set_config
  452. ------------
  453.  1
  454. (1 row)
  455.  
  456. Time: 0,034 ms
  457.  org_id | unit_id | user_id
  458. --------+---------+---------
  459.       1 |       2 |       3
  460. (1 row)
  461.  
  462. Time: 0,104 ms
  463.  org_id | unit_id | user_id
  464. --------+---------+---------
  465.       1 |       2 |       3
  466. (1 row)
  467.  
  468. Time: 0,054 ms
  469.  org_id | unit_id | user_id
  470. --------+---------+---------
  471.       1 |       2 |       3
  472. (1 row)
  473.  
  474. Time: 0,050 ms
  475.  id | org_id | unit_id | user_id
  476. ----+--------+---------+---------
  477.   5 |      1 |       2 |       3
  478. (1 row)
  479.  
  480. Time: 0,307 ms
  481.  id | org_id | unit_id | user_id
  482. ----+--------+---------+---------
  483.   5 |      1 |       2 |       3
  484. (1 row)
  485.  
  486. Time: 0,143 ms
  487.  id | branch
  488. ----+---------
  489.   5 | (1,2,3)
  490. (1 row)
  491.  
  492. Time: 0,151 ms
  493. DO
  494. Time: 1965,860 ms (00:01,966)
  495.  elapsed_ms
  496. ------------
  497.  1964.921
  498. (1 row)
  499.  
  500. Time: 0,116 ms
  501. DO
  502. Time: 1272,192 ms (00:01,272)
  503.  elapsed_ms
  504. ------------
  505.  1271.946
  506. (1 row)
  507.  
  508. Time: 0,205 ms
  509. DO
  510. Time: 1905,913 ms (00:01,906)
  511.  elapsed_ms
  512. ------------
  513.  1905.659
  514. (1 row)
  515.  
  516. Time: 0,046 ms
  517. DO
  518. Time: 9271,593 ms (00:09,272)
  519. DO
  520. Time: 19391,374 ms (00:19,391)
  521. DO
  522. Time: 9901,212 ms (00:09,901)
  523. DO
  524. Time: 12647,792 ms (00:12,648)
  525. DO
  526. Time: 8970,411 ms (00:08,970)
  527. DO
  528. Time: 18970,746 ms (00:18,971)
  529. ROLLBACK
  530. Time: 0,161 ms
  531. RESET
  532. Time: 0,119 ms
  533. DROP TABLE
  534. Time: 0,970 ms
  535. DROP TABLE
  536. Time: 0,518 ms
  537. DROP TABLE
  538. Time: 0,430 ms
  539. DROP FUNCTION
  540. Time: 0,066 ms
  541. DROP FUNCTION
  542. Time: 0,043 ms
  543. DROP FUNCTION
  544. Time: 0,036 ms
  545. ALTER DEFAULT PRIVILEGES
  546. Time: 0,054 ms
  547. ALTER DEFAULT PRIVILEGES
  548. Time: 0,034 ms
  549. DROP ROLE
  550. Time: 0,075 ms
  551. Time: 0,035 ms
  552.  
  553.  
  554. with the increased number of data the time also increases (except for RETURNS TABLE)
  555. Data x3:
  556.  id | org_id | unit_id | user_id
  557. ----+--------+---------+---------
  558.   5 |      1 |       2 |       3
  559.  12 |      1 |       2 |       3
  560.  19 |      1 |       2 |       3
  561. (3 rows)
  562.  
  563. Time: 0,280 ms
  564.  id | org_id | unit_id | user_id
  565. ----+--------+---------+---------
  566.   5 |      1 |       2 |       3
  567.  12 |      1 |       2 |       3
  568.  19 |      1 |       2 |       3
  569. (3 rows)
  570.  
  571. Time: 0,179 ms
  572.  id | branch
  573. ----+---------
  574.   5 | (1,2,3)
  575.  12 | (1,2,3)
  576.  19 | (1,2,3)
  577. (3 rows)
  578.  
  579. Time: 0,166 ms
  580. DO
  581. Time: 3996,013 ms (00:03,996)
  582.  elapsed_ms
  583. ------------
  584.  3995.471
  585. (1 row)
  586.  
  587. Time: 0,130 ms
  588. DO
  589. Time: 1333,295 ms (00:01,333)
  590.  elapsed_ms
  591. ------------
  592.  1333.026
  593. (1 row)
  594.  
  595. Time: 0,134 ms
  596. DO
  597. Time: 3939,919 ms (00:03,940)
  598.  elapsed_ms
  599. ------------
  600.  3939.694
  601. (1 row)
  602.  
  603. Time: 0,133 ms
  604. DO
  605. Time: 9323,095 ms (00:09,323)
  606. DO
  607. Time: 39369,711 ms (00:39,370)
  608. DO
  609. Time: 9943,009 ms (00:09,943)
  610. DO
  611. Time: 13332,607 ms (00:13,333)
  612. DO
  613. Time: 8993,791 ms (00:08,994)
  614. DO
  615. Time: 39473,836 ms (00:39,474)
  616.  
  617.  
  618. Data x6:
  619.  id | org_id | unit_id | user_id
  620. ----+--------+---------+---------
  621.   5 |      1 |       2 |       3
  622.  12 |      1 |       2 |       3
  623.  19 |      1 |       2 |       3
  624.  26 |      1 |       2 |       3
  625.  33 |      1 |       2 |       3
  626.  40 |      1 |       2 |       3
  627. (6 rows)
  628.  
  629. Time: 0,404 ms
  630.  id | org_id | unit_id | user_id
  631. ----+--------+---------+---------
  632.   5 |      1 |       2 |       3
  633.  12 |      1 |       2 |       3
  634.  19 |      1 |       2 |       3
  635.  26 |      1 |       2 |       3
  636.  33 |      1 |       2 |       3
  637.  40 |      1 |       2 |       3
  638. (6 rows)
  639.  
  640. Time: 0,185 ms
  641.  id | branch
  642. ----+---------
  643.   5 | (1,2,3)
  644.  12 | (1,2,3)
  645.  19 | (1,2,3)
  646.  26 | (1,2,3)
  647.  33 | (1,2,3)
  648.  40 | (1,2,3)
  649. (6 rows)
  650.  
  651. Time: 0,431 ms
  652. DO
  653. Time: 6941,705 ms (00:06,942)
  654.  elapsed_ms
  655. ------------
  656.  6940.442
  657. (1 row)
  658.  
  659. Time: 0,108 ms
  660. DO
  661. Time: 1414,257 ms (00:01,414)
  662.  elapsed_ms
  663. ------------
  664.  1414.028
  665. (1 row)
  666.  
  667. Time: 0,116 ms
  668. DO
  669. Time: 7009,730 ms (00:07,010)
  670.  elapsed_ms
  671. ------------
  672.  7009.457
  673. (1 row)
  674.  
  675. Time: 0,136 ms
  676. DO
  677. Time: 9369,038 ms (00:09,369)
  678. DO
  679. Time: 69423,001 ms (01:09,423)
  680. DO
  681. Time: 9997,077 ms (00:09,997)
  682. DO
  683. Time: 14179,923 ms (00:14,180)
  684. DO
  685. Time: 9023,941 ms (00:09,024)
  686. DO
  687. Time: 69650,565 ms (01:09,651)
  688.  
  689.  */
  690.  
Advertisement
Add Comment
Please, Sign In to add comment