Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
109 changes: 84 additions & 25 deletions src/backend/catalog/ag_label.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "access/genam.h"
#include "catalog/indexing.h"
#include "catalog/namespace.h"
#include "executor/executor.h"
#include "nodes/makefuncs.h"
#include "utils/builtins.h"
Expand Down Expand Up @@ -297,46 +298,104 @@ List *get_all_edge_labels_per_graph(EState *estate, Oid graph_oid)
HeapTuple tuple;
TupleTableSlot *slot;
ResultRelInfo *resultRelInfo;
Oid index_oid;

/* setup scan keys to get all edges for the given graph oid */
ScanKeyInit(&scan_keys[1], Anum_ag_label_graph, BTEqualStrategyNumber,
F_OIDEQ, ObjectIdGetDatum(graph_oid));
ScanKeyInit(&scan_keys[0], Anum_ag_label_kind, BTEqualStrategyNumber,
F_CHAREQ, CharGetDatum(LABEL_TYPE_EDGE));
index_oid = get_relname_relid("ag_label_graph_oid_index",
get_namespace_oid("ag_catalog", false));

/* setup the table to be scanned */
ag_label = table_open(ag_label_relation_id(), RowExclusiveLock);
scan_desc = table_beginscan(ag_label, estate->es_snapshot, 2, scan_keys);

resultRelInfo = create_entity_result_rel_info(estate, "ag_catalog",
"ag_label");

slot = ExecInitExtraTupleSlot(
estate, RelationGetDescr(resultRelInfo->ri_RelationDesc),
&TTSOpsHeapTuple);

/* scan through the results and get all the label names. */
while(true)
if (OidIsValid(index_oid))
{
Relation index_rel;
IndexScanDesc index_scan_desc;

slot = ExecInitExtraTupleSlot(
estate, RelationGetDescr(resultRelInfo->ri_RelationDesc),
&TTSOpsBufferHeapTuple);

index_rel = index_open(index_oid, RowExclusiveLock);

ScanKeyInit(&scan_keys[0], Anum_ag_label_name, BTEqualStrategyNumber,
F_OIDEQ, ObjectIdGetDatum(graph_oid));

Comment on lines +323 to +325
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the index-scan setup, ScanKeyInit() uses Anum_ag_label_name as the scan-key attno. For index scans the attno should be the index column number (typically 1 for the first index key), not a heap attribute-number macro (even if it currently happens to be 1). Using the heap Anum macro here is misleading and easy to break if catalog columns are ever reordered—use an explicit index-key attno instead (and consider using ag_label_graph_oid_index_id() rather than name-based lookup).

Copilot uses AI. Check for mistakes.
index_scan_desc = index_beginscan(ag_label, index_rel, estate->es_snapshot, NULL, 1, 0);
index_rescan(index_scan_desc, scan_keys, 1, NULL, 0);

while (index_getnext_slot(index_scan_desc, ForwardScanDirection, slot))
{
Name label;
Name lval;
bool isNull;
Datum datum;
char kind;

/*There isn't field kind in index. So we should check it by hands*/
datum = slot_getattr(slot, Anum_ag_label_kind, &isNull);
if (isNull)
continue;

kind = DatumGetChar(datum);

if (kind != LABEL_TYPE_EDGE)
continue;

datum = slot_getattr(slot, Anum_ag_label_name, &isNull);
if (!isNull)
{
label = DatumGetName(datum);
lval = (Name) palloc(NAMEDATALEN);
namestrcpy(lval, NameStr(*label));
labels = lappend(labels, lval);
}
}

index_endscan(index_scan_desc);
index_close(index_rel, RowExclusiveLock);
} else
{
Name label;
bool isNull;
Datum datum;
slot = ExecInitExtraTupleSlot(
estate, RelationGetDescr(resultRelInfo->ri_RelationDesc),
&TTSOpsHeapTuple);

tuple = heap_getnext(scan_desc, ForwardScanDirection);
// setup scan keys to get all edges for the given graph oid
ScanKeyInit(&scan_keys[1], Anum_ag_label_graph, BTEqualStrategyNumber,
F_OIDEQ, ObjectIdGetDatum(graph_oid));
ScanKeyInit(&scan_keys[0], Anum_ag_label_kind, BTEqualStrategyNumber,
F_CHAREQ, CharGetDatum(LABEL_TYPE_EDGE));
Comment on lines +365 to +369
Copy link

Copilot AI Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file uses C++-style '//' comments in newly added code. The rest of the backend C codebase follows C90/C-style block comments, and using '//' can break builds under stricter C90 settings. Please convert these to /* ... */ comments for consistency and portability.

Copilot uses AI. Check for mistakes.

/* no more labels to process */
if (!HeapTupleIsValid(tuple))
break;
scan_desc = table_beginscan(ag_label, estate->es_snapshot, 2, scan_keys);

ExecStoreHeapTuple(tuple, slot, false);
// scan through the results and get all the label names.
while(true)
{
Name label;
Name lval;
bool isNull;
Datum datum;

datum = slot_getattr(slot, Anum_ag_label_name, &isNull);
label = DatumGetName(datum);
tuple = heap_getnext(scan_desc, ForwardScanDirection);

labels = lappend(labels, label);
}
// no more labels to process
if (!HeapTupleIsValid(tuple))
break;

ExecStoreHeapTuple(tuple, slot, false);

table_endscan(scan_desc);
datum = slot_getattr(slot, Anum_ag_label_name, &isNull);
label = DatumGetName(datum);

lval = (Name) palloc(NAMEDATALEN);
namestrcpy(lval, NameStr(*label));
labels = lappend(labels, lval);
}

table_endscan(scan_desc);
}

destroy_entity_result_rel_info(resultRelInfo);
table_close(resultRelInfo->ri_RelationDesc, RowExclusiveLock);
Expand Down
Loading