SQL parser component for Apache Flink that provides Hive dialect support for parsing Hive-specific DDL and DML statements
—
Table operations provide comprehensive table management including creation with Hive-specific features, alteration, and column management.
Create Hive tables with comprehensive support for partitioning, storage formats, and table properties.
/**
* CREATE TABLE statement for Hive dialect with full Hive table features
* Supports partitioning, external tables, storage formats, and row formats
*/
public class SqlCreateHiveTable extends SqlCreateTable {
/**
* Creates a new Hive table creation statement
* @param pos Parser position information
* @param tableName Name of the table to create
* @param columnList List of table columns
* @param creationContext Context containing constraints and metadata
* @param propertyList Table properties (TBLPROPERTIES)
* @param partColList Partition columns
* @param comment Table comment
* @param isTemporary Whether table is temporary
* @param isExternal Whether table is external
* @param rowFormat Row format specification (SERDE or DELIMITED)
* @param storedAs Storage format specification
* @param location Table location URI
* @param ifNotExists Whether to use IF NOT EXISTS clause
* @throws ParseException if validation fails
*/
public SqlCreateHiveTable(SqlParserPos pos, SqlIdentifier tableName, SqlNodeList columnList,
HiveTableCreationContext creationContext, SqlNodeList propertyList,
SqlNodeList partColList, SqlCharStringLiteral comment, boolean isTemporary,
boolean isExternal, HiveTableRowFormat rowFormat,
HiveTableStoredAs storedAs, SqlCharStringLiteral location,
boolean ifNotExists) throws ParseException;
}Constants:
public static final String IDENTIFIER = "hive";
public static final String TABLE_LOCATION_URI = "hive.location-uri";
public static final String TABLE_IS_EXTERNAL = "hive.is-external";
public static final String PK_CONSTRAINT_TRAIT = "hive.pk.constraint.trait";
public static final String NOT_NULL_CONSTRAINT_TRAITS = "hive.not.null.constraint.traits";
public static final String NOT_NULL_COLS = "hive.not.null.cols";Context class for managing table constraints and metadata during creation.
/**
* Context for Hive table creation containing constraint information
*/
public static class HiveTableCreationContext extends TableCreationContext {
/** Primary key constraint trait */
public SqlHiveConstraintTrait pkTrait = null;
/** List of NOT NULL constraint traits */
public List<SqlHiveConstraintTrait> notNullTraits = null;
/** List of NOT NULL column identifiers */
public List<SqlIdentifier> notNullCols = null;
}Specification for Hive table row format including SERDE and delimited formats.
/**
* ROW FORMAT specification for Hive tables
* Supports both SERDE-based and delimited field formats
*/
public static class HiveTableRowFormat {
/**
* Creates delimited row format specification
* @param pos Parser position
* @param fieldsTerminator Field delimiter character
* @param escape Escape character
* @param collectionTerminator Collection item delimiter
* @param mapKeyTerminator Map key-value delimiter
* @param linesTerminator Line terminator character
* @param nullAs NULL value representation
* @return HiveTableRowFormat instance
* @throws ParseException if validation fails
*/
public static HiveTableRowFormat withDelimited(SqlParserPos pos,
SqlCharStringLiteral fieldsTerminator,
SqlCharStringLiteral escape,
SqlCharStringLiteral collectionTerminator,
SqlCharStringLiteral mapKeyTerminator,
SqlCharStringLiteral linesTerminator,
SqlCharStringLiteral nullAs) throws ParseException;
/**
* Creates SERDE-based row format specification
* @param pos Parser position
* @param serdeClass SerDe class name
* @param serdeProps SerDe properties
* @return HiveTableRowFormat instance
* @throws ParseException if validation fails
*/
public static HiveTableRowFormat withSerDe(SqlParserPos pos, SqlCharStringLiteral serdeClass,
SqlNodeList serdeProps) throws ParseException;
/**
* Converts row format to property list representation
* @return SqlNodeList containing row format properties
*/
public SqlNodeList toPropList();
}Constants:
public static final String SERDE_LIB_CLASS_NAME = "hive.serde.lib.class.name";
public static final String SERDE_INFO_PROP_PREFIX = "hive.serde.info.prop.";
public static final String FIELD_DELIM = SERDE_INFO_PROP_PREFIX + "field.delim";
public static final String COLLECTION_DELIM = SERDE_INFO_PROP_PREFIX + "collection.delim";
public static final String ESCAPE_CHAR = SERDE_INFO_PROP_PREFIX + "escape.delim";
public static final String MAPKEY_DELIM = SERDE_INFO_PROP_PREFIX + "mapkey.delim";
public static final String LINE_DELIM = SERDE_INFO_PROP_PREFIX + "line.delim";
public static final String SERIALIZATION_NULL_FORMAT = SERDE_INFO_PROP_PREFIX + "serialization.null.format";Specification for Hive table storage format including file formats and input/output formats.
/**
* STORED AS specification for Hive tables
* Supports file format and input/output format specifications
*/
public static class HiveTableStoredAs {
/**
* Creates storage format from file format
* @param pos Parser position
* @param fileFormat File format identifier (PARQUET, ORC, TEXTFILE, etc.)
* @return HiveTableStoredAs instance
* @throws ParseException if validation fails
*/
public static HiveTableStoredAs ofFileFormat(SqlParserPos pos, SqlIdentifier fileFormat) throws ParseException;
/**
* Creates storage format from input/output format classes
* @param pos Parser position
* @param inputFormat Input format class name
* @param outputFormat Output format class name
* @return HiveTableStoredAs instance
* @throws ParseException if validation fails
*/
public static HiveTableStoredAs ofInputOutputFormat(SqlParserPos pos,
SqlCharStringLiteral inputFormat,
SqlCharStringLiteral outputFormat) throws ParseException;
/**
* Converts storage format to property list representation
* @return SqlNodeList containing storage format properties
*/
public SqlNodeList toPropList();
}Constants:
public static final String STORED_AS_FILE_FORMAT = "hive.storage.file-format";
public static final String STORED_AS_INPUT_FORMAT = "hive.stored.as.input.format";
public static final String STORED_AS_OUTPUT_FORMAT = "hive.stored.as.output.format";Abstract base class for all table alteration operations.
/**
* Base class for ALTER TABLE operations
* Provides common functionality for all table alterations
*/
public abstract class SqlAlterHiveTable extends SqlAlterTable {
/**
* Creates base table alteration statement
* @param op Type of alteration operation
* @param pos Parser position information
* @param tableName Name of table to alter
* @param partSpec Partition specification (if applicable)
* @param propertyList Properties associated with the alteration
*/
public SqlAlterHiveTable(AlterTableOp op, SqlParserPos pos, SqlIdentifier tableName,
SqlNodeList partSpec, SqlNodeList propertyList);
/**
* Types of table alteration operations supported
*/
public enum AlterTableOp {
CHANGE_TBL_PROPS, // Change table properties
CHANGE_SERDE_PROPS, // Change SerDe properties
CHANGE_FILE_FORMAT, // Change file format
CHANGE_LOCATION, // Change table location
ALTER_COLUMNS // Alter table columns
}
}Constants:
public static final String ALTER_TABLE_OP = "alter.table.op";
public static final String ALTER_COL_CASCADE = "alter.column.cascade";Change table properties (TBLPROPERTIES) of an existing table.
/**
* ALTER TABLE SET TBLPROPERTIES statement
* Changes the properties of an existing table
*/
public class SqlAlterHiveTableProps extends SqlAlterHiveTable {
/**
* Creates table properties alteration statement
* @param pos Parser position information
* @param tableName Name of table to alter
* @param propertyList New properties to set
* @throws ParseException if properties validation fails
*/
public SqlAlterHiveTableProps(SqlParserPos pos, SqlIdentifier tableName,
SqlNodeList propertyList) throws ParseException;
}Change the location of an existing table or partition.
/**
* ALTER TABLE SET LOCATION statement
* Changes the location URI of an existing table or partition
*/
public class SqlAlterHiveTableLocation extends SqlAlterHiveTable {
/**
* Creates table location alteration statement
* @param pos Parser position information
* @param tableName Name of table to alter
* @param partitionSpec Partition specification (null for entire table)
* @param location New location URI
*/
public SqlAlterHiveTableLocation(SqlParserPos pos, SqlIdentifier tableName,
SqlNodeList partitionSpec, SqlCharStringLiteral location);
}Change the file format of an existing table or partition.
/**
* ALTER TABLE SET FILEFORMAT statement
* Changes the file format of an existing table or partition
*/
public class SqlAlterHiveTableFileFormat extends SqlAlterHiveTable {
/**
* Creates table file format alteration statement
* @param pos Parser position information
* @param tableName Name of table to alter
* @param partSpec Partition specification (null for entire table)
* @param format New file format
*/
public SqlAlterHiveTableFileFormat(SqlParserPos pos, SqlIdentifier tableName,
SqlNodeList partSpec, SqlIdentifier format);
}Change the SerDe (Serializer/Deserializer) of an existing table or partition.
/**
* ALTER TABLE SET SERDE statement
* Changes the SerDe class and properties of an existing table or partition
*/
public class SqlAlterHiveTableSerDe extends SqlAlterHiveTable {
/**
* Creates table SerDe alteration statement
* @param pos Parser position information
* @param tableName Name of table to alter
* @param partitionSpec Partition specification (null for entire table)
* @param propertyList SerDe properties
* @param serdeLib SerDe library class name
* @throws ParseException if validation fails
*/
public SqlAlterHiveTableSerDe(SqlParserPos pos, SqlIdentifier tableName,
SqlNodeList partitionSpec, SqlNodeList propertyList,
SqlCharStringLiteral serdeLib) throws ParseException;
}Add, replace, or change table columns.
/**
* ALTER TABLE ADD/REPLACE COLUMNS statement
* Adds new columns or replaces existing columns
*/
public class SqlAlterHiveTableAddReplaceColumn extends SqlAlterHiveTable {
/**
* Creates add/replace columns statement
* @param pos Parser position information
* @param tableName Name of table to alter
* @param cascade Whether to cascade to partitions
* @param columns List of columns to add/replace
* @param replace True for REPLACE COLUMNS, false for ADD COLUMNS
* @throws ParseException if validation fails
*/
public SqlAlterHiveTableAddReplaceColumn(SqlParserPos pos, SqlIdentifier tableName,
boolean cascade, SqlNodeList columns,
boolean replace) throws ParseException;
}
/**
* ALTER TABLE CHANGE COLUMN statement
* Changes an existing column definition
*/
public class SqlAlterHiveTableChangeColumn extends SqlAlterHiveTable {
/**
* Creates change column statement
* @param pos Parser position information
* @param tableName Name of table to alter
* @param cascade Whether to cascade to partitions
* @param oldName Current column name
* @param newColumn New column definition
* @param first Whether to place column first
* @param after Column to place new column after
* @throws ParseException if validation fails
*/
public SqlAlterHiveTableChangeColumn(SqlParserPos pos, SqlIdentifier tableName,
boolean cascade, SqlIdentifier oldName,
SqlRegularColumn newColumn, boolean first,
SqlIdentifier after) throws ParseException;
}// Create partitioned external table with custom storage
String createTableSql = """
CREATE EXTERNAL TABLE IF NOT EXISTS sales_data (
id BIGINT COMMENT 'Unique transaction ID',
customer_id STRING COMMENT 'Customer identifier',
product_name STRING COMMENT 'Product name',
amount DECIMAL(10,2) COMMENT 'Transaction amount',
transaction_date DATE COMMENT 'Date of transaction'
)
COMMENT 'Sales transaction data'
PARTITIONED BY (
year INT COMMENT 'Year of transaction',
month INT COMMENT 'Month of transaction'
)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\\t'
COLLECTION ITEMS TERMINATED BY ','
MAP KEYS TERMINATED BY ':'
LINES TERMINATED BY '\\n'
NULL DEFINED AS '\\\\N'
STORED AS PARQUET
LOCATION '/data/sales'
TBLPROPERTIES (
'parquet.compression' = 'SNAPPY',
'transactional' = 'true',
'owner' = 'data_team'
)
""";// Create table with custom SerDe
String customSerdeTableSql = """
CREATE TABLE json_data (
id BIGINT,
data STRING,
metadata MAP<STRING, STRING>
)
ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'
WITH SERDEPROPERTIES (
'serialization.format' = '1',
'ignore.malformed.json' = 'true'
)
STORED AS TEXTFILE
""";// Change table properties
String alterPropsSql = """
ALTER TABLE sales_data SET TBLPROPERTIES (
'last_modified' = '2023-12-01',
'retention_days' = '1095',
'backup_enabled' = 'true'
)
""";
// Change table location
String alterLocationSql = "ALTER TABLE sales_data SET LOCATION '/data/sales_v2'";
// Change partition location
String alterPartLocationSql = """
ALTER TABLE sales_data PARTITION (year=2023, month=12)
SET LOCATION '/data/sales/2023/12'
""";
// Add columns
String addColumnsSql = """
ALTER TABLE sales_data ADD COLUMNS (
discount_rate DECIMAL(5,4) COMMENT 'Applied discount rate',
payment_method STRING COMMENT 'Payment method used'
) CASCADE
""";
// Change column
String changeColumnSql = """
ALTER TABLE sales_data CHANGE COLUMN amount
total_amount DECIMAL(12,2) COMMENT 'Total transaction amount'
AFTER customer_id CASCADE
""";// Build table creation programmatically
SqlIdentifier tableName = new SqlIdentifier("analytics_data", SqlParserPos.ZERO);
// Define columns
SqlNodeList columns = new SqlNodeList(SqlParserPos.ZERO);
columns.add(new SqlRegularColumn(
SqlParserPos.ZERO,
new SqlIdentifier("id", SqlParserPos.ZERO),
new SqlDataTypeSpec(new SqlBasicTypeNameSpec(SqlTypeName.BIGINT, SqlParserPos.ZERO), SqlParserPos.ZERO),
null, // no default
null // no constraint
));
// Define partition columns
SqlNodeList partColumns = new SqlNodeList(SqlParserPos.ZERO);
partColumns.add(new SqlRegularColumn(
SqlParserPos.ZERO,
new SqlIdentifier("date_partition", SqlParserPos.ZERO),
new SqlDataTypeSpec(new SqlBasicTypeNameSpec(SqlTypeName.DATE, SqlParserPos.ZERO), SqlParserPos.ZERO),
null,
null
));
// Define storage format
HiveTableStoredAs storedAs = HiveTableStoredAs.ofFileFormat(
SqlParserPos.ZERO,
new SqlIdentifier("PARQUET", SqlParserPos.ZERO)
);
// Define row format
HiveTableRowFormat rowFormat = HiveTableRowFormat.withDelimited(
SqlParserPos.ZERO,
SqlLiteral.createCharString(",", SqlParserPos.ZERO), // field delimiter
SqlLiteral.createCharString("\\", SqlParserPos.ZERO), // escape char
SqlLiteral.createCharString("|", SqlParserPos.ZERO), // collection delimiter
SqlLiteral.createCharString(":", SqlParserPos.ZERO), // map key delimiter
SqlLiteral.createCharString("\\n", SqlParserPos.ZERO), // line delimiter
SqlLiteral.createCharString("NULL", SqlParserPos.ZERO) // null format
);
// Create table
SqlCreateHiveTable createTable = new SqlCreateHiveTable(
SqlParserPos.ZERO,
tableName,
columns,
new HiveTableCreationContext(),
new SqlNodeList(SqlParserPos.ZERO), // properties
partColumns,
SqlLiteral.createCharString("Analytics data table", SqlParserPos.ZERO),
false, // not temporary
true, // external table
rowFormat,
storedAs,
SqlLiteral.createCharString("/data/analytics", SqlParserPos.ZERO),
true // IF NOT EXISTS
);Describe Hive tables to get detailed metadata information.
/**
* DESCRIBE statement for Hive tables with extended and formatted options
* Provides detailed metadata about table structure, partitions, and properties
*/
public class SqlDescribeHiveTable extends SqlRichDescribeTable {
/**
* Creates a describe table statement
* @param pos Parser position information
* @param tableNameIdentifier Name of table to describe
* @param extended Whether to use EXTENDED keyword for detailed metadata
* @param formatted Whether to use FORMATTED keyword for formatted output
*/
public SqlDescribeHiveTable(SqlParserPos pos, SqlIdentifier tableNameIdentifier,
boolean extended, boolean formatted);
public boolean isExtended();
public boolean isFormatted();
}Usage Examples:
// Basic table description
String basicDescribeSql = "DESCRIBE sales_data";
// Extended description with detailed metadata
String extendedDescribeSql = "DESCRIBE EXTENDED sales_data";
// Formatted description with structured output
String formattedDescribeSql = "DESCRIBE FORMATTED sales_data";
// Programmatic table description
SqlIdentifier tableName = new SqlIdentifier("customer_profile", SqlParserPos.ZERO);
// Basic describe
SqlDescribeHiveTable basicDescribe = new SqlDescribeHiveTable(
SqlParserPos.ZERO,
tableName,
false, // not extended
false // not formatted
);
// Extended describe for detailed metadata
SqlDescribeHiveTable extendedDescribe = new SqlDescribeHiveTable(
SqlParserPos.ZERO,
tableName,
true, // extended
false // not formatted
);
// Formatted describe for structured output
SqlDescribeHiveTable formattedDescribe = new SqlDescribeHiveTable(
SqlParserPos.ZERO,
tableName,
false, // not extended
true // formatted
);
// Check describe options
if (extendedDescribe.isExtended()) {
System.out.println("Will show extended metadata");
}
if (formattedDescribe.isFormatted()) {
System.out.println("Will show formatted output");
}Describe Output Types:
Integration with Table Analysis:
public class HiveTableAnalyzer {
private SqlParser parser;
private TableEnvironment tableEnv;
public HiveTableAnalyzer(TableEnvironment tableEnv) {
this.tableEnv = tableEnv;
this.parser = SqlParser.create("",
SqlParser.config().withParserFactory(FlinkHiveSqlParserImpl.FACTORY));
}
/**
* Get comprehensive table information
*/
public void analyzeTable(String tableName) {
try {
// Get basic structure
String basicDescribe = "DESCRIBE " + tableName;
TableResult basicResult = tableEnv.executeSql(basicDescribe);
System.out.println("=== Table Structure ===");
basicResult.print();
// Get detailed metadata
String extendedDescribe = "DESCRIBE EXTENDED " + tableName;
TableResult extendedResult = tableEnv.executeSql(extendedDescribe);
System.out.println("=== Extended Metadata ===");
extendedResult.print();
// Get formatted output
String formattedDescribe = "DESCRIBE FORMATTED " + tableName;
TableResult formattedResult = tableEnv.executeSql(formattedDescribe);
System.out.println("=== Formatted Output ===");
formattedResult.print();
} catch (Exception e) {
System.err.println("Failed to analyze table " + tableName + ": " + e.getMessage());
}
}
/**
* Analyze partitioned table
*/
public void analyzePartitionedTable(String tableName) {
analyzeTable(tableName);
try {
// Also show partition information
String showPartitions = "SHOW PARTITIONS " + tableName;
TableResult partitionResult = tableEnv.executeSql(showPartitions);
System.out.println("=== Partition Information ===");
partitionResult.print();
} catch (Exception e) {
System.err.println("Failed to get partition info for " + tableName + ": " + e.getMessage());
}
}
}
// Usage
HiveTableAnalyzer analyzer = new HiveTableAnalyzer(tableEnv);
// Analyze basic table
analyzer.analyzeTable("customer_profile");
// Analyze partitioned table with full details
analyzer.analyzePartitionedTable("sales_data");Install with Tessl CLI
npx tessl i tessl/maven-org-apache-flink--flink-sql-parser-hive