From d13bb5c65ef2a69b01f2bf2decb601e636696f82 Mon Sep 17 00:00:00 2001 From: Julian Hyde Date: Thu, 12 Aug 2010 08:49:13 +0000 Subject: [PATCH] Fix further issues in bug 3042937 by no longer enclosing formula of calculated member and set in single quotes. Also, indent formulas for readability. git-svn-id: https://olap4j.svn.sourceforge.net/svnroot/olap4j/trunk@349 c6a108a4-781c-0410-a6c6-c2d559e19af0 --- src/org/olap4j/mdx/IdentifierNode.java | 8 +------ src/org/olap4j/mdx/ParseTreeWriter.java | 9 ------- src/org/olap4j/mdx/WithMemberNode.java | 14 +++++------ src/org/olap4j/mdx/WithSetNode.java | 5 ++-- testsrc/org/olap4j/mdx/MdxTest.java | 31 +++++++++++++++++++++---- 5 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/org/olap4j/mdx/IdentifierNode.java b/src/org/olap4j/mdx/IdentifierNode.java index e290103..b66a45e 100644 --- a/src/org/olap4j/mdx/IdentifierNode.java +++ b/src/org/olap4j/mdx/IdentifierNode.java @@ -12,8 +12,6 @@ import java.util.AbstractList; import java.util.ArrayList; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import org.olap4j.impl.*; import org.olap4j.type.Type; @@ -165,11 +163,7 @@ public T accept(ParseTreeVisitor visitor) { } public void unparse(ParseTreeWriter writer) { - String str = toString(); - if(writer.isInsideSingleQuote()) { - str = str.replace("'", "''"); - } - writer.getPrintWriter().print(str); + writer.getPrintWriter().print(this); } public String toString() { diff --git a/src/org/olap4j/mdx/ParseTreeWriter.java b/src/org/olap4j/mdx/ParseTreeWriter.java index 24f44f8..84ed6d5 100644 --- a/src/org/olap4j/mdx/ParseTreeWriter.java +++ b/src/org/olap4j/mdx/ParseTreeWriter.java @@ -41,7 +41,6 @@ public class ParseTreeWriter { private final PrintWriter pw; private int linePrefixLength; private String linePrefix; - private boolean isInsideSingleQuote; private static final int INDENT = 4; private static String bigString = " "; @@ -113,14 +112,6 @@ private static synchronized String spaces(int n) } return bigString.substring(0, n); } - - boolean isInsideSingleQuote() { - return isInsideSingleQuote; - } - - void setInsideSingleQuote(boolean isInsideSingleQuote) { - this.isInsideSingleQuote = isInsideSingleQuote; - } } // End ParseTreeWriter.java diff --git a/src/org/olap4j/mdx/WithMemberNode.java b/src/org/olap4j/mdx/WithMemberNode.java index d4a315d..d06daa0 100644 --- a/src/org/olap4j/mdx/WithMemberNode.java +++ b/src/org/olap4j/mdx/WithMemberNode.java @@ -62,20 +62,18 @@ public void unparse(ParseTreeWriter writer) { PrintWriter pw = writer.getPrintWriter(); pw.print("MEMBER "); name.unparse(writer); - pw.print(" AS '"); - writer.setInsideSingleQuote(true); - try { - expression.unparse(writer); - } finally { - writer.setInsideSingleQuote(false); - } - pw.print("'"); + writer.indent(); + pw.println(" AS"); + // The MDX language, and olap4j's parser, allows formulas in calculated + // members and sets to be specified with and without single quotes. + expression.unparse(writer); if (memberPropertyList != null) { for (PropertyValueNode memberProperty : memberPropertyList) { pw.print(", "); memberProperty.unparse(writer); } } + writer.outdent(); } /** diff --git a/src/org/olap4j/mdx/WithSetNode.java b/src/org/olap4j/mdx/WithSetNode.java index 6437e25..88c2179 100644 --- a/src/org/olap4j/mdx/WithSetNode.java +++ b/src/org/olap4j/mdx/WithSetNode.java @@ -54,9 +54,10 @@ public void unparse(ParseTreeWriter writer) { PrintWriter pw = writer.getPrintWriter(); pw.print("SET "); name.unparse(writer); - pw.print(" AS '"); + writer.indent(); + pw.println(" AS"); expression.unparse(writer); - pw.print("'"); + writer.outdent(); } /** diff --git a/testsrc/org/olap4j/mdx/MdxTest.java b/testsrc/org/olap4j/mdx/MdxTest.java index dbb7dba..cbe222e 100644 --- a/testsrc/org/olap4j/mdx/MdxTest.java +++ b/testsrc/org/olap4j/mdx/MdxTest.java @@ -116,10 +116,12 @@ public void testParseIdentifier() { /** * Tests that escaped single quotes ('') nested inside a quoted - * part of a query are unparsed as escaped quotes as well. + * part of a query are handled correctly. The MDX language allows + * expressions for calculated members and sets to be specified with and + * without single quotes; the unparser generates expressions without quotes. */ public void testQuoteEscaping() { - final String query = + String query = "WITH\n" + "MEMBER [CustomerDim].[CustomerName].[XL_QZX] AS 'Aggregate" + "({[CustomerDim].[CustomerName].&[ABC INT''L]," @@ -129,8 +131,29 @@ public void testQuoteEscaping() { + "FROM [cube]\n" + "WHERE ([CustomerDim].[CustomerName].[XL_QZX])"; final MdxParser parser = new DefaultMdxParserImpl(); - final SelectNode rootNode = parser.parseSelect(query); - assertEquals(query,TestContext.unfold(rootNode.toString())); + SelectNode rootNode = parser.parseSelect(query); + TestContext.assertEqualsVerbose( + "WITH\n" + + "MEMBER [CustomerDim].[CustomerName].[XL_QZX] AS\n" + + " Aggregate({[CustomerDim].[CustomerName].&[ABC INT'L], [CustomerDim].[CustomerName].&[XYZ]})\n" + + "SELECT\n" + + "{[Measures].[Sales]} ON COLUMNS\n" + + "FROM [cube]\n" + + "WHERE ([CustomerDim].[CustomerName].[XL_QZX])", + rootNode.toString()); + + // Now named set + query = + "WITH SET Foo as Filter(Bar.Members, Instr(Name, \"'\") > 0)\n" + + "SELECT FROM [Cube]"; + rootNode = parser.parseSelect(query); + TestContext.assertEqualsVerbose( + "WITH\n" + + "SET Foo AS\n" + + " Filter(Bar.Members, (Instr(Name, \"'\") > 0.0))\n" + + "SELECT\n" + + "FROM [Cube]", + rootNode.toString()); } }