Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 29 additions & 7 deletions lib/plsql/procedure_call.rb
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,16 @@ def record_assignment_sql_values_metadata(argument, argument_metadata, record_va
metadata = argument_metadata[:fields][field]
raise ArgumentError, "Wrong field name #{key.inspect} passed to PL/SQL record argument #{argument.inspect}" unless metadata
bind_variable = :"#{argument}_f#{metadata[:position]}"
sql << "l_#{argument}.#{field} := :#{bind_variable};\n"
bind_values[bind_variable] = value
bind_metadata[bind_variable] = metadata
case metadata[:data_type]
when 'PL/SQL BOOLEAN'
sql << "l_#{argument}.#{field} := (:#{bind_variable} = 1);\n"
bind_values[bind_variable] = value.nil? ? nil : (value ? 1 : 0)
bind_metadata[bind_variable] = metadata.merge(:data_type => "NUMBER", :data_precision => 1)
else
sql << "l_#{argument}.#{field} := :#{bind_variable};\n"
bind_values[bind_variable] = value
bind_metadata[bind_variable] = metadata
end
end
[sql, bind_values, bind_metadata]
end
Expand All @@ -362,9 +369,18 @@ def add_return_variable(argument, argument_metadata, is_return_value=false)
# should use different output bind variable as JDBC does not support
# if output bind variable appears in several places
bind_variable = :"#{argument}_o#{metadata[:position]}"
@return_vars << bind_variable
@return_vars_metadata[bind_variable] = metadata
@return_sql << ":#{bind_variable} := l_#{argument}.#{field};\n"
case metadata[:data_type]
when 'PL/SQL BOOLEAN'
@return_vars << bind_variable
@return_vars_metadata[bind_variable] = metadata.merge(:data_type => "NUMBER", :data_precision => 1)
arg_field = "l_#{argument}.#{field}"
@return_sql << ":#{bind_variable} := " << "CASE WHEN #{arg_field} = true THEN 1 " <<
"WHEN #{arg_field} = false THEN 0 ELSE NULL END;\n"
else
@return_vars << bind_variable
@return_vars_metadata[bind_variable] = metadata
@return_sql << ":#{bind_variable} := l_#{argument}.#{field};\n"
end
end
"l_#{argument} := " if is_return_value
when 'PL/SQL BOOLEAN'
Expand Down Expand Up @@ -468,7 +484,13 @@ def return_variable_value(argument, argument_metadata)
when 'PL/SQL RECORD'
return_value = {}
argument_metadata[:fields].each do |field, metadata|
return_value[field] = @cursor[":#{argument}_o#{metadata[:position]}"]
field_value = @cursor[":#{argument}_o#{metadata[:position]}"]
case metadata[:data_type]
when 'PL/SQL BOOLEAN'
return_value[field] = field_value.nil? ? nil : field_value == 1
else
return_value[field] = field_value
end
end
return_value
when 'PL/SQL BOOLEAN'
Expand Down
56 changes: 56 additions & 0 deletions spec/plsql/procedure_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -630,13 +630,26 @@
hire_date DATE
);

TYPE t_candidate IS RECORD(
candidate_id NUMBER(5),
is_approved BOOLEAN
);

TYPE table_of_records IS TABLE OF t_employee;

FUNCTION test_full_name(p_employee t_employee)
RETURN VARCHAR2;

FUNCTION test_empty_records
RETURN table_of_records;

FUNCTION is_approved(p_candidate t_candidate)
RETURN BOOLEAN;

FUNCTION f_set_candidate_status(p_candidate t_candidate, p_status boolean)
RETURN t_candidate;

PROCEDURE p_set_candidate_status(p_candidate t_candidate, p_status boolean, p_result OUT t_candidate);
END;
SQL
plsql.execute <<-SQL
Expand Down Expand Up @@ -667,6 +680,29 @@
CLOSE employees_cur;
RETURN employees_tab;
END;

FUNCTION is_approved(p_candidate t_candidate)
RETURN BOOLEAN
IS
BEGIN
RETURN p_candidate.is_approved;
END;

FUNCTION f_set_candidate_status(p_candidate t_candidate, p_status boolean)
RETURN t_candidate
IS
result t_candidate := p_candidate;
BEGIN
result.is_approved := p_status;
return result;
END;

PROCEDURE p_set_candidate_status(p_candidate t_candidate, p_status boolean, p_result OUT t_candidate)
IS
BEGIN
p_result := p_candidate;
p_result.is_approved := p_status;
END;
END;
SQL
plsql.execute <<-SQL
Expand Down Expand Up @@ -750,6 +786,26 @@
expect(plsql.test_record.test_full_name(@p_employee)).to eq('First Last')
end

context "functions with record parameters having boolean attributes" do
def new_candidate(status)
{:candidate_id => 1, :is_approved => status}
end

[true, false, nil].each do |status|
it "should execute function with record having boolean attribute (#{status})" do
expect(plsql.test_record.is_approved(new_candidate(status))).to eq status
end

it "procedure should return record with boolean attribute as output parameter (#{status})" do
expect(plsql.test_record.p_set_candidate_status(new_candidate(nil), status)[:p_result]).to eq new_candidate(status)
end

it "function should return record with boolean attribute (#{status})" do
expect(plsql.test_record.f_set_candidate_status(new_candidate(nil), status)).to eq new_candidate(status)
end
end
end

end

describe "Function with boolean parameters" do
Expand Down