Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Discussion threadhttps://lists.apache.org/thread/54fyd27m8on1cf3hn6dz564zqmkobjyd
Vote threadhttps://lists.apache.org/thread/bc0qcmg73t4q7do3k657rqcdx1vyjqzy
JIRA

Jira
serverASF JIRA
serverId5aa69414-a9e9-3523-82ec-879b028fb15b
keyFLINK-31256

Release

Please keep the discussion on the mailing list rather than commenting on the wiki (wiki discussions get unwieldy fast).

...

But these features are not very complete compared with other popular engines such as spark, hive, presto and commercial engines such as snowflake.

For example, many popular engines support show operation with filtering except flink, and support describe other objectmany objects(flink only support supports describe table).

show

Support or Not

Support filter or Not

show tables

Yes

Yes

show columns

Yes

Yes

show catalogs

Yes

No

show databases

Yes

No

show functions

Yes

No

show views

Yes

No

show modules

Yes

No

show jars

Yes

No

show jobs

Yes

No

We can see current flink many sql statements only support showing with full datas, without 'FROM/IN' or 'LIKE' filter clause.

show create

Support or Not

show create database

No

show create table

Yes

show create view

Yes

show create function

No

...

describe

...

Support or Not

...

note

...

describe catalog

...

No

...

has sqlNode but not support in table api

...

describe database

...

No

...

has sqlNode but not support in table api

...

describe table

...

Yes

...

describe function

...

No

...

describe view

...

No

current flink only supports describing tables.

So we propose this flip, try to support these useful features.

Proposed Syntax Changes:

We compare flink with other popular engines and give an improved syntax example. Welcome everyone to discuss and improve the final syntax. 

Because it may be modified under discuss, we put it on the google docs. please see FLIP-297: Improve Auxiliary Sql Statements Docs

...

before

...

after(under discussed)

...

Note

...

show catalogs

...

SHOW CATALOGS

...

show databases

...

SHOW DATABASES

...

SHOW DATABASES [ ( FROM | IN ) catalog_name] [ [NOT] LIKE <sql_like_pattern> ]

...

show functions

...

SHOW [USER] FUNCTIONS

...

SHOW [USER] FUNCTIONS [ ( FROM | IN ) [catalog_name.]database_name ] [ [NOT] LIKE <sql_like_pattern> ]

And these improved features are very useful for users and developers.

Comparison with other popular engines


Because each engine has its own personalized auxiliary sql statements features, here are some common operations listed as much as possible, and compare what other unrealized abilities of flink.

We focus on standard sql, but also consider absorbing the syntax of some mature engines to let users know that this is not standard, just for better use (e.g. ILIKE).


show catalogs

Engine

Support or Not, If support show the syntax

Flink

SHOW CATALOGS

Spark

No

Hive

No

Presto

SHOW CATALOGS [ LIKE pattern ]

MySQL

No

SnowFlake

No

 

show databases

Engine

Support or Not, If support show the syntax

Flink

SHOW DATABASES

Spark

SHOW { DATABASES | SCHEMAS } [ LIKE regex_pattern ]

Hive

SHOW (DATABASES|SCHEMAS) [LIKE 'identifier_with_wildcards']

Presto

SHOW SCHEMAS [ FROM catalog ] [ LIKE pattern ]

MySQL

SHOW {DATABASES | SCHEMAS} [LIKE 'pattern' | WHERE expr]

SnowFlake

SHOW [ TERSE ] DATABASES [ HISTORY ] [ LIKE '<pattern>' ]

                                     [ STARTS WITH '<name_string>' ]

                                     [ LIMIT <rows> [ FROM '<name_string>' ] ]



show functions

Engine

Support or Not, If support show the syntax

Flink

SHOW [USER] FUNCTIONS

Spark

SHOW [ function_kind ] FUNCTIONS [ { FROM | IN } database_name ] [ LIKE regex_pattern ]

Hive

SHOW FUNCTIONS [LIKE "<pattern>"]

Presto

SHOW FUNCTIONS [ LIKE pattern [ ESCAPE 'escape_character' ] ]

MySQL

SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_TYPE = 'FUNCTION' ORDER BY ROUTINE_NAME;

SnowFlake

SHOW FUNCTIONS [ LIKE '<pattern>' ]

               [ IN

                    {

                      ACCOUNT                  |

                      DATABASE                 |

                      DATABASE <database_name> |

                      SCHEMA                   |

                      SCHEMA <schema_name>     |

                      <schema_name>

                    }

               ]


show views

Engine

Support or Not, If support show the syntax

Flink

SHOW VIEWS

Spark

SHOW VIEWS [ { FROM | IN } database_name ] [ LIKE regex_pattern ]

Hive

SHOW VIEWS [IN/FROM database_name] [LIKE 'pattern_with_wildcards']

Presto

No

MySQL

SHOW FULL TABLES [FROM db_name] [LIKE 'pattern' | WHERE expr] (Alternative syntax)

SnowFlake

SHOW [ TERSE ] VIEWS [ LIKE '<pattern>' ]

                     [ IN { ACCOUNT | DATABASE [ <db_name> ] | [ SCHEMA ] [ <schema_name> ] } ]

                     [ STARTS WITH '<name_string>' ]

                     [ LIMIT <rows> [ FROM '<name_string>' ] ]


show modules

Engine

Support or Not, If support show the syntax

Flink

SHOW [FULL] MODULES

Spark

No

Hive

No

Presto

No

MySQL

No

SnowFlake

No


show jars

Engine

Support or Not, If support show the syntax

Note

Flink

SHOW JARS

only work in SQL CLI or SQL Gateway.

Spark

No


Hive

No


Presto

No


MySQL

No


SnowFlake

No




show jobs

Engine

Support or Not, If support show the syntax

Note

Flink

SHOW JOBS

only work in SQL CLI or SQL Gateway.

Spark

No


Hive

No


Presto

No


MySQL

No


SnowFlake

No




show create database

Engine

Support or Not, If support show the syntax

Note

Flink

No


Spark

No


Hive

No


Presto

No


MySQL

SHOW CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name

RDBMS, such as Oracle, MariaDB, TiDB also support it.

SnowFlake

No




show create function

Engine

Support or Not, If support show the syntaxes

Note

Flink

No


Spark

No


Hive

No


Presto

SHOW CREATE FUNCTION function_name [ ( parameter_type[, ...] ) ]


MySQL

SHOW CREATE FUNCTION func_name

RDBMS, such as Oracle, MariaDB, TiDB also support it.

SnowFlake

No



describe catalog

Engine

Support or Not, If support show the syntaxes

Note

Flink

No

with catalog-database-table three layer

Spark

No

with database-table layer. schema and database they mean the same thing.

But databricks on aws support it:
{ DESC | DESCRIBE } CATALOG [ EXTENDED ] catalog_name

Hive

No

with database-table layer. schema and database they mean the same thing

Presto

No

Presto is schema-database-table three layer. schema and database are not equal.

MySQL

No

with database-table layer. schema and database they mean the same thing.

SnowFlake

DESC[RIBE] DATABASE <database_name>

SnowFlake is database-schema-table three layer.

database may act as catalog.


describe database

Engine

Support or Not, If support show the syntaxes

Note

Flink

{ DESC | DESCRIBE } DATABASE [ EXTENDED ] db_name

just sqlNode, but not expose to table & sql api

Spark

{ DESC | DESCRIBE } DATABASE [ EXTENDED ] db_name


Hive

DESCRIBE DATABASE [EXTENDED] db_name;

DESCRIBE SCHEMA [EXTENDED] db_name;


Presto

No


MySQL

No


SnowFlake

DESC[RIBE] SCHEMA <schema_name>



describe function

Engine

Support or Not, If support show the syntaxes

Note

Flink

No


Spark

{ DESC | DESCRIBE } FUNCTION [ EXTENDED ] function_name


Hive

DESCRIBEFUNCTION [EXTENDED] <function_name>


Presto

No


MySQL

No


SnowFlake

DESC[RIBE] FUNCTION <name> ( [ <arg_data_type> ] [ , ... ] )



describe view

Engine

Support or Not, If support show the syntaxes

Note

Flink

No


Spark

No


Hive

DESCRIBE [EXTENDED|FORMATTED] <view_name>;


Presto

No


MySQL

No


SnowFlake

DESC[RIBE] VIEW <name>



We can see many popular engines have filtering with show statements, support 'FROM/IN' or 'LIKE/ILIKE' filter clause except flink.
And currently flink only supports describing tables.
And also some unique statements such as show jars/show modules in flink can also support this feature.

So we proposed this FLIP.

Proposed Syntax Changes:

Note: we both support LIKE and ILIKE in this FLIP.

LIKE: sql_like_pattern, case sensitive

ILIKE: sql_like_pattern, same behavior as LIKE except case insensitive

And For consistency, we will add ILIKE support for query either.

Because calcite already support parse ILIKE and exist SqlLikeOperator(SqlLibraryOperators.ILIKE, not std operator). We just need to support it in table & sql api (no need to modify sql keywords and Parser.jj).



before

after(under discussed)

Note

show catalogs

SHOW CATALOGS

SHOW CATALOGS[ [NOT] (LIKE | ILIKE) <sql_like_pattern> ]


show databases

SHOW DATABASES

SHOW DATABASES [ ( FROM | IN ) catalog_name] [ [NOT] (LIKE | ILIKE) <sql_like_pattern> ]


show tables

SHOW TABLES [ ( FROM | IN ) [catalog_name.]database_name ] [ [NOT] LIKE <sql_like_pattern> ]

SHOW TABLES [ ( FROM | IN ) [catalog_name.]database_name ] [ [NOT] (LIKE | ILIKE) <sql_like_pattern> ]

show columns

SHOW COLUMNS ( FROM | IN ) [[catalog_name.]database.]<table_name> [ [NOT] LIKE <sql_like_pattern>]

SHOW COLUMNS ( FROM | IN ) [[catalog_name.]database.]<table_name> [ [NOT] (LIKE | ILIKE) <sql_like_pattern>]

show functions

SHOW [USER] FUNCTIONS

SHOW [USER] FUNCTIONS [ ( FROM | IN ) [catalog_name.]database_name ] [ [NOT] (LIKE | ILIKE) <sql_like_pattern> ]


show views

SHOW VIEWS

SHOW VIEWS [ ( FROM | IN ) [catalog_name.]database_name ] [ [NOT] (LIKE | ILIKE) <sql_like_pattern> ]


show modules

SHOW [FULL] MODULES

SHOW [FULL] MODULES [ [NOT] (LIKE | ILIKE) <sql_like_pattern> ]


show jars

SHOW JARS

SHOW JARS [ [NOT] (LIKE | ILIKE) <sql_like_pattern> ]

only work in SQL CLI or SQL Gateway.

show jobs

SHOW JOBS

SHOW JOBS [ [NOT] (LIKE | ILIKE) <sql_like_pattern> ]

only work in SQL CLI or SQL Gateway.

describe catalog

Not Support

{ DESCRIBE | DESC } CATALOG [ EXTENDED ] catalog_name

If the optional EXTENDED option is specified, it returns the basic metadata information along with the properties


describe database

Not Support

{ DESCRIBE | DESC } DATABASE [ EXTENDED ] [catalog_name.]database_name

If the optional EXTENDED option is specified, it returns the basic metadata information along with the properties like spark and hive. 


describe function

Not Support

{ DESCRIBE | DESC } FUNCTION [ EXTENDED ] [[catalog_name.]database_name.]function_name

If the optional EXTENDED option is specified, the basic metadata information is returned along with the extended information.


...





Proposed CataLog API Changes:

No need to add new apis (there is a discussion about api changes, pls see the discuss thread). 

We can use such as TableEnvironment.getCatalog(catalogName).get().listDatabases(), TableEnvironment.getCatalog(catalogName).get().listFunctions(databaseName) for util to get result.

In TableEnvironmentImpl we do filter for returned full results.


Some SqlNodes and Operations could be added or changed.

Code Block
languagejava
titleOperations
linenumberstrue
// Add SqlDescribeCatalog & DescribeCatalogOperation
// Add SqlDescribeDatabase & DescribeDatabaseOperation
// Add SqlDescribeFunction & DescribeFunctionOperation

About DescribeCatalog:

+-------------------------+-----------------------------+

| catalog_description_item|   catalog_description_value |
+-------------------------+-----------------------------+
|            Catalog Name |                       xxx   |
|               Properties| (key1=val1, key2=val2, ...) |
+-------------------------+-----------------------------+


About DescribeDatabase:

+-------------------------+-----------------------------+
|database_description_item|   database_description_value|
+-------------------------+-----------------------------+
|            Database Name|                    employees|
|              Description|       For software companies|
|               Properties| (key1=val1, key2=val2, ...) |
+-------------------------+-----------------------------+

About DescribeFunction:

+-------------------------+-----------------------------+
|function_description_item|   function_description_value|
+-------------------------+-----------------------------+
|        Function Name    |                    ABS      |
|        Function Language|                    JAVA     |
|        Resource Uri     |                  file://xxx |
|        Details          |                details      |
+-------------------------+-----------------------------+

The concrete describe infos we can get from the specific catalog object.  

// Changed SqlNodes & Operations

// SqlShowCatalogs 
public class SqlShowCatalogs extends SqlCall {

    public static final SqlSpecialOperator OPERATOR =
            new SqlSpecialOperator("SHOW CATALOGS", SqlKind.OTHER);

    protected final SqlLikeType likeType;
    protected final boolean notLike;
    protected final SqlCharStringLiteral likeLiteral;

    public SqlShowCatalogs(SqlParserPos pos) {
        super(pos);
        this.likeType = null;
        this.notLike = false;
        this.likeLiteral = null;
    }

    public SqlShowCatalogs(
            SqlParserPos pos, String likeType, boolean notLike, SqlCharStringLiteral likeLiteral) {
        super(pos);
        if (likeType != null) {
            this.likeType = SqlLikeType.of(likeType);
            this.likeLiteral = requireNonNull(likeLiteral, "Like pattern must not be null");
        } else {
            this.likeType = null;
            this.likeLiteral = null;
        }
        this.notLike = notLike;
    }

    public SqlLikeType getLikeType() {
        return likeType;
    }

    public boolean isLike() {
        return likeType == SqlLikeType.LIKE;
    }

    public boolean isILike() {
        return likeType == SqlLikeType.ILIKE;
    }

    public boolean isWithLike() {
        return isLike() || isILike();
    }

    public boolean isNotLike() {
        return notLike;
    }

    public String getLikeSqlPattern() {
        return Objects.isNull(likeLiteral) ? null : likeLiteral.getValueAs(String.class);
    }

    @Override
    public SqlOperator getOperator() {
        return OPERATOR;
    }

    @Override
    public List<SqlNode> getOperandList() {
        return Collections.emptyList();
    }

    @Override
    public void unparse(SqlWriter writer, int leftPrec, int rightPrec) {
        writer.keyword("SHOW CATALOGS");
        if (isWithLike()) {
            if (isNotLike()) {
                writer.keyword(String.format("NOT %s '%s'", likeType.name(), getLikeSqlPattern()));
            } else {
                writer.keyword(String.format("%s '%s'", likeType.name(), getLikeSqlPattern()));
            }
        }
    }
}

// ShowCatalogsOperation
public class ShowCatalogsOperation implements ShowOperation {

    private final OperationLikeType likeType;
    private final boolean notLike;
    private final String likePattern;

    /** Use when there is no sub-clause. */
    public ShowCatalogsOperation() {
        this.likeType = null;
        this.notLike = false;
        this.likePattern = null;
    }

    /** Use when there is like. */
    public ShowCatalogsOperation(String likeType, boolean notLike, String likePattern) {
        this.likeType = OperationLikeType.of(checkNotNull(likeType, "Like type must not be null"));
        this.likePattern = checkNotNull(likePattern, "Like pattern must not be null");
        this.notLike = notLike;
    }

    public boolean isLike() {
        return likeType == OperationLikeType.LIKE;
    }

    public boolean isIlike() {
        return likeType == OperationLikeType.ILIKE;
    }

    public boolean isWithLike() {
        return isLike() || isIlike();
    }

    public boolean isNotLike() {
        return notLike;
    }

    public String getLikePattern() {
        return likePattern;
    }

    @Override
    public String asSummaryString() {
        StringBuilder builder = new StringBuilder().append("SHOW CATALOGS");
        if (isWithLike()) {
            if (notLike) {
                builder.append(String.format(" NOT %s %s", likeType.name(), likePattern));
            } else {
                builder.append(String.format(" %s %s", likeType.name(), likePattern));
            }
        }
        return builder.toString();
    }
}

// SqlShowDatabases
public class SqlShowDatabases extends SqlCall {

    public static final SqlSpecialOperator OPERATOR =
            new SqlSpecialOperator("SHOW DATABASES", SqlKind.OTHER);

    protected final String preposition;
    protected final SqlIdentifier catalogName;
    protected final SqlLikeType likeType;
    protected final boolean notLike;
    protected final SqlCharStringLiteral likeLiteral;

    public SqlShowDatabases(SqlParserPos pos) {
        super(pos);
        this.preposition = null;
        this.catalogName = null;
        this.likeType = null;
        this.notLike = false;
        this.likeLiteral = null;
    }

    public SqlShowDatabases(
            SqlParserPos pos,
            String preposition,
            SqlIdentifier catalogName,
            String likeType,
            boolean notLike,
            SqlCharStringLiteral likeLiteral) {
        super(pos);
        this.preposition = preposition;
        this.catalogName =
                preposition != null
                        ? requireNonNull(catalogName, "Catalog name must not be null.")
                        : null;
        if (likeType != null) {
            this.likeType = SqlLikeType.of(likeType);
            this.likeLiteral = requireNonNull(likeLiteral, "Like pattern must not be null");
        } else {
            this.likeType = null;
            this.likeLiteral = null;
        }
        this.notLike = notLike;
    }

    public String getPreposition() {
        return preposition;
    }

    public SqlIdentifier getCatalogName() {
        return catalogName;
    }

    public String catalogName() {
        return catalogName != null ? catalogName.getSimple() : null;
    }

    public SqlLikeType getLikeType() {
        return likeType;
    }

    public boolean isLike() {
        return likeType == SqlLikeType.LIKE;
    }

    public boolean isILike() {
        return likeType == SqlLikeType.ILIKE;
    }

    public boolean isNotLike() {
        return notLike;
    }

    public boolean isWithLike() {
        return isLike() || isILike();
    }

    public SqlCharStringLiteral getLikeLiteral() {
        return likeLiteral;
    }

    public String getLikeSqlPattern() {
        return Objects.isNull(likeLiteral) ? null : likeLiteral.getValueAs(String.class);
    }

    @Override
    public SqlOperator getOperator() {
        return OPERATOR;
    }

    @Override
    public List<SqlNode> getOperandList() {
        return Objects.isNull(this.catalogName)
                ? Collections.emptyList()
                : Collections.singletonList(catalogName);
    }

    @Override
    public void unparse(SqlWriter writer, int leftPrec, int rightPrec) {
        if (this.preposition == null) {
            writer.keyword("SHOW DATABASES");
        } else if (catalogName != null) {
            writer.keyword("SHOW DATABASES " + this.preposition);
            catalogName.unparse(writer, leftPrec, rightPrec);
        }
        if (isWithLike()) {

...

show views

...

SHOW VIEWS

...

SHOW VIEWS [ ( FROM | IN ) [catalog_name.]database_name ] [ [NOT] LIKE <sql_like_pattern> ]

...

show modules

...

SHOW [FULL] MODULES

...

SHOW [FULL] MODULES [ [NOT] LIKE <sql_like_pattern> ]

...

show jars

...

SHOW JARS

...

SHOW JARS [ [NOT] LIKE <sql_like_pattern> ]

...

only work in SQL CLI or SQL Gateway.

...

show jobs

...

SHOW JOBS

...

SHOW JOBS [ [NOT] LIKE <sql_like_pattern> ]

...

only work in SQL CLI or SQL Gateway.

...

describe catalog

...

Not Support

...

{ DESCRIBE | DESC } CATALOG catalog_name

...

describe database

...

Not Support

...

{ DESCRIBE | DESC } DATABASE [ EXTENDED ] db_name

...

describe function

...

Not Support

...

{ DESCRIBE | DESC } FUNCTION [ EXTENDED ] function_name

...

...

Proposed CataLog API Changes:

No need to add new apis. 

We can use such as TableEnvironment.getCatalog(catalogName).get().listDatabases(), TableEnvironment.getCatalog(catalogName).get().listFunctions(databaseName) for util to get result.

In TableEnvironmentImpl we do filter for returned full results.

Some Operations could be added or changed.

Code Block
languagejava
titleOperations
linenumberstrue
// Add DescribeCatalogOperation -> Catalog
// Add DescribeDatabaseOperation -> CatalogDataBase
// Add DescribeFunctionOperation -> CatalogFunction

// Changed Operations(offer filtering support)

// ShowCatalogsOperation
public class ShowCatalogsOperation implements ShowOperation {
	
	// enable like
    private final boolean useLike;
    // true for not like, false is like
    private final boolean notLike;
    // like or not like pattern (sql-like-pattern, consistent with current flink behavior)
    private final String likePattern;

    public ShowCatalogsOperation(boolean useLike, boolean notLike, String likePattern) {
        this.useLike = useLike;
        this.notLike = notLike;
        this.likePattern = likePattern;
    }
}

// ShowDatabasesOperation
public class ShowDatabasesOperation implements ShowOperation {

    private final String catalogName;
    private final boolean useLike;
    private final boolean notLike;
    private final String likePattern;
    // in or from to indicate specific catalog or database
    private final String preposition;

    public ShowDatabasesOperation(
            String catalogName,
            boolean useLike,if (isNotLike()) {
            boolean notLike,
   writer.keyword(String.format("NOT %s '%s'",       String likePattern,likeType.name(), getLikeSqlPattern()));
            String} preposition)else {
        this.catalogName = catalogName;
      writer.keyword(String.format("%s '%s'", this.useLike = useLike;
   likeType.name(), getLikeSqlPattern()));
     this.notLike = notLike;
        this.likePattern = likePattern;}
        this.preposition = preposition;}
    }
}

// ShowFunctionsOperationShowDatabasesOperation
public class ShowFunctionsOperationShowDatabasesOperation implements ShowOperation {

    private final String catalogNamepreposition;
    private final String databaseNamecatalogName;
    private final booleanOperationLikeType useLikelikeType;
    private final boolean notLike;
    private final String likePattern;
    private final String preposition;
    private final FunctionScope functionScope;

    /**
 Use when there is * Represent scope of function.
     *no sub-clause. */
    public ShowDatabasesOperation() {
     * <ul>
    this.preposition *= null;
  <li><b>USER</b> return only user-defined functions
  this.catalogName = null;
 *   <li><b>ALL</b> return all user-defined and built-in functions this.likeType = null;
     * </ul>
  this.notLike =  */false;
    public enum FunctionScope {
  this.likePattern = null;
    USER,}

    /** Use when there ALL
is only like.  }*/

    public ShowFunctionsOperation(
    ShowDatabasesOperation(String likeType, boolean notLike, String likePattern) {
        String catalogName,this.preposition = null;
        this.catalogName = null;
  String databaseName,
     this.likeType = OperationLikeType.of(checkNotNull(likeType, "Like type must not boolean useLike,be null"));
        this.likePattern = checkNotNull(likePattern, "Like booleanpattern notLike,
must not be null");
        this.notLike String= likePattern,notLike;
    }

    /** Use when there Stringis preposition,. */
    public   ShowDatabasesOperation(
     FunctionScope functionScope) {
     String preposition,
  this.catalogName = catalogName;
        this.databaseName = databaseName;String catalogName,
        this.useLike = useLike;
  String likeType,
     this.notLike = notLike;
     boolean notLike,
  this.likePattern = likePattern;
        this.preposition = preposition;String likePattern) {
        this.functionScopepreposition = functionScope;
    }

checkNotNull(preposition, "Preposition must not be null");
    public FunctionScope getFunctionScope() {
 this.catalogName = checkNotNull(catalogName, "Catalog name must not returnbe functionScopenull");
    }
}

// ShowViewsOperation
public class ShowViewsOperation implements ShowOperation {
    if (likeType != null) {
    private final String catalogName;
    private finalthis.likeType String databaseName= OperationLikeType.of(likeType);
    private final boolean useLike;
    private finalthis.likePattern boolean notLike;
    private final String likePattern= checkNotNull(likePattern, "Like pattern must not be null");
    private final String preposition;

 } else {
 public ShowViewsOperation(
          this.likeType  String catalogName,= null;
            String databaseName,
    this.likePattern = null;
        boolean useLike,}
        this.notLike = notLike;
  boolean  notLike,}

    public String getPreposition() {
     String likePattern,
  return preposition;
    }

    public String prepositiongetCatalogName() {
        this.catalogName =return catalogName;
    }

    this.databaseName = databaseName;
public boolean isLike() {
        return this.useLikelikeType == useLikeOperationLikeType.LIKE;
    }

    public this.notLike = notLike;
boolean isIlike() {
        return this.likePatternlikeType == likePatternOperationLikeType.ILIKE;
    }

    this.preposition = preposition;
public boolean isWithLike() {
     }
}

// ShowModulesOperation
public class ShowModulesOperationreturn implements ShowOperation {

    private final boolean requireFull;isLike() || isIlike();
    }

    privatepublic finalboolean boolean useLike;isNotLike() {
    private   final booleanreturn notLike;
    private final String likePattern;}

    public String ShowModulesOperationgetLikePattern() {
        return likePattern;
    }

   boolean requireFull,@Override
 boolean useLike, boolean notLike,public String likePatternasSummaryString() {
        this.requireFull = requireFull;
    StringBuilder builder = new this.useLike = useLike;
StringBuilder().append("SHOW DATABASES");
        if this.notLike(preposition != null) notLike;{
        this.likePattern = likePattern;
  builder.append(String.format("  }

    public boolean requireFull() {%s %s", preposition, catalogName));
        return requireFull;}
    }
}

// ShowJarsOperation
public class ShowJarsOperation implements ShowOperationif (isWithLike()) {

    private final boolean useLike;
    private finalif boolean notLike;(notLike) {
    private final String likePattern;

    public ShowJarsOperation(boolean useLike, boolean notLike, String likePattern) {
        this.useLike = useLikebuilder.append(String.format(" NOT %s %s", likeType.name(), likePattern));
        this.notLike = notLike;
  } else {
    this.likePattern = likePattern;
    }
}

// ShowJobsOperation
public class ShowJobsOperation implements ShowOperation {

    private final boolean useLikebuilder.append(String.format(" %s %s", likeType.name(), likePattern));
    private final boolean notLike;
    private final String likePattern;

 }
    public ShowJobsOperation(boolean useLike, boolean notLike,}
 String likePattern) {
     return builder.toString();
  this.useLike = useLike;
        this.notLike = notLike;
        this.likePattern = likePattern;
    }
}

Future Work

 }
}

// omit here. basically same as ShowCatalogs/ShowDatabases above.
// SqlShowFunctions & ShowFunctionsOperation
// SqlShowViews & ShowViewsOperation
// SqlShowModules & ShowModulesOperation
// SqlShowJars & ShowJarsOperation
// SqlShowJobs & ShowJobsOperation

Future Work

TBD.to be added

Compatibility, Deprecation, and Migration Plan

No compatibility and migrationmigration. We will ensure changes of this FLIP will be compatible with current flink behavior.

Test Plan

Add new cases to cover these features.

...