Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Licensed to the Apache Software Foundation (ASF) under one or more
0003  * contributor license agreements.  See the NOTICE file distributed with
0004  * this work for additional information regarding copyright ownership.
0005  * The ASF licenses this file to You under the Apache License, Version 2.0
0006  * (the "License"); you may not use this file except in compliance with
0007  * the License.  You may obtain a copy of the License at
0008  *
0009  *    http://www.apache.org/licenses/LICENSE-2.0
0010  *
0011  * Unless required by applicable law or agreed to in writing, software
0012  * distributed under the License is distributed on an "AS IS" BASIS,
0013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014  * See the License for the specific language governing permissions and
0015  * limitations under the License.
0016  */
0017 
0018 package org.apache.spark.sql.catalyst.expressions;
0019 
0020 import com.google.common.annotations.VisibleForTesting;
0021 
0022 import java.util.Arrays;
0023 import java.util.HashSet;
0024 import java.util.Set;
0025 
0026 /**
0027  * Expression information, will be used to describe a expression.
0028  */
0029 public class ExpressionInfo {
0030     private String className;
0031     private String usage;
0032     private String name;
0033     private String extended;
0034     private String db;
0035     private String arguments;
0036     private String examples;
0037     private String note;
0038     private String group;
0039     private String since;
0040     private String deprecated;
0041 
0042     private static final Set<String> validGroups =
0043         new HashSet<>(Arrays.asList("agg_funcs", "array_funcs", "datetime_funcs",
0044             "json_funcs", "map_funcs", "window_funcs"));
0045 
0046     public String getClassName() {
0047         return className;
0048     }
0049 
0050     public String getUsage() {
0051         return replaceFunctionName(usage);
0052     }
0053 
0054     public String getName() {
0055         return name;
0056     }
0057 
0058     public String getExtended() {
0059         return replaceFunctionName(extended);
0060     }
0061 
0062     public String getSince() {
0063         return since;
0064     }
0065 
0066     public String getArguments() {
0067         return arguments;
0068     }
0069 
0070     @VisibleForTesting
0071     public String getOriginalExamples() {
0072         return examples;
0073     }
0074 
0075     public String getExamples() {
0076         return replaceFunctionName(examples);
0077     }
0078 
0079     public String getNote() {
0080         return note;
0081     }
0082 
0083     public String getDeprecated() {
0084         return deprecated;
0085     }
0086 
0087     public String getGroup() {
0088         return group;
0089     }
0090 
0091     public String getDb() {
0092         return db;
0093     }
0094 
0095     public ExpressionInfo(
0096             String className,
0097             String db,
0098             String name,
0099             String usage,
0100             String arguments,
0101             String examples,
0102             String note,
0103             String group,
0104             String since,
0105             String deprecated) {
0106         assert name != null;
0107         assert arguments != null;
0108         assert examples != null;
0109         assert examples.isEmpty() || examples.contains("    Examples:");
0110         assert note != null;
0111         assert group != null;
0112         assert since != null;
0113         assert deprecated != null;
0114 
0115         this.className = className;
0116         this.db = db;
0117         this.name = name;
0118         this.usage = usage;
0119         this.arguments = arguments;
0120         this.examples = examples;
0121         this.note = note;
0122         this.group = group;
0123         this.since = since;
0124         this.deprecated = deprecated;
0125 
0126         // Make the extended description.
0127         this.extended = arguments + examples;
0128         if (this.extended.isEmpty()) {
0129             this.extended = "\n    No example/argument for _FUNC_.\n";
0130         }
0131         if (!note.isEmpty()) {
0132             if (!note.contains("    ") || !note.endsWith("  ")) {
0133                 throw new IllegalArgumentException("'note' is malformed in the expression [" +
0134                     this.name + "]. It should start with a newline and 4 leading spaces; end " +
0135                     "with a newline and two spaces; however, got [" + note + "].");
0136             }
0137             this.extended += "\n    Note:\n      " + note.trim() + "\n";
0138         }
0139         if (!group.isEmpty() && !validGroups.contains(group)) {
0140             throw new IllegalArgumentException("'group' is malformed in the expression [" +
0141                 this.name + "]. It should be a value in " + validGroups + "; however, " +
0142                 "got [" + group + "].");
0143         }
0144         if (!since.isEmpty()) {
0145             if (Integer.parseInt(since.split("\\.")[0]) < 0) {
0146                 throw new IllegalArgumentException("'since' is malformed in the expression [" +
0147                     this.name + "]. It should not start with a negative number; however, " +
0148                     "got [" + since + "].");
0149             }
0150             this.extended += "\n    Since: " + since + "\n";
0151         }
0152         if (!deprecated.isEmpty()) {
0153             if (!deprecated.contains("    ") || !deprecated.endsWith("  ")) {
0154                 throw new IllegalArgumentException("'deprecated' is malformed in the " +
0155                     "expression [" + this.name + "]. It should start with a newline and 4 " +
0156                     "leading spaces; end with a newline and two spaces; however, got [" +
0157                     deprecated + "].");
0158             }
0159             this.extended += "\n    Deprecated:\n      " + deprecated.trim() + "\n";
0160         }
0161     }
0162 
0163     public ExpressionInfo(String className, String name) {
0164         this(className, null, name, null, "", "", "", "", "", "");
0165     }
0166 
0167     public ExpressionInfo(String className, String db, String name) {
0168         this(className, db, name, null, "", "", "", "", "", "");
0169     }
0170 
0171     /**
0172      * @deprecated This constructor is deprecated as of Spark 3.0. Use other constructors to fully
0173      *   specify each argument for extended usage.
0174      */
0175     @Deprecated
0176     public ExpressionInfo(String className, String db, String name, String usage, String extended) {
0177         // `arguments` and `examples` are concatenated for the extended description. So, here
0178         // simply pass the `extended` as `arguments` and an empty string for `examples`.
0179         this(className, db, name, usage, extended, "", "", "", "", "");
0180     }
0181 
0182     private String replaceFunctionName(String usage) {
0183         if (usage == null) {
0184             return "N/A.";
0185         } else {
0186             return usage.replaceAll("_FUNC_", name);
0187         }
0188     }
0189 }