• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2025 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 %name PerfettoSqlParse
18 %token_prefix TK_
19 %start_symbol input
20 
21 %include {
22 #include <stdio.h>
23 #include <stddef.h>
24 #include "src/trace_processor/perfetto_sql/grammar/perfettosql_grammar_interface.h"
25 
26 #define YYNOERRORRECOVERY 1
27 #define YYPARSEFREENEVERNULL 1
28 }
29 
30 %token CREATE REPLACE PERFETTO MACRO INCLUDE MODULE RETURNS FUNCTION.
31 
32 %left OR.
33 %left AND.
34 %right NOT.
35 %left IS MATCH LIKE_KW BETWEEN IN ISNULL NOTNULL NE EQ.
36 %left GT LE LT GE.
37 %right ESCAPE.
38 %left BITAND BITOR LSHIFT RSHIFT.
39 %left PLUS MINUS.
40 %left STAR SLASH REM.
41 %left CONCAT PTR.
42 %left COLLATE.
43 %right BITNOT.
44 %nonassoc ON.
45 
46 %fallback
47 // Taken from SQLite
48   ID
49   ABORT ACTION AFTER ANALYZE ASC ATTACH BEFORE BEGIN BY CASCADE CAST COLUMNKW
50   CONFLICT DATABASE DEFERRED DESC DETACH DO
51   EACH END EXCLUSIVE EXPLAIN FAIL FOR
52   IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN
53   QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS
54   ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT
55   NULLS FIRST LAST
56   CURRENT FOLLOWING PARTITION PRECEDING RANGE UNBOUNDED
57   EXCLUDE GROUPS OTHERS TIES
58   GENERATED ALWAYS
59   MATERIALIZED
60   REINDEX RENAME CTIME_KW IF
61 // Our additions.
62   FUNCTION MODULE PERFETTO
63   .
64 %wildcard ANY.
65 
66 %token_type {struct PerfettoSqlToken}
67 
68 %extra_context {struct PerfettoSqlParserState* state}
69 %syntax_error {
70   OnPerfettoSqlSyntaxError(state, &yyminor);
71 }
72 
73 // Helper function like scantok but usable by us.
74 pscantok(A) ::= . {
75   assert( yyLookahead!=YYNOCODE );
76   A = yyLookaheadToken;
77 }
78 
79 // Shared rules
80 %type sql_argument_list { struct PerfettoSqlArgumentList* }
81 %destructor sql_argument_list { OnPerfettoSqlFreeArgumentList(state, $$); }
82 sql_argument_list(A) ::=. { A = 0; }
83 sql_argument_list(A) ::= sql_argument_list_nonempty(X). { A = X; }
84 
85 sql_argument_type(A) ::= ID(B). { A = B; }
86 sql_argument_type(A) ::= ID(B) LP ID DOT ID RP. { A = B; }
87 
88 %type sql_argument_list_nonempty { struct PerfettoSqlArgumentList* }
89 %destructor sql_argument_list_nonempty { OnPerfettoSqlFreeArgumentList(state, $$); }
90 sql_argument_list_nonempty(A) ::= sql_argument_list_nonempty(B) COMMA ID(C) sql_argument_type(D). {
91   A = OnPerfettoSqlCreateOrAppendArgument(state, B, &C, &D);
92 }
93 sql_argument_list_nonempty(A) ::= ID(B) sql_argument_type(C). {
94   A = OnPerfettoSqlCreateOrAppendArgument(state, 0, &B, &C);
95 }
96 
97 %type table_schema { struct PerfettoSqlArgumentList* }
98 %destructor table_schema { OnPerfettoSqlFreeArgumentList(state, $$); }
99 table_schema(A) ::=. { A = 0; }
100 table_schema(A) ::= LP sql_argument_list_nonempty(B) RP. { A = B; }
101 
102 // CREATE statements
103 %type or_replace {int}
104 or_replace(A) ::=.                    { A = 0; }
105 or_replace(A) ::= OR REPLACE.         { A = 1; }
106 
107 // CREATE PERFETTO FUNCTION
108 cmd ::= CREATE or_replace(R) PERFETTO FUNCTION ID(N) LP sql_argument_list(A) RP RETURNS return_type(T) AS select(E) pscantok(S). {
109   OnPerfettoSqlCreateFunction(state, R, &N, A, T, &E, &S);
110 }
111 
112 %type return_type { struct PerfettoSqlFnReturnType* }
113 %destructor return_type { OnPerfettoSqlFnFreeReturnType(state, $$); }
114 return_type(Y) ::= ID(X). {
115   Y = OnPerfettoSqlCreateScalarReturnType(&X);
116 }
117 return_type(Y) ::= TABLE LP sql_argument_list_nonempty(A) RP. {
118   Y = OnPerfettoSqlCreateTableReturnType(A);
119 }
120 
121 // CREATE PERFETTO TABLE
122 cmd ::= CREATE or_replace(R) PERFETTO TABLE ID(N) table_schema(S) AS select(A) pscantok(Q). {
123   OnPerfettoSqlCreateTable(state, R, &N, S, &A, &Q);
124 }
125 
126 // CREATE PERFETTO VIEW
127 cmd ::= CREATE(C) or_replace(R) PERFETTO VIEW ID(N) table_schema(S) AS select(A) pscantok(Q). {
128   OnPerfettoSqlCreateView(state, R, &C, &N, S, &A, &Q);
129 }
130 
131 // CREATE PERFETTO INDEX
132 cmd ::= CREATE(C) or_replace(R) PERFETTO INDEX ID(N) ON ID(T) LP indexed_column_list(L) RP. {
133   OnPerfettoSqlCreateIndex(state, R, &C, &N, &T, L);
134 }
135 
136 %type indexed_column_list { struct PerfettoSqlIndexedColumnList* }
137 %destructor indexed_column_list { OnPerfettoSqlFreeIndexedColumnList(state, $$); }
138 indexed_column_list(A) ::= indexed_column_list(B) COMMA ID(C). {
139   A = OnPerfettoSqlCreateOrAppendIndexedColumn(B, &C);
140 }
141 indexed_column_list(A) ::= ID(B). {
142   A = OnPerfettoSqlCreateOrAppendIndexedColumn(0, &B);
143 }
144 
145 // CREATE PERFETTO MACRO
146 cmd ::= CREATE or_replace(R) PERFETTO MACRO ID(N) LP macro_argument_list(A) RP RETURNS ID(T) AS macro_body(S) pscantok(B). {
147   OnPerfettoSqlCreateMacro(state, R, &N, A, &T, &S, &B);
148 }
149 macro_body ::= ANY.
150 macro_body ::= macro_body ANY.
151 
152 %type macro_argument_list_nonempty { struct PerfettoSqlMacroArgumentList* }
153 %destructor macro_argument_list_nonempty { OnPerfettoSqlFreeMacroArgumentList(state, $$); }
154 macro_argument_list_nonempty(A) ::= macro_argument_list_nonempty(D) COMMA ID(B) ID(C). {
155   A = OnPerfettoSqlCreateOrAppendMacroArgument(state, D, &B, &C);
156 }
157 macro_argument_list_nonempty(A) ::= ID(B) ID(C). {
158   A = OnPerfettoSqlCreateOrAppendMacroArgument(state, 0, &B, &C);
159 }
160 
161 %type macro_argument_list { struct PerfettoSqlMacroArgumentList* }
162 %destructor macro_argument_list { OnPerfettoSqlFreeMacroArgumentList(state, $$); }
163 macro_argument_list(A) ::=. { A = 0; }
164 macro_argument_list(A) ::= macro_argument_list_nonempty(B). { A = B; }
165 
166 // INCLUDE statement
167 cmd ::= INCLUDE PERFETTO MODULE module_name(M). {
168   OnPerfettoSqlInclude(state, &M);
169 }
170 module_name(A) ::= ID|STAR|INTERSECT(B). {
171   A = B;
172 }
173 module_name(A) ::= module_name(B) DOT ID|STAR|INTERSECT(C). {
174   A = (struct PerfettoSqlToken) {B.ptr, C.ptr + C.n - B.ptr};
175 }
176 
177 // DROP statement
178 cmd ::= DROP PERFETTO INDEX ID(N) ON ID(T). {
179   OnPerfettoSqlDropIndex(state, &N, &T);
180 }
181