#pragma once
#include <unordered_map>
#include <utility>
#include "binder/binder_scope.h"
#include "binder/expression_binder.h"
#include "binder/query/bound_regular_query.h"
#include "binder/query/query_graph.h"
#include "catalog/catalog_entry/table_catalog_entry.h"
#include "common/copier_config/file_scan_info.h"
#include "parser/ddl/parsed_property_definition.h"
#include "parser/query/graph_pattern/pattern_element.h"
namespace lbug {
namespace extension {
class BinderExtension;
}
namespace parser {
class ProjectionBody;
class ReturnClause;
class WithClause;
class UpdatingClause;
class ReadingClause;
class QueryPart;
class SingleQuery;
struct CreateTableInfo;
struct BaseScanSource;
struct JoinHintNode;
class Statement;
struct YieldVariable;
}
namespace catalog {
class NodeTableCatalogEntry;
class RelGroupCatalogEntry;
class Catalog;
}
namespace main {
class ClientContext;
class Database;
}
namespace function {
struct TableFunction;
}
namespace transaction {
class Transaction;
}
namespace binder {
struct BoundBaseScanSource;
struct BoundCreateTableInfo;
struct BoundInsertInfo;
struct BoundSetPropertyInfo;
struct BoundDeleteInfo;
class BoundWithClause;
class BoundReturnClause;
struct ExportedTableData;
struct BoundJoinHintNode;
struct BoundCopyFromInfo;
struct BoundTableScanInfo;
class Binder {
friend class ExpressionBinder;
public:
explicit Binder(main::ClientContext* clientContext,
std::vector<extension::BinderExtension*> binderExtensions = {})
: lastExpressionId{0}, scope{}, expressionBinder{this, clientContext},
clientContext{clientContext}, binderExtensions{std::move(binderExtensions)} {}
LBUG_API std::unique_ptr<BoundStatement> bind(const parser::Statement& statement);
LBUG_API std::shared_ptr<Expression> createVariable(const std::string& name,
const common::LogicalType& dataType);
LBUG_API std::shared_ptr<Expression> createInvisibleVariable(const std::string& name,
const common::LogicalType& dataType) const;
LBUG_API expression_vector createVariables(const std::vector<std::string>& names,
const std::vector<common::LogicalType>& types);
LBUG_API expression_vector createInvisibleVariables(const std::vector<std::string>& names,
const std::vector<common::LogicalType>& types) const;
std::shared_ptr<Expression> bindWhereExpression(
const parser::ParsedExpression& parsedExpression);
std::shared_ptr<Expression> createVariable(std::string_view name, common::LogicalTypeID typeID);
std::shared_ptr<Expression> createVariable(const std::string& name,
common::LogicalTypeID logicalTypeID);
BoundCreateTableInfo bindCreateTableInfo(const parser::CreateTableInfo* info);
BoundCreateTableInfo bindCreateNodeTableInfo(const parser::CreateTableInfo* info);
BoundCreateTableInfo bindCreateRelTableGroupInfo(const parser::CreateTableInfo* info);
std::unique_ptr<BoundStatement> bindCreateTable(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindCreateTableAs(const parser::Statement& createTable);
std::unique_ptr<BoundStatement> bindCreateType(const parser::Statement& statement) const;
std::unique_ptr<BoundStatement> bindCreateSequence(const parser::Statement& statement) const;
static std::unique_ptr<BoundStatement> bindDrop(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindAlter(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindRenameTable(const parser::Statement& statement) const;
std::unique_ptr<BoundStatement> bindAddProperty(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindDropProperty(const parser::Statement& statement) const;
std::unique_ptr<BoundStatement> bindRenameProperty(const parser::Statement& statement) const;
std::unique_ptr<BoundStatement> bindCommentOn(const parser::Statement& statement) const;
std::unique_ptr<BoundStatement> bindAlterFromToConnection(
const parser::Statement& statement) const;
std::vector<PropertyDefinition> bindPropertyDefinitions(
const std::vector<parser::ParsedPropertyDefinition>& parsedDefinitions,
const std::string& tableName);
std::unique_ptr<parser::ParsedExpression> resolvePropertyDefault(
parser::ParsedExpression* parsedDefault, const common::LogicalType& type,
const std::string& tableName, const std::string& propertyName);
BoundCopyFromInfo bindCopyNodeFromInfo(std::string tableName,
const std::vector<PropertyDefinition>& properties, const parser::BaseScanSource* source,
const parser::options_t& parsingOptions,
const std::vector<std::string>& expectedColumnNames,
const std::vector<common::LogicalType>& expectedColumnTypes, bool byColumn);
BoundCopyFromInfo bindCopyRelFromInfo(std::string tableName,
const std::vector<PropertyDefinition>& properties, const parser::BaseScanSource* source,
const parser::options_t& parsingOptions,
const std::vector<std::string>& expectedColumnNames,
const std::vector<common::LogicalType>& expectedColumnTypes,
const catalog::NodeTableCatalogEntry* fromTable,
const catalog::NodeTableCatalogEntry* toTable);
std::unique_ptr<BoundStatement> bindCopyFromClause(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindCopyNodeFrom(const parser::Statement& statement,
catalog::NodeTableCatalogEntry& nodeEntry);
std::unique_ptr<BoundStatement> bindCopyRelFrom(const parser::Statement& statement,
catalog::RelGroupCatalogEntry& relGroupEntry, const std::string& fromTableName,
const std::string& toTableName);
std::unique_ptr<BoundStatement> bindLegacyCopyRelGroupFrom(const parser::Statement& copyFrom);
std::unique_ptr<BoundStatement> bindCopyToClause(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindExportDatabaseClause(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindImportDatabaseClause(const parser::Statement& statement);
static std::unique_ptr<BoundStatement> bindAttachDatabase(const parser::Statement& statement);
static std::unique_ptr<BoundStatement> bindDetachDatabase(const parser::Statement& statement);
static std::unique_ptr<BoundStatement> bindUseDatabase(const parser::Statement& statement);
static std::unique_ptr<BoundStatement> bindCreateGraph(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindUseGraph(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindExtensionClause(const parser::Statement& statement);
std::unique_ptr<BoundBaseScanSource> bindScanSource(const parser::BaseScanSource* source,
const parser::options_t& options, const std::vector<std::string>& columnNames,
const std::vector<common::LogicalType>& columnTypes);
std::unique_ptr<BoundBaseScanSource> bindFileScanSource(
const parser::BaseScanSource& scanSource, const parser::options_t& options,
const std::vector<std::string>& columnNames,
const std::vector<common::LogicalType>& columnTypes);
std::unique_ptr<BoundBaseScanSource> bindQueryScanSource(
const parser::BaseScanSource& scanSource, const parser::options_t& options,
const std::vector<std::string>& columnNames,
const std::vector<common::LogicalType>& columnTypes);
std::unique_ptr<BoundBaseScanSource> bindObjectScanSource(
const parser::BaseScanSource& scanSource, const parser::options_t& options,
const std::vector<std::string>& columnNames,
const std::vector<common::LogicalType>& columnTypes);
std::unique_ptr<BoundBaseScanSource> bindParameterScanSource(
const parser::BaseScanSource& scanSource, const parser::options_t& options,
const std::vector<std::string>& columnNames,
const std::vector<common::LogicalType>& columnTypes);
std::unique_ptr<BoundBaseScanSource> bindTableFuncScanSource(
const parser::BaseScanSource& scanSource, const parser::options_t& options,
const std::vector<std::string>& columnNames,
const std::vector<common::LogicalType>& columnTypes);
common::case_insensitive_map_t<common::Value> bindParsingOptions(
const parser::options_t& parsingOptions);
common::FileTypeInfo bindFileTypeInfo(const std::vector<std::string>& filePaths) const;
std::vector<std::string> bindFilePaths(const std::vector<std::string>& filePaths) const;
std::unique_ptr<BoundRegularQuery> bindQuery(const parser::Statement& statement);
NormalizedSingleQuery bindSingleQuery(const parser::SingleQuery& singleQuery);
NormalizedQueryPart bindQueryPart(const parser::QueryPart& queryPart);
std::unique_ptr<BoundStatement> bindStandaloneCall(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindStandaloneCallFunction(const parser::Statement& statement);
BoundTableScanInfo bindTableFunc(const std::string& tableFuncName,
const parser::ParsedExpression& expr, std::vector<parser::YieldVariable> yieldVariables);
std::unique_ptr<BoundStatement> bindCreateMacro(const parser::Statement& statement) const;
static std::unique_ptr<BoundStatement> bindTransaction(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindExtension(const parser::Statement& statement);
std::unique_ptr<BoundStatement> bindExplain(const parser::Statement& statement);
std::unique_ptr<BoundReadingClause> bindReadingClause(
const parser::ReadingClause& readingClause);
std::unique_ptr<BoundReadingClause> bindMatchClause(const parser::ReadingClause& readingClause);
std::shared_ptr<BoundJoinHintNode> bindJoinHint(
const QueryGraphCollection& queryGraphCollection, const parser::JoinHintNode& joinHintNode);
std::shared_ptr<BoundJoinHintNode> bindJoinNode(const parser::JoinHintNode& joinHintNode);
void rewriteMatchPattern(BoundGraphPattern& boundGraphPattern);
std::unique_ptr<BoundReadingClause> bindUnwindClause(
const parser::ReadingClause& readingClause);
std::unique_ptr<BoundReadingClause> bindInQueryCall(const parser::ReadingClause& readingClause);
std::unique_ptr<BoundReadingClause> bindLoadFrom(const parser::ReadingClause& readingClause);
std::unique_ptr<BoundUpdatingClause> bindUpdatingClause(
const parser::UpdatingClause& updatingClause);
std::unique_ptr<BoundUpdatingClause> bindInsertClause(
const parser::UpdatingClause& updatingClause);
std::unique_ptr<BoundUpdatingClause> bindMergeClause(
const parser::UpdatingClause& updatingClause);
std::unique_ptr<BoundUpdatingClause> bindSetClause(
const parser::UpdatingClause& updatingClause);
std::unique_ptr<BoundUpdatingClause> bindDeleteClause(
const parser::UpdatingClause& updatingClause);
std::vector<BoundInsertInfo> bindInsertInfos(QueryGraphCollection& queryGraphCollection,
const std::unordered_set<std::string>& patternsInScope_);
void bindInsertNode(std::shared_ptr<NodeExpression> node, std::vector<BoundInsertInfo>& infos);
void bindInsertRel(std::shared_ptr<RelExpression> rel, std::vector<BoundInsertInfo>& infos);
expression_vector bindInsertColumnDataExprs(
const common::case_insensitive_map_t<std::shared_ptr<Expression>>& propertyDataExprs,
const std::vector<PropertyDefinition>& propertyDefinitions);
BoundSetPropertyInfo bindSetPropertyInfo(const parser::ParsedExpression* column,
const parser::ParsedExpression* columnData);
expression_pair bindSetItem(const parser::ParsedExpression* column,
const parser::ParsedExpression* columnData);
BoundWithClause bindWithClause(const parser::WithClause& withClause);
BoundReturnClause bindReturnClause(const parser::ReturnClause& returnClause);
std::pair<expression_vector, std::vector<std::string>> bindProjectionList(
const parser::ProjectionBody& projectionBody);
BoundProjectionBody bindProjectionBody(const parser::ProjectionBody& projectionBody,
const expression_vector& projectionExprs, const std::vector<std::string>& aliases);
expression_vector bindOrderByExpressions(
const std::vector<std::unique_ptr<parser::ParsedExpression>>& parsedExprs);
std::shared_ptr<Expression> bindSkipLimitExpression(const parser::ParsedExpression& expression);
BoundGraphPattern bindGraphPattern(const std::vector<parser::PatternElement>& graphPattern);
QueryGraph bindPatternElement(const parser::PatternElement& patternElement);
std::shared_ptr<Expression> createPath(const std::string& pathName,
const expression_vector& children);
std::shared_ptr<RelExpression> bindQueryRel(const parser::RelPattern& relPattern,
const std::shared_ptr<NodeExpression>& leftNode,
const std::shared_ptr<NodeExpression>& rightNode, QueryGraph& queryGraph);
std::shared_ptr<RelExpression> createNonRecursiveQueryRel(const std::string& parsedName,
const std::vector<catalog::TableCatalogEntry*>& entries,
std::shared_ptr<NodeExpression> srcNode, std::shared_ptr<NodeExpression> dstNode,
RelDirectionType directionType, const std::vector<std::string>& originalLabels);
std::shared_ptr<RelExpression> createRecursiveQueryRel(const parser::RelPattern& relPattern,
const std::vector<catalog::TableCatalogEntry*>& entries,
std::shared_ptr<NodeExpression> srcNode, std::shared_ptr<NodeExpression> dstNode,
RelDirectionType directionType);
expression_vector bindRecursivePatternNodeProjectionList(
const parser::RecursiveRelPatternInfo& info, const NodeOrRelExpression& expr);
expression_vector bindRecursivePatternRelProjectionList(
const parser::RecursiveRelPatternInfo& info, const NodeOrRelExpression& expr);
std::pair<uint64_t, uint64_t> bindVariableLengthRelBound(const parser::RelPattern& relPattern);
std::shared_ptr<NodeExpression> bindQueryNode(const parser::NodePattern& nodePattern,
QueryGraph& queryGraph);
std::shared_ptr<NodeExpression> createQueryNode(const parser::NodePattern& nodePattern);
LBUG_API std::shared_ptr<NodeExpression> createQueryNode(const std::string& parsedName,
const std::vector<catalog::TableCatalogEntry*>& entries,
const std::unordered_map<catalog::TableCatalogEntry*, std::string>& dbNames = {},
const std::vector<std::string>& originalLabels = {});
std::pair<std::vector<catalog::TableCatalogEntry*>,
std::unordered_map<catalog::TableCatalogEntry*, std::string>>
bindNodeTableEntries(const std::vector<std::string>& tableNames) const;
std::vector<catalog::TableCatalogEntry*> bindRelGroupEntries(
const std::vector<std::string>& tableNames) const;
std::pair<catalog::TableCatalogEntry*, std::string> bindNodeTableEntry(
const std::string& name) const;
std::vector<PropertyDefinition> bindRelPropertyDefinitions(const parser::CreateTableInfo& info);
LBUG_API static void validateTableExistence(const main::ClientContext& context,
const std::string& tableName);
LBUG_API static void validateNodeTableType(const catalog::TableCatalogEntry* entry);
LBUG_API static void validateColumnExistence(const catalog::TableCatalogEntry* entry,
const std::string& columnName);
std::string getUniqueExpressionName(const std::string& name);
static bool reservedInColumnName(const std::string& name);
static bool reservedInPropertyLookup(const std::string& name);
void addToScope(const std::vector<std::string>& names, const expression_vector& exprs);
LBUG_API void addToScope(const std::string& name, std::shared_ptr<Expression> expr);
BinderScope saveScope() const;
void restoreScope(BinderScope prevScope);
void replaceExpressionInScope(const std::string& oldName, const std::string& newName,
std::shared_ptr<Expression> expression);
function::TableFunction getScanFunction(const common::FileTypeInfo& typeInfo,
const common::FileScanInfo& fileScanInfo) const;
ExpressionBinder* getExpressionBinder() { return &expressionBinder; }
private:
common::idx_t lastExpressionId;
BinderScope scope;
ExpressionBinder expressionBinder;
main::ClientContext* clientContext;
std::vector<extension::BinderExtension*> binderExtensions;
};
} }