package com.easyagents.federation.sql.runtime;

import org.apache.calcite.sql.SqlDataTypeSpec;
import org.apache.calcite.sql.SqlDynamicParam;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.parser.SqlParserPos;
import org.apache.calcite.sql.validate.SqlValidator;
import org.apache.calcite.sql.validate.SqlValidatorScope;

/**
 * 将调用方声明的 JDBC 参数类型直接交给 Calcite Validator 的动态参数节点。
 *
 * <p>该节点仍按普通 {@code ?} 输出，不向目标数据库注入额外 CAST，且可覆盖
 * Calcite 对 OFFSET/FETCH 动态参数无法自行推导类型的路径。</p>
 */
final class TypedSqlDynamicParam extends SqlDynamicParam {

    private final SqlDataTypeSpec typeSpec;

    /**
     * 创建带声明类型的动态参数。
     *
     * @param index 原 SQL 中的零基参数索引
     * @param position 参数语法位置
     * @param typeSpec Adapter 提供的 Calcite 类型声明
     */
    TypedSqlDynamicParam(int index, SqlParserPos position, SqlDataTypeSpec typeSpec) {
        super(index, position);
        if (typeSpec == null) {
            throw new IllegalArgumentException("typeSpec must not be null");
        }
        this.typeSpec = typeSpec;
    }

    /** {@inheritDoc} */
    @Override
    public void validate(SqlValidator validator, SqlValidatorScope scope) {
        validator.validateDynamicParam(this);
        validator.setValidatedNodeType(this, typeSpec.deriveType(validator));
    }

    /** {@inheritDoc} */
    @Override
    public SqlNode clone(SqlParserPos position) {
        return new TypedSqlDynamicParam(getIndex(), position, typeSpec);
    }
}
