mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-23 22:03:03 +01:00
Detect ambiguities in implicit MATCHING of views in REPLACE
This commit is contained in:
parent
9e4f5fff41
commit
4599805c7f
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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<Firebird::MetaName> 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
|
||||
|
Loading…
Reference in New Issue
Block a user