From d0d6afc88afe7acd7c36e7983a0f12903ae816d4 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Thu, 17 Dec 2020 10:03:40 +0100 Subject: [PATCH] [jOOQ/jOOQ#11134] ParseWithMetaLookups looks up columns in Meta that cannot possibly appear in query --- .../main/java/org/jooq/impl/ParserImpl.java | 92 +++++++++++-------- 1 file changed, 56 insertions(+), 36 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java index 0a9ea0deab..240e764805 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java @@ -584,10 +584,6 @@ final class ParserImpl implements Parser { this.meta = metaLookups == IGNORE_ON_FAILURE || metaLookups == THROW_ON_FAILURE ? dsl.meta() : null; } - // ------------------------------------------------------------------------- - // XXX: Parser configuration - // ------------------------------------------------------------------------- - // ------------------------------------------------------------------------- // XXX: Top level parsing // ------------------------------------------------------------------------- @@ -12530,36 +12526,25 @@ final class ParserContext { private final void scopeEnd() { List> retain = new ArrayList<>(); - for (FieldProxy f : lookupFields) { - Field f1 = null; + for (FieldProxy lookup : lookupFields) { + Field found = null; - for (Field a : fieldScope) { - if (a.getName().equals(f.getName())) { - if (f1 != null) { - position(f.position()); + for (Field f : fieldScope) { + if (f.getName().equals(lookup.getName())) { + if (found != null) { + position(lookup.position()); throw exception("Ambiguous field identifier"); } - f1 = a; - } - } - for (Table t : tableScope) { - Field f2; - - if ((f2 = t.field(f.getName())) != null) { - if (f1 != null) { - position(f.position()); - throw exception("Ambiguous field identifier"); - } - - f1 = f2; + found = f; } } - if (f1 != null) - f.delegate((AbstractField) f1); + found = resolveInTableScope(tableScope, lookup.getQualifiedName(), lookup, found); + if (found != null) + lookup.delegate((AbstractField) found); else - retain.add(f); + retain.add(lookup); } lookupFields.scopeEnd(); @@ -12574,6 +12559,40 @@ final class ParserContext { unknownField(r); } + private final Field resolveInTableScope(Iterable> tables, Name lookupName, FieldProxy lookup, Field found) { + + tableScopeLoop: + for (Table t : tables) { + Field f; + + if (t instanceof JoinTable) { + found = resolveInTableScope(Arrays.asList(((JoinTable) t).lhs, ((JoinTable) t).rhs), lookupName, lookup, found); + } + else if (lookupName.qualified()) { + + // Additional tests: + // - More complex search paths + // - Ambiguities from multiple search paths, when S1.T and S2.T conflict + // - Test fully qualified column names vs partially qualified column names + Name q = lookupName.qualifier(); + boolean x = q.qualified(); + if (x && q.equals(t.getQualifiedName()) || !x && q.last().equals(t.getName())) + if ((found = t.field(lookup.getName())) != null) + break tableScopeLoop; + } + else if ((f = t.field(lookup.getName())) != null) { + if (found != null) { + position(lookup.position()); + throw exception("Ambiguous field identifier"); + } + + found = f; + } + } + + return found; + } + private final void scopeClear() { scopeClear = true; } @@ -12615,16 +12634,17 @@ final class ParserContext { } private final Field lookupField(Name name) { - if (meta != null) { - List> tables = meta.getTables(name.qualifier()); - - if (tables.size() == 1) { - Field field = tables.get(0).field(name); - - if (field != null) - return field; - } - } + // TODO: Restore this logic if name is qualified as [CATALOG.]SCHEMA.TABLE.FIELD +// if (meta != null) { +// List> tables = meta.getTables(name.qualifier()); +// +// if (tables.size() == 1) { +// Field field = tables.get(0).field(name); +// +// if (field != null) +// return field; +// } +// } if (metaLookups == ParseWithMetaLookups.OFF) return field(name);