Forums » Conversion »
Ambiguous database field matches
Added by Antanas Valencius about 3 years ago
I have a couple problems regarding conversion using multiple databases and logical database names.
1. I am trying to convert a project that has multiple databases. Some procedures search for field that has the same name in two databases and get the following error:
[java] 'aab' is ambiguous; 2 matches found [stmt.aab, bank.aab]
How do I solve this issue? Do those procedure have to be mapped manually?
2. There are also issues with unexpected tokens trying to access logical database field:
[java] ./abl/sepastmt_xmla_lvl.p:440:17: unexpected token: arcbase.cif.type
arcbase is the logical name for the database. How do I link logical database names to real database name?
Replies (7)
RE: Ambiguous database field matches - Added by Greg Shah about 3 years ago
I am trying to convert a project that has multiple databases. Some procedures search for field that has the same name in two databases and get the following error:
For these procedures, when compiled in OpenEdge, are both databases connected?
In FWD, one can think of the conversion process as a similar step to the 4GL compilation. The same kinds of dependencies exist. For example, each procedure must be able to find the databases to be used to resolve table and field references. FWD supports multiple databases, but as in OpenEdge, if a table or field reference is ambiguous between these databases then only one of the databases will be "connected" during the conversion. In FWD, we don't really "connect" to the database during conversion. We just configure the knowledge about which databases should be considered connected.
My guess is that you have defined both databases as connected by default in the p2j.cfg.xml
. From Hotel GUI:
<namespace name="hotel" importFile="data/hotel.df" xmlFile="data/namespace/hotel.dict" default="true" > <parameter name="ddl-dialects" value="h2,postgresql" /> <dialect-specific name="h2"> <parameter name="collation" value="en_US_P2J" /> </dialect-specific> </namespace>
The use of default="true"
here means that the hotel
logical database is considered connected for ALL procedures in the project. If you have more than one database set as default, any ambiguous names will fail parsing.
At this time, we do not have a means to remove a default database for a given set of programs. Task #4105 documents some of the current limitations and is the issue in which we plan to fix them. Our common approach right now:
- Only set
default="true"
for databases that truly are connected for all procedures. - Since many applications are written such that modules have common database dependencies AND reside in one or more directories dedicated to that module, we often find that we can use a
directory.hints
file to specify all databases to be connected for that module. See Database Connections and Conversion Hints for details on syntax. Place thedirectory.hints
in the module directory and put the databases and aliases in that file.
There are also issues with unexpected tokens trying to access logical database field:
This is just a manifestation of the same issue. The fix above will also fix this.
How do I link logical database names to real database name?
If you are talking about aliases, you can define them as hints. Hints can be placed in the directory.hints
if they apply to all files in a subdirectory tree. For procedure-specific hints, you can create a ./abl/some/path/program.p.hints
file for hints that are specific to program.p
.
If it is truly the logical database name in use here, then just make sure that the .df
is named the same as the logical database name (e.g. arcbase.df
) and this should also be name used in the namespace
section of p2j.cfg.xml
in the name="arcbase"
attribute. We never use physical database names at conversion time. Even at runtime, we use JDBC URLs to connect to databases.
RE: Ambiguous database field matches - Added by Antanas Valencius about 3 years ago
This has been very helpful, but now I have somewhat related issues.
During the compilation stage (`ant jar`) I get a lot of similar errors, that a reference to a table is ambiguous:
[javac] /home/fwd/FWD/platsrc4/src/com/ba/platon/PltDlon.java:82: error: reference to Hisfld is ambiguous [javac] Hisfld.Buf hisfld = RecordBuffer.define(Hisfld.Buf.class, "bank", "hisfld", "hisfld"); [javac] ^ [javac] both interface com.ba.platon.dmo.indigo.Hisfld in com.ba.platon.dmo.indigo and interface com.ba.platon.dmo.bank.Hisfld in com.ba.platon.dmo.bank match
[javac] /home/fwd/FWD/platsrc4/src/com/ba/platon/PltLon.java:123: error: reference to Acr is ambiguous [javac] Acr.Buf acr = RecordBuffer.define(Acr.Buf.class, "bank", "acr", "acr"); [javac] ^ [javac] both interface com.ba.platon.dmo.indigo.Acr in com.ba.platon.dmo.indigo and interface com.ba.platon.dmo.bank.Acr in com.ba.platon.dmo.bank match
Two databases share common table names. Is there a way to simply solve such issue? Do I need to check logs of conversion stage? Will I need to return to conversion to fix such issue?
RE: Ambiguous database field matches - Added by Eric Faulhaber about 3 years ago
Antanas Valencius wrote:
This has been very helpful, but now I have somewhat related issues.
During the compilation stage (`ant jar`) I get a lot of similar errors, that a reference to a table is ambiguous:
[...]
[...]
Two databases share common table names. Is there a way to simply solve such issue?
Are the indigo
and bank
schemas mirrors/duplicates of each other, or are there just a small number of tables which have overlapping names? If they are mirrors, are both databases connected when running the external procedures for which we are seeing these compile errors?
Do I need to check logs of conversion stage?
Reviewing the conversion log would be useful, yes. In particular, were there any warning messages during the parsing stage (see the Scanning Progress Source (preprocessor, lexer, parser, persist ASTs)
section of the log) for these source files?
Will I need to return to conversion to fix such issue?
Duplicate/ambiguous names generally represent a project configuration or conversion issue. So yes, once the root cause is determined and resolved, re-conversion will be necessary to ensure the correct objects are resolved during compilation.
RE: Ambiguous database field matches - Added by Antanas Valencius about 3 years ago
Are the indigo and bank schemas mirrors/duplicates of each other, or are there just a small number of tables which have overlapping names?@
No, they are not duplicates. indigo
and bank
are different schemas but they happen to share some table names.
If they are mirrors, are both databases connected when running the external procedures for which we are seeing these compile errors?
As mentioned, these schemas are not mirrors. However, in addition to the main schema bank
, for these files additional database indigo
is connected using *.hints
file:
<hints> <database name="indigo" /> </hints>
In particular, were there any warning messages during the parsing stage (see the Scanning Progress Source (preprocessor, lexer, parser, persist ASTs) section of the log) for these source files?
No, I've just checked the logs and there are no errors in conversion stage.
RE: Ambiguous database field matches - Added by Eric Faulhaber about 3 years ago
OK, so since both databases are connected for this program, and the tables in use in this program have the same names across the bank
and indigo
schemas, probably the best way to disambiguate the table names is to use schema hints to rename the conflicting tables in either the indigo
or the bank
schema. This will impact all programs where both of these schemas are in use, and the name changes will flow through all references to these tables in the business logic, and in the SQL (DDL and DML).
The name change hints only need to be applied to one schema, not both, so you will have to decide which is the more appropriate for the change. It sounds from your description that the indigo
schema is a "secondary" schema used less pervasively throughout the application. Based on this assumption, I would recommend renaming the tables in this schema, rather than in the bank
schema. However, you know your application best, so it is up to you to decide. I will assume the indigo
schema for my example, but these concepts can be applied to the other schema instead.
Changing database object names through schema hints is described in the FWD documentation (in the Conversion Hints and Other Customization chapters). However, to make this a bit more straightforward, here's an example, using the indigo
schema.
In the data/namespace/
subdirectory of your project, create a schema hints file. Assuming your exported schema file name is indigo.df
, this would be named indigo.schema.hints
. The hint format is XML. If you want to change the name of the Hisfld
DMO (and corresponding SQL table), the content of this file might look like this:
<?xml version="1.0"?> <hints> <schema> <table name="hisfld"> <phrase match="hisfld" replace="history field" no-inherit="true" /> </table> </schema> </hints>
Now, for the indigo
schema, conversion will create a DMO named HistoryField
and a SQL table named history_field
. The HistoryField.Buf
instance variable will be named historyField
, and all references to hisfld
which were scoped to the indigo
schema in the original program will be translated to references to that historyField
instance variable in the converted, Java code.
This example makes the following assumptions:
- that the original table name is
hisfld
; - that
hisfld
is an abbreviation for "history field" (pure speculation on my part); if this is not appropriate, use whatever phrase you want for thereplace
attribute (excepthisfld
, of course); - that you do not want any fields within the table which are named or contain the phrase
hisfld
to inherit the name override (that is what theno-inherit="true"
attribute does).
You would need to do something similar for the acr
table, and any others that conflict. If you want the replacement to be a compound word, use multiple component words, separated by a space, in the replace
attribute, as I did with history field
. This does not need to be multiple words, it can be whatever you want. Using a space to delimit multiple words tells the conversion to treat each word as a "syllable" of the converted name. Such a name will be camel-cased in Java (e.g., HistoryField
for a class name, historyField
for a variable name). It will be underscore-delimited for a SQL name (e.g., history_field
).
I have written this example from memory, so I would strongly recommend converting just this one program to confirm the changes are correct, before re-converting the entire application.
Hope this helps!
RE: Ambiguous database field matches - Added by Eric Faulhaber about 3 years ago
Eric Faulhaber wrote:
You would need to do something similar for the
acr
table, and any others that conflict.
BTW, in case I was not clear, these additional changes would require additional XML <table>
elements in the indigo.schema.hints
file, not additional hints files.
RE: Ambiguous database field matches - Added by Eric Faulhaber about 3 years ago
We've had some internal discussions since I posted my schema hint suggestion and we've come to the conclusion that this approach may be a heavy-handed solution. You may have hit upon a bug in FWD that we will want to fix, or it may be that there is a problem with your conversion configuration for this particular program.
Before you try my suggested table renaming, could you please provide us more information about this program? A cut-down test case illustrating the problem would be ideal. However, if that is not feasible, I could open a private task into which you could post your p2j.cfg.xml
file, any conversion hints you have applied, your schemas, and the problematic source file (or cut-down versions of these).
If there is a bug in FWD, we want to fix it. If there is a way to fix this with a change to conversion configuration, we would want to figure this out as well.
Thanks!