@@ -108,11 +108,14 @@ static void validatePrimaryKey(const std::string& pkColName,
108108 }
109109}
110110
111- BoundCreateTableInfo Binder::bindCreateTableInfo (const parser::CreateTableInfo* info) {
112- switch (info-> tableType ) {
111+ BoundCreateTableInfo Binder::bindCreateTableInfo (const parser::CreateTableInfo& info) {
112+ switch (info. tableType ) {
113113 case TableType::NODE : {
114114 return bindCreateNodeTableInfo (info);
115115 }
116+ case TableType::EXTERNAL_NODE : {
117+ return bindCreateExternalNodeTableInfo (info);
118+ }
116119 case TableType::REL : {
117120 return bindCreateRelTableInfo (info);
118121 }
@@ -128,24 +131,57 @@ BoundCreateTableInfo Binder::bindCreateTableInfo(const parser::CreateTableInfo*
128131 }
129132}
130133
131- BoundCreateTableInfo Binder::bindCreateNodeTableInfo (const CreateTableInfo* info) {
132- auto propertyDefinitions = bindPropertyDefinitions (info-> propertyDefinitions , info-> tableName );
133- auto & extraInfo = info-> extraInfo ->constCast <ExtraCreateNodeTableInfo>();
134+ BoundCreateTableInfo Binder::bindCreateNodeTableInfo (const CreateTableInfo& info) {
135+ auto propertyDefinitions = bindPropertyDefinitions (info. propertyDefinitions , info. tableName );
136+ auto & extraInfo = info. extraInfo ->constCast <ExtraCreateNodeTableInfo>();
134137 validatePrimaryKey (extraInfo.pKName , propertyDefinitions);
135138 auto boundExtraInfo = std::make_unique<BoundExtraCreateNodeTableInfo>(extraInfo.pKName ,
136139 std::move (propertyDefinitions));
137- return BoundCreateTableInfo (TableType::NODE , info-> tableName , info-> onConflict ,
140+ return BoundCreateTableInfo (TableType::NODE , info. tableName , info. onConflict ,
138141 std::move (boundExtraInfo));
139142}
140143
141- BoundCreateTableInfo Binder::bindCreateRelTableInfo (const CreateTableInfo* info) {
144+ static PropertyDefinition getDefinition (const std::vector<PropertyDefinition>& definitions, const std::string& name) {
145+ for (auto & definition : definitions) {
146+ if (definition.getName () == name) {
147+ return definition.copy ();
148+ }
149+ }
150+ // LCOV_EXCL_START
151+ throw BinderException (stringFormat (" Cannot find property with name {}." , name));
152+ // LCOV_EXCL_STOP
153+ }
154+
155+ static std::string getPhysicalTableName (std::string name) {
156+ return " _" + name;
157+ }
158+
159+ BoundCreateTableInfo Binder::bindCreateExternalNodeTableInfo (const CreateTableInfo& info) {
160+ auto & extraInfo = info.extraInfo ->constCast <ExtraCreateExternalNodeTableInfo>();
161+ auto entry = bindExternalTableEntry (extraInfo.dbName , extraInfo.tableName );
162+ auto & propertyDefinitions = entry->getProperties ();
163+ // Bind physical create node table info
164+ auto pkDefinition = getDefinition (propertyDefinitions, extraInfo.pkName );
165+ std::vector<PropertyDefinition> physicalPropertyDefinitions;
166+ physicalPropertyDefinitions.push_back (pkDefinition.copy ());
167+ auto boundPhysicalExtraInfo = std::make_unique<BoundExtraCreateNodeTableInfo>(extraInfo.pkName , std::move (physicalPropertyDefinitions));
168+ auto boundPhysicalCreateInfo = BoundCreateTableInfo (TableType::NODE ,
169+ getPhysicalTableName (info.tableName ), ConflictAction::ON_CONFLICT_THROW ,
170+ std::move (boundPhysicalExtraInfo));
171+ // Bind create node table reference info
172+ auto boundExtraInfo = std::make_unique<BoundExtraCreateExternalNodeTableInfo>(extraInfo.pkName ,
173+ extraInfo.dbName , extraInfo.tableName , std::move (boundPhysicalCreateInfo), copyVector (propertyDefinitions));
174+ return BoundCreateTableInfo (TableType::EXTERNAL_NODE , info.tableName , info.onConflict , std::move (boundExtraInfo));
175+ }
176+
177+ BoundCreateTableInfo Binder::bindCreateRelTableInfo (const CreateTableInfo& info) {
142178 std::vector<PropertyDefinition> propertyDefinitions;
143179 propertyDefinitions.emplace_back (
144180 ColumnDefinition (InternalKeyword::ID , LogicalType::INTERNAL_ID ()));
145- for (auto & definition : bindPropertyDefinitions (info-> propertyDefinitions , info-> tableName )) {
181+ for (auto & definition : bindPropertyDefinitions (info. propertyDefinitions , info. tableName )) {
146182 propertyDefinitions.push_back (definition.copy ());
147183 }
148- auto & extraInfo = info-> extraInfo ->constCast <ExtraCreateRelTableInfo>();
184+ auto & extraInfo = info. extraInfo ->constCast <ExtraCreateRelTableInfo>();
149185 auto srcMultiplicity = RelMultiplicityUtils::getFwd (extraInfo.relMultiplicity );
150186 auto dstMultiplicity = RelMultiplicityUtils::getBwd (extraInfo.relMultiplicity );
151187 auto srcTableID = bindTableID (extraInfo.srcTableName );
@@ -154,7 +190,7 @@ BoundCreateTableInfo Binder::bindCreateRelTableInfo(const CreateTableInfo* info)
154190 validateTableType (dstTableID, TableType::NODE );
155191 auto boundExtraInfo = std::make_unique<BoundExtraCreateRelTableInfo>(srcMultiplicity,
156192 dstMultiplicity, srcTableID, dstTableID, std::move (propertyDefinitions));
157- return BoundCreateTableInfo (TableType::REL , info-> tableName , info-> onConflict ,
193+ return BoundCreateTableInfo (TableType::REL , info. tableName , info. onConflict ,
158194 std::move (boundExtraInfo));
159195}
160196
@@ -163,29 +199,29 @@ static std::string getRelGroupTableName(const std::string& relGroupName,
163199 return relGroupName + " _" + srcTableName + " _" + dstTableName;
164200}
165201
166- BoundCreateTableInfo Binder::bindCreateRelTableGroupInfo (const CreateTableInfo* info) {
167- auto relGroupName = info-> tableName ;
168- auto & extraInfo = info-> extraInfo ->constCast <ExtraCreateRelTableGroupInfo>();
202+ BoundCreateTableInfo Binder::bindCreateRelTableGroupInfo (const CreateTableInfo& info) {
203+ auto relGroupName = info. tableName ;
204+ auto & extraInfo = info. extraInfo ->constCast <ExtraCreateRelTableGroupInfo>();
169205 auto relMultiplicity = extraInfo.relMultiplicity ;
170206 std::vector<BoundCreateTableInfo> boundCreateRelTableInfos;
171- auto relCreateInfo = std::make_unique< CreateTableInfo> (TableType::REL , " " , info-> onConflict );
172- relCreateInfo-> propertyDefinitions = copyVector (info-> propertyDefinitions );
207+ auto relCreateInfo = CreateTableInfo (TableType::REL , " " , info. onConflict );
208+ relCreateInfo. propertyDefinitions = copyVector (info. propertyDefinitions );
173209 for (auto & [srcTableName, dstTableName] : extraInfo.srcDstTablePairs ) {
174- relCreateInfo-> tableName = getRelGroupTableName (relGroupName, srcTableName, dstTableName);
175- relCreateInfo-> extraInfo =
210+ relCreateInfo. tableName = getRelGroupTableName (relGroupName, srcTableName, dstTableName);
211+ relCreateInfo. extraInfo =
176212 std::make_unique<ExtraCreateRelTableInfo>(relMultiplicity, srcTableName, dstTableName);
177- boundCreateRelTableInfos.push_back (bindCreateRelTableInfo (relCreateInfo. get () ));
213+ boundCreateRelTableInfos.push_back (bindCreateRelTableInfo (relCreateInfo));
178214 }
179215 auto boundExtraInfo =
180216 std::make_unique<BoundExtraCreateRelTableGroupInfo>(std::move (boundCreateRelTableInfos));
181- return BoundCreateTableInfo (TableType::REL_GROUP , info-> tableName , info-> onConflict ,
217+ return BoundCreateTableInfo (TableType::REL_GROUP , info. tableName , info. onConflict ,
182218 std::move (boundExtraInfo));
183219}
184220
185221std::unique_ptr<BoundStatement> Binder::bindCreateTable (const Statement& statement) {
186222 auto createTable = statement.constPtrCast <CreateTable>();
187- auto tableName = createTable->getInfo ()-> tableName ;
188- switch (createTable->getInfo ()-> onConflict ) {
223+ auto tableName = createTable->getInfo (). tableName ;
224+ switch (createTable->getInfo (). onConflict ) {
189225 case common::ConflictAction::ON_CONFLICT_THROW : {
190226 if (clientContext->getCatalog ()->containsTable (clientContext->getTx (), tableName)) {
191227 throw BinderException (tableName + " already exists in catalog." );
0 commit comments