Project

General

Profile

table_lookup.diff

Hynek Cihlar, 07/18/2017 05:04 PM

Download (11.6 KB)

View differences:

src/com/goldencode/p2j/schema/SchemaDictionary.java 2017-07-18 20:03:56 +0000
2141 2141
    *          Name of the table whose node is to be found.
2142 2142
    * @param   toNode
2143 2143
    *          Copy target node.
2144
    * @param   skipGlobal
2144
    * @param   preferTemp
2145 2145
    *          if (@code true}, do not look in the global schema scope to find {@code fromTable}.
2146 2146
    *          
2147 2147
    * @return  Name node as described above.
......
2149 2149
    * @throws  AmbiguousSchemaNameException
2150 2150
    *          if the lookup results in ambiguity within a scope.
2151 2151
    */
2152
   public NameNode findTableFromNode(String fromTable, NameNode toNode, boolean skipGlobal)
2152
   public NameNode findTableFromNode(String fromTable, NameNode toNode, boolean preferTemp)
2153 2153
   throws AmbiguousSchemaNameException
2154 2154
   {
2155 2155
      int type = EntityName.TABLE;
......
2157 2157
      // Try to find the "from" node in any scope.
2158 2158
      String fromName = fromTable;
2159 2159
      
2160
      // look first for a persistent table in the schema global scope; a persistent table takes
2161
      // precedence over a temp-table with the same name, unless this behavior is explicitly
2162
      // overridden (e.g. DEFINE BUFFER x FOR TEMP-TABLE y)
2163
      NameNode fromNode = null;
2164
      if (!skipGlobal)
2165
      {
2166
         try
2167
         {
2168
            fromNode = findEntry(fromTable,
2169
                                 type,
2170
                                 SCHEMA_GLOBAL_SCOPE,
2171
                                 SCHEMA_GLOBAL_SCOPE,
2172
                                 false);
2173
         }
2174
         catch (AmbiguousSchemaNameException exc)
2175
         {
2176
            // if an unambiguous match for a persistent table could not be found, allow fromNode
2177
            // to remain null
2178
         }
2179
      }
2180
      
2181
      // if not found there, look for a temp-table in a higher scope
2182
      if (fromNode == null)
2183
      {
2184
         fromNode = findEntry(fromTable, type, scopes.size() - 1, USER_GLOBAL_SCOPE, false);
2185
      }
2186
      
2160
      NameNode fromNode;
2161
      NameNode nodeGlobal = null;
2162
      NameNode nodeUser = null;
2163

  
2164
      // look for a persistent table in the schema global scope
2165
      try
2166
      {
2167
         nodeGlobal = findEntry(fromTable,
2168
                                type,
2169
                                SCHEMA_GLOBAL_SCOPE,
2170
                                SCHEMA_GLOBAL_SCOPE,
2171
                                false);
2172
      }
2173
      catch (AmbiguousSchemaNameException exc)
2174
      {
2175
         // if an unambiguous match for a persistent table could not be found, allow fromNode
2176
         // to remain null
2177
      }
2178

  
2179
      // look for a temp-table in a higher scope, note that the lookup must always yield
2180
      // an exact match
2181
      try
2182
      {
2183
         nodeUser = findEntry(fromTable,
2184
                              type,
2185
                              scopes.size() - 1,
2186
                              USER_GLOBAL_SCOPE,
2187
                              true);
2188
      }
2189
      catch (AmbiguousSchemaNameException exc)
2190
      {
2191
         // if an unambiguous match for a temp table could not be found, allow fromNode
2192
         // to remain null
2193
      }
2194

  
2195
      // a persistent table takes precedence over a temp-table with the same name,
2196
      // unless this behavior is explicitly overridden (e.g. DEFINE BUFFER x FOR TEMP-TABLE y);
2197
      // when a persistent table is not found always use the temp table regardless of
2198
      // the TEMP-TABLE keyword and vice versa, when a temp table is not found always use the
2199
      // persistent table regardless of the TEMP-TABLE keyword
2200
      fromNode = (preferTemp && nodeUser != null) || nodeGlobal == null ? nodeUser : nodeGlobal;
2201

  
2187 2202
      // Make sure the node we found is not our "to" node. This can happen if the "to" node is
2188 2203
      // named the same as the "from" node, and was not qualified to differentiate it when it was
2189 2204
      // added. Also ensure that the "from" node is not a buffer;  we need the backing table.
......
2224 2239
    * @param   toNode
2225 2240
    *          Name node which represents the table to which the field entries
2226 2241
    *          will be copied.
2227
    * @param   forceTemp
2228
    *          if (@code true}, do not look in the global schema scope to find a "real" table to
2229
    *          replace the temp/work-table {@code fromNode} previously resolved.
2230 2242
    *
2231 2243
    * @throws  AmbiguousSchemaNameException
2232 2244
    *          if <code>table</code> matches more than one entry in the
......
2236 2248
    */
2237 2249
   public void addFieldEntries(String fromTable,
2238 2250
                               NameNode fromNode,
2239
                               NameNode toNode,
2240
                               boolean forceTemp)
2251
                               NameNode toNode)
2241 2252
   throws SchemaException
2242 2253
   {
2243
      addEntries(fromTable, fromNode, toNode, EntityName.TABLE, forceTemp);
2254
      addEntries(fromTable, fromNode, toNode, EntityName.TABLE);
2244 2255
      
2245 2256
      // force all children to have the same line/col numbers as the table
2246 2257
      // node, rather than the line/col nums from the copied (from) table
......
3772 3783
    * @param   type
3773 3784
    *          Type of the parent entity to which child entries are to be
3774 3785
    *          added (using {@link EntityName} constants).
3775
    * @param   forceTemp
3776
    *          if (@code true}, do not look in the global schema scope to find a "real" table to
3777
    *          replace the temp/work-table {@code fromNode} previously resolved.
3778 3786
    *
3779 3787
    * @throws  AmbiguousSchemaNameException
3780 3788
    *          if a database lookup produces more than one match.
......
3784 3792
   private void addEntries(String from,
3785 3793
                           NameNode fromNode,
3786 3794
                           NameNode toNode,
3787
                           int type,
3788
                           boolean forceTemp)
3795
                           int type)
3789 3796
   throws AmbiguousSchemaNameException,
3790 3797
          SchemaException
3791 3798
   {
......
3795 3802
         case BUFFER:
3796 3803
         {
3797 3804
            int fromType = fromNode.getType();
3798
            if (fromType == TEMP_TABLE || fromType == WORK_TABLE)
3799
            {
3800
               // forceTemp indicates we know the from table should be a temp/work table; only
3801
               // search in the schema global scope if set to false
3802
               if (!forceTemp)
3803
               {
3804
                  // If fromNode is a temp table and toNode is a buffer, make
3805
                  // sure fromNode is not masking a real table of the same name.
3806
                  try
3807
                  {
3808
                     NameNode realTable = findEntry(from,
3809
                                                    type,
3810
                                                    SCHEMA_GLOBAL_SCOPE,
3811
                                                    SCHEMA_GLOBAL_SCOPE,
3812
                                                    true);
3813
                     if (realTable != null)
3814
                     {
3815
                        fromNode = realTable;
3816
                     }
3817
                  }
3818
                  catch (AmbiguousSchemaNameException exc)
3819
                  {
3820
                     // This answers our question: there is no real table by this name.
3821
                  }
3822
               }
3823
            }
3824
            else if (fromType == TABLE)
3805
            if (fromType == TABLE)
3825 3806
            {
3826 3807
               // If fromNode is a "real" table, create a fake copy (a
3827 3808
               // shadow) of its parent database node and store it in the
src/com/goldencode/p2j/uast/SymbolResolver.java 2017-07-18 20:03:56 +0000
4738 4738
    *           The table reference in which to add fields.
4739 4739
    * @param    tablename
4740 4740
    *           The name of the table whose fields should be added.
4741
    * @param    skipGlobal
4741
    * @param    preferTemp
4742 4742
    *           if (@code true}, do not look in the global schema scope to find
4743 4743
    *           {@code tablename}.
4744 4744
    *
4745 4745
    * @return   The list of ASTs representing the copied fields.
4746 4746
    */
4747
   public Aast[] addFieldsFrom(Object table, String tablename, boolean skipGlobal)
4747
   public Aast[] addFieldsFrom(Object table, String tablename, boolean preferTemp)
4748 4748
   {
4749 4749
      List<Aast> fields = null;
4750 4750
      try
......
4760 4760
            // current schema
4761 4761
            if (dict.isTable(tablename))
4762 4762
            {
4763
               nn = dict.findTableFromNode(tablename, toTable, skipGlobal);
4763
               nn = dict.findTableFromNode(tablename, toTable, preferTemp);
4764 4764
            }
4765 4765
            
4766 4766
            return nn;
......
4776 4776
         }
4777 4777
         
4778 4778
         // make edits in our local schema dictionary
4779
         schemaDict.addFieldEntries(tablename, fromTable, toTable, skipGlobal);
4779
         schemaDict.addFieldEntries(tablename, fromTable, toTable);
4780 4780
         
4781 4781
         fields = new ArrayList<Aast>();
4782 4782
         Aast child = (Aast) toTable.getAst().getFirstChild();
src/com/goldencode/p2j/uast/progress.g 2017-07-18 20:15:15 +0000
5928 5928
    * @param    st
5929 5929
    *           Static specifier if not null. Only will be non-null if this is a resource defined
5930 5930
    *           as a member of a class definition.
5931
    * @param    forceTemp
5932
    *           if {@code true}, assume {@code recordName} represents a temp-table, and do not
5933
    *           search for it in the global schema scope when adding fields from it to the buffer
5934
    *           being define.
5931
    * @param    preferTemp
5932
    *           if {@code true}, temp-table is given precedence when the symbol name yields
5933
    *           both a temp and persistent table.
5935 5934
    */
5936 5935
   private void defineBufferFromSymbol(Aast symbol,
5937 5936
                                       String recordName,
5938 5937
                                       Aast am,
5939 5938
                                       Aast st,
5940
                                       boolean forceTemp)
5939
                                       boolean preferTemp)
5941 5940
   {
5942 5941
      String name = symbol.getText();
5943 5942
   
......
5947 5946
      // buffer is created in a global scope
5948 5947
      Object table = sym.addTable(name, BUFFER, bufferScope, symbol, am, st);
5949 5948
      
5950
      sym.addFieldsFrom(table, recordName, forceTemp);
5949
      sym.addFieldsFrom(table, recordName, preferTemp);
5951 5950
      
5952 5951
      String bufname = sym.lookupBufferName(name, false);
5953 5952
      symbol.putAnnotation("bufname", bufname);
......
10734 10733
      {
10735 10734
         if (#b != null && rtext != null)
10736 10735
         {
10737
            boolean forceTemp = false;
10736
            boolean preferTemp = false;
10738 10737
            AST ns = #b.getNextSibling();
10739 10738
            if (ns != null && ns.getType() == KW_FOR)
10740 10739
            {
10741 10740
               AST a = ns.getFirstChild();
10742 10741
               if (a != null && a.getType() == KW_TEMP_TAB)
10743 10742
               {
10744
                  forceTemp = true;
10743
                  preferTemp = true;
10745 10744
               }
10746 10745
            }
10747
            defineBufferFromSymbol(#b, rtext, am, st, forceTemp);
10746
            defineBufferFromSymbol(#b, rtext, am, st, preferTemp);
10748 10747
         }
10749 10748
      }
10750 10749
   ;
......
22209 22208
         if (b4table != null)
22210 22209
         {
22211 22210
            Object before = sym.addTable(b4table, TEMP_TABLE, true, #bt, null, null);
22212
            Aast[] fields = sym.addFieldsFrom(before, tablename);
22211
            Aast[] fields = sym.addFieldsFrom(before, tablename, true);
22213 22212
            
22214 22213
            for (int i = 0; i < fields.length; i++)
22215 22214
            {