Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

With PostgreSQL, PK detection fails when PK + FK constraint on same column #1207

Closed
jmichelf opened this issue Nov 5, 2020 · 3 comments
Closed
Labels

Comments

@jmichelf
Copy link

jmichelf commented Nov 5, 2020

Hi
For me, the function schema($table,$fields=NULL,$ttl=0) in sql.php wrongly gives 'pkey'=false when using it with PostgreSQL on a table that have both PK and FK constraints on the same column. In same condition with MySQL, it gives correct result.
The reason might be that the query used for 'pgsql' returns a duplicate row for the same field. Here after the illustration on 'pgsql' :

SELECT
    C.COLUMN_NAME AS field,
    C.DATA_TYPE AS type,
    C.COLUMN_DEFAULT AS defval,
    C.IS_NULLABLE AS nullable,
    T.CONSTRAINT_TYPE AS pkey 
FROM INFORMATION_SCHEMA.COLUMNS AS C 
LEFT OUTER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS K 
    ON C.TABLE_NAME=K.TABLE_NAME 
    AND C.COLUMN_NAME=K.COLUMN_NAME 
    AND C.TABLE_SCHEMA=K.TABLE_SCHEMA 
    AND C.TABLE_CATALOG=K.TABLE_CATALOG 
LEFT OUTER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS T 
    ON K.TABLE_NAME=T.TABLE_NAME 
    AND K.CONSTRAINT_NAME=T.CONSTRAINT_NAME 
    AND K.TABLE_SCHEMA=T.TABLE_SCHEMA 
    AND K.TABLE_CATALOG=T.TABLE_CATALOG WHERE C.TABLE_NAME='my_table' 
    AND C.TABLE_CATALOG='my_db'

    field    |       type        | defval | nullable |    pkey     
-------------+-------------------+--------+----------+-------------
 id          | integer           |        | NO       | PRIMARY KEY
 id          | integer           |        | NO       | FOREIGN KEY   <------- duplicate row
 company_id  | integer           |        | NO       | FOREIGN KEY
 unique_name | character varying |        | NO       | 

The corresponding query on 'mysql':

SHOW columns FROM my_table;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | int(11)      | NO   | PRI | NULL    | auto_increment |
| company_id  | int(11)      | NO   | MUL | NULL    |                |
| unique_name | varchar(128) | NO   | UNI | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+

Additionally, the 'pgsql' column 'id' has no default value, which is intended in my case, and probably has no impact here.

Thanks for your great work on 'f3'.
Kind regards
Jean-Michel

xfra35 added a commit to f3-factory/fatfree-core that referenced this issue Nov 6, 2020
@xfra35
Copy link
Collaborator

xfra35 commented Nov 6, 2020

Thanks for reporting. This should be fixed in f3-factory/fatfree-core@28e7e75.
I assumed that the PK always appears first in the list.

If that was not the case, we should add an ORDER BY condition in the SQL statement. Something like ORDER BY C.ordinal_position,CASE WHEN T.CONSTRAINT_TYPE='PRIMARY KEY' THEN 1 END. But this would have to be tested against the other engines mssql|sqlsrv|sybase|dblib|pgsql|odbc.

@xfra35 xfra35 closed this as completed Nov 6, 2020
@xfra35 xfra35 added the bug label Nov 6, 2020
@jmichelf
Copy link
Author

jmichelf commented Nov 6, 2020

Hi. Thanks, this fix solved my problem.
Jean-Michel

@ivanpenchev
Copy link

@xfra35 this does not work with MSSQL using the dblib driver. The primary column does not appear first in the list thus the sql.php is unable to determine which is the primary column.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants