在浏览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函数的声明。
我在age.control
文件的第20行找到了MODULE_PATHNAME
可能引用的内容
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函数?两者之间的链接在哪里?在哪里可以找到?
我已经深入挖掘了大量的代码,但无济于事,我仍然不明白这一切是如何联系在一起的。
2条答案
按热度按时间koaltpgm1#
CREATE EXTENSION命令在控制文件中用
module_pathname
的值替换MODULE_PATHNAME
。通常,这被设置为$libdir/shared_library_name
,然后在C语言函数的CREATE FUNCTION命令中使用MODULE_PATHNAME,这样脚本文件就不需要硬连接共享库的名称。CREATE FUNCTION命令提供共享库文件的路径和所提供函数的链接符号。如果省略链接符号,则假定它与正在定义的SQL函数的名称相同。PostgreSQL按以下顺序搜索共享库:
1.如果名称是绝对路径,则加载给定的文件。
1.如果名称以字符串
$libdir
开头,则该部分将替换为PostgreSQL包库目录名称,该名称在构建时确定。1.如果名称不包含目录部分,则在配置变量dynamic_library_path指定的路径中搜索文件。
1.否则(在路径中找不到文件,或者它包含非绝对目录部分),动态加载器将尝试采用给定的名称,这很可能会失败。(依赖于当前工作目录是不可靠的。)
如果这个序列不起作用,则将特定于平台的共享库文件扩展名(通常为.so)附加到给定的名称后,然后重试这个序列。如果同样失败,则加载将失败。
bqf10yzr2#
此外,SQL查询和代码中的C函数之间的链接是在PostgreSQL中通过使用MODULE_PATHNAME和CREATE FUNCTION命令建立的。
带有C函数定义的共享库文件建立了SQL查询和C函数定义之间的连接,PostgreSQL读取共享库文件并搜索SQL查询中提供的链接符号;一旦找到,它将使用SQL查询的参数运行相应的C函数。
当您运行SQL查询时,如
PostgreSQL搜索包含SQL查询中提供的create_graph函数的C函数定义的共享库文件。
在这个特殊的例子中,CREATE FUNCTION命令中的MODULE_PATHNAME关键字被age.control文件的module_pathname变量的值所取代。这个变量被设置为$libdir/age,这意味着PostgreSQL将在PostgreSQL包库目录中查找名为age的共享库文件。
PostgreSQL在找到create_graph函数的链接符号后加载共享库文件。在AGE示例中,链接符号与函数名相同,因此PostgreSQL在共享库中搜索名为create_graph的C函数。
PostgreSQL在找到create_graph时使用SQL查询中提供的参数调用C函数定义。C函数定义负责处理参数,执行任何所需的检查或操作,并在必要时返回一个值。