[BUG] Datastore query fails to match identical timestamp
The deno-slack versions
"deno-slack-sdk/": "https://deno.land/x/[email protected]/",
"deno-slack-api/": "https://deno.land/x/[email protected]/",
Deno runtime version
deno 2.1.9 (stable, release, aarch64-apple-darwin)
v8 13.0.245.12-rusty
typescript 5.6.2
OS info
ProductName: macOS
ProductVersion: 15.2
BuildVersion: 24C101
Darwin Kernel Version 24.2.0: Fri Dec 6 19:02:41 PST 2024; root:xnu-11215.61.5~2/RELEASE_ARM64_T6030
Describe the bug
I'm trying to query a datastore for all items that share the same exact value for a timestamp field. A straight equals comparison fails. Providing a range succeeds, but bizarrely, only if the range is big enough.
Steps to reproduce
This is simplified from my app, but I reproduced the bug with just this datastore and the slack cli.
Datastore definition:
import { DefineDatastore, Schema } from "deno-slack-sdk/mod.ts";
const BugreportDatastore = DefineDatastore({
name: "bugreport",
primary_key: "channel_id",
attributes: {
channel_id: {
type: Schema.types.string,
},
batch_ts: {
type: Schema.slack.types.timestamp,
},
},
});
export interface ChannelData {
channel_id: string;
batch_ts: number;
}
export default BugreportDatastore;
Slack CLI steps with actual result:
% slack -w $WORKSPACE -a local datastore put --datastore bugreport '{
"item": {
"channel_id": "C12345ABC",
"batch_ts": 1742941666.812
}
}'
🎉 Stored below record in the datastore: bugreport
{
"batch_ts": 1742941666.812,
"channel_id": "C12345ABC"
}
% slack -w $WORKSPACE -a local datastore query '{
"datastore": "bugreport",
"expression": "#batch_ts = :batch_ts",
"expression_attributes": { "#batch_ts": "batch_ts" },
"expression_values": { ":batch_ts": 1742941666.812 }
}'
🎉 Retrieved 0 items from datastore: bugreport
% slack -w $WORKSPACE -a local datastore query '{
"datastore": "bugreport",
"expression": "#batch_ts BETWEEN :batch_ts1 AND :batch_ts2",
"expression_attributes": { "#batch_ts": "batch_ts" },
"expression_values": { ":batch_ts1": 1742941666, ":batch_ts2": 1742941667 }
}'
🎉 Retrieved 1 items from datastore: bugreport
{
"batch_ts": 1742941666.812,
"channel_id": "C12345ABC"
}
% slack -w $WORKSPACE -a local datastore query '{
"datastore": "bugreport",
"expression": "#batch_ts BETWEEN :batch_ts1 AND :batch_ts2",
"expression_attributes": { "#batch_ts": "batch_ts" },
"expression_values": { ":batch_ts1": 1742941666.81, ":batch_ts2": 1742941667.83 }
}'
🎉 Retrieved 0 items from datastore: bugreport
Expected result
All three queries should succeed.
Using Schema.types.number the behaviour is the same. Only with Schema.types.string was I able to get the query to work testing for equality. (That's fine for me in this instance as I only need exact matches.)
Interestingly, with using strings, the exact comparison succeeds whether I feed the expression value a string or a number, but the range behaviour seems really confusing. It's failing on numerical integers and numerical decimals with an integer value, but succeeding when either of those are presented as strings...
✅ "expression_values": { ":batch_ts1": "1742941666", ":batch_ts2": "1742941667" } ❌ "expression_values": { ":batch_ts1": 1742941666, ":batch_ts2": 1742941667 } ✅ "expression_values": { ":batch_ts1": "1742941666.81", ":batch_ts2": "1742941666.82" } ✅ "expression_values": { ":batch_ts1": 1742941666.81, ":batch_ts2": 1742941666.82 } ✅ "expression_values": { ":batch_ts1": "1742941666.0", ":batch_ts2": "1742941667.0" } ❌ "expression_values": { ":batch_ts1": 1742941666.0, ":batch_ts2": 1742941667.0 }
Hi @mfcarroll thanks for highlighting this 🥇 I was myself surprised by this behavior
As you may already know datastores follow the same syntax as DynamoDB, I believe this is the same underlying issue as boto3/#665
The suggested workaround is to store the float as a string and then use Decimal to cast it
Let me know if this workaround works for you but I'm afraid their isn't much more I could do to resolve this