<?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: Ken Woon</title>
    <description>The latest articles on DEV Community by Ken Woon (@xk_woon).</description>
    <link>https://dev.to/xk_woon</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%2F1028502%2F165e736f-acc3-4631-aee0-6f34cfed549d.png</url>
      <title>DEV Community: Ken Woon</title>
      <link>https://dev.to/xk_woon</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/xk_woon"/>
    <language>en</language>
    <item>
      <title>Introducing AgeSQL: Seamlessly Bridging the Gap Between SQL and Cypher in PostgreSQL</title>
      <dc:creator>Ken Woon</dc:creator>
      <pubDate>Mon, 17 Jul 2023 22:35:21 +0000</pubDate>
      <link>https://dev.to/xk_woon/introducing-agesql-seamlessly-bridging-the-gap-between-sql-and-cypher-in-postgresql-1je0</link>
      <guid>https://dev.to/xk_woon/introducing-agesql-seamlessly-bridging-the-gap-between-sql-and-cypher-in-postgresql-1je0</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Are you looking for a powerful tool that combines the expressive capabilities of Cypher queries with the familiarity of SQL syntax? Meet AgeSQL, a command-line interface (CLI) client for PostgreSQL that extends its capabilities to support both traditional SQL and Cypher queries without the hassle of wrapping Cypher queries. AgeSQL leverages the AGE extension for PostgreSQL, which enables graph queries within the database, making it a versatile tool for working with graph data.&lt;/p&gt;

&lt;p&gt;In this blog post, I'll share the details of my current project, &lt;a href="https://github.com/AGEDB-INC/AgeSQL"&gt;AgeSQL&lt;/a&gt;, its key features, and how you can install and use it to harness the power of both SQL and Cypher in your PostgreSQL database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Need for AgeSQL
&lt;/h2&gt;

&lt;p&gt;Working with graph databases can be both exciting and challenging. Traditional SQL is powerful for certain types of data analysis and manipulation, but when it comes to traversing and querying connected graph data, Cypher, a language specifically designed for graph databases, shines. AgeSQL was born out of the need to have a unified tool that brings together the strengths of SQL and Cypher, making it easier for users to interact with graph databases using a familiar interface.&lt;/p&gt;

&lt;p&gt;What sets this apart from the current version of Apache AGE is that AgeSQL does not require Cypher queries to be wrapped in an SQL function clause, and can be directly written in Cypher syntax. The backend takes the raw user inputs and convert them into a wrapped clause that is compatible in AGE, which will then be sent to the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Addressing the Challenges
&lt;/h2&gt;

&lt;p&gt;Building a CLI tool like AgeSQL comes with its share of challenges. Let's briefly touch on how we've addressed some of these challenges to make AgeSQL a robust and user-friendly tool:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Determining the graph to use: AgeSQL has a mechanism to identify the graph to be queried, allowing it to handle different graphs based on user input.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Determining the number of output parameters: AgeSQL intelligently determines the number of parameters to expect in the final result, which is crucial for processing and presenting query results accurately.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Determining the output type: AgeSQL identifies the appropriate output type for each parameter in the result, taking into account different data types supported by PostgreSQL, such as pg_float8 or agtype.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By addressing these challenges, AgeSQL provides a seamless and efficient experience for executing SQL and Cypher queries within the PostgreSQL database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Features of AgeSQL
&lt;/h2&gt;

&lt;p&gt;AgeSQL offers a variety of features that make it a powerful tool for working with graph data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Seamless integration of Cypher queries into PostgreSQL: AgeSQL supports standard SQL queries in addition to Cypher queries. It internally converts Cypher queries into PostgreSQL functions, eliminating the need for manual function calls.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Execution of Cypher queries: With AgeSQL, you can execute Cypher queries directly within the PostgreSQL database. This allows you to perform graph traversal, pattern matching, and graph analysis operations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integration with traditional SQL: AgeSQL seamlessly wraps Cypher commands in SQL syntax, allowing you to execute them within PostgreSQL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support for graph-specific operations: AgeSQL supports various graph-specific operations, including traversing nodes and edges, retrieving properties, and performing graph analytics.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Familiar psql-like interface: AgeSQL provides an interface similar to PostgreSQL's psql, making it easy for users to interact with the database.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installing and Using AgeSQL
&lt;/h2&gt;

&lt;p&gt;To get started with AgeSQL, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Ensure you have PostgreSQL 15 installed with the AGE extension enabled.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clone the PostgreSQL repository from GitHub and compile the source code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install AGE 12.1.0, a prerequisite for AgeSQL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Clone the AgeSQL repository from GitHub and compile the source code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start the AgeSQL command-line interface.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The detailed step-by-step instructions could be found in the &lt;a href="https://github.com/AGEDB-INC/AgeSQL#readme"&gt;README section&lt;/a&gt; of the GitHub page. Once you're inside the AgeSQL CLI, you can run both SQL and Cypher queries effortlessly. For SQL queries, simply type them as you would in psql. For Cypher queries, remember to set the graph path first using the CREATE GRAPH command or the SET GRAPH_PATH command. AgeSQL seamlessly converts Cypher queries to PostgreSQL functions, so you can execute them without calling functions explicitly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;

&lt;p&gt;Creating graphs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE GRAPH graph_name1;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creating vertices and relationships:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE (a:label)-[e:RELTYPE]-&amp;gt;(b:label);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Returning values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RETURN a AS rslt ORDER BY b ASC SKIP 1 LIMIT 5;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Matching data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MATCH (n:label), (m:label) WHERE property(n) &amp;lt;&amp;gt; property(m)
OPTIONAL MATCH (n)-[r]-&amp;gt;(p), (m)-[s]-&amp;gt;(q);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;AgeSQL is a powerful CLI tool that bridges the gap between SQL and Cypher in PostgreSQL, allowing you to work seamlessly with graph databases using familiar SQL syntax while benefiting from the expressive power of Cypher without having the need to wrap it in an SQL clause. With its seamless integration and support for both SQL and Cypher queries, AgeSQL empowers developers and data analysts to tackle complex graph data with ease.&lt;/p&gt;

&lt;p&gt;So, if you're working with graph databases and want a versatile tool that brings together the best of SQL and Cypher, give AgeSQL a try! Get started with AgeSQL today and unlock the potential of your PostgreSQL database for graph-based operations. Happy graph querying!&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
    </item>
    <item>
      <title>How I Learned Lex and Yacc with Apache AGE Functions</title>
      <dc:creator>Ken Woon</dc:creator>
      <pubDate>Wed, 26 Apr 2023 23:32:31 +0000</pubDate>
      <link>https://dev.to/xk_woon/unlock-the-power-of-lex-and-yacc-with-apache-age-functions-3dof</link>
      <guid>https://dev.to/xk_woon/unlock-the-power-of-lex-and-yacc-with-apache-age-functions-3dof</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As a developer for the open source Apache AGE project, I have been learning to program using Lex and Yacc in order to create functionalities for the extension. Lex and Yacc are powerful tools that can help us generate parsers and scanners for our programming language. However, these tools can be difficult to learn and use without some guidance. &lt;/p&gt;

&lt;p&gt;In the AGE Command Line Interface (CLI) project, we aim to simplify querying in Apache AGE by allowing users to code in Cypher without wrapping it inside a SQL query. In order to do this, we are using Lex and Yacc programs to convert Cypher clauses into functions recognizable by the psql CLI.&lt;/p&gt;

&lt;p&gt;In this blog post, we'll take a closer look at how I used Apache Age functions, specifically the &lt;code&gt;MATCH&lt;/code&gt; function to learn Lex and Yacc coding and start building my own program.&lt;/p&gt;

&lt;h2&gt;
  
  
  Language Processing
&lt;/h2&gt;

&lt;p&gt;In order to understand Lex/Yacc, let's first talk about Language Processing as a whole. Language processing is a crucial component in the world of software development, and it involves several stages to transform source code into executable programs. The process typically involves four key stages: lexical analysis, syntax analysis, semantic analysis and code generation, and target code generation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lexical analysis&lt;/strong&gt; involves breaking down the source code into a series of tokens. These tokens are then analyzed to identify their respective classes, such as identifiers, keywords, and operators. This stage is performed by a tool called a lexer or scanner, which uses a set of rules specified in a formal language like Lex to identify and extract the tokens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Syntax analysis&lt;/strong&gt; is the next step, which involves parsing the token stream to determine whether the code conforms to the grammar of the programming language. This stage is carried out by a parser, which uses a formal language like Yacc to generate a parse tree, representing the syntactic structure of the program.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Semantic analysis and code generation&lt;/strong&gt; is the stage where the parse tree is analyzed to determine the meaning of the program and generate corresponding machine code. This stage involves a series of transformations on the parse tree, including type checking, scope resolution, and code generation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Target code generation&lt;/strong&gt; is the next stage, which involves generating machine code that can be executed on a particular hardware platform. This stage is typically carried out by a code generator, which translates the machine-independent code into machine-specific instructions.&lt;/p&gt;

&lt;p&gt;We will be focusing on the first two steps, which are managed by writing Lex and Yacc files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compilation and Execution
&lt;/h2&gt;

&lt;p&gt;In this blog post, I will be using Flex and Bison instead, which are basically just improved versions of Lex and Yacc. The &lt;code&gt;bison&lt;/code&gt; and &lt;code&gt;flex&lt;/code&gt; commands in the examples below can interchangeable with &lt;code&gt;yacc&lt;/code&gt; and &lt;code&gt;lex&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Before compiling, make sure both &lt;code&gt;{filename}.y&lt;/code&gt; and &lt;code&gt;{filename}.l&lt;/code&gt; exists in the same directory, with {filename} to be whatever name you desire. First run the command below in a terminal window.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bison -d {filename}.y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a &lt;code&gt;{filename}.tab.c&lt;/code&gt; parser file and the &lt;code&gt;-d&lt;/code&gt; option generates the &lt;code&gt;{filename}.tab.h&lt;/code&gt; header file, which may be referenced in the Lex file. Then, run the command below to compile the Lex file.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This generates a file called &lt;code&gt;lex.yy.c&lt;/code&gt;. With the two generated C files, run the following command to compile them into an executable C program.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gcc lex.yy.c {filename}.tab.c -o {filename}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This generates an executable C with a filename you have specified after the &lt;code&gt;-o&lt;/code&gt; option, which tells the compiler to output the file into the specified filename.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Run the command above to execute your newly created program and you have successfully built and executed your program!&lt;/p&gt;

&lt;p&gt;For example, a complete compilation and execution for the file 'match.l' and 'match.y' will look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yacc -d match.y
flex match.l
gcc lex.yy.c match.tab.c -o match
./match
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If any case that an error occurs, there are likely issues with either the Lex or Yacc file, which will be specified by the error message, along with the problematic line and character.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lex Structure
&lt;/h2&gt;

&lt;p&gt;The structure of Lex files will look something like 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;%{
DECLARATIONS
%}

%%
PATTERNS    ACTIONS;
%%

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

&lt;/div&gt;



&lt;p&gt;The first part is enclosed in &lt;code&gt;%{ ... %}&lt;/code&gt; and includes C declarations such as &lt;code&gt;#include&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The section enclosed with &lt;code&gt;%% ... %%&lt;/code&gt; represents the pattern-action pairs that allows the parser to recognize specific tokens that are inputted by the user, and make an action or multiple actions based on the input.&lt;/p&gt;

&lt;p&gt;The last section contains C functions that support the language processing. These functions may be called by the actions from the previous section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Yacc Structure
&lt;/h2&gt;

&lt;p&gt;The structure of Yacc files is similar to that of Lex files and will look something like 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;%{
DECLARATIONS
%}

DEFINITIONS

%%
GRAMMARS : RULES;    {ACTIONS}
%%

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

&lt;/div&gt;



&lt;p&gt;The first part is enclosed in &lt;code&gt;%{ ... %}&lt;/code&gt; and includes C declarations such as &lt;code&gt;#include&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The next section is for yacc definitions that begins with the &lt;code&gt;%&lt;/code&gt; symbol, which consists of the &lt;code&gt;%start&lt;/code&gt;, &lt;code&gt;%token&lt;/code&gt;, &lt;code&gt;%union&lt;/code&gt;, and &lt;code&gt;%types&lt;/code&gt; definitions.&lt;/p&gt;

&lt;p&gt;The section enclosed with &lt;code&gt;%% ... %%&lt;/code&gt; represents grammars that are a set of productions. The left-hand side which are grammars is followed by &lt;code&gt;:&lt;/code&gt;, and a &lt;code&gt;;&lt;/code&gt; to finish the set of rules or &lt;code&gt;|&lt;/code&gt; to add more rules, and a right-hand side with actions that are enclosed in &lt;code&gt;{ ... }&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The last section contains C functions that support the language processing. These functions may be called by the actions from the previous section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Working with Lex
&lt;/h2&gt;

&lt;p&gt;In this example, we will try to replicate the 'MATCH' Cypher command commonly used in AGE.&lt;/p&gt;

&lt;p&gt;In the first part, we will include the 'match.tab.h' header that will be generated after compiling the 'match.y' file. We will also create a variable &lt;code&gt;yyerror&lt;/code&gt; with type void which the parser will call whenever a syntactical error occurs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;%{
#include "match.tab.h"

void yyerror(char* s);
%}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next section is defined with patterns and their actions. The first pattern &lt;code&gt;[ \t\n]&lt;/code&gt; defines whitespaces, tab spaces, and new lines, and tells the compiler to ignore these input. The &lt;code&gt;MATCH&lt;/code&gt; and &lt;code&gt;RETURN&lt;/code&gt; tokens are intuitive and simply returns &lt;code&gt;MATCH&lt;/code&gt; and &lt;code&gt;RETURN&lt;/code&gt; to the compiler. The following symbols are instead returned as key words that will be used in the Yacc file. The &lt;code&gt;exit&lt;/code&gt; token will return the &lt;code&gt;exit_command&lt;/code&gt;, and any string of characters starting with a alphabetic character followed by any alphabetic or numeric character will be recognized as a &lt;code&gt;VAR&lt;/code&gt;. Anything else that are inputted by the user will cause a syntactical error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;%%
[ \t\n]                 ;
"MATCH"                 { return MATCH; }
"RETURN"                { return RETURN; }
"-"                     { return DASH; }
"("                     { return LP; }
")"                     { return RP; }
"["                     { return LB; }
"]"                     { return RB; }
"{"                     { return LC; }
"}"                     { return RC; }
"&amp;lt;"                     { return LT; }
"&amp;gt;"                     { return GT; }
";"                     { return yytext[0]; }
"exit"                  { return exit_command; }
[a-zA-Z][a-zA-Z0-9]*    { return VAR; }
.                       { ECHO; yyerror("unexpected character"); }
%%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is a function in the final part of the Lex file called &lt;code&gt;yywrap()&lt;/code&gt;, which is required if multiple input files will be used.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int yywrap(void) {
    return 1;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Working with Yacc
&lt;/h2&gt;

&lt;p&gt;In the first part, we will include the standard io and lib headers, as well as the 'match.tab.h' header that will be generated after compiling this file. We will also create a variable &lt;code&gt;yyerror&lt;/code&gt; with type void which the parser will call whenever a syntactical error occurs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;%{
#include &amp;lt;stdio.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include "match.tab.h"

void yyerror(char* s);
%}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will then have some Yacc definitions. &lt;code&gt;%union&lt;/code&gt; will allow us to specify the different types that the analyzer can return, which are enclosed in &lt;code&gt;{ ... }&lt;/code&gt;. &lt;code&gt;%start&lt;/code&gt; indicates the default production grammar to look for at the start of the program. &lt;code&gt;%token&lt;/code&gt; describes the expected tokens that the analyzer will be receiving as the specified type. The &lt;code&gt;&amp;lt;str&amp;gt;&lt;/code&gt; after &lt;code&gt;%token&lt;/code&gt; stores the tokens into the union member 'str'.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;%union { char *str; }
%start query
%token &amp;lt;str&amp;gt; MATCH RETURN DASH LP RP LB RB LC RC LT GT VAR exit_command
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There will be 4 production grammars in total, with the &lt;code&gt;query&lt;/code&gt; grammar being the default. This grammar will consist of the &lt;code&gt;statement&lt;/code&gt; grammar, or the &lt;code&gt;exit_command&lt;/code&gt;, which will exit the program. The statement grammar can either be the &lt;code&gt;match_clause&lt;/code&gt;, the &lt;code&gt;return_clause&lt;/code&gt;, or both together. The &lt;code&gt;match_clause&lt;/code&gt; can have grammars that look like one from the list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;MATCH (u)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MATCH (u)-[r]-(v)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MATCH (u)&amp;lt;-[r]-(v)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MATCH (u)-[r]-&amp;gt;(v)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;return_clause&lt;/code&gt; will only allow us to return one variable as of now, which will be fixed in the future.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;%%
query : statement ';'                                                   { ; }
      | exit_command ';'                                                { printf("Exiting program...\n"); exit(EXIT_SUCCESS); }
      ;

statement : match_clause                                                { ; }
          | return_clause                                               { ; }
          | match_clause return_clause                                  { ; }

match_clause : MATCH LP VAR RP                                          { ; }
             | MATCH LP VAR RP DASH LB VAR RB DASH LP VAR RP            { ; }
             | MATCH LP VAR RP LT DASH LB VAR RB DASH LP VAR RP         { ; }
             | MATCH LP VAR RP DASH LB VAR RB DASH GT LP VAR RP         { ; }
             ;

return_clause : RETURN VAR                                              { ; }
              ;
%%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are two functions in the final part of the Yacc file, which are the &lt;code&gt;main()&lt;/code&gt; and &lt;code&gt;yyerror()&lt;/code&gt; functions. The &lt;code&gt;main()&lt;/code&gt; function simply returns &lt;code&gt;yyparse()&lt;/code&gt;, which is a Yacc function that iterates through the grammar to continuously read the input and produce the corresponding action until manually exited or an error is encountered. The &lt;code&gt;yyerror()&lt;/code&gt; is called whenever a syntax error occurs, which simply prints out the error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int main(void) {
    return yyparse();
}

void yyerror(char *s) {
    fprintf(stderr, "%s\n", s);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Program Demo
&lt;/h2&gt;

&lt;p&gt;After compiling and executing the program, you can try typing several different inputs to test if the program is working correctly.&lt;/p&gt;

&lt;p&gt;Trying any of these from the list with interchangeable variable name will pass as successfully parsed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;MATCH (u);&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MATCH (u)-[r]-(v);&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MATCH (u)&amp;lt;-[r]-(v);&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MATCH (u)-[r]-&amp;gt;(v);&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RETURN u;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MATCH (u) RETURN u;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MATCH (u)-[r]-(v) RETURN u;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MATCH (u)&amp;lt;-[r]-(v) RETURN u;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;MATCH (u)-[r]-&amp;gt;(v) RETURN u;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;exit;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you try any other combinations of recognized and unrecognized symbols, the program will spit an error message and exit the program.&lt;/p&gt;

&lt;p&gt;As of now, there are no actions set to the production grammars, which will not show the users any output through successful parses, but will be updated in the future to make the program more functional.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Learning Lex and Yacc programming using Apache Age functions can be an exciting and rewarding journey for any programmer interested in language processing and compiler development. With the help of Apache Age functions, I have learnt how to create my own program and build a compiler that can transform source code into executable programs.&lt;/p&gt;

&lt;p&gt;By mastering the various stages of language processing, including lexical analysis, syntax analysis, semantic analysis, code generation, and code improvement, you can gain a deep understanding of how programming languages work and develop skills that are highly sought after in the software industry.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;I have used &lt;a href="https://youtu.be/54bo1qaHAfk"&gt;this tutorial on Lex&lt;/a&gt; and &lt;a href="https://youtu.be/__-wUHG2rfM"&gt;this tutorial on Flex&lt;/a&gt; to learn the basics of Lex and Flex programming.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
      <category>lex</category>
      <category>yacc</category>
    </item>
    <item>
      <title>The Basics of Querying with Cypher in PostgreSQL using Apache Age</title>
      <dc:creator>Ken Woon</dc:creator>
      <pubDate>Sat, 11 Mar 2023 16:55:02 +0000</pubDate>
      <link>https://dev.to/xk_woon/the-basics-of-querying-with-cypher-in-postgresql-using-apache-age-43p1</link>
      <guid>https://dev.to/xk_woon/the-basics-of-querying-with-cypher-in-postgresql-using-apache-age-43p1</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Welcome to the world of graph databases! When it comes to modelling complex and highly connected data, graph databases have proven to be an efficient and intuitive solution. And one of the most popular graph databases out there is &lt;a href="https://neo4j.com/"&gt;Neo4j&lt;/a&gt;, which uses a query language called &lt;a href="https://neo4j.com/developer/cypher/"&gt;Cypher&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But what if you could use Cypher to query data in PostgreSQL? Well, now you can! Thanks to the Apache Age extension, you can use Cypher to query a graph that is stored in a PostgreSQL database. This powerful combination allows you to take advantage of the benefits of graph databases while leveraging the maturity and stability of PostgreSQL.&lt;/p&gt;

&lt;p&gt;In this blog post, I will walk you through the basics of querying with Cypher in PostgreSQL using the Apache Age extension. Whether you're new to graph databases or an experienced user, this post will help you get started on querying in Apache Age. So let's get started! If you have any doubts setting up your environment, check out my &lt;a href="https://dev.to/xk_woon/how-to-install-postgresql-and-apache-age-on-macos-45m8"&gt;previous post&lt;/a&gt; about the installation process for both PostgreSQL and Apache AGE.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cypher Syntax
&lt;/h2&gt;

&lt;p&gt;The syntax for Cypher is designed to be easy to read and write, making it accessible to both developers and non-technical users. The language is built around the concept of pattern matching, which allows you to describe complex relationships between nodes and edges in your graph data.&lt;/p&gt;

&lt;p&gt;In Cypher, nodes are represented by parenthesis &lt;code&gt;()&lt;/code&gt;, while labels or tags are indicated by a colon &lt;code&gt;:&lt;/code&gt; followed by the label name, which groups nodes by roles or types. For example, a node representing a person who is male could be labelled as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(:Person:Male)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nodes can also have properties, which are enclosed in curly braces &lt;code&gt;{}&lt;/code&gt; and follow the label, such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(:Person {name: 'Jake'})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Relationships, on the other hand, are indicated by hyphens &lt;code&gt;-&lt;/code&gt; or square brackets &lt;code&gt;[]&lt;/code&gt;, and connect two nodes together. The direction of the relationship is specified using &lt;code&gt;&amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;gt;&lt;/code&gt; to indicate the direction of the arrow. For example, if Jake likes Jane, we can represent this with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(:Person {name: 'Jake'})-[:LIKES]-&amp;gt;(:Person {name: 'Jane'})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the colon is dropped &lt;code&gt;-[LIKES]-&amp;gt;&lt;/code&gt;, this will instead represent a variable (alias) instead of a relationship type and all types of relationships will be searched.  &lt;/p&gt;

&lt;p&gt;Similar to nodes, relationships can also have properties, which are enclosed in curly braces &lt;code&gt;{}&lt;/code&gt; and follow the relationship type, such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-[:LIKES {type: 'as a friend'}]-&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, it's worth noting that aliases can be used to refer to nodes and relationships throughout your queries. To use an alias, simply name the node or relationship before the label, such as the &lt;code&gt;a&lt;/code&gt; from &lt;code&gt;(a:Person)&lt;/code&gt;, the &lt;code&gt;r&lt;/code&gt; from &lt;code&gt;[r:LIKES]&lt;/code&gt; and the &lt;code&gt;b&lt;/code&gt; from &lt;code&gt;(b:Person)&lt;/code&gt;. These can be referred to later in your query using the aliases you've defined, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(a)-[r:LIKES {type: 'as a friend'}]-&amp;gt;(b)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Basic Queries
&lt;/h2&gt;

&lt;p&gt;In Apache AGE, Cypher cannot be used in an expression and the query must exist in the SQL &lt;code&gt;FROM&lt;/code&gt; clause of a query. For example, to execute a Cypher query, the typical layout would be 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;SELECT *
FROM cypher('graph_name', $$
    /* Cypher query here, for example:
    MATCH (a:Person)
    RETURN a
    */
$$) AS (person agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cypher queries are written in between the dollar signs &lt;code&gt;$$ $$&lt;/code&gt; of the &lt;code&gt;cypher()&lt;/code&gt; command, which requires a graph name in the beginning to specify which graph is being worked on. Aliases have to be specified for the &lt;code&gt;RETURN&lt;/code&gt; outputs from the Cypher query. The syntax can be generalized as &lt;code&gt;cypher(graph_name, query_string, parameters)&lt;/code&gt;. AGE uses a custom data type called &lt;code&gt;agtype&lt;/code&gt;, which is the only data type returned by AGE.&lt;/p&gt;

&lt;p&gt;In order to start working with graphs in Apache Age using Cypher, the first step is to create a graph. This can be done using the &lt;code&gt;create_graph&lt;/code&gt; function, which takes the name of the graph as its argument:&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('graph_name');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To delete a graph, use &lt;code&gt;drop_graph&lt;/code&gt;, which also takes the name of the graph as an argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT drop_graph('graph_name', true);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have a graph to work with, you can start creating nodes or vertices using the &lt;code&gt;CREATE&lt;/code&gt; clause. To create a simple node, use &lt;code&gt;CREATE (n)&lt;/code&gt;. To create a node with a label, use &lt;code&gt;CREATE (:Person)&lt;/code&gt;. You can also add properties to nodes using the curly brace syntax, such as &lt;code&gt;CREATE (:Person {name: Jack})&lt;/code&gt;, as we saw in the previous section. Here is an example of a complete 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('People', $$
    CREATE (:Person {name: Jack}),
        (:Person {name: Jane})
$$) AS (person agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;MATCH&lt;/code&gt; clause is used to specify patterns that Cypher will search for in the database. To get all vertices in the graph, use &lt;code&gt;MATCH (n)&lt;/code&gt;. To get all vertices with a specific label, use &lt;code&gt;MATCH (n:Person)&lt;/code&gt;. To get related vertices, use &lt;code&gt;MATCH (:Person {name: 'Jack'})-[]-(:Person)&lt;/code&gt;, where the symbol &lt;code&gt;-[]-&lt;/code&gt; means related to, without regard to type or direction of the relationship. You can also match on specific edge types using a variable with &lt;code&gt;MATCH (:Person {name: 'Jack'})-[:LIKES]-&amp;gt;(:Person {name: 'Jane'})&lt;/code&gt;. A full query will look something like:&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('People', $$
    MATCH (a:Person {name: 'Jack'})-[r:LIKES {type: 'as a friend'}]-&amp;gt;(b:Person {name: 'Jane'})
    RETURN a.name, r.type, b.name
$$) AS (he agtype, likes agtype, her agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To delete graph elements, the &lt;code&gt;DELETE&lt;/code&gt; clause can be used. To delete a vertex, use &lt;code&gt;DELETE n&lt;/code&gt;. To delete all vertices and edges in the graph, use:&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('People', $$
    MATCH (n:People)
    DETACH DELETE n
$$) as (n agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To delete edges only, use:&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('People', $$
    MATCH (:People {name: 'Jack'})-[r:LIKES]-&amp;gt;()
    DELETE r 
$$) AS (n agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;SET&lt;/code&gt; clause is used to update labels on nodes and properties on vertices and edges. To set a property, use &lt;code&gt;SET n.age = 25&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 *
FROM cypher('People', $$
    MATCH (a:Person {name: 'Jack'})
    SET a.age = 25
$$) AS (n agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;REMOVE&lt;/code&gt; clause can be used to remove properties from vertices and edges, such as &lt;code&gt;REMOVE n.age&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 *
FROM cypher('People', $$
    MATCH (a:Person {name: 'Jack'})
    REMOVE a.age
$$) AS (n agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, the &lt;code&gt;RETURN&lt;/code&gt; clause allows you to specify which parts of the pattern you're interested in. This could be nodes, relationships, or properties on either of these. When you want to return all vertices, edges, and paths found in a query, you can use the &lt;code&gt;*&lt;/code&gt; symbol:&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('People', $$
    MATCH (a: Person {name: 'Jack'})-[r]-&amp;gt;(b)
    RETURN *
$$) AS (person1 agtype, relationship agtype, person2 agtype);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this section, we learned how to perform basic Cypher queries in Apache Age. We covered the creation and deletion of graphs, as well as the creation, deletion, and modification of nodes and relationships. With this knowledge, we can start building more complex queries to extract insights and knowledge from our data. To find out more about each clauses and other unmentioned clauses, as well as functions available in Apache AGE, check out the &lt;a href="https://age.apache.org/age-manual/master/index.html"&gt;official documentation&lt;/a&gt; available online.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;By learning these fundamental concepts and commands, you can start to leverage the power of graph databases and extract valuable insights and knowledge from your data. With Cypher and Apache Age, you can model your data as a graph, and query it using a familiar, intuitive syntax. Whether you're working on social networks, recommendation engines, fraud detection, or any other problem that can be modelled as a graph, Apache Age can help you store, manage, and query your data efficiently and effectively.&lt;/p&gt;

&lt;p&gt;I hope this blog post has been helpful in getting you started with Cypher queries in Apache Age. Remember, this is just the beginning as there are many more advanced features and techniques to explore as you become more proficient in using this powerful tool. So keep learning, keep practicing, and keep discovering new insights with Cypher and Apache Age.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post is written based on the &lt;a href="https://neo4j.com/developer/get-started/"&gt;Neo4j Getting Started Guide&lt;/a&gt; and the &lt;a href="https://age.apache.org/age-manual/master/index.html"&gt;Apache AGE Master Documentation&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>apacheage</category>
    </item>
    <item>
      <title>How to Install PostgreSQL and Apache AGE on MacOS</title>
      <dc:creator>Ken Woon</dc:creator>
      <pubDate>Thu, 23 Feb 2023 22:52:16 +0000</pubDate>
      <link>https://dev.to/xk_woon/how-to-install-postgresql-and-apache-age-on-macos-45m8</link>
      <guid>https://dev.to/xk_woon/how-to-install-postgresql-and-apache-age-on-macos-45m8</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;PostgreSQL is one of the world's most popular open-source relational database management systems. Its high scalability, reliability, and robustness have made it a top choice for enterprise-level applications. Apache AGE is an extension of PostgreSQL that brings graph database features to the table. While they are available on various operating systems, getting started on a Mac can be challenging for some. In this blog post, I will provide you with a step-by-step guide on how to download and compile PostgreSQL and Apache AGE on MacOS, so you can start using this powerful database system for your projects. Whether you're a beginner or an experienced developer, this guide will help you get started with PostgreSQL and AGE on your Mac. So, let's dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-Installation Procedure
&lt;/h2&gt;

&lt;p&gt;1. Before following the process, make sure Xcode is installed, which can be downloaded for free from the Mac App Store. This provides the necessary development tools and libraries required for building PostgreSQL.&lt;br&gt;
&lt;a href="https://media2.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%2Fxthkqwmhj9bniykcdpq7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fxthkqwmhj9bniykcdpq7.png" alt=" " width="800" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2. After installing Xcode, install Homebrew, a package manager that allows easy installation and management of software packages, by running the following command on Terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3. Install the GCC library which is necessary for compiling PostgreSQL:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;4. Install Git, a version control system that developers use to manage source code changes. You will need this to pull the source codes from GitHub. Run the command on Terminal:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;It should prompt you to install it if Git is not already installed.&lt;/p&gt;

&lt;p&gt;By completing these pre-installation procedures, you'll have everything you need to install and compile PostgreSQL on your Mac. Let's move on to the next steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing PostgreSQL
&lt;/h2&gt;

&lt;p&gt;In this section, I will guide you through the installation process of PostgreSQL on your MacOS device, step-by-step. From cloning the PostgreSQL repository from GitHub to starting the database server and writing PostgreSQL commands. The following commands are all used inside the Terminal.&lt;/p&gt;

&lt;p&gt;1. Change the directory to where you want to install Postgres. I will use my desktop for this tutorial.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;2. Create a directory and name it whatever you like.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;3. Head to the newly created directory.&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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4. Clone the PostgreSQL repository from GitHub.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;5. After it is finished, go to the postgresql folder inside your current directory.&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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;br&gt;
If you would like to use a different version of PostgreSQL (for instance if you want to use Apache AGE that currently only supports versions 11 and 12), follow these steps. If you are fine using the latest version, skip to step 8.&lt;/p&gt;

&lt;p&gt;6. &lt;code&gt;git branch -a&lt;/code&gt; will show a list of branches for the PostgreSQL repo. The format should look like &lt;code&gt;remotes/origin/{release version}&lt;/code&gt;. Copy the &lt;code&gt;{release version}&lt;/code&gt; part of your desired version. I will be using the &lt;code&gt;REL_12_STABLE&lt;/code&gt; branch for this tutorial.&lt;/p&gt;

&lt;p&gt;7. Navigate to the desired branch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout REL_12_STABLE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;8. Run the configure query from the folder. The &lt;code&gt;/usr/local/pgsql&lt;/code&gt; can be replaced with any directory of your choice. Later when compiling your code, it will be directed to install your binary files in that specific directory.&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 --enable-cassert --enable-debug CFLAGS="-glldb -ggdb -O0 -g3 -fno-omit-frame-pointer"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The options and flags &lt;code&gt;--enable-cassert --enable-debug CFLAGS="-glldb -ggdb -Og -g3 -fno-omit-frame-pointer&lt;/code&gt; are required if you need to use debugging tools for development.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This command will generate all the make files for you. If there are any messages saying that a certain library is missing, go ahead and install them using Homebrew, replacing &lt;code&gt;{library name}&lt;/code&gt; with the name of the library required: &lt;code&gt;brew install {library name}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;9. Run the following command to compile the PostgreSQL. &lt;code&gt;-j12&lt;/code&gt; is an option to compile the code in parallel using multiple cores, in this case, 12 cores. You can change the number to however many cores you have/like.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This process will take a while.&lt;/p&gt;

&lt;p&gt;10. Make a directory at the same location specified during the &lt;code&gt;./configure&lt;/code&gt; command. For this example, it would be &lt;code&gt;/usr/local/pgsql&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;sudo mkdir /usr/local/pgsql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;sudo&lt;/code&gt; grants administrative privileges. It should prompt you with a password. Go ahead and enter your computer admin user password and hit enter.&lt;/p&gt;

&lt;p&gt;11. Change the owner of the directory to give permission for the current user to configure the directory. Make sure to change &lt;code&gt;{user name}&lt;/code&gt; to your own.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo chown {user name} /usr/local/pgsql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;12. The files are now ready to be installed using:&lt;br&gt;
&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;13. The next step will be to set the path. Again, the path will depend on the directory you have set previously. Locate the &lt;code&gt;/bin/&lt;/code&gt; folder in your specified path.&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/bin/:$PATH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;14. To specify where you want to create your cluster, use the following command, using any directory you like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export PGDATA=/usr/local/pgsql/bin/data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;15. Initialize your cluster:&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;16. To start the database server and provide the log file:&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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;17. Run the following to complete the installation and start writing in PostgreSQL:&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;If you would like to get out of writing PostgreSQL commands, type &lt;code&gt;\q&lt;/code&gt;. Stop the PostgreSQL server using:&lt;br&gt;
&lt;code&gt;pg_ctl stop -l log&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Congratulations! You have successfully installed PostgreSQL on your MacOS device. With PostgreSQL installed, you can now start building robust and scalable databases for your applications.&lt;/p&gt;
&lt;h2&gt;
  
  
  Installing Apache AGE
&lt;/h2&gt;

&lt;p&gt;Now it is time to move on to Apache AGE. Installing it might seem a bit intimidating, but fear not, as I will guide you through it. In this section, I will walk you through the installation procedure for Apache AGE on your MacOS.&lt;/p&gt;

&lt;p&gt;1. Change the directory to where you want to install AGE. I will use my desktop for this tutorial.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;2. Create a directory and name it whatever you like.&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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3. Head to the newly created directory.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;4. Clone the AGE repository from GitHub.&lt;br&gt;
&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
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;5. After it is finished, go to the age folder inside your current directory.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;6. Navigate to the &lt;code&gt;AGE_PG12.1.0_ALPHA&lt;/code&gt; branch which is compatible for PostgreSQL version 12. &lt;strong&gt;This step can be skipped if you have PostgreSQL version 11 installed.&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;git checkout AGE_PG12.1.0_ALPHA
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;7. In order to compile and install AGE in the specified version of your Postgres, you will need to pass &lt;code&gt;pg_config&lt;/code&gt; inside the bin folder of your installed PostgreSQL directory to 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;sudo make PG_CONFIG=/usr/local/pgsql/bin/pg_config install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should prompt you with a password. Go ahead and enter your computer admin user password and hit enter. Run &lt;code&gt;installcheck&lt;/code&gt; if you would like to run regression tests. There will be an error but it can be ignored.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;make PG_CONFIG=/usr/local/pgsql/bin/pg_config installcheck
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;8. Go back to your installed PostgreSQL directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /usr/local/pgsql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;9. Initialize a database with a name of your choice. I will name this database &lt;code&gt;test&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;bin/initdb test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;10. Before starting the database, there are some options that have to be configured. Use the text editor in Terminal to edit the &lt;code&gt;postgresql.conf&lt;/code&gt; file with the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vim test/postgresql.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The PostgreSQL configuration file should appear.&lt;/p&gt;

&lt;p&gt;11. While in the configuration file, type &lt;code&gt;/port&lt;/code&gt; and hit enter. It should bring you to the line that says &lt;code&gt;#port = 5432&lt;/code&gt;. Press the 'i' key on your keyboard to enter INPUT mode, then delete the &lt;code&gt;#&lt;/code&gt;. Change the port number if you would like to (you might have to change it if there is another instance of server running on the same port). Take note of this port number for later use. Hit 'ESC' to exit INPUT mode.&lt;/p&gt;

&lt;p&gt;12. While in the configuration file, type &lt;code&gt;/preload&lt;/code&gt; and hit enter. It should bring you to the line that says &lt;code&gt;#shared_preload_libraries = ''&lt;/code&gt;. Press the 'i' key on your keyboard to enter INPUT mode, then add in the word &lt;code&gt;age&lt;/code&gt; between the apostrophes. It should look like &lt;code&gt;#shared_preload_libraries = 'age'&lt;/code&gt;. Hit 'ESC' to exit INPUT mode.&lt;/p&gt;

&lt;p&gt;13. While in the configuration file, type &lt;code&gt;/search&lt;/code&gt; and hit enter. It should bring you to the line that says &lt;code&gt;#search_path = '"$user", public'&lt;/code&gt;. Press the 'i' key on your keyboard to enter INPUT mode, then add in the phrase &lt;code&gt;ag_catalog,&lt;/code&gt; before the &lt;code&gt;"$user"&lt;/code&gt;. It should look like &lt;code&gt;#search_path = 'ag_catalog, "$user", public'&lt;/code&gt;. Hit 'ESC' to exit INPUT mode.&lt;/p&gt;

&lt;p&gt;14. While in the configuration file, type &lt;code&gt;:wq&lt;/code&gt; to save and exit the document.&lt;/p&gt;

&lt;p&gt;15. Now, start the database server using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bin/pg_ctl -D test -l logfile start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;16. Create the database with the same port number from the configuration file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bin/createdb --port=5432 test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;17. Open a command line to the database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bin/psql --port=5432 test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now have an interface with the database that allows you to enter SQL commands.&lt;/p&gt;

&lt;p&gt;18. Create the AGE extension and load it during the first time you set up the database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE EXTENSION age;
SET search_path TO ag_catalog;
LOAD 'age';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Age is now installed into PostgreSQL. You are now able to enter Cypher queries into SQL commands.&lt;/p&gt;

&lt;p&gt;Exit the interface with &lt;code&gt;\q&lt;/code&gt; and shut the server down with &lt;code&gt;bin/pg_ctl -D test -l logfile stop&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Congratulations! Now that you have successfully installed Apache AGE, you can start using it to work with your PostgreSQL database. AGE brings in a whole new level of flexibility and performance to your database queries, making it an indispensable tool for big data analytics and real-time data processing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;Now that you have installed PostgreSQL and Apache AGE on your MacOS device, you may be wondering what's next. Here are a few resources and the next steps to help you continue your journey:&lt;/p&gt;

&lt;p&gt;PostgreSQL documentation: The PostgreSQL documentation provides comprehensive information on using and managing PostgreSQL. It is a valuable resource for learning about PostgreSQL's features and functionalities. You can access the documentation at &lt;a href="https://www.postgresql.org/docs/" rel="noopener noreferrer"&gt;https://www.postgresql.org/docs/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;PostgreSQL tutorial: If you're new to PostgreSQL, you can take a look at the PostgreSQL tutorial to learn the basics of PostgreSQL. You can access the tutorial at &lt;a href="https://www.postgresqltutorial.com/" rel="noopener noreferrer"&gt;https://www.postgresqltutorial.com/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Apache AGE documentation: The Apache AGE documentation provides various guides on how to utilize the tool to its fullest. There are information about clauses, functions, and using Cypher in SQL. You can access the documentation at &lt;a href="https://age.apache.org/age-manual/master/index.html" rel="noopener noreferrer"&gt;https://age.apache.org/age-manual/master/index.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I hope these resources and the next steps will help you to continue your data analysis journey. Good luck, and happy Postgres-ing!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post is written based on a webinar held by Bitnine and &lt;a href="https://youtu.be/0-qMwpDh0CA" rel="noopener noreferrer"&gt;this video guide by Bitnine&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>mentorship</category>
      <category>discuss</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
