001package gudusoft.gsqlparser.stmt.oceanbase; 002 003import gudusoft.gsqlparser.EDbVendor; 004import gudusoft.gsqlparser.ESqlStatementType; 005import gudusoft.gsqlparser.TCustomSqlStatement; 006import gudusoft.gsqlparser.TSourceToken; 007import gudusoft.gsqlparser.nodes.TObjectName; 008import gudusoft.gsqlparser.nodes.TParseTreeNode; 009import gudusoft.gsqlparser.nodes.TParseTreeVisitor; 010import gudusoft.gsqlparser.nodes.oceanbase.TOceanbaseCreateOutlineSqlNode; 011 012/** 013 * OceanBase {@code CREATE OUTLINE} statement (Phase 4 Batch 8). 014 * 015 * <p>An OceanBase outline binds a stored execution plan to a SQL 016 * pattern. Downstream tooling can distinguish the two documented forms: 017 * <ul> 018 * <li>{@link #getBoundStatement()} returns the parsed inner statement 019 * (typically a {@code TSelectSqlNode} tree) when the outline is 020 * defined against a SQL pattern inline</li> 021 * <li>{@link #getSqlId()} returns the SQL ID string when the outline 022 * is defined against an existing entry in the plan cache</li> 023 * </ul> 024 * Exactly one of the two is non-null for a valid outline. 025 * 026 * <p>The optional {@code USING HINT /*+ ... */} clause is exposed via 027 * {@link #getUsingHintToken()} as the raw comment token. 028 * 029 * <p>Tagged {@link ESqlStatementType#sstoraclecreateoutline} (reused 030 * per ADR-8 — Oracle already has this enum for the identically-shaped 031 * statement). 032 * 033 * @since 4.0.1.4 034 */ 035public class TCreateOutlineSqlStatement extends TCustomSqlStatement { 036 037 private TObjectName outlineName; 038 private TParseTreeNode boundStatement; 039 private TObjectName sqlId; 040 private TSourceToken usingHintToken; 041 private boolean orReplace; 042 043 public TCreateOutlineSqlStatement(EDbVendor dbvendor) { 044 super(dbvendor); 045 this.sqlstatementtype = ESqlStatementType.sstoraclecreateoutline; 046 } 047 048 public TObjectName getOutlineName() { 049 return outlineName; 050 } 051 052 public TParseTreeNode getBoundStatement() { 053 return boundStatement; 054 } 055 056 public TObjectName getSqlId() { 057 return sqlId; 058 } 059 060 public TSourceToken getUsingHintToken() { 061 return usingHintToken; 062 } 063 064 public boolean isOrReplace() { 065 return orReplace; 066 } 067 068 /** 069 * @return the raw text of the {@code USING HINT} comment (including 070 * the surrounding {@code /*+ ... */}), or {@code null} when 071 * not specified. 072 */ 073 public String getUsingHintText() { 074 return usingHintToken == null ? null : usingHintToken.toString(); 075 } 076 077 @Override 078 public int doParseStatement(TCustomSqlStatement psql) { 079 if (rootNode == null) return -1; 080 super.doParseStatement(psql); 081 TOceanbaseCreateOutlineSqlNode node = 082 (TOceanbaseCreateOutlineSqlNode) rootNode; 083 this.outlineName = node.getOutlineName(); 084 this.boundStatement = node.getBoundStatement(); 085 this.sqlId = node.getSqlId(); 086 this.usingHintToken = node.getUsingHintToken(); 087 this.orReplace = node.isOrReplace(); 088 return 0; 089 } 090 091 @Override 092 public void accept(TParseTreeVisitor v) { 093 v.preVisit(this); 094 v.postVisit(this); 095 } 096 097 @Override 098 public void acceptChildren(TParseTreeVisitor v) { 099 v.preVisit(this); 100 v.postVisit(this); 101 } 102}