^EQ being injected by addEncodedQuery after using ^NQ

Curiously Cory
Kilo Expert

I'm trying to solve a problem where I get a gliderecord to return:

sys_class_name=incident^number=INC0000001
-Global OR-
sys_class_name=problem^number=PRB0000001

I can write the query as: sys_class_name=incident^number=INC0000001^NQsys_class_name=problem^number=PRB0000001
and it returns results in the browser when looking at the list view.

In my widget I'm attempting to write this with a query builder in the following way:
grTask = new GlideRecord('task');
grTask.addQuery('sys_class_name','=','incident');
grTask.addQuery('number','=', 'INC0000001');
grTask.addEncodedQuery('^NQsys_class_name=problem');
grTask.addQuery('number', '=', 'PRB0000001');
grTask.query();

But the query it gives me as a result is: "sys_class_name=incident^number=INC0000001^NQsys_class_name=problem^EQ^number=PRB0000001"

The ^EQ is being injected into the wrong place for some reason. I'm trying to use the query builder because my "real world" scenario is much more complicated and I would prefer to be able to utilize addQuery where possible for data sanitation and best practice.

Steps to reproduce:
Create a new widget.

Server script:
(function() {
//sys_class_name=incident^number=INC0000001
//sys_class_name=problem^number=PRB0000001

data.tasks = [];
grTask = new GlideRecord('task');
grTask.addQuery('sys_class_name','=','incident');
grTask.addQuery('number','=', 'INC0000001');
grTask.addEncodedQuery('^NQsys_class_name=problem');
grTask.addQuery('number', '=', 'PRB0000001');
grTask.query();

while(grTask.next()){ data.tasks.push(grTask.getValue('number')); }

data.query = grTask.getEncodedQuery();
})();

HTML template:
<div>
<pre>{{c.data.query | json}}</pre>
<pre>{{c.data.tasks | json}}</pre>
</div>

2 REPLIES 2

Curiously Cory
Kilo Expert

I found a solution. I don't like it, but I found a solution:

(function() {
  /* populate the 'data' object */
  /* e.g., data.table = $sp.getValue('table'); */
	//sys_class_name=incident^number=INC0000001
	//sys_class_name=problem^number=PRB0000001
	//
	data.tasks = [];
	
	grTask = new GlideRecord('task');
	grTask.addQuery('sys_class_name','=','incident');
	grTask.addQuery('number','=', 'INC0000001');
	
        // use addQuery and prefix with NQ
	grTask.addQuery('NQsys_class_name', '=', 'problem');
	grTask.addQuery('number', '=', 'PRB0000001');
	
	//before running the query, grab the encoded query, it's right but won't run
	var query = grTask.getEncodedQuery();
	
        // go ahead and nuke grTask and create a new one
	grTask = new GlideRecord('task');
        // inject that SAME query you just pulled out of getEncodedQuery
	grTask.addEncodedQuery(query)
        // run that query! And it works.... what?
	grTask.query();
	
	while(gr.next()){
		data.tasks.push(gr.getValue('number'));
	}
	
	data.query = grTask.getEncodedQuery();
	
})();

Hi, I've been just trying to solve a similar problem.
It's silly that the grammar of encoded queries isn't described anywhere.
Apparently, calling the sequence of methods 

addEncodedQuery("statementA^NQstatementB")
addQuery(statementC)

generates the encoded query statementA^NQstatementB^EQ^statementC
which is parsed as (statement A OR statement B) AND statement C

If it weren't for the ^EQ part, it would be parsed as 
statement A OR statement B AND statement C
thus
statement A OR (statement B AND statement C)

I wonder if ServiceNow has documented the semantics at least internally or if it works this way just "by coincidence".