Skip to content

Add btree index filters to the C# sdk with codegen#1848

Closed
lcodes wants to merge 1 commit intomasterfrom
jeremie/btree-index-bounds-cs
Closed

Add btree index filters to the C# sdk with codegen#1848
lcodes wants to merge 1 commit intomasterfrom
jeremie/btree-index-bounds-cs

Conversation

@lcodes
Copy link
Copy Markdown
Contributor

@lcodes lcodes commented Oct 14, 2024

Description of Changes

Adds support for multi-column btree index filtering in the C# client

  • codegen emitting Filter() overloads in the index handles
  • codegen emitting BTree storage and comparison operators
  • runtime changes to make Address and Identity comparable

API and ABI breaking changes

No breaks.

Expected complexity level and risk

Most complexity is in the codegen, the runtime behavior is straightforward; a SortedSet<> per btree with a comparator matching its key columns, and Filter() methods querying that sorted set with min/max values derived from the table row type.

Testing

@bfops
Copy link
Copy Markdown
Collaborator

bfops commented Oct 15, 2024

What's the testing for this change? It looks like the test suite is failing - do existing tests need updating, and/or does it have new tests for the new behavior?

@RReverser
Copy link
Copy Markdown
Contributor

This needs rebase now that Identity/Address representations have changed + snapshot regen.

@bfops bfops added release-rc1 release-any To be landed in any release window and removed release-rc1 labels Oct 21, 2024
@jdetter jdetter removed their request for review November 8, 2024 18:10
@lcodes lcodes force-pushed the jeremie/btree-index-bounds-cs branch from 067ffe6 to f1eedf0 Compare November 11, 2024 18:09
let csharp_field_name_pascal = field_name.replace("r#", "").to_case(Case::Pascal);
let range = match field_type {
AlgebraicType::Product(pt) =>
if pt.elements[0].name == Some("__address_bytes".into()) { ("Address.MinValue", "Address.MaxValue") }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should reuse the is_address and other helpers so that we don't hardcode those names in more places.

Comment on lines +454 to +467
AlgebraicType::I8 => ("sbyte.MinValue", "sbyte.MaxValue"),
AlgebraicType::U8 => ("byte.MinValue", "byte.MaxValue"),
AlgebraicType::I16 => ("short.MinValue", "short.MaxValue"),
AlgebraicType::U16 => ("ushort.MinValue", "ushort.MaxValue"),
AlgebraicType::I32 => ("int.MinValue", "int.MaxValue"),
AlgebraicType::U32 => ("uint.MinValue", "uint.MaxValue"),
AlgebraicType::I64 => ("long.MinValue", "long.MaxValue"),
AlgebraicType::U64 => ("ulong.MinValue", "ulong.MaxValue"),
AlgebraicType::I128 => ("I128.MinValue", "I128.MaxValue"),
AlgebraicType::U128 => ("U128.MinValue", "U128.MaxValue"),
AlgebraicType::I256 => ("I256.MinValue", "I256.MaxValue"),
AlgebraicType::U256 => ("U256.MinValue", "U256.MaxValue"),
AlgebraicType::F32 => ("float.MinValue", "float.MaxValue"),
AlgebraicType::F64 => ("double.MinValue", "double.MaxValue"),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should be able to use is_integer() || is_float() + scalar_or_string_name instead of repeating those.

if pt.elements[0].name == Some("__address_bytes".into()) { ("Address.MinValue", "Address.MaxValue") }
else if pt.elements[0].name == Some("__identity_bytes".into()) { ("Identity.MinValue", "Identity.MaxValue") }
else { todo!() },
AlgebraicType::String => ("\"\"", "\"\\uFFFF\\uFFFF\""),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this is correct. There isn't really a maximum string value, is there?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will probably require some logic revamp to account for types without a maximum.

Comment on lines +490 to +494
writeln!(output, "if ({0} != 0) return {0};", field.csharp_field_name_pascal);
},
_ => {
writeln!(output, "if (a.{0} < b.{0}) return -1;", field.csharp_field_name_pascal);
writeln!(output, "if (a.{0} > b.{0}) return 1;", field.csharp_field_name_pascal);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this shouldn't be necessary, you can just return the result of String.Compare as-is.

match field.field_type {
AlgebraicType::Product(_) => {
writeln!(output, "var {0} = a.{0}.CompareTo(b.{0});", field.csharp_field_name_pascal);
writeln!(output, "if ({0} != 0) return {0};", field.csharp_field_name_pascal);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be necessary, you can just return result of CompareTo.

@CLAassistant
Copy link
Copy Markdown

CLAassistant commented May 3, 2025

CLA assistant check
All committers have signed the CLA.

@cloutiertyler cloutiertyler added the close-stale-pr-create-issue Indicates that the PR is substantially out of date, and should become an issue to reimplement. label Apr 13, 2026
@clockwork-labs-bot
Copy link
Copy Markdown
Collaborator

Closing per the close-stale-pr-create-issue label. This work is now tracked in #4788 for reimplementation on a fresh branch.

Replacement issue: #4788

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

close-stale-pr-create-issue Indicates that the PR is substantially out of date, and should become an issue to reimplement. release-any To be landed in any release window

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants