Skip to content

Commit 16e0d96

Browse files
committed
Fix logic
1 parent 488159d commit 16e0d96

File tree

3 files changed

+52
-24
lines changed

3 files changed

+52
-24
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package fr.insee.vtl.engine.exceptions;
2+
3+
import fr.insee.vtl.model.Positioned;
4+
import fr.insee.vtl.model.exceptions.VtlScriptException;
5+
import java.util.Optional;
6+
7+
public class AlreadyDefinedException extends VtlScriptException {
8+
9+
private static String format(Positioned identifier, Optional<Positioned> container) {
10+
var msg = "'%s', is already defined".formatted(identifier.getPosition().text());
11+
12+
msg += container.map(c -> " in '%s'".formatted(c.getPosition().text())).orElse("");
13+
14+
return msg;
15+
}
16+
17+
private AlreadyDefinedException(Positioned identifier, Optional<Positioned> container) {
18+
super(format(identifier, container), identifier);
19+
}
20+
21+
public AlreadyDefinedException(Positioned identifier) {
22+
super(format(identifier, Optional.empty()), identifier);
23+
}
24+
25+
public AlreadyDefinedException(Positioned identifier, Positioned container) {
26+
super(format(identifier, Optional.of(container)), identifier);
27+
}
28+
}

vtl-engine/src/main/java/fr/insee/vtl/engine/exceptions/UndefinedVariableException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public UndefinedVariableException(String name, Positioned position) {
2121

2222
public UndefinedVariableException(Positioned identifier, Positioned container) {
2323
super(
24-
"undefined variable '%s' in '%'"
24+
"undefined variable '%s' in '%s'"
2525
.formatted(identifier.getPosition().text(), container.getPosition().text()),
2626
identifier);
2727
}

vtl-engine/src/main/java/fr/insee/vtl/engine/visitors/ClauseVisitor.java

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -279,19 +279,27 @@ public DatasetExpression visitFilterClause(VtlParser.FilterClauseContext ctx) {
279279
public DatasetExpression visitRenameClause(VtlParser.RenameClauseContext ctx) {
280280

281281
// Dataset structure in order + lookup maps
282-
final List<Dataset.Component> componentsInOrder =
283-
new ArrayList<>(datasetExpression.getDataStructure().values());
284-
final Set<String> availableColumns =
285-
componentsInOrder.stream()
286-
.map(Dataset.Component::getName)
287-
.collect(Collectors.toCollection(LinkedHashSet::new));
282+
//final List<Dataset.Component> componentsInOrder =
283+
// new ArrayList<>(datasetExpression.getDataStructure().values());
284+
// final Set<String> availableColumns =
285+
// componentsInOrder.stream()
286+
// .map(Dataset.Component::getName)
287+
// .collect(Collectors.toCollection(LinkedHashSet::new));
288+
289+
var structure = datasetExpression.getDataStructure();
288290

289291
// Parse the RENAME clause and validate
290292
Map<String, String> fromTo = new LinkedHashMap<>();
291293
Set<String> toSeen = new LinkedHashSet<>();
292294
Set<String> fromSeen = new LinkedHashSet<>();
293295

296+
Map<String, ParserRuleContext> toCtxMap = new HashMap<>();
297+
Map<String, ParserRuleContext> fromCtxMap = new HashMap<>();
298+
294299
for (VtlParser.RenameClauseItemContext renameCtx : ctx.renameClauseItem()) {
300+
toCtxMap.put(getName(renameCtx.toName), renameCtx.toName);
301+
fromCtxMap.put(getName(renameCtx.fromName), renameCtx.fromName);
302+
295303
final String toNameString = getName(renameCtx.toName);
296304
final String fromNameString = getName(renameCtx.fromName);
297305

@@ -304,7 +312,7 @@ public DatasetExpression visitRenameClause(VtlParser.RenameClauseContext ctx) {
304312
}
305313

306314
// Validate: "from" must exist in dataset
307-
if (!availableColumns.contains(fromNameString)) {
315+
if (!structure.containsKey(fromNameString)) {
308316
throw new VtlRuntimeException(
309317
new UndefinedVariableException(toPositioned(renameCtx.fromName), datasetExpression));
310318
}
@@ -318,10 +326,10 @@ public DatasetExpression visitRenameClause(VtlParser.RenameClauseContext ctx) {
318326
fromTo.put(fromNameString, toNameString);
319327
}
320328

321-
// Validate collisions with untouched dataset columns ("Untouched" = columns that are not
322-
// being renamed)
329+
// Check that the renamed columns do not collide with the remaining columns. This
330+
// is done so that swapping variables works: a -> b, b -> a.
323331
final Set<String> untouched =
324-
availableColumns.stream()
332+
structure.keySet().stream()
325333
.filter(c -> !fromTo.containsKey(c))
326334
.collect(Collectors.toCollection(LinkedHashSet::new));
327335

@@ -331,20 +339,12 @@ public DatasetExpression visitRenameClause(VtlParser.RenameClauseContext ctx) {
331339

332340
// If target already exists as untouched, it would cause a collision
333341
if (untouched.contains(to)) {
334-
Dataset.Component comp = datasetExpression.getDataStructure().get(to);
335-
String meta =
336-
(comp != null)
337-
? String.format(
338-
" (role=%s, type=%s)",
339-
comp.getRole(), comp.getType() != null ? comp.getType() : "n/a")
340-
: "";
341-
342342
throw new VtlRuntimeException(
343-
new InvalidArgumentException(
344-
String.format(
345-
"Error: target name '%s'%s already exists in dataset and is not being renamed.",
346-
to, meta),
347-
fromContext(ctx)));
343+
new AlreadyDefinedException(
344+
toPositioned(toCtxMap.get(to)),
345+
datasetExpression
346+
)
347+
);
348348
}
349349
}
350350

0 commit comments

Comments
 (0)