Emmanuel Allison
Posted on July 30, 2023
Apache AGE (short for A Graph Extension) is an extension to PostgreSQL, giving it graph database functionality. It is open source, and contributions to the project are welcomed. An invaluable tool for this is being able to debug the AGE project, and that's what we'll be doing today.
This article is specifically written for Ubuntu, but can be applied to other Linux distributions.
Prerequisite
To debug AGE, we'll need the following.
- PostgreSQL installed from source code.
- Download and install AGE from the source code.
- Download and install Visual Studio Code from here.
- A C compiler. For this article, gcc is used.
Setup
Open the AGE source code in VS Code. You can do that either by opening the folder in VS code or by running the following in the terminal.
cd ~/age
code .
Replace ~/age
with the path to your AGE source.
To configure the project for debugging, we create a folder .vscode
in the project's root folder, and add the following files:launch.json
, settings.json
, and c_cpp_properties.json
.
-
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Attach",
"type": "cppdbg",
"request": "attach",
"program": "/home/hallixon/postgres/bin/postgres",
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
]
}
]
}
The configuration above enables attaching VS Code's debugger to the postgres
process. Replace /home/hallixon/postgres/bin/postgres
with the path to your PostgreSQL installation.
-
settings.json
{
"files.associations": {
"postgres.h": "c",
"genam.h": "c",
"heapam.h": "c",
"tableam.h": "c",
"table.h": "c",
"htup_details.h": "c",
"skey.h": "c",
"pg_operator.h": "c",
"namespace.h": "c"
}
}
This associates the header files with C language, and informs VS Code to use the same syntax highlighting for C on those files for this workspace.
-
c_cpp_properties.json
{
"configurations": [
{
"name": "Linux",
"includePath": [
"/usr/include/**/**",
"${workspaceFolder}/**",
"/usr/include/**",
"/home/hallixon/postgres/include/**",
"/home/hallixon/postgres/include/server/**",
"/home/hallixon/postgresql-13.11/src/**",
"/home/hallixon/postgresql-13.11/**",
"/home/hallixon/postgresql-13.11/src/backend/**",
"/home/hallixon/postgres/lib/**",
"${workspaceFolder}/src/include/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c17",
"cppStandard": "gnu++17",
"intelliSenseMode": "linux-gcc-x64"
}
],
"version": 4
}
Replace all /home/hallixon/postgresql-13.11
with the path to your PostgreSQL source code, and /home/hallixon/postgres
with the path to your PostgreSQL installation.
You're now set to go.
Running PostgreSQL and Apache AGE
You can check if PostgreSQL is running by running the following command.
ps -e | grep postgres
You should receive an output similar to the following.
18813 ? 00:00:00 postgres
18815 ? 00:00:00 postgres
18816 ? 00:00:00 postgres
18817 ? 00:00:00 postgres
18818 ? 00:00:00 postgres
18819 ? 00:00:00 postgres
18820 ? 00:00:00 postgres
If there was no output, then you can start PostgreSQL by running the code below in the folder containing your PostgreSQL installation.
./pg_ctl -D pgdata -l pg_logfile start
Where pgdata
will be the path to PostgreSQL's database configuration files. By default, the environment variable PGDATA
is used. pg_logfile
is a log file for PostgreSQL to append its logs. If it doesn't exist, PostgreSQL will create it.
Now, create a new database and connect to it.
./createdb age_test
./psql age_test
Now, add the AGE extension to the database.
CREATE EXTENSION IF NOT EXISTS age;
LOAD 'age';
SET search_path = ag_catalog, "$user", public;
To run cypher commands, we need a graph database. To create one, run the following code:
SELECT create_graph('test_graph');
Attaching the Debugger
We need the ID of the postgres
process so we can debug it while it runs. To find the process ID, run the following SQL command in the database.
SELECT pg_backend_pid();
In VS Code, with the AGE project open, press F5. A popup will be opened for you to select the process to attach to. Now, type the process ID of the running postgres
backend process, and select the matching process. The integrated terminal in VS Code will open, requiring Superuser access to process.
Enter y
and put in your password.
Debugging the Cypher reverse()
Method
Open agtype.c
in the src/backend/utils/adt folder, and search for age_reverse
in the code using Ctrl + F. This is the method that handles the reverse()
cypher method.
Add a breakpoint like you see in the picture.
Now, go to your terminal and run the SQL query in your database.
SELECT *
FROM cypher('test_graph', $$
RETURN reverse('everywhere')
$$) AS (reverse agtype);
The breakpoint will be hit.
You can view the values of the local variables by hovering over them, or in the Run and Debug View in VS Code, which is preferable.
You can step into the extract_variadic_args
method, by pressing F11.
Now, step out of the method by pressing Shift+F11. Press F11 to move to the next line. In the Run and Debug View, you'll find out that the variable nargs
, which is the number of arguments passed into the reverse()
cypher method, is changed to 1.
Press F5 to continue running. In the terminal, you should see the result of query displayed.
reverse
--------------
"erehwyreve"
(1 row)
Conclusion
In this article, we were able to debug the AGE source code. This step taken will be one the most important in the journey to understanding and contributing to the Apache AGE project.
Please feel free to comment below if you have questions or if this helped you. Thanks!
Posted on July 30, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.