<?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: Ahmed Hisham</title>
    <description>The latest articles on DEV Community by Ahmed Hisham (@mghrabi).</description>
    <link>https://dev.to/mghrabi</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%2F1059011%2F4b5a8f6b-9215-40ee-81d3-e29dd7d864e9.jpg</url>
      <title>DEV Community: Ahmed Hisham</title>
      <link>https://dev.to/mghrabi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mghrabi"/>
    <language>en</language>
    <item>
      <title>Here's How To Create Your First PostgrSQL Extension Part 4</title>
      <dc:creator>Ahmed Hisham</dc:creator>
      <pubDate>Thu, 27 Jul 2023 06:45:44 +0000</pubDate>
      <link>https://dev.to/mghrabi/heres-how-to-create-your-first-postgrsql-extension-part-4-3k2j</link>
      <guid>https://dev.to/mghrabi/heres-how-to-create-your-first-postgrsql-extension-part-4-3k2j</guid>
      <description>&lt;p&gt;Continuing on &lt;a href="https://dev.to/mghrabi/heres-how-to-create-your-first-postgrsql-extension-part-3-3456"&gt;part3&lt;/a&gt; we got into the stage where we have &lt;code&gt;.sql&lt;/code&gt; file left to build the extension.&lt;/p&gt;

&lt;p&gt;We should name the file as follows &lt;code&gt;add_two_numbers--0.0.1.sql&lt;/code&gt; including the version.&lt;/p&gt;

&lt;p&gt;The file will contain the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE OR REPLACE FUNCTION
add_two_numbers(int,int) RETURNS int AS 'MODULE_PATHNAME','add_two_numbers'
LANGUAGE C STRICT;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we finally can install the extension:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo make install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should get an output similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -O2 -fPIC -I. -I./ -I/usr/local/pgsql-13/include/server -I/usr/local/pgsql-13/include/internal  -D_GNU_SOURCE   -c -o add_two_numbers.o add_two_numbers.c
gcc -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -Wno-format-truncation -Wno-stringop-truncation -g -O2 -fPIC add_two_numbers.o -L/usr/local/pgsql-13/lib   -Wl,--as-needed -Wl,-rpath,'/usr/local/pgsql-13/lib',--enable-new-dtags  -shared -o add_two_numbers.so
/usr/bin/mkdir -p '/usr/local/pgsql-13/share/extension'
/usr/bin/mkdir -p '/usr/local/pgsql-13/share/extension'
/usr/bin/mkdir -p '/usr/local/pgsql-13/lib'
/usr/bin/install -c -m 644 .//add_two_numbers.control '/usr/local/pgsql-13/share/extension/'
/usr/bin/install -c -m 644 .//add_two_numbers--0.0.1.sql  '/usr/local/pgsql-13/share/extension/'
/usr/bin/install -c -m 755  add_two_numbers.so '/usr/local/pgsql-13/lib/'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should mean that the extension is installed successfully. Now it's time to run a postgres instance and test the extension, start a postgres instance from the binaries directory, in my case it will be from &lt;code&gt;usr/local/pgsql-13/bin&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;./pg_ctl start -l logfile -D ./data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the instance:&lt;br&gt;
&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;Create the extension:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;postgres=# CREATE EXTENSION add_two_numbers;
CREATE EXTENSION
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run a query to test the function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;postgres=# SELECT add_two_numbers(1,3);
 add_two_numbers
-----------------
               4
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It worked!, congratulations for building your first extension, I hope that was helpful!.&lt;/p&gt;

</description>
      <category>postgressql</category>
    </item>
    <item>
      <title>Here's How To Create Your First PostgrSQL Extension Part 3</title>
      <dc:creator>Ahmed Hisham</dc:creator>
      <pubDate>Thu, 27 Jul 2023 06:22:19 +0000</pubDate>
      <link>https://dev.to/mghrabi/heres-how-to-create-your-first-postgrsql-extension-part-3-3456</link>
      <guid>https://dev.to/mghrabi/heres-how-to-create-your-first-postgrsql-extension-part-3-3456</guid>
      <description>&lt;p&gt;After &lt;a href="https://dev.to/mghrabi/heres-how-to-create-your-first-postgrsql-extension-part-2-30g5"&gt;part2&lt;/a&gt; we should have one file so far in our directory (&lt;strong&gt;Makefile&lt;/strong&gt;), now we will get into the .control file which provides metadata about the extension, also we will be going through the .c file:&lt;/p&gt;

&lt;h3&gt;
  
  
  Starting by &lt;code&gt;add_two_numbers.control&lt;/code&gt; file:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;comment = 'Simple number add function'
default_version = '0.0.1'
relocatable = true
module_pathname = '$libdir/add_two_numbers'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;comment&lt;/code&gt;: a brief description for extension functionality&lt;/p&gt;

&lt;p&gt;&lt;code&gt;default_version&lt;/code&gt;: as the name suggests, it specifies the default version of the extension&lt;/p&gt;

&lt;p&gt;&lt;code&gt;relocatable&lt;/code&gt;: if set to &lt;strong&gt;true&lt;/strong&gt; it means that this extension can be moved to another location or server without causing issues, some extension crashes once they are moved to a different location, they require a different setup, but in the case of our extension it doesn't.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;module_pathname&lt;/code&gt;: specifies the location to the shared library contains the extension code (the .so file in specific), which in my case will be found in &lt;code&gt;/usr/local/pgsql-13/lib&lt;/code&gt;, and you can specify it manually up above by replacing &lt;code&gt;$libdir&lt;/code&gt; with &lt;code&gt;/usr/local/pgsql-13/lib&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating &lt;code&gt;add_two_numbers.c&lt;/code&gt; file:
&lt;/h2&gt;

&lt;p&gt;The c file contain the actual functionality of the extension, which is the addition operation between two numbers, Here's how we create a extension function in postgres according to docs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#include "postgres.h"
#include "fmgr.h"

PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(add_two_numbers);

Datum
add_two_numbers(PG_FUNCTION_ARGS)
{
int32 arg1 = PG_GETARG_INT32(0);
int32 arg2 = PG_GETARG_INT32(1);

PG_RETURN_INT32(arg1 + arg2);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far if we &lt;code&gt;ls&lt;/code&gt; in the following files should be shown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Makefile  add_two_numbers.c  add_two_numbers.control
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the next part we will create the last file, build the extension and run it together!.&lt;/p&gt;

</description>
      <category>postgressql</category>
    </item>
    <item>
      <title>Here's How To Create Your First PostgrSQL Extension Part 2</title>
      <dc:creator>Ahmed Hisham</dc:creator>
      <pubDate>Wed, 26 Jul 2023 16:39:39 +0000</pubDate>
      <link>https://dev.to/mghrabi/heres-how-to-create-your-first-postgrsql-extension-part-2-30g5</link>
      <guid>https://dev.to/mghrabi/heres-how-to-create-your-first-postgrsql-extension-part-2-30g5</guid>
      <description>&lt;p&gt;We will continue what we started &lt;a href="https://dev.to/mghrabi/heres-how-to-create-your-first-postgrsql-extension-part-1-45fe"&gt;here&lt;/a&gt;, Now let's create the necessary files, and go through each of them. We stopped where we created a directory for the extension &lt;code&gt;add_two_numbers&lt;/code&gt;. In this Blog we will start by creating the &lt;code&gt;Makefile&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Makefile&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MODULES = add_two_numbers
EXTENSION = add_two_numbers
DATA = add_two_numbers--0.0.1.sql
PG_CONFIG = /usr/local/pgsql-13/bin/pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;MODULES&lt;/code&gt;: list of shared-library objects to be built from source files with the same stem, which mean you should specify the name of the c file we will build which we will name &lt;code&gt;add_two_numbers&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;EXTENSION&lt;/code&gt;: specify the name of the extension that postgres will use to identify our extension, we will name it &lt;code&gt;add_two_numbers&lt;/code&gt; as well.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;DATA&lt;/code&gt;: by this variable we specify the sql file that postgres will use to run the necessary queries to create and install the extension in the database.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;PG_CONFIG&lt;/code&gt;: By this variable we specify the path to the &lt;strong&gt;pg_config&lt;/strong&gt; binary file in the postgres database where we will install the extension, this will give the &lt;code&gt;make&lt;/code&gt; command the necessary information for proper installation. Also we will need this variable in the following variable to get the path for a very important file that extensions use in the building process, this file which is &lt;code&gt;pgxs.mk&lt;/code&gt;, it contains generic rules to build extensions.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;PGXS&lt;/code&gt;: as we just said above, here we need to assign a command to that retrieves the &lt;code&gt;pgxs.mk&lt;/code&gt; file location. In &lt;code&gt;$(shell $(PG_CONFIG) --pgxs)&lt;/code&gt; the $(PG_CONFIG) will retrieve what we assigned (PG_CONFIG) variable which is the path to the pg_config file, that's to execute it with the &lt;code&gt;--pgxs&lt;/code&gt; flag to get the path of &lt;code&gt;pgxs.mk&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;include $(PGXS)&lt;/code&gt;: then this part is responsible to include &lt;code&gt;pgxs.mk&lt;/code&gt; so that to apply the rules in that file to build the extension.&lt;/p&gt;

&lt;p&gt;Very important Note: You can always refer to the other variables you can add to Makefile, as by opening &lt;code&gt;pgxs.mk&lt;/code&gt; file you will find instructions on each variable especially for these we created, and for other variables that can be necessary for you later extensions, so take a look on it!. Get the file path by running &lt;code&gt;$(PG_CONFIG) --pgxs&lt;/code&gt; to open it.&lt;/p&gt;

</description>
      <category>postgressql</category>
    </item>
    <item>
      <title>Here's How To Create Your First PostgrSQL Extension Part 1</title>
      <dc:creator>Ahmed Hisham</dc:creator>
      <pubDate>Wed, 26 Jul 2023 12:25:05 +0000</pubDate>
      <link>https://dev.to/mghrabi/heres-how-to-create-your-first-postgrsql-extension-part-1-45fe</link>
      <guid>https://dev.to/mghrabi/heres-how-to-create-your-first-postgrsql-extension-part-1-45fe</guid>
      <description>&lt;p&gt;The following blogs will target the most basics of creating a PostgreSQl extension, at the end you should become pretty familiar with what's required to create an extension for PostgreSQL. the blog series assumes you are working with a linux system like Ubuntu.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Obviously you should have your version of PostgreSQL, and won't matter which version of PostgreSQL you will be using since in this tutorial we will create a very simple extension. If you don't already installed PostgreSQL, you can directly install it's package, or install it from a source code following this blog &lt;a href="https://dev.to/mghrabi/explaining-in-detail-how-to-install-postgresql-from-source-code-on-windows-with-a-full-understanding-3jk7"&gt;here&lt;/a&gt; where I described in details how to do that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating an extension!:
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;By having PostgreSQL installed on your machine, you should have the binaries (executable files) installed somewhere in your system, for me they are in &lt;code&gt;/usr/local/pgsql-13/bin&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now create a directory where you will create the extension (you can create it anywhere) and name it &lt;code&gt;add_two_numbers&lt;/code&gt;:&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;mkdir add_two_numbers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Now we need to understand what are the files exactly we need to create to accomplish the mission, there are three necessary files to create:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Makefile&lt;/code&gt; file: it's used to build the extension, in which you specify the instructions to build the extension.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*.control&lt;/code&gt; file: This file provides a metadata about the extension like the name, version and author.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*.sql&lt;/code&gt; file: this will contain the required sql queries to build the extension functionalities&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*.c&lt;/code&gt; file: And this c file will contain the c functions that your extension supports.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the next blog we will be going through each of them in details and explore the steps to build up the extension!.&lt;/p&gt;

</description>
      <category>postgressql</category>
    </item>
    <item>
      <title>When To Use Graph Database Model Over Relational Database Models</title>
      <dc:creator>Ahmed Hisham</dc:creator>
      <pubDate>Thu, 13 Jul 2023 04:39:51 +0000</pubDate>
      <link>https://dev.to/mghrabi/when-to-use-graph-database-model-over-relational-database-models-4od5</link>
      <guid>https://dev.to/mghrabi/when-to-use-graph-database-model-over-relational-database-models-4od5</guid>
      <description>&lt;p&gt;There are a lot of different database models out there. Nothing is right and wrong, it all depends on the cases and the requirements of the project, the blog will focus on when to use Graph databases over relational ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to use a Graph model?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;When Complex relations exist between data. A general and common case is when building a social media app, you will most probably use a Graph model to handle relations between users, as graph model will be much easier structure to handle complex interconnected data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When project data model is inconsistent and requires frequent changes. Given social media app as an example, the shape of data will often be changed as demands and requirements change, so having flexible data model is necessary&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When Additional attributes are only necessary for some entities (not all of them), in these cases working with relational databases will force you to create a separate table (best practices) to handle additional attributes rather than having (null) value for those attributes in rows that don't have values for them, so it's harder to handle those type of issues in relational models than in graph models which is simpler, and changing the data structure at any point in time is easier&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Running reading queries is simpler with cypher than sql in a lot of cases&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Graph models is not always the best suited, you should always think in terms of performance, which type of databases will bring the best performance possible?, also what type of queries I will often be running?, what kind of data you are working with?, and more importantly what expertise your team has?. Thinking in terms of all of these is important to make the right decision and choose the most suited database model to fit your needs. &lt;/p&gt;

&lt;p&gt;I've been using postgres for a quite a long time, and I came recently across an extension that add and power postgres with graph functionalities, the extension is &lt;code&gt;apache/age&lt;/code&gt; which is worth checking for those want to leverage both graph and relational databases functionalities in a single database.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
    </item>
    <item>
      <title>A Look To A Query Inside Postgres Source Code</title>
      <dc:creator>Ahmed Hisham</dc:creator>
      <pubDate>Tue, 11 Jul 2023 12:47:54 +0000</pubDate>
      <link>https://dev.to/mghrabi/deep-look-inside-postgres-query-part-1-38l7</link>
      <guid>https://dev.to/mghrabi/deep-look-inside-postgres-query-part-1-38l7</guid>
      <description>&lt;p&gt;I would hope this blog to be a start of series where we debug PostgreSQL and see what's going on under the hood. In this blog specifically we will start by a very simple example where we stop at some point in the code using GDB debugger tool, and take a deeper look at how PostgreSQL represent the query and check a single property of it to make sure it's as expected, this will hopefully give us some confident debugging PostgreSQL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Postgres Installation
&lt;/h2&gt;

&lt;p&gt;You of don't already have PostgreSQl installed from source code you can follow this guide &lt;a href="https://dev.to/mghrabi/explaining-in-detail-how-to-install-postgresql-from-source-code-on-windows-with-a-full-understanding-3jk7"&gt;here&lt;/a&gt; and make sure you include the &lt;code&gt;--enable-debug&lt;/code&gt; option. Almost any postgres version will be fine since what we will be debugging is almost untouched since the earliest versions of postgres. Also this blog assumes that you are already familiar with GDB, if not please follow any online tutorial to learn the basics as we won't need more than that :).&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding what we are going to debug
&lt;/h2&gt;

&lt;p&gt;What we will debug exactly is a &lt;strong&gt;Query&lt;/strong&gt; struct which is how postgres represent a query, it's defined in &lt;code&gt;src/include/nodes/parsenodes.h&lt;/code&gt; in postgres codebase (don't be intimidated, you are not expected to know what each property or part of the code represents as postgres is very very huge codebase):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;typedef struct Query
{
    NodeTag     type;

    CmdType     commandType;    /* select|insert|update|delete|merge|utility */

    /* where did I come from? */
    QuerySource querySource pg_node_attr(query_jumble_ignore);

    /*
     * query identifier (can be set by plugins); ignored for equal, as it
     * might not be set; also not stored.  This is the result of the query
     * jumble, hence ignored.
     */
    uint64      queryId pg_node_attr(equal_ignore, query_jumble_ignore, read_write_ignore, read_as(0));

    /* do I set the command result tag? */
    bool        canSetTag pg_node_attr(query_jumble_ignore);

    Node       *utilityStmt;    /* non-null if commandType == CMD_UTILITY */

    /*
     * rtable index of target relation for INSERT/UPDATE/DELETE/MERGE; 0 for
     * SELECT.  This is ignored in the query jumble as unrelated to the
     * compilation of the query ID.
     */
    int         resultRelation pg_node_attr(query_jumble_ignore);

    /* has aggregates in tlist or havingQual */
    bool        hasAggs pg_node_attr(query_jumble_ignore);
    /* has window functions in tlist */
    bool        hasWindowFuncs pg_node_attr(query_jumble_ignore);
    /* has set-returning functions in tlist */
    bool        hasTargetSRFs pg_node_attr(query_jumble_ignore);
    /* has subquery SubLink */
    bool        hasSubLinks pg_node_attr(query_jumble_ignore);
    /* distinctClause is from DISTINCT ON */
    bool        hasDistinctOn pg_node_attr(query_jumble_ignore);
    /* WITH RECURSIVE was specified */
    bool        hasRecursive pg_node_attr(query_jumble_ignore);
    /* has INSERT/UPDATE/DELETE in WITH */
    bool        hasModifyingCTE pg_node_attr(query_jumble_ignore);
    /* FOR [KEY] UPDATE/SHARE was specified */
    bool        hasForUpdate pg_node_attr(query_jumble_ignore);
    /* rewriter has applied some RLS policy */
    bool        hasRowSecurity pg_node_attr(query_jumble_ignore);
    /* is a RETURN statement */
    bool        isReturn pg_node_attr(query_jumble_ignore);

    List       *cteList;        /* WITH list (of CommonTableExpr's) */

    List       *rtable;         /* list of range table entries */

    /*
     * list of RTEPermissionInfo nodes for the rtable entries having
     * perminfoindex &amp;gt; 0
     */
    List       *rteperminfos pg_node_attr(query_jumble_ignore);
    FromExpr   *jointree;       /* table join tree (FROM and WHERE clauses);
                                 * also USING clause for MERGE */

    List       *mergeActionList;    /* list of actions for MERGE (only) */
    /* whether to use outer join */
    bool        mergeUseOuterJoin pg_node_attr(query_jumble_ignore);

    List       *targetList;     /* target list (of TargetEntry) */

    /* OVERRIDING clause */
    OverridingKind override pg_node_attr(query_jumble_ignore);

    OnConflictExpr *onConflict; /* ON CONFLICT DO [NOTHING | UPDATE] */

    List       *returningList;  /* return-values list (of TargetEntry) */

    List       *groupClause;    /* a list of SortGroupClause's */
    bool        groupDistinct;  /* is the group by clause distinct? */

    List       *groupingSets;   /* a list of GroupingSet's if present */

    Node       *havingQual;     /* qualifications applied to groups */

    List       *windowClause;   /* a list of WindowClause's */

    List       *distinctClause; /* a list of SortGroupClause's */

    List       *sortClause;     /* a list of SortGroupClause's */

    Node       *limitOffset;    /* # of result tuples to skip (int8 expr) */
    Node       *limitCount;     /* # of result tuples to return (int8 expr) */
    LimitOption limitOption;    /* limit type */

    List       *rowMarks;       /* a list of RowMarkClause's */

    Node       *setOperations;  /* set-operation tree if this is top level of
                                 * a UNION/INTERSECT/EXCEPT query */

    /*
     * A list of pg_constraint OIDs that the query depends on to be
     * semantically valid
     */
    List       *constraintDeps pg_node_attr(query_jumble_ignore);

    /* a list of WithCheckOption's (added during rewrite) */
    List       *withCheckOptions pg_node_attr(query_jumble_ignore);

    /*
     * The following two fields identify the portion of the source text string
     * containing this query.  They are typically only populated in top-level
     * Queries, not in sub-queries.  When not set, they might both be zero, or
     * both be -1 meaning "unknown".
     */
    /* start location, or -1 if unknown */
    int         stmt_location;
    /* length in bytes; 0 means "rest of string" */
    int         stmt_len pg_node_attr(query_jumble_ignore);
} Query;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What we want to explore from this huge struct is exactly one property, to verify our predictions, the property is &lt;code&gt;CmdType     commandType;&lt;/code&gt; which as described is one from ** select|insert|update|delete|merge|utility **, fair enough.&lt;/p&gt;

&lt;h1&gt;
  
  
  Where to start?
&lt;/h1&gt;

&lt;p&gt;Make sure you have a table created in the database you are running to be able to run sql queries against. Then attach GDB to the postgres process, to know the postgres process, run your postgres instance first then enter 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;testdb=# SELECT pg_backend_pid();
 pg_backend_pid
----------------
          17125
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;copy the process id and then open another terminal and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gdb -p 17125
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we should be ready to debug.&lt;/p&gt;

&lt;h1&gt;
  
  
  Debugging planner function
&lt;/h1&gt;

&lt;p&gt;One of the very important stages that a query goes through is the planner stage, it's the pre-execution phase in which postgres decide the optimum way to fetch data and which algorithm to use etc. We will inspect the planner function, but where can we find the planner function?, you can simply ask vscode to find it for you by type &lt;code&gt;Ctrl + Shift + h&lt;/code&gt; (on windows), and search for &lt;code&gt;planner(&lt;/code&gt; like the following:&lt;/p&gt;

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

&lt;p&gt;we found it!, now open the terminal where you ran gdb, and create a breakpoint at the planner function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;b src/backend/optimizer/plan/planner.c:planner
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you should get an output similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Breakpoint 1 at 0x560af507bcc0: file planner.c, line 269.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;which verifies the breakpoint is created.&lt;/p&gt;

&lt;p&gt;now let's open postgres instance terminal and run a very simple &lt;code&gt;SELECT&lt;/code&gt; query (but make sure you already created the users table to run the same command I'm running, but any other table should work):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;testdb=# SELECT * FROM users;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go back to GDB terminal and press &lt;code&gt;c&lt;/code&gt; and then enter, this will get us to where we created the breakpoint (at the planner function), you should get an output similar to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Breakpoint 1, planner (parse=0x560af6cef470, query_string=0x560af6cee618 "SELECT * from users;", 
    cursorOptions=256, boundParams=0x0) at planner.c:269
warning: Source file is more recent than executable.
269      * so you'd better copy that data structure if you want to plan more than once.
(gdb) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can notice that the argument &lt;strong&gt;parse&lt;/strong&gt; is a pointer to a ** Query** which is what we want to inspect, print it out to make sure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gdb) print parse
$1 = (Query *) 0x560af6cef470
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;mmmm right!, now we want to check the &lt;code&gt;commandType&lt;/code&gt; variable, and according to the query we ran it should be &lt;code&gt;SELECT&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;(gdb) print parse-&amp;gt;commandType
$2 = CMD_SELECT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything is as expected. Now we should have gained a little experience with debugging postgers, and specially the &lt;strong&gt;Query&lt;/strong&gt; struct, which you can go and play around with gdb to check other properties in it like the &lt;code&gt;targetList&lt;/code&gt; variable. &lt;/p&gt;

&lt;p&gt;I hope you found this blog helpful somehow.&lt;/p&gt;

</description>
      <category>postgressql</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Comprehensive Guide On Using (Count) Aggregation Function In Apache AGE</title>
      <dc:creator>Ahmed Hisham</dc:creator>
      <pubDate>Fri, 05 May 2023 02:34:56 +0000</pubDate>
      <link>https://dev.to/mghrabi/comprehensive-guide-on-using-count-aggregation-function-in-apache-age-52nk</link>
      <guid>https://dev.to/mghrabi/comprehensive-guide-on-using-count-aggregation-function-in-apache-age-52nk</guid>
      <description>&lt;p&gt;This blog assumes you already familiar with Apache AGE extension which is an extension for PostgreSQL that adds graph database functionalities to relational database. I chose &lt;code&gt;Count&lt;/code&gt; function since it is a bit tricky to a lot of developers, so by the end of this blog you should feel comfortable using it. We will start out with a simple example, then moving to a hard one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up a database
&lt;/h2&gt;

&lt;p&gt;First we need to create a test database &lt;code&gt;test_db&lt;/code&gt; and create age extension for it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;postgres=# CREATE DATABASE test_db;
CREATE DATABASE
postgres=# \c test_db

test_db=# CREATE EXTENSION age;
CREATE EXTENSION
test_db=# LOAD 'age';
LOAD

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

&lt;/div&gt;



&lt;p&gt;data setup from &lt;a href="https://age.apache.org/age-manual/master/functions/aggregate_functions.html#count"&gt;docs&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SET search_path TO ag_catalog;

SELECT create_graph('graph_name');

SELECT * FROM cypher('graph_name', $$
    CREATE (a:Person {name: 'A', age: 13}),
    (b:Person {name: 'B', age: 33, eyes: "blue"}),
    (c:Person {name: 'C', age: 44, eyes: "blue"}),
    (d1:Person {name: 'D', eyes: "brown"}),
    (d2:Person {name: 'D'}),
    (a)-[:KNOWS]-&amp;gt;(b),
    (a)-[:KNOWS]-&amp;gt;(c),
    (a)-[:KNOWS]-&amp;gt;(d1),
    (b)-[:KNOWS]-&amp;gt;(d2),
    (c)-[:KNOWS]-&amp;gt;(d2)
$$) as (a agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Simple example
&lt;/h2&gt;

&lt;p&gt;Now let's start with a simple example to show the basic use of &lt;code&gt;Count&lt;/code&gt; function:&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', $$
    MATCH (n)
    RETURN count(*)
$$) as (total agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this query &lt;code&gt;MATCH&lt;/code&gt; will fetch all vertices in the graph, and then by the &lt;code&gt;RETURN count(*)&lt;/code&gt; part we inform the query to return the count of all vertices (***** means all here). You should already be familiar with that, the result we will get in our example will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; total
-------
 5
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Harder example
&lt;/h2&gt;

&lt;p&gt;Let's move to more serious example, don't be shocked with what you will see, we will explain everything, these are the required data setup:&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', $$
CREATE (:L {a: 1, b: 2, c: 3}),
       (:L {a: 2, b: 3, c: 1}),
       (:L {a: 3, b: 1, c: 2})
$$) as (a agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's run the following query (we will explain it down below):&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', $$
    MATCH (x:L)
    RETURN (x.a + x.b + x.c) + count(*) + count(*), x.a + x.b + x.c
$$) as (count agtype, key agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you should get the following output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; count | key
-------+-----
 12    | 6
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's explain What happened here, first you need to understand the concept of &lt;strong&gt;grouping key&lt;/strong&gt;, &lt;strong&gt;grouping key&lt;/strong&gt; is what &lt;code&gt;count&lt;/code&gt; function will exactly count, &lt;code&gt;x.a + x.b + x.c&lt;/code&gt; is the grouping key in this example. Let's see how see how this works in detail&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RETURN (x.a + x.b + x.c) + count(*) + count(*), x.a + x.b + x.c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;as &lt;code&gt;x.a + x.b + x.c&lt;/code&gt; is the grouping key, we need to find how many groups it makes, according to the vertices we created above &lt;br&gt;
&lt;code&gt;(:L {a: 1, b: 2, c: 3})&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;(:L {a: 2, b: 3, c: 1})&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;(:L {a: 3, b: 1, c: 2})&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;in all cases &lt;code&gt;(1 + 2 + 3)&lt;/code&gt;, &lt;code&gt;(2 + 3 + 1)&lt;/code&gt; or &lt;code&gt;(3 + 1 + 2)&lt;/code&gt; they all equal &lt;strong&gt;6&lt;/strong&gt; so they fall into the same group, which is one group: &lt;strong&gt;6&lt;/strong&gt;, now &lt;code&gt;count&lt;/code&gt; function will count how many &lt;strong&gt;6&lt;/strong&gt; has showed up, it finds that &lt;strong&gt;6&lt;/strong&gt; appeared &lt;strong&gt;3&lt;/strong&gt; times, so &lt;code&gt;count(*)=3&lt;/code&gt;. So if we computed left column we will get &lt;strong&gt;12&lt;/strong&gt;:&lt;br&gt;
&lt;code&gt;(x.a + x.b + x.c) + count(*) + count(*) =&lt;/code&gt;&lt;br&gt;
&lt;code&gt;(1 + 2 + 3) + 3 + 3 = 12&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;that's why we got the output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; count | key
-------+-----
 12    | 6
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the right part represent the groups that can be formed which will be only one group (&lt;strong&gt;6&lt;/strong&gt;), and the left part yields to 12 for that group!.&lt;/p&gt;

&lt;p&gt;congratulations!, by now you should have much deeper understanding of how &lt;code&gt;count&lt;/code&gt; function with &lt;strong&gt;grouping keys&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
    </item>
    <item>
      <title>How Does PostgreSQL Estimate The Cost Of A Query With The EXPLAIN Command</title>
      <dc:creator>Ahmed Hisham</dc:creator>
      <pubDate>Thu, 04 May 2023 16:15:00 +0000</pubDate>
      <link>https://dev.to/mghrabi/how-does-postgresql-estimate-the-cost-of-a-query-with-the-explain-command-14lc</link>
      <guid>https://dev.to/mghrabi/how-does-postgresql-estimate-the-cost-of-a-query-with-the-explain-command-14lc</guid>
      <description>&lt;p&gt;In this blog we will explore how PostgreSQL EXPLAIN command estimates the cost of a query, we will start by setting up a test database, then we will run a sequential scan command and estimate it manually and then compare it with EXPLAIN result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up a database
&lt;/h2&gt;

&lt;p&gt;First we will create a test database and insert some values into it. Open a postgres instance and create a &lt;code&gt;testdb&lt;/code&gt; database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;postgres=# CREATE DATABASE testdb;
postgres=# \c testdb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a table with two columns as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;testdb=# CREATE TABLE test_tbl (id INTEGER PRIMARY KEY, order_num INTEGER);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we want to insert some random rows into the table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;testdb=# INSERT INTO test_tbl SELECT generate_series(1, 10000), generate_series(1,10000);
INSERT 0 10000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To make sure everything is correct, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;testdb=# SELECT count(*) FROM test_tbl;
count
-------
 10000
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Estimating The Cost Of A Sequential Scan Query
&lt;/h2&gt;

&lt;p&gt;A sequential scan query means that query will need to scan the entire table, going over every single tuple (row). We will run this simple sequential scan query to make our tests on it &lt;code&gt;SELECT * FROM test_tbl&lt;/code&gt;, we will start by printing out the cost of this query using &lt;code&gt;EXPLAIN&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;testdb=# EXPLAIN SELECT * FROM test_tbl;
                          QUERY PLAN
--------------------------------------------------------------
 Seq Scan on test_tbl  (cost=0.00..145.00 rows=10000 width=8)
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can notice the estimated cost has two numbers &lt;strong&gt;0.00&lt;/strong&gt; and &lt;strong&gt;145.00&lt;/strong&gt;, yes they are two numbers, they represent the &lt;strong&gt;start-up&lt;/strong&gt; and the &lt;strong&gt;total&lt;/strong&gt; costs respectively. &lt;/p&gt;

&lt;p&gt;In PostgreSQL, there are three kinds of costs: &lt;strong&gt;start-up&lt;/strong&gt;, &lt;strong&gt;run&lt;/strong&gt; and &lt;strong&gt;total&lt;/strong&gt;. The total cost is the sum of &lt;strong&gt;start-up&lt;/strong&gt; and &lt;strong&gt;run&lt;/strong&gt; costs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;start-up&lt;/strong&gt; cost is the cost expended before exactly fetching the first tuple in the table.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The &lt;strong&gt;run&lt;/strong&gt; cost is the cost to fetch all tuples.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The total cost as described is the sum of the costs of both start-up and run costs.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now let's compute the cost ourselves according to the website &lt;a href="https://www.interdb.jp/pg/pgsql0302.html"&gt;here&lt;/a&gt; the formula is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Total cost = (cpu run cost) + (disk run cost)&lt;/code&gt;&lt;br&gt;
&lt;code&gt;Total cost = (cpu_tuple_cost + cpu_operator_cost) * N_tuples + seq_page_cost * N_pages&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Don't be shocked it is simple, let's understand each variable alone:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;cpu_tuple_cost&lt;/code&gt;: This is the cost of processing each tuple (row) in a query result. The default value is 0.01.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cpu_operator_cost&lt;/code&gt;: This is the cost of processing each operator or function call in a query. The default value is 0.0025.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;seq_page_cost&lt;/code&gt;: This is the cost of reading a page from disk sequentially. The default value is 1.0.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;N_tuples&lt;/code&gt;: This is the number of tuples (rows) returned by the query.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;N_pages&lt;/code&gt;: This is the number of pages read from disk during the query.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All variables are known except for &lt;code&gt;N_tuples&lt;/code&gt; and &lt;code&gt;N_pages&lt;/code&gt; which we can by running 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;testdb=# SELECT relpages, reltuples FROM pg_class WHERE relname = 'test_tbl';
 relpages | reltuples
----------+-----------
       45 |     10000
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can notice, the number of tuples is &lt;strong&gt;10000&lt;/strong&gt; which we inserted, and the number of pages is &lt;strong&gt;45&lt;/strong&gt; (a page is a block of data that is read from or written to disk as a unit, it is a section inside the table file). Now we have everything we need to use the equation:&lt;br&gt;
&lt;code&gt;Total cost = (0.01 + 0.0025) * 10000 + 1.0 * 45&lt;br&gt;
           = 102.5 + 45&lt;br&gt;
           = 147.5&lt;/code&gt;&lt;br&gt;
The result is &lt;strong&gt;147.5&lt;/strong&gt;!, which is almost the same as what the &lt;code&gt;EXPLAIN&lt;/code&gt; command estimated. &lt;/p&gt;

&lt;p&gt;I hope that was helpful.&lt;/p&gt;

</description>
      <category>apacheage</category>
      <category>postgres</category>
    </item>
    <item>
      <title>How To Debug Apache AGE using GDB</title>
      <dc:creator>Ahmed Hisham</dc:creator>
      <pubDate>Wed, 03 May 2023 10:28:36 +0000</pubDate>
      <link>https://dev.to/mghrabi/how-to-debug-apache-age-using-gdb-kl2</link>
      <guid>https://dev.to/mghrabi/how-to-debug-apache-age-using-gdb-kl2</guid>
      <description>&lt;p&gt;This blog post assumes you have already installed postgresql (with debugging flag enabled) and Apache AGE extension,  otherwise you can follow this &lt;a href="https://dev.to/mghrabi/explaining-in-detail-how-to-install-postgresql-from-source-code-on-windows-with-a-full-understanding-3jk7"&gt;blog&lt;/a&gt; for installation process. &lt;/p&gt;

&lt;h2&gt;
  
  
  Loading Apache AGE
&lt;/h2&gt;

&lt;p&gt;1- first we need to run a postgres instance by using &lt;code&gt;psql&lt;/code&gt; but make sure to run the server first, you can do that by the following two commands:&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 start -l log
psql postgres
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2- Load &lt;code&gt;age&lt;/code&gt; and set the search path to &lt;code&gt;ag_catalog&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;LOAD age;
SET search_path = ag_catalog, "$user", public;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3- Now you should be ready to debug AGE, but first we need to know the process of where the backend process of postgres is running, so that we can attach it to the gdb process, we can know the process by 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;SELECT pg_backend_pid();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this should show you an output similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;postgres=# select pg_backend_pid();
 pg_backend_pid
----------------
            439
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4- Now open another terminal and &lt;code&gt;cd&lt;/code&gt; to where age project exits on your machine, and run &lt;code&gt;gdb&lt;/code&gt; to attach it to that process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yourmachine:/mnt/d/bitnine_work/age_project/age$ gdb -p 439 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you should get an output similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later &amp;lt;http://gnu.org/licenses/gpl.html&amp;gt;
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
&amp;lt;http://www.gnu.org/software/gdb/bugs/&amp;gt;.
Find the GDB manual and other documentation resources online at:
    &amp;lt;http://www.gnu.org/software/gdb/documentation/&amp;gt;.

For help, type "help".
Type "apropos word" to search for commands related to "word".
Attaching to process 439
Reading symbols from /usr/local/pgsql-12/bin/postgres...
Reading symbols from /lib/x86_64-linux-gnu/libpthread.so.0...
Reading symbols from /usr/lib/debug/.build-id/7b/4536f41cdaa5888408e82d0836e33dcf436466.debug...
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Reading symbols from /lib/x86_64-linux-gnu/librt.so.1...
Reading symbols from /usr/lib/debug/.build-id/ce/016c975d94bc4770ed8c62d45dea6b71405a2c.debug...
Reading symbols from /lib/x86_64-linux-gnu/libdl.so.2...
Reading symbols from /usr/lib/debug/.build-id/c0/f40155b3f8bf8c494fa800f9ab197ebe20ed6e.debug...
Reading symbols from /lib/x86_64-linux-gnu/libm.so.6...
Reading symbols from /usr/lib/debug/.build-id/fe/91b4090ea04c1559ff71dd9290062776618891.debug...
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...
Reading symbols from /usr/lib/debug/.build-id/18/78e6b475720c7c51969e69ab2d276fae6d1dee.debug...
--Type &amp;lt;RET&amp;gt; for more, q to quit, c to continue without paging--
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5- Let's set a breakpoint to a function that exists in &lt;code&gt;age/src/backend/parser/cypher_analyze.c&lt;/code&gt; file, which is &lt;code&gt;analyze_cypher&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gdb) b src/backend/parser/cypher_analyze.c:analyze_cypher
Breakpoint 1 at 0x7f83c3da8620: file src/backend/parser/cypher_analyze.c, line 624.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;6- Now create a cypher query for any graphs you created before, or create a &lt;code&gt;test&lt;/code&gt; graph, insert some values into it, and then fetch some data, 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;postgres=# SELECT * FROM cypher('test', $$
MATCH (v:person)
RETURN v.name
$$) as (v agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;after running that you will notice that nothing has returned from postgres terminal, that's because &lt;code&gt;gdb&lt;/code&gt; interrupted the process to enable debugging:&lt;/p&gt;

&lt;p&gt;7- In &lt;strong&gt;gdb&lt;/strong&gt; terminal enter the following:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;this will run the code till the breakpoint we set, then enter:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;you will notice that we reached to &lt;code&gt;analyze_cypher&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;We are done!, by using the following basic commands you can print out variables to check their values, or continue the code till the next breakpoint:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;b&lt;/code&gt; for breakpoint, (b )&lt;br&gt;
&lt;code&gt;c&lt;/code&gt; for continue - continues to the next breakpoint&lt;br&gt;
&lt;code&gt;n&lt;/code&gt; for next line&lt;br&gt;
&lt;code&gt;s&lt;/code&gt; for step into&lt;br&gt;
&lt;code&gt;p&lt;/code&gt; for print, (p *) for pointers&lt;br&gt;
&lt;code&gt;bt&lt;/code&gt; for call stack&lt;br&gt;
&lt;code&gt;d&lt;/code&gt; for delete all breakpoints&lt;br&gt;
&lt;code&gt;list&lt;/code&gt; for context&lt;br&gt;
&lt;code&gt;q&lt;/code&gt; for quit.&lt;/p&gt;

&lt;p&gt;Hope this was helpful.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
    </item>
    <item>
      <title>Explaining How And Where PostgreSQL Stores Databases And Tables With Example.</title>
      <dc:creator>Ahmed Hisham</dc:creator>
      <pubDate>Sun, 16 Apr 2023 17:55:17 +0000</pubDate>
      <link>https://dev.to/mghrabi/explaining-where-postgresql-stores-data-with-an-example-1io3</link>
      <guid>https://dev.to/mghrabi/explaining-where-postgresql-stores-data-with-an-example-1io3</guid>
      <description>&lt;p&gt;By the end of this blog you will understand the basics of PostgreSQL architecture and where it store its data especially databases and tables, we will walk through a live example in which we will create a database and a table, and then navigate to where they are stored.&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%2F9h9ylnybw07x3q9bt9bi.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%2F9h9ylnybw07x3q9bt9bi.png" alt="PostgreSQL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Postgres Installation:
&lt;/h2&gt;

&lt;p&gt;To follow this blog you should have PostgreSQL already installed on your machine, you can install it from &lt;a href="https://www.postgresql.org/download/" rel="noopener noreferrer"&gt;here&lt;/a&gt; (but pay attention to where you install PostgreSQL, the default option will be on &lt;strong&gt;C:\Program Files\PostgreSQL\version&lt;/strong&gt;, don't forget to add the path of /bin folder to your environment variables to be able to access PostgreSQL from your terminal using &lt;strong&gt;psql&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating a database with a table:
&lt;/h2&gt;

&lt;p&gt;We will first create a database called &lt;strong&gt;test_db&lt;/strong&gt; with a table called &lt;strong&gt;users&lt;/strong&gt;, we will make it as simple as possible:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;postgres=# CREATE DATABASE test_db;
CREATE DATABASE

postgres=# \c test_db

test_db=# CREATE TABLE users (id SERIAL PRIMARY KEY, username TEXT);
CREATE TABLE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then insert a row (tuple) into &lt;strong&gt;users&lt;/strong&gt; table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test_db=# INSERT INTO users (username) VALUES ('ahmed hisham');
INSERT 0 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A database cluster:
&lt;/h2&gt;

&lt;p&gt;PostgreSQL runs on a single host and manages one database cluster (a database cluster is a collection of databases), as you can see below, each database contains its tables.&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%2Fe78swoyzmww7xkj0tgrk.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%2Fe78swoyzmww7xkj0tgrk.png" alt="Logical_Structure"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In PostgreSQL all objects including (databases and tables which are refered to as objects) are managed by a respective object identifiers (OIDs), this is a unique value for each object. Each database is a subdirectory named by its oid. PostgreSQL stores its databases in the &lt;strong&gt;base&lt;/strong&gt; folder &lt;strong&gt;PostgreSQL/YOUR_VERSION/data/base&lt;/strong&gt;. The parent directory &lt;strong&gt;(data)&lt;/strong&gt; or &lt;strong&gt;PGDATA&lt;/strong&gt; has the following architecture:&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%2Fejnf1gmcu4b2pxuehcd3.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%2Fejnf1gmcu4b2pxuehcd3.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each database is a subdirectory in &lt;strong&gt;/base&lt;/strong&gt; folder and it is named by its oid as described above, tables are files stored inside database subdirectory, and named by its oid (table oid) as well, so our &lt;strong&gt;test_db&lt;/strong&gt; is inside &lt;strong&gt;/base&lt;/strong&gt; directory, and &lt;strong&gt;users&lt;/strong&gt; table is a file inside &lt;strong&gt;test_db&lt;/strong&gt; subdirectory.&lt;/p&gt;

&lt;p&gt;Our mission is to move to &lt;strong&gt;users&lt;/strong&gt; table file and check if the row we inserted above to &lt;strong&gt;users&lt;/strong&gt; table is really stored there. But wait, all databases subdirectories are named by their oid and we don't know the oid of &lt;strong&gt;test_db&lt;/strong&gt; as if you &lt;strong&gt;ls&lt;/strong&gt; inside &lt;strong&gt;base&lt;/strong&gt; subdirectory you will get the following output (list of database oids):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ahmeduser@ahmed:/usr/local/pgsql-12/bin/data/base$ ls
1  12674  12675  32768  40960  49152  pgsql_tmp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So to get &lt;strong&gt;test_db&lt;/strong&gt; subdirectory oid we need to know its oid, to do that run 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;test_db=# SELECT datname, oid FROM pg_database where datname='test_db';
 datname |  oid
---------+-------
 test_db | 49152
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above command go to &lt;strong&gt;pg_database&lt;/strong&gt; which is a system catalog that stores information about databases and their corresponding oids. We need to do the same for &lt;strong&gt;users&lt;/strong&gt; table and get its oid:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test_db=# SELECT relname, oid FROM pg_class where relname='users';
 relname |  oid
---------+-------
 users   | 57346
(1 row)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;pg_class&lt;/strong&gt; is the same as &lt;strong&gt;pg_database&lt;/strong&gt; but for tables.&lt;/p&gt;

&lt;p&gt;Now let's navigate to &lt;strong&gt;test_db&lt;/strong&gt; subdirectory using its oid &lt;strong&gt;49152&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;ahmeduser@ahmed:/usr/local/pgsql-12/bin/data/base$ cd 49152
ahmeduser@ahmed:/usr/local/pgsql-12/bin/data/base/49152$ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open &lt;strong&gt;users&lt;/strong&gt; table file using any editor you like, I will use &lt;strong&gt;vim&lt;/strong&gt; in my linux terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ahmeduser@ahmed:/usr/local/pgsql-12/bin/data/base/49152$ vim 57346
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output: &lt;br&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%2Fmnq3xpml6kfhu8w2ihlc.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%2Fmnq3xpml6kfhu8w2ihlc.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should get a similar result, you can notice that the username value I inserted was &lt;strong&gt;ahmed hisham&lt;/strong&gt; which appears at the bottom of the file (note: these characters &lt;strong&gt;@^&lt;/strong&gt; represent free spaces, free spaces are necessary for PostgreSQL to manage how to store and scan data inside table files).&lt;/p&gt;

&lt;p&gt;We are done!, you should by now have an idea of where and how PostgreSQL stores databases and tables, I hope that was useful, feel free to ask any question.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
    </item>
    <item>
      <title>Explaining In Detail How To Install PostgreSQL From Source Code On Windows With a Full Understanding.</title>
      <dc:creator>Ahmed Hisham</dc:creator>
      <pubDate>Fri, 07 Apr 2023 21:01:28 +0000</pubDate>
      <link>https://dev.to/mghrabi/explaining-in-detail-how-to-install-postgresql-from-source-code-on-windows-with-a-full-understanding-3jk7</link>
      <guid>https://dev.to/mghrabi/explaining-in-detail-how-to-install-postgresql-from-source-code-on-windows-with-a-full-understanding-3jk7</guid>
      <description>&lt;p&gt;In this blog I will provide a full understanding of the steps of installing PostgreSQL from the source code and how to get it to work properly, also the installation process should make postgres ready to LOAD Apache AGE extension, and I provided resources at the end of the blog to know how to install Apache AGE.&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Postgres?
&lt;/h1&gt;

&lt;p&gt;PostgreSQL is a powerful open-source relational database (RDB) management system that uses SQL as its main query language. PostgreSQL proved to be highly reliable, stable, scalable, and secure. As it is a relational database, it provides ACID properties which stands for (Atomicity, Consistency, Isolation, and Durability).&lt;/p&gt;

&lt;h1&gt;
  
  
  How To Install Postgres From Source Code:
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1- Requirements before Installation
&lt;/h2&gt;

&lt;p&gt;To work with Apache AGE Extension you need to install Linux subsystem on your windows as Apache AGE is not supporting windows installation yet. So you will need to enable &lt;strong&gt;Windows Subsystem For Linux&lt;/strong&gt; on your windows to able to install wsl, you can do that by searching for &lt;strong&gt;Turn Windows features on or off&lt;/strong&gt; on the windows search bar down below, then scroll down till you find &lt;strong&gt;Windows Subsystem for Linux&lt;/strong&gt; and check it. Now restart your machine and you should be ready to go.&lt;/p&gt;

&lt;p&gt;To install wsl (this blog assumes you have Windows 10 version 2004 or higher), you will only need to open command prompt &lt;strong&gt;as an administrator&lt;/strong&gt; and run 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;wsl --install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will download Ubuntu as the distro by default and for more information you can check &lt;a href="https://www.windowscentral.com/software-apps/the-best-linux-distros-for-wsl-on-windows-10-and-11"&gt;here&lt;/a&gt;, also make sure to download linux terminal for the right distro from Windows Store, I'm using Ubuntu 20.04.5 LTS for this tutorial:&lt;/p&gt;

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

&lt;h2&gt;
  
  
  2- Installation:
&lt;/h2&gt;

&lt;p&gt;Installing PostgreSQL from source code make it more customisable to fit your application needs and it also make it easier to switch between different versions, In this blog we will install PostgreSQL 12 as it is the latest version that Apache AGE extension supports for now (very soon it will support PostgreSQL 13, you can always check &lt;a href="https://github.com/apache/age/releases"&gt;here&lt;/a&gt;), but the installation process of future supported versions will be the same.&lt;/p&gt;

&lt;p&gt;1- Open your linux terminal &lt;strong&gt;as an administrator&lt;/strong&gt; and run the following command (this will ensure you have the required git and PostgreSQL dependencies for installation):&lt;br&gt;
&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;2- Before cloning the repository, to access the drives of your machine on terminal you can simply run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /mnt/c
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3- this will change the current directory to the root directory of C drive. Now create a directory where you will install PostgreSQL, we will name it (age_project) and then clone the PostgreSQL repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir age_project
cd age_project
git clone https://git.postgresql.org/git/postgresql.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4- Access &lt;code&gt;postgresql&lt;/code&gt; directory and switch to PostgreSQL 12&lt;br&gt;
&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;5- Now if you &lt;code&gt;ls&lt;/code&gt; in the directory, you will find a configure script which we should be run to configure the source code for installation:&lt;br&gt;
&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 --enable-debug 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the --prefix option specifies the installation directory for PostgreSQL 12 as &lt;code&gt;/usr/local/pgsql-12&lt;/code&gt;, &lt;code&gt;/usr/local/&lt;/code&gt; is where locally compiled applications install to by default, so when we compile the code it knows where to send the compiled files, note: we didn't create that directory yet, we just informed postgresql to store the executable files there after compilation (specifically after running &lt;code&gt;make install&lt;/code&gt; command later), so we will need to create the directory in a next step. The &lt;code&gt;--enable-debug&lt;/code&gt; is necessary to allow debugging for source code.&lt;/p&gt;

&lt;p&gt;6- Run the &lt;code&gt;make&lt;/code&gt; command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;7- Now the executable files are in the same directory but we still need to install them where we specified above, to &lt;code&gt;/usr/local/pgsql-12&lt;/code&gt; directory, to do that run the following command to create the folder first, change the owner and then install (make sure to replace [user] with your user name):&lt;br&gt;
&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;8- After installation we are almost done, the remaining step is to add some environment variables to be able to access the executable files in the terminal, we do this by 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;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;we exported &lt;code&gt;/usr/local/pgsql-12/bin/&lt;/code&gt; as it contains the executable files of PostgreSQL 12 such as &lt;code&gt;pg_ctl&lt;/code&gt; which we will use to run postgres server.&lt;br&gt;
we exported the data directory &lt;code&gt;/usr/local/pgsql-12/bin/data&lt;/code&gt; because it is where postgres stores the data like databases data, each database created has a subdirectory there.&lt;/p&gt;

&lt;p&gt;9- Finally it is time to work with postgres, we will first initiate the cluster (A database cluster is a collection of databases), we simply need to run &lt;code&gt;initdb&lt;/code&gt; in the terminal (which is one of the files installed in &lt;code&gt;/usr/local/pgsql-12/bin/&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;initdb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;10- start a server by 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;pg_ctl start -l logfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in this case we named the log file &lt;code&gt;logfile&lt;/code&gt; which will be created and it contains information about the server activity.&lt;/p&gt;

&lt;p&gt;11- Now start postgres by running:&lt;br&gt;
&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;12- Congrats you are done!, you can exit psql by &lt;code&gt;\q&lt;/code&gt; and stop the server by running:&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 stop -l logfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With having PostgreSQL running you can successfully &lt;code&gt;LOAD&lt;/code&gt; Apache AGE extension, you can clone it from github repo &lt;a href="https://github.com/apache/age"&gt;here&lt;/a&gt;, and for more information about how to deal with it you can visit &lt;a href="https://age.apache.org/"&gt;https://age.apache.org/&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheag</category>
      <category>wsl</category>
      <category>ubuntu</category>
    </item>
  </channel>
</rss>
