Saturday, October 28, 2023

PostgreSQL Large Object with Examples

 

Create table with large object support

Table is optional. Even there is no table created, large object can still be created via these lo_ functions.

create table t (id int primary key, loc oid);

Populate table with different methods of large object construction

-- obtain bytea data, and create lo using lo_from_bytea 

mytest=> select 'test string'::bytea;
          bytea
--------------------------
 \x7465737420737472696e67
(1 row)

mytest=> insert into t values (1,lo_from_bytea(0,'\x7465737420737472696e67'));
INSERT 0 1
-- combine above example into single step

mytest=> insert into t values (2,lo_from_bytea(0,'test string1'::bytea));
INSERT 0 1

-- create lo first, populate data and insert into table with lo oid

mytest=> select lo_create(0);
 lo_create
-----------
     16418
(1 row)

mytest=> begin;
BEGIN
mytest=*> SELECT pg_catalog.lo_open('16418',131072);
 lo_open
---------
       0
(1 row)

mytest=*> SELECT pg_catalog.lowrite(0,'test string2'::bytea);
 lowrite
---------
      12
(1 row)

mytest=*> SELECT pg_catalog.lo_close(0);
 lo_close
----------
        0
(1 row)

mytest=*> commit;
COMMIT

mytest=> insert into t values (3,'16418');
INSERT 0 1
-- create lo oid directly and populate data

mytest=> select max(loid) from pg_catalog.pg_largeobject;
  max
-------
 16418
(1 row)

mytest=> insert into t values (4, lo_create(16419));
INSERT 0 1

mytest=> select pg_catalog.lo_put('16419',0,'test string3'::bytea);
 lo_put
--------

(1 row)

Examples to query data

mytest=> select * from pg_largeobject;
 loid  | pageno |            data
-------+--------+----------------------------
 16416 |      0 | \x7465737420737472696e67
 16417 |      0 | \x7465737420737472696e6731
 16418 |      0 | \x7465737420737472696e6732
 16419 |      0 | \x7465737420737472696e6733
(4 rows)

mytest=> select * from pg_largeobject_metadata;
  oid  | lomowner | lomacl
-------+----------+--------
 16416 |    16397 |
 16417 |    16397 |
 16418 |    16397 |
 16419 |    16397 |
(4 rows)

mytest=> select id, encode(lo_get(loc),'escape') lo_to_text  from t;
 id |  lo_to_text
----+--------------
  1 | test string
  2 | test string1
  3 | test string2
  4 | test string3
(4 rows)
mytest=> select id, loc, lo_get(loc), encode(lo_get(loc),'escape') lo_to_text  from t;
 id |  loc  |           lo_get           |  lo_to_text
----+-------+----------------------------+--------------
  1 | 16416 | \x7465737420737472696e67   | test string
  2 | 16417 | \x7465737420737472696e6731 | test string1
  3 | 16418 | \x7465737420737472696e6732 | test string2
  4 | 16419 | \x7465737420737472696e6733 | test string3
(4 rows)

Delete rows and large objects

mytest=> delete from t where id=1;
DELETE 1
mytest=> select lo_unlink('16417');
 lo_unlink
-----------
         1
(1 row)

mytest=> select * from pg_largeobject;
 loid  | pageno |            data
-------+--------+----------------------------
 16416 |      0 | \x7465737420737472696e67
 16418 |      0 | \x7465737420737472696e6732
 16419 |      0 | \x7465737420737472696e6733
(3 rows)

mytest=> select id, loc, lo_get(loc)  from t;
ERROR:  large object 16417 does not exist

$ vacuumlo -h rdspg.ciscfgtmcrn3.us-east-1.rds.amazonaws.com mytest -v
Connected to database "mytest"
Checking loc in public.t
Successfully removed 1 large objects from database "mytest".
mytest=> delete from t where id=3;
DELETE 1
select lo_unlink('16418');
 lo_unlink
-----------
         1
(1 row)

Export data using pg_dump

$ pg_dump -h rdspg.ciscfgtmcrn3.us-east-1.rds.amazonaws.com

--
-- PostgreSQL database dump
--

-- Dumped from database version 15.4
-- Dumped by pg_dump version 15.3

SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;

SET default_tablespace = '';

SET default_table_access_method = heap;

--
-- Name: t; Type: TABLE; Schema: public; Owner: postgres
--

CREATE TABLE public.t (
    id integer NOT NULL,
    loc oid
);


ALTER TABLE public.t OWNER TO postgres;

--
-- Name: 16419; Type: BLOB; Schema: -; Owner: postgres
--

SELECT pg_catalog.lo_create('16419');


ALTER LARGE OBJECT 16419 OWNER TO postgres;

--
-- Data for Name: t; Type: TABLE DATA; Schema: public; Owner: postgres
--

COPY public.t (id, loc) FROM stdin;
4	16419
\.


--
-- Data for Name: BLOBS; Type: BLOBS; Schema: -; Owner: -
--

BEGIN;

SELECT pg_catalog.lo_open('16419', 131072);
SELECT pg_catalog.lowrite(0, '\x7465737420737472696e6733');
SELECT pg_catalog.lo_close(0);

COMMIT;

--
-- Name: t t_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
--

ALTER TABLE ONLY public.t
    ADD CONSTRAINT t_pkey PRIMARY KEY (id);


--
-- PostgreSQL database dump complete
--

Use LO Extension

-- clean up

mytest=> drop table t;
DROP TABLE
mytest=> select lo_unlink('16419');
 lo_unlink
-----------
         1
(1 row)

mytest=> select * from pg_largeobject;
 loid | pageno | data
------+--------+------
(0 rows)

-- create extension and table using the lo extension
mytest=> create extension lo;
CREATE EXTENSION

mytest=> create table t (id int primary key, loc lo);
CREATE TABLE

mytest=> create or replace trigger t_trigger_cleanup_lo before update or delete on t
mytest-> for each row execute function lo_manage(loc);
CREATE TRIGGER

-- populate data

mytest=> insert into t values (1,lo_from_bytea(0,'test string1'::bytea));
INSERT 0 1
mytest=> insert into t values (2,lo_from_bytea(0,'test string2'::bytea));
INSERT 0 1
mytest=> insert into t values (3,lo_from_bytea(0,'test string3'::bytea));
INSERT 0 1
mytest=> insert into t values (4,lo_from_bytea(0,'test string4'::bytea));
INSERT 0 1

mytest=> select * from pg_largeobject;
 loid  | pageno |            data
-------+--------+----------------------------
 16438 |      0 | \x7465737420737472696e6731
 16439 |      0 | \x7465737420737472696e6732
 16440 |      0 | \x7465737420737472696e6733
 16441 |      0 | \x7465737420737472696e6734
(4 rows)

-- delete data
mytest=> delete from t where id in (1,3);
DELETE 2

-- verify data, both data and lo delete without orphan records
mytest=> select * from t;
 id |  loc
----+-------
  2 | 16439
  4 | 16441
(2 rows)

mytest=> select * from pg_largeobject;
 loid  | pageno |            data
-------+--------+----------------------------
 16439 |      0 | \x7465737420737472696e6732
 16441 |      0 | \x7465737420737472696e6734
(2 rows)
Reference: 

Saturday, October 7, 2023

Oracle 23c new feature: default running background processes

 select distinct name,description,

  json_value(attributes,'$.instance_critical' returning varchar) critical,
  json_value(attributes,'$.restartable' returning varchar) restartable,
  json_value(attributes,'$.worker' returning varchar) worker
from v$bgprocess where paddr<>'00' order by name;
NAMEDESCRIPTIONCRITICALRESTARTABLEWORKER
AQPCAQ Process Coordnonono
BG00Testing SRV processnonoyes
BG01Testing SRV processnonoyes
BG02Testing SRV process3nonoyes
CJQ0Job Queue Coordinatornoyesno
CKPTcheckpointyesnono
CL00process cleanup slaveyesnoyes
CLMNprocess cleanupyesnono
D000Dispatchersnonoyes
DBRMDataBase Resource Manageryesnono
DBW0db writer process 0yesnono
DIA0diagnosibility process 0noyesno
DIA1Deadlock Detectionnoyesno
DIAGdiagnosibility processnoyesno
FENCIOServer fence monitoryesnono
GCR0GCR Helpers (LMHB)nonoyes
GCW0GCR Monitor processes (LMHB)nonoyes
GEN0generic0yesnono
GEN2generic2yesnono
LGWRRedo etc.yesnono
LMHBlm heartbeat monitornoyesno
LREGListener Registrationyesnono
M000MMON slave class 1nonoyes
M001MMON slave class 1nonoyes
M002MMON slave class 1nonoyes
M003MMON slave class 1nonoyes
M005MMON slave class 1nonoyes
M006MMON slave class 1nonoyes
M007MMON slave class 1nonoyes
M008MMON slave class 1nonoyes
M009MMON slave class 1nonoyes
MMANMemory Manageryesnono
MMNLManageability Monitor Process 2noyesno
MMONManageability Monitor Processnoyesno
OFSDOracle File Server BGnoyesno
PMANprocess manageryesnono
PMONprocess cleanupyesnono
PSP0process spawner 0yesnono
PXMNPX Monitornoyesno
Q003QMON MSnonoyes
Q004QMON MSnonoyes
QM02QMON MSnonoyes
RCBGResult Cache: Backgroundnonono
RECOdistributed recoverynoyesno
S000Shared serversnonoyes
SCMNnonoyes
SMCOSpace Manager Processnoyesno
SMONSystem Monitor Processyesnono
SVCBservices background monitornoyesno
TMONTransport Monitornonono
TT00Redo Transportnonoyes
TT01Redo Transportnonoyes
VKRMVirtual sKeduler for Resource Managernoyesno
VKTMVirtual Keeper of TiMe processyesnono
VOSDVOS Daemonyesnono
W000space management slave poolnonoyes
W001space management slave poolnonoyes

Oracle 23c new feature: SQL Property Graphs

 

Demo Environment

$ sql hr/hr@192.168.0.200/FREEPDB1


SQLcl: Release 23.2 Production on Sat Oct 07 20:20:22 2023

Copyright (c) 1982, 2023, Oracle.  All rights reserved.

Connected to:
Oracle Database 23c Free Release 23.0.0.0.0 - Develop, Learn, and Run for Free
Version 23.3.0.23.09

SQL>
SQL> show user
USER is "HR"
SQL> 
SQL> set pages 999
SQL> set lines 120

Clean Up

SQL> drop property graph if exists employee_graph;

Property GRAPH dropped.

Create Property Graph

create property graph employee_graph
  vertex tables (
    HR.EMPLOYEES
    key (EMPLOYEE_ID)
    properties (EMPLOYEE_ID,FIRST_NAME, LAST_NAME,HIRE_DATE,JOB_ID,SALARY)
  )
  edge tables (
    HR.EMPLOYEES as WORK_FOR
    key (EMPLOYEE_ID)
    source key (EMPLOYEE_ID) REFERENCES EMPLOYEES(EMPLOYEE_ID)
    destination key (MANAGER_ID) REFERENCES EMPLOYEES(EMPLOYEE_ID)
  )
  /
SQL> create property graph employee_graph
  2    vertex tables (
  3      HR.EMPLOYEES
  4      key (EMPLOYEE_ID)
  5      properties (EMPLOYEE_ID,FIRST_NAME, LAST_NAME,HIRE_DATE,JOB_ID,SALARY)
  6    )
  7    edge tables (
  8      HR.EMPLOYEES as WORK_FOR
  9      key (EMPLOYEE_ID)
 10      source key (EMPLOYEE_ID) REFERENCES EMPLOYEES(EMPLOYEE_ID)
 11      destination key (MANAGER_ID) REFERENCES EMPLOYEES(EMPLOYEE_ID)
 12    )
 13*   /

Property GRAPH created.

Query Property Graph Example 1 (With Explain Plan)

-- top 20 rows order by mgr's employee_id for direct employees under him/her
select * from graph_table( employee_graph 
    match (src) -  [IS WORK_FOR] -> (dst)
    columns (src.employee_id as emp_id, src.first_name||src.last_name as EMP_NAME,
    dst.employee_id as mgr_id, dst.first_name||dst.last_name as MGR_NAME)
    ) 
order by mgr_id fetch first 20 rows only;
SQL> select * from graph_table( employee_graph
  2      match (src) -  [IS WORK_FOR] -> (dst)
  3      columns (src.employee_id as emp_id, src.first_name||src.last_name as EMP_NAME,
  4      dst.employee_id as mgr_id, dst.first_name||dst.last_name as MGR_NAME)
  5      )
  6* order by mgr_id fetch first 20 rows only;

   EMP_ID EMP_NAME               MGR_ID MGR_NAME
_________ ___________________ _________ _____________
      101 NeenaYang                 100 StevenKing
      102 LexGarcia                 100 StevenKing
      114 DenLi                     100 StevenKing
      120 MatthewWeiss              100 StevenKing
      121 AdamFripp                 100 StevenKing
      122 PayamKaufling             100 StevenKing
      123 ShantaVollman             100 StevenKing
      124 KevinMourgos              100 StevenKing
      145 JohnSingh                 100 StevenKing
      146 KarenPartners             100 StevenKing
      147 AlbertoErrazuriz          100 StevenKing
      148 GeraldCambrault           100 StevenKing
      149 EleniZlotkey              100 StevenKing
      201 MichaelMartinez           100 StevenKing
      108 NancyGruenberg            101 NeenaYang
      200 JenniferWhalen            101 NeenaYang
      203 SusanJacobs               101 NeenaYang
      204 HermannBrown              101 NeenaYang
      205 ShelleyHiggins            101 NeenaYang
      103 AlexanderJames            102 LexGarcia

20 rows selected.
PLAN_TABLE_OUTPUT
_____________________________________________________________________________________________________
Plan hash value: 1451186655

--------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |                |    20 |  2000 |     1   (0)| 00:00:01 |
|*  1 |  VIEW                           |                |    20 |  2000 |     1   (0)| 00:00:01 |
|*  2 |   WINDOW NOSORT STOPKEY         |                |    20 |  1820 |     1   (0)| 00:00:01 |
|   3 |    NESTED LOOPS                 |                |    20 |  1820 |     1   (0)| 00:00:01 |
|   4 |     NESTED LOOPS                |                |   642 |  1820 |     1   (0)| 00:00:01 |
|   5 |      TABLE ACCESS BY INDEX ROWID| EMPLOYEES      |   107 |  4173 |     1   (0)| 00:00:01 |
|   6 |       INDEX FULL SCAN           | EMP_EMP_ID_PK  |    21 |       |     1   (0)| 00:00:01 |
|*  7 |      INDEX RANGE SCAN           | EMP_MANAGER_IX |     6 |       |     0   (0)| 00:00:01 |
|   8 |     TABLE ACCESS BY INDEX ROWID | EMPLOYEES      |     1 |    52 |     0   (0)| 00:00:01 |
--------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=20)
   2 - filter(ROW_NUMBER() OVER ( ORDER BY "DST"."EMPLOYEE_ID")<=20)
   7 - access("DST"."EMPLOYEE_ID"="MANAGER_ID")

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)

26 rows selected.

Query Property Graph Example 2 (With Explain Plan)

-- top 20 rows order by emp's employee_id for direct employees under job title 'AD_PRES'
select * from graph_table( employee_graph 
    match (src) -  [IS WORK_FOR] -> (dst where dst.JOB_ID='AD_PRES')
    columns (src.employee_id as emp_id, src.first_name||src.last_name as EMP_NAME,
    dst.employee_id as mgr_id, dst.first_name||dst.last_name as MGR_NAME)
    ) 
order by emp_id fetch first 20 rows only; 
SQL> select * from graph_table( employee_graph
  2      match (src) -  [IS WORK_FOR] -> (dst where dst.JOB_ID='AD_PRES')
  3      columns (src.employee_id as emp_id, src.first_name||src.last_name as EMP_NAME,
  4      dst.employee_id as mgr_id, dst.first_name||dst.last_name as MGR_NAME)
  5      )
  6* order by emp_id fetch first 20 rows only;

   EMP_ID EMP_NAME               MGR_ID MGR_NAME
_________ ___________________ _________ _____________
      101 NeenaYang                 100 StevenKing
      102 LexGarcia                 100 StevenKing
      114 DenLi                     100 StevenKing
      120 MatthewWeiss              100 StevenKing
      121 AdamFripp                 100 StevenKing
      122 PayamKaufling             100 StevenKing
      123 ShantaVollman             100 StevenKing
      124 KevinMourgos              100 StevenKing
      145 JohnSingh                 100 StevenKing
      146 KarenPartners             100 StevenKing
      147 AlbertoErrazuriz          100 StevenKing
      148 GeraldCambrault           100 StevenKing
      149 EleniZlotkey              100 StevenKing
      201 MichaelMartinez           100 StevenKing

14 rows selected.
PLAN_TABLE_OUTPUT
____________________________________________________________________________________________________
Plan hash value: 4176738749

-------------------------------------------------------------------------------------------------
| Id  | Operation                       | Name          | Rows  | Bytes | Cost (%CPU)| Time     |
-------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                |               |     6 |   600 |     1   (0)| 00:00:01 |
|*  1 |  VIEW                           |               |     6 |   600 |     1   (0)| 00:00:01 |
|*  2 |   WINDOW NOSORT STOPKEY         |               |     6 |   588 |     1   (0)| 00:00:01 |
|   3 |    NESTED LOOPS                 |               |     6 |   588 |     1   (0)| 00:00:01 |
|   4 |     NESTED LOOPS                |               |   107 |   588 |     1   (0)| 00:00:01 |
|   5 |      TABLE ACCESS BY INDEX ROWID| EMPLOYEES     |   107 |  5564 |     1   (0)| 00:00:01 |
|   6 |       INDEX FULL SCAN           | EMP_EMP_ID_PK |   107 |       |     1   (0)| 00:00:01 |
|*  7 |      INDEX RANGE SCAN           | EMP_JOB_IX    |     1 |       |     0   (0)| 00:00:01 |
|*  8 |     TABLE ACCESS BY INDEX ROWID | EMPLOYEES     |     1 |    46 |     0   (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=20)
   2 - filter(ROW_NUMBER() OVER ( ORDER BY "SRC"."EMPLOYEE_ID")<=20)
   7 - access("DST"."JOB_ID"='AD_PRES')
   8 - filter("DST"."EMPLOYEE_ID"="MANAGER_ID")

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)

Query Property Graph Example 3 (With Explain Plan)

select * from graph_table( employee_graph 
    match (emp) -  [IS WORK_FOR] -> (mgr1) -  [IS WORK_FOR] -> (mgr2) -  [IS WORK_FOR] -> (mgr3)  
    columns (emp.employee_id as emp_id, emp.first_name||emp.last_name as EMP_NAME,
    mgr1.first_name||mgr1.last_name as L1_MGR_NAME,
    mgr2.first_name||mgr2.last_name as L2_MGR_NAME,
    mgr3.first_name||mgr3.last_name as L3_MGR_NAME)
    ) 
order by L3_MGR_NAME,L2_MGR_NAME, L1_MGR_NAME fetch first 20 rows only; 
SQL> select * from graph_table( employee_graph
  2      match (emp) -  [IS WORK_FOR] -> (mgr1) -  [IS WORK_FOR] -> (mgr2) -  [IS WORK_FOR] -> (mgr3)
  3      columns (emp.employee_id as emp_id, emp.first_name||emp.last_name as EMP_NAME,
  4      mgr1.first_name||mgr1.last_name as L1_MGR_NAME,
  5      mgr2.first_name||mgr2.last_name as L2_MGR_NAME,
  6      mgr3.first_name||mgr3.last_name as L3_MGR_NAME)
  7      )
  8* order by L3_MGR_NAME,L2_MGR_NAME, L1_MGR_NAME fetch first 20 rows only;

   EMP_ID EMP_NAME            L1_MGR_NAME       L2_MGR_NAME    L3_MGR_NAME
_________ ___________________ _________________ ______________ ______________
      104 BruceMiller         AlexanderJames    LexGarcia      StevenKing
      107 DianaNguyen         AlexanderJames    LexGarcia      StevenKing
      106 ValliJackson        AlexanderJames    LexGarcia      StevenKing
      105 DavidWilliams       AlexanderJames    LexGarcia      StevenKing
      109 DanielFaviet        NancyGruenberg    NeenaYang      StevenKing
      110 JohnChen            NancyGruenberg    NeenaYang      StevenKing
      111 IsmaelSciarra       NancyGruenberg    NeenaYang      StevenKing
      112 Jose ManuelUrman    NancyGruenberg    NeenaYang      StevenKing
      113 LuisPopp            NancyGruenberg    NeenaYang      StevenKing
      206 WilliamGietz        ShelleyHiggins    NeenaYang      StevenKing

10 rows selected.
PLAN_TABLE_OUTPUT
__________________________________________________________________________________________________________________
Plan hash value: 1600920025

---------------------------------------------------------------------------------------------------------------
| Id  | Operation                                  | Name             | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                           |                  |    20 |  3880 |     4  (50)| 00:00:01 |
|   1 |  SORT ORDER BY                             |                  |    20 |  3880 |     4  (50)| 00:00:01 |
|*  2 |   VIEW                                     |                  |    20 |  3880 |     3  (34)| 00:00:01 |
|*  3 |    WINDOW SORT PUSHED RANK                 |                  |   104 | 20280 |     3  (34)| 00:00:01 |
|   4 |     NESTED LOOPS                           |                  |   104 | 20280 |     2   (0)| 00:00:01 |
|   5 |      NESTED LOOPS                          |                  |   630 | 20280 |     2   (0)| 00:00:01 |
|   6 |       NESTED LOOPS                         |                  |   105 | 15015 |     2   (0)| 00:00:01 |
|   7 |        NESTED LOOPS                        |                  |   106 |  9646 |     2   (0)| 00:00:01 |
|   8 |         VIEW                               | index$_join$_009 |   107 |  4173 |     2   (0)| 00:00:01 |
|*  9 |          HASH JOIN                         |                  |       |       |            |          |
|  10 |           INDEX FAST FULL SCAN             | EMP_EMP_ID_PK    |   107 |  4173 |     1   (0)| 00:00:01 |
|  11 |           INDEX FAST FULL SCAN             | EMP_NAME_IX      |   107 |  4173 |     1   (0)| 00:00:01 |
|  12 |         TABLE ACCESS BY INDEX ROWID BATCHED| EMPLOYEES        |     1 |    52 |     0   (0)| 00:00:01 |
|* 13 |          INDEX RANGE SCAN                  | EMP_MANAGER_IX   |     6 |       |     0   (0)| 00:00:01 |
|  14 |        TABLE ACCESS BY INDEX ROWID BATCHED | EMPLOYEES        |     1 |    52 |     0   (0)| 00:00:01 |
|* 15 |         INDEX RANGE SCAN                   | EMP_MANAGER_IX   |     6 |       |     0   (0)| 00:00:01 |
|* 16 |       INDEX RANGE SCAN                     | EMP_MANAGER_IX   |     6 |       |     0   (0)| 00:00:01 |
|  17 |      TABLE ACCESS BY INDEX ROWID           | EMPLOYEES        |     1 |    52 |     0   (0)| 00:00:01 |
---------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("from$_subquery$_002"."rowlimit_$$_rownumber"<=20)
   3 - filter(ROW_NUMBER() OVER ( ORDER BY "MGR3"."FIRST_NAME"||"MGR3"."LAST_NAME","MGR2"."FIRST_NAME"|
              |"MGR2"."LAST_NAME","MGR1"."FIRST_NAME"||"MGR1"."LAST_NAME")<=20)
   9 - access(ROWID=ROWID)
  13 - access("MGR3"."EMPLOYEE_ID"="MANAGER_ID")
  15 - access("MGR2"."EMPLOYEE_ID"="MANAGER_ID")
  16 - access("MGR1"."EMPLOYEE_ID"="MANAGER_ID")

Note
-----
   - dynamic statistics used: dynamic sampling (level=2)

39 rows selected.

Troubleshooting

ORA-01031: insufficient privileges
01031. 00000 -  "insufficient privileges"
*Cause:    An attempt was made to perform a database operation without
           the necessary privileges.
*Action:   Ask your database administrator or designated security
           administrator to grant you the necessary privileges

To fix:

SQL> grant create property graph to hr;

Grant succeeded.

References: