hasura / hasura/graphql-engine

Custom function not working correctly with graphql

Open
#7,368 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
32.1k
Forks
3k
PR merge metrics
PR metrics pending

Description

I have written a custom function which returns the right response in the SQL editor but not with graphql explorer.

CREATE
OR REPLACE FUNCTION public.session_groupings(
  group_bys text [] DEFAULT '{}' :: text [],
  "sessionWhere" json DEFAULT NULL :: json
) RETURNS SETOF session_groupings_type LANGUAGE sql STABLE AS $ function $
SELECT
  (
    CASE
      WHEN 'session_id' = ANY(group_bys) THEN session_id
      ELSE NULL
    END
  ) AS session_id,
  (
    CASE
      WHEN 'project_id' = ANY(group_bys) THEN project_id
      ELSE NULL
    END
  ) AS project_id,
  (
    CASE
      WHEN 'created_at' = ANY(group_bys) THEN created_at
      ELSE NULL
    END
  ) AS created_at,
  (
    CASE
      WHEN 'language' = ANY(group_bys) THEN language
      ELSE NULL
    END
  ) AS language,
  (
    CASE
      WHEN 'country' = ANY(group_bys) THEN country
      ELSE NULL
    END
  ) AS country,
  (
    CASE
      WHEN 'city' = ANY(group_bys) THEN city
      ELSE NULL
    END
  ) AS city,
  (
    CASE
      WHEN 'postal_code' = ANY(group_bys) THEN postal_code
      ELSE NULL
    END
  ) AS postal_code,
  (
    CASE
      WHEN 'region' = ANY(group_bys) THEN region
      ELSE NULL
    END
  ) AS region,
  (
    CASE
      WHEN 'latitude' = ANY(group_bys) THEN latitude
      ELSE NULL
    END
  ) AS latitude,
  (
    CASE
      WHEN 'longitude' = ANY(group_bys) THEN longitude
      ELSE NULL
    END
  ) AS longitude,
  (
    CASE
      WHEN 'continent' = ANY(group_bys) THEN continent
      ELSE NULL
    END
  ) AS continent,
  (
    CASE
      WHEN 'timezone' = ANY(group_bys) THEN timezone
      ELSE NULL
    END
  ) AS timezone,
  (
    CASE
      WHEN 'ip' = ANY(group_bys) THEN ip
      ELSE NULL
    END
  ) AS ip,
  (
    CASE
      WHEN 'origin' = ANY(group_bys) THEN origin
      ELSE NULL
    END
  ) AS origin,
  (
    CASE
      WHEN 'region_code' = ANY(group_bys) THEN region_code
      ELSE NULL
    END
  ) AS region_code,
  (
    CASE
      WHEN 'os_name' = ANY(group_bys) THEN os_name
      ELSE NULL
    END
  ) AS os_name,
  (
    CASE
      WHEN 'os_version' = ANY(group_bys) THEN os_version
      ELSE NULL
    END
  ) AS os_version,
  (
    CASE
      WHEN 'client_name' = ANY(group_bys) THEN client_name
      ELSE NULL
    END
  ) AS client_name,
  (
    CASE
      WHEN 'client_type' = ANY(group_bys) THEN client_type
      ELSE NULL
    END
  ) AS client_type,
  (
    CASE
      WHEN 'client_version' = ANY(group_bys) THEN client_version
      ELSE NULL
    END
  ) AS client_version,
  (
    CASE
      WHEN 'client_engine' = ANY(group_bys) THEN client_engine
      ELSE NULL
    END
  ) AS client_engine,
  (
    CASE
      WHEN 'device_brand' = ANY(group_bys) THEN device_brand
      ELSE NULL
    END
  ) AS device_brand,
  (
    CASE
      WHEN 'device_type' = ANY(group_bys) THEN device_type
      ELSE NULL
    END
  ) AS device_type,
  (
    CASE
      WHEN 'device_model' = ANY(group_bys) THEN device_model
      ELSE NULL
    END
  ) AS device_model,
  (
    CASE
      WHEN 'referrer' = ANY(group_bys) THEN referrer
      ELSE NULL
    END
  ) AS referrer,
  (
    CASE
      WHEN 'event_type' = ANY(group_bys) THEN event_type
      ELSE NULL
    END
  ) AS event_type,
  (
    CASE
      WHEN 'event_value' = ANY(group_bys) THEN event_value
      ELSE NULL
    END
  ) AS event_value,
  (
    CASE
      WHEN 'protocol' = ANY(group_bys) THEN protocol
      ELSE NULL
    END
  ) AS protocol,
  (
    CASE
      WHEN 'pathname' = ANY(group_bys) THEN pathname
      ELSE NULL
    END
  ) AS pathname,
  (
    CASE
      WHEN 'updated_at' = ANY(group_bys) THEN updated_at
      ELSE NULL
    END
  ) AS updated_at,
  count(*) as "count"
from
  public.session
where
  (
    "sessionWhere" #>> '{session_id,_eq}' IS NULL
    OR (
      "session_id" :: text = (
        "sessionWhere" #>> '{session_id,_eq}')::text
      )
    )
    AND (
      "sessionWhere" #>> '{project_id,_eq}' IS NULL
      OR (
        "project_id" :: text = "sessionWhere" #>> '{project_id,_eq}'
      )
    )
    AND (
      "sessionWhere" #>> '{created_at,_gt}' IS NULL
      OR (
        "created_at" :: text > ("sessionWhere" #>> '{created_at,_gt}')
)
      )
      AND (
        "sessionWhere" #>> '{language,_eq}' IS NULL
        OR (
          "language" = "sessionWhere" #>> '{language,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{country,_eq}' IS NULL
        OR (
          "country" = "sessionWhere" #>> '{country,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{city,_eq}' IS NULL
        OR (
          "city" = "sessionWhere" #>> '{city,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{postal_code,_eq}' IS NULL
        OR (
          "postal_code" = "sessionWhere" #>> '{postal_code,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{region,_eq}' IS NULL
        OR (
          "region" = "sessionWhere" #>> '{region,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{latitude,_eq}' IS NULL
        OR (
          "latitude" = "sessionWhere" #>> '{latitude,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{longitude,_eq}' IS NULL
        OR (
          "longitude" = "sessionWhere" #>> '{longitude,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{continent,_eq}' IS NULL
        OR (
          "continent" = "sessionWhere" #>> '{continent,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{timezone,_eq}' IS NULL
        OR (
          "timezone" = "sessionWhere" #>> '{timezone,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{ip,_eq}' IS NULL
        OR (
          "ip" = "sessionWhere" #>> '{ip,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{origin,_eq}' IS NULL
        OR (
          "origin" = "sessionWhere" #>> '{origin,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{region_code,_eq}' IS NULL
        OR (
          "region_code" = "sessionWhere" #>> '{region_code,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{os_name,_eq}' IS NULL
        OR (
          "os_name" = "sessionWhere" #>> '{os_name,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{os_version,_eq}' IS NULL
        OR (
          "os_version" = "sessionWhere" #>> '{os_version,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{client_name,_eq}' IS NULL
        OR (
          "client_name" = "sessionWhere" #>> '{client_name,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{client_type,_eq}' IS NULL
        OR (
          "client_type" = "sessionWhere" #>> '{client_type,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{client_version,_eq}' IS NULL
        OR (
          "client_version" = "sessionWhere" #>> '{client_version,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{client_engine,_eq}' IS NULL
        OR (
          "client_engine" = "sessionWhere" #>> '{client_engine,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{device_brand,_eq}' IS NULL
        OR (
          "device_brand" = "sessionWhere" #>> '{device_brand,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{device_type,_eq}' IS NULL
        OR (
          "device_type" = "sessionWhere" #>> '{device_type,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{device_model,_eq}' IS NULL
        OR (
          "device_model" = "sessionWhere" #>> '{device_model,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{referrer,_eq}' IS NULL
        OR (
          "referrer" = "sessionWhere" #>> '{referrer,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{event_type,_eq}' IS NULL
        OR (
          "event_type" = "sessionWhere" #>> '{event_type,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{event_value,_eq}' IS NULL
        OR (
          "event_value" = "sessionWhere" #>> '{event_value,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{protocol,_eq}' IS NULL
        OR (
          "protocol" = "sessionWhere" #>> '{protocol,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{pathname,_eq}' IS NULL
        OR (
          "pathname" = "sessionWhere" #>> '{pathname,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{updated_at,_eq}' IS NULL
        OR (
          "updated_at" :: text = "sessionWhere" #>> '{updated_at,_eq}'
        )
      )
      AND (
        "sessionWhere" #>> '{created_at,_eq}' IS NULL
        OR (
          "created_at" :: date = to_date(
            "sessionWhere" #>> '{created_at,_eq}','MM-DD-YYYY')
          )
        )
        AND (
          "sessionWhere" #>> '{created_at,_gte}' IS NULL
          OR (
            "created_at" :: date >= to_date(
              "sessionWhere" #>> '{created_at,_gte}','MM-DD-YYYY')
            )
          )
          AND (
            "sessionWhere" #>> '{created_at,_lte}' IS NULL
            OR (
              "created_at" :: date <= to_date(
                "sessionWhere" #>> '{created_at,_lte}','MM-DD-YYYY')
              )
            )
            group by
              (
                CASE
                  WHEN 'session_id' = ANY(group_bys) THEN session_id
                END
              ),
              (
                CASE
                  WHEN 'project_id' = ANY(group_bys) THEN project_id
                END
              ),
              (
                CASE
                  WHEN 'created_at' = ANY(group_bys) THEN created_at
                END
              ),
              (
                CASE
                  WHEN 'language' = ANY(group_bys) THEN language
                END
              ),
              (
                CASE
                  WHEN 'country' = ANY(group_bys) THEN country
                END
              ),
              (
                CASE
                  WHEN 'city' = ANY(group_bys) THEN city
                END
              ),
              (
                CASE
                  WHEN 'postal_code' = ANY(group_bys) THEN postal_code
                END
              ),
              (
                CASE
                  WHEN 'region' = ANY(group_bys) THEN region
                END
              ),
              (
                CASE
                  WHEN 'latitude' = ANY(group_bys) THEN latitude
                END
              ),
              (
                CASE
                  WHEN 'longitude' = ANY(group_bys) THEN longitude
                END
              ),
              (
                CASE
                  WHEN 'continent' = ANY(group_bys) THEN continent
                END
              ),
              (
                CASE
                  WHEN 'timezone' = ANY(group_bys) THEN timezone
                END
              ),
              (
                CASE
                  WHEN 'ip' = ANY(group_bys) THEN ip
                END
              ),
              (
                CASE
                  WHEN 'origin' = ANY(group_bys) THEN origin
                END
              ),
              (
                CASE
                  WHEN 'region_code' = ANY(group_bys) THEN region_code
                END
              ),
              (
                CASE
                  WHEN 'os_name' = ANY(group_bys) THEN os_name
                END
              ),
              (
                CASE
                  WHEN 'os_version' = ANY(group_bys) THEN os_version
                END
              ),
              (
                CASE
                  WHEN 'client_name' = ANY(group_bys) THEN client_name
                END
              ),
              (
                CASE
                  WHEN 'client_type' = ANY(group_bys) THEN client_type
                END
              ),
              (
                CASE
                  WHEN 'client_version' = ANY(group_bys) THEN client_version
                END
              ),
              (
                CASE
                  WHEN 'client_engine' = ANY(group_bys) THEN client_engine
                END
              ),
              (
                CASE
                  WHEN 'device_brand' = ANY(group_bys) THEN device_brand
                END
              ),
              (
                CASE
                  WHEN 'device_type' = ANY(group_bys) THEN device_type
                END
              ),
              (
                CASE
                  WHEN 'device_model' = ANY(group_bys) THEN device_model
                END
              ),
              (
                CASE
                  WHEN 'referrer' = ANY(group_bys) THEN referrer
                END
              ),
              (
                CASE
                  WHEN 'event_type' = ANY(group_bys) THEN event_type
                END
              ),
              (
                CASE
                  WHEN 'event_value' = ANY(group_bys) THEN event_value
                END
              ),
              (
                CASE
                  WHEN 'protocol' = ANY(group_bys) THEN protocol
                END
              ),
              (
                CASE
                  WHEN 'pathname' = ANY(group_bys) THEN pathname
                END
              ),
              (
                CASE
                  WHEN 'updated_at' = ANY(group_bys) THEN updated_at
                END
              ) $ function $

When I run

select session_groupings('{country}', '{"project_id": {"_eq": "951f4001-36fc-4bb7-9d87-e37bd4c56502"},"created_at": {"_gte": "05-10-2021" ,"_lte": "06-10-2021" }}')

This gives me the right results.
But when I run it with API explorer the results are wrong
I am calling it like

query MyQuery($sessionWhere: json, $group_bys: _text) {
  session_groupings(args: {sessionWhere: $sessionWhere, group_bys: $group_bys}) {
    country_name {
      name
    }
    count
  }
}

then the variables are like so

{
  "group_bys": "{country}",
  "sessionWhere": {
    "project_id": {"_eq": "951f4001-36fc-4bb7-9d87-e37bd4c56502"},
    "created_at": {"_gte": "05-10-2021" ,"_lte": "06-10-2021" }
  }
}

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the public.session_groupings PostgreSQL function and reproduce the discrepancy in the SQL editor and GraphQL Explorer. Compare the GraphQL request and returned result with the function's SQL response; done means the custom function returns the expected data through GraphQL, with a focused reproduction or regression test if the repository provides one.

Written by the indexing model from the issue text.

Assessment

Tech stack
graphql, postgresql
Domain
api, databases
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.