Write a Postgresql proxy. The Beginning.

siscia_

Simone Mosciatti

Posted on May 14, 2019

Write a Postgresql proxy. The Beginning.

This series of articles will follow my progress in creating a RediSQL proxy for Postgres, pg-redis-proxy.

The end goal of this project is to have a proxy that will listen to the PG protocol, forward the queries to RediSQL, and finally return the answer to the original client.

If the project is successful I hope to integrate the code into RediSQL itself, so to provide another interface for RediSQL, not just the Redis protocol but also — directly — the PG protocol.

Caveats

The abstraction I am going to build will definitely be a leaky one.

Indeed SQLite (on which is based RediSQL) does not support a lot of features of PG. Classical examples are all the DATE datatypes that are not supported in SQLite.

However I still feel it may be useful and fun to build.

Approach

Ideally I would like to have the code merge into the main RediSQL, this would definitely suggest to code it in Rust.

But Rust is a “production” language.

At least in my experience, you need to have a quite good understanding of the problem and of the design before to successfully code something in Rust.

Moreover, there is this old expression in programming that suggest to plan for at least one prototype that you will eventually throw away and re-write from scratch.

Indeed I am not so sure of the whole architecture and of the problem I will be facing while writing this proxy.

The first version of pg-redis-proxy will be written in Python3.

The goals of the Python version

The goals of the first python version are:

  1. Get to know the PG protocol
  2. Quickly explore several possible architecture
  3. Provide some open source libraries and guidance for other that wants to explore a similar project

I will stop developing the project when it will be possible to execute a simple SQL file against an instance of pg-redis-proxy and have it return the expected result.

The SQL file I am aim to is something like:

CREATE TABLE foo(a INT, b INT, c INT);
INSERT INTO foo VALUES(1,2,3);
PREPARE insertfoo (int, int, int) AS
    INSERT INTO foo VALUES($1, $2, $3);
EXECUTE insertfoo(5,6,7);
INSERT INTO foo VALUES(4,5,6);
EXECUTE insertfoo(8,9,0); 

SELECT * FROM foo;

I am not aiming to code anything more than what is extremely strictly necessary, but I will be extremely open to accept pull requests.

Hence if you are interesting in the project, or in piece of the project, feel free to contribute in the repository.

The repo

You can follow the progress on this github repository.

Finally, if you are interested in following this project you can either follow me on twitter or subscribe to the mail-list in the original blog.

💖 💪 🙅 🚩
siscia_
Simone Mosciatti

Posted on May 14, 2019

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related