Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions test/test2498.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
if (typeof exports === 'object') {
var assert = require('assert');
var alasql = require('..');
}

let testId = '2498';

describe(`Test ${testId} - parser AST surface`, function () {
it('A) exposes statements[] and where.toJS() for parsed statements', function () {
const ast = alasql.parse('SELECT 1 FROM ? WHERE x < $y');
assert.ok(Array.isArray(ast.statements));
assert.strictEqual(ast.statements.length, 1);

const where = ast.statements[0].where;
assert.strictEqual(typeof where.toJS, 'function');

const js = where.toJS('p', '', null);
assert.strictEqual(typeof js, 'string');

const fn = new Function('alasql', 'p', 'params', `return Boolean(${js});`);
assert.strictEqual(fn(alasql, {x: 1}, {y: 2}), true);
assert.strictEqual(fn(alasql, {x: 3}, {y: 2}), false);
});

it('B) preserves stable expression node shapes used by parser consumers', function () {
Comment thread
mathiasrw marked this conversation as resolved.
const parsed = {
paramWhere: alasql.parse('SELECT 1 FROM ? WHERE x < $y').statements[0].where.expression,
numWhere: alasql.parse('SELECT 1 FROM ? WHERE x < 10').statements[0].where.expression,
strWhere: alasql.parse("SELECT 1 FROM ? WHERE x = 'abc'").statements[0].where.expression,
boolWhere: alasql.parse('SELECT 1 FROM ? WHERE x = TRUE').statements[0].where.expression,
uniWhere: alasql.parse('SELECT 1 FROM ? WHERE -x < 0').statements[0].where.expression,
};

assert.strictEqual(parsed.paramWhere.left.tableid, undefined);
assert.strictEqual(parsed.numWhere.left.tableid, undefined);
assert.strictEqual(parsed.strWhere.left.tableid, undefined);
assert.strictEqual(parsed.boolWhere.left.tableid, undefined);
assert.strictEqual(parsed.uniWhere.left.right.tableid, undefined);

const actual = JSON.parse(JSON.stringify(parsed));
const expected = {
paramWhere: {left: {columnid: 'x'}, op: '<', right: {param: 'y'}},
numWhere: {left: {columnid: 'x'}, op: '<', right: {value: 10}},
strWhere: {left: {columnid: 'x'}, op: '=', right: {value: 'abc'}},
boolWhere: {left: {columnid: 'x'}, op: '=', right: {value: true}},
uniWhere: {
left: {op: '-', right: {columnid: 'x'}},
op: '<',
right: {value: 0},
},
};

assert.deepStrictEqual(actual, expected);
});
});
59 changes: 59 additions & 0 deletions types/alasql.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,67 @@ declare module 'alasql' {
<T = unknown>(params?: any, cb?: AlaSQLCallback<T>, scope?: unknown): T;
}

type AlaSQLDefaultColumns = {[columnName: string]: string};
Comment thread
mathiasrw marked this conversation as resolved.

/**
* Base parsed expression node.
* Node shapes below are part of the public parser AST surface and follow semver.
*/
interface AlaSQLExpression {
toJS(context: string, tableid: string | number, defcols: AlaSQLDefaultColumns | null): string;
}

interface Op extends AlaSQLExpression {
left: ExpressionNode;
op: string;
right?: ExpressionNode;
right1?: ExpressionNode;
right2?: ExpressionNode;
}

interface Column extends AlaSQLExpression {
columnid: string;
tableid?: string;
databaseid?: string;
}

interface ParamValue extends AlaSQLExpression {
param: string | number;
}

interface NumValue extends AlaSQLExpression {
value: number;
}

interface StringValue extends AlaSQLExpression {
value: string;
}

interface LogicValue extends AlaSQLExpression {
value: boolean;
}

interface UniOp extends AlaSQLExpression {
op: string | null;
right: ExpressionNode;
}

type ExpressionNode = Op | Column | ParamValue | NumValue | StringValue | LogicValue | UniOp;

interface ExpressionWrapper extends AlaSQLExpression {
expression: ExpressionNode;
reduced?: boolean;
}

interface Statement {
compile(databaseid: string): AlaSQLStatement;
where?: ExpressionWrapper;
[key: string]: unknown;
}

// abstract Syntax Tree
interface AlaSQLAST {
statements: Statement[];
compile(databaseid: string): AlaSQLStatement;
}

Expand Down
Loading