From b2c7edf3250b4732ef5675ef538e564d7a28ca97 Mon Sep 17 00:00:00 2001 From: Julian Hyde Date: Tue, 9 Nov 2010 18:44:22 +0000 Subject: [PATCH] Fix MONDRIAN-831, "Failure parsing queries with member identifiers beginning with '_' and not expressed between brackets". git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@365 c6a108a4-781c-0410-a6c6-c2d559e19af0 --- src/org/olap4j/mdx/ParseRegion.java | 9 ++++- src/org/olap4j/mdx/parser/impl/Scanner.java | 3 +- testsrc/org/olap4j/test/ParserTest.java | 43 +++++++++++++++++---- 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/src/org/olap4j/mdx/ParseRegion.java b/src/org/olap4j/mdx/ParseRegion.java index 95682cd..091e984 100644 --- a/src/org/olap4j/mdx/ParseRegion.java +++ b/src/org/olap4j/mdx/ParseRegion.java @@ -9,6 +9,8 @@ */ package org.olap4j.mdx; +import org.olap4j.impl.Olap4jUtil; + /** * Region of parser source code. * @@ -335,8 +337,11 @@ private static int lineColToIndex(String code, int line, int column) --column; int i = 0; while (line-- > 0) { - i = code.indexOf(NL, i) - + NL.length(); + // Works on linux where line ending is "\n"; + // also works on windows where line ending is "\r\n". + // Even works if they supply linux strings on windows. + i = code.indexOf("\n", i) + + "\n".length(); } return i + column; } diff --git a/src/org/olap4j/mdx/parser/impl/Scanner.java b/src/org/olap4j/mdx/parser/impl/Scanner.java index cae730d..28100b9 100644 --- a/src/org/olap4j/mdx/parser/impl/Scanner.java +++ b/src/org/olap4j/mdx/parser/impl/Scanner.java @@ -591,6 +591,7 @@ public Symbol next_token() throws IOException { case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z': + case '_': case '$': /* parse an identifier */ id = new StringBuilder(); for (;;) { @@ -609,7 +610,7 @@ public Symbol next_token() throws IOException { case 'Y': case 'Z': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - case '_': + case '_': case '$': break; default: String strId = id.toString(); diff --git a/testsrc/org/olap4j/test/ParserTest.java b/testsrc/org/olap4j/test/ParserTest.java index 465da90..35281a9 100644 --- a/testsrc/org/olap4j/test/ParserTest.java +++ b/testsrc/org/olap4j/test/ParserTest.java @@ -178,19 +178,48 @@ public void testNegativeCases() throws Exception { } public void testScannerPunc() { - // '$' is OK inside brackets but not outside + assertParseQuery( + "with member [Measures].__Foo as 1 + 2\n" + + "select __Foo on 0\n" + + "from _Bar_Baz", + "WITH\n" + + "MEMBER [Measures].__Foo AS\n" + + " (1.0 + 2.0)\n" + + "SELECT\n" + + "__Foo ON COLUMNS\n" + + "FROM _Bar_Baz"); + + // # is not allowed + assertParseQueryFails( + "with member [Measures].#^_Foo as 1 + 2\n" + + "select __Foo on 0\n" + + "from _Bar#Baz", + "Unexpected character '#'"); + assertParseQueryFails( + "with member [Measures].Foo as 1 + 2\n" + + "select Foo on 0\n" + + "from Bar#B^az", + "Unexpected character '#'"); + + // The spec doesn't allow $ but SSAS allows it so we allow it too. + assertParseQuery( + "with member [Measures].$Foo as 1 + 2\n" + + "select $Foo on 0\n" + + "from Bar$Baz", + "WITH\n" + + "MEMBER [Measures].$Foo AS\n" + + " (1.0 + 2.0)\n" + + "SELECT\n" + + "$Foo ON COLUMNS\n" + + "FROM Bar$Baz"); + // '$' is OK inside brackets too assertParseQuery( "select [measures].[$foo] on columns from sales", "SELECT\n" + "[measures].[$foo] ON COLUMNS\n" + "FROM sales"); - // todo: parser off by one - assertParseQueryFails( - "select [measures].$^f^oo on columns from sales", - "Unexpected character '\\$'"); - - // ']' unexcpected + // ']' unexpected assertParseQueryFails( "select { Customers]^.^Children } on columns from [Sales]", "Unexpected character ']'");