salk31 / RedQueryBuilder

SQL Query Builder UI JavaScript component
http://redquerybuilder.appspot.com/
Eclipse Public License 1.0
95 stars 22 forks source link

java.lang.ClassCastException passing args on a MULTI field #1

Closed matt-schwartz closed 10 years ago

matt-schwartz commented 10 years ago

Using version 0.5, passing in an array of strings to the create method for a MULTI field fails. Here's a trimmed down version of my code:

var config = {
    meta : {
        tables : [ {
            "name" : "ticket",
            "label" : "Ticket",
            "columns" : [ {
                "name" : "title",
                "label" : "Title",
                "type" : "STRING",
                "size" : 255
            }, {
                "name" : "priority",
                "label" : "Priority",
                "type" : "REF"
            }  ],
            fks : []
        } ],

        types : [ {
            "name" : "REF",
            "editor" : "SELECT",
            "operators" : [ {
                "name" : "IN",
                "label" : "any of",
                "cardinality" : "MULTI"
            }]
        }  ]
    }
};

RedQueryBuilderFactory.create(config, 
  'SELECT "x0"."title", "x0"."priority" FROM "ticket" "x0" WHERE ("x0"."status" = (?))',
  ['in_process']
);

java.lang.ClassCastException is output in the Safari console. If I pass an empty array [] no error is thrown. An arg list of strings is always passed to the onSqlChange method for every field type, so I would expect the exact same array to work when passed into the create method.

salk31 commented 10 years ago

Please could you try the current development branch http://0-6-0.redquerybuilder.appspot.com/ ?

NB for cardinality:"MULTI" you need to use "IN" (not "=")

If possible could you look at https://github.com/salk31/RedQueryBuilder/issues/2 and suggest what would be best for your app?

matt-schwartz commented 10 years ago

Better! If I provide it SQL with "IN" and some parameters it fills correctly. That's fixed. But the SQL it generates on output has "=" instead of "IN". So, this works:

RedQueryBuilderFactory.create(config, 
  'SELECT "x0"."title", "x0"."priority" FROM "ticket" "x0" WHERE ("x0"."status" IN (?, ?))',
  ['in_process','pending_approval']
);

But fresh SQL coming out from new selections looks like:

SELECT "x0"."title", "x0"."priority"  FROM "ticket" "x0" WHERE ("x0"."priority" = (?, ?))

That should be IN (?, ?). Closer!

salk31 commented 10 years ago

Afraid I can't reproduce it this time. The code below seems to function OK for me. I replaced the contents of simple.js and got correct output (I think).

RedQueryBuilderFactory.create({
     meta : {
        tables : [ {
            "name" : "ticket",
            "label" : "Ticket",
            "columns" : [  {
                "name" : "priority",
                "label" : "Priority",
                "type" : "REF"
            }  ],
            fks : []
        } ],

        types : [ {
            "name" : "REF",
            "editor" : "SELECT",
            "operators" : [ {
                "name" : "IN",
                "label" : "any of",
                "cardinality" : "MULTI"
            }]
        }  ]
    },
    onSqlChange : function(sql, args) {
        var out = sql + '\r\n';
        for (var i = 0; i < args.length; i++) {
            var arg = args[i];
            out += 'arg' + i;
            if (arg != null) {
                out += ' type=' + Object.prototype.toString.call(arg) + ' toString=' + arg;
            } else {
                out += ' null';
            }
            out += '\r\n';
        }
        document.getElementById("debug").value = out;
    },
    enumerate : function(request, response) {
        if (request.columnName == 'CATEGORY') {
            response([{value:'A', label:'Small'}, {value:'B', label:'Medium'}]);
        } else {
            response([{value:'M', label:'Male'}, {value:'F', label:'Female'}]);
        }
    },
    editors : [ {
        name : 'DATE',
        format : 'dd.MM.yyyy'
    } ]
},'SELECT  "x0"."priority" FROM "ticket" "x0" WHERE ("x0"."priority" IN (?))',
  ['in_process']);

output

SELECT "x0"."priority"
FROM "ticket" "x0"
WHERE ("x0"."priority" IN (?, ?))
arg0 type=[object String] toString=M
arg1 type=[object String] toString=F

I'm testing in Chrome on XP in case that is the difference. Would be a first if a browser quirk for this sort of thing.

salk31 commented 10 years ago

Hmmm. Does seem to be a bug when changing columns with different cardinality. Will fix ASAP.

salk31 commented 10 years ago

This has only passed automatic tests but it seems like we are in different time zones so you might want to try it:

http://0-6-0.redquerybuilder.appspot.com/

I'll do some more testing tomorrow.

matt-schwartz commented 10 years ago

It works! Thanks so much for fixing this. I actually found a new related error. If I use NOT IN, like

"name" : "REF",
"editor" : "SELECT",
"operators" : [ {
    "name" : "IN",
    "label" : "is",
    "cardinality" : "MULTI"
}, {
    "name" : "NOT IN",
    "label" : "is not",
    "cardinality" : "MULTI"
}]

It generates good SQL, but that SQL fails when passed into RedQueryBuilderFactory.create. The console says

java.sql.SQLException: In SELECT "x0"."title", "x0"."description", "x0"."status", "x0"."priority", "x0"."bug", "x0"."created_time", "x0"."modifieid_time" FROM "ticket" "x0" WHERE ("x0"."status" NOT IN (?, ?)) at 171 wanted )

171 is the start of "NOT". Would you like me to open a new ticket?

salk31 commented 10 years ago

Phew. Please could you raise another bug? Quite a thorny issue how to deal with "NOT". Unlike "IS NULL", "NOT IN" is two keywords.

So not sure if better to dumb down the SQL parser so it doesn't understand "NOT" or try and get generic support for "NOT" in the UI.

matt-schwartz commented 10 years ago

I posted to a new issue: #3