[#1982] Change RenderNameStyle.UPPER, LOWER, AS_IS to quote literals if

needed
This commit is contained in:
Lukas Eder 2012-11-30 13:01:15 +01:00
parent 7e3ab4e67a
commit 962a0226c9
2 changed files with 61 additions and 33 deletions

View File

@ -38,6 +38,7 @@ package org.jooq.impl;
import static java.util.Arrays.asList;
import java.util.Stack;
import java.util.regex.Pattern;
import org.jooq.Configuration;
import org.jooq.QueryPart;
@ -57,23 +58,24 @@ class DefaultRenderContext extends AbstractContext<RenderContext> implements Ren
/**
* Generated UID
*/
private static final long serialVersionUID = -8358225526567622252L;
private static final long serialVersionUID = -8358225526567622252L;
private static final Pattern IDENTIFIER_PATTERN = Pattern.compile("[A-Za-z][A-Za-z0-9_]*");
private final StringBuilder sql;
private boolean inline;
private boolean renderNamedParams;
private boolean qualify = true;
private int alias;
private CastMode castMode = CastMode.DEFAULT;
private SQLDialect[] castDialects;
private int indent;
private Stack<Integer> indentLock = new Stack<Integer>();
private int printMargin = 80;
private final StringBuilder sql;
private boolean inline;
private boolean renderNamedParams;
private boolean qualify = true;
private int alias;
private CastMode castMode = CastMode.DEFAULT;
private SQLDialect[] castDialects;
private int indent;
private Stack<Integer> indentLock = new Stack<Integer>();
private int printMargin = 80;
// [#1632] Cached values from Settings
private RenderKeywordStyle cachedRenderKeywordStyle;
private RenderNameStyle cachedRenderNameStyle;
private boolean cachedRenderFormatted;
private RenderKeywordStyle cachedRenderKeywordStyle;
private RenderNameStyle cachedRenderNameStyle;
private boolean cachedRenderFormatted;
DefaultRenderContext(Configuration configuration) {
super(configuration);
@ -265,21 +267,43 @@ class DefaultRenderContext extends AbstractContext<RenderContext> implements Ren
return this;
}
// Quoting is needed when explicitly requested...
boolean needsQuote = RenderNameStyle.QUOTED == cachedRenderNameStyle
// ... or when an identifier contains special characters [#1982]
|| !IDENTIFIER_PATTERN.matcher(literal).matches();
if (RenderNameStyle.LOWER == cachedRenderNameStyle) {
sql(literal.toLowerCase());
literal = literal.toLowerCase();
}
else if (RenderNameStyle.UPPER == cachedRenderNameStyle) {
sql(literal.toUpperCase());
literal = literal.toUpperCase();
}
else if (RenderNameStyle.AS_IS == cachedRenderNameStyle) {
if (!needsQuote) {
sql(literal);
}
else {
switch (configuration.getDialect()) {
// MySQL supports backticks and double quotes
case MYSQL:
sql("`").sql(literal.replace("`", "``")).sql("`");
break;
// SQLite is supposed to support all sorts of delimiters, but it
// seems too buggy
case SQLITE:
sql(literal);
break;
// T-SQL databases use brackets
case ASE:
case SQLSERVER:
case SYBASE:
sql("[").sql(literal.replace("]", "]]")).sql("]");
break;
// Most dialects implement the SQL standard, using double quotes
case CUBRID:
case DB2:
case DERBY:
@ -289,23 +313,8 @@ class DefaultRenderContext extends AbstractContext<RenderContext> implements Ren
case INGRES:
case ORACLE:
case POSTGRES:
sql('"').sql(literal.replace("\"", "\"\"")).sql('"');
break;
// SQLite is supposed to support all sorts of delimiters, but it
// seems too buggy
case SQLITE:
sql(literal);
break;
case ASE:
case SQLSERVER:
case SYBASE:
sql("[").sql(literal.replace("]", "]]")).sql("]");
break;
default:
sql(literal);
sql('"').sql(literal.replace("\"", "\"\"")).sql('"');
break;
}
}

View File

@ -2584,6 +2584,25 @@ public class BasicTest {
assertEquals("select ? from \"TABLE1\" where \"TABLE1\".\"ID1\" = ?", r_ref.render(q));
}
@Test
public void testRenderNameStyleWithSpecialCharacters() {
Query q = create.select(val(1).as("Aa \"Bb\" Cc")).from(TABLE1.as("Xx ''Yy''\\ Zz"));
RenderContext r_refI = r_refI();
r_refI.getSettings().setRenderNameStyle(RenderNameStyle.AS_IS);
assertEquals("select 1 \"Aa \"\"Bb\"\" Cc\" from TABLE1 \"Xx ''Yy''\\ Zz\"", r_refI.render(q));
r_refI.getSettings().setRenderNameStyle(RenderNameStyle.LOWER);
assertEquals("select 1 \"aa \"\"bb\"\" cc\" from table1 \"xx ''yy''\\ zz\"", r_refI.render(q));
r_refI.getSettings().setRenderNameStyle(RenderNameStyle.UPPER);
assertEquals("select 1 \"AA \"\"BB\"\" CC\" from TABLE1 \"XX ''YY''\\ ZZ\"", r_refI.render(q));
r_refI.getSettings().setRenderNameStyle(RenderNameStyle.QUOTED);
assertEquals("select 1 \"Aa \"\"Bb\"\" Cc\" from \"TABLE1\" \"Xx ''Yy''\\ Zz\"", r_refI.render(q));
}
@Test
public void testRenderKeywordStyle() {
Query q = create.select(val(1)).from(TABLE1).where(FIELD_ID1.equal(2));