Skip to content

Commit 543353d

Browse files
committed
[fix][core] Support operations on tables without primary keys
1 parent ed93d20 commit 543353d

File tree

2 files changed

+52
-11
lines changed

2 files changed

+52
-11
lines changed

core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@
8888
import org.apache.calcite.sql.TableCharacteristic;
8989
import org.apache.calcite.sql.fun.SqlCase;
9090
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
91-
import org.apache.calcite.sql.fun.SqlSumAggFunction;
9291
import org.apache.calcite.sql.parser.SqlParserPos;
9392
import org.apache.calcite.sql.type.*;
9493
import org.apache.calcite.sql.util.IdPair;
@@ -167,6 +166,7 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
167166
* Alias prefix generated for source columns when rewriting UPDATE to MERGE.
168167
*/
169168
public static final String UPDATE_ANON_PREFIX = "SYS$ANON";
169+
public static final String IMPLICIT_COL_NAME = "_ROWID";
170170

171171
//~ Instance fields --------------------------------------------------------
172172

@@ -4895,7 +4895,7 @@ protected RelDataType createTargetRowType(
48954895
? logicalTargetRowType
48964896
: realTargetRowType;
48974897

4898-
checkFieldCount(insert.getTargetTable(), table, strategies,
4898+
checkFieldCount(insert.getTargetColumnList(), insert.getTargetTable(), table, strategies,
48994899
targetRowTypeToValidate, realTargetRowType,
49004900
source, logicalSourceRowType, logicalTargetRowType);
49014901

@@ -5027,21 +5027,23 @@ private void checkConstraint(
50275027
* make a subset of fields(start from the left first field) whose
50285028
* length is equals with the source row type fields number
50295029
*/
5030-
private void checkFieldCount(SqlNode node, SqlValidatorTable table,
5030+
private void checkFieldCount(SqlNodeList targetColumnList, SqlNode node, SqlValidatorTable table,
50315031
List<ColumnStrategy> strategies, RelDataType targetRowTypeToValidate,
50325032
RelDataType realTargetRowType, SqlNode source,
50335033
RelDataType logicalSourceRowType, RelDataType logicalTargetRowType) {
5034-
final int sourceFieldCount = logicalSourceRowType.getFieldCount();
5035-
final int targetFieldCount = logicalTargetRowType.getFieldCount();
5036-
final int targetRealFieldCount = realTargetRowType.getFieldCount();
5037-
if (sourceFieldCount != targetFieldCount
5038-
&& sourceFieldCount != targetRealFieldCount) {
5034+
//final int sourceFieldCount = logicalSourceRowType.getFieldCount();
5035+
//final int targetFieldCount = logicalTargetRowType.getFieldCount();
5036+
//final int targetRealFieldCount = realTargetRowType.getFieldCount();
5037+
//if (sourceFieldCount != targetFieldCount
5038+
// && sourceFieldCount != targetRealFieldCount) {
50395039
// Allows the source row fields count to be equal with either
50405040
// the logical or the real(excludes columns that can not insert into)
50415041
// target row fields count.
5042-
throw newValidationError(node,
5043-
RESOURCE.unmatchInsertColumn(targetFieldCount, sourceFieldCount));
5044-
}
5042+
//throw newValidationError(node,
5043+
// RESOURCE.unmatchInsertColumn(targetFieldCount, sourceFieldCount));
5044+
// return;
5045+
//}
5046+
checkFieldCount(targetColumnList, node, logicalSourceRowType, logicalTargetRowType);
50455047
// Ensure that non-nullable fields are targeted.
50465048
for (final RelDataTypeField field : table.getRowType().getFieldList()) {
50475049
final RelDataTypeField targetField =
@@ -5071,6 +5073,41 @@ private void checkFieldCount(SqlNode node, SqlValidatorTable table,
50715073
}
50725074
}
50735075

5076+
protected void checkFieldCount(SqlNodeList targetColumnList, SqlNode node, RelDataType logicalSourceRowType,
5077+
RelDataType logicalTargetRowType) {
5078+
final int sourceFieldCount = logicalSourceRowType.getFieldCount();
5079+
final int targetFieldCount = logicalTargetRowType.getFieldCount();
5080+
int implicitNum = 0;
5081+
int sourceImplicitNum = 0;
5082+
5083+
if (targetColumnList != null) {
5084+
for (SqlNode identifier : targetColumnList.getList()) {
5085+
if (identifier instanceof SqlIdentifier && isImplicitKey(((SqlIdentifier) identifier).getLastName())) {
5086+
sourceImplicitNum++;
5087+
}
5088+
}
5089+
} else {
5090+
// if there is no target column in insert sql,then use default row type
5091+
for (String fieldName : logicalSourceRowType.getFieldNames()) {
5092+
if (isImplicitKey(fieldName)) {
5093+
sourceImplicitNum++;
5094+
}
5095+
}
5096+
}
5097+
for (String fieldName : logicalTargetRowType.getFieldNames()) {
5098+
if (isImplicitKey(fieldName)) {
5099+
implicitNum++;
5100+
}
5101+
}
5102+
if ((sourceFieldCount - sourceImplicitNum) != (targetFieldCount - implicitNum)) {
5103+
throw newValidationError(node, RESOURCE.unmatchInsertColumn(targetFieldCount, sourceFieldCount));
5104+
}
5105+
}
5106+
5107+
public static boolean isImplicitKey(String fieldName) {
5108+
return IMPLICIT_COL_NAME.equals(fieldName);
5109+
}
5110+
50745111
/** Returns whether a query uses {@code DEFAULT} to populate a given
50755112
* column. */
50765113
private static boolean isValuesWithDefault(SqlNode source, int column) {

core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@
114114
import static org.apache.calcite.sql.SqlUtil.stripAs;
115115

116116
import static java.util.Objects.requireNonNull;
117+
import static org.apache.calcite.sql.validate.SqlValidatorImpl.isImplicitKey;
117118

118119
/**
119120
* Converts a SQL parse tree (consisting of
@@ -4075,6 +4076,9 @@ private Blackboard createInsertBlackboard(RelOptTable targetTable,
40754076
final List<ColumnStrategy> strategies = targetTable.getColumnStrategies();
40764077
final List<String> targetFields = targetTable.getRowType().getFieldNames();
40774078
for (String targetColumnName : targetColumnNames) {
4079+
if (isImplicitKey(targetColumnName)) {
4080+
continue;
4081+
}
40784082
final int i = targetFields.indexOf(targetColumnName);
40794083
switch (strategies.get(i)) {
40804084
case STORED:

0 commit comments

Comments
 (0)