Skip to content

Conversation

ting-lan-wang
Copy link
Contributor

@ting-lan-wang ting-lan-wang commented Aug 19, 2025

Description

Fixes TestReturningWithNullToZeroValues.

We previously declared the PL/SQL collection as follows:
TYPE t_records IS TABLE OF "users"%ROWTYPE;
However, this causes an error when the struct fields represent only a subset of the actual table.
The error is:
ORA-06550: line 17, column 41: PL/SQL: ORA-00913: too many values

For example, in TestReturningWithNullToZeroValues, the struct is declared as:

type user struct {
	gorm.Model
	Name string `gorm:"default:null"`
}

The struct user leverages the existing user table which is declared by the following struct:

type User struct {
	gorm.Model
	Name      string
	Age       uint
	Birthday  *time.Time
	Account   Account
	Pets      []*Pet
	NamedPet  *Pet
	Toys      []Toy   `gorm:"polymorphic:Owner"`
	Tools     []Tools `gorm:"polymorphicType:Type;polymorphicId:CustomID"`
	CompanyID *int
	Company   Company
	ManagerID *uint
	Manager   *User
	Team      []User     `gorm:"foreignkey:ManagerID"`
	Languages []Language `gorm:"many2many:UserSpeak;"`
	Friends   []*User    `gorm:"many2many:user_friends;"`
	Active    bool
}

To address this mismatch, the function writeTableRecordCollectionDecl was added.
It generates a PL/SQL declaration where the record type matches only the fields present in the provided struct, avoiding the too many values error.

Here's an example of the generated PLSQL before the changes:

DECLARE
  TYPE t_records IS TABLE OF "users"%ROWTYPE;
  l_inserted_records t_records;
  TYPE t_col_0_array IS TABLE OF TIMESTAMP WITH TIME ZONE;
  l_col_0_array t_col_0_array;
  TYPE t_col_1_array IS TABLE OF TIMESTAMP WITH TIME ZONE;
  l_col_1_array t_col_1_array;
  TYPE t_col_2_array IS TABLE OF TIMESTAMP WITH TIME ZONE;
  l_col_2_array t_col_2_array;
BEGIN
  l_col_0_array := t_col_0_array('2025-08-15 11:56:28.247', '2025-08-15 11:56:28.247');
  l_col_1_array := t_col_1_array('2025-08-15 11:56:28.247', '2025-08-15 11:56:28.247');
  l_col_2_array := t_col_2_array(NULL, NULL);
  FORALL i IN 1..2
    INSERT INTO "users" ("created_at", "updated_at", "deleted_at") VALUES (l_col_0_array(i), l_col_1_array(i), l_col_2_array(i))
    RETURNING "id", "created_at", "updated_at", "deleted_at", "name"
    BULK COLLECT INTO l_inserted_records;
    <too long; trimmed>
END;

and after the changes:

DECLARE
  TYPE t_record IS RECORD (
    "id" "users"."id"%TYPE,
    "created_at" "users"."created_at"%TYPE,
    "updated_at" "users"."updated_at"%TYPE,
    "deleted_at" "users"."deleted_at"%TYPE,
    "name" "users"."name"%TYPE
  );
  TYPE t_records IS TABLE OF t_record;
  l_inserted_records t_records;
  TYPE t_col_0_array IS TABLE OF TIMESTAMP WITH TIME ZONE;
  l_col_0_array t_col_0_array;
  TYPE t_col_1_array IS TABLE OF TIMESTAMP WITH TIME ZONE;
  l_col_1_array t_col_1_array;
  TYPE t_col_2_array IS TABLE OF TIMESTAMP WITH TIME ZONE;
  l_col_2_array t_col_2_array;
BEGIN
  l_col_0_array := t_col_0_array('2025-08-19 10:54:12.584', '2025-08-19 10:54:12.584');
  l_col_1_array := t_col_1_array('2025-08-19 10:54:12.584', '2025-08-19 10:54:12.584');
  l_col_2_array := t_col_2_array(NULL, NULL);
  FORALL i IN 1..2
    INSERT INTO "users" ("created_at", "updated_at", "deleted_at") VALUES (l_col_0_array(i), l_col_1_array(i), l_col_2_array(i))
    RETURNING "id", "created_at", "updated_at", "deleted_at", "name"
    BULK COLLECT INTO l_inserted_records;
    <too long; trimmed>
END;

Type of change

Please delete options that are not relevant.

  • [v] Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Aug 19, 2025
Copy link
Member

@aarrasseayoub01 aarrasseayoub01 left a comment

Choose a reason for hiding this comment

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

Great!

@ting-lan-wang ting-lan-wang merged commit e7363a1 into main Aug 19, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OCA Verified All contributors have signed the Oracle Contributor Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants