Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Feature/cursor pk join #666

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
May 25, 2018
Merged

Feature/cursor pk join #666

merged 36 commits into from
May 25, 2018

Conversation

lwasylow
Copy link
Member

Changes to implement join by cursor and unordered compare.
fixes #453

lwasylow added 21 commits April 23, 2018 19:44
Adding compare for join by
Update if statement to simplify
Remove synonyms for temp tables
updated docs
updated docs
Capture PK Hash to improve lookup
fix to get columns diff
@jgebal
Copy link
Member

jgebal commented May 12, 2018

@lwasylow , can you update the branch and resolve conflicts

order by 1,2,3 desc;

--Act
ut3.ut.expect(l_actual).to_equal(l_expected).join_by('OWNER');
Copy link
Member

Choose a reason for hiding this comment

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

How is this test working? I guess the OWNER field is not unique in the dataset so we get some sort of cartesian join here.
Is this the test working by lock or is the logic so clever to somehow make it work?

Copy link
Member Author

Choose a reason for hiding this comment

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

We are partition row number over PK HASH and join on pk_hash and duplicate no.
Because duplicate_no in both sets match we got success.
If we have an extra row we would get extra row error.
But agree that test is probably not the best example of join on uniquness.

Copy link
Member

Choose a reason for hiding this comment

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

Right, so in fact we are preventing cartesian joins and if key is not unique we would do a join by a rownum within join key value.
Worth documenting - I already forgot it was supposed to work like this

Copy link
Member Author

Choose a reason for hiding this comment

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

Documentation has been updated with more details

l_expected_message := q'[%Actual: refcursor [ count = 3 ] was expected to equal: refcursor [ count = 3 ]%
Diff:%
%Unable to join sets:%
%Unknown key to join by in expected:/*/OWNER%
Copy link
Member

Choose a reason for hiding this comment

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

Maybe better to name it like
Join key /*/OWNER does not exist in expected

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated to refactor new name

ut.expect(l_actual_message).to_be_like(l_expected_message);
end;

procedure cur_joinby_comp_twocols_exkey is
Copy link
Member

Choose a reason for hiding this comment

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

This behaviour should be mentioned in documentation

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated docs

l_expected_message := q'[%Actual: refcursor [ count = 3 ] was expected to equal: refcursor [ count = 3 ]%
Diff:%
%Unable to join sets:%
%Unknown key to join by in actual:/*/RNI%]';
Copy link
Member

Choose a reason for hiding this comment

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

Lets remove the /*/ prefix so it is aligned with KEY: TEST in line 1287 (Expected: <USER_ID>-600</USER_ID> for key: TEST)
I think we should be consistent when showing messages to users.

Copy link
Member Author

Choose a reason for hiding this comment

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

Challenge here is that we do not know what column name is missing only what XPATH expression to join by is not present. Because we allow user to pass in Xpath expression.
The message

Expected: <USER_ID>-600</USER_ID> for key: TEST

Is extracted from piece of XML using xpath.

In scenario where there is missing key we cannot use that XPATH to extract information about column and we cannot assume that xpath expression is a column name and not some xpath search string with wildcard.

Copy link
Member

Choose a reason for hiding this comment

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

Can you do a testcase for join on nested table element in cursor column?
Would be interesting to see such join happening.

Copy link
Member Author

Choose a reason for hiding this comment

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

Few tests added for nested table element of test_dummy_object from test helper package

lwasylow added 2 commits May 18, 2018 00:14
Updated documentation
Shift packages around for current user id
l_expected_message := q'[%Actual: refcursor [ count = % ] was expected to equal: refcursor [ count = % ]
%Diff:%
%Rows: [ 2 differences ]%
%Missing: <USERNAME>TEST</USERNAME><USER_ID>-600</USER_ID> for key: -600:TEST%
Copy link
Member

Choose a reason for hiding this comment

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

I have a doubt about readability of this message to the user.
Missing: <USERNAME>TEST</USERNAME><USER_ID>-600</USER_ID> for key: -600:TEST
If we don't join by PK, we use syntax like
Row No. 3 - Missing: <RN>3</RN>
How about if we would present it to the user in a similar way:
PK <USERNAME>TEST</USERNAME><USER_ID>-600</USER_ID> missing.

Copy link
Member

Choose a reason for hiding this comment

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

I think we should exclude PK columns from the Missing/Extra data list - this is duplicated info.

Copy link
Member Author

Choose a reason for hiding this comment

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

Agree, will update

Copy link
Member Author

Choose a reason for hiding this comment

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

Make sense

l_expected_message := q'[%Actual: refcursor [ count = % ] was expected to equal: refcursor [ count = % ]
%Diff:%
%Rows: [ 1 differences ]%
%Expected: <USER_ID>-600</USER_ID> for key: TEST:Y%
Copy link
Member

Choose a reason for hiding this comment

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

I believe, this could be more readable if it was:
PK <USERNAME>TEST</USERNAME><IS_VALID>Y</IS_VALID> - Expected: <USER_ID>-600</USER_ID>
PK <USERNAME>TEST</USERNAME><IS_VALID>Y</IS_VALID> - Actual: <USER_ID>-610</USER_ID>

Copy link
Member Author

Choose a reason for hiding this comment

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

Make sense

--Act
ut3.ut.expect(l_actual).to_equal(l_expected).unordered;
--Assert
ut.expect(expectations.failed_expectations_data()).to_be_not_null();
Copy link
Member

Choose a reason for hiding this comment

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

What data will the user see in this case?
Can you test for an expected message?

l_expected_message := q'[%Actual: refcursor [ count = 3 ] was expected to equal: refcursor [ count = 3 ]%
Diff:%
%Unable to join sets:%
%Join key /*/RN does not exists in expected%
Copy link
Member

Choose a reason for hiding this comment

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

Can we remove the leading /*/ from the message?
That way we get actual column name rather than XPATH.
Not sure if it makes sense but probably 98% of use-cases will be joins by regular columns (not nested elements)

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah we can make that assumption just have to updated docs to mention that.

ut.expect(expectations.failed_expectations_data()).to_be_empty();
end;

procedure compare_nested_tab_col_un is
Copy link
Member

Choose a reason for hiding this comment

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

The test is actually for an object in a cursor column, not a nested table.
Can you rename those tests and add an additional test for a nested table (like ut_varchar2_list or so)?
I wonder how it will work with a nested table containing more than one row.
Maybe we should not support that at all?

Copy link
Member Author

Choose a reason for hiding this comment

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

that looks fine select * from table(ut_varchar2_list) for one or two columns ut_key_value_pairs

from table(l_expected_tab) order by 1 desc;

--Act
ut3.ut.expect(l_actual).to_equal(l_expected).join_by('KEY');
Copy link
Member

Choose a reason for hiding this comment

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

What will happen when your cursor l_actual is:

select rownum rn, l_actual_tab
  from dual connect by level <=2;
ut3.ut.expect(l_actual).to_equal(l_expected).join_by('RN,L_ACTUAL_TAB/KEY');

The dataset is then something like:

<?xml version="1.0"?>
<ROWSET>
 <ROW>
  <RN>1</RN>
  <L_ACTUAL_TAB>
   <UT_KEY_VALUE_PAIR>
    <KEY>1</KEY>
    <VALUE>Something 1</VALUE>
   </UT_KEY_VALUE_PAIR>
   <UT_KEY_VALUE_PAIR>
    <KEY>2</KEY>
    <VALUE>Something 2</VALUE>
   </UT_KEY_VALUE_PAIR>
  </L_ACTUAL_TAB>
 </ROW>
 <ROW>
  <RN>2</RN>
  <L_ACTUAL_TAB>
   <UT_KEY_VALUE_PAIR>
    <KEY>1</KEY>
    <VALUE>Something 1</VALUE>
   </UT_KEY_VALUE_PAIR>
   <UT_KEY_VALUE_PAIR>
    <KEY>2</KEY>
    <VALUE>Something 2</VALUE>
   </UT_KEY_VALUE_PAIR>
  </L_ACTUAL_TAB>
 </ROW>
</ROWSET>

That will not be (and probably should not be) supporter but might be still worth documenting in test.
We just don't know what will happen as there is not test case to document how the ut.expect will behave.

Copy link
Member

@jgebal jgebal left a comment

Choose a reason for hiding this comment

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

This looks really good now!
Will you be able to add one more test case (as per comment)?

@lwasylow
Copy link
Member Author

Sure thing

@jgebal jgebal added this to the 3.1.2 milestone May 25, 2018
@jgebal jgebal merged commit 3acfb6c into develop May 25, 2018
@lwasylow lwasylow deleted the feature/cursor_pk_join branch May 29, 2018 21:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add ability to join cursors by specific columns(PK/UK)
2 participants