Skip to content

Commit

Permalink
[SPARK-51395][SQL] Refine handling of default values in procedures
Browse files Browse the repository at this point in the history
  • Loading branch information
aokolnychyi committed Mar 6, 2025
1 parent cdba396 commit 425e456
Show file tree
Hide file tree
Showing 8 changed files with 469 additions and 15 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.apache.spark.sql.connector.catalog;

import java.util.Objects;
import javax.annotation.Nullable;

import org.apache.spark.annotation.Evolving;
import org.apache.spark.sql.connector.expressions.Expression;

@Evolving
public class DefaultValue {
private final String sql;
private final Expression expr;

public DefaultValue(String sql) {
this(sql, null /* no expression */);
}

public DefaultValue(Expression expr) {
this(null /* no sql */, expr);
}

public DefaultValue(String sql, Expression expr) {
if (sql == null && expr == null) {
throw new IllegalArgumentException("SQL and expression can't be both null");
}
this.sql = sql;
this.expr = expr;
}

@Nullable
public String getSql() {
return sql;
}

@Nullable
public Expression getExpression() {
return expr;
}

@Override
public boolean equals(Object other) {
if (this == other) return true;
if (other == null || getClass() != other.getClass()) return false;
DefaultValue that = (DefaultValue) other;
return Objects.equals(sql, that.sql) && Objects.equals(expr, that.expr);
}

@Override
public int hashCode() {
return Objects.hash(sql, expr);
}

@Override
public String toString() {
return String.format("DefaultValue{sql=%s, expression=%s}", sql, expr);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
import javax.annotation.Nullable;

import org.apache.spark.annotation.Evolving;
import org.apache.spark.sql.connector.catalog.DefaultValue;
import org.apache.spark.sql.connector.expressions.Expression;
import org.apache.spark.sql.internal.connector.ProcedureParameterImpl;
import org.apache.spark.sql.types.DataType;

Expand Down Expand Up @@ -68,7 +70,7 @@ static Builder in(String name, DataType dataType) {
* null if not provided.
*/
@Nullable
String defaultValueExpression();
DefaultValue defaultValue();

/**
* Returns the comment of this parameter or null if not provided.
Expand All @@ -89,7 +91,7 @@ class Builder {
private final Mode mode;
private final String name;
private final DataType dataType;
private String defaultValueExpression;
private DefaultValue defaultValue;
private String comment;

private Builder(Mode mode, String name, DataType dataType) {
Expand All @@ -99,10 +101,26 @@ private Builder(Mode mode, String name, DataType dataType) {
}

/**
* Sets the default value expression of the parameter.
* Sets the default value of the parameter using SQL.
*/
public Builder defaultValue(String defaultValueExpression) {
this.defaultValueExpression = defaultValueExpression;
public Builder defaultValue(String sql) {
this.defaultValue = new DefaultValue(sql);
return this;
}

/**
* Sets the default value of the parameter using an expression.
*/
public Builder defaultValue(Expression expression) {
this.defaultValue = new DefaultValue(expression);
return this;
}

/**
* Sets the default value of the parameter.
*/
public Builder defaultValue(DefaultValue defaultValue) {
this.defaultValue = defaultValue;
return this;
}

Expand All @@ -118,7 +136,7 @@ public Builder comment(String comment) {
* Builds the stored procedure parameter.
*/
public ProcedureParameter build() {
return new ProcedureParameterImpl(mode, name, dataType, defaultValueExpression, comment);
return new ProcedureParameterImpl(mode, name, dataType, defaultValue, comment);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -135,10 +135,11 @@ object NamedParametersSupport {
}

private def toInputParameter(param: ProcedureParameter): InputParameter = {
val defaultValue = Option(param.defaultValueExpression).map { expr =>
ResolveDefaultColumns.analyze(param.name, param.dataType, expr, "CALL")
val defaultValueExpr = Option(param.defaultValue).map { defaultValue =>
val sql = ResolveDefaultColumns.generateSQL(defaultValue)
ResolveDefaultColumns.analyze(param.name, param.dataType, sql, "CALL")
}
InputParameter(param.name, defaultValue)
InputParameter(param.name, defaultValueExpr)
}

private def defaultRearrange(
Expand Down
Loading

0 comments on commit 425e456

Please sign in to comment.