New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow binding of PL/SQL indexed tables #309
Conversation
Signed-off-by: Dieter Oberkofler <dieter.oberkofler@gmail.com>
Where is NJSDebug::dump() is used in the code? Is it for debugging purpose? |
@pvenkatraman Yes, I've use it extensively for debugging purposes but have removed its invocations. |
@cjbj I have just merged in the 1.5 changes to make the pull request again conflict free. |
@cjbj Is there anything else you need me do in order to have my pull request merged? |
@doberkofler thanks for updating it. I'm just back from vacation and will catch up with @pvenkatraman about the feature. It's on our list to review for 1.6. |
An update on this: @pvenkatraman is working on the merge. He is |
@cjbj the existing code base is not the easiest to understand and I spend quite some time to get to know the code and try to fit the (currently undocumented) coding patterns and style. I must admit, that I would have preferred to have a chance to better understand where I might have made mistakes and/or to discuss them. Having changes modified and merged by others without a proper discussion does not really help a new project member and is actually also not very motivating. |
@doberkofler we can certainly discuss the issues we see before making changes. You can then decide whether to let us do the work or whether you want to spend more of your own time. I don't think anything is big. Your PR is great. @pvenkatraman is the best person to make comments; I'll let him jump in. Feel free to shoot us any questions on the code base at anytime. |
@doberkofler - The allocation AllocateBindArray() in Connection::GetOutBindParamsArray () function does not look right. For OUT binds, the allocation happens after the SQL execution in Connection::Async_AfterExecute (). As your code drop has working test cases, I am trying to understand and place this allocation correctly. Memory leak issues are difficult to investigate in node environment and would like to get this cleared off first. |
@pvenkatraman Thank you for reviewing my pull request. I would just have a few quick questions before I dig into the code:
|
@doberkofler
NULL values in IN bind array
|
array allocationWhen looking at |
NULL values in IN bind arrayI double checked my code and the processing of NULL values appears to be correct. |
Bind-by-PositionI now double checked my implementation and came to the conclusion, that positional binding of arrays is actually possible and relatively easy to implement but make the API really hard to understand. |
|
I absolutely agree on this, if positional binding is not supported.
I seem to have misunderstood the positional binding by looking at the documentation.
that I would not want to support. An example like this:
should be supported and I will try to add this in the next couple of days. |
You are using one error message with long-substituion string(s)I get your point but I'm really not sure if using separate error messages for the rather large number of parameter validation errors would not only pollute the list of error messages. I generally agree that having separate error messages with individual numbers is a good idea but I guess I'm not convinces that the individual parameter validation errors are really different errors and not only different extra information on one and the same error. |
@doberkofler keep us in the loop on progress. I don't want to break our current cadence of monthly releases and we'll need some time to complete testing. I'd prefer to get all the other small issues sorted and add bind-by-pos next month. One general problem with substitution in messages is it can make messages harder to translate (if we ever translate them). |
|
||
// Allocate for OUT Binds of PL/SQL indexed tables variables | ||
size_t arrayElementSize = bind->maxSize; | ||
Connection::AllocateBindArray(dataType, bind, executeBaton, &arrayElementSize); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please move this allocation to Connection::cbDynBufferAllocate (). For IN (IN & INOUT) binds from the value, we allocate for C-type and fill in the value(s). For OUT bind this is deferred to Connection::PrepareAndBind(). Only after OCIStmtPrepare2() we can determine whether the given SQL statement contains RETURNING INTO clause (DML returning). In this case, the OUT bind will return an array of values.
It is difficult to consolidate all the allocations to one place, but we can always try in another transaction.
As your drop is allocating for array, moving this allocation to Connection::cbDynBufferAllocate would be appropriate.
Please try the test case: CREATE OR REPLACE PACKAGE oracledb_testpack CREATE OR REPLACE PACKAGE BODY oracledb_testpack set serveroutput on; CREATE OR REPLACE PACKAGE oracledb_testpack CREATE OR REPLACE PACKAGE BODY oracledb_testpack this reports NJS-034 - does not support NULL bind values. |
To reply to your comment on one error message/multiple error messate: We do use same error message in multiple places and if it suits it is good. My comment particularly is about the substitution strings, which are bigger. We try to keep all code, strings etc within 80 characters as per our coding standards. My suggestion is to phrase multiple smaller error messages. |
@doberkofler I am working on suggestions. Let me know your ideas too. |
I want to make sure that I understand the positional binding correctly. Does the following unit test properly describe what you expect to be supported? it('43.1.2 binding PL/SQL indexed table IN by position', function(done) {
async.series([
function(callback) {
var proc = "CREATE OR REPLACE PACKAGE\n" +
"oracledb_testpack\n" +
"IS\n" +
" TYPE stringsType IS TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER;\n" +
" TYPE numbersType IS TABLE OF NUMBER INDEX BY BINARY_INTEGER;\n" +
" PROCEDURE test(strings IN stringsType, numbers IN numbersType);\n" +
"END;";
connection.should.be.ok;
connection.execute(
proc,
function(err) {
should.not.exist(err);
callback();
}
);
},
function(callback) {
var proc = "CREATE OR REPLACE PACKAGE BODY\n" +
"oracledb_testpack\n" +
"IS\n" +
" PROCEDURE test(strings IN stringsType, numbers IN numbersType)\n" +
" IS\n" +
" s VARCHAR2(2000) := '';\n" +
" BEGIN\n" +
" FOR i IN 1 .. strings.COUNT LOOP\n" +
" s := s || NVL(strings(i), 'NULL');\n" +
" END LOOP;\n" +
" FOR i IN 1 .. numbers.COUNT LOOP\n" +
" s := s || NVL(numbers(i), 0);\n" +
" END LOOP;\n" +
" IF (s <> 'NULLJohnDoe0811') THEN\n" +
" RAISE VALUE_ERROR;\n" +
" END IF;\n" +
" END;\n" +
"END;";
connection.should.be.ok;
connection.execute(
proc,
function(err) {
should.not.exist(err);
callback();
}
);
},
function(callback) {
var bindvars = [
{type: oracledb.STRING, dir: oracledb.BIND_IN, val: ['John', 'Doe']},
{type: oracledb.NUMBER, dir: oracledb.BIND_IN, val: [8, 11]}
];
connection.execute(
"BEGIN :result := oracledb_testpack.test(:1, :2); END;",
bindvars,
function(err, result) {
should.not.exist(err);
// console.log(result);
callback();
}
);
},
function(callback) {
connection.execute(
"DROP PACKAGE oracledb_testpack",
function(err) {
should.not.exist(err);
callback();
}
);
}
], done);
}); |
I understand but have just been trying to make the error messages as helpful as possible.
I understand and do not want to get into the coding style discussion but may I ask 3 short questions:
I understand and will try to shorten them. Can the error messages have multiple lines if the 80 character line length seems to be so important? |
@doberkofler your sample looks fine to me:
Are you treating mismatched array lengths as an error? Don't worry about the 80 char limit; I think I convinced @pvenkatraman not to worry too. It came about from an ancient C compiler implementation on a particular platform that truncated longer lines. I agree that it looks too short for modern programming. The node-oracledb coding standard is not strict. Follow the general style and everything will be fine. |
Bind-by-PositionI just pushed the commit a211c8b that implements the positional binding and adds the needed unit test. |
@doberkofler Thanks! We'll pick it up and get ready for a release. Did you see my email? |
Merged to 1.6. Thanks @doberkofler ! |
This pull request fixes the issue #98. It enhances the API to allow to bind procedural code using PL/SQL indexed tables.
Summary:
PL/SQL:
JavaScript: