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

fix sending mutiple queries with single query bug #236

Merged
merged 2 commits into from
Nov 14, 2016

Conversation

shanexu
Copy link
Contributor

@shanexu shanexu commented Nov 8, 2016

should use @Filed and @FormUrlEncoded, or the arguments will encoded as query string append to request URL.

@codecov-io
Copy link

codecov-io commented Nov 8, 2016

Current coverage is 72.30% (diff: 63.63%)

Merging #236 into master will decrease coverage by 0.05%

@@             master       #236   diff @@
==========================================
  Files            11         11          
  Lines           633        639     +6   
  Methods           0          0          
  Messages          0          0          
  Branches         75         75          
==========================================
+ Hits            458        462     +4   
- Misses          142        144     +2   
  Partials         33         33          

Powered by Codecov. Last update 5d11e5f...94bd9e2

@majst01
Copy link
Collaborator

majst01 commented Nov 9, 2016

I already had the same idea, thanks, would you please show the behavior in a unit-test then i will merge.

@shanexu
Copy link
Contributor Author

shanexu commented Nov 9, 2016

    @Test
    public void testPostQuery() {
        String dbName = "unittest_" + System.currentTimeMillis();
        this.influxDB.createDatabase(dbName);
        QueryResult result = this.influxDB.query(new Query("SELECT * FROM not_exists;SELECT * FROM not_exists", dbName, true));
        Assert.assertEquals(2, result.getResults().size());
        this.influxDB.deleteDatabase(dbName);
    }

this will fail if use @Query

@majst01
Copy link
Collaborator

majst01 commented Nov 9, 2016

Yes of course, but include some tests, one for failing and one for working which shows how your code modifications make it work. A note on the README.md regarding multiple Queries in one request would also be helpful.

@shanexu
Copy link
Contributor Author

shanexu commented Nov 9, 2016

    @Test
    public void testPostQuery() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.readTimeout(1, TimeUnit.MINUTES);
        builder.connectTimeout(1, TimeUnit.MINUTES);
        builder.writeTimeout(1, TimeUnit.MINUTES);
        this.influxDB = InfluxDBFactory.connect("http://" + TestUtils.getInfluxIP() + ":" + TestUtils.getInfluxPORT(true), "admin", "admin", builder);
        String dbName = "unittest_" + System.currentTimeMillis();
        this.influxDB.createDatabase(dbName);
        String query = "SELECT * FROM not_exists";
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < 1 << 18; i++) {
            sb.append(query).append(";");
        }
        sb.deleteCharAt(sb.length() - 1);
        this.influxDB.query(new Query(sb.toString(), dbName, true));
        this.influxDB.deleteDatabase(dbName);
    }

this test case should throw exception if use @Query, http header is limited to a fixed size. When using @Query, the arguments will append to request url, and create a http request with large header.
When using @Field, the arugments are encoded into form and append to http request body.

@majst01
Copy link
Collaborator

majst01 commented Nov 12, 2016

@shanexu can you please rebase and resolve the merge conflict ?
After that i would like to merge it

@majst01
Copy link
Collaborator

majst01 commented Nov 12, 2016

@shanexu You should rebase, or clone again. The way you did it now does not show what you changed.

Please try again

@shanexu
Copy link
Contributor Author

shanexu commented Nov 12, 2016

Now, using @Field will cause

    @Test
    public void testWriteEnableGzip() {

this unit test case fail.
I need to read influxdb's source code to verify the problem.

influxdb does not handle a query request with Content-Encoding: gzip and Content-Type: application/x-www-form-urlencoded, so we should skip compressing for query request.

@shanexu shanexu changed the base branch from master to old_master November 12, 2016 23:58
@shanexu shanexu changed the base branch from old_master to master November 12, 2016 23:58
@shanexu
Copy link
Contributor Author

shanexu commented Nov 13, 2016

@majst01 is it OK now?

@jiafu1115
Copy link
Contributor

jiafu1115 commented Nov 13, 2016

@shanexu you can squash your commit into one commit to make PR's commit clean:
(I sqush all commits and force push then I only have one commit for one PR)
now your PR had 6 commits.Just one suggestion you can ignore it. Thanks.

@majst01
Copy link
Collaborator

majst01 commented Nov 13, 2016

@jiafu1115 what do you think, i am fine with this PR

Copy link
Contributor

@jiafu1115 jiafu1115 left a comment

Choose a reason for hiding this comment

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

@shanexu @majst01 are you sure of this:
influxdb does not handle a query request with Content-Encoding: gzip and Content-Type: application/x-www-form-urlencoded, so we should skip compressing for query request.
are you sure that it is influxdb's issue? if so you can skip it after all that gzip's focus is on write.

I provide some tiny suggestions on unit tests. Thanks. You can go ahead!

this.influxDB.createDatabase(dbName);
QueryResult result = this.influxDB.query(new Query("SELECT * FROM not_exists;SELECT * FROM not_exists", dbName, false));
Assert.assertEquals(2, result.getResults().size());
this.influxDB.deleteDatabase(dbName);
Copy link
Contributor

Choose a reason for hiding this comment

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

try...finally to make use tmp database to be removed

}

@Test
public void testPostQuery() {
Copy link
Contributor

Choose a reason for hiding this comment

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

add java doc or change test's method's name to show what's your test focus?

this.influxDB.createDatabase(dbName);
QueryResult result = this.influxDB.query(new Query("SELECT * FROM not_exists;SELECT * FROM not_exists", dbName));
Assert.assertEquals(2, result.getResults().size());
this.influxDB.deleteDatabase(dbName);
Copy link
Contributor

Choose a reason for hiding this comment

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

should using try...finally to delete tmp db

public void testPostQuery() {
String dbName = "unittest_" + System.currentTimeMillis();
try {
this.influxDB.createDatabase(dbName);
Copy link
Contributor

Choose a reason for hiding this comment

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

move to 123 from 125.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think it's necessary. Droping a non-existent database will not cause any problem.

Copy link
Contributor

Choose a reason for hiding this comment

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

it is one of best practices instead of if it is necessary for this case. So it is up to you. just one advice for best practice.

Copy link
Contributor

@jiafu1115 jiafu1115 left a comment

Choose a reason for hiding this comment

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

why need this (I notice the encoded=true in all query methods)? if need it, why loss it in write method on 333 line?

@@ -318,8 +319,9 @@ public QueryResult query(final Query query) {
call = this.influxDBService.postQuery(this.username,
this.password, query.getDatabase(), query.getCommand());
} else {
String encodedCommand = UrlEscapers.urlFormParameterEscaper().escape(query.getCommand());
Copy link
Contributor

Choose a reason for hiding this comment

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

why need this (I notice the encoded=true in all query methods)? if need it, why loss it in write method on 333 line?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

okhttp-3.4.2 use different policies on encoding query parameter and form field.

For query parameter
HttpUrl.java#L1120

    /** Encodes the query parameter using UTF-8 and adds it to this URL's query string. */
    public Builder addQueryParameter(String name, String value) {
      if (name == null) throw new NullPointerException("name == null");
      if (encodedQueryNamesAndValues == null) encodedQueryNamesAndValues = new ArrayList<>();
      encodedQueryNamesAndValues.add(
          canonicalize(name, QUERY_COMPONENT_ENCODE_SET, false, false, true, true));
      encodedQueryNamesAndValues.add(value != null
          ? canonicalize(value, QUERY_COMPONENT_ENCODE_SET, false, false, true, true)
          : null);
      return this;
    }

it does not encode some characters, for example ;, but influxdb need ; encode into %3B.

For form field
FormBody.java#L110

    public Builder add(String name, String value) {
      names.add(HttpUrl.canonicalize(name, FORM_ENCODE_SET, false, false, true, true));
      values.add(HttpUrl.canonicalize(value, FORM_ENCODE_SET, false, false, true, true));
      return this;
    }

it does encode ; and some other characters.

Copy link
Contributor

Choose a reason for hiding this comment

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

So why loss encode in line 333? It is query too

Copy link
Contributor Author

Choose a reason for hiding this comment

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

my fault, I see, i missed this one. i will fix this

Copy link
Contributor

@jiafu1115 jiafu1115 left a comment

Choose a reason for hiding this comment

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

SHOW+DATABASES? looks strange.....

@@ -362,7 +362,7 @@ public void deleteDatabase(final String name) {
@Override
public List<String> describeDatabases() {
QueryResult result = execute(this.influxDBService.query(this.username,
this.password, "SHOW DATABASES"));
this.password, "SHOW+DATABASES"));
Copy link
Contributor

Choose a reason for hiding this comment

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

SHOW+DATABASES? looks strange.....

Copy link
Contributor Author

@shanexu shanexu Nov 13, 2016

Choose a reason for hiding this comment

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

a space can be encoded into + or %20

@jiafu1115
Copy link
Contributor

jiafu1115 commented Nov 14, 2016

@shanexu I have one idea that if we can move url encode into new method called query.getCommandWithEncoded()? Then we may limit the code change lines and not change every where. For known command, we can does't encode it such as "create database" WDYT?

@jiafu1115
Copy link
Contributor

@shanexu do you have qq? we can talk offline.

@shanexu shanexu changed the title using Field to Post fix send mutiple queries bug Nov 14, 2016
@shanexu shanexu changed the title fix send mutiple queries bug fix sending mutiple queries with single query bug Nov 14, 2016
@jiafu1115
Copy link
Contributor

LGTM now. you missed the test cases so that coverage decreased

@majst01
Copy link
Collaborator

majst01 commented Nov 14, 2016

I`m going to merge this now, thanks for all of you for digging into that issue.

@majst01 majst01 merged commit 970aca8 into influxdata:master Nov 14, 2016
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.

4 participants