OmenApps / django-postgresql-dag

Directed Acyclic Graphs with a variety of methods for both Nodes and Edges, and multiple exports (NetworkX, Pandas, etc). This project is the foundation for a commercial product, so expect regular improvements. PR's and other contributions are welcomed.
Apache License 2.0
41 stars 6 forks source link

UpwardPathQuery and DownwardPathQuery result in error due to default casting #10

Open JackAtOmenApps opened 2 years ago

JackAtOmenApps commented 2 years ago

When performing path queries, the path is cast as bigint while the array of ids is cast as integer

Example query explain from our codebase:

WITH RECURSIVE traverse(parent_id, child_id, depth, PATH) AS
    (SELECT first.parent_id,
            first.child_id,
            1 AS depth, ARRAY[first.parent_id] AS PATH
     FROM flow_networks_networkedge AS FIRST
     WHERE parent_id = 4269
     UNION ALL SELECT first.parent_id,
                      first.child_id,
                      second.depth + 1 AS depth,
                      PATH || first.parent_id AS PATH
     FROM flow_networks_networkedge AS FIRST,
          traverse AS SECOND
     WHERE first.parent_id = second.child_id
         AND (first.parent_id <> ALL(second.path)) )
SELECT UNNEST(ARRAY[pkid]) AS pkid
FROM
    (SELECT PATH || ARRAY[4215], depth
     FROM traverse
     WHERE child_id = 4215
         AND depth <= 20
     LIMIT 1) AS x(pkid);

Result:

ERROR:  operator does not exist: bigint[] || integer[]
LINE 17:     (SELECT PATH || ARRAY[4215], depth
                          ^
HINT:  No operator matches the given name and argument types. You might need to add explicit type casts.
SQL state: 42883
Character: 657
JackAtOmenApps commented 2 years ago

This is due to new Django versions allowing a default auto field of various types. In the past it was only an AutoField (::integer), but now the user can set it as a BigAutoField (::bigint), or UUIDField (::uuid).

https://docs.djangoproject.com/en/3.2/topics/db/models/#automatic-primary-key-fields

Additionally, the pkid type may be set manually per-model. Need to be able to account for this in the query.