From e4be2f2d5e2508e738223f222a2071d975ea611d Mon Sep 17 00:00:00 2001 From: Yasuo Honda Date: Mon, 13 Apr 2026 21:19:26 +0900 Subject: [PATCH] Strip precision from TIMESTAMP data types in %ROWTYPE fields ALL_TAB_COLUMNS.DATA_TYPE includes precision for TIMESTAMP and INTERVAL types (e.g., TIMESTAMP(6) WITH LOCAL TIME ZONE) even when declared without explicit precision. Strip it to match the exact strings expected by type mapping in oci_connection.rb, jdbc_connection.rb, and procedure_call.rb. Uses the same approach as table.rb: data_type.sub(/\(\d+\)/, "") Co-Authored-By: Jochen Schug <4573581+joschug@users.noreply.github.com> Co-Authored-By: Claude Opus 4.6 (1M context) --- lib/plsql/procedure.rb | 3 +++ spec/plsql/procedure_spec.rb | 38 ++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/lib/plsql/procedure.rb b/lib/plsql/procedure.rb index 25f6b33..f1bd945 100644 --- a/lib/plsql/procedure.rb +++ b/lib/plsql/procedure.rb @@ -397,6 +397,9 @@ def get_field_definitions(argument_metadata) # :nodoc: col_no, col_name, col_type_name, col_length, col_precision, col_scale, col_char_length, col_char_used = r + # remove precision (n) from data_type (returned for TIMESTAMPs and INTERVALs) + col_type_name = col_type_name.sub(/\(\d+\)/, "") + fields[col_name.downcase.to_sym] = { position: col_no.to_i, data_type: col_type_name, diff --git a/spec/plsql/procedure_spec.rb b/spec/plsql/procedure_spec.rb index 581c32e..3e8392d 100644 --- a/spec/plsql/procedure_spec.rb +++ b/spec/plsql/procedure_spec.rb @@ -2427,6 +2427,44 @@ def new_candidate(status) end end +describe "Function with TIMESTAMP columns in %ROWTYPE" do + before(:all) do + plsql.connect! CONNECTION_PARAMS + plsql.execute "DROP FUNCTION test_timestamp_fn" rescue nil + plsql.execute "DROP TABLE test_timestamp_tbl" rescue nil + plsql.execute <<-SQL + CREATE TABLE test_timestamp_tbl ( + id NUMBER, + ts TIMESTAMP, + ts_tz TIMESTAMP WITH TIME ZONE, + ts_ltz TIMESTAMP WITH LOCAL TIME ZONE + ) + SQL + plsql.execute <<-SQL + CREATE OR REPLACE FUNCTION test_timestamp_fn(p_rec test_timestamp_tbl%ROWTYPE) + RETURN NUMBER + IS + BEGIN + RETURN p_rec.id; + END; + SQL + end + + after(:all) do + plsql.execute "DROP FUNCTION test_timestamp_fn" rescue nil + plsql.execute "DROP TABLE test_timestamp_tbl" rescue nil + plsql.logoff + end + + it "should strip precision from TIMESTAMP data types in %ROWTYPE fields" do + procedure = PLSQL::Procedure.find(plsql, :test_timestamp_fn) + fields = procedure.arguments[0][:p_rec][:fields] + expect(fields[:ts][:data_type]).to eq("TIMESTAMP") + expect(fields[:ts_tz][:data_type]).to eq("TIMESTAMP WITH TIME ZONE") + expect(fields[:ts_ltz][:data_type]).to eq("TIMESTAMP WITH LOCAL TIME ZONE") + end +end + describe "Function with TABLE OF %ROWTYPE parameter defined in package" do before(:all) do plsql.connect! CONNECTION_PARAMS