table_lookup.diff
| 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 |
{
|