mirror of
https://github.com/apache/sqoop.git
synced 2025-05-06 09:30:33 +08:00
SQOOP-1429: Fix native characters usage for SqlServer object names
(Venkat Ranganathan via Jarek Jarcec Cecho)
This commit is contained in:
parent
d2b3ab971e
commit
74ec89452b
@ -38,6 +38,7 @@
|
|||||||
import com.cloudera.sqoop.mapreduce.JdbcUpdateExportJob;
|
import com.cloudera.sqoop.mapreduce.JdbcUpdateExportJob;
|
||||||
import com.cloudera.sqoop.util.ExportException;
|
import com.cloudera.sqoop.util.ExportException;
|
||||||
import com.cloudera.sqoop.util.ImportException;
|
import com.cloudera.sqoop.util.ImportException;
|
||||||
|
|
||||||
import org.apache.sqoop.cli.RelatedOptions;
|
import org.apache.sqoop.cli.RelatedOptions;
|
||||||
import org.apache.sqoop.mapreduce.sqlserver.SqlServerExportBatchOutputFormat;
|
import org.apache.sqoop.mapreduce.sqlserver.SqlServerExportBatchOutputFormat;
|
||||||
import org.apache.sqoop.mapreduce.sqlserver.SqlServerInputFormat;
|
import org.apache.sqoop.mapreduce.sqlserver.SqlServerInputFormat;
|
||||||
@ -226,14 +227,30 @@ protected String getSchemaQuery() {
|
|||||||
|
|
||||||
return "'" + schema + "'";
|
return "'" + schema + "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getListColumnsQuery(String tableName) {
|
protected String getListColumnsQuery(String tableName) {
|
||||||
return
|
return
|
||||||
super.getListColumnsQuery(tableName)
|
"SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS "
|
||||||
|
+ "WHERE TABLE_SCHEMA = (" + getSchemaQuery() + ") "
|
||||||
|
+ " AND TABLE_NAME = N'" + tableName + "' "
|
||||||
+ " ORDER BY ORDINAL_POSITION";
|
+ " ORDER BY ORDINAL_POSITION";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getPrimaryKeyQuery(String tableName) {
|
||||||
|
return
|
||||||
|
"SELECT kcu.COLUMN_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc, "
|
||||||
|
+ " INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu "
|
||||||
|
+ "WHERE tc.TABLE_SCHEMA = kcu.TABLE_SCHEMA "
|
||||||
|
+ " AND tc.TABLE_NAME = kcu.TABLE_NAME "
|
||||||
|
+ " AND tc.CONSTRAINT_SCHEMA = kcu.CONSTRAINT_SCHEMA "
|
||||||
|
+ " AND tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME "
|
||||||
|
+ " AND tc.TABLE_SCHEMA = (" + getSchemaQuery() + ") "
|
||||||
|
+ " AND tc.TABLE_NAME = N'" + tableName + "' "
|
||||||
|
+ " AND tc.CONSTRAINT_TYPE = 'PRIMARY KEY'";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String escapeColName(String colName) {
|
public String escapeColName(String colName) {
|
||||||
return escapeObjectName(colName);
|
return escapeObjectName(colName);
|
||||||
|
@ -97,10 +97,12 @@ protected DBSplitter getSplitter(int sqlDataType) {
|
|||||||
case Types.DOUBLE:
|
case Types.DOUBLE:
|
||||||
return new FloatSplitter();
|
return new FloatSplitter();
|
||||||
|
|
||||||
case Types.CHAR:
|
|
||||||
case Types.NCHAR:
|
|
||||||
case Types.VARCHAR:
|
|
||||||
case Types.NVARCHAR:
|
case Types.NVARCHAR:
|
||||||
|
case Types.NCHAR:
|
||||||
|
return new NTextSplitter();
|
||||||
|
|
||||||
|
case Types.CHAR:
|
||||||
|
case Types.VARCHAR:
|
||||||
case Types.LONGVARCHAR:
|
case Types.LONGVARCHAR:
|
||||||
return new TextSplitter();
|
return new TextSplitter();
|
||||||
|
|
||||||
|
28
src/java/org/apache/sqoop/mapreduce/db/NTextSplitter.java
Normal file
28
src/java/org/apache/sqoop/mapreduce/db/NTextSplitter.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance
|
||||||
|
* with the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.sqoop.mapreduce.db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implement DBSplitter over native text strings.
|
||||||
|
*/
|
||||||
|
public class NTextSplitter extends TextSplitter {
|
||||||
|
|
||||||
|
public NTextSplitter() {
|
||||||
|
setUseNCharStrings(true);
|
||||||
|
}
|
||||||
|
}
|
@ -39,6 +39,8 @@ public class TextSplitter extends BigDecimalSplitter {
|
|||||||
|
|
||||||
private static final Log LOG = LogFactory.getLog(TextSplitter.class);
|
private static final Log LOG = LogFactory.getLog(TextSplitter.class);
|
||||||
|
|
||||||
|
private boolean useNCharStrings = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method needs to determine the splits between two user-provided
|
* This method needs to determine the splits between two user-provided
|
||||||
* strings. In the case where the user's strings are 'A' and 'Z', this is
|
* strings. In the case where the user's strings are 'A' and 'Z', this is
|
||||||
@ -90,8 +92,8 @@ public List<InputSplit> split(Configuration conf, ResultSet results,
|
|||||||
// divide cleanly.
|
// divide cleanly.
|
||||||
int numSplits = ConfigurationHelper.getConfNumMaps(conf);
|
int numSplits = ConfigurationHelper.getConfNumMaps(conf);
|
||||||
|
|
||||||
String lowClausePrefix = colName + " >= '";
|
String lowClausePrefix = colName + " >= " + (useNCharStrings ? "N'" : "'");
|
||||||
String highClausePrefix = colName + " < '";
|
String highClausePrefix = colName + " < " + (useNCharStrings ? "N'" : "'");
|
||||||
|
|
||||||
// If there is a common prefix between minString and maxString, establish
|
// If there is a common prefix between minString and maxString, establish
|
||||||
// it and pull it out of minString and maxString.
|
// it and pull it out of minString and maxString.
|
||||||
@ -123,7 +125,8 @@ public List<InputSplit> split(Configuration conf, ResultSet results,
|
|||||||
if (i == splitStrings.size() - 1) {
|
if (i == splitStrings.size() - 1) {
|
||||||
// This is the last one; use a closed interval.
|
// This is the last one; use a closed interval.
|
||||||
splits.add(new DataDrivenDBInputFormat.DataDrivenDBInputSplit(
|
splits.add(new DataDrivenDBInputFormat.DataDrivenDBInputSplit(
|
||||||
lowClausePrefix + start + "'", colName + " <= '" + end + "'"));
|
lowClausePrefix + start + "'", colName
|
||||||
|
+ " <= " + (useNCharStrings ? "N'" : "'") + end + "'"));
|
||||||
} else {
|
} else {
|
||||||
// Normal open-interval case.
|
// Normal open-interval case.
|
||||||
splits.add(new DataDrivenDBInputFormat.DataDrivenDBInputSplit(
|
splits.add(new DataDrivenDBInputFormat.DataDrivenDBInputSplit(
|
||||||
@ -225,4 +228,12 @@ public String bigDecimalToString(BigDecimal bd) {
|
|||||||
|
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setUseNCharStrings(boolean use) {
|
||||||
|
useNCharStrings = use;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isUseNCharStrings() {
|
||||||
|
return useNCharStrings;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -134,4 +134,13 @@ public void testCommonPrefix() throws SQLException {
|
|||||||
assertEquals("Hardy", splits.get(splits.size() -1));
|
assertEquals("Hardy", splits.get(splits.size() -1));
|
||||||
assertEquals(6, splits.size());
|
assertEquals(6, splits.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testNChar() throws SQLException {
|
||||||
|
// Splits between 'Hand' and 'Hardy'
|
||||||
|
NTextSplitter splitter = new NTextSplitter();
|
||||||
|
assertEquals(true, splitter.isUseNCharStrings());
|
||||||
|
TextSplitter splitter2 = new TextSplitter();
|
||||||
|
assertEquals(false, splitter2.isUseNCharStrings());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user