-
Notifications
You must be signed in to change notification settings - Fork 237
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
[CALCITE-5964] Add test case checking that connection.getMetaData().getTables() handles responses with different signature shapes. #227
base: main
Are you sure you want to change the base?
Conversation
…etTables() handles responses with different signature shapes. Also adding in Type.CLASS to ConnectionProperty.java and the associated getters.
eb50d7e
to
143e336
Compare
Add in rows fix lint
143e336
to
d3e6a9f
Compare
|
||
/** Returns the class value of this property. Throws if not set and no | ||
* default. */ | ||
public Class<?> getClazz(Class<?> clazz, Class<?> defaultValue) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Java convention uses clazz
because class
is a keyword. getClass
is not a keyword. Just call this getClass
. Same goes for all other names that contain the word "class" but are not keywords.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a small chance for confusion with Object.getClass()
. So, I would recommend calling it getType
.
@@ -434,6 +447,30 @@ public T apply(ConnectionProperty connectionProperty, String s) { | |||
} | |||
}; | |||
} | |||
|
|||
public static <T> Converter<T> clazzConverter(final T clazz, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
T
can be narrowed to Class<T>
, since there's only 1 callsite for this function and it will always pass in a Class<X>
for some X
. That would also make the variable name less confusing.
I suppose that would make this a Converter<Class<?>>
. You may want to add another type variable for defaultClass
.
@@ -388,6 +388,32 @@ public MetaColumn( | |||
public String getName() { | |||
return columnName; | |||
} | |||
public static String[] getColumnNames() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might as well link to some documentation: https://docs.oracle.com/en/java/javase/20/docs/api/java.sql/java/sql/DatabaseMetaData.html#getColumns(java.lang.String,java.lang.String,java.lang.String,java.lang.String)
Also add a comment explaining why anybody might want to override this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's static so it can't be overridden, the reader thinks. The fact that the caller is using reflection to find and invoke it could definitely do with some commentary, if that is indeed the best way for the caller to get this information.
+ "[\"PUBLIC\",\"SCOTT\",\"EMP\",\"TABLE\",null,null,null,null,null,null,\"MEMORY\",false,null,\"EXTRA_LABEL2\"]," | ||
+ "[\"PUBLIC\",\"SCOTT\",\"BONUS\",\"TABLE\",null,null,null,null,null,null,\"MEMORY\",false,null,\"EXTRA_LABEL3\"]," | ||
+ "[\"PUBLIC\",\"SCOTT\",\"SALGRADE\",\"TABLE\",null,null,null,null,null,null,\"MEMORY\",false,null,null]]}," | ||
+ "\"updateCount\":-1,\"rpcMetadata\":null}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This JSON blob is impenetrable. How did you produce this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran another test within Avatica and took that json blob and modified it
What does 'impenetrable' mean here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's hard to read this data fixture and understand its direct relationship with assertions in tests.
There's also the usual problem with mocking - how do you keep your mocks in sync with the real implementation. When Avatica changes its response, tests depending on this fixture will go stale without further notice and there is no forcing function to cause them to be updated until or unless a regression occurs. But this problem is hard to solve without designing for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So one thing to note is that this test really just shows that whatever Signature comes in (different columns, different orders), Avatica is able to handle the different shapes and read them in the supplied order.
It doesn't test whether the real implementation is providing a correct response in the right order. That part should be up to the implementation.
Maybe that point wasn't clear by this additional test, perhaps I should shorten the JSON to contain fewer columns and add a comment stating that the point is that the signature column order matches up with the resultset columns?
@@ -127,6 +127,21 @@ private Connection getMockConnection() { | |||
connection.close(); | |||
} | |||
|
|||
@Test public void testTablesAdditionalColumns() throws Exception { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not convinced of the usefulness of this test. Which part of the production code is actually being exercised? Kinda looks like we're just stubbing a mock, then testing that we stubbed it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It mocks getting the response, but it actually tests the client code in RemoteMeta that handles the response and parses the signature into the ResultSet.
@@ -388,6 +388,32 @@ public MetaColumn( | |||
public String getName() { | |||
return columnName; | |||
} | |||
public static String[] getColumnNames() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's static so it can't be overridden, the reader thinks. The fact that the caller is using reflection to find and invoke it could definitely do with some commentary, if that is indeed the best way for the caller to get this information.
+ "[\"PUBLIC\",\"SCOTT\",\"EMP\",\"TABLE\",null,null,null,null,null,null,\"MEMORY\",false,null,\"EXTRA_LABEL2\"]," | ||
+ "[\"PUBLIC\",\"SCOTT\",\"BONUS\",\"TABLE\",null,null,null,null,null,null,\"MEMORY\",false,null,\"EXTRA_LABEL3\"]," | ||
+ "[\"PUBLIC\",\"SCOTT\",\"SALGRADE\",\"TABLE\",null,null,null,null,null,null,\"MEMORY\",false,null,null]]}," | ||
+ "\"updateCount\":-1,\"rpcMetadata\":null}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's hard to read this data fixture and understand its direct relationship with assertions in tests.
There's also the usual problem with mocking - how do you keep your mocks in sync with the real implementation. When Avatica changes its response, tests depending on this fixture will go stale without further notice and there is no forcing function to cause them to be updated until or unless a regression occurs. But this problem is hard to solve without designing for it.
b97b819
to
4c0999b
Compare
Also adding in Type.CLASS to ConnectionProperty.java and the associated getters.