Skip to content

Extract PL/SQL boolean conversion helpers in ProcedureCall#293

Merged
yahonda merged 1 commit into
rsim:masterfrom
yahonda:extract-plsql-boolean-helpers
May 13, 2026
Merged

Extract PL/SQL boolean conversion helpers in ProcedureCall#293
yahonda merged 1 commit into
rsim:masterfrom
yahonda:extract-plsql-boolean-helpers

Conversation

@yahonda
Copy link
Copy Markdown
Collaborator

@yahonda yahonda commented May 13, 2026

Summary

ProcedureCall had the same two-and-a-half boolean conversion patterns scattered across four call sites:

  • value.nil? ? nil : (value ? 1 : 0) (Ruby → NUMBER(1) for bind values) — 2 sites
  • numeric_value.nil? ? nil : numeric_value == 1 (NUMBER(1) → Ruby on the way back) — 2 sites
  • metadata.merge(data_type: "NUMBER", data_precision: 1) (override the bind metadata so the BOOLEAN parameter rides on a NUMBER bind) — 4 sites

PL/SQL BOOLEAN cannot be bound through the SQL layer, so the library swaps in a NUMBER(1) bind and re-assigns on the server side. That trick currently has its conversion code copy-pasted across add_argument, record_assignment_sql_values_metadata, add_return_variable, and return_variable_value, which makes any future change to how booleans are marshalled (e.g. accepting 'Y'/'N', aligning JDBC) a multi-site edit.

This PR introduces three small private helpers and one frozen constant on ProcedureCall, and replaces the eight call sites. Behavior is unchanged.

PLSQL_BOOLEAN_METADATA = { data_type: "NUMBER", data_precision: 1 }.freeze

def ruby_value_to_plsql_boolean(value)
  value.nil? ? nil : (value ? 1 : 0)
end

def plsql_boolean_to_ruby_value(numeric_value)
  numeric_value.nil? ? nil : numeric_value == 1
end

def plsql_boolean_metadata(base_metadata)
  base_metadata.merge(PLSQL_BOOLEAN_METADATA)
end

Out of scope on purpose:

  • The PL/SQL string literals (CASE WHEN ... THEN 1 ..., IF ... THEN o_x := 1 ...) that build the server-side conversion remain unchanged — those are SQL generation, not Ruby-side value conversion.
  • jdbc_connection.rb, oci_connection.rb, and procedure.rb boolean handling are not touched in this PR.

Diff stat: lib/plsql/procedure_call.rb | 30 ++++++++++++++++++++++-------- (+22 / -8), no other files modified.

Test plan

  • bundle exec rspec spec/plsql/procedure_spec.rb -e "boolean" — 15 examples, 0 failures
  • bundle exec rspec spec/plsql/procedure_spec.rb — 195 examples, 0 failures, 1 pre-existing pending (the Oracle 9.2 indexed-by-binary-integer skip at procedure_spec.rb:1525)
  • ruby -c lib/plsql/procedure_call.rb passes
  • No remaining occurrences of value.nil? ? nil : (value ? 1 : 0), nil? ? nil : * == 1, or the literal data_type: "NUMBER", data_precision: 1 outside the new helpers/constant

Tested locally against Oracle AI Database 23ai Free (FREEPDB1) on macOS with MRI Ruby 4.0.4 + ruby-oci8 2.2.14. CI will exercise the JDBC path as well.

🤖 Generated with Claude Code

The `value.nil? ? nil : (value ? 1 : 0)` and `value.nil? ? nil : value == 1`
patterns and the `data_type: "NUMBER", data_precision: 1` metadata override
were each repeated across `add_argument`, `record_assignment_sql_values_metadata`,
`add_return_variable`, and `return_variable_value`. Collapse them into three
private helpers so the BOOLEAN-as-NUMBER(1) trick has a single point of change.

No behavior change. `spec/plsql/procedure_spec.rb` is green (195 examples, 0
failures, 1 pre-existing pending).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@yahonda yahonda force-pushed the extract-plsql-boolean-helpers branch from 3e729fe to 14e76d6 Compare May 13, 2026 01:18
@yahonda yahonda merged commit afab1dc into rsim:master May 13, 2026
20 checks passed
@yahonda yahonda deleted the extract-plsql-boolean-helpers branch May 13, 2026 01:28
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