Skip to content

feat: implement Oracle-compatible UTL_ENCODE package#1338

Merged
gaoxueyu merged 1 commit into
IvorySQL:masterfrom
jiaoshuntian:utl_encode
May 29, 2026
Merged

feat: implement Oracle-compatible UTL_ENCODE package#1338
gaoxueyu merged 1 commit into
IvorySQL:masterfrom
jiaoshuntian:utl_encode

Conversation

@jiaoshuntian
Copy link
Copy Markdown
Collaborator

@jiaoshuntian jiaoshuntian commented May 18, 2026

(BASE64_ENCODE and BASE64_DECODE)

Add UTL_ENCODE built-in package to ivorysql_ora extension, providing Oracle-compatible base64 encoding and decoding via RAW (bytea) input/output.

BASE64_ENCODE:

  • Encodes binary data to base64 ASCII using 64-character lines with LF terminator after each line (RFC 1521 MIME format, matching Oracle's convention)
  • Empty input returns empty RAW; NULL input returns NULL (STRICT)

BASE64_DECODE:

  • Decodes base64-encoded RAW data back to binary
  • Strips embedded whitespace (\n, \r, \t, space) before decoding so that output from BASE64_ENCODE (which inserts LF every 64 chars) round-trips correctly
  • Whitespace-only input returns empty RAW; NULL input returns NULL (STRICT)
  • Invalid base64 characters raise ERRCODE_INVALID_PARAMETER_VALUE

Implementation:

  • C functions ivorysql_utl_encode_base64_encode / _base64_decode in utl_encode.c
  • PL/iSQL package spec and body wrap the C functions as utl_encode.base64_encode / utl_encode.base64_decode with RAW parameter types
  • Build system wired in Makefile, meson.build, and ivorysql_ora_merge_sqls
  • Regression tests cover: NULL, empty, known values, round-trips at line-break boundaries (48 / 49 / 200 bytes), CRLF handling, whitespace-only input, and PL/iSQL package interface

resolve #1053

Summary by CodeRabbit

  • New Features

    • Added UTL_ENCODE package for Oracle compatibility with BASE64_ENCODE and BASE64_DECODE functions, supporting encoding and decoding of binary data with proper whitespace handling and error detection for invalid input.
  • Tests

    • Added comprehensive test suite for UTL_ENCODE functionality including NULL handling, round-trip verification, boundary cases, and error scenarios.

Review Change Stack

…nd BASE64_DECODE)

Add UTL_ENCODE built-in package to ivorysql_ora extension, providing Oracle-compatible
base64 encoding and decoding via RAW (bytea) input/output.

BASE64_ENCODE:
- Encodes binary data to base64 ASCII using 64-character lines with LF terminator
  after each line (RFC 1521 MIME format, matching Oracle's convention)
- Empty input returns empty RAW; NULL input returns NULL (STRICT)

BASE64_DECODE:
- Decodes base64-encoded RAW data back to binary
- Strips embedded whitespace (\n, \r, \t, space) before decoding so that output
  from BASE64_ENCODE (which inserts LF every 64 chars) round-trips correctly
- Whitespace-only input returns empty RAW; NULL input returns NULL (STRICT)
- Invalid base64 characters raise ERRCODE_INVALID_PARAMETER_VALUE

Implementation:
- C functions ivorysql_utl_encode_base64_encode / _base64_decode in utl_encode.c
- PL/iSQL package spec and body wrap the C functions as utl_encode.base64_encode /
  utl_encode.base64_decode with RAW parameter types
- Build system wired in Makefile, meson.build, and ivorysql_ora_merge_sqls
- Regression tests cover: NULL, empty, known values, round-trips at line-break
  boundaries (48 / 49 / 200 bytes), CRLF handling, whitespace-only input,
  and PL/iSQL package interface
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 18, 2026

📝 Walkthrough

Walkthrough

This PR adds UTL_ENCODE, an Oracle-compatible package providing BASE64_ENCODE and BASE64_DECODE functions for binary data encoding/decoding. It includes C implementations with proper line-break handling, SQL registration, build configuration updates, and comprehensive test coverage with expected output validation.

Changes

UTL_ENCODE Oracle Compatibility Feature

Layer / File(s) Summary
Base64 Encode/Decode C Implementation
contrib/ivorysql_ora/src/builtin_packages/utl_encode/utl_encode.c
C functions ivorysql_utl_encode_base64_encode and ivorysql_utl_encode_base64_decode implement base64 encoding with line breaks at 64-character boundaries and decoding with whitespace tolerance for Oracle compatibility.
SQL Extension Registration and PL/SQL Package
contrib/ivorysql_ora/src/builtin_packages/utl_encode/utl_encode--1.0.sql
Registers sys.utl_encode_base64_encode and sys.utl_encode_base64_decode C-backed functions, exposing them through a utl_encode PL/SQL package with base64_encode/base64_decode that delegate to the underlying C functions.
Build System Integration
contrib/ivorysql_ora/Makefile, contrib/ivorysql_ora/meson.build, contrib/ivorysql_ora/ivorysql_ora_merge_sqls
Updates Makefile OBJS and ORA_REGRESS targets, meson.build source list, and merge manifest to include utl_encode.c and dbms_lock.c modules with regression test targets.
Test Suite and Expected Output
contrib/ivorysql_ora/sql/utl_encode.sql, contrib/ivorysql_ora/expected/utl_encode.out
SQL tests exercise NULL handling, known input/output verification, round-trip correctness at line-break boundaries (48/49 bytes), large-input round-trips (200 bytes), whitespace-only cases, and invalid base64 error conditions; expected output captures all results and error messages.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested reviewers

  • bigplaice

Poem

🐰 Base64 hops through bytes with grace,
Encoding data, leaving space—
Newlines break the ASCII art,
Decode strips whitespace, plays its part.
Oracle smiles: a feature complete! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The PR fully implements Oracle-compatible UTL_ENCODE Base64 encoding/decoding as requested in issue #1053, with complete C implementation, SQL definitions, test coverage, and build configuration.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing UTL_ENCODE; build system updates (Makefile, meson.build, ivorysql_ora_merge_sqls) support the new feature without introducing unrelated modifications.
Title check ✅ Passed The title clearly and concisely summarizes the main change: implementing an Oracle-compatible UTL_ENCODE package with BASE64_ENCODE and BASE64_DECODE functions, which aligns with all the code additions across C, SQL, and build configuration files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
contrib/ivorysql_ora/sql/utl_encode.sql (1)

11-73: ⚡ Quick win

Add explicit tests for empty RAW and mixed embedded whitespace decode paths.

Line 11 onward validates most behavior, but the feature contract for empty input and embedded whitespace stripping is not asserted directly. Please add those cases and update expected output accordingly.

✅ Proposed test additions
 -- NULL input returns NULL (STRICT modifier)
 SELECT utl_encode.base64_encode(NULL) IS NULL;
+-- Empty input returns empty RAW
+SELECT rawtohex(utl_encode.base64_encode(hextoraw(''))) IS NULL;

@@
 -- NULL input returns NULL (STRICT modifier)
 SELECT utl_encode.base64_decode(NULL) IS NULL;
+-- Empty input returns empty RAW
+SELECT rawtohex(utl_encode.base64_decode(hextoraw(''))) IS NULL;

@@
 -- Decode known base64 string: 'SGVsbG8=\n' -> 'Hello' bytes
 -- hextoraw('534756736247383D0A') = 'SGVsbG8=\n', hextoraw('48656C6C6F') = 'Hello'
 SELECT rawtohex(utl_encode.base64_decode(hextoraw('534756736247383D0A'))) = '48656C6C6F';
+-- Embedded whitespace tolerance (LF/CR/TAB/SPACE inside payload)
+-- 'SGV s\r\nbG8=\t' -> 'Hello'
+SELECT rawtohex(utl_encode.base64_decode(hextoraw('53475620730D0A6247383D09'))) = '48656C6C6F';
As per coding guidelines `**/sql/*.sql`: Test SQL files. Ensure comprehensive coverage of features.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@contrib/ivorysql_ora/sql/utl_encode.sql` around lines 11 - 73, Add explicit
tests asserting empty-RAW behavior and the whitespace-stripping decode path: add
a case that invokes utl_encode.base64_encode and utl_encode.base64_decode with
an empty RAW input and assert the result is an empty RAW (use rawtohex checks
consistent with existing tests), and add tests that feed base64 inputs
containing embedded whitespace/CR/LF/tabs into utl_encode.base64_decode and
assert they decode to the same binary as the equivalent whitespace-free base64
string; reference the existing tests around utl_encode.base64_encode and
utl_encode.base64_decode to place these new assertions adjacent to the NULL and
round-trip checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@contrib/ivorysql_ora/sql/utl_encode.sql`:
- Around line 11-73: Add explicit tests asserting empty-RAW behavior and the
whitespace-stripping decode path: add a case that invokes
utl_encode.base64_encode and utl_encode.base64_decode with an empty RAW input
and assert the result is an empty RAW (use rawtohex checks consistent with
existing tests), and add tests that feed base64 inputs containing embedded
whitespace/CR/LF/tabs into utl_encode.base64_decode and assert they decode to
the same binary as the equivalent whitespace-free base64 string; reference the
existing tests around utl_encode.base64_encode and utl_encode.base64_decode to
place these new assertions adjacent to the NULL and round-trip checks.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5682c4cc-0f49-4798-9f84-ae348a9f7f2d

📥 Commits

Reviewing files that changed from the base of the PR and between 1911b46 and 783905a.

📒 Files selected for processing (7)
  • contrib/ivorysql_ora/Makefile
  • contrib/ivorysql_ora/expected/utl_encode.out
  • contrib/ivorysql_ora/ivorysql_ora_merge_sqls
  • contrib/ivorysql_ora/meson.build
  • contrib/ivorysql_ora/sql/utl_encode.sql
  • contrib/ivorysql_ora/src/builtin_packages/utl_encode/utl_encode--1.0.sql
  • contrib/ivorysql_ora/src/builtin_packages/utl_encode/utl_encode.c

@jiaoshuntian jiaoshuntian changed the title feat: implement Oracle-compatible UTL_ENCODE package (BASE64_ENCODE a… feat: implement Oracle-compatible UTL_ENCODE package May 18, 2026
@gaoxueyu gaoxueyu merged commit 4252ce4 into IvorySQL:master May 29, 2026
9 checks passed
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.

oracle compatibility feature: UTL_ENCODE

2 participants