microsoft / microsoft/multiclouddb-sdk-for-java

[BUG] Apply the portable numeric contract to query literals and parameters

Open
#108 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug java
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:

  1. ExpressionParser.toLiteral(...) converts decimal literals with Double.parseDouble(...) and parses integral literals as Integer/Long. Precision may be lost before validation, and an integer outside the long range can escape as an unnormalized parse failure.
  2. DefaultMulticloudDbClient.isLegacyExpression(...) treats an expression() value beginning with SELECT, 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 as nativeExpression().

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

  1. Submit a portable expression containing a high-precision decimal or an integral literal outside the signed-64-bit range.
  2. Compare it with the same value supplied as a parameter.
  3. Submit an otherwise portable expression() containing one of the legacy heuristic tokens.
  4. 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.