///////////////////////////////////////////////////////////////////////////// // // WQL Version 1.1 for WBEM M6 / SMS Opal. // // This file describes a validated LL(1) grammar for top-down // or recursive descent parsing of WQL. // // raymcc 11-Sep-97 Created // ///////////////////////////////////////////////////////////////////////////// ::= WQL_TOK_SELECT ; ///////////////////////////////////////////////////////////////////////////// // // SELECT statement // ///////////////////////////////////////////////////////////////////////////// ::= ; ::= WQL_TOK_ALL; ::= WQL_TOK_DISTINCT; ::= <>; ::= WQL_TOK_SELECT // Additionally, must be a single col & not an asterisk ; ///////////////////////////////////////////////////////////////////////////// // // Column reference list // // Supports either simple names, *, or qualified names of the form // "table.col" where table could be a literal table name or an aliased // table name. At this point in the parsing, we can't really tell // which one is being used. // // Either * is required, or at least one column reference. // ///////////////////////////////////////////////////////////////////////////// ::= ; ::= WQL_TOK_ASTERISK; ::= WQL_TOK_COUNT ; ::= WQL_TOK_COMMA ; ::= <>; ::= WQL_TOK_OPEN_PAREN WQL_TOK_CLOSE_PAREN; ::= WQL_TOK_ASTERISK; ::= ; ///////////////////////////////////////////////////////////////////////////// // // Column reference // // Used both in the WHERE clause and the COUNT clause // ///////////////////////////////////////////////////////////////////////////// ::= ; ///////////////////////////////////////////////////////////////////////////// // // qualified names // // (dot-separated names with optional array references. // ///////////////////////////////////////////////////////////////////////////// ::= WQL_TOK_IDENT ; ::= WQL_TOK_DOT WQL_TOK_IDENT ; ::= WQL_TOK_OPEN_BRACKET WQL_TOK_INT WQL_TOK_CLOSEBRACKET ; ::= <>; // Dummy to enforce array semantics ::= <>; ///////////////////////////////////////////////////////////////////////////// // // "FROM" clause // // Both SQL-89 and SQL-92 join syntax supported. // ///////////////////////////////////////////////////////////////////////////// ::= WQL_TOK_FROM ; ::= ; ::= ; ::= ; ::= <>; // Unary query ///////////////////////////////////////////////////////////////////////////// // // Table reference // // This supports a single table reference in a FROM clause, whether // an isolated name, or alias (with or without AS). // ///////////////////////////////////////////////////////////////////////////// ::= ; ::= WQL_TOK_IDENT; ::= ; ::= <>; ::= WQL_TOK_IDENT; ::= WQL_TOK_AS; ::= <>; ///////////////////////////////////////////////////////////////////////////// // // SQL-89 Joins // ///////////////////////////////////////////////////////////////////////////// ::= WQL_TOK_COMMA ; ::= ; ::= WQL_TOK_COMMA ; ::= <>; ///////////////////////////////////////////////////////////////////////////// // // SQL-92 Joins. // // We support: // 1. [INNER] JOIN // 2. LEFT [OUTER] JOIN // 3. RIGHT [OUTER] JOIN // 4. FULL [OUTER] JOIN // ///////////////////////////////////////////////////////////////////////////// ::= ; ::= WQL_TOK_INNER ; ::= WQL_TOK_FULL ; ::= WQL_TOK_LEFT ; ::= WQL_TOK_RIGHT ; ::= WQL_TOK_OUTER; ::= <>; ::= WQL_TOK_JOIN ; ::= WQL_TOK_ON ; ::= ; ::= <>; ///////////////////////////////////////////////////////////////////////////// // // "WHERE" clause // ///////////////////////////////////////////////////////////////////////////// ::= WQL_TOK_WHERE ; ::= <>; // 'where' is not required ///////////////////////////////////////////////////////////////////////////// // // WHERE OPTIONS // // We currently force the GROUP BY to precede ORDER BY if they are both // present. If this causes a problem, we can fix it by using an // iterative construct below and doing the checking in the parser itself // as a semantic operation. // ///////////////////////////////////////////////////////////////////////////// ::= ; ::= WQL_TOK_GROUP WQL_TOK_BY ; ::= <>; ::= WQL_TOK_HAVING ; ::= <>; ::= WQL_TOK_ORDER WQL_TOK_BY ; ::= <>; ///////////////////////////////////////////////////////////////////////////// // // Simple column list with no asterisk // ///////////////////////////////////////////////////////////////////////////// ::= ; ::= WQL_TOK_COMMA ; ::= <>; ///////////////////////////////////////////////////////////////////////////// // // Relational expressions // // These set out the precedence of typed expressions relative to the // NOT, AND, OR and parentheses operators. // ///////////////////////////////////////////////////////////////////////////// ::= ; ::= WQL_TOK_OR ; ::= <>; ::= ; ::= WQL_TOK_AND ; ::= <>; ::= WQL_TOK_NOT ; ::= WQL_TOK_OPEN_PAREN WQL_TOK_CLOSE_PAREN; ::= ; ///////////////////////////////////////////////////////////////////////////// // // Typed expression // // This is the lower level expression which requires a relational // operator. Many of these combined constitute a relational expression. // ///////////////////////////////////////////////////////////////////////////// ::= ; ::= ; ::= ; ::= ; ::= ; ::= ; ::= ; ::= ; // Operator must be _IN or _NOT_IN ///////////////////////////////////////////////////////////////////////////// // // Function calls // // Each of the recognized functions is part of the grammar. // ///////////////////////////////////////////////////////////////////////////// ::= WQL_TOK_UPPER ; ::= WQL_TOK_LOWER ; ::= WQL_TOK_DATEPART ; ::= WQL_TOK_QUALIFIER ; ::= WQL_TOK_ISNULL ; ::= WQL_TOK_OPEN_PAREN WQL_TOK_CLOSE_PAREN ; ::= ; ::= WQL_TOK_COMMA ; ::= <>; ::= ; ::= ; ///////////////////////////////////////////////////////////////////////////// // // IN clause // // We support three syntax branches: // (a) IN with subselect // (b) IN with const-list // (c) IN with qualified name which is an array reference // ///////////////////////////////////////////////////////////////////////////// ::= WQL_TOK_OPEN_PAREN WQL_TOK_CLOSE_PAREN; ::= ; ::= ; ::= ; ///////////////////////////////////////////////////////////////////////////// // // Comma-separated list of constants // ///////////////////////////////////////////////////////////////////////////// ::= ; ::= WQL_TOK_COMMA ; ::= <>; ///////////////////////////////////////////////////////////////////////////// // // Primary relational operator terminals // Some branching with continuators occurs for IS, IN, and NOT. // ///////////////////////////////////////////////////////////////////////////// ::= WQL_TOK_LE; ::= WQL_TOK_LT; ::= WQL_TOK_GE; ::= WQL_TOK_GT; ::= WQL_TOK_EQ; ::= WQL_TOK_NE; ::= WQL_TOK_LIKE; ::= WQL_TOK_BETWEEN; ::= WQL_TOK_IS ; ::= WQL_TOK_ISA; ::= WQL_TOK_IN; ::= WQL_TOK_NOT ; ///////////////////////////////////////////////////////////////////////////// // // Tokens which can follow IS // ///////////////////////////////////////////////////////////////////////////// ::= WQL_TOK_LIKE; ::= WQL_TOK_BEFORE; ::= WQL_TOK_AFTER; ::= WQL_TOK_BETWEEN; ::= WQL_TOK_NULL; ::= WQL_TOK_NOT ; ::= WQL_TOK_IN; ::= WQL_TOK_A; ///////////////////////////////////////////////////////////////////////////// // // Tokens which can follow NOT // ///////////////////////////////////////////////////////////////////////////// ::= WQL_TOK_LIKE; ::= WQL_TOK_BEFORE; ::= WQL_TOK_AFTER; ::= WQL_TOK_BETWEEN; ::= WQL_TOK_NULL; ::= WQL_TOK_IN; ::= WQL_TOK_A; ///////////////////////////////////////////////////////////////////////////// // // Typed constants (literals) // ///////////////////////////////////////////////////////////////////////////// ::= WQL_TOK_QSTRING; ::= WQL_TOK_INT; ::= WQL_TOK_REAL; ::= WQL_TOK_NULL; ///////////////////////////////////////////////////////////////////////////// // // Transact-SQL plagiarism: Datepart // // datepart(ident, col) // ///////////////////////////////////////////////////////////////////////////// ::= WQL_TOK_OPEN_PAREN WQL_TOK_IDENT // yy, mm,dd, hh, mm, ss, year, month, etc. WQL_TOK_COMMA WQL_TOK_CLOSE_PAREN ; // RAIX xxxx: Ensure that lexer returns single quoted strings as valid, and recognizes escapes // RAID 3716: Syntax to reference a qualifier; promised to do this // qualifier(prop, "MyQual") = 'xxx' qualifier("MyQual") = 'const' // RAID xxxx : Hex constants // // Intrinsic function applied to columns in "select a, func(b), c from d where..." // Use of qualified asterisks "select t1.*, t2.*, t3.x from ..." // // BETWEEN needs to be supported *correctly* // Unexpected Features: (1) subselects in IN, (2) DatePart (required new approach to functions // because of the keyword problem, (3) functionized col-refs, (4) COUNT(col-name) as opposed // to COUNT(*), (5)