From 0478d4fffa9ca31928ed2a0c8db295739e55679b Mon Sep 17 00:00:00 2001 From: asfernandes Date: Mon, 21 Jul 2014 02:37:58 +0000 Subject: [PATCH] Fixed CORE-4488 - Wrong results of FOR SELECT FROM AS CURSOR and table is modified inside cursor's begin...end block. --- doc/sql.extensions/README.cursor_variables.txt | 5 ++++- src/dsql/ExprNodes.cpp | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/doc/sql.extensions/README.cursor_variables.txt b/doc/sql.extensions/README.cursor_variables.txt index 575b521d2c..93a7ac859c 100644 --- a/doc/sql.extensions/README.cursor_variables.txt +++ b/doc/sql.extensions/README.cursor_variables.txt @@ -21,7 +21,10 @@ Cursor variables 4) Cursor variables are read-only. 5) A FOR SELECT without AS CURSOR needs the use of INTO, while with AS CURSOR it's not required, but still allowed. With FETCH, INTO is now optional. - 6) It's allowed now to use the colon prefix when assigning to variables or NEW's fields. + 6) It's allowed now to use the colon prefix when assigning to variables or NEW's fields. + 7) Reading from a cursor variable returns the current field values. That means an UPDATE (with + WHERE CURRENT OF) also updates the fields for subsequent reads. And DELETE (with WHERE + CURRENT OF) makes subsequent reads to return NULL. Examples: 1. diff --git a/src/dsql/ExprNodes.cpp b/src/dsql/ExprNodes.cpp index 23c2438a07..8d733a1a2e 100644 --- a/src/dsql/ExprNodes.cpp +++ b/src/dsql/ExprNodes.cpp @@ -6820,6 +6820,16 @@ void DerivedFieldNode::genBlr(DsqlCompilerScratch* dsqlScratch) dsqlScratch->appendUChar(derivedContexts[i]); } } + else if ((context->ctx_flags & CTX_cursor) && val->is()) + { + // ASF: FieldNode::execute do not verify rpb_number.isValid(), and due to system triggers + // and also singular queries, we cannot start to do it. So to fix CORE-4488, we introduce + // the usage of blr_derived_expr for cursor fields, which in practice prefixes the + // FieldNode::execute by a test of rpb_number.isValid(). + dsqlScratch->appendUChar(blr_derived_expr); + dsqlScratch->appendUChar(1); + GEN_stuff_context(dsqlScratch, val->as()->dsqlContext); + } GEN_expr(dsqlScratch, value); }