/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ #include "postgres.h" #include "access/genam.h" #include "access/heapam.h" #include "access/htup.h" #include "access/htup_details.h" #include "access/skey.h" #include "access/stratnum.h" #include "catalog/indexing.h" #include "catalog/namespace.h" #include "nodes/makefuncs.h" #include "storage/lockdefs.h" #include "utils/fmgroids.h" #include "utils/fmgrprotos.h" #include "utils/lsyscache.h" #include "utils/rel.h" #include "utils/relcache.h" #include "catalog/ag_graph.h" #include "utils/ag_cache.h" static Oid get_graph_namespace(const char *graph_name); // INSERT INTO ag_catalog.ag_graph VALUES (graph_name, nsp_id) void insert_graph(const Name graph_name, const Oid nsp_id) { Datum values[Natts_ag_graph]; bool nulls[Natts_ag_graph]; Relation ag_graph; HeapTuple tuple; AssertArg(graph_name); AssertArg(OidIsValid(nsp_id)); ag_graph = table_open(ag_graph_relation_id(), RowExclusiveLock); values[Anum_ag_graph_oid - 1] = ObjectIdGetDatum(nsp_id); nulls[Anum_ag_graph_oid - 1] = false; values[Anum_ag_graph_name - 1] = NameGetDatum(graph_name); nulls[Anum_ag_graph_name - 1] = false; values[Anum_ag_graph_namespace - 1] = ObjectIdGetDatum(nsp_id); nulls[Anum_ag_graph_namespace - 1] = false; tuple = heap_form_tuple(RelationGetDescr(ag_graph), values, nulls); /* * CatalogTupleInsert() is originally for PostgreSQL's catalog. However, * it is used at here for convenience. */ CatalogTupleInsert(ag_graph, tuple); table_close(ag_graph, RowExclusiveLock); } // DELETE FROM ag_catalog.ag_graph WHERE name = graph_name void delete_graph(const Name graph_name) { ScanKeyData scan_keys[1]; Relation ag_graph; SysScanDesc scan_desc; HeapTuple tuple; ScanKeyInit(&scan_keys[0], Anum_ag_graph_name, BTEqualStrategyNumber, F_NAMEEQ, NameGetDatum(graph_name)); ag_graph = table_open(ag_graph_relation_id(), RowExclusiveLock); scan_desc = systable_beginscan(ag_graph, ag_graph_name_index_id(), true, NULL, 1, scan_keys); tuple = systable_getnext(scan_desc); if (!HeapTupleIsValid(tuple)) { ereport(ERROR, (errcode(ERRCODE_UNDEFINED_SCHEMA), errmsg("graph \"%s\" does not exist", NameStr(*graph_name)))); } CatalogTupleDelete(ag_graph, &tuple->t_self); systable_endscan(scan_desc); table_close(ag_graph, RowExclusiveLock); } // Function updates graph name in ag_graph table. void update_graph_name(const Name graph_name, const Name new_name) { ScanKeyData scan_keys[1]; Relation ag_graph; SysScanDesc scan_desc; HeapTuple cur_tuple; Datum repl_values[Natts_ag_graph]; bool repl_isnull[Natts_ag_graph]; bool do_replace[Natts_ag_graph]; HeapTuple new_tuple; // open and scan ag_graph for graph name ScanKeyInit(&scan_keys[0], Anum_ag_graph_name, BTEqualStrategyNumber, F_NAMEEQ, NameGetDatum(graph_name)); ag_graph = table_open(ag_graph_relation_id(), RowExclusiveLock); scan_desc = systable_beginscan(ag_graph, ag_graph_name_index_id(), true, NULL, 1, scan_keys); cur_tuple = systable_getnext(scan_desc); if (!HeapTupleIsValid(cur_tuple)) { ereport(ERROR, (errcode(ERRCODE_UNDEFINED_SCHEMA), errmsg("graph \"%s\" does not exist", NameStr(*graph_name)))); } // modify (which creates a new tuple) the current tuple's graph name MemSet(repl_values, 0, sizeof(repl_values)); MemSet(repl_isnull, false, sizeof(repl_isnull)); MemSet(do_replace, false, sizeof(do_replace)); repl_values[Anum_ag_graph_name - 1] = NameGetDatum(new_name); repl_isnull[Anum_ag_graph_name - 1] = false; do_replace[Anum_ag_graph_name - 1] = true; new_tuple = heap_modify_tuple(cur_tuple, RelationGetDescr(ag_graph), repl_values, repl_isnull, do_replace); // update the current tuple with the new tuple CatalogTupleUpdate(ag_graph, &cur_tuple->t_self, new_tuple); // end scan and close ag_graph systable_endscan(scan_desc); table_close(ag_graph, RowExclusiveLock); } Oid get_graph_oid(const char *graph_name) { graph_cache_data *cache_data; cache_data = search_graph_name_cache(graph_name); if (cache_data) { return cache_data->oid; } else { return InvalidOid; } } static Oid get_graph_namespace(const char *graph_name) { graph_cache_data *cache_data; cache_data = search_graph_name_cache(graph_name); if (!cache_data) { ereport(ERROR, (errcode(ERRCODE_UNDEFINED_SCHEMA), errmsg("graph \"%s\" does not exist", graph_name))); } return cache_data->namespace; } char *get_graph_namespace_name(const char *graph_name) { return get_namespace_name(get_graph_namespace(graph_name)); }