AlaSQL / alasql

AlaSQL.js - JavaScript SQL database for browser and Node.js. Handles both traditional relational tables and nested JSON data (NoSQL). Export, store, and import data from localStorage, IndexedDB, or Excel.
http://alasql.org
MIT License
7.01k stars 650 forks source link

CREATE FUNCTION causes an extra row in subsequent SELECT in same batch #1826

Closed wigsaparelli closed 10 months ago

wigsaparelli commented 10 months ago

Description of problem

You get a weird extra row if you call CREATE FUNCTION in the same batch (same alasql call) as subsequent SELECT statement. alasql users ideally shouldn't have to parse out CREATE FUNCTION calls as multiple statements in a single batch should be fine.

Code to repro

const data = [ { a: 2 }, { a: 4 }, { a: 6} ];
const createFunc = "CREATE FUNCTION cubic AS ``function(x) { return x*x*x; }``;";
const selectSql = "SELECT cubic(a) AS colA FROM ?";
const res = alasql(createFunc + selectSql, [data]);
console.log(res);

The above logs out:

[ 1, [ { colA: 8 }, { colA: 64 }, { colA: 216 } ] ]

The weird first row containing 1 only occurs if you have CREATE FUNCTION in the same batch as subsequent SELECT.

wigsaparelli commented 10 months ago

Ah, I've actually only just noticed that the result is actually an array of perhaps statement outputs. But then I'd need to know how many statements are in the batch. Any way of turning off output for statements that don't really produce any like CREATE FUNCTION ?

mathiasrw commented 10 months ago

There are good reasons for the logic to be as it is.

Why not do something like

alasql("CREATE FUNCTION cubic AS ``function(x) { return x*x*x; }``;")

const data = [ { a: 2 }, { a: 4 }, { a: 6} ];
const res = alasql("SELECT cubic(a) AS colA FROM ?", [data]);
console.log(res);
wigsaparelli commented 10 months ago

There are good reasons for the logic to be as it is.

Why not do something like

alasql("CREATE FUNCTION cubic AS ``function(x) { return x*x*x; }``;")

const data = [ { a: 2 }, { a: 4 }, { a: 6} ];
const res = alasql("SELECT cubic(a) AS colA FROM ?", [data]);
console.log(res);

As then we'd have to parse the input script which we were trying to avoid (want to just pass it onto alasql which has to parse it anyway). Not to worry, we've coded around it by checking if the output/result is an array or an array of arrays.