From 4599805c7f719de8795b6ecf2b0d1d25fa2ca693 Mon Sep 17 00:00:00 2001 From: asfernandes Date: Thu, 7 Sep 2006 03:30:31 +0000 Subject: [PATCH] Detect ambiguities in implicit MATCHING of views in REPLACE --- src/common/classes/GenericMap.h | 27 +++++++++++++--- src/common/classes/tree.h | 5 +-- src/dsql/metd.epp | 55 +++++++++++++++++++++++---------- 3 files changed, 64 insertions(+), 23 deletions(-) diff --git a/src/common/classes/GenericMap.h b/src/common/classes/GenericMap.h index 2bc3f56482..0dcb9fc552 100644 --- a/src/common/classes/GenericMap.h +++ b/src/common/classes/GenericMap.h @@ -67,6 +67,28 @@ public: GenericMap() : tree(&getPool()), mCount(0) { } GenericMap(MemoryPool& a_pool) : AutoStorage(a_pool), tree(&getPool()), mCount(0) { } ~GenericMap() { + clear(); + } + + void takeOwnership(GenericMap& from) { + clear(); + + tree = from.tree; + mCount = from.mCount; + + if (from.tree.getFirst()) { + while (true) { + bool haveMore = from.tree.fastRemove(); + if (!haveMore) + break; + } + } + + from.mCount = 0; + } + + // Clear the map + void clear() { if (tree.getFirst()) { while (true) { KeyValuePair* temp = tree.current(); @@ -75,11 +97,8 @@ public: if (!haveMore) break; } } - } - // Clear the map - void clear() { - tree.clear(); + mCount = 0; } // Returns true if value existed diff --git a/src/common/classes/tree.h b/src/common/classes/tree.h index e1f4cd95c3..5476c58942 100644 --- a/src/common/classes/tree.h +++ b/src/common/classes/tree.h @@ -115,9 +115,10 @@ public: append(from); } - BePlusTree& operator=(const BePlusTree& from) { + BePlusTree& operator =(BePlusTree& from) { clear(); append(from); + return *this; } void clear() { @@ -245,7 +246,7 @@ public: return ((NodeList*)root)->getCount() * bytes_per_node; } - void append(const BePlusTree& from) { + void append(BePlusTree& from) { // This is slow approach especially when used for assignment. // Optimize it when need arises. Accessor accessor(&from); diff --git a/src/dsql/metd.epp b/src/dsql/metd.epp index cb59b134cd..800ff12ee2 100644 --- a/src/dsql/metd.epp +++ b/src/dsql/metd.epp @@ -1791,6 +1791,8 @@ dsql_rel* METD_get_view_base(dsql_req* request, * is more than one. * If there is only one base, put in fields a map of * top view field name / bottom base field name. + * Ignores the field in the case of a base field name + * appearing more than one time in a level. * **************************************/ @@ -1801,7 +1803,7 @@ dsql_rel* METD_get_view_base(dsql_req* request, isc_db_handle DB = dbb->dbb_database_handle; bool first = true; bool cont = true; - MetaNamePairMap aux; + MetaNamePairMap previousAux; fields.clear(); @@ -1832,6 +1834,9 @@ dsql_rel* METD_get_view_base(dsql_req* request, relation = METD_get_relation(request, relation_name); delete relation_name; + Firebird::Array ambiguities; + MetaNamePairMap currentAux; + THREAD_EXIT(); if (!relation) @@ -1847,33 +1852,49 @@ dsql_rel* METD_get_view_base(dsql_req* request, THREAD_ENTER(); - if (first) - { - fields.put( - (RFL.RDB$FIELD_NAME.NULL ? "" : RFL.RDB$FIELD_NAME), - (RFL.RDB$BASE_FIELD.NULL ? "" : RFL.RDB$BASE_FIELD)); + if (RFL.RDB$BASE_FIELD.NULL) + RFL.RDB$BASE_FIELD[0] = '\0'; - aux.put( - (RFL.RDB$BASE_FIELD.NULL ? "" : RFL.RDB$BASE_FIELD), - (RFL.RDB$FIELD_NAME.NULL ? "" : RFL.RDB$FIELD_NAME)); - } + if (RFL.RDB$FIELD_NAME.NULL) + RFL.RDB$FIELD_NAME[0] = '\0'; + + if (currentAux.exist(RFL.RDB$BASE_FIELD)) + ambiguities.add(RFL.RDB$BASE_FIELD); else { - Firebird::MetaName field; - - if (aux.get(RFL.RDB$FIELD_NAME, field)) + if (first) { - fields.put(field, - (RFL.RDB$BASE_FIELD.NULL ? "" : RFL.RDB$BASE_FIELD)); + fields.put(RFL.RDB$FIELD_NAME, RFL.RDB$BASE_FIELD); + currentAux.put(RFL.RDB$BASE_FIELD, RFL.RDB$FIELD_NAME); + } + else + { + Firebird::MetaName field; - aux.remove(RFL.RDB$FIELD_NAME); - aux.put((RFL.RDB$BASE_FIELD.NULL ? "" : RFL.RDB$BASE_FIELD), field); + if (previousAux.get(RFL.RDB$FIELD_NAME, field)) + { + fields.put(field, RFL.RDB$BASE_FIELD); + currentAux.put(RFL.RDB$BASE_FIELD, field); + } } } THREAD_EXIT(); END_FOR + for (Firebird::MetaName* i = ambiguities.begin(); i != ambiguities.end(); ++i) + { + Firebird::MetaName field; + + if (currentAux.get(*i, field)) + { + currentAux.remove(*i); + fields.remove(field); + } + } + + previousAux.takeOwnership(currentAux); + if (relation->rel_flags & REL_view) view_name = X.RDB$RELATION_NAME; else