Todos los productos
Search
Centro de documentos

MaxCompute:Reescritura de SQL incompatible

Última actualización: Sep 24, 2026

Este tema describe cómo modificar sentencias SQL incompatibles.

Contexto

MaxCompute V2.0 adopta por completo el ecosistema de código abierto. Admite más funciones del lenguaje y se ejecuta con mayor rapidez. Sin embargo, aplica comprobaciones de sintaxis más estrictas. Las consultas con sintaxis imprecisa que se ejecutaban correctamente en versiones anteriores del compilador pueden generar errores en MaxCompute V2.0.

group.by.with.star

Descripción: este problema ocurre cuando se utiliza una sentencia select * …group by….

  • En MaxCompute V2.0, la lista GROUP BY debe incluir todas las columnas de la tabla de origen; de lo contrario, se genera un error.

  • Las versiones anteriores de MaxCompute admiten la sintaxis select * from ... group by key incluso si la lista GROUP BY no incluye todas las columnas de la tabla de origen.

Ejemplos

  • Escenario 1: la clave GROUP BY no incluye todas las columnas de la tabla de origen.

    • Sintaxis incorrecta

      select * from t group by key;
    • Mensaje de error

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

      select distinct key from t;
  • Escenario 2: la clave GROUP BY incluye todas las columnas.

    • A continuación se muestra una sintaxis que no se recomienda utilizar.

      select * from t group by key, value; -- t has columns key and value
    • Aunque esta sintaxis no genera un error en MaxCompute V2.0, se recomienda cambiar la sentencia de la siguiente manera.

      select distinct key, value from t;

bad.escape

Descripción: este problema está relacionado con secuencias de escape incorrectas.

Según las reglas de MaxCompute, para representar caracteres ASCII del 0 al 127 en un literal de cadena se debe usar una barra invertida seguida de un número octal de tres dígitos. Por ejemplo, puede usar "\001" y "\002" para representar 0 y 1. No obstante, las versiones anteriores también procesaban \01 y \0001 como \001.

Este comportamiento puede resultar confuso. Por ejemplo, no es posible usar "\0001" para representar "\000" seguido de "1". Para los usuarios que migran desde otros sistemas, esto también puede provocar errores de exactitud.

Nota

Agregar un número a \000, como \0001 - \0009 o \00001, puede devolver un error.

MaxCompute V2.0 resuelve este problema. Modifique las secuencias incorrectas en sus scripts.

  • Sintaxis incorrecta

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

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

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

column.repeated.in.creation

Descripción: en MaxCompute V2.0, se genera un error si se usan nombres de columna duplicados al crear una tabla.

Ejemplo

  • Sintaxis incorrecta

    create table t (a BIGINT, b BIGINT, a BIGINT);
  • Mensaje de error

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

    create table t (a BIGINT, b BIGINT);

string.join.double

Descripción: este problema ocurre en una condición JOIN donde el lado izquierdo del signo igual es de tipo STRING y el derecho es de tipo DOUBLE.

  • Las versiones anteriores de MaxCompute convierten ambos lados al tipo BIGINT. Esta conversión puede causar una pérdida significativa de precisión. Por ejemplo, la condición de unión 1.1="1" se evalúa como verdadera.

  • Para mantener la compatibilidad con Hive, MaxCompute V2.0 convierte ambos lados al tipo DOUBLE.

Ejemplo

  • No recomendado

    select * from t1 join t2 on t1.double_value = t2.string_value;
  • Mensaje de advertencia

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

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

window.ref.prev.window.alias

Descripción: este problema ocurre cuando una función de ventana hace referencia a un alias de otra función de ventana en la misma lista SELECT.

Ejemplo

  • Si rn no existe en t1, la siguiente sintaxis es incorrecta.

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

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

    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

Descripción: en una lista SELECT, puede usar un asterisco (*) para seleccionar todas las columnas de una tabla. Sin embargo, no es posible agregar un alias después del asterisco (). Esta sintaxis no está permitida ni siquiera cuando el asterisco () se expande a una sola columna. El compilador de MaxCompute V2.0 reporta un error para estos casos.

Ejemplo

  • Sintaxis incorrecta

    select * as alias from table_test;
  • Mensaje de error

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

    select * from table_test;

agg.having.ref.prev.agg.alias

Descripción: este problema ocurre cuando la lista SELECT hace referencia al alias de una función de agregación anterior y existe una cláusula HAVING.

Ejemplo

  • Sintaxis incorrecta

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

    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

    En este ejemplo, s y cnt no existen en la tabla de origen t1. Las versiones anteriores de MaxCompute no reportaban un error debido a la cláusula HAVING. MaxCompute V2.0 reporta un error de column cannot be resolved.

  • Sintaxis correcta

    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

Descripción: de forma predeterminada, MaxCompute requiere agregar una cláusula limit después de una cláusula order by para limitar la cantidad de resultados devueltos. Este requisito existe porque order by realiza una ordenación completa, lo cual tiene un rendimiento de ejecución bajo si no se usa una cláusula limit.

Ejemplo

  • Sintaxis incorrecta

    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;
  • Mensaje de error

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

Agregue una cláusula limit a la subconsulta order by v.uv desc.

Además, MaxCompute V1.0 no es estricto al comprobar las vistas. Por ejemplo, puede crear una vista en un proyecto donde no se requiera la comprobación de limit si establece odps.sql.validate.orderby.limit=false.

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

Para acceder a esta vista:

select * from table_view;

MaxCompute V1.0 no reporta ningún error. MaxCompute V2.0 reporta el siguiente mensaje de error:

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

Descripción: este problema está relacionado con el uso de aliases generados automáticamente.

Las versiones anteriores de MaxCompute generan automáticamente un alias para cada expresión en una sentencia SELECT. Este alias se muestra en la consola. Sin embargo, las reglas para generarlo no están garantizadas y pueden cambiar. Por lo tanto, no utilice alias generados automáticamente.

MaxCompute V2.0 emite una advertencia cuando se usan alias generados automáticamente. Por ahora no es posible prohibir esta práctica, ya que se utiliza ampliamente.

En algunos casos, las reglas para generar alias cambian entre versiones de MaxCompute. Dado que ciertos trabajos en producción dependen de estos alias, dichas consultas pueden fallar durante una actualización o reversión de versión de MaxCompute. Si se presenta este problema, modifique sus consultas para especificar explícitamente los alias de las columnas que desea usar.

Ejemplo

  • No recomendado

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

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

non.boolean.filter

Problema al usar una condición de filtro que no es BOOLEAN.

MaxCompute no permite conversiones implícitas entre tipos booleanos y otros tipos de datos. No obstante, las versiones anteriores permiten usar BIGINT como condición de filtro en ciertos casos. MaxCompute V2.0 ya no admite este comportamiento. Si sus scripts contienen este tipo de condiciones de filtro, modifíquelas. A continuación se muestra un ejemplo:

Sintaxis incorrecta:

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

Mensaje de error:

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

El método correcto es el siguiente:

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

post.select.ambiguous

Problema al hacer referencia a columnas con nombres en conflicto en sentencias order by, cluster by, distribute by o sort by.

En las versiones anteriores de MaxCompute, el sistema selecciona de forma predeterminada la última columna de la lista SELECT como objeto de la operación. MaxCompute V2.0 reporta un error. Modifique sus sentencias. A continuación se muestra un ejemplo:

Sintaxis incorrecta:

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

Mensaje de error:

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

La corrección adecuada es la siguiente:

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

Este cambio también abarca los casos en los que los nombres entran en conflicto pero la semántica es la misma. Aunque esto no genera ambigüedad, se reporta una advertencia para invitarlo a corregirlo, ya que esta sintaxis puede provocar errores con facilidad.

duplicated.partition.column

Problema al especificar particiones con el mismo nombre en una consulta.

Las versiones anteriores de MaxCompute no reportaban un error cuando se especificaba una clave de partición con el mismo nombre. En su lugar, el valor de la segunda clave sobrescribía el de la primera. Este comportamiento podía causar confusión fácilmente. MaxCompute V2.0 reporta un error en este caso. Los siguientes ejemplos ilustran el problema:

Sintaxis incorrecta 1:

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

Durante la ejecución, se ignora ds = ‘1’.

El método correcto es el siguiente:

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

Sintaxis incorrecta 2:

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

Procedimiento correcto:

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

order.by.col.ambiguous

Problema con un alias duplicado en la lista select al que después hace referencia una cláusula order by.

Sintaxis incorrecta:

select id, id
from table_test 
order by id;

El método correcto es el siguiente:

select id, id id2
from table_name 
order by id;

Elimine el alias duplicado antes de hacer referencia a él en la cláusula order by.

in.subquery.without.result

Problema en el que se reporta que colx no existe en la tabla de origen si colx in subquery no devuelve resultados.

Sintaxis incorrecta:

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

Mensaje de error:

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

ctas.if.not.exists

Problema de sintaxis incorrecta en la tabla de destino.

Si la tabla de destino ya existe, las versiones anteriores de MaxCompute no realizan comprobaciones de sintaxis. MaxCompute V2.0 sí las lleva a cabo de forma normal. Este cambio puede generar varios mensajes de error. A continuación se muestra un ejemplo:

Sintaxis incorrecta:

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

Mensaje de error:

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

worker.restart.instance.timeout

En las versiones anteriores de MaxCompute, cada registro que genera una función definida por el usuario (UDF) activa una operación de escritura en el sistema de archivos distribuido y envía un heartbeat a Fuxi. Si la UDF no produce resultados durante 10 minutos, recibirá el siguiente mensaje de error:

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

El framework de tiempo de ejecución de MaxCompute V2.0 es compatible con la vectorización. Este proceso maneja varias filas de una columna a la vez para mejorar la eficiencia de ejecución. Sin embargo, puede provocar que sentencias que antes se ejecutaban sin errores ahora superen el tiempo de espera. Esto sucede si el intervalo entre la salida de dos registros era menor a 10 minutos. Como se procesan múltiples filas simultáneamente, es posible que los heartbeats no se envíen a Fuxi a tiempo.

Si se presenta este error, compruebe primero si su UDF tiene problemas de rendimiento, por ejemplo, si cada registro tarda varios segundos en procesarse. Si no logra optimizar el rendimiento de la UDF, intente resolver el problema estableciendo manualmente el tamaño de lote de filas. El valor predeterminado es 1024.

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

divide.nan.or.overflow

Problema en el que las versiones anteriores de MaxCompute no aplican plegado de constantes en divisiones.

Por ejemplo, para la siguiente sentencia, el plan de ejecución física en las versiones anteriores de MaxCompute es este:

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

Como se observa, las funciones IF y Divide se conservan. Durante la ejecución, la expresión Divide del segundo parámetro no se evalúa porque el primer parámetro de IF es falso. Por lo tanto, no se genera ninguna excepción de división por cero.

Sin embargo, MaxCompute V2.0 admite el plegado de constantes para divisiones y reporta un error, como se muestra en el siguiente ejemplo:

Sintaxis incorrecta:

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

Mensaje de error:

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

Además del error anterior, también podría presentarse un error de desbordamiento. Por ejemplo:

Sintaxis incorrecta:

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

Mensaje de error:

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

El método correcto es el siguiente:

Elimine el uso de /0 y reemplácelo por una constante válida.

El plegado de constantes de CASE WHEN presenta un problema similar. Por ejemplo, en CASE WHEN TRUE THEN 0 ELSE 0/0, MaxCompute V2.0 evalúa todas las subexpresiones durante el plegado de constantes. Esto provoca un error de división por cero.

CASE WHEN puede involucrar escenarios de optimización más complejos. Por ejemplo:

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;

El optimizador traslada la operación de división hacia la subconsulta. La transformación es similar a la siguiente:

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;

Mensaje de error:

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

En este caso, el plegado de constantes de la primera cláusula de UNION ALL reporta un error. Para resolverlo, mueva la cláusula CASE WHEN de la sentencia SQL a la subconsulta, elimine la cláusula CASE WHEN innecesaria y quite el 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

Las versiones anteriores de MaxCompute son compatibles con la optimización Multi-way Join. Varias uniones que usan la misma clave de combinación se fusionan en una sola tarea de Fuxi. Un ejemplo es J4_1_2_3_Stg1 en la siguiente consulta:

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

Plan de ejecución física en las versiones anteriores de 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

Si agrega una sugerencia MapJoin, el plan de ejecución física en las versiones anteriores de MaxCompute no cambia. Esto indica que dichas versiones priorizan la optimización Multi-way Join y pueden ignorar las sugerencias MapJoin especificadas por el usuario.

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

El plan de ejecución física en las versiones anteriores de MaxCompute es el mismo que el anterior.

El optimizador de MaxCompute V2.0 prioriza las sugerencias MapJoin especificadas por el usuario. En el ejemplo anterior, si t1 es grande, podría encontrar un error similar al siguiente:

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 …

En este caso, si el comportamiento de MapJoin no es el esperado, elimine la sugerencia MapJoin.

sigkill.oom

De forma similar al problema small.table.exceeds.mem.limit, si especifica una sugerencia MapJoin y la tabla pequeña indicada es grande, la consulta podría ejecutarse correctamente en las versiones anteriores de MaxCompute porque se optimiza como Multi-way Join. En MaxCompute V2.0, puede establecer odps.sql.mapjoin.memory.max para evitar errores causados cuando la tabla pequeña supera el límite de memoria. Sin embargo, cada worker de MaxCompute tiene un límite de memoria fijo. Si la tabla pequeña es demasiado grande, el worker se detiene por un error de falta de memoria (OOM). El error es similar al siguiente:

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

Ante esta situación, elimine la sugerencia MapJoin y utilice un Multi-way Join.

wm_concat.first.argument.const

La descripción de WM_CONCAT en Aggregate functions siempre ha indicado que el primer parámetro de WM_CONCAT debe ser una constante. Las versiones anteriores de MaxCompute no eran estrictas con esta comprobación. Por ejemplo, si la tabla de origen no tenía datos, no se reportaba ningún error aunque el primer parámetro de WM_CONCAT fuera un 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.

MaxCompute V2.0 comprueba la validez de los parámetros durante la fase de planificación. Si el primer parámetro de WM_CONCAT no es una constante, se reporta un error de inmediato. A continuación se muestra un ejemplo:

Sintaxis incorrecta:

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

Mensaje de error:

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 es una tabla particionada que tiene dos particiones:

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

Para la sentencia SQL anterior, la columna pt de tipo String y las constantes de tipo INT se convierten al tipo DOUBLE para realizar la comparación. Incluso si el proyecto tiene configurado odps.sql.udf.strict.mode=true, las versiones anteriores de MaxCompute no reportan ningún error. Todos los valores de pt se filtran. MaxCompute V2.0 sí reporta un error. A continuación se muestra un ejemplo:

Sintaxis incorrecta:

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

Mensaje de error:

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 una columna de clave de partición STRING con constantes de tipo INT. Cambie las constantes de tipo INT al tipo STRING.

having.use.select.alias

La especificación SQL define que las cláusulas GROUP BY y HAVING se procesan antes que la cláusula SELECT. Por lo tanto, la cláusula HAVING no puede usar un alias de columna generado por la cláusula SELECT.

Ejemplo

  • Sintaxis incorrecta:

    select id id2 from table_name group by id having id2 > 0;
  • Mensaje de error:

    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

    En este ejemplo, id2 es un nuevo alias de columna generado en la cláusula SELECT y no se puede usar en la cláusula HAVING.

dynamic.pt.to.static

Descripción: en MaxCompute V2.0, el optimizador a veces convierte las particiones dinámicas en particiones estáticas.

Ejemplo

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

se convierte en

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

Si especifica un valor de partición no válido, como un uso incorrecto de '${bizdate}', MaxCompute V2.0 reporta un error durante la fase de comprobación de sintaxis. Para obtener más información, consulte Partitions.

Sintaxis incorrecta:

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

Mensaje de error:

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

En las versiones anteriores de MaxCompute, la sentencia SQL no genera datos debido a la cláusula LIMIT 0 y no se crea ninguna partición dinámica. Por lo tanto, no se reporta ningún error.

lot.not.in.subquery

Descripción: este problema está relacionado con la forma en que se manejan los valores NULL en una subconsulta IN.

En las operaciones IN del estándar SQL, si la lista de valores contiene NULL, el valor devuelto no es false. Solo puede ser NULL o true. Por ejemplo, 1 in (null, 1, 2, 3) devuelve true, 1 in (null, 2, 3) devuelve NULL y null in (null, 1, 2, 3) devuelve NULL. De manera similar, en una operación NOT IN, si la lista contiene NULL, el valor devuelto solo puede ser false o NULL, nunca true.

MaxCompute V2.0 maneja este problema según el comportamiento del estándar SQL. Si recibe este aviso, revise sus consultas para determinar si la subconsulta de la operación IN puede devolver valores nulos. Compruebe también si el comportamiento ante valores nulos es el esperado. De no ser así, aplique las modificaciones necesarias.

Ejemplo

  • Si la columna accepted no contiene valores NULL, puede ignorar este problema. Si contiene valores nulos, la sentencia c not in (select accepted from c_list), que antes devolvía true, ahora devuelve NULL en MaxCompute V2.0.

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

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