Skip to content

FINERACT-2713: Bind untyped report parameters numerically so Postgres cascades work - #6185

Open
oluexpert99 wants to merge 1 commit into
apache:developfrom
TECHSERVICES-LIMITED:bugfix/FINERACT-2713
Open

FINERACT-2713: Bind untyped report parameters numerically so Postgres cascades work#6185
oluexpert99 wants to merge 1 commit into
apache:developfrom
TECHSERVICES-LIMITED:bugfix/FINERACT-2713

Conversation

@oluexpert99

Copy link
Copy Markdown
Contributor
 - Since FINERACT-2624 switched report-parameter substitution from string interpolation to
    JDBC bind variables, a placeholder that appears in a report's SQL but is not one of that
    report's own declared parameters binds as a String. On PostgreSQL, comparing a bigint
    column to a bound character varying raises "operator does not exist: bigint = character
    varying" and the query fails with HTTP 403; MySQL and MariaDB coerce the types silently,
    which is why CI does not see it.
  - The stock loanOfficerIdSelectAll option lookup is the clearest case. Its SQL filters
    "... and o.id = ${officeId}", where officeId is supplied by the parent parameter, so
    ReadReportingServiceImpl.getSQLtoRun loads the format types of loanOfficerIdSelectAll,
    finds no entry for officeId, and castParamValue falls through to returning the raw
    String. Every report whose Loan Officer dropdown cascades off office is therefore empty
    on a PostgreSQL deployment.
  - When no format type is declared, infer a numeric bind for a plain integer value so
    strict engines compare correctly. The inference is deliberately narrow: the value must
    match -?(0|[1-9]\d*), so currency codes, free text and identifiers carrying leading
    zeros such as 000123 keep their String binding and are not mangled into numbers.
    Declared NUMBER, INTEGER and DATE types are untouched.
  - Add ReadReportingServiceImplTest, which captures the values bound for a report whose SQL
    cascades on ${officeId}: an untyped "1" must arrive as a Long, while "USD" and "000123"
    must stay Strings and a declared number type must keep working. The first case fails on
    the unfixed code with "expected: java.lang.Long<1> but was: java.lang.String<1>"; the
    other three assert the narrowness of the inference and hold either way by design.

Description

Describe the changes made and why they were made. (Ignore if these details are present on the associated Apache Fineract JIRA ticket.)

Checklist

Please make sure these boxes are checked before submitting your pull request - thanks!

  • Write the commit message as per our guidelines
  • Acknowledge that we will not review PRs that are not passing the build ("green") - it is your responsibility to get a proposed PR to pass the build, not primarily the project's maintainers.
  • Create/update unit or integration tests for verifying the changes made.
  • Follow our coding conventions.
  • Add required Swagger annotation and update API documentation at fineract-provider/src/main/resources/static/legacy-docs/apiLive.htm with details of any API changes
  • This PR must not be a "code dump". Large changes can be made in a branch, with assistance. Ask for help on the developer mailing list.
  • If merging this PR resolves a JIRA issue, I will mark that issue as resolved and set "Fix Version/s" appropriately.

Your assigned reviewer(s) will follow our guidelines for code reviews.

… cascades work

- Since FINERACT-2624 switched report-parameter substitution from string interpolation to
  JDBC bind variables, a placeholder that appears in a report's SQL but is not one of that
  report's own declared parameters binds as a String. On PostgreSQL, comparing a bigint
  column to a bound character varying raises "operator does not exist: bigint = character
  varying" and the query fails with HTTP 403; MySQL and MariaDB coerce the types silently,
  which is why CI does not see it.
- The stock loanOfficerIdSelectAll option lookup is the clearest case. Its SQL filters
  "... and o.id = ${officeId}", where officeId is supplied by the parent parameter, so
  ReadReportingServiceImpl.getSQLtoRun loads the format types of loanOfficerIdSelectAll,
  finds no entry for officeId, and castParamValue falls through to returning the raw
  String. Every report whose Loan Officer dropdown cascades off office is therefore empty
  on a PostgreSQL deployment.
- When no format type is declared, infer a numeric bind for a plain integer value so
  strict engines compare correctly. The inference is deliberately narrow: the value must
  match -?(0|[1-9]\d*), so currency codes, free text and identifiers carrying leading
  zeros such as 000123 keep their String binding and are not mangled into numbers.
  Declared NUMBER, INTEGER and DATE types are untouched.
- Add ReadReportingServiceImplTest, which captures the values bound for a report whose SQL
  cascades on ${officeId}: an untyped "1" must arrive as a Long, while "USD" and "000123"
  must stay Strings and a declared number type must keep working. The first case fails on
  the unfixed code with "expected: java.lang.Long<1> but was: java.lang.String<1>"; the
  other three assert the narrowness of the inference and hold either way by design.

Signed-off-by: oluexpert99 <farooq@techservicehub.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant