From c19f717c10aec67d8dda61cabab14619d82bc4ed Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Wed, 13 Mar 2024 16:55:10 +0100 Subject: [PATCH] [jOOQ/jOOQ#16446] Avoid ScopeStack iteration in ParseScope.scopeEnd() and scopeResolve() if we're not looking up meta data --- .../main/java/org/jooq/impl/ParserImpl.java | 95 ++++++++++--------- .../main/java/org/jooq/impl/ScopeStack.java | 2 +- 2 files changed, 52 insertions(+), 45 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java index 7782da281e..bb738afb33 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java @@ -15627,10 +15627,12 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { } private final void scopeResolve() { - if (!lookupFields.isEmpty()) - unknownField(lookupFields.iterator().next()); - if (!lookupQualifiedAsterisks.isEmpty()) - unknownTable(lookupQualifiedAsterisks.iterator().next()); + if (metaLookups() != ParseWithMetaLookups.OFF) { + if (!lookupFields.isEmpty()) + unknownField(lookupFields.iterator().next()); + if (!lookupQualifiedAsterisks.isEmpty()) + unknownTable(lookupQualifiedAsterisks.iterator().next()); + } } private final void scopeStart() { @@ -15643,48 +15645,52 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { } private final void scopeEnd(Query scopeOwner) { - List> fields = new ArrayList<>(); + List> fields = null; - // [#14372] Avoid looking up tables at a higher scope level - lookupLoop: - for (QualifiedAsteriskProxy lookup : scope.lookupQualifiedAsterisks.iterableAtScopeLevel()) { - for (Table t : scope.tableScope) { + if (metaLookups() != ParseWithMetaLookups.OFF) { + fields = new ArrayList<>(); - // [#15056] TODO: Could there be an ambiguity, as with fields? - if (t.getName().equals(lookup.$table().getName())) { - lookup.delegate((QualifiedAsteriskImpl) t.asterisk()); - continue lookupLoop; - } - } + // [#14372] Avoid looking up tables at a higher scope level + lookupLoop: + for (QualifiedAsteriskProxy lookup : scope.lookupQualifiedAsterisks.iterableAtScopeLevel()) { + for (Table t : scope.tableScope) { - // [#15056] TODO: Should we support references to higher scopes? - unknownTable(lookup); - } - - // [#14372] Avoid looking up fields at a higher scope level - for (FieldProxy lookup : scope.lookupFields.iterableAtScopeLevel()) { - Value> found = null; - - for (Field f : scope.fieldScope) { - if (f.getName().equals(lookup.getName())) { - if (found != null) { - position(lookup.position()); - throw exception("Ambiguous field identifier"); + // [#15056] TODO: Could there be an ambiguity, as with fields? + if (t.getName().equals(lookup.$table().getName())) { + lookup.delegate((QualifiedAsteriskImpl) t.asterisk()); + continue lookupLoop; } - - // TODO: Does this instance of "found" really interact with the one below? - found = new Value<>(0, f); } + + // [#15056] TODO: Should we support references to higher scopes? + unknownTable(lookup); } - found = resolveInTableScope(scope.tableScope.valueIterable(), lookup.getQualifiedName(), lookup, found); + // [#14372] Avoid looking up fields at a higher scope level + for (FieldProxy lookup : scope.lookupFields.iterableAtScopeLevel()) { + Value> found = null; - if (found != null && !(found.value() instanceof FieldProxy)) { - lookup.delegate((AbstractField) found.value()); - } - else { - lookup.scopeOwner(scopeOwner); - fields.add(lookup); + for (Field f : scope.fieldScope) { + if (f.getName().equals(lookup.getName())) { + if (found != null) { + position(lookup.position()); + throw exception("Ambiguous field identifier"); + } + + // TODO: Does this instance of "found" really interact with the one below? + found = new Value<>(0, f); + } + } + + found = resolveInTableScope(scope.tableScope.valueIterable(), lookup.getQualifiedName(), lookup, found); + + if (found != null && !(found.value() instanceof FieldProxy)) { + lookup.delegate((AbstractField) found.value()); + } + else { + lookup.scopeOwner(scopeOwner); + fields.add(lookup); + } } } @@ -15693,12 +15699,13 @@ final class DefaultParseContext extends AbstractScope implements ParseContext { scope.tableScope.scopeEnd(); scope.fieldScope.scopeEnd(); - for (FieldProxy r : fields) - if (scope.lookupFields.get(r.getQualifiedName()) == null) - if (scope.lookupFields.inScope()) - scope.lookupFields.set(r.getQualifiedName(), r); - else - unknownField(r); + if (fields != null) + for (FieldProxy r : fields) + if (scope.lookupFields.get(r.getQualifiedName()) == null) + if (scope.lookupFields.inScope()) + scope.lookupFields.set(r.getQualifiedName(), r); + else + unknownField(r); } private final void scopeClear() { diff --git a/jOOQ/src/main/java/org/jooq/impl/ScopeStack.java b/jOOQ/src/main/java/org/jooq/impl/ScopeStack.java index 9322a141b5..1bb9accaca 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ScopeStack.java +++ b/jOOQ/src/main/java/org/jooq/impl/ScopeStack.java @@ -96,7 +96,7 @@ final class ScopeStack implements Iterable { } final boolean isEmpty() { - return !iterator().hasNext(); + return !stack().isEmpty() && !iterator().hasNext(); } final Iterable> valueIterable() {