Skip to content
Draft
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
45 changes: 45 additions & 0 deletions test/test2498.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
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 () {
const paramWhere = alasql.parse('SELECT 1 FROM ? WHERE x < $y').statements[0].where.expression;
assert.strictEqual(paramWhere.left.columnid, 'x');
assert.strictEqual(paramWhere.left.tableid, undefined);
assert.strictEqual(paramWhere.op, '<');
assert.strictEqual(paramWhere.right.param, 'y');

const numWhere = alasql.parse('SELECT 1 FROM ? WHERE x < 10').statements[0].where.expression;
assert.strictEqual(numWhere.right.value, 10);

const strWhere = alasql.parse("SELECT 1 FROM ? WHERE x = 'abc'").statements[0].where.expression;
assert.strictEqual(strWhere.right.value, 'abc');

const boolWhere = alasql.parse('SELECT 1 FROM ? WHERE x = TRUE').statements[0].where.expression;
assert.strictEqual(boolWhere.right.value, true);

const uniWhere = alasql.parse('SELECT 1 FROM ? WHERE -x < 0').statements[0].where.expression;
assert.strictEqual(uniWhere.left.op, '-');
assert.strictEqual(uniWhere.left.right.columnid, 'x');
});
});
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};

/**
* 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