Skip to content

feat(UTL_RAW): UTL_RAW.CAST_TO_RAW#1337

Open
hs-liuxh wants to merge 1 commit into
IvorySQL:masterfrom
hs-liuxh:ora/utl_raw
Open

feat(UTL_RAW): UTL_RAW.CAST_TO_RAW#1337
hs-liuxh wants to merge 1 commit into
IvorySQL:masterfrom
hs-liuxh:ora/utl_raw

Conversation

@hs-liuxh
Copy link
Copy Markdown
Collaborator

@hs-liuxh hs-liuxh commented May 15, 2026

Oracle compatible feature: UTL_RAW

#1057

Summary by CodeRabbit

  • New Features
    • Introduced UTL_RAW Oracle-compatible package with CAST_TO_RAW function for converting text to hexadecimal representation and endianness constants.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 15, 2026

📝 Walkthrough

Walkthrough

This PR introduces a new Oracle-compatible UTL_RAW package for IvorySQL. The implementation consists of a C function that converts text input to hexadecimal representation, wrapped by a SQL package specification and body, integrated into the build system with comprehensive test coverage.

Changes

UTL_RAW Oracle-Compatible Package

Layer / File(s) Summary
C hex conversion function
contrib/ivorysql_ora/src/builtin_packages/utl_raw/utl_raw.c
ora_utl_raw_cast_to_raw C function converts input text bytes to uppercase hexadecimal using varlena-safe memory allocation and handles NULL inputs correctly.
SQL package specification and wrapper
contrib/ivorysql_ora/src/builtin_packages/utl_raw/utl_raw--1.0.sql
UTL_RAW package defines CAST_TO_RAW(c IN VARCHAR2) RETURN VARCHAR2 function and endianness constants (big_endian, little_endian, machine_endian); wraps C-backed helper sys.utl_raw_cast_to_raw marked STRICT and IMMUTABLE.
Build system integration and test suite
contrib/ivorysql_ora/Makefile, contrib/ivorysql_ora/ivorysql_ora_merge_sqls, contrib/ivorysql_ora/sql/utl_raw.sql, contrib/ivorysql_ora/expected/utl_raw.out
Makefile adds utl_raw.o object and regression target; merge list registers the SQL module; test suite validates CAST_TO_RAW across normal strings, NULL, empty string, multibyte characters (Chinese), mixed text, and special characters with expected output.

Sequence Diagram

sequenceDiagram
  participant Test as Test SQL
  participant Pkg as UTL_RAW.CAST_TO_RAW
  participant Helper as sys.utl_raw_cast_to_raw
  participant CFunc as ora_utl_raw_cast_to_raw
  Test->>Pkg: CAST_TO_RAW(varchar2)
  Pkg->>Helper: call with text cast
  Helper->>CFunc: invoke C function
  CFunc->>Helper: return hex text
  Helper->>Pkg: return result
  Pkg->>Test: return varchar2
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related issues

Suggested reviewers

  • NotHimmel
  • jiaoshuntian

Poem

A rabbit hops through hex so bright,
Converting bytes to VARCHAR2 light,
From C to SQL, a faithful chain,
Where CAST_TO_RAW brings Oracle's reign! 🐰✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically identifies the main feature addition: implementing UTL_RAW.CAST_TO_RAW, which is the core functionality across all changed files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

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

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 OpenGrep (1.20.0)

OpenGrep fatal error (exit code 2): [00.16][ERROR]: Error: exception Unix_error: No such file or directory stat contrib/ivorysql_ora/src/builtin_packages/utl_raw/utl_raw.c
Raised by primitive operation at UTmp.replace_named_pipe_by_regular_file_if_needed in file "libs/commons/UTmp.ml", line 145, characters 8-27
Called from Scan_CLI.replace_target_roots_by_regular_files_where_needed.(fun) in file "src/osemgrep/cli_scan/Scan_CLI.ml", lines 1086-1087, characters 19-65
Called from List_.fast_map in file "libs/commons/List_.ml", line 8

🔧 SQLFluff (4.1.0)
contrib/ivorysql_ora/src/builtin_packages/utl_raw/utl_raw--1.0.sql

User Error: Specified path does not exist. Check it/they exist(s): contrib/ivorysql_ora/src/builtin_packages/utl_raw/utl_raw--1.0.sql.

contrib/ivorysql_ora/sql/utl_raw.sql

User Error: Specified path does not exist. Check it/they exist(s): contrib/ivorysql_ora/sql/utl_raw.sql.

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

Actionable comments posted: 1

🤖 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.

Inline comments:
In `@contrib/ivorysql_ora/src/builtin_packages/utl_raw/utl_raw.c`:
- Around line 45-48: Before calling palloc to allocate result, check that the
computed size (VARHDRSZ + datalen * 2) does not exceed MaxAllocSize (or
otherwise allowable allocation threshold) and raise a controlled ereport/elog
error if it does; specifically, in the code that computes datalen and assigns
result (using VARHDRSZ, datalen, and palloc), compute the needed_size = VARHDRSZ
+ datalen * 2, verify needed_size <= MaxAllocSize (or use SizeIsValid/alloc size
helper used in the project), and call ereport(ERROR, ...) with a clear message
on overly large input when the check fails, only then call palloc(needed_size)
to assign result.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: aae3b8e1-469c-4f4d-9736-03306cb80cc8

📥 Commits

Reviewing files that changed from the base of the PR and between 35e086c and 4822d52.

📒 Files selected for processing (6)
  • contrib/ivorysql_ora/Makefile
  • contrib/ivorysql_ora/expected/utl_raw.out
  • contrib/ivorysql_ora/ivorysql_ora_merge_sqls
  • contrib/ivorysql_ora/sql/utl_raw.sql
  • contrib/ivorysql_ora/src/builtin_packages/utl_raw/utl_raw--1.0.sql
  • contrib/ivorysql_ora/src/builtin_packages/utl_raw/utl_raw.c

Comment on lines +45 to +48
datalen = VARSIZE_ANY_EXHDR(input);

result = palloc(VARHDRSZ + datalen * 2);
out = VARDATA(result);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

cat -n contrib/ivorysql_ora/src/builtin_packages/utl_raw/utl_raw.c | head -60

Repository: IvorySQL/IvorySQL

Length of output: 2143


🏁 Script executed:

rg "MaxAllocSize" --type c -B2 -A2

Repository: IvorySQL/IvorySQL

Length of output: 44163


🏁 Script executed:

rg "VARHDRSZ.*datalen" --type c -B3 -A3

Repository: IvorySQL/IvorySQL

Length of output: 3619


🏁 Script executed:

grep -n "if.*datalen.*>" contrib/ivorysql_ora/src/builtin_packages/utl_raw/utl_raw.c

Repository: IvorySQL/IvorySQL

Length of output: 43


🏁 Script executed:

rg "encode\.c" --type c -A5 "MaxAllocSize - VARHDRSZ" | head -20

Repository: IvorySQL/IvorySQL

Length of output: 125


Add an explicit size guard before output allocation.

Line 47 computes VARHDRSZ + datalen * 2 without checking MaxAllocSize. For very large inputs, palloc will fail with a low-level allocation error instead of a controlled function error. PostgreSQL's established practice is to pre-check allocation sizes to provide deterministic, user-friendly error messages.

💡 Suggested fix
 	data = VARDATA_ANY(input);
 	datalen = VARSIZE_ANY_EXHDR(input);
 
+	if (datalen > (MaxAllocSize - VARHDRSZ) / 2)
+		ereport(ERROR,
+				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
+				 errmsg("input is too long for UTL_RAW.CAST_TO_RAW")));
+
 	result = palloc(VARHDRSZ + datalen * 2);
 	out = VARDATA(result);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
datalen = VARSIZE_ANY_EXHDR(input);
result = palloc(VARHDRSZ + datalen * 2);
out = VARDATA(result);
data = VARDATA_ANY(input);
datalen = VARSIZE_ANY_EXHDR(input);
if (datalen > (MaxAllocSize - VARHDRSZ) / 2)
ereport(ERROR,
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
errmsg("input is too long for UTL_RAW.CAST_TO_RAW")));
result = palloc(VARHDRSZ + datalen * 2);
out = VARDATA(result);
🤖 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/src/builtin_packages/utl_raw/utl_raw.c` around lines 45
- 48, Before calling palloc to allocate result, check that the computed size
(VARHDRSZ + datalen * 2) does not exceed MaxAllocSize (or otherwise allowable
allocation threshold) and raise a controlled ereport/elog error if it does;
specifically, in the code that computes datalen and assigns result (using
VARHDRSZ, datalen, and palloc), compute the needed_size = VARHDRSZ + datalen *
2, verify needed_size <= MaxAllocSize (or use SizeIsValid/alloc size helper used
in the project), and call ereport(ERROR, ...) with a clear message on overly
large input when the check fails, only then call palloc(needed_size) to assign
result.

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