2017-07-05 1 views
-1

Je veux ajouter un udf à calcite. Le paramètre udf est un nom de table, et il retournera une valeur varchar. Y a-t-il un échantillon pour cela? Merci.Comment ajouter un udf qui est le paramètre est un nom de table

Mon sql test est:

SELECT MYTEST22(a), MYTEST(a), MYTEST1(a), COUNT(*) 
FROM alisis.table1 
WHERE a=max_dt(alisis.table1) 
GROUP BY MYTEST22(a),MYTEST(a),MYTEST1(a) 

max_dt est la fonction que je veux ajouter.

+0

S'il vous plaît [modifier] votre question pour montrer [le code que vous avez jusqu'à présent] (http://whathaveyoutried.com). Vous devez inclure au moins un aperçu (mais de préférence un [mcve]) du code que vous rencontrez des problèmes, puis nous pouvons essayer d'aider avec le problème spécifique. Vous devriez aussi lire [ask]. –

Répondre

1

Je ne sais pas ce que votre envie de faire, pourriez-vous faire une explication claire?

Aucune fonction ne peut accepter table comme paramètre, les paramètres doivent être certain type, String, Int ou autres. Alors constants et columns peuvent être utilisés comme paramètres. Si votre sens est le nom de la table en tant que paramètre, SQL doit être comme suit:

SELECT MYTEST22(a), MYTEST(a), MYTEST1(a), COUNT(*) 
FROM alisis.table1 
WHERE a=max_dt('alisis.table1') 
GROUP BY MYTEST22(a),MYTEST(a),MYTEST1(a) 

Comme je l'ai connu, toutes les fonctions Calcite (version 1.11) pris en charge sont définis à SqlStdOperatorTable. Si vous souhaitez prendre en charge d'autres fonctions, vous pouvez mettre en œuvre une classe qui étend SqlStdOperatorTable, par exemple:

public class TestOperatorTable extends SqlStdOperatorTable { 
    private static volatile TestOperatorTable instance; 
    public static TestOperatorTable instance() { 
    if (instance == null) { 
     synchronized(TestOperatorTable.class) { 
     if (instance == null) { 
      instance = new TestOperatorTable(); 
      // Use reflection to register the expressions stored in public fields. 
      instance.init(); 
     } 
     } 
    } 
    return instance; 
    } 

    /** Follow add your functions */ 
    public static SqlFunction LTRIM = new SqlTrimFunction("LTRIM"); 
} 

SqlTrimFunction comme suit:

public class SqlTrimFunction extends SqlFunction { 
    public SqlTrimFunction(String funcName) { 
    super(
     funcName, 
     SqlKind.OTHER_FUNCTION, 
     ReturnTypes.VARCHAR_2000, // return type is String 
     InferTypes.FIRST_KNOWN, 
     OperandTypes.STRING,  // parameter type is String 
     SqlFunctionCategory.STRING 
    ); 
    } 
} 

Lorsque vous créez un SqlValidator, par exemple SqlValidatorImpl, vous devriez utilisez TestOperatorTable comme premier paramètre.

+0

Oui, la fonction que je veux prendre en charge a le nom de la table en tant que paramètre. Mon test sql a une erreur de syntaxe. Je vais essayer de mettre en œuvre la classe. Merci beaucoup! –

+0

@ fei.chen, vous pouvez accepter cette réponse. – inferno

+0

@ fei.chen https://stackoverflow.com/a/44962144/1314077 cela peut être utile d'ajouter UDF, ne se prolongent pas SqlStdOperatorTable. – inferno