Todos os produtos
Search
Central de documentação

MaxCompute:Reescrita de SQL incompatível

Última atualização: Aug 21, 2026

Este tópico descreve como modifique instruções SQL incompatíveis.

Informações básicas

O MaxCompute V2.0 adota totalmente o ecossistema open source, com suporte a mais recursos de linguagem e maior velocidade de execução. No entanto, essa versão aplica verificações de sintaxe mais rigorosas. Consultas com sintaxe imprecisa executadas com sucesso em versões anteriores do compilador podem gerar erros no MaxCompute V2.0.

group.by.with.star

Descrição: Este problema ocorre ao usar uma instrução select * …group by….

  • No MaxCompute V2.0, a lista GROUP BY deve incluir todas as colunas da tabela de origem. Caso contrário, ocorrerá um erro.

  • Versões anteriores do MaxCompute aceitavam a sintaxe select * from ... group by key mesmo quando a lista GROUP BY não continha todas as colunas da tabela de origem.

Exemplos

  • Cenário 1: A chave GROUP BY não inclui todas as colunas da tabela de origem.

    • Sintaxe incorreta

      select * from t group by key;
    • Mensagem de erro

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

      select distinct key from t;
  • Cenário 2: A chave GROUP BY inclui todas as colunas.

    • A sintaxe abaixo não é recomendada.

      select * from t group by key, value; -- t has columns key and value
    • Embora essa sintaxe não gere erro no MaxCompute V2.0, recomenda-se alterar a instrução conforme mostrado a seguir.

      select distinct key, value from t;

bad.escape

Descrição: Este problema refere-se a sequências de escape incorretas.

Segundo as regras do MaxCompute, use uma barra invertida seguida de um número octal de três dígitos para representar caracteres ASCII de 0 a 127 em um literal de string. Por exemplo, "\001" e "\002" representam 0 e 1, respectivamente. Contudo, versões anteriores também processavam \01 e \0001 como \001.

Esse comportamento pode causar confusão. Não é possível usar "\0001" para representar "\000" seguido de "1". Para usuários que migram de outros sistemas, isso também pode resultar em erros de integridade dos dados.

Nota

Adicionar um número após \000, como \0001 - \0009 ou \00001, pode retornar um erro.

O MaxCompute V2.0 resolve essa questão. Modifique as sequências incorretas em seus scripts.

  • Sintaxe incorreta

    select split(key, "\01"), value like "\0001" from t;
  • Mensagem de erro

    FAILED: ODPS-0130161:[1,19] Parse exception - unexpected escape sequence: 01
    ODPS-0130161:[1,38] Parse exception - unexpected escape sequence: 0001
  • Sintaxe correta

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

column.repeated.in.creation

Descrição: No MaxCompute V2.0, ocorre um erro se você usar nomes de coluna duplicados durante a criação de uma tabela.

Exemplo

  • Sintaxe incorreta

    create table t (a BIGINT, b BIGINT, a BIGINT);
  • Mensagem de erro

    FAILED: ODPS-0130071:[1,37] Semantic analysis exception - column repeated in creation: a
  • Sintaxe correta

    create table t (a BIGINT, b BIGINT);

string.join.double

Descrição: Este problema surge em uma condição JOIN na qual o lado esquerdo do sinal de igual é do tipo STRING e o lado direito é do tipo DOUBLE.

  • Versões anteriores do MaxCompute convertiam ambos os lados para o tipo BIGINT. Essa conversão podia causar perda significativa de precisão. Por exemplo, a condição de junção 1.1="1" era considerada verdadeira.

  • Para garantir compatibilidade com o Hive, o MaxCompute V2.0 converte ambos os lados para o tipo DOUBLE.

Exemplo

  • Não recomendado

    select * from t1 join t2 on t1.double_value = t2.string_value;
  • Mensagem de aviso

    WARNING:[1,48]  implicit conversion from STRING to DOUBLE, potential data loss, use CAST function to suppress
  • Sintaxe recomendada

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

window.ref.prev.window.alias

Descrição: Este problema acontece quando uma função de janela referencia um alias de outra função de janela na mesma lista SELECT.

Exemplo

  • Se rn não existir em t1, a sintaxe a seguir estará incorreta.

    select row_number() over (partition by c1 order by c1) rn,
    row_number() over (partition by c1 order by rn) rn2
    from t1;
  • Mensagem de erro

    FAILED: ODPS-0130071:[2,45] Semantic analysis exception - column rn cannot be resolved
  • Sintaxe correta

    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

Descrição: Em uma lista SELECT, o asterisco (*) selecione todas as colunas de uma tabela. Entretanto, não é permitido adicionar um alias após o asterisco (). Essa restrição vale mesmo que o asterisco () se expanda para apenas uma coluna. O compilador do MaxCompute V2.0 reporta erro para essa sintaxe.

Exemplo

  • Sintaxe incorreta

    select * as alias from table_test;
  • Mensagem de erro

    FAILED: ODPS-0130161:[1,10] Parse exception - invalid token 'as'
  • Sintaxe correta

    select * from table_test;

agg.having.ref.prev.agg.alias

Descrição: Esta situação ocorre quando a lista SELECT referencia o alias de uma função de agregação anterior e há uma cláusula HAVING presente.

Exemplo

  • Sintaxe incorreta

    select count(c1) cnt,
    sum(c1) / cnt avg
    from t1
    group by c2
    having cnt > 1;
  • Mensagem de erro

    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

    Neste exemplo, s e cnt não existem na tabela de origem t1. Versões anteriores do MaxCompute não reportavam erro devido à presença da cláusula HAVING. Já o MaxCompute V2.0 retorna um erro de column cannot be resolved.

  • Sintaxe correta

    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

Descrição: Por padrão, o MaxCompute exige uma cláusula limit após uma cláusula order by para restringir a quantidade de resultados retornados. Esse requisito existe porque o order by executa uma ordenação completa, o que resulta em baixo desempenho de execução sem o uso de limit.

Exemplo

  • Sintaxe incorreta

    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;
  • Mensagem de erro

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

Adicione uma cláusula limit à subconsulta order by v.uv desc.

Além disso, o MaxCompute V1.0 não é rigoroso na verificação de views. É possível crie uma view em um projeto onde a validação de limit não é obrigatória definindo odps.sql.validate.orderby.limit=false.

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

Para acessar esta view:

select * from table_view;

O MaxCompute V1.0 não reporta erro nesse caso. O MaxCompute V2.0 exibe a seguinte mensagem de erro:

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

Descrição: Este tópico aborda o uso de aliases gerados automaticamente.

Versões anteriores do MaxCompute geravam automaticamente um alias para cada expressão em uma instrução SELECT e o exibiam no console. Como as regras para essa geração não são garantidas e podem mudar, evite usar aliases gerados automaticamente.

O MaxCompute V2.0 emite um aviso quando aliases gerados automaticamente são usados. No momento, não é possível proibir totalmente essa prática devido ao seu uso disseminado.

Em alguns casos, as regras de geração de aliases mudam entre versões do MaxCompute. Como certos jobs online dependem desses aliases, consultas podem falhar durante atualizações ou rollbacks de versão. Se enfrentar esse problema, modifique suas consultas para especifique explicitamente os aliases das colunas desejadas.

Exemplo

  • Não recomendado

    select _c0 from (select count(*) from table_name) t;
  • Sintaxe recomendada:

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

non.boolean.filter

Problema ao usar uma condição de filtro não BOOLEAN.

O MaxCompute não permite conversões implícitas entre tipos Boolean e outros tipos de dados. Versões anteriores permitiam, em certos casos, o uso de BIGINT como condição de filtro. O MaxCompute V2.0 bloqueia esse comportamento. Caso seus scripts contenham tais condições, modifique-as. Veja um exemplo:

Sintaxe incorreta:

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

Mensagem de erro:

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

A forma correta é:

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

post.select.ambiguous

Problema ao referenciar colunas com nomes conflitantes em instruções order by, cluster by, distribute by ou sort by.

Em versões anteriores do MaxCompute, o sistema selecionava por padrão a última coluna da lista SELECT como alvo da operação. O MaxCompute V2.0 reporta erro nessa situação. Modifique suas instruções conforme o exemplo:

Sintaxe incorreta:

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

Mensagem de erro:

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

A correção adequada é:

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

Essa alteração abrange também casos em que há conflito de nomes, mas a semântica permanece a mesma. Embora não cause ambiguidade direta, um aviso é emitido para incentivar a correção, pois essa sintaxe tende a gerar erros facilmente.

duplicated.partition.column

Problema ao especifique partições com o mesmo nome em uma consulta.

Versões anteriores do MaxCompute não reportavam erro ao especifique chaves de partição com nomes idênticos; o valor da chave posterior simplesmente sobrescrevia o da anterior. Esse comportamento gerava confusão. O MaxCompute V2.0 passa a reportar erro nesses casos. Os exemplos a seguir ilustram o problema:

Sintaxe incorreta 1:

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

Durante a execução, ds = ‘1’ é ignorado.

A forma correta é:

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

Sintaxe incorreta 2:

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

Procedimento correto:

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

order.by.col.ambiguous

Problema com alias duplicado na lista select referenciado posteriormente por uma cláusula order by.

Sintaxe incorreta:

select id, id
from table_test 
order by id;

A forma correta é:

select id, id id2
from table_name 
order by id;

Remova o alias duplicado antes de referenciá-lo na cláusula order by.

in.subquery.without.result

Problema em que colx é reportado como inexistente na tabela de origem se colx in subquery não retornar resultados.

Sintaxe incorreta:

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

Mensagem de erro:

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

ctas.if.not.exists

Problema com sintaxe incorreta para a tabela de destino.

Se a tabela de destino já existir, versões anteriores do MaxCompute não realizavam verificações de sintaxe. O MaxCompute V2.0 executa as validações normais, o que pode gerar diversas mensagens de erro. Veja um exemplo:

Sintaxe incorreta:

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

Mensagem de erro:

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

worker.restart.instance.timeout

Em versões anteriores do MaxCompute, cada registro gerado por uma User-Defined Function (UDF) acionava uma operação de escrita no sistema de arquivos distribuído e enviava um heartbeat ao Fuxi. Se a UDF não produzisse resultados por 10 minutos, a seguinte mensagem de erro aparecia:

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

O framework de runtime do MaxCompute V2.0 suporta vetorização, processando múltiplas linhas de uma coluna simultaneamente para aumentar a eficiência. Porém, a vetorização pode causar timeout em instruções que antes rodavam sem erros. Isso ocorre se o intervalo entre a saída de dois registros for inferior a 10 minutos. Como várias linhas são processadas em lote, os heartbeats podem não ser enviados ao Fuxi a tempo.

Ao encontrar esse erro, verifique primeiro se sua UDF apresenta problemas de desempenho, como demora de vários segundos por registro. Se não for possível otimizar a UDF, tente resolver ajustando manualmente o tamanho do lote de linhas. O valor padrão é 1024.

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

divide.nan.or.overflow

Problema em que versões anteriores do MaxCompute não aplicavam constant folding em divisões.

Por exemplo, para a instrução abaixo, o plano de execução física nas versões anteriores era:

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

Note que as funções IF e Divide permanecem. Durante a execução, a expressão Divide no segundo parâmetro não é avaliada porque o primeiro parâmetro de IF é falso, evitando exceção de divisão por zero.

Contudo, o MaxCompute V2.0 suporta constant folding para divisões e reporta erro, conforme o exemplo:

Sintaxe incorreta:

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

Mensagem de erro:

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

Além do erro acima, pode ocorrer um erro de overflow. Exemplo:

Sintaxe incorreta:

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

Mensagem de erro:

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

A forma correta é:

Elimine o uso de /0 e substitua por uma constante válida.

O constant folding de CASE WHEN apresenta problema similar. Em CASE WHEN TRUE THEN 0 ELSE 0/0, o MaxCompute V2.0 avalia todas as subexpressões durante o constant folding, causando erro de divisão por zero.

Cenários de otimização com CASE WHEN podem ser mais complexos. Exemplo:

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;

O otimizador empurra a operação de divisão para dentro da subconsulta. A transformação assemelha-se a:

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;

Mensagem de erro:

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

Nesse caso, o constant folding da primeira cláusula do UNION ALL gera erro. Para corrigir, mova a cláusula CASE WHEN da instrução SQL para a subconsulta, remova a cláusula CASE WHEN desnecessária e elimine o uso de /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

Versões anteriores do MaxCompute suportavam a otimização Multi-way Join. Múltiplas junções usando a mesma chave eram mescladas em uma única tarefa Fuxi, como J4_1_2_3_Stg1 na consulta abaixo:

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

Plano de execução física em versões anteriores do 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

Ao adicionar um hint MapJoin, o plano de execução física nas versões antigas permanecia inalterado. Isso indica que versões anteriores priorizavam a otimização Multi-way Join, podendo ignorar hints MapJoin definidos pelo usuário.

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

O plano de execução física nas versões anteriores permanecia idêntico ao anterior.

O otimizador do MaxCompute V2.0 prioriza hints MapJoin especificados pelo usuário. No exemplo acima, se t1 for grande, pode ocorrer um erro semelhante a:

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 …

Se o comportamento do MapJoin não for o esperado, remova o hint MapJoin.

sigkill.oom

Assim como no problema small.table.exceeds.mem.limit, ao especifique um hint MapJoin com uma tabela pequena que seja muito grande, a consulta podia ter sucesso em versões anteriores por ser otimizada como Multi-way Join. No MaxCompute V2.0, defina odps.sql.mapjoin.memory.max para evitar erros de limite de memória da tabela pequena. Porém, cada worker do MaxCompute possui um limite fixo de memória. Se a tabela for excessivamente grande, o worker será encerrado por erro de out-of-memory (OOM). O erro assemelha-se a:

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

Nessa situação, remova o hint MapJoin e utilize Multi-way Join.

wm_concat.first.argument.const

A documentação de WM_CONCAT em Aggregate functions sempre exigiu que o primeiro parâmetro fosse uma constante. Versões anteriores do MaxCompute não eram rigorosas nessa verificação. Se a tabela de origem estivesse vazia, nenhum erro era reportado mesmo que o primeiro parâmetro fosse um ColumnReference.

Function declaration:
string wm_concat(string separator, string str)
Parameter description:
separator: A constant of the String type. This is the separator. Other data types or non-constants will cause an exception.

O MaxCompute V2.0 valida os parâmetros durante a fase de planejamento. Se o primeiro parâmetro de WM_CONCAT não for constante, um erro é reportado imediatamente. Exemplo:

Sintaxe incorreta:

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

Mensagem de erro:

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 é uma tabela particionada com duas partições:

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');

Na instrução SQL acima, a coluna pt do tipo String e as constantes do tipo INT são convertidas para DOUBLE para comparação. Mesmo com o projeto configurado como odps.sql.udf.strict.mode=true, versões anteriores não reportavam erro, filtrando todos os valores de pt. O MaxCompute V2.0 reporta erro. Exemplo:

Sintaxe incorreta:

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

Mensagem de erro:

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.

Evite comparar uma coluna de chave de partição STRING com constantes do tipo INT. Altere as constantes INT para o tipo STRING.

having.use.select.alias

A especificação SQL define que as cláusulas GROUP BY e HAVING são processadas antes da cláusula SELECT. Logo, a cláusula HAVING não pode usar um alias de coluna gerado pela cláusula SELECT.

Exemplo

  • Sintaxe incorreta:

    select id id2 from table_name group by id having id2 > 0;
  • Mensagem de erro:

    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

    Neste exemplo, id2 é um novo alias de coluna gerado na cláusula SELECT e não pode ser usado na cláusula HAVING.

dynamic.pt.to.static

Descrição: No MaxCompute V2.0, partições dinâmicas são ocasionalmente convertidas em partições estáticas pelo otimizador.

Exemplo

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

é convertido para

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

Se você especifique um valor de partição inválido, como um uso incorreto de '${bizdate}', o MaxCompute V2.0 reportará erro durante a fase de verificação de sintaxe. Para mais informações, consulte Partitions.

Sintaxe incorreta:

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

Mensagem de erro:

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

Em versões anteriores, a instrução SQL não produzia dados devido à cláusula LIMIT 0 e nenhuma partição dinâmica era criada, portanto, nenhum erro era reportado.

lot.not.in.subquery

Descrição: Este problema refere-se ao tratamento de valores NULL em subconsultas IN.

Em operações IN do SQL padrão, se a lista de valores contiver NULL, o retorno nunca será false, podendo ser apenas NULL ou true. Por exemplo, 1 in (null, 1, 2, 3) retorna true, 1 in (null, 2, 3) retorna NULL e null in (null, 1, 2, 3) retorna NULL. Analogamente, em operações NOT IN, se a lista contiver NULL, o retorno será apenas false ou NULL, nunca true.

O MaxCompute V2.0 segue o comportamento do SQL padrão. Ao receber este aviso, verifique se a subconsulta na operação IN pode retornar valores nulos e confirme se o comportamento resultante atende às suas expectativas. Caso contrário, faça as modificações necessárias.

Exemplo

  • Se a coluna accepted não contiver valores NULL, ignore este aviso. Se houver valores nulos, a instrução c not in (select accepted from c_list), que antes retornava true, agora retornará NULL no MaxCompute V2.0.

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

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