1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "src/trace_processor/perfetto_sql/intrinsics/functions/create_function.h"
18
19 #include <queue>
20 #include <stack>
21
22 #include "perfetto/base/status.h"
23 #include "perfetto/trace_processor/basic_types.h"
24 #include "src/trace_processor/perfetto_sql/engine/perfetto_sql_engine.h"
25 #include "src/trace_processor/perfetto_sql/parser/function_util.h"
26 #include "src/trace_processor/sqlite/scoped_db.h"
27 #include "src/trace_processor/sqlite/sql_source.h"
28 #include "src/trace_processor/sqlite/sqlite_engine.h"
29 #include "src/trace_processor/sqlite/sqlite_utils.h"
30 #include "src/trace_processor/tp_metatrace.h"
31 #include "src/trace_processor/util/status_macros.h"
32
33 namespace perfetto {
34 namespace trace_processor {
35
Run(PerfettoSqlEngine * engine,size_t argc,sqlite3_value ** argv,SqlValue &,Destructors &)36 base::Status CreateFunction::Run(PerfettoSqlEngine* engine,
37 size_t argc,
38 sqlite3_value** argv,
39 SqlValue&,
40 Destructors&) {
41 RETURN_IF_ERROR(sqlite::utils::CheckArgCount("CREATE_FUNCTION", argc, 3u));
42
43 sqlite3_value* prototype_value = argv[0];
44 sqlite3_value* return_type_value = argv[1];
45 sqlite3_value* sql_defn_value = argv[2];
46
47 // Type check all the arguments.
48 {
49 auto type_check = [prototype_value](sqlite3_value* value,
50 SqlValue::Type type, const char* desc) {
51 base::Status status = sqlite::utils::TypeCheckSqliteValue(value, type);
52 if (!status.ok()) {
53 return base::ErrStatus("CREATE_FUNCTION[prototype=%s]: %s %s",
54 sqlite3_value_text(prototype_value), desc,
55 status.c_message());
56 }
57 return base::OkStatus();
58 };
59
60 RETURN_IF_ERROR(type_check(prototype_value, SqlValue::Type::kString,
61 "function prototype (first argument)"));
62 RETURN_IF_ERROR(type_check(return_type_value, SqlValue::Type::kString,
63 "return type (second argument)"));
64 RETURN_IF_ERROR(type_check(sql_defn_value, SqlValue::Type::kString,
65 "SQL definition (third argument)"));
66 }
67
68 // Extract the arguments from the value wrappers.
69 auto extract_string = [](sqlite3_value* value) -> base::StringView {
70 return reinterpret_cast<const char*>(sqlite3_value_text(value));
71 };
72 std::string prototype_str = extract_string(prototype_value).ToStdString();
73 std::string return_type_str = extract_string(return_type_value).ToStdString();
74 std::string sql_defn_str = extract_string(sql_defn_value).ToStdString();
75
76 FunctionPrototype prototype;
77 RETURN_IF_ERROR(ParsePrototype(base::StringView(prototype_str), prototype));
78 return engine->RegisterRuntimeFunction(
79 true /* replace */, prototype, return_type_str,
80 SqlSource::FromTraceProcessorImplementation(std::move(sql_defn_str)));
81 }
82
Run(PerfettoSqlEngine * engine,size_t argc,sqlite3_value ** argv,SqlValue &,Destructors &)83 base::Status ExperimentalMemoize::Run(PerfettoSqlEngine* engine,
84 size_t argc,
85 sqlite3_value** argv,
86 SqlValue&,
87 Destructors&) {
88 RETURN_IF_ERROR(
89 sqlite::utils::CheckArgCount("EXPERIMENTAL_MEMOIZE", argc, 1));
90 base::StatusOr<std::string> function_name =
91 sqlite::utils::ExtractStringArg("MEMOIZE", "function_name", argv[0]);
92 RETURN_IF_ERROR(function_name.status());
93 return engine->EnableSqlFunctionMemoization(*function_name);
94 }
95
96 } // namespace trace_processor
97 } // namespace perfetto
98