Merge from match + load csv invalid behaviour
This commit is contained in:
@@ -4598,7 +4598,7 @@ LoadCsv::LoadCsv(std::shared_ptr<LogicalOperator> input, Expression *file, bool
|
|||||||
MG_ASSERT(file_, "Something went wrong - '{}' member file_ shouldn't be a nullptr", __func__);
|
MG_ASSERT(file_, "Something went wrong - '{}' member file_ shouldn't be a nullptr", __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadCsv::Accept(HierarchicalLogicalOperatorVisitor &visitor) { return false; };
|
ACCEPT_WITH_INPUT(LoadCsv)
|
||||||
|
|
||||||
class LoadCsvCursor;
|
class LoadCsvCursor;
|
||||||
|
|
||||||
@@ -4649,14 +4649,12 @@ TypedValue CsvRowToTypedMap(csv::Reader::Row &row, csv::Reader::Header header) {
|
|||||||
class LoadCsvCursor : public Cursor {
|
class LoadCsvCursor : public Cursor {
|
||||||
const LoadCsv *self_;
|
const LoadCsv *self_;
|
||||||
const UniqueCursorPtr input_cursor_;
|
const UniqueCursorPtr input_cursor_;
|
||||||
bool input_is_once_;
|
bool did_pull_;
|
||||||
std::optional<csv::Reader> reader_{};
|
std::optional<csv::Reader> reader_{};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LoadCsvCursor(const LoadCsv *self, utils::MemoryResource *mem)
|
LoadCsvCursor(const LoadCsv *self, utils::MemoryResource *mem)
|
||||||
: self_(self), input_cursor_(self_->input_->MakeCursor(mem)) {
|
: self_(self), input_cursor_(self_->input_->MakeCursor(mem)), did_pull_{false} {}
|
||||||
input_is_once_ = dynamic_cast<Once *>(self_->input_.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Pull(Frame &frame, ExecutionContext &context) override {
|
bool Pull(Frame &frame, ExecutionContext &context) override {
|
||||||
SCOPED_PROFILE_OP("LoadCsv");
|
SCOPED_PROFILE_OP("LoadCsv");
|
||||||
@@ -4674,12 +4672,14 @@ class LoadCsvCursor : public Cursor {
|
|||||||
|
|
||||||
bool input_pulled = input_cursor_->Pull(frame, context);
|
bool input_pulled = input_cursor_->Pull(frame, context);
|
||||||
|
|
||||||
// If the input is Once, we have to keep going until we read all the rows,
|
if (input_pulled) {
|
||||||
// regardless of whether the pull on Once returned false.
|
if (did_pull_) {
|
||||||
// If we have e.g. MATCH(n) LOAD CSV ... AS x SET n.name = x.name, then we
|
throw QueryRuntimeException(
|
||||||
// have to read at most cardinality(n) rows (but we can read less and stop
|
"LOAD CSV can be executed only once, please check if the cardinality of the operator before LOAD CSV is 1");
|
||||||
// pulling MATCH).
|
}
|
||||||
if (!input_is_once_ && !input_pulled) return false;
|
did_pull_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
auto row = reader_->GetNextRow(context.evaluation_context.memory);
|
auto row = reader_->GetNextRow(context.evaluation_context.memory);
|
||||||
if (!row) {
|
if (!row) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -874,11 +874,27 @@ bool PlanToJsonVisitor::PreVisit(query::plan::CallProcedure &op) {
|
|||||||
bool PlanToJsonVisitor::PreVisit(query::plan::LoadCsv &op) {
|
bool PlanToJsonVisitor::PreVisit(query::plan::LoadCsv &op) {
|
||||||
json self;
|
json self;
|
||||||
self["name"] = "LoadCsv";
|
self["name"] = "LoadCsv";
|
||||||
self["file"] = ToJson(op.file_);
|
|
||||||
self["with_header"] = op.with_header_;
|
if (op.file_) {
|
||||||
self["ignore_bad"] = op.ignore_bad_;
|
self["file"] = ToJson(op.file_);
|
||||||
self["delimiter"] = ToJson(op.delimiter_);
|
}
|
||||||
self["quote"] = ToJson(op.quote_);
|
|
||||||
|
if (op.with_header_) {
|
||||||
|
self["with_header"] = op.with_header_;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op.ignore_bad_) {
|
||||||
|
self["ignore_bad"] = op.ignore_bad_;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op.delimiter_) {
|
||||||
|
self["delimiter"] = ToJson(op.delimiter_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op.quote_) {
|
||||||
|
self["quote"] = ToJson(op.quote_);
|
||||||
|
}
|
||||||
|
|
||||||
self["row_variable"] = ToJson(op.row_var_);
|
self["row_variable"] = ToJson(op.row_var_);
|
||||||
|
|
||||||
op.input_->Accept(*this);
|
op.input_->Accept(*this);
|
||||||
|
|||||||
@@ -477,6 +477,16 @@ class IndexLookupRewriter final : public HierarchicalLogicalOperatorVisitor {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PreVisit(LoadCsv &op) override {
|
||||||
|
prev_ops_.push_back(&op);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PostVisit(LoadCsv & /*op*/) override {
|
||||||
|
prev_ops_.pop_back();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<LogicalOperator> new_root_;
|
std::shared_ptr<LogicalOperator> new_root_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2022 Memgraph Ltd.
|
// Copyright 2023 Memgraph Ltd.
|
||||||
//
|
//
|
||||||
// Use of this software is governed by the Business Source License
|
// Use of this software is governed by the Business Source License
|
||||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2022 Memgraph Ltd.
|
// Copyright 2023 Memgraph Ltd.
|
||||||
//
|
//
|
||||||
// Use of this software is governed by the Business Source License
|
// Use of this software is governed by the Business Source License
|
||||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Copyright 2022 Memgraph Ltd.
|
// Copyright 2023 Memgraph Ltd.
|
||||||
//
|
//
|
||||||
// Use of this software is governed by the Business Source License
|
// Use of this software is governed by the Business Source License
|
||||||
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
// included in the file licenses/BSL.txt; by using this file, you agree to be bound by the terms of the Business Source
|
||||||
|
|||||||
Reference in New Issue
Block a user