| 23 | namespace processor { |
| 24 | |
| 25 | static ScanRelTableInfo getRelTableScanInfo(const TableCatalogEntry& tableEntry, |
| 26 | RelDataDirection direction, RelTable* relTable, bool shouldScanNbrID, |
| 27 | const expression_vector& properties, const std::vector<ColumnPredicateSet>& columnPredicates, |
| 28 | main::ClientContext* clientContext) { |
| 29 | std::vector<ColumnPredicateSet> columnPredicateSets = copyVector(columnPredicates); |
| 30 | if (!columnPredicateSets.empty()) { |
| 31 | // Since we insert a nbr column. We need to pad an empty nbr column predicate set. |
| 32 | columnPredicateSets.insert(columnPredicateSets.begin(), ColumnPredicateSet()); |
| 33 | } |
| 34 | auto tableInfo = ScanRelTableInfo(relTable, std::move(columnPredicateSets), direction); |
| 35 | // We always should scan nbrID from relTable. This is not a property in the schema label, so |
| 36 | // cannot be bound to a column in the front-end. |
| 37 | auto nbrColumnID = shouldScanNbrID ? NBR_ID_COLUMN_ID : INVALID_COLUMN_ID; |
| 38 | tableInfo.addColumnInfo(nbrColumnID, ColumnCaster(LogicalType::INTERNAL_ID())); |
| 39 | auto binder = Binder(clientContext); |
| 40 | auto expressionBinder = ExpressionBinder(&binder, clientContext); |
| 41 | for (auto& expr : properties) { |
| 42 | auto& property = expr->constCast<PropertyExpression>(); |
| 43 | if (property.hasProperty(tableEntry.getTableID())) { |
| 44 | auto propertyName = property.getPropertyName(); |
| 45 | if (!tableEntry.containsProperty(propertyName) && tableEntry.containsProperty("data")) { |
| 46 | auto columnCaster = ColumnCaster(LogicalType::JSON()); |
| 47 | columnCaster.setJSONExtract(propertyName); |
| 48 | tableInfo.addColumnInfo(tableEntry.getColumnID("data"), std::move(columnCaster)); |
| 49 | continue; |
| 50 | } |
| 51 | auto& columnType = tableEntry.getProperty(propertyName).getType(); |
| 52 | auto columnCaster = ColumnCaster(columnType.copy()); |
| 53 | if (property.getDataType() != columnType) { |
| 54 | auto columnExpr = std::make_shared<PropertyExpression>(property); |
| 55 | columnExpr->dataType = columnType.copy(); |
| 56 | columnCaster.setCastExpr( |
| 57 | expressionBinder.forceCast(columnExpr, property.getDataType())); |
| 58 | } |
| 59 | tableInfo.addColumnInfo(tableEntry.getColumnID(propertyName), std::move(columnCaster)); |
| 60 | } else { |
| 61 | tableInfo.addColumnInfo(INVALID_COLUMN_ID, ColumnCaster(LogicalType::ANY())); |
| 62 | } |
| 63 | } |
| 64 | return tableInfo; |
| 65 | } |
| 66 | |
| 67 | static bool isRelTableQualifies(ExtendDirection direction, table_id_t srcTableID, |
| 68 | table_id_t dstTableID, table_id_t boundNodeTableID, const table_id_set_t& nbrTableISet) { |
no test coverage detected