blob: adca9dbe00a0a6c404408acddea5ed818d368d08 [file] [log] [blame]
/*
* 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),
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 1\n"
" SELECT * FROM slice\n"
" ^\n");
ASSERT_EQ(source.AsTraceback(7),
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 8\n"
" SELECT * FROM slice\n"
" ^\n");
}
TEST(SqlSourceTest, Substr) {
SqlSource source =
SqlSource::FromExecuteQuery("SELECT * FROM slice").Substr(9, 10);
ASSERT_EQ(source.sql(), "FROM slice");
ASSERT_EQ(source.AsTraceback(0),
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 10\n"
" FROM slice\n"
" ^\n");
ASSERT_EQ(source.AsTraceback(6),
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 16\n"
" FROM slice\n"
" ^\n");
}
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),
"Fully expanded statement\n"
" SELECT * FROM slice\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 1\n"
" macro!()\n"
" ^\n"
" Trace Processor Internal line 1 col 1\n"
" SELECT * FROM slice\n"
" ^\n");
ASSERT_EQ(source.AsTraceback(7),
"Fully expanded statement\n"
" SELECT * FROM slice\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 1\n"
" macro!()\n"
" ^\n"
" Trace Processor Internal line 1 col 8\n"
" SELECT * FROM slice\n"
" ^\n");
}
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),
"Fully expanded statement\n"
" SELECT * FROM slice\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 1\n"
" macro!()\n"
" ^\n"
" Trace Processor Internal line 1 col 1\n"
" nested!()\n"
" ^\n"
" Trace Processor Internal line 1 col 1\n"
" SELECT * FROM slice\n"
" ^\n");
ASSERT_EQ(source.AsTraceback(7),
"Fully expanded statement\n"
" SELECT * FROM slice\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 1\n"
" macro!()\n"
" ^\n"
" Trace Processor Internal line 1 col 1\n"
" nested!()\n"
" ^\n"
" Trace Processor Internal line 1 col 8\n"
" SELECT * FROM slice\n"
" ^\n");
}
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),
"Fully expanded statement\n"
" SELECT 0 WHERE 0\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 1\n"
" foo!()\n"
" ^\n"
" Trace Processor Internal line 1 col 1\n"
" SELECT 0 WHERE 0\n"
" ^\n");
ASSERT_EQ(source.AsTraceback(4),
"Fully expanded statement\n"
" SELECT 0 WHERE 0\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 1\n"
" foo!()\n"
" ^\n"
" Trace Processor Internal line 1 col 5\n"
" SELECT 0 WHERE 0\n"
" ^\n");
}
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),
"Fully expanded statement\n"
" SELECT ts, dur, ts + dur AS ts_end FROM slice\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 1\n"
" SELECT cols!() FROM slice\n"
" ^\n");
ASSERT_EQ(rewritten.AsTraceback(40),
"Fully expanded statement\n"
" SELECT ts, dur, ts + dur AS ts_end FROM slice\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 21\n"
" SELECT cols!() FROM slice\n"
" ^\n");
// Offset points at the nested source.
ASSERT_EQ(rewritten.AsTraceback(16),
"Fully expanded statement\n"
" SELECT ts, dur, ts + dur AS ts_end FROM slice\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 8\n"
" SELECT cols!() FROM slice\n"
" ^\n"
" Trace Processor Internal line 1 col 10\n"
" ts, dur, ts + dur AS ts_end\n"
" ^\n");
}
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),
"Fully expanded statement\n"
" SELECT id, ts, dur, depth, name FROM slice\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 1\n"
" SELECT cols!() FROM slice\n"
" ^\n");
ASSERT_EQ(rewritten.AsTraceback(37),
"Fully expanded statement\n"
" SELECT id, ts, dur, depth, name FROM slice\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 21\n"
" SELECT cols!() FROM slice\n"
" ^\n");
// Offset points at the first nested source.
ASSERT_EQ(rewritten.AsTraceback(15),
"Fully expanded statement\n"
" SELECT id, ts, dur, depth, name FROM slice\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 8\n"
" SELECT cols!() FROM slice\n"
" ^\n"
" Trace Processor Internal line 1 col 5\n"
" id, common_cols!(), other_cols!(), name\n"
" ^\n"
" Trace Processor Internal line 1 col 5\n"
" ts, dur\n"
" ^\n");
// Offset points at the second nested source.
ASSERT_EQ(rewritten.AsTraceback(20),
"Fully expanded statement\n"
" SELECT id, ts, dur, depth, name FROM slice\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 8\n"
" SELECT cols!() FROM slice\n"
" ^\n"
" Trace Processor Internal line 1 col 21\n"
" id, common_cols!(), other_cols!(), name\n"
" ^\n"
" Trace Processor Internal line 1 col 1\n"
" depth\n"
" ^\n");
ASSERT_EQ(rewritten.AsTraceback(22),
"Fully expanded statement\n"
" SELECT id, ts, dur, depth, name FROM slice\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 8\n"
" SELECT cols!() FROM slice\n"
" ^\n"
" Trace Processor Internal line 1 col 21\n"
" id, common_cols!(), other_cols!(), name\n"
" ^\n"
" Trace Processor Internal line 1 col 3\n"
" depth\n"
" ^\n");
}
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),
"Fully expanded statement\n"
" id, ts, dur, depth, name\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 8\n"
" cols!()\n"
" ^\n"
" Trace Processor Internal line 1 col 1\n"
" id, common_cols!(), other_cols!(), name\n"
" ^\n");
ASSERT_EQ(cols.AsTraceback(5),
"Fully expanded statement\n"
" id, ts, dur, depth, name\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 8\n"
" cols!()\n"
" ^\n"
" Trace Processor Internal line 1 col 5\n"
" id, common_cols!(), other_cols!(), name\n"
" ^\n"
" Trace Processor Internal line 1 col 2\n"
" ts, dur\n"
" ^\n");
ASSERT_EQ(cols.AsTraceback(14),
"Fully expanded statement\n"
" id, ts, dur, depth, name\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 8\n"
" cols!()\n"
" ^\n"
" Trace Processor Internal line 1 col 21\n"
" id, common_cols!(), other_cols!(), name\n"
" ^\n"
" Trace Processor Internal line 1 col 2\n"
" depth\n"
" ^\n");
// Intersect with nested.
SqlSource intersect = rewritten.Substr(8, 13);
ASSERT_EQ(intersect.sql(), "d, ts, dur, d");
ASSERT_EQ(intersect.AsTraceback(0),
"Fully expanded statement\n"
" d, ts, dur, d\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 8\n"
" cols!()\n"
" ^\n"
" Trace Processor Internal line 1 col 2\n"
" d, common_cols!(), other_cols!()\n"
" ^\n");
ASSERT_EQ(intersect.AsTraceback(4),
"Fully expanded statement\n"
" d, ts, dur, d\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 8\n"
" cols!()\n"
" ^\n"
" Trace Processor Internal line 1 col 5\n"
" d, common_cols!(), other_cols!()\n"
" ^\n"
" Trace Processor Internal line 1 col 2\n"
" ts, dur\n"
" ^\n");
ASSERT_EQ(intersect.AsTraceback(12),
"Fully expanded statement\n"
" d, ts, dur, d\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 8\n"
" cols!()\n"
" ^\n"
" Trace Processor Internal line 1 col 21\n"
" d, common_cols!(), other_cols!()\n"
" ^\n"
" Trace Processor Internal line 1 col 1\n"
" d\n"
" ^\n");
}
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),
"Fully expanded statement\n"
" INSERT a.z, y FROM (SELECT slice.x, slice.y, slice.z FROM slice) a\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 1\n"
" SELECT foo!(a) FROM bar!(slice) a\n"
" ^\n"
" Trace Processor Internal line 1 col 1\n"
" INSERT \n"
" ^\n");
ASSERT_EQ(
rerewritten.AsTraceback(8),
"Fully expanded statement\n"
" INSERT a.z, y FROM (SELECT slice.x, slice.y, slice.z FROM slice) a\n"
" ^\n"
"Traceback (most recent call last):\n"
" File \"stdin\" line 1 col 8\n"
" SELECT foo!(a) FROM bar!(slice) a\n"
" ^\n"
" Trace Processor Internal line 1 col 1\n"
" a.x, a.y\n"
" ^\n"
" Trace Processor Internal line 1 col 2\n"
" a.z, \n"
" ^\n");
}
} // namespace
} // namespace trace_processor
} // namespace perfetto