Skip to content
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

Table operations #762

Merged
merged 21 commits into from Jul 16, 2021
Merged

Table operations #762

merged 21 commits into from Jul 16, 2021

Conversation

devinrsmith
Copy link
Member

@devinrsmith devinrsmith commented Jun 17, 2021

A non-comprehensive first pass at extracting table operations api from Table.

First commit is table-api module standalone.

Second commit is incorporating table-api into DB/Table.

@devinrsmith devinrsmith added table api core Core development tasks labels Jun 17, 2021
@devinrsmith devinrsmith added this to the June 2021 milestone Jun 17, 2021
@devinrsmith devinrsmith requested a review from rcaudy June 17, 2021 19:06
@devinrsmith devinrsmith self-assigned this Jun 17, 2021
@devinrsmith
Copy link
Member Author

Documentation requirements: targeted javadocs.

@rcaudy rcaudy self-assigned this Jun 18, 2021
@devinrsmith
Copy link
Member Author

devinrsmith commented Jun 23, 2021

Part of this PR (which way may need to revisit) is appending 2 to some new table operation methods, due to non-overloadability of java generics. For example:

    TOPS updateView(Collection<String> columns);
    TOPS updateView2(Collection<Selectable> columns);

Looks like this is causing some sort of auto-completion failure.

So, should we:

  • Fix the autocomplete tests and live w/ the 2 methods?
  • Choose a different prefix for these new semi-overloads? newUpdateView(Collection<Selectable> columns)
  • Something else?

Error:

 ColumnExpressionCompletionHandlerTest.Completion should offer column name completion from when a where clause contains an unclosed String with a partial prefix (cursor position 19)

Condition not satisfied:

result.size() == 2
|      |      |
|      3      false
[CompletionItem{start=7, length=12, textEdit=TextEdit{range=Range{start=Position{line=1, character=6}, end=Position{line=1, character=18}}, text='updateView2('}}
, CompletionItem{start=20, length=3, textEdit=TextEdit{range=Range{start=Position{line=1, character=19}, end=Position{line=1, character=22}}, text=''Date = 
'}}
, CompletionItem{start=20, length=3, textEdit=TextEdit{range=Range{start=Position{line=1, character=19}, end=Position{line=1, character=22}}, text=''Delta = 
'}}
]

@JamesXNelson
Copy link
Member

updateView2 is a terrible pattern. Naming is hard, but we should come up with something more descriptive.

If the new name does start w/ updateView, it's fine to just add more cases to the test.

@devinrsmith
Copy link
Member Author

Current plan is to delete Collection<String> methods, and use Collection<StrongType>, so we can use the same overloaded name.

@devinrsmith devinrsmith requested a review from rcaudy June 28, 2021 22:07
Copy link
Member

@JamesXNelson JamesXNelson left a comment

Choose a reason for hiding this comment

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

Left quite a few comments regarding docs. Given the size of this PR and the urgency, I think it'd be okay if we just translate these requests into a "Document Table Operations API" issue.

I would like to see the vanila error messages approved before merging though.

Comment on lines -1308 to -1334
/**
* Perform a cross join with the right table.
* <p>
* Returns a table that is the cartesian product of left rows X right rows, with one column for each of the left
* table's columns, and one column corresponding to each of the right table's columns that are included in the
* columnsToAdd argument. The rows are ordered first by the left table then by the right table. If columnsToMatch
* is non-empty then the product is filtered by the supplied match conditions.
* <p>
* To efficiently produce updates, the bits that represent a key for a given row are split into two. Unless specified,
* join reserves 16 bits to represent a right row. When there are too few bits to represent all of the right rows
* for a given aggregation group the table will shift a bit from the left side to the right side. The default of 16
* bits was carefully chosen because it results in an efficient implementation to process live updates.
* <p>
* An {@link io.deephaven.db.v2.utils.OutOfKeySpaceException} is thrown when the total number of bits needed
* to express the result table exceeds that needed to represent Long.MAX_VALUE. There are a few work arounds:
* - If the left table is sparse, consider flattening the left table.
* - If there are no key-columns and the right table is sparse, consider flattening the right table.
* - If the maximum size of a right table's group is small, you can reserve fewer bits by setting numRightBitsToReserve on initialization.
* <p>
* Note: If you can prove that a given group has at most one right-row then you should prefer using {@link #naturalJoin}.
*
* @param rightTable The right side table on the join.
* @param columnsToMatch A collection of match conditions ("leftColumn=rightColumn" or "columnFoundInBoth")
* @param columnsToAdd A collection of the columns from the right side that need to be added to the left
* side as a result of the match.
* @return a new table joined according to the specification in columnsToMatch and columnsToAdd
*/
Copy link
Member

Choose a reason for hiding this comment

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

Has this javadoc moved somewhere? I don't see it offhand, but maybe hidden under a [+] somewhere...


@Override
public void visit(ColumnName columnName) {
out = new MatchPair(columnName.name(), columnName.name());
Copy link
Member

Choose a reason for hiding this comment

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

does it make sense to validate that out == null before assignment?

Copy link
Member Author

Choose a reason for hiding this comment

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

Technically, yes - the visitor pattern where I'm expecting a single call and single output it is a bit more correct to ensure it hasn't been invoked yet. I usually handle the output side checking that it's not null on return. That said, it's internal code, so it's not something an end-user can invoke incorrectly. In my latest code, this specific visitor no longer exists.

Comment on lines 101 to 108
private void expectParseFailure(String x) {
try {
ColumnAssignment.parse(x);
failBecauseExceptionWasNotThrown(IllegalArgumentException.class);
} catch (IllegalArgumentException e) {
// ignore
}
}
Copy link
Member

Choose a reason for hiding this comment

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

It's perfectly legal to do:

@Test(expected=IllegalArgumentException.class)
void doSomething() {
    ColumnAssignment.parse("Foo≡Bar")
}

Copy link
Member Author

Choose a reason for hiding this comment

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

This annotation doesn't work in Junit 5 (what I'm using here). There may be a more canonical way to express expectations for failures in Junit 5?

@devinrsmith devinrsmith requested a review from rcaudy July 8, 2021 18:05
@devinrsmith devinrsmith requested a review from rcaudy July 16, 2021 00:03
@devinrsmith devinrsmith merged commit 3fb181b into deephaven:main Jul 16, 2021
@devinrsmith devinrsmith deleted the table-operations branch July 16, 2021 15:10
jmao-denver pushed a commit to jmao-denver/deephaven-core that referenced this pull request Apr 11, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants