Thread: Add value in an Array
Hi all.
I am a french student working on a PostgreSQL database.
So i want to create a view which use a fonction (write in PLPGSQL) .
This function will take a colum from a table (the column is integer[] based) and add a value in the array.
So i dont find an operator to make this command.
Someone can help me ?
Best regards.
Jérôme Chochon
I'm writing additional C functions to extend PostgreSQL 7.2.1 on Red Hat Linux 7.3, a process whose details are apparently not well documented. I've got my first function written, using the functions in the source file numeric.c as a model. I tried compiling it using the advice offered by Bruce Momjian in his book (highly recommended), PostgreSQL: Introduction and Concepts: The next step is to compile the C file into an object file that contains CPU instructions. As part of this step, you must create a special object file that can be dynamically linked into the POSTGRESQL server. Many operating systems require special flags to create an object file that can be dynamically linked. The best way to find the required flags is to go to pgsql/src/test/regress and type make clean and then make regress.so. <a name="tex2html247" href="http://www.ca.postgresql.org/docs/aw_pgsql_book/footnode.html#foot21643">24.1 This command will display the compile commands used to generate the dynamically linkable object file regress.so. The -I compile flags allow searching for include files. Other flags are used for generating dynamic object files; use them to compile your C code into a dynamically linkable object file. You may need to consult your operating system documentation for assistance in locating the proper flags. This is where I'm stumped. make clean yields the error message "GNUmakefile:16: ../../../src/Makefile.global: No such file or directory". I then tried renaming the file Makefile.global.in to Makefile.global and running make clean again. This got a little farther but resulted in the message "../../../src/Makefile.global:269: ../../../src/Makefile.port: No such file or directory". I can't find a Makefile.port file anywhere. Any idea what I'm doing wrong? Thanks in advance for your guidance.
John Gunther <inbox@bucksvsbytes.com> writes: > Any idea what I'm doing wrong?<br> (a) you didn't run configure, which creates the files you are missing. (b) you posted HTML mail to the list. Please don't do that. regards, tom lane
Tom Lane wrote: >(a) you didn't run configure, which creates the files you are missing. > > Thanks, Tom. Your reply caused me to learn a lot about building PostgreSQL from source. Now I'm much further along: I have created a dynamic library (bvbpglib.so) containing one PostgreSQL C function (bvbpgsortword). This function calls a "regular" (non-PostgreSQL) C function (bvbmakesortstring). My current problem is that my psql statement: CREATE FUNCTION bvbpgsortword(TEXT) RETURNS TEXT AS '/usr/include/bvbpglib' LANGUAGE C WITH (ISSTRICT); fails with "undefined symbol: bvbmakesortstring" This is probably the result of some fundamental deficit in my understanding of C writing/compiling/linking, but what puzzles me is that bvbmakesortstring is called successfully from another C program I wrote. Only in psql does it come back undefined. Thanks. John Gunther For anyone is interested in enlightening me, relevant source follows: SOURCE FOR bvbpglib.c (used to create bvbpglib.so, contains PostgreSQL function bvbpgsortword): #include "postgres.h" #include "fmgr.h" #include <string.h> #include "bvblib.h" Datum bvbpgsortword(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(bvbpgsortword); Datum bvbpgsortword(PG_FUNCTION_ARGS){ //declarations char *bvbmakesortstring(const char *input, const int bitmodes, const unsigned short int minlength, const char *keeplist, const char *outdelim, const char *stoplist); text *instr = PG_GETARG_TEXT_P(0); text *outstr; unsigned int length; char *target; //code target=VARDATA(outstr); target = bvbmakesortstring(VARDATA(instr),1,0,"","}",""); length=strlen(target-1); target[length]=0; VARATT_SIZEP(outstr) = length + VARHDRSZ; PG_RETURN_TEXT_P(outstr); } SOURCE FOR test.c (this successfully calls bvbmakesortstring): #include <stdio.h> #include "bvblib.h" int /*function*/ main(){ printf("out=%s\n",bvbmakesortstring("test-mctöst'tëst",0,0,",","=","A")); return 0; } PARTIAL SOURCE FOR bvblib.c (this library contains bvbmakesortstring): #include <string.h> #include "bvblib.h" char bvbstr[65535]; char *bvbmakesortstring( const char *instr, const int bitmodes, const unsigned short int minlength, const char *keeplist, const char *outdelim, const char *stoplist ) {<code>... return bvbstr;//return the sort-ready string } SOURCE FOR bvblib.h: #ifndef BVBLIB_H /* has this been included */ #define BVBLIB_H /* if not say its been done once */ char bvbstr[65535]; char *bvbmakesortstring( const char *instr, //string to be processed const int bitmodes, const unsigned short int minlength, //words shorter than this are ignored const char *keeplist, //chars to be kept in output words const char *outdelim, //char string to use as word delimiter const char *stoplist //space-separated words to be ignored ); #endif /* end the #ifndef construct */
P.S. I forgot to supply the commands I used to compile and link my bvbpglib.so library: gcc -O2 -march=i386 -mcpu=i686 -Wall -Wmissing-prototypes -Wmissing-declarations -fpic -I/usr/src/redhat/BUILD/postgresql-7.2.1/src/interfaces/libpq -I/usr/src/redhat/BUILD/postgresql-7.2.1/src/include -I/usr/kerberos/include -c -o bvbpglib.o bvbpglib.c gcc -shared -o /usr/include/bvbpglib.so bvbpglib.o John G John Gunther wrote: > Tom Lane wrote: > >> (a) you didn't run configure, which creates the files you are missing. >> >> > Thanks, Tom. Your reply caused me to learn a lot about building > PostgreSQL from source. > > Now I'm much further along: I have created a dynamic library > (bvbpglib.so) containing one PostgreSQL C function (bvbpgsortword). > This function calls a "regular" (non-PostgreSQL) C function > (bvbmakesortstring). > > My current problem is that my psql statement: > CREATE FUNCTION bvbpgsortword(TEXT) RETURNS TEXT AS > '/usr/include/bvbpglib' LANGUAGE C WITH (ISSTRICT); > fails with "undefined symbol: bvbmakesortstring" > > This is probably the result of some fundamental deficit in my > understanding of C writing/compiling/linking, but what puzzles me is > that bvbmakesortstring is called successfully from another C program I > wrote. Only in psql does it come back undefined. > > Thanks. > > John Gunther > > For anyone is interested in enlightening me, relevant source follows: > > SOURCE FOR bvbpglib.c (used to create bvbpglib.so, contains PostgreSQL > function bvbpgsortword): > #include "postgres.h" > #include "fmgr.h" > #include <string.h> > #include "bvblib.h" > Datum bvbpgsortword(PG_FUNCTION_ARGS); > PG_FUNCTION_INFO_V1(bvbpgsortword); > Datum bvbpgsortword(PG_FUNCTION_ARGS){ > //declarations > char *bvbmakesortstring(const char *input, const int bitmodes, > const unsigned short int minlength, const char *keeplist, const char > *outdelim, const char *stoplist); > text *instr = PG_GETARG_TEXT_P(0); > text *outstr; > unsigned int length; > char *target; > //code > target=VARDATA(outstr); > target = bvbmakesortstring(VARDATA(instr),1,0,"","}",""); > length=strlen(target-1); > target[length]=0; > VARATT_SIZEP(outstr) = length + VARHDRSZ; > PG_RETURN_TEXT_P(outstr); > } > > SOURCE FOR test.c (this successfully calls bvbmakesortstring): > #include <stdio.h> > #include "bvblib.h" > int /*function*/ main(){ > > printf("out=%s\n",bvbmakesortstring("test-mctöst'tëst",0,0,",","=","A")); > return 0; > } > > PARTIAL SOURCE FOR bvblib.c (this library contains bvbmakesortstring): > #include <string.h> > #include "bvblib.h" > char bvbstr[65535]; > char *bvbmakesortstring( > const char *instr, > const int bitmodes, > const unsigned short int minlength, > const char *keeplist, > const char *outdelim, > const char *stoplist > ) > {<code>... > return bvbstr;//return the sort-ready string > } > > SOURCE FOR bvblib.h: > #ifndef BVBLIB_H /* has this been included */ > #define BVBLIB_H /* if not say its been done once */ > char bvbstr[65535]; > char *bvbmakesortstring( > const char *instr, //string to be > processed > const int bitmodes, > const unsigned short int minlength, //words shorter than this > are ignored > const char *keeplist, //chars > to be kept in output words > const char *outdelim, //char > string to use as word delimiter > const char *stoplist > //space-separated words to be ignored > ); > #endif /* end the #ifndef construct */ > > > > ---------------------------(end of broadcast)--------------------------- > TIP 2: you can get off all lists at once with the unregister command > (send "unregister YourEmailAddressHere" to majordomo@postgresql.org) >
John Gunther <inbox@bucksvsbytes.com> writes: > Now I'm much further along: I have created a dynamic library > (bvbpglib.so) containing one PostgreSQL C function (bvbpgsortword). This > function calls a "regular" (non-PostgreSQL) C function (bvbmakesortstring). > My current problem is that my psql statement: > CREATE FUNCTION bvbpgsortword(TEXT) RETURNS TEXT AS > '/usr/include/bvbpglib' LANGUAGE C WITH (ISSTRICT); > fails with "undefined symbol: bvbmakesortstring" > This is probably the result of some fundamental deficit in my > understanding of C writing/compiling/linking, but what puzzles me is > that bvbmakesortstring is called successfully from another C program I > wrote. Only in psql does it come back undefined. You have to make sure that the dynamic linker knows where to find the library that contains bvbmakesortstring --- when one .so file depends on another, the first one needs to be explicitly marked that way. I think it would work to mention the other .so file as a library in the link command for bvbpglib.so. Try "ldd" on bvbpglib.so to see which libraries it's marked as needing, and whether the dynamic linker knows where to find them. regards, tom lane
Tom Lane wrote: >I think it would work to mention the other .so file as a library in >the link command for bvbpglib.so. > > Thanks again Tom. That did the trick for getting CREATE FUNCTION to complete. Sorry to be such a pain folks, but please be patient or just ignore me. I now have what appears to be a C function extension to PostgreSQL, but it's not returning any visible value, most likely because my C code isn't doing what I want it to. Here's a trivial version of the function -- all I want it to do is return "abcdef", regardless of the input received. #include "postgres.h" #include "fmgr.h" #include <string.h> Datum bvbpgsortword(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(bvbpgsortword); Datum bvbpgsortword(PG_FUNCTION_ARGS){ //declarations text *instr = PG_GETARG_TEXT_P(0); text *outstr; //code memcpy(outstr,"abcdef",6);//needed to move data from char constant to pg's text type? VARATT_SIZEP(outstr) = 6 + VARHDRSZ;//set length for text value? PG_RETURN_TEXT_P(outstr);//return text value, i.e. 'abcdef', to PostgreSQL? } Here's my SQL statement: SELECT proname, bvbpgsortword("proname") FROM pg_proc; The query result has procedure names in column1 and nothing in column 2. I'm doubtless making some fundamental mistake here. John Gunther
John Gunther <inbox@bucksvsbytes.com> writes: > Datum bvbpgsortword(PG_FUNCTION_ARGS){ > //declarations > text *instr = PG_GETARG_TEXT_P(0); > text *outstr; > //code > memcpy(outstr,"abcdef",6);//needed to move data from char constant > to pg's text type? > VARATT_SIZEP(outstr) = 6 + VARHDRSZ;//set length for text value? > PG_RETURN_TEXT_P(outstr);//return text value, i.e. 'abcdef', to > PostgreSQL? > } You're missing a palloc() (didn't your compiler warn about use of an uninitialized variable here?). And the memcpy needs to point at VARDATA(outstr) not just outstr. regards, tom lane