0
0
mirror of https://github.com/PostHog/posthog.git synced 2024-11-21 21:49:51 +01:00

feat(cdp): Added kinesis template (#23635)

Co-authored-by: Marius Andra <marius.andra@gmail.com>
This commit is contained in:
Ben White 2024-07-16 15:55:05 +02:00 committed by GitHub
parent 3c266b2e28
commit cbf1f0c86f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 635 additions and 100 deletions

View File

@ -328,7 +328,7 @@ function HogFunctionInputSchemaControls({ value, onChange, onDone }: HogFunction
/>
<div className="flex-1" />
<LemonButton status="danger" icon={<IconTrash />} size="small" onClick={() => onChange(null)} />
<LemonButton size="small" onClick={() => onDone()}>
<LemonButton type="secondary" size="small" onClick={() => onDone()}>
Done
</LemonButton>
</div>

View File

@ -8,4 +8,14 @@
33, 1, 48, 2, "print", 1, 35, 33, 1, 33, 2, 33, 3, 33, 4, 43, 2, 43, 2, 33, 5, 43, 3, 33, 6, 48, 33, 3, 48, 33, 1, 48,
2, "print", 1, 35, 33, 1, 33, 2, 33, 3, 33, 4, 43, 2, 43, 2, 33, 5, 43, 3, 33, 6, 48, 33, 3, 48, 33, 1, 48, 2, "print",
1, 35, 33, 1, 33, 1, 33, 2, 33, 3, 33, 4, 43, 2, 43, 2, 33, 5, 43, 3, 33, 1, 45, 33, 1, 45, 33, 1, 45, 6, 2, "print", 1,
35, 33, 1, 33, 2, 33, 3, 33, 4, 43, 2, 43, 2, 33, 5, 43, 3, 33, 1, 45, 33, 1, 45, 33, 1, 45, 2, "print", 1, 35, 35]
35, 33, 1, 33, 2, 33, 3, 33, 4, 43, 2, 43, 2, 33, 5, 43, 3, 33, 1, 45, 33, 1, 45, 33, 1, 45, 2, "print", 1, 35, 32,
"------", 2, "print", 1, 35, 33, 4, 33, 1, 33, 2, 33, 3, 43, 3, 2, "arrayPushBack", 2, 2, "print", 1, 35, 33, 0, 33, 1,
33, 2, 33, 3, 43, 3, 2, "arrayPushFront", 2, 2, "print", 1, 35, 33, 1, 33, 2, 33, 3, 43, 3, 2, "arrayPopBack", 1, 2,
"print", 1, 35, 33, 1, 33, 2, 33, 3, 43, 3, 2, "arrayPopFront", 1, 2, "print", 1, 35, 33, 3, 33, 2, 33, 1, 43, 3, 2,
"arraySort", 1, 2, "print", 1, 35, 33, 1, 33, 2, 33, 3, 43, 3, 2, "arrayReverse", 1, 2, "print", 1, 35, 33, 3, 33, 2,
33, 1, 43, 3, 2, "arrayReverseSort", 1, 2, "print", 1, 35, 32, ",", 33, 1, 33, 2, 33, 3, 43, 3, 2, "arrayStringConcat",
2, 2, "print", 1, 35, 32, "-----", 2, "print", 1, 35, 33, 1, 33, 2, 33, 3, 33, 4, 43, 4, 36, 1, 2, "print", 1, 35, 33,
5, 36, 1, 2, "arrayPushBack", 2, 35, 36, 1, 2, "print", 1, 35, 33, 0, 36, 1, 2, "arrayPushFront", 2, 35, 36, 1, 2,
"print", 1, 35, 36, 1, 2, "arrayPopBack", 1, 35, 36, 1, 2, "print", 1, 35, 36, 1, 2, "arrayPopFront", 1, 35, 36, 1, 2,
"print", 1, 35, 36, 1, 2, "arraySort", 1, 35, 36, 1, 2, "print", 1, 35, 36, 1, 2, "arrayReverse", 1, 35, 36, 1, 2,
"print", 1, 35, 36, 1, 2, "arrayReverseSort", 1, 35, 36, 1, 2, "print", 1, 35, 35, 35]

View File

@ -16,3 +16,21 @@ null
null
5
4
------
[1, 2, 3, 4]
[0, 1, 2, 3]
[1, 2]
[2, 3]
[1, 2, 3]
[3, 2, 1]
[3, 2, 1]
1,2,3
-----
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 4]

View File

@ -0,0 +1,4 @@
["_h", 32, "this is a secure string", 36, 0, 32, "string:", 2, "print", 2, 35, 36, 0, 2, "md5Hex", 1, 32,
"md5Hex(string):", 2, "print", 2, 35, 36, 0, 2, "sha256Hex", 1, 32, "sha256Hex(string):", 2, "print", 2, 35, 32, "1",
32, "string", 32, "more", 32, "keys", 43, 4, 36, 1, 32, "data:", 2, "print", 2, 35, 36, 1, 2, "sha256HmacChainHex", 1,
32, "sha256HmacChainHex(data):", 2, "print", 2, 35, 35, 35]

View File

@ -0,0 +1,5 @@
string: this is a secure string
md5Hex(string): e7b466647ea215dbe59b00c756560911
sha256Hex(string): 5216c0931310b31737ef30353830c234901283544e934f54eb75f622cfb86c9d
data: ['1', 'string', 'more', 'keys']
sha256HmacChainHex(data): 826820d7eeca97f26ca18096be85fed346f6fd9cc18d64e72c935bea3450dbd9

View File

@ -1,32 +1,32 @@
["_h", 34, 1234377543.123456, 2, "fromUnixTimestamp", 1, 32, "%Y-%m-%d %H:%i:%S", 36, 0, 2, "formatDateTime", 2, 2,
"print", 1, 35, 32, "Europe/Brussels", 32, "%Y-%m-%d %H:%i:%S", 36, 0, 2, "formatDateTime", 3, 2, "print", 1, 35, 32,
"America/New_York", 32, "%Y-%m-%d %H:%i:%S", 36, 0, 2, "formatDateTime", 3, 2, "print", 1, 35, 32, "-----", 2, "print",
1, 35, 32, "%a", 36, 0, 2, "formatDateTime", 2, 32, "%a: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%b", 36, 0, 2,
"formatDateTime", 2, 32, "%b: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%c", 36, 0, 2, "formatDateTime", 2, 32, "%c: ",
2, "concat", 2, 2, "print", 1, 35, 32, "%C", 36, 0, 2, "formatDateTime", 2, 32, "%C: ", 2, "concat", 2, 2, "print", 1,
35, 32, "%d", 36, 0, 2, "formatDateTime", 2, 32, "%d: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%D", 36, 0, 2,
"formatDateTime", 2, 32, "%D: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%e", 36, 0, 2, "formatDateTime", 2, 32, "%e: ",
2, "concat", 2, 2, "print", 1, 35, 32, "%F", 36, 0, 2, "formatDateTime", 2, 32, "%F: ", 2, "concat", 2, 2, "print", 1,
35, 32, "%g", 36, 0, 2, "formatDateTime", 2, 32, "%g: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%G", 36, 0, 2,
"formatDateTime", 2, 32, "%G: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%h", 36, 0, 2, "formatDateTime", 2, 32, "%h: ",
2, "concat", 2, 2, "print", 1, 35, 32, "%H", 36, 0, 2, "formatDateTime", 2, 32, "%H: ", 2, "concat", 2, 2, "print", 1,
35, 32, "%i", 36, 0, 2, "formatDateTime", 2, 32, "%i: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%I", 36, 0, 2,
"formatDateTime", 2, 32, "%I: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%j", 36, 0, 2, "formatDateTime", 2, 32, "%j: ",
2, "concat", 2, 2, "print", 1, 35, 32, "%k", 36, 0, 2, "formatDateTime", 2, 32, "%k: ", 2, "concat", 2, 2, "print", 1,
35, 32, "%l", 36, 0, 2, "formatDateTime", 2, 32, "%l: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%m", 36, 0, 2,
"formatDateTime", 2, 32, "%m: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%M", 36, 0, 2, "formatDateTime", 2, 32, "%M: ",
2, "concat", 2, 2, "print", 1, 35, 32, "%n", 36, 0, 2, "formatDateTime", 2, 32, "%n: ", 2, "concat", 2, 2, "print", 1,
35, 32, "%p", 36, 0, 2, "formatDateTime", 2, 32, "%p: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%r", 36, 0, 2,
"formatDateTime", 2, 32, "%r: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%R", 36, 0, 2, "formatDateTime", 2, 32, "%R: ",
2, "concat", 2, 2, "print", 1, 35, 32, "%s", 36, 0, 2, "formatDateTime", 2, 32, "%s: ", 2, "concat", 2, 2, "print", 1,
35, 32, "%S", 36, 0, 2, "formatDateTime", 2, 32, "%S: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%t", 36, 0, 2,
"formatDateTime", 2, 32, "%t: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%T", 36, 0, 2, "formatDateTime", 2, 32, "%T: ",
2, "concat", 2, 2, "print", 1, 35, 32, "%u", 36, 0, 2, "formatDateTime", 2, 32, "%u: ", 2, "concat", 2, 2, "print", 1,
35, 32, "%V", 36, 0, 2, "formatDateTime", 2, 32, "%V: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%w", 36, 0, 2,
"formatDateTime", 2, 32, "%w: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%W", 36, 0, 2, "formatDateTime", 2, 32, "%W: ",
2, "concat", 2, 2, "print", 1, 35, 32, "%y", 36, 0, 2, "formatDateTime", 2, 32, "%y: ", 2, "concat", 2, 2, "print", 1,
35, 32, "%Y", 36, 0, 2, "formatDateTime", 2, 32, "%Y: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%z", 36, 0, 2,
"formatDateTime", 2, 32, "%z: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%%", 36, 0, 2, "formatDateTime", 2, 32, "%%: ",
2, "concat", 2, 2, "print", 1, 35, 32, "-----", 2, "print", 1, 35, 32, "one banana", 36, 0, 2, "formatDateTime", 2, 2,
"print", 1, 35, 32, "%Y no way %m is this %d a %H real %i time %S", 36, 0, 2, "formatDateTime", 2, 2, "print", 1, 35,
35]
"America/New_York", 32, "%Y-%m-%d %H:%i:%S", 36, 0, 2, "formatDateTime", 3, 2, "print", 1, 35, 32, "%Y%m%dT%H%i%sZ", 36,
0, 2, "formatDateTime", 2, 2, "print", 1, 35, 32, "-----", 2, "print", 1, 35, 32, "%a", 36, 0, 2, "formatDateTime", 2,
32, "%a: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%b", 36, 0, 2, "formatDateTime", 2, 32, "%b: ", 2, "concat", 2, 2,
"print", 1, 35, 32, "%c", 36, 0, 2, "formatDateTime", 2, 32, "%c: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%C", 36, 0,
2, "formatDateTime", 2, 32, "%C: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%d", 36, 0, 2, "formatDateTime", 2, 32,
"%d: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%D", 36, 0, 2, "formatDateTime", 2, 32, "%D: ", 2, "concat", 2, 2,
"print", 1, 35, 32, "%e", 36, 0, 2, "formatDateTime", 2, 32, "%e: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%F", 36, 0,
2, "formatDateTime", 2, 32, "%F: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%g", 36, 0, 2, "formatDateTime", 2, 32,
"%g: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%G", 36, 0, 2, "formatDateTime", 2, 32, "%G: ", 2, "concat", 2, 2,
"print", 1, 35, 32, "%h", 36, 0, 2, "formatDateTime", 2, 32, "%h: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%H", 36, 0,
2, "formatDateTime", 2, 32, "%H: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%i", 36, 0, 2, "formatDateTime", 2, 32,
"%i: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%I", 36, 0, 2, "formatDateTime", 2, 32, "%I: ", 2, "concat", 2, 2,
"print", 1, 35, 32, "%j", 36, 0, 2, "formatDateTime", 2, 32, "%j: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%k", 36, 0,
2, "formatDateTime", 2, 32, "%k: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%l", 36, 0, 2, "formatDateTime", 2, 32,
"%l: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%m", 36, 0, 2, "formatDateTime", 2, 32, "%m: ", 2, "concat", 2, 2,
"print", 1, 35, 32, "%M", 36, 0, 2, "formatDateTime", 2, 32, "%M: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%n", 36, 0,
2, "formatDateTime", 2, 32, "%n: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%p", 36, 0, 2, "formatDateTime", 2, 32,
"%p: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%r", 36, 0, 2, "formatDateTime", 2, 32, "%r: ", 2, "concat", 2, 2,
"print", 1, 35, 32, "%R", 36, 0, 2, "formatDateTime", 2, 32, "%R: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%s", 36, 0,
2, "formatDateTime", 2, 32, "%s: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%S", 36, 0, 2, "formatDateTime", 2, 32,
"%S: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%t", 36, 0, 2, "formatDateTime", 2, 32, "%t: ", 2, "concat", 2, 2,
"print", 1, 35, 32, "%T", 36, 0, 2, "formatDateTime", 2, 32, "%T: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%u", 36, 0,
2, "formatDateTime", 2, 32, "%u: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%V", 36, 0, 2, "formatDateTime", 2, 32,
"%V: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%w", 36, 0, 2, "formatDateTime", 2, 32, "%w: ", 2, "concat", 2, 2,
"print", 1, 35, 32, "%W", 36, 0, 2, "formatDateTime", 2, 32, "%W: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%y", 36, 0,
2, "formatDateTime", 2, 32, "%y: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%Y", 36, 0, 2, "formatDateTime", 2, 32,
"%Y: ", 2, "concat", 2, 2, "print", 1, 35, 32, "%z", 36, 0, 2, "formatDateTime", 2, 32, "%z: ", 2, "concat", 2, 2,
"print", 1, 35, 32, "%%", 36, 0, 2, "formatDateTime", 2, 32, "%%: ", 2, "concat", 2, 2, "print", 1, 35, 32, "-----", 2,
"print", 1, 35, 32, "one banana", 36, 0, 2, "formatDateTime", 2, 2, "print", 1, 35, 32,
"%Y no way %m is this %d a %H real %i time %S", 36, 0, 2, "formatDateTime", 2, 2, "print", 1, 35, 35]

View File

@ -1,6 +1,7 @@
2009-02-11 18:39:03
2009-02-11 19:39:03
2009-02-11 13:39:03
20090211T183903Z
-----
%a: Wed
%b: Feb

View File

@ -3,23 +3,20 @@
36, 0, 15, 40, 15, 36, 0, 2, "print", 1, 35, 33, 1, 36, 0, 6, 37, 0, 39, -22, 35, 32, "i", 1, 1, 2, "print", 1, 35, 32,
"-- test emptier for loop --", 2, "print", 1, 35, 33, 0, 33, 3, 36, 0, 15, 40, 15, 32, "woo", 2, "print", 1, 35, 33, 1,
36, 0, 6, 37, 0, 39, -22, 32, "hoo", 2, "print", 1, 35, 35, 32, "-- for in loop with arrays --", 2, "print", 1, 35, 33,
1, 33, 2, 33, 3, 43, 3, 31, 31, 31, 31, 31, 31, 36, 0, 37, 1, 36, 1, 2, "values", 1, 37, 3, 33, 0, 37, 4, 36, 3, 2,
"length", 1, 37, 5, 36, 5, 36, 4, 15, 40, 22, 36, 3, 36, 4, 45, 37, 6, 36, 6, 2, "print", 1, 35, 36, 4, 33, 1, 6, 37, 4,
39, -29, 35, 35, 35, 35, 35, 35, 35, 32, "-- for in loop with arrays and keys --", 2, "print", 1, 35, 33, 1, 33, 2, 33,
3, 43, 3, 31, 31, 31, 31, 31, 31, 31, 36, 0, 37, 1, 36, 1, 2, "keys", 1, 37, 2, 36, 1, 2, "values", 1, 37, 3, 33, 0, 37,
4, 36, 3, 2, "length", 1, 37, 5, 36, 5, 36, 4, 15, 40, 31, 36, 2, 36, 4, 45, 37, 6, 36, 3, 36, 4, 45, 37, 7, 36, 7, 36,
6, 2, "print", 2, 35, 36, 4, 33, 1, 6, 37, 4, 39, -38, 35, 35, 35, 35, 35, 35, 35, 35, 32,
"-- for in loop with tuples --", 2, "print", 1, 35, 33, 1, 33, 2, 33, 3, 44, 3, 31, 31, 31, 31, 31, 31, 36, 0, 37, 1,
36, 1, 2, "values", 1, 37, 3, 33, 0, 37, 4, 36, 3, 2, "length", 1, 37, 5, 36, 5, 36, 4, 15, 40, 22, 36, 3, 36, 4, 45,
37, 6, 36, 6, 2, "print", 1, 35, 36, 4, 33, 1, 6, 37, 4, 39, -29, 35, 35, 35, 35, 35, 35, 35, 32,
"-- for in loop with tuples and keys --", 2, "print", 1, 35, 33, 1, 33, 2, 33, 3, 44, 3, 31, 31, 31, 31, 31, 31, 31, 36,
0, 37, 1, 36, 1, 2, "keys", 1, 37, 2, 36, 1, 2, "values", 1, 37, 3, 33, 0, 37, 4, 36, 3, 2, "length", 1, 37, 5, 36, 5,
36, 4, 15, 40, 31, 36, 2, 36, 4, 45, 37, 6, 36, 3, 36, 4, 45, 37, 7, 36, 7, 36, 6, 2, "print", 2, 35, 36, 4, 33, 1, 6,
37, 4, 39, -38, 35, 35, 35, 35, 35, 35, 35, 35, 32, "-- for in loop with dicts --", 2, "print", 1, 35, 32, "first", 32,
"v1", 32, "second", 32, "v2", 32, "third", 32, "v3", 42, 3, 31, 31, 31, 31, 31, 31, 36, 0, 37, 1, 36, 1, 2, "values", 1,
37, 3, 33, 0, 37, 4, 36, 3, 2, "length", 1, 37, 5, 36, 5, 36, 4, 15, 40, 22, 36, 3, 36, 4, 45, 37, 6, 36, 6, 2, "print",
1, 35, 36, 4, 33, 1, 6, 37, 4, 39, -29, 35, 35, 35, 35, 35, 35, 35, 32, "-- for in loop with dicts and keys --", 2,
"print", 1, 35, 32, "first", 32, "v1", 32, "second", 32, "v2", 32, "third", 32, "v3", 42, 3, 31, 31, 31, 31, 31, 31, 31,
36, 0, 37, 1, 36, 1, 2, "keys", 1, 37, 2, 36, 1, 2, "values", 1, 37, 3, 33, 0, 37, 4, 36, 3, 2, "length", 1, 37, 5, 36,
5, 36, 4, 15, 40, 31, 36, 2, 36, 4, 45, 37, 6, 36, 3, 36, 4, 45, 37, 7, 36, 7, 36, 6, 2, "print", 2, 35, 36, 4, 33, 1,
6, 37, 4, 39, -38, 35, 35, 35, 35, 35, 35, 35, 35]
1, 33, 2, 33, 3, 43, 3, 36, 0, 36, 1, 2, "values", 1, 33, 0, 36, 2, 2, "length", 1, 31, 36, 4, 36, 3, 15, 40, 22, 36, 2,
36, 3, 45, 37, 5, 36, 5, 2, "print", 1, 35, 36, 3, 33, 1, 6, 37, 3, 39, -29, 35, 35, 35, 35, 35, 35, 32,
"-- for in loop with arrays and keys --", 2, "print", 1, 35, 33, 1, 33, 2, 33, 3, 43, 3, 36, 0, 36, 1, 2, "keys", 1, 36,
1, 2, "values", 1, 33, 0, 36, 3, 2, "length", 1, 31, 31, 36, 5, 36, 4, 15, 40, 31, 36, 2, 36, 4, 45, 37, 6, 36, 3, 36,
4, 45, 37, 7, 36, 7, 36, 6, 2, "print", 2, 35, 36, 4, 33, 1, 6, 37, 4, 39, -38, 35, 35, 35, 35, 35, 35, 35, 35, 32,
"-- for in loop with tuples --", 2, "print", 1, 35, 33, 1, 33, 2, 33, 3, 44, 3, 36, 0, 36, 1, 2, "values", 1, 33, 0, 36,
2, 2, "length", 1, 31, 36, 4, 36, 3, 15, 40, 22, 36, 2, 36, 3, 45, 37, 5, 36, 5, 2, "print", 1, 35, 36, 3, 33, 1, 6, 37,
3, 39, -29, 35, 35, 35, 35, 35, 35, 32, "-- for in loop with tuples and keys --", 2, "print", 1, 35, 33, 1, 33, 2, 33,
3, 44, 3, 36, 0, 36, 1, 2, "keys", 1, 36, 1, 2, "values", 1, 33, 0, 36, 3, 2, "length", 1, 31, 31, 36, 5, 36, 4, 15, 40,
31, 36, 2, 36, 4, 45, 37, 6, 36, 3, 36, 4, 45, 37, 7, 36, 7, 36, 6, 2, "print", 2, 35, 36, 4, 33, 1, 6, 37, 4, 39, -38,
35, 35, 35, 35, 35, 35, 35, 35, 32, "-- for in loop with dicts --", 2, "print", 1, 35, 32, "first", 32, "v1", 32,
"second", 32, "v2", 32, "third", 32, "v3", 42, 3, 36, 0, 36, 1, 2, "values", 1, 33, 0, 36, 2, 2, "length", 1, 31, 36, 4,
36, 3, 15, 40, 22, 36, 2, 36, 3, 45, 37, 5, 36, 5, 2, "print", 1, 35, 36, 3, 33, 1, 6, 37, 3, 39, -29, 35, 35, 35, 35,
35, 35, 32, "-- for in loop with dicts and keys --", 2, "print", 1, 35, 32, "first", 32, "v1", 32, "second", 32, "v2",
32, "third", 32, "v3", 42, 3, 36, 0, 36, 1, 2, "keys", 1, 36, 1, 2, "values", 1, 33, 0, 36, 3, 2, "length", 1, 31, 31,
36, 5, 36, 4, 15, 40, 31, 36, 2, 36, 4, 45, 37, 6, 36, 3, 36, 4, 45, 37, 7, 36, 7, 36, 6, 2, "print", 2, 35, 36, 4, 33,
1, 6, 37, 4, 39, -38, 35, 35, 35, 35, 35, 35, 35, 35]

View File

@ -0,0 +1,7 @@
["_h", 32, " hello world ", 2, "trim", 1, 2, "print", 1, 35, 32, " hello world ", 2, "trimLeft", 1, 2, "print", 1,
35, 32, " hello world ", 2, "trimRight", 1, 2, "print", 1, 35, 32, "x", 32, "xxxx hello world xx", 2, "trim", 2, 2,
"print", 1, 35, 32, "x", 32, "xxxx hello world xx", 2, "trimLeft", 2, 2, "print", 1, 35, 32, "x", 32,
"xxxx hello world xx", 2, "trimRight", 2, 2, "print", 1, 35, 32, "hello world and more", 32, " ", 2, "splitByString",
2, 2, "print", 1, 35, 33, 1, 32, "hello world and more", 32, " ", 2, "splitByString", 3, 2, "print", 1, 35, 33, 2, 32,
"hello world and more", 32, " ", 2, "splitByString", 3, 2, "print", 1, 35, 33, 10, 32, "hello world and more", 32, " ",
2, "splitByString", 3, 2, "print", 1, 35]

View File

@ -0,0 +1,10 @@
hello world
hello world
hello world
hello world
hello world xx
xxxx hello world
['hello', 'world', 'and', 'more']
['hello']
['hello', 'world']
['hello', 'world', 'and', 'more']

View File

@ -18,3 +18,32 @@ print([1, [2, [3, 4], ], 5]?.6?.3?.1)
print([1, [2, [3, 4], ], 5]?.[6]?.[3]?.[1])
print([1, [2, [3, 4]], 5][1][1][1] + 1)
print([1, [2, [3, 4, ], ], 5, ].1.1.1)
print('------')
print(arrayPushBack([1,2,3], 4))
print(arrayPushFront([1,2,3], 0))
print(arrayPopBack([1,2,3]))
print(arrayPopFront([1,2,3]))
print(arraySort([3,2,1]))
print(arrayReverse([1,2,3]))
print(arrayReverseSort([3,2,1]))
print(arrayStringConcat([1,2,3], ','))
print('-----')
let arr := [1,2,3,4] // we don't modify arr
print(arr)
arrayPushBack(arr, 5)
print(arr)
arrayPushFront(arr, 0)
print(arr)
arrayPopBack(arr)
print(arr)
arrayPopFront(arr)
print(arr)
arraySort(arr)
print(arr)
arrayReverse(arr)
print(arr)
arrayReverseSort(arr)
print(arr)

View File

@ -0,0 +1,8 @@
let string := 'this is a secure string'
print('string:', string)
print('md5Hex(string):', md5Hex(string))
print('sha256Hex(string):', sha256Hex(string))
let data := ['1', 'string', 'more', 'keys']
print('data:', data)
print('sha256HmacChainHex(data):', sha256HmacChainHex(data))

View File

@ -2,6 +2,7 @@ let dt := fromUnixTimestamp(1234377543.123456)
print(formatDateTime(dt, '%Y-%m-%d %H:%i:%S'))
print(formatDateTime(dt, '%Y-%m-%d %H:%i:%S', 'Europe/Brussels'))
print(formatDateTime(dt, '%Y-%m-%d %H:%i:%S', 'America/New_York'))
print(formatDateTime(dt, '%Y%m%dT%H%i%sZ'))
print('-----')
print('%a: ' || formatDateTime(dt, '%a'))

View File

@ -0,0 +1,10 @@
print(trim(' hello world '))
print(trimLeft(' hello world '))
print(trimRight(' hello world '))
print(trim('xxxx hello world xx', 'x'))
print(trimLeft('xxxx hello world xx', 'x'))
print(trimRight('xxxx hello world xx', 'x'))
print(splitByString(' ', 'hello world and more'))
print(splitByString(' ', 'hello world and more', 1))
print(splitByString(' ', 'hello world and more', 2))
print(splitByString(' ', 'hello world and more', 10))

View File

@ -208,18 +208,24 @@ def execute_bytecode(
push_stack({})
case Operation.ARRAY:
count = next_token()
elems = stack[-count:]
stack = stack[:-count]
mem_used -= sum(mem_stack[-count:])
mem_stack = mem_stack[:-count]
push_stack(elems)
if count > 0:
elems = stack[-count:]
stack = stack[:-count]
mem_used -= sum(mem_stack[-count:])
mem_stack = mem_stack[:-count]
push_stack(elems)
else:
push_stack([])
case Operation.TUPLE:
count = next_token()
elems = stack[-count:]
stack = stack[:-count]
mem_used -= sum(mem_stack[-count:])
mem_stack = mem_stack[:-count]
push_stack(tuple(elems))
if count > 0:
elems = stack[-count:]
stack = stack[:-count]
mem_used -= sum(mem_stack[-count:])
mem_stack = mem_stack[:-count]
push_stack(tuple(elems))
else:
push_stack(())
case Operation.JUMP:
count = next_token()
ip += count

View File

@ -21,6 +21,7 @@ from .date import (
is_hog_datetime,
is_hog_date,
)
from .crypto import sha256Hex, md5Hex, sha256HmacChainHex
if TYPE_CHECKING:
from posthog.models import Team
@ -210,12 +211,53 @@ def replaceAll(args: list[Any], team: Optional["Team"], stdout: Optional[list[st
return args[0].replace(args[1], args[2])
def trim(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]], timeout: int) -> str:
if len(args) > 1 and len(args[1]) > 1:
return ""
return args[0].strip(args[1] if len(args) > 1 else None)
def trimLeft(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]], timeout: int) -> str:
if len(args) > 1 and len(args[1]) > 1:
return ""
return args[0].lstrip(args[1] if len(args) > 1 else None)
def trimRight(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]], timeout: int) -> str:
if len(args) > 1 and len(args[1]) > 1:
return ""
return args[0].rstrip(args[1] if len(args) > 1 else None)
def splitByString(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]], timeout: int) -> list:
separator = args[0]
string = args[1]
if len(args) > 2:
parts = string.split(separator, args[2])
if len(parts) > args[2]:
return parts[: args[2]]
return parts
return string.split(separator)
def generateUUIDv4(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]], timeout: int) -> str:
import uuid
return str(uuid.uuid4())
def _sha256Hex(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]], timeout: int) -> str:
return sha256Hex(args[0])
def _md5Hex(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]], timeout: int) -> str:
return md5Hex(args[0])
def _sha256HmacChainHex(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]], timeout: int) -> str:
return sha256HmacChainHex(args[0])
def keys(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]], timeout: int) -> list:
obj = args[0]
if isinstance(obj, dict):
@ -234,6 +276,65 @@ def values(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]],
return []
def arrayPushBack(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]], timeout: int) -> list:
arr = args[0]
item = args[1]
if not isinstance(arr, list):
return [item]
return [*arr, item]
def arrayPushFront(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]], timeout: int) -> list:
arr = args[0]
item = args[1]
if not isinstance(arr, list):
return [item]
return [item, *arr]
def arrayPopBack(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]], timeout: int) -> list:
arr = args[0]
if not isinstance(arr, list):
return []
return arr[:-1]
def arrayPopFront(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]], timeout: int) -> list:
arr = args[0]
if not isinstance(arr, list):
return []
return arr[1:]
def arraySort(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]], timeout: int) -> list:
arr = args[0]
if not isinstance(arr, list):
return []
return sorted(arr)
def arrayReverse(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]], timeout: int) -> list:
arr = args[0]
if not isinstance(arr, list):
return []
return arr[::-1]
def arrayReverseSort(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]], timeout: int) -> list:
arr = args[0]
if not isinstance(arr, list):
return []
return sorted(arr, reverse=True)
def arrayStringConcat(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]], timeout: int) -> str:
arr = args[0]
sep = args[1] if len(args) > 1 else ""
if not isinstance(arr, list):
return ""
return sep.join([str(s) for s in arr])
def _now(args: list[Any], team: Optional["Team"], stdout: Optional[list[str]], timeout: int) -> Any:
return now()
@ -298,9 +399,24 @@ STL: dict[str, Callable[[list[Any], Optional["Team"], list[str] | None, int], An
"decodeURLComponent": decodeURLComponent,
"replaceOne": replaceOne,
"replaceAll": replaceAll,
"trim": trim,
"trimLeft": trimLeft,
"trimRight": trimRight,
"splitByString": splitByString,
"generateUUIDv4": generateUUIDv4,
"sha256Hex": _sha256Hex,
"md5Hex": _md5Hex,
"sha256HmacChainHex": _sha256HmacChainHex,
"keys": keys,
"values": values,
"arrayPushBack": arrayPushBack,
"arrayPushFront": arrayPushFront,
"arrayPopBack": arrayPopBack,
"arrayPopFront": arrayPopFront,
"arraySort": arraySort,
"arrayReverse": arrayReverse,
"arrayReverseSort": arrayReverseSort,
"arrayStringConcat": arrayStringConcat,
"now": _now,
"toUnixTimestamp": _toUnixTimestamp,
"fromUnixTimestamp": _fromUnixTimestamp,

View File

@ -0,0 +1,21 @@
import hashlib
import hmac
def md5Hex(data: str) -> str:
return hashlib.md5(data.encode()).hexdigest()
def sha256Hex(data: str) -> str:
return hashlib.sha256(data.encode()).hexdigest()
def sha256HmacChainHex(data: list) -> str:
if len(data) < 2:
raise ValueError("Data array must contain at least two elements.")
hmac_obj = hmac.new(data[0].encode(), data[1].encode(), hashlib.sha256)
for i in range(2, len(data)):
hmac_obj = hmac.new(hmac_obj.digest(), data[i].encode(), hashlib.sha256)
return hmac_obj.hexdigest()

View File

@ -1,6 +1,6 @@
{
"name": "@posthog/hogvm",
"version": "1.0.25",
"version": "1.0.26",
"description": "PostHog Hog Virtual Machine",
"types": "dist/index.d.ts",
"main": "dist/index.js",

View File

@ -0,0 +1,22 @@
import * as crypto from 'crypto'
export function sha256Hex(data: string): string {
return crypto.createHash('sha256').update(data).digest('hex')
}
export function md5Hex(data: string): string {
return crypto.createHash('md5').update(data).digest('hex')
}
export function sha256HmacChainHex(data: string[]): string {
if (data.length < 2) {
throw new Error('Data array must contain at least two elements.')
}
let hmac = crypto.createHmac('sha256', data[0])
hmac.update(data[1])
for (let i = 2; i < data.length; i++) {
hmac = crypto.createHmac('sha256', hmac.digest())
hmac.update(data[i])
}
return hmac.digest('hex')
}

View File

@ -57,7 +57,7 @@ export function toHogDateTime(timestamp: number | HogDate, zone?: string): HogDa
// EXPORTED STL functions
export function now(zone?: string): HogDateTime {
return toHogDateTime(Date.now(), zone)
return toHogDateTime(Date.now() / 1000, zone)
}
export function toUnixTimestamp(input: HogDateTime | HogDate | string, zone?: string): number {

View File

@ -1,5 +1,4 @@
import { DateTime } from 'luxon'
import {
fromUnixTimestamp,
fromUnixTimestampMilli,
@ -15,6 +14,7 @@ import {
toUnixTimestampMilli,
formatDateTime,
} from './date'
import { sha256Hex, sha256HmacChainHex, md5Hex } from './crypto'
import { printHogStringOutput } from './print'
export const STL: Record<string, (args: any[], name: string, timeout: number) => any> = {
@ -189,6 +189,49 @@ export const STL: Record<string, (args: any[], name: string, timeout: number) =>
replaceAll(args) {
return args[0].replaceAll(args[1], args[2])
},
trim([str, char = ' ']) {
if (char.length !== 1) {
return ''
}
let start = 0
while (str[start] === char) {
start++
}
let end = str.length
while (str[end - 1] === char) {
end--
}
if (start >= end) {
return ''
}
return str.slice(start, end)
},
trimLeft([str, char = ' ']) {
if (char.length !== 1) {
return ''
}
let start = 0
while (str[start] === char) {
start++
}
return str.slice(start)
},
trimRight([str, char = ' ']) {
if (char.length !== 1) {
return ''
}
let end = str.length
while (str[end - 1] === char) {
end--
}
return str.slice(0, end)
},
splitByString([separator, str, maxSplits = undefined]) {
if (maxSplits === undefined) {
return str.split(separator)
}
return str.split(separator, maxSplits)
},
generateUUIDv4() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
const r = (Math.random() * 16) | 0
@ -196,8 +239,16 @@ export const STL: Record<string, (args: any[], name: string, timeout: number) =>
return v.toString(16)
})
},
keys(args) {
const obj = args[0]
sha256Hex([str]) {
return sha256Hex(str)
},
md5Hex([str]) {
return md5Hex(str)
},
sha256HmacChainHex([data]) {
return sha256HmacChainHex(data)
},
keys([obj]) {
if (typeof obj === 'object') {
if (Array.isArray(obj)) {
return Array.from(obj.keys())
@ -208,8 +259,7 @@ export const STL: Record<string, (args: any[], name: string, timeout: number) =>
}
return []
},
values(args) {
const obj = args[0]
values([obj]) {
if (typeof obj === 'object') {
if (Array.isArray(obj)) {
return [...obj]
@ -220,6 +270,54 @@ export const STL: Record<string, (args: any[], name: string, timeout: number) =>
}
return []
},
arrayPushBack([arr, item]) {
if (!Array.isArray(arr)) {
return [item]
}
return [...arr, item]
},
arrayPushFront([arr, item]) {
if (!Array.isArray(arr)) {
return [item]
}
return [item, ...arr]
},
arrayPopBack([arr]) {
if (!Array.isArray(arr)) {
return []
}
return arr.slice(0, arr.length - 1)
},
arrayPopFront([arr]) {
if (!Array.isArray(arr)) {
return []
}
return arr.slice(1)
},
arraySort([arr]) {
if (!Array.isArray(arr)) {
return []
}
return [...arr].sort()
},
arrayReverse([arr]) {
if (!Array.isArray(arr)) {
return []
}
return [...arr].reverse()
},
arrayReverseSort([arr]) {
if (!Array.isArray(arr)) {
return []
}
return [...arr].sort().reverse()
},
arrayStringConcat([arr, separator = '']) {
if (!Array.isArray(arr)) {
return ''
}
return arr.join(separator)
},
now() {
return now()
},

View File

@ -50,7 +50,7 @@
"@google-cloud/storage": "^5.8.5",
"@maxmind/geoip2-node": "^3.4.0",
"@posthog/clickhouse": "^1.7.0",
"@posthog/hogvm": "^1.0.25",
"@posthog/hogvm": "^1.0.26",
"@posthog/plugin-scaffold": "1.4.4",
"@sentry/node": "^7.49.0",
"@sentry/profiling-node": "^0.3.0",

View File

@ -44,8 +44,8 @@ dependencies:
specifier: ^1.7.0
version: 1.7.0
'@posthog/hogvm':
specifier: ^1.0.25
version: 1.0.25(luxon@3.4.4)(re2@1.20.3)
specifier: ^1.0.26
version: 1.0.26(luxon@3.4.4)(re2@1.20.3)
'@posthog/plugin-scaffold':
specifier: 1.4.4
version: 1.4.4
@ -3110,8 +3110,8 @@ packages:
engines: {node: '>=12'}
dev: false
/@posthog/hogvm@1.0.25(luxon@3.4.4)(re2@1.20.3):
resolution: {integrity: sha512-q8j/vN/OXcRKYseCZ6veHoKcGqP9bdM+S3ECs0MGRrr7iyEKF6I7hUtu+jS5mD3Ubo+ceo8DQfTj/Me+s/4cBA==}
/@posthog/hogvm@1.0.26(luxon@3.4.4)(re2@1.20.3):
resolution: {integrity: sha512-lkJflxu/LP9TnXXW1FCePr2iaKKD7XKq68ipmtFY7v43km3ma0Se4NnuftiSX9evGIpQVXT/9JB5LY9waM/lJw==}
peerDependencies:
luxon: ^3.4.4
re2: ^1.21.3

View File

@ -5,10 +5,10 @@ from .hubspot.template_hubspot import template as hubspot
from .customerio.template_customerio import template as customerio
from .intercom.template_intercom import template as intercom
from .clearbit.template_clearbit import template as clearbit
from .aws_kinesis.template_aws_kinesis import template as aws_kinesis
HOG_FUNCTION_TEMPLATES = [webhook, hello_world, slack, hubspot, customerio, intercom, clearbit]
HOG_FUNCTION_TEMPLATES = [webhook, hello_world, slack, hubspot, customerio, intercom, clearbit, aws_kinesis]
HOG_FUNCTION_TEMPLATES_BY_ID = {template.id: template for template in HOG_FUNCTION_TEMPLATES}
__all__ = ["HOG_FUNCTION_TEMPLATES", "HOG_FUNCTION_TEMPLATES_BY_ID"]

View File

@ -0,0 +1,134 @@
from posthog.cdp.templates.hog_function_template import HogFunctionTemplate
template: HogFunctionTemplate = HogFunctionTemplate(
status="beta",
id="template-aws-kinesis",
name="AWS Kinesis",
description="Put data to an AWS Kinesis stream",
# icon_url="/api/projects/@current/hog_functions/icon/?id=posthog.com&temp=true",
hog="""
fn uploadToKinesis(data) {
let region := inputs.aws_region
let endpoint := f'https://kinesis.{region}.amazonaws.com'
let service := 'kinesis'
let amzDate := formatDateTime(now(), '%Y%m%dT%H%i%sZ')
let date := formatDateTime(now(), '%Y%m%d')
let payload := jsonStringify({
'StreamName': inputs.aws_kinesis_stream_arn,
'PartitionKey': inputs.aws_kinesis_partition_key,
'Data': base64Encode(data),
})
let requestHeaders := {
'Content-Type': 'application/x-amz-json-1.1',
'X-Amz-Target': 'Kinesis_20131202.PutRecord',
'X-Amz-Date': amzDate,
'Host': f'kinesis.{region}.amazonaws.com',
}
let canonicalHeaderParts := []
for (let key, value in requestHeaders) {
let val := replaceAll(trim(value), '\\\\s+', ' ')
canonicalHeaderParts := arrayPushBack(canonicalHeaderParts, f'{lower(key)}:{val}')
}
let canonicalHeaders := arrayStringConcat(arraySort(canonicalHeaderParts), '\\n') || '\\n'
let signedHeaderParts := []
for (let key, value in requestHeaders) {
signedHeaderParts := arrayPushBack(signedHeaderParts, lower(key))
}
let signedHeaders := arrayStringConcat(arraySort(signedHeaderParts), ';')
let canonicalRequest := arrayStringConcat([
'POST',
'/',
'',
canonicalHeaders,
signedHeaders,
sha256Hex(payload),
], '\\n')
let credentialScope := f'{date}/{region}/{service}/aws4_request'
let stringToSign := arrayStringConcat([
'AWS4-HMAC-SHA256',
amzDate,
credentialScope,
sha256Hex(canonicalRequest),
], '\\n')
let signature := sha256HmacChainHex([
f'AWS4{inputs.aws_secret_access_key}', date, region, service, 'aws4_request', stringToSign
])
let authorizationHeader :=
f'AWS4-HMAC-SHA256 Credential={inputs.aws_access_key_id}/{credentialScope}, ' ||
f'SignedHeaders={signedHeaders}, ' ||
f'Signature={signature}'
requestHeaders['Authorization'] := authorizationHeader
let res := fetch(endpoint, {
'headers': requestHeaders,
'body': payload,
'method': 'POST'
})
if (res.status >= 200 and res.status < 300) {
print('Event sent successfully!')
return
}
print('Error sending event:', res.status, res.body)
}
uploadToKinesis(jsonStringify(inputs.payload))
""".strip(),
inputs_schema=[
{
"key": "aws_access_key_id",
"type": "string",
"label": "AWS Access Key ID",
"secret": True,
"required": True,
},
{
"key": "aws_secret_access_key",
"type": "string",
"label": "AWS Secret Access Key",
"secret": True,
"required": True,
},
{
"key": "aws_region",
"type": "string",
"label": "AWS Region",
"secret": False,
"required": True,
"default": "us-east-1",
},
{
"key": "aws_kinesis_stream_arn",
"type": "string",
"label": "Kinesis Stream ARN",
"secret": False,
"required": True,
},
{
"key": "aws_kinesis_partition_key",
"type": "string",
"label": "Kinesis Partition Key",
"secret": False,
"required": False,
},
{
"key": "payload",
"type": "json",
"label": "Message Payload",
"default": {"event": "{event}", "person": "{person}"},
"secret": False,
"required": False,
},
],
)

View File

@ -0,0 +1,36 @@
from freezegun import freeze_time
from posthog.cdp.templates.helpers import BaseHogFunctionTemplateTest
from posthog.cdp.templates.aws_kinesis.template_aws_kinesis import template as template_aws_kinesis
class TestTemplateAwsKinesis(BaseHogFunctionTemplateTest):
template = template_aws_kinesis
@freeze_time("2024-04-16T12:34:51Z")
def test_function_works(self):
res = self.run_function(
inputs={
"aws_access_key_id": "aws_access_key_id",
"aws_secret_access_key": "aws_secret_access_key",
"aws_region": "aws_region",
"aws_kinesis_stream_arn": "aws_kinesis_stream_arn",
"aws_kinesis_partition_key": "1",
"payload": {"hello": "world"},
}
)
assert res.result is None
assert self.get_mock_fetch_calls()[0] == (
"https://kinesis.aws_region.amazonaws.com",
{
"headers": {
"Content-Type": "application/x-amz-json-1.1",
"X-Amz-Target": "Kinesis_20131202.PutRecord",
"X-Amz-Date": "20240416T123451Z",
"Host": "kinesis.aws_region.amazonaws.com",
"Authorization": "AWS4-HMAC-SHA256 Credential=aws_access_key_id/20240416/aws_region/kinesis/aws4_request, SignedHeaders=content-type;host;x-amz-date;x-amz-target, Signature=65b18913b42d8a7a1d33c0711da192d5a2e99eb79fb08ab3e5eefb6488b903ff",
},
"body": '{"StreamName": "aws_kinesis_stream_arn", "PartitionKey": "1", "Data": "eyJoZWxsbyI6ICJ3b3JsZCJ9"}',
"method": "POST",
},
)

View File

@ -248,7 +248,7 @@ class BytecodeBuilder(Visitor):
return response
if node.name not in STL and node.name not in self.functions and node.name not in self.supported_functions:
raise QueryError(f"HogQL function `{node.name}` is not implemented")
raise QueryError(f"Hog function `{node.name}` is not implemented")
if node.name in self.functions and len(node.args) != len(self.functions[node.name].params):
raise QueryError(
f"Function `{node.name}` expects {len(self.functions[node.name].params)} arguments, got {len(node.args)}"
@ -346,27 +346,31 @@ class BytecodeBuilder(Visitor):
# set up a bunch of temporary variables
expr_local = self._declare_local("__H_expr_H__") # the obj/array itself
expr_keys_local = self._declare_local("__H_keys_H__") # keys
expr_values_local = self._declare_local("__H_values_H__") # values
loop_index_local = self._declare_local("__H_index_H__") # 0
loop_limit_local = self._declare_local("__H_limit_H__") # length of keys
key_var_local = self._declare_local(key_var) if key_var is not None else -1 # loop key
value_var_local = self._declare_local(value_var) # loop value
response.extend([Operation.NULL] * (7 if key_var is not None else 6))
response.extend([*self.visit(node.expr), Operation.SET_LOCAL, expr_local])
response.extend(self.visit(node.expr))
# populate keys, value, loop index and max loop index
if key_var is not None:
response.extend(
[Operation.GET_LOCAL, expr_local, Operation.CALL, "keys", 1, Operation.SET_LOCAL, expr_keys_local]
)
response.extend(
[Operation.GET_LOCAL, expr_local, Operation.CALL, "values", 1, Operation.SET_LOCAL, expr_values_local]
)
response.extend([Operation.INTEGER, 0, Operation.SET_LOCAL, loop_index_local])
response.extend(
[Operation.GET_LOCAL, expr_values_local, Operation.CALL, "length", 1, Operation.SET_LOCAL, loop_limit_local]
)
expr_keys_local = self._declare_local("__H_keys_H__") # keys
response.extend([Operation.GET_LOCAL, expr_local, Operation.CALL, "keys", 1])
else:
expr_keys_local = None
expr_values_local = self._declare_local("__H_values_H__") # values
response.extend([Operation.GET_LOCAL, expr_local, Operation.CALL, "values", 1])
loop_index_local = self._declare_local("__H_index_H__") # 0
response.extend([Operation.INTEGER, 0])
loop_limit_local = self._declare_local("__H_limit_H__") # length of keys
response.extend([Operation.GET_LOCAL, expr_values_local, Operation.CALL, "length", 1])
if key_var is not None:
key_var_local = self._declare_local(key_var) # loop key
response.extend([Operation.NULL])
else:
key_var_local = None
value_var_local = self._declare_local(value_var) # loop value
response.extend([Operation.NULL])
# check if loop_index < loop_limit
condition = [Operation.GET_LOCAL, loop_limit_local, Operation.GET_LOCAL, loop_index_local, Operation.LT]

View File

@ -339,7 +339,7 @@ class TestMetadata(ClickhouseTestMixin, APIBaseTest):
"isValidView": False,
"notices": [],
"warnings": [],
"errors": [{"end": 15, "fix": None, "message": "HogQL function `NONO` is not implemented", "start": 9}],
"errors": [{"end": 15, "fix": None, "message": "Hog function `NONO` is not implemented", "start": 9}],
},
)
@ -361,8 +361,6 @@ class TestMetadata(ClickhouseTestMixin, APIBaseTest):
metadata.dict()
| {
"isValid": False,
"errors": [
{"end": 17, "fix": None, "message": "HogQL function `NONO` is not implemented", "start": 11}
],
"errors": [{"end": 17, "fix": None, "message": "Hog function `NONO` is not implemented", "start": 11}],
},
)