001package gudusoft.gsqlparser.sqlcmds; 002 003import gudusoft.gsqlparser.*; 004import gudusoft.gsqlparser.stmt.TUnknownSqlStatement; 005 006/** 007 * Impala SQL command resolver. 008 * 009 * <p>Impala historically shared {@link TSqlCmdsHive}; this subclass keeps the 010 * Hive command table but adds the Impala-only statements (COMPUTE STATS, 011 * DROP STATS, INVALIDATE METADATA, REFRESH, SHUTDOWN) so the statement 012 * splitter recognizes them instead of flagging the whole statement invalid. 013 * Statements without a dedicated grammar rule are routed through 014 * {@link TUnknownSqlStatement} carrying their specific statement type. 015 */ 016public class TSqlCmdsImpala extends TSqlCmdsHive { 017 018 public TSqlCmdsImpala() { 019 super(EDbVendor.dbvimpala); 020 } 021 022 @Override 023 protected void initializeCommands() { 024 super.initializeCommands(); 025 026 // Impala-specific commands. COMPUTE, INVALIDATE, REFRESH and SHUTDOWN 027 // lead words carry no raw token constant on the Hive/Impala lexer 028 // path, so they are string-matched in issql() below. 029 addCmd(TBaseType.rrw_truncate, "if", "exists", ESqlStatementType.sstTruncate); 030 addCmd(TBaseType.rrw_truncate, ESqlStatementType.sstTruncate); 031 addCmd(TBaseType.rrw_drop, "incremental", "stats", ESqlStatementType.sstimpaladropstats); 032 addCmd(TBaseType.rrw_drop, "stats", ESqlStatementType.sstimpaladropstats); 033 } 034 035 @Override 036 public TCustomSqlStatement issql(TSourceToken token, EFindSqlStateType state, TCustomSqlStatement currentStatement) { 037 // COMPUTE [INCREMENTAL] STATS and INVALIDATE METADATA: their lead 038 // words carry no stable raw token constant, so match by text (same 039 // approach as the RELOAD/LIST/REPL handling in TSqlCmdsHive). The 040 // second solid word is verified to avoid claiming identifiers. 041 if (state == EFindSqlStateType.stnormal && token.issolidtoken()) { 042 String tokenStr = token.toString(); 043 // non-identifier-compare: raw keyword text, not a DB object name 044 if (tokenStr.equalsIgnoreCase("COMPUTE")) { 045 TSourceToken next = token.nextSolidToken(); 046 if (next != null && (next.toString().equalsIgnoreCase("STATS") 047 || next.toString().equalsIgnoreCase("INCREMENTAL"))) { // non-identifier-compare: keyword text 048 TCustomSqlStatement ret = new TUnknownSqlStatement(this.vendor); 049 ret.sqlstatementtype = ESqlStatementType.sstimpalacomputestats; 050 return ret; 051 } 052 } else if (tokenStr.equalsIgnoreCase("INVALIDATE")) { // non-identifier-compare: keyword text 053 TSourceToken next = token.nextSolidToken(); 054 if (next != null && next.toString().equalsIgnoreCase("METADATA")) { // non-identifier-compare: keyword text 055 TCustomSqlStatement ret = new TUnknownSqlStatement(this.vendor); 056 ret.sqlstatementtype = ESqlStatementType.sstimpalainvalidatemetadata; 057 return ret; 058 } 059 } else if (tokenStr.equalsIgnoreCase("REFRESH")) { // non-identifier-compare: keyword text 060 // REFRESH table [PARTITION (...)], REFRESH AUTHORIZATION, 061 // REFRESH FUNCTIONS db. A statement can never start with a 062 // bare identifier, so claiming the lead word is safe. 063 TCustomSqlStatement ret = new TUnknownSqlStatement(this.vendor); 064 ret.sqlstatementtype = ESqlStatementType.sstimpalarefresh; 065 return ret; 066 } else if (tokenStr.equalsIgnoreCase("SHUTDOWN")) { // non-identifier-compare: keyword text 067 TCustomSqlStatement ret = new TUnknownSqlStatement(this.vendor); 068 ret.sqlstatementtype = ESqlStatementType.sstimpalashutdown; 069 return ret; 070 } 071 } 072 073 return super.issql(token, state, currentStatement); 074 } 075}