php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #29058 odbc_foreignkeys does not return imported keys *Fix*
Submitted: 2004-07-08 05:36 UTC Modified: 2004-07-15 17:09 UTC
From: mirage at rateaprof dot com Assigned:
Status: Closed Package: ODBC related
PHP Version: 5.0.0RC3 OS: Redhat 8
Private report: No CVE-ID: None
 [2004-07-08 05:36 UTC] mirage at rateaprof dot com
Description:
------------
I am running IBM DB2 v8.1 fixpack 5
I am running PHP-5RC2/3 (same php_odbc.c file, no diffs)

If I call:
odbc_foreignkeys ($dbconn, "", "schema", "table", "", "", "");

I get all foreign keys for this table (i.e. I get a list of all other tables that reference fields in schema.table).

--
In theory, I should be able to:
odbc_foreignkeys ($dbconn, "", "", "", "", "schema", "table")

And in return I get all schema2.table2.column2 names of other tables that columns in schema.table reference.  In otherwords, what keys does this table reference?

Well it always returns nothing... 

--
So is it me, or is it php_odbc.c?  Well I went ahead and tested /opt/IBM/db2/V8.1/samples/cli/tbconstr.c and reversed the arguments for SQLForeignKeys from ExportedKeys query:
  /* get the list of foreign key columns */
  cliRC = SQLForeignKeys(hstmt,
                         NULL,
                         0,
                         tbSchema,
                         SQL_NTS,
                         tbName,
                         SQL_NTS,
                         NULL,
                         0,
                         tbSchema,
                         SQL_NTS,
                         tbName,
                         SQL_NTS);


So it would become the following to query ImportedKeys
  /* get the list of foreign key columns */
  cliRC = SQLForeignKeys(hstmt,
                         NULL,
                         0,
                         NULL,
                         SQL_NTS,
                         NULL,
                         SQL_NTS,
                         NULL,
                         0,
                         tbSchema,
                         SQL_NTS,
                         tbName,
                         SQL_NTS);


Yup it works in the pure C+odbc version... it just doesn't work in php, so somewhere between the php-odbc_foreignkeys(,...) call and the odbc_php.c, we lose the return values... I can't tell where since I don't know enough to debug php... I'd be more than happy to help, but I  don't know how.

Can someone see if perhaps return values are being thrown away? Or arguments to the php call are lost? 

--

I did check that the proper dynamic library was being used by running ldd libphp5.so, and yes it does link to the current v8.1 library... 


Reproduce code:
---------------
So I get all the tables with odbc_tables($dbconn, "", "schema", "%", "");

Then to get Exported Keys which works:

        $cols = odbc_foreignkeys($dbconn, odbc_result($tables,1),odbc_result($tables,2), odbc_result($tables,3), "", "", "") or die(odbc_errormsg());


Then to get Imported Keys which does not work:

        $cols = odbc_foreignkeys($dbconn, "", "", ""odbc_result($tables,1),odbc_result($tables,2), odbc_result($tables,3)) or die(odbc_errormsg());

Expected result:
----------------
If jeff.a (a) is a primary key, and jeff.b(d) references jeff.a(a):

jeff.a (a) is exported to jeff.b (d) - Yes this works

jeff.b (d) imports jeff.a (a) - this does not return from the odbc_foreign keys call for imported keys

Actual result:
--------------

	JEFF	A	TABLE	
TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	DATA_TYPE	TYPE_NAME	COLUMN_SIZE	BUFFER_LENGTH	DECIMAL_DIGITS	NUM_PREC_RADIX	NULLABLE	REMARKS	COLUMN_DEF	SQL_DATA_TYPE	SQL_DATETIME_SUB	CHAR_OCTET_LENGTH	ORDINAL_POSITION	IS_NULLABLE
NULL	JEFF	A	A	4	INTEGER	10	4	0	10	0	NULL	NULL	4	NULL	NULL	1	NO
NULL	JEFF	A	B	4	INTEGER	10	4	0	10	1	NULL	NULL	4	NULL	NULL	2	YES
function result = 2
TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	KEY_SEQ	PK_NAME
NULL	JEFF	A	A	1	SQL040707170936160
function result = 1
Exported Keys
.JEFF.A
PKTABLE_CAT	PKTABLE_SCHEM	PKTABLE_NAME	PKCOLUMN_NAME	FKTABLE_CAT	FKTABLE_SCHEM	FKTABLE_NAME	FKCOLUMN_NAME	KEY_SEQ	UPDATE_RULE	DELETE_RULE	FK_NAME	PK_NAME	DEFERRABILITY
NULL	JEFF	A	A	NULL	JEFF	B	D	1	3	3	SQL040707170938220	SQL040707170936160	7
NULL	JEFF	A	A	NULL	JEFF	C	AA	1	3	3	SQL040707171829700	SQL040707170936160	7
function result = 2
Imported Keys
.JEFF.A
No rows found
function result = 0
	JEFF	B	TABLE	
TABLE_CAT	TABLE_SCHEM	TABLE_NAME	COLUMN_NAME	DATA_TYPE	TYPE_NAME	COLUMN_SIZE	BUFFER_LENGTH	DECIMAL_DIGITS	NUM_PREC_RADIX	NULLABLE	REMARKS	COLUMN_DEF	SQL_DATA_TYPE	SQL_DATETIME_SUB	CHAR_OCTET_LENGTH	ORDINAL_POSITION	IS_NULLABLE
NULL	JEFF	B	C	4	INTEGER	10	4	0	10	1	NULL	NULL	4	NULL	NULL	1	YES
NULL	JEFF	B	D	4	INTEGER	10	4	0	10	1	NULL	NULL	4	NULL	NULL	2	YES
NULL	JEFF	B	E	4	INTEGER	10	4	0	10	1	NULL	NULL	4	NULL	NULL	3	YES
function result = 3
No rows found
function result = 0
Exported Keys
.JEFF.B
No rows found
function result = 0
Imported Keys
.JEFF.B
No rows found
function result = 0

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-07-08 21:23 UTC] mirage at rateaprof dot com
Sorry coppied wrong code block, but the first code snip should have read (with nulls in the fk fields).  BTW Problem still exists, it was just my 'pasteo' in the bux report.

  /* get the list of foreign key columns */
  cliRC = SQLForeignKeys(hstmt,
                         NULL,
                         0,
                         tbSchema,
                         SQL_NTS,
                         tbName,
                         SQL_NTS,
                         NULL,
                         0,
                         NULL,
                         SQL_NTS,
                         NULL,
                         SQL_NTS);
 [2004-07-09 09:25 UTC] mirage at rateaprof dot com
Okay this is a partial fix, I don't know how to finish it:

In php-src/ext/odbc/php_odbc.c
look in PHP_FUNCTION(odbc_foreignkeys)
There is a line:

#ifdef HAVE_DBMAKER
#define EMPTY_TO_NULL
...
#endif

IBM DB2 also needs this feature to set fields of "" in php to NULL in the C-ODBC call.  I know this because I did a

if (!strlen(pcat)) pcat=NULL;
and the same for ptable, pschema, fcat, fschema, ftable
and the problem is fixed.

I'm not exactly the person who really knows how best to make the ifdef detect DB2 as well, but if one of you could make it essentially:

#ifdef (HAVE_DBMAKER || HAVE_DB2) 
..
#endif

Then that would be awesome!  And that folks will fix the problem in DB2 :)

Cheers!

Jeff
 [2004-07-09 09:58 UTC] mirage at rateaprof dot com
It looks like the line to use is:

#if defined (HAVE_DBMAKER) || defined (HAVE_IBMDB2)
#define EMPTY_TO_NULL (xstr) \
...
#endif

If you have any questions, just let me know.
 [2004-07-15 17:09 UTC] kalowsky@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.

Patch applied. thanks
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Jun 18 07:01:31 2024 UTC