6892_14378_uncommitted.patch
new/src/com/goldencode/p2j/persist/dialect/Dialect.java 2023-01-20 15:56:52 +0000 | ||
---|---|---|
91 | 91 |
** RAA 20230109 Added method getSequenceSetValString(). |
92 | 92 |
** SVL 20230110 P2JIndex.components() provides direct access to the components array in order to |
93 | 93 |
** improve performance. |
94 |
** AL2 20230117 Consider selection using wildcard with allowSelectWildcard. |
|
94 | 95 |
*/ |
95 | 96 | |
96 | 97 |
/* |
... | ... | |
1529 | 1530 |
{ |
1530 | 1531 |
return index.getName(); |
1531 | 1532 |
} |
1533 | ||
1534 |
/** |
|
1535 |
* Check if this dialect allows the selection of fields using * wildcard. Also, quantification should |
|
1536 |
* also be supported if this is allowed (alias.*). |
|
1537 |
* |
|
1538 |
* @return {@code true} if we can use * as selection wildcard. |
|
1539 |
*/ |
|
1540 |
public boolean allowSelectWildcard() |
|
1541 |
{ |
|
1542 |
return false; |
|
1543 |
} |
|
1532 | 1544 |
} |
new/src/com/goldencode/p2j/persist/dialect/P2JH2Dialect.java 2023-01-20 15:56:52 +0000 | ||
---|---|---|
105 | 105 |
** OM 20221026 Excluded table name from index name by default. It will be added as needed by |
106 | 106 |
** dialects. |
107 | 107 |
** RAA 20230109 Overrided methods getSequenceSetValString() and getSequenceCurrValString(). |
108 |
** AL2 20230117 Allow allowSelectWildcard. |
|
108 | 109 |
*/ |
109 | 110 | |
110 | 111 |
/* |
... | ... | |
1820 | 1821 |
{ |
1821 | 1822 |
return "idx__" + index.getTable() + "_" + index.getName(); |
1822 | 1823 |
} |
1824 | ||
1825 |
/** |
|
1826 |
* Check if this dialect allows the selection of fields using * wildcard. Also, quantification should |
|
1827 |
* also be supported if this is allowed (alias.*). |
|
1828 |
* |
|
1829 |
* @return {@code true} if we can use * as selection wildcard. |
|
1830 |
*/ |
|
1831 |
public boolean allowSelectWildcard() |
|
1832 |
{ |
|
1833 |
return true; |
|
1834 |
} |
|
1823 | 1835 |
} |
new/src/com/goldencode/p2j/persist/orm/DmoMeta.java 2023-01-20 15:56:52 +0000 | ||
---|---|---|
45 | 45 |
** SVL 20230113 Improved performance by replacing some "for-each" loops with indexed "for" loops. |
46 | 46 |
** HC 20230118 Eliminated some of the uses of String.toUpperCase and/or String.toLowerCase |
47 | 47 |
** for performance. |
48 |
** AL2 20230120 Compute if the underlying DMO requires extra computed columns. |
|
48 | 49 |
** CA 20221114 Added API to get the denormalized properties for a DMO extent property name. |
49 | 50 |
*/ |
50 | 51 | |
... | ... | |
277 | 278 |
/** Map of property names to extents for DMO array properties */ |
278 | 279 |
private Map<String, Integer> extentMap = null; |
279 | 280 |
|
281 |
/** Check if this DMO is going to have computed columns in the underlying database representation */ |
|
282 |
private Boolean hasComputedColumns = null; |
|
283 |
|
|
280 | 284 |
/** The map used in type-widening operations. */ |
281 | 285 |
private static final Map<Class<? extends BaseDataType>, Class<? extends BaseDataType>> toWider = |
282 | 286 |
new IdentityHashMap<>(); |
... | ... | |
1574 | 1578 |
} |
1575 | 1579 |
|
1576 | 1580 |
/** |
1581 |
* Check if this DMO has computed columns in the underlying database representation. This is |
|
1582 |
* used mostly for temporary tables and may not be completely compatible with persistent tables. |
|
1583 |
* |
|
1584 |
* @return {@code true} if we also have other columns that the legacy ones in the database. |
|
1585 |
*/ |
|
1586 |
public boolean hasComputedColumns() |
|
1587 |
{ |
|
1588 |
if (hasComputedColumns == null) |
|
1589 |
{ |
|
1590 |
hasComputedColumns = false; |
|
1591 |
|
|
1592 |
Set<Map.Entry<String, Property>> fieldEntries = this.propsByName.entrySet(); |
|
1593 |
|
|
1594 |
Set<Property> indexedProperties = new HashSet<>(); |
|
1595 |
Iterator<P2JIndex> databaseIndexes = this.getDatabaseIndexes(); |
|
1596 |
|
|
1597 |
while (databaseIndexes.hasNext()) |
|
1598 |
{ |
|
1599 |
P2JIndex index = databaseIndexes.next(); |
|
1600 |
ArrayList<P2JIndexComponent> components = index.components(); |
|
1601 |
for (int i = 0; i < components.size(); i++) |
|
1602 |
{ |
|
1603 |
P2JIndexComponent comp = components.get(i); |
|
1604 |
Property property = this.getFieldInfo(comp.getPropertyName()); |
|
1605 |
indexedProperties.add(property); |
|
1606 |
} |
|
1607 |
} |
|
1608 | ||
1609 |
for (Map.Entry<String, Property> field : fieldEntries) |
|
1610 |
{ |
|
1611 |
Property property = field.getValue(); |
|
1612 |
|
|
1613 |
if (indexedProperties.contains(property) && property._isCharacter) |
|
1614 |
{ |
|
1615 |
hasComputedColumns = true; |
|
1616 |
break; |
|
1617 |
} |
|
1618 | ||
1619 |
if (property.extent > 0) |
|
1620 |
{ |
|
1621 |
hasComputedColumns = true; |
|
1622 |
break; |
|
1623 |
} |
|
1624 |
|
|
1625 |
if (property._isDatetimeTz) |
|
1626 |
{ |
|
1627 |
hasComputedColumns = true; |
|
1628 |
break; |
|
1629 |
} |
|
1630 |
} |
|
1631 |
} |
|
1632 |
return hasComputedColumns; |
|
1633 |
} |
|
1634 |
|
|
1635 |
/** |
|
1577 | 1636 |
* Get the map of DMO property names to {@code P2JField} objects describing the corresponding fields, |
1578 | 1637 |
* creating it first, if necessary. |
1579 | 1638 |
* |
new/src/com/goldencode/p2j/persist/orm/FqlToSqlConverter.java 2023-01-20 15:56:52 +0000 | ||
---|---|---|
45 | 45 |
** SVL 20230108 Improved performance by replacing some "for-each" loops with indexed "for" loops. |
46 | 46 |
** 20221031 Collected fields of "select" query. |
47 | 47 |
** 20221101 Fixed possible NPE. |
48 |
** AL2 20230120 Introduced wildcard selection for some temp-tables. |
|
48 | 49 |
*/ |
49 | 50 | |
50 | 51 |
/* |
... | ... | |
123 | 124 |
import com.goldencode.p2j.schema.*; |
124 | 125 |
import com.goldencode.p2j.util.*; |
125 | 126 |
import com.goldencode.p2j.util.LogicalExpressionConverter.*; |
127 | ||
126 | 128 |
import org.apache.commons.lang3.tuple.*; |
127 | 129 |
import antlr.*; |
128 | 130 | |
... | ... | |
291 | 293 |
this.schema = db.isMeta() ? MetadataManager.META_SCHEMA : DatabaseManager.getSchema(db); |
292 | 294 |
this.queryParams = queryParams; |
293 | 295 |
this.useSqlTableAlias = useSqlTableAlias; |
294 |
this.generateUniqueSqlColumnNames = true;
|
|
296 |
this.generateUniqueSqlColumnNames = false;
|
|
295 | 297 |
this.useWordTables = !SchemaDictionary.TEMP_TABLE_DB.equals(schema) && |
296 | 298 |
!db.isDirty() && !db.isMeta() && dialect.useWordTables(); |
297 | 299 |
} |
... | ... | |
1447 | 1449 |
while(!tbls.add(cte)); |
1448 | 1450 |
return cte; |
1449 | 1451 |
} |
1452 |
|
|
1453 |
/** |
|
1454 |
* Check if we can simply use an alias.* syntax instead of listing all SQL fields. |
|
1455 |
* |
|
1456 |
* @param dmoMeta |
|
1457 |
* The meta of the table to be considered for wildcard field selection. |
|
1458 |
* |
|
1459 |
* @return {@code true} if we can emit an wildcard syntax for field selection. |
|
1460 |
*/ |
|
1461 |
private boolean canUseWildcard(DmoMeta dmoMeta) |
|
1462 |
{ |
|
1463 |
return cte4order == null && !dmoMeta.hasComputedColumns(); |
|
1464 |
} |
|
1450 | 1465 | |
1451 | 1466 |
/** |
1452 | 1467 |
* Expands the alias into all its properties in a SELECT clause. |
... | ... | |
1462 | 1477 |
{ |
1463 | 1478 |
int fieldCounter = 0; |
1464 | 1479 |
String sqlTableAliasName = getSqlTableAliasName(alias); |
1480 |
if (dialect.allowSelectWildcard() && |
|
1481 |
canUseWildcard(dmoMeta) && |
|
1482 |
!NO_ALIAS.equals(sqlTableAliasName)) |
|
1483 |
{ |
|
1484 |
if (!first) |
|
1485 |
{ |
|
1486 |
sb.append(", "); |
|
1487 |
} |
|
1488 |
sb.append(sqlTableAliasName).append(".*"); |
|
1489 |
fieldCounter = dmoMeta.propsByName.size(); |
|
1490 | ||
1491 |
if (rowStructure != null) |
|
1492 |
{ |
|
1493 |
rowStructure.add(new RowStructure(dmoMeta.dmoImplInterface, fieldCounter)); |
|
1494 |
} |
|
1495 |
|
|
1496 |
return; |
|
1497 |
} |
|
1465 | 1498 |
Set<Map.Entry<String, Property>> fieldEntries = dmoMeta.propsByName.entrySet(); |
1466 | 1499 |
for (Map.Entry<String, Property> field : fieldEntries) |
1467 | 1500 |
{ |
... | ... | |
1514 | 1547 |
if (generateUniqueSqlColumnNames) |
1515 | 1548 |
{ |
1516 | 1549 |
sb.append(" as "); |
1517 |
appendColAlias.accept("column");
|
|
1550 |
appendColAlias.accept("c"); |
|
1518 | 1551 |
} |
1519 | 1552 |
++fieldCounter; |
1520 | 1553 |
} |
... | ... | |
1528 | 1561 |
if (generateUniqueSqlColumnNames) |
1529 | 1562 |
{ |
1530 | 1563 |
sb.append(" as "); |
1531 |
appendColAlias.accept("column");
|
|
1564 |
appendColAlias.accept("c"); |
|
1532 | 1565 |
} |
1533 | 1566 |
++fieldCounter; |
1534 | 1567 |
} |
... | ... | |
3169 | 3202 |
{ |
3170 | 3203 |
return "id" + (columnUid++) + "_"; |
3171 | 3204 |
} |
3172 |
else if (property.propId < 0) |
|
3173 |
{ |
|
3174 |
return "column" + (columnUid++) + "_" + (aliases.size() - 1) + "_"; |
|
3175 |
} |
|
3176 | 3205 |
else |
3177 | 3206 |
{ |
3178 |
String fqlName = property.column; |
|
3179 |
int k = 0; |
|
3180 |
while (k < fqlName.length() && Character.isLetter(fqlName.charAt(k))) |
|
3181 |
{ |
|
3182 |
k++; |
|
3183 |
} |
|
3184 |
String sqlName = fqlName.substring(0, k); |
|
3185 |
if (sqlName.isEmpty()) |
|
3186 |
{ |
|
3187 |
sqlName = "column"; |
|
3188 |
} |
|
3189 |
return sqlName + (columnUid++) + "_" + (aliases.size() - 1) + "_"; |
|
3207 |
// in most of the cases the aliases deque is empty, so avoid forcing extra characters in the alias: |
|
3208 |
// convey that ord == 0 is the same as lacking ord |
|
3209 |
int ord = aliases.size() - 1; |
|
3210 |
return "c" + (columnUid++) + (ord == 0 ? "" : "_" + ord) + "_"; |
|
3190 | 3211 |
} |
3191 | 3212 |
} |
3192 | 3213 |
|