blob: 9b598e6429f1492a817a39e4d26e49ac3574cbf9 [file]
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "src/trace_processor/sqlite/sql_source.h"
#include "test/gtest_and_gmock.h"
namespace perfetto {
namespace trace_processor {
namespace {
TEST(SqlSourceTest, Factory) {
SqlSource source = SqlSource::FromExecuteQuery("SELECT * FROM slice");
ASSERT_EQ(source.AsTraceback(0),
R"( --> query:1:1
|
1 | SELECT * FROM slice
| ^
)");
ASSERT_EQ(source.AsTraceback(7),
R"( --> query:1:8
|
1 | SELECT * FROM slice
| ^
)");
}
TEST(SqlSourceTest, Substr) {
SqlSource source =
SqlSource::FromExecuteQuery("SELECT * FROM slice").Substr(9, 10);
ASSERT_EQ(source.sql(), "FROM slice");
ASSERT_EQ(source.AsTraceback(0),
R"( --> query:1:10
|
1 | FROM slice
| ^
)");
ASSERT_EQ(source.AsTraceback(6),
R"( --> query:1:16
|
1 | FROM slice
| ^
)");
}
TEST(SqlSourceTest, RewriteAllIgnoreExisting) {
SqlSource source =
SqlSource::FromExecuteQuery("macro!()")
.RewriteAllIgnoreExisting(SqlSource::FromTraceProcessorImplementation(
"SELECT * FROM slice"));
ASSERT_EQ(source.sql(), "SELECT * FROM slice");
ASSERT_EQ(source.AsTraceback(0),
R"( --> query:1:1
|
1 | macro!()
| ^
= note: fully expanded statement:
SELECT * FROM slice
^
--> trace processor internal:1:1
|
1 | SELECT * FROM slice
| ^
)");
ASSERT_EQ(source.AsTraceback(7),
R"( --> query:1:1
|
1 | macro!()
| ^
= note: fully expanded statement:
SELECT * FROM slice
^
--> trace processor internal:1:8
|
1 | SELECT * FROM slice
| ^
)");
}
TEST(SqlSourceTest, NestedFullRewrite) {
SqlSource nested =
SqlSource::FromTraceProcessorImplementation("nested!()")
.RewriteAllIgnoreExisting(SqlSource::FromTraceProcessorImplementation(
"SELECT * FROM slice"));
ASSERT_EQ(nested.sql(), "SELECT * FROM slice");
SqlSource source = SqlSource::FromExecuteQuery("macro!()")
.RewriteAllIgnoreExisting(std::move(nested));
ASSERT_EQ(source.sql(), "SELECT * FROM slice");
ASSERT_EQ(source.AsTraceback(0),
R"( --> query:1:1
|
1 | macro!()
| ^
= note: fully expanded statement:
SELECT * FROM slice
^
--> trace processor internal:1:1
|
1 | nested!()
| ^
--> trace processor internal:1:1
|
1 | SELECT * FROM slice
| ^
)");
ASSERT_EQ(source.AsTraceback(7),
R"( --> query:1:1
|
1 | macro!()
| ^
= note: fully expanded statement:
SELECT * FROM slice
^
--> trace processor internal:1:1
|
1 | nested!()
| ^
--> trace processor internal:1:8
|
1 | SELECT * FROM slice
| ^
)");
}
TEST(SqlSourceTest, RewriteAllIgnoresExistingCorrectly) {
SqlSource foo =
SqlSource::FromExecuteQuery("foo!()").RewriteAllIgnoreExisting(
SqlSource::FromTraceProcessorImplementation("SELECT * FROM slice"));
SqlSource source = foo.RewriteAllIgnoreExisting(
SqlSource::FromTraceProcessorImplementation("SELECT 0 WHERE 0"));
ASSERT_EQ(source.sql(), "SELECT 0 WHERE 0");
ASSERT_EQ(source.AsTraceback(0),
R"( --> query:1:1
|
1 | foo!()
| ^
= note: fully expanded statement:
SELECT 0 WHERE 0
^
--> trace processor internal:1:1
|
1 | SELECT 0 WHERE 0
| ^
)");
ASSERT_EQ(source.AsTraceback(4),
R"( --> query:1:1
|
1 | foo!()
| ^
= note: fully expanded statement:
SELECT 0 WHERE 0
^
--> trace processor internal:1:5
|
1 | SELECT 0 WHERE 0
| ^
)");
}
TEST(SqlSourceTest, Rewriter) {
SqlSource::Rewriter rewriter(
SqlSource::FromExecuteQuery("SELECT cols!() FROM slice"));
rewriter.Rewrite(7, 14,
SqlSource::FromTraceProcessorImplementation(
"ts, dur, ts + dur AS ts_end"));
SqlSource rewritten = std::move(rewriter).Build();
ASSERT_EQ(rewritten.sql(), "SELECT ts, dur, ts + dur AS ts_end FROM slice");
// Offset points at the top level source.
ASSERT_EQ(rewritten.AsTraceback(0),
R"( --> query:1:1
|
1 | SELECT cols!() FROM slice
| ^
= note: fully expanded statement:
SELECT ts, dur, ts + dur AS ts_end FROM slice
^
)");
ASSERT_EQ(rewritten.AsTraceback(40),
R"( --> query:1:21
|
1 | SELECT cols!() FROM slice
| ^
= note: fully expanded statement:
SELECT ts, dur, ts + dur AS ts_end FROM slice
^
)");
// Offset points at the nested source.
ASSERT_EQ(rewritten.AsTraceback(16),
R"( --> query:1:8
|
1 | SELECT cols!() FROM slice
| ^
= note: fully expanded statement:
SELECT ts, dur, ts + dur AS ts_end FROM slice
^
--> trace processor internal:1:10
|
1 | ts, dur, ts + dur AS ts_end
| ^
)");
}
TEST(SqlSourceTest, NestedRewriter) {
SqlSource::Rewriter nested_rewrite(
SqlSource::FromTraceProcessorImplementation(
"id, common_cols!(), other_cols!(), name"));
nested_rewrite.Rewrite(
4, 18, SqlSource::FromTraceProcessorImplementation("ts, dur"));
nested_rewrite.Rewrite(20, 33,
SqlSource::FromTraceProcessorImplementation("depth"));
SqlSource::Rewriter rewriter(
SqlSource::FromExecuteQuery("SELECT cols!() FROM slice"));
rewriter.Rewrite(7, 14, std::move(nested_rewrite).Build());
SqlSource rewritten = std::move(rewriter).Build();
ASSERT_EQ(rewritten.sql(), "SELECT id, ts, dur, depth, name FROM slice");
// Offset points at the top level source.
ASSERT_EQ(rewritten.AsTraceback(0),
R"( --> query:1:1
|
1 | SELECT cols!() FROM slice
| ^
= note: fully expanded statement:
SELECT id, ts, dur, depth, name FROM slice
^
)");
ASSERT_EQ(rewritten.AsTraceback(37),
R"( --> query:1:21
|
1 | SELECT cols!() FROM slice
| ^
= note: fully expanded statement:
SELECT id, ts, dur, depth, name FROM slice
^
)");
// Offset points at the first nested source.
ASSERT_EQ(rewritten.AsTraceback(15),
R"( --> query:1:8
|
1 | SELECT cols!() FROM slice
| ^
= note: fully expanded statement:
SELECT id, ts, dur, depth, name FROM slice
^
--> trace processor internal:1:5
|
1 | id, common_cols!(), other_cols!(), name
| ^
--> trace processor internal:1:5
|
1 | ts, dur
| ^
)");
// Offset points at the second nested source.
ASSERT_EQ(rewritten.AsTraceback(20),
R"( --> query:1:8
|
1 | SELECT cols!() FROM slice
| ^
= note: fully expanded statement:
SELECT id, ts, dur, depth, name FROM slice
^
--> trace processor internal:1:21
|
1 | id, common_cols!(), other_cols!(), name
| ^
--> trace processor internal:1:1
|
1 | depth
| ^
)");
ASSERT_EQ(rewritten.AsTraceback(22),
R"( --> query:1:8
|
1 | SELECT cols!() FROM slice
| ^
= note: fully expanded statement:
SELECT id, ts, dur, depth, name FROM slice
^
--> trace processor internal:1:21
|
1 | id, common_cols!(), other_cols!(), name
| ^
--> trace processor internal:1:3
|
1 | depth
| ^
)");
}
TEST(SqlSourceTest, NestedRewriteSubstr) {
SqlSource::Rewriter nested_rewrite(
SqlSource::FromTraceProcessorImplementation(
"id, common_cols!(), other_cols!(), name"));
nested_rewrite.Rewrite(
4, 18, SqlSource::FromTraceProcessorImplementation("ts, dur"));
nested_rewrite.Rewrite(20, 33,
SqlSource::FromTraceProcessorImplementation("depth"));
SqlSource::Rewriter rewriter(
SqlSource::FromExecuteQuery("SELECT cols!() FROM slice"));
rewriter.Rewrite(7, 14, std::move(nested_rewrite).Build());
SqlSource rewritten = std::move(rewriter).Build();
ASSERT_EQ(rewritten.sql(), "SELECT id, ts, dur, depth, name FROM slice");
// Full macro cover.
SqlSource cols = rewritten.Substr(7, 24);
ASSERT_EQ(cols.sql(), "id, ts, dur, depth, name");
ASSERT_EQ(cols.AsTraceback(0),
R"( --> query:1:8
|
1 | cols!()
| ^
= note: fully expanded statement:
id, ts, dur, depth, name
^
--> trace processor internal:1:1
|
1 | id, common_cols!(), other_cols!(), name
| ^
)");
ASSERT_EQ(cols.AsTraceback(5),
R"( --> query:1:8
|
1 | cols!()
| ^
= note: fully expanded statement:
id, ts, dur, depth, name
^
--> trace processor internal:1:5
|
1 | id, common_cols!(), other_cols!(), name
| ^
--> trace processor internal:1:2
|
1 | ts, dur
| ^
)");
ASSERT_EQ(cols.AsTraceback(14),
R"( --> query:1:8
|
1 | cols!()
| ^
= note: fully expanded statement:
id, ts, dur, depth, name
^
--> trace processor internal:1:21
|
1 | id, common_cols!(), other_cols!(), name
| ^
--> trace processor internal:1:2
|
1 | depth
| ^
)");
// Intersect with nested.
SqlSource intersect = rewritten.Substr(8, 13);
ASSERT_EQ(intersect.sql(), "d, ts, dur, d");
ASSERT_EQ(intersect.AsTraceback(0),
R"( --> query:1:8
|
1 | cols!()
| ^
= note: fully expanded statement:
d, ts, dur, d
^
--> trace processor internal:1:2
|
1 | d, common_cols!(), other_cols!()
| ^
)");
ASSERT_EQ(intersect.AsTraceback(4),
R"( --> query:1:8
|
1 | cols!()
| ^
= note: fully expanded statement:
d, ts, dur, d
^
--> trace processor internal:1:5
|
1 | d, common_cols!(), other_cols!()
| ^
--> trace processor internal:1:2
|
1 | ts, dur
| ^
)");
ASSERT_EQ(intersect.AsTraceback(12),
R"( --> query:1:8
|
1 | cols!()
| ^
= note: fully expanded statement:
d, ts, dur, d
^
--> trace processor internal:1:21
|
1 | d, common_cols!(), other_cols!()
| ^
--> trace processor internal:1:1
|
1 | d
| ^
)");
}
TEST(SqlSourceTest, Rerewrites) {
SqlSource::Rewriter rewriter(
SqlSource::FromExecuteQuery("SELECT foo!(a) FROM bar!(slice) a"));
rewriter.Rewrite(7, 14,
SqlSource::FromTraceProcessorImplementation("a.x, a.y"));
rewriter.Rewrite(20, 31,
SqlSource::FromTraceProcessorImplementation(
"(SELECT slice.x, slice.y, slice.z FROM slice)"));
SqlSource rewritten = std::move(rewriter).Build();
ASSERT_EQ(
rewritten.sql(),
"SELECT a.x, a.y FROM (SELECT slice.x, slice.y, slice.z FROM slice) a");
SqlSource::Rewriter rerewriter(std::move(rewritten));
rerewriter.Rewrite(0, 7,
SqlSource::FromTraceProcessorImplementation("INSERT "));
rerewriter.Rewrite(7, 14,
SqlSource::FromTraceProcessorImplementation("a.z, "));
SqlSource rerewritten = std::move(rerewriter).Build();
ASSERT_EQ(
rerewritten.sql(),
"INSERT a.z, y FROM (SELECT slice.x, slice.y, slice.z FROM slice) a");
ASSERT_EQ(rerewritten.AsTraceback(0),
R"( --> query:1:1
|
1 | SELECT foo!(a) FROM bar!(slice) a
| ^
= note: fully expanded statement:
INSERT a.z, y FROM (SELECT slice.x, slice.y, slice.z FROM slice) a
^
--> trace processor internal:1:1
|
1 | INSERT
| ^
)");
ASSERT_EQ(rerewritten.AsTraceback(8),
R"( --> query:1:8
|
1 | SELECT foo!(a) FROM bar!(slice) a
| ^
= note: fully expanded statement:
INSERT a.z, y FROM (SELECT slice.x, slice.y, slice.z FROM slice) a
^
--> trace processor internal:1:1
|
1 | a.x, a.y
| ^
--> trace processor internal:1:2
|
1 | a.z,
| ^
)");
}
} // namespace
} // namespace trace_processor
} // namespace perfetto