Skip site navigation (1) Skip section navigation (2)

Peripheral Links

Header And Logo

PostgreSQL
| The world's most advanced open source database.

Site Navigation

Search archives
  Advanced Search

Re: could not load library; undefined symbol: itoa




On Apr 21, 2009, at 12:08 PM, bence(at)net(dot)info(dot)hu wrote:

Hi!

I' have tried to add a C language function called 'djb_hash' to my databse. It accepts a 32 chars length text as input, and returns a ten chars length
numeric string.
It implements the 'djb_hash' string hash algorithm, wich unfortunetly returns unsigned int type, so a I had to write it as a C language function. So I had to convert the return value to text. I used to compile it with MinGW
and used it on Windows, but now I'd like to use on Linux (Ubuntu 9.04,
PostgreSQL 8.3).

Hm.. you can use a built-in bigint datatype if integer range is not sufficient for you. Of course C would give you a faster implementation then pl/pgsql or any other pl language, but it is a more complex one.


When I was trying to compile, I ran into numerous errors that concerned
type definitions in the headrs (postgres.h, fmgr.h, c.h). The point is
I have changed the 'varlena' definition in the 'c.h' (the vl_len_ is now
int)

I think this is the wrong way to deal with that errors. You shouldn't modify postgres headers for the addon function.

Now I have successfully complied, but I can't add it because it
complains about:

undefined symbol: itoa


itoa is a non-standard function and AFAIK is missing in glibc. Use sprintf instead.


Here is the definition of the function:
#include <math.h>
#include <string.h>
#include "/usr/include/postgresql/8.3/server/postgres.h"
#include "/usr/include/postgresql/8.3/server/fmgr.h"

The latest 2 should be

#include "postgres.h"
#include "fmgr.h"

before including all other files. I recommend you either use -I/path/ to/server/includes or use PGXS as described here:
http://www.postgresql.org/docs/8.3/interactive/xfunc-c.html#DFUNC

Also, you shouldn't deal with varlena attributes, like vl_len_ directly. Instead, use textin to convert you result from char * to the text type on exit, i.e with the following macro:

#define GET_TEXT(cstrp) DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(cstrp)))
It will return the value of text * for you.



#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

PG_FUNCTION_INFO_V1(djb_hash);
Datum
djb_hash(PG_FUNCTION_ARGS)
{
	char buffer[32];
	char output[11];
	char* str;
	text *szoveg = PG_GETARG_TEXT_P(0);
	text *hash_text = (text*) palloc(VARHDRSZ+10);
	hash_text->vl_len_ = VARHDRSZ+10;


	unsigned int hash = 5381;
	unsigned int i = 0;
	unsigned int number = 0;


	memcpy(buffer,szoveg->vl_dat,32);
	str = &buffer[0];


	for(i=0; i<32; str++, i++)
	{
	   hash = ((hash << 5) + hash) + (*str);
	}

	str = &output[0];
	number = hash/pow(10,9);

	if(number != 0)
	{
		hash = hash - number*pow(10,9);
		(*str) = '0'+ number;
	}
	else
	(*str)='0';

	str++;

	for(i=8;str;str++,i--)
	{
		number = 0;
		number = hash/pow(10,i);

		if (number == 0)
			(*str) = '0';

		else
		{
			itoa((int)hash, str, 10);
			break;
		}
	}

	memcpy(hash_text->vl_dat,output,10);

	PG_RETURN_TEXT_P(hash_text);
}

I probably missed something. So any idea would be helpful.
Thanks in advance.


--
Alexey Klyukin       http://www.CommandPrompt.com
The PostgreSQL Company - Command Prompt, Inc.




Home | Main Index | Thread Index

Privacy Policy | About PostgreSQL
Copyright © 1996 – 2012 PostgreSQL Global Development Group