--- /dev/null
+# This Source Code Form is subject to the terms of the Mozilla Public\r
+# License, v. 2.0. If a copy of the MPL was not distributed with this\r
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.\r
+#\r
+# This Source Code Form is "Incompatible With Secondary Licenses", as\r
+# defined by the Mozilla Public License, v. 2.0.\r
+\r
+##################\r
+#Bugzilla Test 13#\r
+#####schema#######\r
+\r
+# Check the Bugzilla database schema to ensure no field names conflict\r
+# with SQL reserved words.\r
+\r
+use strict;\r
+use lib qw(. t lib);\r
+use Bugzilla;\r
+use Bugzilla::DB::Schema;\r
+\r
+\r
+# SQL reserved words\r
+use constant RESERVED_WORDS => qw(\r
+ ABSOLUTE ACTION ACTOR ADD AFTER ALL ALLOCATE ALTER ANY AND ARE ASC ASSERTION ASYNC AT\r
+ ATTRIBUTES BEFORE BEGIN BETWEEN BIT BIT_LENGTH BOOLEAN BOTH BREADTH CALL CASCADE\r
+ CASCADED CASE CAST CATALOG CHARACTER_LENGTH CHAR_LENGTH COLLATE\r
+ COLLATION COLUMN COMPLETION CONNECT CONNECTION CONSTRAINT CONSTRAINTS\r
+ CONVERT CORRESPONDING CREATE CROSS CURRENT_DATE CURRENT_PATH CURRENT_TIME\r
+ CURRENT_TIMESTAMP CURRENT_USER CYCLE DATA DATE DAY DEALLOCATE DECLARE DEFAULT DEFERRABLE\r
+ DEFERRED DELETE DEPTH DESC DESCRIBE DESCRIPTOR DESTROY DIAGNOSTICS DICTIONARY\r
+ DISCONNECT DISTINCT DO DOMAIN DROP EACH ELEMENT ELSE ELSEIF END END-EXEC EQUALS EXCEPT\r
+ EXCEPTION EXECUTE EXTERNAL EXTRACT FACTOR FALSE FIRST FOR FROM FULL GENERAL GET\r
+ GLOBAL GRANT GROUP HAVING HOLD HOUR IDENTITY IF IGNORE IMMEDIATE IN INITIALLY INNER INPUT\r
+ INSENSITIVE INSERT INSTEAD INTERSECT INTERVAL IS ISOLATION JOIN LAST LEADING LEAVE\r
+ LEFT LESS LEVEL LIMIT LIST LOCAL LOOP LOWER MATCH MINUTE MODIFY MONTH NAMES\r
+ NATIONAL NATURAL NCHAR NEW NEW_TABLE NEXT NO NONE NOT NULL NULLIF OBJECT\r
+ OCTET_LENGTH OFF OID OLD OLD_TABLE ONLY OPERATION OPERATOR OPERATORS OR ORDER OTHERS\r
+ OUTER OUTPUT OVERLAPS PAD PARAMETERS PARTIAL PATH PENDANT POSITION POSTFIX\r
+ PREFIX PREORDER PREPARE PRESERVE PRIOR PRIVATE PROTECTED READ RECURSIVE REF\r
+ REFERENCING RELATIVE REPLACE RESIGNAL RESTRICT RETURN RETURNS REVOKE RIGHT\r
+ ROLE ROUTINE ROW ROWS SAVEPOINT SCROLL SEARCH SECOND SELECT SENSITIVE SEQUENCE\r
+ SESSION SESSION_USER SIGNAL SIMILAR SIZE SPACE SQLEXCEPTION SQLSTATE\r
+ SQLWARNING START STATE STRUCTURE SUBSTRING SYMBOL SYSTEM_USER TABLE TEMPORARY\r
+ TERM TEST THEN THERE TIME TIMESTAMP TIMEZONE_HOUR TIMEZONE_MINUTE TRAILING\r
+ TRANSACTION TRANSLATE TRANSLATION TRIGGER TRIM TRUE TUPLE UNDER\r
+ UNKNOWN UNION UNIQUE UPDATE UPPER USAGE USING VARCHAR VARIABLE VARYING VIRTUAL VISIBLE\r
+ WAIT WHEN WHERE WHILE WITH WITHOUT WRITE YEAR ZONE\r
+);\r
+\r
+# Few Exceptions are removed from the above list\r
+# i.e. VALUE, TYPE, ALIAS, COALESCE\r
+\r
+our $dbh;\r
+our $schema;\r
+our @tables;\r
+\r
+BEGIN {\r
+ $schema = Bugzilla::DB::Schema->new("Mysql");\r
+ @tables = $schema->get_table_list();\r
+}\r
+\r
+use Test::More tests => scalar(@tables);\r
+\r
+foreach my $table (@tables) {\r
+ my @reserved;\r
+\r
+ if (grep { uc($table) eq $_ } RESERVED_WORDS) {\r
+ push(@reserved, $table);\r
+ }\r
+\r
+ foreach my $column ($schema->get_table_columns($table)) {\r
+ if (grep { uc($column) eq $_ } RESERVED_WORDS) {\r
+ push(@reserved, $column);\r
+ }\r
+ }\r
+\r
+ if (scalar @reserved) {\r
+ ok(0, "Table $table use reserved words: " . join(", ", @reserved));\r
+ }\r
+ else {\r
+ ok(1, "Table $table does not use reserved words");\r
+ }\r
+}\r
+\r
+exit 0;\r