提交 2f403af6 authored 作者: Owner's avatar Owner

Created instance class for configuration preventing static Tomcat test case failures

上级 3a056e47
......@@ -1181,7 +1181,7 @@ Emulation settings can be appended to the database URL:
It is not recommended to use overly restrictive settings as system
columns can accidentally get their identifiers truncated leading to
undefined behavior.
undefined behavior. A minimum value of 30 is enforced.
","
-- Emulate popular database settings
SET COLUMN_NAME_RULES=EMULATE=ORACLE128 -- Emulate Oracle 128 character column identifiers
......@@ -1189,10 +1189,11 @@ SET COLUMN_NAME_RULES=EMULATE=ORACLE30; -- Emulate Oracle 30 character column id
SET COLUMN_NAME_RULES=EMULATE=POSTGRES; -- Emulate Postgres
SET COLUMN_NAME_RULES=DEFAULT; -- Reset back to default H2 allow-anything rules
-- Custom settings
SET COLUMN_NAME_RULES=MAX_IDENTIFIER_LENGTH = 10; -- Custom configure max identifier length
SET COLUMN_NAME_RULES=MAX_IDENTIFIER_LENGTH = 30; -- Custom configure max identifier length (minimum value is 30)
SET COLUMN_NAME_RULES=REGULAR_EXPRESSION_MATCH_ALLOWED = '[A-Za-z0-9_]+'; -- Custom configure Java RegEx for allowed characters
SET COLUMN_NAME_RULES=REGULAR_EXPRESSION_MATCH_DISALLOWED = '[^A-Za-z0-9_]+'; -- Custom configure Java RegEx for disallowed characters
SET COLUMN_NAME_RULES=DEFAULT_COLUMN_NAME_PATTERN = '_unnamed$$'; -- Custom configure default column name, $$ is replaced by column Nth ordinal
SET COLUMN_NAME_RULES=GENERATE_UNIQUE_COLUMN_NAMES = 1; -- Generate unique column names (default is 0, meaning false)
"
"Commands (Other)","SET CLUSTER","
......
......@@ -5269,12 +5269,13 @@ public class Parser {
// array of length 1 to receive extra 'output' field in addition to
// return value
querySQLOutput[0] = StringUtils.cache(theQuery.getPlanSQL());
ColumnNamer columnNamer = new ColumnNamer(theQuery.getSession());
ArrayList<Expression> withExpressions = theQuery.getExpressions();
for (int i = 0; i < withExpressions.size(); ++i) {
Expression columnExp = withExpressions.get(i);
// use the passed in column name if supplied, otherwise use alias (if found) otherwise use column name
// derived from column expression
String columnName = ColumnNamer.getColumnName(columnExp,i,cols).replace("\n", " ").replace("\r", " ");
String columnName = columnNamer.getColumnName(columnExp,i,cols);
columnTemplateList.add(new Column(columnName,
columnExp.getType()));
......
......@@ -231,10 +231,11 @@ public class CreateTable extends SchemaCommand {
private void generateColumnsFromQuery() {
int columnCount = asQuery.getColumnCount();
ArrayList<Expression> expressions = asQuery.getExpressions();
ColumnNamer columnNamer= new ColumnNamer(session);
for (int i = 0; i < columnCount; i++) {
Expression expr = expressions.get(i);
int type = expr.getType();
String name = ColumnNamer.getColumnName(expr,i,expr.getAlias());
String name = columnNamer.getColumnName(expr,i,expr.getAlias());
long precision = expr.getPrecision();
int displaySize = expr.getDisplaySize();
DataType dt = DataType.getDataType(type);
......
......@@ -840,10 +840,13 @@ public class Select extends Query {
sort = prepareOrder(orderList, expressions.size());
orderList = null;
}
ColumnNamer columnNamer= new ColumnNamer(session);
for (int i = 0; i < expressions.size(); i++) {
Expression e = expressions.get(i);
if(!ColumnNamer.isAllowableColumnName(e.getAlias())){
String columnName = ColumnNamer.getColumnName(e,i,e.getAlias());
String proposedColumnName = e.getAlias();
String columnName = columnNamer.getColumnName(e,i,proposedColumnName);
// if the name changed, create an alias
if(!columnName.equals(proposedColumnName)){
e = new Alias(e,columnName,true);
}
expressions.set(i, e.optimize(session));
......
......@@ -36,9 +36,10 @@ public class SelectListColumnResolver implements ColumnResolver {
columns = new Column[columnCount];
expressions = new Expression[columnCount];
ArrayList<Expression> columnList = select.getExpressions();
ColumnNamer columnNamer= new ColumnNamer(select.getSession());
for (int i = 0; i < columnCount; i++) {
Expression expr = columnList.get(i);
String columnName = ColumnNamer.getColumnName(expr, i, expr.getAlias());
String columnName = columnNamer.getColumnName(expr, i, expr.getAlias());
Column column = new Column(columnName, Value.NULL);
column.setTable(null, i);
columns[i] = column;
......
......@@ -330,6 +330,7 @@ public class SelectUnion extends Query {
expressions = New.arrayList();
ArrayList<Expression> le = left.getExpressions();
ArrayList<Expression> re = right.getExpressions();
ColumnNamer columnNamer= new ColumnNamer(session);
for (int i = 0; i < len; i++) {
Expression l = le.get(i);
Expression r = re.get(i);
......@@ -337,7 +338,7 @@ public class SelectUnion extends Query {
long prec = Math.max(l.getPrecision(), r.getPrecision());
int scale = Math.max(l.getScale(), r.getScale());
int displaySize = Math.max(l.getDisplaySize(), r.getDisplaySize());
String columnName = ColumnNamer.getColumnName(l,i,l.getAlias());
String columnName = columnNamer.getColumnName(l,i,l.getAlias());
Column col = new Column(columnName, type, prec, scale, displaySize);
Expression e = new ExpressionColumn(session.getDatabase(), col);
expressions.add(e);
......
......@@ -23,7 +23,7 @@ import org.h2.result.RowFactory;
import org.h2.schema.Schema;
import org.h2.table.Table;
import org.h2.tools.CompressTool;
import org.h2.util.ColumnNamer;
import org.h2.util.ColumnNamerConfiguration;
import org.h2.util.JdbcUtils;
import org.h2.util.StringUtils;
import org.h2.value.CompareMode;
......@@ -538,7 +538,10 @@ public class Set extends Prepared {
case SetTypes.COLUMN_NAME_RULES: {
session.getUser().checkAdmin();
ColumnNamer.configure(expression.getColumnName());
if(session.getColumnNamerConfiguration()==null){
session.setColumnNamerConfiguration(ColumnNamerConfiguration.getDefault());
}
session.getColumnNamerConfiguration().configure(expression.getColumnName());
break;
}
......
......@@ -42,6 +42,7 @@ import org.h2.table.SubQueryInfo;
import org.h2.table.Table;
import org.h2.table.TableFilter;
import org.h2.table.TableType;
import org.h2.util.ColumnNamerConfiguration;
import org.h2.util.New;
import org.h2.util.SmallLRUCache;
import org.h2.value.Value;
......@@ -126,6 +127,7 @@ public class Session extends SessionWithState {
private boolean joinBatchEnabled;
private boolean forceJoinOrder;
private boolean lazyQueryExecution;
private ColumnNamerConfiguration columnNamerConfiguration;
/**
* Tables marked for ANALYZE after the current transaction is committed.
* Prevents us calling ANALYZE repeatedly in large transactions.
......@@ -162,6 +164,7 @@ public class Session extends SessionWithState {
this.lockTimeout = setting == null ?
Constants.INITIAL_LOCK_TIMEOUT : setting.getIntValue();
this.currentSchemaName = Constants.SCHEMA_MAIN;
this.columnNamerConfiguration = ColumnNamerConfiguration.getDefault();
}
public void setLazyQueryExecution(boolean lazyQueryExecution) {
......@@ -1751,4 +1754,12 @@ public class Session extends SessionWithState {
}
}
public ColumnNamerConfiguration getColumnNamerConfiguration() {
return columnNamerConfiguration;
}
public void setColumnNamerConfiguration(ColumnNamerConfiguration columnNamerConfiguration) {
this.columnNamerConfiguration = columnNamerConfiguration;
}
}
......@@ -163,6 +163,7 @@ public class TableView extends Table {
tables = New.arrayList(query.getTables());
ArrayList<Expression> expressions = query.getExpressions();
ArrayList<Column> list = New.arrayList();
ColumnNamer columnNamer= new ColumnNamer(session);
for (int i = 0, count = query.getColumnCount(); i < count; i++) {
Expression expr = expressions.get(i);
String name = null;
......@@ -174,7 +175,7 @@ public class TableView extends Table {
if (name == null) {
name = expr.getAlias();
}
name = ColumnNamer.getColumnName(expr,i,name);
name = columnNamer.getColumnName(expr,i,name);
if (type == Value.UNKNOWN) {
type = expr.getType();
}
......
package org.h2.util;
import java.util.HashSet;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.h2.engine.Session;
import org.h2.expression.Expression;
import org.h2.message.DbException;
public class ColumnNamer {
private static final String DEFAULT_COLUMN_NAME = "DEFAULT";
private static final String DEFAULT_COMMAND = "DEFAULT";
private static final String REGULAR_EXPRESSION_MATCH_DISALLOWED = "REGULAR_EXPRESSION_MATCH_DISALLOWED = ";
private static final String REGULAR_EXPRESSION_MATCH_ALLOWED = "REGULAR_EXPRESSION_MATCH_ALLOWED = ";
private static final String DEFAULT_COLUMN_NAME_PATTERN = "DEFAULT_COLUMN_NAME_PATTERN = ";
private static final String MAX_IDENTIFIER_LENGTH = "MAX_IDENTIFIER_LENGTH = ";
private static final String EMULATE_COMMAND = "EMULATE = ";
private ColumnNamerConfiguration configuration;
private Session session;
private Set<String> existingColumnNames = new HashSet<String>();
public ColumnNamer(Session session) {
this.session = session;
if(this.session!=null && this.session.getColumnNamerConfiguration()!=null){
// use original from session
this.configuration = this.session.getColumnNamerConfiguration();
}
else{
// detached namer, create new
this.configuration = ColumnNamerConfiguration.getDefault();
if(session!=null){
session.setColumnNamerConfiguration(this.configuration);
}
}
}
/**
* Create a standardized column name that isn't null and doesn't have a CR/LF in it.
* @param columnExp the column expression
* @param indexOfColumn index of column in below array
* @return
*/
public static String getColumnName(Expression expr, int indexOfColumn) {
public String getColumnName(Expression expr, int indexOfColumn) {
return getColumnName(expr,indexOfColumn,(String) null);
}
/**
......@@ -31,7 +45,7 @@ public class ColumnNamer {
* @param columnNameOverides array of overriding column names
* @return the new column name
*/
public static String getColumnName(Expression columnExp, int indexOfColumn, String[] columnNameOverides){
public String getColumnName(Expression columnExp, int indexOfColumn, String[] columnNameOverides){
String columnNameOverride = null;
if (columnNameOverides != null && columnNameOverides.length > indexOfColumn){
columnNameOverride = columnNameOverides[indexOfColumn];
......@@ -46,7 +60,7 @@ public class ColumnNamer {
* @param columnNameOverride single overriding column name
* @return the new column name
*/
public static String getColumnName(Expression columnExp, int indexOfColumn, String columnNameOverride) {
public String getColumnName(Expression columnExp, int indexOfColumn, String columnNameOverride) {
// try a name from the column name override
String columnName = null;
if (columnNameOverride != null){
......@@ -90,106 +104,59 @@ public class ColumnNamer {
}
// go with a innocuous default name pattern
if (columnName==null){
columnName = defaultColumnNamePattern.replace("$$", ""+(indexOfColumn+1));
}
columnName = configuration.getDefaultColumnNamePattern().replace("$$", ""+(indexOfColumn+1));
}
if(existingColumnNames.contains(columnName) && configuration.isGenerateUniqueColumnNames()){
columnName = generateUniqueName(columnName);
}
existingColumnNames.add(columnName);
return columnName;
}
public static boolean isAllowableColumnName(String proposedName){
private String generateUniqueName(String columnName) {
String newColumnName = columnName;
int loopCount = 2;
while(existingColumnNames.contains(newColumnName)){
String loopCountString = "_"+loopCount;
newColumnName = columnName.substring(0,Math.min(columnName.length(), configuration.getMaxIdentiferLength()-loopCountString.length()))+loopCountString;
loopCount++;
}
return newColumnName;
}
public boolean isAllowableColumnName(String proposedName){
// check null
if (proposedName == null){
return false;
}
// check size limits
if (proposedName.length() > maxIdentiferLength || proposedName.length()==0){
if (proposedName.length() > configuration.getMaxIdentiferLength() || proposedName.length()==0){
return false;
}
Matcher match = compiledRegularExpressionMatchAllowed.matcher(proposedName);
Matcher match = configuration.getCompiledRegularExpressionMatchAllowed().matcher(proposedName);
if(!match.matches()){
return false;
}
return true;
}
private static String fixColumnName(String proposedName) {
Matcher match = compiledRegularExpressionMatchDisallowed.matcher(proposedName);
private String fixColumnName(String proposedName) {
Matcher match = configuration.getCompiledRegularExpressionMatchDisallowed().matcher(proposedName);
proposedName = match.replaceAll("");
// check size limits - then truncate
if (proposedName.length() > maxIdentiferLength){
proposedName=proposedName.substring(0, maxIdentiferLength);
if (proposedName.length() > configuration.getMaxIdentiferLength()){
proposedName=proposedName.substring(0, configuration.getMaxIdentiferLength());
}
return proposedName;
}
private static String unquoteString(String s){
if(s.startsWith("'") && s.endsWith("'")){
s = s.substring(1, s.length()-1);
return s;
}
return s;
public ColumnNamerConfiguration getConfiguration() {
return configuration;
}
static int maxIdentiferLength = Integer.MAX_VALUE;
static String regularExpressionMatchAllowed = "(?m)(?s).+";
static String regularExpressionMatchDisallowed = "(?m)(?s)[\\x00]";
static String defaultColumnNamePattern = "_unnamed_column_$$_";
static Pattern compiledRegularExpressionMatchAllowed = Pattern.compile(regularExpressionMatchAllowed);
static Pattern compiledRegularExpressionMatchDisallowed = Pattern.compile(regularExpressionMatchDisallowed);
public static void configure(String stringValue) {
try{
if(stringValue.equalsIgnoreCase(DEFAULT_COMMAND)){
maxIdentiferLength = Integer.MAX_VALUE;
regularExpressionMatchAllowed = "(?m)(?s).+";
regularExpressionMatchDisallowed = "(?m)(?s)[\\x00]";
defaultColumnNamePattern = "_UNNAMED_$$";
} else if(stringValue.equalsIgnoreCase(EMULATE_COMMAND+"ORACLE128")){
maxIdentiferLength = 128;
regularExpressionMatchAllowed = "(?m)(?s)\"?[A-Za-z0-9_]+\"?";
regularExpressionMatchDisallowed = "(?m)(?s)[^A-Za-z0-9_\"]";
defaultColumnNamePattern = "_UNNAMED_$$";
} else if(stringValue.equalsIgnoreCase(EMULATE_COMMAND+"ORACLE30")){
maxIdentiferLength = 30;
regularExpressionMatchAllowed = "(?m)(?s)\"?[A-Za-z0-9_]+\"?";
regularExpressionMatchDisallowed = "(?m)(?s)[^A-Za-z0-9_\"]";
defaultColumnNamePattern = "_UNNAMED_$$";
}else if(stringValue.equalsIgnoreCase(EMULATE_COMMAND+"POSTGRES")){
maxIdentiferLength = 31;
regularExpressionMatchAllowed = "(?m)(?s)\"?[A-Za-z0-9_\"]+\"?";
regularExpressionMatchDisallowed = "(?m)(?s)[^A-Za-z0-9_\"]";
defaultColumnNamePattern = "_UNNAMED_$$";
} else if(stringValue.startsWith(MAX_IDENTIFIER_LENGTH)){
maxIdentiferLength = Math.max(0,Integer.parseInt(stringValue.substring(MAX_IDENTIFIER_LENGTH.length())));
} else if(stringValue.startsWith(DEFAULT_COLUMN_NAME_PATTERN)){
defaultColumnNamePattern =unquoteString(stringValue.substring(DEFAULT_COLUMN_NAME_PATTERN.length()));
} else if(stringValue.startsWith(REGULAR_EXPRESSION_MATCH_ALLOWED)){
regularExpressionMatchAllowed=unquoteString(stringValue.substring(REGULAR_EXPRESSION_MATCH_ALLOWED.length()));
} else if(stringValue.startsWith(REGULAR_EXPRESSION_MATCH_DISALLOWED)){
regularExpressionMatchDisallowed =unquoteString(stringValue.substring(REGULAR_EXPRESSION_MATCH_DISALLOWED.length()));
}
else
{
throw DbException.getInvalidValueException("SET COLUMN_NAME_RULES: unknown id:"+stringValue,
stringValue);
}
// recompile RE patterns
compiledRegularExpressionMatchAllowed = Pattern.compile(regularExpressionMatchAllowed);
compiledRegularExpressionMatchDisallowed = Pattern.compile(regularExpressionMatchDisallowed);
}
//Including NumberFormatException|PatternSyntaxException
catch(RuntimeException e){
throw DbException.getInvalidValueException("SET COLUMN_NAME_RULES:"+e.getMessage(),
stringValue);
}
}
}
package org.h2.util;
import java.util.regex.Pattern;
import org.h2.message.DbException;
public class ColumnNamerConfiguration {
private static final String DEFAULT_COMMAND = "DEFAULT";
private static final String REGULAR_EXPRESSION_MATCH_DISALLOWED = "REGULAR_EXPRESSION_MATCH_DISALLOWED = ";
private static final String REGULAR_EXPRESSION_MATCH_ALLOWED = "REGULAR_EXPRESSION_MATCH_ALLOWED = ";
private static final String DEFAULT_COLUMN_NAME_PATTERN = "DEFAULT_COLUMN_NAME_PATTERN = ";
private static final String MAX_IDENTIFIER_LENGTH = "MAX_IDENTIFIER_LENGTH = ";
private static final String EMULATE_COMMAND = "EMULATE = ";
private static final String GENERATE_UNIQUE_COLUMN_NAMES = "GENERATE_UNIQUE_COLUMN_NAMES = ";
private int maxIdentiferLength;
private String regularExpressionMatchAllowed;
private String regularExpressionMatchDisallowed;
private String defaultColumnNamePattern;
private boolean generateUniqueColumnNames;
private Pattern compiledRegularExpressionMatchAllowed;
private Pattern compiledRegularExpressionMatchDisallowed;
public ColumnNamerConfiguration(int maxIdentiferLength, String regularExpressionMatchAllowed,
String regularExpressionMatchDisallowed, String defaultColumnNamePattern, boolean generateUniqueColumnNames) {
this.maxIdentiferLength = maxIdentiferLength;
this.regularExpressionMatchAllowed = regularExpressionMatchAllowed;
this.regularExpressionMatchDisallowed = regularExpressionMatchDisallowed;
this.defaultColumnNamePattern = defaultColumnNamePattern;
this.generateUniqueColumnNames = generateUniqueColumnNames;
compiledRegularExpressionMatchAllowed = Pattern.compile(regularExpressionMatchAllowed);
compiledRegularExpressionMatchDisallowed = Pattern.compile(regularExpressionMatchDisallowed);
}
public int getMaxIdentiferLength() {
return maxIdentiferLength;
}
public void setMaxIdentiferLength(int maxIdentiferLength) {
this.maxIdentiferLength = maxIdentiferLength;
}
public String getRegularExpressionMatchAllowed() {
return regularExpressionMatchAllowed;
}
public void setRegularExpressionMatchAllowed(String regularExpressionMatchAllowed) {
this.regularExpressionMatchAllowed = regularExpressionMatchAllowed;
}
public String getRegularExpressionMatchDisallowed() {
return regularExpressionMatchDisallowed;
}
public void setRegularExpressionMatchDisallowed(String regularExpressionMatchDisallowed) {
this.regularExpressionMatchDisallowed = regularExpressionMatchDisallowed;
}
public String getDefaultColumnNamePattern() {
return defaultColumnNamePattern;
}
public void setDefaultColumnNamePattern(String defaultColumnNamePattern) {
this.defaultColumnNamePattern = defaultColumnNamePattern;
}
public Pattern getCompiledRegularExpressionMatchAllowed() {
return compiledRegularExpressionMatchAllowed;
}
public void setCompiledRegularExpressionMatchAllowed(Pattern compiledRegularExpressionMatchAllowed) {
this.compiledRegularExpressionMatchAllowed = compiledRegularExpressionMatchAllowed;
}
public Pattern getCompiledRegularExpressionMatchDisallowed() {
return compiledRegularExpressionMatchDisallowed;
}
public void setCompiledRegularExpressionMatchDisallowed(Pattern compiledRegularExpressionMatchDisallowed) {
this.compiledRegularExpressionMatchDisallowed = compiledRegularExpressionMatchDisallowed;
}
public void configure(String stringValue) {
try{
if(stringValue.equalsIgnoreCase(DEFAULT_COMMAND)){
setMaxIdentiferLength(Integer.MAX_VALUE);
setRegularExpressionMatchAllowed("(?m)(?s).+");
setRegularExpressionMatchDisallowed("(?m)(?s)[\\x00]");
setDefaultColumnNamePattern("_UNNAMED_$$");
} else if(stringValue.equalsIgnoreCase(EMULATE_COMMAND+"ORACLE128")){
setMaxIdentiferLength(128);
setRegularExpressionMatchAllowed("(?m)(?s)\"?[A-Za-z0-9_]+\"?");
setRegularExpressionMatchDisallowed("(?m)(?s)[^A-Za-z0-9_\"]");
setDefaultColumnNamePattern("_UNNAMED_$$");
} else if(stringValue.equalsIgnoreCase(EMULATE_COMMAND+"ORACLE30")){
setMaxIdentiferLength(30);
setRegularExpressionMatchAllowed("(?m)(?s)\"?[A-Za-z0-9_]+\"?");
setRegularExpressionMatchDisallowed("(?m)(?s)[^A-Za-z0-9_\"]");
setDefaultColumnNamePattern("_UNNAMED_$$");
}else if(stringValue.equalsIgnoreCase(EMULATE_COMMAND+"POSTGRES")){
setMaxIdentiferLength(31);
setRegularExpressionMatchAllowed("(?m)(?s)\"?[A-Za-z0-9_\"]+\"?");
setRegularExpressionMatchDisallowed("(?m)(?s)[^A-Za-z0-9_\"]");
setDefaultColumnNamePattern("_UNNAMED_$$");
} else if(stringValue.startsWith(MAX_IDENTIFIER_LENGTH)){
int maxLength = Integer.parseInt(stringValue.substring(MAX_IDENTIFIER_LENGTH.length()));
setMaxIdentiferLength(Math.max(30,maxLength));
if(maxLength!=getMaxIdentiferLength()){
throw DbException.getInvalidValueException("Illegal value (<30) in SET COLUMN_NAME_RULES="+stringValue,stringValue);
}
} else if(stringValue.startsWith(GENERATE_UNIQUE_COLUMN_NAMES)){
setGenerateUniqueColumnNames(Integer.parseInt(stringValue.substring(GENERATE_UNIQUE_COLUMN_NAMES.length()))==1);
} else if(stringValue.startsWith(DEFAULT_COLUMN_NAME_PATTERN)){
setDefaultColumnNamePattern(unquoteString(stringValue.substring(DEFAULT_COLUMN_NAME_PATTERN.length())));
} else if(stringValue.startsWith(REGULAR_EXPRESSION_MATCH_ALLOWED)){
setRegularExpressionMatchAllowed(unquoteString(stringValue.substring(REGULAR_EXPRESSION_MATCH_ALLOWED.length())));
} else if(stringValue.startsWith(REGULAR_EXPRESSION_MATCH_DISALLOWED)){
setRegularExpressionMatchDisallowed(unquoteString(stringValue.substring(REGULAR_EXPRESSION_MATCH_DISALLOWED.length())));
}
else
{
throw DbException.getInvalidValueException("SET COLUMN_NAME_RULES: unknown id:"+stringValue,
stringValue);
}
// recompile RE patterns
setCompiledRegularExpressionMatchAllowed(Pattern.compile(getRegularExpressionMatchAllowed()));
setCompiledRegularExpressionMatchDisallowed(Pattern.compile(getRegularExpressionMatchDisallowed()));
}
//Including NumberFormatException|PatternSyntaxException
catch(RuntimeException e){
throw DbException.getInvalidValueException("SET COLUMN_NAME_RULES:"+e.getMessage(),
stringValue);
}
}
public static ColumnNamerConfiguration getDefault(){
return new ColumnNamerConfiguration(Integer.MAX_VALUE, "(?m)(?s).+", "(?m)(?s)[\\x00]", "_unnamed_column_$$_",false);
}
private static String unquoteString(String s){
if(s.startsWith("'") && s.endsWith("'")){
s = s.substring(1, s.length()-1);
return s;
}
return s;
}
public boolean isGenerateUniqueColumnNames() {
return generateUniqueColumnNames;
}
public void setGenerateUniqueColumnNames(boolean generateUniqueColumnNames) {
this.generateUniqueColumnNames = generateUniqueColumnNames;
}
}
\ No newline at end of file
......@@ -230,6 +230,7 @@ import org.h2.test.utils.SelfDestructor;
import org.h2.tools.DeleteDbFiles;
import org.h2.tools.Server;
import org.h2.util.AbbaLockingDetector;
import org.h2.util.TestColumnNamer;
import org.h2.util.New;
import org.h2.util.Profiler;
import org.h2.util.StringUtils;
......@@ -782,6 +783,8 @@ kill -9 `jps -l | grep "org.h2.test." | cut -d " " -f 1`
addTest(new TestViewDropView());
addTest(new TestReplace());
addTest(new TestSynonymForTable());
addTest(new TestColumnNamer());
// jaqu
addTest(new AliasMapTest());
......
......@@ -4,7 +4,7 @@
--
-- Try a custom column naming rules setup
SET COLUMN_NAME_RULES=MAX_IDENTIFIER_LENGTH = 10;
SET COLUMN_NAME_RULES=MAX_IDENTIFIER_LENGTH = 30;
> ok
SET COLUMN_NAME_RULES=REGULAR_EXPRESSION_MATCH_ALLOWED = '[A-Za-z0-9_]+';
......@@ -16,11 +16,14 @@ SET COLUMN_NAME_RULES=REGULAR_EXPRESSION_MATCH_DISALLOWED = '[^A-Za-z0-9_]+';
SET COLUMN_NAME_RULES=DEFAULT_COLUMN_NAME_PATTERN = 'noName$$';
> ok
SELECT 1 AS VERY_VERY_VERY_LONG_ID, SUM(X)+1 AS _123456789012345, SUM(X)+1 , SUM(X)+1
SET COLUMN_NAME_RULES=GENERATE_UNIQUE_COLUMN_NAMES = 1;
> ok
SELECT 1 AS VERY_VERY_VERY_LONG_ID_VERY_VERY_VERY_LONG_ID, SUM(X)+1 AS _123456789012345, SUM(X)+1 , SUM(X)+1
+47, 'x' , '!!!' , '!!!!' FROM SYSTEM_RANGE(1,2);
> VERY_VERY_ _123456789 SUMX1 SUMX147 x noName6 noName7
> ---------- ---------- ----- ------- - ------- -------
> 1 4 4 51 x !!! !!!!
> VERY_VERY_VERY_LONG_ID_VERY_VE _123456789012345 SUMX1 SUMX147 x noName6 noName7
> ------------------------------ ---------------- ----- ------- - ------- -------
> 1 4 4 51 x !!! !!!!
SET COLUMN_NAME_RULES=EMULATE=ORACLE128;
> ok
......
package org.h2.util;
import org.h2.expression.Expression;
import org.h2.expression.ValueExpression;
import org.h2.test.TestBase;
public class TestColumnNamer extends TestBase {
private String[] ids = new String[]{
"ABC"
,"123"
,"a\n2"
,"a$c%d#e@f!."
,null
,"VERYVERYVERYVERYVERYVERYLONGVERYVERYVERYVERYVERYVERYLONGVERYVERYVERYVERYVERYVERYLONG"
,"'!!!'"
,"'!!!!'"
,"3.1415"
,"\r"
,"col1"
,"col1"
,"col1"
,"col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2"
,"col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2col2"
};
private String[] expectedColumnName= {"ABC"
,"123"
,"a2"
,"acdef"
,"colName6"
,"VERYVERYVERYVERYVERYVERYLONGVE"
,"colName8"
,"colName9"
,"31415"
,"colName11"
,"col1"
,"col1_2"
,"col1_3"
,"col2col2col2col2col2col2col2co"
,"col2col2col2col2col2col2col2_2"};
public static void main(String[] args){
new TestColumnNamer().test();
}
public void test() {
ColumnNamer columnNamer = new ColumnNamer(null);
columnNamer.getConfiguration().configure("MAX_IDENTIFIER_LENGTH = 30");
columnNamer.getConfiguration().configure("REGULAR_EXPRESSION_MATCH_ALLOWED = '[A-Za-z0-9_]+'");
columnNamer.getConfiguration().configure("REGULAR_EXPRESSION_MATCH_DISALLOWED = '[^A-Za-z0-9_]+'");
columnNamer.getConfiguration().configure("DEFAULT_COLUMN_NAME_PATTERN = 'colName$$'");
columnNamer.getConfiguration().configure("GENERATE_UNIQUE_COLUMN_NAMES = 1");
int index =0;
for(String id : ids){
Expression columnExp = ValueExpression.getDefault();
String newColumnName = columnNamer.getColumnName(columnExp , index+1, id);
assertTrue(newColumnName!=null);
assertTrue(newColumnName.length()<=30);
assertTrue(newColumnName.length()>=1);
assertEquals(newColumnName,expectedColumnName[index]);
index++;
}
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论