Skip to content

Conversation

@sudarshan12s
Copy link
Contributor

@sudarshan12s sudarshan12s commented Nov 3, 2025

Summary

  • Avoid IDENTITY_COLUMN in all_tab_columns table and FETCH FIRST sql syntax on Oracle Database versions, where CDB support is not there.

  • Fix outBinds handling in Execute node UI which chooses to return outbinds as objects. — Handle the outbinds returned as object and populate them correctly.

  • Add privilege login option — expose privilege options like SYSDBA, SYSPRELIM, SYSOPER, ... for connections that require elevated privileges .

  • Allow BLOB data as Serialized form of Buffer ( { type: 'Buffer', data: [...] } ) in Execute node UI

Related Linear tickets, Github issues, and Community forum posts

Review / Merge checklist

  • PR title and summary are descriptive. (conventions)
  • Docs updated or follow-up ticket created.
  • Tests included.
  • PR Labeled with release/backport (if the PR is an urgent fix that needs to be backported)

Note

Adds privilege-based login, fixes SQL/version compatibility (FETCH FIRST/ROWNUM, metadata queries), and normalizes outBinds incl. BLOB buffers in Oracle node.

  • Oracle Node
    • Compatibility: Detect server version to switch between FETCH FIRST and ROWNUM, and use version-appropriate column metadata queries (with/without IDENTITY_COLUMN).
    • Query Building: Refactor select to build an inner query before applying WHERE/ORDER BY/LIMIT.
    • Bind Handling: Normalize outBinds returned as objects; support BLOB binds from Buffers or serialized { type: 'Buffer', data: [...] }.
  • Credentials/Transport
    • Privilege Login: Add privilege option to oracleDBApi credentials and pass through in transport config.
  • Types/Utils
    • Add TableColumnRow type; extend OracleDBNodeCredentials with privilege.
  • Tests
    • Expand tests for version detection, IN-clause bind expansion, PL/SQL out binds, BLOB handling, and mixed/null value binding.

Written by Cursor Bugbot for commit f17991e. This will update automatically on new commits. Configure here.

@n8n-assistant n8n-assistant bot added community Authored by a community member node/improvement New feature or request in linear Issue or PR has been created in Linear for internal review labels Nov 3, 2025
@n8n-assistant
Copy link

n8n-assistant bot commented Nov 3, 2025

Hey @sudarshan12s,

Thank you for your contribution. We appreciate the time and effort you’ve taken to submit this pull request.

Before we can proceed, please ensure the following:
• Tests are included for any new functionality, logic changes or bug fixes.
• The PR aligns with our contribution guidelines.

Regarding new nodes:
We no longer accept new nodes directly into the core codebase. Instead, we encourage contributors to follow our Community Node Submission Guide to publish nodes independently.

If your node integrates with an AI service that you own or represent, please email [email protected] and we will be happy to discuss the best approach.

About review timelines:
This PR has been added to our internal tracker as "GHC-5329". While we plan to review it, we are currently unable to provide an exact timeframe. Our goal is to begin reviews within a month, but this may change depending on team priorities. We will reach out when the review begins.

Thank you again for contributing to n8n.

rollback: jest.fn(),
};

Object.defineProperty(fakeConnection, 'oracleServerVersion', {

Choose a reason for hiding this comment

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

Perhaps call the variable mockConnection instead of fakeConnection

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

4 issues found across 6 files

Prompt for AI agents (all 4 issues)

Understand the root cause of the following 4 issues and fix them.


<file name="packages/nodes-base/nodes/Oracle/Sql/helpers/utils.ts">

<violation number="1" location="packages/nodes-base/nodes/Oracle/Sql/helpers/utils.ts:848">
Null BLOB bind values now trigger a UserError. Allow nulls to pass through so existing workflows can still write NULL into BLOB columns.</violation>

<violation number="2" location="packages/nodes-base/nodes/Oracle/Sql/helpers/utils.ts:856">
Rule violated: **Prefer Typeguards over Type casting**

Avoid the `(bindVal as any)` assertions here and introduce a proper type guard (e.g. `isSerializedBuffer`) so the Buffer shape is validated without bypassing the type system.

(Based on your team&#39;s feedback about replacing `as` casts around Buffer handling with runtime guards.) [FEEDBACK_USED]</violation>
</file>

<file name="packages/nodes-base/nodes/Oracle/Sql/helpers/interfaces.ts">

<violation number="1" location="packages/nodes-base/nodes/Oracle/Sql/helpers/interfaces.ts:132">
Please type CHAR_LENGTH as number | null since ALL_TAB_COLUMNS.CHAR_LENGTH is NULL for non-character columns; keeping it as number can lead callers to assume it’s always numeric and skip null checks.</violation>
</file>

<file name="packages/nodes-base/credentials/OracleDBApi.credentials.ts">

<violation number="1" location="packages/nodes-base/credentials/OracleDBApi.credentials.ts:17">
Rule violated: **Prefer Typeguards over Type casting**

Casting the `oracledb` module to `any` to access privilege constants suppresses its declared typings and violates the &quot;Prefer Typeguards over Type casting&quot; rule; please rely on typed keys (e.g., via `satisfies`/`as const`) so the lookup stays type-safe.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.

case 'blob':
bindVal = item.valueBlob;
break;
if (Buffer.isBuffer(bindVal)) {
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Nov 3, 2025

Choose a reason for hiding this comment

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

Null BLOB bind values now trigger a UserError. Allow nulls to pass through so existing workflows can still write NULL into BLOB columns.

Prompt for AI agents
Address the following comment on packages/nodes-base/nodes/Oracle/Sql/helpers/utils.ts at line 848:

<comment>Null BLOB bind values now trigger a UserError. Allow nulls to pass through so existing workflows can still write NULL into BLOB columns.</comment>

<file context>
@@ -795,7 +845,23 @@ export function getBindParameters(
 				case &#39;blob&#39;:
 					bindVal = item.valueBlob;
-					break;
+					if (Buffer.isBuffer(bindVal)) {
+						break;
+					}
</file context>

✅ Addressed in 9a7ddfb

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added NULL check

COLUMN_NAME: string;
DATA_TYPE: string;
DATA_LENGTH: number;
CHAR_LENGTH: number;
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Nov 3, 2025

Choose a reason for hiding this comment

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

Please type CHAR_LENGTH as number | null since ALL_TAB_COLUMNS.CHAR_LENGTH is NULL for non-character columns; keeping it as number can lead callers to assume it’s always numeric and skip null checks.

Prompt for AI agents
Address the following comment on packages/nodes-base/nodes/Oracle/Sql/helpers/interfaces.ts at line 132:

<comment>Please type CHAR_LENGTH as number | null since ALL_TAB_COLUMNS.CHAR_LENGTH is NULL for non-character columns; keeping it as number can lead callers to assume it’s always numeric and skip null checks.</comment>

<file context>
@@ -122,3 +123,16 @@ export type ExecuteOpBindParam =
+	COLUMN_NAME: string;
+	DATA_TYPE: string;
+	DATA_LENGTH: number;
+	CHAR_LENGTH: number;
+	DEFAULT_LENGTH: number | null;
+	NULLABLE: &#39;Y&#39; | &#39;N&#39;;
</file context>
Suggested change
CHAR_LENGTH: number;
CHAR_LENGTH: number | null;
Fix with Cubic

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The CHAR_LENGTH will come as 0 if its not valid like for number type.

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for the feedback! I've saved this as a new learning to improve future reviews.


const privilegeOptions = privilegeKeys.map((key) => ({
name: key,
value: (oracledb as any)[key],
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Nov 3, 2025

Choose a reason for hiding this comment

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

Rule violated: Prefer Typeguards over Type casting

Casting the oracledb module to any to access privilege constants suppresses its declared typings and violates the "Prefer Typeguards over Type casting" rule; please rely on typed keys (e.g., via satisfies/as const) so the lookup stays type-safe.

Prompt for AI agents
Address the following comment on packages/nodes-base/credentials/OracleDBApi.credentials.ts at line 17:

<comment>Casting the `oracledb` module to `any` to access privilege constants suppresses its declared typings and violates the &quot;Prefer Typeguards over Type casting&quot; rule; please rely on typed keys (e.g., via `satisfies`/`as const`) so the lookup stays type-safe.</comment>

<file context>
@@ -1,4 +1,21 @@
+
+const privilegeOptions = privilegeKeys.map((key) =&gt; ({
+	name: key,
+	value: (oracledb as any)[key],
+}));
 
</file context>
Fix with Cubic

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The map is static and keys are always exposed by oracledb module.

if (
bindVal &&
typeof bindVal === 'object' &&
(bindVal as any).type === 'Buffer' &&
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot Nov 3, 2025

Choose a reason for hiding this comment

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

Rule violated: **Prefer Typeguards over Type casting** Avoid the `(bindVal as any)` assertions here and introduce a proper type guard (e.g. `isSerializedBuffer`) so the Buffer shape is validated without bypassing the type system. (Based on your team's feedback about replacing `as` casts around Buffer handling with runtime guards.)

View Feedback

Prompt for AI agents ~~~ Address the following comment on packages/nodes-base/nodes/Oracle/Sql/helpers/utils.ts at line 856: Avoid the `(bindVal as any)` assertions here and introduce a proper type guard (e.g. `isSerializedBuffer`) so the Buffer shape is validated without bypassing the type system. (Based on your team's feedback about replacing `as` casts around Buffer handling with runtime guards.) @@ -795,7 +845,23 @@ export function getBindParameters( + if ( + bindVal && + typeof bindVal === 'object' && + (bindVal as any).type === 'Buffer' && + Array.isArray((bindVal as any).data) + ) { ~~~
Fix with Cubic

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added isSerializedBuffer to check the type.

displayName: 'Privilege',
name: 'privilege',
type: 'options',
description: 'The privilege to use when establishing connection to the database',
Copy link

Choose a reason for hiding this comment

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

either "a connection" or "connections". Or change "establishing connection" to "connecting"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed to The privilege to use when connecting to the database

break;
}
throw new UserError(
'BLOB data must be valid Buffer or \'{ type: "Buffer", data: [...] }\'',
Copy link

Choose a reason for hiding this comment

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

"a valid"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

This PR is being reviewed by Cursor Bugbot

Details

Your team is on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle for each member of your team.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.


const conn = await pool.getConnection();
const isCDBSupported = conn.oracleServerVersion >= 1200000000;
await conn.close();
Copy link

Choose a reason for hiding this comment

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

Bug: Connection leak from unclosed database connection

Connection resource leak: The database connection is acquired but not protected by try-finally. If an error occurs after getConnection() on line 90 but before close() on line 92 (e.g., if accessing conn.oracleServerVersion throws an error), the connection will not be closed and will leak. This should be wrapped in a try-finally block to ensure the connection is always closed.

Fix in Cursor Fix in Web

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oracleServerVersion is a public exported attribute exposed from oracledb module which is always available. It should not cause an exception.

@sudarshan12s sudarshan12s changed the title fix(Oracle DB Node): resolve SQL compatibility issues and correct outBind generation fix(Oracle DB Node): Resolve SQL compatibility issues and correct outBind generation Nov 5, 2025
// Allow null or undefined to represent SQL NULL BLOB values
if (bindVal === null) {
break;
}
Copy link

Choose a reason for hiding this comment

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

Bug: Standardize BLOB Null Value Checks

The comment states both null and undefined should represent SQL NULL BLOB values, but the code only checks for null. When bindVal is undefined, it bypasses the null check and eventually throws an error. The condition should be if (bindVal === null || bindVal === undefined) to match the comment's stated intent and handle optional BLOB values consistently.

Fix in Cursor Fix in Web

@sharadraju
Copy link

@RomanDavydchuk Request your help with this review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community Authored by a community member in linear Issue or PR has been created in Linear for internal review node/improvement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants