Просматривая код AGE, я нашел этот age-1.3.0.sql
файл, в котором, как мне кажется, созданы все таблицы и объявлены все функции.
Например строка номер 94
CREATE FUNCTION ag_catalog.create_graph(graph_name name)
RETURNS void
LANGUAGE c
AS 'MODULE_PATHNAME';
Я предполагаю, что это объявление функции create_graph.
Я нашел то, на что может ссылаться MODULE_PATHNAME
в файле age.control
в строке номер 20.
module_pathname = '$libdir/age'
И определение функции C для создания графика, которая, я полагаю, является этой функцией в /src/backend/commands/graph_commands.c, строка номер 60: -
/* function that is evoked for creating a graph */
Datum create_graph(PG_FUNCTION_ARGS)
{
char *graph;
Name graph_name;
char *graph_name_str;
Oid nsp_id;
//if no argument is passed with the function, graph name cannot be null
if (PG_ARGISNULL(0))
{
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("graph name can not be NULL")));
}
//gets graph name as function argument
graph_name = PG_GETARG_NAME(0);
graph_name_str = NameStr(*graph_name);
//checking if the name of the graph falls under the pre-decided graph naming conventions(regex)
if (!is_valid_graph_name(graph_name_str))
{
ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("graph name is invalid")));
}
//graph name must be unique, a graph with the same name should not exist
if (graph_exists(graph_name_str))
{
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_SCHEMA),
errmsg("graph \"%s\" already exists", graph_name_str)));
}
nsp_id = create_schema_for_graph(graph_name);
//inserts the graph info into the relation which has all the other existing graphs info
insert_graph(graph_name, nsp_id);
//Increment the Command counter before create the generic labels.
CommandCounterIncrement();
//Create the default label tables
graph = graph_name->data;
create_label(graph, AG_DEFAULT_LABEL_VERTEX, LABEL_TYPE_VERTEX, NIL);
create_label(graph, AG_DEFAULT_LABEL_EDGE, LABEL_TYPE_EDGE, NIL);
ereport(NOTICE,
(errmsg("graph \"%s\" has been created", NameStr(*graph_name))));
//according to postgres specification of c-language functions if function returns void this is the syntax
PG_RETURN_VOID();
}
Я хотел спросить, как получается, что когда SQL-запрос типа
SELECT * FROM ag_catalog.create_graph('graph_name');
выполняется, функция C в указанном файле выполняется? Где связь между ними? И где я могу найти его?
Я много копался в коде безрезультатно, я до сих пор не понимаю, как все это связано.
Команда CREATE EXTENSION заменяет MODULE_PATHNAME
значением module_pathname
в управляющем файле. Как правило, для этого устанавливается значение $libdir/shared_library_name
, а затем MODULE_PATHNAME используется в командах CREATE FUNCTION для функций языка C, поэтому файлам сценариев не нужно жестко связывать имя общей библиотеки.
Команда CREATE FUNCTION предоставляет путь к файлу общей библиотеки и символ ссылки для предоставленной функции. Если символ ссылки опущен, предполагается, что он совпадает с именем определяемой функции SQL. PostgreSQL ищет общую библиотеку в следующем порядке:
$libdir
, эта часть заменяется на
Имя каталога библиотеки пакетов PostgreSQL, которое определяется в
время сборки.Если эта последовательность не работает, расширение имени файла общей библиотеки для конкретной платформы (часто .so) добавляется к заданному имени, и эта последовательность повторяется. Если и это не удастся, то и загрузка не удастся.