Skip to content

Commit 60cb5d7

Browse files
committed
remove alter ops code to split PR
1 parent 7e7b831 commit 60cb5d7

File tree

2 files changed

+2
-731
lines changed

2 files changed

+2
-731
lines changed

core/src/main/java/org/apache/gravitino/catalog/ManagedFunctionOperations.java

Lines changed: 2 additions & 283 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import com.google.common.base.Preconditions;
2222
import java.io.IOException;
2323
import java.time.Instant;
24-
import java.util.ArrayList;
2524
import java.util.Arrays;
2625
import java.util.HashSet;
2726
import java.util.List;
@@ -41,8 +40,6 @@
4140
import org.apache.gravitino.function.FunctionChange;
4241
import org.apache.gravitino.function.FunctionColumn;
4342
import org.apache.gravitino.function.FunctionDefinition;
44-
import org.apache.gravitino.function.FunctionDefinitions;
45-
import org.apache.gravitino.function.FunctionImpl;
4643
import org.apache.gravitino.function.FunctionParam;
4744
import org.apache.gravitino.function.FunctionType;
4845
import org.apache.gravitino.meta.AuditInfo;
@@ -167,20 +164,8 @@ public Function registerFunction(
167164
@Override
168165
public Function alterFunction(NameIdentifier ident, FunctionChange... changes)
169166
throws NoSuchFunctionException, IllegalArgumentException {
170-
try {
171-
return store.update(
172-
ident,
173-
FunctionEntity.class,
174-
Entity.EntityType.FUNCTION,
175-
oldEntity -> applyChanges(oldEntity, changes));
176-
177-
} catch (NoSuchEntityException e) {
178-
throw new NoSuchFunctionException(e, "Function %s does not exist", ident);
179-
} catch (EntityAlreadyExistsException e) {
180-
throw new IllegalArgumentException("Failed to alter function " + ident, e);
181-
} catch (IOException e) {
182-
throw new RuntimeException("Failed to alter function " + ident, e);
183-
}
167+
// TODO: Implement when FunctionEntity is available
168+
throw new UnsupportedOperationException("alterFunction: FunctionEntity not yet implemented");
184169
}
185170

186171
@Override
@@ -257,74 +242,6 @@ private Function doRegisterFunction(
257242
}
258243
}
259244

260-
private FunctionEntity applyChanges(FunctionEntity oldEntity, FunctionChange... changes) {
261-
String newComment = oldEntity.comment();
262-
List<FunctionDefinition> newDefinitions =
263-
new ArrayList<>(Arrays.asList(oldEntity.definitions()));
264-
265-
for (FunctionChange change : changes) {
266-
if (change instanceof FunctionChange.UpdateComment) {
267-
newComment = ((FunctionChange.UpdateComment) change).newComment();
268-
269-
} else if (change instanceof FunctionChange.AddDefinition) {
270-
FunctionDefinition defToAdd = ((FunctionChange.AddDefinition) change).definition();
271-
validateNoArityOverlap(newDefinitions, defToAdd);
272-
newDefinitions.add(defToAdd);
273-
274-
} else if (change instanceof FunctionChange.RemoveDefinition) {
275-
FunctionParam[] paramsToRemove = ((FunctionChange.RemoveDefinition) change).parameters();
276-
validateRemoveDefinition(newDefinitions, paramsToRemove);
277-
newDefinitions.removeIf(def -> parametersMatch(def.parameters(), paramsToRemove));
278-
279-
} else if (change instanceof FunctionChange.AddImpl) {
280-
FunctionChange.AddImpl addImpl = (FunctionChange.AddImpl) change;
281-
FunctionParam[] targetParams = addImpl.parameters();
282-
FunctionImpl implToAdd = addImpl.implementation();
283-
newDefinitions = addImplToDefinition(newDefinitions, targetParams, implToAdd);
284-
285-
} else if (change instanceof FunctionChange.UpdateImpl) {
286-
FunctionChange.UpdateImpl updateImpl = (FunctionChange.UpdateImpl) change;
287-
FunctionParam[] targetParams = updateImpl.parameters();
288-
FunctionImpl.RuntimeType runtime = updateImpl.runtime();
289-
FunctionImpl newImpl = updateImpl.implementation();
290-
newDefinitions = updateImplInDefinition(newDefinitions, targetParams, runtime, newImpl);
291-
292-
} else if (change instanceof FunctionChange.RemoveImpl) {
293-
FunctionChange.RemoveImpl removeImpl = (FunctionChange.RemoveImpl) change;
294-
FunctionParam[] targetParams = removeImpl.parameters();
295-
FunctionImpl.RuntimeType runtime = removeImpl.runtime();
296-
newDefinitions = removeImplFromDefinition(newDefinitions, targetParams, runtime);
297-
298-
} else {
299-
throw new IllegalArgumentException("Unknown function change: " + change);
300-
}
301-
}
302-
303-
String currentUser = PrincipalUtils.getCurrentUserName();
304-
Instant now = Instant.now();
305-
AuditInfo newAuditInfo =
306-
AuditInfo.builder()
307-
.withCreator(oldEntity.auditInfo().creator())
308-
.withCreateTime(oldEntity.auditInfo().createTime())
309-
.withLastModifier(currentUser)
310-
.withLastModifiedTime(now)
311-
.build();
312-
313-
return FunctionEntity.builder()
314-
.withId(oldEntity.id())
315-
.withName(oldEntity.name())
316-
.withNamespace(oldEntity.namespace())
317-
.withComment(newComment)
318-
.withFunctionType(oldEntity.functionType())
319-
.withDeterministic(oldEntity.deterministic())
320-
.withReturnType(oldEntity.returnType())
321-
.withReturnColumns(oldEntity.returnColumns())
322-
.withDefinitions(newDefinitions.toArray(new FunctionDefinition[0]))
323-
.withVersion(oldEntity.version() + 1)
324-
.withAuditInfo(newAuditInfo)
325-
.build();
326-
}
327-
328245
/**
329246
* Validates that all definitions in the array do not have overlapping arities. This is used when
330247
* registering a function with multiple definitions.
@@ -357,40 +274,6 @@ private void validateDefinitionsNoArityOverlap(FunctionDefinition[] definitions)
357274
}
358275
}
359276

360-
/**
361-
* Validates that a new definition does not create ambiguous function arities with existing
362-
* definitions. Each definition can support multiple arities based on parameters with default
363-
* values.
364-
*
365-
* <p>Gravitino enforces strict validation to prevent ambiguity. Operations MUST fail if a new
366-
* definition's invocation arities overlap with existing ones. For example, if an existing
367-
* definition {@code foo(int, float default 1.0)} supports arities {@code (int)} and {@code (int,
368-
* float)}, adding a new definition {@code foo(int, string default 'x')} (which supports {@code
369-
* (int)} and {@code (int, string)}) will be REJECTED because both support the call {@code
370-
* foo(1)}. This ensures every function invocation deterministically maps to a single definition.
371-
*
372-
* @param existingDefinitions The current definitions.
373-
* @param newDefinition The definition to add.
374-
* @throws IllegalArgumentException If the new definition creates overlapping arities.
375-
*/
376-
private void validateNoArityOverlap(
377-
List<FunctionDefinition> existingDefinitions, FunctionDefinition newDefinition) {
378-
Set<String> newArities = computeArities(newDefinition);
379-
380-
for (FunctionDefinition existing : existingDefinitions) {
381-
Set<String> existingArities = computeArities(existing);
382-
for (String arity : newArities) {
383-
if (existingArities.contains(arity)) {
384-
throw new IllegalArgumentException(
385-
String.format(
386-
"Cannot add definition: arity '%s' overlaps with an existing definition. "
387-
+ "This would create ambiguous function invocations.",
388-
arity));
389-
}
390-
}
391-
}
392-
}
393-
394277
/**
395278
* Computes all possible invocation arities for a function definition. A definition with N
396279
* parameters where the last M have default values supports arities from (N-M) to N parameters.
@@ -456,168 +339,4 @@ private Set<String> computeArities(FunctionDefinition definition) {
456339

457340
return arities;
458341
}
459-
460-
/**
461-
* Validates that a definition can be removed.
462-
*
463-
* @param definitions The current definitions.
464-
* @param paramsToRemove The parameters identifying the definition to remove.
465-
* @throws IllegalArgumentException If the definition doesn't exist or is the only one.
466-
*/
467-
private void validateRemoveDefinition(
468-
List<FunctionDefinition> definitions, FunctionParam[] paramsToRemove) {
469-
boolean found = false;
470-
for (FunctionDefinition def : definitions) {
471-
if (parametersMatch(def.parameters(), paramsToRemove)) {
472-
found = true;
473-
break;
474-
}
475-
}
476-
477-
if (!found) {
478-
throw new IllegalArgumentException(
479-
"Cannot remove definition: no definition found with the specified parameters");
480-
}
481-
482-
if (definitions.size() == 1) {
483-
throw new IllegalArgumentException(
484-
"Cannot remove the only definition. Use dropFunction to remove the entire function.");
485-
}
486-
}
487-
488-
private boolean parametersMatch(FunctionParam[] params1, FunctionParam[] params2) {
489-
if (params1.length != params2.length) {
490-
return false;
491-
}
492-
for (int i = 0; i < params1.length; i++) {
493-
if (!params1[i].name().equals(params2[i].name())
494-
|| !params1[i].dataType().equals(params2[i].dataType())) {
495-
return false;
496-
}
497-
}
498-
return true;
499-
}
500-
501-
private List<FunctionDefinition> addImplToDefinition(
502-
List<FunctionDefinition> definitions, FunctionParam[] targetParams, FunctionImpl implToAdd) {
503-
List<FunctionDefinition> result = new ArrayList<>();
504-
boolean found = false;
505-
506-
for (FunctionDefinition def : definitions) {
507-
if (parametersMatch(def.parameters(), targetParams)) {
508-
found = true;
509-
// Check if runtime already exists
510-
for (FunctionImpl existingImpl : def.impls()) {
511-
if (existingImpl.runtime() == implToAdd.runtime()) {
512-
throw new IllegalArgumentException(
513-
String.format(
514-
"Cannot add implementation: runtime '%s' already exists in this definition. "
515-
+ "Use updateImpl to replace it.",
516-
implToAdd.runtime()));
517-
}
518-
}
519-
List<FunctionImpl> impls = new ArrayList<>(Arrays.asList(def.impls()));
520-
impls.add(implToAdd);
521-
result.add(FunctionDefinitions.of(def.parameters(), impls.toArray(new FunctionImpl[0])));
522-
} else {
523-
result.add(def);
524-
}
525-
}
526-
527-
if (!found) {
528-
throw new IllegalArgumentException(
529-
"Cannot add implementation: no definition found with the specified parameters");
530-
}
531-
532-
return result;
533-
}
534-
535-
private List<FunctionDefinition> updateImplInDefinition(
536-
List<FunctionDefinition> definitions,
537-
FunctionParam[] targetParams,
538-
FunctionImpl.RuntimeType runtime,
539-
FunctionImpl newImpl) {
540-
List<FunctionDefinition> result = new ArrayList<>();
541-
boolean definitionFound = false;
542-
boolean runtimeFound = false;
543-
544-
for (FunctionDefinition def : definitions) {
545-
if (parametersMatch(def.parameters(), targetParams)) {
546-
definitionFound = true;
547-
List<FunctionImpl> impls = new ArrayList<>();
548-
for (FunctionImpl impl : def.impls()) {
549-
if (impl.runtime() == runtime) {
550-
runtimeFound = true;
551-
impls.add(newImpl);
552-
} else {
553-
impls.add(impl);
554-
}
555-
}
556-
result.add(FunctionDefinitions.of(def.parameters(), impls.toArray(new FunctionImpl[0])));
557-
} else {
558-
result.add(def);
559-
}
560-
}
561-
562-
if (!definitionFound) {
563-
throw new IllegalArgumentException(
564-
"Cannot update implementation: no definition found with the specified parameters");
565-
}
566-
567-
if (!runtimeFound) {
568-
throw new IllegalArgumentException(
569-
String.format(
570-
"Cannot update implementation: runtime '%s' not found in the definition", runtime));
571-
}
572-
573-
return result;
574-
}
575-
576-
private List<FunctionDefinition> removeImplFromDefinition(
577-
List<FunctionDefinition> definitions,
578-
FunctionParam[] targetParams,
579-
FunctionImpl.RuntimeType runtime) {
580-
List<FunctionDefinition> result = new ArrayList<>();
581-
boolean definitionFound = false;
582-
boolean runtimeFound = false;
583-
584-
for (FunctionDefinition def : definitions) {
585-
if (parametersMatch(def.parameters(), targetParams)) {
586-
definitionFound = true;
587-
588-
// Check if this is the only implementation
589-
if (def.impls().length == 1) {
590-
if (def.impls()[0].runtime() == runtime) {
591-
throw new IllegalArgumentException(
592-
"Cannot remove the only implementation. Use removeDefinition to remove the entire definition.");
593-
}
594-
}
595-
596-
List<FunctionImpl> impls = new ArrayList<>();
597-
for (FunctionImpl impl : def.impls()) {
598-
if (impl.runtime() == runtime) {
599-
runtimeFound = true;
600-
} else {
601-
impls.add(impl);
602-
}
603-
}
604-
result.add(FunctionDefinitions.of(def.parameters(), impls.toArray(new FunctionImpl[0])));
605-
} else {
606-
result.add(def);
607-
}
608-
}
609-
610-
if (!definitionFound) {
611-
throw new IllegalArgumentException(
612-
"Cannot remove implementation: no definition found with the specified parameters");
613-
}
614-
615-
if (!runtimeFound) {
616-
throw new IllegalArgumentException(
617-
String.format(
618-
"Cannot remove implementation: runtime '%s' not found in the definition", runtime));
619-
}
620-
621-
return result;
622-
}
623342
}

0 commit comments

Comments
 (0)