001package gudusoft.gsqlparser.nodes.starrocks; 002 003import gudusoft.gsqlparser.*; 004import gudusoft.gsqlparser.nodes.*; 005import gudusoft.gsqlparser.nodes.flink.TFlinkTableProperty; 006 007/** 008 * Represents the StarRocks FILES() table function for reading data from external storage. 009 * 010 * <p>The FILES() function allows querying data files directly from cloud storage 011 * (S3, HDFS, GCS, Azure Blob, etc.) without creating external tables.</p> 012 * 013 * <p>Syntax:</p> 014 * <pre> 015 * FILES( 016 * "path" = "s3://bucket/path/*.parquet", 017 * "format" = "parquet", 018 * "aws.s3.access_key" = "xxx", 019 * "aws.s3.secret_key" = "xxx", 020 * "aws.s3.region" = "us-west-2" 021 * ) 022 * </pre> 023 * 024 * <p>Example usage:</p> 025 * <pre> 026 * SELECT * FROM FILES( 027 * "path" = "s3://bucket/data.parquet", 028 * "format" = "parquet" 029 * ); 030 * 031 * INSERT INTO my_table SELECT * FROM FILES(...); 032 * </pre> 033 * 034 * @see <a href="https://docs.starrocks.io/docs/sql-reference/sql-functions/table-functions/files/">StarRocks FILES Documentation</a> 035 */ 036public class TFilesTableFunction extends TTableFunction { 037 038 /** 039 * The list of key-value properties passed to FILES(). 040 * Common properties include: 041 * - path: The file path (S3, HDFS, local, etc.) 042 * - format: File format (parquet, orc, csv, json, avro) 043 * - aws.s3.access_key, aws.s3.secret_key, aws.s3.region: S3 credentials 044 * - columns_from_path: Extract columns from file path 045 * - list_files_only: Only list files without reading data 046 * - list_recursively: Recursively list directories 047 */ 048 private TPTNodeList<TFlinkTableProperty> properties; 049 050 /** 051 * Creates a new TFilesTableFunction. 052 */ 053 public TFilesTableFunction() { 054 this.functionType = EFunctionType.files_t; 055 } 056 057 /** 058 * Initialize with properties list. 059 * @param arg1 the properties list (TPTNodeList<TFlinkTableProperty>) 060 */ 061 @Override 062 public void init(Object arg1) { 063 if (arg1 instanceof TPTNodeList) { 064 @SuppressWarnings("unchecked") 065 TPTNodeList<TFlinkTableProperty> props = (TPTNodeList<TFlinkTableProperty>) arg1; 066 this.properties = props; 067 } 068 } 069 070 /** 071 * Initialize with function name and properties list. 072 * @param arg1 the function name (TObjectName) 073 * @param arg2 the properties list (TPTNodeList<TFlinkTableProperty>) 074 */ 075 @Override 076 public void init(Object arg1, Object arg2) { 077 if (arg1 instanceof TObjectName) { 078 this.functionName = (TObjectName) arg1; 079 } 080 if (arg2 instanceof TPTNodeList) { 081 @SuppressWarnings("unchecked") 082 TPTNodeList<TFlinkTableProperty> props = (TPTNodeList<TFlinkTableProperty>) arg2; 083 this.properties = props; 084 } 085 } 086 087 /** 088 * Gets the properties list. 089 * @return the list of key-value properties 090 */ 091 public TPTNodeList<TFlinkTableProperty> getProperties() { 092 return properties; 093 } 094 095 /** 096 * Sets the properties list. 097 * @param properties the list of key-value properties 098 */ 099 public void setProperties(TPTNodeList<TFlinkTableProperty> properties) { 100 this.properties = properties; 101 } 102 103 /** 104 * Gets a property value by key name. 105 * @param key the property key (without quotes) 106 * @return the property value (without quotes), or null if not found 107 */ 108 public String getPropertyValue(String key) { 109 if (properties == null || key == null) return null; 110 for (int i = 0; i < properties.size(); i++) { 111 TFlinkTableProperty prop = properties.getElement(i); 112 if (key.equals(prop.getKeyString())) { 113 return prop.getValueString(); 114 } 115 } 116 return null; 117 } 118 119 /** 120 * Gets the file path from the "path" property. 121 * @return the file path, or null if not specified 122 */ 123 public String getPath() { 124 return getPropertyValue("path"); 125 } 126 127 /** 128 * Gets the file format from the "format" property. 129 * @return the format (parquet, orc, csv, json, avro), or null if not specified 130 */ 131 public String getFormat() { 132 return getPropertyValue("format"); 133 } 134 135 /** 136 * Checks if this is a list-files-only operation. 137 * @return true if list_files_only is "true", false otherwise 138 */ 139 public boolean isListFilesOnly() { 140 String value = getPropertyValue("list_files_only"); 141 return "true".equalsIgnoreCase(value); 142 } 143 144 /** 145 * Checks if recursive listing is enabled. 146 * @return true if list_recursively is "true", false otherwise 147 */ 148 public boolean isListRecursively() { 149 String value = getPropertyValue("list_recursively"); 150 return "true".equalsIgnoreCase(value); 151 } 152 153 /** 154 * Gets the columns_from_path property value. 155 * @return the columns_from_path value, or null if not specified 156 */ 157 public String getColumnsFromPath() { 158 return getPropertyValue("columns_from_path"); 159 } 160 161 @Override 162 public void doParse(TCustomSqlStatement psql, ESqlClause plocation) { 163 this.dbvendor = psql.dbvendor; 164 // FILES() properties don't need special parsing - they are literal string values 165 } 166 167 @Override 168 public void accept(TParseTreeVisitor v) { 169 v.preVisit(this); 170 v.postVisit(this); 171 } 172 173 @Override 174 public void acceptChildren(TParseTreeVisitor v) { 175 v.preVisit(this); 176 if (functionName != null) { 177 functionName.acceptChildren(v); 178 } 179 if (properties != null) { 180 properties.acceptChildren(v); 181 } 182 v.postVisit(this); 183 } 184}