microsoft / microsoft/multiclouddb-sdk-for-java
[BUG] Apply the portable numeric contract to query literals and parameters
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 7
- Forks
- 7
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 1
Description
Bug description
Portable query numeric literals and parameters can bypass a common numeric boundary in two independent ways:
ExpressionParser.toLiteral(...)converts decimal literals withDouble.parseDouble(...)and parses integral literals asInteger/Long. Precision may be lost before validation, and an integer outside thelongrange can escape as an unnormalized parse failure.DefaultMulticloudDbClient.isLegacyExpression(...)treats anexpression()value beginning withSELECT, containing:, or beginning with#as an opaque provider expression. That path bypasses portable parsing, capability checks, validation, and parameter normalization. Explicit native passthrough already exists asnativeExpression().
This predates #105 and should be fixed separately from partial update.
Provider
- Azure Cosmos DB
- Amazon DynamoDB
- Google Cloud Spanner
- Not provider-specific
Reproduction steps
- Submit a portable expression containing a high-precision decimal or an integral literal outside the signed-64-bit range.
- Compare it with the same value supplied as a parameter.
- Submit an otherwise portable
expression()containing one of the legacy heuristic tokens. - Observe that the requests do not consistently traverse the same parser/validator/translator path.
Expected behaviour
expression() always uses the portable pipeline. Numeric literals retain their source precision until the shared numeric contract validates/canonicalizes them. Only nativeExpression() performs provider-native passthrough.
Actual behaviour
Numeric literals are eagerly narrowed, and the legacy heuristic silently sends some expression() requests directly to a provider.
Acceptance criteria
- Numeric literal text is parsed without pre-validation precision loss.
- Literal and parameter values use the same portable numeric rules and structured errors.
- Any value-changing normalization follows the shared warning policy.
-
expression()never silently becomes a native expression. -
nativeExpression()remains the explicit provider-specific escape hatch. - Parser and cross-provider translation tests cover decimal precision, range boundaries, and legacy-token cases.
Additional context
Related umbrella issues: #37 and #64.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading ExpressionParser.toLiteral(...) and DefaultMulticloudDbClient.isLegacyExpression(...), then trace how portable expressions reach validation and provider translation. Run or extend the parser and cross-provider translation tests for decimal precision, range boundaries, parameters, and legacy-token cases. Done means expression() follows the portable path while nativeExpression() remains the explicit passthrough.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend-api-design, databases, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 50/100