/* // $Id: //guest/paul_dymecki/mondrian/src/main/mondrian/olap/Parser.cup#1 $ // This software is subject to the terms of the Common Public License // Agreement, available at the following URL: // http://www.opensource.org/licenses/cpl.html. // (C) Copyright 1999-2002 Kana Software, Inc. and others. // All Rights Reserved. // You must accept the terms of that agreement to use this software. // // jhyde, 20 January, 1999 // // Grammar condensed from OLE DB reference // (http://www.microsoft.com/data/reference/oledb2.htm) by jhyde on 990120. */ import java_cup.runtime.*; // Preliminaries to set up and use the scanner. // action code {: ... :}; parser code {: // Generated from $Id: //guest/paul_dymecki/mondrian/src/main/mondrian/olap/Parser.cup#1 $ private Scanner scanner; private String sQuery; private Connection mdxConnection; /** Called only by {@link ConnectionBase#parseQuery} and * {@link ConnectionBase#parseExpression}. **/ Query parseInternal( Connection mdxConnection, String sQuery, boolean debug) { Symbol parse_tree = null; this.scanner = new StringScanner(sQuery, debug); this.mdxConnection = mdxConnection; this.sQuery = sQuery; try { if (debug) { parse_tree = debug_parse(); } else { parse_tree = parse(); } return (Query) parse_tree.value; } catch (Exception e) { // "Error while parsing MDX statement '%1'" throw Util.getRes().newWhileParsingMdx(e, sQuery); } finally { this.scanner = null; this.mdxConnection = null; this.sQuery = null; } } /** override this function to make your kind of query */ protected Query makeQuery( Formula firstFormula, QueryAxis firstAxis, String cube, Exp slicer, QueryPart firstCellProp) { return new Query( mdxConnection, firstFormula, firstAxis, cube, slicer, firstCellProp); } // Override lr_parser methods for NLS. With this error handling scheme, // all errors are fatal. public void report_fatal_error( String message, Object info) throws java.lang.Exception { done_parsing(); try { report_error(message, info); } catch (Throwable e) { // "MDX parser cannot recover from previous error(s)" throw Util.getRes().newMdxFatalError(e); } } // override lr_parser method public void report_error(String message, Object info) { // "Error: %1" throw Util.getRes().newMdxError(message); } // override lr_parser method public void syntax_error(Symbol cur_token) { String s = cur_token.value.toString(); if (cur_token.left != -1) { int loc[] = new int[2]; scanner.getLocation(cur_token, loc); // "Syntax error at line %2, column %3, token '%1'" throw Util.getRes().newMdxSyntaxErrorAt( s, Integer.toString(loc[0] + 1), Integer.toString(loc[1] + 1)); } else { // "Syntax error at token '%1'" throw Util.getRes().newMdxSyntaxError(s); } } public void unrecovered_syntax_error(Symbol cur_token) throws java.lang.Exception { // "Couldn't repair and continue parse" String sFatalSyntaxError = Util.getRes().getMdxFatalSyntaxError(); report_fatal_error(sFatalSyntaxError, cur_token); } :}; init with {: scanner.init(); :}; scan with {: return scanner.next_token(); :}; // Terminals (tokens returned by the scanner). // a. Keywords. terminal AND, AS, CELL, CELL_ORDINAL, DIMENSION, EMPTY, FORMATTED_VALUE, FROM, MEMBER, NON, NOT, ON, OR, PROPERTIES, QUOTE, SELECT, SET, VALUE, WHERE, XOR, WITH; // b. Symbols terminal ASTERISK, // * COLON, // : COMMA, // , CONCAT, // || DOT, // . EQ, // = GE, // >= GT, // > LBRACE, // { LE, // <= LPAREN, // ( LT, // < MINUS, // - NE, // <> PLUS, // + RBRACE, // } RPAREN, // ) SOLIDUS; // / // c. Typed terminals terminal Double NUMBER; terminal String ID; terminal String QUOTED_ID; terminal String AMP_QUOTED_ID; terminal String STRING; terminal String UNKNOWN; // a token the lexer doesn't like! // Non terminals non terminal QueryAxis axis_specification, axis_specification_list, axis_specification_list_opt; non terminal Exp exp_list, exp_list_opt, expression, factor, slicer_specification, term, value_expression, value_expression_primary, where_clause_opt; non terminal QueryPart select_statement; non terminal Id compound_id, cube_name, cube_specification, member_name, set_name; non terminal String axis_name, comp_op, identifier, quoted_identifier, unquoted_identifier, amp_quoted_identifier, keyword; non terminal QueryPart cell_props, cell_props_opt; non terminal Formula formula_specification, member_specification, set_specification, single_formula_specification, with_formula_specification_opt; non terminal MemberProperty comma_member_property_def_list_opt, member_property_def_list, member_property_definition; non terminal cell_opt, cell_property, cell_property_list, dim_props, dim_props_opt, dimension_opt, mandatory_cell_property, optional_cell_property, property, property_list, provider_specific_cell_property, unsigned_integer; non terminal Boolean non_empty_opt; // Start symbol start with select_statement; // ---------------------------------------------------------------------------- // Elements // // // <identifier> ::= <regular_identifier> | <delimited_identifier> quoted_identifier ::= QUOTED_ID ; amp_quoted_identifier ::= AMP_QUOTED_ID ; unquoted_identifier ::= ID | keyword ; identifier ::= unquoted_identifier | quoted_identifier ; // a keyword (unlike a reserved word) can be converted back into an // identifier in some contexts keyword ::= DIMENSION {: RESULT = "Dimension"; :} | PROPERTIES {: RESULT = "Properties"; :} ; compound_id ::= identifier:i {: RESULT = new Id(i); :} | compound_id:hd DOT identifier:tl {: hd.append(tl); RESULT = hd; :} ; // // <regular_identifier> ::= <alpha_char> [{<alpha_char> | <digit> // | <underscore>}...] // // <delimited_identifier> ::= // <start_delimiter>{<double_end_delimiter> | <nondelimit_end_symbol>} // [{<double_end_delimiter> | <nondelimit_end_symbol> }...] // <end_delimiter> // // <start_delimiter> ::= <open_bracket> // // <end_delimiter> ::= <close_bracket> // // <double_end_delimiter> ::= <end_delimiter> end_delimiter> // // <nondelimit_end_symbol> ::= !! <any_character_except_delimit_end_symbol> // // <cube_name> ::= [ [ [ <data_source>] <catalog_name>] [<schema_name>].] // <identifier> cube_name ::= compound_id ; // // <data_source> ::= <identifier> // // <catalog_name> ::= <identifier> // // <schema_name> ::= <identifier> // // <dim_hier> ::= [<cube_name>.]<dimension_name> // | [[<cube_name>.]< dimension_name>.]<hierarchy_name> // jhyde: Need more lookahead for this to work... just use id in place of dim_hier. // dim_hier ::= id; // // <dimension_name> ::= <identifier> // | <member>.DIMENSION // | <level>.DIMENSION // | <hierarchy>.DIMENSION // // <hierarchy_name> ::= <identifier> // | < member>.HIERARCHY // | <level>.HIERARCHY // // <level> ::= [<dim_hier>.]< identifier> // | <dim_hier>.LEVELS(<index>) // | <member>.LEVEL // // Note: The first production is for the case when named levels are // supported. The second production is for the case when named levels are not // supported. // // // <member> ::= [<level>.]<identifier> // | <dim_hier>.<identifier> // | <member>.<identifier> // | <member_value_expression> // // Note: The <member>.<identifier> recognizes the fact that members may // sometimes need to be qualified by their parent names. For example, // "Portland" is a city in Oregon, and also in Maine. So a reference to // Portland will be either Oregon.Portland or Maine.Portland. // // // <property> ::= <mandatory_property> | <user_defined_property> // // <mandatory_property> ::= CATALOG_NAME // | SCHEMA_NAME // | CUBE_NAME // | DIMENSION_UNIQUE_NAME // | HIERARCHY_UNIQUE_NAME // | LEVEL_UNIQUE_NAME // | LEVEL_NUMBER // | MEMBER_UNIQUE_NAME // | MEMBER_NAME // | MEMBER_TYPE // | MEMBER_GUID // | MEMBER_CAPTION // | MEMBER_ORDINAL // | CHILDREN_CARDINALITY // | PARENT_LEVEL // | PARENT_UNIQUE_NAME // | PARENT_COUNT // | DESCRIPTION // // <user_defined_property> ::= <dim_hier>.<identifier> // | <level>.<identifier> // | <member>.<identifier> // // Note: The three productions recognize the fact that a property can apply to // all the members of a dimension, or all the members of a level, or just to a // member. // // // <tuple> ::= <member> // | (<member> [, <member>...]) // | <tuple_value_expression> // // Note: Each member must be from a different dimension or from a different // hierarchy. // // // <set> ::= <member>:<member> // // Note: Each member must be from the same hierarchy and the same level. // // // | <set_value_expression> // | <open_brace>[<set>|<tuple> [, <set>|<tuple>...]]<close_brace> // // Note: Duplicates (if any) are always retained when specifying sets in this // fashion. // // // | (<set>) // // <open_brace> ::= { // // <close_brace> ::= } // // <open_bracket> ::= [ // // <close_bracket> ::= ] // // <underscore> ::= _ // // <alpha_char> ::= a | b | c | ...| z | A | B | C | ... | Z // // <digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 // // Leveling Rules for Elements // // The ability to qualify a cube name by one or more of <data_source>, // <catalog_name>, or <schema_name> is optional. Consumers can check the value // of the property MDPROP_MDX_OBJQUALIFICATION to see whether a provider // supports cube qualification. // // // The ability to qualify a dimension name by a cube name is // optional. Consumers can check the value of the property // MDPROP_MDX_OBJQUALIFICATION to see whether a provider supports dimension // qualification. // // // The ability to qualify a hierarchy name by a dimension name or by cube name // and dimension name is optional. Consumers can check the value of the // property MDPROP_MDX_OBJQUALIFICATION to see whether a provider supports // hierarchy qualification. // // // The provider need support only one of the two productions for <level>. If it // supports // // <level> ::= [<dim_hier>.] <identifier> // // then the ability to qualify by <dim_hier> is optional. // // Consumers can check the value of the property MDPROP_NAMED_LEVELS to see if // the provider supports named levels. If it does, then the consumer can check // MDPROP_MDX_OBJQUALIFICATION to see whether named levels can be qualified by // <dim_hier>. // // The ability to qualify a member by a level, a member, or <dim_hier> is // optional. Consumers can check the value of the property // MDPROP_MDX_OBJQUALIFICATION to see whether a provider supports member // qualification. // // Note: Several leveling rules above make it optional to qualify // multidimensional schema object names. However, this does not imply that the // ability to generate unique names for members, levels, dimensions, and // hierarchies is optional. Providers are required to furnish unique names in // the schema rowsets for these objects. If providers generate unique names by // means other than qualification, then the ability to qualify is optional. For // more information, see 'Provider Implementation Considerations for Unique // Names' in Chapter 2. // // // ---------------------------------------------------------------------------- // // // Expressions // // Note: The syntax of <value_expression> is generally the same as SQL-92, // subclause 6.11, <value_expression>. Differences are: // // <tuple>[.VALUE], <property>[.VALUE], and <conditional_expression> are new // values for <value_expression_primary>. // // // There are new values for <numeric_value_function>, mainly for statistical // analysis. // // // The BNF for <value_expression_primary>, <character_string_literal>, and // <string_value_expression> have been shortened by eliminating several // intermediate nonterminals. // // <value_expression> ::= <numeric_value_expression> // | <string_value_expression> // // <numeric_value_expression> ::= <term> // | <numeric_value_expression> {<plus> | <minus>} <term> value_expression ::= term | value_expression:x PLUS term:y {: RESULT = new FunCall("+", new Exp[] {x, y}, FunDef.TypeInfix); :} | value_expression:x MINUS term:y {: RESULT = new FunCall("-", new Exp[] {x, y}, FunDef.TypeInfix); :} | value_expression:x OR term:y {: RESULT = new FunCall("OR", new Exp[] {x, y}, FunDef.TypeInfix); :} | value_expression:x XOR term:y {: RESULT = new FunCall("XOR", new Exp[] {x, y}, FunDef.TypeInfix); :} | value_expression:x CONCAT term:y {: RESULT = new FunCall("||", new Exp[] {x, y}, FunDef.TypeInfix); :} ; // // <term> ::= <factor> | <term> {<asterisk> | <solidus>} <factor> term ::= factor | term:x ASTERISK factor:y {: RESULT = new FunCall("*", new Exp[] {x, y}, FunDef.TypeInfix); :} | term:x SOLIDUS factor:y {: RESULT = new FunCall("/", new Exp[] {x, y}, FunDef.TypeInfix); :} | term:x AND factor:y {: RESULT = new FunCall("AND", new Exp[] {x, y}, FunDef.TypeInfix); :} ; // // <factor> ::= [<sign>] <numeric_primary> // factor ::= value_expression_primary | PLUS value_expression_primary:p {: RESULT = p; :} | MINUS value_expression_primary:p {: RESULT = new FunCall("-", new Exp[] {p}, FunDef.TypePrefix); :} | NOT value_expression_primary:p {: RESULT = new FunCall("NOT", new Exp[] {p}, FunDef.TypePrefix); :} ; // <sign> ::= + | - // // <plus> ::= + // // <minus> ::= - // // <asterisk>::= * // // <solidus> ::= / // // <numeric_primary> ::= <value_expression_primary> // | <numeric_value_function> // // Note: The data type of <value_expression_primary> in the above production // shall be numeric. // // // <value_expression_primary> ::= <unsigned_numeric_literal> // | (<value_expression>) // | <character_string_literal> // | [<cube_name>.]<tuple>[.VALUE] // | <property>[.VALUE] // | <conditional_expression> value_expression_primary ::= STRING:s {: RESULT = Literal.createString(s); :} | NUMBER:d {: RESULT = Literal.create(d); :} | identifier:i {: RESULT = new Id(i); :} | value_expression_primary:i DOT unquoted_identifier:j {: RESULT = new FunCall(j, new Exp[] {i}, FunDef.TypeProperty); :} | value_expression_primary:i DOT quoted_identifier:j {: if (i instanceof Id) { ((Id) i).append(j); RESULT = i; } else { RESULT = new FunCall( j, new Exp[] {i}, FunDef.TypePropertyQuoted); } :} | value_expression_primary:i DOT amp_quoted_identifier:j {: if (i instanceof Id) { ((Id) i).append(j, true); RESULT = i; } else { RESULT = new FunCall( j, new Exp[] {i}, FunDef.TypePropertyAmpQuoted); } :} | value_expression_primary:i DOT identifier:j LPAREN exp_list_opt:lis RPAREN {: ((QueryPart) i).append((QueryPart) lis); RESULT = new FunCall(j, ExpBase.makeArray(i), FunDef.TypeMethod); :} | identifier:i LPAREN exp_list_opt:lis RPAREN {: RESULT = new FunCall( i, ExpBase.makeArray(lis), FunDef.TypeFunction); :} | LPAREN exp_list:lis RPAREN {: // Whereas ([Sales],[Time]) and () are tuples, ([Sales]) and (5) // are just expressions. RESULT = new FunCall( "()", ExpBase.makeArray(lis), FunDef.TypeParentheses); :} | LBRACE exp_list_opt:lis RBRACE {: // set built from sets/tuples RESULT = new FunCall( "{}", ExpBase.makeArray(lis), FunDef.TypeBraces); :} ; // // <conditional_expression> ::= <if_expression> | <case_expression> // // <if_expression> ::= iif(<search_condition>, <true_part>, <false_part>) // // <true_part> ::= <value_expression> // // <false_part> ::= <value_expression> // // <case_expression> ::= <simple_case> | <searched_case> | <coalesce_empty> // // <simple_case> ::= CASE <case_operand> // <simple_when_clause>... // [<else_clause>] // END // // <searched_case> ::= CASE // <searched_when_clause>... // [<else_clause>] // END // // <simple_when_clause> ::= WHEN <when_operand> THEN <result> // // <searched_when_clause> ::= WHEN <search_condition> THEN <result> // // <else_clause> ::= ELSE <value_expression> // // <case_operand> ::= <value_expression> // // <when_operand> ::= <value_expression> // // <result> ::= <value_expression> // // <coalesce_empty> ::= COALESCEEMPTY (<value_expression> // {, <value_expression> }...) // // <signed_numeric_literal> ::= [<sign>]<unsigned_numeric_literal> // // <unsigned_numeric_literal> ::= <exact_numeric_literal> // | <approximate_numeric_literal> // // <exact_numeric_literal> ::= <unsigned_integer>[.<unsigned_integer>] // | <unsigned_integer>. // | .<unsigned_integer> // // <unsigned_integer> ::= {<digit>}... // // <approximate_numeric_literal> ::= <mantissa>E<exponent> // // <mantissa> ::= < exact_numeric_literal> // // <exponent> ::= [<sign>]<unsigned_integer> // // <string_value_expression> ::= <value_expression_primary> // | <string_value_expression> // <concatenation_operator> // <value_expression_primary> // // Note: The data type of <value_expression_primary> in the above production // shall be a character string. // // // <character_string_literal> ::= <quote>[<character_representation>...] // <quote> // // <character_representation> ::= <nonquote_character> | <quote_symbol> // // <nonquote_character> ::= !! // <any_character_in_the_character_set_other_than_quote> // // <quote_symbol> ::= <quote> <quote> // // <quote> ::= ' // // <concatenation_operator> ::= || // // Leveling Rules for Expressions // // The following productions for <value_expression_primary> are optional: // // The ability to qualify <tuple>[.VALUE] by <cube_name> in a value expression // primary is optional. Consumers can check the value of the property // MDPROP_MDX_OUTERREFERENCE to see whether a provider supports this feature. // // // <property>[.VALUE]. Consumers can check the value of the property // MDPROP_MDX_QUERYBYPROPERTY to see whether a provider supports this feature. // // // <simple_case>, <searched_case>. Consumers can check the value of the // property MDPROP_MDX_CASESUPPORT to see whether a provider supports this // feature. // // ---------------------------------------------------------------------------- // Search Condition // // <search_condition> ::= <boolean_term> // | <search_condition> {OR | XOR} <boolean_term> // // <boolean_term> ::= <boolean_factor> | <boolean_term> AND <boolean_factor> // // <boolean_factor> ::= [NOT] <boolean_primary> // // <boolean_primary> ::= <value_expression> <comp_op> <value_expression> // | ISEMPTY(<value_expression>) // | (<search_condition>) // <comp_op> ::= <equals_operator> // | <not_equals_operator> // | <less_than_operator> // | <greater_than_operator> // | <less_than_or_equals_operator> // | <greater_than_or_equals_operator> comp_op ::= EQ {: RESULT = "="; :} | NE {: RESULT = "<>"; :} | LT {: RESULT = "<"; :} | GT {: RESULT = ">"; :} | LE {: RESULT = "<="; :} | GE {: RESULT = ">="; :} ; // // <equals_operator> ::= = // // <not_equals_operator> ::= <> // // <greater_than_operator> ::= > // // <less_than_operator> ::= < // // <greater_than_or_equals_operator> ::= >= // // <less_than_or_equals_operator> ::= <= // // Leveling Rules for Search Condition // // If <value_expression> in a <boolean_primary> value is a string value // expression, then support for <comp_op> values other than <equals_operator> // and <not_equals_operator> is optional. Consumers can check the value of the // property MDPROP_MDX_STRING_COMPOP to see whether a provider supports this // feature. // ---------------------------------------------------------------------------- // Set Value Expression // // <index> ::= <numeric_value_expression> // // Note: <index> denotes an integer argument. If an arbitrary // <numeric_value_expression> appears here, then it is truncated to the nearest // integer. // // // <percentage> ::= <numeric_value_expression> // // <set_value_expression> ::= <dim_hier>.MEMBERS // | <level>.MEMBERS // | <member>.CHILDREN // | BOTTOMCOUNT(<set>, <index> // [, <numeric_value_expression>]) // | BOTTOMPERCENT(<set>, <percentage>, // <numeric_value_expression>) // | BOTTOMSUM(<set>, <numeric_value_expression>, // <numeric_value_expression>) // | CROSSJOIN(<set>, <set>) // | DESCENDANTS(<member>, <level> [,<desc_flags>]) // // Note: In the absence of explicit <desc_flags> specification, SELF is the // default. // // | DISTINCT(<set>) // | DRILLDOWNLEVEL(<set> [, <level>]]) // | DRILLDOWNLEVELBOTTOM(<set>, <index> // [,[<level>] [, <numeric_value_expression>]]) // | DRILLDOWNLEVELTOP(<set>, <index>[, [<level>] // [, <numeric_value_expression>]]) // | DRILLDOWNMEMBER(<set>, <set>[, RECURSIVE]) // | DRILLDOWNMEMBERBOTTOM(<set>, <set>, <index> // [, <numeric_value_expression>][, RECURSIVE]]) // | DRILLDOWNMEMBERTOP(<set>, <set>, <index> // [, [<numeric_value_expression>][, RECURSIVE]]) // | DRILLUPLEVEL(<set>[, <level>]]) // | DRILLUPMEMBER(<set>, <set>) // | EXCEPT(<set>, <set> [, ALL]) // | EXTRACT(<set>, <dim_hier>[, <dim_hier>...]) // | FILTER(<set>, <search_condition>) // | GENERATE(<set>, <set> [, ALL]) // | HIERARCHIZE(<set>) // | INTERSECT(<set>, <set> [, ALL]) // | LASTPERIODS(<index> [, <member>]) // | MTD([<member>]) // | ORDER(<set>, <value_expression> // [, ASC | DESC | BASC | BDESC]) // // Note: In the absence of explicit specification, ASC is the default. // // // | PERIODSTODATE([<level>[, <member>]]) // | QTD([<member>]) // | TOGGLEDRILLSTATE(<set1>, <set2>[, RECURSIVE]) // // Note: With the exception of CROSSJOIN, all set functions that take more than // one <set> argument require that the two set arguments have tuples of the // same dimensionality. // // // | TOPCOUNT(<set>, <index> // [, <numeric_value_expression>]) // | TOPPERCENT(<set>, <percentage>, // <numeric_value_expression>) // | TOPSUM(<set>, <numeric_value_expression>, // <numeric_value_expression>) // | UNION(<set>, <set> [, ALL]) // | WTD([<member>]) // | YTD(<member>) // // <desc_flags> ::= SELF // | AFTER // | BEFORE // | BEFORE_AND_AFTER // | SELF_AND_AFTER // | SELF_AND_BEFORE // | SELF_BEFORE_AFTER // // ---------------------------------------------------------------------------- // Member Value Expression // // <member_value_expression> ::= <member>.{PARENT | FIRSTCHILD | LASTCHILD // | PREVMEMBER | NEXTMEMBER} // | <member>.LEAD(<index>) // | <member>.LAG(<index>) // // Note: LAG(<index>) is the same as LEAD(-<index>) // // // | <member>.{FIRSTSIBLING | LASTSIBLING} // | <dimension>.[CURRENTMEMBER] // | <dimension>.DEFAULTMEMBER // | <hierarchy>.DEFAULTMEMBER // | ANCESTOR(<member>, <level>) // | CLOSINGPERIOD([<level>[, <member>]) // | COUSIN(<member>, <member>) // | OPENINGPERIOD([<level>[, <member>]) // | PARALLELPERIOD([<level>[, <index> // [, <member>]]]) expression ::= expression:x COLON value_expression:y {: // range yields set RESULT = new FunCall(":", new Exp[] {x, y}, FunDef.TypeInfix); :} | expression:x comp_op:op value_expression:y {: // e.g. 1 < 5 RESULT = new FunCall(op, new Exp[] {x, y}, FunDef.TypeInfix); :} | value_expression ; exp_list_opt ::= /* empty */ | exp_list ; exp_list ::= expression | expression:hd COMMA exp_list:tl {: ((QueryPart) hd).append((QueryPart) tl); RESULT = hd; :} ; // // Leveling Rules for Member Value Expression // // The following member functions are optional: COUSIN, PARALLELPERIOD, // OPENINGPERIOD, CLOSINGPERIOD. Consumers can check the value of the property // MDPROP_MDX_MEMBER_FUNCTIONS to see whether a provider supports this feature. // // // * Tuple Value Expression // // <tuple_value_expression> ::= <set>.CURRENTMEMBER // | <set>[.ITEM](<string_value_expression> // [, <string_value_expression>...] | <index>) // // // * Numeric Value Function // // <numeric_value_function> ::= // AGGREGATE(<set> [, <numeric_value_expression>]) // | AVG(<set>[, <numeric_value_expression>]) // | CORRELATION(<set> [, <numeric_value_expression>] // [, <numeric_value_expression>]) // | COVARIANCE(<set>[, <numeric_value_expression> // [, <numeric_value_expression>]) // | COUNT(<set>[, INCLUDEEMPTY]) // | LINREGINTERCEPT(<set>[, <numeric_value_expression> // // // Leveling Rules for Numeric Value Function // // The following numeric functions are optional: MEDIAN, VAR, STDEV, RANK, // AGGREGATE, COVARIANCE, CORRELATION, LINREGSLOPE, LINREGVARIANCE, LINREGR2, // LINREGPOINT. Consumers can check the value of the property // MDPROP_MDX_NUMERIC_FUNCTIONS to see whether a provider supports this // feature. // // ---------------------------------------------------------------------------- // MDX Statement // // <MDX_statement> ::= <select_statement> // | <create_formula_statement> // | <drop_formula_statement> // // <select_statement> ::= [WITH <formula_specification>] // SELECT [<axis_specification> // [, <axis_specification>...]] // FROM [<cube_specification>] // WHERE [<slicer_specification>] // [<cell_props>] // jhyde: The above is wrong... you can omit 'WHERE'. select_statement ::= with_formula_specification_opt:f SELECT axis_specification_list_opt:a FROM cube_specification:c where_clause_opt:w cell_props_opt:cp {: Parser parser = (Parser) CUP$Parser$parser; // We want 'Sales', not '[Sales]', and can't handle 'Schema.Sales' // yet. String cubeName = c.getElement(0); RESULT = parser.makeQuery(f, a, cubeName, w, cp); :}; with_formula_specification_opt ::= WITH formula_specification:f {: RESULT = f; :} | /* empty */ ; axis_specification_list_opt ::= /* empty */ | axis_specification_list; axis_specification_list ::= axis_specification | axis_specification:hd COMMA axis_specification_list:tl {: hd.append(tl); RESULT = hd; :} ; where_clause_opt ::= /* empty */ | WHERE slicer_specification:s {: RESULT = s; :}; cell_props_opt ::= cell_props | /* empty */ ; // // <formula_specification> ::= <single_formula_specification> // [<single_formula_specification>...] // formula_specification ::= single_formula_specification | single_formula_specification:hd formula_specification:tl {: hd.append(tl); RESULT = hd; :} ; // <single_formula_specification> ::= <member_specification> // | <set_specification> // single_formula_specification ::= member_specification | set_specification ; // // <member_specification> ::= MEMBER <member_name> AS <value_expression> // [, <solve_order_specification>] // [, <member_property_definition>...] member_specification ::= MEMBER member_name:m AS QUOTE value_expression:e QUOTE comma_member_property_def_list_opt:l {: RESULT = new Formula( m.toStringArray(), e, MemberProperty.makeArray(l)); :} | MEMBER member_name:m AS value_expression:e comma_member_property_def_list_opt:l {: RESULT = new Formula( m.toStringArray(), e, MemberProperty.makeArray(l)); :} ; comma_member_property_def_list_opt ::= /* empty */ | COMMA member_property_def_list:l {: RESULT = l; :} ; member_property_def_list ::= member_property_definition | member_property_definition:hd COMMA member_property_def_list:tl {: RESULT = hd; RESULT.append(tl); :} ; // // <member_name> ::= <member>.<identifier> // | <cube_name>.<member>.<identifier> // member_name ::= compound_id; // // Note: // // The identifier defines a new member. The qualification member has enough // information to specify the dimension, and the level in the dimension that // this new member should be on. // // // If <member_name> is part of a member specification that appears in a create // formula statement or is part of a drop formula statement, then it must be // qualified by a cube name, as in the second production above. // // <solve_order_specification> ::= SOLVE_ORDER = <unsigned_integer> // // <member_property_definition> ::= <identifier> = <value_expression> member_property_definition ::= identifier:id EQ value_expression:e {: RESULT = new MemberProperty(id, e); :} ; // // Note: Since the property definition appears in the context of a member // definition, there is enough information to associate the identifier (which // is the property name) in the above production with a member. // // // <set_specification> ::= SET <set_name> AS <set> set_specification ::= SET set_name:s AS QUOTE expression:e QUOTE {: RESULT = new Formula(s.toStringArray(), e); :} | SET set_name:s AS expression:e {: RESULT = new Formula(s.toStringArray(), e); :} ; // // <set_name> ::= <identifier> | <cube_name>.<identifier> set_name ::= compound_id ; // // Note: If <set_name> is part of a set specification that appears in a create // formula statement or is part of a drop formula statement, then it must be // qualified by a cube name, as in the second production above. // // // <axis_specification> ::= [NON EMPTY] <set> [<dim_props>] ON <axis_name> axis_specification ::= non_empty_opt:b expression:s dim_props_opt ON axis_name:a {: RESULT = new QueryAxis(b.booleanValue(), s, a, QueryAxis.subtotalsUndefined); :} ; non_empty_opt ::= /* empty */ {: RESULT = new Boolean(false); :} | NON EMPTY {: RESULT = new Boolean(true); :} ; dim_props_opt ::= /* empty */ | dim_props ; // // <axis_name> ::= COLUMNS // | ROWS // | PAGES // | CHAPTERS // | SECTIONS // | AXIS(<index>) // jhyde: we don't support 'AXIS(<index>)' axis_name ::= identifier; // // <dim_props> ::= [DIMENSION] PROPERTIES <property> [, <property>...] dim_props ::= dimension_opt PROPERTIES property_list ; dimension_opt ::= /* empty */ | DIMENSION ; property_list ::= property | property COMMA property_list ; // // <cube_specification> ::= [<cube_name>] [, <cube_name>] // jhyde: In this implementation, you must supply EXACTLY one cube. cube_specification ::= cube_name; // // <slicer_specification> ::= {<set> | <tuple>} slicer_specification ::= expression; // // <cell_props> ::= [CELL] PROPERTIES <cell_property> [, <cell_property>...] cell_props ::= cell_opt PROPERTIES cell_property_list ; cell_opt ::= /* empty */ | CELL ; cell_property_list ::= cell_property | cell_property COMMA cell_property_list ; // // <cell_property> ::= <mandatory_cell_property> // | <optional_cell_property> // | <provider_specific_cell_property> cell_property ::= mandatory_cell_property | optional_cell_property | provider_specific_cell_property ; // // <mandatory_cell_property> ::= CELL_ORDINAL | VALUE | FORMATTED_VALUE mandatory_cell_property ::= CELL_ORDINAL | VALUE | FORMATTED_VALUE; // // <optional_cell_property> ::= FORMAT_STRING // | FORE_COLOR // | BACK_COLOR // | FONT_NAME // | FONT_SIZE // | FONT_FLAGS // // <provider_specific_cell_property> ::= <identifier> provider_specific_cell_property ::= identifier; // // <create_formula_statement> ::= CREATE [<scope>]<formula_specification> // // <drop_formula_statement> ::= <drop_member_statement> // | <drop_set_statement> // // <drop_member_statement> ::= DROP MEMBER <member_name> // [, <member_name>...] // // <drop_set_statement> ::= DROP SET <set_name> [, <set_name>...] // // <scope> := GLOBAL | SESSION // // Leveling Rules for MDX Statement // // Support for <formula_specification> is optional. Consumers can check the // value of the property MDPROP_MDX_FORMULAS to see whether a provider supports // this feature. // // // Support for <set> in <slicer_specification> is optional. Consumers can check // the value of the property MDPROP_MDX_SLICER to see whether a provider // supports this feature. // // // Support for more than one cube name in <cube_specification> is // optional. Support for having no cube name in the FROM clause (that is, the // cube is implicitly defined by the axis and slicer dimensions) is also // optional. Consumers can check the value of the property MDPROP_MDX_JOINCUBES // to see whether a provider supports this feature. // // // The axis names CHAPTERS and SECTIONS are optional. Consumers can check the // value of the property MDPROP_AXES to see whether a provider supports this // feature. // // // Support for <index> > 2 in the AXIS(<index>) function is optional. Consumers // can check the value of the property MDPROP_AXES to see whether a provider // supports this feature. // // // Support for <create_formula_statement> is optional. Consumers can check the // value of the property MDPROP_MDX_FORMULAS to see whether a provider supports // this feature. // // // Support for <scope> of GLOBAL is optional. Consumers can check the value of // the property MDPROP_MDX_FORMULAS to see whether a provider supports this // feature. // // End Parser.cup
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 1820 | Paul Robert Dymecki | mondrian: Integrate latest from //guest/julian_hyde | ||
//guest/julian_hyde/mondrian/src/main/mondrian/olap/Parser.cup | |||||
#3 | 1576 | Julian Hyde |
mondrian: fix dataset (add column customer.ordinal); create dataset for oracle; get queries working on oracle; get format strings working; refactor out new packages mondrian.rolap.agg and mondrian.rolap.sql. |
||
#2 | 1499 | Julian Hyde |
Mondrian: Re-organize functions and type-checking Add mondrian.olap.fun package |
||
#1 | 1453 | Julian Hyde | mondrian: first source check-in |