Thursday, April 2, 2015

Extending PostgreSQL with own C functions

Power of open source, if you are not happy with what PostgreSQL currently offers, you write own extension in C. Compile code with your functions into shared library, install it and they will become available from PostgreSQL. OK there are some rules and procedures. Once we are inside PostgreSQL we are using its types, interfaces and utilities. Let us do Hello World example. To build example you will need postgresql-server-dev-9.1 or whatever version you are using, installed on your Linux box.


As we can see we are using new V1 spec. That is modified concat_text example from PostgreSQL documentation, look for 35.9.4. Version 1 Calling Conventions. We have load of different VAR macros. For example:

VARHDRSZ is the same as sizeof(int4), but it's considered good style to use the macro VARHDRSZ to refer to the size of the overhead for a variable-length type.

That is from PostgreSQL documentation. SET_VARSIZE we can find in includes postgres.h


Unless you are on big endian. Going through header file one also can read in comments more about Datum and varlena datatypes. Then we got palloc which corresponds to malloc, memcpy you already know and GET and RETURN macros. It is obvious that for writing extensions one needs to familiarize himself with PostgreSQL internals. Power without knowledge and responsibility exists only in fery tails told by “software evangelists” at annual developers developers developers meetings.
Variables passed around by PostgreSQL may be on the disc, do not change them.
To build shared library I used the following Makefile:


Rather long story to get location of pgxs. That pgxs is location of makefiles for building extensions. It is not trivial build and using provided mk files is right way to do it. After that we can copy say_hello.so to some reasonable location or give full path to it in create function declaration.


PostgreSQL already allows Python through untrusted language PL/Python. One can utilize power of Python for functions or triggers without learning much about PostgreSQL internals. But again if you need power and speed, you can use what PostgreSQL speaks internally and that is C.

Wednesday, April 1, 2015

SQLite parameterized query in C

Still very angry at Discovery Health but that is not reason to stop using C. To execute parameterized query we prepare SQL statement with one or more placeholders. Placeholder could be question mark, alone or followed by number, column, dollar sign or at sign followed by alphanumeric. For example:

select title, full_name from jane where id = @id;

We prepare such statement using sqlite3_prepare_v2, later we bind our parameter and finally execute query. To do binding we will use appropriate function, there is few of them:


All bind functions will return SQLITE_OK if binding is successful or error code if it fails. The first argument is handle to prepared statement. The second argument is index of parameter. The third argument is value to be set. For blob, text we have the fourth argument, size in bytes and the fifth – destructor function. Instead of destructor function we can pass constants SQLITE_STATIC - do nothing or SQLITE_TRANSIENT – make local copy and free it when done. To find out what is index of parameter we are using this function:

int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName);

We pass prepared statement and parameter name it returns zero if there is no such parameter or parameter index if it exists. Even if we know that our parameter must have index one, we will still look for it to demonstrate how it is done. Here is the code:


Database should be loaded with required values in previous examples, if not here is sql to create it:

CREATE TABLE jane ( id INTEGER PRIMARY KEY NOT NULL, title TEXT, full_name TEXT NOT NULL )
INSERT INTO jane VALUES(1,'Mr','Smith');
INSERT INTO jane VALUES(2,'Mrs','Doe');
INSERT INTO jane VALUES(3,'Mr','Doe');


After we build it using:

gcc -g test.c -lsqlite3 -o test

We execute test and see the following output:


We could also misspell parameter name and rebuild to check is error handling working.

Tuesday, March 31, 2015

PostgreSQL, libpqxx and prepared statement example

As I promised, if people are finding interesting introductory article,  I will write more about PostgreSQL and libpqxx. But before I start with programming – rant.
I am still looking for work and finding none. Today went to Discovery Health, had very pleasant 45 minutes chat with their architect and BA and promise that we will talk again. Later guy from employment agency, who arranged meeting, calls and says that they do not want me since I do not have ANSI C in CV?! Like somebody from management decided to override decision of interviewers. If ANSI C in CV is precondition, why they wasted my time and invited me for interview? I wish them the same from their customers. BTW I am usually employed as senior developer and not as C developer or, Perl developer.
Back to programming, this time C++, had enough of ANSI C for today. Environment is Linux, I am using the same PostgreSQL and libpqxx as last time and to compile example we will use:

g++ hello_prep.cxx -o hello_prep -I/usr/local/include/ -lpqxx -lpq


This time I used test092.cxx, run dpkg with -L switch on libpqxx3-doc to see where is it. It tests passing binary parameter to prepared statement. Test macros are replaced with printing of tested values to standard output and setup of connection/transaction is included. Here is the code:


After connection is successfully obtained, transaction T is constructed. Temp table is created and after confirmation that prepared statements are supported, testing goes on. We have prepare::declaration and prepare::invocation, available in reference generated with doxygen. Adding parameters is in iterative fashion and feels natural, as they say in documentation like varargs from C. Library is well designed and easy to use, documentation, tutorial and tests are supplied. Lengths and contents should match and test succeeds.

Sunday, March 29, 2015

SQLite C API another convenience routine example

Last time we presented sqlite3_exec example. Beside sqlite3_exec we can use wrapper around  sqlite3_exec and that is sqlite3_get_table. We will get, if call is successful, array of UTF-8 zero terminated strings and we have to free that array at the end. Here is interface for sqlite3_get_table and sqlite3_free_table:


It is quite self-explanatory. Number of rows doesn't count column names and we need to add one to it. Cleanup is required in the any case, if all is ОК we need to call sqlite3_free_table, if there is failure we need to do cleanup of error message, like with  sqlite3_exec. We will retrieve content of that jane table from sqlite3_exec example, then we inserted three rows into table. Here is the code:


Very simple and very user friendly API. If we build and execute binary, we should get error:

Get table failure: no such table: jane

Our table is in surogat.db, we repair example, recompile and we should see table printout:


That is legacy interface and usage is not recommended, though it is very user friendly and that is the reason I supplied example.
As usual, example is built on Linux using gcc and successfully tested. Didn't try on different OS or compiler.

Tests, pointers, arrays and GDB

While I was looking for work, actually I am still looking for work, they sent me to do some tests. Those are some “tech check” rubbish tests which are testing how much of man pages you know by hart. Not do you have logic of programmer and real working knowledge but how well have you memorized help files. So let me explain how you are going to deal with those test and real life problems in sensible way. While agile approach is very desirable in project management, memorizing help files is what industry expects from programmers. Everything further happens on Linux and we will do some debugging to find out answers.
About every book teaching C contains story how one can declare array and access array elements via pointer arithmetic. Something like this:


Expression *arr1d+i is not really pointer arithmetic since dereferencing will happen before addition, and everybody who worked in C longer than two weeks knows it, but it will also produce desired result. I also omitted array length and gcc managed to read it from initializer. Now we can declare some pointers and assign address of our array to them.


Array is just pointer to its first element, we got type and everything right. If we now take address of array we will have double pointer? Not really.


Produces this warning:

warning: initialization from incompatible pointer type [enabled by default]

Since we do not know what is wrong, what type for pointer to array we are getting instead double pointer to integer, we will ask GDB. This is the code:



and we will save it as untitled.c and build using

gcc -g -Wall -o untitled untitled.c
untitled.c: In function ‘main’:
untitled.c:12:16: warning: initialization from incompatible pointer type [enabled by default]
untitled.c:13:7: warning: unused variable ‘p1d11’ [-Wunused-variable]
untitled.c:12:8: warning: unused variable ‘p1d12’ [-Wunused-variable]

This is together with output. Switch -g means that we want debugg info and -Wall that we want all warnings. Now we start interactive session and ask GDB what we want to know:


It printed few lines of messages about license, where to report bugs and similar and loaded symbols for untitled. On prompt (gdb) we type in start and it starts and breaks on the first possible line. We try info locals and see that array is not initialized yet, so we execute next. Now array is initialized and we print it. Finally we ask it to print &arr1d and we learn what is the type of our “double pointer”.


This is what address of array returns and how “double pointer” should be declared, really ugly question on some idiotic test.
Things are becoming more interesting with multidimensional arrays. For example:

int arr2d[][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}};

We can not omit everything even if we are supplying initializer, just the first square bracket may be empty. How about asking some questions? Start GDB session and ask all what you need to know:


Simple as that. There is one more question left, what will happen with double pointer initialized to address of array, why it not working? Again we are agile and write code:


That will execute and print *p = 1?! Start GDB session and check what is happening:


Abbreviated print is p and x will print content of memory at some address. Array is not just pointer, there is size of it what counts. If we have used ld format in printf, we would see slightly bigger output than just one ;-)
That would be such lovely question for test, what would be output if we replace %d with %ld? Naturally it will be *p = 8589934593!
Ask yourself stupid questions for fun and for profit.

Saturday, March 28, 2015

More SQLite C API

In previous instalment we used sqlite3_open and sqlite3_prepare to connect to db file and execute select statement. Let us take a better look at it again. Those functions are legacy interface, we could use new sqlite3_open_v2 and sqlite3_prepare_v2 which are allowing us more control over execution and they are also recommended by SQLite development team. Let us look at sqlite3_open. This is from SQLite documentation:


In all three cases, the first argument is name of database file to be opened and the second one is handle:

typedef struct sqlite3 sqlite3;


We will need that handle to manipulate db and close it at the end. From comment we see that string with name of db file could be UTF-8 or UTF-16 encoded. What are flags? Here are definitions:


I will wisely skip last four, for now. If we specify SQLITE_OPEN_READWRITE we should be able to read and write, unless OS have marked file as read only, file must exist or error is returned. In order to simulate behavior of sqlite3_open we should use  SQLITE_OPEN_READWRITE |  SQLITE_OPEN_CREATE. The fourth argument of sqlite3_open_v2 function is name of the sqlit3_vfs object that defines the operating system interface that the new database connection should use. If we pass NULL as the fourth argument we get default sqlit3_vfs object.
If  sqlite3_open_v2 doesn't return SQLITE_OK, we have error and we should exit. We still may have proper db handle or NULL handle, calling sqlite3_close with NULL pointer is not problem.
So, we have something like this as template:


Call to sqlite3_errmsg should return string with description of message. We want to do resource management and to match  sqlite3_open with sqlite3_close. If we compile this and we do not have some.db file, after execution we should see descriptive error message.

./test
Failure to open database: unable to open database file


While passing to sqlite3_close NULL pointer is not problem, passing to it handle of already closed connection is problem.
Situation with sqlite3_prepare_v2 is similar to  sqlite3_open_v2, new API is preferable to legacy one and it should be used. Here both new and legacy functions are accepting the same number of arguments but behavior is different. Please check in documentation how they differ.


There is also UTF-16 version with about the same arguments. It prepares statement, compiles it to bytecode  and if successful returns pointer to compiled  sqlite3_stmt.


After statement is successfully prepared we iterate using sqlite3_step and at the end we finalize statement. In the case of sqlite3_prepare  returning error, we in general want to check is statement handle points to something and do cleanup if it does.
There is convenience wrapper around  prepare_v2-step-finalize, it is sqlite3_exec.


If we are doing insert, we do not really need callback, so we pass NULL pointer as the third and fourth argument.


If we don't have table jane in test.db exec will return error.

Exec failure: no such table: jane

or if we execute it more than once:

Exec failure: PRIMARY KEY must be unique

Error message is allocated using sqlite3_malloc and we have to free it using sqlite3_free.

Friday, March 27, 2015

SQLite C API introduction

I guess you are already using some kind of Linux if you are reading this. Install SQLite libraries and dev libraries, on my box they are called libsqlite3-0 and libsqlite3-dev. On your Linux packages may be called slightly differently. For example if your distro is Debian based you will check for packages executing in terminal:

apt-cache search sqlite

You do not need elevated privileges to execute that.
Also install sqlite3 command line interface for SQLite 3.
SQLite is embedded relational database engine. It was popular before but then Android made it part of OS and now it is like totally popular. There is no server and consequently no SQLite database administrator.
In order to build examples we need to specify linker switch, like this:

gcc testme.c -lsqlite3 -o test

Everything should be in path. Also we need to include appropriate header file in example:


We open database file, if it doesn't exist it will create it, if it can't we report error and exit. Next, we prepare statement, using legacy interface, and again check for error. Function sqlite3_step evaluates prepared statement, similarly we retrieve some metadata and print that to standard output.
Before we run example we will create table so that we can show some kind of output from our program. All that in the same folder where is binary, so that we don't have to fiddle with full path.



Now we can run our test program and see output like this.

type    name    tbl_name    rootpage    sql   
------------------------------------------------------
table    jane    jane    2    CREATE TABLE jane ( id INTEGER PRIMARY KEY NOT NULL, title TEXT, full_name TEXT NOT NULL )   


That was simple connect to database and select, there will be more in next instalment.