@@ -1096,6 +1096,119 @@ pub enum Expression {
10961096}
10971097
10981098impl Expression {
1099+ /// Returns `true` if this expression is a valid top-level SQL statement.
1100+ ///
1101+ /// Bare expressions like identifiers, literals, and function calls are not
1102+ /// valid statements. This is used by `validate()` to reject inputs like
1103+ /// `SELECT scooby dooby doo` which the parser splits into `SELECT scooby AS dooby`
1104+ /// plus the bare identifier `doo`.
1105+ pub fn is_statement ( & self ) -> bool {
1106+ match self {
1107+ // Queries
1108+ Expression :: Select ( _)
1109+ | Expression :: Union ( _)
1110+ | Expression :: Intersect ( _)
1111+ | Expression :: Except ( _)
1112+ | Expression :: Subquery ( _)
1113+ | Expression :: Values ( _)
1114+ | Expression :: PipeOperator ( _)
1115+
1116+ // DML
1117+ | Expression :: Insert ( _)
1118+ | Expression :: Update ( _)
1119+ | Expression :: Delete ( _)
1120+ | Expression :: Copy ( _)
1121+ | Expression :: Put ( _)
1122+ | Expression :: Merge ( _)
1123+
1124+ // DDL
1125+ | Expression :: CreateTable ( _)
1126+ | Expression :: DropTable ( _)
1127+ | Expression :: AlterTable ( _)
1128+ | Expression :: CreateIndex ( _)
1129+ | Expression :: DropIndex ( _)
1130+ | Expression :: CreateView ( _)
1131+ | Expression :: DropView ( _)
1132+ | Expression :: AlterView ( _)
1133+ | Expression :: AlterIndex ( _)
1134+ | Expression :: Truncate ( _)
1135+ | Expression :: TruncateTable ( _)
1136+ | Expression :: CreateSchema ( _)
1137+ | Expression :: DropSchema ( _)
1138+ | Expression :: DropNamespace ( _)
1139+ | Expression :: CreateDatabase ( _)
1140+ | Expression :: DropDatabase ( _)
1141+ | Expression :: CreateFunction ( _)
1142+ | Expression :: DropFunction ( _)
1143+ | Expression :: CreateProcedure ( _)
1144+ | Expression :: DropProcedure ( _)
1145+ | Expression :: CreateSequence ( _)
1146+ | Expression :: DropSequence ( _)
1147+ | Expression :: AlterSequence ( _)
1148+ | Expression :: CreateTrigger ( _)
1149+ | Expression :: DropTrigger ( _)
1150+ | Expression :: CreateType ( _)
1151+ | Expression :: DropType ( _)
1152+ | Expression :: Comment ( _)
1153+
1154+ // Session/Transaction/Control
1155+ | Expression :: Use ( _)
1156+ | Expression :: Set ( _)
1157+ | Expression :: SetStatement ( _)
1158+ | Expression :: Transaction ( _)
1159+ | Expression :: Commit ( _)
1160+ | Expression :: Rollback ( _)
1161+ | Expression :: Grant ( _)
1162+ | Expression :: Revoke ( _)
1163+ | Expression :: Cache ( _)
1164+ | Expression :: Uncache ( _)
1165+ | Expression :: LoadData ( _)
1166+ | Expression :: Pragma ( _)
1167+ | Expression :: Describe ( _)
1168+ | Expression :: Show ( _)
1169+ | Expression :: Kill ( _)
1170+ | Expression :: Execute ( _)
1171+ | Expression :: Declare ( _)
1172+ | Expression :: Refresh ( _)
1173+ | Expression :: AlterSession ( _)
1174+ | Expression :: LockingStatement ( _)
1175+
1176+ // Analyze
1177+ | Expression :: Analyze ( _)
1178+ | Expression :: AnalyzeStatistics ( _)
1179+ | Expression :: AnalyzeHistogram ( _)
1180+ | Expression :: AnalyzeSample ( _)
1181+ | Expression :: AnalyzeListChainedRows ( _)
1182+ | Expression :: AnalyzeDelete ( _)
1183+
1184+ // Attach/Detach/Install/Summarize
1185+ | Expression :: Attach ( _)
1186+ | Expression :: Detach ( _)
1187+ | Expression :: Install ( _)
1188+ | Expression :: Summarize ( _)
1189+
1190+ // Pivot at statement level
1191+ | Expression :: Pivot ( _)
1192+ | Expression :: Unpivot ( _)
1193+
1194+ // Command (raw/unparsed statements)
1195+ | Expression :: Command ( _)
1196+ | Expression :: Raw ( _)
1197+
1198+ // Return statement
1199+ | Expression :: ReturnStmt ( _) => true ,
1200+
1201+ // Annotated wraps another expression with comments — check inner
1202+ Expression :: Annotated ( a) => a. this . is_statement ( ) ,
1203+
1204+ // Alias at top level can wrap a statement (e.g., parenthesized subquery with alias)
1205+ Expression :: Alias ( a) => a. this . is_statement ( ) ,
1206+
1207+ // Everything else (identifiers, literals, operators, functions, etc.)
1208+ _ => false ,
1209+ }
1210+ }
1211+
10991212 /// Create a literal number expression from an integer.
11001213 pub fn number ( n : i64 ) -> Self {
11011214 Expression :: Literal ( Literal :: Number ( n. to_string ( ) ) )
@@ -3602,6 +3715,9 @@ pub enum DataType {
36023715 // fields: Vec of (field_name, field_type, not_null)
36033716 Object { fields : Vec < ( String , DataType , bool ) > , modifier : Option < String > } ,
36043717
3718+ // Nullable wrapper (ClickHouse): Nullable(String), Nullable(Int32)
3719+ Nullable { inner : Box < DataType > } ,
3720+
36053721 // Custom/User-defined
36063722 Custom { name : String } ,
36073723
0 commit comments