Merge from match + load csv invalid behaviour

This commit is contained in:
Josip Mrden
2023-05-05 15:34:25 +02:00
parent 109150641c
commit 90d17f1bfd
6 changed files with 45 additions and 19 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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:

View File

@@ -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

View File

@@ -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

View File

@@ -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