1#!/usr/bin/env python3 2# Copyright (C) 2021 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# This tool checks that every create (table|view) is prefixed by 17# drop (table|view). 18 19from __future__ import absolute_import 20from __future__ import division 21from __future__ import print_function 22 23import os 24import re 25import sys 26 27ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 28 29 30def check(path): 31 with open(path) as f: 32 lines = [l.strip() for l in f.readlines()] 33 34 # Check that CREATE VIEW/TABLE has a matching DROP VIEW/TABLE before it. 35 errors = 0 36 d_type, d_name = None, None 37 for line in lines: 38 m = re.match(r'^DROP (TABLE|VIEW) IF EXISTS (.*);$', line) 39 if m is not None: 40 d_type, d_name = m.group(1), m.group(2) 41 continue 42 m = re.match(r'^CREATE (?:VIRTUAL )?(TABLE|VIEW) (.*) (?:AS|USING).*', line) 43 if m is None: 44 continue 45 type, name = m.group(1), m.group(2) 46 if type != d_type or name != d_name: 47 sys.stderr.write( 48 ('Missing DROP %s before CREATE %s\n') % (d_type, d_type)) 49 sys.stderr.write(('%s:\n"%s" vs %s %s\n') % (path, line, d_type, d_name)) 50 errors += 1 51 d_type, d_name = None, None 52 53 # Ban the use of LIKE in non-comment lines. 54 for line in lines: 55 if line.startswith('--'): 56 continue 57 58 if 'like' in line.casefold(): 59 sys.stderr.write( 60 'LIKE is banned in trace processor metrics. Prefer GLOB instead.\n') 61 sys.stderr.write('Offending file: %s\n' % path) 62 errors += 1 63 64 return errors 65 66 67def main(): 68 errors = 0 69 metrics_sources = os.path.join(ROOT_DIR, 'src', 'trace_processor', 'metrics', 70 'sql') 71 for root, _, files in os.walk(metrics_sources, topdown=True): 72 for f in files: 73 path = os.path.join(root, f) 74 if path.endswith('.sql'): 75 errors += check(path) 76 return 0 if errors == 0 else 1 77 78 79if __name__ == '__main__': 80 sys.exit(main()) 81