legend-studio icon indicating copy to clipboard operation
legend-studio copied to clipboard

Bug: Unable to open query builder form editor for multiply `Boolean` expression of an explosion property.

Open MauricioUyaguari opened this issue 2 years ago • 1 comments

Similar issues

  • [X] I have searched and found no existing similar issues

How are you using Studio?

Legend Query

Current and expected behavior

When editing a query lambda on an explosion property with multiple booleans, the rendering of the query builder will fail with Can't display query in form mode due to: Can't process filter expression: no compatible filter operator processer available from plugins. We should be able to process the given lambda. If required we may need to enable derived filter expression support

Steps to reproduce

  • Open query builder by right clicking on model::Person
  • Go to query builder text mode
  • Copy below lambda and the query builder. Query
{date: Date[1],brands: String[*]|model::Person.all()->filter(
  x|$x.firm->exists(
    x_1|$x_1.brand->in(
      $brands
    ) &&
      ($x_1.date ==
      $date)
  )
)->project(
  [
    x|$x.name
  ],
  ['name']
)}

Model data

###Relational
Database store::MyDatabase
(
  Schema MySchema
  (
    Table PersonTable1
    (
      Brand VARCHAR(128) NOT NULL,
      NAME VARCHAR(128),
      LASTNAME VARCHAR(128),
      Nick_Name VARCHAR(128) NOT NULL,
      Hq1_State VARCHAR(128),
      Hq1_Street VARCHAR(128),
      Hq2_State VARCHAR(128),
      Hq2_Street VARCHAR(128),
      Value DOUBLE,
      Locations INTEGER,
      Found_Date DATE PRIMARY KEY,
      ID VARCHAR(128) PRIMARY KEY
    )
    Table PersonTable2
    (
      Brand VARCHAR(128) NOT NULL,
      NAME VARCHAR(128),
      LASTNAME VARCHAR(128),
      Nick_Name VARCHAR(128) NOT NULL,
      Hq1_State VARCHAR(128),
      Hq1_Street VARCHAR(128),
      Hq2_State VARCHAR(128),
      Hq2_Street VARCHAR(128),
      Value DOUBLE,
      Locations INTEGER,
      Found_Date DATE PRIMARY KEY,
      ID VARCHAR(128) PRIMARY KEY
    )
  )
)


###Pure
Class model::Firm
{
  hq1: model::HQ[0..1];
  hq2: model::HQ[0..1];
  brand: String[1];
  value: Float[1];
  date: Date[1];
  locations: Integer[1];
}

Class model::HQ
{
  state: String[1];
  street: String[1];
}

Class model::Person
{
  name: String[1];
  lastName: String[1];
  nickName: String[1];
  firm: model::Firm[*];
}


###Mapping
Mapping mapping::MyMapping
(
  *model::Person: Operation
  {
    meta::pure::router::operations::union_OperationSetImplementation_1__SetImplementation_MANY_(person1,person2)
  }
  model::Person[person1]: Relational
  {
    ~primaryKey
    (
      [store::MyDatabase]MySchema.PersonTable1.Found_Date,
      [store::MyDatabase]MySchema.PersonTable1.ID
    )
    ~mainTable [store::MyDatabase]MySchema.PersonTable1
    name: [store::MyDatabase]MySchema.PersonTable1.NAME,
    lastName: [store::MyDatabase]MySchema.PersonTable1.LASTNAME,
    nickName: [store::MyDatabase]MySchema.PersonTable1.Nick_Name,
    firm
    (
      hq1
      (
        state: [store::MyDatabase]MySchema.PersonTable1.Hq1_State,
        street: [store::MyDatabase]MySchema.PersonTable1.Hq1_Street
      ),
      hq2
      (
        state: [store::MyDatabase]MySchema.PersonTable1.Hq2_State,
        street: [store::MyDatabase]MySchema.PersonTable1.Hq2_Street
      ),
      brand: [store::MyDatabase]MySchema.PersonTable1.Brand,
      locations: [store::MyDatabase]MySchema.PersonTable1.Locations,
      value: [store::MyDatabase]MySchema.PersonTable1.Value,
      date: [store::MyDatabase]MySchema.PersonTable1.Found_Date
    )
  }
  model::Person[person2]: Relational
  {
    ~primaryKey
    (
      [store::MyDatabase]MySchema.PersonTable2.Found_Date,
      [store::MyDatabase]MySchema.PersonTable2.ID
    )
    ~mainTable [store::MyDatabase]MySchema.PersonTable2
    name: [store::MyDatabase]MySchema.PersonTable2.NAME,
    lastName: [store::MyDatabase]MySchema.PersonTable2.LASTNAME,
    nickName: [store::MyDatabase]MySchema.PersonTable2.Nick_Name,
    firm
    (
      hq1
      (
        state: [store::MyDatabase]MySchema.PersonTable2.Hq1_State,
        street: [store::MyDatabase]MySchema.PersonTable2.Hq1_Street
      ),
      hq2
      (
        state: [store::MyDatabase]MySchema.PersonTable2.Hq2_State,
        street: [store::MyDatabase]MySchema.PersonTable2.Hq2_Street
      ),
      brand: [store::MyDatabase]MySchema.PersonTable2.Brand,
      locations: [store::MyDatabase]MySchema.PersonTable2.Locations,
      value: [store::MyDatabase]MySchema.PersonTable2.Value,
      date: [store::MyDatabase]MySchema.PersonTable2.Found_Date
    )
  }
)

Environment

Windows

Possible solution and workaround

Equivalent query grammar will work.

{date: Date[1],nickNames: String[*],brands: String[*]|model::Person.all()->filter(
  x|$x.firm->exists(
    x_1|$x_1.brand->in(
      $brands
    )
  ) &&
    ($x.firm->exists(
    x_1|$x_1.date ==
      $date
  ) &&
    $x.nickName->in(
    $nickNames
  ))
)->project(
  [
    x|$x.name
  ],
  ['name']
)}

Contribution

  • [X] I would like to work on the fix for this issue

MauricioUyaguari avatar Nov 04 '21 20:11 MauricioUyaguari

Main issue is query builder is not understanding multiple grouped expression within the exists. Query Builder throws an error for the below as its expecting a single expression within the exists

$x.firm->exists(
    x_1|$x_1.brand->in(
      $brands
    ) &&
      ($x_1.date ==
      $date)
  ) 

It does not throw for the same logical expression below which separates the below into 2 exist expressions.

$x.firm->exists(
    x_1|$x_1.brand->in(
      $brands
    )
  ) &&
    ($x.firm->exists(
    x_1|$x_1.date ==
      $date
  ) 

Thoughts on solution

  • [ ] During processing convert the first expression into the second
    • DrawbackDoesn't keep user intent.
    • Follows what we are doing in flattening grouped expression. Also maps to a corresponding supported UI component providing UI for the properties
  • [ ] Implement #627. Will deal with similar cases as above. Also if we choose not to even handle the above it will keep the user intent.

Solution could be both the implementation of 627 and the flatten on this expression. @akphi thoughts???

MauricioUyaguari avatar Nov 05 '21 18:11 MauricioUyaguari