From b700d9bc535deb3e41d28e94bb62b8fca0e43d2e Mon Sep 17 00:00:00 2001 From: Raghav Aggarwal Date: Wed, 13 May 2026 21:13:32 +0530 Subject: [PATCH 1/2] HIVE-29610: Add support for SQL wildcards (% and _) in SHOW COLUMNS aligning with other SHOW commands --- .../column/show/ShowColumnsOperation.java | 6 +- .../apache/hadoop/hive/ql/udf/UDFLike.java | 2 + .../show_columns_inconsistency.q | 21 +++++ .../llap/show_columns_inconsistency.q.out | 93 +++++++++++++++++++ 4 files changed, 119 insertions(+), 3 deletions(-) create mode 100644 ql/src/test/queries/clientpositive/show_columns_inconsistency.q create mode 100644 ql/src/test/results/clientpositive/llap/show_columns_inconsistency.q.out diff --git a/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/column/show/ShowColumnsOperation.java b/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/column/show/ShowColumnsOperation.java index 289479b7ee79..cd40dc919668 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/column/show/ShowColumnsOperation.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/ddl/table/column/show/ShowColumnsOperation.java @@ -36,6 +36,7 @@ import org.apache.hadoop.hive.ql.metadata.HiveException; import org.apache.hadoop.hive.ql.metadata.Table; import org.apache.hadoop.hive.ql.session.SessionState; +import org.apache.hadoop.hive.ql.udf.UDFLike; /** * Operation process of showing the columns. @@ -77,10 +78,9 @@ private Matcher getMatcher() { if (columnPattern == null) { columnPattern = "*"; } - columnPattern = columnPattern.toLowerCase(); - columnPattern = columnPattern.replaceAll("\\*", ".*"); - Pattern pattern = Pattern.compile(columnPattern); + String regex = UDFLike.likePatternToRegExp(columnPattern, false, true); + Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); return pattern.matcher(""); } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFLike.java b/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFLike.java index b455e91b452e..a6917e580ea4 100755 --- a/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFLike.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFLike.java @@ -85,6 +85,8 @@ public static String likePatternToRegExp(String likePattern, boolean literalize, sb.append("."); } else if (n == '%') { sb.append(greedyMatch ? ".*" : ".*?"); + } else if (n == '*' && !literalize) { + sb.append(greedyMatch ? ".*" : ".*?"); } else { sb.append(literalize ? Pattern.quote(Character.toString(n)) : n); } diff --git a/ql/src/test/queries/clientpositive/show_columns_inconsistency.q b/ql/src/test/queries/clientpositive/show_columns_inconsistency.q new file mode 100644 index 000000000000..7973587a6da2 --- /dev/null +++ b/ql/src/test/queries/clientpositive/show_columns_inconsistency.q @@ -0,0 +1,21 @@ +CREATE DATABASE IF NOT EXISTS col_test_db; +USE col_test_db; + +CREATE TABLE wildcard_table ( + id_primary INT, + id_secondary INT, + name_first STRING, + name_last STRING +); + + +SHOW TABLES LIKE 'wild%'; +SHOW TABLES LIKE 'wild*'; +SHOW TABLES LIKE 'none|wildcard_table'; + +SHOW COLUMNS FROM wildcard_table LIKE 'id%'; +SHOW COLUMNS FROM wildcard_table LIKE 'name_%'; +SHOW COLUMNS FROM wildcard_table LIKE 'id*'; +SHOW COLUMNS FROM wildcard_table LIKE 'id_primary|name_first'; + +DROP DATABASE col_test_db CASCADE; diff --git a/ql/src/test/results/clientpositive/llap/show_columns_inconsistency.q.out b/ql/src/test/results/clientpositive/llap/show_columns_inconsistency.q.out new file mode 100644 index 000000000000..ea103d5d5887 --- /dev/null +++ b/ql/src/test/results/clientpositive/llap/show_columns_inconsistency.q.out @@ -0,0 +1,93 @@ +PREHOOK: query: CREATE DATABASE IF NOT EXISTS col_test_db +PREHOOK: type: CREATEDATABASE +PREHOOK: Output: database:col_test_db +POSTHOOK: query: CREATE DATABASE IF NOT EXISTS col_test_db +POSTHOOK: type: CREATEDATABASE +POSTHOOK: Output: database:col_test_db +PREHOOK: query: USE col_test_db +PREHOOK: type: SWITCHDATABASE +PREHOOK: Input: database:col_test_db +POSTHOOK: query: USE col_test_db +POSTHOOK: type: SWITCHDATABASE +POSTHOOK: Input: database:col_test_db +PREHOOK: query: CREATE TABLE wildcard_table ( + id_primary INT, + id_secondary INT, + name_first STRING, + name_last STRING +) +PREHOOK: type: CREATETABLE +PREHOOK: Output: col_test_db@wildcard_table +PREHOOK: Output: database:col_test_db +POSTHOOK: query: CREATE TABLE wildcard_table ( + id_primary INT, + id_secondary INT, + name_first STRING, + name_last STRING +) +POSTHOOK: type: CREATETABLE +POSTHOOK: Output: col_test_db@wildcard_table +POSTHOOK: Output: database:col_test_db +PREHOOK: query: SHOW TABLES LIKE 'wild%' +PREHOOK: type: SHOWTABLES +PREHOOK: Input: database:col_test_db +POSTHOOK: query: SHOW TABLES LIKE 'wild%' +POSTHOOK: type: SHOWTABLES +POSTHOOK: Input: database:col_test_db +wildcard_table +PREHOOK: query: SHOW TABLES LIKE 'wild*' +PREHOOK: type: SHOWTABLES +PREHOOK: Input: database:col_test_db +POSTHOOK: query: SHOW TABLES LIKE 'wild*' +POSTHOOK: type: SHOWTABLES +POSTHOOK: Input: database:col_test_db +wildcard_table +PREHOOK: query: SHOW TABLES LIKE 'none|wildcard_table' +PREHOOK: type: SHOWTABLES +PREHOOK: Input: database:col_test_db +POSTHOOK: query: SHOW TABLES LIKE 'none|wildcard_table' +POSTHOOK: type: SHOWTABLES +POSTHOOK: Input: database:col_test_db +wildcard_table +PREHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'id%' +PREHOOK: type: SHOWCOLUMNS +PREHOOK: Input: col_test_db@wildcard_table +POSTHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'id%' +POSTHOOK: type: SHOWCOLUMNS +POSTHOOK: Input: col_test_db@wildcard_table +id_primary +id_secondary +PREHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'name_%' +PREHOOK: type: SHOWCOLUMNS +PREHOOK: Input: col_test_db@wildcard_table +POSTHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'name_%' +POSTHOOK: type: SHOWCOLUMNS +POSTHOOK: Input: col_test_db@wildcard_table +name_first +name_last +PREHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'id*' +PREHOOK: type: SHOWCOLUMNS +PREHOOK: Input: col_test_db@wildcard_table +POSTHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'id*' +POSTHOOK: type: SHOWCOLUMNS +POSTHOOK: Input: col_test_db@wildcard_table +id_primary +id_secondary +PREHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'id_primary|name_first' +PREHOOK: type: SHOWCOLUMNS +PREHOOK: Input: col_test_db@wildcard_table +POSTHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'id_primary|name_first' +POSTHOOK: type: SHOWCOLUMNS +POSTHOOK: Input: col_test_db@wildcard_table +id_primary +name_first +PREHOOK: query: DROP DATABASE col_test_db CASCADE +PREHOOK: type: DROPDATABASE +PREHOOK: Input: database:col_test_db +PREHOOK: Output: col_test_db@wildcard_table +PREHOOK: Output: database:col_test_db +POSTHOOK: query: DROP DATABASE col_test_db CASCADE +POSTHOOK: type: DROPDATABASE +POSTHOOK: Input: database:col_test_db +POSTHOOK: Output: col_test_db@wildcard_table +POSTHOOK: Output: database:col_test_db From 8dc62615fd297a095b1f27635585f246bcf14a51 Mon Sep 17 00:00:00 2001 From: Raghav Aggarwal Date: Wed, 20 May 2026 11:41:36 +0530 Subject: [PATCH 2/2] Addressing review comments --- .../apache/hadoop/hive/ql/udf/UDFLike.java | 5 +- .../show_columns_inconsistency.q | 21 ------ .../clientpositive/show_columns_like.q | 27 ++++++++ ...sistency.q.out => show_columns_like.q.out} | 69 ++++++++++++------- 4 files changed, 75 insertions(+), 47 deletions(-) delete mode 100644 ql/src/test/queries/clientpositive/show_columns_inconsistency.q create mode 100644 ql/src/test/queries/clientpositive/show_columns_like.q rename ql/src/test/results/clientpositive/llap/{show_columns_inconsistency.q.out => show_columns_like.q.out} (57%) diff --git a/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFLike.java b/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFLike.java index a6917e580ea4..12becaa8e7cb 100755 --- a/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFLike.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/udf/UDFLike.java @@ -83,9 +83,8 @@ public static String likePatternToRegExp(String likePattern, boolean literalize, if (n == '_') { sb.append("."); - } else if (n == '%') { - sb.append(greedyMatch ? ".*" : ".*?"); - } else if (n == '*' && !literalize) { + } else if (n == '%' || (n == '*' && !literalize)) { + // Both % and * (when not literalized) are treated as standard regex .* sb.append(greedyMatch ? ".*" : ".*?"); } else { sb.append(literalize ? Pattern.quote(Character.toString(n)) : n); diff --git a/ql/src/test/queries/clientpositive/show_columns_inconsistency.q b/ql/src/test/queries/clientpositive/show_columns_inconsistency.q deleted file mode 100644 index 7973587a6da2..000000000000 --- a/ql/src/test/queries/clientpositive/show_columns_inconsistency.q +++ /dev/null @@ -1,21 +0,0 @@ -CREATE DATABASE IF NOT EXISTS col_test_db; -USE col_test_db; - -CREATE TABLE wildcard_table ( - id_primary INT, - id_secondary INT, - name_first STRING, - name_last STRING -); - - -SHOW TABLES LIKE 'wild%'; -SHOW TABLES LIKE 'wild*'; -SHOW TABLES LIKE 'none|wildcard_table'; - -SHOW COLUMNS FROM wildcard_table LIKE 'id%'; -SHOW COLUMNS FROM wildcard_table LIKE 'name_%'; -SHOW COLUMNS FROM wildcard_table LIKE 'id*'; -SHOW COLUMNS FROM wildcard_table LIKE 'id_primary|name_first'; - -DROP DATABASE col_test_db CASCADE; diff --git a/ql/src/test/queries/clientpositive/show_columns_like.q b/ql/src/test/queries/clientpositive/show_columns_like.q new file mode 100644 index 000000000000..3fba48083327 --- /dev/null +++ b/ql/src/test/queries/clientpositive/show_columns_like.q @@ -0,0 +1,27 @@ +CREATE DATABASE IF NOT EXISTS col_test_db; +USE col_test_db; + +CREATE TABLE wildcard_table ( + id_primary INT, + id_secondary INT, + name_first STRING, + name_last STRING, + MixedCaseColumn INT, + another_Mixed_Col STRING +); + +SHOW COLUMNS FROM wildcard_table LIKE 'id%'; +SHOW COLUMNS FROM wildcard_table LIKE 'name_%'; +-- Case Insensitivity test +SHOW COLUMNS FROM wildcard_table LIKE 'mixedcase%'; +SHOW COLUMNS FROM wildcard_table LIKE 'another_mixed_col'; +SHOW COLUMNS FROM wildcard_table LIKE 'id*'; +SHOW COLUMNS FROM wildcard_table LIKE 'id_primary|name_first'; + +-- Additional tests for '_' and empty results +SHOW COLUMNS FROM wildcard_table LIKE 'id_secondar_'; +SHOW COLUMNS FROM wildcard_table LIKE 'id__rimary'; +SHOW COLUMNS FROM wildcard_table LIKE 'abc%'; +SHOW COLUMNS FROM wildcard_table LIKE 'id__'; + +DROP DATABASE col_test_db CASCADE; diff --git a/ql/src/test/results/clientpositive/llap/show_columns_inconsistency.q.out b/ql/src/test/results/clientpositive/llap/show_columns_like.q.out similarity index 57% rename from ql/src/test/results/clientpositive/llap/show_columns_inconsistency.q.out rename to ql/src/test/results/clientpositive/llap/show_columns_like.q.out index ea103d5d5887..269d3cb4e350 100644 --- a/ql/src/test/results/clientpositive/llap/show_columns_inconsistency.q.out +++ b/ql/src/test/results/clientpositive/llap/show_columns_like.q.out @@ -14,7 +14,9 @@ PREHOOK: query: CREATE TABLE wildcard_table ( id_primary INT, id_secondary INT, name_first STRING, - name_last STRING + name_last STRING, + MixedCaseColumn INT, + another_Mixed_Col STRING ) PREHOOK: type: CREATETABLE PREHOOK: Output: col_test_db@wildcard_table @@ -23,32 +25,13 @@ POSTHOOK: query: CREATE TABLE wildcard_table ( id_primary INT, id_secondary INT, name_first STRING, - name_last STRING + name_last STRING, + MixedCaseColumn INT, + another_Mixed_Col STRING ) POSTHOOK: type: CREATETABLE POSTHOOK: Output: col_test_db@wildcard_table POSTHOOK: Output: database:col_test_db -PREHOOK: query: SHOW TABLES LIKE 'wild%' -PREHOOK: type: SHOWTABLES -PREHOOK: Input: database:col_test_db -POSTHOOK: query: SHOW TABLES LIKE 'wild%' -POSTHOOK: type: SHOWTABLES -POSTHOOK: Input: database:col_test_db -wildcard_table -PREHOOK: query: SHOW TABLES LIKE 'wild*' -PREHOOK: type: SHOWTABLES -PREHOOK: Input: database:col_test_db -POSTHOOK: query: SHOW TABLES LIKE 'wild*' -POSTHOOK: type: SHOWTABLES -POSTHOOK: Input: database:col_test_db -wildcard_table -PREHOOK: query: SHOW TABLES LIKE 'none|wildcard_table' -PREHOOK: type: SHOWTABLES -PREHOOK: Input: database:col_test_db -POSTHOOK: query: SHOW TABLES LIKE 'none|wildcard_table' -POSTHOOK: type: SHOWTABLES -POSTHOOK: Input: database:col_test_db -wildcard_table PREHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'id%' PREHOOK: type: SHOWCOLUMNS PREHOOK: Input: col_test_db@wildcard_table @@ -65,6 +48,20 @@ POSTHOOK: type: SHOWCOLUMNS POSTHOOK: Input: col_test_db@wildcard_table name_first name_last +PREHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'mixedcase%' +PREHOOK: type: SHOWCOLUMNS +PREHOOK: Input: col_test_db@wildcard_table +POSTHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'mixedcase%' +POSTHOOK: type: SHOWCOLUMNS +POSTHOOK: Input: col_test_db@wildcard_table +mixedcasecolumn +PREHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'another_mixed_col' +PREHOOK: type: SHOWCOLUMNS +PREHOOK: Input: col_test_db@wildcard_table +POSTHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'another_mixed_col' +POSTHOOK: type: SHOWCOLUMNS +POSTHOOK: Input: col_test_db@wildcard_table +another_mixed_col PREHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'id*' PREHOOK: type: SHOWCOLUMNS PREHOOK: Input: col_test_db@wildcard_table @@ -81,6 +78,32 @@ POSTHOOK: type: SHOWCOLUMNS POSTHOOK: Input: col_test_db@wildcard_table id_primary name_first +PREHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'id_secondar_' +PREHOOK: type: SHOWCOLUMNS +PREHOOK: Input: col_test_db@wildcard_table +POSTHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'id_secondar_' +POSTHOOK: type: SHOWCOLUMNS +POSTHOOK: Input: col_test_db@wildcard_table +id_secondary +PREHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'id__rimary' +PREHOOK: type: SHOWCOLUMNS +PREHOOK: Input: col_test_db@wildcard_table +POSTHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'id__rimary' +POSTHOOK: type: SHOWCOLUMNS +POSTHOOK: Input: col_test_db@wildcard_table +id_primary +PREHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'abc%' +PREHOOK: type: SHOWCOLUMNS +PREHOOK: Input: col_test_db@wildcard_table +POSTHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'abc%' +POSTHOOK: type: SHOWCOLUMNS +POSTHOOK: Input: col_test_db@wildcard_table +PREHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'id__' +PREHOOK: type: SHOWCOLUMNS +PREHOOK: Input: col_test_db@wildcard_table +POSTHOOK: query: SHOW COLUMNS FROM wildcard_table LIKE 'id__' +POSTHOOK: type: SHOWCOLUMNS +POSTHOOK: Input: col_test_db@wildcard_table PREHOOK: query: DROP DATABASE col_test_db CASCADE PREHOOK: type: DROPDATABASE PREHOOK: Input: database:col_test_db