# Storm SQL 語言參考
Storm SQL 使用 Apache Calcite 來轉換和評估 SQL 語句. Storm SQL 還采用了來自 Calcite 的 Rex 編譯器,因此 Storm SQL 將處理由 Calcite 的默認 SQL 解析器識別的 SQL 方言。
本文基于 Calcite 官網的 SQL 參考手冊, 移除了部分 Storm SQL 不支持的內容, 添加了一些 Storm SQL 支持的內容.
請先閱讀 [Storm SQL integration](storm-sql.html) 頁面, 了解 Storm SQL 支持哪些特性.
## 語法
Calcite 提供豐富的 SQL 語法. 但是 Storm SQL 并不是一個數據庫系統, 它用于處理流式數據, 因此只支持語法的子集. Storm SQL 不會重定義 SQL 語法, 只優化 Calcite 提供的轉換器, 因此 SQL 語句仍然基于 Calcite 的 SQL 語法進行轉換.
SQL 語法表現為 類[BNF](http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form) 的形式.
<figure class="highlight">
```
statement:
setStatement
| resetStatement
| explain
| describe
| insert
| update
| merge
| delete
| query
setStatement:
[ ALTER ( SYSTEM | SESSION ) ] SET identifier '=' expression
resetStatement:
[ ALTER ( SYSTEM | SESSION ) ] RESET identifier
| [ ALTER ( SYSTEM | SESSION ) ] RESET ALL
explain:
EXPLAIN PLAN
[ WITH TYPE | WITH IMPLEMENTATION | WITHOUT IMPLEMENTATION ]
[ EXCLUDING ATTRIBUTES | INCLUDING [ ALL ] ATTRIBUTES ]
FOR ( query | insert | update | merge | delete )
describe:
DESCRIBE DATABASE databaseName
| DESCRIBE CATALOG [ databaseName . ] catalogName
| DESCRIBE SCHEMA [ [ databaseName . ] catalogName ] . schemaName
| DESCRIBE [ TABLE ] [ [ [ databaseName . ] catalogName . ] schemaName . ] tableName [ columnName ]
| DESCRIBE [ STATEMENT ] ( query | insert | update | merge | delete )
insert:
( INSERT | UPSERT ) INTO tablePrimary
[ '(' column [, column ]* ')' ]
query
update:
UPDATE tablePrimary
SET assign [, assign ]*
[ WHERE booleanExpression ]
assign:
identifier '=' expression
merge:
MERGE INTO tablePrimary [ [ AS ] alias ]
USING tablePrimary
ON booleanExpression
[ WHEN MATCHED THEN UPDATE SET assign [, assign ]* ]
[ WHEN NOT MATCHED THEN INSERT VALUES '(' value [ , value ]* ')' ]
delete:
DELETE FROM tablePrimary [ [ AS ] alias ]
[ WHERE booleanExpression ]
query:
values
| WITH withItem [ , withItem ]* query
| {
select
| selectWithoutFrom
| query UNION [ ALL ] query
| query EXCEPT query
| query INTERSECT query
}
[ ORDER BY orderItem [, orderItem ]* ]
[ LIMIT { count | ALL } ]
[ OFFSET start { ROW | ROWS } ]
[ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ]
withItem:
name
[ '(' column [, column ]* ')' ]
AS '(' query ')'
orderItem:
expression [ ASC | DESC ] [ NULLS FIRST | NULLS LAST ]
select:
SELECT [ STREAM ] [ ALL | DISTINCT ]
{ * | projectItem [, projectItem ]* }
FROM tableExpression
[ WHERE booleanExpression ]
[ GROUP BY { groupItem [, groupItem ]* } ]
[ HAVING booleanExpression ]
[ WINDOW windowName AS windowSpec [, windowName AS windowSpec ]* ]
selectWithoutFrom:
SELECT [ ALL | DISTINCT ]
{ * | projectItem [, projectItem ]* }
projectItem:
expression [ [ AS ] columnAlias ]
| tableAlias . *
tableExpression:
tableReference [, tableReference ]*
| tableExpression [ NATURAL ] [ LEFT | RIGHT | FULL ] JOIN tableExpression [ joinCondition ]
joinCondition:
ON booleanExpression
| USING '(' column [, column ]* ')'
tableReference:
tablePrimary
[ [ AS ] alias [ '(' columnAlias [, columnAlias ]* ')' ] ]
tablePrimary:
[ [ catalogName . ] schemaName . ] tableName
'(' TABLE [ [ catalogName . ] schemaName . ] tableName ')'
| [ LATERAL ] '(' query ')'
| UNNEST '(' expression ')' [ WITH ORDINALITY ]
| [ LATERAL ] TABLE '(' [ SPECIFIC ] functionName '(' expression [, expression ]* ')' ')'
values:
VALUES expression [, expression ]*
groupItem:
expression
| '(' ')'
| '(' expression [, expression ]* ')'
| CUBE '(' expression [, expression ]* ')'
| ROLLUP '(' expression [, expression ]* ')'
| GROUPING SETS '(' groupItem [, groupItem ]* ')'
windowRef:
windowName
| windowSpec
windowSpec:
[ windowName ]
'('
[ ORDER BY orderItem [, orderItem ]* ]
[ PARTITION BY expression [, expression ]* ]
[
RANGE numericOrIntervalExpression { PRECEDING | FOLLOWING }
| ROWS numericExpression { PRECEDING | FOLLOWING }
]
')'
```
</figure>
在 _merge_ 中, 必須有 WHEN MATCH 或者 WHEN NOT MATCH 從句的其中之一.
在 _orderItem_ 中, 如果 _expression_ 是一個正整數 _n_, 他表示 SELECT 從句中的第 _n_ 個項目.
聚合查詢是包含 GROUP BY 或 HAVING 的查詢, 子句或 SELECT 子句中的聚合函數。 在 SELECT 中,匯總查詢的 HAVING 和 ORDER BY 子句,所有表達式必須在當前組內是恒定的(即分組常量由GROUP BY子句定義,或常量)或聚合函數或常量和聚合的組合功能。 聚合和分組功能只能出現在聚合查詢,并且僅在 SELECT,HAVING 或 ORDER BY 子句中。
一個標量子查詢是像表達式一樣使用的子查詢. 如果子查詢沒有返回行, 值為 NULL; 如果返回多行, 就是錯誤的.
IN, EXISTS 和 標量子查詢可以在任何使用 expression 的地方使用(比如 SELECT 從句, WHERE 從句, JOIN 后面的 ON 從句, 或者作為一個聚合函數的參數).
一個 IN, EXISTS 或者標量子查詢可能是相關的; 意思是, 可以引用封閉查詢的 FROM 從句中的表。
_selectWithoutFrom_ 等價于 VALUES, 但是并非標準 SQL, 只在允許在特定的[conformance levels](/org/apache/calcite/sql/validate/SqlConformance.html#isFromRequired--)上.
## 關鍵詞
下列是一個 SQL 的關鍵詞列表. 這個列表頁來自于 Calcite SQL 的參考手冊.
A, **ABS**, ABSOLUTE, ACTION, ADA, ADD, ADMIN, AFTER, **ALL**, **ALLOCATE**, **ALLOW**, **ALTER**, ALWAYS, **AND**, **ANY**, **ARE**, **ARRAY**, **AS**, ASC, **ASENSITIVE**, ASSERTION, ASSIGNMENT, **ASYMMETRIC**, **AT**, **ATOMIC**, ATTRIBUTE, ATTRIBUTES, **AUTHORIZATION**, **AVG**, BEFORE, **BEGIN**, BERNOULLI, **BETWEEN**, **BIGINT**, **BINARY**, **BIT**, **BLOB**, **BOOLEAN**, **BOTH**, BREADTH, **BY**, C, **CALL**, **CALLED**, **CARDINALITY**, CASCADE, **CASCADED**, **CASE**, **CAST**, CATALOG, CATALOG_NAME, **CEIL**, **CEILING**, CENTURY, CHAIN, **CHAR**, **CHARACTER**, CHARACTERISTICTS, CHARACTERS, **CHARACTER_LENGTH**, CHARACTER_SET_CATALOG, CHARACTER_SET_NAME, CHARACTER_SET_SCHEMA, **CHAR_LENGTH**, **CHECK**, CLASS_ORIGIN, **CLOB**, **CLOSE**, **COALESCE**, COBOL, **COLLATE**, COLLATION, COLLATION_CATALOG, COLLATION_NAME, COLLATION_SCHEMA, **COLLECT**, **COLUMN**, COLUMN_NAME, COMMAND_FUNCTION, COMMAND_FUNCTION_CODE, **COMMIT**, COMMITTED, **CONDITION**, CONDITION_NUMBER, **CONNECT**, CONNECTION, CONNECTION_NAME, **CONSTRAINT**, CONSTRAINTS, CONSTRAINT_CATALOG, CONSTRAINT_NAME, CONSTRAINT_SCHEMA, CONSTRUCTOR, CONTAINS, CONTINUE, **CONVERT**, **CORR**, **CORRESPONDING**, **COUNT**, **COVAR_POP**, **COVAR_SAMP**, **CREATE**, **CROSS**, **CUBE**, **CUME_DIST**, **CURRENT**, **CURRENT_CATALOG**, **CURRENT_DATE**, **CURRENT_DEFAULT_TRANSFORM_GROUP**, **CURRENT_PATH**, **CURRENT_ROLE**, **CURRENT_SCHEMA**, **CURRENT_TIME**, **CURRENT_TIMESTAMP**, **CURRENT_TRANSFORM_GROUP_FOR_TYPE**, **CURRENT_USER**, **CURSOR**, CURSOR_NAME, **CYCLE**, DATA, DATABASE, **DATE**, DATETIME_INTERVAL_CODE, DATETIME_INTERVAL_PRECISION, **DAY**, **DEALLOCATE**, **DEC**, DECADE, **DECIMAL**, **DECLARE**, **DEFAULT**, DEFAULTS, DEFERRABLE, DEFERRED, DEFINED, DEFINER, DEGREE, **DELETE**, **DENSE_RANK**, DEPTH, **DEREF**, DERIVED, DESC, **DESCRIBE**, DESCRIPTION, DESCRIPTOR, **DETERMINISTIC**, DIAGNOSTICS, **DISALLOW**, **DISCONNECT**, DISPATCH, **DISTINCT**, DOMAIN, **DOUBLE**, DOW, DOY, **DROP**, **DYNAMIC**, DYNAMIC_FUNCTION, DYNAMIC_FUNCTION_CODE, **EACH**, **ELEMENT**, **ELSE**, **END**, **END-EXEC**, EPOCH, EQUALS, **ESCAPE**, **EVERY**, **EXCEPT**, EXCEPTION, EXCLUDE, EXCLUDING, **EXEC**, **EXECUTE**, **EXISTS**, **EXP**, **EXPLAIN**, **EXTEND**, **EXTERNAL**, **EXTRACT**, **FALSE**, **FETCH**, **FILTER**, FINAL, FIRST, **FIRST_VALUE**, **FLOAT**, **FLOOR**, FOLLOWING, **FOR**, **FOREIGN**, FORTRAN, FOUND, FRAC_SECOND, **FREE**, **FROM**, **FULL**, **FUNCTION**, **FUSION**, G, GENERAL, GENERATED, **GET**, **GLOBAL**, GO, GOTO, **GRANT**, GRANTED, **GROUP**, **GROUPING**, **HAVING**, HIERARCHY, **HOLD**, **HOUR**, **IDENTITY**, IMMEDIATE, IMPLEMENTATION, **IMPORT**, **IN**, INCLUDING, INCREMENT, **INDICATOR**, INITIALLY, **INNER**, **INOUT**, INPUT, **INSENSITIVE**, **INSERT**, INSTANCE, INSTANTIABLE, **INT**, **INTEGER**, **INTERSECT**, **INTERSECTION**, **INTERVAL**, **INTO**, INVOKER, **IS**, ISOLATION, JAVA, **JOIN**, K, KEY, KEY_MEMBER, KEY_TYPE, LABEL, **LANGUAGE**, **LARGE**, LAST, **LAST_VALUE**, **LATERAL**, **LEADING**, **LEFT**, LENGTH, LEVEL, LIBRARY, **LIKE**, **LIMIT**, **LN**, **LOCAL**, **LOCALTIME**, **LOCALTIMESTAMP**, LOCATOR, **LOWER**, M, MAP, **MATCH**, MATCHED, **MAX**, MAXVALUE, **MEMBER**, **MERGE**, MESSAGE_LENGTH, MESSAGE_OCTET_LENGTH, MESSAGE_TEXT, **METHOD**, MICROSECOND, MILLENNIUM, **MIN**, **MINUTE**, MINVALUE, **MOD**, **MODIFIES**, **MODULE**, **MONTH**, MORE, **MULTISET**, MUMPS, NAME, NAMES, **NATIONAL**, **NATURAL**, **NCHAR**, **NCLOB**, NESTING, **NEW**, **NEXT**, **NO**, **NONE**, **NORMALIZE**, NORMALIZED, **NOT**, **NULL**, NULLABLE, **NULLIF**, NULLS, NUMBER, **NUMERIC**, OBJECT, OCTETS, **OCTET_LENGTH**, **OF**, **OFFSET**, **OLD**, **ON**, **ONLY**, **OPEN**, OPTION, OPTIONS, **OR**, **ORDER**, ORDERING, ORDINALITY, OTHERS, **OUT**, **OUTER**, OUTPUT, **OVER**, **OVERLAPS**, **OVERLAY**, OVERRIDING, PAD, **PARAMETER**, PARAMETER_MODE, PARAMETER_NAME, PARAMETER_ORDINAL_POSITION, PARAMETER_SPECIFIC_CATALOG, PARAMETER_SPECIFIC_NAME, PARAMETER_SPECIFIC_SCHEMA, PARTIAL, **PARTITION**, PASCAL, PASSTHROUGH, PATH, **PERCENTILE_CONT**, **PERCENTILE_DISC**, **PERCENT_RANK**, PLACING, PLAN, PLI, **POSITION**, **POWER**, PRECEDING, **PRECISION**, **PREPARE**, PRESERVE, **PRIMARY**, PRIOR, PRIVILEGES, **PROCEDURE**, PUBLIC, QUARTER, **RANGE**, **RANK**, READ, **READS**, **REAL**, **RECURSIVE**, **REF**, **REFERENCES**, **REFERENCING**, **REGR_AVGX**, **REGR_AVGY**, **REGR_COUNT**, **REGR_INTERCEPT**, **REGR_R2**, **REGR_SLOPE**, **REGR_SXX**, **REGR_SXY**, **REGR_SYY**, RELATIVE, **RELEASE**, REPEATABLE, **RESET**, RESTART, RESTRICT, **RESULT**, **RETURN**, RETURNED_CARDINALITY, RETURNED_LENGTH, RETURNED_OCTET_LENGTH, RETURNED_SQLSTATE, **RETURNS**, **REVOKE**, **RIGHT**, ROLE, **ROLLBACK**, **ROLLUP**, ROUTINE, ROUTINE_CATALOG, ROUTINE_NAME, ROUTINE_SCHEMA, **ROW**, **ROWS**, ROW_COUNT, **ROW_NUMBER**, **SAVEPOINT**, SCALE, SCHEMA, SCHEMA_NAME, **SCOPE**, SCOPE_CATALOGS, SCOPE_NAME, SCOPE_SCHEMA, **SCROLL**, **SEARCH**, **SECOND**, SECTION, SECURITY, **SELECT**, SELF, **SENSITIVE**, SEQUENCE, SERIALIZABLE, SERVER, SERVER_NAME, SESSION, **SESSION_USER**, **SET**, SETS, **SIMILAR**, SIMPLE, SIZE, **SMALLINT**, **SOME**, SOURCE, SPACE, **SPECIFIC**, **SPECIFICTYPE**, SPECIFIC_NAME, **SQL**, **SQLEXCEPTION**, **SQLSTATE**, **SQLWARNING**, SQL_TSI_DAY, SQL_TSI_FRAC_SECOND, SQL_TSI_HOUR, SQL_TSI_MICROSECOND, SQL_TSI_MINUTE, SQL_TSI_MONTH, SQL_TSI_QUARTER, SQL_TSI_SECOND, SQL_TSI_WEEK, SQL_TSI_YEAR, **SQRT**, **START**, STATE, STATEMENT, **STATIC**, **STDDEV_POP**, **STDDEV_SAMP**, **STREAM**, STRUCTURE, STYLE, SUBCLASS_ORIGIN, **SUBMULTISET**, SUBSTITUTE, **SUBSTRING**, **SUM**, **SYMMETRIC**, **SYSTEM**, **SYSTEM_USER**, **TABLE**, **TABLESAMPLE**, TABLE_NAME, TEMPORARY, **THEN**, TIES, **TIME**, **TIMESTAMP**, TIMESTAMPADD, TIMESTAMPDIFF, **TIMEZONE_HOUR**, **TIMEZONE_MINUTE**, **TINYINT**, **TO**, TOP_LEVEL_COUNT, **TRAILING**, TRANSACTION, TRANSACTIONS_ACTIVE, TRANSACTIONS_COMMITTED, TRANSACTIONS_ROLLED_BACK, TRANSFORM, TRANSFORMS, **TRANSLATE**, **TRANSLATION**, **TREAT**, **TRIGGER**, TRIGGER_CATALOG, TRIGGER_NAME, TRIGGER_SCHEMA, **TRIM**, **TRUE**, TYPE, **UESCAPE**, UNBOUNDED, UNCOMMITTED, UNDER, **UNION**, **UNIQUE**, **UNKNOWN**, UNNAMED, **UNNEST**, **UPDATE**, **UPPER**, **UPSERT**, USAGE, **USER**, USER_DEFINED_TYPE_CATALOG, USER_DEFINED_TYPE_CODE, USER_DEFINED_TYPE_NAME, USER_DEFINED_TYPE_SCHEMA, **USING**, **VALUE**, **VALUES**, **VARBINARY**, **VARCHAR**, **VARYING**, **VAR_POP**, **VAR_SAMP**, VERSION, VIEW, WEEK, **WHEN**, **WHENEVER**, **WHERE**, **WIDTH_BUCKET**, **WINDOW**, **WITH**, **WITHIN**, **WITHOUT**, WORK, WRAPPER, WRITE, XML, **YEAR**, ZONE.
## 標識符
標識符是在 SQL 查詢中使用的表名, 列, 和其他元數據元素.
未被引號括起來的標識符, 比如 emp, 必須以字母打頭且只能包含字母, 數字, 下劃線. 他們會隱式的轉換為大寫.
被引號引起來的標識符, 例如 `"Employee Name"`, 以雙引號開始和結束. 他們可以包含幾乎任何字符, 包括空白和其他標點. 如果你想在標識符中包含一個雙引號, 使用雙引號進行轉義, 像這樣: `"An employee called ""Fred""."`.
在 Calcite 中, 與引用的對象的名稱匹配的標識符是大小寫敏感的. 但是記住, 被引號括起來的標識符會在匹配前隱式轉化為大寫, 如果它引用的對象的名稱是使用未被引號括起來的標識符創建的, 它的名稱也會被轉換成大寫.
## 數據類型
### 標量類型
| Data type | Description | Range and examples |
| --- | --- | --- |
| BOOLEAN | Logical values | Values: TRUE, FALSE, UNKNOWN |
| TINYINT | 1 byte signed integer | Range is -255 to 256 |
| SMALLINT | 2 byte signed integer | Range is -32768 to 32767 |
| INTEGER, INT | 4 byte signed integer | Range is -2147483648 to 2147483647 |
| BIGINT | 8 byte signed integer | Range is -9223372036854775808 to 9223372036854775807 |
| DECIMAL(p, s) | Fixed point | Example: 123.45 is a DECIMAL(5, 2) value. |
| NUMERIC | Fixed point | |
| REAL, FLOAT | 4 byte floating point | 6 decimal digits precision |
| DOUBLE | 8 byte floating point | 15 decimal digits precision |
| CHAR(n), CHARACTER(n) | Fixed-width character string | 'Hello', '' (empty string), _latin1'Hello', n'Hello', _UTF16'Hello', 'Hello' 'there' (literal split into multiple parts) |
| VARCHAR(n), CHARACTER VARYING(n) | Variable-length character string | As CHAR(n) |
| BINARY(n) | Fixed-width binary string | x'45F0AB', x'' (empty binary string), x'AB' 'CD' (multi-part binary string literal) |
| VARBINARY(n), BINARY VARYING(n) | Variable-length binary string | As BINARY(n) |
| DATE | Date | Example: DATE '1969-07-20' |
| TIME | Time of day | Example: TIME '20:17:40' |
| TIMESTAMP [ WITHOUT TIME ZONE ] | Date and time | Example: TIMESTAMP '1969-07-20 20:17:40' |
| TIMESTAMP WITH TIME ZONE | Date and time with time zone | Example: TIMESTAMP '1969-07-20 20:17:40 America/Los Angeles' |
| INTERVAL timeUnit [ TO timeUnit ] | Date time interval | Examples: INTERVAL '1:5' YEAR TO MONTH, INTERVAL '45' DAY |
| Anchored interval | Date time interval | Example: (DATE '1969-07-20', DATE '1972-08-29') |
Where:
<figure class="highlight">
```
timeUnit:
MILLENNIUM | CENTURY | DECADE | YEAR | QUARTER | MONTH | WEEK | DOY | DOW | DAY | HOUR | MINUTE | SECOND | EPOCH
```
</figure>
注意:
* DATE, TIME, TIMESTAMP 是不帶時區的. 也沒有比如UTC(像Java那樣)或者本地時區作為默認時區. 它需要用戶或者應用提供時區的處理.
### 非標量類型
| 類型 | 描述 |
| --- | --- |
| ANY | 一個類型未知的值 |
| ROW | 一列或者多列組成的行 |
| MAP | 鍵值映射的集合 |
| MULTISET | 可能包含重復內容的未排序的集合 |
| ARRAY | 有序的,可能包含重復的連續集合 |
| CURSOR | 查詢結果的游標 |
## 運算符和函數
### 運算符優先級
運算符優先級和結合性, 從高到低.
| 運算符 | 優先級 |
| --- | --- |
| . | 左 |
| [](array%20element) | 左 |
| + - (unary plus, minus) | 右 |
| * / | 左 |
| + - | 左 |
| BETWEEN, IN, LIKE, SIMILAR | - |
| < > = <= >= <> != | 左 |
| IS NULL, IS FALSE, IS NOT TRUE etc. | - |
| NOT | 右 |
| AND | 左 |
| OR | 左 |
### 比較運算符
| 語法 | 描述 |
| --- | --- |
| value1 = value2 | 相等 |
| value1 <> value2 | 不等 |
| value1 != value2 | 不等 (only available at some conformance levels) |
| value1 > value2 | 大于 |
| value1 >= value2 | 大于等于 |
| value1 < value2 | 小于 |
| value1 <= value2 | 小于等于 |
| value IS NULL | _value_ 是否為 null |
| value IS NOT NULL | _value_ 是否不為 null |
| value1 IS DISTINCT FROM value2 | 兩個值是否不等, null 值認為是相等 |
| value1 IS NOT DISTINCT FROM value2 | 兩個值是否相等, null 值認為是相等 |
| value1 BETWEEN value2 AND value3 | Whether _value1_ is greater than or equal to _value2_ and less than or equal to _value3_ |
| value1 NOT BETWEEN value2 AND value3 | _value1_ 是否小于 _value2_ 或大于 _value3_ |
| string1 LIKE string2 [ ESCAPE string3 ] | _string1_ 與模式 _string2_ 是否匹配 |
| string1 NOT LIKE string2 [ ESCAPE string3 ] | _string1_ 與模式 _string2_ 是否不匹配 |
| string1 SIMILAR TO string2 [ ESCAPE string3 ] | _string1_ 與正則 _string2_ 是否匹配 |
| string1 NOT SIMILAR TO string2 [ ESCAPE string3 ] | _string1_ 與正則 _string2_ 是否不匹配 |
| value IN (value [, value]* ) | _value_ 是否與列表中的每一個值都相等 |
| value NOT IN (value [, value]* ) | _value_ 是否與列表中的每一個值都不等 |
Not supported yet on Storm SQL: 目前 Storm SQL 中不支持的運算符:
| 語法 | 描述 |
| --- | --- |
| value IN (sub-query) | 是否 _value_ 等于 _sub-query_ 返回的行 |
| value NOT IN (sub-query) | 是否 _value_ 不等于 _sub-query_ 返回的行 |
| EXISTS (sub-query) | 是否 _sub-query_ 返回至少一個行 |
Storm SQL 當前不支持子查詢, 因此上面的操作不能正常工作. 這個問題會在不久的將來修復.
### 邏輯運算符
| 語法 | 描述 |
| --- | --- |
| boolean1 OR boolean2 | 或 |
| boolean1 AND boolean2 | 且 |
| NOT boolean | 是否為True ; _boolean_ 為 UNKNOWN 則返回 UNKNOWN |
| boolean IS FALSE | 是否為False; _boolean_ 為 UNKNOWN 則返回 UNKNOWN |
| boolean IS NOT FALSE | 是否不為False; _boolean_ 為 UNKNOWN 則返回 UNKNOWN |
| boolean IS TRUE | 是否為True; _boolean_ 為 UNKNOWN 則返回 UNKNOWN |
| boolean IS NOT TRUE | 是否不為True; _boolean_ 為 UNKNOWN 則返回 UNKNOWN |
| boolean IS UNKNOWN | 判斷是否是 UNKNOWN |
| boolean IS NOT UNKNOWN | 判斷是否不是 UNKNOWN |
### 數學運算符和函數
| 語法 | 描述 |
| --- | --- |
| + numeric | 返回 _numeric_ |
| :- numeric | 返回負 _numeric_ |
| numeric1 + numeric2 | 返回 _numeric1_ 加 _numeric2_ |
| numeric1 - numeric2 | 返回 _numeric1_ 減 _numeric2_ |
| numeric1 * numeric2 | 返回 _numeric1_ 乘以 _numeric2_ |
| numeric1 / numeric2 | 返回 _numeric1_ 除以 _numeric2_ |
| POWER(numeric1, numeric2) | 返回 _numeric1_ 的 _numeric2_ 次方 |
| ABS(numeric) | 返回絕對值 _numeric_ |
| MOD(numeric, numeric) | 取余 _numeric1_ 除以 _numeric2_. 如果被除數為負, 則余數為負 |
| SQRT(numeric) | 返回平方根 _numeric_ |
| LN(numeric) | 返回 _numeric_ 的自然對數 (底數 _e_) |
| LOG10(numeric) | 返回 _numeric_ 的常用對數 (底數 10) |
| EXP(numeric) | 返回 _e_ 的 _numeric_ 次方 |
| CEIL(numeric) | 向上取整 _numeric_, 返回大于或者等于 _numeric_ 的最小整數 |
| FLOOR(numeric) | 向下取整 _numeric_, 返回小于或者等于 _numeric_ 的最小整數 |
### 字符串運算符和函數
| 語法 | 描述 |
| --- | --- |
| string || string | 連接2個字符串 |
| CHAR_LENGTH(string) | 返回字符串長度 |
| CHARACTER_LENGTH(string) | 與 CHAR_LENGTH(_string_) 等價 |
| UPPER(string) | 轉換為大寫 |
| LOWER(string) | 轉換為小寫 |
| POSITION(string1 IN string2) | 返回 _string1_ 在 _string2_ 中首次出現位置 |
| TRIM( { BOTH | LEADING | TRAILING } string1 FROM string2) | 從 _string2_ 的 頭/尾/兩頭 移除 _string1_ 的最長匹配 |
| OVERLAY(string1 PLACING string2 FROM integer [ FOR integer2 ]) | 用 _string2_ 替換 _string1_ |
| SUBSTRING(string FROM integer) | 從給定的位置開始返回一個子串 |
| SUBSTRING(string FROM integer FOR integer) | 從給定位置返回一個指定長度的子串 |
| INITCAP(string) | 將 _string_ 中每個單詞首字母大寫其他字母小寫. 單詞是由空白字符分隔開的字符序列 |
未實現的:
* SUBSTRING(string FROM regexp FOR regexp)
### 二進制字符串操作符和函數
| 語法 | 描述 |
| --- | --- |
| binary || binary | 連接2個二進制字符串. |
| POSITION(binary1 IN binary2) | 返回二進制串 _binary1_ 在 _binary2_ 中首次出現位置 |
| OVERLAY(binary1 PLACING binary2 FROM integer [ FOR integer2 ]) | 替換 |
已知的 bug:
| 語法 | 描述 |
| --- | --- |
| SUBSTRING(binary FROM integer) | 從指定的位置截取 |
| SUBSTRING(binary FROM integer FOR integer) | 從指定位置截取指定長度的串 |
Calcite 1.9.0 有bug, 當編譯 SUBSTRING 函數的時候會拋出異常. 這個問題會在后續版本中修復.
### Date/time 函數
| 語法 | 描述 |
| --- | --- |
| EXTRACT(timeUnit FROM datetime) | 返回時間中的指定字段 |
| FLOOR(datetime TO timeUnit) | 根據 timeUnit 向下取整 |
| CEIL(datetime TO timeUnit) | 根據 timeUnit 向上取整 |
未實現的:
* EXTRACT(timeUnit FROM interval)
* CEIL(interval)
* FLOOR(interval)
* datetime - datetime timeUnit [ TO timeUnit ]
* interval OVERLAPS interval
* + interval
* - interval
* interval + interval
* interval - interval
* interval / interval
* datetime + interval
* datetime - interval
Storm SQL 特有的:
| 語法 | 描述 |
| --- | --- |
| LOCALTIME | 以類型 TIME 返回當前會話時區的當前時間 |
| LOCALTIME(precision) | 以類型 TIME 返回當前會話時區的當前時間, 精度precision |
| LOCALTIMESTAMP | 以類型 TIMESTAMP 返回當前會話時區的當前時間 |
| LOCALTIMESTAMP(precision) | 以類型 TIMESTAMP 返回當前會話時區的當前時間, 精度precision |
| CURRENT_TIME | 以類型 TIMESTAMP WITH TIME ZONE 返回當前會話時區的當前時間 |
| CURRENT_DATE | 以類型 DATE 返回當前會話時區的當前時間 |
| CURRENT_TIMESTAMP | 以類型 TIMESTAMP WITH TIME ZONE 返回當前會話時區的當前時間 |
SQL標準規定,上述運算符在評估查詢時應返回相同的值。 Storm SQL將每個查詢轉換為Trident拓撲并運行,因此在評估SQL語句時,技術上當前的日期/時間應該是固定的。 由于這個限制,當創建Trident拓撲時,當前日期/時間將被修復,并且這些運算符應該在拓撲生命周期中返回相同的值。
### 系統函數
Storm SQL 當前不支持的函數:
| 語法 | 描述 |
| --- | --- |
| USER | 等價于CURRENT_USER |
| CURRENT_USER | 當前執行上下文的用戶名 |
| SESSION_USER | 會話的用戶名 |
| SYSTEM_USER | 返回系統標識的當前數據存儲的用戶 user |
| CURRENT_PATH | 返回表示當前查找范圍的字符串,用于引用用戶定義的例程和類型 |
| CURRENT_ROLE | 返回當前活動 role |
這些操作符并不代表 Storm SQL 的運行時,所以除非我們找到正確的語義,否則這些操作可能永遠不會被支持。
### 條件函數和操作符
| 語法 | 描述 |
| --- | --- |
| CASE value
WHEN value1 [, value11 ]* THEN result1
[ WHEN valueN [, valueN1 ]* THEN resultN ]*
[ ELSE resultZ ]
END | 簡單 case 語句 |
| CASE
WHEN condition1 THEN result1
[ WHEN conditionN THEN resultN ]*
[ ELSE resultZ ]
END | 搜索 case 語句 |
| NULLIF(value, value) | 值相同返回.
例如, `NULLIF(5, 5)` 返回 NULL; `NULLIF(5, 0)` 返回 5. |
| COALESCE(value, value [, value ]* ) | 前一個值為 null 則返回后一個值.
例如, `COALESCE(NULL, 5)` 返回 5. |
### 類型轉換
| 語法 | 描述 |
| --- | --- |
| CAST(value AS type) | 把值轉換為給定的類型. |
### 值構造器
| 語法 | 描述 |
| --- | --- |
| ROW (value [, value]* ) | 從值列表中創建一個行. |
| map '[' key ']' | 根據 key 返回 value. |
| array '[' index ']' | 返回某個位置的 array 的元素值. |
| ARRAY '[' value [, value ]* ']' | 從值列表中創建一個 array. |
| MAP '[' key, value [, key, value ]* ']' | 從 key-value 列表中創建一個 map. |
### 集合函數
| 語法 | 描述 |
| --- | --- |
| ELEMENT(value) | 返回 array 或 multiset 的唯一元素; 如果集合為空,則為null; 如果它有多個元素,則拋出異常。 |
| CARDINALITY(value) | 返回 array 或 multiset 的元素數. |
另請參考: UNNEST關系運算符將集合轉換為關系.
### JDBC 函數轉義
#### 數字
| 語法 | 描述 |
| --- | --- |
| {fn ABS(numeric)} | 返回 _numeric_ 的絕對值 |
| {fn EXP(numeric)} | 返回 _e_ 的 _numeric_ 次方 |
| {fn LOG(numeric)} | 返回 _numeric_ 的自然對數 (底數為 _e_) |
| {fn LOG10(numeric)} | 返回 _numeric_ 的以10為底的對數 |
| {fn MOD(numeric1, numeric2)} | 返回 _numeric1_ 被 _numeric2_ 除的余數. 被除數 _numeric1_ 為負數的時候余數為負 |
| {fn POWER(numeric1, numeric2)} | 返回 _numeric1_ 的 _numeric2_ 次方 |
未實現的:
* {fn ACOS(numeric)} - Returns the arc cosine of _numeric_
* {fn ASIN(numeric)} - Returns the arc sine of _numeric_
* {fn ATAN(numeric)} - Returns the arc tangent of _numeric_
* {fn ATAN2(numeric, numeric)}
* {fn CEILING(numeric)} - Rounds _numeric_ up, and returns the smallest number that is greater than or equal to _numeric_
* {fn COS(numeric)} - Returns the cosine of _numeric_
* {fn COT(numeric)}
* {fn DEGREES(numeric)} - Converts _numeric_ from radians to degrees
* {fn FLOOR(numeric)} - Rounds _numeric_ down, and returns the largest number that is less than or equal to _numeric_
* {fn PI()} - Returns a value that is closer than any other value to _pi_
* {fn RADIANS(numeric)} - Converts _numeric_ from degrees to radians
* {fn RAND(numeric)}
* {fn ROUND(numeric, numeric)}
* {fn SIGN(numeric)}
* {fn SIN(numeric)} - Returns the sine of _numeric_
* {fn SQRT(numeric)} - Returns the square root of _numeric_
* {fn TAN(numeric)} - Returns the tangent of _numeric_
* {fn TRUNCATE(numeric, numeric)}
#### 字符串
| 字符串 | 描述 |
| --- | --- |
| {fn CONCAT(character, character)} | 連接字符串 |
| {fn LOCATE(string1, string2)} | 返回 _string2_ 在 _string1_ 中首次出現的位置. 如果指定了 _integer_ , 則從 _integer_ 為起點開搜索. |
| {fn INSERT(string1, start, length, string2)} | 把 _string2_ 插入 _string1_ |
| {fn LCASE(string)} | 返回小寫 |
| {fn LENGTH(string)} | 返回字符數 |
| {fn SUBSTRING(string, offset, length)} | 字符串截取, 從 offset 的位置開始截取,長度為 length |
| {fn UCASE(string)} | 返回大寫 |
已知的bug:
| 語法 | 描述 |
| --- | --- |
| {fn LOCATE(string1, string2 [, integer])} | 返回 _string2_ 在 _string1_ 中首次出現的位置. 如果指定了 _integer_ , 則從 _integer_ 為起點開搜索. |
| {fn LTRIM(string)} | 移除 _string_ 頭部的空白字符 |
| {fn RTRIM(string)} | 移除 _string_ 尾部的空白字符 |
Calcite 1.9.0 在函數使用位置參數的時候會拋出異常, {fn LTRIM} 和 {fn RTRIM} 在編譯 SQL 語句的時候. 這個能在將來的版本中修復.
未實現的:
* {fn ASCII(string)} - 轉換單個字符的字符串為 ASCII 碼, 為 0 - 255 之間的整數
* {fn CHAR(string)}
* {fn DIFFERENCE(string, string)}
* {fn LEFT(string, integer)}
* {fn REPEAT(string, integer)}
* {fn REPLACE(string, string, string)}
* {fn RIGHT(string, integer)}
* {fn SOUNDEX(string)}
* {fn SPACE(integer)}
#### Date/time
| 語法 | 描述 |
| --- | --- |
| {fn CURDATE()} | 等價于 `CURRENT_DATE` |
| {fn CURTIME()} | 等價于 `LOCALTIME` |
| {fn NOW()} | 等價于 `LOCALTIMESTAMP` |
| {fn QUARTER(date)} | 等價于 `EXTRACT(QUARTER FROM date)`. 返回 1 和 4 之間的整數. |
| {fn TIMESTAMPADD(timeUnit, count, timestamp)} | 添加 _count_ 個 _timeUnit_ 間隔到 timestamp |
| {fn TIMESTAMPDIFF(timeUnit, timestamp1, timestamp2)} | _timestamp1_ 減去 _timestamp2_ 結果存在 _timeUnit_ 中 |
未實現的:
* {fn DAYNAME(date)}
* {fn DAYOFMONTH(date)}
* {fn DAYOFWEEK(date)}
* {fn DAYOFYEAR(date)}
* {fn HOUR(time)}
* {fn MINUTE(time)}
* {fn MONTH(date)}
* {fn MONTHNAME(date)}
* {fn SECOND(time)}
* {fn WEEK(date)}
* {fn YEAR(date)}
#### 系統
未實現的:
* {fn DATABASE()}
* {fn IFNULL(value, value)}
* {fn USER(value, value)}
* {fn CONVERT(value, type)}
### 聚合函數(aggregrate functions)
Storm SQL 當前不支持聚合函數.
### 窗口函數(windowing functions)
Storm SQL 當前不支持窗口函數
### 分組函數(grouping functions)
Storm SQL 不支持分組函數
### 用戶定義函數(User-defined functions)
用戶可以使用 `CREATE FUNCTION` 語句定義 user defined function(標量). 例如, 下面的語句使用 `org.apache.storm.sql.TestUtils$MyPlus` 類定義了一個 `MYPLUS` 函數.
```
CREATE FUNCTION MYPLUS AS 'org.apache.storm.sql.TestUtils$MyPlus'
```
Storm SQL 通過檢驗定義的個方法來確定函數是標量還是聚合. 如果類中定義了一個 `evaluate` 方法, Storm SQL 把這個函數作為 `標量` 對待.
標量函數的類的例子:
```
public class MyPlus {
public static Integer evaluate(Integer x, Integer y) {
return x + y;
}
}
```
請注意, 用戶在運行 Storm SQL runner 時候應當使用 `--jars` 或者 `--artifacts`, 來確保 UDFs 在 classpath 路徑下可見.
## 外部數據源
### 指定外部數據源
在 StormSQL 中數據表現為一個外部表. 用戶可以使用 `CREATE EXTERNAL TABLE` 語句指定數據源. `CREATE EXTERNAL TABLE` 的語法與 [Hive 數據定義語言](https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL) 定義的語法緊密相關.
```
CREATE EXTERNAL TABLE table_name field_list
[ STORED AS
INPUTFORMAT input_format_classname
OUTPUTFORMAT output_format_classname
]
LOCATION location
[ TBLPROPERTIES tbl_properties ]
[ AS select_stmt ]
```
默認輸入格式和輸出格式都是 JSON. 我們會在將來的章節介紹 `supported formats`.
例如, 下面的語句指定了一個 Kafka spout 和 sink:
```
CREATE EXTERNAL TABLE FOO (ID INT PRIMARY KEY) LOCATION 'kafka://localhost:2181/brokers?topic=test' TBLPROPERTIES '{"producer":{"bootstrap.servers":"localhost:9092","acks":"1","key.serializer":"org.apache.org.apache.storm.kafka.IntSerializer","value.serializer":"org.apache.org.apache.storm.kafka.ByteBufferSerializer"}}'
```
請注意, 用戶在運行 Storm SQL runner 時候應當使用 `--jars` 或者 `--artifacts`, 來確保 UDFs 在 classpath 可見.
### 植入外部數據源
用戶通過實現 `ISqlTridentDataSource` 接口并使用 Java 的 service loader 機制進行注冊,以植入外部數據源. 基于表的 URI 的模式來選擇外部數據源. 更多細節請參考 `storm-sql-kafka` 的實現.
### 支持的格式
| 格式 | 輸入格式類 | 輸出格式類 | 需要屬性 |
| --- | --- | --- | --- |
| JSON | org.apache.storm.sql.runtime.serde.json.JsonScheme | org.apache.storm.sql.runtime.serde.json.JsonSerializer | No |
| Avro | org.apache.storm.sql.runtime.serde.avro.AvroScheme | org.apache.storm.sql.runtime.serde.avro.AvroSerializer | Yes |
| CSV | org.apache.storm.sql.runtime.serde.csv.CsvScheme | org.apache.storm.sql.runtime.serde.csv.CsvSerializer | No |
| TSV | org.apache.storm.sql.runtime.serde.tsv.TsvScheme | org.apache.storm.sql.runtime.serde.tsv.TsvSerializer | No |
#### Avro
Avro 需要用戶描述記錄的模式(輸入和輸出). 模式應該在 `TBLPROPERTIES` 上描述. 輸入格式需要描述給 `input.avro.schema`, 輸出格式需要描述給 `output.avro.schema`. 模式字符串應當是一個轉義后的 JSON, 因此 `TBLPROPERTIES` 是有效的 JSON.
示例 Schema 定義:
`"input.avro.schema": "{\"type\": \"record\", \"name\": \"large_orders\", \"fields\" : [ {\"name\": \"ID\", \"type\": \"int\"}, {\"name\": \"TOTAL\", \"type\": \"int\"} ]}"`
`"output.avro.schema": "{\"type\": \"record\", \"name\": \"large_orders\", \"fields\" : [ {\"name\": \"ID\", \"type\": \"int\"}, {\"name\": \"TOTAL\", \"type\": \"int\"} ]}"`
#### CSV
使用 [Standard RFC4180](https://tools.ietf.org/html/rfc4180) CSV Parser, 不需要任何其他的屬性.
#### TSV
默認情況下, TSV 使用 `\t` 作為分隔符, 但是用戶可以通過 `input.tsv.delimiter` 或者 `output.tsv.delimiter` 設置其他的分隔符.
### 可支持的數據源
| 數據源 | Artifact Name | 位置前綴 | 支持輸入數據源 | 支持輸出數據源 | 需要屬性 |
| --- | --- | --- | --- | --- | --- |
| Socket | | `socket://host:port` | Yes | Yes | No |
| Kafka | org.apache.storm:storm-sql-kafka | `kafka://zkhost:port/broker_path?topic=topic` | Yes | Yes | Yes |
| Redis | org.apache.storm:storm-sql-redis | `redis://:[password]@host:port/[dbIdx]` | No | Yes | Yes |
| MongoDB | org.apache.stormg:storm-sql-mongodb | `mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]` | No | Yes | Yes |
| HDFS | org.apache.storm:storm-sql-hdfs | `hdfs://host:port/path-to-file` | No | Yes | Yes |
#### Socket
Socket 數據源是一個內置的特性, 因此用戶無需在 `--artifacts` 選項中添加任何依賴.
請注意, Socket 數據源只是用于測試: 不能保證 exactly-once 和 at-least-once.
貼士: `netcat` 是一個 Socket 便捷工具: 用戶可以使用 netcat 連接 Socket 數據源, 既可以作為輸入也可以用作輸出.
#### Kafka
Kafka 僅當用作輸出數據源的時候需要定義下列屬性:
* `producer`: 指定 Kafka Producer 配置 - 更多細節請參考 [Kafka producer configs](http://kafka.apache.org/documentation.html#producerconfigs).
* `bootstrap.servers` 必須在 `producer` 中定義這個值
請注意, `storm-sql-kafka` 需要用戶提供 `storm-kafka` 依賴, `storm-kafka` 又依賴于 `kafka` , `kafka-clients`. 你可以在 `--artifacts` 選項中使用下列的工作引用, 并且在需要的時候修改依賴的版本
`org.apache.storm:storm-sql-kafka:2.0.0-SNAPSHOT,org.apache.storm:storm-kafka:2.0.0-SNAPSHOT,org.apache.kafka:kafka_2.10:0.8.2.2^org.slf4j:slf4j-log4j12,org.apache.kafka:kafka-clients:0.8.2.2`
#### Redis
Redis 數據源需要設置下列屬性:
* `data.type`: 用于存儲的數據類型 - 僅支持 `"STRING"` 和 `"HASH"`
* `data.additional.key`: key, 當數據類型同時需要 key 和 field 時設置 (field 作為字段使用)
* `redis.timeout`: 超時時間, 毫秒 (ex. `"3000"`)
* `use.redis.cluster`: 如果 Redis 是集群環境為 `"true"`, 否則為 `"false"`.
請注意, `storm-sql-redis` 需要用戶提供 `storm-redis` 依賴. 你可以在 `--artifacts` 選項中使用下列的工作引用, 并且在需要的時候修改依賴的版本
`org.apache.storm:storm-sql-redis:2.0.0-SNAPSHOT,org.apache.storm:storm-redis:2.0.0-SNAPSHOT`
#### MongoDB
MongoDB 數據源需要設置以下屬性
`{"collection.name": "storm_sql_mongo", "trident.ser.field": "serfield"}`
* `trident.ser.field`: 存儲字段 - 記錄會序列化并以 BSON 存儲在字段中
* `collection.name`: 集合名稱
請注意, `storm-sql-mongodb` 需要用戶提供 `storm-mongodb` 依賴. 你可以在 `--artifacts` 選項中使用下列的工作引用, 并且在需要的時候修改依賴的版本
`org.apache.storm:storm-sql-mongodb:2.0.0-SNAPSHOT,org.apache.storm:storm-mongodb:2.0.0-SNAPSHOT`
當前不支持使用保留字段存儲.
#### HDFS
HDFS 數據源需要設置下列屬性
* `hdfs.file.path`: HDFS 文件路徑
* `hdfs.file.name`: HDFS 文件名 - 參考 [SimpleFileNameFormat](http://github.com/apache/storm/blob/master%0A/external/storm-hdfs/src/main/java/org/apache/storm/hdfs/trident/format/SimpleFileNameFormat.java)
* `hdfs.rotation.size.kb`: HDFS FileSizeRotationPolicy 單位 KB
* `hdfs.rotation.time.seconds`: HDFS TimedRotationPolicy 單位 seconds
請注意 `hdfs.rotation.size.kb` 和 `hdfs.rotation.time.seconds` 只能采用其中一種來實現文件滾動.
還要注意 `storm-sql-hdfs` 需要用戶提供 `storm-hdfs` 依賴. 你可以在 `--artifacts` 選項中使用下列的工作引用, 并且在需要的時候修改依賴的版本
`org.apache.storm:storm-sql-hdfs:2.0.0-SNAPSHOT,org.apache.storm:storm-hdfs:2.0.0-SNAPSHOT`
還有, 需要提供 hdfs 配置文件. 可以將 `core-site.xml` 和 `hdfs-site.xml` 文件放到 Storm 安裝目錄的 `conf` 目錄下面.
- Storm 基礎
- 概念
- Scheduler(調度器)
- Configuration
- Guaranteeing Message Processing
- 守護進程容錯
- 命令行客戶端
- Storm UI REST API
- 理解 Storm Topology 的 Parallelism(并行度)
- FAQ
- Layers on Top of Storm
- Storm Trident
- Trident 教程
- Trident API 綜述
- Trident State
- Trident Spouts
- Trident RAS API
- Storm SQL
- Storm SQL 集成
- Storm SQL 示例
- Storm SQL 語言參考
- Storm SQL 內部實現
- Flux
- Storm 安裝和部署
- 設置Storm集群
- 本地模式
- 疑難解答
- 在生產集群上運行 Topology
- Maven
- 安全地運行 Apache Storm
- CGroup Enforcement
- Pacemaker
- 資源感知調度器 (Resource Aware Scheduler)
- 用于分析 Storm 的各種內部行為的 Metrics
- Windows 用戶指南
- Storm 中級
- 序列化
- 常見 Topology 模式
- Clojure DSL
- 使用沒有jvm的語言編輯storm
- Distributed RPC
- Transactional Topologies
- Hooks
- Storm Metrics
- Storm 狀態管理
- Windowing Support in Core Storm
- Joining Streams in Storm Core
- Storm Distributed Cache API
- Storm 調試
- 動態日志級別設置
- Storm Logs
- 動態員工分析
- 拓撲事件檢查器
- Storm 與外部系統, 以及其它庫的集成
- Storm Kafka Integration
- Storm Kafka 集成(0.10.x+)
- Storm HBase Integration
- Storm HDFS Integration
- Storm Hive 集成
- Storm Solr 集成
- Storm Cassandra 集成
- Storm JDBC 集成
- Storm JMS 集成
- Storm Redis 集成
- Azue Event Hubs 集成
- Storm Elasticsearch 集成
- Storm MQTT(Message Queuing Telemetry Transport, 消息隊列遙測傳輸) 集成
- Storm MongoDB 集成
- Storm OpenTSDB 集成
- Storm Kinesis 集成
- Storm Druid 集成
- Storm and Kestrel
- Container, Resource Management System Integration
- Storm 高級
- 針對 Storm 定義一個不是 JVM 的 DSL
- 多語言協議
- Storm 內部實現
- 翻譯進度