tywalch/electrodb

Dynamo throws Invalid FilterExpression error on a collection query due to redundant parentheses

Euclidean-Dev opened this issue ยท 10 comments

Describe the bug
When querying a collection, the dynamodb client throws an error concerning the filter expression having more parentheses than needed. As a workaround, by passing in an edited filter expression in the params object, the query succeeds.

i.e.

 .go({
	params: {
		FilterExpression: "(#__edb_e__ = :__edb_e___client AND #__edb_v__ = :__edb_v___client) OR (#__edb_e__ = :__edb_e___session AND #__edb_v__ = :__edb_v___session)"
	}
})

Note that v3 of the AWS SDK is being used:

export * as Dynamo from "./dynamo";

import { type EntityConfiguration } from "electrodb";
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient } from "@aws-sdk/lib-dynamodb";
import { Table } from "sst/node/table";

const Client = new DynamoDBClient({ region: "us-east-1" });
export const DocumentClient = DynamoDBDocumentClient.from(Client, {
	marshallOptions: {
		convertEmptyValues: true
	}
});

export const Configuration: EntityConfiguration = {
	table: Table.table.tableName,
	client: DocumentClient
};

AWS SDK Version
3.319.0

ElectroDB Version
2.5.1

Expected behavior
The generated filterExpression shouldn't have the outer set of parentheses.

Errors

{
  KeyConditionExpression: '#pk = :pk and begins_with(#sk1, :sk1)',
  TableName: 'table',
  ExpressionAttributeNames: {
    '#pk': 'pk',
    '#sk1': 'sk',
    '#__edb_e__': '__edb_e__',
    '#__edb_v__': '__edb_v__'
  },
  ExpressionAttributeValues: {
    ':pk': '$app#practitionerid_123',
    ':sk1': '$bookings',
    ':__edb_e___client': 'Client',
    ':__edb_v___client': '1',
    ':__edb_e___session': 'Session',
    ':__edb_v___session': '1'
  },
  FilterExpression: '((#__edb_e__ = :__edb_e___client AND #__edb_v__ = :__edb_v___client) OR (#__edb_e__ = :__edb_e___session AND #__edb_v__ = :__edb_v___session))'
}

ElectroError: Error thrown by DynamoDB client: "Invalid FilterExpression: The expression has redundant parentheses;" -

Hey @Euclidean-Dev ๐Ÿ‘‹

Are you able to share your model and the query that recreates this?

Hey @tywalch ! Yep, here's the playground link...

@Euclidean-Dev are you able to put together an example where DynamoDB throws? I recreated your example and executed it successfully (the client did not throw an exception) with both the v2 client and v3 client here:

https://gist.github.com/tywalch/6ca99d717189af78591f7308e8658283

Hi @tywalch.

Hmmm. This is very strange.

So I just now tried a couple of things to see whether I could narrow it down some more. And noticed that it only throws the redundant parentheses error if I do the following:

console.log(query.params());
const clients = await query.go();

But it doesn't throw if I comment out the console.log?

//console.log(query.params());
const clients = await query.go();

This is because you're calling a terminal operation ("go" and "params") twice on the same chain "query"

Ah! Sorry! Of course it is, the error response confused me and I totally missed that. Thanks @tywalch

This ticket is good though because I've seen someone else do this once as well, so I think there are improvements that could be made here ๐Ÿ‘

Cool! I don't want to waste any of your time. You're a legend! I've not looked at electrodb's source yet but maybe even something simple to prompt as a reminder could be good for us plebs. ๐Ÿ˜‚

    if (this.terminalOperationCalled) {
      throw new Error("Terminal operation (go or params) has already been called on this query chain.");
    }

@Euclidean-Dev
A fix for this is in ElectroDB version 2.6.0 ๐Ÿ‘

Thanks @tywalch !! You da man!