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

Change in TableId behaviour for non default BigQueryClient project 1.44 -> 1.45 #3808

Closed
NickApostolidesMatillion opened this issue Oct 11, 2018 · 16 comments · Fixed by #4227
Assignees
Labels
api: bigquery Issues related to the BigQuery API. priority: p1 Important issue which blocks shipping the next release. Will be fixed prior to next release. 🚨 This issue needs some love. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.

Comments

@NickApostolidesMatillion
Copy link

NickApostolidesMatillion commented Oct 11, 2018

When using the getTable method of the BigQuery client the project of the TableId is overwritten. TableId would previously ignore this if a project had been set. Table Id has been changed such that the project is always overwritten. There is now no way to get a table for a project other than the one the client was created for.

TableId tableId = TableId.of(project, schema, tableName);
Table table = client.getTable(tableId);
// table returns null if project != client.getOptions().getProjectId()

this is due to the change in TableId

In BigQueryImpl:

public Table getTable(TableId tableId, TableOption... options) {
    final TableId completeTableId = tableId.setProjectId(getOptions().getProjectId());
    ...

TableId old code:

TableId setProjectId(String projectId) {
  return getProject() != null ? this : TableId.of(projectId, getDataset(), getTable());
}

TableId new code:

TableId setProjectId(String projectId) {
  Preconditions
    .checkArgument(!Strings.isNullOrEmpty(projectId), "Provided projectId is null or empty");
  return TableId.of(projectId, getDataset(), getTable());
}
@JustinBeckwith JustinBeckwith added the triage me I really want to be triaged. label Oct 12, 2018
@sduskis sduskis added type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. api: bigquery Issues related to the BigQuery API. priority: p1 Important issue which blocks shipping the next release. Will be fixed prior to next release. labels Oct 14, 2018
@JustinBeckwith JustinBeckwith added the 🚨 This issue needs some love. label Oct 16, 2018
@MMMarcy
Copy link

MMMarcy commented Oct 17, 2018

@NickApostolidesMatillion I'm the author of that change. It was due to #3283 and this behavior is definitely unintended. However, reverting the change will re-open the mentioned issue.

Perhaps something like:

public Table getTable(TableId tableId, TableOption... options) {

    final TableId completeTableId = tableId.setProjectId(
        tableId.getProjectId() == null
        ? getOptions().getProjectId()
        : tableId.getProjectId()
    );
...
}

Would solve your issue and still keep the fix for #3283 (granted that now you supply a TableId with the desired projectId already set).

@NickApostolidesMatillion
Copy link
Author

@MMMarcy that would work for us. It is more suitable to have this logic in BigQueryImpl.

Thanks

@MMMarcy
Copy link

MMMarcy commented Oct 17, 2018

Perfect. Waiting for the owners thoughts now. If positive, I can open a PR

@MMMarcy
Copy link

MMMarcy commented Oct 17, 2018

Actually, thinking more about this using the proposed solution I mentioned hides too much of the behavior to the caller. Maybe overloading the getTable method with

public Table getTable(TableId tableId, ProjectId projectId, TableOption... options) {
...
}

seems a better alternative.

@NickApostolidesMatillion
Copy link
Author

NickApostolidesMatillion commented Oct 17, 2018

TableId already has a factory method including the project:

public static TableId of(String project, String dataset, String table)

I would suggest that if the project is set in TableId, the developer knows the project he/she wants.

@JustinBeckwith JustinBeckwith added 🚨 This issue needs some love. and removed 🚨 This issue needs some love. triage me I really want to be triaged. labels Oct 17, 2018
@JustinBeckwith JustinBeckwith added 🚨 This issue needs some love. and removed 🚨 This issue needs some love. labels Oct 27, 2018
JesseLovelace pushed a commit that referenced this issue Oct 30, 2018
Now getTable of BigQueryImpl checks if the provided TableId has the
project set. If yes, the set projectId is used, otherwise the projectId
used when creating the BigQuery client will be used.

The additional test checks this behavior by calling getTableId with an
empty projectId.
@polleyg
Copy link

polleyg commented Nov 12, 2018

Unless I've missed something obvious folks, I think this issue needs to be reopened. The PR only fixed the getTable() method, but the same bug exists for other methods like delete(TableId tableId) and update(TableInfo tableInfo). Other methods like create() and update() also appear to have the same issue.

@NickApostolidesMatillion
Copy link
Author

@MMMarcy Can this issue be reopened and all occurrences be fixed or the original change reverted?

@chingor13 chingor13 reopened this Nov 13, 2018
@chingor13
Copy link
Contributor

@JesseLovelace PTAL

@polleyg
Copy link

polleyg commented Nov 14, 2018

Hey Folks - happy to open new issue(s) if that's what is needed to get this fixed up? Just let me know.

@JustinBeckwith JustinBeckwith added 🚨 This issue needs some love. and removed 🚨 This issue needs some love. labels Nov 19, 2018
@polleyg
Copy link

polleyg commented Nov 22, 2018

Hey Folks - any chance of getting someone to look at this? It's becoming a bit of a problem now. Maybe reverting the original change should be considered.

@mikekap
Copy link

mikekap commented Dec 3, 2018

I think there's way more callsites of setProjectId that aren't fixed - including insertAll that are still broken. IntelliJ shows 15 usages of which 3 are fixed now.

@mikekap
Copy link

mikekap commented Dec 6, 2018

@MMMarcy given the extent of the breakage - what was the motivation behind the original change? The setProjectId method is package-private so it shouldn't have been called externally.

@sduskis sduskis reopened this Dec 6, 2018
@sduskis
Copy link
Contributor

sduskis commented Dec 6, 2018

@pmakani, it looks like there are more places that need to change.

@chingor13
Copy link
Contributor

@pmakani Did #4196 actually fix all the cases?

@chingor13 chingor13 reopened this Dec 12, 2018
@polleyg
Copy link

polleyg commented Dec 13, 2018

@chingor13 I was about to ask the same. He's all the references I see to setProject() in my IDEA..
screen shot 2018-12-13 at 11 00 13 am

@lepistone
Copy link

Hi, we believe this is still broken as of today (1.65.0). As in the description of this ticket, still There is now no way to get a table for a project other than the one the client was created for.

Specifically, in https://github.com/googleapis/google-cloud-java/blob/master/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/BigQueryImpl.java#L635-L639 , the project in my tableId will always be overridden with the project of the service, if the service has a project.

Maybe the intention of that code was to override the project only if it is not set in tableId? Then the code would look like

          tableId.setProjectId(
              Strings.isNullOrEmpty(tableId.getProjectId())
                  ? serviceOptions.getProjectId());
                  : tableId.getProject()

Or maybe, the confusion arose between TableId and TableInfo. The code above calls TableId::setProject, which will always perform the change. See: https://github.com/googleapis/google-cloud-java/blob/master/google-cloud-clients/google-cloud-bigquery/src/main/java/com/google/cloud/bigquery/TableId.java#L100

Thanks!

stephaniewang526 pushed a commit to googleapis/java-bigquery that referenced this issue Dec 6, 2019
Now getTable of BigQueryImpl checks if the provided TableId has the
project set. If yes, the set projectId is used, otherwise the projectId
used when creating the BigQuery client will be used.

The additional test checks this behavior by calling getTableId with an
empty projectId.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: bigquery Issues related to the BigQuery API. priority: p1 Important issue which blocks shipping the next release. Will be fixed prior to next release. 🚨 This issue needs some love. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants