Project

General

Profile

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 the directory.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 the replace attribute (except hisfld, 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 the no-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!

    (1-7/7)