Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge pull request #569 from hochang/master

inline udf assignment
  • Loading branch information...
commit 069b7d2509e3ec3046f9ae54f776743a942eba9b 2 parents 48ebe0f + 7c62bbd
@hochang hochang authored
View
6 modules/app/package.json
@@ -1,7 +1,7 @@
{
"author": "ql.io",
"name": "ql.io-app",
- "version": "0.8.7",
+ "version": "0.8.8a",
"repository": {
"type": "git",
"url": "https://github.com/ql-io/ql.io"
@@ -15,8 +15,8 @@
},
"dependencies": {
"commander": "1.0.0",
- "ql.io-console": "0.8.6",
- "ql.io-compiler": "0.8.3",
+ "ql.io-console": "0.8.7a",
+ "ql.io-compiler": "0.8.4",
"winston": "0.6.2",
"express": "2.5.11",
"underscore": "1.3.3",
View
15 modules/compiler/lib/compiler.js
@@ -83,7 +83,7 @@ function plan(compiled) {
}
else if (line.type === 'try') {
//dependsOn are the lines in try clause
- divescope(line.tryClause, line);
+ divescope(line.dependsOn, line);
_.each(line.catchClause, function(mycatch, k){
divescope(mycatch.lines, line);
});
@@ -130,7 +130,7 @@ function plan(compiled) {
}
else if (line.type === 'try') {
//dependsOn are the lines in try clause
- divescope(line.tryClause, line);
+ divescope(line.dependsOn, line);
_.each(line.catchClause, function(mycatch, k){
divescope(mycatch.lines, line);
});
@@ -246,6 +246,14 @@ function walk(line, symbols) {
break;
case 'define':
introspectObject(line.object, symbols, line.dependsOn, line);
+ if(line.udf && line.udf != 'require'){
+ _.each(line.args, function(arg){
+ dependency = symbols[arg.name];
+ if(dependency){
+ addDep(line, line.dependsOn, dependency, symbols);
+ }
+ });
+ }
break;
case 'return':
walk(line.rhs, symbols);
@@ -308,7 +316,8 @@ function walk(line, symbols) {
});
break;
case 'try':
- _.each(line.tryClause, function(tryline){
+ _.each(line.dependsOn, function(tryline){
+ addListener(tryline, line);
walk(tryline, symbols);
});
_.each(line.catchClause, function(currentcatch){
View
9 modules/compiler/lib/peg/ql.js
@@ -777,13 +777,18 @@ module.exports = (function(){
}
}
}
+ var catchConds = [];
+ for(var i = 0; i < catchClause.length; i++){
+ catchConds.push(catchClause[i].condition);
+ }
return {
id : id++,
line : line,
type : 'try',
- tryClause : tryClause,
+ dependsOn : tryClause.concat(catchConds),
catchClause : catchClause,
- finallyClause : finallyClause || undefined
+ finallyClause : finallyClause || undefined,
+ lock : false
}
})(pos0.offset, pos0.line, pos0.column, result0[4], result0[7], result0[8]);
}
View
2  modules/compiler/package.json
@@ -1,7 +1,7 @@
{
"author": "ql.io",
"name": "ql.io-compiler",
- "version": "0.8.3",
+ "version": "0.8.4",
"repository": {
"type": "git",
"url": "https://github.com/ql-io/ql.io"
View
9 modules/compiler/pegs/ql.peg
@@ -469,13 +469,18 @@ TryClause = 'try' insig '{' insig tryClause:TryCrlf+ insig '}' catchClause:Catch
}
}
}
+ var catchConds = [];
+ for(var i = 0; i < catchClause.length; i++){
+ catchConds.push(catchClause[i].condition);
+ }
return {
id : id++,
line : line,
type : 'try',
- tryClause : tryClause,
+ dependsOn : tryClause.concat(catchConds),
catchClause : catchClause,
- finallyClause : finallyClause || undefined
+ finallyClause : finallyClause || undefined,
+ lock : false
}
}
View
2  modules/compiler/test/scope-test.js
@@ -27,7 +27,7 @@ module.exports = {
}\n\
finally {select * from bbb}";
var statement = compiler.compile(q);
- test.equals(statement.rhs.tryClause.length, 2);
+ test.equals(statement.rhs.dependsOn.length, 3);
test.equals(statement.rhs.catchClause.length, 1);
test.equals(statement.rhs.catchClause[0].condition.values, 'asdf');
test.equals(statement.rhs.catchClause[0].condition.logic, 'normal');
View
6 modules/console/package.json
@@ -1,7 +1,7 @@
{
"author": "ql.io",
"name": "ql.io-console",
- "version": "0.8.6",
+ "version": "0.8.7a",
"repository": {
"type": "git",
"url": "https://github.com/ql-io/ql.io"
@@ -15,9 +15,9 @@
"express": "2.5.11",
"ejs": "0.8.0",
"underscore": "1.3.3",
- "ql.io-engine": "0.8.5",
+ "ql.io-engine": "0.8.6a",
"ql.io-mutable-uri": "0.8.0",
- "ql.io-compiler": "0.8.3",
+ "ql.io-compiler": "0.8.4",
"winston": "0.6.2",
"browserify": "1.14.2",
"uglify-js": "1.3.3",
View
3  modules/console/public/scripts/console.js
@@ -425,6 +425,8 @@ $(document).ready(function() {
})
emitter.on('script-done', function (data) {
markers.push(editor.setMarker(data.line - 1, data.elapsed + ' ms', 'green'));
+ delPic();
+ $('#step').hide();
});
}
@@ -438,6 +440,7 @@ $(document).ready(function() {
};
socket.send(JSON.stringify(packet));
delPic();
+ $('#step').hide();
}
function delPic(){
View
43 modules/engine/lib/engine.js
@@ -42,6 +42,7 @@ var configLoader = require('./engine/config.js'),
winston = require('winston'),
compiler = require('ql.io-compiler'),
visualization = require('./engine/visualization'),
+ udf = require('./engine/udf'),
_ = require('underscore'),
EventEmitter = require('events').EventEmitter,
util = require('util'),
@@ -306,7 +307,7 @@ Engine.prototype.execute = function() {
});
break;
case 'try':
- _.each(statement.tryClause, function(line){
+ _.each(statement.dependsOn, function(line){
init(line);
});
_.each(statement.catchClause, function(currentcatch){
@@ -354,7 +355,7 @@ Engine.prototype.execute = function() {
execState[statement.id].state = eventTypes.STATEMENT_SUCCESS;
switch(statement.type){
case 'try':
- _.each(statement.tryClause, function(tryline){//these are just lines within try{}
+ _.each(statement.dependsOn, function(tryline){//these are just lines within try{}
skipVar(tryline);
});
_.each(statement.catchClause, function(mycatch,k){
@@ -382,6 +383,9 @@ Engine.prototype.execute = function() {
_.each(statement.listeners, function(listener) {
execState[listener.id].count--;
if (!(listener.fbhold)){
+ if(listener.type === 'try'){
+ listener.lock = false;
+ }
return listener;
}
});
@@ -433,10 +437,20 @@ Engine.prototype.execute = function() {
if(skip) {
return;
}
- if(statement.scope && execState[statement.scope.id].state === eventTypes.STATEMENT_WAITING) {
+ if(statement.scope && execState[statement.scope.id].state === eventTypes.STATEMENT_WAITING &&
+ (statement.scope.type !== 'try' || !statement.scope.lock)) {
sweep(statement.scope);
return;
}
+ if(statement.type === 'try'){
+ var dependsDone = _.all(statement.dependsOn, function(tryline){
+ return execState[tryline.id].state === 'statement-success';
+ });
+ if(!dependsDone){
+ //block revisit try from lines in this scope.
+ statement.lock = true;
+ }
+ }
_.each(statement.dependsOn, function(dependency) {
if(execState[dependency.id].state === eventTypes.STATEMENT_WAITING) {
// Exec the dependency
@@ -456,17 +470,12 @@ Engine.prototype.execute = function() {
}
var todo = statement.rhs || statement,
- scopeDone = !todo.scope || execState[todo.scope.id].state === eventTypes.STATEMENT_SUCCESS;
+ scopeDone = !todo.scope || execState[todo.scope.id].state === eventTypes.STATEMENT_SUCCESS || (todo.scope.lock && _.contains(todo.scope.dependsOn, todo));
if(execState[todo.id].state === eventTypes.STATEMENT_WAITING && // Don't try if in-flight
execState[todo.id].count === 0 &&
scopeDone) {
execState[todo.id].state = eventTypes.STATEMENT_IN_FLIGHT;
- if(todo.type === 'try'){
- _.each(todo.tryClause, function(tryline){
- sweep(tryline);
- });
- }
if (emitterID && !step1) {
// only used for debugger
unexecuted.push(statement);
@@ -531,6 +540,9 @@ Engine.prototype.execute = function() {
_.each(todo.listeners, function(listener) {
execState[listener.id].count--;
if (!(listener.fbhold)){
+ if(listener.type === 'try'){
+ listener.lock = false;
+ }
sweep(listener);
}
});
@@ -712,6 +724,7 @@ function _execOne(opts, statement, parentEvent, cb) {
obj = jsonfill.fill(statement.object, params);
}
else if(statement.udf) {
+ if (statement.udf === 'require'){
args = [];
_.each(_.pluck(statement.args, 'value'), function(arg) {
args.push(jsonfill.lookup(arg, opts.context));
@@ -723,6 +736,18 @@ function _execOne(opts, statement, parentEvent, cb) {
console.log(e.stack || e);
return cb(e);
}
+ }else{//assign variable using udf.
+ udf.applyAssign(opts, statement, function(err, results) {
+ if(err) {
+ cb('udf assignment failed.')
+ }
+ else {
+ if(statement.assign) {
+ obj = results;
+ }
+ }
+ });
+ }
}
opts.context[statement.assign] = obj;
View
9 modules/engine/lib/engine/log-emitter.js
@@ -26,9 +26,15 @@ var eventTypes = require('./event-types.js'),
* The point of this emitter is to capture events in a hierarchy so know which part of the script
* caused what HTTP request.
*/
+
+var tid = 0;
var LogEmitter = module.exports = function() {
events.EventEmitter.call(this);
+ function gettid(){
+ return tid++;
+ }
+
/**
* This begins a new event and returns an event object
*
@@ -60,7 +66,8 @@ var LogEmitter = module.exports = function() {
clazz: 'begin',
type: type || 'ql.io',
name: name || 'ql.io',
- uuid: (parent && parent.uuid ? parent.uuid : uuid())
+ uuid: (parent && parent.uuid ? parent.uuid : uuid()),
+ tid: (parent && parent.tid ? parent.tid : gettid()) // nodejs does not has multiple threads. the tid would trick Cal to consider calls in different threads.
};
this.emit(eventTypes.BEGIN_EVENT, event, message);
View
23 modules/engine/lib/engine/udf.js
@@ -127,6 +127,29 @@ exports.applyWhere = function(opts, statement, results, cb, tempNames, tempIndic
}
}
+exports.applyAssign = function(opts, statement, cb){
+ var fn = resolveUdf(opts, statement),
+ context = opts.context,
+ args = _.map(statement.args, function(arg){
+ if(arg.name){
+ return context[arg.name];
+ }else{
+ return arg.value;
+ }
+ }),
+ wrapper = {
+ __proto__: context
+ },
+ result, err;
+ try{
+ result = fn.apply(wrapper, args);;
+ }catch(e){
+ err = e;
+ }finally{
+ cb(null, result);
+ }
+ //return result;
+}
function resolve(opts, columns, extras, udf, tempNames, tempIndices) {
var fn = resolveUdf(opts, udf);
if(fn) {
View
13 modules/engine/lib/udfs/standard.js
@@ -32,8 +32,17 @@ exports.require = function() {
return module.require.apply(null, args);
}
catch(e) {
- args[0] = __dirname + '/' + name;
- return module.require.apply(null, args);
+ try {
+ var splitpath = process.cwd().split('/');
+ splitpath[splitpath.length-1] = name;
+ args[0] = splitpath.join('/');
+ return module.require.apply(null, args);
+
+ } catch(e) {
+ args[0] = __dirname + '/' + name;
+ return module.require.apply(null, args);
+ }
}
+
}
}
View
4 modules/engine/package.json
@@ -1,7 +1,7 @@
{
"author": "ql.io",
"name": "ql.io-engine",
- "version": "0.8.5",
+ "version": "0.8.6a",
"repository": {
"type": "git",
"url": "https://github.com/ql-io/ql.io"
@@ -14,7 +14,7 @@
"winston": "0.6.2",
"underscore": "1.3.3",
"xml2json": "https://github.com/ql-io/node-xml2json/tarball/master",
- "ql.io-compiler": "0.8.3",
+ "ql.io-compiler": "0.8.4",
"ql.io-mutable-uri": "0.8.0",
"ql.io-uri-template": "0.8.0",
"ql.io-str-template": "0.8.0",
View
103 modules/engine/test/assign-udf-test.js
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2012 eBay Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+var _ = require('underscore'),
+ util = require('util'),
+ Engine = require('../lib/engine');
+
+var engine = new Engine();
+
+process.on('uncaughtException', function(error) {
+ console.log(error.stack || error);
+});
+module.exports = {
+ 'with-args': function(test) {
+ var script = 'u = require("./test/udfs/addone.js");\
+ x = 1;\
+ y = 2;\
+ b = u.add(x, y);\
+ return b';
+ engine.execute(script, function (emitter) {
+ emitter.on('end', function (err, results) {
+ if(err) {
+ console.log(err.stack || err);
+ test.ok(false);
+ }
+ else {
+ test.equals(results.body, 3);
+ }
+ });
+ test.done();
+ });
+ },
+ 'no-arg': function(test) {
+ var script = 'u = require("./test/udfs/addone.js");\
+ x = 1;\
+ b = u.addonex();\
+ return b';
+ engine.execute(script, function (emitter) {
+ emitter.on('end', function (err, results) {
+ if(err) {
+ console.log(err.stack || err);
+ test.ok(false);
+ }
+ else {
+ test.equals(results.body, 2);
+ }
+ });
+ test.done();
+ });
+ },
+ 'dependency-check': function(test) {
+ var script = 'u = require("./test/udfs/addone.js");\
+ b = u.add(x_beta, y_beta);\
+ x = 1;\
+ x_beta = select * from x;\
+ y = 2;\
+ y_beta = select * from y;\
+ return b';
+ engine.execute(script, function (emitter) {
+ emitter.on('end', function (err, results) {
+ if(err) {
+ console.log(err.stack || err);
+ test.ok(false);
+ }
+ else {
+ test.equals(results.body, 3);
+ }
+ });
+ test.done();
+ });
+ },
+ 'direct-pass': function(test) {
+ var script = 'u = require("./test/udfs/addone.js");\
+ x = 1;\
+ b = u.add(x, 2);\
+ return b';
+ engine.execute(script, function (emitter) {
+ emitter.on('end', function (err, results) {
+ if(err) {
+ console.log(err.stack || err);
+ test.ok(false);
+ }
+ else {
+ test.equals(results.body, 3);
+ }
+ });
+ test.done();
+ });
+ }
+}
View
28 modules/engine/test/scope-test.js
@@ -230,3 +230,31 @@ module.exports['ifelse-nested'] = function(test) {
}
}});
};
+
+module.exports['ifelse-nested'] = function(test) {
+ var q = 'foo = true \
+ bar = false\
+ try{\
+ mycond = select * from bar\
+ if(mycond){\
+ result4 = "hello world";\
+ }else{\
+ NoLanguagePack = true\
+ throw (NoLanguagePack)\
+ } \
+ }\
+ catch (NoLanguagePack){\
+ result3 = "not found"\
+ }\
+ return result4 || result3';
+ engine.exec({script: q, cb: function(err, result) {
+ if(err) {
+ test.fail('got error: ' + err.stack);
+ test.done();
+ }
+ else {
+ test.equals(result.body, "not found");
+ test.done();
+ }
+ }});
+}
View
24 modules/engine/test/udfs/addone.js
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2012 eBay Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+exports.addonex = function() {
+ var b = this.x+1;
+ return b;
+}
+
+exports.add = function(a, b){
+ var c = a + b;
+ return c;
+}
Please sign in to comment.
Something went wrong with that request. Please try again.