JavaScript UDF ์ ํ ์ฌํญยถ
Snowflake ํ๊ฒฝ ๋ด์์ ์์ ์ฑ์ ๋ณด์ฅํ๊ธฐ ์ํด Snowflake๋ JavaScript UDF์ ๋ค์๊ณผ ๊ฐ์ ์ ํ ์ฌํญ์ ์ ์ฉํฉ๋๋ค. ์ด๋ฌํ ์ ํ ์ฌํญ์ UDF ์์ฑ ์ ํธ์ถ๋์ง ์๊ณ , ์คํ๋ ค UDF๊ฐ ํธ์ถ๋ ๋ ๋ฐํ์์ ํธ์ถ๋ฉ๋๋ค. ์ด ํญ๋ชฉ์์๋ ์ผ๋ฐ JavaScript UDF(์ฌ์ฉ์ ์ ์ ํจ์) ์๊ตฌ ์ฌํญ ๋ฐ ์ฌ์ฉ ์ธ๋ถ ์ ๋ณด, ๊ทธ๋ฆฌ๊ณ JavaScript UDF์ ๊ด๋ จ๋ ์ ํ ์ฌํญ์ ๋ค๋ฃน๋๋ค.
์ด ํญ๋ชฉ์ ๋ด์ฉ:
JavaScript ์๋ณธ ์ฝ๋์ ์ต๋ ํฌ๊ธฐยถ
Snowflake์์๋ JavaScript UDF์ ๋ณธ๋ฌธ์์ JavaScript ์์ค ์ฝ๋์ ์ต๋ ํฌ๊ธฐ๋ฅผ ์ ํํฉ๋๋ค. Snowflake์์๋ ์ด ํฌ๊ธฐ๋ฅผ 100KB๋ก ์ ํํ ๊ฒ์ ๊ถ์ฅํฉ๋๋ค. (์ฝ๋๋ ์์ถ๋ ํํ๋ก ์ ์ฅ๋๋ฉฐ ์ ํํ ์ ํ์ ์ฝ๋์ ์์ถ๋ฅ ์ ๋ฐ๋ผ ๋ค๋ฆ ๋๋ค.)
๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋๋ฌด ๋ง์ด ์ฌ์ฉํ๋ฉด UDF๊ฐ ์คํจํ๊ฒ ๋ฉ๋๋ค.ยถ
JavaScript UDF๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋๋ฌด ๋ง์ด ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์คํจํ๊ฒ ๋ฉ๋๋ค. ํน์ ์ ํ์ ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค. ๋๋ฌด ๋ง์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ฉด ์ค๋ฅ๊ฐ ๋ฐํ๋ฉ๋๋ค.
์๋ฃํ๋ ๋ฐ ๋๋ฌด ์ค๋ ๊ฑธ๋ฆฌ๋ฉด UDF๊ฐ ์ข ๋ฃ๋๊ณ ์ค๋ฅ๊ฐ ๋ฐํ๋ฉ๋๋ค.ยถ
์๋ฃํ๋ ๋ฐ ๋๋ฌด ์ค๋ ๊ฑธ๋ฆฌ๋ JavaScript UDF๋ ์ข ๋ฃ๋์ด ์ฌ์ฉ์์๊ฒ ์ค๋ฅ๊ฐ ๋ฐํ๋ฉ๋๋ค. ๋ํ, ๋ฌดํ ๋ฃจํ์ ๋ค์ด๊ฐ๋ JavaScript UDF๋ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค.
๊ณผ๋ํ ์คํ ๊น์ด๋ก ์ธํด ์ค๋ฅ๊ฐ ๋ฐ์ํจยถ
์ฌ๊ท๋ก ์ธํ ๊ณผ๋ํ ์คํ ๊น์ด๋ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค.
์ ์ญ ์ํยถ
์ผ๋ฐ์ ์ผ๋ก Snowflake๋ UDF ๋ฐ๋ณต ์ฌ์ด์ JavaScript ์ ์ญ ์ํ๋ฅผ ์ ์งํฉ๋๋ค. ๊ทธ๋ฌ๋ ํจ์ ํธ์ถ ์ฌ์ด์ ์ฌ์ฉํ ์ ์๋ ์ ์ญ ์ํ์ ๋ํ ์ด์ ์์ ์ฌํญ์ ์์กดํด์๋ ์ ๋ฉ๋๋ค. ๋ํ, ๋ชจ๋ ํ์ด ๋์ผ JavaScript ํ๊ฒฝ ๋ด์์ ์คํ๋ ๊ฒ์ด๋ผ๊ณ ๊ฐ์ ํด์๋ ์ ๋ฉ๋๋ค.
์ค์ ๋ก ์ ์ญ ์ํ๋ ๋ค์๊ณผ ๊ด๋ จ์ด ์์ต๋๋ค.
๋ณต์กํ๊ฑฐ๋ ๋ถ๋ด์ด ํฐ ์ด๊ธฐํ ๋ ผ๋ฆฌ. ๊ธฐ๋ณธ์ ์ผ๋ก, ์ ๊ณต๋ UDF ์ฝ๋๋ ์ฒ๋ฆฌ๋ ๋ชจ๋ ํ์ ๋ํด ํ๊ฐ๋ฉ๋๋ค. ํด๋น ์ฝ๋์ ๋ณต์กํ ๋ ผ๋ฆฌ๊ฐ ํฌํจ๋์ด ์์ผ๋ฉด ์ด๋ ๋นํจ์จ์ ์ผ ์ ์์ต๋๋ค.
idempotent๊ฐ ์๋ ์ฝ๋๊ฐ ํฌํจ๋ ํจ์. ์ผ๋ฐ์ ์ธ ํจํด์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
Date.prototype._originalToString = Date.prototype.toString; Date.prototype.toString = function() { /* ... SOME CUSTOM CODE ... */ this._originalToString() }
์ด ์ฝ๋๋ ์ฒ์ ์คํ๋ ๋
toString
๋ฐ_originalToString
์ํ๋ฅผ ๋ณ๊ฒฝํฉ๋๋ค. ์ด๋ฌํ ๋ณ๊ฒฝ ์ฌํญ์ ์ ์ญ ์ํ๋ก ์ ์ง๋๋ฉฐ ์ด ์ฝ๋๊ฐ ๋ ๋ฒ์งธ๋ก ์คํ๋๋ ๊ฒฝ์ฐ, ์ฌ๊ท๋ฅผ ์์ฑํ๋ ๋ฐฉ์์ผ๋ก ๊ฐ์ด ๋ค์ ๋ณ๊ฒฝ๋ฉ๋๋ค.toString
์ด ๋ ๋ฒ์งธ๋ก ํธ์ถ๋๋ฉด ์ฝ๋๊ฐ ๋ฌดํํ ๋ฐ๋ณต๋ฉ๋๋ค(์คํ ๊ณต๊ฐ์ด ์์ง๋ ๋๊น์ง).
์ด๋ฌํ ์ํฉ์์ ๊ถ์ฅ๋๋ ํจํด์ JavaScript์ ์ ์ญ ๋ณ์ ์๋ฏธ ์ฒด๊ณ๋ฅผ ์ฌ์ฉํ์ฌ ๊ด๋ จ ์ฝ๋๊ฐ ํ ๋ฒ๋ง ํ๊ฐ๋๋๋ก ๋ณด์ฅํ๋ ๊ฒ์ ๋๋ค. ์๋ฅผ ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
var setup = function() { /* SETUP LOGIC */ }; if (typeof(setup_done) === "undefined") { setup(); setup_done = true; // setting global variable to true }
์ด ๋ฉ์ปค๋์ฆ์ ์ฝ๋ ํ๊ฐ์ ํจ๊ณผ๋ฅผ ์บ์ํ๋ ๊ฒฝ์ฐ์๋ง ์์ ํฉ๋๋ค. ์ด๊ธฐํ ํ์ ์ ์ญ ์ปจํ ์คํธ๊ฐ ๋ชจ๋ ํ์ ๋ํด ๋ณด์กด๋๋ค๋ ๋ณด์ฅ์ ์์ผ๋ฉฐ ๋น์ฆ๋์ค ๋ ผ๋ฆฌ๋ ์ด์ ์์กดํ์ง ์์์ผ ํฉ๋๋ค.
JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌยถ
JavaScript UDF๋ ํ์ค JavaScript ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํ ์ก์ธ์ค๋ฅผ ์ง์ํฉ๋๋ค. ์ฌ๊ธฐ์๋ ๋ธ๋ผ์ฐ์ ์์ ์ผ๋ฐ์ ์ผ๋ก ์ ๊ณตํ๋ ๋ง์ ์ค๋ธ์ ํธ์ ๋ฉ์๋๊ฐ ์ ์ธ๋ฉ๋๋ค. ์ถ๊ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ฐ์ ธ์ค๊ฑฐ๋ ํฌํจํ๊ฑฐ๋ ํธ์ถํ๋ ๋ฉ์ปค๋์ฆ์ด ์์ต๋๋ค. ๋ชจ๋ ํ์ ์ฝ๋๋ UDF์ ํฌํจ๋์ด์ผ ํฉ๋๋ค.
๋ํ, ๊ธฐ๋ณธ ์ ๊ณต JavaScript eval()
ํจ์๊ฐ ๋นํ์ฑํ๋ฉ๋๋ค.
๋ฐํ๋ ๋ฒ ๋ฆฌ์ธํธ ํฌ๊ธฐ ๋ฐ ๊น์ดยถ
๋ฐํ๋ ๋ฒ ๋ฆฌ์ธํธ ์ค๋ธ์ ํธ์๋ ํฌ๊ธฐ ๋ฐ ์ค์ฒฉ ๊น์ด ์ ํ์ด ์ ์ฉ๋ฉ๋๋ค.
- ํฌ๊ธฐ:
ํ์ฌ ๋ช ๋ฉ๊ฐ๋ฐ์ดํธ๋ก ์ ํ๋์ด ์์ง๋ง, ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค.
- ๊น์ด:
ํ์ฌ ์ค์ฒฉ ๊น์ด๋ 1000์ผ๋ก ์ ํ๋์ง๋ง ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค.
์ค๋ธ์ ํธ๊ฐ ๋๋ฌด ํฌ๊ฑฐ๋ ๋๋ฌด ๊น์ผ๋ฉด UDF ํธ์ถ ์ ์ค๋ฅ๊ฐ ๋ฐํ๋ฉ๋๋ค.
์ธ์ ๋ฐ ๋ฐํ ์ ํ ์ ์ฝ ์กฐ๊ฑด์ด ๋๋๋ก ๋ฌด์๋จยถ
์ธ์ ๋๋ ๋ฐํ ๊ฐ์ ๋ํด ์ ์ธ๋ ํน์ ์ ํ์ ํน์ฑ์ UDF ํธ์ถ ์ ๋ฌด์๋ฉ๋๋ค. ์ด๋ฌํ ๊ฒฝ์ฐ ์์ ๋ ๊ฐ์ ์ ์ธ์ ์ง์ ๋ ์ ์ฝ ์กฐ๊ฑด์ ์ค์ํ๋์ง ์ฌ๋ถ์ ๊ด๊ณ์์ด ์์ ๋ ๊ฐ์ผ๋ก ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
๋ค์์ ๋ ผ๋ฆฌ๊ฐ JavaScript๋ก ์์ฑ๋ UDF์ ๋ํด ๋ฌด์๋ฉ๋๋ค.
VARCHAR ์ ํ์ ์ธ์ ๊ธธ์ด
์ยถ
๋ค์ ์์ ์ ์ฝ๋๋ arg1
์ธ์์ ๋ฐํ ๊ฐ์ด 1์ ์ดํ์ VARCHAR์ด์ด์ผ ํ๋ค๊ณ ์ ์ธํฉ๋๋ค. ํ์ง๋ง ๊ฐ์ด 1์๋ณด๋ค ๊ธด arg1
๋ก ์ด ํจ์๋ฅผ ํธ์ถํ๋ฉด ์ ์ฝ ์กฐ๊ฑด์ด ์ง์ ๋์ง ์์ ๊ฒ์ฒ๋ผ ์ฑ๊ณตํฉ๋๋ค.
CREATE OR REPLACE FUNCTION tf (arg1 VARCHAR(1))
RETURNS VARCHAR(1)
LANGUAGE JAVASCRIPT AS 'return A.substr(3, 3);';