473,385 Members | 1,342 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

UDF call to C wrapper for PCRE library fails - SQL0444N, Reason code: "5", SQLSTATE=42724

Hi all,

I'm trying to complete the samples from the excellent 2003
developerWorks article "Bringing the Power of Regular Expression
Matching to SQL" by Knut Stolze:

http://tinyurl.com/3bhrnn

I've managed to compile and link the C code from "Listing 5", the
regexpSimple() wrapper (see link). The build options are pretty much
the result of trial-and-error using the samples in
/home/db2inst1/sqllib/samples/c/. Any advice on how to successfully
call the C wrapper from a DB2 UDF is appreciated.

# Environment
DB2/LINUX 9.1.0
gcc (GCC) 3.4.6 20060404 (Red Hat 3.4.6-3)

# Flags
$ EXTRA_LFLAG="-Wl,-rpath,$DB2PATH/lib"
$ DB2PATH=/home/db2inst1/sqllib
$ DB2V9LIBS=/opt/ibm/db2/V9.1
$ SHARED_LIB_NAME=regexUdf

# Compile the program.
$ gcc $EXTRA_C_FLAGS -fpic -I$DB2PATH/include -I$DB2V9LIBS/include -c
utilapi.c -D_REENTRANT
$ gcc $EXTRA_C_FLAGS -fpic -I$DB2PATH/include -I$DB2V9LIBS/include -c
regex1.c -D_REENTRANT

# Link the program and create a shared library
$ gcc $EXTRA_C_FLAGS -shared -o $SHARED_LIB_NAME regex1.o utilapi.o
$EXTRA_LFLAG -L$DB2PATH/lib -ldb2 -lpthread

# Copy and chown shared library
$ cp $SHARED_LIB_NAME $DB2PATH/function
$ chown db2inst1: $DB2PATH/function/$SHARED_LIB_NAME
$ ls -l /home/db2inst1/sqllib/function/regexUdf
-rwxr-xr-x 1 db2inst1 db2grp1 10624 Feb 20 10:16 /home/db2inst1/
sqllib/function/regexUdf

However, calling this function from DB2 fails with "SQL0444N":

$ sudo su - db2inst1
$ db2 "connect to sample user db2inst1"
Enter current password for db2inst1:

Database Connection Information

Database server = DB2/LINUX 9.1.0
SQL authorization ID = DB2INST1
Local database alias = SAMPLE

$ db2 -t -f /home/db2inst1/test/db2/regex/regex1.sql
DB20000I The SQL command completed successfully.

$ db2 "select FIRSTNME, LASTNAME from employee where regex1('\w+',
FIRSTNME) = 1"

FIRSTNME LASTNAME
------------ ---------------
SQL0444N Routine "REGEX1" (specific name "REGEXSIMPLE") is
implemented with
code in library or path ".../sqllib/function/regexUdf", function
"regexpSimple" which cannot be accessed. Reason code: "5".
SQLSTATE=42724

$ cat /home/db2inst1/test/db2/regex/regex1.sql
CREATE FUNCTION regex1(pattern VARCHAR(2048), string CLOB(10M))
RETURNS INTEGER
SPECIFIC regexSimple
EXTERNAL NAME 'regexUdf!regexpSimple'
LANGUAGE C
PARAMETER STYLE DB2SQL
DETERMINISTIC
NOT FENCED
RETURNS NULL ON NULL INPUT
NO SQL
NO EXTERNAL ACTION
ALLOW PARALLEL;

$ cat /home/db2inst1/test/db2/regex/regex1.c
/*
http://www-128.ibm.com/developerwork...301stolze.html

listing5

A small chunk of C code, which implements the UDF entry point. This
entry point is called by DB2 during the query execution for each
row to be matched against the pattern. Listing 5 is an example what
this code could look like. For the description of the pcre_*
function and macros, refer to the documentation of the PCRE
library. For compiling the C code and building the shared
libraries, refer to the DB2 Application Development Guide.

*/

#include <pcre/pcre.h>
#include <sqludf.h>

void regexpSimple(
// input parameters
SQLUDF_VARCHAR *pattern, SQLUDF_CLOB *str,
// output
SQLUDF_INTEGER *match,
// null indicators
SQLUDF_NULLIND *pattern_ind, SQLUDF_NULLIND *str_ind,
SQLUDF_NULLIND *match_ind,
SQLUDF_TRAIL_ARGS)
{
pcre *re = NULL;
const char *error = NULL;
int errOffset = 0;
int rc = 0;

// we assume successful return
*match_ind = 0;

// compile the pattern to its internal representation
re = pcre_compile(pattern, 0 /* default options */, &error,
&errOffset, NULL);
if (re == NULL) {
snprintf(SQLUDF_MSGTX, 70, "Regexp compilation failed at "
"offset %d: %s\n", errOffset, error);
strcpy(SQLUDF_STATE, "38900");
(*pcre_free)(re);
return;
}

// match the string againts the pattern
rc = pcre_exec(re, NULL, str->data, str->length, 0,
0 /* default options */, NULL, 0);
switch (rc) {
case PCRE_ERROR_NOMATCH:
*match = 0;
break;
case PCRE_ERROR_BADOPTION:
snprintf(SQLUDF_MSGTX, 70, "An unrecognized bit was set in the
"
"options argument");
strcpy(SQLUDF_STATE, "38901");
break;
case PCRE_ERROR_NOMEMORY:
snprintf(SQLUDF_MSGTX, 70, "Not enough memory available.");
strcpy(SQLUDF_STATE, "38902");
break;
default:
if (rc < 0) {
snprintf(SQLUDF_MSGTX, 70, "A regexp match error "
"occured: %d", rc);
strcpy(SQLUDF_STATE, "38903");
}
else {
*match = 1;
}
break;
}

// cleanup
(*pcre_free)(re);
return;
}

--
Serman D.

Feb 20 '07 #1
2 5652
Serman D. wrote:
Hi all,

I'm trying to complete the samples from the excellent 2003
developerWorks article "Bringing the Power of Regular Expression
Matching to SQL" by Knut Stolze:

http://tinyurl.com/3bhrnn

I've managed to compile and link the C code from "Listing 5", the
regexpSimple() wrapper (see link). The build options are pretty much
the result of trial-and-error using the samples in
/home/db2inst1/sqllib/samples/c/. Any advice on how to successfully
call the C wrapper from a DB2 UDF is appreciated.

# Environment
DB2/LINUX 9.1.0
gcc (GCC) 3.4.6 20060404 (Red Hat 3.4.6-3)

# Flags
$ EXTRA_LFLAG="-Wl,-rpath,$DB2PATH/lib"
$ DB2PATH=/home/db2inst1/sqllib
$ DB2V9LIBS=/opt/ibm/db2/V9.1
$ SHARED_LIB_NAME=regexUdf

# Compile the program.
$ gcc $EXTRA_C_FLAGS -fpic -I$DB2PATH/include -I$DB2V9LIBS/include -c
utilapi.c -D_REENTRANT
Why are you compiling (and later linking) with "utilapi.c"? Just get rid of
it.
$ gcc $EXTRA_C_FLAGS -fpic -I$DB2PATH/include -I$DB2V9LIBS/include -c
regex1.c -D_REENTRANT
Remove the -I$DB2V9LIBS/include thing. It is not needed.
# Link the program and create a shared library
$ gcc $EXTRA_C_FLAGS -shared -o $SHARED_LIB_NAME regex1.o utilapi.o
$EXTRA_LFLAG -L$DB2PATH/lib -ldb2 -lpthread
Since the code does not access any DB2 APIs, you don't need -ldb2 here.

On the other hand, you must specify -lpcre here so that the PCRE library is
used when your shared lib is loaded. Otherwise, PCRE is not loaded,
leading to unresolved symbols and the SQL0444 you are seeing.
# Copy and chown shared library
$ cp $SHARED_LIB_NAME $DB2PATH/function
$ chown db2inst1: $DB2PATH/function/$SHARED_LIB_NAME
$ ls -l /home/db2inst1/sqllib/function/regexUdf
-rwxr-xr-x 1 db2inst1 db2grp1 10624 Feb 20 10:16 /home/db2inst1/
sqllib/function/regexUdf

However, calling this function from DB2 fails with "SQL0444N":

$ sudo su - db2inst1
$ db2 "connect to sample user db2inst1"
Enter current password for db2inst1:

Database Connection Information

Database server = DB2/LINUX 9.1.0
SQL authorization ID = DB2INST1
Local database alias = SAMPLE

$ db2 -t -f /home/db2inst1/test/db2/regex/regex1.sql
DB20000I The SQL command completed successfully.

$ db2 "select FIRSTNME, LASTNAME from employee where regex1('\w+',
FIRSTNME) = 1"

FIRSTNME LASTNAME
------------ ---------------
SQL0444N Routine "REGEX1" (specific name "REGEXSIMPLE") is
implemented with
code in library or path ".../sqllib/function/regexUdf", function
"regexpSimple" which cannot be accessed. Reason code: "5".
SQLSTATE=42724

$ cat /home/db2inst1/test/db2/regex/regex1.sql
CREATE FUNCTION regex1(pattern VARCHAR(2048), string CLOB(10M))
RETURNS INTEGER
SPECIFIC regexSimple
EXTERNAL NAME 'regexUdf!regexpSimple'
LANGUAGE C
PARAMETER STYLE DB2SQL
DETERMINISTIC
NOT FENCED
RETURNS NULL ON NULL INPUT
NO SQL
NO EXTERNAL ACTION
ALLOW PARALLEL;

$ cat /home/db2inst1/test/db2/regex/regex1.c
/*
http://www-128.ibm.com/developerwork...301stolze.html
>
listing5

A small chunk of C code, which implements the UDF entry point. This
entry point is called by DB2 during the query execution for each
row to be matched against the pattern. Listing 5 is an example what
this code could look like. For the description of the pcre_*
function and macros, refer to the documentation of the PCRE
library. For compiling the C code and building the shared
libraries, refer to the DB2 Application Development Guide.

*/

#include <pcre/pcre.h>
#include <sqludf.h>
You may want to add the following here:

#include <stdio.h>
#include <string.h>
void regexpSimple(
// input parameters
SQLUDF_VARCHAR *pattern, SQLUDF_CLOB *str,
// output
SQLUDF_INTEGER *match,
// null indicators
SQLUDF_NULLIND *pattern_ind, SQLUDF_NULLIND *str_ind,
SQLUDF_NULLIND *match_ind,
SQLUDF_TRAIL_ARGS)
{
pcre *re = NULL;
const char *error = NULL;
int errOffset = 0;
int rc = 0;

// we assume successful return
*match_ind = 0;

// compile the pattern to its internal representation
re = pcre_compile(pattern, 0 /* default options */, &error,
&errOffset, NULL);
if (re == NULL) {
snprintf(SQLUDF_MSGTX, 70, "Regexp compilation failed at "
"offset %d: %s\n", errOffset, error);
strcpy(SQLUDF_STATE, "38900");
(*pcre_free)(re);
return;
}

// match the string againts the pattern
rc = pcre_exec(re, NULL, str->data, str->length, 0,
0 /* default options */, NULL, 0);
switch (rc) {
case PCRE_ERROR_NOMATCH:
*match = 0;
break;
case PCRE_ERROR_BADOPTION:
snprintf(SQLUDF_MSGTX, 70, "An unrecognized bit was set in the
"
"options argument");
strcpy(SQLUDF_STATE, "38901");
break;
case PCRE_ERROR_NOMEMORY:
snprintf(SQLUDF_MSGTX, 70, "Not enough memory available.");
strcpy(SQLUDF_STATE, "38902");
break;
default:
if (rc < 0) {
snprintf(SQLUDF_MSGTX, 70, "A regexp match error "
"occured: %d", rc);
strcpy(SQLUDF_STATE, "38903");
}
else {
*match = 1;
}
break;
}

// cleanup
(*pcre_free)(re);
return;
}
Here is what I did just now:

$ gcc -c -o regexUdf.o -I ~/sqllib/include regexUdf.c -D_REENTRANT
$ gcc -o regexUdf -shared -fpic regexUdf.o
$ nm regexUdf
[...]
U pcre_compile
U pcre_exec
U pcre_free
000005ac T regexpSimple

$ cp regexUdf ~/sqllib/function/

$ db2 -tvf regex.sql
CREATE FUNCTION regex1(pattern VARCHAR(2048), string CLOB(10M))
RETURNS INTEGER
SPECIFIC regexSimple
EXTERNAL NAME 'regexUdf!regexpSimple'
LANGUAGE C
PARAMETER STYLE DB2SQL
DETERMINISTIC
NOT FENCED
RETURNS NULL ON NULL INPUT
NO SQL
NO EXTERNAL ACTION
ALLOW PARALLEL
DB20000I The SQL command completed successfully.

$ db2 "values regex1('\\w+', 'abcdef')"

1
-----------
1

1 record(s) selected.

--
Knut Stolze
DB2 z/OS Utilities Development
IBM Germany
Feb 20 '07 #2

Thank you Knut. Your comments are very useful.

--
Serman D.

Feb 20 '07 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: Jean-Marc Blaise | last post by:
Hi Folks, I'm getting this message with the XML tutorial: getstart_exportXML.cmd file: SQL0444N Routine "DB2XML.CONTENT" (specific name "DB2XMLCONTENTVF") is implemented with code in library...
1
by: GarthVader | last post by:
I'm new to DB2 and am trying to execute a parameterized stored procedure from within a VB 6.0 application. We're using DB2 WSE version 8.2 with fixpack 10 running on a Windows Small Business...
3
by: NG | last post by:
I installed DB2 in Linux OS. I tried to create database and I am getting the following error message: SQL0444N Routine "db2spcat" (specific name "SQL060216094049640") is implemented with code...
0
by: technocrat | last post by:
I am trying to build a java stor proc from RAD and i get this error: ########################################################### CONTROL.INIT - Build started. CONTROL.INIT - Created temporary...
0
by: Eil | last post by:
Have 2 databases under the same db2 udb instance (aix 5.3.0.0, db2 udb V8.1, fixpak 9). Able to run the db2advis command successfully against one database. On the other database, always...
0
by: Serman D. | last post by:
Hi, I am trying to implement an MD5 checksum function using an UDF call to C wrapper returning the MD5 checksum. I've downloaded a free (LGPL) implementation in C of the MD5 algorithm from...
2
by: murthydb2 | last post by:
Can someone help me to find a solution for the below error . Problem Description: I have a User-defined function which is written using an external C program file . When this UDF is called the...
1
by: N61601 | last post by:
A connection is made to a z/OS system and the following command is issued. db2 =call TESTDB.TESTPROC('STRING,99,?,?) SQL0444N Routine "TESTPROC" (specific name "") is implemented with code in...
0
by: flyman | last post by:
I am unable to find any information regarding the below error. Any assistance would be greatly appreciated? Thank , you I am attempting to run the below command (or attempt to connect to any...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.