-
Notifications
You must be signed in to change notification settings - Fork 597
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add runtime option for javascript language
- Loading branch information
Showing
27 changed files
with
1,709 additions
and
158 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,240 @@ | ||
statement ok | ||
CREATE FUNCTION gcd(a int, b int) RETURNS int LANGUAGE javascript RUNTIME deno AS $$ | ||
if(a == null || b == null) { | ||
return null; | ||
} | ||
while (b != 0) { | ||
let t = b; | ||
b = a % b; | ||
a = t; | ||
} | ||
return a; | ||
$$; | ||
|
||
query I | ||
select gcd(25, 15); | ||
---- | ||
5 | ||
|
||
statement ok | ||
drop function gcd; | ||
|
||
statement ok | ||
create function decimal_add(a decimal, b decimal) returns decimal language javascript RUNTIME deno as $$ | ||
return a.add(b); | ||
$$; | ||
|
||
query R | ||
select decimal_add(1.11, 2.22); | ||
---- | ||
3.33 | ||
|
||
statement ok | ||
drop function decimal_add; | ||
|
||
|
||
statement ok | ||
create function to_string(a boolean, b smallint, c int, d bigint, e real, f float, g decimal, h varchar, i bytea, j jsonb) returns varchar language javascript RUNTIME deno as $$ | ||
return a.toString() + b.toString() + c.toString() + d.toString() + e.toString() + f.toString() + g.toString() + h.toString() + i.toString() + JSON.stringify(j); | ||
$$; | ||
|
||
query T | ||
select to_string(false, 1::smallint, 2, 3, 4.5, 6.7, 8.9, 'abc', '\x010203', '{"key": 1}'); | ||
---- | ||
false1234.56.78.9abc1,2,3{"key":1} | ||
|
||
statement ok | ||
drop function to_string; | ||
|
||
# show data types in javascript | ||
statement ok | ||
create function js_typeof(a boolean, b smallint, c int, d bigint, e real, f float, g decimal, h varchar, i bytea, j jsonb) returns jsonb language javascript RUNTIME deno as $$ | ||
return { | ||
boolean: typeof a, | ||
smallint: typeof b, | ||
int: typeof c, | ||
bigint: typeof d, | ||
real: typeof e, | ||
float: typeof f, | ||
decimal: typeof g, | ||
varchar: typeof h, | ||
bytea: typeof i, | ||
jsonb: typeof j, | ||
}; | ||
$$; | ||
|
||
query T | ||
select js_typeof(false, 1::smallint, 2, 3, 4.5, 6.7, 8.9, 'abc', '\x010203', '{"key": 1}'); | ||
---- | ||
{"bigint": "bigint", "boolean": "boolean", "bytea": "object", "decimal": "object", "float": "number", "int": "number", "jsonb": "object", "real": "number", "smallint": "number", "varchar": "string"} | ||
|
||
statement ok | ||
drop function js_typeof; | ||
|
||
statement ok | ||
create function return_all(a boolean, b smallint, c int, d bigint, e real, f float, g decimal, h varchar, i bytea, j jsonb, s struct<f1 int, f2 int>) | ||
returns struct<a boolean, b smallint, c int, d bigint, e real, f float, g decimal, h varchar, i bytea, j jsonb, s struct<f1 int, f2 int>> | ||
language javascript runtime deno as $$ | ||
return {a,b,c,d,e,f,g,h,i,j,s}; | ||
$$; | ||
|
||
query T | ||
select (return_all( | ||
true, | ||
1 ::smallint, | ||
1, | ||
1, | ||
1, | ||
1, | ||
12345678901234567890.12345678, | ||
'string', | ||
'bytes', | ||
'{"key":1}', | ||
row(1, 2)::struct<f1 int, f2 int> | ||
)).*; | ||
---- | ||
t 1 1 1 1 1 12345678901234567890.12345678 string \x6279746573 {"key": 1} (1,2) | ||
|
||
statement ok | ||
drop function return_all; | ||
|
||
|
||
statement ok | ||
create function series(n int) returns table (x int) language javascript RUNTIME deno as $$ | ||
for(let i = 0; i < n; i++) { | ||
yield i; | ||
} | ||
$$; | ||
|
||
query I | ||
select series(5); | ||
---- | ||
0 | ||
1 | ||
2 | ||
3 | ||
4 | ||
|
||
statement ok | ||
drop function series; | ||
|
||
|
||
statement ok | ||
create function split(s varchar) returns table (word varchar, length int) language javascript RUNTIME deno as $$ | ||
for(let word of s.split(' ')) { | ||
yield { word: word, length: word.length }; | ||
} | ||
$$; | ||
|
||
query IT | ||
select * from split('rising wave'); | ||
---- | ||
rising 6 | ||
wave 4 | ||
|
||
statement ok | ||
drop function split; | ||
|
||
|
||
statement ok | ||
CREATE FUNCTION digest( t string ) RETURNS bytea LANGUAGE javascript RUNTIME deno AS $$ | ||
const subtle = crypto.subtle; | ||
const key = await subtle.generateKey({ | ||
name: 'HMAC', | ||
hash: 'SHA-256', | ||
length: 256, | ||
}, true, ['sign', 'verify']); | ||
|
||
const enc = new TextEncoder(); | ||
const message = enc.encode(t); | ||
|
||
const result = await subtle.sign({ | ||
name: 'HMAC', | ||
}, key, message); | ||
console.log('result', result); | ||
return result; | ||
$$ ASYNC; | ||
|
||
query I | ||
select bit_length(digest('Hello')); | ||
---- | ||
256 | ||
|
||
statement ok | ||
drop function digest; | ||
|
||
statement ok | ||
CREATE FUNCTION delay_response() | ||
RETURNS TABLE (x int) LANGUAGE javascript RUNTIME deno AS $$ | ||
const delayedResponses = { | ||
delays: [50, 10, 15], | ||
wait(delay) { | ||
return new Promise((resolve) => { | ||
setTimeout(resolve, delay); | ||
}); | ||
}, | ||
|
||
async *[Symbol.asyncIterator]() { | ||
for (const delay of this.delays) { | ||
await this.wait(delay); | ||
yield delay; | ||
} | ||
}, | ||
}; | ||
return delayedResponses; | ||
$$ SYNC; | ||
|
||
query I | ||
select * FROM delay_response(); | ||
---- | ||
50 | ||
10 | ||
15 | ||
|
||
statement ok | ||
drop function delay_response; | ||
|
||
system ok | ||
python3 e2e_test/udf/mock_server.py & | ||
|
||
# wait for server to start | ||
sleep 1s | ||
|
||
statement ok | ||
CREATE FUNCTION fetch_api() RETURNS TABLE ( data struct< idx int>) LANGUAGE javascript RUNTIME deno AS $$ | ||
const response = await fetch('http://127.0.0.1:4101'); | ||
const resp = await response.json(); | ||
for (const r of resp.results) { | ||
yield r; | ||
} | ||
$$ ASYNC GENERATOR; | ||
|
||
query I | ||
select * FROM fetch_api(); | ||
---- | ||
1 | ||
2 | ||
|
||
statement ok | ||
drop function fetch_api; | ||
|
||
system ok | ||
pkill -9 python3 | ||
|
||
system ok | ||
e2e_test/udf/sse/server/target/release/sse-server & | ||
|
||
statement ok | ||
CREATE FUNCTION call_sse() RETURNS TABLE ( data struct<data struct<greetings string>>) LANGUAGE javascript RUNTIME deno USING LINK 'fs://e2e_test/udf/sse/bundled.table.js' SYNC; | ||
|
||
query I | ||
select * FROM call_sse(); | ||
---- | ||
(Hi) | ||
(Bonjour) | ||
(Hola) | ||
(Ciao) | ||
(Zdravo) | ||
|
||
system ok | ||
pkill -9 sse-server |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import http.server | ||
import sys | ||
|
||
class MockHTTPRequestHandler(http.server.BaseHTTPRequestHandler): | ||
"""HTTPServer mock request handler""" | ||
|
||
def do_GET(self): # pylint: disable=invalid-name | ||
"""Handle GET requests""" | ||
self.send_response(200) | ||
self.send_header("Content-Type", "application/json") | ||
self.end_headers() | ||
self.wfile.write(b'{"results": [{"idx": 1}, {"idx": 2}]}') | ||
|
||
def log_request(self, code=None, size=None): | ||
"""Don't log anything""" | ||
|
||
def main() -> int: | ||
"""Echo the input arguments to standard output""" | ||
|
||
httpd = http.server.HTTPServer( ("127.0.0.1", 4101), MockHTTPRequestHandler) | ||
httpd.serve_forever() | ||
|
||
if __name__ == '__main__': | ||
sys.exit(main()) |
Oops, something went wrong.