Отличия SQL диалекта YQL от ANSI SQL
В данном разделе описываются различие SQL диалекта YQL и стандарта ISO/IEC 9075-2 (part 2: Foundation) в версии SQL-2011.
Сравнение делается по таблице №38 из стандарта
("Feature taxonomy and definition for mandatory features").
Отличия в поведении YQL от ANSI SQL
В данной таблице собраны сценарии когда один и тот же запрос по-разному работает в YQL и в ANSI SQL.
Идентификатор | Название | Отличия в поведении |
---|---|---|
E011-04 | Arithmetic operators | В YQL подавляются ошибки в арифметических вычислениях. Например выражение 1/0 имеет тип Int32? и значение NULL . В ANSI SQL в этом случае возникает ошибка |
E011-06 | Implicit casting among the numeric data types | В YQL нет неявного кастинга между NUMERIC и INTEGER/FLOAT. |
E031-01 | Delimited identifiers | В YQL выражение SELECT "a" FROM foo возвращает строковую константу. В ANSI "a" – это идентификатор (колонка a ) |
E071-02 | UNION ALL table operator | В ANSI SQL колонки объединяются по позиционному принципу, в YQL - по именам. В YQL ORDER BY, OFFSET, LIMIT относится к последнему элементу объединения. В ANSI - к результату UNION ALL . |
Статус поддержки ANSI SQL
Идентификатор | Название | Поддержка | Комментарий |
---|---|---|---|
E011 | Numeric data types | Частично | |
E011-01 | INTEGER and SMALLINT data types | Да | Дополнительно имеется поддержка знаковые и беззнаковые интегральные типы: [U]INT{8,16,32,64} и TINYINT . |
E011-02 | REAL, DOUBLE PRECISION and FLOAT data types data types | Частично | FLOAT(<binary_precision>) не поддерживается |
E011-03 | DECIMAL and NUMERIC data types | Да | Поддерживается DECIMAL(p,s) |
E011-04 | Arithmetic operators | Да | |
E011-05 | Numeric comparison | Да | |
E011-06 | Implicit casting among the numeric data types | Частично | Стандарт допускает неявное преобразование всех numeric типов друг к другу. У нас неявно кастятся только "родственные" типы. |
[E021](####E021 Character string types) | Character string types | Частично | Не поддерживается CHAR(len) , VARCHAR(len) |
E021-01 | CHARACTER data type | Нет | |
E021-02 | CHARACTER VARYING data type | Частично | Ближайшим аналогом является String |
E021-03 | Character literals | Частично | Не поддерживается автоконкатенация 'aaa' 'bbb' |
E021-04 | CHARACTER_LENGTH function | Нет | |
E021-05 | OCTET_LENGTH function | Частично | ближайшим аналогом является LEN() |
E021-06 | SUBSTRING | Частично | Отличие в синтаксисе |
E021-07 | Character concatenation | Да | Поддерживается для типа String |
E021-08 | UPPER and LOWER functions | Нет | Доступны через String UDF |
E021-09 | TRIM function | Нет | Может быть реализована через String UDF |
E021-10 | Implicit casting among the fixed-length and variable-length character string types | Нет | Отсутствуют соответствующие типы |
E021-11 | POSITION function | Частично | Аналогом является FIND |
E021-12 | Character comparison | Частично | Сравнение для типа String выполняется побайтно |
E031 | Identifiers | Частично | |
E031-01 | Delimited identifiers | Частично | В YQL используется бэктики для идентификаторов вместо двойных кавычек по стандарту |
E031-02 | Lower case identifiers | Да | |
E031-03 | Trailing underscore | Да | |
E051 | Basic query specification | Частично | |
E051-01 | SELECT DISTINCT | Частично | Не поддерживается SELECT DISTINCT * |
E051-02 | GROUP BY clause | Да | |
E051-04 | GROUP BY can contain columns not in <select list> | Да | |
E051-05 | Select items can be renamed | Да | SELECT foo AS bar |
E051-06 | HAVING clause | Да | |
E051-07 | Qualified * in select list | Да | SELECT a.*, 1 AS foo FROM T AS a |
E051-08 | Correlation name in the FROM clause | Да | SELECT ... FROM T AS a |
E051-09 | Rename columns in the FROM clause | Нет | SELECT ... FROM T AS a (x AS foo, y AS bar) |
E061 | Basic predicates and search conditions | Частично | |
E061-01 | Comparison predicate | Да | Операторы <,>,=,<>,<=,>= |
E061-02 | BETWEEN predicate | Частично | |
E061-03 | IN predicate with list of values | Да | |
E061-04 | LIKE predicate | Да | |
E061-05 | LIKE predicate: ESCAPE clause | Да | |
E061-06 | NULL predicate | Да | |
E061-07 | Quantified comparison predicate | Нет | X < ANY (...) |
E061-08 | EXISTS predicate | Да | |
E061-09 | Subqueries in comparison predicate | Да | Скалярный контекст для подзапроса |
E061-11 | Subqueries in IN predicate | Да | |
E061-12 | Subqueries in quantified comparison predicate | Нет | |
E061-13 | Correlated subqueries | Нет | |
E061-14 | Search condition | Да | SELECT ... WHERE <search condition> |
E071 | Basic query expressions | Частично | Объединение результатов нескольких запросов |
E071-01 | UNION DISTINCT table operator | Нет | |
E071-02 | UNION ALL table operator | Да | |
E071-03 | EXCEPT DISTINCT table operator | Нет | |
E071-05 | Columns combined via table operators need not have exactly the same data type | Да | UNION ALL разрешает совместимые типы для колонок |
E071-06 | Table operators in subqueries | Да | UNION ALL может использоваться в подзапросах |
E081 | Basic privileges | Нет | Привилегии для INSERT/SELECT/DELETE/UPDATE |
E091 | Set functions | Да | |
E091-01 | AVG | Да | |
E091-02 | COUNT | Да | |
E091-03 | MAX | Да | |
E091-04 | MIN | Да | |
E091-05 | SUM | Да | |
E091-06 | ALL quantifier | Да | SELECT AVG(ALL x) |
E091-07 | DISTINCT quantifier | Да | SELECT AVG(DISTINCT x) |
E101 | Basic data manipulation | Да | |
E101-01 | INSERT statement | Да | |
E101-03 | Searched UPDATE statement | Да | |
E101-04 | Searched DELETE statement | Да | |
E111 | Single row SELECT statement | Нет | SELECT ... INTO <param1>, <param2> ... FROM |
E121 | Basic cursor support | Нет | DECLARE CURSOR |
E131 | Null value support (nulls in lieu of values) | Да | |
E141 | Basic integrity constraints | Частично | |
E141-01 | NOT NULL constraints | Нет | |
E141-02 | UNIQUE constraint of NOT NULL columns | Нет | |
E141-03 | PRIMARY KEY constraints | Да | |
E141-04 | Basic FOREIGN KEY constraint with the NO ACTION default for both referential delete action and referential update action | ? | |
E141-06 | CHECK constraint | Нет | |
E141-07 | Column defaults | Нет | |
E141-08 | NOT NULL inferred on PRIMARY KEY | Да | |
E141-10 | Names in a foreign key can be specified in any order | ? | |
E151 | Transaction support | Нет | COMMIT в YQL упорядочивает операции в пределах одной транзакции |
E151-01 | COMMIT statement | Нет | |
E151-02 | ROLLBACK statement | Нет | |
E152 | Basic SET TRANSACTION statement | Нет | ISOLATION LEVEL etc |
E152-01 | SET TRANSACTION statement: ISOLATION LEVEL SERIALIZABLE clause | Нет | |
E152-02 | SET TRANSACTION statement: READ ONLY and READ WRITE clauses | Нет | |
E153 | Updatable queries with subqueries | Нет | ? |
E161 | SQL comments using leading double minus | Да | |
E171 | SQLSTATE support | Нет | |
E182 | Host language binding | Нет |
E021 Character string types
Должны поддерживаться:
CHARACTER[(len)]
(он жеCHAR
)- строковой тип фиксированной длинныVAR CHAR[(len)]
(он жеCHARACTER VARYING
) - строковой тип переменной длинны
Должен так же поддерживаться опциональный спецификатор CHARACTER SET cs
и возможность задать правила сортировки с помощью COLLATE
В YQL эти типы не поддерживаются. Ближайшим аналогом является тип String
,
который представляет собой бинарную строку переменной длинны.
E021-03 Character literals
По стандарту, строковой литерал имеет следующий вид
<character string literal> ::=
[ <introducer> <character set specification> ]
<quote> [ <character representation>... ] <quote>
[ { <separator> <quote> [ <character representation>... ] <quote> }... ]
<separator> ::=
{ <comment> | <white space> }...
<introducer> ::=
<underscore>
<character representation> ::=
<nonquote character>
| <quote symbol>
<quote symbol> ::=
<quote> <quote>
В YQL:
- Не поддерживается экранирование через
'
- Не поддерживается
<character set specification>
- Не поддерживается неявная конкатенация литералов (
'aaa' 'bbb'
по стандарту означает то же что и'aaabbb
)
С другой стороны:
- Строковые литералы можно заключать в двойные кавычки
"aaa"
- Работает C-style экранирование через бэкслеш
- Поддерживаются многострочные строковые литералы
E021-05 OCTET_LENGTH function
CHARACTER_LENGTH(<character value expression>) [USING CHARACTERS | OCTETS]
OCTET_LENGTH(<string value expression>)
В YQL поддерживается LENGTH(<string value expressiom>)
которая возвращает длину строки в байтах
E021-06 SUBSTRING function
<character substring function> ::=
SUBSTRING <left paren> <character value expression> FROM <start position>
[ FOR <string length> ] [ USING CHARACTERS | OCTETS ] <right paren>
В YQL поддерживается в варианте SUBSTRING(str, start, len)
.
Нумерация символов в строке в YQL начинается с нуля
E021-09 TRIM function
TRIM([[LEADING | TRAILING | BOTH] [<char value expression>] FROM] <char value expression>)
Удаления префикса/суффикса из строки. В YQL не поддерживается, функциональный эквивалент можно получить с использованием String/Unicode UDF
E021-11 POSITION function
POSITION(S1 IN S2) [USING CHARACTERS | OCTETS]
Поиск подстроки S1 в S2.
В YQL доступен в варианте FIND(S2, S1)
. Позиции нумеруются с 0, если строка не найдена, возвращается NULL.
E031 Identifiers
По стандарту, идентификаторы (например имена таблиц и колонок) могут являться
regular identifiers и delimited identifiers.
Regular identifiers начинаются с буквы и могут содержать только буквы, цифры и символы подчеркивания.
E031-01 Delimited identifiers
Delimited identifiers заключены в кавычки: "abc def"
и могут содержать произвольные символы.
Кавычки экранируются двойными кавычками: "complex ""identifier"""
В YQL вместо кавычек используются бэктики
E051 Basic query specification
Общий вид SELECT запроса в стандарте такой
<query specification> ::=
SELECT [ <set quantifier> ] <select list> <table expression>
<set quantifier> ::=
DISTINCT
| ALL
<select list> ::=
<asterisk>
| <select sublist> [ { <comma> <select sublist> }... ]
<select sublist> ::=
<derived column>
| <qualified asterisk>
<qualified asterisk> ::=
<asterisked identifier chain> <period> <asterisk>
| <all fields reference>
<asterisked identifier chain> ::=
<asterisked identifier> [ { <period> <asterisked identifier> }... ]
<asterisked identifier> ::=
<identifier>
<derived column> ::=
<value expression> [ <as clause> ]
<as clause> ::=
[ AS ] <column name>
<all fields reference> ::=
<value expression primary> <period> <asterisk>
[ AS <left paren> <all fields column name list> <right paren> ]
<all fields column name list> ::=
<column name list>
<table expression> ::=
<from clause>
[ <where clause> ]
[ <group by clause> ]
[ <having clause> ]
[ <window clause> ]
<from clause> ::=
FROM <table reference list>
<table reference list> ::=
<table reference> [ { <comma> <table reference> }... ]
В YQL не поддерживаются множественные таблицы после FROM
(<table reference list>
содержит более одного элемента)
E051-01 SELECT DISTINCT
SELECT DISTINCT поддерживается за исключением варианта с asterisk/qualified asterisk
E051-07 Qualified * in select list
В YQL:
<asterisk identifier chain>
может состоять только из одного элемента- В
<all fields reference>
не поддерживаются алиасы<all fields column name list>
<value expression primary>
может содержать только ссылку на таблицу
E061-01 Comparison predicate
В YQL поддерживаются операторы <,>,=,<>,<=,>= для совместимых типов
E061-02 BETWEEN predicate
<between predicate> ::=
<row value predicand> <between predicate part 2>
<between predicate part 2> ::=
[ NOT ] BETWEEN [ ASYMMETRIC | SYMMETRIC ]
<row value predicand> AND <row value predicand>
В YQL не поддерживаются SYMMETRIC/ASSYMETRIC - A BETWEEN B AND C
эквивалентно A >= B AND A <= C
.
E061-07 Quantified comparison predicate
<quantified comparison predicate> ::=
<row value predicand> <quantified comparison predicate part 2>
<quantified comparison predicate part 2> ::=
<comp op> <quantifier> <table subquery>
<quantifier> ::=
<all>
| <some>
<all> ::= ALL
<some> ::=
SOME
| ANY