Home Reference Source Test

src/modules/constructRelationalGraph.test.js

// add test cases for constructRelationalGraph

import {constructRelationalGraph} from './constructRelationalGraph';

describe('constructRelationalGraph', () => {
  /** @test {constructRelationalGraph} */
  it('should return the correct graph for a simple expression', () => {
    const expr = {
      selection: {
        arguments: {
          select: {
            cmp: {
              lhs: 'Doctor.id',
              op: '$eq',
              rhs: '1',
            },
          },
        },
        children: [
          {
            relation: 'Doctor',
          },
        ],
      },
    };
    const {graph, globalSelections} = constructRelationalGraph(expr);
    expect(graph).toEqual({
      Doctor: {
        selections: [
          {
            cmp: {
              lhs: 'Doctor.id',
              op: '$eq',
              rhs: '1',
            },
          },
        ],
        edges: {},
      },
    });
    expect(globalSelections).toEqual([]);
  });

  /** @test {constructRelationalGraph} */
  it('should return the correct global selections for simple expression', () => {
    const expr = {
      selection: {
        arguments: {
          select: {
            cmp: {
              lhs: '2',
              op: '$eq',
              rhs: '1',
            },
          },
        },
        children: [
          {
            relation: 'Doctor',
          },
        ],
      },
    };
    const {globalSelections} = constructRelationalGraph(expr);
    expect(globalSelections).toEqual([{cmp: {lhs: '2', op: '$eq', rhs: '1'}}]);
  });

  /** @test {constructRelationalGraph} */
  it('should correctly parse multiple selections with and operator', () => {
    const expr = {
      selection: {
        arguments: {
          select: {
            and: {
              clauses: [
                {
                  cmp: {
                    lhs: 'Doctor.id',
                    op: '$eq',
                    rhs: '1',
                  },
                },
                {
                  cmp: {
                    lhs: 'Doctor.firstName',
                    op: '$eq',
                    rhs: '2',
                  },
                },
              ],
            },
          },
        },
        children: [
          {
            relation: 'Doctor',
          },
        ],
      },
    };
    const {graph, globalSelections} = constructRelationalGraph(expr);
    expect(graph).toEqual({
      Doctor: {
        selections: [
          {
            cmp: {
              lhs: 'Doctor.id',
              op: '$eq',
              rhs: '1',
            },
          },
          {
            cmp: {
              lhs: 'Doctor.firstName',
              op: '$eq',
              rhs: '2',
            },
          },
        ],
        edges: {},
      },
    });
    expect(globalSelections).toEqual([]);
  });

  it('should correctly parse multiple selections with and operator and global selections', () => {
    const expr = {
      selection: {
        arguments: {
          select: {
            and: {
              clauses: [
                {
                  cmp: {
                    lhs: 'Doctor.id',
                    op: '$eq',
                    rhs: '1',
                  },
                },
                {
                  cmp: {
                    lhs: 'Doctor.firstName',
                    op: '$eq',
                    rhs: '2',
                  },
                },
                {
                  cmp: {
                    lhs: '2',
                    op: '$eq',
                    rhs: '2',
                  },
                },
              ],
            },
          },
        },
        children: [
          {
            relation: 'Doctor',
          },
        ],
      },
    };
    const {graph, globalSelections} = constructRelationalGraph(expr);
    expect(graph).toEqual({
      Doctor: {
        selections: [
          {
            cmp: {
              lhs: 'Doctor.id',
              op: '$eq',
              rhs: '1',
            },
          },
          {
            cmp: {
              lhs: 'Doctor.firstName',
              op: '$eq',
              rhs: '2',
            },
          },
        ],
        edges: {},
      },
    });
    expect(globalSelections).toEqual([{cmp: {lhs: '2', op: '$eq', rhs: '2'}}]);
  });

  it('should handle invalid selection operator types like "or"', () => {
    const expr = {
      selection: {
        arguments: {
          select: {
            or: {
              clauses: [
                {
                  cmp: {
                    lhs: 'Doctor.id',
                    op: '$eq',
                    rhs: '1',
                  },
                },
                {
                  cmp: {
                    lhs: 'Doctor.firstName',
                    op: '$eq',
                    rhs: '2',
                  },
                },
              ],
            },
          },
        },
        children: [
          {
            relation: 'Doctor',
          },
        ],
      },
    };
    const {graph, globalSelections} = constructRelationalGraph(expr);
    expect(graph).toEqual({
      Doctor: {
        selections: [],
        edges: {},
      },
    });
    expect(globalSelections).toEqual([]);
  });

  it('should handle simple join expressions with selection clauses', () => {
    const expr = {
      selection: {
        arguments: {
          select: {
            cmp: {
              lhs: 'Doctor.id',
              op: '$eq',
              rhs: '1',
            },
          },
        },
        children: [
          {
            join: {
              left: {
                relation: 'Doctor',
              },
              right: {
                relation: 'Patient',
              },
              type: 'inner',
              condition: {
                cmp: {
                  lhs: 'Doctor.id',
                  op: '$eq',
                  rhs: 'Patient.primaryDoctor',
                },
              },
            },
          },
        ],
      },
    };
    const {graph, globalSelections} = constructRelationalGraph(expr);
    expect(graph).toEqual({
      Doctor: {
        selections: [
          {
            cmp: {
              lhs: 'Doctor.id',
              op: '$eq',
              rhs: '1',
            },
          },
        ],
        edges: {
          Patient: [
            {
              condition: {
                lhs: 'Doctor.id',
                op: '$eq',
                rhs: 'Patient.primaryDoctor',
              },
              type: 'inner',
            },
          ],
        },
      },
      Patient: {
        selections: [],
        edges: {
          Doctor: [
            {
              condition: {
                lhs: 'Doctor.id',
                op: '$eq',
                rhs: 'Patient.primaryDoctor',
              },
              type: 'inner',
            },
          ],
        },
      },
    });
    expect(globalSelections).toEqual([]);
  });

  it('should handle complex join expressions with selection clauses', () => {
    const expr = {
      selection: {
        arguments: {
          select: {
            and: {
              clauses: [
                {
                  cmp: {
                    lhs: 'Doctor.id',
                    op: '$eq',
                    rhs: '1',
                  },
                },
                {
                  cmp: {
                    lhs: 'Patient.id',
                    op: '$eq',
                    rhs: '2',
                  },
                },
              ],
            },
          },
        },
        children: [
          {
            join: {
              left: {
                join: {
                  left: {
                    relation: 'Doctor',
                  },
                  right: {
                    relation: 'Patient',
                  },
                  type: 'inner',
                  condition: {
                    cmp: {
                      lhs: 'Doctor.id',
                      op: '$eq',
                      rhs: 'Patient.primaryDoctor',
                    },
                  },
                },
              },
              right: {
                relation: 'Department',
              },
              type: 'inner',
              condition: {
                cmp: {
                  lhs: 'Doctor.departmentId',
                  op: '$eq',
                  rhs: 'Department.id',
                },
              },
            },
          },
        ],
      },
    };
    const {graph, globalSelections} = constructRelationalGraph(expr);
    expect(graph).toEqual({
      Doctor: {
        selections: [
          {
            cmp: {
              lhs: 'Doctor.id',
              op: '$eq',
              rhs: '1',
            },
          },
        ],
        edges: {
          Patient: [
            {
              condition: {
                lhs: 'Doctor.id',
                op: '$eq',
                rhs: 'Patient.primaryDoctor',
              },
              type: 'inner',
            },
          ],
          Department: [
            {
              condition: {
                lhs: 'Doctor.departmentId',
                op: '$eq',
                rhs: 'Department.id',
              },
              type: 'inner',
            },
          ],
        },
      },
      Patient: {
        selections: [
          {
            cmp: {
              lhs: 'Patient.id',
              op: '$eq',
              rhs: '2',
            },
          },
        ],
        edges: {
          Doctor: [
            {
              condition: {
                lhs: 'Doctor.id',
                op: '$eq',
                rhs: 'Patient.primaryDoctor',
              },
              type: 'inner',
            },
          ],
        },
      },
      Department: {
        selections: [],
        edges: {
          Doctor: [
            {
              condition: {
                lhs: 'Doctor.departmentId',
                op: '$eq',
                rhs: 'Department.id',
              },
              type: 'inner',
            },
          ],
        },
      },
    });
    expect(globalSelections).toEqual([]);
  });

  it('should handle cyclic join expressions with selection clauses', () => {
    const expr = {
      selection: {
        arguments: {
          select: {
            and: {
              clauses: [
                {
                  cmp: {
                    lhs: 'Doctor.id',
                    op: '$eq',
                    rhs: '1',
                  },
                },
                {
                  cmp: {
                    lhs: 'Patient.id',
                    op: '$eq',
                    rhs: '2',
                  },
                },
              ],
            },
          },
        },
        children: [
          {
            join: {
              left: {
                join: {
                  left: {
                    relation: 'Doctor',
                  },
                  right: {
                    relation: 'Patient',
                  },
                  type: 'inner',
                  condition: {
                    cmp: {
                      lhs: 'Doctor.id',
                      op: '$eq',
                      rhs: 'Patient.primaryDoctor',
                    },
                  },
                },
              },
              right: {
                relation: 'Department',
              },
              type: 'inner',
              condition: {
                and: {
                  clauses: [
                    {
                      cmp: {
                        lhs: 'Doctor.departmentId',
                        op: '$eq',
                        rhs: 'Department.id',
                      },
                    },
                    {
                      cmp: {
                        lhs: 'Patient.id',
                        op: '$eq',
                        rhs: 'Department.id',
                      },
                    },
                  ],
                },
              },
            },
          },
        ],
      },
    };
    const {graph, globalSelections} = constructRelationalGraph(expr);
    expect(graph).toEqual({
      Doctor: {
        selections: [
          {
            cmp: {
              lhs: 'Doctor.id',
              op: '$eq',
              rhs: '1',
            },
          },
        ],
        edges: {
          Patient: [
            {
              condition: {
                lhs: 'Doctor.id',
                op: '$eq',
                rhs: 'Patient.primaryDoctor',
              },
              type: 'inner',
            },
          ],
          Department: [
            {
              condition: {
                lhs: 'Doctor.departmentId',
                op: '$eq',
                rhs: 'Department.id',
              },
              type: 'inner',
            },
          ],
        },
      },
      Patient: {
        selections: [
          {
            cmp: {
              lhs: 'Patient.id',
              op: '$eq',
              rhs: '2',
            },
          },
        ],
        edges: {
          Doctor: [
            {
              condition: {
                lhs: 'Doctor.id',
                op: '$eq',
                rhs: 'Patient.primaryDoctor',
              },
              type: 'inner',
            },
          ],
          Department: [
            {
              condition: {
                lhs: 'Patient.id',
                op: '$eq',
                rhs: 'Department.id',
              },
              type: 'inner',
            },
          ],
        },
      },
      Department: {
        selections: [],
        edges: {
          Doctor: [
            {
              condition: {
                lhs: 'Doctor.departmentId',
                op: '$eq',
                rhs: 'Department.id',
              },
              type: 'inner',
            },
          ],
          Patient: [
            {
              condition: {
                lhs: 'Patient.id',
                op: '$eq',
                rhs: 'Department.id',
              },
              type: 'inner',
            },
          ],
        },
      },
    });
    expect(globalSelections).toEqual([]);
  });

  it('should not optimize for edge case join conditions', () => {
    const expr1 = {
      selection: {
        arguments: {
          select: {
            cmp: {
              lhs: 'Doctor.id',
              op: '$eq',
              rhs: '1',
            },
          },
        },
        children: [
          {
            join: {
              left: {
                join: {
                  left: {
                    relation: 'Doctor',
                  },
                  right: {
                    relation: 'Patient',
                  },
                  type: 'inner',
                  condition: {
                    cmp: {
                      lhs: 'Doctor.id',
                      op: '$eq',
                      rhs: 'Patient.primaryDoctor',
                    },
                  },
                },
              },
              right: {
                relation: 'Department',
              },
              type: 'inner',
              condition: {
                cmp: {
                  lhs: '1',
                  op: '$eq',
                  rhs: '1',
                },
              },
            },
          },
        ],
      },
    };

    const expr2 = {
      selection: {
        arguments: {
          select: {
            cmp: {
              lhs: 'Doctor.id',
              op: '$eq',
              rhs: '1',
            },
          },
        },
        children: [
          {
            join: {
              left: {
                join: {
                  left: {
                    relation: 'Doctor',
                  },
                  right: {
                    relation: 'Patient',
                  },
                  type: 'inner',
                  condition: {
                    cmp: {
                      lhs: 'Doctor.id',
                      op: '$eq',
                      rhs: 'Patient.primaryDoctor',
                    },
                  },
                },
              },
              right: {
                relation: 'Department',
              },
              type: 'inner',
              condition: '1',
            },
          },
        ],
      },
    };
    // expect empty graph and global selections
    const {canOptimize: canOptimizeExpr1} = constructRelationalGraph(expr1);
    const {canOptimize: canOptimizeExpr2} = constructRelationalGraph(expr2);
    expect(canOptimizeExpr1).toEqual(false);
    expect(canOptimizeExpr2).toEqual(false);
  });

  it('should not optimize for multi-table join query', () => {
    const expr = {
      selection: {
        arguments: {
          select: {
            cmp: {
              lhs: 'Doctor.id',
              op: '$eq',
              rhs: '1',
            },
          },
        },
        children: [
          {
            join: {
              left: {
                relation: 'Doctor',
              },
              right: {
                relation: 'Patient',
              },
              type: 'inner',
              condition: {
                cmp: {
                  lhs: 'Doctor.id',
                  op: '$eq',
                  rhs: 'Patient.primaryDoctor',
                },
              },
            },
          },
          {
            join: {
              left: {
                relation: 'Patient',
              },
              right: {
                relation: 'Visit',
              },
              type: 'inner',
              condition: {
                cmp: {
                  lhs: 'Patient.id',
                  op: '$eq',
                  rhs: 'Visit.patient',
                },
              },
            },
          },
        ],
      },
    };
    const {canOptimize} = constructRelationalGraph(expr);
    expect(canOptimize).toEqual(false);
  });
});