Skip to content

Conversation

@ericl
Copy link
Contributor

@ericl ericl commented Nov 30, 2016

What changes were proposed in this pull request?

Due to confusion between URI vs paths, in certain cases we escape partition values too many times, which causes some Hive client operations to fail or write data to the wrong location. This PR fixes at least some of these cases.

To my understanding this is how values, filesystem paths, and URIs interact.

  • Hive stores raw (unescaped) partition values that are returned to you directly when you call listPartitions.
  • Internally, we convert these raw values to filesystem paths via ExternalCatalogUtils.[un]escapePathName.
  • In some circumstances we store URIs instead of filesystem paths. When a path is converted to a URI via path.toURI, the escaped partition values are further URI-encoded. This means that to get a path back from a URI, you must call new Path(new URI(uriTxt)) in order to decode the URI-encoded string.
  • In CatalogStorageFormat we store URIs as strings. This makes it easy to forget to URI-decode the value before converting it into a path.
  • Finally, the Hive client itself uses mostly Paths for representing locations, and only URIs occasionally.

In the future we should probably clean this up, perhaps by dropping use of URIs when unnecessary. We should also try fixing escaping for partition names as well as values, though names are unlikely to contain special characters.

cc @mallman @cloud-fan @yhuai

How was this patch tested?

Unit tests.

// spark.sql(s"""
// |alter table test partition (A=0, B='%')
// |rename to partition (A=100, B='%')""".stripMargin)
// assert(spark.sql("select * from test where a = 100").count() == 1)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@cloud-fan this seems to crash in some of the post-processing code inHiveExternalCatalog:renamePartitions. Any ideas there?


// TODO(ekl) fix overwrite table
// spark.sql("show partitions test").show(false)
// spark.sql("insert overwrite table test partition (a, b) select id, id, '%' from range(1)")
Copy link
Contributor Author

@ericl ericl Nov 30, 2016

Choose a reason for hiding this comment

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

This crashes in the hive client. Not sure why, it might be a hive bug when deleting partitions that have been overwritten.

@SparkQA
Copy link

SparkQA commented Nov 30, 2016

Test build #69370 has finished for PR 16071 at commit 4162229.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@ericl ericl changed the title [SPARK-18635] [SQL] Partition name/values not escaped correctly in some cases [SPARK-18635] [SQL] [WIP] Partition name/values not escaped correctly in some cases Nov 30, 2016
spark.sql(s"""
|alter table test partition (A=0, B='%')
|set location '${dir.getAbsolutePath}'""".stripMargin)
assert(spark.sql("select * from test").count() == 29) // missing 1
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this 29 instead of 30?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since the partition was moved, there are no files in the new location. Hence -1 file

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah. I see. So Hive/Spark doesn't move partition data when the partition location is changed. Might be clearer to call that out in your comment rather than just "missing 1".

@mallman
Copy link
Contributor

mallman commented Nov 30, 2016

I can't vouch for how Path and URI work together to do the right thing, however the test coverage looks good. LGTM overall.

@ericl
Copy link
Contributor Author

ericl commented Nov 30, 2016

Ok I've figured out issues with the other test cases, they seem to be due to a separate bug: https://issues.apache.org/jira/browse/SPARK-18659

@ericl ericl changed the title [SPARK-18635] [SQL] [WIP] Partition name/values not escaped correctly in some cases [SPARK-18635] [SQL] Partition name/values not escaped correctly in some cases Nov 30, 2016
@SparkQA
Copy link

SparkQA commented Dec 1, 2016

Test build #69431 has finished for PR 16071 at commit 1bd10ba.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

asfgit pushed a commit that referenced this pull request Dec 1, 2016
…e cases

## What changes were proposed in this pull request?

Due to confusion between URI vs paths, in certain cases we escape partition values too many times, which causes some Hive client operations to fail or write data to the wrong location. This PR fixes at least some of these cases.

To my understanding this is how values, filesystem paths, and URIs interact.
- Hive stores raw (unescaped) partition values that are returned to you directly when you call listPartitions.
- Internally, we convert these raw values to filesystem paths via `ExternalCatalogUtils.[un]escapePathName`.
- In some circumstances we store URIs instead of filesystem paths. When a path is converted to a URI via `path.toURI`, the escaped partition values are further URI-encoded. This means that to get a path back from a URI, you must call `new Path(new URI(uriTxt))` in order to decode the URI-encoded string.
- In `CatalogStorageFormat` we store URIs as strings. This makes it easy to forget to URI-decode the value before converting it into a path.
- Finally, the Hive client itself uses mostly Paths for representing locations, and only URIs occasionally.

In the future we should probably clean this up, perhaps by dropping use of URIs when unnecessary. We should also try fixing escaping for partition names as well as values, though names are unlikely to contain special characters.

cc mallman cloud-fan yhuai

## How was this patch tested?

Unit tests.

Author: Eric Liang <[email protected]>

Closes #16071 from ericl/spark-18635.

(cherry picked from commit 88f559f)
Signed-off-by: Wenchen Fan <[email protected]>
@cloud-fan
Copy link
Contributor

LGTM, merging to master/2.1!

@asfgit asfgit closed this in 88f559f Dec 1, 2016
robert3005 pushed a commit to palantir/spark that referenced this pull request Dec 2, 2016
…e cases

## What changes were proposed in this pull request?

Due to confusion between URI vs paths, in certain cases we escape partition values too many times, which causes some Hive client operations to fail or write data to the wrong location. This PR fixes at least some of these cases.

To my understanding this is how values, filesystem paths, and URIs interact.
- Hive stores raw (unescaped) partition values that are returned to you directly when you call listPartitions.
- Internally, we convert these raw values to filesystem paths via `ExternalCatalogUtils.[un]escapePathName`.
- In some circumstances we store URIs instead of filesystem paths. When a path is converted to a URI via `path.toURI`, the escaped partition values are further URI-encoded. This means that to get a path back from a URI, you must call `new Path(new URI(uriTxt))` in order to decode the URI-encoded string.
- In `CatalogStorageFormat` we store URIs as strings. This makes it easy to forget to URI-decode the value before converting it into a path.
- Finally, the Hive client itself uses mostly Paths for representing locations, and only URIs occasionally.

In the future we should probably clean this up, perhaps by dropping use of URIs when unnecessary. We should also try fixing escaping for partition names as well as values, though names are unlikely to contain special characters.

cc mallman cloud-fan yhuai

## How was this patch tested?

Unit tests.

Author: Eric Liang <[email protected]>

Closes apache#16071 from ericl/spark-18635.
uzadude pushed a commit to uzadude/spark that referenced this pull request Jan 27, 2017
…e cases

## What changes were proposed in this pull request?

Due to confusion between URI vs paths, in certain cases we escape partition values too many times, which causes some Hive client operations to fail or write data to the wrong location. This PR fixes at least some of these cases.

To my understanding this is how values, filesystem paths, and URIs interact.
- Hive stores raw (unescaped) partition values that are returned to you directly when you call listPartitions.
- Internally, we convert these raw values to filesystem paths via `ExternalCatalogUtils.[un]escapePathName`.
- In some circumstances we store URIs instead of filesystem paths. When a path is converted to a URI via `path.toURI`, the escaped partition values are further URI-encoded. This means that to get a path back from a URI, you must call `new Path(new URI(uriTxt))` in order to decode the URI-encoded string.
- In `CatalogStorageFormat` we store URIs as strings. This makes it easy to forget to URI-decode the value before converting it into a path.
- Finally, the Hive client itself uses mostly Paths for representing locations, and only URIs occasionally.

In the future we should probably clean this up, perhaps by dropping use of URIs when unnecessary. We should also try fixing escaping for partition names as well as values, though names are unlikely to contain special characters.

cc mallman cloud-fan yhuai

## How was this patch tested?

Unit tests.

Author: Eric Liang <[email protected]>

Closes apache#16071 from ericl/spark-18635.
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