| 137 | } |
| 138 | |
| 139 | ArrowTableCreationResult ArrowTableSupport::createRelTableFromArrowTable( |
| 140 | main::Connection& connection, const std::string& tableName, const std::string& srcTableName, |
| 141 | const std::string& dstTableName, ArrowSchemaWrapper schema, |
| 142 | std::vector<ArrowArrayWrapper> arrays, const std::string& srcColumnName, |
| 143 | const std::string& dstColumnName) { |
| 144 | if (srcColumnName != "from" || dstColumnName != "to") { |
| 145 | throw common::RuntimeException( |
| 146 | "Arrow relationship registration currently requires endpoint columns named 'from' and " |
| 147 | "'to'"); |
| 148 | } |
| 149 | |
| 150 | int64_t numColumns = schema.n_children; |
| 151 | if (numColumns < 2) { |
| 152 | throw common::RuntimeException( |
| 153 | "Arrow relationship table must contain at least source and destination columns"); |
| 154 | } |
| 155 | |
| 156 | auto srcColIdx = findArrowColumnByName(schema, srcColumnName); |
| 157 | auto dstColIdx = findArrowColumnByName(schema, dstColumnName); |
| 158 | if (srcColIdx < 0 || dstColIdx < 0) { |
| 159 | throw common::RuntimeException("Arrow relationship table must include endpoint columns '" + |
| 160 | srcColumnName + "' and '" + dstColumnName + "'"); |
| 161 | } |
| 162 | if (srcColIdx == dstColIdx) { |
| 163 | throw common::RuntimeException("Source and destination endpoint columns must be distinct"); |
| 164 | } |
| 165 | |
| 166 | std::vector<std::string> propertyDefs; |
| 167 | for (int64_t i = 0; i < numColumns; ++i) { |
| 168 | if (i == srcColIdx || i == dstColIdx) { |
| 169 | continue; |
| 170 | } |
| 171 | std::string colName = schema.children[i]->name; |
| 172 | std::string colType = |
| 173 | common::ArrowConverter::fromArrowSchema(schema.children[i]).toString(); |
| 174 | propertyDefs.push_back(colName + " " + colType); |
| 175 | } |
| 176 | |
| 177 | std::vector<std::string> relDefs; |
| 178 | relDefs.push_back("FROM " + srcTableName + " TO " + dstTableName); |
| 179 | relDefs.insert(relDefs.end(), propertyDefs.begin(), propertyDefs.end()); |
| 180 | std::string tableDef = "(" + join(relDefs, ", ") + ")"; |
| 181 | |
| 182 | ArrowRelTableData data; |
| 183 | data.layout = ArrowRelTableLayout::FLAT; |
| 184 | data.schema = std::move(schema); |
| 185 | data.arrays = std::move(arrays); |
| 186 | std::string arrowId = registerArrowRelData(std::move(data)); |
| 187 | |
| 188 | std::string statement = "CREATE REL TABLE " + tableName + " " + tableDef + |
| 189 | " WITH (storage='arrow://" + arrowId + "')"; |
| 190 | auto queryResult = connection.query(statement); |
| 191 | if (!queryResult->isSuccess()) { |
| 192 | unregisterArrowData(arrowId); |
| 193 | } |
| 194 | |
| 195 | return {std::move(queryResult), arrowId}; |
| 196 | } |