[jOOQ/jOOQ#16446] Avoid ScopeStack iteration in ParseScope.scopeEnd() and scopeResolve() if we're not looking up meta data

This commit is contained in:
Lukas Eder 2024-03-13 16:55:10 +01:00
parent 55fb16bd66
commit c19f717c10
2 changed files with 52 additions and 45 deletions

View File

@ -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<FieldProxy<?>> fields = new ArrayList<>();
List<FieldProxy<?>> 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<Field<?>> 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<Field<?>> 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() {

View File

@ -96,7 +96,7 @@ final class ScopeStack<K, V> implements Iterable<V> {
}
final boolean isEmpty() {
return !iterator().hasNext();
return !stack().isEmpty() && !iterator().hasNext();
}
final Iterable<Value<V>> valueIterable() {