<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Omar Saad</title>
    <description>The latest articles on DEV Community by Omar Saad (@omarsaad).</description>
    <link>https://dev.to/omarsaad</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1058267%2F0537f0a8-90db-42fc-91b4-0f0def534ee5.png</url>
      <title>DEV Community: Omar Saad</title>
      <link>https://dev.to/omarsaad</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/omarsaad"/>
    <language>en</language>
    <item>
      <title>Building a PostgreSQL Database Client with libpq in C: Connecting and Executing Queries</title>
      <dc:creator>Omar Saad</dc:creator>
      <pubDate>Fri, 14 Jul 2023 10:00:09 +0000</pubDate>
      <link>https://dev.to/omarsaad/building-a-postgresql-database-client-with-libpq-in-c-connecting-and-executing-queries-5a51</link>
      <guid>https://dev.to/omarsaad/building-a-postgresql-database-client-with-libpq-in-c-connecting-and-executing-queries-5a51</guid>
      <description>&lt;p&gt;In this tutorial, we will explore the basics of libpq, a powerful library that allows C application developers to seamlessly interact with the PostgreSQL database. Whether you're new to libpq or looking to enhance your understanding, this guide will provide you with the necessary knowledge to leverage its capabilities effectively.&lt;/p&gt;

&lt;p&gt;Throughout this tutorial, we'll cover the fundamental aspects of libpq, starting from establishing connections to executing queries and handling the results. By the end, you'll have a solid foundation for incorporating PostgreSQL functionality into your C applications with ease.&lt;/p&gt;

&lt;p&gt;Before we begin, make sure you have the PostgreSQL server installed and running on your system. With that in place, let's dive into the world of libpq and discover how it can simplify your interaction with the PostgreSQL database in your C applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting Up the Environment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before we dive into using libpq, let's ensure that we have the necessary environment set up on our computer. Follow the steps below to prepare your environment for working with libpq:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Install PostgreSQL:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visit the official PostgreSQL website (&lt;a href="https://www.postgresql.org"&gt;https://www.postgresql.org&lt;/a&gt;) and download the appropriate version for your operating system.&lt;/li&gt;
&lt;li&gt;Follow the installation instructions provided by PostgreSQL to install the software on your computer.&lt;/li&gt;
&lt;li&gt;Make sure to remember the location where PostgreSQL is installed, as we'll need it later.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Choose a Directory:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Decide on a directory where you want to create your C file for working with libpq. This directory can be anywhere on your computer.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Create a C File:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open a text editor or an integrated development environment (IDE) of your choice.&lt;/li&gt;
&lt;li&gt;Create a new file with a ".c" extension (e.g., &lt;code&gt;libpq_example.c&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Save the file in the directory you selected earlier.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, your environment is set up, and you have a dedicated C file to work with libpq. In the next sections, we will explore how to utilize libpq to interact with PostgreSQL from your C application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting Up libpq&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To begin working with libpq in your C program, you need to import the necessary libraries. Open your C program file and include the following libraries at the top:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;libpq-fe.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These libraries provide essential functionalities for your program, including input/output operations, memory allocation and the libpq library itself.&lt;/p&gt;

&lt;p&gt;If your integrated development environment (IDE) displays an error in the &lt;code&gt;libpq-fe.h&lt;/code&gt; include line, don't worry. We will address this issue during the compilation process by linking the required libraries.&lt;/p&gt;

&lt;p&gt;By including these libraries in your program, you're ready to proceed with utilizing libpq to interact with PostgreSQL effectively. In the upcoming sections, we will explore how to establish connections, execute queries, and handle the results using libpq in your C application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Establishing a Connection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To establish a connection to the PostgreSQL database using libpq, we will use the &lt;code&gt;PQconnectdb()&lt;/code&gt; function. This function opens a new database connection based on the parameters provided in the &lt;code&gt;conninfo&lt;/code&gt; string.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;conninfo&lt;/code&gt; string contains one or more parameter settings in the format of &lt;code&gt;keyword=value&lt;/code&gt;, separated by whitespace. You can use default parameters by passing an empty string, or specify custom parameters as needed. To include a null value or a value with spaces, enclose it in single quotes (&lt;code&gt;keyword='value'&lt;/code&gt;). If necessary, escape single quotes within the value using a backslash (&lt;code&gt;\'&lt;/code&gt;). Spaces around the equal sign are optional.&lt;/p&gt;

&lt;p&gt;It's important to note that the &lt;code&gt;PQconnectdb()&lt;/code&gt; function always returns a non-null &lt;code&gt;PGconn&lt;/code&gt; object pointer, unless there is insufficient memory to allocate the object.&lt;/p&gt;

&lt;p&gt;During the connection process, you can check the status of the connection using the &lt;code&gt;PQstatus()&lt;/code&gt; function. If the status is &lt;code&gt;CONNECTION_BAD&lt;/code&gt;, the connection procedure has failed. Conversely, if the status is &lt;code&gt;CONNECTION_OK&lt;/code&gt;, the connection is ready.&lt;/p&gt;

&lt;p&gt;To properly close the connection and free the memory used by the &lt;code&gt;PGconn&lt;/code&gt; object, call the &lt;code&gt;PQfinish()&lt;/code&gt; function. Even if the backend connection attempt fails (as indicated by &lt;code&gt;PQstatus&lt;/code&gt;), it is essential to call &lt;code&gt;PQfinish()&lt;/code&gt; to release the allocated memory. After calling &lt;code&gt;PQfinish()&lt;/code&gt;, the &lt;code&gt;PGconn&lt;/code&gt; pointer should not be used further.&lt;/p&gt;

&lt;p&gt;Here's the complete code to establish a connection to the database using libpq:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;libpq-fe.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"libpq tutorial&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Connect to the database&lt;/span&gt;
    &lt;span class="c1"&gt;// conninfo is a string of keywords and values separated by spaces.&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;conninfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"dbname=your_db_name user=your_user_name password=your_password host=localhost port=5432"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Create a connection&lt;/span&gt;
    &lt;span class="n"&gt;PGconn&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PQconnectdb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conninfo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Check if the connection is successful&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PQstatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;CONNECTION_OK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// If not successful, print the error message and finish the connection&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error while connecting to the database server: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PQerrorMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="c1"&gt;// Finish the connection&lt;/span&gt;
        &lt;span class="n"&gt;PQfinish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Exit the program&lt;/span&gt;
        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// We have successfully established a connection to the database server&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connection Established&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Port: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PQport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Host: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PQhost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DBName: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PQdb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// Close the connection and free the memory&lt;/span&gt;
    &lt;span class="n"&gt;PQfinish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this code, replace &lt;code&gt;your_db_name&lt;/code&gt;, &lt;code&gt;your_user_name&lt;/code&gt;, and &lt;code&gt;your_password&lt;/code&gt; with the appropriate values for your PostgreSQL setup. The program prints the connection details, such as the port, host, and database name, to confirm the successful connection. Finally, the connection is closed using &lt;code&gt;PQfinish()&lt;/code&gt; to release the memory allocated for the &lt;code&gt;PGconn&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Executing Queries&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once a successful connection to the database has been established, we can proceed to execute queries using libpq. The main function we'll use for query execution is &lt;code&gt;PQexec()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;PQexec()&lt;/code&gt; function is used to submit a query to PostgreSQL and wait for the result. It returns a &lt;code&gt;PGresult&lt;/code&gt; pointer, which encapsulates the query result returned by the database backend. In most cases, a non-null pointer is returned, except in situations such as out-of-memory conditions or critical errors preventing the query from being sent to the backend. If a null pointer is returned, it should be treated as a &lt;code&gt;PGRES_FATAL_ERROR&lt;/code&gt; result. To obtain more information about the error, you can use the &lt;code&gt;PQerrorMessage()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;PGresult&lt;/code&gt; structure should be maintained as an abstraction when working with the query result. It is recommended to use accessor functions instead of directly referencing the fields of the &lt;code&gt;PGresult&lt;/code&gt; structure, as the fields may change in future versions of libpq.&lt;/p&gt;

&lt;p&gt;After executing a query using &lt;code&gt;PQexec()&lt;/code&gt;, you can check the result status using &lt;code&gt;PQresultStatus()&lt;/code&gt;. The possible result statuses include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;PGRES_EMPTY_QUERY&lt;/code&gt;: The query string sent to the backend was empty.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PGRES_COMMAND_OK&lt;/code&gt;: The command completed successfully, but no data was returned.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PGRES_TUPLES_OK&lt;/code&gt;: The query executed successfully and returned tuples (rows).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PGRES_COPY_OUT&lt;/code&gt;: Data transfer (Copy Out) from the server has started.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PGRES_COPY_IN&lt;/code&gt;: Data transfer (Copy In) to the server has started.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PGRES_BAD_RESPONSE&lt;/code&gt;: The server's response was not understood.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PGRES_NONFATAL_ERROR&lt;/code&gt;: A non-fatal error occurred during query execution.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PGRES_FATAL_ERROR&lt;/code&gt;: A fatal error occurred during query execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the query result status is &lt;code&gt;PGRES_TUPLES_OK&lt;/code&gt;, you can use various functions to retrieve information about the returned tuples. Some useful functions include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;PQntuples()&lt;/code&gt;: Returns the number of tuples (rows) in the query result.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PQnfields()&lt;/code&gt;: Returns the number of fields (attributes) in each tuple of the query result.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PQfname()&lt;/code&gt;: Returns the field (attribute) name associated with the given field index. Field indices start at 0.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PQftype()&lt;/code&gt;: Returns the field type associated with the given field index. The returned integer represents an internal coding of the type. Field indices start at 0.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PQgetvalue()&lt;/code&gt;: Returns the value of a specific field (attribute) in a tuple of the query result. Tuple and field indices start at 0.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These functions provide essential capabilities for retrieving and working with the query results.&lt;/p&gt;

&lt;p&gt;The full code for establishing a database connection and executing a query using libpq:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdlib.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;libpq-fe.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;argc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"libpq tutorial&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Connect to the database&lt;/span&gt;
    &lt;span class="c1"&gt;// conninfo is a string of keywords and values separated by spaces.&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;conninfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"dbname=your_db_name user=your_user_name password=your_password host=localhost port=5432"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Create a connection&lt;/span&gt;
    &lt;span class="n"&gt;PGconn&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PQconnectdb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conninfo&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Check if the connection is successful&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PQstatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;CONNECTION_OK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// If not successful, print the error message and finish the connection&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error while connecting to the database server: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PQerrorMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="c1"&gt;// Finish the connection&lt;/span&gt;
        &lt;span class="n"&gt;PQfinish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Exit the program&lt;/span&gt;
        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// We have successfully established a connection to the database server&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Connection Established&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Port: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PQport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Host: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PQhost&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DBName: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PQdb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// Execute a query&lt;/span&gt;
    &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"SELECT * FROM your_table_name"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Submit the query and retrieve the result&lt;/span&gt;
    &lt;span class="n"&gt;PGresult&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PQexec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Check the status of the query result&lt;/span&gt;
    &lt;span class="n"&gt;ExecStatusType&lt;/span&gt; &lt;span class="n"&gt;resStatus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PQresultStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Convert the status to a string and print it&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Query Status: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PQresStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resStatus&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

    &lt;span class="c1"&gt;// Check if the query execution was successful&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resStatus&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;PGRES_TUPLES_OK&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// If not successful, print the error message and finish the connection&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error while executing the query: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PQerrorMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="c1"&gt;// Clear the result&lt;/span&gt;
        &lt;span class="n"&gt;PQclear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Finish the connection&lt;/span&gt;
        &lt;span class="n"&gt;PQfinish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Exit the program&lt;/span&gt;
        &lt;span class="n"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// We have successfully executed the query&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Query Executed Successfully&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Get the number of rows and columns in the query result&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PQntuples&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PQnfields&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Number of rows: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Number of columns: %d&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Print the column names&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%s&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PQfname&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Print all the rows and columns&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;cols&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Print the column value&lt;/span&gt;
            &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%s&lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PQgetvalue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;j&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Clear the result&lt;/span&gt;
    &lt;span class="n"&gt;PQclear&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Finish the connection&lt;/span&gt;
    &lt;span class="n"&gt;PQfinish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to replace &lt;code&gt;your_db_name&lt;/code&gt;, &lt;code&gt;your_user_name&lt;/code&gt;, &lt;code&gt;your_password&lt;/code&gt;, and &lt;code&gt;your_table_name&lt;/code&gt; with the appropriate values for your PostgreSQL setup. The program establishes a connection, executes a SELECT query, and displays the query result in a tabular format. Finally, it clears the result and closes the connection using the &lt;code&gt;PQclear()&lt;/code&gt; and &lt;code&gt;PQfinish()&lt;/code&gt; functions, respectively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compiling and Running Your Program&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To compile and run your code, follow the steps below:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Ensure that the PostgreSQL bin directory is included in your environment variables' path. This allows the compiler to locate the necessary PostgreSQL libraries and executables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open the terminal or command prompt and navigate to the directory where your C file is located.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use the following command to compile your code:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   gcc myprogram.c -o myprogram -I "path/to/postgres/include" -L "path/to/postgres/lib" -lpq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;myprogram.c&lt;/code&gt; with the name of your C file. The &lt;code&gt;-I&lt;/code&gt; flag followed by the path to the PostgreSQL include directory specifies the location of the header files. The &lt;code&gt;-L&lt;/code&gt; flag followed by the path to the PostgreSQL lib directory specifies the location of the library files. The &lt;code&gt;-lpq&lt;/code&gt; flag tells the compiler to link against the libpq library.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   gcc myprogram.c -o myprogram -I "/usr/local/pgsql/include" -L "/usr/local/pgsql/lib" -lpq
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Once the compilation is successful, you will have an executable file named &lt;code&gt;myprogram&lt;/code&gt; in the same directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run your program using the following command:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   ./myprogram
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command executes the &lt;code&gt;myprogram&lt;/code&gt; executable.&lt;/p&gt;

&lt;p&gt;Make sure to replace &lt;code&gt;"path/to/postgres/include"&lt;/code&gt; and &lt;code&gt;"path/to/postgres/lib"&lt;/code&gt; with the actual paths to the PostgreSQL include and lib directories on your system.&lt;/p&gt;

&lt;p&gt;By following these steps, you will be able to compile and run your libpq program successfully.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Congratulations! You've Created a C Program to Connect to a PostgreSQL Database and Execute a Query&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here are the references for further reading and exploring libpq and PostgreSQL:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;libpq - PostgreSQL C Library Documentation: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Link: &lt;a href="https://www.postgresql.org/docs/current/libpq.html"&gt;libpq - PostgreSQL C Library Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PostgreSQL Documentation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The official documentation for PostgreSQL, which covers various aspects of working with PostgreSQL, including SQL syntax, administration, and client interfaces.&lt;/li&gt;
&lt;li&gt;Link: &lt;a href="https://www.postgresql.org/docs/current/index.html"&gt;PostgreSQL Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These references will serve as valuable resources to deepen your understanding of libpq and PostgreSQL as you continue to explore and develop your C applications.&lt;/p&gt;

&lt;p&gt;Happy learning and coding!&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>bitnine</category>
      <category>c</category>
      <category>database</category>
    </item>
    <item>
      <title>Indexing in PostgreSQL: Boost Your Database Queries</title>
      <dc:creator>Omar Saad</dc:creator>
      <pubDate>Sun, 09 Jul 2023 10:06:04 +0000</pubDate>
      <link>https://dev.to/omarsaad/indexing-in-postgresql-boost-your-database-queries-hlo</link>
      <guid>https://dev.to/omarsaad/indexing-in-postgresql-boost-your-database-queries-hlo</guid>
      <description>&lt;p&gt;In this tutorial, we will explore the concept of indexing in PostgreSQL, a popular relational database system. Indexing is a technique that PostgreSQL provides to help us retrieve data quickly and efficiently. By using indexes effectively, we can significantly improve the performance of our database queries, making them run faster and smoother.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Indexing?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine you're reading a book and you need to find a specific chapter. Instead of flipping through each page one by one, you can turn to the book's index, which lists the page numbers of each chapter. This way, you can quickly locate the desired chapter without much effort.&lt;/p&gt;

&lt;p&gt;In databases, indexing works similarly. When you want to search for data based on an indexed attribute, you can first search within the data structure that holds the index. This data structure is often sorted, making the search process more efficient. By using indexes, we minimize the need for disk visits, which ultimately speeds up our queries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How are Indexes Stored?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Indexes are typically stored in separate efficient data structures, such as B-trees, in order to enable fast retrieval of the indexed data. B-trees (short for balanced trees) are commonly used in databases because they provide efficient search and retrieval operations.&lt;/p&gt;

&lt;p&gt;A B-tree is a self-balancing tree structure where each node can contain multiple keys and pointers to child nodes. The keys in a B-tree are arranged in a sorted order, allowing for efficient searching and traversal.&lt;/p&gt;

&lt;p&gt;When an index is created on a specific column or set of columns, the database system builds the corresponding B-tree data structure to store the index. This structure organizes the indexed values in a hierarchical manner, which facilitates quick data access.&lt;/p&gt;

&lt;p&gt;The B-tree structure allows for efficient searching by performing a series of comparisons to determine the path through the tree, ultimately leading to the desired data. This minimizes the number of disk accesses required to locate the indexed information, resulting in faster retrieval times.&lt;/p&gt;

&lt;p&gt;By using B-trees and other efficient data structures, databases like PostgreSQL optimize index storage and retrieval, enabling speedy access to indexed data and improving overall query performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Types of Indexes in PostgreSQL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PostgreSQL offers various types of indexes to cater to different use cases. Here are the commonly used index types:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;B-tree:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;B-tree indexes are the default index type in PostgreSQL.&lt;/li&gt;
&lt;li&gt;They are well-suited for handling range queries and provide efficient searching, insertion, and deletion operations.&lt;/li&gt;
&lt;li&gt;B-tree indexes work effectively for most common scenarios.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Hash:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hash indexes use a hash function to map keys to specific locations in the index.&lt;/li&gt;
&lt;li&gt;They are particularly efficient for equality-based lookups but may not perform well with range queries.&lt;/li&gt;
&lt;li&gt;Hash indexes work best when the indexed column has a high number of distinct values.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;GiST (Generalized Search Tree):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GiST indexes are versatile and support a wide range of data types.&lt;/li&gt;
&lt;li&gt;They provide customizable search strategies for specific data types, allowing efficient searching for non-standard criteria.&lt;/li&gt;
&lt;li&gt;GiST indexes are useful for geometric, text, and network data types, among others.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SP-GiST (Space-Partitioned Generalized Search Tree):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SP-GiST indexes are an extension of GiST indexes and offer improved performance for certain types of data.&lt;/li&gt;
&lt;li&gt;They are designed to handle space-partitioning problems and can be advantageous for specific data structures, such as quad-trees or prefix trees.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;GIN (Generalized Inverted Index):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GIN indexes are specialized for handling complex queries involving array-like data types, full-text search, and other composite types.&lt;/li&gt;
&lt;li&gt;They allow efficient searching for values within arrays or composite types, making them suitable for scenarios where containment or similarity checks are required.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When creating an index in PostgreSQL, you can specify the desired index type based on your specific requirements. Each index type has its own advantages and considerations, so it's important to choose the appropriate index type for the given use case.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Disadvantages of Indexes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Although Indexes help to improve query performance in many cases but they also have disadvantages!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Additional Storage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Indexes require additional storage space, although it is typically smaller compared to the size of the table.&lt;/li&gt;
&lt;li&gt;The overhead of maintaining indexes should be considered when estimating storage requirements.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Slower Writes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whenever a row is inserted or updated, the corresponding indexes need to be updated as well.&lt;/li&gt;
&lt;li&gt;This additional maintenance can slow down write operations, so it's essential to evaluate the trade-off between improved read performance and potentially slower writes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It's crucial to understand that indexing is not a universal solution. It requires a thorough understanding of the data and careful consideration of the specific use case. As Stéphane Faroult and Peter Robson state in their book "The Art of SQL," &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Indexing is not a panacea: effective deployment rests on your complete understanding of the data you are dealing with and making the appropriate judgments.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In conclusion, indexes are valuable tools for improving query performance in PostgreSQL. However, it is essential to approach indexing with a clear understanding of why and when to use it. Consider the specific requirements and characteristics of your database before implementing indexes.&lt;/p&gt;

&lt;p&gt;Optimization is an ongoing process when it comes to indexes. Regularly reviewing and optimizing indexes can help ensure that they continue to enhance query performance effectively. This may involve monitoring index usage, considering different index types, and making adjustments as needed.&lt;/p&gt;

&lt;p&gt;Remember, indexing is not a one-size-fits-all solution. It requires careful consideration and optimization to strike the right balance between improved performance and any potential drawbacks. By employing indexing judiciously and continually optimizing it, you can maximize the benefits of indexes in PostgreSQL and enhance the overall efficiency of your database operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://medium.com/geekculture/indexing-in-postgres-db-4cf502ce1b4e"&gt;Medium: Indexing in Postgres DB&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.postgresql.org/docs/current/indexes.html"&gt;PostgreSQL Documentation: Indexes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://planetscale.com/blog/what-are-the-disadvantages-of-database-indexes"&gt;PlanetScale: What Are the Disadvantages of Database Indexes?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>postgres</category>
      <category>database</category>
      <category>bitnine</category>
    </item>
    <item>
      <title>Trigonometric Functions in Apache AGE</title>
      <dc:creator>Omar Saad</dc:creator>
      <pubDate>Wed, 28 Jun 2023 20:00:43 +0000</pubDate>
      <link>https://dev.to/omarsaad/trigonometric-functions-in-apache-age-4hna</link>
      <guid>https://dev.to/omarsaad/trigonometric-functions-in-apache-age-4hna</guid>
      <description>&lt;p&gt;In this tutorial, we will delve into the trigonometric functions offered by Apache AGE. These functions can be utilized in our Cypher queries to enhance their functionality and calculations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Apache AGE ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apache AGE is a graph database system that is built on top of PostgreSQL. It allows users to store, manage, and analyze large-scale graph data in a highly performant and scalable way.&lt;/p&gt;

&lt;p&gt;Apache AGE combines the benefits of a powerful relational database management system (PostgreSQL) with the flexibility and scalability of a graph database. This means that users can store their data in a relational format and also perform graph-based queries and analyses on the data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;PostgreSQL Version 11 or 12: Make sure you have PostgreSQL installed on your machine. Apache AGE relies on PostgreSQL, so it's important to have either version 11 or 12.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Apache AGE Installation and Configuration: Install and configure Apache AGE to seamlessly integrate with your PostgreSQL installation. If you haven't installed PostgreSQL and Apache AGE yet, we recommend following our comprehensive step-by-step guide for easy installation on Windows. You can access the tutorial &lt;a href="https://dev.to/omarsaad/step-by-step-guide-to-install-postgresql-apache-age-on-windows-28gf"&gt;here&lt;/a&gt;. This guide will walk you through the entire process and ensure a smooth setup.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Trigonometric Functions in Apache AGE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;degrees&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;degrees() function in Apache AGE is used to convert radians to degrees.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT *
FROM cypher('graph_name', $$
    RETURN degrees(3.14159)
$$) as (deg agtype);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The number of degrees of 3.14159 is returned which will be around 180.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;radians&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;radians() function in Apache AGE is used to convert degree to radian.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT *
FROM cypher('graph_name', $$
    RETURN radians(180)
$$) as (deg agtype);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The radian of 180 degrees will be returned which is pi.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;pi&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;pi() returns the mathematical constant pi.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT *
FROM cypher('graph_name', $$
    RETURN pi()
$$) as (p agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The constant pi should be returned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;sin&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;sin() returns the sine of the given number.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT *
FROM cypher('graph_name', $$
    RETURN sin(0.5)
$$) as (s agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result of sin(0.5) will be returned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;cos&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;cos() returns the cosine of a given number.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT *
FROM cypher('graph_name', $$
    RETURN cos(0.5)
$$) as (s agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result of cos(0.5) will be returned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tan&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;tan() returns the tangent of a given number.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT *
FROM cypher('graph_name', $$
    RETURN tan(0.5)
$$) as (s agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result of tan(0.5) will be returned.&lt;/p&gt;

&lt;p&gt;In addition to the functions we discussed earlier, Apache AGE also provides other useful trigonometric functions, namely &lt;code&gt;acos()&lt;/code&gt;, &lt;code&gt;asin()&lt;/code&gt;, &lt;code&gt;atan()&lt;/code&gt;, and &lt;code&gt;atan2()&lt;/code&gt;. These functions offer various functionalities for trigonometric calculations. &lt;code&gt;acos()&lt;/code&gt; calculates the arc cosine of a value, &lt;code&gt;asin()&lt;/code&gt; computes the arc sine, &lt;code&gt;atan()&lt;/code&gt; evaluates the arc tangent, and &lt;code&gt;atan2()&lt;/code&gt; allows you to calculate the arc tangent of two given values. The usage of these functions is similar to what we previously explored, making them accessible for performing different trigonometric computations on your graph data within Apache AGE's Cypher queries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In conclusion, Apache AGE offers a range of trigonometric functions that can be leveraged for performing calculations involving angles and trigonometric operations in graph analysis. By incorporating these functions into your Cypher queries, you can enhance your graph analysis workflows and gain deeper insights from your graph data.&lt;/p&gt;

</description>
      <category>apacheage</category>
      <category>postgres</category>
      <category>bitnine</category>
      <category>database</category>
    </item>
    <item>
      <title>Exploring Numeric Functions in Apache AGE: A Comprehensive Tutorial</title>
      <dc:creator>Omar Saad</dc:creator>
      <pubDate>Sat, 24 Jun 2023 22:21:55 +0000</pubDate>
      <link>https://dev.to/omarsaad/exploring-numeric-functions-in-apache-age-a-comprehensive-tutorial-5c1</link>
      <guid>https://dev.to/omarsaad/exploring-numeric-functions-in-apache-age-a-comprehensive-tutorial-5c1</guid>
      <description>&lt;p&gt;In this tutorial, we will delve into the numeric functions offered by Apache AGE. These functions can be utilized in our Cypher queries to enhance their functionality and calculations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Apache AGE ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apache AGE is a graph database system that is built on top of PostgreSQL. It allows users to store, manage, and analyze large-scale graph data in a highly performant and scalable way.&lt;/p&gt;

&lt;p&gt;Apache AGE combines the benefits of a powerful relational database management system (PostgreSQL) with the flexibility and scalability of a graph database. This means that users can store their data in a relational format and also perform graph-based queries and analyses on the data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;PostgreSQL Version 11 or 12: Make sure you have PostgreSQL installed on your machine. Apache AGE relies on PostgreSQL, so it's important to have either version 11 or 12.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Apache AGE Installation and Configuration: Install and configure Apache AGE to seamlessly integrate with your PostgreSQL installation. If you haven't installed PostgreSQL and Apache AGE yet, we recommend following our comprehensive step-by-step guide for easy installation on Windows. You can access the tutorial &lt;a href="https://dev.to/omarsaad/step-by-step-guide-to-install-postgresql-apache-age-on-windows-28gf"&gt;here&lt;/a&gt;. This guide will walk you through the entire process and ensure a smooth setup.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Numeric Functions in Apache AGE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;rand()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;rand()&lt;/code&gt; function in Apache AGE generates a random floating-point number within the range of 0 (inclusive) to 1 (exclusive), denoted as [0, 1). The numbers produced by this function follow an approximate uniform distribution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="n"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;cypher&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'graph_name'&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;$$&lt;/span&gt;
    &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="nf"&gt;rand&lt;/span&gt;&lt;span class="ss"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;$$&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="n"&gt;agtype&lt;/span&gt;&lt;span class="ss"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above query will return a random number.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;abs()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;abs()&lt;/code&gt; function in Apache AGE calculates and returns the absolute value of a given number.&lt;/p&gt;

&lt;p&gt;Here's an example of using the &lt;code&gt;abs()&lt;/code&gt; function in a Cypher query within Apache AGE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="n"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;cypher&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'graph_name'&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;$$&lt;/span&gt;
    &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="nf"&gt;abs&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;$$&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="n"&gt;agtype&lt;/span&gt;&lt;span class="ss"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above query will return the absolute value which is &lt;code&gt;5&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ceil()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;ceil()&lt;/code&gt; function returns the smallest floating-point number that is greater than or equal to the given number and equal to a mathematical integer.&lt;/p&gt;

&lt;p&gt;Here's an example using the &lt;code&gt;ceil()&lt;/code&gt; function in a Cypher query within Apache AGE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="n"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;cypher&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'graph_name'&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;$$&lt;/span&gt;
    &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="nf"&gt;ceil&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; 
&lt;span class="n"&gt;$$&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ceil&lt;/span&gt; &lt;span class="n"&gt;agtype&lt;/span&gt;&lt;span class="ss"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ceiling of 0.1 is returned which is 1.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;floor()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;floor()&lt;/code&gt; function  returns the greatest floating-point number that is less than or equal to the given number and equal to a mathematical integer.&lt;/p&gt;

&lt;p&gt;Here's an example using the &lt;code&gt;floor()&lt;/code&gt; function in a Cypher query within Apache AGE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="n"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;cypher&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'graph_name'&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;$$&lt;/span&gt;
    &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.1&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; 
&lt;span class="n"&gt;$$&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;flr&lt;/span&gt; &lt;span class="n"&gt;agtype&lt;/span&gt;&lt;span class="ss"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The floor of 0.1 is returned which is 0.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;round()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;round()&lt;/code&gt; function returns the value of the given number rounded to the nearest integer.&lt;/p&gt;

&lt;p&gt;Here's an example using the &lt;code&gt;round()&lt;/code&gt; function in a Cypher query within Apache AGE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="n"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;cypher&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'graph_name'&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;$$&lt;/span&gt;
    &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;3.141592&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; 
&lt;span class="n"&gt;$$&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rounded_value&lt;/span&gt; &lt;span class="n"&gt;agtype&lt;/span&gt;&lt;span class="ss"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above query 3.0 is returned.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;sign()&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;sign()&lt;/code&gt; function in Apache AGE returns the sign of a given number. It indicates whether the number is positive, negative, or zero.&lt;/p&gt;

&lt;p&gt;Here's an example using the &lt;code&gt;sign()&lt;/code&gt; function in a Cypher query within Apache AGE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cypher"&gt;&lt;code&gt;&lt;span class="n"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="k"&gt;cypher&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'graph_name'&lt;/span&gt;&lt;span class="ss"&gt;,&lt;/span&gt; &lt;span class="n"&gt;$$&lt;/span&gt;
    &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="nf"&gt;sign&lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; 
&lt;span class="n"&gt;$$&lt;/span&gt;&lt;span class="ss"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="ss"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sign_value&lt;/span&gt; &lt;span class="n"&gt;agtype&lt;/span&gt;&lt;span class="ss"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;sign()&lt;/code&gt; function returns the following values:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1 if the number is positive&lt;/li&gt;
&lt;li&gt;-1 if the number is negative&lt;/li&gt;
&lt;li&gt;0 if the number is zero&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this tutorial, we explored various numeric functions available in Apache AGE and learned how to incorporate them into our Cypher queries. We covered essential functions such as &lt;code&gt;rand()&lt;/code&gt;, &lt;code&gt;abs()&lt;/code&gt;, &lt;code&gt;ceil()&lt;/code&gt;, &lt;code&gt;floor()&lt;/code&gt;, &lt;code&gt;round()&lt;/code&gt;, and &lt;code&gt;sign()&lt;/code&gt;, each serving a distinct purpose in performing calculations and manipulating numeric values. By leveraging these functions, we can enhance the capabilities of our Cypher queries within Apache AGE, enabling us to work with random numbers, absolute values, rounding, ceiling, floor, and signum operations. With this newfound knowledge, you are now equipped to utilize these numeric functions effectively to analyze and manipulate numerical data in your Apache AGE graph databases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://age.apache.org/age-manual/master/index.html"&gt;Apache AGE documentation&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/apache/age"&gt;Apache AGE Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contribute to Apache AGE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/apache/age"&gt;Apache AGE Github&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/apache/age-viewer"&gt;Apache AGE Viewer Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
      <category>database</category>
    </item>
    <item>
      <title>Building Graph Database Applications with Apache AGE and Node.js: A Step-by-Step Tutorial</title>
      <dc:creator>Omar Saad</dc:creator>
      <pubDate>Thu, 22 Jun 2023 20:47:00 +0000</pubDate>
      <link>https://dev.to/omarsaad/building-graph-database-applications-with-apache-age-and-nodejs-a-step-by-step-tutorial-33a1</link>
      <guid>https://dev.to/omarsaad/building-graph-database-applications-with-apache-age-and-nodejs-a-step-by-step-tutorial-33a1</guid>
      <description>&lt;p&gt;In this tutorial we will introduce how to use Apache AGE with your NodeJs application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Apache AGE ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apache AGE is a graph database system that is built on top of PostgreSQL. It allows users to store, manage, and analyze large-scale graph data in a highly performant and scalable way.&lt;/p&gt;

&lt;p&gt;Apache AGE combines the benefits of a powerful relational database management system (PostgreSQL) with the flexibility and scalability of a graph database. This means that users can store their data in a relational format and also perform graph-based queries and analyses on the data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;PostgreSQL Version 11 or 12: Make sure you have PostgreSQL installed on your machine. Apache AGE relies on PostgreSQL, so it's important to have either version 11 or 12.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Apache AGE Installation and Configuration: Install and configure Apache AGE to seamlessly integrate with your PostgreSQL installation. If you haven't installed PostgreSQL and Apache AGE yet, we recommend following our comprehensive step-by-step guide for easy installation on Windows. You can access the tutorial &lt;a href="https://dev.to/omarsaad/step-by-step-guide-to-install-postgresql-apache-age-on-windows-28gf"&gt;here&lt;/a&gt;. This guide will walk you through the entire process and ensure a smooth setup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Node.js: Ensure that Node.js is installed on your system. You can download and install the latest version of Node.js from the official website: &lt;a href="https://nodejs.org/en"&gt;Node.js&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Having Node.js installed will provide the necessary runtime environment for running your Node.js applications and executing JavaScript code.&lt;/p&gt;

&lt;p&gt;Verify the installation by opening a terminal or command prompt and running the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the version number of Node.js printed in the terminal if it is installed correctly.&lt;/p&gt;

&lt;p&gt;If Node.js is not installed, please download and install it using the appropriate installer for your operating system.&lt;/p&gt;

&lt;p&gt;Now that you have Node.js installed, you're ready to proceed with the tutorial and explore the integration of Apache AGE with Node.js and PostgreSQL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apache AGE with NodeJs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1. To initialize a new Node.js project, you can run the &lt;code&gt;npm init&lt;/code&gt; command in your project directory. This command will prompt you with a series of questions to gather information about your project and generate a &lt;code&gt;package.json&lt;/code&gt; file. The &lt;code&gt;package.json&lt;/code&gt; file is essential for managing your project's dependencies and scripts.&lt;/p&gt;

&lt;p&gt;To run &lt;code&gt;npm init&lt;/code&gt;, open your terminal or command prompt, navigate to your project directory, and execute the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will be prompted to enter various details such as the project name, version, description, entry point, test command, repository, and more. Feel free to provide the relevant information according to your project requirements. If you wish to skip any prompts, you can add the &lt;code&gt;-y&lt;/code&gt; flag to automatically generate the &lt;code&gt;package.json&lt;/code&gt; file with default values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm init -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have completed the &lt;code&gt;npm init&lt;/code&gt; process, a &lt;code&gt;package.json&lt;/code&gt; file will be created in your project directory, which will serve as a configuration file for your Node.js project.&lt;/p&gt;

&lt;p&gt;2.To configure your application's environment variables, you'll need to create a &lt;code&gt;.env&lt;/code&gt; file. This file will store the necessary variables for your application to connect to the PostgreSQL database. Here's an example of how the &lt;code&gt;.env&lt;/code&gt; file should be structured:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POSTGRES_HOST=127.0.0.1
POSTGRES_PORT=5432
POSTGRES_DB=your_db_name
POSTGRES_USER=your_user_name
POSTGRES_PASSWORD=your_password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;your_db_name&lt;/code&gt;, &lt;code&gt;your_user_name&lt;/code&gt;, and &lt;code&gt;your_password&lt;/code&gt; with the actual values specific to your PostgreSQL setup. These variables specify the host, port, database name, username, and password required for establishing a connection between your Node.js application and the PostgreSQL database.&lt;/p&gt;

&lt;p&gt;3.Include the following dependencies in &lt;code&gt;package.json&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"express"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^4.17.1"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"pg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^8.5.1"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"dotenv"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^8.2.0"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure that the formatting of your &lt;code&gt;package.json&lt;/code&gt; file remains intact.&lt;/p&gt;

&lt;p&gt;Once you have added the dependencies, save the changes to your &lt;code&gt;package.json&lt;/code&gt; file. Your Node.js application will now be able to utilize these dependencies.&lt;/p&gt;

&lt;p&gt;4. Create &lt;code&gt;server.js&lt;/code&gt; file in your main directory. This file will be the entry point of your application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
require('dotenv').config();

const app = express();
const port = process.env.PORT || 3000;

// Define your routes and middleware here
//TODO

app.listen(port, () =&amp;gt; {
  console.log(`Server running on port ${port}`);
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5. Create a file named &lt;code&gt;database.js&lt;/code&gt; in your project's directory. This file will handle the database connection settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Pool } from 'pg';
import dotenv from 'dotenv';

dotenv.config();

const POSTGRES_HOST = process.env.POSTGRES_HOST;
const POSTGRES_PORT = process.env.POSTGRES_PORT;
const POSTGRES_DB = process.env.POSTGRES_DB;
const POSTGRES_USER = process.env.POSTGRES_USER;
const POSTGRES_PASSWORD = process.env.POSTGRES_PASSWORD;

const client = new Pool({
  host: POSTGRES_HOST,
  port: POSTGRES_PORT,
  database: POSTGRES_DB,
  user: POSTGRES_USER,
  password: POSTGRES_PASSWORD,
  // If local, set ssl to false to avoid errors
  // ssl: true,
});
async function initAGE() {
    const sql = `CREATE EXTENSION IF NOT EXISTS age;
    LOAD 'age';
    client.query(sql);
    SET search_path to ag_catalog,"$user",public; `;
    try{
    const conn = await client.connect();
    await conn.query(sql);
    conn.release();
    } catch (err) {
        throw new Error(`Could not init agent. Error: ${err}`);
    }
}


export default {
    initAGE,
    client
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;6. Create &lt;code&gt;product_model.js&lt;/code&gt; file in which we will implement the basic CRUD operations for our products application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import client from "./database";


export class ProductStore {
    GRAPH_NAME = 'products';
    async getAllProducts() {
        try {
            const conn = await client.connect();
            const sql = `SELECT * FROM 
            cypher('${GRAPH_NAME}', $$
                MATCH (p:Product) RETURN p
                $$)
            as (result agtype)`;
            const result = await conn.query(sql);
            conn.release();
            return result.rows;
        } catch (err) {
            throw new Error(`Could not get products. Error: ${err}`);
        }
    }

    async createProduct(name,price,category) {
        try{
            const conn = await client.connect();
            const sql = `SELECT * FROM 
            cypher('${GRAPH_NAME}', $$
                CREATE (p:Product {name: '${name}', price: ${price}, category: '${category}'}) RETURN p
                $$)
            as (result agtype)`;
            const result = await conn.query(sql);
            conn.release();
            return result.rows;

        } catch (err) {
            throw new Error(`Could not add new product ${product.name}. Error: ${err}`);
        }
    }

    async getProductById(id) {
        try {
            const conn = await client.connect();
            const sql = `SELECT * FROM 
            cypher('${GRAPH_NAME}', $$
                MATCH (p:Product) WHERE id(p) = ${id} RETURN p
                $$)
            as (result agtype)`;
            const result = await conn.query(sql);
            conn.release();
            return result.rows;
        } catch (err) {
            throw new Error(`Could not get product ${id}. Error: ${err}`);
        }
    }

    async updateProduct(id, name, price, category) {
        try {
            const conn = await client.connect();
            const sql = `SELECT * FROM 
            cypher('${GRAPH_NAME}', $$
                MATCH (p:Product) WHERE id(p) = ${id} SET p.name = '${name}', p.price = ${price}, p.category = '${category}' RETURN p
                $$)
            as (result agtype)`;
            const result = await conn.query(sql);
            conn.release();
            return result.rows;
        } catch (err) {
            throw new Error(`Could not update product ${id}. Error: ${err}`);
        }
    }

    async deleteProduct(id) {
        try {
            const conn = await client.connect();
            const sql = `SELECT * FROM 
            cypher('${GRAPH_NAME}', $$
                MATCH (p:Product) WHERE id(p) = ${id} DELETE p
                $$)
            as (result agtype)`;
            const result = await conn.query(sql);
            conn.release();
            return result.rows;
        } catch (err) {
            throw new Error(`Could not delete product ${id}. Error: ${err}`);
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;7. We will edit our &lt;code&gt;server.js&lt;/code&gt; file to add products routes.&lt;br&gt;
   For this example we will only implement GET and POST routes.&lt;br&gt;
   The updated &lt;code&gt;server.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const express = require('express');
require('dotenv').config();


const app = express();
const port = process.env.PORT || 3000;

// Define your routes and middleware here
const initAGE = require('./database').initAGE;
// Load AGE extension
initAGE();
app.get('/products', (req, res) =&amp;gt; {
    try{
    const productModel = require('./product_model');
    const products = productModel.getProducts();
    res.send({
        message : 'Products retrieved successfully',
        data : products
    });
    return;
    } catch (err) {
        res.send({
            message : `Could not get products. Error: ${err}`,
            data : []
        });
        return;
    }

});

app.post('/products', (req, res) =&amp;gt; {
    try{
    const productModel = require('./product_model');
    const products = productModel.createProduct(req.body.name, req.body.price, req.body.category);
    res.send({
        message : 'Products created successfully',
        data : products
    });
    return;
    } catch (err) {
        res.send({
            message : `Could not create products. Error: ${err}`,
            data : []
        });
        return;
    }

});

app.listen(port, () =&amp;gt; {
  console.log(`Server running on port ${port}`);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;8. Run &lt;code&gt;npm install&lt;/code&gt; to install the project dependencies.&lt;/p&gt;

&lt;p&gt;9. Run &lt;code&gt;npm run start&lt;/code&gt; to start nodejs server.&lt;/p&gt;

&lt;p&gt;10. Now you can test the server using postman or any other tools by making the following requests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST localhost:3000/products
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The body of the POST request should be in the following format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"name" : "Iphone 14",
"price": 1000,
"category" : "Mobile phones"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we want to retrieve all the products than we should send the following request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET localhost:3000/products
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This request should return all the products in our database.&lt;/p&gt;

&lt;p&gt;Congratulations on successfully building your Node.js application integrated with PostgreSQL and Apache AGE! You've created a powerful combination that enables efficient data management and advanced graph-based querying. Well done!&lt;/p&gt;

&lt;p&gt;In the upcoming tutorials, we will delve into building more complex applications to further deepen our understanding. We will explore advanced features, demonstrate practical use cases, and tackle more intricate scenarios. By expanding our knowledge and exploring these advanced concepts, we will be able to leverage the full potential of integrating Apache AGE.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://age.apache.org/age-manual/master/index.html"&gt;Apache AGE documentation&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/apache/age"&gt;Apache AGE Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contribute to Apache AGE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/apache/age"&gt;Apache AGE Github&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/apache/age-viewer"&gt;Apache AGE Viewer Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>apacheage</category>
      <category>postgres</category>
      <category>node</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Adding Custom Functions to Apache AGE Source Code: A Step-by-Step Tutorial</title>
      <dc:creator>Omar Saad</dc:creator>
      <pubDate>Sun, 04 Jun 2023 19:55:49 +0000</pubDate>
      <link>https://dev.to/omarsaad/adding-custom-functions-to-apache-age-source-code-a-step-by-step-tutorial-5756</link>
      <guid>https://dev.to/omarsaad/adding-custom-functions-to-apache-age-source-code-a-step-by-step-tutorial-5756</guid>
      <description>&lt;p&gt;In this tutorial, we will walk you through the process of adding a new function to the Apache AGE source code. For the purpose of this tutorial, we will create a simple function that takes two integer numbers as arguments, adds them together, and returns the result.&lt;/p&gt;

&lt;p&gt;Also in the upcoming tutorial, we will improve our function by enabling it to accept &lt;code&gt;agtype&lt;/code&gt; as an input, allowing seamless integration with Cypher queries. Stay tuned for more!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Apache AGE ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apache AGE is a graph extension for PostgreSQL, designed to enhance its capabilities by adding graph database functionality. With AGE, users can utilize the power and flexibility of PostgreSQL while also leveraging graph-based data storage, querying, and analysis. This combination allows for efficient handling of graph data within a familiar PostgreSQL environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;PostgreSQL Version 11 or 12: Make sure you have PostgreSQL installed on your machine. Apache AGE relies on PostgreSQL, so it's important to have either version 11 or 12.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Apache AGE Installation and Configuration: Install and configure Apache AGE to seamlessly integrate with your PostgreSQL installation. If you haven't installed PostgreSQL and Apache AGE yet, we recommend following our comprehensive step-by-step guide for easy installation on Windows. You can access the tutorial &lt;a href="https://dev.to/omarsaad/step-by-step-guide-to-install-postgresql-apache-age-on-windows-28gf"&gt;here&lt;/a&gt;. This guide will walk you through the entire process and ensure a smooth setup.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Creating a Custom Function in Apache AGE Source Code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this section of the tutorial, we will go through the steps to create a custom function that adds two integer numbers and returns the result. Follow these numbered steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a new file named &lt;code&gt;math_functions.c&lt;/code&gt; in the &lt;code&gt;src/backend/commands&lt;/code&gt; folder. This file will serve as the implementation for our custom mathematical function.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open the &lt;code&gt;math_functions.c&lt;/code&gt; file in your preferred text editor or integrated development environment (IDE).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Include the necessary header files for the function implementation. These may include &lt;code&gt;postgres.h&lt;/code&gt; for PostgreSQL-specific declarations and &lt;code&gt;fmgr.h&lt;/code&gt; for function manager definitions.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;4. Define the &lt;code&gt;adder&lt;/code&gt; function as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt; &lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"postgres.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt; &lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"fmgr.h"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
 &lt;span class="n"&gt;PG_FUNCTION_INFO_V1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;adder&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

 &lt;span class="n"&gt;Datum&lt;/span&gt;
 &lt;span class="nf"&gt;adder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PG_FUNCTION_ARGS&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
 &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;elog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;INFO&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Adder function called"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PG_ARGISNULL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;PG_ARGISNULL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;ereport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ERROR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;errcode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ERRCODE_INVALID_PARAMETER_VALUE&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                        &lt;span class="n"&gt;errmsg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Num1 and Num2 must not be NULL"&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// // Get the values of the two arguments&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PG_GETARG_INT32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PG_GETARG_INT32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;arg1&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;arg2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="n"&gt;PG_RETURN_INT32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, we first include the necessary header files: postgres.h for PostgreSQL-specific declarations and fmgr.h for function manager definitions and &lt;code&gt;utils/agtype.h&lt;/code&gt; for AGType functionality, are included.&lt;/p&gt;

&lt;p&gt;The line &lt;code&gt;PG_FUNCTION_INFO_V1(adder);&lt;/code&gt; defines the function information for the adder function. This macro is necessary for PostgreSQL to recognize the function.&lt;/p&gt;

&lt;p&gt;The adder function is implemented to take two int arguments, arg1 and arg2. It calculates their sum and stores it in the result variable.&lt;/p&gt;

&lt;p&gt;Then a check is performed to verify if both arguments are provided. If any of the arguments is not provided (i.e., &lt;code&gt;NULL&lt;/code&gt;), an error is raised using the &lt;code&gt;ereport&lt;/code&gt; function, specifying that both arguments must be provided.&lt;/p&gt;

&lt;p&gt;Finally, &lt;code&gt;PG_RETURN_INT32(result)&lt;/code&gt; is used to return the result of the addition as the output of the function.&lt;/p&gt;

&lt;p&gt;Note: &lt;code&gt;elog&lt;/code&gt; is used to print to the console you can use it to debug your code.&lt;/p&gt;

&lt;p&gt;5. In the main project directory, locate the file named &lt;code&gt;Makefile&lt;/code&gt; and open it. Within the &lt;code&gt;Makefile&lt;/code&gt;, locate the &lt;code&gt;OBJS&lt;/code&gt; section and add the following directory to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/backend/commands/math_functions.o 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding this entry to the &lt;code&gt;OBJS&lt;/code&gt; section ensures that the object file is included in the compilation process when building the project.&lt;/p&gt;

&lt;p&gt;6. Open the &lt;code&gt;age--1.2.0.sql&lt;/code&gt; file and add the following signature to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- Signature: adder(integer, integer)
-- Purpose: Adds two integers and returns the result.
CREATE  FUNCTION adder(int, int)
    RETURNS int
    LANGUAGE c
    AS 'MODULE_PATHNAME';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above code adds a signature to the &lt;code&gt;age--1.2.0.sql&lt;/code&gt; file. This signature defines a function named &lt;code&gt;adder&lt;/code&gt; that takes two integer arguments. The function is implemented in the C language and its code resides in the shared library specified by &lt;code&gt;'MODULE_PATHNAME'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;7. Navigate to the main project directory and execute the command &lt;code&gt;make install&lt;/code&gt; to build the source code.&lt;/p&gt;

&lt;p&gt;8. To reset the Apache AGE extension and start fresh, you can execute the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DROP EXTENSION age CASCADE;
CREATE EXTENSION age;
LOAD 'age';
SET search_path = ag_catalog, "$user", public;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;9. Run the following command to start the database server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; pg_ctl -D /path/to/data/directory -l logfile -o  "-p &amp;lt;your_port_number&amp;gt;" start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;/path/to/data/directory&lt;/code&gt; with the actual path to your PostgreSQL data directory. This is the directory where the database files are stored.&lt;/p&gt;

&lt;p&gt;Replace &lt;code&gt;&amp;lt;your_port_number&amp;gt;&lt;/code&gt; with the port number on which you want the database server to listen.&lt;/p&gt;

&lt;p&gt;Running this command will start the PostgreSQL database server using the specified data directory and port number. The server log will be written to the specified &lt;code&gt;logfile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;10. Testing Our Function.&lt;/p&gt;

&lt;p&gt;First start &lt;code&gt;psql&lt;/code&gt; using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;psql -U &amp;lt;your_username&amp;gt; -p &amp;lt;your_port_number&amp;gt; -d &amp;lt;your_database_name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we will call our function with 1 an 2 as an arguments.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;ag_catalog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;adder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kORMcZtv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3nq85d1ug28p5f1rbgi8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kORMcZtv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3nq85d1ug28p5f1rbgi8.png" alt="Function call output" width="552" height="130"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's fantastic! Creating your first function in the Apache AGE source code is indeed a significant step towards contributing to the project. By adding custom functionality, you can enhance the capabilities of Apache AGE and make a valuable contribution to the community.&lt;/p&gt;

&lt;p&gt;Contributing to open-source projects like Apache AGE not only allows you to expand your skills but also enables you to collaborate with other developers and make a positive impact on the project's development.&lt;/p&gt;

&lt;p&gt;Congratulations on taking this important step, and best of luck with your future contributions to Apache AGE!&lt;/p&gt;

&lt;p&gt;In the upcoming tutorial, we will improve our function by enabling it to accept &lt;code&gt;agtype&lt;/code&gt; as an input, allowing seamless integration with Cypher queries. Stay tuned for more!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://dev.to/rrrokhtar/guide-to-age-contribution-and-modifying-the-source-code-to-add-new-functions-l7m"&gt;Guide to AGE contribution and modifying the source code to add new functions&lt;/a&gt;&lt;br&gt;
&lt;a href="https://age.apache.org/age-manual/master/index.html"&gt;Apache AGE documentation&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/apache/age"&gt;Apache AGE Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contribute to Apache AGE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/apache/age"&gt;Apache AGE Github&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/apache/age-viewer"&gt;Apache AGE Viewer Github&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Mastering Query Performance Analysis and Query Plan Understanding in Apache AGE</title>
      <dc:creator>Omar Saad</dc:creator>
      <pubDate>Fri, 19 May 2023 13:09:56 +0000</pubDate>
      <link>https://dev.to/omarsaad/mastering-query-performance-analysis-and-query-plan-understanding-in-apache-age-56d</link>
      <guid>https://dev.to/omarsaad/mastering-query-performance-analysis-and-query-plan-understanding-in-apache-age-56d</guid>
      <description>&lt;p&gt;Welcome to our tutorial on analyzing query performance and understanding the exact query plan executed by Apache AGE. In today's data-driven world, optimizing query execution is crucial for efficient data processing and extracting valuable insights. By diving into the intricacies of query analysis, you can uncover potential performance bottlenecks and make informed decisions to enhance the speed and resource utilization of your queries.&lt;/p&gt;

&lt;p&gt;In this tutorial, we will guide you through the process of analyzing query performance in Apache AGE.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Apache AGE ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apache AGE is a graph database system that is built on top of PostgreSQL. It allows users to store, manage, and analyze large-scale graph data in a highly performant and scalable way.&lt;/p&gt;

&lt;p&gt;Apache AGE combines the benefits of a powerful relational database management system (PostgreSQL) with the flexibility and scalability of a graph database. This means that users can store their data in a relational format and also perform graph-based queries and analyses on the data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before diving into the query performance analysis and query plan understanding in Apache AGE, make sure you have the following prerequisites in place:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;PostgreSQL Version 11 or 12: Ensure that you have PostgreSQL installed on your machine. Apache AGE works in conjunction with PostgreSQL, so having either version 11 or 12 is necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Apache AGE Installation and Configuration: Install and configure Apache AGE to work seamlessly with your PostgreSQL installation. This integration will enable you to leverage Apache AGE's powerful capabilities for query performance analysis and query plan understanding.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you haven't installed PostgreSQL and Apache AGE yet, we recommend following our step-by-step guide for easy installation on Windows. You can find the tutorial &lt;a href="https://dev.to/omarsaad/step-by-step-guide-to-install-postgresql-apache-age-on-windows-28gf"&gt;here&lt;/a&gt;. This guide will walk you through the installation process, ensuring a smooth setup for your query analysis journey in Apache AGE.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating a simple graph database schema&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this section, we will create a simple graph database schema specifically tailored for an online mobile phone store. This schema will serve as the foundation for our query analysis examples in this tutorial.&lt;/p&gt;

&lt;p&gt;To begin, execute the following query to create a graph named &lt;code&gt;mobile_phones_store&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT create_graph('mobile_phones_store');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our graph, we will have two types of vertices: 'User' and 'Product'. The 'User' vertex represents the customers of the online store, while the 'Product' vertex represents the mobile phones available for purchase.&lt;/p&gt;

&lt;p&gt;Additionally, we will have one type of edge called 'PURCHASED'. This edge signifies the relationship between a 'User' and a 'Product' when a user makes a purchase.&lt;/p&gt;

&lt;p&gt;Then we will populate our graph database with some data using the following queries:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adding users to our database:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM cypher('mobile_phones_store',
$$
MERGE(:User{name:"user1" , country:"USA" , birth_date:"10-10-1980"})

 $$) as (res agtype)
;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM cypher('mobile_phones_store',
$$
MERGE(:User{name:"user2" , country:"Egypt" , birth_date:"7-7-2000"})

 $$) as (res agtype)
;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can repeat the above query pattern for any number of users you want to add. Simply change the user details such as name, country, and birth date accordingly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adding products to our database:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM cypher('mobile_phones_store',
$$
MERGE(:Product{name:"Iphone 14", brand:"Apple", price:1000.00})
$$) AS (V agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM cypher('mobile_phones_store',
$$
MERGE(:Product{name:"Samsung S23", brand:"Samsung", price:800.00})
$$) AS (V agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can add any number of products you want.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adding Relationships&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM cypher('mobile_phones_store',
$$
MATCH (u:User{name:"user1"}), (p:Product{name:"Iphone 14"})
MERGE (u)-[:PURCHASED]-&amp;gt;(p)
$$) AS (res agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we're adding a relationship of type "PURCHASED" between the user "user1" and the product "Product1". You can modify the query by changing the user and product names to create relationships between different users and products.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Query Execution and Analysis&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that we have created a sample graph database and populated it with data, it's time to dive into query execution and analysis. In this section, we will explore various techniques and tools to analyze the performance of queries and understand the query plans executed by Apache AGE.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why we need to know how our query is executed ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Understanding how a query is executed is crucial for several reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Query Performance Optimization: By knowing how a query is executed, you can identify performance bottlenecks and optimize the query for better execution. You can analyze the query plan, identify expensive operations, and make informed decisions to improve the query's performance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Identifying Performance Issues: If a query is not performing well, understanding its execution process can help you pinpoint the areas causing the slowdown. It allows you to identify inefficient joins, excessive data scans, or suboptimal use of indexes. This knowledge enables you to address these issues and optimize the query accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Efficient Indexing: Understanding query execution helps you make informed decisions about indexing. You can analyze the query plan and identify which columns are frequently used in filters or joins. This knowledge allows you to create appropriate indexes on those columns, improving query performance by reducing the data retrieval and processing overhead.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Query Tuning and Optimization: When you know how a query is executed, you can tune and optimize it by rewriting the query, restructuring the schema, or applying query hints. This knowledge helps you make informed decisions to achieve better query performance and resource utilization.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;How to know the execution plan of a query in Apache AGE ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To know the execution plan in Apache AGE, you can use the EXPLAIN keyword. It provides detailed information about how the engine executes a query.&lt;/p&gt;

&lt;p&gt;Let's take an example where we want to retrieve all users who have purchased any Apple products. To analyze the execution plan, you can run the following query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM cypher('mobile_phones_store',$$
EXPLAIN MATCH (u:User)-[r:PURCHASED]-&amp;gt;(p:Product{brand: "Apple"}) 
RETURN u,r,p

$$) AS (u agtype,r agtype,p agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output of the query is: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R1DXANf5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/weleqpuumvb6pc8ih2ht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R1DXANf5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/weleqpuumvb6pc8ih2ht.png" alt="Image description" width="800" height="383"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The execution plan:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MwlB0d6L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yc3l86pw65kmbqe0g8tt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MwlB0d6L--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yc3l86pw65kmbqe0g8tt.png" alt="Image description" width="800" height="197"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The query plan suggests that the execution involves a hash join operation and a nested loop operation.&lt;/p&gt;

&lt;p&gt;1) Hash Join:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Estimated cost: The estimated cost of the hash join operation is between 1.09 and 3.29 (representing the overall expense of executing the join).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Expected rows: The hash join is expected to produce 2 rows as a result.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Width: The width of each row in the hash join operation is estimated to be 96 bytes. This refers to the approximate size of each row in terms of the amount of data it contains.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Hash condition: The join operation is performed based on the "start_id" column of the "PURCHASED" relation (which represents the relationship between users and products) and the "id" column of the "USER" relation. This means that the hash join will match rows where the "start_id" in the "PURCHASED" relation is equal to the "id" in the "USER" relation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2) Nested Loop:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Estimated cost: 0.00 to 2.14&lt;/li&gt;
&lt;li&gt;Expected rows: 2&lt;/li&gt;
&lt;li&gt;Width: 108&lt;/li&gt;
&lt;li&gt;Join filter: The join is filtered based on the "end_id" column of relation "r"(which is the "PURCHASED" edge) and the "id" column of relation "p" (which is the "Product" relation).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;a. Seq Scan on "Product" p:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Estimated cost: 0.00 to 1.03&lt;/li&gt;
&lt;li&gt;Expected rows: 1&lt;/li&gt;
&lt;li&gt;Width: 79&lt;/li&gt;
&lt;li&gt;Filter: The scan is filtered based on the brand property value which is "Apple" in our example.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;"Seq Scan" stands for Sequential Scan, which is a type of table access method used in database systems. It refers to the process of scanning a table sequentially from the beginning to the end to retrieve the desired rows.&lt;/p&gt;

&lt;p&gt;This means that a sequential scan is performed on the "Product" table (relation "p"). The database engine reads each row of the table in a sequential manner to check for the desired condition. In this case, the condition is applied to the "properties" column to filter the rows and select only those where the "brand" property matches "Apple".&lt;/p&gt;

&lt;p&gt;The estimated cost represents the expected expense of performing the sequential scan operation, which can vary depending on factors such as the size of the table and the efficiency of the storage system. The expected rows and width provide estimates about the number of rows and the size of each row for the "Product" table in this particular scan operation.&lt;/p&gt;

&lt;p&gt;b. Seq Scan on "PURCHASED" r:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Estimated cost: 0.00 to 1.05&lt;/li&gt;
&lt;li&gt;Expected rows: 5&lt;/li&gt;
&lt;li&gt;Width: 29&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3) Hash:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Estimated cost: 1.04&lt;/li&gt;
&lt;li&gt;Expected rows: 4&lt;/li&gt;
&lt;li&gt;Width: 76&lt;/li&gt;
&lt;li&gt;Seq Scan on "User" u:&lt;/li&gt;
&lt;li&gt;Estimated cost: 0.00 to 1.04&lt;/li&gt;
&lt;li&gt;Expected rows: 4&lt;/li&gt;
&lt;li&gt;Width: 76&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Overall, the execution plan suggests that the query involves joining the "Product" table with the "PURCHASED" table, filtered based on the brand value "Apple". The result is then joined with the "User" table based on their respective IDs. The exact costs, row estimates, and widths may vary depending on the data and database statistics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this tutorial, we learned how to analyze query performance and understand the execution plan in Apache AGE. By examining the execution plan using the &lt;code&gt;EXPLAIN&lt;/code&gt; keyword, we can gain insights into the query's order of operations, join methods, and optimization techniques employed by the query planner.&lt;/p&gt;

&lt;p&gt;By continuously refining our understanding of query execution and optimization techniques, we can leverage Apache AGE effectively and build efficient graph-based applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://age.apache.org/age-manual/master/index.html"&gt;Apache AGE documentation&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/apache/age"&gt;Apache AGE Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contribute to Apache AGE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/apache/age"&gt;Apache AGE Github&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/apache/age-viewer"&gt;Apache AGE Viewer Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>apacheage</category>
      <category>postgres</category>
      <category>graphdatabase</category>
    </item>
    <item>
      <title>Apache AGE: Combining the Best of Relational and Graph Databases for Effective Data Management</title>
      <dc:creator>Omar Saad</dc:creator>
      <pubDate>Thu, 04 May 2023 21:24:50 +0000</pubDate>
      <link>https://dev.to/omarsaad/apache-age-combining-the-best-of-relational-and-graph-databases-for-effective-data-management-3jjp</link>
      <guid>https://dev.to/omarsaad/apache-age-combining-the-best-of-relational-and-graph-databases-for-effective-data-management-3jjp</guid>
      <description>&lt;p&gt;In today's digital world, data is everywhere and is growing at an unprecedented rate. To make sense of this data and extract meaningful insights, it is important to choose the right database technology. Apache AGE is one such technology that has gained significant attention in the industry.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is PostgreSQL ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;PostgreSQL is one of the most famous relational databases in the world that is designed to manage and store large amounts of structured data.&lt;/p&gt;

&lt;p&gt;PostgreSQL is open-source and it is known for its reliability, robustness, and scalability. It provides a variety of advanced features, including support for transactions, stored procedures, and triggers.&lt;/p&gt;

&lt;p&gt;PostgreSQL supports a wide range of data types, including text, numeric, and date/time data, as well as more complex data structures such as arrays, JSON, and XML.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Apache AGE ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apache AGE is a graph database system that is built on top of PostgreSQL. It allows users to store, manage, and analyze large-scale graph data in a highly performant and scalable way.&lt;/p&gt;

&lt;p&gt;Apache AGE combines the benefits of a powerful relational database management system (PostgreSQL) with the flexibility and scalability of a graph database. This means that users can store their data in a relational format and also perform graph-based queries and analyses on the data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to choose Relational Databases ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Relational databases are ideal for applications that require data to be structured in a consistent way, such as those involving financial transactions or inventory management. They are designed to handle data that fits into tables with predefined columns and data types, making them a good fit for applications with clearly defined data models.&lt;/p&gt;

&lt;p&gt;Relational databases also have strong consistency and ACID (Atomicity, Consistency, Isolation, and Durability) guarantees, making them well-suited for applications that require strict data integrity and consistency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to choose Graph Databases ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Graph databases are a specialized type of database that are designed to store and manage graph data, which is data that can be represented as a collection of nodes and edges.&lt;/p&gt;

&lt;p&gt;Graph databases are ideal for handling complex relationships, unstructured data, and high scalability and performance. They are highly flexible and allow for easy addition or modification of data without affecting the structure of the database. Additionally, built-in visualization tools make it easy to explore and understand the data. If your application involves any of these scenarios, a graph database may be the right choice for you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to choose Apache AGE ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apache AGE is a unique database technology that combines the benefits of both relational databases and graph databases. It is built on top of PostgreSQL, which means that users can write SQL queries to retrieve data from tables, or write Cypher queries to retrieve data from graphs. This makes Apache AGE an excellent solution, especially for those who want to use a relational database alongside a graph database. Additionally, Apache AGE is an open-source project, which means that it is free to use.&lt;/p&gt;

&lt;p&gt;Apache AGE provides a variety of libraries for different frameworks, such as Node.js, Python and Java, making it easy for developers to integrate it into their applications. It is also very user-friendly and easy to use, and the Apache AGE documentation provides all the necessary information to get started with the database technology.&lt;/p&gt;

&lt;p&gt;You can download Apache AGE and start writing your first query by following &lt;br&gt;
&lt;a href="https://age.apache.org/age-manual/master/index.html"&gt;Apache AGE documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also If you want to visualize your queries you can use &lt;a href="https://github.com/apache/age-viewer"&gt;AGE Viewer&lt;/a&gt;&lt;br&gt;
which is a very good tool to see the results of your queries.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apache AGE Applications&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apache AGE can be used in a wide range of applications such as :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Social Media Applications&lt;/li&gt;
&lt;li&gt;Recommendation Systems.&lt;/li&gt;
&lt;li&gt;Fraud Detection.&lt;/li&gt;
&lt;li&gt;Network analysis.&lt;/li&gt;
&lt;li&gt;Bioinformatics.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The potential applications of Apache AGE are not limited to these examples. In fact, any data that can be represented as a graph can benefit from the capabilities of Apache AGE.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://age.apache.org/age-manual/master/index.html"&gt;Apache AGE documentation&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/apache/age"&gt;Apache AGE Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contribute to Apache AGE&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/apache/age"&gt;Apache AGE Github&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/apache/age-viewer"&gt;Apache AGE Viewer Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>apacheage</category>
      <category>postgres</category>
      <category>graphdatabase</category>
    </item>
    <item>
      <title>Step by step guide to install Apache AGE Viewer</title>
      <dc:creator>Omar Saad</dc:creator>
      <pubDate>Tue, 25 Apr 2023 22:22:25 +0000</pubDate>
      <link>https://dev.to/omarsaad/step-by-step-guide-to-install-apache-age-viewer-1o5d</link>
      <guid>https://dev.to/omarsaad/step-by-step-guide-to-install-apache-age-viewer-1o5d</guid>
      <description>&lt;p&gt;In this post, we will discuss how to install AGE viewer from source code on windows machine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;br&gt;
Before proceeding with the installation of AGE viewer from source code on your Windows machine, make sure you have the following prerequisites in place:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;PostgreSQL: You should have PostgreSQL version 11 or 12 already installed on your machine. If you haven't installed it yet, you can follow this guide for step-by-step instructions: &lt;a href="https://dev.to/omarsaad/step-by-step-guide-to-install-postgresql-apache-age-on-windows-28gf"&gt;Step by Step Guide to Install PostgreSQL on Windows&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Apache AGE: Apache AGE should be installed and configured with PostgreSQL on your PC. If you haven't installed and configured Apache AGE yet, you can refer to the same guide mentioned above: &lt;a href="https://dev.to/omarsaad/step-by-step-guide-to-install-postgresql-apache-age-on-windows-28gf"&gt;Step by Step Guide to Install PostgreSQL + Apache AGE on Windows&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Git: You should have Git installed on your machine. If you don't have it installed, you can download and install it from the official Git website &lt;a href="https://git-scm.com/" rel="noopener noreferrer"&gt;Git Installation&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;4.Node.js: You should have Node.js installed on your machine. Node.js is a JavaScript runtime that AGE viewer relies on. You can download and install Node.js from the official Node.js website &lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;Node.js Installation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By ensuring that you have PostgreSQL, Apache AGE, Git, and Node.js installed and configured correctly, you'll be ready to proceed with the installation of AGE viewer from source code on your Windows machine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Apache AGE ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apache AGE is a graph database system that is built on top of PostgreSQL. It allows users to store, manage, and analyze large-scale graph data in a highly performant and scalable way.&lt;/p&gt;

&lt;p&gt;Apache AGE combines the benefits of a powerful relational database management system (PostgreSQL) with the flexibility and scalability of a graph database. This means that users can store their data in a relational format and also perform graph-based queries and analyses on the data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Apache-Age Viewer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Apache-Age Viewer is a web based user interface that provides visualization of graph data stored in a PostgreSQL database with AGE extension. It is graph visualization tool, for Apache AGE [1].&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to install Apache AGE viewer ?&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Choose a directory where you want to install the project, and then open the Command Prompt (CMD) terminal in that directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clone the age-viewer project by running the following command in the terminal:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

git clone https://github.com/apache/age-viewer.git


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;navigate to the project directory.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

cd age-viewer


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Install the required node modules using.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

npm run setup


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;Now you can start the &lt;code&gt;age-vewer&lt;/code&gt; project.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

npm run start


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;After completing the installation and running the Apache AGE viewer application, your web browser will automatically open with the URL &lt;code&gt;localhost:3000&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, you need to establish a connection to a database by filling out the required information, as shown in the image below:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95myrwylrstha25xklm9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95myrwylrstha25xklm9.png" alt="AGE Viewer DB connection"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please ensure that you provide all the necessary details correctly, including the database host, port, username, password, and database name. Once you have entered the information, you can proceed to establish the connection to the database, which will enable the Apache AGE viewer application to access and retrieve data for analysis and visualization.&lt;/p&gt;

&lt;p&gt;Congratulations! With Apache AGE viewer successfully installed, you can now run queries and visualize graph data to gain insights from your database. We hope you found this tutorial helpful and enjoyable. If you have any further questions or need additional assistance, feel free to ask. Thank you for following this installation guide!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/apache/age-viewer" rel="noopener noreferrer"&gt;age-viewer&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/omarsaad/step-by-step-guide-to-install-postgresql-apache-age-on-windows-28gf"&gt;Step by step guide to install PostgreSQL + Apache AGE on Windows&lt;/a&gt;&lt;/p&gt;

</description>
      <category>apacheage</category>
      <category>postgres</category>
      <category>database</category>
      <category>agedb</category>
    </item>
    <item>
      <title>Getting Started with Apache AGE: Writing Your First Query for a Simple Database App</title>
      <dc:creator>Omar Saad</dc:creator>
      <pubDate>Mon, 10 Apr 2023 15:35:38 +0000</pubDate>
      <link>https://dev.to/omarsaad/getting-started-with-apache-age-writing-your-first-query-for-a-simple-database-app-10ag</link>
      <guid>https://dev.to/omarsaad/getting-started-with-apache-age-writing-your-first-query-for-a-simple-database-app-10ag</guid>
      <description>&lt;p&gt;In this tutorial, we will guide you through the process of creating a simple database using PostgreSQL and Apache AGE. PostgreSQL is a powerful relational database management system (RDBMS) that is widely used in the industry due to its performance, scalability, and reliability. However, when combined with Apache AGE, it adds graph database capabilities, making it even more useful in a variety of applications.&lt;/p&gt;

&lt;p&gt;With Apache AGE, you can use SQL and Cypher queries to access and analyze your data. SQL is a standard query language that is widely used for relational databases, while Cypher is a graph query language that allows you to perform powerful graph traversals and pattern matching. By learning both query languages, you'll have a powerful set of tools to work with data in different ways, depending on the needs of your application.&lt;/p&gt;

&lt;p&gt;Throughout this tutorial, you will learn the basics of creating tables, inserting data, and querying data using both SQL and Cypher. By the end of the tutorial, you'll have a solid understanding of how to use PostgreSQL and Apache AGE together, and you'll be ready to start building your own applications that leverage the power of both technologies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before starting this tutorial, you need to make sure that you have installed PostgreSQL version 11 or 12 and Apache AGE. If you haven't installed them yet, you can follow the steps in this tutorial &lt;a href="https://dev.to/omarsaad/step-by-step-guide-to-install-postgresql-apache-age-on-windows-28gf"&gt;Step-by-Step Guide to Install PostgreSQL &amp;amp; Apache AGE on Windows.&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To visualize the graph generated by the queries in this tutorial, you can use &lt;a href="https://github.com/apache/age-viewer"&gt;AGE Viewer&lt;/a&gt;. This is a useful tool to help you understand the graph structure and relationships between nodes and edges. It can also help you identify any issues with your queries and data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AGE Graph Fundamentals: Vertices and Edges&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In AGE, a vertex represents a fundamental entity in a graph, which can exist independently. Each vertex may be assigned a label, and may have zero or more outgoing edges, as well as zero or more incoming edges.&lt;/p&gt;

&lt;p&gt;On the other hand, an edge in AGE encodes a directed connection between exactly two nodes, namely the source node and the target node. An outgoing edge represents a directed relationship from the perspective of its source node, while an incoming edge represents a directed relationship from the perspective of its target node. Each edge is assigned exactly one edge type.&lt;/p&gt;

&lt;p&gt;Understanding the basics of vertices and edges is crucial to working with graphs in AGE. By leveraging these fundamental concepts, users can effectively model complex relationships and dependencies between various entities in their data, enabling them to extract meaningful insights and knowledge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Database Entities&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this tutorial, we will be creating a basic online ordering application that allows users to place orders for products. The application will utilize two main types of vertices, namely &lt;code&gt;User&lt;/code&gt; and &lt;code&gt;Product&lt;/code&gt;, and one edge type, which is &lt;code&gt;ORDERS&lt;/code&gt;. This means that a user can order one or more products through the &lt;code&gt;ORDERS&lt;/code&gt; edge type. By utilizing these vertices and edges, we can represent the relationships and interactions between the various entities in our application. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating The Application&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Configuring AGE with PostgreSQL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To configure AGE with PostgreSQL, you need to load the AGE extension and set the search path to &lt;code&gt;ag_catalog&lt;/code&gt;. Here are the correct SQL queries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;LOAD 'age'
SET search_path to ag_catalog,"your_user_name",public;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first query loads the AGE extension, while the second query sets the search path to &lt;code&gt;ag_catalog&lt;/code&gt; and public. Make sure to replace "your_user_name" with your actual PostgreSQL username.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Creating a graph&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To store our data, we need to create a new graph. This can be achieved by executing the following SQL query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM ag_catalog.create_graph('graph_name');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This query will create a new graph with the specified name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Creating Users&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, we will create a 'User' vertex (node) to represent our user in the graph. We can also add some properties to the node such as name, email, phone, and address.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT *
FROM cypher('online_orders', $$
    CREATE(:User{name:"user1" ,email : "test@test.com" , phone:"123456" , address : "Egypt"});
$$) AS (result agtype)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This query will create a new vertex with the label 'User' and the specified properties, and return the result in the 'result' column.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;agtype&lt;/code&gt; is a data type in AGE that represents an Abstract Graph object. It can store graphs, vertices, edges, and other graph-related data structures. It is similar to the JSON data type in PostgreSQL but is optimized for graph data. The agtype data type is used extensively in AGE for storing and querying graph data.&lt;/p&gt;

&lt;p&gt;Adding more users...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT *
FROM cypher('online_orders', $$
    CREATE(:User{name:"user2" ,email : "test2@test.com" , phone:"123488" , address : "USA"})
$$) AS (result agtype)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can use the following query to verify the inserted users:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM cypher('online_orders' , $$
MATCH(u:User) RETURN u
$$) AS (result agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This query uses the &lt;code&gt;MATCH&lt;/code&gt;clause to retrieve all the &lt;code&gt;User&lt;/code&gt; nodes in the &lt;code&gt;online_orders&lt;/code&gt; graph and returns them in the result set. The &lt;code&gt;AS result&lt;/code&gt; clause renames the result set to result.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Creating Products&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, we can create a 'Product' vertex (node) to hold all product-related data such as name and price (additional properties can also be added).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT *
FROM cypher('online_orders', $$
    CREATE (:Product{name:"Product 1", price: 10.99}),
           (:Product{name:"Product 2", price: 5.99}),
           (:Product{name:"Product 3", price: 7.50})
$$) AS (result agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This query creates three products in our graph.&lt;/p&gt;

&lt;p&gt;You can use the following query to verify the inserted products:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM cypher('online_orders' , $$
MATCH(u:Product) RETURN u
$$) AS (result agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This query uses the &lt;code&gt;MATCH&lt;/code&gt;clause to retrieve all the &lt;code&gt;Product&lt;/code&gt; nodes in the &lt;code&gt;online_orders&lt;/code&gt; graph.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Creating Edges&lt;/strong&gt;&lt;br&gt;
In this step, we will create the ORDERS relationship (edge) to represent the relation between users and a product. Whenever a user wants to make an order, we will create this relationship between the user and the desired product(s). Additionally, we can add some properties to edges, just like we did with the nodes. In this example, we will add the current time and the quantity in the edge.&lt;/p&gt;

&lt;p&gt;To make an order for Product 1 with a quantity of five for user1 that we created previously, execute the following query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT * FROM cypher('online_orders' , $$
    MATCH (u:User{name:'user1'}) , (p:Product{name:"Product 1"})
    CREATE((u)-[o:ORDERS{time:timestamp() , quantity:5}]-&amp;gt;(p))
    RETURN u,o,p
$$) AS (u agtype, o agtype, p agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After inserting the data, the AGE viewer can be used to visualize the graph and its relationships.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kYgufiP0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uk1eaw4ipxu5morzwy0k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kYgufiP0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uk1eaw4ipxu5morzwy0k.png" alt="Image description" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Based on the data shown in the AGE viewer, it appears that user1 has an &lt;code&gt;ORDERS&lt;/code&gt;relationship with &lt;code&gt;Product 1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you want to display all the data in the graph you can run the following query:&lt;/p&gt;

&lt;p&gt;You can run the following query to display all the data in the graph:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT *
FROM cypher('online_orders', $$
    MATCH (u:User), (p:Product)
    OPTIONAL MATCH (u)-[o:ORDERS]-&amp;gt;(p)
    RETURN u, o, p
$$) AS (u agtype, o agtype, p agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--saBQYFOK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3lsph7k3xwx3ny18glt0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--saBQYFOK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3lsph7k3xwx3ny18glt0.png" alt="Image description" width="800" height="308"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that this will return all users, their orders, and the products they ordered. However, for larger graphs with many nodes and edges, this query can be slow and resource-intensive. It is recommended to use filters and limit the number of results returned when querying large graphs.&lt;/p&gt;

&lt;p&gt;Note: This is a simple example for illustration purposes only. In a real-world scenario, there would be more complex data models and relationships between nodes and edges.&lt;/p&gt;

&lt;p&gt;Great! You have created a simple graph using AGE and PostgreSQL. This was just a simple example to demonstrate the basic steps involved in creating and querying a graph. There are many other features and capabilities of AGE that you can explore to build more complex and sophisticated graphs to meet your specific requirements. We hope this tutorial has been helpful in getting you started with AGE and PostgreSQL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://age.apache.org/age-manual/master/intro/setup.html"&gt;AGE - Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contribute to Apache AGE&lt;/strong&gt;&lt;br&gt;
Apache AGE website: &lt;a href="https://age.apache.org/"&gt;https://age.apache.org/&lt;/a&gt;&lt;br&gt;
Apache AGE Github: &lt;a href="https://github.com/apache/age"&gt;https://github.com/apache/age&lt;/a&gt;&lt;/p&gt;

</description>
      <category>apacheage</category>
      <category>postgres</category>
      <category>graphdatabase</category>
      <category>database</category>
    </item>
    <item>
      <title>Step by step guide to install PostgreSQL + Apache AGE on Windows</title>
      <dc:creator>Omar Saad</dc:creator>
      <pubDate>Sat, 08 Apr 2023 14:44:06 +0000</pubDate>
      <link>https://dev.to/omarsaad/step-by-step-guide-to-install-postgresql-apache-age-on-windows-28gf</link>
      <guid>https://dev.to/omarsaad/step-by-step-guide-to-install-postgresql-apache-age-on-windows-28gf</guid>
      <description>&lt;p&gt;In this post, we will discuss how to install PostgreSQL and Apache AGE on a Windows machine in a step-by-step manner. By the end of this guide, you'll have a fully functional PostgreSQL database and Apache AGE graph database, ready to use for your data-driven applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is PostgreSQL ?&lt;/strong&gt;&lt;br&gt;
PostgreSQL is one of the most famous relational databases in the world that is designed to manage and store large amounts of structured data.&lt;/p&gt;

&lt;p&gt;PostgreSQL is open-source and it is known for its reliability, robustness, and scalability. It provides a variety of advanced features, including support for transactions, stored procedures, and triggers.&lt;/p&gt;

&lt;p&gt;PostgreSQL supports a wide range of data types, including text, numeric, and date/time data, as well as more complex data structures such as arrays, JSON, and XML.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Apache AGE ?&lt;/strong&gt;&lt;br&gt;
Apache AGE is a graph database system that is built on top of PostgreSQL. It allows users to store, manage, and analyze large-scale graph data in a highly performant and scalable way.&lt;/p&gt;

&lt;p&gt;Apache AGE combines the benefits of a powerful relational database management system (PostgreSQL) with the flexibility and scalability of a graph database. This means that users can store their data in a relational format and also perform graph-based queries and analyses on the data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How to install PostgreSQL and Apache Age ?&lt;/strong&gt;&lt;br&gt;
Currently, Apache AGE does not support Windows. Therefore, in this tutorial, we will use Windows Subsystem for Linux (WSL) as an alternative.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Install WSL.&lt;/strong&gt;&lt;br&gt;
To enable WSL on your computer, follow these steps: First, go to the Control Panel, and then select Programs. Next, select Turn Windows features on or off. From the list of features, enable both Virtual Machine Platform and Windows Subsystem for Linux, as shown in the image&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fydnposvo0a3konmxodi0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fydnposvo0a3konmxodi0.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After enabling WSL, the next step is to install a Linux distribution for Windows. To do this, open the Microsoft Store and search for 'Linux.' You will see several options available, and you can choose the one you prefer. For the purposes of this tutorial, we will be using 'Ubuntu 22.04.2 LTS'.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Installing PostgreSQL from source code.&lt;/strong&gt;&lt;br&gt;
Please note that currently, Apache AGE only supports PostgreSQL versions 11 and 12, so we must install one of these versions. Before proceeding, we need to install some dependencies. To do this, open a bash terminal by navigating to any directory and typing 'bash' in the address bar, and then run the appropriate command.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

sudo apt install git libreadline-dev zlib1g-dev bison flex build-essential


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Next, create a directory where you want to install PostgreSQL and clone the Postgres repository into it.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

mkdir postgres-AGE-project
cd postgres-AGE-project
git clone https://git.postgresql.org/git/postgresql.git


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Navigate to the 'postgresql' directory and switch to a compatible version branch. For the purposes of this tutorial, we'll be using version 12.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

cd postgresql
git checkout REL_12_STABLE


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Compile the source code and specify the directory where you want the binaries to be installed. Note that this process may take some time to complete.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

./configure –prefix=/usr/local/pgsql-12
make 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After the compilation process is complete, run the following command to add permissions for the binaries directory and replace user by your username. Once this is done, proceed to install PostgreSQL&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

sudo mkdir /usr/local/pgsql-12
sudo chown user /usr/local/pgsql-12
make install


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To ensure that PostgreSQL can be accessed from anywhere in the terminal, it is necessary to set up the following environment variables&lt;br&gt;
These commands will add the PostgreSQL binaries directory to the system path and set the PGDATA directory to the location of the PostgreSQL data files.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

export PATH=/usr/local/pgsql-12/bin/:$PATH
export PGDATA=/usr/local/pgsql-12/bin/data


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now that you have installed PostgreSQL, you can create a new cluster, which is a collection of databases managed by a single instance of the PostgreSQL server. To create a new cluster, run the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

initdb


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After initializing the cluster, you can start the PostgreSQL server by running the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

pg_ctl -D /usr/local/pgsql-12/bin/data -l logfile start


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now you can start PostgreSQL by running the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

psql postgres


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Congratulations! You have successfully installed and started PostgreSQL.&lt;/p&gt;

&lt;p&gt;To exit PostgreSQL run &lt;code&gt;\q&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To stop the server run the following command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

pg_ctl -D /usr/local/pgsql-12/bin/data -l logfile stop


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;If you would like more detailed information about the installation process, you can visit the following link: &lt;a href="https://www.postgresql.org/docs/12/installation.html" rel="noopener noreferrer"&gt;PostgreSQL documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Installing Apache AGE from source code.&lt;/strong&gt;&lt;br&gt;
To install Apache AGE from source code, go to the main directory of the postgres-AGE-project that we created earlier and execute the following command to clone the AGE project.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

git clone https://github.com/apache/age.git


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To proceed with the installation, navigate to the project directory and switch to the latest stable release, which is version 1.1.0.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

cd age
git checkout release/PG12/1.1.0


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Set the environment variable PG_CONFIG. we need to set the PG_CONFIG environment variable to specify the location of the PostgreSQL pg_config utility. pg_config is a command-line utility that provides information about the installed version of PostgreSQL, including the location of files and libraries required for compiling and linking programs against PostgreSQL. Apache AGE uses pg_config to determine the location of the PostgreSQL header files and libraries needed to compile the AGE extension.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

export PG_CONFIG=/usr/local/pgsql-12/bin/pg_config


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then install AGE extension by running this command:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

make install


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Now you have AGE installed to add the extension in your postgres server run the following SQL commands:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

CREATE EXTENSION age;    


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then every time you want to use AGE you must load the extension.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

LOAD 'age';    


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Great job! You have successfully installed Apache AGE on your system.&lt;/p&gt;

&lt;p&gt;You can find further information on AGE installation and usage on the official Apache AGE documentation at  &lt;a href="https://age.apache.org/age-manual/master/index.html" rel="noopener noreferrer"&gt;AGE documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.postgresql.org/" rel="noopener noreferrer"&gt;PostgreSQL&lt;/a&gt;&lt;br&gt;
&lt;a href="https://age.apache.org/age-manual/master/intro/setup.html" rel="noopener noreferrer"&gt;AGE - Installation giude&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Contribute to Apache AGE&lt;/strong&gt;&lt;br&gt;
Apache AGE website: &lt;a href="https://age.apache.org/" rel="noopener noreferrer"&gt;https://age.apache.org/&lt;/a&gt;&lt;br&gt;
Apache AGE Github: &lt;a href="https://github.com/apache/age" rel="noopener noreferrer"&gt;https://github.com/apache/age&lt;/a&gt;&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
      <category>database</category>
    </item>
  </channel>
</rss>
