summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraneporada <[email protected]>2022-08-09 14:31:56 +0300
committeraneporada <[email protected]>2022-08-09 14:31:56 +0300
commitad45d2a71f75d80a4e78754bb028116ced95dafb (patch)
treeb2eb15b846120ceed864c47d206f17cb246e83f9
parentacfd90c7557e01d7453cb59130f9a0aeeb4952f4 (diff)
[] Return empty result when reading from empty/non-existing S3 "directories"
-rw-r--r--ydb/library/yql/providers/s3/provider/yql_s3_io_discovery.cpp38
1 files changed, 28 insertions, 10 deletions
diff --git a/ydb/library/yql/providers/s3/provider/yql_s3_io_discovery.cpp b/ydb/library/yql/providers/s3/provider/yql_s3_io_discovery.cpp
index f0bb1f488f2..acc8744720c 100644
--- a/ydb/library/yql/providers/s3/provider/yql_s3_io_discovery.cpp
+++ b/ydb/library/yql/providers/s3/provider/yql_s3_io_discovery.cpp
@@ -32,10 +32,11 @@ struct TListRequest {
TString Token;
TString Url;
TString Pattern;
+ TString UserPath;
};
bool operator<(const TListRequest& a, const TListRequest& b) {
- return std::tie(a.Token, a.Url, a.Pattern) < std::tie(b.Token, b.Url, b.Pattern);
+ return std::tie(a.Token, a.Url, a.Pattern, a.UserPath) < std::tie(b.Token, b.Url, b.Pattern, b.UserPath);
}
using TPendingRequests = TMap<TListRequest, NThreading::TFuture<IS3Lister::TListResult>>;
@@ -150,13 +151,10 @@ public:
}
const auto& listEntries = std::get<IS3Lister::TListEntries>(listResult);
- if (listEntries.empty()) {
- if (IS3Lister::HasWildcards(req.Pattern)) {
- ctx.AddError(TIssue(ctx.GetPosition(object.Pos()), TStringBuilder() << "Object " << req.Pattern << " has no items."));
- } else {
- ctx.AddError(TIssue(ctx.GetPosition(object.Pos()),
- TStringBuilder() << "Object " << req.Pattern << " doesn't exist" << (req.Pattern.EndsWith('/') ? " or is a directory." : ".")));
- }
+ if (listEntries.empty() && !generatedColumnsConfig && !req.UserPath.EndsWith("/")) {
+ // request to list particular files that are missing
+ ctx.AddError(TIssue(ctx.GetPosition(object.Pos()),
+ TStringBuilder() << "Object " << req.UserPath << " doesn't exist."));
return TStatus::Error;
}
@@ -226,6 +224,21 @@ public:
auto settings = read.Ref().Child(4)->ChildrenList();
auto userSchema = ExtractSchema(settings);
+ if (pathNodes.empty()) {
+ auto data = ctx.Builder(read.Pos())
+ .Callable("List")
+ .Callable(0, "ListType")
+ .Add(0, userSchema.front())
+ .Seal()
+ .Seal()
+ .Build();
+ if (userSchema.back()) {
+ data = ctx.NewCallable(read.Pos(), "AssumeColumnOrder", { data, userSchema.back() });
+ }
+ replaces.emplace(node, ctx.NewCallable(read.Pos(), "Cons!", { read.World().Ptr(), data }));
+ continue;
+ }
+
TExprNode::TPtr s3Object;
s3Object = Build<TS3Object>(ctx, object.Pos())
.Paths(ctx.NewList(object.Pos(), std::move(pathNodes)))
@@ -345,10 +358,15 @@ private:
TListRequest req;
req.Token = tokenStr;
req.Url = url;
+ req.UserPath = path;
if (partitionedBy.empty()) {
- // treat paths as regular wildcard patterns
- req.Pattern = path;
+ if (path.EndsWith("/")) {
+ req.Pattern = path + "*";
+ } else {
+ // treat paths as regular wildcard patterns
+ req.Pattern = path;
+ }
} else {
if (IS3Lister::HasWildcards(path)) {
ctx.AddError(TIssue(ctx.GetPosition(read.Pos()), TStringBuilder() << "Path prefix: '" << path << "' contains wildcards"));