89
Views
9
Comments
[SQL Sandbox] "An item with the same key has already been added." Error
sql-sandbox
Web icon
Forge component by Leonardo Fernandes
Application Type
Traditional Web

We use the latest version in our project.

On some of the environments, the same query fails.

On our DEV and TST environment we receive this message "An item with the same key has already been added. "

On ACC and PROD it runs.

All referenced entities are available and we don't use physical table names, only the functional ones like: {Users}

Hi Peter,

This is a standard error message coming from Dictionary type object in C# when it tries to add a key that already exists.

Can you share the stack trace to point in the right direction finding the bug?

If I go to a different module that has this entity also referenced, I'm able to execute it. So it also depends from which module I'm running this query.

Stacktrace:

An item with the same key has already been added.
   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at OutSystems.NssSQLCMD.Parser.ContextualQueryParser..ctor(IEnumerable`1 entities)
   at OutSystems.NssSQLCMD.CssSQLCMD.MssParseContextualQuery(String ssContextualSQL, RLEntityDetailsRecordList ssContext, String& ssSQL, Boolean& ssHasInferredConnectionName, String& ssInferredConnectionName, Boolean& ssHasInferredOutput, RLEntityAttributeDetailsRecordList& ssInferredOutput)
   at ssSQL.RssExtensionSQLCMD.MssParseContextualQuery(HeContext heContext, String inParamContextualSQL, RecordList inParamContext, String& outParamSQL, Boolean& outParamHasInferredConnectionName, String& outParamInferredConnectionName, Boolean& outParamHasInferredOutput, RecordList& outParamInferredOutput) 


Hi Peter,

Can you confirm if you don't have another entity with the module which is ending up with this error message?

Example

  • MyEntity exists in MyModule1
  • MyEntity exists in MyModule2
  • You added a reference to MyModule1.MyEntity in MyModule2
  • Then accessed SQL Sandbox with Module1 and type a select query on MyEntity.

I know if there's any duplicate name in referenced Entity, it will be suffixed with 2 or 3 or ... But just want to confirm with you about such situation because the internal names of both entities are still the same.

Sorry for my very late reply.

When I do a simple query in Module 1:

"SELECT * FROM {checklistitem}" it fails with the message.

Checklistitem exists only in Module 1

Hi @Peter Van Den Ochtend 

Please suggest how di you resolve this issue, if already? Following up because fixing this would need some changes in the component in helping build the next minor version, if at all.

Having a similar issue with same error message.  In my case a consumer module imports references to two different entities that happen to have the same name.

Application Modules

  • Consumer
  • ProducerA
  • ProducerB

Consumer References

  • ProducerA.Thing as Thing
  • ProducerB.Thing as Thing2

All queries fail to execute with the same error message when SQL Sandbox's module view is set to Consumer.  It does not matter if the query uses the seemingly conflicted entity references or not in the query.

Note intellisence works and identifies {Thing} and {Thing1}.

The issue is probably with translation of OutSystems SQL to the database's SQL.

Hi Erik,

The strange thing is that I can use the same query, in the same module but only on a different environment. All the dependencies are the same. Why does it work there?

This error is still an ongoing thing and very annoying because now you can't use an end-user module that holds most of the entities but now you have to go to a lower level module and use the physical table name to join the entities. :(

I just started having this issue today. Doesn't matter which entity I pick - I get the same error. Even entity names that I know are unique. Very frustrating. I love this tool and recommend it often.

I'd like to suggest a fix for this issue to the dev team to be implemented in the next version of the component, if you agree with it. I have attached a modified OML containing my changes, which are detailed below.

The issue stems from what appears to be a flaw in the OutSystems metadata which drives the logic. When multiple entities with the same name are referenced by a single module, OutSystems usually gives them different names in the Espace_Entity metadata, but sometimes it doesn't. When it doesn't, the ContextualQueryParser constructor (in the extension) experiences this error because it tries to create multiple records in the dictionary with the same key (the key comes from the name in Espace_Entity). This applies to the whole module, regardless of which entities you are using in your query as the error happens when building the list of referenced entities before it even looks at the entered SQL.

I'm not sure why the metadata doesn't always come out with appropriately deduplicated names, but my solution is to add some logic to enforce name deduplication in the GetContextualEntities action to ensure they're unique before we get to ContextualQueryParser. Placing this logic in GetContextualEntities also ensures the on-screen 'Intellisense' entity names match the names which will be used in the parser.

I have added an action called EnforceUniqueEntityNames to the end of GetContextualEntities, which checks each entity name and appends a number to any duplicates to ensure they are unique. I also added an inline action called EnumerateEntityName, which is used inside EnforceUniqueEntityNames.

SQL.oml
Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.