Skip to content

Commit 0345fc1

Browse files
committed
Add external node table
1 parent cf1330d commit 0345fc1

File tree

65 files changed

+5100
-4293
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+5100
-4293
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
-DATASET CSV empty
2+
3+
--
4+
5+
-CASE ExternalDuckDBTable
6+
7+
-STATEMENT load extension "${KUZU_ROOT_DIRECTORY}/extension/duckdb/build/libduckdb.kuzu_extension"
8+
---- ok
9+
-STATEMENT ATTACH '${KUZU_ROOT_DIRECTORY}/dataset/databases/duckdb_database/tinysnb.db' as tinysnb (dbtype duckdb, skip_unsupported_table = true);
10+
---- 1
11+
Attached database successfully.
12+
-STATEMENT BEGIN TRANSACTION;
13+
---- ok
14+
-STATEMENT CREATE EXTERNAL NODE TABLE duck_person AS tinysnb.person (PRIMARY KEY (ID));
15+
---- ok
16+
-STATEMENT COMMIT;
17+
---- ok
18+
-RELOADDB
19+
-STATEMENT CALL SHOW_TABLES() RETURN *;
20+
---- 1
21+
duck_person|EXTERNAL_NODE|local(kuzu)|
22+
-STATEMENT BEGIN TRANSACTION;
23+
---- ok
24+
-STATEMENT ALTER TABLE duck_person RENAME TO d_person;
25+
---- ok
26+
-STATEMENT COMMIT;
27+
---- ok
28+
-RELOADDB
29+
-STATEMENT CALL SHOW_TABLES() RETURN *;
30+
---- 1
31+
d_person|EXTERNAL_NODE|local(kuzu)|
32+
-STATEMENT BEGIN TRANSACTION;
33+
---- ok
34+
-STATEMENT DROP TABLE d_person;
35+
---- ok
36+
-STATEMENT COMMIT;
37+
---- ok
38+
-RELOADDB
39+
-STATEMENT CALL SHOW_TABLES() RETURN *;
40+
---- 0
41+
-STATEMENT load extension "${KUZU_ROOT_DIRECTORY}/extension/duckdb/build/libduckdb.kuzu_extension"
42+
---- ok
43+
-STATEMENT ATTACH '${KUZU_ROOT_DIRECTORY}/dataset/databases/duckdb_database/tinysnb.db' as tinysnb (dbtype duckdb, skip_unsupported_table = true);
44+
---- 1
45+
Attached database successfully.
46+
-STATEMENT CREATE EXTERNAL NODE TABLE duck_person AS tinysnb.person (PRIMARY KEY (ID));
47+
---- 1
48+
Table duck_person has been created.
49+
-STATEMENT COPY duck_person FROM (LOAD FROM tinysnb.person RETURN ID);
50+
---- ok
51+
-STATEMENT MATCH (a:duck_person) RETURN a.ID, a.fName;
52+
---- 8
53+
0|Alice
54+
2|Bob
55+
3|Carol
56+
5|Dan
57+
7|Elizabeth
58+
8|Farooq
59+
9|Greg
60+
10|Hubert Blaine Wolfeschlegelsteinhausenbergerdorff

scripts/antlr4/Cypher.g4

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ EXPORT : ( 'E' | 'e' ) ( 'X' | 'x' ) ( 'P' | 'p' ) ( 'O' | 'o' ) ( 'R' | 'r' ) (
9494

9595
EXTENSION : ( 'E' | 'e' ) ( 'X' | 'x' ) ( 'T' | 't' ) ( 'E' | 'e' ) ( 'N' | 'n' ) ( 'S' | 's' ) ( 'I' | 'i' ) ( 'O' | 'o' ) ( 'N' | 'n' ) ;
9696

97+
EXTERNAL : ( 'E' | 'e' ) ( 'X' | 'x' ) ( 'T' | 't' ) ( 'E' | 'e' ) ( 'R' | 'r' ) ( 'N' | 'n' ) ( 'A' | 'a' ) ( 'L' | 'l' ) ;
98+
9799
FALSE : ( 'F' | 'f' ) ( 'A' | 'a' ) ( 'L' | 'l' ) ( 'S' | 's' ) ( 'E' | 'e' ) ;
98100

99101
FROM : ( 'F' | 'f' ) ( 'R' | 'r' ) ( 'O' | 'o' ) ( 'M' | 'm' ) ;
@@ -231,6 +233,7 @@ oC_Cypher
231233
oC_Statement
232234
: oC_Query
233235
| kU_CreateNodeTable
236+
| kU_CreateExternalNodeTable
234237
| kU_CreateRelTable
235238
| kU_CreateRelTableGroup
236239
| kU_CreateRdfGraph
@@ -318,10 +321,13 @@ kU_IfNotExists
318321
: IF SP NOT SP EXISTS ;
319322

320323
kU_CreateNodeTable
321-
: CREATE SP NODE SP TABLE SP (kU_IfNotExists SP)? oC_SchemaName SP? '(' SP? kU_PropertyDefinitions SP? ( ',' SP? kU_CreateNodeConstraint ) SP? ')' ;
324+
: CREATE SP NODE SP TABLE SP ( kU_IfNotExists SP )? oC_SchemaName SP? '(' SP? kU_PropertyDefinitions SP? ( ',' SP? kU_PrimaryKey ) SP? ')' ;
325+
326+
kU_CreateExternalNodeTable
327+
: CREATE SP EXTERNAL SP NODE SP TABLE SP oC_SchemaName SP AS SP oC_SchemaName kU_TableLookup SP? '(' SP? kU_PrimaryKey SP? ')' ;
322328

323329
kU_CreateRelTable
324-
: CREATE SP REL SP TABLE SP (kU_IfNotExists SP)? oC_SchemaName SP? '(' SP? kU_RelTableConnection SP? ( ',' SP? kU_PropertyDefinitions SP? )? ( ',' SP? oC_SymbolicName SP? )? ')' ;
330+
: CREATE SP REL SP TABLE SP ( kU_IfNotExists SP )? oC_SchemaName SP? '(' SP? kU_RelTableConnection SP? ( ',' SP? kU_PropertyDefinitions SP? )? ( ',' SP? oC_SymbolicName SP? )? ')' ;
325331

326332
kU_CreateRelTableGroup
327333
: CREATE SP REL SP TABLE SP GROUP SP (kU_IfNotExists SP)? oC_SchemaName SP? '(' SP? kU_RelTableConnection ( SP? ',' SP? kU_RelTableConnection )+ SP? ( ',' SP? kU_PropertyDefinitions SP? )? ( ',' SP? oC_SymbolicName SP? )? ')' ;
@@ -330,10 +336,10 @@ kU_RelTableConnection
330336
: FROM SP oC_SchemaName SP TO SP oC_SchemaName ;
331337

332338
kU_CreateRdfGraph
333-
: CREATE SP RDFGRAPH SP (kU_IfNotExists SP)? oC_SchemaName ;
339+
: CREATE SP RDFGRAPH SP ( kU_IfNotExists SP )? oC_SchemaName ;
334340

335341
kU_CreateSequence
336-
: CREATE SP SEQUENCE SP (kU_IfNotExists SP)? oC_SchemaName (SP kU_SequenceOptions)* ;
342+
: CREATE SP SEQUENCE SP ( kU_IfNotExists SP )? oC_SchemaName ( SP kU_SequenceOptions )* ;
337343

338344
kU_CreateType
339345
: CREATE SP TYPE SP oC_SchemaName SP AS SP kU_DataType SP? ;
@@ -393,7 +399,7 @@ kU_PropertyDefinitions : kU_PropertyDefinition ( SP? ',' SP? kU_PropertyDefiniti
393399

394400
kU_PropertyDefinition : kU_ColumnDefinition ( SP kU_Default )? ;
395401

396-
kU_CreateNodeConstraint : PRIMARY SP KEY SP? '(' SP? oC_PropertyKeyName SP? ')' ;
402+
kU_PrimaryKey : PRIMARY SP KEY SP? '(' SP? oC_PropertyKeyName SP? ')' ;
397403

398404
DECIMAL: ( 'D' | 'd' ) ( 'E' | 'e' ) ( 'C' | 'c' ) ( 'I' | 'i' ) ( 'M' | 'm' ) ( 'A' | 'a' ) ( 'L' | 'l' ) ;
399405

@@ -808,6 +814,9 @@ kU_CountSubquery
808814
oC_PropertyLookup
809815
: '.' SP? ( oC_PropertyKeyName | STAR ) ;
810816

817+
kU_TableLookup
818+
: '.' SP? oC_SchemaName ;
819+
811820
oC_CaseExpression
812821
: ( ( CASE ( SP? oC_CaseAlternative )+ ) | ( CASE SP? oC_Expression ( SP? oC_CaseAlternative )+ ) ) ( SP? ELSE SP? oC_Expression )? SP? END ;
813822

@@ -954,10 +963,6 @@ kU_NonReservedKeywords
954963
| TYPE
955964
| USE
956965
| WRITE
957-
| SINGLE
958-
| NONE
959-
| ANY
960-
| ALL
961966
;
962967

963968
UnescapedSymbolicName

scripts/antlr4/hash.md5

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
675c2985175bbbf23811cbc12a11870e
1+
2e49cc9ece0a0f04e6b8518c18f148fc

src/antlr4/Cypher.g4

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ oC_Cypher
88
oC_Statement
99
: oC_Query
1010
| kU_CreateNodeTable
11+
| kU_CreateExternalNodeTable
1112
| kU_CreateRelTable
1213
| kU_CreateRelTableGroup
1314
| kU_CreateRdfGraph
@@ -95,10 +96,13 @@ kU_IfNotExists
9596
: IF SP NOT SP EXISTS ;
9697

9798
kU_CreateNodeTable
98-
: CREATE SP NODE SP TABLE SP (kU_IfNotExists SP)? oC_SchemaName SP? '(' SP? kU_PropertyDefinitions SP? ( ',' SP? kU_CreateNodeConstraint ) SP? ')' ;
99+
: CREATE SP NODE SP TABLE SP ( kU_IfNotExists SP )? oC_SchemaName SP? '(' SP? kU_PropertyDefinitions SP? ( ',' SP? kU_PrimaryKey ) SP? ')' ;
100+
101+
kU_CreateExternalNodeTable
102+
: CREATE SP EXTERNAL SP NODE SP TABLE SP oC_SchemaName SP AS SP oC_SchemaName kU_TableLookup SP? '(' SP? kU_PrimaryKey SP? ')' ;
99103

100104
kU_CreateRelTable
101-
: CREATE SP REL SP TABLE SP (kU_IfNotExists SP)? oC_SchemaName SP? '(' SP? kU_RelTableConnection SP? ( ',' SP? kU_PropertyDefinitions SP? )? ( ',' SP? oC_SymbolicName SP? )? ')' ;
105+
: CREATE SP REL SP TABLE SP ( kU_IfNotExists SP )? oC_SchemaName SP? '(' SP? kU_RelTableConnection SP? ( ',' SP? kU_PropertyDefinitions SP? )? ( ',' SP? oC_SymbolicName SP? )? ')' ;
102106

103107
kU_CreateRelTableGroup
104108
: CREATE SP REL SP TABLE SP GROUP SP (kU_IfNotExists SP)? oC_SchemaName SP? '(' SP? kU_RelTableConnection ( SP? ',' SP? kU_RelTableConnection )+ SP? ( ',' SP? kU_PropertyDefinitions SP? )? ( ',' SP? oC_SymbolicName SP? )? ')' ;
@@ -107,10 +111,10 @@ kU_RelTableConnection
107111
: FROM SP oC_SchemaName SP TO SP oC_SchemaName ;
108112

109113
kU_CreateRdfGraph
110-
: CREATE SP RDFGRAPH SP (kU_IfNotExists SP)? oC_SchemaName ;
114+
: CREATE SP RDFGRAPH SP ( kU_IfNotExists SP )? oC_SchemaName ;
111115

112116
kU_CreateSequence
113-
: CREATE SP SEQUENCE SP (kU_IfNotExists SP)? oC_SchemaName (SP kU_SequenceOptions)* ;
117+
: CREATE SP SEQUENCE SP ( kU_IfNotExists SP )? oC_SchemaName ( SP kU_SequenceOptions )* ;
114118

115119
kU_CreateType
116120
: CREATE SP TYPE SP oC_SchemaName SP AS SP kU_DataType SP? ;
@@ -170,7 +174,7 @@ kU_PropertyDefinitions : kU_PropertyDefinition ( SP? ',' SP? kU_PropertyDefiniti
170174

171175
kU_PropertyDefinition : kU_ColumnDefinition ( SP kU_Default )? ;
172176

173-
kU_CreateNodeConstraint : PRIMARY SP KEY SP? '(' SP? oC_PropertyKeyName SP? ')' ;
177+
kU_PrimaryKey : PRIMARY SP KEY SP? '(' SP? oC_PropertyKeyName SP? ')' ;
174178

175179
DECIMAL: ( 'D' | 'd' ) ( 'E' | 'e' ) ( 'C' | 'c' ) ( 'I' | 'i' ) ( 'M' | 'm' ) ( 'A' | 'a' ) ( 'L' | 'l' ) ;
176180

@@ -585,6 +589,9 @@ kU_CountSubquery
585589
oC_PropertyLookup
586590
: '.' SP? ( oC_PropertyKeyName | STAR ) ;
587591

592+
kU_TableLookup
593+
: '.' SP? oC_SchemaName ;
594+
588595
oC_CaseExpression
589596
: ( ( CASE ( SP? oC_CaseAlternative )+ ) | ( CASE SP? oC_Expression ( SP? oC_CaseAlternative )+ ) ) ( SP? ELSE SP? oC_Expression )? SP? END ;
590597

src/antlr4/keywords.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ EXISTS
3838
EXPLAIN
3939
EXPORT
4040
EXTENSION
41+
EXTERNAL
4142
FALSE
4243
FROM
4344
GLOB

src/binder/bind/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ add_library(
2020
bind_transaction.cpp
2121
bind_updating_clause.cpp
2222
bind_extension.cpp
23+
bind_external.cpp
2324
bind_export_database.cpp
2425
bind_import_database.cpp
2526
bind_use_database.cpp)

src/binder/bind/bind_ddl.cpp

Lines changed: 57 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,14 @@ static void validatePrimaryKey(const std::string& pkColName,
107107
}
108108
}
109109

110-
BoundCreateTableInfo Binder::bindCreateTableInfo(const parser::CreateTableInfo* info) {
111-
switch (info->tableType) {
110+
BoundCreateTableInfo Binder::bindCreateTableInfo(const parser::CreateTableInfo& info) {
111+
switch (info.tableType) {
112112
case TableType::NODE: {
113113
return bindCreateNodeTableInfo(info);
114114
}
115+
case TableType::EXTERNAL_NODE: {
116+
return bindCreateExternalNodeTableInfo(info);
117+
}
115118
case TableType::REL: {
116119
return bindCreateRelTableInfo(info);
117120
}
@@ -127,24 +130,57 @@ BoundCreateTableInfo Binder::bindCreateTableInfo(const parser::CreateTableInfo*
127130
}
128131
}
129132

130-
BoundCreateTableInfo Binder::bindCreateNodeTableInfo(const CreateTableInfo* info) {
131-
auto propertyDefinitions = bindPropertyDefinitions(info->propertyDefinitions, info->tableName);
132-
auto& extraInfo = info->extraInfo->constCast<ExtraCreateNodeTableInfo>();
133+
BoundCreateTableInfo Binder::bindCreateNodeTableInfo(const CreateTableInfo& info) {
134+
auto propertyDefinitions = bindPropertyDefinitions(info.propertyDefinitions, info.tableName);
135+
auto& extraInfo = info.extraInfo->constCast<ExtraCreateNodeTableInfo>();
133136
validatePrimaryKey(extraInfo.pKName, propertyDefinitions);
134137
auto boundExtraInfo = std::make_unique<BoundExtraCreateNodeTableInfo>(extraInfo.pKName,
135138
std::move(propertyDefinitions));
136-
return BoundCreateTableInfo(TableType::NODE, info->tableName, info->onConflict,
139+
return BoundCreateTableInfo(TableType::NODE, info.tableName, info.onConflict,
137140
std::move(boundExtraInfo));
138141
}
139142

140-
BoundCreateTableInfo Binder::bindCreateRelTableInfo(const CreateTableInfo* info) {
143+
static PropertyDefinition getDefinition(const std::vector<PropertyDefinition>& definitions, const std::string& name) {
144+
for (auto& definition : definitions) {
145+
if (definition.getName() == name) {
146+
return definition.copy();
147+
}
148+
}
149+
// LCOV_EXCL_START
150+
throw BinderException(stringFormat("Cannot find property with name {}.", name));
151+
// LCOV_EXCL_STOP
152+
}
153+
154+
static std::string getPhysicalTableName(std::string name) {
155+
return "_" + name;
156+
}
157+
158+
BoundCreateTableInfo Binder::bindCreateExternalNodeTableInfo(const CreateTableInfo& info) {
159+
auto& extraInfo = info.extraInfo->constCast<ExtraCreateExternalNodeTableInfo>();
160+
auto entry = bindExternalTableEntry(extraInfo.dbName, extraInfo.tableName);
161+
auto& propertyDefinitions = entry->getProperties();
162+
// Bind physical create node table info
163+
auto pkDefinition = getDefinition(propertyDefinitions, extraInfo.pkName);
164+
std::vector<PropertyDefinition> physicalPropertyDefinitions;
165+
physicalPropertyDefinitions.push_back(pkDefinition.copy());
166+
auto boundPhysicalExtraInfo = std::make_unique<BoundExtraCreateNodeTableInfo>(extraInfo.pkName, std::move(physicalPropertyDefinitions));
167+
auto boundPhysicalCreateInfo = BoundCreateTableInfo(TableType::NODE,
168+
getPhysicalTableName(info.tableName), ConflictAction::ON_CONFLICT_THROW,
169+
std::move(boundPhysicalExtraInfo));
170+
// Bind create node table reference info
171+
auto boundExtraInfo = std::make_unique<BoundExtraCreateExternalNodeTableInfo>(extraInfo.pkName,
172+
extraInfo.dbName, extraInfo.tableName, std::move(boundPhysicalCreateInfo), copyVector(propertyDefinitions));
173+
return BoundCreateTableInfo(TableType::EXTERNAL_NODE, info.tableName, info.onConflict, std::move(boundExtraInfo));
174+
}
175+
176+
BoundCreateTableInfo Binder::bindCreateRelTableInfo(const CreateTableInfo& info) {
141177
std::vector<PropertyDefinition> propertyDefinitions;
142178
propertyDefinitions.emplace_back(
143179
ColumnDefinition(InternalKeyword::ID, LogicalType::INTERNAL_ID()));
144-
for (auto& definition : bindPropertyDefinitions(info->propertyDefinitions, info->tableName)) {
180+
for (auto& definition : bindPropertyDefinitions(info.propertyDefinitions, info.tableName)) {
145181
propertyDefinitions.push_back(definition.copy());
146182
}
147-
auto& extraInfo = info->extraInfo->constCast<ExtraCreateRelTableInfo>();
183+
auto& extraInfo = info.extraInfo->constCast<ExtraCreateRelTableInfo>();
148184
auto srcMultiplicity = RelMultiplicityUtils::getFwd(extraInfo.relMultiplicity);
149185
auto dstMultiplicity = RelMultiplicityUtils::getBwd(extraInfo.relMultiplicity);
150186
auto srcTableID = bindTableID(extraInfo.srcTableName);
@@ -153,7 +189,7 @@ BoundCreateTableInfo Binder::bindCreateRelTableInfo(const CreateTableInfo* info)
153189
validateTableType(dstTableID, TableType::NODE);
154190
auto boundExtraInfo = std::make_unique<BoundExtraCreateRelTableInfo>(srcMultiplicity,
155191
dstMultiplicity, srcTableID, dstTableID, std::move(propertyDefinitions));
156-
return BoundCreateTableInfo(TableType::REL, info->tableName, info->onConflict,
192+
return BoundCreateTableInfo(TableType::REL, info.tableName, info.onConflict,
157193
std::move(boundExtraInfo));
158194
}
159195

@@ -162,29 +198,29 @@ static std::string getRelGroupTableName(const std::string& relGroupName,
162198
return relGroupName + "_" + srcTableName + "_" + dstTableName;
163199
}
164200

165-
BoundCreateTableInfo Binder::bindCreateRelTableGroupInfo(const CreateTableInfo* info) {
166-
auto relGroupName = info->tableName;
167-
auto& extraInfo = info->extraInfo->constCast<ExtraCreateRelTableGroupInfo>();
201+
BoundCreateTableInfo Binder::bindCreateRelTableGroupInfo(const CreateTableInfo& info) {
202+
auto relGroupName = info.tableName;
203+
auto& extraInfo = info.extraInfo->constCast<ExtraCreateRelTableGroupInfo>();
168204
auto relMultiplicity = extraInfo.relMultiplicity;
169205
std::vector<BoundCreateTableInfo> boundCreateRelTableInfos;
170-
auto relCreateInfo = std::make_unique<CreateTableInfo>(TableType::REL, "", info->onConflict);
171-
relCreateInfo->propertyDefinitions = copyVector(info->propertyDefinitions);
206+
auto relCreateInfo = CreateTableInfo(TableType::REL, "", info.onConflict);
207+
relCreateInfo.propertyDefinitions = copyVector(info.propertyDefinitions);
172208
for (auto& [srcTableName, dstTableName] : extraInfo.srcDstTablePairs) {
173-
relCreateInfo->tableName = getRelGroupTableName(relGroupName, srcTableName, dstTableName);
174-
relCreateInfo->extraInfo =
209+
relCreateInfo.tableName = getRelGroupTableName(relGroupName, srcTableName, dstTableName);
210+
relCreateInfo.extraInfo =
175211
std::make_unique<ExtraCreateRelTableInfo>(relMultiplicity, srcTableName, dstTableName);
176-
boundCreateRelTableInfos.push_back(bindCreateRelTableInfo(relCreateInfo.get()));
212+
boundCreateRelTableInfos.push_back(bindCreateRelTableInfo(relCreateInfo));
177213
}
178214
auto boundExtraInfo =
179215
std::make_unique<BoundExtraCreateRelTableGroupInfo>(std::move(boundCreateRelTableInfos));
180-
return BoundCreateTableInfo(TableType::REL_GROUP, info->tableName, info->onConflict,
216+
return BoundCreateTableInfo(TableType::REL_GROUP, info.tableName, info.onConflict,
181217
std::move(boundExtraInfo));
182218
}
183219

184220
std::unique_ptr<BoundStatement> Binder::bindCreateTable(const Statement& statement) {
185221
auto createTable = statement.constPtrCast<CreateTable>();
186-
auto tableName = createTable->getInfo()->tableName;
187-
switch (createTable->getInfo()->onConflict) {
222+
auto tableName = createTable->getInfo().tableName;
223+
switch (createTable->getInfo().onConflict) {
188224
case common::ConflictAction::ON_CONFLICT_THROW: {
189225
if (clientContext->getCatalog()->containsTable(clientContext->getTx(), tableName)) {
190226
throw BinderException(tableName + " already exists in catalog.");

src/binder/bind/bind_external.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#include "binder/binder.h"
2+
#include "main/database_manager.h"
3+
#include "common/exception/binder.h"
4+
#include "main/client_context.h"
5+
#include "catalog/catalog_entry/external_node_table_catalog_entry.h"
6+
7+
using namespace kuzu::common;
8+
using namespace kuzu::catalog;
9+
10+
namespace kuzu {
11+
namespace binder {
12+
13+
catalog::TableCatalogEntry* Binder::bindExternalTableEntry(const std::string& dbName,
14+
const std::string& tableName) {
15+
auto attachedDB = clientContext->getDatabaseManager()->getAttachedDatabase(dbName);
16+
if (attachedDB == nullptr) {
17+
throw BinderException{stringFormat("No database named {} has been attached.", dbName)};
18+
}
19+
auto attachedCatalog = attachedDB->getCatalog();
20+
auto tableID = attachedCatalog->getTableID(clientContext->getTx(), tableName);
21+
return attachedCatalog->getTableCatalogEntry(clientContext->getTx(), tableID);
22+
}
23+
24+
void Binder::bindExternalTableEntry(NodeOrRelExpression& nodeOrRel) {
25+
if (nodeOrRel.isMultiLabeled() || nodeOrRel.isEmpty()) {
26+
return ;
27+
}
28+
auto entry = nodeOrRel.getSingleEntry();
29+
switch (entry->getType()) {
30+
case CatalogEntryType::EXTERNAL_NODE_TABLE_ENTRY: {
31+
auto& tableEntry = entry->constCast<ExternalNodeTableCatalogEntry>();
32+
auto externalEntry = bindExternalTableEntry(tableEntry.getExternalDBName(), tableEntry.getExternalTableName());
33+
nodeOrRel.setExternalEntry(externalEntry);
34+
} break ;
35+
default:
36+
break;
37+
}
38+
}
39+
40+
}
41+
}

0 commit comments

Comments
 (0)