edgedb-js icon indicating copy to clipboard operation
edgedb-js copied to clipboard

InternalServerError: more than one row returned by a subquery used as an expression

Open izakfilmalter opened this issue 2 years ago • 1 comments

Got another doozy. Link properties keep killing me. I have the following:

Schema:

module default {
  global current_user_id -> uuid;

  scalar type ParticipantTag extending enum<'invited', 'applied'>;

  type Hangout Location {
    required property name -> str;

    required multi link participants extending participant -> User;
  }

  abstract link participant {
    property tag -> ParticipantTag;
  }

  type User {
    property name -> str;

    multi link hangouts := .<participants[is Hangout];
  }
}

Query:

const query = e.select(e.Hangout, (x) => ({
  filter: e.op(x.id, '=', e.uuid(hangoutId)),
  participants: (y) => ({
    '@tag': true,
  }),
}))

EdgeQL:

WITH
  __scope_0_Hangout := DETACHED default::Hangout
SELECT __scope_0_Hangout {
  participants := assert_exists((
    WITH
      __scope_1_User := (
        SELECT __scope_0_Hangout.participants {
          __linkprop_tag := __scope_0_Hangout.participants@tag
        }
      )
    SELECT __scope_1_User {
      single @tag := __scope_1_User.__linkprop_tag
    }
  ))
}

If I have a single participant, the query is successful. If I have more than one, I get the following error: InternalServerError: more than one row returned by a subquery used as an expression.

If I change the query to not get the link property, and just return name:

const query = e.select(e.Hangout, (x) => ({
  filter: e.op(x.id, '=', e.uuid(hangoutId)),
  participants: (y) => ({
    name: true,
  }),
}))

It works with several participants.

**Versions

  • OS: MacOS 12.2 (21D49)
  • EdgeDB version: 2.1+52c90a7
  • edgedb-js version: e.g. 0.20.10

I think this might be related to https://github.com/edgedb/edgedb/issues/3706

izakfilmalter avatar Aug 18 '22 19:08 izakfilmalter

After poking around some, I was able to get the following working:

const query = e.select(e.Hangout, (x) => ({
  filter: e.op(x.id, '=', e.uuid(hangoutId)),
  foo: e.select(x.participants, (x) => ({
    '@tag': true,
  })),
}))

EdgeQL:

WITH
  __scope_0_Hangout := DETACHED default::Hangout
SELECT __scope_0_Hangout {
  multi foo := (
    WITH
      __scope_1_User := (
        SELECT __scope_0_Hangout.participants {
          __linkprop_tag := __scope_0_Hangout.participants@tag
        }
      )
    SELECT __scope_1_User {
      single @tag := __scope_1_User.__linkprop_tag
    }
  )
}

Seems like the I need to use a free object till this gets resolved.

izakfilmalter avatar Aug 18 '22 19:08 izakfilmalter

This is a server bug, https://github.com/edgedb/edgedb/issues/5179, fixed by https://github.com/edgedb/edgedb/pull/5182

msullivan avatar Mar 15 '23 05:03 msullivan