Skip to content

Fix#95: support host and port arguments configuration for different DBMSs in SQLancer #315

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 22 commits into from Mar 25, 2021
Merged

Conversation

ghost
Copy link

@ghost ghost commented Mar 12, 2021

What problem does this PR solve?

Issue number: #95

Summary

Supporting host/port arguments for the follow databases:

  • PostgreSQL
  • MySQL
  • MariaDB
  • TiDB
  • Clickhouse
  • CockRoachDB
  • Citus extends PostgreSQL

Release note

No release note

Copy link
Contributor

@mrigger mrigger left a comment

Choose a reason for hiding this comment

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

Thanks a lot for the PR. The changes look great overall.

I think that we need to expose the default port and host to the user in some way. See my thoughts in this respect as an in-line comment. Let me know if you have any follow-up questions or thoughts.

Thanks again for the great PR!

@@ -31,6 +31,10 @@
import sqlancer.mysql.gen.tblmaintenance.MySQLRepair;

public class MySQLProvider extends SQLProviderAdapter<MySQLGlobalState, MySQLOptions> {
protected String username;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are these (and equivalent variables in other classes) fields and not local variables? They are only used in the createDatabase method, no?

Copy link
Contributor

Choose a reason for hiding this comment

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

I do not really understand. Could you expand on what issues there might be when using a local variable rather than a field?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ideally, we would still use local variables here, but if you are reluctant to do this for this PR, I can also do this in a future follow-up PR.

@@ -102,9 +104,19 @@ public void generateDatabase(ClickHouseGlobalState globalState) throws Exception

@Override
public SQLConnection createDatabase(ClickHouseGlobalState globalState) throws SQLException {
host = globalState.getOptions().getHost();
port = globalState.getOptions().getPort();
if ("sqlancer".equals(host)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

As mentioned before, I think that this check makes it difficult to understand what's going on. I think that we want that the user has a clear understanding of the default values for the host and port. Currently, "sqlancer" is displayed as a default value for the host and port, but actually, these default values are overwritten by DBMS-specific ones that the user cannot see. I see two potential options to address this:

  1. we put these options in a base option class that is used by all the DBMS-specific option classes and instantiated with suitable default values. This is the option that I further explained in my previous comment.
  2. We set host and port to be null, and include the default values as part of the DBMS description in the options. For example, every provider implementation could implement a method int getDefaultPort() and String getDefaultHost() that is then used in the main class to print the default values. For example, for ClickHouse, the following would be printed:
  clickhouse      ClickHouse (default port: 8123, default host: localhost)
      Usage: clickhouse [options]
        Options:
        ...

Previously, you mentioned that the host and port can be null, but would this not result in an invalid URL?

Copy link
Author

@ghost ghost Mar 17, 2021

Choose a reason for hiding this comment

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

This process actually involves two points:
(1) The user does not specify the host and port, then we need to replace it with the default value, which is different in different databases. This may be better set in xxOptions.java of each database.
(2) If the user sets one of host and port, we should use the value provided by the user to replace the default value of these systems. This should probably be set in xxProvider.java.

This may be modified in several places, refactoring several parts...(-:

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, there are multiple ways to implement this. It would be great to have this, so that the user knows about the default values.

ClickHouseOptions clickHouseOptions = globalState.getDmbsSpecificOptions();
globalState.setClickHouseOptions(clickHouseOptions);
String url = "jdbc:clickhouse://localhost:8123/default";
// String url = "jdbc:clickhouse://localhost:8123/default";
String url = "jdbc:clickhouse://" + host + ":" + port + "/defult";
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo: this should be default.

Copy link
Author

Choose a reason for hiding this comment

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

Typo: this should be default.

I will modify it next time pull request.

@@ -49,6 +49,12 @@
@Parameter(names = "--password", description = "The password used to log into the DBMS")
private String password = "sqlancer"; // NOPMD

@Parameter(names = "--host", description = "The host used to log into the DBMS")
private String host = "sqlancer"; // NOPMD
Copy link
Contributor

Choose a reason for hiding this comment

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

Since these options are not supported by all DBMSs (yet): Would it be possible to insert a (static) check method that is called by every provider that does not support these? This is optional for this PR, but it might be a useful future improvement.

Copy link
Author

@ghost ghost Mar 17, 2021

Choose a reason for hiding this comment

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

Since these options are not supported by all DBMSs (yet): Would it be possible to insert a (static) check method that is called by every provider that does not support these? This is optional for this PR, but it might be a useful future improvement.

We modify the description information to remind users that this value will be reset by the system. Is it feasible?

@Parameter(names = "--host", description = "The host used to log into the DBMS. If the user does not specify this value, it will be reset to localhost by the system")
    private String host = "sqlancer"; // NOPMD

@Parameter(names = "--host", description = "The host used to log into the DBMS. If the user does not specify this value, it will be reset to database system default port by the system")
    private String host = "sqlancer"; // NOPMD

In fact, another important function of placeholders is to facilitate us to determine whether the user has specified this parameter, so invalid values ​​should be used as placeholders. The value sqlancer is a good choice. These two values ​​are actually essentially different from username and password. The default of host is localhost. The default of port is database parameter.

what do you think? :) (-:

Copy link
Contributor

Choose a reason for hiding this comment

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

I do not yet understand yet why we need any placeholders in the options. None of the other options have deliberately invalid default values, I believe. If you want to indicate that no port or host have been set, should they be null?

Copy link
Author

Choose a reason for hiding this comment

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

I do not yet understand yet why we need any placeholders in the options. None of the other options have deliberately invalid default values, I believe. If you want to indicate that no port or host have been set, should they be null?

Yes, null is also possible. But according to the previous design, does the system still have to reset the host and port to the corresponding to localhost and the default port of database respectively? If you think null is more appropriate, I am willing to modify it. LMK, please.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, I believe that either null, while also printing the default values when the help text is printed, or implementing them as DBMS-specific options (rather than in MainOptions) would be ways to achieve this.

@ghost
Copy link
Author

ghost commented Mar 18, 2021

TBR. Please let me know if this version can be merged? Thank you @mrigger

@mrigger
Copy link
Contributor

mrigger commented Mar 19, 2021

Sorry for the delayed response! As mentioned, it would be great to address the two concerns I mentioned: (1) we want to display the default values that each DBMS uses to the user as part of the help text and (2) not use invalid default values (i.e., either use null or implement them as DBMS-specific options). Please let me know if there are any unclarities, and I will provide more details.

@ghost
Copy link
Author

ghost commented Mar 20, 2021

TBR @mrigger
If there is anything inappropriate, please let me know!

@@ -23,7 +23,7 @@
import sqlancer.common.oracle.CompositeTestOracle;
import sqlancer.common.oracle.TestOracle;

@Parameters(separators = "=", commandDescription = "Test CockroachDB")
@Parameters(separators = "=", commandDescription = "CockroachDB (default port: 26257, default host: localhost)")
Copy link
Contributor

Choose a reason for hiding this comment

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

Rather than hard-coding the port and localhost, could you please introduce constants for them that you use in both the description and when setting the values?

For example, in CockroachDBOptions you can have a field final static int DEFAULT_PORT = 26257; and reference it both here as "CockroachDB (default port: " + CockroachDBOptions.DEFAULT_PORT + ... and below in createDatabase. By doing so, the help text and actual default values will always be consistent.

Copy link
Author

Choose a reason for hiding this comment

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

Indeed, the current help text and default value can be consistent here.
Thank you for your suggestions.
TBR @mrigger

Copy link
Contributor

Choose a reason for hiding this comment

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

Sorry again for the late response - I had some full-day obligations in the last couple of days, and will be able to respond much faster in the future.

Why does using the constant in the annotation text not work?

private String host = null; // NOPMD

@Parameter(names = "--port", description = "The port used to log into the DBMS")
private int port = -1; // NOPMD
Copy link
Contributor

Choose a reason for hiding this comment

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

Rather than checking for -1, could you please introduce a constant like NO_PORT_SET and use it also in the createDatabase methods?

String databaseName = globalState.getDatabaseName();
String url = "jdbc:mysql://127.0.0.1:4000/";
// String url = "jdbc:mysql://127.0.0.1:4000/";
Copy link
Contributor

Choose a reason for hiding this comment

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

Ideally, we could remove the commented-out code (but you don't need to do this for this PR).

@mrigger
Copy link
Contributor

mrigger commented Mar 20, 2021

TBR @mrigger
If there is anything inappropriate, please let me know!

Thanks a lot again for your changes and for your patience! After introducing constants and using them to replace the hard-coded values, we can likely merge the PR.

@ghost
Copy link
Author

ghost commented Mar 21, 2021

TBR @mrigger Thanks for your suggestions. Please review the latest revisions, and if necessary, please suggest revisions.

@mrigger
Copy link
Contributor

mrigger commented Mar 25, 2021

Thanks a lot for your PR and for incorporating my improvement suggestions. I highly appreciate it! Merging the PR now.

For future PRs, please pay attention to a "clean" commit history by avoid merges as well as rewriting the history for incorporating feedback (and removing accidentally committed files), see https://github.com/sqlancer/sqlancer/blob/master/CONTRIBUTING.md#commit-history.

@mrigger mrigger merged commit 695dda5 into sqlancer:master Mar 25, 2021
@ghost
Copy link
Author

ghost commented Mar 25, 2021

Thanks a lot for your PR and for incorporating my improvement suggestions. I highly appreciate it! Merging the PR now.

For future PRs, please pay attention to a "clean" commit history by avoid merges as well as rewriting the history for incorporating feedback (and removing accidentally committed files), see https://github.com/sqlancer/sqlancer/blob/master/CONTRIBUTING.md#commit-history.

Thanks for your suggestions. It’s a great honor to contribute to this project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy