日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

不兼容SQL重寫

本文為您介紹如何修改不兼容SQL。

背景信息

MaxCompute 2.0完全擁抱開源生態,支持更多的語言功能,擁有更快的運行速度。但是MaxCompute 2.0會執行更嚴格的語法檢測,一些在舊版本編譯器下正常執行的不嚴謹的語法在MaxCompute 2.0下執行會報錯。

group.by.with.star

說明:即select * …group by…語句。

  • MaxCompute 2.0版本中,要求Group By列表是源表中所有的列,否則執行報錯。

  • 舊版MaxCompute中,即使Group By列表不覆蓋源表中所有的列,也支持select * from group by key語法。

示例

  • 場景1:Group By Key中不包含所有列。

    • 錯誤寫法

      select * from t group by key;
    • 報錯信息

      FAILED: ODPS-0130071:[1,8] Semantic analysis exception - column reference t.value should appear in GROUP BY key
    • 正確寫法

      select distinct key from t;
  • 場景2:group by key包含所有列。

    • 如下寫法不推薦。

      select * from t group by key, value; -- t has columns key and value
    • 雖然MaxCompute2.0不會報錯,但推薦改為如下。

      select distinct key, value from t;

bad.escape

說明:錯誤的escape序列問題。

按照MaxCompute規定,在String literal中應該用反斜線加三位8進制數字表示從0到127的ASCII字符。例如:使用“\001”、“\002”表示0、1。但\01、\0001也被當作\001處理了。

這種方式會給新用戶帶來困擾,比如需要用“\0001”表示“\000”+“1”,便沒有辦法實現。同時對于從其他系統遷移而來的用戶而言,會導致正確性錯誤。

說明

\000后面再加數字,如\0001 - \0009\00001的寫法可能會返回錯誤。

MaxCompute 2.0會解決此問題,對腳本中錯誤的序列進行修改。

  • 錯誤寫法

    select split(key, "\01"), value like "\0001" from t;
  • 報錯信息

    FAILED: ODPS-0130161:[1,19] Parse exception - unexpected escape sequence: 01
    ODPS-0130161:[1,38] Parse exception - unexpected escape sequence: 0001
  • 正確改法

    select split(key, "\001"), value like "\001" from t;

column.repeated.in.creation

說明:如果創建表時列名重復,MaxCompute 2.0將會報錯。

示例

  • 錯誤寫法

    create table t (a BIGINT, b BIGINT, a BIGINT);
  • 報錯信息

    FAILED: ODPS-0130071:[1,37] Semantic analysis exception - column repeated in creation: a
  • 正確寫法

    create table t (a BIGINT, b BIGINT);

string.join.double

說明:寫JOIN條件時,等號的左右兩邊分別是STRING和DOUBLE類型。

  • 舊版MaxCompute會把兩邊都轉成BIGINT類型,會導致嚴重的精度損失問題,例如:1.1=“1”在連接條件中會被認為是相等的。

  • MaxCompute 2.0會與Hive兼容轉為DOUBLE類型。

示例

  • 不推薦寫法

    select * from t1 join t2 on t1.double_value = t2.string_value;
  • Warning信息

    WARNING:[1,48]  implicit conversion from STRING to DOUBLE, potential data loss, use CAST function to suppress
  • 推薦改法

    select * from t1 join t2 on t.double_value = cast(t2.string_value as double);

window.ref.prev.window.alias

說明:Window Function引用同級select List中的其他Window Function Alias的問題。

示例

  • 如果rn在t1中不存在,錯誤寫法如下。

    select row_number() over (partition by c1 order by c1) rn,
    row_number() over (partition by c1 order by rn) rn2
    from t1;
  • 報錯信息

    FAILED: ODPS-0130071:[2,45] Semantic analysis exception - column rn cannot be resolved
  • 正確改法

    select row_number() over (partition by c1 order by rn) rn2
    from
    (select c1, row_number() over (partition by c1 order by c1) rn
    from t1
    ) tmp;

select.invalid.token.after.star

說明:select列表里面允許用戶使用星號(*)代表選擇某張表的全部列,但星號(*)后面不允許加alias,即使星號(*)展開之后只有一列也不允許,新一代編譯器將會對類似語法進行報錯。

示例

  • 錯誤寫法

    select * as alias from table_test;
  • 報錯信息

    FAILED: ODPS-0130161:[1,10] Parse exception - invalid token 'as'
  • 正確改法

    select * from table_test;

agg.having.ref.prev.agg.alias

說明:有Having子句的情況下,select List可以出現前面Aggregate Function Alias的問題。

示例

  • 錯誤寫法

    select count(c1) cnt,
    sum(c1) / cnt avg
    from t1
    group by c2
    having cnt > 1;
  • 報錯信息

    FAILED: ODPS-0130071:[2,11] Semantic analysis exception - column cnt cannot be resolved
    ODPS-0130071:[2,11] Semantic analysis exception - column reference cnt should appear in GROUP BY key

    其中s、cnt在源表t1中都不存在,但因為有Having子句,舊版MaxCompute并未報錯,MaxCompute 2.0則會提示column cannot be resolve,并報錯。

  • 正確改法

    select cnt, s, s/cnt avg
    from
    (
    select count(c1) cnt,
    sum(c1) s
    from t1
    group by c2
    having count(c1) > 1
    ) tmp;

order.by.no.limit

說明:MaxCompute默認order by后需要增加limit限制數量,因為order by是全量排序,沒有limit時執行性能較低。

示例

  • 錯誤寫法

    select * from (select *
    from (select cast(login_user_cnt as int) as uv, '3' as shuzi
    from test_login_cnt where type = 'device' and type_name = 'mobile') v
    order by v.uv desc) v
    order by v.shuzi limit 20;
  • 報錯信息

    FAILED: ODPS-0130071:[4,1] Semantic analysis exception - ORDER BY must be used with a LIMIT clause

在子查詢order by v.uv desc中增加limit

另外,MaxCompute 1.0對于view的檢查不夠嚴格。比如在一個不需要檢查limit的Project(odps.sql.validate.orderby.limit=false)中,創建了一個View。

create view table_view as select id from table_view order by id;

若訪問此View:

select * from table_view;

MaxCompute 1.0不會報錯,而MaxCompute 2.0會報如下錯誤信息:

FAILED: ODPS-0130071:[1,15] Semantic analysis exception - while resolving view xdj.xdj_view_limit - ORDER BY must be used with a LIMIT clause

generated.column.name.multi.window

說明:使用自動生成的alias的問題。

舊版MaxCompute會為select語句中的每個表達式自動生成一個alias,這個alias會最后顯示在Console上。但是,它并不承諾這個alias的生成規則,也不承諾這個alias的生成規則會保持不變,所以不建議用戶使用自動生成的alias。

MaxCompute 2.0會對使用自動生成alias的情況給予警告,由于牽涉面較廣,暫時無法直接給予禁止。

對于某些情況,MaxCompute的不同版本間生成的alias規則存在已知的變動,但因為已有一些線上作業依賴于此類alias,這些查詢在 MaxCompute版本升級或者回滾時可能會失敗,存在此問題的用戶,請修改您的查詢,對于感興趣的列,顯式地指定列的別名。

示例

  • 不推薦寫法

    select _c0 from (select count(*) from table_name) t;
  • 建議改法:

    select c from (select count(*) c from table_name) t;

non.boolean.filter

使用了非BOOLEAN過濾條件的問題。

MaxCompute不允許布爾類型與其他類型之間的隱式轉換,但舊版MaxCompute會允許用戶在某些情況下使用BIGINT作為過濾條件。MaxCompute 2.0將不再允許,如果您的腳本中存在這樣的過濾條件,請及時修改。示例如下:

錯誤寫法:

select id, count(*) from table_name group by id having id;

報錯信息:

FAILED: ODPS-0130071:[1,50] Semantic analysis exception - expect a BOOLEAN expression

正確改法:

select id, count(*) from table_name group by id having id <> 0;

post.select.ambiguous

在order by、cluster by、distribute by、sort by等語句中,引用了名字沖突的列的問題。

舊版MaxCompute中,系統會默認選取Select列表中的后一列作為操作對象,MaxCompute 2.0將會報錯,請及時修改。示例如下:

錯誤寫法:

select a, b as a from t order by a limit 10;

報錯信息:

FAILED: ODPS-0130071:[1,34] Semantic analysis exception - a is ambiguous, can be both t.a or null.a

正確改法:

select a as c, b as a from t order by a limit 10;

本次推送修改會包括名字沖突但語義一樣的情況,雖然不會出現歧義,但是考慮到這種情況容易導致錯誤,作為一個警告,希望用戶進行修改。

duplicated.partition.column

在query中指定了同名的partition的問題。

舊版MaxCompute在用戶指定同名partition key時并未報錯,而是后一個的值直接覆蓋了前一個,容易產生混亂。MaxCompute2.0將會對此情況進行報錯,示例如下:

錯誤寫法一:

insert overwrite table partition (ds = '1', ds = '2')select ... ;

實際上,在運行時ds = ‘1’被忽略。

正確改法:

insert overwrite table partition (ds = '2')select ... ;

錯誤寫法二:

create table t (a bigint, ds string) partitioned by (ds string);

正確改法:

create table t (a bigint) partitioned by (ds string);

order.by.col.ambiguous

select list中alias重復,之后的order by子句引用到重復的alias的問題。

錯誤寫法:

select id, id
from table_test 
order by id;

正確改法:

select id, id id2
from table_name 
order by id;

需要去掉重復的alias,order by子句再進行引用。

in.subquery.without.result

colx in subquery沒有返回任何結果,則colx在源表中不存在的問題。

錯誤寫法:

select * from table_name
where not_exist_col in (select id from table_name limit 0);

報錯信息:

FAILED: ODPS-0130071:[2,7] Semantic analysis exception - column not_exist_col cannot be resolved

ctas.if.not.exists

目標表語法錯誤問題。

如果目標表已經存在,舊版MaxCompute不會做任何語法檢查,MaxCompute 2.0則會做正常的語法檢查,這種情況會出現很多錯誤信息,示例如下:

錯誤寫法:

create table if not exists table_name
as
select * from not_exist_table;

報錯信息:

FAILED: ODPS-0130131:[1,50] Table not found - table meta_dev.not_exist_table cannot be resolved

worker.restart.instance.timeout

舊版MaxCompute UDF每輸出一條記錄,便會觸發一次對分布式文件系統的寫操作,同時會向Fuxi發送心跳,如果UDF 10分鐘沒有輸出任何結果,會得到如下錯誤提示:

FAILED: ODPS-0123144: Fuxi job failed - WorkerRestart errCode:252,errMsg:kInstanceMonitorTimeout, usually caused by bad udf performance.

MaxCompute 2.0的Runtime框架支持向量化,一次會處理某一列的多行來提升執行效率。但向量化可能導致原來不會報錯的語句(2條記錄的輸出時間間隔不超過10分鐘),因為一次處理多行,沒有及時向Fuxi發送心跳而導致超時。

遇到這個錯誤,建議首先檢查UDF是否有性能問題,每條記錄需要數秒的處理時間。如果無法優化UDF性能,可以嘗試手動設置batch row大小來繞開(默認為1024):

set odps.sql.executionengine.batch.rowcount=16;

divide.nan.or.overflow

舊版MaxCompute不會做除法常量折疊的問題。

比如如下語句,舊版MaxCompute對應的物理執行計劃如下:

explain
select if(false, 0/0, 1.0)
from table_name;
in task M1_Stg1:
    Data source: meta_dev.table_name
    TS: alias: table_name
      SEL: If(False, Divide(UDFToDouble(0), UDFToDouble(0)), 1.0)
        FS: output: None

由此可以看出,IF和Divide函數仍然被保留,運行時因為IF第一個參數為false,第二個參數Divide的表達式不需要求值,所以不會出現除零異常。

而MaxCompute 2.0支持除法常量折疊,所以會報錯。如下所示:

錯誤寫法:

select IF(FALSE, 0/0, 1.0)
from table_name;

報錯信息:

FAILED: ODPS-0130071:[1,19] Semantic analysis exception - encounter runtime exception while evaluating function /, detailed message: DIVIDE func result NaN, two params are 0.000000 and 0.000000

除了上述的錯誤,還可能遇到overflow錯誤,比如:

錯誤寫法:

select if(false, 1/0, 1.0)
from table_name;

報錯信息:

FAILED: ODPS-0130071:[1,19] Semantic analysis exception - encounter runtime exception while evaluating function /, detailed message: DIVIDE func result overflow, two params are 1.000000 and 0.000000

正確改法:

建議去掉/0的用法,換成合法常量。

CASE WHEN常量折疊也有類似問題,比如:CASE WHEN TRUE THEN 0 ELSE 0/0,MaxCompute 2.0常量折疊時所有子表達式都會求值,導致除0錯誤。

CASE WHEN可能涉及更復雜的優化場景,比如:

select case when key = 0 then 0 else 1/key end
from (
select 0 as key from src
union all
select key from src) r;

優化器會將除法下推到子查詢中,轉換類似于:

M (
select case when 0 = 0 then 0 else 1/0 end c1 from src
UNION ALL
select case when key = 0 then 0 else 1/key end c1 from src) r;

報錯信息:

FAILED: ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed: java.lang.ArithmeticException: DIVIDE func result overflow, two params are 1.000000 and 0.000000

其中UNION ALL第一個子句常量折疊報錯,建議將SQL中的 CASE WHEN挪到子查詢中,并去掉無用的CASE WHEN和去掉/0用法:

select c1 end
from (
select 0 c1 end from src
union all
select case when key = 0 then 0 else 1/key end) r;

small.table.exceeds.mem.limit

舊版MaxCompute支持Multi-way Join優化,多個Join如果有相同Join Key,會合并到一個Fuxi Task中執行,比如下面例子中的J4_1_2_3_Stg1:

explain
select t1.*
from t1 join t2 on t1.c1 = t2.c1
join t3 on t1.c1 = t3.c1;

舊版MaxCompute物理執行計劃:

In Job job0:
root Tasks: M1_Stg1, M2_Stg1, M3_Stg1
J4_1_2_3_Stg1 depends on: M1_Stg1, M2_Stg1, M3_Stg1

In Task M1_Stg1:
    Data source: meta_dev.t1

In Task M2_Stg1:
    Data source: meta_dev.t2

In Task M3_Stg1:
    Data source: meta_dev.t3

In Task J4_1_2_3_Stg1:
    JOIN: t1 INNER JOIN unknown INNER JOIN unknown
        SEL: t1._col0, t1._col1, t1._col2
            FS: output: None

如果增加MapJoin hint,舊版MaxCompute物理執行計劃不會改變。也就是說對于舊版MaxCompute優先應用Multi-way Join優化,并且可以忽略用戶指定MapJoin hint。

explain
select /* +mapjoin(t1) */ t1.*
from t1 join t2 on t1.c1 = t2.c1
join t3 on t1.c1 = t3.c1;

舊版MaxCompute物理執行計劃同上。

MaxCompute 2.0 Optimizer會優先使用用戶指定的MapJoin hint,對于上述例子,如果t1比較大的話,會遇到類似錯誤:

FAILED: ODPS-0010000:System internal error - SQL Runtime Internal Error: Hash Join Cursor HashJoin_REL… small table exceeds, memory limit(MB) 640, fixed memory used …, variable memory used …

對于這種情況,如果MapJoin不是期望行為,建議去掉MapJoin hint。

sigkill.oom

同small.table.exceeds.mem.limit,如果用戶指定了MapJoin hint,并且用戶本身所指定的小表比較大。在舊版MaxCompute下有可能被優化成Multi-way Join從而成功。但在MaxCompute 2.0下,用戶可能通過設定odps.sql.mapjoin.memory.max來避免小表超限的錯誤,但每個MaxCompute worker有固定的內存限制,如果小表本身過大,則MaxCompute worker會由于內存超限而被殺掉,錯誤類似于:

Fuxi job failed - WorkerRestart errCode:9,errMsg:SigKill(OOM), usually caused by OOM(outof memory).

這里建議您去掉MapJoin hint,使用Multi-way Join。

wm_concat.first.argument.const

聚合函數 中關于WM_CONCAT的說明,一直要求WM_CONCAT第一個參數為常量,舊版MaxCompute檢查不嚴格,比如源表沒有數據,就算WM_CONCAT第一個參數為ColumnReference,也不會報錯。

函數聲明:
string wm_concat(string separator, string str)
參數說明:
separator:String類型常量,分隔符。其他類型或非常量將引發異常。

MaxCompute 2.0會在plan階段便檢查參數的合法性,假如WM_CONCAT的第一個參數不是常量,會立即報錯。示例如下:

錯誤寫法:

select wm_concat(value, ',') FROM src group by value;

報錯信息:

FAILED: ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed: com.aliyun.odps.lot.cbo.validator.AggregateCallValidator$AggregateCallValidationException: Invalid argument type - The first argument of WM_CONCAT must be constant string.

pt.implicit.convertion.failed

srcpt是一個分區表,并有兩個分區:

create table srcpt(key STRING, value STRING) partitioned by (pt STRING);
alter table srcpt add partition (pt='pt1');
alter table srcpt add partition (pt='pt2');

對于以上SQL,String類型pt列,INT類型常量,都會轉為DOUBLE進行比較。即使Project設置了odps.sql.udf.strict.mode=true,舊版MaxCompute不會報錯,所有pt都會過濾掉,而MaxCompute 2.0會直接報錯。示例如下:

錯誤寫法:

select key from srcpt where pt in (1, 2);

報錯信息:

FAILED: ODPS-0130071:[0,0] Semantic analysis exception - physical plan generation failed: java.lang.NumberFormatException: ODPS-0123091:Illegal type cast - In function cast, value 'pt1' cannot be casted from String to Double.

建議避免STRING分區列和INT類型常量比較,將INT類型常量改成STRING類型。

having.use.select.alias

SQL規范定義Group by + Having子句是Select子句之前階段,所以Having中不應該使用Select子句生成的Column alias。

示例

  • 錯誤寫法:

    select id id2 from table_name group by id having id2 > 0;
  • 報錯信息:

    FAILED: ODPS-0130071:[1,44] Semantic analysis exception - column id2 cannot be resolvedODPS-0130071:[1,44] Semantic analysis exception - column reference id2 should appear in GROUP BY key

    其中id2為Select子句中新生成的Column alias,不應該在Having子句中使用。

dynamic.pt.to.static

說明:MaxCompute2.0動態分區某些情況會被優化器轉換成靜態分區處理。

示例

insert overwrite table srcpt partition(pt) select id, 'pt1' from table_name;

會被轉化成

insert overwrite table srcpt partition(pt='pt1') select id from table_name;

如果用戶指定的分區值不合法,比如錯誤地使用了’${bizdate}’,MaxCompute 2.0語法檢查階段便會報錯。詳情請參見分區

錯誤寫法:

insert overwrite table srcpt partition(pt) select id, '${bizdate}' from table_name limit 0;

報錯信息:

FAILED: ODPS-0130071:[1,24] Semantic analysis exception - wrong columns count 2 in data source, requires 3 columns (includes dynamic partitions if any)

舊版MaxCompute因為LIMIT 0,SQL最終沒有輸出任何數據,動態分區不會創建,所以最終不報錯。

lot.not.in.subquery

說明:In subquery中NULL值的處理問題。

在標準SQL的IN 運算中,如果后面的值列表中出現NULL,則返回值不會出現false,只可能是NULL或者true。如1 in (null, 1, 2, 3) 為true,而1 in (null, 2, 3) 為NULL,null in (null, 1, 2, 3) 為NULL。同理not in操作在列表中有NULL的情況下,只會返回false或者NULL,不會出現true。

MaxCompute 2.0會用標準的行為進行處理,收到此提醒的用戶請注意檢查您的查詢,IN操作中的子查詢中是否會出現空值,出現空值時行為是否與您預期相符,如果不符合預期請做相應的修改。

示例

  • select * from t where c not in (select accepted from c_list);

    若accepted中不會出現NULL值,則此問題可忽略。若出現空值,則c not in (select accepted from c_list)原先返回true,則新版本返回NULL。

  • 正確寫法

    select * from t where c not in (select accepted from c_list where accepted is not null)