Skip to content

Commit a093225

Browse files
committed
Address comments
Signed-off-by: Tomoyuki Morita <moritato@amazon.com>
1 parent ce40b23 commit a093225

File tree

3 files changed

+47
-55
lines changed

3 files changed

+47
-55
lines changed

core/src/main/java/org/opensearch/sql/ast/expression/QualifiedName.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
@Getter
2323
@EqualsAndHashCode(callSuper = false)
2424
public class QualifiedName extends UnresolvedExpression {
25+
public static final String DELIMITER = ".";
2526
private final List<String> parts;
2627

2728
public QualifiedName(String name) {
@@ -94,7 +95,7 @@ public QualifiedName rest() {
9495
}
9596

9697
public String toString() {
97-
return String.join(".", this.parts);
98+
return String.join(DELIMITER, this.parts);
9899
}
99100

100101
@Override
@@ -106,4 +107,20 @@ public List<UnresolvedExpression> getChild() {
106107
public <R, C> R accept(AbstractNodeVisitor<R, C> nodeVisitor, C context) {
107108
return nodeVisitor.visitQualifiedName(this, context);
108109
}
110+
111+
public String sub(int fromIndex, int toIndex) {
112+
return String.join(DELIMITER, parts.subList(fromIndex, toIndex));
113+
}
114+
115+
public String sub(int fromIndex) {
116+
return String.join(DELIMITER, parts.subList(fromIndex, parts.size()));
117+
}
118+
119+
public String getPart(int at) {
120+
return parts.get(at);
121+
}
122+
123+
public int getPartsCount() {
124+
return parts.size();
125+
}
109126
}

core/src/main/java/org/opensearch/sql/calcite/ExtendedRexBuilder.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,10 @@ public RexNode castToTargetType(RexNode node, RexNode target) {
197197
return makeCast(target.getType(), node, true, true);
198198
}
199199

200-
/** Utility to cast ANY to specific types to avoid compare issue */
200+
/**
201+
* Utility to cast ANY to specific types to avoid compare issue in Calcite:
202+
* https://issues.apache.org/jira/browse/CALCITE-7206
203+
*/
201204
RexNode castAnyToAlignTypes(RexNode rexNode, CalcitePlanContext context) {
202205
return rexNode.accept(
203206
new RexConverter() {

core/src/main/java/org/opensearch/sql/calcite/rel/QualifiedNameResolver.java

Lines changed: 25 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -109,43 +109,24 @@ private static RexNode resolveInNonJoinCondition(
109109
.orElseThrow(() -> getNotFoundException(nameNode));
110110
}
111111

112-
private static String joinParts(List<String> parts, int start, int length) {
113-
StringBuilder sb = new StringBuilder();
114-
for (int i = 0; i < length; i++) {
115-
if (start < i) {
116-
sb.append(".");
117-
}
118-
sb.append(parts.get(start + i));
119-
}
120-
return sb.toString();
121-
}
122-
123-
private static String joinParts(List<String> parts, int start) {
124-
return joinParts(parts, start, parts.size() - start);
125-
}
126-
127112
private static Optional<RexNode> resolveFieldWithAlias(
128113
QualifiedName nameNode, CalcitePlanContext context, int inputCount) {
129-
List<String> parts = nameNode.getParts();
130114
log.debug(
131-
"resolveFieldWithAlias() called with nameNode={}, parts={}, inputCount={}",
132-
nameNode,
133-
parts,
134-
inputCount);
115+
"resolveFieldWithAlias() called with nameNode={}, inputCount={}", nameNode, inputCount);
135116

136-
if (parts.size() >= 2) {
117+
if (nameNode.getPartsCount() >= 2) {
137118
// Consider first part as table alias
138-
String alias = parts.get(0);
119+
String alias = nameNode.getPart(0);
139120
log.debug("resolveFieldWithAlias() trying alias={}", alias);
140121

141122
// Try to resolve the longest match first
142-
for (int length = parts.size() - 1; 1 <= length; length--) {
143-
String field = joinParts(parts, 1, length);
123+
for (int length = nameNode.getPartsCount() - 1; 1 <= length; length--) {
124+
String field = nameNode.sub(1, length);
144125
log.debug("resolveFieldWithAlias() trying field={} with length={}", field, length);
145126

146127
Optional<RexNode> fieldNode = tryToResolveField(alias, field, context, inputCount);
147128
if (fieldNode.isPresent()) {
148-
return Optional.of(resolveFieldAccess(context, parts, 1, length, fieldNode.get()));
129+
return Optional.of(resolveFieldAccess(context, nameNode, 1, length, fieldNode.get()));
149130
}
150131
}
151132
}
@@ -154,18 +135,16 @@ private static Optional<RexNode> resolveFieldWithAlias(
154135

155136
private static Optional<RexNode> resolveDynamicFieldsWithAlias(
156137
QualifiedName nameNode, CalcitePlanContext context, int inputCount) {
157-
List<String> parts = nameNode.getParts();
158138
log.debug(
159-
"resolveDynamicFieldsWithAlias() called with nameNode={}, parts={}, inputCount={}",
139+
"resolveDynamicFieldsWithAlias() called with nameNode={}, inputCount={}",
160140
nameNode,
161-
parts,
162141
inputCount);
163142

164-
if (parts.size() >= 2) {
143+
if (nameNode.getPartsCount() >= 2) {
165144
// Consider first part as table alias
166-
String alias = parts.get(0);
145+
String alias = nameNode.getPart(0);
167146

168-
String fieldName = String.join(".", parts.subList(1, parts.size()));
147+
String fieldName = nameNode.sub(1);
169148
Optional<RexNode> dynamicField =
170149
tryToResolveField(alias, DYNAMIC_FIELDS_MAP, context, inputCount);
171150
return dynamicField.map(field -> createItemAccess(field, fieldName, context));
@@ -176,18 +155,14 @@ private static Optional<RexNode> resolveDynamicFieldsWithAlias(
176155

177156
private static Optional<RexNode> resolveDynamicFields(
178157
QualifiedName nameNode, CalcitePlanContext context, int inputCount) {
179-
List<String> parts = nameNode.getParts();
180158
log.debug(
181-
"resolveDynamicFields() called with nameNode={}, parts={}, inputCount={}",
182-
nameNode,
183-
parts,
184-
inputCount);
159+
"resolveDynamicFields() called with nameNode={}, inputCount={}", nameNode, inputCount);
185160

186161
List<Set<String>> inputFieldNames = collectInputFieldNames(context, inputCount);
187162

188163
for (int i = 0; i < inputCount; i++) {
189164
if (inputFieldNames.get(i).contains(DYNAMIC_FIELDS_MAP)) {
190-
String fieldName = String.join(".", parts);
165+
String fieldName = nameNode.toString();
191166
RexNode dynamicField = context.relBuilder.field_(inputCount, i, DYNAMIC_FIELDS_MAP);
192167
RexNode itemAccess = createItemAccess(dynamicField, fieldName, context);
193168
return Optional.of(itemAccess);
@@ -218,16 +193,15 @@ private static Optional<RexNode> resolveFieldWithoutAlias(
218193

219194
List<Set<String>> inputFieldNames = collectInputFieldNames(context, inputCount);
220195

221-
List<String> parts = nameNode.getParts();
222-
for (int length = parts.size(); 1 <= length; length--) {
223-
String fieldName = joinParts(parts, 0, length);
196+
for (int length = nameNode.getPartsCount(); 1 <= length; length--) {
197+
String fieldName = nameNode.sub(0, length);
224198
log.debug("resolveFieldWithoutAlias() trying fieldName={} with length={}", fieldName, length);
225199

226200
int foundInput = findInputContainingFieldName(inputCount, inputFieldNames, fieldName);
227201
log.debug("resolveFieldWithoutAlias() foundInput={}", foundInput);
228202
if (foundInput != -1) {
229203
RexNode fieldNode = context.relBuilder.field_(inputCount, foundInput, fieldName);
230-
return Optional.of(resolveFieldAccess(context, parts, 0, length, fieldNode));
204+
return Optional.of(resolveFieldAccess(context, nameNode, 0, length, fieldNode));
231205
}
232206
}
233207
return Optional.empty();
@@ -268,10 +242,9 @@ private static Optional<RexNode> resolveRenamedField(
268242
QualifiedName nameNode, CalcitePlanContext context) {
269243
log.debug("resolveRenamedField() called with nameNode={}", nameNode);
270244

271-
List<String> parts = nameNode.getParts();
272-
if (parts.size() >= 2) {
245+
if (nameNode.getPartsCount() >= 2) {
273246
List<String> candidates = findCandidatesByRenamedFieldName(nameNode, context);
274-
String alias = parts.get(0);
247+
String alias = nameNode.getPart(0);
275248
for (String candidate : candidates) {
276249
try {
277250
return Optional.of(context.relBuilder.field_(alias, candidate));
@@ -289,20 +262,19 @@ private static Optional<RexNode> resolveRenamedField(
289262
*/
290263
private static List<String> findCandidatesByRenamedFieldName(
291264
QualifiedName renamedFieldName, CalcitePlanContext context) {
292-
String originalFieldName = joinParts(renamedFieldName.getParts(), 1);
265+
String originalFieldName = renamedFieldName.sub(1);
293266
return context.relBuilder.peek().getRowType().getFieldNames().stream()
294267
.filter(col -> getNameBeforeRename(col).equals(originalFieldName))
295268
.toList();
296269
}
297270

298271
private static String getNameBeforeRename(String fieldName) {
299-
return fieldName.substring(fieldName.indexOf(".") + 1);
272+
return fieldName.substring(fieldName.indexOf(QualifiedName.DELIMITER) + 1);
300273
}
301274

302275
private static Optional<RexNode> resolveCorrelationField(
303276
QualifiedName nameNode, CalcitePlanContext context) {
304277
log.debug("resolveCorrelationField() called with nameNode={}", nameNode);
305-
List<String> parts = nameNode.getParts();
306278
return context
307279
.peekCorrelVar()
308280
.map(
@@ -311,12 +283,12 @@ private static Optional<RexNode> resolveCorrelationField(
311283
// Try full match, then consider first part as table alias
312284
for (int start = 0; start <= 1; start++) {
313285
// Try to resolve the longest match first
314-
for (int length = parts.size() - start; 1 <= length; length--) {
315-
String fieldName = joinParts(parts, start, length);
286+
for (int length = nameNode.getPartsCount() - start; 1 <= length; length--) {
287+
String fieldName = nameNode.sub(start, length);
316288
log.debug("resolveCorrelationField() trying fieldName={}", fieldName);
317289
if (fieldNameList.contains(fieldName)) {
318290
RexNode field = context.relBuilder.field_(correlation, fieldName);
319-
return resolveFieldAccess(context, parts, start, length, field);
291+
return resolveFieldAccess(context, nameNode, start, length, field);
320292
}
321293
}
322294
}
@@ -325,11 +297,11 @@ private static Optional<RexNode> resolveCorrelationField(
325297
}
326298

327299
private static RexNode resolveFieldAccess(
328-
CalcitePlanContext context, List<String> parts, int start, int length, RexNode field) {
329-
if (length == parts.size() - start) {
300+
CalcitePlanContext context, QualifiedName name, int start, int length, RexNode field) {
301+
if (length == name.getPartsCount() - start) {
330302
return field;
331303
} else {
332-
String itemName = joinParts(parts, length + start, parts.size() - 1 - length);
304+
String itemName = name.sub(length + start, name.getPartsCount() - 1 - length);
333305
return createItemAccess(field, itemName, context);
334306
}
335307
}

0 commit comments

Comments
 (0)