PostgreSQL Source Code git master
Loading...
Searching...
No Matches
propgraphcmds.h File Reference
Include dependency graph for propgraphcmds.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

ObjectAddress CreatePropGraph (ParseState *pstate, const CreatePropGraphStmt *stmt)
 
ObjectAddress AlterPropGraph (ParseState *pstate, const AlterPropGraphStmt *stmt)
 

Function Documentation

◆ AlterPropGraph()

ObjectAddress AlterPropGraph ( ParseState pstate,
const AlterPropGraphStmt stmt 
)
extern

Definition at line 1291 of file propgraphcmds.c.

1292{
1293 Oid pgrelid;
1294 ListCell *lc;
1296
1299 stmt->missing_ok ? RVR_MISSING_OK : 0,
1301 NULL);
1302 if (pgrelid == InvalidOid)
1303 {
1305 (errmsg("relation \"%s\" does not exist, skipping",
1306 stmt->pgname->relname)));
1307 return InvalidObjectAddress;
1308 }
1309
1311
1312 foreach(lc, stmt->add_vertex_tables)
1313 {
1315 struct element_info *vinfo;
1316 Relation rel;
1317 Oid peoid;
1318
1320 vinfo->kind = PGEKIND_VERTEX;
1321
1323
1324 rel = table_open(vinfo->relid, NoLock);
1325
1327 ereport(ERROR,
1329 errmsg("cannot add temporary element table to non-temporary property graph"),
1330 errdetail("Table \"%s\" is a temporary table.", get_rel_name(vinfo->relid)),
1331 parser_errposition(pstate, vertex->vtable->location)));
1332
1333 if (vertex->vtable->alias)
1334 vinfo->aliasname = vertex->vtable->alias->aliasname;
1335 else
1336 vinfo->aliasname = vertex->vtable->relname;
1337
1338 vinfo->key = propgraph_element_get_key(pstate, vertex->vkey, rel, vinfo->aliasname, vertex->location);
1339
1340 vinfo->labels = vertex->labels;
1341
1342 table_close(rel, NoLock);
1343
1346 CStringGetDatum(vinfo->aliasname)))
1347 ereport(ERROR,
1349 errmsg("alias \"%s\" already exists in property graph \"%s\"",
1350 vinfo->aliasname, stmt->pgname->relname),
1351 parser_errposition(pstate, vertex->vtable->location));
1352
1354
1358 }
1359
1360 foreach(lc, stmt->add_edge_tables)
1361 {
1363 struct element_info *einfo;
1364 Relation rel;
1367 Oid peoid;
1368
1370 einfo->kind = PGEKIND_EDGE;
1371
1373
1374 rel = table_open(einfo->relid, NoLock);
1375
1377 ereport(ERROR,
1379 errmsg("cannot add temporary element table to non-temporary property graph"),
1380 errdetail("Table \"%s\" is a temporary table.", get_rel_name(einfo->relid)),
1381 parser_errposition(pstate, edge->etable->location)));
1382
1383 if (edge->etable->alias)
1384 einfo->aliasname = edge->etable->alias->aliasname;
1385 else
1386 einfo->aliasname = edge->etable->relname;
1387
1388 einfo->key = propgraph_element_get_key(pstate, edge->ekey, rel, einfo->aliasname, edge->location);
1389
1390 einfo->srcvertexid = get_vertex_oid(pstate, pgrelid, edge->esrcvertex, edge->location);
1391 einfo->destvertexid = get_vertex_oid(pstate, pgrelid, edge->edestvertex, edge->location);
1392
1393 einfo->srcrelid = get_element_relid(einfo->srcvertexid);
1394 einfo->destrelid = get_element_relid(einfo->destvertexid);
1395
1396 srcrel = table_open(einfo->srcrelid, AccessShareLock);
1397 destrel = table_open(einfo->destrelid, AccessShareLock);
1398
1399 propgraph_edge_get_ref_keys(pstate, edge->esrckey, edge->esrcvertexcols, rel, srcrel,
1400 einfo->aliasname, edge->location, "SOURCE",
1401 &einfo->srckey, &einfo->srcref, &einfo->srceqop);
1402 propgraph_edge_get_ref_keys(pstate, edge->edestkey, edge->edestvertexcols, rel, destrel,
1403 einfo->aliasname, edge->location, "DESTINATION",
1404 &einfo->destkey, &einfo->destref, &einfo->desteqop);
1405
1406 einfo->labels = edge->labels;
1407
1410
1411 table_close(rel, NoLock);
1412
1415 CStringGetDatum(einfo->aliasname)))
1416 ereport(ERROR,
1418 errmsg("alias \"%s\" already exists in property graph \"%s\"",
1419 einfo->aliasname, stmt->pgname->relname),
1420 parser_errposition(pstate, edge->etable->location));
1421
1423
1427 }
1428
1429 foreach(lc, stmt->drop_vertex_tables)
1430 {
1431 char *alias = strVal(lfirst(lc));
1432 Oid peoid;
1433 ObjectAddress obj;
1434
1435 peoid = get_vertex_oid(pstate, pgrelid, alias, -1);
1437 performDeletion(&obj, stmt->drop_behavior, 0);
1438 }
1439
1440 foreach(lc, stmt->drop_edge_tables)
1441 {
1442 char *alias = strVal(lfirst(lc));
1443 Oid peoid;
1444 ObjectAddress obj;
1445
1446 peoid = get_edge_oid(pstate, pgrelid, alias, -1);
1448 performDeletion(&obj, stmt->drop_behavior, 0);
1449 }
1450
1451 /* Remove any orphaned pg_propgraph_label entries */
1452 if (stmt->drop_vertex_tables || stmt->drop_edge_tables)
1453 {
1455 {
1457 {
1458 ObjectAddress obj;
1459
1461 performDeletion(&obj, stmt->drop_behavior, 0);
1462 }
1463 }
1464 }
1465
1466 foreach(lc, stmt->add_labels)
1467 {
1469 Oid peoid;
1470 Oid pgerelid;
1472
1473 Assert(lp->label);
1474
1475 if (stmt->element_kind == PROPGRAPH_ELEMENT_KIND_VERTEX)
1476 peoid = get_vertex_oid(pstate, pgrelid, stmt->element_alias, -1);
1477 else
1478 peoid = get_edge_oid(pstate, pgrelid, stmt->element_alias, -1);
1479
1481
1484
1488 }
1489
1490 if (stmt->drop_label)
1491 {
1492 Oid peoid;
1493 Oid labeloid;
1495 ObjectAddress obj;
1496
1497 if (stmt->element_kind == PROPGRAPH_ELEMENT_KIND_VERTEX)
1498 peoid = get_vertex_oid(pstate, pgrelid, stmt->element_alias, -1);
1499 else
1500 peoid = get_edge_oid(pstate, pgrelid, stmt->element_alias, -1);
1501
1505 CStringGetDatum(stmt->drop_label));
1506 if (!labeloid)
1507 ereport(ERROR,
1509 errmsg("property graph \"%s\" element \"%s\" has no label \"%s\"",
1510 get_rel_name(pgrelid), stmt->element_alias, stmt->drop_label),
1511 parser_errposition(pstate, -1));
1512
1517
1518 if (!ellabeloid)
1519 ereport(ERROR,
1521 errmsg("property graph \"%s\" element \"%s\" has no label \"%s\"",
1522 get_rel_name(pgrelid), stmt->element_alias, stmt->drop_label),
1523 parser_errposition(pstate, -1));
1524
1526 performDeletion(&obj, stmt->drop_behavior, 0);
1527
1528 /* Remove any orphaned pg_propgraph_label entries */
1530 {
1532 performDeletion(&obj, stmt->drop_behavior, 0);
1533 }
1534 }
1535
1536 if (stmt->add_properties)
1537 {
1538 Oid peoid;
1539 Oid pgerelid;
1540 Oid labeloid;
1542
1543 if (stmt->element_kind == PROPGRAPH_ELEMENT_KIND_VERTEX)
1544 peoid = get_vertex_oid(pstate, pgrelid, stmt->element_alias, -1);
1545 else
1546 peoid = get_edge_oid(pstate, pgrelid, stmt->element_alias, -1);
1547
1551 CStringGetDatum(stmt->alter_label));
1552 if (!labeloid)
1553 ereport(ERROR,
1555 errmsg("property graph \"%s\" element \"%s\" has no label \"%s\"",
1556 get_rel_name(pgrelid), stmt->element_alias, stmt->alter_label),
1557 parser_errposition(pstate, -1));
1558
1563 if (!ellabeloid)
1564 ereport(ERROR,
1566 errmsg("property graph \"%s\" element \"%s\" has no label \"%s\"",
1567 get_rel_name(pgrelid), stmt->element_alias, stmt->alter_label),
1568 parser_errposition(pstate, -1));
1569
1571
1573
1577 }
1578
1579 if (stmt->drop_properties)
1580 {
1581 Oid peoid;
1582 Oid labeloid;
1584 ObjectAddress obj;
1585
1586 if (stmt->element_kind == PROPGRAPH_ELEMENT_KIND_VERTEX)
1587 peoid = get_vertex_oid(pstate, pgrelid, stmt->element_alias, -1);
1588 else
1589 peoid = get_edge_oid(pstate, pgrelid, stmt->element_alias, -1);
1590
1594 CStringGetDatum(stmt->alter_label));
1595 if (!labeloid)
1596 ereport(ERROR,
1598 errmsg("property graph \"%s\" element \"%s\" has no label \"%s\"",
1599 get_rel_name(pgrelid), stmt->element_alias, stmt->alter_label),
1600 parser_errposition(pstate, -1));
1601
1606
1607 if (!ellabeloid)
1608 ereport(ERROR,
1610 errmsg("property graph \"%s\" element \"%s\" has no label \"%s\"",
1611 get_rel_name(pgrelid), stmt->element_alias, stmt->alter_label),
1612 parser_errposition(pstate, -1));
1613
1614 foreach(lc, stmt->drop_properties)
1615 {
1616 char *propname = strVal(lfirst(lc));
1617 Oid propoid;
1618 Oid plpoid;
1619
1624 if (!propoid)
1625 ereport(ERROR,
1627 errmsg("property graph \"%s\" element \"%s\" label \"%s\" has no property \"%s\"",
1628 get_rel_name(pgrelid), stmt->element_alias, stmt->alter_label, propname),
1629 parser_errposition(pstate, -1));
1630
1632
1634 performDeletion(&obj, stmt->drop_behavior, 0);
1635 }
1636
1638 }
1639
1640 /* Remove any orphaned pg_propgraph_property entries */
1641 if (stmt->drop_properties || stmt->drop_vertex_tables || stmt->drop_edge_tables)
1642 {
1644 {
1645 Relation rel;
1646 SysScanDesc scan;
1647 ScanKeyData key[1];
1648
1650 ScanKeyInit(&key[0],
1654 /* XXX no suitable index */
1655 scan = systable_beginscan(rel, InvalidOid, true, NULL, 1, key);
1656 if (!systable_getnext(scan))
1657 {
1658 ObjectAddress obj;
1659
1661 performDeletion(&obj, stmt->drop_behavior, 0);
1662 }
1663
1664 systable_endscan(scan);
1666 }
1667 }
1668
1669 /*
1670 * Invalidate relcache entry of the property graph so that the queries in
1671 * the cached plans referencing the property graph will be rewritten
1672 * considering changes to the propert graph.
1673 */
1675
1676 return pgaddress;
1677}
#define Assert(condition)
Definition c.h:942
void performDeletion(const ObjectAddress *object, DropBehavior behavior, int flags)
Definition dependency.c:279
int errcode(int sqlerrcode)
Definition elog.c:874
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:39
#define NOTICE
Definition elog.h:35
#define ereport(elevel,...)
Definition elog.h:150
#define palloc0_object(type)
Definition fe_memutils.h:75
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:603
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:514
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
#define stmt
void CacheInvalidateRelcacheByRelid(Oid relid)
Definition inval.c:1691
#define NoLock
Definition lockdefs.h:34
#define ShareRowExclusiveLock
Definition lockdefs.h:41
#define AccessShareLock
Definition lockdefs.h:36
#define RowShareLock
Definition lockdefs.h:37
char * get_rel_name(Oid relid)
Definition lsyscache.c:2148
char get_rel_persistence(Oid relid)
Definition lsyscache.c:2298
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
Definition namespace.c:442
@ RVR_MISSING_OK
Definition namespace.h:90
static char * errmsg
const ObjectAddress InvalidObjectAddress
#define ObjectAddressSet(addr, class_id, object_id)
int parser_errposition(ParseState *pstate, int location)
Definition parse_node.c:106
@ PROPGRAPH_ELEMENT_KIND_VERTEX
#define lfirst(lc)
Definition pg_list.h:172
#define lfirst_node(type, lc)
Definition pg_list.h:176
#define foreach_oid(var, lst)
Definition pg_list.h:471
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
static Datum CStringGetDatum(const char *X)
Definition postgres.h:370
#define InvalidOid
unsigned int Oid
static int fb(int x)
static void check_all_labels_properties(Oid pgrelid)
static Oid get_edge_oid(ParseState *pstate, Oid pgrelid, const char *alias, int location)
static ArrayType * propgraph_element_get_key(ParseState *pstate, const List *keycols, Relation element_rel, const char *aliasname, int location)
static Oid get_element_relid(Oid peid)
static Oid get_vertex_oid(ParseState *pstate, Oid pgrelid, const char *alias, int location)
static void insert_property_records(Oid graphid, Oid ellabeloid, Oid pgerelid, const PropGraphProperties *properties)
static Oid insert_label_record(Oid graphid, Oid peoid, const char *label)
static void check_element_label_properties(Oid ellabeloid)
static List * get_graph_label_ids(Oid graphid)
static Oid insert_element_record(ObjectAddress pgaddress, struct element_info *einfo)
static List * get_label_element_label_ids(Oid labelid)
static List * get_graph_property_ids(Oid graphid)
static void check_element_properties(Oid peoid)
static void propgraph_edge_get_ref_keys(ParseState *pstate, const List *keycols, const List *refcols, Relation edge_rel, Relation ref_rel, const char *aliasname, int location, const char *type, ArrayType **outkey, ArrayType **outref, ArrayType **outeqop)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition scankey.c:76
#define BTEqualStrategyNumber
Definition stratnum.h:31
Form_pg_class rd_rel
Definition rel.h:111
ArrayType * key
#define SearchSysCacheExists2(cacheId, key1, key2)
Definition syscache.h:102
#define GetSysCacheOid2(cacheId, oidcol, key1, key2)
Definition syscache.h:111
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40
void RangeVarCallbackOwnsRelation(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg)
#define strVal(v)
Definition value.h:82
void CommandCounterIncrement(void)
Definition xact.c:1102

References AccessShareLock, Assert, BTEqualStrategyNumber, CacheInvalidateRelcacheByRelid(), check_all_labels_properties(), check_element_label_properties(), check_element_properties(), CommandCounterIncrement(), CStringGetDatum(), ereport, errcode(), errdetail(), errmsg, ERROR, fb(), foreach_oid, get_edge_oid(), get_element_relid(), get_graph_label_ids(), get_graph_property_ids(), get_label_element_label_ids(), get_rel_name(), get_rel_persistence(), get_vertex_oid(), GetSysCacheOid2, insert_element_record(), insert_label_record(), insert_property_records(), InvalidObjectAddress, InvalidOid, element_info::key, lfirst, lfirst_node, NoLock, NOTICE, ObjectAddressSet, ObjectIdGetDatum(), palloc0_object, parser_errposition(), performDeletion(), propgraph_edge_get_ref_keys(), propgraph_element_get_key(), PROPGRAPH_ELEMENT_KIND_VERTEX, RangeVarCallbackOwnsRelation(), RangeVarGetRelidExtended(), RelationData::rd_rel, RowShareLock, RVR_MISSING_OK, ScanKeyInit(), SearchSysCacheExists2, ShareRowExclusiveLock, stmt, strVal, systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by ProcessUtilitySlow().

◆ CreatePropGraph()

ObjectAddress CreatePropGraph ( ParseState pstate,
const CreatePropGraphStmt stmt 
)
extern

Definition at line 104 of file propgraphcmds.c.

105{
108 ListCell *lc;
114
115 if (stmt->pgname->relpersistence == RELPERSISTENCE_UNLOGGED)
118 errmsg("property graphs cannot be unlogged because they do not have storage")));
119
121
122 foreach(lc, stmt->vertex_tables)
123 {
125 struct element_info *vinfo;
126 Relation rel;
127
129 vinfo->kind = PGEKIND_VERTEX;
130
132
133 rel = table_open(vinfo->relid, NoLock);
134
135 if (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
137
138 if (vertex->vtable->alias)
139 vinfo->aliasname = vertex->vtable->alias->aliasname;
140 else
141 vinfo->aliasname = vertex->vtable->relname;
142
146 errmsg("alias \"%s\" used more than once as element table", vinfo->aliasname),
147 parser_errposition(pstate, vertex->location)));
148
149 vinfo->key = propgraph_element_get_key(pstate, vertex->vkey, rel, vinfo->aliasname, vertex->location);
150
151 vinfo->labels = vertex->labels;
152
153 table_close(rel, NoLock);
154
156
158 }
159
160 foreach(lc, stmt->edge_tables)
161 {
163 struct element_info *einfo;
164 Relation rel;
165 ListCell *lc2;
170
172 einfo->kind = PGEKIND_EDGE;
173
175
176 rel = table_open(einfo->relid, NoLock);
177
178 if (rel->rd_rel->relpersistence == RELPERSISTENCE_TEMP)
180
181 if (edge->etable->alias)
182 einfo->aliasname = edge->etable->alias->aliasname;
183 else
184 einfo->aliasname = edge->etable->relname;
185
189 errmsg("alias \"%s\" used more than once as element table", einfo->aliasname),
190 parser_errposition(pstate, edge->location)));
191
192 einfo->key = propgraph_element_get_key(pstate, edge->ekey, rel, einfo->aliasname, edge->location);
193
194 einfo->srcvertex = edge->esrcvertex;
195 einfo->destvertex = edge->edestvertex;
196
197 srcrelid = 0;
198 destrelid = 0;
199 foreach(lc2, vertex_infos)
200 {
201 struct element_info *vinfo = lfirst(lc2);
202
203 if (strcmp(vinfo->aliasname, edge->esrcvertex) == 0)
204 srcrelid = vinfo->relid;
205
206 if (strcmp(vinfo->aliasname, edge->edestvertex) == 0)
207 destrelid = vinfo->relid;
208
209 if (srcrelid && destrelid)
210 break;
211 }
212 if (!srcrelid)
215 errmsg("source vertex \"%s\" of edge \"%s\" does not exist",
216 edge->esrcvertex, einfo->aliasname),
217 parser_errposition(pstate, edge->location)));
218 if (!destrelid)
221 errmsg("destination vertex \"%s\" of edge \"%s\" does not exist",
222 edge->edestvertex, einfo->aliasname),
223 parser_errposition(pstate, edge->location)));
224
227
228 propgraph_edge_get_ref_keys(pstate, edge->esrckey, edge->esrcvertexcols, rel, srcrel,
229 einfo->aliasname, edge->location, "SOURCE",
230 &einfo->srckey, &einfo->srcref, &einfo->srceqop);
231 propgraph_edge_get_ref_keys(pstate, edge->edestkey, edge->edestvertexcols, rel, destrel,
232 einfo->aliasname, edge->location, "DESTINATION",
233 &einfo->destkey, &einfo->destref, &einfo->desteqop);
234
235 einfo->labels = edge->labels;
236
239
240 table_close(rel, NoLock);
241
243
245 }
246
247 cstmt->relation = stmt->pgname;
248 cstmt->oncommit = ONCOMMIT_NOOP;
249
250 /*
251 * Automatically make it temporary if any component tables are temporary
252 * (see also DefineView()).
253 */
254 if (stmt->pgname->relpersistence == RELPERSISTENCE_PERMANENT
256 {
257 cstmt->relation = copyObject(cstmt->relation);
258 cstmt->relation->relpersistence = RELPERSISTENCE_TEMP;
260 (errmsg("property graph \"%s\" will be temporary",
261 stmt->pgname->relname)));
262 }
263
265
266 foreach(lc, vertex_infos)
267 {
268 struct element_info *vinfo = lfirst(lc);
269 Oid peoid;
270
273 }
274
275 foreach(lc, edge_infos)
276 {
277 struct element_info *einfo = lfirst(lc);
278 Oid peoid;
279 ListCell *lc2;
280
281 /*
282 * Look up the vertices again. Now the vertices have OIDs assigned,
283 * which we need.
284 */
285 foreach(lc2, vertex_infos)
286 {
287 struct element_info *vinfo = lfirst(lc2);
288
289 if (strcmp(vinfo->aliasname, einfo->srcvertex) == 0)
290 {
291 einfo->srcvertexid = vinfo->elementid;
292 einfo->srcrelid = vinfo->relid;
293 }
294 if (strcmp(vinfo->aliasname, einfo->destvertex) == 0)
295 {
296 einfo->destvertexid = vinfo->elementid;
297 einfo->destrelid = vinfo->relid;
298 }
299 if (einfo->srcvertexid && einfo->destvertexid)
300 break;
301 }
302 Assert(einfo->srcvertexid);
303 Assert(einfo->destvertexid);
304 Assert(einfo->srcrelid);
305 Assert(einfo->destrelid);
308 }
309
311
315
316 return pgaddress;
317}
List * lappend(List *list, void *datum)
Definition list.c:339
List * lappend_oid(List *list, Oid datum)
Definition list.c:375
bool list_member(const List *list, const void *datum)
Definition list.c:661
#define copyObject(obj)
Definition nodes.h:232
#define makeNode(_type_)
Definition nodes.h:161
#define NIL
Definition pg_list.h:68
@ ONCOMMIT_NOOP
Definition primnodes.h:59
Definition pg_list.h:54
ObjectAddress DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ObjectAddress *typaddress, const char *queryString)
Definition tablecmds.c:784
String * makeString(char *str)
Definition value.c:63

References AccessShareLock, Assert, check_all_labels_properties(), check_element_properties(), CommandCounterIncrement(), copyObject, DefineRelation(), element_info::destrelid, ereport, errcode(), errmsg, ERROR, fb(), foreach_oid, insert_element_record(), InvalidOid, lappend(), lappend_oid(), lfirst, lfirst_node, list_member(), makeNode, makeString(), NIL, NoLock, NOTICE, ONCOMMIT_NOOP, palloc0_object, parser_errposition(), propgraph_edge_get_ref_keys(), propgraph_element_get_key(), RangeVarCallbackOwnsRelation(), RangeVarGetRelidExtended(), RelationData::rd_rel, element_info::srcrelid, stmt, table_close(), and table_open().

Referenced by ProcessUtilitySlow().