Creating an extension test in postgresql

2019-03-22 04:51发布

问题:

I want to create an extension test in postgres (Using PostGis), so I want to do the following steps:

1.- Edit the file btree_interval.c from btree_gist in this way:

gbt_intvkey_cmp(const void *a, const void *b)
{
    intvKEY    *ia = (intvKEY *) (((const Nsrt *) a)->t);
    intvKEY    *ib = (intvKEY *) (((const Nsrt *) b)->t);
    int         res;
  ......
  ......

  printf("Test for PostGis\n");

    return res;
}

Only add a printf, because I just want to do a little test

2.- Run the following command:

gcc -shared -o btree_gist_test.so -fPIC btree_gist.c

My doubts are:

1.- I don't know where I can find the file btree_gist.c once postgresql is installed and then run the command above.

If you ask me: 'Why don't just you do that downloading the source code?' Well, because When I did, I got this error message:

 #include "postgres.h"
                      ^
compilation terminated

So, I thought that it's better do it in the same folder where postgresql is already installed.

2.- Once I get the btree_gist_test.so I know that I have to copy to the path /usr/lib/postgresql/lib/, but I'm not sure if I have to create a symbolic link to a somewhere else for this file.

回答1:

This is a minimal example that works if you have the postgresql-server development package for ubuntu installed

extension.c
A simple extension

/* Postgres headers */
#include <postgres.h>
#include <utils/rel.h>

#include <stdio.h>
#include <string.h>

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

static char *
extract_string(text *word)
{
    char *head;
    char *tail;

    if (word == NULL)
        return NULL;

    head = VARDATA(word);
    tail = head + VARSIZE(word) - VARHDRSZ;
    tail[0] = '\0';

    return head;
}

PG_FUNCTION_INFO_V1(compare_strings);
Datum
compare_strings(PG_FUNCTION_ARGS)
{
    char *lhs;
    char *rhs;

    lhs = extract_string(PG_GETARG_TEXT_P(0));
    rhs = extract_string(PG_GETARG_TEXT_P(1));

    PG_RETURN_BOOL(strcmp(lhs, rhs) == 0);
}

Makefile
A simple Makefile to illustrate how you could build the extension.

CC     = gcc
OBJECT = extension.o
NAME   = my-extension.so
CFLAGS = -Wall -Werror -g3 -O0 -I$(shell pg_config --includedir-server)

all: $(OBJECT)
    $(CC) -shared -o $(NAME) $(OBJECT)

%.o: %.c
    $(CC) -c -fPIC $(CFLAGS) $<

install: all
    @install -Dv -m755 $(NAME) $(shell pg_config --pkglibdir)/$(NAME)
    @psql -U postgres -f create-function.sql

clean:
    @rm -fv *.o *.so

create-function.sql
A simple script to create the function

CREATE OR REPLACE FUNCTION 
    compare_strings(VARCHAR,VARCHAR) RETURNS integer AS 'my-extension' 
LANGUAGE C STRICT;

As it seems from your question, you will be able to understand what this does and also how to make it work for your use case.



回答2:

There are two ways to compile most extensions:

In the PostgreSQL source tree, if you've compiled PostgreSQL in that source tree:

  • cd to the extension directory
  • make there
  • make install

... or, if the extension is not directly inside the source tree for PostgreSQL or you want to use it with a different PostgreSQL install, use PGXS.

Assuming that you're using binary packages:

  • Make sure that the directory containing pg_config is on your PATH environment variable
  • make USE_PGXS=1
  • if that succeeds, sudo make USE_PGXS=1 install

For more information:

  • pgxs and extension building infrastructure
  • compiling PostgreSQL
  • extensions