1use super::{Render, RenderCtx, RenderMode, RenderSpelling};
17use crate::ast::{
18 AccessControlStatement, AccountName, AfterMatchSkip, AggregateArgs, AliasSpelling,
19 AlterColumnAction, AlterColumnTarget, AlterDatabase, AlterDatabaseAction, AlterDatabaseOption,
20 AlterDatabaseOptions, AlterEvent, AlterExtension, AlterExtensionAction, AlterInstance,
21 AlterInstanceAction, AlterLogfileGroup, AlterObjectDepends, AlterObjectSchema,
22 AlterResourceGroup, AlterRoutine, AlterSequence, AlterSequenceOption, AlterServer, AlterSystem,
23 AlterSystemAction, AlterTable, AlterTableAction, AlterTablespace, AlterTablespaceAction,
24 AlterUser, AlterUserSpec, AlterView, AnalyzeHistogram, AnalyzeStatement, ApplyKind, ArgSyntax,
25 ArrayExpr, ArraySpelling, ArrayTypeSpelling, AsOfJoinKind, AssignGtidsKind, AttachStatement,
26 AuthOption, AutoIncrementSpelling, BinaryOperator, BinaryTypeName, BinlogStatement,
27 BitStringRadix, BitwiseXorSpelling, BlobTypeName, BooleanTypeName, CacheIndexKeyList,
28 CacheIndexKeyword, CacheIndexStatement, CacheIndexTable, CacheIndexTargets, CallStatement,
29 CaseExpr, CaseStatement, CastSyntax, CeilSpelling, ChangeReplicationSourceOption,
30 ChangeReplicationSourceOptionValue, CharacterSetKeyword, CharacterTypeName, Charset,
31 CharsetAnnotation, CharsetKeyword, CheckTableOption, CheckpointStatement, ChecksumTableOption,
32 CloneDataDirectory, CloneSsl, CloneStatement, CloseCursorStatement, ColumnConstraint,
33 ColumnDef, ColumnOption, ColumnsSpelling, CommentOnStatement, CommentTarget, CompoundStatement,
34 ComprehensionSource, ConditionInfoItem, ConditionInfoItemName, ConditionValue,
35 ConditionalBranch, ConfigParameter, ConflictAction, ConflictResolution, ConflictTarget,
36 ConstraintCharacteristics, ConstraintCheckTime, ConstraintsTarget, CopyDirection,
37 CopyIntoSource, CopyIntoStatement, CopyIntoTarget, CopyOption, CopyOptionValue, CopySource,
38 CopyStatement, CopyTarget, CreateDatabase, CreateEvent, CreateExtension, CreateExtensionOption,
39 CreateFunction, CreateIndex, CreateLogfileGroup, CreateMacro, CreateProcedure,
40 CreateResourceGroup, CreateSchema, CreateSecret, CreateSequence, CreateServer,
41 CreateSpatialReferenceSystem, CreateStoredTrigger, CreateTable, CreateTableBody,
42 CreateTableOption, CreateTableOptionKind, CreateTablespace, CreateTrigger, CreateType,
43 CreateTypeDefinition, CreateUser, CreateView, CreateVirtualTable, Cte, CteBody, CteCycleClause,
44 CteCycleMark, CteSearchClause, DataType, DatabaseKeyword, DeallocateKeyword,
45 DeallocateStatement, DecimalTypeName, Declaration, DefaultRoleTarget, DefaultValue, Definer,
46 Delete, DerivedSpelling, DescribeColumn, DescribeStatement, DetachPartitionMode,
47 DetachStatement, DiagnosticsArea, DiagnosticsInfo, DmlSelection, DmlTarget, DoArg,
48 DoExpressionsStatement, DoStatement, DoubleTypeName, DropBehavior, DropDatabase, DropEvent,
49 DropIndexOnTable, DropLogfileGroup, DropObjectKind, DropResourceGroup, DropSecretStmt,
50 DropServer, DropSpatialReferenceSystem, DropStatement, DropTablespace, DropTransform,
51 EmptyMatchesMode, EqualsSpelling, EventOnCompletion, EventSchedule, EventStatus,
52 ExcludeConstraint, ExcludeElement, ExcludeOperator, ExecuteStatement, ExecuteUsingStatement,
53 ExplainFormat, ExplainKeyword, ExplainOption, ExplainStatement, ExportStatement, Expr,
54 Extension, ExtensionVersion, ExtractExpr, FetchCursorStatement, FetchSpelling, FieldSelector,
55 FilterWhereSpelling, FlushOption, FlushStatement, FlushTablesLock, FlushTarget, ForClause,
56 ForJsonMode, ForRoot, ForXmlElements, ForXmlMode, ForceKind, ForeignKeyMatch, ForeignKeyRef,
57 FormatClause, FromFirstLast, FunctionArg, FunctionBody, FunctionCall, FunctionNullBehavior,
58 FunctionOption, FunctionParam, FunctionParamDefault, FunctionParamDefaultSpelling,
59 FunctionParamMode, GeneratedColumn, GeneratedColumnSpelling, GeneratedColumnStorage,
60 GetDiagnosticsStatement, GrantAs, GrantObject, Grantee, GroupByAllSpelling, GroupByItem,
61 GroupReplicationOption, HandlerAction, HandlerCondition, HandlerIndexDirection,
62 HandlerKeyComparison, HandlerOperation, HandlerReadSelector, HandlerScanDirection,
63 HandlerStatement, HelpStatement, HierarchicalClause, Ident, IdentityColumn, IdentityGeneration,
64 IdentityOption, IfStatement, ImportStatement, ImportTableStatement, IndexAlgorithm,
65 IndexColumn, IndexHint, IndexHintAction, IndexHintKeyword, IndexHintScope, IndexLock,
66 IndexLockAlgorithmOption, IndexedBy, Insert, InsertColumnMatching, InsertOverriding,
67 InsertSource, InsertTarget, InsertValue, InsertValues, InsertVerb, InstallComponentSetElement,
68 InstallComponentSetScope, InstallComponentSetValue, InstallStatement, InstanceLockStatement,
69 IntWidth, IntegerDivideSpelling, IntegerTypeName, IntervalFields, IntoTarget, IoThreadKeyword,
70 IsDistinctFromSpelling, IsJsonExpr, IsNotDistinctFromSpelling, IsolationLevel,
71 IterateStatement, Join, JoinConstraint, JoinOperator, JsonAggregateBody, JsonAggregateExpr,
72 JsonArrayBody, JsonArrayExpr, JsonBehavior, JsonBehaviorKind, JsonConstructorExpr,
73 JsonConstructorKind, JsonEncoding, JsonFormat, JsonFuncExpr, JsonFuncKind, JsonItemType,
74 JsonKeyValue, JsonKeyValueSpelling, JsonNullClause, JsonObjectExpr, JsonPassingArg,
75 JsonQuotesBehavior, JsonReturning, JsonTable, JsonTableColumn, JsonValueExpr,
76 JsonWrapperBehavior, KeyCacheName, KillStatement, KillTarget, LambdaParamSpelling,
77 LanguageName, LateralView, LeaveStatement, LikeSpelling, Limit, LimitBy, LimitPercent,
78 LimitSyntax, Literal, LiteralKind, LoadDataConcurrency, LoadDataDuplicate, LoadDataEnclosed,
79 LoadDataFieldOrVar, LoadDataFields, LoadDataFormat, LoadDataIgnoreRows, LoadDataIgnoreUnit,
80 LoadDataLines, LoadDataStatement, LoadFieldsSpelling, LoadIndexStatement, LoadIndexTable,
81 LoadIndexTargets, LoadStatement, LoadTarget, LockStrength, LockTablesStatement, LockWait,
82 LockingClause, LockingSpelling, LoopStatement, MacroBody, MacroParam, MacroSpelling,
83 MatchRecognize, MatchRecognizePattern, MatchSearchModifier, Measure, Merge, MergeAction,
84 MergeMatchKind, MergeWhenClause, ModuleArg, ModuloSpelling, NamedObjectKind,
85 NamedOperatorSpelling, NamedWindow, NoExt, NoWriteToBinlog, NormalizationForm, NotEqSpelling,
86 NullInclusion, NullTestSpelling, NullTreatment, ObjectName, ObjectRefKind, ObjectReference,
87 OnCommitAction, OnConflict, OnlySyntax, OpenCursorStatement, OpenJson, OpenJsonColumn,
88 OperatorArgs, OrderByAll, OrderByExpr, OrderByUsing, ParameterKind, ParameterSigil,
89 PartitionBound, PartitionElem, PartitionSelection, PartitionSpec, PartitionStrategy,
90 PasswordLockOption, PipeAggregateExpr, PipeOperator, PipeRenameItem, Pivot, PivotColumn,
91 PivotExpr, PivotSpelling, PivotValueSource, PragmaStatement, PrepareFromStatement,
92 PrepareSource, PrepareStatement, Privilege, PrivilegeKind, PrivilegeLevel,
93 PrivilegeLevelObject, PrivilegeObjectType, Privileges, PurgeStatement, PurgeTarget, Quantifier,
94 Query, QuoteStyle, ReadOnlyValue, ReferentialAction, RegexpSpelling, ReindexStatement,
95 RelationInheritance, RenameStatement, RepairTableOption, RepeatStatement, RepetitionQuantifier,
96 ReplicaSpelling, ReplicaThreadOption, ReplicaUntilCondition, ReplicationFilterRule,
97 ReplicationStatement, RequirePrimaryKeyCheck, ResourceGroupState, ResourceGroupThreadPriority,
98 ResourceGroupType, ResourceGroupVcpu, ResourceLimit, ReturnStatement, Returning, RewriteDbPair,
99 RoleSpec, RollupSpelling, RoutineKind, RoutineObjectKind, RoutineSignature, RowsFromItem,
100 RowsPerMatch, SampleClause, SampleUnit, SchemaObjectKind, SchemaRelocationObject, SecretOption,
101 SecretPersistence, Select, SelectDistinct, SelectItem, SelectSpelling, SemiAntiSide,
102 SemiStructuredAccessExpr, SemiStructuredPathSegment, ServerOption, ServerOptionKind,
103 SessionStatement, SessionVariableKind, SetAssignment, SetCharacterSetValue, SetExpr,
104 SetNamesValue, SetOperator, SetParameterValue, SetQuantifier, SetScope, SetValue,
105 SetVariableAssignment, SetVariableKeyword, SetVariableValue, Setting, ShowBare,
106 ShowColumnsSpelling, ShowCreateKind, ShowDiagnosticKind, ShowEngineArtifact, ShowFilter,
107 ShowFrom, ShowFromKeyword, ShowFunctionsFilter, ShowFunctionsScope, ShowIndexSpelling,
108 ShowLimit, ShowListing, ShowProfileType, ShowRef, ShowRefKind, ShowRefTarget, ShowRoutineKind,
109 ShowScope, ShowStatement, ShowTarget, SignalItem, SignalItemName, SignalStatement, Signedness,
110 SizeLiteral, SizeUnit, SpecialFunctionKeyword, SpecialSetValue, SqlDataAccess,
111 SqlSecurityContext, SrsAttribute, Statement, StatementInfoItem, StatementInfoItemName,
112 StringFunc, StructConstructorArg, StructConstructorField, StructField, StructKeySpelling,
113 StructTypeField, StructTypeSpelling, SubscriptKind, SubsetDefinition, SymbolDefinition,
114 SystemVariableScope, SystemVariableScopeKind, TableAlias, TableConstraint, TableConstraintDef,
115 TableElement, TableFactor, TableFunctionColumn, TableHint, TableKeyword, TableLikeAction,
116 TableLikeFeature, TableLikeOption, TableLock, TableLockKind, TableMaintenanceKind,
117 TableMaintenanceStatement, TableOption, TableOptionValue, TableRename, TableSample,
118 TableStorageParameter, TableVersion, TableWithJoins, TablespaceOption, TablespaceSizeOption,
119 TemporaryTableKind, TextTypeName, TimeTypeName, TimeZone, TimestampTypeName, TlsOption,
120 TlsRequirement, TransactionAccessMode, TransactionBlockKeyword, TransactionMode,
121 TransactionModeKind, TransactionStart, TransactionStatement, TriggerEvent, TriggerOrder,
122 TriggerTiming, TrimSide, TruthValue, UnaryOperator, UndoTablespaceState, UninstallStatement,
123 UnlockTablesStatement, Unpivot, UnpivotColumn, UnpivotSpelling, Update, UpdateAssignment,
124 UpdateExtensionsStatement, UpdateTupleSource, UpdateValue, Upsert, UseStatement, UserAttribute,
125 UserRename, UserRoleList, UserRoleListKind, UserSpec, VacuumAnalyze, VacuumStatement, Values,
126 ValuesItem, VcpuRange, ViewAlgorithm, ViewCheckOption, ViewOptions, WhileStatement,
127 WildcardOptions, WildcardRename, WildcardReplace, WindowDefinition, WindowFrame,
128 WindowFrameBound, WindowFrameExclusion, WindowFrameUnits, WindowSpec, With, WithRoleSpec,
129 WrappedTypeKind, XaAssociation, XaStartKeyword, XaStatement, XaSuspend, Xid, XmlAttribute,
130 XmlDocumentOrContent, XmlFunc, XmlIndentOption, XmlNamespace, XmlPassingMechanism,
131 XmlStandalone, XmlTable, XmlTableColumn, XmlWhitespaceOption,
132};
133use crate::dialect::TargetSpelling;
134use crate::precedence::{
135 BindingPower, BindingPowerTable, SetOperationBindingPowerTable, Side, UNPARENTHESIZED_IN_LIST,
136 needs_parens_between,
137};
138use std::fmt;
139use thin_vec::ThinVec;
140
141#[cfg(test)]
170use crate::generated::render_skeleton as skeleton;
171#[cfg(test)]
172const _: skeleton::RenderShapeFingerprint<0x668c6569aa20f965> = skeleton::CURRENT_RENDER_SHAPE_DCL;
173#[cfg(test)]
174const _: skeleton::RenderShapeFingerprint<0xea69d9b785020501> = skeleton::CURRENT_RENDER_SHAPE_DDL;
175#[cfg(test)]
176const _: skeleton::RenderShapeFingerprint<0xbc51c89e49732760> = skeleton::CURRENT_RENDER_SHAPE_DML;
177#[cfg(test)]
178const _: skeleton::RenderShapeFingerprint<0xbcc8a4346507a25c> = skeleton::CURRENT_RENDER_SHAPE_EXPR;
179#[cfg(test)]
180const _: skeleton::RenderShapeFingerprint<0xffd1225e92e4dab2> = skeleton::CURRENT_RENDER_SHAPE_EXT;
181#[cfg(test)]
182const _: skeleton::RenderShapeFingerprint<0xbc5427055a4e813c> =
183 skeleton::CURRENT_RENDER_SHAPE_IDENT;
184#[cfg(test)]
185const _: skeleton::RenderShapeFingerprint<0x509ea17dec9af986> =
186 skeleton::CURRENT_RENDER_SHAPE_LITERAL;
187#[cfg(test)]
188const _: skeleton::RenderShapeFingerprint<0x8b1ed704455adf27> =
189 skeleton::CURRENT_RENDER_SHAPE_MATCH_RECOGNIZE;
190#[cfg(test)]
191const _: skeleton::RenderShapeFingerprint<0x5ebfaa9fb0c1caf9> =
192 skeleton::CURRENT_RENDER_SHAPE_PIPE_OPS;
193#[cfg(test)]
194const _: skeleton::RenderShapeFingerprint<0xd3444362d3f03fe8> =
195 skeleton::CURRENT_RENDER_SHAPE_PIVOT;
196#[cfg(test)]
197const _: skeleton::RenderShapeFingerprint<0x305c97c17f4b1723> =
198 skeleton::CURRENT_RENDER_SHAPE_QUERY;
199#[cfg(test)]
200const _: skeleton::RenderShapeFingerprint<0x6f0ed6cfb3c83310> = skeleton::CURRENT_RENDER_SHAPE_STMT;
201#[cfg(test)]
202const _: skeleton::RenderShapeFingerprint<0xfb50d22f049b4cc7> =
203 skeleton::CURRENT_RENDER_SHAPE_STORED_PROGRAM;
204#[cfg(test)]
205const _: skeleton::RenderShapeFingerprint<0x0b580e5e0de8de03> = skeleton::CURRENT_RENDER_SHAPE_TCL;
206#[cfg(test)]
207const _: skeleton::RenderShapeFingerprint<0x03efd7c0644eb26a> = skeleton::CURRENT_RENDER_SHAPE_TY;
208#[cfg(test)]
209const _: skeleton::RenderShapeFingerprint<0x30c6b7a3fb94d049> = skeleton::CURRENT_RENDER_SHAPE_UTIL;
210#[cfg(test)]
211const _: skeleton::RenderShapeFingerprint<0x585b3bd313272236> =
212 skeleton::CURRENT_RENDER_SHAPE_WINDOW;
213
214impl Render for NoExt {
219 fn render(&self, _ctx: &RenderCtx<'_>, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
220 match *self {}
222 }
223}
224
225impl Render for Ident {
226 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
227 if ctx.mode() == RenderMode::Redacted {
235 return f.write_str("id");
236 }
237 let text = ctx.resolve(self.sym);
238 let (open, close, doubled) = match self.quote {
242 QuoteStyle::None => return f.write_str(text),
243 QuoteStyle::UnicodeDouble => {
250 if honours_source_spelling(ctx) {
251 if let Some(src) = ctx.slice(self.meta.span) {
252 return f.write_str(src);
253 }
254 }
255 ('"', '"', "\"\"")
256 }
257 QuoteStyle::Single => ('\'', '\'', "''"),
258 QuoteStyle::Double => ('"', '"', "\"\""),
259 QuoteStyle::Backtick => ('`', '`', "``"),
260 QuoteStyle::Bracket => ('[', ']', "]]"),
261 };
262 if text.contains(close) {
265 let escaped = text.replace(close, doubled);
266 write!(f, "{open}{escaped}{close}")
267 } else {
268 write!(f, "{open}{text}{close}")
269 }
270 }
271}
272
273impl Render for ObjectName {
274 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
275 for (i, part) in self.0.iter().enumerate() {
276 if i > 0 {
277 f.write_str(".")?;
278 }
279 part.render(ctx, f)?;
280 }
281 Ok(())
282 }
283}
284
285impl Render for Literal {
286 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
287 if ctx.mode() == RenderMode::Redacted {
288 return f.write_str("?");
289 }
290 if let Some(text) = ctx.slice(self.meta.span) {
291 return f.write_str(text);
293 }
294 match &self.kind {
299 LiteralKind::Null => f.write_str("NULL"),
300 LiteralKind::Boolean(true) => f.write_str("TRUE"),
301 LiteralKind::Boolean(false) => f.write_str("FALSE"),
302 LiteralKind::Integer | LiteralKind::Float | LiteralKind::Decimal => f.write_str("0"),
303 LiteralKind::String => f.write_str("''"),
304 LiteralKind::Date => f.write_str("DATE '1970-01-01'"),
305 LiteralKind::Time { time_zone } => {
306 f.write_str("TIME")?;
307 render_time_zone_suffix(*time_zone, f)?;
308 f.write_str(" '00:00:00'")
309 }
310 LiteralKind::Timestamp { time_zone } => {
311 f.write_str("TIMESTAMP")?;
312 render_time_zone_suffix(*time_zone, f)?;
313 f.write_str(" '1970-01-01 00:00:00'")
314 }
315 LiteralKind::Interval { fields, .. } => {
316 f.write_str("INTERVAL '0'")?;
317 match fields {
318 Some(fields) => f.write_str(interval_fields_suffix(*fields)),
319 None => Ok(()),
320 }
321 }
322 LiteralKind::BitString { radix } => f.write_str(match radix {
323 BitStringRadix::Binary => "B'0'",
324 BitStringRadix::Hex => "X'0'",
325 }),
326 LiteralKind::Money => f.write_str("$0"),
327 }
328 }
329}
330
331impl<X: Extension + Render> Render for DataType<X> {
332 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
333 let target = type_render_target(ctx);
334 match self {
335 DataType::Boolean { spelling, .. } => f.write_str(boolean_type_name(target, *spelling)),
336 DataType::TinyInt { display_width, .. } => render_sized(f, "TINYINT", *display_width),
337 DataType::SmallInt { display_width, .. } => render_sized(f, "SMALLINT", *display_width),
338 DataType::MediumInt { display_width, .. } => {
339 render_sized(f, "MEDIUMINT", *display_width)
340 }
341 DataType::Integer {
342 spelling,
343 display_width,
344 ..
345 } => render_sized(f, integer_type_name(target, *spelling), *display_width),
346 DataType::BigInt { display_width, .. } => render_sized(f, "BIGINT", *display_width),
347 DataType::Decimal {
348 spelling,
349 precision,
350 scale,
351 ..
352 } => {
353 render_precision_scale(f, decimal_type_name(target, *spelling), *precision, *scale)
354 }
355 DataType::Float { precision, .. } => render_sized(f, "FLOAT", *precision),
356 DataType::Real { .. } => f.write_str("REAL"),
357 DataType::Double { spelling, .. } => f.write_str(double_type_name(*spelling)),
358 DataType::Text {
359 spelling, charset, ..
360 } => {
361 f.write_str(text_type_name(target, *spelling))?;
362 render_optional_charset_annotation(ctx, target, charset.as_deref(), f)
363 }
364 DataType::Blob { spelling, .. } => f.write_str(blob_type_name(target, *spelling)),
365 DataType::Character {
366 spelling,
367 size,
368 charset,
369 ..
370 } => {
371 render_sized(f, character_type_name(target, *spelling), *size)?;
372 render_optional_charset_annotation(ctx, target, charset.as_deref(), f)
373 }
374 DataType::Binary { spelling, size, .. } => {
375 render_sized(f, binary_type_name(target, *spelling), *size)
376 }
377 DataType::Bit { varying, size, .. } => {
378 render_sized(f, if *varying { "BIT VARYING" } else { "BIT" }, *size)
379 }
380 DataType::Json { .. } => f.write_str("JSON"),
381 DataType::Uuid { .. } => f.write_str("UUID"),
382 DataType::Date { .. } => f.write_str("DATE"),
383 DataType::Time {
384 spelling,
385 precision,
386 time_zone,
387 ..
388 } => render_time_type(target, *spelling, *precision, *time_zone, f),
389 DataType::Timestamp {
390 spelling,
391 precision,
392 time_zone,
393 ..
394 } => render_timestamp_type(target, *spelling, *precision, *time_zone, f),
395 DataType::Interval {
396 fields, precision, ..
397 } => render_interval_type(*fields, *precision, f),
398 DataType::Enum {
399 values, charset, ..
400 } => {
401 render_value_list_type(ctx, "ENUM", values, f)?;
402 render_optional_charset_annotation(ctx, target, charset.as_deref(), f)
403 }
404 DataType::Set {
405 values, charset, ..
406 } => {
407 render_value_list_type(ctx, "SET", values, f)?;
408 render_optional_charset_annotation(ctx, target, charset.as_deref(), f)
409 }
410 DataType::NumericModifier {
411 element,
412 signedness,
413 zerofill,
414 ..
415 } => render_numeric_modifier_type(ctx, element.as_deref(), *signedness, *zerofill, f),
416 DataType::Array {
417 element,
418 size,
419 spelling,
420 ..
421 } => render_array_type(ctx, element, *size, *spelling, f),
422 DataType::Struct {
423 fields, spelling, ..
424 } => match spelling {
425 StructTypeSpelling::AngleBracket => {
426 render_composite_type_angle(ctx, "STRUCT", fields, f)
427 }
428 _ => render_composite_type(ctx, struct_type_keyword(*spelling), fields, f),
429 },
430 DataType::Union { members, .. } => render_composite_type(ctx, "UNION", members, f),
431 DataType::Map { key, value, .. } => {
432 f.write_str("MAP(")?;
433 key.render(ctx, f)?;
434 f.write_str(", ")?;
435 value.render(ctx, f)?;
436 f.write_str(")")
437 }
438 DataType::Wrapped { kind, inner, .. } => {
439 f.write_str(wrapped_type_keyword(*kind))?;
440 f.write_str("(")?;
441 inner.render(ctx, f)?;
442 f.write_str(")")
443 }
444 DataType::FixedString { length, .. } => write!(f, "FixedString({length})"),
447 DataType::DateTime64 {
450 precision,
451 timezone,
452 ..
453 } => {
454 write!(f, "DateTime64({precision}")?;
455 if let Some(timezone) = timezone {
456 f.write_str(", ")?;
457 timezone.render(ctx, f)?;
458 }
459 f.write_str(")")
460 }
461 DataType::Nested { fields, .. } => render_composite_type(ctx, "Nested", fields, f),
465 DataType::FixedWidthInt { signed, width, .. } => {
468 f.write_str(fixed_width_int_name(*signed, *width))
469 }
470 DataType::UserDefined {
471 name, modifiers, ..
472 } => {
473 name.render(ctx, f)?;
474 render_literal_modifiers(ctx, f, modifiers)
475 }
476 DataType::Liberal { words, args, .. } => {
481 for (index, word) in words.iter().enumerate() {
482 if index > 0 {
483 f.write_str(" ")?;
484 }
485 word.render(ctx, f)?;
486 }
487 render_numeric_modifiers(f, args)
488 }
489 DataType::Other { ext, .. } => ext.render(ctx, f),
492 }
493 }
494}
495
496impl<X: Extension + Render> Render for StructTypeField<X> {
497 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
498 self.name.render(ctx, f)?;
499 f.write_str(" ")?;
500 self.ty.render(ctx, f)
501 }
502}
503
504#[derive(Clone, Copy, Debug, PartialEq, Eq)]
513enum TypeRenderTarget {
514 PreserveSource,
515 Ansi,
516 Postgres,
517}
518
519fn type_render_target(ctx: &RenderCtx<'_>) -> TypeRenderTarget {
520 match ctx.spelling() {
524 RenderSpelling::PreserveSource => TypeRenderTarget::PreserveSource,
525 RenderSpelling::TargetDialect => match ctx.target().target_spelling {
526 TargetSpelling::Ansi => TypeRenderTarget::Ansi,
527 TargetSpelling::Postgres => TypeRenderTarget::Postgres,
528 },
529 }
530}
531
532fn boolean_type_name(target: TypeRenderTarget, spelling: BooleanTypeName) -> &'static str {
533 match target {
534 TypeRenderTarget::PreserveSource => match spelling {
535 BooleanTypeName::Boolean => "BOOLEAN",
536 BooleanTypeName::Bool => "BOOL",
537 },
538 TypeRenderTarget::Ansi => "BOOLEAN",
539 TypeRenderTarget::Postgres => "BOOLEAN",
540 }
541}
542
543fn integer_type_name(target: TypeRenderTarget, spelling: IntegerTypeName) -> &'static str {
544 match target {
545 TypeRenderTarget::PreserveSource => match spelling {
546 IntegerTypeName::Int => "INT",
547 IntegerTypeName::Integer => "INTEGER",
548 },
549 TypeRenderTarget::Ansi => "INTEGER",
550 TypeRenderTarget::Postgres => "INTEGER",
551 }
552}
553
554fn decimal_type_name(target: TypeRenderTarget, spelling: DecimalTypeName) -> &'static str {
555 match target {
556 TypeRenderTarget::PreserveSource => match spelling {
557 DecimalTypeName::Decimal => "DECIMAL",
558 DecimalTypeName::Dec => "DEC",
559 DecimalTypeName::Numeric => "NUMERIC",
560 },
561 TypeRenderTarget::Ansi => "DECIMAL",
562 TypeRenderTarget::Postgres => "NUMERIC",
563 }
564}
565
566fn double_type_name(spelling: DoubleTypeName) -> &'static str {
567 match spelling {
568 DoubleTypeName::DoublePrecision => "DOUBLE PRECISION",
569 DoubleTypeName::Double => "DOUBLE",
570 }
571}
572
573fn text_type_name(target: TypeRenderTarget, spelling: TextTypeName) -> &'static str {
574 match target {
575 TypeRenderTarget::PreserveSource => match spelling {
576 TextTypeName::Text => "TEXT",
577 TextTypeName::TinyText => "TINYTEXT",
578 TextTypeName::MediumText => "MEDIUMTEXT",
579 TextTypeName::LongText => "LONGTEXT",
580 },
581 TypeRenderTarget::Ansi | TypeRenderTarget::Postgres => "TEXT",
584 }
585}
586
587fn blob_type_name(target: TypeRenderTarget, spelling: BlobTypeName) -> &'static str {
588 match target {
589 TypeRenderTarget::PreserveSource => match spelling {
590 BlobTypeName::Blob => "BLOB",
591 BlobTypeName::TinyBlob => "TINYBLOB",
592 BlobTypeName::MediumBlob => "MEDIUMBLOB",
593 BlobTypeName::LongBlob => "LONGBLOB",
594 },
595 TypeRenderTarget::Ansi => "BLOB",
598 TypeRenderTarget::Postgres => "BYTEA",
599 }
600}
601
602fn character_type_name(target: TypeRenderTarget, spelling: CharacterTypeName) -> &'static str {
603 let varying = matches!(
606 spelling,
607 CharacterTypeName::CharVarying
608 | CharacterTypeName::CharacterVarying
609 | CharacterTypeName::Varchar
610 | CharacterTypeName::NcharVarying
611 | CharacterTypeName::NationalCharVarying
612 | CharacterTypeName::NationalCharacterVarying
613 );
614 match target {
615 TypeRenderTarget::PreserveSource => match spelling {
616 CharacterTypeName::Char => "CHAR",
617 CharacterTypeName::Character => "CHARACTER",
618 CharacterTypeName::CharVarying => "CHAR VARYING",
619 CharacterTypeName::CharacterVarying => "CHARACTER VARYING",
620 CharacterTypeName::Varchar => "VARCHAR",
621 CharacterTypeName::Nchar => "NCHAR",
622 CharacterTypeName::NcharVarying => "NCHAR VARYING",
623 CharacterTypeName::NationalChar => "NATIONAL CHAR",
624 CharacterTypeName::NationalCharVarying => "NATIONAL CHAR VARYING",
625 CharacterTypeName::NationalCharacter => "NATIONAL CHARACTER",
626 CharacterTypeName::NationalCharacterVarying => "NATIONAL CHARACTER VARYING",
627 },
628 TypeRenderTarget::Ansi => {
629 if varying {
630 "CHARACTER VARYING"
631 } else {
632 "CHARACTER"
633 }
634 }
635 TypeRenderTarget::Postgres => {
636 if varying {
637 "VARCHAR"
638 } else {
639 "CHAR"
640 }
641 }
642 }
643}
644
645fn render_optional_charset_annotation(
656 ctx: &RenderCtx<'_>,
657 target: TypeRenderTarget,
658 annotation: Option<&CharsetAnnotation>,
659 f: &mut fmt::Formatter<'_>,
660) -> fmt::Result {
661 let Some(annotation) = annotation else {
662 return Ok(());
663 };
664 if target != TypeRenderTarget::PreserveSource {
665 return Ok(());
666 }
667 match annotation.charset {
668 Some(Charset::Named) => {
669 f.write_str(" CHARACTER SET ")?;
670 if let Some(name) = &annotation.name {
673 name.render(ctx, f)?;
674 }
675 }
676 Some(Charset::Ascii) => f.write_str(" ASCII")?,
677 Some(Charset::Unicode) => f.write_str(" UNICODE")?,
678 Some(Charset::Byte) => f.write_str(" BYTE")?,
679 None => {}
680 }
681 if annotation.binary {
682 f.write_str(" BINARY")?;
683 }
684 Ok(())
685}
686
687fn binary_type_name(target: TypeRenderTarget, spelling: BinaryTypeName) -> &'static str {
688 match target {
689 TypeRenderTarget::PreserveSource => match spelling {
690 BinaryTypeName::Binary => "BINARY",
691 BinaryTypeName::BinaryVarying => "BINARY VARYING",
692 BinaryTypeName::Varbinary => "VARBINARY",
693 BinaryTypeName::Bytea => "BYTEA",
694 },
695 TypeRenderTarget::Ansi => match spelling {
696 BinaryTypeName::Binary => "BINARY",
697 BinaryTypeName::BinaryVarying => "BINARY VARYING",
698 BinaryTypeName::Varbinary => "BINARY VARYING",
699 BinaryTypeName::Bytea => "BYTEA",
700 },
701 TypeRenderTarget::Postgres => match spelling {
702 BinaryTypeName::Binary => "BYTEA",
703 BinaryTypeName::BinaryVarying => "BYTEA",
704 BinaryTypeName::Varbinary => "BYTEA",
705 BinaryTypeName::Bytea => "BYTEA",
706 },
707 }
708}
709
710fn render_time_type(
711 target: TypeRenderTarget,
712 spelling: TimeTypeName,
713 precision: Option<u32>,
714 time_zone: TimeZone,
715 f: &mut fmt::Formatter<'_>,
716) -> fmt::Result {
717 match target {
718 TypeRenderTarget::PreserveSource => match spelling {
719 TimeTypeName::Time => {
720 render_sized(f, "TIME", precision)?;
721 render_time_zone_suffix(time_zone, f)
722 }
723 TimeTypeName::Timetz => render_sized(f, "TIMETZ", precision),
724 },
725 TypeRenderTarget::Ansi => {
726 render_sized(f, "TIME", precision)?;
727 render_time_zone_suffix(time_zone_from_spelling(time_zone, spelling), f)
728 }
729 TypeRenderTarget::Postgres => match time_zone_from_spelling(time_zone, spelling) {
730 TimeZone::Unspecified => render_sized(f, "TIME", precision),
731 TimeZone::WithTimeZone => render_sized(f, "TIMETZ", precision),
732 TimeZone::WithoutTimeZone => {
733 render_sized(f, "TIME", precision)?;
734 f.write_str(" WITHOUT TIME ZONE")
735 }
736 },
737 }
738}
739
740fn render_timestamp_type(
741 target: TypeRenderTarget,
742 spelling: TimestampTypeName,
743 precision: Option<u32>,
744 time_zone: TimeZone,
745 f: &mut fmt::Formatter<'_>,
746) -> fmt::Result {
747 match target {
748 TypeRenderTarget::PreserveSource => match spelling {
749 TimestampTypeName::Timestamp => {
750 render_sized(f, "TIMESTAMP", precision)?;
751 render_time_zone_suffix(time_zone, f)
752 }
753 TimestampTypeName::Timestamptz => render_sized(f, "TIMESTAMPTZ", precision),
754 TimestampTypeName::Datetime => render_sized(f, "DATETIME", precision),
755 },
756 TypeRenderTarget::Ansi => {
757 render_sized(f, "TIMESTAMP", precision)?;
758 render_time_zone_suffix(time_zone_from_timestamp_spelling(time_zone, spelling), f)
759 }
760 TypeRenderTarget::Postgres => {
761 match time_zone_from_timestamp_spelling(time_zone, spelling) {
762 TimeZone::Unspecified => render_sized(f, "TIMESTAMP", precision),
763 TimeZone::WithTimeZone => render_sized(f, "TIMESTAMPTZ", precision),
764 TimeZone::WithoutTimeZone => {
765 render_sized(f, "TIMESTAMP", precision)?;
766 f.write_str(" WITHOUT TIME ZONE")
767 }
768 }
769 }
770 }
771}
772
773fn time_zone_from_spelling(time_zone: TimeZone, spelling: TimeTypeName) -> TimeZone {
774 match spelling {
775 TimeTypeName::Time => time_zone,
776 TimeTypeName::Timetz => TimeZone::WithTimeZone,
777 }
778}
779
780fn time_zone_from_timestamp_spelling(time_zone: TimeZone, spelling: TimestampTypeName) -> TimeZone {
781 match spelling {
782 TimestampTypeName::Timestamp => time_zone,
783 TimestampTypeName::Timestamptz => TimeZone::WithTimeZone,
784 TimestampTypeName::Datetime => TimeZone::Unspecified,
787 }
788}
789
790fn render_time_zone_suffix(time_zone: TimeZone, f: &mut fmt::Formatter<'_>) -> fmt::Result {
791 match time_zone {
792 TimeZone::Unspecified => Ok(()),
793 TimeZone::WithTimeZone => f.write_str(" WITH TIME ZONE"),
794 TimeZone::WithoutTimeZone => f.write_str(" WITHOUT TIME ZONE"),
795 }
796}
797
798fn render_interval_type(
799 fields: Option<IntervalFields>,
800 precision: Option<u32>,
801 f: &mut fmt::Formatter<'_>,
802) -> fmt::Result {
803 f.write_str("INTERVAL")?;
804 match fields {
805 Some(IntervalFields::Year) => render_interval_field(f, "YEAR", precision),
806 Some(IntervalFields::Month) => render_interval_field(f, "MONTH", precision),
807 Some(IntervalFields::Day) => render_interval_field(f, "DAY", precision),
808 Some(IntervalFields::Hour) => render_interval_field(f, "HOUR", precision),
809 Some(IntervalFields::Minute) => render_interval_field(f, "MINUTE", precision),
810 Some(IntervalFields::Second) => render_interval_field(f, "SECOND", precision),
811 Some(IntervalFields::YearToMonth) => f.write_str(" YEAR TO MONTH"),
812 Some(IntervalFields::DayToHour) => f.write_str(" DAY TO HOUR"),
813 Some(IntervalFields::DayToMinute) => f.write_str(" DAY TO MINUTE"),
814 Some(IntervalFields::DayToSecond) => {
815 f.write_str(" DAY TO ")?;
816 render_sized(f, "SECOND", precision)
817 }
818 Some(IntervalFields::HourToMinute) => f.write_str(" HOUR TO MINUTE"),
819 Some(IntervalFields::HourToSecond) => {
820 f.write_str(" HOUR TO ")?;
821 render_sized(f, "SECOND", precision)
822 }
823 Some(IntervalFields::MinuteToSecond) => {
824 f.write_str(" MINUTE TO ")?;
825 render_sized(f, "SECOND", precision)
826 }
827 Some(IntervalFields::Week) => render_interval_field(f, "WEEK", precision),
828 Some(IntervalFields::Quarter) => render_interval_field(f, "QUARTER", precision),
829 Some(IntervalFields::Decade) => render_interval_field(f, "DECADE", precision),
830 Some(IntervalFields::Century) => render_interval_field(f, "CENTURY", precision),
831 Some(IntervalFields::Millennium) => render_interval_field(f, "MILLENNIUM", precision),
832 Some(IntervalFields::Millisecond) => render_interval_field(f, "MILLISECOND", precision),
833 Some(IntervalFields::Microsecond) => render_interval_field(f, "MICROSECOND", precision),
834 Some(IntervalFields::DayToMicrosecond) => {
839 render_interval_field(f, "DAY TO MICROSECOND", precision)
840 }
841 Some(IntervalFields::HourToMicrosecond) => {
842 render_interval_field(f, "HOUR TO MICROSECOND", precision)
843 }
844 Some(IntervalFields::MinuteToMicrosecond) => {
845 render_interval_field(f, "MINUTE TO MICROSECOND", precision)
846 }
847 Some(IntervalFields::SecondToMicrosecond) => {
848 render_interval_field(f, "SECOND TO MICROSECOND", precision)
849 }
850 None => match precision {
851 Some(precision) => write!(f, "({precision})"),
852 None => Ok(()),
853 },
854 }
855}
856
857fn render_interval_field(
858 f: &mut fmt::Formatter<'_>,
859 name: &str,
860 precision: Option<u32>,
861) -> fmt::Result {
862 f.write_str(" ")?;
863 render_sized(f, name, precision)
864}
865
866fn interval_fields_suffix(fields: IntervalFields) -> &'static str {
870 match fields {
871 IntervalFields::Year => " YEAR",
872 IntervalFields::Month => " MONTH",
873 IntervalFields::Day => " DAY",
874 IntervalFields::Hour => " HOUR",
875 IntervalFields::Minute => " MINUTE",
876 IntervalFields::Second => " SECOND",
877 IntervalFields::YearToMonth => " YEAR TO MONTH",
878 IntervalFields::DayToHour => " DAY TO HOUR",
879 IntervalFields::DayToMinute => " DAY TO MINUTE",
880 IntervalFields::DayToSecond => " DAY TO SECOND",
881 IntervalFields::HourToMinute => " HOUR TO MINUTE",
882 IntervalFields::HourToSecond => " HOUR TO SECOND",
883 IntervalFields::MinuteToSecond => " MINUTE TO SECOND",
884 IntervalFields::Week => " WEEK",
885 IntervalFields::Quarter => " QUARTER",
886 IntervalFields::Decade => " DECADE",
887 IntervalFields::Century => " CENTURY",
888 IntervalFields::Millennium => " MILLENNIUM",
889 IntervalFields::Millisecond => " MILLISECOND",
890 IntervalFields::Microsecond => " MICROSECOND",
891 IntervalFields::DayToMicrosecond => " DAY TO MICROSECOND",
892 IntervalFields::HourToMicrosecond => " HOUR TO MICROSECOND",
893 IntervalFields::MinuteToMicrosecond => " MINUTE TO MICROSECOND",
894 IntervalFields::SecondToMicrosecond => " SECOND TO MICROSECOND",
895 }
896}
897
898fn mysql_interval_unit_suffix(unit: IntervalFields) -> &'static str {
907 match unit {
908 IntervalFields::Year => " YEAR",
909 IntervalFields::Month => " MONTH",
910 IntervalFields::Day => " DAY",
911 IntervalFields::Hour => " HOUR",
912 IntervalFields::Minute => " MINUTE",
913 IntervalFields::Second => " SECOND",
914 IntervalFields::Week => " WEEK",
915 IntervalFields::Quarter => " QUARTER",
916 IntervalFields::Microsecond => " MICROSECOND",
917 IntervalFields::YearToMonth => " YEAR_MONTH",
918 IntervalFields::DayToHour => " DAY_HOUR",
919 IntervalFields::DayToMinute => " DAY_MINUTE",
920 IntervalFields::DayToSecond => " DAY_SECOND",
921 IntervalFields::HourToMinute => " HOUR_MINUTE",
922 IntervalFields::HourToSecond => " HOUR_SECOND",
923 IntervalFields::MinuteToSecond => " MINUTE_SECOND",
924 IntervalFields::DayToMicrosecond => " DAY_MICROSECOND",
925 IntervalFields::HourToMicrosecond => " HOUR_MICROSECOND",
926 IntervalFields::MinuteToMicrosecond => " MINUTE_MICROSECOND",
927 IntervalFields::SecondToMicrosecond => " SECOND_MICROSECOND",
928 IntervalFields::Decade
930 | IntervalFields::Century
931 | IntervalFields::Millennium
932 | IntervalFields::Millisecond => " MICROSECOND",
933 }
934}
935
936fn render_sized(f: &mut fmt::Formatter<'_>, name: &str, size: Option<u32>) -> fmt::Result {
937 match size {
938 Some(size) => write!(f, "{name}({size})"),
939 None => f.write_str(name),
940 }
941}
942
943fn render_precision_scale(
944 f: &mut fmt::Formatter<'_>,
945 name: &str,
946 precision: Option<i32>,
947 scale: Option<i32>,
948) -> fmt::Result {
949 f.write_str(name)?;
950 match (precision, scale) {
951 (Some(precision), Some(scale)) => write!(f, "({precision}, {scale})"),
952 (Some(precision), None) => write!(f, "({precision})"),
953 (None, Some(scale)) => write!(f, "(*, {scale})"),
954 (None, None) => Ok(()),
955 }
956}
957
958fn render_literal_modifiers(
969 ctx: &RenderCtx<'_>,
970 f: &mut fmt::Formatter<'_>,
971 modifiers: &[Literal],
972) -> fmt::Result {
973 if modifiers.is_empty() {
974 return Ok(());
975 }
976 f.write_str("(")?;
977 for (index, modifier) in modifiers.iter().enumerate() {
978 if index > 0 {
979 f.write_str(", ")?;
980 }
981 if let Some(text) = ctx.slice(modifier.meta.span) {
982 f.write_str(text)?;
983 } else {
984 modifier.render(ctx, f)?;
985 }
986 }
987 f.write_str(")")
988}
989
990fn render_numeric_modifiers(f: &mut fmt::Formatter<'_>, modifiers: &[u32]) -> fmt::Result {
991 if modifiers.is_empty() {
992 return Ok(());
993 }
994 f.write_str("(")?;
995 for (index, modifier) in modifiers.iter().enumerate() {
996 if index > 0 {
997 f.write_str(", ")?;
998 }
999 write!(f, "{modifier}")?;
1000 }
1001 f.write_str(")")
1002}
1003
1004fn render_value_list_type(
1007 ctx: &RenderCtx<'_>,
1008 name: &str,
1009 values: &[Literal],
1010 f: &mut fmt::Formatter<'_>,
1011) -> fmt::Result {
1012 f.write_str(name)?;
1013 f.write_str("(")?;
1014 render_comma_separated(values, ctx, f)?;
1015 f.write_str(")")
1016}
1017
1018fn wrapped_type_keyword(kind: WrappedTypeKind) -> &'static str {
1024 match kind {
1025 WrappedTypeKind::Nullable => "Nullable",
1026 WrappedTypeKind::LowCardinality => "LowCardinality",
1027 }
1028}
1029
1030fn fixed_width_int_name(signed: bool, width: IntWidth) -> &'static str {
1035 match (signed, width) {
1036 (true, IntWidth::W8) => "Int8",
1037 (true, IntWidth::W16) => "Int16",
1038 (true, IntWidth::W32) => "Int32",
1039 (true, IntWidth::W64) => "Int64",
1040 (true, IntWidth::W128) => "Int128",
1041 (true, IntWidth::W256) => "Int256",
1042 (false, IntWidth::W8) => "UInt8",
1043 (false, IntWidth::W16) => "UInt16",
1044 (false, IntWidth::W32) => "UInt32",
1045 (false, IntWidth::W64) => "UInt64",
1046 (false, IntWidth::W128) => "UInt128",
1047 (false, IntWidth::W256) => "UInt256",
1048 }
1049}
1050
1051fn struct_type_keyword(spelling: StructTypeSpelling) -> &'static str {
1052 match spelling {
1053 StructTypeSpelling::Struct | StructTypeSpelling::AngleBracket => "STRUCT",
1054 StructTypeSpelling::Row => "ROW",
1055 }
1056}
1057
1058fn render_composite_type_angle<X: Extension + Render>(
1060 ctx: &RenderCtx<'_>,
1061 keyword: &str,
1062 fields: &[StructTypeField<X>],
1063 f: &mut fmt::Formatter<'_>,
1064) -> fmt::Result {
1065 f.write_str(keyword)?;
1066 f.write_str("<")?;
1067 render_comma_separated(fields, ctx, f)?;
1068 f.write_str(">")
1069}
1070
1071fn render_composite_type<X: Extension + Render>(
1075 ctx: &RenderCtx<'_>,
1076 keyword: &str,
1077 fields: &[StructTypeField<X>],
1078 f: &mut fmt::Formatter<'_>,
1079) -> fmt::Result {
1080 f.write_str(keyword)?;
1081 f.write_str("(")?;
1082 render_comma_separated(fields, ctx, f)?;
1083 f.write_str(")")
1084}
1085
1086fn render_array_type<X: Extension + Render>(
1089 ctx: &RenderCtx<'_>,
1090 element: &DataType<X>,
1091 size: Option<u32>,
1092 spelling: ArrayTypeSpelling,
1093 f: &mut fmt::Formatter<'_>,
1094) -> fmt::Result {
1095 if matches!(spelling, ArrayTypeSpelling::AngleBracket) {
1096 f.write_str("ARRAY<")?;
1097 element.render(ctx, f)?;
1098 return f.write_str(">");
1099 }
1100 element.render(ctx, f)?;
1101 match spelling {
1102 ArrayTypeSpelling::Bracket => match size {
1103 Some(n) => write!(f, "[{n}]"),
1104 None => f.write_str("[]"),
1105 },
1106 ArrayTypeSpelling::Keyword => {
1107 f.write_str(" ARRAY")?;
1108 match size {
1109 Some(n) => write!(f, "[{n}]"),
1110 None => Ok(()),
1111 }
1112 }
1113 ArrayTypeSpelling::AngleBracket => unreachable!("handled above"),
1114 }
1115}
1116
1117fn render_numeric_modifier_type<X: Extension + Render>(
1121 ctx: &RenderCtx<'_>,
1122 element: Option<&DataType<X>>,
1123 signedness: Signedness,
1124 zerofill: bool,
1125 f: &mut fmt::Formatter<'_>,
1126) -> fmt::Result {
1127 let mut wrote = false;
1128 if let Some(element) = element {
1129 element.render(ctx, f)?;
1130 wrote = true;
1131 }
1132 let sign = match signedness {
1133 Signedness::Unspecified => None,
1134 Signedness::Signed => Some("SIGNED"),
1135 Signedness::Unsigned => Some("UNSIGNED"),
1136 };
1137 if let Some(sign) = sign {
1138 if wrote {
1139 f.write_str(" ")?;
1140 }
1141 f.write_str(sign)?;
1142 wrote = true;
1143 }
1144 if zerofill {
1145 if wrote {
1146 f.write_str(" ")?;
1147 }
1148 f.write_str("ZEROFILL")?;
1149 }
1150 Ok(())
1151}
1152
1153impl Render for BinaryOperator {
1154 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1155 f.write_str(match self {
1158 BinaryOperator::Plus => "+",
1159 BinaryOperator::Minus => "-",
1160 BinaryOperator::Multiply => "*",
1161 BinaryOperator::Divide => "/",
1162 BinaryOperator::Modulo(ModuloSpelling::Percent) => "%",
1165 BinaryOperator::Modulo(ModuloSpelling::Mod) => "MOD",
1166 BinaryOperator::IntegerDivide(IntegerDivideSpelling::Div) => "DIV",
1170 BinaryOperator::IntegerDivide(IntegerDivideSpelling::SlashSlash) => "//",
1171 BinaryOperator::Exponent => "^",
1174 BinaryOperator::StringConcat => "||",
1175 BinaryOperator::Contains => "@>",
1176 BinaryOperator::ContainedBy => "<@",
1177 BinaryOperator::Overlap => "&&",
1178 BinaryOperator::JsonGet => "->",
1179 BinaryOperator::JsonGetText => "->>",
1180 BinaryOperator::JsonExists => "?",
1181 BinaryOperator::JsonExistsAny => "?|",
1182 BinaryOperator::JsonExistsAll => "?&",
1183 BinaryOperator::JsonPathExists => "@?",
1184 BinaryOperator::JsonPathMatch => "@@",
1185 BinaryOperator::JsonExtractPath => "#>",
1186 BinaryOperator::JsonExtractPathText => "#>>",
1187 BinaryOperator::JsonDeletePath => "#-",
1188 BinaryOperator::BitwiseOr => "|",
1189 BinaryOperator::BitwiseAnd => "&",
1190 BinaryOperator::BitwiseShiftLeft => "<<",
1191 BinaryOperator::BitwiseShiftRight => ">>",
1192 BinaryOperator::BitwiseXor(BitwiseXorSpelling::Hash) => "#",
1195 BinaryOperator::BitwiseXor(BitwiseXorSpelling::Caret) => "^",
1196 BinaryOperator::Eq(EqualsSpelling::Single) => "=",
1199 BinaryOperator::Eq(EqualsSpelling::Double) => "==",
1200 BinaryOperator::NotEq(NotEqSpelling::Bang) if honours_source_spelling(ctx) => "!=",
1206 BinaryOperator::NotEq(_) => "<>",
1207 BinaryOperator::Lt => "<",
1208 BinaryOperator::LtEq => "<=",
1209 BinaryOperator::Gt => ">",
1210 BinaryOperator::GtEq => ">=",
1211 BinaryOperator::IsDistinctFrom(IsDistinctFromSpelling::Keyword) => "IS DISTINCT FROM",
1214 BinaryOperator::IsDistinctFrom(IsDistinctFromSpelling::Is) => "IS NOT",
1215 BinaryOperator::IsNotDistinctFrom(IsNotDistinctFromSpelling::Keyword) => {
1220 "IS NOT DISTINCT FROM"
1221 }
1222 BinaryOperator::IsNotDistinctFrom(IsNotDistinctFromSpelling::NullSafeEq) => "<=>",
1223 BinaryOperator::IsNotDistinctFrom(IsNotDistinctFromSpelling::Is) => "IS",
1224 BinaryOperator::Regexp(RegexpSpelling::Rlike) => "RLIKE",
1225 BinaryOperator::Regexp(RegexpSpelling::Regexp) => "REGEXP",
1226 BinaryOperator::Glob => "GLOB",
1227 BinaryOperator::StartsWith => "^@",
1228 BinaryOperator::Match => "MATCH",
1229 BinaryOperator::Overlaps => "OVERLAPS",
1230 BinaryOperator::And => "AND",
1231 BinaryOperator::Xor => "XOR",
1232 BinaryOperator::Or => "OR",
1233 })
1234 }
1235}
1236
1237impl Render for UnaryOperator {
1238 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1239 f.write_str(match self {
1240 UnaryOperator::Not => "NOT",
1241 UnaryOperator::Minus => "-",
1242 UnaryOperator::Plus => "+",
1243 UnaryOperator::BitwiseNot => "~",
1244 UnaryOperator::Prior => "PRIOR",
1245 })
1246 }
1247}
1248
1249impl Render for SetOperator {
1250 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1251 f.write_str(match self {
1252 SetOperator::Union => "UNION",
1253 SetOperator::Intersect => "INTERSECT",
1254 SetOperator::Except => "EXCEPT",
1255 })
1256 }
1257}
1258
1259impl Render for Quantifier {
1260 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1261 f.write_str(match self {
1262 Quantifier::Any => "ANY",
1263 Quantifier::All => "ALL",
1264 Quantifier::Some => "SOME",
1265 })
1266 }
1267}
1268
1269impl Render for SetQuantifier {
1270 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1271 f.write_str(match self {
1272 SetQuantifier::All => "ALL",
1273 SetQuantifier::Distinct => "DISTINCT",
1274 })
1275 }
1276}
1277
1278impl<X: Extension + Render> Render for Expr<X> {
1283 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1284 match self {
1285 Expr::Column { name, .. } => name.render(ctx, f),
1286 Expr::Literal { literal, .. } => literal.render(ctx, f),
1287 Expr::BinaryOp {
1288 left, op, right, ..
1289 } => {
1290 let full = ctx.mode() == RenderMode::Parenthesized;
1291 open_group(full, f)?;
1292 render_operand(
1293 left,
1294 binary_child_needs_parens(&ctx.target().binding_powers, op, left, Side::Left),
1295 ctx,
1296 f,
1297 )?;
1298 f.write_str(" ")?;
1299 op.render(ctx, f)?;
1300 f.write_str(" ")?;
1301 render_operand(
1302 right,
1303 binary_child_needs_parens(&ctx.target().binding_powers, op, right, Side::Right),
1304 ctx,
1305 f,
1306 )?;
1307 close_group(full, f)
1308 }
1309 Expr::UnaryOp { op, expr, .. } => {
1310 let full = ctx.mode() == RenderMode::Parenthesized;
1311 open_group(full, f)?;
1312 op.render(ctx, f)?;
1313 if matches!(op, UnaryOperator::Not | UnaryOperator::Prior) {
1316 f.write_str(" ")?;
1317 }
1318 render_operand(
1319 expr,
1320 prefix_operand_needs_parens(&ctx.target().binding_powers, op, expr),
1321 ctx,
1322 f,
1323 )?;
1324 close_group(full, f)
1325 }
1326 Expr::Function { call, .. } => call.render(ctx, f),
1327 Expr::Case { case, .. } => case.render(ctx, f),
1328 Expr::Extract { extract, .. } => extract.render(ctx, f),
1329 Expr::JsonFunc { json_func, .. } => json_func.render(ctx, f),
1330 Expr::JsonObject { json_object, .. } => json_object.render(ctx, f),
1331 Expr::JsonArray { json_array, .. } => json_array.render(ctx, f),
1332 Expr::JsonAggregate { json_aggregate, .. } => json_aggregate.render(ctx, f),
1333 Expr::JsonConstructor {
1334 json_constructor, ..
1335 } => json_constructor.render(ctx, f),
1336 Expr::IsJson { is_json, .. } => is_json.render(ctx, f),
1337 Expr::XmlFunc { xml_func, .. } => xml_func.render(ctx, f),
1338 Expr::StringFunc { string_func, .. } => string_func.render(ctx, f),
1339 Expr::IsDocument { expr, negated, .. } => {
1340 let full = ctx.mode() == RenderMode::Parenthesized;
1341 open_group(full, f)?;
1342 render_predicate_operand(
1343 expr,
1344 ctx.target().binding_powers.predicate(),
1345 Side::Left,
1346 ctx,
1347 f,
1348 )?;
1349 f.write_str(if *negated {
1350 " IS NOT DOCUMENT"
1351 } else {
1352 " IS DOCUMENT"
1353 })?;
1354 close_group(full, f)
1355 }
1356 Expr::Cast {
1357 expr,
1358 data_type,
1359 syntax,
1360 try_cast,
1361 ..
1362 } => match syntax {
1363 CastSyntax::Call => {
1366 f.write_str(if *try_cast { "TRY_CAST(" } else { "CAST(" })?;
1367 expr.render(ctx, f)?;
1368 f.write_str(" AS ")?;
1369 data_type.render(ctx, f)?;
1370 f.write_str(")")
1371 }
1372 CastSyntax::DoubleColon => {
1373 let full = ctx.mode() == RenderMode::Parenthesized;
1374 open_group(full, f)?;
1375 render_pg_operand(
1376 expr,
1377 ctx.target().binding_powers.typecast,
1378 Side::Left,
1379 ctx,
1380 f,
1381 )?;
1382 f.write_str("::")?;
1383 data_type.render(ctx, f)?;
1384 close_group(full, f)
1385 }
1386 CastSyntax::PrefixTyped => {
1391 data_type.render(ctx, f)?;
1392 f.write_str(" ")?;
1393 expr.render(ctx, f)
1394 }
1395 CastSyntax::Convert => {
1398 f.write_str("CONVERT(")?;
1399 expr.render(ctx, f)?;
1400 f.write_str(", ")?;
1401 data_type.render(ctx, f)?;
1402 f.write_str(")")
1403 }
1404 },
1405 Expr::IsNull {
1406 expr,
1407 negated,
1408 spelling,
1409 ..
1410 } => {
1411 let full = ctx.mode() == RenderMode::Parenthesized;
1412 open_group(full, f)?;
1413 render_predicate_operand(
1414 expr,
1415 ctx.target().binding_powers.predicate(),
1416 Side::Left,
1417 ctx,
1418 f,
1419 )?;
1420 f.write_str(match (spelling, negated) {
1421 (NullTestSpelling::Is, false) => " IS NULL",
1422 (NullTestSpelling::Is, true) => " IS NOT NULL",
1423 (NullTestSpelling::Postfix, false) => " ISNULL",
1424 (NullTestSpelling::Postfix, true) => " NOTNULL",
1425 (NullTestSpelling::PostfixNotNull, _) => " NOT NULL",
1427 })?;
1428 close_group(full, f)
1429 }
1430 Expr::IsTruth {
1431 expr,
1432 value,
1433 negated,
1434 ..
1435 } => {
1436 let full = ctx.mode() == RenderMode::Parenthesized;
1437 open_group(full, f)?;
1438 render_predicate_operand(
1439 expr,
1440 ctx.target().binding_powers.predicate(),
1441 Side::Left,
1442 ctx,
1443 f,
1444 )?;
1445 f.write_str(match (negated, value) {
1446 (false, TruthValue::True) => " IS TRUE",
1447 (true, TruthValue::True) => " IS NOT TRUE",
1448 (false, TruthValue::False) => " IS FALSE",
1449 (true, TruthValue::False) => " IS NOT FALSE",
1450 (false, TruthValue::Unknown) => " IS UNKNOWN",
1451 (true, TruthValue::Unknown) => " IS NOT UNKNOWN",
1452 })?;
1453 close_group(full, f)
1454 }
1455 Expr::IsNormalized {
1456 expr,
1457 form,
1458 negated,
1459 ..
1460 } => {
1461 let full = ctx.mode() == RenderMode::Parenthesized;
1462 open_group(full, f)?;
1463 render_predicate_operand(
1464 expr,
1465 ctx.target().binding_powers.predicate(),
1466 Side::Left,
1467 ctx,
1468 f,
1469 )?;
1470 f.write_str(if *negated { " IS NOT " } else { " IS " })?;
1471 if let Some(form) = form {
1472 f.write_str(match form {
1473 NormalizationForm::Nfc => "NFC ",
1474 NormalizationForm::Nfd => "NFD ",
1475 NormalizationForm::Nfkc => "NFKC ",
1476 NormalizationForm::Nfkd => "NFKD ",
1477 })?;
1478 }
1479 f.write_str("NORMALIZED")?;
1480 close_group(full, f)
1481 }
1482 Expr::Between {
1483 expr,
1484 low,
1485 high,
1486 negated,
1487 symmetric,
1488 ..
1489 } => {
1490 let full = ctx.mode() == RenderMode::Parenthesized;
1491 open_group(full, f)?;
1492 let range = ctx.target().binding_powers.range_predicate();
1493 render_predicate_operand(expr, range, Side::Left, ctx, f)?;
1494 f.write_str(if *negated {
1495 " NOT BETWEEN "
1496 } else {
1497 " BETWEEN "
1498 })?;
1499 if *symmetric {
1500 f.write_str("SYMMETRIC ")?;
1501 }
1502 render_predicate_operand(low, range, Side::Right, ctx, f)?;
1503 f.write_str(" AND ")?;
1504 render_predicate_operand(high, range, Side::Right, ctx, f)?;
1505 close_group(full, f)
1506 }
1507 Expr::Like {
1508 expr,
1509 pattern,
1510 escape,
1511 negated,
1512 spelling,
1513 ..
1514 } => {
1515 let full = ctx.mode() == RenderMode::Parenthesized;
1516 open_group(full, f)?;
1517 let range = ctx.target().binding_powers.range_predicate();
1518 render_predicate_operand(expr, range, Side::Left, ctx, f)?;
1519 f.write_str(match (negated, spelling) {
1520 (false, LikeSpelling::Like) => " LIKE ",
1521 (true, LikeSpelling::Like) => " NOT LIKE ",
1522 (false, LikeSpelling::ILike) => " ILIKE ",
1523 (true, LikeSpelling::ILike) => " NOT ILIKE ",
1524 (false, LikeSpelling::SimilarTo) => " SIMILAR TO ",
1525 (true, LikeSpelling::SimilarTo) => " NOT SIMILAR TO ",
1526 })?;
1527 render_predicate_operand(pattern, range, Side::Right, ctx, f)?;
1528 if let Some(escape) = escape {
1529 f.write_str(" ESCAPE ")?;
1530 render_predicate_operand(escape, range, Side::Right, ctx, f)?;
1531 }
1532 close_group(full, f)
1533 }
1534 Expr::InList {
1535 expr,
1536 list,
1537 negated,
1538 ..
1539 } => {
1540 let full = ctx.mode() == RenderMode::Parenthesized;
1541 open_group(full, f)?;
1542 render_predicate_operand(
1543 expr,
1544 ctx.target().binding_powers.range_predicate(),
1545 Side::Left,
1546 ctx,
1547 f,
1548 )?;
1549 f.write_str(if *negated { " NOT IN (" } else { " IN (" })?;
1550 render_comma_separated(list, ctx, f)?;
1551 f.write_str(")")?;
1552 close_group(full, f)
1553 }
1554 Expr::InSubquery {
1555 expr,
1556 subquery,
1557 negated,
1558 ..
1559 } => {
1560 let full = ctx.mode() == RenderMode::Parenthesized;
1561 open_group(full, f)?;
1562 render_predicate_operand(
1563 expr,
1564 ctx.target().binding_powers.range_predicate(),
1565 Side::Left,
1566 ctx,
1567 f,
1568 )?;
1569 f.write_str(if *negated { " NOT IN " } else { " IN " })?;
1570 render_query_in_parens(subquery, ctx, f)?;
1571 close_group(full, f)
1572 }
1573 Expr::InExpr {
1574 expr, rhs, negated, ..
1575 } => {
1576 let table = &ctx.target().binding_powers;
1581 let full = ctx.mode() == RenderMode::Parenthesized;
1582 open_group(full, f)?;
1583 render_operand(
1584 expr,
1585 operand_needs_parens(table, UNPARENTHESIZED_IN_LIST, expr, Side::Left),
1586 ctx,
1587 f,
1588 )?;
1589 f.write_str(if *negated { " NOT IN " } else { " IN " })?;
1590 render_operand(
1591 rhs,
1592 operand_needs_parens(table, UNPARENTHESIZED_IN_LIST, rhs, Side::Right),
1593 ctx,
1594 f,
1595 )?;
1596 close_group(full, f)
1597 }
1598 Expr::Exists { query, .. } => {
1599 let full = ctx.mode() == RenderMode::Parenthesized;
1600 open_group(full, f)?;
1601 f.write_str("EXISTS ")?;
1602 render_query_in_parens(query, ctx, f)?;
1603 close_group(full, f)
1604 }
1605 Expr::QuantifiedComparison {
1606 left,
1607 op,
1608 quantifier,
1609 subquery,
1610 ..
1611 } => {
1612 let full = ctx.mode() == RenderMode::Parenthesized;
1613 open_group(full, f)?;
1614 render_predicate_operand(
1615 left,
1616 ctx.target().binding_powers.comparison,
1617 Side::Left,
1618 ctx,
1619 f,
1620 )?;
1621 f.write_str(" ")?;
1622 op.render(ctx, f)?;
1623 f.write_str(" ")?;
1624 quantifier.render(ctx, f)?;
1625 f.write_str(" ")?;
1626 render_query_in_parens(subquery, ctx, f)?;
1627 close_group(full, f)
1628 }
1629 Expr::QuantifiedList {
1630 left,
1631 op,
1632 quantifier,
1633 array,
1634 ..
1635 } => {
1636 let full = ctx.mode() == RenderMode::Parenthesized;
1637 open_group(full, f)?;
1638 render_predicate_operand(
1639 left,
1640 ctx.target().binding_powers.comparison,
1641 Side::Left,
1642 ctx,
1643 f,
1644 )?;
1645 f.write_str(" ")?;
1646 op.render(ctx, f)?;
1647 f.write_str(" ")?;
1648 quantifier.render(ctx, f)?;
1649 f.write_str(" (")?;
1650 array.render(ctx, f)?;
1651 f.write_str(")")?;
1652 close_group(full, f)
1653 }
1654 Expr::QuantifiedLike {
1655 left,
1656 pattern,
1657 quantifier,
1658 negated,
1659 spelling,
1660 ..
1661 } => {
1662 let full = ctx.mode() == RenderMode::Parenthesized;
1663 open_group(full, f)?;
1664 render_predicate_operand(
1665 left,
1666 ctx.target().binding_powers.range_predicate(),
1667 Side::Left,
1668 ctx,
1669 f,
1670 )?;
1671 f.write_str(match (negated, spelling) {
1672 (false, LikeSpelling::Like) => " LIKE ",
1673 (true, LikeSpelling::Like) => " NOT LIKE ",
1674 (false, LikeSpelling::ILike) => " ILIKE ",
1675 (true, LikeSpelling::ILike) => " NOT ILIKE ",
1676 (false, LikeSpelling::SimilarTo) => " SIMILAR TO ",
1679 (true, LikeSpelling::SimilarTo) => " NOT SIMILAR TO ",
1680 })?;
1681 quantifier.render(ctx, f)?;
1682 f.write_str(" (")?;
1683 pattern.render(ctx, f)?;
1684 f.write_str(")")?;
1685 close_group(full, f)
1686 }
1687 Expr::Subquery { query, .. } => render_query_in_parens(query, ctx, f),
1688 Expr::Parameter { kind, .. } => match kind {
1689 ParameterKind::Positional(index) => write!(f, "${index}"),
1690 ParameterKind::Numbered(index) => write!(f, "?{index}"),
1691 ParameterKind::Anonymous => f.write_str("?"),
1692 ParameterKind::Named { name, sigil } => {
1697 let sigil = match sigil {
1698 ParameterSigil::Colon => ':',
1699 ParameterSigil::At => '@',
1700 ParameterSigil::Dollar => '$',
1701 };
1702 write!(f, "{sigil}{}", ctx.resolve(*name))
1703 }
1704 },
1705 Expr::PositionalColumn { index, .. } => write!(f, "#{index}"),
1709 Expr::SessionVariable { kind, name, .. } => {
1715 let prefix = match kind {
1716 SessionVariableKind::User => "@",
1717 SessionVariableKind::System => "@@",
1718 SessionVariableKind::SystemGlobal => "@@global.",
1719 SessionVariableKind::SystemSession => "@@session.",
1720 };
1721 write!(f, "{prefix}{}", ctx.resolve(*name))
1722 }
1723 Expr::Subscript { subscript, .. } => {
1724 let full = ctx.mode() == RenderMode::Parenthesized;
1725 open_group(full, f)?;
1726 let base_needs_parens = matches!(
1733 subscript.base,
1734 Expr::Cast {
1735 syntax: CastSyntax::DoubleColon,
1736 ..
1737 }
1738 ) || operand_needs_parens(
1739 &ctx.target().binding_powers,
1740 ctx.target().binding_powers.subscript,
1741 &subscript.base,
1742 Side::Left,
1743 );
1744 render_operand(&subscript.base, base_needs_parens, ctx, f)?;
1745 f.write_str("[")?;
1746 match subscript.kind {
1747 SubscriptKind::Index => {
1748 if let Some(index) = &subscript.lower {
1750 index.render(ctx, f)?;
1751 }
1752 }
1753 SubscriptKind::Slice => {
1754 if let Some(lower) = &subscript.lower {
1755 lower.render(ctx, f)?;
1756 }
1757 f.write_str(":")?;
1758 if let Some(upper) = &subscript.upper {
1759 upper.render(ctx, f)?;
1760 }
1761 }
1762 SubscriptKind::SliceWithStep => {
1763 if let Some(lower) = &subscript.lower {
1764 lower.render(ctx, f)?;
1765 }
1766 f.write_str(":")?;
1767 match &subscript.upper {
1770 Some(upper) => upper.render(ctx, f)?,
1771 None => f.write_str("-")?,
1772 }
1773 f.write_str(":")?;
1774 if let Some(step) = &subscript.step {
1775 step.render(ctx, f)?;
1776 }
1777 }
1778 }
1779 f.write_str("]")?;
1780 close_group(full, f)
1781 }
1782 Expr::SemiStructuredAccess {
1783 semi_structured_access,
1784 ..
1785 } => semi_structured_access.render(ctx, f),
1786 Expr::Collate { collate, .. } => {
1787 let full = ctx.mode() == RenderMode::Parenthesized;
1788 open_group(full, f)?;
1789 render_pg_operand(
1790 &collate.expr,
1791 ctx.target().binding_powers.collate,
1792 Side::Left,
1793 ctx,
1794 f,
1795 )?;
1796 f.write_str(" COLLATE ")?;
1797 collate.collation.render(ctx, f)?;
1798 close_group(full, f)
1799 }
1800 Expr::AtTimeZone { at_time_zone, .. } => {
1801 let full = ctx.mode() == RenderMode::Parenthesized;
1802 open_group(full, f)?;
1803 let bp = ctx.target().binding_powers.at_time_zone;
1804 render_pg_operand(&at_time_zone.expr, bp, Side::Left, ctx, f)?;
1805 f.write_str(" AT TIME ZONE ")?;
1806 render_pg_operand(&at_time_zone.zone, bp, Side::Right, ctx, f)?;
1809 close_group(full, f)
1810 }
1811 Expr::Interval { value, unit, .. } => {
1812 let full = ctx.mode() == RenderMode::Parenthesized;
1818 open_group(full, f)?;
1819 f.write_str("INTERVAL ")?;
1820 value.render(ctx, f)?;
1821 f.write_str(mysql_interval_unit_suffix(*unit))?;
1822 close_group(full, f)
1823 }
1824 Expr::Array { array, .. } => match &**array {
1825 ArrayExpr::Elements {
1826 elements, spelling, ..
1827 } => {
1828 f.write_str(match spelling {
1829 ArraySpelling::Keyword => "ARRAY[",
1830 ArraySpelling::Bracket => "[",
1831 })?;
1832 render_comma_separated(elements, ctx, f)?;
1833 f.write_str("]")
1834 }
1835 ArrayExpr::Subquery { query, .. } => {
1836 f.write_str("ARRAY")?;
1837 render_query_in_parens(query, ctx, f)
1838 }
1839 ArrayExpr::Comprehension { comprehension, .. } => {
1840 f.write_str("[")?;
1841 comprehension.element.render(ctx, f)?;
1842 f.write_str(" for ")?;
1843 render_ident_list(&comprehension.vars, ctx, f)?;
1844 f.write_str(" in ")?;
1845 render_comprehension_source(&comprehension.source, ctx, f)?;
1846 if let Some(filter) = &comprehension.filter {
1847 f.write_str(" if ")?;
1848 filter.render(ctx, f)?;
1849 }
1850 f.write_str("]")
1851 }
1852 },
1853 Expr::Struct { r#struct, .. } => {
1854 f.write_str("{")?;
1855 for (i, field) in r#struct.fields.iter().enumerate() {
1856 if i > 0 {
1857 f.write_str(", ")?;
1858 }
1859 field.render(ctx, f)?;
1860 }
1861 f.write_str("}")
1862 }
1863 Expr::StructConstructor { constructor, .. } => {
1864 f.write_str("STRUCT")?;
1865 if !constructor.fields.is_empty() {
1866 f.write_str("<")?;
1867 render_comma_separated(&constructor.fields, ctx, f)?;
1868 f.write_str(">")?;
1869 }
1870 f.write_str("(")?;
1871 render_comma_separated(&constructor.args, ctx, f)?;
1872 f.write_str(")")
1873 }
1874 Expr::Map { map, .. } => {
1875 f.write_str("MAP {")?;
1876 for (i, entry) in map.entries.iter().enumerate() {
1877 if i > 0 {
1878 f.write_str(", ")?;
1879 }
1880 entry.key.render(ctx, f)?;
1881 f.write_str(": ")?;
1882 entry.value.render(ctx, f)?;
1883 }
1884 f.write_str("}")
1885 }
1886 Expr::Row { row, .. } => {
1887 f.write_str(if row.explicit { "ROW(" } else { "(" })?;
1888 render_comma_separated(&row.fields, ctx, f)?;
1889 f.write_str(")")
1890 }
1891 Expr::FieldSelection {
1892 field_selection, ..
1893 } => {
1894 f.write_str("(")?;
1898 field_selection.base.render(ctx, f)?;
1899 f.write_str(").")?;
1900 match &field_selection.selector {
1901 FieldSelector::Field { field, .. } => field.render(ctx, f),
1902 FieldSelector::Star { .. } => f.write_str("*"),
1903 }
1904 }
1905 Expr::SpecialFunction {
1906 keyword, precision, ..
1907 } => {
1908 f.write_str(special_function_keyword(*keyword))?;
1909 if let Some(precision) = precision {
1910 write!(f, "({precision})")?;
1911 }
1912 Ok(())
1913 }
1914 Expr::NamedOperator { named_operator, .. } => render_extension_infix(
1923 ctx,
1924 f,
1925 ctx.target().binding_powers.any_operator,
1926 (&named_operator.left, &named_operator.right),
1927 |f| match named_operator.spelling {
1928 NamedOperatorSpelling::Bare => {
1929 f.write_str(" ")?;
1930 f.write_str(ctx.resolve(named_operator.op))?;
1931 f.write_str(" ")
1932 }
1933 NamedOperatorSpelling::OperatorKeyword => {
1934 f.write_str(" OPERATOR(")?;
1935 for part in &named_operator.schema.0 {
1936 part.render(ctx, f)?;
1937 f.write_str(".")?;
1938 }
1939 f.write_str(ctx.resolve(named_operator.op))?;
1940 f.write_str(") ")
1941 }
1942 },
1943 ),
1944 Expr::PrefixOperator {
1949 prefix_operator, ..
1950 } => render_extension_prefix(
1951 ctx,
1952 f,
1953 ctx.target().binding_powers.any_operator.left,
1954 |f| {
1955 f.write_str(ctx.resolve(prefix_operator.op))?;
1956 f.write_str(" ")
1957 },
1958 &prefix_operator.operand,
1959 ),
1960 Expr::PostfixOperator {
1964 postfix_operator, ..
1965 } => render_extension_postfix(
1966 ctx,
1967 f,
1968 ctx.target().binding_powers.any_operator,
1969 &postfix_operator.operand,
1970 |f| {
1971 f.write_str(" ")?;
1972 f.write_str(ctx.resolve(postfix_operator.op))
1973 },
1974 ),
1975 Expr::Lambda { lambda, .. } => {
1980 let full = ctx.mode() == RenderMode::Parenthesized;
1981 open_group(full, f)?;
1982 match lambda.spelling {
1983 LambdaParamSpelling::Keyword => {
1987 f.write_str("lambda ")?;
1988 render_comma_separated(&lambda.params, ctx, f)?;
1989 f.write_str(": ")?;
1990 lambda.body.render(ctx, f)?;
1991 }
1992 arrow => {
1993 match arrow {
1994 LambdaParamSpelling::Bare if lambda.params.len() == 1 => {
1998 lambda.params[0].render(ctx, f)?;
1999 }
2000 LambdaParamSpelling::RowKeyword => {
2001 f.write_str("ROW(")?;
2002 render_comma_separated(&lambda.params, ctx, f)?;
2003 f.write_str(")")?;
2004 }
2005 _ => {
2007 f.write_str("(")?;
2008 render_comma_separated(&lambda.params, ctx, f)?;
2009 f.write_str(")")?;
2010 }
2011 }
2012 f.write_str(" -> ")?;
2013 render_pg_operand(
2014 &lambda.body,
2015 ctx.target().binding_powers.binary(&BinaryOperator::JsonGet),
2016 Side::Right,
2017 ctx,
2018 f,
2019 )?;
2020 }
2021 }
2022 close_group(full, f)
2023 }
2024 Expr::Columns {
2031 qualifier,
2032 pattern,
2033 options,
2034 spelling,
2035 ..
2036 } => {
2037 if matches!(spelling, ColumnsSpelling::Star) {
2038 if let Some(qualifier) = qualifier {
2040 qualifier.render(ctx, f)?;
2041 f.write_str(".")?;
2042 }
2043 f.write_str("*")?;
2044 if let Some(options) = options {
2045 render_wildcard_options(options, ctx, f)?;
2046 }
2047 return Ok(());
2048 }
2049 if matches!(spelling, ColumnsSpelling::Unpack) {
2050 f.write_str("*")?;
2051 }
2052 f.write_str("COLUMNS(")?;
2053 match pattern {
2054 Some(pattern) => pattern.render(ctx, f)?,
2055 None => {
2056 if let Some(qualifier) = qualifier {
2057 qualifier.render(ctx, f)?;
2058 f.write_str(".")?;
2059 }
2060 f.write_str("*")?;
2061 if let Some(options) = options {
2062 render_wildcard_options(options, ctx, f)?;
2063 }
2064 }
2065 }
2066 f.write_str(")")
2067 }
2068 Expr::Other { ext, .. } => ext.render(ctx, f),
2069 }
2070 }
2071}
2072
2073fn special_function_keyword(keyword: SpecialFunctionKeyword) -> &'static str {
2075 match keyword {
2076 SpecialFunctionKeyword::CurrentCatalog => "CURRENT_CATALOG",
2077 SpecialFunctionKeyword::CurrentDate => "CURRENT_DATE",
2078 SpecialFunctionKeyword::CurrentRole => "CURRENT_ROLE",
2079 SpecialFunctionKeyword::CurrentSchema => "CURRENT_SCHEMA",
2080 SpecialFunctionKeyword::CurrentTime => "CURRENT_TIME",
2081 SpecialFunctionKeyword::CurrentTimestamp => "CURRENT_TIMESTAMP",
2082 SpecialFunctionKeyword::CurrentUser => "CURRENT_USER",
2083 SpecialFunctionKeyword::LocalTime => "LOCALTIME",
2084 SpecialFunctionKeyword::LocalTimestamp => "LOCALTIMESTAMP",
2085 SpecialFunctionKeyword::SessionUser => "SESSION_USER",
2086 SpecialFunctionKeyword::SystemUser => "SYSTEM_USER",
2087 SpecialFunctionKeyword::User => "USER",
2088 SpecialFunctionKeyword::UtcDate => "UTC_DATE",
2089 SpecialFunctionKeyword::UtcTime => "UTC_TIME",
2090 SpecialFunctionKeyword::UtcTimestamp => "UTC_TIMESTAMP",
2091 }
2092}
2093
2094fn open_group(group: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2095 if group {
2096 f.write_str("(")?;
2097 }
2098 Ok(())
2099}
2100
2101fn close_group(group: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2102 if group {
2103 f.write_str(")")?;
2104 }
2105 Ok(())
2106}
2107
2108fn render_operand<X: Extension + Render>(
2114 child: &Expr<X>,
2115 canonical_parens: bool,
2116 ctx: &RenderCtx<'_>,
2117 f: &mut fmt::Formatter<'_>,
2118) -> fmt::Result {
2119 let wrap = match ctx.mode() {
2120 RenderMode::Parenthesized => false,
2121 RenderMode::Canonical | RenderMode::Redacted => canonical_parens,
2122 };
2123 open_group(wrap, f)?;
2124 child.render(ctx, f)?;
2125 close_group(wrap, f)
2126}
2127
2128fn render_predicate_operand<X: Extension + Render>(
2143 child: &Expr<X>,
2144 parent: BindingPower,
2145 side: Side,
2146 ctx: &RenderCtx<'_>,
2147 f: &mut fmt::Formatter<'_>,
2148) -> fmt::Result {
2149 render_operand(
2150 child,
2151 operand_needs_parens(&ctx.target().binding_powers, parent, child, side),
2152 ctx,
2153 f,
2154 )
2155}
2156
2157fn render_query_in_parens<X: Extension + Render>(
2158 query: &Query<X>,
2159 ctx: &RenderCtx<'_>,
2160 f: &mut fmt::Formatter<'_>,
2161) -> fmt::Result {
2162 f.write_str("(")?;
2163 query.render(ctx, f)?;
2164 f.write_str(")")
2165}
2166
2167fn binary_child_needs_parens<X: Extension + Render>(
2179 bp: &BindingPowerTable,
2180 parent: &BinaryOperator,
2181 child: &Expr<X>,
2182 side: Side,
2183) -> bool {
2184 match child {
2185 Expr::BinaryOp { op, .. } => bp.needs_parens(parent, op, side),
2186 Expr::UnaryOp { op, .. } => match side {
2187 Side::Right => false,
2188 Side::Left => bp.prefix(op) < bp.binary(parent).left,
2189 },
2190 Expr::Between { .. }
2191 | Expr::Like { .. }
2192 | Expr::QuantifiedLike { .. }
2193 | Expr::InList { .. }
2194 | Expr::InSubquery { .. } => {
2195 needs_parens_between(bp.binary(parent), bp.range_predicate(), side)
2196 }
2197 Expr::IsNull { .. } | Expr::IsTruth { .. } | Expr::IsNormalized { .. } => {
2198 needs_parens_between(bp.binary(parent), bp.predicate(), side)
2199 }
2200 Expr::QuantifiedComparison { .. } => {
2203 needs_parens_between(bp.binary(parent), bp.comparison, side)
2204 }
2205 Expr::InExpr { .. } => {
2206 needs_parens_between(bp.binary(parent), UNPARENTHESIZED_IN_LIST, side)
2207 }
2208 Expr::NamedOperator { .. } => {
2209 needs_parens_between(bp.binary(parent), bp.any_operator, side)
2210 }
2211 Expr::PrefixOperator { .. } => match side {
2212 Side::Right => false,
2213 Side::Left => bp.any_operator.left < bp.binary(parent).left,
2214 },
2215 Expr::PostfixOperator { .. } => match side {
2218 Side::Left => false,
2219 Side::Right => bp.any_operator.left < bp.binary(parent).right,
2220 },
2221 Expr::Lambda { .. } => {
2224 needs_parens_between(bp.binary(parent), bp.binary(&BinaryOperator::JsonGet), side)
2225 }
2226 Expr::Other { ext, .. } => match ext.operand_binding_power() {
2227 Some(child) => needs_parens_between(bp.binary(parent), child, side),
2228 None => false,
2229 },
2230 _ => false,
2231 }
2232}
2233
2234fn prefix_operand_needs_parens<X: Extension + Render>(
2244 bp: &BindingPowerTable,
2245 op: &UnaryOperator,
2246 operand: &Expr<X>,
2247) -> bool {
2248 match operand {
2249 Expr::BinaryOp { op: child, .. } => bp.binary(child).left < bp.prefix(op),
2250 Expr::UnaryOp { op: inner, .. } => is_sign(op) && is_sign(inner),
2251 Expr::Between { .. }
2252 | Expr::Like { .. }
2253 | Expr::QuantifiedLike { .. }
2254 | Expr::InList { .. }
2255 | Expr::InSubquery { .. } => bp.range_predicate().left < bp.prefix(op),
2256 Expr::IsNull { .. } | Expr::IsTruth { .. } | Expr::IsNormalized { .. } => {
2257 bp.predicate().left < bp.prefix(op)
2258 }
2259 Expr::QuantifiedComparison { .. } => bp.comparison.left < bp.prefix(op),
2262 Expr::InExpr { .. } => UNPARENTHESIZED_IN_LIST.left < bp.prefix(op),
2263 Expr::NamedOperator { .. } => bp.any_operator.left < bp.prefix(op),
2264 Expr::PrefixOperator { .. } => bp.any_operator.left < bp.prefix(op),
2267 Expr::PostfixOperator { .. } => bp.any_operator.left < bp.prefix(op),
2270 Expr::Lambda { .. } => bp.binary(&BinaryOperator::JsonGet).left < bp.prefix(op),
2272 Expr::Other { ext, .. } => ext
2273 .operand_binding_power()
2274 .is_some_and(|child| child.left < bp.prefix(op)),
2275 _ => false,
2276 }
2277}
2278
2279fn is_sign(op: &UnaryOperator) -> bool {
2280 matches!(op, UnaryOperator::Minus | UnaryOperator::Plus)
2281}
2282
2283fn render_pg_operand<X: Extension + Render>(
2287 child: &Expr<X>,
2288 parent: BindingPower,
2289 side: Side,
2290 ctx: &RenderCtx<'_>,
2291 f: &mut fmt::Formatter<'_>,
2292) -> fmt::Result {
2293 let canonical = operand_needs_parens(&ctx.target().binding_powers, parent, child, side);
2294 render_operand(child, canonical, ctx, f)
2295}
2296
2297fn operand_needs_parens<X: Extension + Render>(
2311 bp: &BindingPowerTable,
2312 parent: BindingPower,
2313 child: &Expr<X>,
2314 side: Side,
2315) -> bool {
2316 let child_bp = match child {
2317 Expr::BinaryOp { op, .. } => bp.binary(op),
2318 Expr::UnaryOp { op, .. } => {
2319 return side == Side::Left && bp.prefix(op) < parent.left;
2320 }
2321 Expr::Between { .. }
2322 | Expr::Like { .. }
2323 | Expr::QuantifiedLike { .. }
2324 | Expr::InList { .. }
2325 | Expr::InSubquery { .. } => bp.range_predicate(),
2326 Expr::IsNull { .. } | Expr::IsTruth { .. } | Expr::IsNormalized { .. } => bp.predicate(),
2327 Expr::QuantifiedComparison { .. } => bp.comparison,
2330 Expr::InExpr { .. } => UNPARENTHESIZED_IN_LIST,
2331 Expr::Cast {
2332 syntax: CastSyntax::DoubleColon,
2333 ..
2334 } => bp.typecast,
2335 Expr::Subscript { .. } => bp.subscript,
2336 Expr::Collate { .. } => bp.collate,
2337 Expr::AtTimeZone { .. } => bp.at_time_zone,
2338 Expr::FieldSelection { .. } => bp.field_selection,
2339 Expr::NamedOperator { .. } => bp.any_operator,
2342 Expr::PrefixOperator { .. } => {
2345 return side == Side::Left && bp.any_operator.left < parent.left;
2346 }
2347 Expr::PostfixOperator { .. } => {
2350 return side == Side::Right && bp.any_operator.left < parent.right;
2351 }
2352 Expr::Lambda { .. } => bp.binary(&BinaryOperator::JsonGet),
2354 Expr::Other { ext, .. } => match ext.operand_binding_power() {
2355 Some(child_bp) => child_bp,
2356 None => return false,
2357 },
2358 _ => return false,
2359 };
2360 needs_parens_between(parent, child_bp, side)
2361}
2362
2363pub fn render_extension_infix<X: Extension + Render>(
2380 ctx: &RenderCtx<'_>,
2381 f: &mut fmt::Formatter<'_>,
2382 bp: BindingPower,
2383 operands: (&Expr<X>, &Expr<X>),
2384 op: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
2385) -> fmt::Result {
2386 let (left, right) = operands;
2387 let table = &ctx.target().binding_powers;
2388 let full = ctx.mode() == RenderMode::Parenthesized;
2389 open_group(full, f)?;
2390 render_operand(
2391 left,
2392 operand_needs_parens(table, bp, left, Side::Left),
2393 ctx,
2394 f,
2395 )?;
2396 op(f)?;
2397 render_operand(
2398 right,
2399 operand_needs_parens(table, bp, right, Side::Right),
2400 ctx,
2401 f,
2402 )?;
2403 close_group(full, f)
2404}
2405
2406pub fn render_extension_prefix<X: Extension + Render>(
2413 ctx: &RenderCtx<'_>,
2414 f: &mut fmt::Formatter<'_>,
2415 bp: u8,
2416 op: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
2417 operand: &Expr<X>,
2418) -> fmt::Result {
2419 let full = ctx.mode() == RenderMode::Parenthesized;
2420 open_group(full, f)?;
2421 op(f)?;
2422 render_operand(
2423 operand,
2424 prefix_extension_operand_needs_parens(&ctx.target().binding_powers, bp, operand),
2425 ctx,
2426 f,
2427 )?;
2428 close_group(full, f)
2429}
2430
2431pub fn render_extension_postfix<X: Extension + Render>(
2442 ctx: &RenderCtx<'_>,
2443 f: &mut fmt::Formatter<'_>,
2444 bp: BindingPower,
2445 operand: &Expr<X>,
2446 op: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
2447) -> fmt::Result {
2448 let table = &ctx.target().binding_powers;
2449 let full = ctx.mode() == RenderMode::Parenthesized;
2450 open_group(full, f)?;
2451 render_operand(
2452 operand,
2453 operand_needs_parens(table, bp, operand, Side::Left),
2454 ctx,
2455 f,
2456 )?;
2457 op(f)?;
2458 close_group(full, f)
2459}
2460
2461fn prefix_extension_operand_needs_parens<X: Extension + Render>(
2467 table: &BindingPowerTable,
2468 bp: u8,
2469 operand: &Expr<X>,
2470) -> bool {
2471 match operand {
2472 Expr::BinaryOp { op, .. } => table.binary(op).left < bp,
2473 Expr::IsNull { .. } | Expr::IsTruth { .. } | Expr::IsNormalized { .. } => {
2474 table.predicate().left < bp
2475 }
2476 Expr::Between { .. }
2479 | Expr::Like { .. }
2480 | Expr::QuantifiedLike { .. }
2481 | Expr::InList { .. }
2482 | Expr::InSubquery { .. } => table.range_predicate().left < bp,
2483 Expr::QuantifiedComparison { .. } => table.comparison.left < bp,
2484 Expr::InExpr { .. } => UNPARENTHESIZED_IN_LIST.left < bp,
2485 Expr::NamedOperator { .. } => table.any_operator.left < bp,
2486 Expr::PrefixOperator { .. } => table.any_operator.left < bp,
2487 Expr::PostfixOperator { .. } => table.any_operator.left < bp,
2488 Expr::Lambda { .. } => table.binary(&BinaryOperator::JsonGet).left < bp,
2490 Expr::Other { ext, .. } => ext
2491 .operand_binding_power()
2492 .is_some_and(|child| child.left < bp),
2493 _ => false,
2494 }
2495}
2496
2497impl<X: Extension + Render> Render for Statement<X> {
2502 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2503 match self {
2504 Statement::Query { query, .. } => query.render(ctx, f),
2505 Statement::CreateTable { create, .. } => create.render(ctx, f),
2506 Statement::AlterTable { alter, .. } => alter.render(ctx, f),
2507 Statement::Drop { drop, .. } => drop.render(ctx, f),
2508 Statement::CreateSchema { schema, .. } => schema.render(ctx, f),
2509 Statement::CreateView { view, .. } => view.render(ctx, f),
2510 Statement::AlterView { alter, .. } => alter.render(ctx, f),
2511 Statement::CreateIndex { index, .. } => index.render(ctx, f),
2512 Statement::CreateFunction { create, .. } => create.render(ctx, f),
2513 Statement::CreateProcedure { create, .. } => create.render(ctx, f),
2514 Statement::AlterRoutine { alter, .. } => alter.render(ctx, f),
2515 Statement::CreateEvent { create, .. } => create.render(ctx, f),
2516 Statement::AlterEvent { alter, .. } => alter.render(ctx, f),
2517 Statement::DropEvent { drop, .. } => drop.render(ctx, f),
2518 Statement::DropDatabase { drop, .. } => drop.render(ctx, f),
2519 Statement::DropIndex { drop, .. } => drop.render(ctx, f),
2520 Statement::CreateDatabase { create, .. } => create.render(ctx, f),
2521 Statement::DropRoutine {
2522 kind,
2523 if_exists,
2524 routines,
2525 behavior,
2526 ..
2527 } => {
2528 f.write_str("DROP ")?;
2529 kind.render(ctx, f)?;
2530 if *if_exists {
2531 f.write_str(" IF EXISTS")?;
2532 }
2533 f.write_str(" ")?;
2534 render_comma_separated(routines, ctx, f)?;
2535 render_drop_behavior(*behavior, ctx, f)
2536 }
2537 Statement::DropTransform { drop, .. } => drop.render(ctx, f),
2538 Statement::Truncate {
2539 tables,
2540 table_keyword,
2541 restart_identity,
2542 behavior,
2543 ..
2544 } => {
2545 if *table_keyword || !honours_source_spelling(ctx) {
2548 f.write_str("TRUNCATE TABLE ")?;
2549 } else {
2550 f.write_str("TRUNCATE ")?;
2551 }
2552 render_comma_separated(tables, ctx, f)?;
2553 match restart_identity {
2554 Some(true) => f.write_str(" RESTART IDENTITY")?,
2555 Some(false) => f.write_str(" CONTINUE IDENTITY")?,
2556 None => {}
2557 }
2558 render_drop_behavior(*behavior, ctx, f)
2559 }
2560 Statement::CommentOn { comment, .. } => {
2561 let CommentOnStatement {
2562 target,
2563 name,
2564 comment,
2565 ..
2566 } = comment.as_ref();
2567 f.write_str("COMMENT ON ")?;
2568 f.write_str(match target {
2569 CommentTarget::Table => "TABLE ",
2570 CommentTarget::Column => "COLUMN ",
2571 CommentTarget::Database => "DATABASE ",
2572 CommentTarget::Procedure { .. } => "PROCEDURE ",
2573 })?;
2574 name.render(ctx, f)?;
2575 if let CommentTarget::Procedure {
2576 arg_types: Some(arg_types),
2577 } = target
2578 {
2579 f.write_str("(")?;
2580 render_comma_separated(arg_types, ctx, f)?;
2581 f.write_str(")")?;
2582 }
2583 f.write_str(" IS ")?;
2584 match comment {
2585 Some(literal) => literal.render(ctx, f)?,
2586 None => f.write_str("NULL")?,
2587 }
2588 Ok(())
2589 }
2590 Statement::Insert { insert, .. } => insert.render(ctx, f),
2591 Statement::Update { update, .. } => update.render(ctx, f),
2592 Statement::Delete { delete, .. } => delete.render(ctx, f),
2593 Statement::Merge { merge, .. } => merge.render(ctx, f),
2594 Statement::Transaction { transaction, .. } => transaction.render(ctx, f),
2595 Statement::Xa { xa, .. } => xa.render(ctx, f),
2596 Statement::Session { session, .. } => session.render(ctx, f),
2597 Statement::AccessControl { access, .. } => access.render(ctx, f),
2598 Statement::Copy { copy, .. } => copy.render(ctx, f),
2599 Statement::CopyInto { copy, .. } => copy.render(ctx, f),
2600 Statement::Export { export, .. } => export.render(ctx, f),
2601 Statement::Import { import, .. } => import.render(ctx, f),
2602 Statement::Explain { explain, .. } => explain.render(ctx, f),
2603 Statement::Describe { describe, .. } => describe.render(ctx, f),
2604 Statement::Show { show, .. } => show.render(ctx, f),
2605 Statement::Kill { kill, .. } => kill.render(ctx, f),
2606 Statement::Handler { handler, .. } => handler.render(ctx, f),
2607 Statement::Install { install, .. } => install.render(ctx, f),
2608 Statement::Uninstall { uninstall, .. } => uninstall.render(ctx, f),
2609 Statement::Shutdown { .. } => f.write_str("SHUTDOWN"),
2610 Statement::Restart { .. } => f.write_str("RESTART"),
2611 Statement::Clone { clone, .. } => clone.render(ctx, f),
2612 Statement::ImportTable { import_table, .. } => import_table.render(ctx, f),
2613 Statement::Help { help, .. } => help.render(ctx, f),
2614 Statement::Binlog { binlog, .. } => binlog.render(ctx, f),
2615 Statement::Pragma { pragma, .. } => pragma.render(ctx, f),
2616 Statement::Attach { attach, .. } => attach.render(ctx, f),
2617 Statement::Detach { detach, .. } => detach.render(ctx, f),
2618 Statement::Checkpoint { checkpoint, .. } => checkpoint.render(ctx, f),
2619 Statement::Load { load, .. } => load.render(ctx, f),
2620 Statement::LoadData { load_data, .. } => load_data.render(ctx, f),
2621 Statement::UpdateExtensions {
2622 update_extensions, ..
2623 } => update_extensions.render(ctx, f),
2624 Statement::Vacuum { vacuum, .. } => vacuum.render(ctx, f),
2625 Statement::Reindex { reindex, .. } => reindex.render(ctx, f),
2626 Statement::Analyze { analyze, .. } => analyze.render(ctx, f),
2627 Statement::TableMaintenance {
2628 table_maintenance, ..
2629 } => table_maintenance.render(ctx, f),
2630 Statement::CacheIndex { cache_index, .. } => cache_index.render(ctx, f),
2631 Statement::LoadIndex { load_index, .. } => load_index.render(ctx, f),
2632 Statement::Rename { rename, .. } => rename.render(ctx, f),
2633 Statement::Flush { flush, .. } => flush.render(ctx, f),
2634 Statement::Purge { purge, .. } => purge.render(ctx, f),
2635 Statement::Replication { replication, .. } => replication.render(ctx, f),
2636 Statement::CreateUser { create, .. } => create.render(ctx, f),
2637 Statement::AlterUser { alter, .. } => alter.render(ctx, f),
2638 Statement::UserRoleList { statement, .. } => statement.render(ctx, f),
2639 Statement::Use { use_statement, .. } => use_statement.render(ctx, f),
2640 Statement::CreateTrigger { create, .. } => create.render(ctx, f),
2641 Statement::CreateStoredTrigger { create, .. } => create.render(ctx, f),
2642 Statement::CreateMacro { create, .. } => create.render(ctx, f),
2643 Statement::CreateSecret { create, .. } => create.render(ctx, f),
2644 Statement::DropSecret { drop, .. } => drop.render(ctx, f),
2645 Statement::CreateType { create, .. } => create.render(ctx, f),
2646 Statement::CreateVirtualTable { create, .. } => create.render(ctx, f),
2647 Statement::CreateSequence { create, .. } => create.render(ctx, f),
2648 Statement::CreateExtension { create, .. } => create.render(ctx, f),
2649 Statement::AlterExtension { alter, .. } => alter.render(ctx, f),
2650 Statement::CreateTablespace { create, .. } => create.render(ctx, f),
2651 Statement::AlterTablespace { alter, .. } => alter.render(ctx, f),
2652 Statement::DropTablespace { drop, .. } => drop.render(ctx, f),
2653 Statement::CreateLogfileGroup { create, .. } => create.render(ctx, f),
2654 Statement::AlterLogfileGroup { alter, .. } => alter.render(ctx, f),
2655 Statement::DropLogfileGroup { drop, .. } => drop.render(ctx, f),
2656 Statement::AlterObjectDepends { alter, .. } => alter.render(ctx, f),
2657 Statement::AlterSystem { alter, .. } => alter.render(ctx, f),
2658 Statement::AlterDatabase { alter, .. } => alter.render(ctx, f),
2659 Statement::AlterDatabaseOptions { alter, .. } => alter.render(ctx, f),
2660 Statement::CreateServer { create, .. } => create.render(ctx, f),
2661 Statement::AlterServer { alter, .. } => alter.render(ctx, f),
2662 Statement::DropServer { drop, .. } => drop.render(ctx, f),
2663 Statement::AlterInstance { alter, .. } => alter.render(ctx, f),
2664 Statement::CreateSpatialReferenceSystem { create, .. } => create.render(ctx, f),
2665 Statement::DropSpatialReferenceSystem { drop, .. } => drop.render(ctx, f),
2666 Statement::CreateResourceGroup { create, .. } => create.render(ctx, f),
2667 Statement::AlterResourceGroup { alter, .. } => alter.render(ctx, f),
2668 Statement::DropResourceGroup { drop, .. } => drop.render(ctx, f),
2669 Statement::AlterSequence { alter, .. } => alter.render(ctx, f),
2670 Statement::AlterObjectSchema { alter, .. } => alter.render(ctx, f),
2671 Statement::Pivot { pivot, .. } => pivot.render(ctx, f),
2672 Statement::Unpivot { unpivot, .. } => unpivot.render(ctx, f),
2673 Statement::ShowRef { show, .. } => show.render(ctx, f),
2677 Statement::Prepare { prepare, .. } => prepare.render(ctx, f),
2678 Statement::Execute { execute, .. } => execute.render(ctx, f),
2679 Statement::PrepareFrom { prepare_from, .. } => prepare_from.render(ctx, f),
2680 Statement::ExecuteUsing { execute_using, .. } => execute_using.render(ctx, f),
2681 Statement::Deallocate { deallocate, .. } => deallocate.render(ctx, f),
2682 Statement::Call { call, .. } => call.render(ctx, f),
2683 Statement::Do { do_block, .. } => do_block.render(ctx, f),
2684 Statement::DoExpressions { do_expressions, .. } => do_expressions.render(ctx, f),
2685 Statement::LockTables { lock_tables, .. } => lock_tables.render(ctx, f),
2686 Statement::UnlockTables { unlock_tables, .. } => unlock_tables.render(ctx, f),
2687 Statement::InstanceLock { instance_lock, .. } => instance_lock.render(ctx, f),
2688 Statement::Compound { compound, .. } => compound.render(ctx, f),
2689 Statement::If { if_statement, .. } => if_statement.render(ctx, f),
2690 Statement::Case { case_statement, .. } => case_statement.render(ctx, f),
2691 Statement::Loop { loop_statement, .. } => loop_statement.render(ctx, f),
2692 Statement::While {
2693 while_statement, ..
2694 } => while_statement.render(ctx, f),
2695 Statement::Repeat { repeat, .. } => repeat.render(ctx, f),
2696 Statement::Leave { leave, .. } => leave.render(ctx, f),
2697 Statement::Iterate { iterate, .. } => iterate.render(ctx, f),
2698 Statement::Return {
2699 return_statement, ..
2700 } => return_statement.render(ctx, f),
2701 Statement::OpenCursor { open, .. } => open.render(ctx, f),
2702 Statement::FetchCursor { fetch, .. } => fetch.render(ctx, f),
2703 Statement::CloseCursor { close, .. } => close.render(ctx, f),
2704 Statement::Signal { signal, .. } => signal.render_as(ctx, f, "SIGNAL"),
2705 Statement::Resignal { resignal, .. } => resignal.render_as(ctx, f, "RESIGNAL"),
2706 Statement::GetDiagnostics {
2707 get_diagnostics, ..
2708 } => get_diagnostics.render(ctx, f),
2709 Statement::Other { ext, .. } => ext.render(ctx, f),
2710 }
2711 }
2712}
2713
2714impl<X: Extension + Render> Render for Insert<X> {
2715 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2716 if let Some(with) = &self.with {
2717 with.render(ctx, f)?;
2718 f.write_str(" ")?;
2719 }
2720 f.write_str(match self.verb {
2726 InsertVerb::Insert => "INSERT",
2727 InsertVerb::Replace => "REPLACE",
2728 })?;
2729 if let Some(or_action) = self.or_action {
2730 f.write_str(" OR ")?;
2731 or_action.render(ctx, f)?;
2732 }
2733 f.write_str(" INTO ")?;
2734 self.target.render(ctx, f)?;
2735 if let Some(mode) = self.column_matching {
2736 f.write_str(match mode {
2737 InsertColumnMatching::ByName => " BY NAME",
2738 InsertColumnMatching::ByPosition => " BY POSITION",
2739 })?;
2740 }
2741 if let Some(overriding) = self.overriding {
2742 f.write_str(" ")?;
2743 overriding.render(ctx, f)?;
2744 }
2745 f.write_str(" ")?;
2746 self.source.render(ctx, f)?;
2747 render_table_alias(self.row_alias.as_ref(), ctx, f)?;
2750 if let Some(upsert) = &self.upsert {
2751 f.write_str(" ")?;
2752 upsert.render(ctx, f)?;
2753 }
2754 render_returning_clause(self.returning.as_ref(), ctx, f)
2755 }
2756}
2757
2758impl Render for InsertTarget {
2759 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2760 self.name.render(ctx, f)?;
2761 render_alias(self.alias.as_ref(), self.alias_spelling, ctx, f)?;
2762 if !self.columns.is_empty() {
2763 f.write_str(" (")?;
2764 render_ident_list(&self.columns, ctx, f)?;
2765 f.write_str(")")?;
2766 }
2767 Ok(())
2768 }
2769}
2770
2771impl Render for InsertOverriding {
2772 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2773 f.write_str(match self {
2774 Self::SystemValue => "OVERRIDING SYSTEM VALUE",
2775 Self::UserValue => "OVERRIDING USER VALUE",
2776 })
2777 }
2778}
2779
2780impl Render for ConflictResolution {
2781 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2782 f.write_str(match self {
2783 Self::Rollback => "ROLLBACK",
2784 Self::Abort => "ABORT",
2785 Self::Fail => "FAIL",
2786 Self::Ignore => "IGNORE",
2787 Self::Replace => "REPLACE",
2788 })
2789 }
2790}
2791
2792impl<X: Extension + Render> Render for InsertSource<X> {
2793 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2794 match self {
2795 Self::DefaultValues { default, .. } => {
2796 default.render(ctx, f)?;
2797 f.write_str(" VALUES")
2798 }
2799 Self::Values { values, .. } => values.render(ctx, f),
2800 Self::Query { query, .. } => query.render(ctx, f),
2801 Self::Set { assignments, .. } => {
2802 f.write_str("SET ")?;
2803 render_update_assignments(assignments, ctx, f)
2804 }
2805 }
2806 }
2807}
2808
2809impl<X: Extension + Render> Render for InsertValues<X> {
2810 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2811 f.write_str("VALUES ")?;
2813 render_values_rows(&self.rows, false, ctx, f)
2814 }
2815}
2816
2817impl<X: Extension + Render> Render for InsertValue<X> {
2818 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2819 match self {
2820 Self::Expr { expr, .. } => expr.render(ctx, f),
2821 Self::Default { default, .. } => default.render(ctx, f),
2822 }
2823 }
2824}
2825
2826impl Render for DefaultValue {
2827 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2828 f.write_str("DEFAULT")
2829 }
2830}
2831
2832impl Render for DmlTarget {
2833 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2834 render_relation_inheritance(&self.inheritance, &self.name, ctx, f)?;
2835 render_alias(self.alias.as_ref(), self.alias_spelling, ctx, f)
2836 }
2837}
2838
2839impl<X: Extension + Render> Render for Update<X> {
2840 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2841 if let Some(with) = &self.with {
2842 with.render(ctx, f)?;
2843 f.write_str(" ")?;
2844 }
2845 f.write_str("UPDATE")?;
2846 if let Some(or_action) = self.or_action {
2847 f.write_str(" OR ")?;
2848 or_action.render(ctx, f)?;
2849 }
2850 f.write_str(" ")?;
2851 self.target.render(ctx, f)?;
2852 f.write_str(" SET ")?;
2853 render_update_assignments(&self.assignments, ctx, f)?;
2854 if !self.from.is_empty() {
2855 f.write_str(" FROM ")?;
2856 render_comma_separated(&self.from, ctx, f)?;
2857 }
2858 render_dml_selection(self.selection.as_ref(), ctx, f)?;
2859 render_mutation_order_by_limit(&self.order_by, self.limit.as_ref(), ctx, f)?;
2860 render_returning_clause(self.returning.as_ref(), ctx, f)
2861 }
2862}
2863
2864impl<X: Extension + Render> Render for UpdateAssignment<X> {
2865 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2866 match self {
2867 Self::Single { target, value, .. } => {
2868 target.render(ctx, f)?;
2869 f.write_str(" = ")?;
2870 value.render(ctx, f)
2871 }
2872 Self::Tuple {
2873 targets, source, ..
2874 } => {
2875 f.write_str("(")?;
2876 render_comma_separated(targets, ctx, f)?;
2877 f.write_str(") = ")?;
2878 source.render(ctx, f)
2879 }
2880 }
2881 }
2882}
2883
2884impl<X: Extension + Render> Render for UpdateValue<X> {
2885 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2886 match self {
2887 Self::Expr { expr, .. } => expr.render(ctx, f),
2888 Self::Default { default, .. } => default.render(ctx, f),
2889 }
2890 }
2891}
2892
2893impl<X: Extension + Render> Render for UpdateTupleSource<X> {
2894 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2895 match self {
2896 Self::Row {
2897 explicit, values, ..
2898 } => {
2899 f.write_str(if *explicit { "ROW(" } else { "(" })?;
2900 render_comma_separated(values, ctx, f)?;
2901 f.write_str(")")
2902 }
2903 Self::Subquery { query, .. } => {
2904 f.write_str("(")?;
2905 query.render(ctx, f)?;
2906 f.write_str(")")
2907 }
2908 Self::Default { default, .. } => default.render(ctx, f),
2909 }
2910 }
2911}
2912
2913impl<X: Extension + Render> Render for Delete<X> {
2914 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2915 if let Some(with) = &self.with {
2916 with.render(ctx, f)?;
2917 f.write_str(" ")?;
2918 }
2919 f.write_str("DELETE FROM ")?;
2920 self.target.render(ctx, f)?;
2921 if !self.using.is_empty() {
2922 f.write_str(" USING ")?;
2923 render_comma_separated(&self.using, ctx, f)?;
2924 }
2925 render_dml_selection(self.selection.as_ref(), ctx, f)?;
2926 render_mutation_order_by_limit(&self.order_by, self.limit.as_ref(), ctx, f)?;
2927 render_returning_clause(self.returning.as_ref(), ctx, f)
2928 }
2929}
2930
2931fn render_update_assignments<X: Extension + Render>(
2938 assignments: &[UpdateAssignment<X>],
2939 ctx: &RenderCtx<'_>,
2940 f: &mut fmt::Formatter<'_>,
2941) -> fmt::Result {
2942 for (i, assignment) in assignments.iter().enumerate() {
2943 if i > 0 {
2944 f.write_str(", ")?;
2945 }
2946 assignment.render(ctx, f)?;
2947 }
2948 Ok(())
2949}
2950
2951fn render_dml_selection<X: Extension + Render>(
2952 selection: Option<&DmlSelection<X>>,
2953 ctx: &RenderCtx<'_>,
2954 f: &mut fmt::Formatter<'_>,
2955) -> fmt::Result {
2956 if let Some(selection) = selection {
2957 f.write_str(" WHERE ")?;
2958 selection.render(ctx, f)?;
2959 }
2960 Ok(())
2961}
2962
2963impl<X: Extension + Render> Render for DmlSelection<X> {
2964 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2965 match self {
2966 Self::Where { condition, .. } => condition.render(ctx, f),
2967 Self::CurrentOf { cursor, .. } => {
2968 f.write_str("CURRENT OF ")?;
2969 cursor.render(ctx, f)
2970 }
2971 }
2972 }
2973}
2974
2975fn render_mutation_order_by_limit<X: Extension + Render>(
2979 order_by: &[OrderByExpr<X>],
2980 limit: Option<&Limit<X>>,
2981 ctx: &RenderCtx<'_>,
2982 f: &mut fmt::Formatter<'_>,
2983) -> fmt::Result {
2984 if !order_by.is_empty() {
2985 f.write_str(" ORDER BY ")?;
2986 render_comma_separated(order_by, ctx, f)?;
2987 }
2988 if let Some(limit) = limit {
2989 f.write_str(" ")?;
2990 limit.render(ctx, f)?;
2991 }
2992 Ok(())
2993}
2994
2995fn render_returning_clause<X: Extension + Render>(
2998 returning: Option<&Returning<X>>,
2999 ctx: &RenderCtx<'_>,
3000 f: &mut fmt::Formatter<'_>,
3001) -> fmt::Result {
3002 if let Some(returning) = returning {
3003 f.write_str(" ")?;
3004 returning.render(ctx, f)?;
3005 }
3006 Ok(())
3007}
3008
3009impl<X: Extension + Render> Render for Returning<X> {
3010 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3011 f.write_str("RETURNING ")?;
3012 render_comma_separated(&self.items, ctx, f)
3013 }
3014}
3015
3016impl<X: Extension + Render> Render for Upsert<X> {
3017 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3018 match self {
3019 Upsert::OnConflict { conflict, .. } => conflict.render(ctx, f),
3020 Upsert::OnDuplicateKeyUpdate { assignments, .. } => {
3021 f.write_str("ON DUPLICATE KEY UPDATE ")?;
3022 render_update_assignments(assignments, ctx, f)
3023 }
3024 }
3025 }
3026}
3027
3028impl<X: Extension + Render> Render for OnConflict<X> {
3029 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3030 f.write_str("ON CONFLICT")?;
3031 if let Some(target) = &self.target {
3032 f.write_str(" ")?;
3033 target.render(ctx, f)?;
3034 }
3035 f.write_str(" ")?;
3036 self.action.render(ctx, f)
3037 }
3038}
3039
3040impl<X: Extension + Render> Render for ConflictTarget<X> {
3041 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3042 match self {
3043 ConflictTarget::Index {
3044 columns, predicate, ..
3045 } => {
3046 f.write_str("(")?;
3047 render_comma_separated(columns, ctx, f)?;
3048 f.write_str(")")?;
3049 if let Some(predicate) = predicate {
3050 f.write_str(" WHERE ")?;
3051 predicate.render(ctx, f)?;
3052 }
3053 Ok(())
3054 }
3055 ConflictTarget::Constraint { name, .. } => {
3056 f.write_str("ON CONSTRAINT ")?;
3057 name.render(ctx, f)
3058 }
3059 }
3060 }
3061}
3062
3063impl<X: Extension + Render> Render for ConflictAction<X> {
3064 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3065 match self {
3066 ConflictAction::Nothing { .. } => f.write_str("DO NOTHING"),
3067 ConflictAction::Update {
3068 assignments,
3069 selection,
3070 ..
3071 } => {
3072 f.write_str("DO UPDATE SET ")?;
3073 render_update_assignments(assignments, ctx, f)?;
3074 if let Some(selection) = selection {
3075 f.write_str(" WHERE ")?;
3076 selection.render(ctx, f)?;
3077 }
3078 Ok(())
3079 }
3080 }
3081 }
3082}
3083
3084impl<X: Extension + Render> Render for Merge<X> {
3085 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3086 if let Some(with) = &self.with {
3087 with.render(ctx, f)?;
3088 f.write_str(" ")?;
3089 }
3090 f.write_str("MERGE INTO ")?;
3091 self.target.render(ctx, f)?;
3092 f.write_str(" USING ")?;
3093 self.using.render(ctx, f)?;
3094 f.write_str(" ON ")?;
3095 self.on.render(ctx, f)?;
3096 for clause in &self.clauses {
3097 f.write_str(" ")?;
3098 clause.render(ctx, f)?;
3099 }
3100 render_returning_clause(self.returning.as_ref(), ctx, f)
3101 }
3102}
3103
3104impl<X: Extension + Render> Render for MergeWhenClause<X> {
3105 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3106 f.write_str(match self.match_kind {
3110 MergeMatchKind::Matched => "WHEN MATCHED",
3111 MergeMatchKind::NotMatchedByTarget => "WHEN NOT MATCHED",
3112 MergeMatchKind::NotMatchedBySource => "WHEN NOT MATCHED BY SOURCE",
3113 })?;
3114 if let Some(condition) = &self.condition {
3115 f.write_str(" AND ")?;
3116 condition.render(ctx, f)?;
3117 }
3118 f.write_str(" THEN ")?;
3119 self.action.render(ctx, f)
3120 }
3121}
3122
3123impl<X: Extension + Render> Render for MergeAction<X> {
3124 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3125 match self {
3126 MergeAction::Insert {
3127 columns,
3128 overriding,
3129 values,
3130 ..
3131 } => {
3132 f.write_str("INSERT")?;
3133 if !columns.is_empty() {
3134 f.write_str(" (")?;
3135 render_ident_list(columns, ctx, f)?;
3136 f.write_str(")")?;
3137 }
3138 if let Some(overriding) = overriding {
3139 f.write_str(" ")?;
3140 overriding.render(ctx, f)?;
3141 }
3142 f.write_str(" VALUES (")?;
3143 render_comma_separated(values, ctx, f)?;
3144 f.write_str(")")
3145 }
3146 MergeAction::InsertDefault { default, .. } => {
3147 f.write_str("INSERT ")?;
3148 default.render(ctx, f)?;
3149 f.write_str(" VALUES")
3150 }
3151 MergeAction::Update { assignments, .. } => {
3152 f.write_str("UPDATE SET ")?;
3153 render_update_assignments(assignments, ctx, f)
3154 }
3155 MergeAction::UpdateStar { .. } => f.write_str("UPDATE SET *"),
3156 MergeAction::InsertStar { .. } => f.write_str("INSERT *"),
3157 MergeAction::InsertByName { star, .. } => {
3158 f.write_str("INSERT BY NAME")?;
3159 if *star {
3160 f.write_str(" *")?;
3161 }
3162 Ok(())
3163 }
3164 MergeAction::Error { .. } => f.write_str("ERROR"),
3165 MergeAction::Delete { .. } => f.write_str("DELETE"),
3166 MergeAction::DoNothing { .. } => f.write_str("DO NOTHING"),
3167 }
3168 }
3169}
3170
3171impl Render for TransactionStatement {
3172 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3173 match self {
3174 Self::Begin {
3175 syntax,
3176 mode,
3177 block,
3178 modes,
3179 ..
3180 } => {
3181 f.write_str(match syntax {
3182 TransactionStart::Begin => "BEGIN",
3183 TransactionStart::Start => "START TRANSACTION",
3184 })?;
3185 if let Some(mode) = mode {
3186 f.write_str(" ")?;
3187 mode.render(ctx, f)?;
3188 }
3189 if *syntax == TransactionStart::Begin && honours_source_spelling(ctx) {
3194 render_transaction_block_keyword(*block, f)?;
3195 }
3196 render_transaction_modes(modes, ctx, f)
3197 }
3198 Self::Commit { block, .. } => {
3199 f.write_str("COMMIT")?;
3200 if honours_source_spelling(ctx) {
3201 render_transaction_block_keyword(*block, f)?;
3202 }
3203 Ok(())
3204 }
3205 Self::Rollback {
3206 block,
3207 savepoint_keyword,
3208 to_savepoint,
3209 ..
3210 } => {
3211 f.write_str("ROLLBACK")?;
3212 if honours_source_spelling(ctx) {
3213 render_transaction_block_keyword(*block, f)?;
3214 }
3215 if let Some(name) = to_savepoint {
3216 if *savepoint_keyword || !honours_source_spelling(ctx) {
3220 f.write_str(" TO SAVEPOINT ")?;
3221 } else {
3222 f.write_str(" TO ")?;
3223 }
3224 name.render(ctx, f)?;
3225 }
3226 Ok(())
3227 }
3228 Self::Savepoint { name, .. } => {
3229 f.write_str("SAVEPOINT ")?;
3230 name.render(ctx, f)
3231 }
3232 Self::Release {
3233 savepoint_keyword,
3234 savepoint,
3235 ..
3236 } => {
3237 if *savepoint_keyword || !honours_source_spelling(ctx) {
3240 f.write_str("RELEASE SAVEPOINT ")?;
3241 } else {
3242 f.write_str("RELEASE ")?;
3243 }
3244 savepoint.render(ctx, f)
3245 }
3246 Self::SetCharacteristics { modes, .. } => {
3247 f.write_str("SET TRANSACTION")?;
3248 render_transaction_modes(modes, ctx, f)
3249 }
3250 }
3251 }
3252}
3253
3254fn render_transaction_block_keyword(
3259 block: Option<TransactionBlockKeyword>,
3260 f: &mut fmt::Formatter<'_>,
3261) -> fmt::Result {
3262 match block {
3263 Some(TransactionBlockKeyword::Transaction) => f.write_str(" TRANSACTION"),
3264 Some(TransactionBlockKeyword::Work) => f.write_str(" WORK"),
3265 None => Ok(()),
3266 }
3267}
3268
3269fn render_transaction_modes(
3272 modes: &[TransactionMode],
3273 ctx: &RenderCtx<'_>,
3274 f: &mut fmt::Formatter<'_>,
3275) -> fmt::Result {
3276 render_leading_space_comma_separated(modes, ctx, f)
3277}
3278
3279impl Render for TransactionModeKind {
3280 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3281 f.write_str(match self {
3282 Self::Deferred => "DEFERRED",
3283 Self::Immediate => "IMMEDIATE",
3284 Self::Exclusive => "EXCLUSIVE",
3285 })
3286 }
3287}
3288
3289impl Render for TransactionMode {
3290 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3291 match self {
3292 Self::IsolationLevel { level, .. } => {
3293 f.write_str("ISOLATION LEVEL ")?;
3294 level.render(ctx, f)
3295 }
3296 Self::AccessMode { access, .. } => access.render(ctx, f),
3297 Self::Deferrable { deferrable, .. } => f.write_str(if *deferrable {
3298 "DEFERRABLE"
3299 } else {
3300 "NOT DEFERRABLE"
3301 }),
3302 }
3303 }
3304}
3305
3306impl Render for IsolationLevel {
3307 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3308 f.write_str(match self {
3309 Self::ReadUncommitted => "READ UNCOMMITTED",
3310 Self::ReadCommitted => "READ COMMITTED",
3311 Self::RepeatableRead => "REPEATABLE READ",
3312 Self::Serializable => "SERIALIZABLE",
3313 })
3314 }
3315}
3316
3317impl Render for TransactionAccessMode {
3318 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3319 f.write_str(match self {
3320 Self::ReadOnly => "READ ONLY",
3321 Self::ReadWrite => "READ WRITE",
3322 })
3323 }
3324}
3325
3326impl Render for XaStatement {
3327 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3328 match self {
3329 Self::Start {
3330 keyword,
3331 xid,
3332 association,
3333 ..
3334 } => {
3335 f.write_str(match keyword {
3336 XaStartKeyword::Start => "XA START ",
3337 XaStartKeyword::Begin => "XA BEGIN ",
3338 })?;
3339 xid.render(ctx, f)?;
3340 if let Some(association) = association {
3341 f.write_str(match association {
3342 XaAssociation::Join => " JOIN",
3343 XaAssociation::Resume => " RESUME",
3344 })?;
3345 }
3346 Ok(())
3347 }
3348 Self::End { xid, suspend, .. } => {
3349 f.write_str("XA END ")?;
3350 xid.render(ctx, f)?;
3351 if let Some(suspend) = suspend {
3352 f.write_str(match suspend {
3353 XaSuspend::Suspend => " SUSPEND",
3354 XaSuspend::SuspendForMigrate => " SUSPEND FOR MIGRATE",
3355 })?;
3356 }
3357 Ok(())
3358 }
3359 Self::Prepare { xid, .. } => {
3360 f.write_str("XA PREPARE ")?;
3361 xid.render(ctx, f)
3362 }
3363 Self::Commit { xid, one_phase, .. } => {
3364 f.write_str("XA COMMIT ")?;
3365 xid.render(ctx, f)?;
3366 if *one_phase {
3367 f.write_str(" ONE PHASE")?;
3368 }
3369 Ok(())
3370 }
3371 Self::Rollback { xid, .. } => {
3372 f.write_str("XA ROLLBACK ")?;
3373 xid.render(ctx, f)
3374 }
3375 Self::Recover { convert_xid, .. } => {
3376 f.write_str("XA RECOVER")?;
3377 if *convert_xid {
3378 f.write_str(" CONVERT XID")?;
3379 }
3380 Ok(())
3381 }
3382 }
3383 }
3384}
3385
3386impl Render for Xid {
3387 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3388 self.gtrid.render(ctx, f)?;
3389 if let Some(bqual) = &self.bqual {
3390 f.write_str(", ")?;
3391 bqual.render(ctx, f)?;
3392 }
3393 if let Some(format_id) = &self.format_id {
3394 f.write_str(", ")?;
3395 format_id.render(ctx, f)?;
3396 }
3397 Ok(())
3398 }
3399}
3400
3401impl<X: Extension + Render> Render for SessionStatement<X> {
3402 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3403 match self {
3404 Self::Set {
3405 scope,
3406 name,
3407 assignment,
3408 value,
3409 ..
3410 } => {
3411 f.write_str("SET")?;
3412 render_set_scope(*scope, ctx, f)?;
3413 f.write_str(" ")?;
3414 name.render(ctx, f)?;
3415 f.write_str(match assignment {
3418 SetAssignment::Equals if honours_source_spelling(ctx) => " = ",
3419 _ => " TO ",
3420 })?;
3421 value.render(ctx, f)
3422 }
3423 Self::SetTimeZone { scope, value, .. } => {
3424 f.write_str("SET")?;
3425 render_set_scope(*scope, ctx, f)?;
3426 f.write_str(" TIME ZONE ")?;
3427 value.render(ctx, f)
3428 }
3429 Self::SetRole { scope, role, .. } => {
3430 f.write_str("SET")?;
3431 render_set_scope(*scope, ctx, f)?;
3432 f.write_str(" ROLE ")?;
3433 role.render(ctx, f)
3434 }
3435 Self::SetSessionAuthorization { scope, user, .. } => {
3436 f.write_str("SET")?;
3437 render_set_scope(*scope, ctx, f)?;
3438 f.write_str(" SESSION AUTHORIZATION ")?;
3439 user.render(ctx, f)
3440 }
3441 Self::SetConstraints {
3442 constraints,
3443 check_time,
3444 ..
3445 } => {
3446 f.write_str("SET CONSTRAINTS ")?;
3447 constraints.render(ctx, f)?;
3448 f.write_str(" ")?;
3449 check_time.render(ctx, f)
3450 }
3451 Self::SetNames { value, .. } => {
3452 f.write_str("SET NAMES ")?;
3453 value.render(ctx, f)
3454 }
3455 Self::SetSessionCharacteristics { modes, .. } => {
3456 f.write_str("SET SESSION CHARACTERISTICS AS TRANSACTION")?;
3457 render_transaction_modes(modes, ctx, f)
3458 }
3459 Self::Reset { scope, target, .. } => {
3460 f.write_str("RESET")?;
3461 render_set_scope(*scope, ctx, f)?;
3462 f.write_str(" ")?;
3463 target.render(ctx, f)
3464 }
3465 Self::Show {
3466 target, verbose, ..
3467 } => {
3468 f.write_str("SHOW ")?;
3469 target.render(ctx, f)?;
3470 if *verbose {
3471 f.write_str(" VERBOSE")?;
3472 }
3473 Ok(())
3474 }
3475 Self::SetVariables { assignments, .. } => {
3476 f.write_str("SET ")?;
3477 render_comma_separated(assignments, ctx, f)
3478 }
3479 Self::SetCharacterSet { keyword, value, .. } => {
3480 f.write_str(match keyword {
3481 CharacterSetKeyword::CharacterSet => "SET CHARACTER SET ",
3482 CharacterSetKeyword::Charset => "SET CHARSET ",
3483 })?;
3484 value.render(ctx, f)
3485 }
3486 Self::SetResourceGroup {
3487 name, thread_ids, ..
3488 } => {
3489 f.write_str("SET RESOURCE GROUP ")?;
3490 name.render(ctx, f)?;
3491 if let Some(thread_ids) = thread_ids {
3492 f.write_str(" FOR ")?;
3493 render_comma_separated(thread_ids, ctx, f)?;
3494 }
3495 Ok(())
3496 }
3497 }
3498 }
3499}
3500
3501impl<X: Extension + Render> Render for SetVariableAssignment<X> {
3502 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3503 match self {
3504 Self::SystemVariable {
3505 scope,
3506 name,
3507 assignment,
3508 value,
3509 ..
3510 } => {
3511 scope.render_prefix(name, ctx, f)?;
3512 render_mysql_set_assignment(*assignment, ctx, f)?;
3513 value.render(ctx, f)
3514 }
3515 Self::UserVariable {
3516 name,
3517 assignment,
3518 value,
3519 ..
3520 } => {
3521 f.write_str("@")?;
3522 name.render(ctx, f)?;
3523 render_mysql_set_assignment(*assignment, ctx, f)?;
3524 value.render(ctx, f)
3525 }
3526 }
3527 }
3528}
3529
3530fn render_mysql_set_assignment(
3534 assignment: SetAssignment,
3535 ctx: &RenderCtx<'_>,
3536 f: &mut fmt::Formatter<'_>,
3537) -> fmt::Result {
3538 f.write_str(match assignment {
3539 SetAssignment::ColonEquals if honours_source_spelling(ctx) => " := ",
3540 _ => " = ",
3541 })
3542}
3543
3544impl SystemVariableScope {
3545 fn render_prefix(
3548 self,
3549 name: &ObjectName,
3550 ctx: &RenderCtx<'_>,
3551 f: &mut fmt::Formatter<'_>,
3552 ) -> fmt::Result {
3553 match self {
3554 Self::Implicit => name.render(ctx, f),
3555 Self::Keyword(kind) => {
3556 kind.render(ctx, f)?;
3557 f.write_str(" ")?;
3558 name.render(ctx, f)
3559 }
3560 Self::AtAt => {
3561 f.write_str("@@")?;
3562 name.render(ctx, f)
3563 }
3564 Self::AtAtScoped(kind) => {
3565 f.write_str("@@")?;
3568 f.write_str(kind.at_at_prefix())?;
3569 f.write_str(".")?;
3570 name.render(ctx, f)
3571 }
3572 }
3573 }
3574}
3575
3576impl SystemVariableScopeKind {
3577 fn at_at_prefix(self) -> &'static str {
3580 match self {
3581 Self::Global => "global",
3582 Self::Session => "session",
3583 Self::Local => "local",
3584 Self::Persist => "persist",
3585 Self::PersistOnly => "persist_only",
3586 }
3587 }
3588}
3589
3590impl Render for SystemVariableScopeKind {
3591 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3593 f.write_str(match self {
3594 Self::Global => "GLOBAL",
3595 Self::Session => "SESSION",
3596 Self::Local => "LOCAL",
3597 Self::Persist => "PERSIST",
3598 Self::PersistOnly => "PERSIST_ONLY",
3599 })
3600 }
3601}
3602
3603impl<X: Extension + Render> Render for SetVariableValue<X> {
3604 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3605 match self {
3606 Self::Default { .. } => f.write_str("DEFAULT"),
3607 Self::Keyword { keyword, .. } => keyword.render(ctx, f),
3608 Self::Expr { expr, .. } => expr.render(ctx, f),
3609 }
3610 }
3611}
3612
3613impl Render for SetVariableKeyword {
3614 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3615 f.write_str(match self {
3616 Self::On => "ON",
3617 Self::All => "ALL",
3618 Self::Binary => "BINARY",
3619 Self::Row => "ROW",
3620 Self::System => "SYSTEM",
3621 })
3622 }
3623}
3624
3625impl Render for SetCharacterSetValue {
3626 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3627 match self {
3628 Self::Default { .. } => f.write_str("DEFAULT"),
3629 Self::Charset { charset, .. } => charset.render(ctx, f),
3630 }
3631 }
3632}
3633
3634impl Render for AlterSystem {
3635 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3636 f.write_str("ALTER SYSTEM ")?;
3637 match &self.action {
3638 AlterSystemAction::Set {
3639 name,
3640 assignment,
3641 value,
3642 ..
3643 } => {
3644 f.write_str("SET ")?;
3645 name.render(ctx, f)?;
3646 f.write_str(match assignment {
3649 SetAssignment::Equals if honours_source_spelling(ctx) => " = ",
3650 _ => " TO ",
3651 })?;
3652 value.render(ctx, f)
3653 }
3654 AlterSystemAction::Reset { target, .. } => {
3655 f.write_str("RESET ")?;
3656 target.render(ctx, f)
3657 }
3658 }
3659 }
3660}
3661
3662impl Render for AlterDatabase {
3663 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3664 f.write_str("ALTER DATABASE ")?;
3665 if self.if_exists {
3666 f.write_str("IF EXISTS ")?;
3667 }
3668 self.name.render(ctx, f)?;
3669 match &self.action {
3670 AlterDatabaseAction::SetAlias { new_name, .. } => {
3671 f.write_str(" SET ALIAS TO ")?;
3672 new_name.render(ctx, f)
3673 }
3674 }
3675 }
3676}
3677
3678impl Render for AlterDatabaseOptions {
3679 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3680 f.write_str(match self.spelling {
3681 DatabaseKeyword::Database => "ALTER DATABASE",
3682 DatabaseKeyword::Schema => "ALTER SCHEMA",
3683 })?;
3684 if let Some(name) = &self.name {
3685 f.write_str(" ")?;
3686 name.render(ctx, f)?;
3687 }
3688 for option in &self.options {
3689 f.write_str(" ")?;
3690 option.render(ctx, f)?;
3691 }
3692 Ok(())
3693 }
3694}
3695
3696impl Render for AlterDatabaseOption {
3697 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3698 let sep = |equals: bool| if equals { " = " } else { " " };
3701 match self {
3702 Self::CharacterSet {
3703 default,
3704 keyword,
3705 equals,
3706 charset,
3707 ..
3708 } => {
3709 if *default {
3710 f.write_str("DEFAULT ")?;
3711 }
3712 f.write_str(match keyword {
3713 CharsetKeyword::CharacterSet => "CHARACTER SET",
3714 CharsetKeyword::Charset => "CHARSET",
3715 })?;
3716 f.write_str(sep(*equals))?;
3717 charset.render(ctx, f)
3718 }
3719 Self::Collate {
3720 default,
3721 equals,
3722 collation,
3723 ..
3724 } => {
3725 if *default {
3726 f.write_str("DEFAULT ")?;
3727 }
3728 f.write_str("COLLATE")?;
3729 f.write_str(sep(*equals))?;
3730 collation.render(ctx, f)
3731 }
3732 Self::Encryption {
3733 default,
3734 equals,
3735 value,
3736 ..
3737 } => {
3738 if *default {
3739 f.write_str("DEFAULT ")?;
3740 }
3741 f.write_str("ENCRYPTION")?;
3742 f.write_str(sep(*equals))?;
3743 value.render(ctx, f)
3744 }
3745 Self::ReadOnly { equals, value, .. } => {
3746 f.write_str("READ ONLY")?;
3747 f.write_str(sep(*equals))?;
3748 f.write_str(match value {
3749 ReadOnlyValue::Default => "DEFAULT",
3750 ReadOnlyValue::Off => "0",
3751 ReadOnlyValue::On => "1",
3752 })
3753 }
3754 }
3755 }
3756}
3757
3758impl Render for CreateServer {
3759 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3760 f.write_str("CREATE SERVER ")?;
3761 self.name.render(ctx, f)?;
3762 f.write_str(" FOREIGN DATA WRAPPER ")?;
3763 self.wrapper.render(ctx, f)?;
3764 f.write_str(" OPTIONS (")?;
3765 render_server_options(&self.options, ctx, f)?;
3766 f.write_str(")")
3767 }
3768}
3769
3770impl Render for AlterServer {
3771 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3772 f.write_str("ALTER SERVER ")?;
3773 self.name.render(ctx, f)?;
3774 f.write_str(" OPTIONS (")?;
3775 render_server_options(&self.options, ctx, f)?;
3776 f.write_str(")")
3777 }
3778}
3779
3780impl Render for DropServer {
3781 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3782 f.write_str("DROP SERVER ")?;
3783 if self.if_exists {
3784 f.write_str("IF EXISTS ")?;
3785 }
3786 self.name.render(ctx, f)
3787 }
3788}
3789
3790fn render_server_options(
3793 options: &[ServerOption],
3794 ctx: &RenderCtx<'_>,
3795 f: &mut fmt::Formatter<'_>,
3796) -> fmt::Result {
3797 for (i, option) in options.iter().enumerate() {
3798 if i > 0 {
3799 f.write_str(", ")?;
3800 }
3801 option.render(ctx, f)?;
3802 }
3803 Ok(())
3804}
3805
3806impl Render for ServerOption {
3807 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3808 f.write_str(match self.kind {
3809 ServerOptionKind::Host => "HOST ",
3810 ServerOptionKind::Database => "DATABASE ",
3811 ServerOptionKind::User => "USER ",
3812 ServerOptionKind::Password => "PASSWORD ",
3813 ServerOptionKind::Socket => "SOCKET ",
3814 ServerOptionKind::Owner => "OWNER ",
3815 ServerOptionKind::Port => "PORT ",
3816 })?;
3817 self.value.render(ctx, f)
3818 }
3819}
3820
3821impl Render for CreateSpatialReferenceSystem {
3822 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3823 f.write_str("CREATE ")?;
3824 if self.or_replace {
3825 f.write_str("OR REPLACE ")?;
3826 }
3827 f.write_str("SPATIAL REFERENCE SYSTEM ")?;
3828 if self.if_not_exists {
3829 f.write_str("IF NOT EXISTS ")?;
3830 }
3831 self.srid.render(ctx, f)?;
3832 for attribute in &self.attributes {
3833 f.write_str(" ")?;
3834 attribute.render(ctx, f)?;
3835 }
3836 Ok(())
3837 }
3838}
3839
3840impl Render for SrsAttribute {
3841 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3842 match self {
3843 Self::Name { value, .. } => {
3844 f.write_str("NAME ")?;
3845 value.render(ctx, f)
3846 }
3847 Self::Definition { value, .. } => {
3848 f.write_str("DEFINITION ")?;
3849 value.render(ctx, f)
3850 }
3851 Self::Organization {
3852 organization,
3853 identifier,
3854 ..
3855 } => {
3856 f.write_str("ORGANIZATION ")?;
3857 organization.render(ctx, f)?;
3858 f.write_str(" IDENTIFIED BY ")?;
3859 identifier.render(ctx, f)
3860 }
3861 Self::Description { value, .. } => {
3862 f.write_str("DESCRIPTION ")?;
3863 value.render(ctx, f)
3864 }
3865 }
3866 }
3867}
3868
3869impl Render for DropSpatialReferenceSystem {
3870 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3871 f.write_str("DROP SPATIAL REFERENCE SYSTEM ")?;
3872 if self.if_exists {
3873 f.write_str("IF EXISTS ")?;
3874 }
3875 self.srid.render(ctx, f)
3876 }
3877}
3878
3879impl Render for CreateResourceGroup {
3880 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3881 f.write_str("CREATE RESOURCE GROUP ")?;
3882 self.name.render(ctx, f)?;
3883 f.write_str(if self.type_equals {
3884 " TYPE = "
3885 } else {
3886 " TYPE "
3887 })?;
3888 self.group_type.render(ctx, f)?;
3889 if let Some(vcpu) = &self.vcpu {
3890 f.write_str(" ")?;
3891 vcpu.render(ctx, f)?;
3892 }
3893 if let Some(priority) = &self.thread_priority {
3894 f.write_str(" ")?;
3895 priority.render(ctx, f)?;
3896 }
3897 if let Some(state) = &self.state {
3898 f.write_str(" ")?;
3899 state.render(ctx, f)?;
3900 }
3901 Ok(())
3902 }
3903}
3904
3905impl Render for AlterResourceGroup {
3906 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3907 f.write_str("ALTER RESOURCE GROUP ")?;
3908 self.name.render(ctx, f)?;
3909 if let Some(vcpu) = &self.vcpu {
3910 f.write_str(" ")?;
3911 vcpu.render(ctx, f)?;
3912 }
3913 if let Some(priority) = &self.thread_priority {
3914 f.write_str(" ")?;
3915 priority.render(ctx, f)?;
3916 }
3917 if let Some(state) = &self.state {
3918 f.write_str(" ")?;
3919 state.render(ctx, f)?;
3920 }
3921 if self.force {
3922 f.write_str(" FORCE")?;
3923 }
3924 Ok(())
3925 }
3926}
3927
3928impl Render for DropResourceGroup {
3929 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3930 f.write_str("DROP RESOURCE GROUP ")?;
3931 self.name.render(ctx, f)?;
3932 if self.force {
3933 f.write_str(" FORCE")?;
3934 }
3935 Ok(())
3936 }
3937}
3938
3939impl Render for ResourceGroupType {
3940 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3941 f.write_str(match self {
3942 Self::System => "SYSTEM",
3943 Self::User => "USER",
3944 })
3945 }
3946}
3947
3948impl Render for ResourceGroupState {
3949 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3950 f.write_str(match self {
3951 Self::Enable => "ENABLE",
3952 Self::Disable => "DISABLE",
3953 })
3954 }
3955}
3956
3957impl Render for ResourceGroupVcpu {
3958 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3959 f.write_str(if self.equals { "VCPU = " } else { "VCPU " })?;
3960 for (i, range) in self.ranges.iter().enumerate() {
3961 if i > 0 {
3962 f.write_str(", ")?;
3963 }
3964 range.render(ctx, f)?;
3965 }
3966 Ok(())
3967 }
3968}
3969
3970impl Render for VcpuRange {
3971 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3972 self.start.render(ctx, f)?;
3973 if let Some(end) = &self.end {
3974 f.write_str("-")?;
3975 end.render(ctx, f)?;
3976 }
3977 Ok(())
3978 }
3979}
3980
3981impl Render for ResourceGroupThreadPriority {
3982 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3983 f.write_str(if self.equals {
3984 "THREAD_PRIORITY = "
3985 } else {
3986 "THREAD_PRIORITY "
3987 })?;
3988 if self.negative {
3989 f.write_str("-")?;
3990 }
3991 self.value.render(ctx, f)
3992 }
3993}
3994
3995impl Render for AlterInstance {
3996 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3997 f.write_str("ALTER INSTANCE ")?;
3998 self.action.render(ctx, f)
3999 }
4000}
4001
4002impl Render for AlterInstanceAction {
4003 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4004 match self {
4005 Self::RotateInnodbMasterKey { .. } => f.write_str("ROTATE INNODB MASTER KEY"),
4006 Self::RotateBinlogMasterKey { .. } => f.write_str("ROTATE BINLOG MASTER KEY"),
4007 Self::ReloadTls {
4008 channel,
4009 no_rollback_on_error,
4010 ..
4011 } => {
4012 f.write_str("RELOAD TLS")?;
4013 if let Some(channel) = channel {
4014 f.write_str(" FOR CHANNEL ")?;
4015 channel.render(ctx, f)?;
4016 }
4017 if *no_rollback_on_error {
4018 f.write_str(" NO ROLLBACK ON ERROR")?;
4019 }
4020 Ok(())
4021 }
4022 Self::ReloadKeyring { .. } => f.write_str("RELOAD KEYRING"),
4023 Self::EnableInnodbRedoLog { .. } => f.write_str("ENABLE INNODB REDO_LOG"),
4024 Self::DisableInnodbRedoLog { .. } => f.write_str("DISABLE INNODB REDO_LOG"),
4025 }
4026 }
4027}
4028
4029impl<X: Extension + Render> Render for AlterSequence<X> {
4030 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4031 f.write_str("ALTER SEQUENCE ")?;
4032 if self.if_exists {
4033 f.write_str("IF EXISTS ")?;
4034 }
4035 self.name.render(ctx, f)?;
4036 for option in &self.options {
4039 f.write_str(" ")?;
4040 option.render(ctx, f)?;
4041 }
4042 Ok(())
4043 }
4044}
4045
4046impl<X: Extension + Render> Render for AlterSequenceOption<X> {
4047 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4048 match self {
4049 Self::Common { option, .. } => option.render(ctx, f),
4050 Self::Restart { value: None, .. } => f.write_str("RESTART"),
4051 Self::Restart {
4052 value: Some(expr), ..
4053 } => {
4054 f.write_str("RESTART WITH ")?;
4055 expr.render(ctx, f)
4056 }
4057 Self::As { data_type, .. } => {
4058 f.write_str("AS ")?;
4059 data_type.render(ctx, f)
4060 }
4061 Self::OwnedBy { owner: None, .. } => f.write_str("OWNED BY NONE"),
4062 Self::OwnedBy {
4063 owner: Some(name), ..
4064 } => {
4065 f.write_str("OWNED BY ")?;
4066 name.render(ctx, f)
4067 }
4068 Self::SequenceName { name, .. } => {
4069 f.write_str("SEQUENCE NAME ")?;
4070 name.render(ctx, f)
4071 }
4072 }
4073 }
4074}
4075
4076impl Render for AlterObjectSchema {
4077 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4078 f.write_str("ALTER ")?;
4079 f.write_str(match self.object_type {
4080 SchemaRelocationObject::Table => "TABLE ",
4081 SchemaRelocationObject::View => "VIEW ",
4082 SchemaRelocationObject::Sequence => "SEQUENCE ",
4083 })?;
4084 if self.if_exists {
4085 f.write_str("IF EXISTS ")?;
4086 }
4087 self.name.render(ctx, f)?;
4088 f.write_str(" SET SCHEMA ")?;
4089 self.new_schema.render(ctx, f)
4090 }
4091}
4092
4093fn render_set_scope(
4096 scope: Option<SetScope>,
4097 ctx: &RenderCtx<'_>,
4098 f: &mut fmt::Formatter<'_>,
4099) -> fmt::Result {
4100 if let Some(scope) = scope {
4101 f.write_str(" ")?;
4102 scope.render(ctx, f)?;
4103 }
4104 Ok(())
4105}
4106
4107impl Render for SpecialSetValue {
4108 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4109 match self {
4110 Self::Default { .. } => f.write_str("DEFAULT"),
4111 Self::Local { .. } => f.write_str("LOCAL"),
4112 Self::None { .. } => f.write_str("NONE"),
4113 Self::Value { value, .. } => value.render(ctx, f),
4114 }
4115 }
4116}
4117
4118impl Render for ConstraintsTarget {
4119 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4120 match self {
4121 Self::All { .. } => f.write_str("ALL"),
4122 Self::Names { names, .. } => render_comma_separated(names, ctx, f),
4123 }
4124 }
4125}
4126
4127impl Render for ConstraintCheckTime {
4128 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4129 f.write_str(match self {
4130 Self::Deferred => "DEFERRED",
4131 Self::Immediate => "IMMEDIATE",
4132 })
4133 }
4134}
4135
4136impl Render for SetNamesValue {
4137 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4138 match self {
4139 Self::Default { .. } => f.write_str("DEFAULT"),
4140 Self::Charset {
4141 charset, collation, ..
4142 } => {
4143 charset.render(ctx, f)?;
4144 if let Some(collation) = collation {
4145 f.write_str(" COLLATE ")?;
4146 collation.render(ctx, f)?;
4147 }
4148 Ok(())
4149 }
4150 }
4151 }
4152}
4153
4154impl Render for SetScope {
4155 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4156 f.write_str(match self {
4157 Self::Session => "SESSION",
4158 Self::Local => "LOCAL",
4159 Self::Global => "GLOBAL",
4160 })
4161 }
4162}
4163
4164impl Render for SetValue {
4165 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4166 match self {
4167 Self::Default { .. } => f.write_str("DEFAULT"),
4168 Self::Values { values, .. } => render_comma_separated(values, ctx, f),
4169 }
4170 }
4171}
4172
4173impl Render for SetParameterValue {
4174 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4175 match self {
4176 Self::Literal { literal, .. } => literal.render(ctx, f),
4177 Self::Name { name, .. } => name.render(ctx, f),
4178 Self::List { values, .. } => {
4179 f.write_str("[")?;
4180 render_comma_separated(values, ctx, f)?;
4181 f.write_str("]")
4182 }
4183 }
4184 }
4185}
4186
4187impl Render for ConfigParameter {
4188 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4189 match self {
4190 Self::All { .. } => f.write_str("ALL"),
4191 Self::Named { name, .. } => name.render(ctx, f),
4192 }
4193 }
4194}
4195
4196impl<X: Extension + Render> Render for AccessControlStatement<X> {
4197 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4198 match self {
4199 Self::Grant {
4200 privileges,
4201 object,
4202 grantees,
4203 with_grant_option,
4204 granted_by,
4205 ..
4206 } => {
4207 f.write_str("GRANT ")?;
4208 privileges.render(ctx, f)?;
4209 f.write_str(" ON ")?;
4210 object.render(ctx, f)?;
4211 f.write_str(" TO ")?;
4212 render_comma_separated(grantees, ctx, f)?;
4213 if *with_grant_option {
4214 f.write_str(" WITH GRANT OPTION")?;
4215 }
4216 render_granted_by(granted_by, ctx, f)
4217 }
4218 Self::Revoke {
4219 grant_option_for,
4220 privileges,
4221 object,
4222 grantees,
4223 granted_by,
4224 behavior,
4225 ..
4226 } => {
4227 f.write_str("REVOKE ")?;
4228 if *grant_option_for {
4229 f.write_str("GRANT OPTION FOR ")?;
4230 }
4231 privileges.render(ctx, f)?;
4232 f.write_str(" ON ")?;
4233 object.render(ctx, f)?;
4234 f.write_str(" FROM ")?;
4235 render_comma_separated(grantees, ctx, f)?;
4236 render_granted_by(granted_by, ctx, f)?;
4237 render_drop_behavior(*behavior, ctx, f)
4238 }
4239 Self::GrantRole {
4240 roles,
4241 grantees,
4242 with_admin_option,
4243 granted_by,
4244 ..
4245 } => {
4246 f.write_str("GRANT ")?;
4247 render_ident_list(roles, ctx, f)?;
4248 f.write_str(" TO ")?;
4249 render_comma_separated(grantees, ctx, f)?;
4250 if *with_admin_option {
4251 f.write_str(" WITH ADMIN OPTION")?;
4252 }
4253 render_granted_by(granted_by, ctx, f)
4254 }
4255 Self::RevokeRole {
4256 admin_option_for,
4257 roles,
4258 grantees,
4259 granted_by,
4260 behavior,
4261 ..
4262 } => {
4263 f.write_str("REVOKE ")?;
4264 if *admin_option_for {
4265 f.write_str("ADMIN OPTION FOR ")?;
4266 }
4267 render_ident_list(roles, ctx, f)?;
4268 f.write_str(" FROM ")?;
4269 render_comma_separated(grantees, ctx, f)?;
4270 render_granted_by(granted_by, ctx, f)?;
4271 render_drop_behavior(*behavior, ctx, f)
4272 }
4273 Self::AccountGrantPrivilege {
4274 privileges,
4275 object,
4276 grantees,
4277 with_grant_option,
4278 grant_as,
4279 ..
4280 } => {
4281 f.write_str("GRANT ")?;
4282 privileges.render(ctx, f)?;
4283 f.write_str(" ON ")?;
4284 object.render(ctx, f)?;
4285 f.write_str(" TO ")?;
4286 render_comma_separated(grantees, ctx, f)?;
4287 if *with_grant_option {
4288 f.write_str(" WITH GRANT OPTION")?;
4289 }
4290 if let Some(grant_as) = grant_as {
4291 f.write_str(" ")?;
4292 grant_as.render(ctx, f)?;
4293 }
4294 Ok(())
4295 }
4296 Self::AccountGrantProxy {
4297 proxy,
4298 grantees,
4299 with_grant_option,
4300 ..
4301 } => {
4302 f.write_str("GRANT PROXY ON ")?;
4303 proxy.render(ctx, f)?;
4304 f.write_str(" TO ")?;
4305 render_comma_separated(grantees, ctx, f)?;
4306 if *with_grant_option {
4307 f.write_str(" WITH GRANT OPTION")?;
4308 }
4309 Ok(())
4310 }
4311 Self::AccountGrantRole {
4312 roles,
4313 grantees,
4314 with_admin_option,
4315 ..
4316 } => {
4317 f.write_str("GRANT ")?;
4318 render_comma_separated(roles, ctx, f)?;
4319 f.write_str(" TO ")?;
4320 render_comma_separated(grantees, ctx, f)?;
4321 if *with_admin_option {
4322 f.write_str(" WITH ADMIN OPTION")?;
4323 }
4324 Ok(())
4325 }
4326 Self::AccountRevokePrivilege {
4327 if_exists,
4328 privileges,
4329 object,
4330 grantees,
4331 ignore_unknown_user,
4332 ..
4333 } => {
4334 f.write_str("REVOKE ")?;
4335 if *if_exists {
4336 f.write_str("IF EXISTS ")?;
4337 }
4338 privileges.render(ctx, f)?;
4339 f.write_str(" ON ")?;
4340 object.render(ctx, f)?;
4341 f.write_str(" FROM ")?;
4342 render_comma_separated(grantees, ctx, f)?;
4343 render_ignore_unknown_user(*ignore_unknown_user, f)
4344 }
4345 Self::AccountRevokeAll {
4346 if_exists,
4347 privileges_keyword,
4348 grantees,
4349 ignore_unknown_user,
4350 ..
4351 } => {
4352 f.write_str("REVOKE ")?;
4353 if *if_exists {
4354 f.write_str("IF EXISTS ")?;
4355 }
4356 if *privileges_keyword || !honours_source_spelling(ctx) {
4359 f.write_str("ALL PRIVILEGES, GRANT OPTION FROM ")?;
4360 } else {
4361 f.write_str("ALL, GRANT OPTION FROM ")?;
4362 }
4363 render_comma_separated(grantees, ctx, f)?;
4364 render_ignore_unknown_user(*ignore_unknown_user, f)
4365 }
4366 Self::AccountRevokeProxy {
4367 if_exists,
4368 proxy,
4369 grantees,
4370 ignore_unknown_user,
4371 ..
4372 } => {
4373 f.write_str("REVOKE ")?;
4374 if *if_exists {
4375 f.write_str("IF EXISTS ")?;
4376 }
4377 f.write_str("PROXY ON ")?;
4378 proxy.render(ctx, f)?;
4379 f.write_str(" FROM ")?;
4380 render_comma_separated(grantees, ctx, f)?;
4381 render_ignore_unknown_user(*ignore_unknown_user, f)
4382 }
4383 Self::AccountRevokeRole {
4384 if_exists,
4385 roles,
4386 grantees,
4387 ignore_unknown_user,
4388 ..
4389 } => {
4390 f.write_str("REVOKE ")?;
4391 if *if_exists {
4392 f.write_str("IF EXISTS ")?;
4393 }
4394 render_comma_separated(roles, ctx, f)?;
4395 f.write_str(" FROM ")?;
4396 render_comma_separated(grantees, ctx, f)?;
4397 render_ignore_unknown_user(*ignore_unknown_user, f)
4398 }
4399 }
4400 }
4401}
4402
4403fn render_ignore_unknown_user(
4405 ignore_unknown_user: bool,
4406 f: &mut fmt::Formatter<'_>,
4407) -> fmt::Result {
4408 if ignore_unknown_user {
4409 f.write_str(" IGNORE UNKNOWN USER")?;
4410 }
4411 Ok(())
4412}
4413
4414impl Render for PrivilegeLevelObject {
4415 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4416 match self.object_type {
4417 PrivilegeObjectType::Table { explicit } => {
4418 if explicit {
4419 f.write_str("TABLE ")?;
4420 }
4421 }
4422 PrivilegeObjectType::Function => f.write_str("FUNCTION ")?,
4423 PrivilegeObjectType::Procedure => f.write_str("PROCEDURE ")?,
4424 }
4425 self.level.render(ctx, f)
4426 }
4427}
4428
4429impl Render for PrivilegeLevel {
4430 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4431 match self {
4432 Self::Global { .. } => f.write_str("*.*"),
4433 Self::CurrentDatabase { .. } => f.write_str("*"),
4434 Self::Database { database, .. } => {
4435 database.render(ctx, f)?;
4436 f.write_str(".*")
4437 }
4438 Self::Object { name, .. } => name.render(ctx, f),
4439 }
4440 }
4441}
4442
4443impl Render for GrantAs {
4444 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4445 f.write_str("AS ")?;
4446 self.user.render(ctx, f)?;
4447 if let Some(with_role) = &self.with_role {
4448 f.write_str(" WITH ROLE ")?;
4449 with_role.render(ctx, f)?;
4450 }
4451 Ok(())
4452 }
4453}
4454
4455impl Render for WithRoleSpec {
4456 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4457 match self {
4458 Self::Roles { roles, .. } => render_comma_separated(roles, ctx, f),
4459 Self::All { except, .. } => {
4460 f.write_str("ALL")?;
4461 if !except.is_empty() {
4462 f.write_str(" EXCEPT ")?;
4463 render_comma_separated(except, ctx, f)?;
4464 }
4465 Ok(())
4466 }
4467 Self::None { .. } => f.write_str("NONE"),
4468 Self::Default { .. } => f.write_str("DEFAULT"),
4469 }
4470 }
4471}
4472
4473fn render_granted_by(
4475 granted_by: &Option<RoleSpec>,
4476 ctx: &RenderCtx<'_>,
4477 f: &mut fmt::Formatter<'_>,
4478) -> fmt::Result {
4479 if let Some(grantor) = granted_by {
4480 f.write_str(" GRANTED BY ")?;
4481 grantor.render(ctx, f)?;
4482 }
4483 Ok(())
4484}
4485
4486impl Render for Privileges {
4487 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4488 match self {
4489 Self::All {
4492 privileges_keyword, ..
4493 } => {
4494 if *privileges_keyword || !honours_source_spelling(ctx) {
4495 f.write_str("ALL PRIVILEGES")
4496 } else {
4497 f.write_str("ALL")
4498 }
4499 }
4500 Self::List { privileges, .. } => render_comma_separated(privileges, ctx, f),
4501 }
4502 }
4503}
4504
4505impl Render for Privilege {
4506 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4507 match self {
4508 Self::Known { kind, columns, .. } => {
4509 kind.render(ctx, f)?;
4510 render_privilege_columns(columns, ctx, f)
4511 }
4512 Self::Other { name, columns, .. } => {
4513 name.render(ctx, f)?;
4514 render_privilege_columns(columns, ctx, f)
4515 }
4516 }
4517 }
4518}
4519
4520fn render_privilege_columns(
4522 columns: &[Ident],
4523 ctx: &RenderCtx<'_>,
4524 f: &mut fmt::Formatter<'_>,
4525) -> fmt::Result {
4526 if !columns.is_empty() {
4527 f.write_str(" (")?;
4528 render_ident_list(columns, ctx, f)?;
4529 f.write_str(")")?;
4530 }
4531 Ok(())
4532}
4533
4534impl Render for PrivilegeKind {
4535 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4536 f.write_str(match self {
4537 Self::Select => "SELECT",
4538 Self::Insert => "INSERT",
4539 Self::Update => "UPDATE",
4540 Self::Delete => "DELETE",
4541 Self::Truncate => "TRUNCATE",
4542 Self::References => "REFERENCES",
4543 Self::Trigger => "TRIGGER",
4544 Self::Usage => "USAGE",
4545 Self::Execute => "EXECUTE",
4546 Self::Create => "CREATE",
4547 Self::Connect => "CONNECT",
4548 Self::Temporary => "TEMPORARY",
4549 Self::Temp => "TEMP",
4550 Self::Maintain => "MAINTAIN",
4551 Self::Index => "INDEX",
4552 Self::Alter => "ALTER",
4553 Self::Drop => "DROP",
4554 Self::Reload => "RELOAD",
4555 Self::Shutdown => "SHUTDOWN",
4556 Self::Process => "PROCESS",
4557 Self::File => "FILE",
4558 Self::Super => "SUPER",
4559 Self::Event => "EVENT",
4560 Self::GrantOption => "GRANT OPTION",
4561 Self::ShowDatabases => "SHOW DATABASES",
4562 Self::CreateTemporaryTables => "CREATE TEMPORARY TABLES",
4563 Self::LockTables => "LOCK TABLES",
4564 Self::ReplicationSlave => "REPLICATION SLAVE",
4565 Self::ReplicationClient => "REPLICATION CLIENT",
4566 Self::CreateView => "CREATE VIEW",
4567 Self::ShowView => "SHOW VIEW",
4568 Self::CreateRoutine => "CREATE ROUTINE",
4569 Self::AlterRoutine => "ALTER ROUTINE",
4570 Self::CreateUser => "CREATE USER",
4571 Self::CreateTablespace => "CREATE TABLESPACE",
4572 Self::CreateRole => "CREATE ROLE",
4573 Self::DropRole => "DROP ROLE",
4574 })
4575 }
4576}
4577
4578impl<X: Extension + Render> Render for GrantObject<X> {
4579 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4580 match self {
4581 Self::Table {
4582 explicit, names, ..
4583 } => {
4584 if *explicit {
4585 f.write_str("TABLE ")?;
4586 }
4587 render_comma_separated(names, ctx, f)
4588 }
4589 Self::Named { kind, names, .. } => {
4590 kind.render(ctx, f)?;
4591 f.write_str(" ")?;
4592 render_comma_separated(names, ctx, f)
4593 }
4594 Self::Routines { kind, routines, .. } => {
4595 kind.render(ctx, f)?;
4596 f.write_str(" ")?;
4597 render_comma_separated(routines, ctx, f)
4598 }
4599 Self::AllInSchema { kind, schemas, .. } => {
4600 f.write_str("ALL ")?;
4601 kind.render(ctx, f)?;
4602 f.write_str(" IN SCHEMA ")?;
4603 render_comma_separated(schemas, ctx, f)
4604 }
4605 }
4606 }
4607}
4608
4609impl Render for NamedObjectKind {
4610 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4611 f.write_str(match self {
4612 Self::Sequence => "SEQUENCE",
4613 Self::Database => "DATABASE",
4614 Self::Schema => "SCHEMA",
4615 Self::Domain => "DOMAIN",
4616 Self::Type => "TYPE",
4617 Self::Language => "LANGUAGE",
4618 Self::Tablespace => "TABLESPACE",
4619 Self::ForeignDataWrapper => "FOREIGN DATA WRAPPER",
4620 Self::ForeignServer => "FOREIGN SERVER",
4621 })
4622 }
4623}
4624
4625impl Render for RoutineObjectKind {
4626 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4627 f.write_str(match self {
4628 Self::Function => "FUNCTION",
4629 Self::Procedure => "PROCEDURE",
4630 Self::Routine => "ROUTINE",
4631 })
4632 }
4633}
4634
4635impl Render for SchemaObjectKind {
4636 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4637 f.write_str(match self {
4638 Self::Tables => "TABLES",
4639 Self::Sequences => "SEQUENCES",
4640 Self::Functions => "FUNCTIONS",
4641 Self::Procedures => "PROCEDURES",
4642 Self::Routines => "ROUTINES",
4643 })
4644 }
4645}
4646
4647impl<X: Extension + Render> Render for RoutineSignature<X> {
4648 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4649 self.name.render(ctx, f)?;
4650 if let Some(arg_types) = &self.arg_types {
4651 f.write_str("(")?;
4652 render_comma_separated(arg_types, ctx, f)?;
4653 f.write_str(")")?;
4654 }
4655 Ok(())
4656 }
4657}
4658
4659impl Render for Grantee {
4660 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4661 if self.group {
4662 f.write_str("GROUP ")?;
4663 }
4664 self.spec.render(ctx, f)
4665 }
4666}
4667
4668impl Render for RoleSpec {
4669 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4670 match self {
4671 Self::Public { .. } => f.write_str("PUBLIC"),
4672 Self::CurrentRole { .. } => f.write_str("CURRENT_ROLE"),
4673 Self::CurrentUser { .. } => f.write_str("CURRENT_USER"),
4674 Self::SessionUser { .. } => f.write_str("SESSION_USER"),
4675 Self::Name { name, .. } => name.render(ctx, f),
4676 }
4677 }
4678}
4679
4680impl<X: Extension + Render> Render for CopyStatement<X> {
4681 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4682 f.write_str("COPY ")?;
4683 if self.binary {
4685 f.write_str("BINARY ")?;
4686 }
4687 self.source.render(ctx, f)?;
4688 f.write_str(" ")?;
4689 self.direction.render(ctx, f)?;
4690 f.write_str(" ")?;
4691 self.target.render(ctx, f)?;
4692 if let Some(delimiters) = &self.delimiters {
4695 f.write_str(" DELIMITERS ")?;
4696 delimiters.render(ctx, f)?;
4697 }
4698 if !self.options.is_empty() {
4703 if self.parenthesized {
4704 f.write_str(" WITH (")?;
4705 render_comma_separated(&self.options, ctx, f)?;
4706 f.write_str(")")?;
4707 } else {
4708 for option in &self.options {
4709 f.write_str(" ")?;
4710 option.render(ctx, f)?;
4711 }
4712 }
4713 }
4714 if let Some(filter) = &self.filter {
4717 f.write_str(" WHERE ")?;
4718 filter.render(ctx, f)?;
4719 }
4720 Ok(())
4721 }
4722}
4723
4724impl<X: Extension + Render> Render for CopySource<X> {
4725 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4726 match self {
4727 Self::Table { table, columns, .. } => {
4728 table.render(ctx, f)?;
4729 if !columns.is_empty() {
4730 f.write_str(" (")?;
4731 render_ident_list(columns, ctx, f)?;
4732 f.write_str(")")?;
4733 }
4734 Ok(())
4735 }
4736 Self::Query { query, .. } => {
4737 f.write_str("(")?;
4738 query.render(ctx, f)?;
4739 f.write_str(")")
4740 }
4741 }
4742 }
4743}
4744
4745impl Render for CopyDirection {
4746 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4747 f.write_str(match self {
4748 Self::From => "FROM",
4749 Self::To => "TO",
4750 })
4751 }
4752}
4753
4754impl Render for CopyTarget {
4755 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4756 match self {
4757 Self::File { path, .. } => path.render(ctx, f),
4758 Self::Stdin { .. } => f.write_str("STDIN"),
4759 Self::Stdout { .. } => f.write_str("STDOUT"),
4760 Self::Program { command, .. } => {
4761 f.write_str("PROGRAM ")?;
4762 command.render(ctx, f)
4763 }
4764 }
4765 }
4766}
4767
4768impl Render for CopyOption {
4769 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4770 self.name.render(ctx, f)?;
4771 if let Some(value) = &self.value {
4772 f.write_str(" ")?;
4773 value.render(ctx, f)?;
4774 }
4775 Ok(())
4776 }
4777}
4778
4779impl Render for CopyOptionValue {
4780 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4781 match self {
4782 Self::Word { word, .. } => word.render(ctx, f),
4783 Self::String { value, .. } => value.render(ctx, f),
4784 Self::Number { value, .. } => value.render(ctx, f),
4785 Self::Star { .. } => f.write_str("*"),
4786 Self::List { values, .. } => {
4787 f.write_str("(")?;
4788 render_comma_separated(values, ctx, f)?;
4789 f.write_str(")")
4790 }
4791 Self::OptionList { options, .. } => {
4795 f.write_str("(")?;
4796 render_copy_into_options(options, ctx, f)?;
4797 f.write_str(")")
4798 }
4799 Self::Force { kind, columns, .. } => {
4800 kind.render(ctx, f)?;
4801 f.write_str(" ")?;
4802 if columns.is_empty() {
4804 f.write_str("*")
4805 } else {
4806 render_ident_list(columns, ctx, f)
4807 }
4808 }
4809 }
4810 }
4811}
4812
4813impl Render for ForceKind {
4814 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4815 f.write_str(match self {
4816 Self::Quote => "QUOTE",
4817 Self::Null => "NULL",
4818 Self::NotNull => "NOT NULL",
4819 })
4820 }
4821}
4822
4823fn render_copy_into_options(
4829 options: &[CopyOption],
4830 ctx: &RenderCtx<'_>,
4831 f: &mut fmt::Formatter<'_>,
4832) -> fmt::Result {
4833 for (i, option) in options.iter().enumerate() {
4834 if i > 0 {
4835 f.write_str(" ")?;
4836 }
4837 option.name.render(ctx, f)?;
4838 if let Some(value) = &option.value {
4839 f.write_str(" = ")?;
4840 value.render(ctx, f)?;
4841 }
4842 }
4843 Ok(())
4844}
4845
4846impl<X: Extension + Render> Render for CopyIntoStatement<X> {
4847 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4848 f.write_str("COPY INTO ")?;
4849 self.target.render(ctx, f)?;
4850 f.write_str(" FROM ")?;
4851 self.source.render(ctx, f)?;
4852 if !self.options.is_empty() {
4853 f.write_str(" ")?;
4854 render_copy_into_options(&self.options, ctx, f)?;
4855 }
4856 Ok(())
4857 }
4858}
4859
4860impl Render for ExportStatement {
4861 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4862 f.write_str("EXPORT DATABASE ")?;
4863 if let Some(database) = &self.database {
4866 database.render(ctx, f)?;
4867 f.write_str(" TO ")?;
4868 }
4869 self.path.render(ctx, f)?;
4870 if !self.options.is_empty() {
4874 if self.parenthesized {
4875 f.write_str(" (")?;
4876 render_comma_separated(&self.options, ctx, f)?;
4877 f.write_str(")")?;
4878 } else {
4879 for option in &self.options {
4880 f.write_str(" ")?;
4881 option.render(ctx, f)?;
4882 }
4883 }
4884 }
4885 Ok(())
4886 }
4887}
4888
4889impl Render for ImportStatement {
4890 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4891 f.write_str("IMPORT DATABASE ")?;
4892 self.path.render(ctx, f)
4893 }
4894}
4895
4896impl Render for CopyIntoTarget {
4897 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4898 match self {
4899 Self::Table { table, columns, .. } => {
4900 table.render(ctx, f)?;
4901 if !columns.is_empty() {
4902 f.write_str(" (")?;
4903 render_ident_list(columns, ctx, f)?;
4904 f.write_str(")")?;
4905 }
4906 Ok(())
4907 }
4908 Self::External { location, .. } => location.render(ctx, f),
4909 Self::Stage { reference, .. } => reference.render(ctx, f),
4910 }
4911 }
4912}
4913
4914impl<X: Extension + Render> Render for CopyIntoSource<X> {
4915 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4916 match self {
4917 Self::Table { table, .. } => table.render(ctx, f),
4918 Self::External { location, .. } => location.render(ctx, f),
4919 Self::Stage { reference, .. } => reference.render(ctx, f),
4920 Self::Query { query, .. } => {
4921 f.write_str("(")?;
4922 query.render(ctx, f)?;
4923 f.write_str(")")
4924 }
4925 }
4926 }
4927}
4928
4929impl Render for ExplainKeyword {
4930 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4931 f.write_str(match self {
4932 Self::Explain => "EXPLAIN",
4933 Self::Describe => "DESCRIBE",
4934 Self::Desc => "DESC",
4935 })
4936 }
4937}
4938
4939impl<X: Extension + Render> Render for ExplainStatement<X> {
4940 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4941 self.spelling.render(ctx, f)?;
4942 if self.parenthesized {
4943 f.write_str(" (")?;
4944 render_comma_separated(&self.options, ctx, f)?;
4945 f.write_str(")")?;
4946 } else {
4947 for option in &self.options {
4949 f.write_str(" ")?;
4950 option.render(ctx, f)?;
4951 }
4952 }
4953 f.write_str(" ")?;
4954 self.statement.render(ctx, f)
4955 }
4956}
4957
4958impl Render for ExplainOption {
4959 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4960 match self {
4961 Self::Analyze { value, .. } => {
4962 render_explain_word_option("ANALYZE", value.as_ref(), ctx, f)
4963 }
4964 Self::Verbose { value, .. } => {
4965 render_explain_word_option("VERBOSE", value.as_ref(), ctx, f)
4966 }
4967 Self::Format { format, .. } => {
4968 f.write_str("FORMAT ")?;
4969 format.render(ctx, f)
4970 }
4971 Self::Other { name, value, .. } => {
4972 name.render(ctx, f)?;
4973 if let Some(value) = value {
4974 f.write_str(" ")?;
4975 value.render(ctx, f)?;
4976 }
4977 Ok(())
4978 }
4979 }
4980 }
4981}
4982
4983fn render_explain_word_option(
4985 keyword: &str,
4986 value: Option<&Ident>,
4987 ctx: &RenderCtx<'_>,
4988 f: &mut fmt::Formatter<'_>,
4989) -> fmt::Result {
4990 f.write_str(keyword)?;
4991 if let Some(value) = value {
4992 f.write_str(" ")?;
4993 value.render(ctx, f)?;
4994 }
4995 Ok(())
4996}
4997
4998impl Render for ExplainFormat {
4999 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5000 f.write_str(match self {
5001 Self::Text => "TEXT",
5002 Self::Xml => "XML",
5003 Self::Json => "JSON",
5004 Self::Yaml => "YAML",
5005 })
5006 }
5007}
5008
5009impl Render for DescribeStatement {
5010 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5011 self.keyword.render(ctx, f)?;
5012 f.write_str(" ")?;
5013 self.table.render(ctx, f)?;
5014 if let Some(column) = &self.column {
5015 f.write_str(" ")?;
5016 column.render(ctx, f)?;
5017 }
5018 Ok(())
5019 }
5020}
5021
5022impl Render for DescribeColumn {
5023 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5024 match self {
5025 Self::Name { name, .. } => name.render(ctx, f),
5026 Self::Wild { pattern, .. } => pattern.render(ctx, f),
5027 }
5028 }
5029}
5030
5031impl<X: Extension + Render> Render for ShowStatement<X> {
5032 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5033 self.target.render(ctx, f)
5034 }
5035}
5036
5037impl<X: Extension + Render> Render for ShowTarget<X> {
5038 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5039 match self {
5040 Self::Tables {
5041 extended,
5042 full,
5043 all,
5044 from,
5045 filter,
5046 ..
5047 } => {
5048 f.write_str("SHOW ")?;
5049 if *extended {
5050 f.write_str("EXTENDED ")?;
5051 }
5052 if *full {
5053 f.write_str("FULL ")?;
5054 }
5055 if *all {
5056 f.write_str("ALL ")?;
5057 }
5058 f.write_str("TABLES")?;
5059 if let Some(from) = from {
5060 f.write_str(" ")?;
5061 from.render(ctx, f)?;
5062 }
5063 if let Some(filter) = filter {
5064 f.write_str(" ")?;
5065 filter.render(ctx, f)?;
5066 }
5067 Ok(())
5068 }
5069 Self::Columns {
5070 extended,
5071 full,
5072 spelling,
5073 table,
5074 database,
5075 filter,
5076 ..
5077 } => {
5078 f.write_str("SHOW ")?;
5079 if *extended {
5080 f.write_str("EXTENDED ")?;
5081 }
5082 if *full {
5083 f.write_str("FULL ")?;
5084 }
5085 f.write_str(match spelling {
5086 ShowColumnsSpelling::Columns => "COLUMNS ",
5087 ShowColumnsSpelling::Fields => "FIELDS ",
5088 })?;
5089 table.render(ctx, f)?;
5090 if let Some(database) = database {
5091 f.write_str(" ")?;
5092 database.render(ctx, f)?;
5093 }
5094 if let Some(filter) = filter {
5095 f.write_str(" ")?;
5096 filter.render(ctx, f)?;
5097 }
5098 Ok(())
5099 }
5100 Self::Create {
5101 kind,
5102 name,
5103 if_not_exists,
5104 ..
5105 } => {
5106 f.write_str("SHOW CREATE ")?;
5107 f.write_str(match kind {
5108 ShowCreateKind::Table => "TABLE ",
5109 ShowCreateKind::View => "VIEW ",
5110 ShowCreateKind::Database { schema: false } => "DATABASE ",
5111 ShowCreateKind::Database { schema: true } => "SCHEMA ",
5112 ShowCreateKind::Event => "EVENT ",
5113 ShowCreateKind::Procedure => "PROCEDURE ",
5114 ShowCreateKind::Function => "FUNCTION ",
5115 ShowCreateKind::Trigger => "TRIGGER ",
5116 })?;
5117 if *if_not_exists {
5118 f.write_str("IF NOT EXISTS ")?;
5119 }
5120 name.render(ctx, f)
5121 }
5122 Self::Functions {
5123 kind, from, filter, ..
5124 } => {
5125 f.write_str("SHOW ")?;
5126 if let Some(kind) = kind {
5127 f.write_str(match kind {
5128 ShowFunctionsScope::User => "USER ",
5129 ShowFunctionsScope::System => "SYSTEM ",
5130 ShowFunctionsScope::All => "ALL ",
5131 })?;
5132 }
5133 f.write_str("FUNCTIONS")?;
5134 if let Some(from) = from {
5135 f.write_str(" ")?;
5136 from.render(ctx, f)?;
5137 }
5138 if let Some(filter) = filter {
5139 f.write_str(" ")?;
5140 filter.render(ctx, f)?;
5141 }
5142 Ok(())
5143 }
5144 Self::RoutineStatus { kind, filter, .. } => {
5145 f.write_str(match kind {
5146 ShowRoutineKind::Function => "SHOW FUNCTION STATUS",
5147 ShowRoutineKind::Procedure => "SHOW PROCEDURE STATUS",
5148 })?;
5149 if let Some(filter) = filter {
5150 f.write_str(" ")?;
5151 filter.render(ctx, f)?;
5152 }
5153 Ok(())
5154 }
5155 Self::Listing {
5156 kind, from, filter, ..
5157 } => {
5158 f.write_str("SHOW ")?;
5159 match kind {
5160 ShowListing::Databases { schemas } => {
5161 f.write_str(if *schemas { "SCHEMAS" } else { "DATABASES" })?;
5162 }
5163 ShowListing::CharacterSet { charset } => {
5164 f.write_str(if *charset { "CHARSET" } else { "CHARACTER SET" })?;
5165 }
5166 ShowListing::Collation => f.write_str("COLLATION")?,
5167 ShowListing::Status { scope } => {
5168 render_show_scope(*scope, f)?;
5169 f.write_str("STATUS")?;
5170 }
5171 ShowListing::Variables { scope } => {
5172 render_show_scope(*scope, f)?;
5173 f.write_str("VARIABLES")?;
5174 }
5175 ShowListing::Events => f.write_str("EVENTS")?,
5176 ShowListing::TableStatus => f.write_str("TABLE STATUS")?,
5177 ShowListing::OpenTables => f.write_str("OPEN TABLES")?,
5178 ShowListing::Triggers { full } => {
5179 if *full {
5180 f.write_str("FULL ")?;
5181 }
5182 f.write_str("TRIGGERS")?;
5183 }
5184 }
5185 if let Some(from) = from {
5186 f.write_str(" ")?;
5187 from.render(ctx, f)?;
5188 }
5189 if let Some(filter) = filter {
5190 f.write_str(" ")?;
5191 filter.render(ctx, f)?;
5192 }
5193 Ok(())
5194 }
5195 Self::Bare { kind, .. } => {
5196 f.write_str("SHOW ")?;
5197 f.write_str(match kind {
5198 ShowBare::Plugins => "PLUGINS",
5199 ShowBare::Engines { storage: true } => "STORAGE ENGINES",
5200 ShowBare::Engines { storage: false } => "ENGINES",
5201 ShowBare::Privileges => "PRIVILEGES",
5202 ShowBare::Profiles => "PROFILES",
5203 ShowBare::Processlist { full: true } => "FULL PROCESSLIST",
5204 ShowBare::Processlist { full: false } => "PROCESSLIST",
5205 ShowBare::BinaryLogs => "BINARY LOGS",
5206 ShowBare::Replicas => "REPLICAS",
5207 ShowBare::BinaryLogStatus => "BINARY LOG STATUS",
5208 })
5209 }
5210 Self::Index {
5211 spelling,
5212 extended,
5213 table,
5214 database,
5215 filter,
5216 ..
5217 } => {
5218 f.write_str("SHOW ")?;
5219 if *extended {
5220 f.write_str("EXTENDED ")?;
5221 }
5222 f.write_str(match spelling {
5223 ShowIndexSpelling::Index => "INDEX ",
5224 ShowIndexSpelling::Indexes => "INDEXES ",
5225 ShowIndexSpelling::Keys => "KEYS ",
5226 })?;
5227 table.render(ctx, f)?;
5228 if let Some(database) = database {
5229 f.write_str(" ")?;
5230 database.render(ctx, f)?;
5231 }
5232 if let Some(filter) = filter {
5233 f.write_str(" ")?;
5234 filter.render(ctx, f)?;
5235 }
5236 Ok(())
5237 }
5238 Self::Engine {
5239 engine, artifact, ..
5240 } => {
5241 f.write_str("SHOW ENGINE ")?;
5242 match engine {
5243 Some(name) => name.render(ctx, f)?,
5244 None => f.write_str("ALL")?,
5245 }
5246 f.write_str(match artifact {
5247 ShowEngineArtifact::Status => " STATUS",
5248 ShowEngineArtifact::Mutex => " MUTEX",
5249 ShowEngineArtifact::Logs => " LOGS",
5250 })
5251 }
5252 Self::ReplicaStatus { channel, .. } => {
5253 f.write_str("SHOW REPLICA STATUS")?;
5254 if let Some(channel) = channel {
5255 f.write_str(" FOR CHANNEL ")?;
5256 channel.render(ctx, f)?;
5257 }
5258 Ok(())
5259 }
5260 Self::Diagnostics {
5261 kind, count, limit, ..
5262 } => {
5263 f.write_str("SHOW ")?;
5264 if *count {
5265 f.write_str("COUNT(*) ")?;
5266 }
5267 f.write_str(match kind {
5268 ShowDiagnosticKind::Warnings => "WARNINGS",
5269 ShowDiagnosticKind::Errors => "ERRORS",
5270 })?;
5271 if let Some(limit) = limit {
5272 f.write_str(" ")?;
5273 render_show_limit(limit, ctx, f)?;
5274 }
5275 Ok(())
5276 }
5277 Self::RoutineCode { kind, name, .. } => {
5278 f.write_str(match kind {
5279 ShowRoutineKind::Function => "SHOW FUNCTION CODE ",
5280 ShowRoutineKind::Procedure => "SHOW PROCEDURE CODE ",
5281 })?;
5282 name.render(ctx, f)
5283 }
5284 Self::Grants {
5285 user, using_roles, ..
5286 } => {
5287 f.write_str("SHOW GRANTS")?;
5288 if let Some(user) = user {
5289 f.write_str(" FOR ")?;
5290 user.render(ctx, f)?;
5291 if !using_roles.is_empty() {
5292 f.write_str(" USING ")?;
5293 render_comma_separated(using_roles, ctx, f)?;
5294 }
5295 }
5296 Ok(())
5297 }
5298 Self::CreateUser { user, .. } => {
5299 f.write_str("SHOW CREATE USER ")?;
5300 user.render(ctx, f)
5301 }
5302 Self::Profile {
5303 types,
5304 query,
5305 limit,
5306 ..
5307 } => {
5308 f.write_str("SHOW PROFILE")?;
5309 for (index, ty) in types.iter().enumerate() {
5310 f.write_str(if index == 0 { " " } else { ", " })?;
5311 f.write_str(ty.keyword())?;
5312 }
5313 if let Some(query) = query {
5314 f.write_str(" FOR QUERY ")?;
5315 query.render(ctx, f)?;
5316 }
5317 if let Some(limit) = limit {
5318 f.write_str(" ")?;
5319 render_show_limit(limit, ctx, f)?;
5320 }
5321 Ok(())
5322 }
5323 Self::LogEvents {
5324 relay,
5325 log_name,
5326 position,
5327 limit,
5328 channel,
5329 ..
5330 } => {
5331 f.write_str(if *relay {
5332 "SHOW RELAYLOG EVENTS"
5333 } else {
5334 "SHOW BINLOG EVENTS"
5335 })?;
5336 if let Some(log_name) = log_name {
5337 f.write_str(" IN ")?;
5338 log_name.render(ctx, f)?;
5339 }
5340 if let Some(position) = position {
5341 f.write_str(" FROM ")?;
5342 position.render(ctx, f)?;
5343 }
5344 if let Some(limit) = limit {
5345 f.write_str(" ")?;
5346 render_show_limit(limit, ctx, f)?;
5347 }
5348 if let Some(channel) = channel {
5349 f.write_str(" FOR CHANNEL ")?;
5350 channel.render(ctx, f)?;
5351 }
5352 Ok(())
5353 }
5354 }
5355 }
5356}
5357
5358impl ShowProfileType {
5359 fn keyword(self) -> &'static str {
5361 match self {
5362 Self::All => "ALL",
5363 Self::BlockIo => "BLOCK IO",
5364 Self::ContextSwitches => "CONTEXT SWITCHES",
5365 Self::Cpu => "CPU",
5366 Self::Ipc => "IPC",
5367 Self::Memory => "MEMORY",
5368 Self::PageFaults => "PAGE FAULTS",
5369 Self::Source => "SOURCE",
5370 Self::Swaps => "SWAPS",
5371 }
5372 }
5373}
5374
5375fn render_show_limit(
5379 limit: &ShowLimit,
5380 ctx: &RenderCtx<'_>,
5381 f: &mut fmt::Formatter<'_>,
5382) -> fmt::Result {
5383 f.write_str("LIMIT ")?;
5384 match &limit.offset {
5385 Some(offset) if limit.offset_keyword => {
5386 limit.row_count.render(ctx, f)?;
5387 f.write_str(" OFFSET ")?;
5388 offset.render(ctx, f)
5389 }
5390 Some(offset) => {
5391 offset.render(ctx, f)?;
5392 f.write_str(", ")?;
5393 limit.row_count.render(ctx, f)
5394 }
5395 None => limit.row_count.render(ctx, f),
5396 }
5397}
5398
5399fn render_show_scope(scope: Option<ShowScope>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5402 if let Some(scope) = scope {
5403 f.write_str(match scope {
5404 ShowScope::Global => "GLOBAL ",
5405 ShowScope::Session => "SESSION ",
5406 ShowScope::Local => "LOCAL ",
5407 })?;
5408 }
5409 Ok(())
5410}
5411
5412impl Render for ShowFunctionsFilter {
5413 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5414 match self {
5415 Self::Name { like, name, .. } => {
5416 if *like {
5417 f.write_str("LIKE ")?;
5418 }
5419 name.render(ctx, f)
5420 }
5421 Self::Regex { like, pattern, .. } => {
5422 if *like {
5423 f.write_str("LIKE ")?;
5424 }
5425 pattern.render(ctx, f)
5426 }
5427 }
5428 }
5429}
5430
5431impl Render for ShowFrom {
5432 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5433 f.write_str(match self.keyword {
5434 ShowFromKeyword::From => "FROM ",
5435 ShowFromKeyword::In => "IN ",
5436 })?;
5437 self.name.render(ctx, f)
5438 }
5439}
5440
5441impl<X: Extension + Render> Render for ShowFilter<X> {
5442 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5443 match self {
5444 Self::Like { pattern, .. } => {
5445 f.write_str("LIKE ")?;
5446 pattern.render(ctx, f)
5447 }
5448 Self::Where { predicate, .. } => {
5449 f.write_str("WHERE ")?;
5450 predicate.render(ctx, f)
5451 }
5452 }
5453 }
5454}
5455
5456impl<X: Extension + Render> Render for KillStatement<X> {
5457 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5458 f.write_str("KILL")?;
5459 match self.target {
5460 KillTarget::Unspecified => {}
5461 KillTarget::Connection => f.write_str(" CONNECTION")?,
5462 KillTarget::Query => f.write_str(" QUERY")?,
5463 }
5464 f.write_str(" ")?;
5465 self.id.render(ctx, f)
5466 }
5467}
5468
5469impl<X: Extension + Render> Render for InstallStatement<X> {
5470 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5471 match self {
5472 InstallStatement::Plugin { name, soname, .. } => {
5473 f.write_str("INSTALL PLUGIN ")?;
5474 name.render(ctx, f)?;
5475 f.write_str(" SONAME ")?;
5476 soname.render(ctx, f)
5477 }
5478 InstallStatement::Component { urns, set, .. } => {
5479 f.write_str("INSTALL COMPONENT ")?;
5480 render_comma_separated(urns, ctx, f)?;
5481 if !set.is_empty() {
5482 f.write_str(" SET ")?;
5483 render_comma_separated(set, ctx, f)?;
5484 }
5485 Ok(())
5486 }
5487 }
5488 }
5489}
5490
5491impl Render for UninstallStatement {
5492 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5493 match self {
5494 UninstallStatement::Plugin { name, .. } => {
5495 f.write_str("UNINSTALL PLUGIN ")?;
5496 name.render(ctx, f)
5497 }
5498 UninstallStatement::Component { urns, .. } => {
5499 f.write_str("UNINSTALL COMPONENT ")?;
5500 render_comma_separated(urns, ctx, f)
5501 }
5502 }
5503 }
5504}
5505
5506impl<X: Extension + Render> Render for InstallComponentSetElement<X> {
5507 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5508 match self.scope {
5509 None => {}
5510 Some(InstallComponentSetScope::Global) => f.write_str("GLOBAL ")?,
5511 Some(InstallComponentSetScope::Persist) => f.write_str("PERSIST ")?,
5512 }
5513 self.name.render(ctx, f)?;
5514 render_mysql_set_assignment(self.assignment, ctx, f)?;
5515 self.value.render(ctx, f)
5516 }
5517}
5518
5519impl<X: Extension + Render> Render for InstallComponentSetValue<X> {
5520 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5521 match self {
5522 InstallComponentSetValue::On { .. } => f.write_str("ON"),
5523 InstallComponentSetValue::Expr { expr, .. } => expr.render(ctx, f),
5524 }
5525 }
5526}
5527
5528impl<X: Extension + Render> Render for HandlerStatement<X> {
5529 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5530 f.write_str("HANDLER ")?;
5531 self.table.render(ctx, f)?;
5532 f.write_str(" ")?;
5533 self.operation.render(ctx, f)
5534 }
5535}
5536
5537impl<X: Extension + Render> Render for HandlerOperation<X> {
5538 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5539 match self {
5540 HandlerOperation::Open {
5541 alias, as_keyword, ..
5542 } => {
5543 f.write_str("OPEN")?;
5544 if let Some(alias) = alias {
5545 f.write_str(if *as_keyword { " AS " } else { " " })?;
5547 alias.render(ctx, f)?;
5548 }
5549 Ok(())
5550 }
5551 HandlerOperation::Close { .. } => f.write_str("CLOSE"),
5552 HandlerOperation::Read {
5553 selector,
5554 selection,
5555 limit,
5556 ..
5557 } => {
5558 f.write_str("READ ")?;
5559 selector.render(ctx, f)?;
5560 if let Some(selection) = selection {
5561 f.write_str(" WHERE ")?;
5562 selection.render(ctx, f)?;
5563 }
5564 if let Some(limit) = limit {
5565 f.write_str(" ")?;
5566 limit.render(ctx, f)?;
5567 }
5568 Ok(())
5569 }
5570 }
5571 }
5572}
5573
5574impl<X: Extension + Render> Render for HandlerReadSelector<X> {
5575 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5576 match self {
5577 HandlerReadSelector::Scan { direction, .. } => f.write_str(match direction {
5578 HandlerScanDirection::First => "FIRST",
5579 HandlerScanDirection::Next => "NEXT",
5580 }),
5581 HandlerReadSelector::Index {
5582 index, direction, ..
5583 } => {
5584 index.render(ctx, f)?;
5585 f.write_str(match direction {
5586 HandlerIndexDirection::First => " FIRST",
5587 HandlerIndexDirection::Next => " NEXT",
5588 HandlerIndexDirection::Prev => " PREV",
5589 HandlerIndexDirection::Last => " LAST",
5590 })
5591 }
5592 HandlerReadSelector::Key {
5593 index,
5594 comparison,
5595 key,
5596 ..
5597 } => {
5598 index.render(ctx, f)?;
5599 f.write_str(match comparison {
5600 HandlerKeyComparison::Eq => " = (",
5601 HandlerKeyComparison::GreaterOrEqual => " >= (",
5602 HandlerKeyComparison::LessOrEqual => " <= (",
5603 HandlerKeyComparison::Greater => " > (",
5604 HandlerKeyComparison::Less => " < (",
5605 })?;
5606 render_comma_separated(key, ctx, f)?;
5607 f.write_str(")")
5608 }
5609 }
5610 }
5611}
5612
5613impl Render for CloneStatement {
5614 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5615 match self {
5616 CloneStatement::Local { data_directory, .. } => {
5617 f.write_str("CLONE LOCAL ")?;
5618 data_directory.render(ctx, f)
5619 }
5620 CloneStatement::Instance {
5621 source,
5622 port,
5623 password,
5624 data_directory,
5625 ssl,
5626 ..
5627 } => {
5628 f.write_str("CLONE INSTANCE FROM ")?;
5629 source.render(ctx, f)?;
5630 f.write_str(":")?;
5631 port.render(ctx, f)?;
5632 f.write_str(" IDENTIFIED BY ")?;
5633 password.render(ctx, f)?;
5634 if let Some(data_directory) = data_directory {
5635 f.write_str(" ")?;
5636 data_directory.render(ctx, f)?;
5637 }
5638 match ssl {
5639 CloneSsl::Unspecified => {}
5640 CloneSsl::Require => f.write_str(" REQUIRE SSL")?,
5641 CloneSsl::RequireNo => f.write_str(" REQUIRE NO SSL")?,
5642 }
5643 Ok(())
5644 }
5645 }
5646 }
5647}
5648
5649impl Render for CloneDataDirectory {
5650 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5651 f.write_str(if self.equals {
5652 "DATA DIRECTORY = "
5653 } else {
5654 "DATA DIRECTORY "
5655 })?;
5656 self.path.render(ctx, f)
5657 }
5658}
5659
5660impl Render for ImportTableStatement {
5661 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5662 f.write_str("IMPORT TABLE FROM ")?;
5663 render_comma_separated(&self.files, ctx, f)
5664 }
5665}
5666
5667impl Render for HelpStatement {
5668 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5669 f.write_str("HELP ")?;
5670 self.topic.render(ctx, f)
5671 }
5672}
5673
5674impl Render for BinlogStatement {
5675 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5676 f.write_str("BINLOG ")?;
5677 self.event.render(ctx, f)
5678 }
5679}
5680
5681impl Render for PragmaStatement {
5682 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5683 f.write_str("PRAGMA ")?;
5684 self.name.render(ctx, f)?;
5685 if let Some(value) = &self.value {
5686 if self.parenthesized {
5689 f.write_str("(")?;
5690 value.render(ctx, f)?;
5691 f.write_str(")")?;
5692 } else {
5693 f.write_str(" = ")?;
5694 value.render(ctx, f)?;
5695 }
5696 }
5697 Ok(())
5698 }
5699}
5700
5701impl<X: Extension + Render> Render for AttachStatement<X> {
5702 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5703 f.write_str("ATTACH ")?;
5704 if self.database_keyword {
5705 f.write_str("DATABASE ")?;
5706 }
5707 self.target.render(ctx, f)?;
5708 f.write_str(" AS ")?;
5709 self.schema.render(ctx, f)
5710 }
5711}
5712
5713impl Render for DetachStatement {
5714 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5715 f.write_str("DETACH ")?;
5716 if self.database_keyword {
5717 f.write_str("DATABASE ")?;
5718 }
5719 if self.if_exists {
5720 f.write_str("IF EXISTS ")?;
5721 }
5722 self.schema.render(ctx, f)
5723 }
5724}
5725
5726impl Render for CheckpointStatement {
5727 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5728 if self.force {
5729 f.write_str("FORCE ")?;
5730 }
5731 f.write_str("CHECKPOINT")?;
5732 if let Some(database) = &self.database {
5733 f.write_str(" ")?;
5734 database.render(ctx, f)?;
5735 }
5736 Ok(())
5737 }
5738}
5739
5740impl Render for LoadStatement {
5741 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5742 f.write_str("LOAD ")?;
5743 self.target.render(ctx, f)
5744 }
5745}
5746
5747impl Render for LoadTarget {
5748 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5749 match self {
5750 Self::Name { name, .. } => name.render(ctx, f),
5751 Self::Path { path, .. } => path.render(ctx, f),
5752 }
5753 }
5754}
5755
5756impl Render for UseStatement {
5757 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5758 f.write_str("USE ")?;
5759 self.name.render(ctx, f)
5760 }
5761}
5762
5763impl Render for UpdateExtensionsStatement {
5764 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5765 f.write_str("UPDATE EXTENSIONS")?;
5766 if !self.extensions.is_empty() {
5770 f.write_str(" (")?;
5771 render_comma_separated(&self.extensions, ctx, f)?;
5772 f.write_str(")")?;
5773 }
5774 Ok(())
5775 }
5776}
5777
5778impl<X: Extension + Render> Render for VacuumStatement<X> {
5779 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5780 f.write_str("VACUUM")?;
5781 match self.analyze {
5785 Some(VacuumAnalyze::Keyword) => f.write_str(" ANALYZE")?,
5786 Some(VacuumAnalyze::Parenthesized) => f.write_str(" (ANALYZE)")?,
5787 None => {}
5788 }
5789 if let Some(schema) = &self.schema {
5792 f.write_str(" ")?;
5793 schema.render(ctx, f)?;
5794 }
5795 if let Some(table) = &self.table {
5796 f.write_str(" ")?;
5797 table.render(ctx, f)?;
5798 }
5799 if let Some(columns) = &self.columns {
5801 f.write_str(" (")?;
5802 render_comma_separated(columns, ctx, f)?;
5803 f.write_str(")")?;
5804 }
5805 if let Some(into) = &self.into {
5807 f.write_str(" INTO ")?;
5808 into.render(ctx, f)?;
5809 }
5810 Ok(())
5811 }
5812}
5813
5814impl Render for ReindexStatement {
5815 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5816 f.write_str("REINDEX")?;
5817 if let Some(target) = &self.target {
5818 f.write_str(" ")?;
5819 target.render(ctx, f)?;
5820 }
5821 Ok(())
5822 }
5823}
5824
5825impl Render for AnalyzeStatement {
5826 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5827 f.write_str("ANALYZE")?;
5828 if let Some(target) = &self.target {
5829 f.write_str(" ")?;
5830 target.render(ctx, f)?;
5831 }
5832 if let Some(columns) = &self.columns {
5834 f.write_str(" (")?;
5835 render_comma_separated(columns, ctx, f)?;
5836 f.write_str(")")?;
5837 }
5838 Ok(())
5839 }
5840}
5841
5842impl Render for TableMaintenanceStatement {
5843 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5844 let (verb, prefix) = match &self.kind {
5846 TableMaintenanceKind::Analyze {
5847 no_write_to_binlog, ..
5848 } => ("ANALYZE", *no_write_to_binlog),
5849 TableMaintenanceKind::Check { .. } => ("CHECK", None),
5850 TableMaintenanceKind::Checksum { .. } => ("CHECKSUM", None),
5851 TableMaintenanceKind::Optimize {
5852 no_write_to_binlog, ..
5853 } => ("OPTIMIZE", *no_write_to_binlog),
5854 TableMaintenanceKind::Repair {
5855 no_write_to_binlog, ..
5856 } => ("REPAIR", *no_write_to_binlog),
5857 };
5858 f.write_str(verb)?;
5859 if let Some(prefix) = prefix {
5860 f.write_str(" ")?;
5861 f.write_str(no_write_to_binlog_keyword(prefix))?;
5862 }
5863 f.write_str(" ")?;
5864 f.write_str(table_keyword_str(self.table_keyword))?;
5865 f.write_str(" ")?;
5866 render_comma_separated(&self.tables, ctx, f)?;
5867 match &self.kind {
5869 TableMaintenanceKind::Analyze {
5870 histogram: Some(histogram),
5871 ..
5872 } => {
5873 f.write_str(" ")?;
5874 histogram.render(ctx, f)?;
5875 }
5876 TableMaintenanceKind::Check { options, .. } => {
5877 for option in options {
5878 f.write_str(" ")?;
5879 f.write_str(check_table_option_keyword(*option))?;
5880 }
5881 }
5882 TableMaintenanceKind::Checksum {
5883 option: Some(option),
5884 ..
5885 } => {
5886 f.write_str(" ")?;
5887 f.write_str(checksum_table_option_keyword(*option))?;
5888 }
5889 TableMaintenanceKind::Repair { options, .. } => {
5890 for option in options {
5891 f.write_str(" ")?;
5892 f.write_str(repair_table_option_keyword(*option))?;
5893 }
5894 }
5895 TableMaintenanceKind::Analyze {
5896 histogram: None, ..
5897 }
5898 | TableMaintenanceKind::Checksum { option: None, .. }
5899 | TableMaintenanceKind::Optimize { .. } => {}
5900 }
5901 Ok(())
5902 }
5903}
5904
5905impl Render for AnalyzeHistogram {
5906 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5907 match self {
5908 AnalyzeHistogram::Update {
5909 columns, buckets, ..
5910 } => {
5911 f.write_str("UPDATE HISTOGRAM ON ")?;
5912 render_comma_separated(columns, ctx, f)?;
5913 if let Some(buckets) = buckets {
5914 f.write_str(" WITH ")?;
5915 buckets.render(ctx, f)?;
5916 f.write_str(" BUCKETS")?;
5917 }
5918 }
5919 AnalyzeHistogram::Drop { columns, .. } => {
5920 f.write_str("DROP HISTOGRAM ON ")?;
5921 render_comma_separated(columns, ctx, f)?;
5922 }
5923 }
5924 Ok(())
5925 }
5926}
5927
5928impl Render for CacheIndexStatement {
5929 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5930 f.write_str("CACHE INDEX ")?;
5931 self.targets.render(ctx, f)?;
5932 f.write_str(" IN ")?;
5933 self.cache.render(ctx, f)
5934 }
5935}
5936
5937impl Render for CacheIndexTargets {
5938 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5939 match self {
5940 CacheIndexTargets::Tables { tables, .. } => render_comma_separated(tables, ctx, f),
5941 CacheIndexTargets::Partition {
5942 table,
5943 partition,
5944 keys,
5945 ..
5946 } => {
5947 table.render(ctx, f)?;
5948 f.write_str(" ")?;
5949 partition.render(ctx, f)?;
5950 if let Some(keys) = keys {
5951 f.write_str(" ")?;
5952 keys.render(ctx, f)?;
5953 }
5954 Ok(())
5955 }
5956 }
5957 }
5958}
5959
5960impl Render for CacheIndexTable {
5961 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5962 self.table.render(ctx, f)?;
5963 if let Some(keys) = &self.keys {
5964 f.write_str(" ")?;
5965 keys.render(ctx, f)?;
5966 }
5967 Ok(())
5968 }
5969}
5970
5971impl Render for LoadIndexStatement {
5972 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5973 f.write_str("LOAD INDEX INTO CACHE ")?;
5974 self.targets.render(ctx, f)
5975 }
5976}
5977
5978impl Render for LoadIndexTargets {
5979 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5980 match self {
5981 LoadIndexTargets::Tables { tables, .. } => render_comma_separated(tables, ctx, f),
5982 LoadIndexTargets::Partition {
5983 table,
5984 partition,
5985 keys,
5986 ignore_leaves,
5987 ..
5988 } => {
5989 table.render(ctx, f)?;
5990 f.write_str(" ")?;
5991 partition.render(ctx, f)?;
5992 if let Some(keys) = keys {
5993 f.write_str(" ")?;
5994 keys.render(ctx, f)?;
5995 }
5996 if *ignore_leaves {
5997 f.write_str(" IGNORE LEAVES")?;
5998 }
5999 Ok(())
6000 }
6001 }
6002 }
6003}
6004
6005impl Render for LoadIndexTable {
6006 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6007 self.table.render(ctx, f)?;
6008 if let Some(keys) = &self.keys {
6009 f.write_str(" ")?;
6010 keys.render(ctx, f)?;
6011 }
6012 if self.ignore_leaves {
6013 f.write_str(" IGNORE LEAVES")?;
6014 }
6015 Ok(())
6016 }
6017}
6018
6019impl Render for CacheIndexKeyList {
6020 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6021 f.write_str(match self.keyword {
6022 CacheIndexKeyword::Index => "INDEX",
6023 CacheIndexKeyword::Key => "KEY",
6024 })?;
6025 f.write_str(" (")?;
6026 render_comma_separated(&self.keys, ctx, f)?;
6027 f.write_str(")")
6028 }
6029}
6030
6031impl Render for KeyCacheName {
6032 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6033 match self {
6034 KeyCacheName::Named { name, .. } => name.render(ctx, f),
6035 KeyCacheName::Default { .. } => f.write_str("DEFAULT"),
6036 }
6037 }
6038}
6039
6040impl Render for PartitionSelection {
6041 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6042 match self {
6043 PartitionSelection::All { .. } => f.write_str("PARTITION (ALL)"),
6044 PartitionSelection::Names { names, .. } => {
6045 f.write_str("PARTITION (")?;
6046 render_comma_separated(names, ctx, f)?;
6047 f.write_str(")")
6048 }
6049 }
6050 }
6051}
6052
6053impl Render for RenameStatement {
6054 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6055 match self {
6056 RenameStatement::Table {
6057 table_keyword,
6058 renames,
6059 ..
6060 } => {
6061 f.write_str("RENAME ")?;
6062 f.write_str(table_keyword_str(*table_keyword))?;
6063 f.write_str(" ")?;
6064 render_comma_separated(renames, ctx, f)
6065 }
6066 RenameStatement::User { renames, .. } => {
6067 f.write_str("RENAME USER ")?;
6068 render_comma_separated(renames, ctx, f)
6069 }
6070 }
6071 }
6072}
6073
6074impl Render for TableRename {
6075 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6076 self.from.render(ctx, f)?;
6077 f.write_str(" TO ")?;
6078 self.to.render(ctx, f)
6079 }
6080}
6081
6082impl Render for UserRename {
6083 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6084 self.from.render(ctx, f)?;
6085 f.write_str(" TO ")?;
6086 self.to.render(ctx, f)
6087 }
6088}
6089
6090impl Render for FlushStatement {
6091 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6092 f.write_str("FLUSH")?;
6093 if let Some(prefix) = self.no_write_to_binlog {
6094 f.write_str(" ")?;
6095 f.write_str(no_write_to_binlog_keyword(prefix))?;
6096 }
6097 f.write_str(" ")?;
6098 self.target.render(ctx, f)
6099 }
6100}
6101
6102impl Render for FlushTarget {
6103 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6104 match self {
6105 FlushTarget::Tables {
6106 table_keyword,
6107 tables,
6108 lock,
6109 ..
6110 } => {
6111 f.write_str(table_keyword_str(*table_keyword))?;
6112 if !tables.is_empty() {
6113 f.write_str(" ")?;
6114 render_comma_separated(tables, ctx, f)?;
6115 }
6116 if let Some(lock) = lock {
6117 f.write_str(" ")?;
6118 f.write_str(match lock {
6119 FlushTablesLock::WithReadLock => "WITH READ LOCK",
6120 FlushTablesLock::ForExport => "FOR EXPORT",
6121 })?;
6122 }
6123 Ok(())
6124 }
6125 FlushTarget::Options { options, .. } => render_comma_separated(options, ctx, f),
6126 }
6127 }
6128}
6129
6130impl Render for FlushOption {
6131 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6132 match self {
6133 FlushOption::Privileges { .. } => f.write_str("PRIVILEGES"),
6134 FlushOption::Logs { .. } => f.write_str("LOGS"),
6135 FlushOption::BinaryLogs { .. } => f.write_str("BINARY LOGS"),
6136 FlushOption::EngineLogs { .. } => f.write_str("ENGINE LOGS"),
6137 FlushOption::ErrorLogs { .. } => f.write_str("ERROR LOGS"),
6138 FlushOption::GeneralLogs { .. } => f.write_str("GENERAL LOGS"),
6139 FlushOption::SlowLogs { .. } => f.write_str("SLOW LOGS"),
6140 FlushOption::RelayLogs { channel, .. } => {
6141 f.write_str("RELAY LOGS")?;
6142 if let Some(channel) = channel {
6143 f.write_str(" FOR CHANNEL ")?;
6144 channel.render(ctx, f)?;
6145 }
6146 Ok(())
6147 }
6148 FlushOption::Status { .. } => f.write_str("STATUS"),
6149 FlushOption::UserResources { .. } => f.write_str("USER_RESOURCES"),
6150 FlushOption::OptimizerCosts { .. } => f.write_str("OPTIMIZER_COSTS"),
6151 }
6152 }
6153}
6154
6155impl<X: Extension + Render> Render for PurgeStatement<X> {
6156 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6157 f.write_str("PURGE BINARY LOGS ")?;
6158 self.target.render(ctx, f)
6159 }
6160}
6161
6162impl<X: Extension + Render> Render for PurgeTarget<X> {
6163 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6164 match self {
6165 PurgeTarget::To { log, .. } => {
6166 f.write_str("TO ")?;
6167 log.render(ctx, f)
6168 }
6169 PurgeTarget::Before { datetime, .. } => {
6170 f.write_str("BEFORE ")?;
6171 datetime.render(ctx, f)
6172 }
6173 }
6174 }
6175}
6176
6177fn render_for_channel(
6180 channel: &Option<Literal>,
6181 ctx: &RenderCtx<'_>,
6182 f: &mut fmt::Formatter<'_>,
6183) -> fmt::Result {
6184 if let Some(channel) = channel {
6185 f.write_str(" FOR CHANNEL ")?;
6186 channel.render(ctx, f)?;
6187 }
6188 Ok(())
6189}
6190
6191fn render_replica_connection_option(
6194 keyword: &str,
6195 value: &Option<Literal>,
6196 ctx: &RenderCtx<'_>,
6197 f: &mut fmt::Formatter<'_>,
6198) -> fmt::Result {
6199 if let Some(value) = value {
6200 f.write_str(keyword)?;
6201 value.render(ctx, f)?;
6202 }
6203 Ok(())
6204}
6205
6206impl Render for ReplicationStatement {
6207 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6208 match self {
6209 ReplicationStatement::ChangeSource {
6210 options, channel, ..
6211 } => {
6212 f.write_str("CHANGE REPLICATION SOURCE TO ")?;
6213 render_comma_separated(options, ctx, f)?;
6214 render_for_channel(channel, ctx, f)
6215 }
6216 ReplicationStatement::ChangeFilter { rules, channel, .. } => {
6217 f.write_str("CHANGE REPLICATION FILTER ")?;
6218 render_comma_separated(rules, ctx, f)?;
6219 render_for_channel(channel, ctx, f)
6220 }
6221 ReplicationStatement::StartReplica {
6222 threads,
6223 until,
6224 user,
6225 password,
6226 default_auth,
6227 plugin_dir,
6228 channel,
6229 ..
6230 } => {
6231 f.write_str("START REPLICA")?;
6232 if !threads.is_empty() {
6233 f.write_str(" ")?;
6234 render_comma_separated(threads, ctx, f)?;
6235 }
6236 if !until.is_empty() {
6237 f.write_str(" UNTIL ")?;
6238 render_comma_separated(until, ctx, f)?;
6239 }
6240 render_replica_connection_option(" USER = ", user, ctx, f)?;
6241 render_replica_connection_option(" PASSWORD = ", password, ctx, f)?;
6242 render_replica_connection_option(" DEFAULT_AUTH = ", default_auth, ctx, f)?;
6243 render_replica_connection_option(" PLUGIN_DIR = ", plugin_dir, ctx, f)?;
6244 render_for_channel(channel, ctx, f)
6245 }
6246 ReplicationStatement::StopReplica {
6247 threads, channel, ..
6248 } => {
6249 f.write_str("STOP REPLICA")?;
6250 if !threads.is_empty() {
6251 f.write_str(" ")?;
6252 render_comma_separated(threads, ctx, f)?;
6253 }
6254 render_for_channel(channel, ctx, f)
6255 }
6256 ReplicationStatement::StartGroupReplication { options, .. } => {
6257 f.write_str("START GROUP_REPLICATION")?;
6258 if !options.is_empty() {
6259 f.write_str(" ")?;
6260 render_comma_separated(options, ctx, f)?;
6261 }
6262 Ok(())
6263 }
6264 ReplicationStatement::StopGroupReplication { .. } => {
6265 f.write_str("STOP GROUP_REPLICATION")
6266 }
6267 }
6268 }
6269}
6270
6271impl Render for ChangeReplicationSourceOption {
6272 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6273 f.write_str(self.name.keyword())?;
6274 f.write_str(" = ")?;
6275 self.value.render(ctx, f)
6276 }
6277}
6278
6279impl Render for ChangeReplicationSourceOptionValue {
6280 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6281 match self {
6282 Self::String { value, .. } | Self::Number { value, .. } => value.render(ctx, f),
6283 Self::NullableString { value, .. } => match value {
6284 Some(value) => value.render(ctx, f),
6285 None => f.write_str("NULL"),
6286 },
6287 Self::User { account, .. } => match account {
6288 Some(account) => account.render(ctx, f),
6289 None => f.write_str("NULL"),
6290 },
6291 Self::ServerIds { ids, .. } => {
6292 f.write_str("(")?;
6293 render_comma_separated(ids, ctx, f)?;
6294 f.write_str(")")
6295 }
6296 Self::PrimaryKeyCheck { check, .. } => f.write_str(match check {
6297 RequirePrimaryKeyCheck::On => "ON",
6298 RequirePrimaryKeyCheck::Off => "OFF",
6299 RequirePrimaryKeyCheck::Stream => "STREAM",
6300 RequirePrimaryKeyCheck::Generate => "GENERATE",
6301 }),
6302 Self::AssignGtids { kind, uuid, .. } => match kind {
6303 AssignGtidsKind::Off => f.write_str("OFF"),
6304 AssignGtidsKind::Local => f.write_str("LOCAL"),
6305 AssignGtidsKind::Uuid => match uuid {
6306 Some(uuid) => uuid.render(ctx, f),
6307 None => Ok(()),
6308 },
6309 },
6310 }
6311 }
6312}
6313
6314impl Render for ReplicationFilterRule {
6315 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6316 match self {
6317 Self::DoDb { databases, .. } => {
6318 f.write_str("REPLICATE_DO_DB = (")?;
6319 render_comma_separated(databases, ctx, f)?;
6320 f.write_str(")")
6321 }
6322 Self::IgnoreDb { databases, .. } => {
6323 f.write_str("REPLICATE_IGNORE_DB = (")?;
6324 render_comma_separated(databases, ctx, f)?;
6325 f.write_str(")")
6326 }
6327 Self::DoTable { tables, .. } => {
6328 f.write_str("REPLICATE_DO_TABLE = (")?;
6329 render_comma_separated(tables, ctx, f)?;
6330 f.write_str(")")
6331 }
6332 Self::IgnoreTable { tables, .. } => {
6333 f.write_str("REPLICATE_IGNORE_TABLE = (")?;
6334 render_comma_separated(tables, ctx, f)?;
6335 f.write_str(")")
6336 }
6337 Self::WildDoTable { patterns, .. } => {
6338 f.write_str("REPLICATE_WILD_DO_TABLE = (")?;
6339 render_comma_separated(patterns, ctx, f)?;
6340 f.write_str(")")
6341 }
6342 Self::WildIgnoreTable { patterns, .. } => {
6343 f.write_str("REPLICATE_WILD_IGNORE_TABLE = (")?;
6344 render_comma_separated(patterns, ctx, f)?;
6345 f.write_str(")")
6346 }
6347 Self::RewriteDb { pairs, .. } => {
6348 f.write_str("REPLICATE_REWRITE_DB = (")?;
6349 render_comma_separated(pairs, ctx, f)?;
6350 f.write_str(")")
6351 }
6352 }
6353 }
6354}
6355
6356impl Render for RewriteDbPair {
6357 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6358 f.write_str("(")?;
6359 self.from.render(ctx, f)?;
6360 f.write_str(", ")?;
6361 self.to.render(ctx, f)?;
6362 f.write_str(")")
6363 }
6364}
6365
6366impl Render for ReplicaThreadOption {
6367 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6368 f.write_str(match self {
6369 Self::Sql { .. } => "SQL_THREAD",
6370 Self::Io {
6371 keyword: IoThreadKeyword::Io,
6372 ..
6373 } => "IO_THREAD",
6374 Self::Io {
6375 keyword: IoThreadKeyword::Relay,
6376 ..
6377 } => "RELAY_THREAD",
6378 })
6379 }
6380}
6381
6382impl Render for ReplicaUntilCondition {
6383 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6384 match self {
6385 Self::SourceLogFile { value, .. } => {
6386 f.write_str("SOURCE_LOG_FILE = ")?;
6387 value.render(ctx, f)
6388 }
6389 Self::SourceLogPos { value, .. } => {
6390 f.write_str("SOURCE_LOG_POS = ")?;
6391 value.render(ctx, f)
6392 }
6393 Self::RelayLogFile { value, .. } => {
6394 f.write_str("RELAY_LOG_FILE = ")?;
6395 value.render(ctx, f)
6396 }
6397 Self::RelayLogPos { value, .. } => {
6398 f.write_str("RELAY_LOG_POS = ")?;
6399 value.render(ctx, f)
6400 }
6401 Self::SqlBeforeGtids { value, .. } => {
6402 f.write_str("SQL_BEFORE_GTIDS = ")?;
6403 value.render(ctx, f)
6404 }
6405 Self::SqlAfterGtids { value, .. } => {
6406 f.write_str("SQL_AFTER_GTIDS = ")?;
6407 value.render(ctx, f)
6408 }
6409 Self::SqlAfterMtsGaps { .. } => f.write_str("SQL_AFTER_MTS_GAPS"),
6410 }
6411 }
6412}
6413
6414impl Render for GroupReplicationOption {
6415 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6416 match self {
6417 Self::User { value, .. } => {
6418 f.write_str("USER = ")?;
6419 value.render(ctx, f)
6420 }
6421 Self::Password { value, .. } => {
6422 f.write_str("PASSWORD = ")?;
6423 value.render(ctx, f)
6424 }
6425 Self::DefaultAuth { value, .. } => {
6426 f.write_str("DEFAULT_AUTH = ")?;
6427 value.render(ctx, f)
6428 }
6429 }
6430 }
6431}
6432
6433impl Render for AccountName {
6434 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6435 match self {
6436 Self::Account { user, host, .. } => {
6437 user.render(ctx, f)?;
6438 if let Some(host) = host {
6439 f.write_str("@")?;
6440 host.render(ctx, f)?;
6441 }
6442 Ok(())
6443 }
6444 Self::CurrentUser { parens, .. } => {
6445 f.write_str("CURRENT_USER")?;
6446 if *parens {
6447 f.write_str("()")?;
6448 }
6449 Ok(())
6450 }
6451 }
6452 }
6453}
6454
6455struct UserOptionTail<'a> {
6461 require: &'a Option<TlsRequirement>,
6462 resource_options: &'a [ResourceLimit],
6463 password_lock_options: &'a [PasswordLockOption],
6464 attribute: &'a Option<UserAttribute>,
6465}
6466
6467fn render_user_option_tail(
6470 tail: UserOptionTail<'_>,
6471 ctx: &RenderCtx<'_>,
6472 f: &mut fmt::Formatter<'_>,
6473) -> fmt::Result {
6474 if let Some(require) = tail.require {
6475 f.write_str(" ")?;
6476 require.render(ctx, f)?;
6477 }
6478 if !tail.resource_options.is_empty() {
6479 f.write_str(" WITH")?;
6481 for option in tail.resource_options {
6482 f.write_str(" ")?;
6483 option.render(ctx, f)?;
6484 }
6485 }
6486 for option in tail.password_lock_options {
6487 f.write_str(" ")?;
6488 option.render(ctx, f)?;
6489 }
6490 if let Some(attribute) = tail.attribute {
6491 f.write_str(" ")?;
6492 attribute.render(ctx, f)?;
6493 }
6494 Ok(())
6495}
6496
6497impl Render for CreateUser {
6498 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6499 f.write_str("CREATE USER ")?;
6500 if self.if_not_exists {
6501 f.write_str("IF NOT EXISTS ")?;
6502 }
6503 render_comma_separated(&self.users, ctx, f)?;
6504 if !self.default_roles.is_empty() {
6505 f.write_str(" DEFAULT ROLE ")?;
6506 render_comma_separated(&self.default_roles, ctx, f)?;
6507 }
6508 render_user_option_tail(
6509 UserOptionTail {
6510 require: &self.require,
6511 resource_options: &self.resource_options,
6512 password_lock_options: &self.password_lock_options,
6513 attribute: &self.attribute,
6514 },
6515 ctx,
6516 f,
6517 )
6518 }
6519}
6520
6521impl Render for UserSpec {
6522 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6523 self.account.render(ctx, f)?;
6524 if let Some(auth) = &self.auth {
6525 f.write_str(" ")?;
6526 auth.render(ctx, f)?;
6527 }
6528 Ok(())
6529 }
6530}
6531
6532impl Render for AuthOption {
6533 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6534 match self {
6535 Self::Password { password, .. } => {
6536 f.write_str("IDENTIFIED BY ")?;
6537 password.render(ctx, f)
6538 }
6539 Self::RandomPassword { .. } => f.write_str("IDENTIFIED BY RANDOM PASSWORD"),
6540 Self::Plugin { plugin, .. } => {
6541 f.write_str("IDENTIFIED WITH ")?;
6542 plugin.render(ctx, f)
6543 }
6544 Self::PluginAs {
6545 plugin,
6546 auth_string,
6547 ..
6548 } => {
6549 f.write_str("IDENTIFIED WITH ")?;
6550 plugin.render(ctx, f)?;
6551 f.write_str(" AS ")?;
6552 auth_string.render(ctx, f)
6553 }
6554 Self::PluginByPassword {
6555 plugin, password, ..
6556 } => {
6557 f.write_str("IDENTIFIED WITH ")?;
6558 plugin.render(ctx, f)?;
6559 f.write_str(" BY ")?;
6560 password.render(ctx, f)
6561 }
6562 Self::PluginByRandomPassword { plugin, .. } => {
6563 f.write_str("IDENTIFIED WITH ")?;
6564 plugin.render(ctx, f)?;
6565 f.write_str(" BY RANDOM PASSWORD")
6566 }
6567 }
6568 }
6569}
6570
6571impl Render for TlsRequirement {
6572 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6573 f.write_str("REQUIRE ")?;
6574 match self {
6575 Self::None { .. } => f.write_str("NONE"),
6576 Self::Ssl { .. } => f.write_str("SSL"),
6577 Self::X509 { .. } => f.write_str("X509"),
6578 Self::Options { options, .. } => {
6579 for (i, option) in options.iter().enumerate() {
6580 if i > 0 {
6581 f.write_str(" AND ")?;
6582 }
6583 option.render(ctx, f)?;
6584 }
6585 Ok(())
6586 }
6587 }
6588 }
6589}
6590
6591impl Render for TlsOption {
6592 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6593 match self {
6594 Self::Subject { value, .. } => {
6595 f.write_str("SUBJECT ")?;
6596 value.render(ctx, f)
6597 }
6598 Self::Issuer { value, .. } => {
6599 f.write_str("ISSUER ")?;
6600 value.render(ctx, f)
6601 }
6602 Self::Cipher { value, .. } => {
6603 f.write_str("CIPHER ")?;
6604 value.render(ctx, f)
6605 }
6606 }
6607 }
6608}
6609
6610impl Render for ResourceLimit {
6611 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6612 let (keyword, value) = match self {
6613 Self::MaxQueriesPerHour { value, .. } => ("MAX_QUERIES_PER_HOUR", value),
6614 Self::MaxUpdatesPerHour { value, .. } => ("MAX_UPDATES_PER_HOUR", value),
6615 Self::MaxConnectionsPerHour { value, .. } => ("MAX_CONNECTIONS_PER_HOUR", value),
6616 Self::MaxUserConnections { value, .. } => ("MAX_USER_CONNECTIONS", value),
6617 };
6618 f.write_str(keyword)?;
6619 f.write_str(" ")?;
6620 value.render(ctx, f)
6621 }
6622}
6623
6624impl Render for PasswordLockOption {
6625 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6626 match self {
6627 Self::AccountLock { .. } => f.write_str("ACCOUNT LOCK"),
6628 Self::AccountUnlock { .. } => f.write_str("ACCOUNT UNLOCK"),
6629 Self::PasswordExpire { .. } => f.write_str("PASSWORD EXPIRE"),
6630 Self::PasswordExpireDefault { .. } => f.write_str("PASSWORD EXPIRE DEFAULT"),
6631 Self::PasswordExpireNever { .. } => f.write_str("PASSWORD EXPIRE NEVER"),
6632 Self::PasswordExpireInterval { days, .. } => {
6633 f.write_str("PASSWORD EXPIRE INTERVAL ")?;
6634 days.render(ctx, f)?;
6635 f.write_str(" DAY")
6636 }
6637 Self::PasswordHistory { count, .. } => {
6638 f.write_str("PASSWORD HISTORY ")?;
6639 count.render(ctx, f)
6640 }
6641 Self::PasswordHistoryDefault { .. } => f.write_str("PASSWORD HISTORY DEFAULT"),
6642 Self::PasswordReuseInterval { days, .. } => {
6643 f.write_str("PASSWORD REUSE INTERVAL ")?;
6644 days.render(ctx, f)?;
6645 f.write_str(" DAY")
6646 }
6647 Self::PasswordReuseIntervalDefault { .. } => {
6648 f.write_str("PASSWORD REUSE INTERVAL DEFAULT")
6649 }
6650 Self::PasswordRequireCurrent { .. } => f.write_str("PASSWORD REQUIRE CURRENT"),
6651 Self::PasswordRequireCurrentDefault { .. } => {
6652 f.write_str("PASSWORD REQUIRE CURRENT DEFAULT")
6653 }
6654 Self::PasswordRequireCurrentOptional { .. } => {
6655 f.write_str("PASSWORD REQUIRE CURRENT OPTIONAL")
6656 }
6657 Self::FailedLoginAttempts { count, .. } => {
6658 f.write_str("FAILED_LOGIN_ATTEMPTS ")?;
6659 count.render(ctx, f)
6660 }
6661 Self::PasswordLockTime { days, .. } => {
6662 f.write_str("PASSWORD_LOCK_TIME ")?;
6663 days.render(ctx, f)
6664 }
6665 Self::PasswordLockTimeUnbounded { .. } => f.write_str("PASSWORD_LOCK_TIME UNBOUNDED"),
6666 }
6667 }
6668}
6669
6670impl Render for UserAttribute {
6671 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6672 match self {
6673 Self::Comment { comment, .. } => {
6674 f.write_str("COMMENT ")?;
6675 comment.render(ctx, f)
6676 }
6677 Self::Attribute { attribute, .. } => {
6678 f.write_str("ATTRIBUTE ")?;
6679 attribute.render(ctx, f)
6680 }
6681 }
6682 }
6683}
6684
6685impl Render for AlterUser {
6686 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6687 f.write_str("ALTER USER ")?;
6688 match self {
6689 Self::Modify {
6690 if_exists,
6691 users,
6692 require,
6693 resource_options,
6694 password_lock_options,
6695 attribute,
6696 ..
6697 } => {
6698 if *if_exists {
6699 f.write_str("IF EXISTS ")?;
6700 }
6701 render_comma_separated(users, ctx, f)?;
6702 render_user_option_tail(
6703 UserOptionTail {
6704 require,
6705 resource_options,
6706 password_lock_options,
6707 attribute,
6708 },
6709 ctx,
6710 f,
6711 )
6712 }
6713 Self::DefaultRole {
6714 if_exists,
6715 user,
6716 roles,
6717 ..
6718 } => {
6719 if *if_exists {
6720 f.write_str("IF EXISTS ")?;
6721 }
6722 user.render(ctx, f)?;
6723 f.write_str(" DEFAULT ROLE ")?;
6724 roles.render(ctx, f)
6725 }
6726 }
6727 }
6728}
6729
6730impl Render for AlterUserSpec {
6731 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6732 self.account.render(ctx, f)?;
6733 if let Some(auth) = &self.auth {
6734 f.write_str(" ")?;
6735 auth.render(ctx, f)?;
6736 }
6737 if let Some(replace) = &self.replace {
6738 f.write_str(" REPLACE ")?;
6739 replace.render(ctx, f)?;
6740 }
6741 if self.retain_current_password {
6742 f.write_str(" RETAIN CURRENT PASSWORD")?;
6743 }
6744 if self.discard_old_password {
6745 f.write_str(" DISCARD OLD PASSWORD")?;
6746 }
6747 Ok(())
6748 }
6749}
6750
6751impl Render for DefaultRoleTarget {
6752 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6753 match self {
6754 Self::All { .. } => f.write_str("ALL"),
6755 Self::None { .. } => f.write_str("NONE"),
6756 Self::Roles { roles, .. } => render_comma_separated(roles, ctx, f),
6757 }
6758 }
6759}
6760
6761impl Render for UserRoleList {
6762 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6763 let (verb, guard) = match self.kind {
6764 UserRoleListKind::DropUser => ("DROP USER ", "IF EXISTS "),
6765 UserRoleListKind::CreateRole => ("CREATE ROLE ", "IF NOT EXISTS "),
6766 UserRoleListKind::DropRole => ("DROP ROLE ", "IF EXISTS "),
6767 };
6768 f.write_str(verb)?;
6769 if self.if_guard {
6770 f.write_str(guard)?;
6771 }
6772 render_comma_separated(&self.names, ctx, f)
6773 }
6774}
6775
6776fn no_write_to_binlog_keyword(prefix: NoWriteToBinlog) -> &'static str {
6778 match prefix {
6779 NoWriteToBinlog::NoWriteToBinlog => "NO_WRITE_TO_BINLOG",
6780 NoWriteToBinlog::Local => "LOCAL",
6781 }
6782}
6783
6784fn table_keyword_str(keyword: TableKeyword) -> &'static str {
6786 match keyword {
6787 TableKeyword::Table => "TABLE",
6788 TableKeyword::Tables => "TABLES",
6789 }
6790}
6791
6792fn check_table_option_keyword(option: CheckTableOption) -> &'static str {
6794 match option {
6795 CheckTableOption::ForUpgrade => "FOR UPGRADE",
6796 CheckTableOption::Quick => "QUICK",
6797 CheckTableOption::Fast => "FAST",
6798 CheckTableOption::Medium => "MEDIUM",
6799 CheckTableOption::Extended => "EXTENDED",
6800 CheckTableOption::Changed => "CHANGED",
6801 }
6802}
6803
6804fn checksum_table_option_keyword(option: ChecksumTableOption) -> &'static str {
6806 match option {
6807 ChecksumTableOption::Quick => "QUICK",
6808 ChecksumTableOption::Extended => "EXTENDED",
6809 }
6810}
6811
6812fn repair_table_option_keyword(option: RepairTableOption) -> &'static str {
6814 match option {
6815 RepairTableOption::Quick => "QUICK",
6816 RepairTableOption::Extended => "EXTENDED",
6817 RepairTableOption::UseFrm => "USE_FRM",
6818 }
6819}
6820
6821impl<X: Extension + Render> Render for PrepareStatement<X> {
6822 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6823 f.write_str("PREPARE ")?;
6824 self.name.render(ctx, f)?;
6825 if !self.parameter_types.is_empty() {
6829 f.write_str("(")?;
6830 render_comma_separated(&self.parameter_types, ctx, f)?;
6831 f.write_str(")")?;
6832 }
6833 f.write_str(" AS ")?;
6834 self.statement.render(ctx, f)
6835 }
6836}
6837
6838impl<X: Extension + Render> Render for ExecuteStatement<X> {
6839 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6840 f.write_str("EXECUTE ")?;
6841 self.name.render(ctx, f)?;
6842 if !self.args.is_empty() {
6845 f.write_str("(")?;
6846 render_comma_separated(&self.args, ctx, f)?;
6847 f.write_str(")")?;
6848 }
6849 Ok(())
6850 }
6851}
6852
6853impl Render for DeallocateStatement {
6854 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6855 f.write_str(match self.keyword {
6858 DeallocateKeyword::Deallocate => "DEALLOCATE ",
6859 DeallocateKeyword::Drop => "DROP ",
6860 })?;
6861 if self.prepare_keyword {
6862 f.write_str("PREPARE ")?;
6863 }
6864 self.name.render(ctx, f)
6865 }
6866}
6867
6868impl Render for PrepareFromStatement {
6869 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6870 f.write_str("PREPARE ")?;
6871 self.name.render(ctx, f)?;
6872 f.write_str(" FROM ")?;
6873 self.source.render(ctx, f)
6874 }
6875}
6876
6877impl Render for PrepareSource {
6878 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6879 match self {
6880 PrepareSource::Text { source, .. } => source.render(ctx, f),
6882 PrepareSource::Variable { name, .. } => {
6885 f.write_str("@")?;
6886 name.render(ctx, f)
6887 }
6888 }
6889 }
6890}
6891
6892impl Render for ExecuteUsingStatement {
6893 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6894 f.write_str("EXECUTE ")?;
6895 self.name.render(ctx, f)?;
6896 if let Some((first, rest)) = self.using.split_first() {
6899 f.write_str(" USING @")?;
6900 first.render(ctx, f)?;
6901 for name in rest {
6902 f.write_str(", @")?;
6903 name.render(ctx, f)?;
6904 }
6905 }
6906 Ok(())
6907 }
6908}
6909
6910impl<X: Extension + Render> Render for CallStatement<X> {
6911 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6912 f.write_str("CALL ")?;
6913 self.name.render(ctx, f)?;
6914 if self.parenthesized {
6917 f.write_str("(")?;
6918 render_comma_separated(&self.args, ctx, f)?;
6919 f.write_str(")")?;
6920 }
6921 Ok(())
6922 }
6923}
6924
6925impl Render for DoStatement {
6926 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6927 f.write_str("DO")?;
6928 for arg in &self.args {
6932 f.write_str(" ")?;
6933 arg.render(ctx, f)?;
6934 }
6935 Ok(())
6936 }
6937}
6938
6939impl Render for DoArg {
6940 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6941 match self {
6942 DoArg::Body { body, .. } => body.render(ctx, f),
6943 DoArg::Language { name, .. } => {
6944 f.write_str("LANGUAGE ")?;
6945 name.render(ctx, f)
6946 }
6947 }
6948 }
6949}
6950
6951impl Render for LanguageName {
6952 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6953 match self {
6954 Self::Word { word, .. } => word.render(ctx, f),
6955 Self::String { value, .. } => value.render(ctx, f),
6956 }
6957 }
6958}
6959
6960impl<X: Extension + Render> Render for DoExpressionsStatement<X> {
6961 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6962 f.write_str("DO ")?;
6964 render_comma_separated(&self.items, ctx, f)
6965 }
6966}
6967
6968impl Render for LockTablesStatement {
6969 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6970 f.write_str(if self.plural {
6973 "LOCK TABLES "
6974 } else {
6975 "LOCK TABLE "
6976 })?;
6977 render_comma_separated(&self.tables, ctx, f)
6978 }
6979}
6980
6981impl Render for TableLock {
6982 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6983 self.name.render(ctx, f)?;
6984 if let Some(alias) = &self.alias {
6985 f.write_str(" ")?;
6988 alias.render(ctx, f)?;
6989 }
6990 f.write_str(" ")?;
6991 self.kind.render(ctx, f)
6992 }
6993}
6994
6995impl Render for TableLockKind {
6996 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6997 f.write_str(match self {
6998 TableLockKind::Read => "READ",
6999 TableLockKind::ReadLocal => "READ LOCAL",
7000 TableLockKind::Write => "WRITE",
7001 })
7002 }
7003}
7004
7005impl Render for UnlockTablesStatement {
7006 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7007 f.write_str(if self.plural {
7008 "UNLOCK TABLES"
7009 } else {
7010 "UNLOCK TABLE"
7011 })
7012 }
7013}
7014
7015impl Render for InstanceLockStatement {
7016 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7017 f.write_str(if self.acquire {
7018 "LOCK INSTANCE FOR BACKUP"
7019 } else {
7020 "UNLOCK INSTANCE"
7021 })
7022 }
7023}
7024
7025impl<X: Extension + Render> Render for LoadDataStatement<X> {
7026 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7027 f.write_str("LOAD ")?;
7030 self.format.render(ctx, f)?;
7031 if let Some(concurrency) = self.concurrency {
7032 f.write_str(" ")?;
7033 concurrency.render(ctx, f)?;
7034 }
7035 if self.local {
7036 f.write_str(" LOCAL")?;
7037 }
7038 f.write_str(" INFILE ")?;
7039 self.file.render(ctx, f)?;
7040 if let Some(on_duplicate) = self.on_duplicate {
7041 f.write_str(" ")?;
7042 on_duplicate.render(ctx, f)?;
7043 }
7044 f.write_str(" INTO TABLE ")?;
7045 self.table.render(ctx, f)?;
7046 if !self.partitions.is_empty() {
7047 f.write_str(" PARTITION (")?;
7048 render_comma_separated(&self.partitions, ctx, f)?;
7049 f.write_str(")")?;
7050 }
7051 if let Some(charset) = &self.charset {
7052 f.write_str(" CHARACTER SET ")?;
7053 charset.render(ctx, f)?;
7054 }
7055 if let Some(tag) = &self.rows_identified_by {
7056 f.write_str(" ROWS IDENTIFIED BY ")?;
7057 tag.render(ctx, f)?;
7058 }
7059 if let Some(fields) = &self.fields {
7060 f.write_str(" ")?;
7061 fields.render(ctx, f)?;
7062 }
7063 if let Some(lines) = &self.lines {
7064 f.write_str(" ")?;
7065 lines.render(ctx, f)?;
7066 }
7067 if let Some(ignore_rows) = &self.ignore_rows {
7068 f.write_str(" ")?;
7069 ignore_rows.render(ctx, f)?;
7070 }
7071 if !self.columns.is_empty() {
7072 f.write_str(" (")?;
7073 render_comma_separated(&self.columns, ctx, f)?;
7074 f.write_str(")")?;
7075 }
7076 if !self.set.is_empty() {
7077 f.write_str(" SET ")?;
7078 render_comma_separated(&self.set, ctx, f)?;
7079 }
7080 Ok(())
7081 }
7082}
7083
7084impl Render for LoadDataFormat {
7085 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7086 f.write_str(match self {
7087 LoadDataFormat::Data => "DATA",
7088 LoadDataFormat::Xml => "XML",
7089 })
7090 }
7091}
7092
7093impl Render for LoadDataConcurrency {
7094 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7095 f.write_str(match self {
7096 LoadDataConcurrency::LowPriority => "LOW_PRIORITY",
7097 LoadDataConcurrency::Concurrent => "CONCURRENT",
7098 })
7099 }
7100}
7101
7102impl Render for LoadDataDuplicate {
7103 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7104 f.write_str(match self {
7105 LoadDataDuplicate::Replace => "REPLACE",
7106 LoadDataDuplicate::Ignore => "IGNORE",
7107 })
7108 }
7109}
7110
7111impl Render for LoadDataFields {
7112 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7113 self.spelling.render(ctx, f)?;
7116 if let Some(terminated_by) = &self.terminated_by {
7117 f.write_str(" TERMINATED BY ")?;
7118 terminated_by.render(ctx, f)?;
7119 }
7120 if let Some(enclosed_by) = &self.enclosed_by {
7121 f.write_str(" ")?;
7122 enclosed_by.render(ctx, f)?;
7123 }
7124 if let Some(escaped_by) = &self.escaped_by {
7125 f.write_str(" ESCAPED BY ")?;
7126 escaped_by.render(ctx, f)?;
7127 }
7128 Ok(())
7129 }
7130}
7131
7132impl Render for LoadFieldsSpelling {
7133 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7134 f.write_str(match self {
7135 LoadFieldsSpelling::Fields => "FIELDS",
7136 LoadFieldsSpelling::Columns => "COLUMNS",
7137 })
7138 }
7139}
7140
7141impl Render for LoadDataEnclosed {
7142 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7143 if self.optionally {
7144 f.write_str("OPTIONALLY ")?;
7145 }
7146 f.write_str("ENCLOSED BY ")?;
7147 self.value.render(ctx, f)
7148 }
7149}
7150
7151impl Render for LoadDataLines {
7152 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7153 f.write_str("LINES")?;
7154 if let Some(starting_by) = &self.starting_by {
7155 f.write_str(" STARTING BY ")?;
7156 starting_by.render(ctx, f)?;
7157 }
7158 if let Some(terminated_by) = &self.terminated_by {
7159 f.write_str(" TERMINATED BY ")?;
7160 terminated_by.render(ctx, f)?;
7161 }
7162 Ok(())
7163 }
7164}
7165
7166impl Render for LoadDataIgnoreRows {
7167 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7168 f.write_str("IGNORE ")?;
7169 self.count.render(ctx, f)?;
7170 f.write_str(" ")?;
7171 self.unit.render(ctx, f)
7172 }
7173}
7174
7175impl Render for LoadDataIgnoreUnit {
7176 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7177 f.write_str(match self {
7178 LoadDataIgnoreUnit::Lines => "LINES",
7179 LoadDataIgnoreUnit::Rows => "ROWS",
7180 })
7181 }
7182}
7183
7184impl Render for LoadDataFieldOrVar {
7185 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7186 match self {
7187 LoadDataFieldOrVar::Column { name, .. } => name.render(ctx, f),
7188 LoadDataFieldOrVar::Variable { name, .. } => {
7191 f.write_str("@")?;
7192 name.render(ctx, f)
7193 }
7194 }
7195 }
7196}
7197
7198impl<X: Extension + Render> Render for CreateTrigger<X> {
7199 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7200 f.write_str("CREATE")?;
7201 if let Some(temporary) = self.temporary {
7202 f.write_str(" ")?;
7203 temporary.render(ctx, f)?;
7204 }
7205 f.write_str(" TRIGGER")?;
7206 if self.if_not_exists {
7207 f.write_str(" IF NOT EXISTS")?;
7208 }
7209 f.write_str(" ")?;
7210 self.name.render(ctx, f)?;
7211 if let Some(timing) = self.timing {
7212 f.write_str(" ")?;
7213 timing.render(ctx, f)?;
7214 }
7215 f.write_str(" ")?;
7216 self.event.render(ctx, f)?;
7217 f.write_str(" ON ")?;
7218 self.table.render(ctx, f)?;
7219 if self.for_each_row {
7220 f.write_str(" FOR EACH ROW")?;
7221 }
7222 if let Some(when) = &self.when {
7223 f.write_str(" WHEN ")?;
7224 when.render(ctx, f)?;
7225 }
7226 f.write_str(" BEGIN ")?;
7227 for statement in &self.body {
7228 statement.render(ctx, f)?;
7229 f.write_str("; ")?;
7230 }
7231 f.write_str("END")
7232 }
7233}
7234
7235impl Render for TriggerTiming {
7236 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7237 f.write_str(match self {
7238 TriggerTiming::Before => "BEFORE",
7239 TriggerTiming::After => "AFTER",
7240 TriggerTiming::InsteadOf => "INSTEAD OF",
7241 })
7242 }
7243}
7244
7245impl Render for TriggerEvent {
7246 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7247 match self {
7248 TriggerEvent::Delete { .. } => f.write_str("DELETE"),
7249 TriggerEvent::Insert { .. } => f.write_str("INSERT"),
7250 TriggerEvent::Update { columns, .. } => {
7251 f.write_str("UPDATE")?;
7252 if !columns.is_empty() {
7253 f.write_str(" OF ")?;
7254 render_ident_list(columns, ctx, f)?;
7255 }
7256 Ok(())
7257 }
7258 }
7259 }
7260}
7261
7262impl<X: Extension + Render> Render for CreateStoredTrigger<X> {
7263 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7264 f.write_str("CREATE ")?;
7265 if let Some(definer) = &self.definer {
7266 definer.render(ctx, f)?;
7267 f.write_str(" ")?;
7268 }
7269 f.write_str("TRIGGER ")?;
7270 if self.if_not_exists {
7271 f.write_str("IF NOT EXISTS ")?;
7272 }
7273 self.name.render(ctx, f)?;
7274 f.write_str(" ")?;
7275 self.timing.render(ctx, f)?;
7276 f.write_str(" ")?;
7277 self.event.render(ctx, f)?;
7278 f.write_str(" ON ")?;
7279 self.table.render(ctx, f)?;
7280 f.write_str(" FOR EACH ROW")?;
7281 if let Some(ordering) = &self.ordering {
7282 f.write_str(" ")?;
7283 ordering.render(ctx, f)?;
7284 }
7285 f.write_str(" ")?;
7286 self.body.render(ctx, f)
7287 }
7288}
7289
7290impl Render for TriggerOrder {
7291 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7292 match self {
7293 TriggerOrder::Follows { anchor, .. } => {
7294 f.write_str("FOLLOWS ")?;
7295 anchor.render(ctx, f)
7296 }
7297 TriggerOrder::Precedes { anchor, .. } => {
7298 f.write_str("PRECEDES ")?;
7299 anchor.render(ctx, f)
7300 }
7301 }
7302 }
7303}
7304
7305fn render_compound_body<X: Extension + Render>(
7313 body: &[Statement<X>],
7314 ctx: &RenderCtx<'_>,
7315 f: &mut fmt::Formatter<'_>,
7316) -> fmt::Result {
7317 for statement in body {
7318 f.write_str(" ")?;
7319 statement.render(ctx, f)?;
7320 f.write_str(";")?;
7321 }
7322 Ok(())
7323}
7324
7325impl<X: Extension + Render> Render for CompoundStatement<X> {
7326 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7327 if let Some(label) = &self.label {
7328 label.render(ctx, f)?;
7329 f.write_str(": ")?;
7330 }
7331 f.write_str("BEGIN")?;
7332 for declaration in &self.declarations {
7333 f.write_str(" ")?;
7334 declaration.render(ctx, f)?;
7335 f.write_str(";")?;
7336 }
7337 render_compound_body(&self.body, ctx, f)?;
7338 f.write_str(" END")?;
7339 if let Some(end_label) = &self.end_label {
7340 f.write_str(" ")?;
7341 end_label.render(ctx, f)?;
7342 }
7343 Ok(())
7344 }
7345}
7346
7347impl<X: Extension + Render> Render for Declaration<X> {
7348 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7349 match self {
7350 Declaration::Variable {
7351 names,
7352 data_type,
7353 default,
7354 ..
7355 } => {
7356 f.write_str("DECLARE ")?;
7357 render_ident_list(names, ctx, f)?;
7358 f.write_str(" ")?;
7359 data_type.render(ctx, f)?;
7360 if let Some(default) = default {
7361 f.write_str(" DEFAULT ")?;
7362 default.render(ctx, f)?;
7363 }
7364 Ok(())
7365 }
7366 Declaration::Condition { name, value, .. } => {
7367 f.write_str("DECLARE ")?;
7368 name.render(ctx, f)?;
7369 f.write_str(" CONDITION FOR ")?;
7370 value.render(ctx, f)
7371 }
7372 Declaration::Cursor { name, query, .. } => {
7373 f.write_str("DECLARE ")?;
7374 name.render(ctx, f)?;
7375 f.write_str(" CURSOR FOR ")?;
7376 query.render(ctx, f)
7377 }
7378 Declaration::Handler {
7379 action,
7380 conditions,
7381 body,
7382 ..
7383 } => {
7384 f.write_str("DECLARE ")?;
7385 action.render(ctx, f)?;
7386 f.write_str(" HANDLER FOR ")?;
7387 render_comma_separated(conditions, ctx, f)?;
7388 f.write_str(" ")?;
7389 body.render(ctx, f)
7390 }
7391 }
7392 }
7393}
7394
7395impl Render for HandlerAction {
7396 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7397 f.write_str(match self {
7398 HandlerAction::Continue => "CONTINUE",
7399 HandlerAction::Exit => "EXIT",
7400 HandlerAction::Undo => "UNDO",
7401 })
7402 }
7403}
7404
7405impl Render for ConditionValue {
7406 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7407 match self {
7408 ConditionValue::SqlState {
7409 value_keyword,
7410 sqlstate,
7411 ..
7412 } => {
7413 f.write_str("SQLSTATE ")?;
7414 if *value_keyword {
7415 f.write_str("VALUE ")?;
7416 }
7417 sqlstate.render(ctx, f)
7418 }
7419 ConditionValue::ErrorCode { code, .. } => code.render(ctx, f),
7420 ConditionValue::ConditionName { name, .. } => name.render(ctx, f),
7421 }
7422 }
7423}
7424
7425impl Render for HandlerCondition {
7426 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7427 match self {
7428 HandlerCondition::SqlState {
7429 value_keyword,
7430 sqlstate,
7431 ..
7432 } => {
7433 f.write_str("SQLSTATE ")?;
7434 if *value_keyword {
7435 f.write_str("VALUE ")?;
7436 }
7437 sqlstate.render(ctx, f)
7438 }
7439 HandlerCondition::ErrorCode { code, .. } => code.render(ctx, f),
7440 HandlerCondition::ConditionName { name, .. } => name.render(ctx, f),
7441 HandlerCondition::SqlWarning { .. } => f.write_str("SQLWARNING"),
7442 HandlerCondition::NotFound { .. } => f.write_str("NOT FOUND"),
7443 HandlerCondition::SqlException { .. } => f.write_str("SQLEXCEPTION"),
7444 }
7445 }
7446}
7447
7448impl<X: Extension + Render> Render for ConditionalBranch<X> {
7449 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7450 self.guard.render(ctx, f)?;
7451 f.write_str(" THEN")?;
7452 render_compound_body(&self.body, ctx, f)
7453 }
7454}
7455
7456impl<X: Extension + Render> Render for IfStatement<X> {
7457 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7458 f.write_str("IF ")?;
7459 for (i, branch) in self.branches.iter().enumerate() {
7460 if i > 0 {
7461 f.write_str(" ELSEIF ")?;
7462 }
7463 branch.render(ctx, f)?;
7464 }
7465 if let Some(else_body) = &self.else_body {
7466 f.write_str(" ELSE")?;
7467 render_compound_body(else_body, ctx, f)?;
7468 }
7469 f.write_str(" END IF")
7470 }
7471}
7472
7473impl<X: Extension + Render> Render for CaseStatement<X> {
7474 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7475 f.write_str("CASE")?;
7476 if let Some(operand) = &self.operand {
7477 f.write_str(" ")?;
7478 operand.render(ctx, f)?;
7479 }
7480 for branch in &self.when_branches {
7481 f.write_str(" WHEN ")?;
7482 branch.render(ctx, f)?;
7483 }
7484 if let Some(else_body) = &self.else_body {
7485 f.write_str(" ELSE")?;
7486 render_compound_body(else_body, ctx, f)?;
7487 }
7488 f.write_str(" END CASE")
7489 }
7490}
7491
7492impl<X: Extension + Render> Render for LoopStatement<X> {
7493 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7494 if let Some(label) = &self.label {
7495 label.render(ctx, f)?;
7496 f.write_str(": ")?;
7497 }
7498 f.write_str("LOOP")?;
7499 render_compound_body(&self.body, ctx, f)?;
7500 f.write_str(" END LOOP")?;
7501 if let Some(end_label) = &self.end_label {
7502 f.write_str(" ")?;
7503 end_label.render(ctx, f)?;
7504 }
7505 Ok(())
7506 }
7507}
7508
7509impl<X: Extension + Render> Render for WhileStatement<X> {
7510 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7511 if let Some(label) = &self.label {
7512 label.render(ctx, f)?;
7513 f.write_str(": ")?;
7514 }
7515 f.write_str("WHILE ")?;
7516 self.condition.render(ctx, f)?;
7517 f.write_str(" DO")?;
7518 render_compound_body(&self.body, ctx, f)?;
7519 f.write_str(" END WHILE")?;
7520 if let Some(end_label) = &self.end_label {
7521 f.write_str(" ")?;
7522 end_label.render(ctx, f)?;
7523 }
7524 Ok(())
7525 }
7526}
7527
7528impl<X: Extension + Render> Render for RepeatStatement<X> {
7529 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7530 if let Some(label) = &self.label {
7531 label.render(ctx, f)?;
7532 f.write_str(": ")?;
7533 }
7534 f.write_str("REPEAT")?;
7535 render_compound_body(&self.body, ctx, f)?;
7536 f.write_str(" UNTIL ")?;
7537 self.condition.render(ctx, f)?;
7538 f.write_str(" END REPEAT")?;
7539 if let Some(end_label) = &self.end_label {
7540 f.write_str(" ")?;
7541 end_label.render(ctx, f)?;
7542 }
7543 Ok(())
7544 }
7545}
7546
7547impl Render for LeaveStatement {
7548 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7549 f.write_str("LEAVE ")?;
7550 self.label.render(ctx, f)
7551 }
7552}
7553
7554impl Render for IterateStatement {
7555 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7556 f.write_str("ITERATE ")?;
7557 self.label.render(ctx, f)
7558 }
7559}
7560
7561impl<X: Extension + Render> Render for ReturnStatement<X> {
7562 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7563 f.write_str("RETURN ")?;
7564 self.value.render(ctx, f)
7565 }
7566}
7567
7568impl Render for OpenCursorStatement {
7569 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7570 f.write_str("OPEN ")?;
7571 self.cursor.render(ctx, f)
7572 }
7573}
7574
7575impl Render for CloseCursorStatement {
7576 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7577 f.write_str("CLOSE ")?;
7578 self.cursor.render(ctx, f)
7579 }
7580}
7581
7582impl Render for FetchCursorStatement {
7583 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7584 f.write_str("FETCH ")?;
7585 if self.next_keyword {
7586 f.write_str("NEXT ")?;
7587 }
7588 if self.from_keyword {
7589 f.write_str("FROM ")?;
7590 }
7591 self.cursor.render(ctx, f)?;
7592 f.write_str(" INTO ")?;
7593 render_ident_list(&self.targets, ctx, f)
7594 }
7595}
7596
7597impl<X: Extension + Render> SignalStatement<X> {
7598 fn render_as(
7601 &self,
7602 ctx: &RenderCtx<'_>,
7603 f: &mut fmt::Formatter<'_>,
7604 keyword: &str,
7605 ) -> fmt::Result {
7606 f.write_str(keyword)?;
7607 if let Some(condition) = &self.condition {
7608 f.write_str(" ")?;
7609 condition.render(ctx, f)?;
7610 }
7611 if !self.set_items.is_empty() {
7612 f.write_str(" SET ")?;
7613 render_comma_separated(&self.set_items, ctx, f)?;
7614 }
7615 Ok(())
7616 }
7617}
7618
7619impl<X: Extension + Render> Render for SignalItem<X> {
7620 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7621 self.name.render(ctx, f)?;
7622 f.write_str(" = ")?;
7623 self.value.render(ctx, f)
7624 }
7625}
7626
7627impl Render for SignalItemName {
7628 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7629 f.write_str(match self {
7630 SignalItemName::ClassOrigin => "CLASS_ORIGIN",
7631 SignalItemName::SubclassOrigin => "SUBCLASS_ORIGIN",
7632 SignalItemName::ConstraintCatalog => "CONSTRAINT_CATALOG",
7633 SignalItemName::ConstraintSchema => "CONSTRAINT_SCHEMA",
7634 SignalItemName::ConstraintName => "CONSTRAINT_NAME",
7635 SignalItemName::CatalogName => "CATALOG_NAME",
7636 SignalItemName::SchemaName => "SCHEMA_NAME",
7637 SignalItemName::TableName => "TABLE_NAME",
7638 SignalItemName::ColumnName => "COLUMN_NAME",
7639 SignalItemName::CursorName => "CURSOR_NAME",
7640 SignalItemName::MessageText => "MESSAGE_TEXT",
7641 SignalItemName::MysqlErrno => "MYSQL_ERRNO",
7642 })
7643 }
7644}
7645
7646impl<X: Extension + Render> Render for GetDiagnosticsStatement<X> {
7647 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7648 f.write_str("GET")?;
7649 match self.area {
7650 DiagnosticsArea::Implicit => {}
7651 DiagnosticsArea::Current => f.write_str(" CURRENT")?,
7652 DiagnosticsArea::Stacked => f.write_str(" STACKED")?,
7653 }
7654 f.write_str(" DIAGNOSTICS ")?;
7655 self.info.render(ctx, f)
7656 }
7657}
7658
7659impl<X: Extension + Render> Render for DiagnosticsInfo<X> {
7660 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7661 match self {
7662 DiagnosticsInfo::Statement { items, .. } => render_comma_separated(items, ctx, f),
7663 DiagnosticsInfo::Condition { number, items, .. } => {
7664 f.write_str("CONDITION ")?;
7665 number.render(ctx, f)?;
7666 f.write_str(" ")?;
7667 render_comma_separated(items, ctx, f)
7668 }
7669 }
7670 }
7671}
7672
7673impl<X: Extension + Render> Render for StatementInfoItem<X> {
7674 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7675 self.target.render(ctx, f)?;
7676 f.write_str(" = ")?;
7677 self.name.render(ctx, f)
7678 }
7679}
7680
7681impl Render for StatementInfoItemName {
7682 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7683 f.write_str(match self {
7684 StatementInfoItemName::Number => "NUMBER",
7685 StatementInfoItemName::RowCount => "ROW_COUNT",
7686 })
7687 }
7688}
7689
7690impl<X: Extension + Render> Render for ConditionInfoItem<X> {
7691 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7692 self.target.render(ctx, f)?;
7693 f.write_str(" = ")?;
7694 self.name.render(ctx, f)
7695 }
7696}
7697
7698impl Render for ConditionInfoItemName {
7699 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7700 f.write_str(match self {
7701 ConditionInfoItemName::ClassOrigin => "CLASS_ORIGIN",
7702 ConditionInfoItemName::SubclassOrigin => "SUBCLASS_ORIGIN",
7703 ConditionInfoItemName::ConstraintCatalog => "CONSTRAINT_CATALOG",
7704 ConditionInfoItemName::ConstraintSchema => "CONSTRAINT_SCHEMA",
7705 ConditionInfoItemName::ConstraintName => "CONSTRAINT_NAME",
7706 ConditionInfoItemName::CatalogName => "CATALOG_NAME",
7707 ConditionInfoItemName::SchemaName => "SCHEMA_NAME",
7708 ConditionInfoItemName::TableName => "TABLE_NAME",
7709 ConditionInfoItemName::ColumnName => "COLUMN_NAME",
7710 ConditionInfoItemName::CursorName => "CURSOR_NAME",
7711 ConditionInfoItemName::MessageText => "MESSAGE_TEXT",
7712 ConditionInfoItemName::MysqlErrno => "MYSQL_ERRNO",
7713 ConditionInfoItemName::ReturnedSqlstate => "RETURNED_SQLSTATE",
7714 })
7715 }
7716}
7717
7718impl<X: Extension + Render> Render for CreateTable<X> {
7719 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7720 f.write_str("CREATE")?;
7721 if self.or_replace {
7722 f.write_str(" OR REPLACE")?;
7723 }
7724 if let Some(temporary) = self.temporary {
7725 f.write_str(" ")?;
7726 temporary.render(ctx, f)?;
7727 }
7728 if self.unlogged {
7731 f.write_str(" UNLOGGED")?;
7732 }
7733 f.write_str(" TABLE")?;
7734 if self.if_not_exists {
7735 f.write_str(" IF NOT EXISTS")?;
7736 }
7737 f.write_str(" ")?;
7738 self.name.render(ctx, f)?;
7739 match &self.body {
7740 CreateTableBody::Definition { .. }
7745 | CreateTableBody::PartitionOf { .. }
7746 | CreateTableBody::OfType { .. }
7747 | CreateTableBody::LikeSource { .. } => {
7751 self.body.render(ctx, f)?;
7752 render_inherits(&self.inherits, ctx, f)?;
7753 render_partition_by(&self.partition_by, ctx, f)?;
7754 render_access_method(&self.access_method, ctx, f)?;
7755 render_create_table_options(&self.options, ctx, f)?;
7756 }
7757 CreateTableBody::AsQuery {
7758 columns,
7759 query,
7760 with_data,
7761 ..
7762 } => {
7763 render_ctas_columns(columns, ctx, f)?;
7764 render_access_method(&self.access_method, ctx, f)?;
7767 render_create_table_options(&self.options, ctx, f)?;
7768 render_ctas_query_tail(query, *with_data, ctx, f)?;
7769 }
7770 CreateTableBody::AsExecute {
7771 columns,
7772 execute,
7773 with_data,
7774 ..
7775 } => {
7776 render_ctas_columns(columns, ctx, f)?;
7777 render_access_method(&self.access_method, ctx, f)?;
7778 render_create_table_options(&self.options, ctx, f)?;
7779 f.write_str(" AS ")?;
7780 execute.render(ctx, f)?;
7781 render_with_data(*with_data, f)?;
7782 }
7783 }
7784 Ok(())
7785 }
7786}
7787
7788fn render_inherits(
7791 inherits: &[ObjectName],
7792 ctx: &RenderCtx<'_>,
7793 f: &mut fmt::Formatter<'_>,
7794) -> fmt::Result {
7795 if !inherits.is_empty() {
7796 f.write_str(" INHERITS (")?;
7797 render_comma_separated(inherits, ctx, f)?;
7798 f.write_str(")")?;
7799 }
7800 Ok(())
7801}
7802
7803fn render_partition_by<X: Extension + Render>(
7806 partition_by: &Option<Box<PartitionSpec<X>>>,
7807 ctx: &RenderCtx<'_>,
7808 f: &mut fmt::Formatter<'_>,
7809) -> fmt::Result {
7810 if let Some(spec) = partition_by {
7811 f.write_str(" PARTITION BY ")?;
7812 spec.render(ctx, f)?;
7813 }
7814 Ok(())
7815}
7816
7817fn render_access_method(
7820 access_method: &Option<Box<Ident>>,
7821 ctx: &RenderCtx<'_>,
7822 f: &mut fmt::Formatter<'_>,
7823) -> fmt::Result {
7824 if let Some(method) = access_method {
7825 f.write_str(" USING ")?;
7826 method.render(ctx, f)?;
7827 }
7828 Ok(())
7829}
7830
7831impl Render for TemporaryTableKind {
7832 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7833 f.write_str(match self {
7834 Self::Temp => "TEMP",
7835 Self::Temporary => "TEMPORARY",
7836 })
7837 }
7838}
7839
7840fn render_create_table_options<X: Extension + Render>(
7846 options: &[CreateTableOption<X>],
7847 ctx: &RenderCtx<'_>,
7848 f: &mut fmt::Formatter<'_>,
7849) -> fmt::Result {
7850 for (index, option) in options.iter().enumerate() {
7851 let sqlite_option = matches!(
7852 option.kind,
7853 CreateTableOptionKind::WithoutRowid { .. } | CreateTableOptionKind::Strict { .. }
7854 );
7855 f.write_str(if index > 0 && sqlite_option {
7856 ", "
7857 } else {
7858 " "
7859 })?;
7860 option.render(ctx, f)?;
7861 }
7862 Ok(())
7863}
7864
7865impl<X: Extension + Render> Render for CreateTableBody<X> {
7866 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7867 match self {
7868 Self::Definition { elements, .. } => {
7869 f.write_str(" (")?;
7870 render_comma_separated(elements, ctx, f)?;
7871 f.write_str(")")
7872 }
7873 Self::AsQuery {
7874 columns,
7875 query,
7876 with_data,
7877 ..
7878 } => {
7879 render_ctas_columns(columns, ctx, f)?;
7880 render_ctas_query_tail(query, *with_data, ctx, f)
7881 }
7882 Self::AsExecute {
7883 columns,
7884 execute,
7885 with_data,
7886 ..
7887 } => {
7888 render_ctas_columns(columns, ctx, f)?;
7889 f.write_str(" AS ")?;
7890 execute.render(ctx, f)?;
7891 render_with_data(*with_data, f)
7892 }
7893 Self::PartitionOf {
7894 parent,
7895 elements,
7896 bound,
7897 ..
7898 } => {
7899 f.write_str(" PARTITION OF ")?;
7900 parent.render(ctx, f)?;
7901 if !elements.is_empty() {
7904 f.write_str(" (")?;
7905 render_comma_separated(elements, ctx, f)?;
7906 f.write_str(")")?;
7907 }
7908 f.write_str(" ")?;
7909 bound.render(ctx, f)
7910 }
7911 Self::OfType {
7912 type_name,
7913 elements,
7914 ..
7915 } => {
7916 f.write_str(" OF ")?;
7917 type_name.render(ctx, f)?;
7918 if !elements.is_empty() {
7921 f.write_str(" (")?;
7922 render_comma_separated(elements, ctx, f)?;
7923 f.write_str(")")?;
7924 }
7925 Ok(())
7926 }
7927 Self::LikeSource {
7928 source,
7929 parenthesized,
7930 ..
7931 } => {
7932 if *parenthesized {
7934 f.write_str(" (LIKE ")?;
7935 source.render(ctx, f)?;
7936 f.write_str(")")
7937 } else {
7938 f.write_str(" LIKE ")?;
7939 source.render(ctx, f)
7940 }
7941 }
7942 }
7943 }
7944}
7945
7946impl<X: Extension + Render> Render for PartitionSpec<X> {
7947 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7948 self.strategy.render(ctx, f)?;
7949 f.write_str(" (")?;
7950 render_comma_separated(&self.columns, ctx, f)?;
7951 f.write_str(")")
7952 }
7953}
7954
7955impl Render for PartitionStrategy {
7956 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7957 f.write_str(match self {
7958 Self::List => "LIST",
7959 Self::Range => "RANGE",
7960 Self::Hash => "HASH",
7961 })
7962 }
7963}
7964
7965impl<X: Extension + Render> Render for PartitionElem<X> {
7966 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7967 if self.parenthesized {
7972 f.write_str("(")?;
7973 self.expr.render(ctx, f)?;
7974 f.write_str(")")?;
7975 } else {
7976 self.expr.render(ctx, f)?;
7977 }
7978 if let Some(collation) = &self.collation {
7979 f.write_str(" COLLATE ")?;
7980 collation.render(ctx, f)?;
7981 }
7982 if let Some(opclass) = &self.opclass {
7983 f.write_str(" ")?;
7984 opclass.render(ctx, f)?;
7985 }
7986 Ok(())
7987 }
7988}
7989
7990impl<X: Extension + Render> Render for PartitionBound<X> {
7991 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7992 match self {
7993 Self::List { values, .. } => {
7994 f.write_str("FOR VALUES IN (")?;
7995 render_comma_separated(values, ctx, f)?;
7996 f.write_str(")")
7997 }
7998 Self::Range { from, to, .. } => {
7999 f.write_str("FOR VALUES FROM (")?;
8000 render_comma_separated(from, ctx, f)?;
8001 f.write_str(") TO (")?;
8002 render_comma_separated(to, ctx, f)?;
8003 f.write_str(")")
8004 }
8005 Self::Hash {
8006 modulus, remainder, ..
8007 } => {
8008 f.write_str("FOR VALUES WITH (MODULUS ")?;
8009 modulus.render(ctx, f)?;
8010 f.write_str(", REMAINDER ")?;
8011 remainder.render(ctx, f)?;
8012 f.write_str(")")
8013 }
8014 Self::Default { .. } => f.write_str("DEFAULT"),
8015 }
8016 }
8017}
8018
8019fn render_ctas_columns(
8020 columns: &[Ident],
8021 ctx: &RenderCtx<'_>,
8022 f: &mut fmt::Formatter<'_>,
8023) -> fmt::Result {
8024 if !columns.is_empty() {
8025 f.write_str(" (")?;
8026 render_ident_list(columns, ctx, f)?;
8027 f.write_str(")")?;
8028 }
8029 Ok(())
8030}
8031
8032fn render_ctas_query_tail<X: Extension + Render>(
8033 query: &Query<X>,
8034 with_data: Option<bool>,
8035 ctx: &RenderCtx<'_>,
8036 f: &mut fmt::Formatter<'_>,
8037) -> fmt::Result {
8038 f.write_str(" AS ")?;
8039 query.render(ctx, f)?;
8040 render_with_data(with_data, f)
8041}
8042
8043fn render_with_data(with_data: Option<bool>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8047 match with_data {
8048 Some(true) => f.write_str(" WITH DATA"),
8049 Some(false) => f.write_str(" WITH NO DATA"),
8050 None => Ok(()),
8051 }
8052}
8053
8054impl<X: Extension + Render> Render for TableElement<X> {
8055 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8056 match self {
8057 Self::Column { column, .. } => column.render(ctx, f),
8058 Self::Constraint { constraint, .. } => constraint.render(ctx, f),
8059 Self::Like {
8060 source, options, ..
8061 } => {
8062 f.write_str("LIKE ")?;
8063 source.render(ctx, f)?;
8064 for option in options {
8065 f.write_str(" ")?;
8066 option.render(ctx, f)?;
8067 }
8068 Ok(())
8069 }
8070 }
8071 }
8072}
8073
8074impl Render for TableLikeOption {
8075 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8076 self.action.render(ctx, f)?;
8077 f.write_str(" ")?;
8078 self.feature.render(ctx, f)
8079 }
8080}
8081
8082impl Render for TableLikeAction {
8083 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8084 f.write_str(match self {
8085 Self::Including => "INCLUDING",
8086 Self::Excluding => "EXCLUDING",
8087 })
8088 }
8089}
8090
8091impl Render for TableLikeFeature {
8092 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8093 f.write_str(match self {
8094 Self::Comments => "COMMENTS",
8095 Self::Compression => "COMPRESSION",
8096 Self::Constraints => "CONSTRAINTS",
8097 Self::Defaults => "DEFAULTS",
8098 Self::Generated => "GENERATED",
8099 Self::Identity => "IDENTITY",
8100 Self::Indexes => "INDEXES",
8101 Self::Statistics => "STATISTICS",
8102 Self::Storage => "STORAGE",
8103 Self::All => "ALL",
8104 })
8105 }
8106}
8107
8108impl<X: Extension + Render> Render for ColumnDef<X> {
8109 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8110 self.name.render(ctx, f)?;
8111 render_column_def_tail(self, ctx, f)
8115 }
8116}
8117
8118impl<X: Extension + Render> Render for ColumnConstraint<X> {
8119 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8120 if let Some(name) = &self.name {
8121 f.write_str("CONSTRAINT ")?;
8122 name.render(ctx, f)?;
8123 if !matches!(self.option, ColumnOption::Bare { .. }) {
8126 f.write_str(" ")?;
8127 }
8128 }
8129 self.option.render(ctx, f)?;
8130 if let Some(conflict) = self.conflict {
8131 f.write_str(" ON CONFLICT ")?;
8132 conflict.render(ctx, f)?;
8133 }
8134 render_constraint_characteristics(&self.characteristics, ctx, f)
8135 }
8136}
8137
8138fn render_constraint_characteristics(
8141 characteristics: &Option<Box<ConstraintCharacteristics>>,
8142 ctx: &RenderCtx<'_>,
8143 f: &mut fmt::Formatter<'_>,
8144) -> fmt::Result {
8145 if let Some(characteristics) = characteristics {
8146 f.write_str(" ")?;
8147 characteristics.render(ctx, f)?;
8148 }
8149 Ok(())
8150}
8151
8152impl Render for ConstraintCharacteristics {
8153 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8154 let mut written = false;
8157 if let Some(deferrable) = self.deferrable {
8158 f.write_str(if deferrable {
8159 "DEFERRABLE"
8160 } else {
8161 "NOT DEFERRABLE"
8162 })?;
8163 written = true;
8164 }
8165 if let Some(initially_deferred) = self.initially_deferred {
8166 if written {
8167 f.write_str(" ")?;
8168 }
8169 f.write_str(if initially_deferred {
8170 "INITIALLY DEFERRED"
8171 } else {
8172 "INITIALLY IMMEDIATE"
8173 })?;
8174 }
8175 Ok(())
8176 }
8177}
8178
8179impl<X: Extension + Render> Render for ColumnOption<X> {
8180 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8181 match self {
8182 Self::Null { .. } => f.write_str("NULL"),
8183 Self::NotNull { .. } => f.write_str("NOT NULL"),
8184 Self::Default { expr, .. } => {
8185 f.write_str("DEFAULT ")?;
8186 expr.render(ctx, f)
8187 }
8188 Self::Generated { generated, .. } => generated.render(ctx, f),
8189 Self::Identity { identity, .. } => identity.render(ctx, f),
8190 Self::PrimaryKey {
8191 ascending,
8192 index_tablespace,
8193 ..
8194 } => {
8195 f.write_str("PRIMARY KEY")?;
8196 match ascending {
8197 Some(true) => f.write_str(" ASC")?,
8198 Some(false) => f.write_str(" DESC")?,
8199 None => {}
8200 }
8201 render_using_index_tablespace(index_tablespace.as_deref(), ctx, f)
8202 }
8203 Self::Unique {
8204 nulls_not_distinct,
8205 index_tablespace,
8206 ..
8207 } => {
8208 f.write_str("UNIQUE")?;
8209 render_nulls_not_distinct(*nulls_not_distinct, f)?;
8210 render_using_index_tablespace(index_tablespace.as_deref(), ctx, f)
8211 }
8212 Self::AutoIncrement { spelling, .. } => spelling.render(ctx, f),
8213 Self::Collate { collation, .. } => {
8214 f.write_str("COLLATE ")?;
8215 collation.render(ctx, f)
8216 }
8217 Self::Check {
8218 expr, no_inherit, ..
8219 } => {
8220 f.write_str("CHECK (")?;
8221 expr.render(ctx, f)?;
8222 f.write_str(")")?;
8223 if *no_inherit {
8224 f.write_str(" NO INHERIT")?;
8225 }
8226 Ok(())
8227 }
8228 Self::References { reference, .. } => reference.render(ctx, f),
8229 Self::Bare { .. } => Ok(()),
8232 Self::Other { ext, .. } => ext.render(ctx, f),
8233 }
8234 }
8235}
8236
8237impl Render for AutoIncrementSpelling {
8238 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8239 f.write_str(match self {
8240 Self::Underscored => "AUTO_INCREMENT",
8241 Self::Joined => "AUTOINCREMENT",
8242 })
8243 }
8244}
8245
8246impl Render for ForeignKeyRef {
8247 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8248 f.write_str("REFERENCES ")?;
8249 self.table.render(ctx, f)?;
8250 if !self.columns.is_empty() {
8251 f.write_str(" (")?;
8252 render_ident_list(&self.columns, ctx, f)?;
8253 f.write_str(")")?;
8254 }
8255 if let Some(match_type) = self.match_type {
8259 f.write_str(" MATCH ")?;
8260 match_type.render(ctx, f)?;
8261 }
8262 let render_on_delete = |f: &mut fmt::Formatter<'_>| -> fmt::Result {
8263 if let Some(on_delete) = &self.on_delete {
8264 f.write_str(" ON DELETE ")?;
8265 on_delete.render(ctx, f)?;
8266 }
8267 Ok(())
8268 };
8269 let render_on_update = |f: &mut fmt::Formatter<'_>| -> fmt::Result {
8270 if let Some(on_update) = &self.on_update {
8271 f.write_str(" ON UPDATE ")?;
8272 on_update.render(ctx, f)?;
8273 }
8274 Ok(())
8275 };
8276 if self.update_before_delete && honours_source_spelling(ctx) {
8277 render_on_update(f)?;
8278 render_on_delete(f)?;
8279 } else {
8280 render_on_delete(f)?;
8281 render_on_update(f)?;
8282 }
8283 Ok(())
8284 }
8285}
8286
8287impl Render for ForeignKeyMatch {
8288 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8289 f.write_str(match self {
8290 Self::Full => "FULL",
8291 Self::Partial => "PARTIAL",
8292 Self::Simple => "SIMPLE",
8293 })
8294 }
8295}
8296
8297impl Render for ReferentialAction {
8298 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8299 match self {
8300 Self::NoAction { .. } => f.write_str("NO ACTION"),
8301 Self::Restrict { .. } => f.write_str("RESTRICT"),
8302 Self::Cascade { .. } => f.write_str("CASCADE"),
8303 Self::SetNull { columns, .. } => render_set_action(ctx, f, "SET NULL", columns),
8304 Self::SetDefault { columns, .. } => render_set_action(ctx, f, "SET DEFAULT", columns),
8305 }
8306 }
8307}
8308
8309fn render_set_action(
8311 ctx: &RenderCtx<'_>,
8312 f: &mut fmt::Formatter<'_>,
8313 keyword: &str,
8314 columns: &[Ident],
8315) -> fmt::Result {
8316 f.write_str(keyword)?;
8317 if !columns.is_empty() {
8318 f.write_str(" (")?;
8319 render_ident_list(columns, ctx, f)?;
8320 f.write_str(")")?;
8321 }
8322 Ok(())
8323}
8324
8325impl<X: Extension + Render> Render for GeneratedColumn<X> {
8326 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8327 f.write_str(match self.spelling {
8330 GeneratedColumnSpelling::GeneratedAlways => "GENERATED ALWAYS AS (",
8331 GeneratedColumnSpelling::Shorthand => "AS (",
8332 })?;
8333 self.expr.render(ctx, f)?;
8334 f.write_str(")")?;
8335 if let Some(storage) = self.storage {
8336 f.write_str(" ")?;
8337 storage.render(ctx, f)?;
8338 }
8339 Ok(())
8340 }
8341}
8342
8343impl Render for GeneratedColumnStorage {
8344 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8345 f.write_str(match self {
8346 Self::Stored => "STORED",
8347 Self::Virtual => "VIRTUAL",
8348 })
8349 }
8350}
8351
8352impl<X: Extension + Render> Render for IdentityColumn<X> {
8353 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8354 f.write_str("GENERATED ")?;
8355 self.generation.render(ctx, f)?;
8356 f.write_str(" AS IDENTITY")?;
8357 if !self.options.is_empty() {
8358 f.write_str(" (")?;
8359 for (index, option) in self.options.iter().enumerate() {
8360 if index > 0 {
8361 f.write_str(" ")?;
8362 }
8363 option.render(ctx, f)?;
8364 }
8365 f.write_str(")")?;
8366 }
8367 Ok(())
8368 }
8369}
8370
8371impl Render for IdentityGeneration {
8372 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8373 f.write_str(match self {
8374 Self::Always => "ALWAYS",
8375 Self::ByDefault => "BY DEFAULT",
8376 })
8377 }
8378}
8379
8380impl<X: Extension + Render> Render for IdentityOption<X> {
8381 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8382 match self {
8383 Self::StartWith { expr, .. } => {
8384 f.write_str("START WITH ")?;
8385 expr.render(ctx, f)
8386 }
8387 Self::IncrementBy { expr, .. } => {
8388 f.write_str("INCREMENT BY ")?;
8389 expr.render(ctx, f)
8390 }
8391 Self::MinValue {
8392 value: Some(expr), ..
8393 } => {
8394 f.write_str("MINVALUE ")?;
8395 expr.render(ctx, f)
8396 }
8397 Self::MinValue { value: None, .. } => f.write_str("NO MINVALUE"),
8398 Self::MaxValue {
8399 value: Some(expr), ..
8400 } => {
8401 f.write_str("MAXVALUE ")?;
8402 expr.render(ctx, f)
8403 }
8404 Self::MaxValue { value: None, .. } => f.write_str("NO MAXVALUE"),
8405 Self::Cache { expr, .. } => {
8406 f.write_str("CACHE ")?;
8407 expr.render(ctx, f)
8408 }
8409 Self::Cycle { cycle: true, .. } => f.write_str("CYCLE"),
8410 Self::Cycle { cycle: false, .. } => f.write_str("NO CYCLE"),
8411 }
8412 }
8413}
8414
8415impl<X: Extension + Render> Render for TableConstraintDef<X> {
8416 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8417 if let Some(name) = &self.name {
8418 f.write_str("CONSTRAINT ")?;
8419 name.render(ctx, f)?;
8420 if !matches!(self.constraint, TableConstraint::Bare { .. }) {
8423 f.write_str(" ")?;
8424 }
8425 }
8426 self.constraint.render(ctx, f)?;
8427 if self.no_inherit {
8431 f.write_str(" NO INHERIT")?;
8432 }
8433 if self.not_valid {
8434 f.write_str(" NOT VALID")?;
8435 }
8436 render_constraint_characteristics(&self.characteristics, ctx, f)
8437 }
8438}
8439
8440impl<X: Extension + Render> Render for TableConstraint<X> {
8441 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8442 match self {
8443 Self::PrimaryKey {
8444 columns, include, ..
8445 } => {
8446 f.write_str("PRIMARY KEY (")?;
8447 render_comma_separated(columns, ctx, f)?;
8448 f.write_str(")")?;
8449 render_include_columns(include, ctx, f)
8450 }
8451 Self::Unique {
8452 columns,
8453 nulls_not_distinct,
8454 include,
8455 ..
8456 } => {
8457 f.write_str("UNIQUE")?;
8458 render_nulls_not_distinct(*nulls_not_distinct, f)?;
8459 f.write_str(" (")?;
8460 render_comma_separated(columns, ctx, f)?;
8461 f.write_str(")")?;
8462 render_include_columns(include, ctx, f)
8463 }
8464 Self::Check { expr, .. } => {
8465 f.write_str("CHECK (")?;
8466 expr.render(ctx, f)?;
8467 f.write_str(")")
8468 }
8469 Self::Exclude { exclude, .. } => exclude.render(ctx, f),
8470 Self::ForeignKey {
8471 columns,
8472 references,
8473 ..
8474 } => {
8475 f.write_str("FOREIGN KEY (")?;
8476 render_ident_list(columns, ctx, f)?;
8477 f.write_str(") ")?;
8478 references.render(ctx, f)
8479 }
8480 Self::Bare { .. } => Ok(()),
8483 Self::Other { ext, .. } => ext.render(ctx, f),
8484 }
8485 }
8486}
8487
8488fn render_include_columns(
8491 include: &[Ident],
8492 ctx: &RenderCtx<'_>,
8493 f: &mut fmt::Formatter<'_>,
8494) -> fmt::Result {
8495 if !include.is_empty() {
8496 f.write_str(" INCLUDE (")?;
8497 render_ident_list(include, ctx, f)?;
8498 f.write_str(")")?;
8499 }
8500 Ok(())
8501}
8502
8503fn render_nulls_not_distinct(
8506 nulls_not_distinct: Option<bool>,
8507 f: &mut fmt::Formatter<'_>,
8508) -> fmt::Result {
8509 match nulls_not_distinct {
8510 Some(false) => f.write_str(" NULLS NOT DISTINCT"),
8511 Some(true) => f.write_str(" NULLS DISTINCT"),
8512 None => Ok(()),
8513 }
8514}
8515
8516fn render_using_index_tablespace(
8519 tablespace: Option<&Ident>,
8520 ctx: &RenderCtx<'_>,
8521 f: &mut fmt::Formatter<'_>,
8522) -> fmt::Result {
8523 if let Some(tablespace) = tablespace {
8524 f.write_str(" USING INDEX TABLESPACE ")?;
8525 tablespace.render(ctx, f)?;
8526 }
8527 Ok(())
8528}
8529
8530impl<X: Extension + Render> Render for ExcludeConstraint<X> {
8531 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8532 f.write_str("EXCLUDE")?;
8533 if let Some(method) = &self.method {
8534 f.write_str(" USING ")?;
8535 method.render(ctx, f)?;
8536 }
8537 f.write_str(" (")?;
8538 render_comma_separated(&self.elements, ctx, f)?;
8539 f.write_str(")")?;
8540 render_include_columns(&self.include, ctx, f)?;
8541 if !self.with_params.is_empty() {
8542 f.write_str(" WITH (")?;
8543 render_comma_separated(&self.with_params, ctx, f)?;
8544 f.write_str(")")?;
8545 }
8546 render_using_index_tablespace(self.index_tablespace.as_ref(), ctx, f)?;
8547 if let Some(predicate) = &self.predicate {
8548 f.write_str(" WHERE (")?;
8549 predicate.render(ctx, f)?;
8550 f.write_str(")")?;
8551 }
8552 Ok(())
8553 }
8554}
8555
8556impl<X: Extension + Render> Render for ExcludeElement<X> {
8557 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8558 if self.parenthesized {
8561 f.write_str("(")?;
8562 self.expr.render(ctx, f)?;
8563 f.write_str(")")?;
8564 } else {
8565 self.expr.render(ctx, f)?;
8566 }
8567 if let Some(collation) = &self.collation {
8568 f.write_str(" COLLATE ")?;
8569 collation.render(ctx, f)?;
8570 }
8571 if let Some(opclass) = &self.opclass {
8572 f.write_str(" ")?;
8573 opclass.render(ctx, f)?;
8574 if !self.opclass_params.is_empty() {
8575 f.write_str(" (")?;
8576 render_comma_separated(&self.opclass_params, ctx, f)?;
8577 f.write_str(")")?;
8578 }
8579 }
8580 match self.asc {
8581 Some(true) => f.write_str(" ASC")?,
8582 Some(false) => f.write_str(" DESC")?,
8583 None => {}
8584 }
8585 match self.nulls_first {
8586 Some(true) => f.write_str(" NULLS FIRST")?,
8587 Some(false) => f.write_str(" NULLS LAST")?,
8588 None => {}
8589 }
8590 f.write_str(" WITH ")?;
8591 self.operator.render(ctx, f)
8592 }
8593}
8594
8595impl Render for ExcludeOperator {
8596 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8597 match self.spelling {
8598 NamedOperatorSpelling::Bare => f.write_str(ctx.resolve(self.op)),
8600 NamedOperatorSpelling::OperatorKeyword => {
8603 f.write_str("OPERATOR(")?;
8604 for part in &self.schema.0 {
8605 part.render(ctx, f)?;
8606 f.write_str(".")?;
8607 }
8608 f.write_str(ctx.resolve(self.op))?;
8609 f.write_str(")")
8610 }
8611 }
8612 }
8613}
8614
8615impl<X: Extension + Render> Render for CreateTableOption<X> {
8616 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8617 self.kind.render(ctx, f)
8618 }
8619}
8620
8621impl<X: Extension + Render> Render for CreateTableOptionKind<X> {
8622 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8623 match self {
8624 Self::With { params, .. } => {
8625 f.write_str("WITH (")?;
8626 render_comma_separated(params, ctx, f)?;
8627 f.write_str(")")
8628 }
8629 Self::OnCommit { action, .. } => {
8630 f.write_str("ON COMMIT ")?;
8631 action.render(ctx, f)
8632 }
8633 Self::Tablespace { tablespace, .. } => {
8634 f.write_str("TABLESPACE ")?;
8635 tablespace.render(ctx, f)
8636 }
8637 Self::KeyValue { option, .. } => option.render(ctx, f),
8638 Self::WithoutRowid { .. } => f.write_str("WITHOUT ROWID"),
8639 Self::Strict { .. } => f.write_str("STRICT"),
8640 Self::WithoutOids { .. } => f.write_str("WITHOUT OIDS"),
8641 }
8642 }
8643}
8644
8645impl Render for TableOption {
8646 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8647 self.name.render(ctx, f)?;
8651 f.write_str(" = ")?;
8652 self.value.render(ctx, f)
8653 }
8654}
8655
8656impl Render for TableOptionValue {
8657 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8658 match self {
8659 Self::Word { word, .. } => word.render(ctx, f),
8660 Self::String { value, .. } | Self::Number { value, .. } => value.render(ctx, f),
8661 }
8662 }
8663}
8664
8665impl Render for OnCommitAction {
8666 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8667 f.write_str(match self {
8668 Self::PreserveRows => "PRESERVE ROWS",
8669 Self::DeleteRows => "DELETE ROWS",
8670 Self::Drop => "DROP",
8671 })
8672 }
8673}
8674
8675impl<X: Extension + Render> Render for TableStorageParameter<X> {
8676 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8677 self.name.render(ctx, f)?;
8678 if let Some(value) = &self.value {
8679 f.write_str(" = ")?;
8680 value.render(ctx, f)?;
8681 }
8682 Ok(())
8683 }
8684}
8685
8686impl<X: Extension + Render> Render for AlterTable<X> {
8687 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8688 f.write_str("ALTER TABLE")?;
8689 if self.if_exists {
8690 f.write_str(" IF EXISTS")?;
8691 }
8692 f.write_str(" ")?;
8693 self.name.render(ctx, f)?;
8694 f.write_str(" ")?;
8695 render_comma_separated(&self.actions, ctx, f)
8696 }
8697}
8698
8699impl Render for AlterColumnTarget {
8700 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8701 for (i, part) in self.parts.iter().enumerate() {
8702 if i > 0 {
8703 f.write_str(".")?;
8704 }
8705 part.render(ctx, f)?;
8706 }
8707 Ok(())
8708 }
8709}
8710
8711fn render_optional_column_keyword(
8715 column_keyword: bool,
8716 ctx: &RenderCtx<'_>,
8717 f: &mut fmt::Formatter<'_>,
8718) -> fmt::Result {
8719 if column_keyword || !honours_source_spelling(ctx) {
8720 f.write_str(" COLUMN")?;
8721 }
8722 Ok(())
8723}
8724
8725fn render_column_def_tail<X: Extension + Render>(
8726 column: &ColumnDef<X>,
8727 ctx: &RenderCtx<'_>,
8728 f: &mut fmt::Formatter<'_>,
8729) -> fmt::Result {
8730 if let Some(data_type) = &column.data_type {
8731 f.write_str(" ")?;
8732 data_type.render(ctx, f)?;
8733 }
8734 if let Some(storage) = &column.storage {
8735 f.write_str(" STORAGE ")?;
8736 storage.render(ctx, f)?;
8737 }
8738 if let Some(compression) = &column.compression {
8739 f.write_str(" COMPRESSION ")?;
8740 compression.render(ctx, f)?;
8741 }
8742 for constraint in &column.constraints {
8743 f.write_str(" ")?;
8744 constraint.render(ctx, f)?;
8745 }
8746 Ok(())
8747}
8748
8749impl<X: Extension + Render> Render for AlterTableAction<X> {
8750 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8751 match self {
8752 Self::AddColumn {
8755 if_not_exists,
8756 column_keyword,
8757 target,
8758 column,
8759 ..
8760 } => {
8761 f.write_str("ADD")?;
8762 render_optional_column_keyword(*column_keyword, ctx, f)?;
8763 if *if_not_exists {
8764 f.write_str(" IF NOT EXISTS")?;
8765 }
8766 f.write_str(" ")?;
8767 if let Some(target) = target {
8768 target.render(ctx, f)?;
8769 render_column_def_tail(column, ctx, f)
8770 } else {
8771 column.render(ctx, f)
8772 }
8773 }
8774 Self::DropColumn {
8775 if_exists,
8776 column_keyword,
8777 name,
8778 behavior,
8779 ..
8780 } => {
8781 f.write_str("DROP")?;
8782 render_optional_column_keyword(*column_keyword, ctx, f)?;
8783 if *if_exists {
8784 f.write_str(" IF EXISTS")?;
8785 }
8786 f.write_str(" ")?;
8787 name.render(ctx, f)?;
8788 render_drop_behavior(*behavior, ctx, f)
8789 }
8790 Self::AlterColumn {
8791 column_keyword,
8792 name,
8793 change,
8794 ..
8795 } => {
8796 f.write_str("ALTER")?;
8797 render_optional_column_keyword(*column_keyword, ctx, f)?;
8798 f.write_str(" ")?;
8799 name.render(ctx, f)?;
8800 f.write_str(" ")?;
8801 change.render(ctx, f)
8802 }
8803 Self::AddConstraint { constraint, .. } => {
8804 f.write_str("ADD ")?;
8805 constraint.render(ctx, f)
8806 }
8807 Self::DropConstraint {
8808 if_exists,
8809 name,
8810 behavior,
8811 ..
8812 } => {
8813 f.write_str("DROP CONSTRAINT")?;
8814 if *if_exists {
8815 f.write_str(" IF EXISTS")?;
8816 }
8817 f.write_str(" ")?;
8818 name.render(ctx, f)?;
8819 render_drop_behavior(*behavior, ctx, f)
8820 }
8821 Self::RenameColumn {
8822 column_keyword,
8823 name,
8824 new_name,
8825 ..
8826 } => {
8827 f.write_str("RENAME")?;
8828 render_optional_column_keyword(*column_keyword, ctx, f)?;
8829 f.write_str(" ")?;
8830 name.render(ctx, f)?;
8831 f.write_str(" TO ")?;
8832 new_name.render(ctx, f)
8833 }
8834 Self::RenameTable { new_name, .. } => {
8835 f.write_str("RENAME TO ")?;
8836 new_name.render(ctx, f)
8837 }
8838 Self::AttachPartition {
8839 partition, bound, ..
8840 } => {
8841 f.write_str("ATTACH PARTITION ")?;
8842 partition.render(ctx, f)?;
8843 f.write_str(" ")?;
8844 bound.render(ctx, f)
8845 }
8846 Self::DetachPartition {
8847 partition, mode, ..
8848 } => {
8849 f.write_str("DETACH PARTITION ")?;
8850 partition.render(ctx, f)?;
8851 match mode {
8852 Some(DetachPartitionMode::Concurrently) => f.write_str(" CONCURRENTLY"),
8853 Some(DetachPartitionMode::Finalize) => f.write_str(" FINALIZE"),
8854 None => Ok(()),
8855 }
8856 }
8857 }
8858 }
8859}
8860
8861impl<X: Extension + Render> Render for AlterColumnAction<X> {
8862 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8863 match self {
8864 Self::SetDefault { expr, .. } => {
8865 f.write_str("SET DEFAULT ")?;
8866 expr.render(ctx, f)
8867 }
8868 Self::DropDefault { .. } => f.write_str("DROP DEFAULT"),
8869 Self::SetNotNull { .. } => f.write_str("SET NOT NULL"),
8870 Self::DropNotNull { .. } => f.write_str("DROP NOT NULL"),
8871 Self::SetDataType {
8874 set_data,
8875 data_type,
8876 using,
8877 ..
8878 } => {
8879 if *set_data || !honours_source_spelling(ctx) {
8880 f.write_str("SET DATA TYPE ")?;
8881 } else {
8882 f.write_str("TYPE ")?;
8883 }
8884 data_type.render(ctx, f)?;
8885 if let Some(using) = using {
8886 f.write_str(" USING ")?;
8887 using.render(ctx, f)?;
8888 }
8889 Ok(())
8890 }
8891 }
8892 }
8893}
8894
8895impl Render for DropStatement {
8896 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8897 f.write_str("DROP ")?;
8898 self.object_kind.render(ctx, f)?;
8899 if self.if_exists {
8900 f.write_str(" IF EXISTS")?;
8901 }
8902 f.write_str(" ")?;
8903 render_comma_separated(&self.names, ctx, f)?;
8904 render_drop_behavior(self.behavior, ctx, f)
8905 }
8906}
8907
8908impl Render for DropObjectKind {
8909 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8910 f.write_str(match self {
8911 Self::Table => "TABLE",
8912 Self::View => "VIEW",
8913 Self::MaterializedView => "MATERIALIZED VIEW",
8914 Self::Index => "INDEX",
8915 Self::Schema => "SCHEMA",
8916 Self::Type => "TYPE",
8917 Self::Sequence => "SEQUENCE",
8918 Self::Macro => "MACRO",
8919 Self::MacroTable => "MACRO TABLE",
8920 Self::Trigger => "TRIGGER",
8921 })
8922 }
8923}
8924
8925impl Render for DropBehavior {
8926 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8927 f.write_str(match self {
8928 Self::Cascade => "CASCADE",
8929 Self::Restrict => "RESTRICT",
8930 })
8931 }
8932}
8933
8934fn render_drop_behavior(
8937 behavior: Option<DropBehavior>,
8938 ctx: &RenderCtx<'_>,
8939 f: &mut fmt::Formatter<'_>,
8940) -> fmt::Result {
8941 if let Some(behavior) = behavior {
8942 f.write_str(" ")?;
8943 behavior.render(ctx, f)?;
8944 }
8945 Ok(())
8946}
8947
8948impl<X: Extension + Render> Render for CreateSchema<X> {
8949 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8950 f.write_str("CREATE SCHEMA")?;
8951 if self.if_not_exists {
8952 f.write_str(" IF NOT EXISTS")?;
8953 }
8954 if let Some(name) = &self.name {
8955 f.write_str(" ")?;
8956 name.render(ctx, f)?;
8957 }
8958 if let Some(authorization) = &self.authorization {
8959 f.write_str(" AUTHORIZATION ")?;
8960 authorization.render(ctx, f)?;
8961 }
8962 for element in &self.elements {
8967 f.write_str(" ")?;
8968 element.render(ctx, f)?;
8969 }
8970 Ok(())
8971 }
8972}
8973
8974impl<X: Extension + Render> Render for CreateView<X> {
8975 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8976 f.write_str("CREATE")?;
8977 if self.or_replace {
8978 f.write_str(" OR REPLACE")?;
8979 }
8980 if let Some(temporary) = self.temporary {
8981 f.write_str(" ")?;
8982 temporary.render(ctx, f)?;
8983 }
8984 if self.materialized {
8985 f.write_str(" MATERIALIZED")?;
8986 }
8987 if self.recursive {
8990 f.write_str(" RECURSIVE")?;
8991 }
8992 self.options.render(ctx, f)?;
8995 f.write_str(" VIEW")?;
8996 if self.if_not_exists {
8997 f.write_str(" IF NOT EXISTS")?;
8998 }
8999 f.write_str(" ")?;
9000 self.name.render(ctx, f)?;
9001 if !self.columns.is_empty() {
9002 f.write_str(" (")?;
9003 render_ident_list(&self.columns, ctx, f)?;
9004 f.write_str(")")?;
9005 }
9006 f.write_str(" AS ")?;
9007 self.query.render(ctx, f)?;
9008 if let Some(check_option) = self.check_option {
9009 f.write_str(" ")?;
9010 check_option.render(ctx, f)?;
9011 }
9012 render_with_data(self.with_data, f)
9013 }
9014}
9015
9016impl<X: Extension + Render> Render for AlterView<X> {
9017 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9018 f.write_str("ALTER")?;
9019 self.options.render(ctx, f)?;
9022 f.write_str(" VIEW ")?;
9023 self.name.render(ctx, f)?;
9024 if !self.columns.is_empty() {
9025 f.write_str(" (")?;
9026 render_ident_list(&self.columns, ctx, f)?;
9027 f.write_str(")")?;
9028 }
9029 f.write_str(" AS ")?;
9030 self.query.render(ctx, f)?;
9031 if let Some(check_option) = self.check_option {
9032 f.write_str(" ")?;
9033 check_option.render(ctx, f)?;
9034 }
9035 Ok(())
9036 }
9037}
9038
9039impl Render for ViewOptions {
9040 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9043 if let Some(algorithm) = self.algorithm {
9044 f.write_str(" ALGORITHM = ")?;
9045 algorithm.render(ctx, f)?;
9046 }
9047 if let Some(definer) = &self.definer {
9048 f.write_str(" ")?;
9049 definer.render(ctx, f)?;
9050 }
9051 if let Some(sql_security) = self.sql_security {
9052 f.write_str(" SQL SECURITY ")?;
9053 sql_security.render(ctx, f)?;
9054 }
9055 Ok(())
9056 }
9057}
9058
9059impl Render for ViewAlgorithm {
9060 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9061 f.write_str(match self {
9062 Self::Undefined => "UNDEFINED",
9063 Self::Merge => "MERGE",
9064 Self::TempTable => "TEMPTABLE",
9065 })
9066 }
9067}
9068
9069impl<X: Extension + Render> Render for CreateSecret<X> {
9070 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9071 f.write_str("CREATE ")?;
9072 if self.persistent {
9073 f.write_str("PERSISTENT ")?;
9074 }
9075 f.write_str("SECRET ")?;
9076 self.name.render(ctx, f)?;
9077 f.write_str(" (")?;
9078 render_comma_separated(&self.options, ctx, f)?;
9079 f.write_str(")")
9080 }
9081}
9082
9083impl<X: Extension + Render> Render for SecretOption<X> {
9084 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9085 self.name.render(ctx, f)?;
9086 f.write_str(" ")?;
9087 self.value.render(ctx, f)
9088 }
9089}
9090
9091impl Render for DropSecretStmt {
9092 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9093 f.write_str("DROP ")?;
9094 match self.persistence {
9095 SecretPersistence::Default => {}
9096 SecretPersistence::Temporary => f.write_str("TEMPORARY ")?,
9097 SecretPersistence::Persistent => f.write_str("PERSISTENT ")?,
9098 }
9099 f.write_str("SECRET ")?;
9100 if self.if_exists {
9101 f.write_str("IF EXISTS ")?;
9102 }
9103 self.name.render(ctx, f)?;
9104 if let Some(storage) = &self.storage {
9105 f.write_str(" FROM ")?;
9106 storage.render(ctx, f)?;
9107 }
9108 Ok(())
9109 }
9110}
9111
9112impl<X: Extension + Render> Render for CreateType<X> {
9113 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9114 f.write_str("CREATE")?;
9115 if self.or_replace {
9116 f.write_str(" OR REPLACE")?;
9117 }
9118 if let Some(temporary) = self.temporary {
9119 f.write_str(" ")?;
9120 temporary.render(ctx, f)?;
9121 }
9122 f.write_str(" TYPE")?;
9123 if self.if_not_exists {
9124 f.write_str(" IF NOT EXISTS")?;
9125 }
9126 f.write_str(" ")?;
9127 self.name.render(ctx, f)?;
9128 f.write_str(" AS ")?;
9129 self.definition.render(ctx, f)
9130 }
9131}
9132
9133impl Render for CreateVirtualTable {
9134 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9135 f.write_str("CREATE VIRTUAL TABLE ")?;
9136 if self.if_not_exists {
9137 f.write_str("IF NOT EXISTS ")?;
9138 }
9139 self.name.render(ctx, f)?;
9140 f.write_str(" USING ")?;
9141 self.module.render(ctx, f)?;
9142 if let Some(args) = &self.args {
9143 f.write_str("(")?;
9144 render_comma_separated(args, ctx, f)?;
9145 f.write_str(")")?;
9146 }
9147 Ok(())
9148 }
9149}
9150
9151impl Render for ModuleArg {
9152 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9153 if ctx.mode() == RenderMode::Redacted {
9158 return f.write_str("?");
9159 }
9160 f.write_str(ctx.resolve(self.text))
9163 }
9164}
9165
9166impl<X: Extension + Render> Render for CreateSequence<X> {
9167 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9168 f.write_str("CREATE")?;
9169 if let Some(temporary) = self.temporary {
9170 f.write_str(" ")?;
9171 temporary.render(ctx, f)?;
9172 }
9173 f.write_str(" SEQUENCE")?;
9174 if self.if_not_exists {
9175 f.write_str(" IF NOT EXISTS")?;
9176 }
9177 f.write_str(" ")?;
9178 self.name.render(ctx, f)?;
9179 for option in &self.options {
9182 f.write_str(" ")?;
9183 option.render(ctx, f)?;
9184 }
9185 Ok(())
9186 }
9187}
9188
9189impl Render for CreateExtension {
9190 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9191 f.write_str("CREATE EXTENSION")?;
9192 if self.if_not_exists {
9193 f.write_str(" IF NOT EXISTS")?;
9194 }
9195 f.write_str(" ")?;
9196 self.name.render(ctx, f)?;
9197 if self.with {
9199 f.write_str(" WITH")?;
9200 }
9201 for option in &self.options {
9202 f.write_str(" ")?;
9203 option.render(ctx, f)?;
9204 }
9205 Ok(())
9206 }
9207}
9208
9209impl Render for CreateExtensionOption {
9210 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9211 match self {
9212 Self::Schema { name, .. } => {
9213 f.write_str("SCHEMA ")?;
9214 name.render(ctx, f)
9215 }
9216 Self::Version { version, .. } => {
9217 f.write_str("VERSION ")?;
9218 version.render(ctx, f)
9219 }
9220 Self::Cascade { .. } => f.write_str("CASCADE"),
9221 }
9222 }
9223}
9224
9225impl Render for ExtensionVersion {
9226 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9227 match self {
9228 Self::Word { word, .. } => word.render(ctx, f),
9229 Self::String { value, .. } => value.render(ctx, f),
9230 }
9231 }
9232}
9233
9234impl<X: Extension + Render> Render for AlterExtension<X> {
9235 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9236 f.write_str("ALTER EXTENSION ")?;
9237 self.name.render(ctx, f)?;
9238 f.write_str(" ")?;
9239 self.action.render(ctx, f)
9240 }
9241}
9242
9243impl<X: Extension + Render> Render for AlterExtensionAction<X> {
9244 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9245 match self {
9246 Self::Update { version, .. } => {
9247 f.write_str("UPDATE")?;
9248 if let Some(version) = version {
9249 f.write_str(" TO ")?;
9250 version.render(ctx, f)?;
9251 }
9252 Ok(())
9253 }
9254 Self::Change { add, member, .. } => {
9255 f.write_str(if *add { "ADD " } else { "DROP " })?;
9256 member.render(ctx, f)
9257 }
9258 }
9259 }
9260}
9261
9262impl Render for SizeLiteral {
9263 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9264 if let Some(text) = ctx.slice(self.meta.span) {
9267 return f.write_str(text);
9268 }
9269 f.write_str("0")?;
9272 match self.unit {
9273 Some(SizeUnit::Kilo) => f.write_str("K"),
9274 Some(SizeUnit::Mega) => f.write_str("M"),
9275 Some(SizeUnit::Giga) => f.write_str("G"),
9276 None => Ok(()),
9277 }
9278 }
9279}
9280
9281impl Render for TablespaceOption {
9282 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9283 match self {
9284 Self::Size {
9285 kind, equals, size, ..
9286 } => {
9287 f.write_str(match kind {
9288 TablespaceSizeOption::InitialSize => "INITIAL_SIZE",
9289 TablespaceSizeOption::AutoextendSize => "AUTOEXTEND_SIZE",
9290 TablespaceSizeOption::MaxSize => "MAX_SIZE",
9291 TablespaceSizeOption::ExtentSize => "EXTENT_SIZE",
9292 TablespaceSizeOption::UndoBufferSize => "UNDO_BUFFER_SIZE",
9293 TablespaceSizeOption::RedoBufferSize => "REDO_BUFFER_SIZE",
9294 TablespaceSizeOption::FileBlockSize => "FILE_BLOCK_SIZE",
9295 })?;
9296 f.write_str(if *equals { " = " } else { " " })?;
9297 size.render(ctx, f)
9298 }
9299 Self::Nodegroup { equals, value, .. } => {
9300 f.write_str("NODEGROUP")?;
9301 f.write_str(if *equals { " = " } else { " " })?;
9302 value.render(ctx, f)
9303 }
9304 Self::Engine {
9305 storage,
9306 equals,
9307 name,
9308 ..
9309 } => {
9310 f.write_str(if *storage { "STORAGE ENGINE" } else { "ENGINE" })?;
9311 f.write_str(if *equals { " = " } else { " " })?;
9312 name.render(ctx, f)
9313 }
9314 Self::Wait { negated, .. } => f.write_str(if *negated { "NO_WAIT" } else { "WAIT" }),
9315 Self::Comment { equals, value, .. } => {
9316 f.write_str("COMMENT")?;
9317 f.write_str(if *equals { " = " } else { " " })?;
9318 value.render(ctx, f)
9319 }
9320 Self::Encryption { equals, value, .. } => {
9321 f.write_str("ENCRYPTION")?;
9322 f.write_str(if *equals { " = " } else { " " })?;
9323 value.render(ctx, f)
9324 }
9325 Self::EngineAttribute { equals, value, .. } => {
9326 f.write_str("ENGINE_ATTRIBUTE")?;
9327 f.write_str(if *equals { " = " } else { " " })?;
9328 value.render(ctx, f)
9329 }
9330 }
9331 }
9332}
9333
9334fn render_tablespace_options(
9338 options: &[TablespaceOption],
9339 ctx: &RenderCtx<'_>,
9340 f: &mut fmt::Formatter<'_>,
9341) -> fmt::Result {
9342 for option in options {
9343 f.write_str(" ")?;
9344 option.render(ctx, f)?;
9345 }
9346 Ok(())
9347}
9348
9349impl Render for CreateTablespace {
9350 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9351 f.write_str(if self.undo {
9352 "CREATE UNDO TABLESPACE "
9353 } else {
9354 "CREATE TABLESPACE "
9355 })?;
9356 self.name.render(ctx, f)?;
9357 if let Some(datafile) = &self.datafile {
9358 f.write_str(" ADD DATAFILE ")?;
9359 datafile.render(ctx, f)?;
9360 }
9361 if let Some(lg) = &self.use_logfile_group {
9362 f.write_str(" USE LOGFILE GROUP ")?;
9363 lg.render(ctx, f)?;
9364 }
9365 render_tablespace_options(&self.options, ctx, f)
9366 }
9367}
9368
9369impl Render for AlterTablespace {
9370 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9371 f.write_str(
9373 if matches!(self.action, AlterTablespaceAction::SetState { .. }) {
9374 "ALTER UNDO TABLESPACE "
9375 } else {
9376 "ALTER TABLESPACE "
9377 },
9378 )?;
9379 self.name.render(ctx, f)?;
9380 f.write_str(" ")?;
9381 self.action.render(ctx, f)
9382 }
9383}
9384
9385impl Render for AlterTablespaceAction {
9386 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9387 match self {
9388 Self::AddDatafile {
9389 datafile, options, ..
9390 } => {
9391 f.write_str("ADD DATAFILE ")?;
9392 datafile.render(ctx, f)?;
9393 render_tablespace_options(options, ctx, f)
9394 }
9395 Self::DropDatafile {
9396 datafile, options, ..
9397 } => {
9398 f.write_str("DROP DATAFILE ")?;
9399 datafile.render(ctx, f)?;
9400 render_tablespace_options(options, ctx, f)
9401 }
9402 Self::Rename { new_name, .. } => {
9403 f.write_str("RENAME TO ")?;
9404 new_name.render(ctx, f)
9405 }
9406 Self::Options { options, .. } => {
9407 let mut first = true;
9410 for option in options {
9411 if !first {
9412 f.write_str(" ")?;
9413 }
9414 first = false;
9415 option.render(ctx, f)?;
9416 }
9417 Ok(())
9418 }
9419 Self::SetState { state, options, .. } => {
9420 f.write_str(match state {
9421 UndoTablespaceState::Active => "SET ACTIVE",
9422 UndoTablespaceState::Inactive => "SET INACTIVE",
9423 })?;
9424 render_tablespace_options(options, ctx, f)
9425 }
9426 }
9427 }
9428}
9429
9430impl Render for DropTablespace {
9431 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9432 f.write_str(if self.undo {
9433 "DROP UNDO TABLESPACE "
9434 } else {
9435 "DROP TABLESPACE "
9436 })?;
9437 self.name.render(ctx, f)?;
9438 render_tablespace_options(&self.options, ctx, f)
9439 }
9440}
9441
9442impl Render for CreateLogfileGroup {
9443 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9444 f.write_str("CREATE LOGFILE GROUP ")?;
9445 self.name.render(ctx, f)?;
9446 f.write_str(" ADD UNDOFILE ")?;
9447 self.undofile.render(ctx, f)?;
9448 render_tablespace_options(&self.options, ctx, f)
9449 }
9450}
9451
9452impl Render for AlterLogfileGroup {
9453 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9454 f.write_str("ALTER LOGFILE GROUP ")?;
9455 self.name.render(ctx, f)?;
9456 f.write_str(" ADD UNDOFILE ")?;
9457 self.undofile.render(ctx, f)?;
9458 render_tablespace_options(&self.options, ctx, f)
9459 }
9460}
9461
9462impl Render for DropLogfileGroup {
9463 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9464 f.write_str("DROP LOGFILE GROUP ")?;
9465 self.name.render(ctx, f)?;
9466 render_tablespace_options(&self.options, ctx, f)
9467 }
9468}
9469
9470impl<X: Extension + Render> Render for ObjectReference<X> {
9471 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9472 match self {
9473 Self::Named { kind, name, .. } => {
9474 kind.render(ctx, f)?;
9475 f.write_str(" ")?;
9476 name.render(ctx, f)
9477 }
9478 Self::Routine {
9479 kind, signature, ..
9480 } => {
9481 kind.render(ctx, f)?;
9482 f.write_str(" ")?;
9483 signature.render(ctx, f)
9484 }
9485 Self::Aggregate { name, args, .. } => {
9486 f.write_str("AGGREGATE ")?;
9487 name.render(ctx, f)?;
9488 args.render(ctx, f)
9489 }
9490 Self::Operator {
9491 schema, op, args, ..
9492 } => {
9493 f.write_str("OPERATOR ")?;
9494 for part in &schema.0 {
9495 part.render(ctx, f)?;
9496 f.write_str(".")?;
9497 }
9498 f.write_str(ctx.resolve(*op))?;
9499 f.write_str(" ")?;
9500 args.render(ctx, f)
9501 }
9502 Self::OperatorClass {
9503 family,
9504 name,
9505 access_method,
9506 ..
9507 } => {
9508 f.write_str(if *family {
9509 "OPERATOR FAMILY "
9510 } else {
9511 "OPERATOR CLASS "
9512 })?;
9513 name.render(ctx, f)?;
9514 f.write_str(" USING ")?;
9515 access_method.render(ctx, f)
9516 }
9517 Self::Cast { from, to, .. } => {
9518 f.write_str("CAST (")?;
9519 from.render(ctx, f)?;
9520 f.write_str(" AS ")?;
9521 to.render(ctx, f)?;
9522 f.write_str(")")
9523 }
9524 Self::Type { domain, name, .. } => {
9525 f.write_str(if *domain { "DOMAIN " } else { "TYPE " })?;
9526 name.render(ctx, f)
9527 }
9528 Self::Transform {
9529 type_name,
9530 language,
9531 ..
9532 } => {
9533 f.write_str("TRANSFORM FOR ")?;
9534 type_name.render(ctx, f)?;
9535 f.write_str(" LANGUAGE ")?;
9536 language.render(ctx, f)
9537 }
9538 Self::Trigger { name, table, .. } => {
9539 f.write_str("TRIGGER ")?;
9540 name.render(ctx, f)?;
9541 f.write_str(" ON ")?;
9542 table.render(ctx, f)
9543 }
9544 }
9545 }
9546}
9547
9548impl<X: Extension + Render> Render for AlterObjectDepends<X> {
9549 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9550 f.write_str("ALTER ")?;
9551 self.object.render(ctx, f)?;
9552 if self.no {
9553 f.write_str(" NO")?;
9554 }
9555 f.write_str(" DEPENDS ON EXTENSION ")?;
9556 self.extension.render(ctx, f)
9557 }
9558}
9559
9560impl<X: Extension + Render> Render for DropTransform<X> {
9561 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9562 let ObjectReference::Transform {
9567 type_name,
9568 language,
9569 ..
9570 } = &self.object
9571 else {
9572 unreachable!("DROP TRANSFORM always carries an ObjectReference::Transform")
9573 };
9574 f.write_str("DROP TRANSFORM")?;
9575 if self.if_exists {
9576 f.write_str(" IF EXISTS")?;
9577 }
9578 f.write_str(" FOR ")?;
9579 type_name.render(ctx, f)?;
9580 f.write_str(" LANGUAGE ")?;
9581 language.render(ctx, f)?;
9582 render_drop_behavior(self.behavior, ctx, f)
9583 }
9584}
9585
9586impl Render for ObjectRefKind {
9587 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9588 f.write_str(match self {
9589 Self::Table => "TABLE",
9590 Self::Sequence => "SEQUENCE",
9591 Self::View => "VIEW",
9592 Self::MaterializedView => "MATERIALIZED VIEW",
9593 Self::Index => "INDEX",
9594 Self::ForeignTable => "FOREIGN TABLE",
9595 Self::Collation => "COLLATION",
9596 Self::Conversion => "CONVERSION",
9597 Self::Statistics => "STATISTICS",
9598 Self::TextSearchParser => "TEXT SEARCH PARSER",
9599 Self::TextSearchDictionary => "TEXT SEARCH DICTIONARY",
9600 Self::TextSearchTemplate => "TEXT SEARCH TEMPLATE",
9601 Self::TextSearchConfiguration => "TEXT SEARCH CONFIGURATION",
9602 Self::AccessMethod => "ACCESS METHOD",
9603 Self::EventTrigger => "EVENT TRIGGER",
9604 Self::Extension => "EXTENSION",
9605 Self::ForeignDataWrapper => "FOREIGN DATA WRAPPER",
9606 Self::Language => "LANGUAGE",
9608 Self::Publication => "PUBLICATION",
9609 Self::Schema => "SCHEMA",
9610 Self::Server => "SERVER",
9611 Self::Database => "DATABASE",
9612 Self::Role => "ROLE",
9613 Self::Tablespace => "TABLESPACE",
9614 })
9615 }
9616}
9617
9618impl<X: Extension + Render> Render for AggregateArgs<X> {
9619 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9620 match self {
9621 Self::Star { .. } => f.write_str("(*)"),
9622 Self::Types {
9623 direct, order_by, ..
9624 } => {
9625 f.write_str("(")?;
9626 render_comma_separated(direct, ctx, f)?;
9627 if let Some(order_by) = order_by {
9628 if !direct.is_empty() {
9629 f.write_str(" ")?;
9630 }
9631 f.write_str("ORDER BY ")?;
9632 render_comma_separated(order_by, ctx, f)?;
9633 }
9634 f.write_str(")")
9635 }
9636 }
9637 }
9638}
9639
9640impl<X: Extension + Render> Render for OperatorArgs<X> {
9641 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9642 f.write_str("(")?;
9643 match &self.left {
9644 Some(left) => left.render(ctx, f)?,
9645 None => f.write_str("NONE")?,
9646 }
9647 f.write_str(", ")?;
9648 match &self.right {
9649 Some(right) => right.render(ctx, f)?,
9650 None => f.write_str("NONE")?,
9651 }
9652 f.write_str(")")
9653 }
9654}
9655
9656impl<X: Extension + Render> Render for CreateTypeDefinition<X> {
9657 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9658 match self {
9659 Self::Enum { labels, .. } => render_value_list_type(ctx, "ENUM", labels, f),
9662 Self::EnumFromQuery { query, .. } => {
9663 f.write_str("ENUM (")?;
9664 query.render(ctx, f)?;
9665 f.write_str(")")
9666 }
9667 Self::Alias { data_type, .. } => data_type.render(ctx, f),
9668 }
9669 }
9670}
9671
9672impl Render for ViewCheckOption {
9673 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9674 f.write_str(match self {
9675 Self::Unspecified => "WITH CHECK OPTION",
9676 Self::Cascaded => "WITH CASCADED CHECK OPTION",
9677 Self::Local => "WITH LOCAL CHECK OPTION",
9678 })
9679 }
9680}
9681
9682impl<X: Extension + Render> Render for CreateIndex<X> {
9683 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9684 f.write_str("CREATE")?;
9685 if self.unique {
9686 f.write_str(" UNIQUE")?;
9687 }
9688 f.write_str(" INDEX")?;
9689 if self.concurrently {
9690 f.write_str(" CONCURRENTLY")?;
9691 }
9692 if self.if_not_exists {
9693 f.write_str(" IF NOT EXISTS")?;
9694 }
9695 if let Some(name) = &self.name {
9696 f.write_str(" ")?;
9697 name.render(ctx, f)?;
9698 }
9699 f.write_str(" ON ")?;
9700 self.table.render(ctx, f)?;
9701 if let Some(using) = &self.using {
9702 f.write_str(" USING ")?;
9703 using.render(ctx, f)?;
9704 }
9705 f.write_str(" (")?;
9706 render_comma_separated(&self.columns, ctx, f)?;
9707 f.write_str(")")?;
9708 if let Some(predicate) = &self.predicate {
9709 f.write_str(" WHERE ")?;
9710 predicate.render(ctx, f)?;
9711 }
9712 Ok(())
9713 }
9714}
9715
9716fn render_sort_direction(
9720 asc: Option<bool>,
9721 nulls_first: Option<bool>,
9722 f: &mut fmt::Formatter<'_>,
9723) -> fmt::Result {
9724 match asc {
9725 Some(true) => f.write_str(" ASC")?,
9726 Some(false) => f.write_str(" DESC")?,
9727 None => {}
9728 }
9729 match nulls_first {
9730 Some(true) => f.write_str(" NULLS FIRST")?,
9731 Some(false) => f.write_str(" NULLS LAST")?,
9732 None => {}
9733 }
9734 Ok(())
9735}
9736
9737impl<X: Extension + Render> Render for IndexColumn<X> {
9738 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9739 self.expr.render(ctx, f)?;
9740 render_sort_direction(self.asc, self.nulls_first, f)
9741 }
9742}
9743
9744impl Render for CreateDatabase {
9745 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9746 f.write_str("CREATE DATABASE ")?;
9747 if self.if_not_exists {
9748 f.write_str("IF NOT EXISTS ")?;
9749 }
9750 self.name.render(ctx, f)
9751 }
9752}
9753
9754impl<X: Extension + Render> Render for CreateFunction<X> {
9755 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9756 f.write_str("CREATE ")?;
9757 if self.or_replace {
9758 f.write_str("OR REPLACE ")?;
9759 }
9760 if let Some(definer) = &self.definer {
9761 definer.render(ctx, f)?;
9762 f.write_str(" ")?;
9763 }
9764 f.write_str("FUNCTION ")?;
9765 if self.if_not_exists {
9766 f.write_str("IF NOT EXISTS ")?;
9767 }
9768 self.name.render(ctx, f)?;
9769 f.write_str("(")?;
9771 render_comma_separated(&self.params, ctx, f)?;
9772 f.write_str(")")?;
9773 if let Some(returns) = &self.returns {
9774 f.write_str(" RETURNS ")?;
9775 returns.render(ctx, f)?;
9776 }
9777 for option in &self.options {
9778 f.write_str(" ")?;
9779 option.render(ctx, f)?;
9780 }
9781 if let Some(body) = &self.body {
9784 f.write_str(" ")?;
9785 body.render(ctx, f)?;
9786 }
9787 Ok(())
9788 }
9789}
9790
9791impl<X: Extension + Render> Render for FunctionParam<X> {
9792 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9793 if let Some(mode) = &self.mode {
9794 f.write_str(match mode {
9795 FunctionParamMode::In => "IN ",
9796 FunctionParamMode::Out => "OUT ",
9797 FunctionParamMode::InOut => "INOUT ",
9798 FunctionParamMode::Variadic => "VARIADIC ",
9799 })?;
9800 }
9801 if let Some(name) = &self.name {
9802 name.render(ctx, f)?;
9803 f.write_str(" ")?;
9804 }
9805 self.data_type.render(ctx, f)?;
9806 if let Some(default) = &self.default {
9807 f.write_str(" ")?;
9808 default.render(ctx, f)?;
9809 }
9810 Ok(())
9811 }
9812}
9813
9814impl<X: Extension + Render> Render for FunctionParamDefault<X> {
9815 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9816 f.write_str(match self.spelling {
9817 FunctionParamDefaultSpelling::Default => "DEFAULT ",
9818 FunctionParamDefaultSpelling::Equals => "= ",
9819 })?;
9820 self.value.render(ctx, f)
9821 }
9822}
9823
9824impl<X: Extension + Render> Render for CreateMacro<X> {
9825 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9826 f.write_str("CREATE")?;
9827 if self.or_replace {
9828 f.write_str(" OR REPLACE")?;
9829 }
9830 if let Some(temporary) = self.temporary {
9831 f.write_str(" ")?;
9832 temporary.render(ctx, f)?;
9833 }
9834 f.write_str(match self.spelling {
9835 MacroSpelling::Macro => " MACRO",
9836 MacroSpelling::Function => " FUNCTION",
9837 })?;
9838 if self.if_not_exists {
9839 f.write_str(" IF NOT EXISTS")?;
9840 }
9841 f.write_str(" ")?;
9842 self.name.render(ctx, f)?;
9843 f.write_str("(")?;
9845 render_comma_separated(&self.params, ctx, f)?;
9846 f.write_str(") AS ")?;
9847 self.body.render(ctx, f)
9848 }
9849}
9850
9851impl<X: Extension + Render> Render for MacroParam<X> {
9852 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9853 self.name.render(ctx, f)?;
9854 if let Some(default) = &self.default {
9855 f.write_str(" := ")?;
9856 default.render(ctx, f)?;
9857 }
9858 Ok(())
9859 }
9860}
9861
9862impl<X: Extension + Render> Render for MacroBody<X> {
9863 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9864 match self {
9865 Self::Scalar { expr, .. } => expr.render(ctx, f),
9866 Self::Table { query, .. } => {
9867 f.write_str("TABLE ")?;
9868 query.render(ctx, f)
9869 }
9870 }
9871 }
9872}
9873
9874impl<X: Extension + Render> Render for FunctionOption<X> {
9875 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9876 match self {
9877 Self::Language { name, .. } => {
9878 f.write_str("LANGUAGE ")?;
9879 name.render(ctx, f)
9880 }
9881 Self::As { body, .. } => {
9882 f.write_str("AS ")?;
9883 body.render(ctx, f)
9884 }
9885 Self::NullBehavior { behavior, .. } => behavior.render(ctx, f),
9886 Self::Deterministic { not, .. } => f.write_str(if *not {
9887 "NOT DETERMINISTIC"
9888 } else {
9889 "DETERMINISTIC"
9890 }),
9891 Self::DataAccess { access, .. } => access.render(ctx, f),
9892 Self::SqlSecurity { context, .. } => {
9893 f.write_str("SQL SECURITY ")?;
9894 context.render(ctx, f)
9895 }
9896 Self::Comment { comment, .. } => {
9897 f.write_str("COMMENT ")?;
9898 comment.render(ctx, f)
9899 }
9900 }
9901 }
9902}
9903
9904impl Render for SqlDataAccess {
9905 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9906 f.write_str(match self {
9907 Self::ContainsSql => "CONTAINS SQL",
9908 Self::NoSql => "NO SQL",
9909 Self::ReadsSqlData => "READS SQL DATA",
9910 Self::ModifiesSqlData => "MODIFIES SQL DATA",
9911 })
9912 }
9913}
9914
9915impl Render for SqlSecurityContext {
9916 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9917 f.write_str(match self {
9918 Self::Definer => "DEFINER",
9919 Self::Invoker => "INVOKER",
9920 })
9921 }
9922}
9923
9924impl<X: Extension + Render> Render for FunctionBody<X> {
9925 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9926 match self {
9927 Self::Definition { definition, .. } => definition.render(ctx, f),
9930 Self::Return { expr, .. } => {
9932 f.write_str("RETURN ")?;
9933 expr.render(ctx, f)
9934 }
9935 Self::Block { body, .. } => body.render(ctx, f),
9937 }
9938 }
9939}
9940
9941impl Render for Definer {
9942 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9943 f.write_str("DEFINER = ")?;
9944 match self {
9945 Self::Account { user, host, .. } => {
9946 user.render(ctx, f)?;
9947 if let Some(host) = host {
9948 f.write_str("@")?;
9949 host.render(ctx, f)?;
9950 }
9951 Ok(())
9952 }
9953 Self::CurrentUser { parens, .. } => {
9954 f.write_str("CURRENT_USER")?;
9955 if *parens {
9956 f.write_str("()")?;
9957 }
9958 Ok(())
9959 }
9960 }
9961 }
9962}
9963
9964impl<X: Extension + Render> Render for CreateProcedure<X> {
9965 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9966 f.write_str("CREATE ")?;
9967 if let Some(definer) = &self.definer {
9968 definer.render(ctx, f)?;
9969 f.write_str(" ")?;
9970 }
9971 f.write_str("PROCEDURE ")?;
9972 if self.if_not_exists {
9973 f.write_str("IF NOT EXISTS ")?;
9974 }
9975 self.name.render(ctx, f)?;
9976 f.write_str("(")?;
9978 render_comma_separated(&self.params, ctx, f)?;
9979 f.write_str(")")?;
9980 for characteristic in &self.characteristics {
9981 f.write_str(" ")?;
9982 characteristic.render(ctx, f)?;
9983 }
9984 f.write_str(" ")?;
9985 self.body.render(ctx, f)
9986 }
9987}
9988
9989impl<X: Extension + Render> Render for AlterRoutine<X> {
9990 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9991 f.write_str(match self.kind {
9992 RoutineKind::Procedure => "ALTER PROCEDURE ",
9993 RoutineKind::Function => "ALTER FUNCTION ",
9994 })?;
9995 self.name.render(ctx, f)?;
9996 for characteristic in &self.characteristics {
9997 f.write_str(" ")?;
9998 characteristic.render(ctx, f)?;
9999 }
10000 Ok(())
10001 }
10002}
10003
10004impl Render for FunctionNullBehavior {
10005 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10006 f.write_str(match self {
10007 Self::CalledOnNull => "CALLED ON NULL INPUT",
10008 Self::ReturnsNullOnNull => "RETURNS NULL ON NULL INPUT",
10009 Self::Strict => "STRICT",
10010 })
10011 }
10012}
10013
10014impl<X: Extension + Render> Render for EventSchedule<X> {
10015 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10016 match self {
10017 Self::At { at, .. } => {
10018 f.write_str("AT ")?;
10019 at.render(ctx, f)
10020 }
10021 Self::Every {
10022 value,
10023 unit,
10024 starts,
10025 ends,
10026 ..
10027 } => {
10028 f.write_str("EVERY ")?;
10029 value.render(ctx, f)?;
10030 f.write_str(mysql_interval_unit_suffix(*unit))?;
10033 if let Some(starts) = starts {
10034 f.write_str(" STARTS ")?;
10035 starts.render(ctx, f)?;
10036 }
10037 if let Some(ends) = ends {
10038 f.write_str(" ENDS ")?;
10039 ends.render(ctx, f)?;
10040 }
10041 Ok(())
10042 }
10043 }
10044 }
10045}
10046
10047fn render_event_on_completion(
10050 on_completion: EventOnCompletion,
10051 f: &mut fmt::Formatter<'_>,
10052) -> fmt::Result {
10053 f.write_str(match on_completion {
10054 EventOnCompletion::Preserve => " ON COMPLETION PRESERVE",
10055 EventOnCompletion::NotPreserve => " ON COMPLETION NOT PRESERVE",
10056 })
10057}
10058
10059fn render_event_status(status: EventStatus, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10061 f.write_str(match status {
10062 EventStatus::Enable => " ENABLE",
10063 EventStatus::Disable => " DISABLE",
10064 EventStatus::DisableOnReplica(ReplicaSpelling::Slave) => " DISABLE ON SLAVE",
10065 EventStatus::DisableOnReplica(ReplicaSpelling::Replica) => " DISABLE ON REPLICA",
10066 })
10067}
10068
10069impl<X: Extension + Render> Render for CreateEvent<X> {
10070 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10071 f.write_str("CREATE ")?;
10072 if let Some(definer) = &self.definer {
10073 definer.render(ctx, f)?;
10074 f.write_str(" ")?;
10075 }
10076 f.write_str("EVENT ")?;
10077 if self.if_not_exists {
10078 f.write_str("IF NOT EXISTS ")?;
10079 }
10080 self.name.render(ctx, f)?;
10081 f.write_str(" ON SCHEDULE ")?;
10082 self.schedule.render(ctx, f)?;
10083 if let Some(on_completion) = self.on_completion {
10084 render_event_on_completion(on_completion, f)?;
10085 }
10086 if let Some(status) = self.status {
10087 render_event_status(status, f)?;
10088 }
10089 if let Some(comment) = &self.comment {
10090 f.write_str(" COMMENT ")?;
10091 comment.render(ctx, f)?;
10092 }
10093 f.write_str(" DO ")?;
10094 self.body.render(ctx, f)
10095 }
10096}
10097
10098impl<X: Extension + Render> Render for AlterEvent<X> {
10099 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10100 f.write_str("ALTER ")?;
10101 if let Some(definer) = &self.definer {
10102 definer.render(ctx, f)?;
10103 f.write_str(" ")?;
10104 }
10105 f.write_str("EVENT ")?;
10106 self.name.render(ctx, f)?;
10107 if let Some(schedule) = &self.schedule {
10108 f.write_str(" ON SCHEDULE ")?;
10109 schedule.render(ctx, f)?;
10110 }
10111 if let Some(on_completion) = self.on_completion {
10112 render_event_on_completion(on_completion, f)?;
10113 }
10114 if let Some(rename_to) = &self.rename_to {
10115 f.write_str(" RENAME TO ")?;
10116 rename_to.render(ctx, f)?;
10117 }
10118 if let Some(status) = self.status {
10119 render_event_status(status, f)?;
10120 }
10121 if let Some(comment) = &self.comment {
10122 f.write_str(" COMMENT ")?;
10123 comment.render(ctx, f)?;
10124 }
10125 if let Some(body) = &self.body {
10126 f.write_str(" DO ")?;
10127 body.render(ctx, f)?;
10128 }
10129 Ok(())
10130 }
10131}
10132
10133impl Render for DropEvent {
10134 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10135 f.write_str("DROP EVENT ")?;
10136 if self.if_exists {
10137 f.write_str("IF EXISTS ")?;
10138 }
10139 self.name.render(ctx, f)
10140 }
10141}
10142
10143impl Render for DropDatabase {
10144 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10145 f.write_str(match self.spelling {
10146 DatabaseKeyword::Database => "DROP DATABASE ",
10147 DatabaseKeyword::Schema => "DROP SCHEMA ",
10148 })?;
10149 if self.if_exists {
10150 f.write_str("IF EXISTS ")?;
10151 }
10152 self.name.render(ctx, f)
10153 }
10154}
10155
10156impl Render for DropIndexOnTable {
10157 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10158 f.write_str("DROP INDEX ")?;
10159 self.name.render(ctx, f)?;
10160 f.write_str(" ON ")?;
10161 self.table.render(ctx, f)?;
10162 for option in &self.options {
10163 f.write_str(" ")?;
10164 option.render(ctx, f)?;
10165 }
10166 Ok(())
10167 }
10168}
10169
10170impl Render for IndexLockAlgorithmOption {
10171 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10172 let (keyword, equals, value) = match self {
10173 Self::Algorithm { equals, value } => ("ALGORITHM", *equals, value.render_str()),
10174 Self::Lock { equals, value } => ("LOCK", *equals, value.render_str()),
10175 };
10176 f.write_str(keyword)?;
10177 f.write_str(if equals { " = " } else { " " })?;
10178 f.write_str(value)
10179 }
10180}
10181
10182impl IndexAlgorithm {
10183 fn render_str(self) -> &'static str {
10185 match self {
10186 Self::Default => "DEFAULT",
10187 Self::Inplace => "INPLACE",
10188 Self::Instant => "INSTANT",
10189 Self::Copy => "COPY",
10190 }
10191 }
10192}
10193
10194impl IndexLock {
10195 fn render_str(self) -> &'static str {
10197 match self {
10198 Self::Default => "DEFAULT",
10199 Self::None => "NONE",
10200 Self::Shared => "SHARED",
10201 Self::Exclusive => "EXCLUSIVE",
10202 }
10203 }
10204}
10205
10206impl<X: Extension + Render> Render for Query<X> {
10207 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10208 if let Some(with) = &self.with {
10209 with.render(ctx, f)?;
10210 f.write_str(" ")?;
10211 }
10212 self.body.render(ctx, f)?;
10213 if !self.order_by.is_empty() {
10214 f.write_str(" ORDER BY ")?;
10215 render_comma_separated(&self.order_by, ctx, f)?;
10216 }
10217 if let Some(all) = &self.order_by_all {
10220 f.write_str(" ORDER BY ")?;
10221 all.render(ctx, f)?;
10222 }
10223 if let Some(limit_by) = &self.limit_by {
10226 f.write_str(" ")?;
10227 limit_by.render(ctx, f)?;
10228 }
10229 if let Some(limit) = &self.limit {
10230 f.write_str(" ")?;
10231 limit.render(ctx, f)?;
10232 }
10233 if !self.settings.is_empty() {
10235 f.write_str(" SETTINGS ")?;
10236 render_comma_separated(&self.settings, ctx, f)?;
10237 }
10238 if let Some(format) = &self.format {
10240 f.write_str(" ")?;
10241 format.render(ctx, f)?;
10242 }
10243 for locking in &self.locking {
10246 f.write_str(" ")?;
10247 locking.render(ctx, f)?;
10248 }
10249 for op in &self.pipe_operators {
10252 f.write_str(" ")?;
10253 op.render(ctx, f)?;
10254 }
10255 if let Some(for_clause) = &self.for_clause {
10258 f.write_str(" ")?;
10259 for_clause.render(ctx, f)?;
10260 }
10261 Ok(())
10262 }
10263}
10264
10265impl<X: Extension + Render> Render for PipeOperator<X> {
10266 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10267 match self {
10271 PipeOperator::Where { predicate, .. } => {
10272 f.write_str("|> WHERE ")?;
10273 predicate.render(ctx, f)
10274 }
10275 PipeOperator::Select { items, .. } => {
10276 f.write_str("|> SELECT ")?;
10277 render_comma_separated(items, ctx, f)
10278 }
10279 PipeOperator::Extend { items, .. } => {
10280 f.write_str("|> EXTEND ")?;
10281 render_comma_separated(items, ctx, f)
10282 }
10283 PipeOperator::As { alias, .. } => {
10284 f.write_str("|> AS ")?;
10285 alias.render(ctx, f)
10286 }
10287 PipeOperator::OrderBy { keys, .. } => {
10288 f.write_str("|> ORDER BY ")?;
10289 render_comma_separated(keys, ctx, f)
10290 }
10291 PipeOperator::Limit { count, offset, .. } => {
10292 f.write_str("|> LIMIT ")?;
10293 count.render(ctx, f)?;
10294 if let Some(offset) = offset {
10295 f.write_str(" OFFSET ")?;
10296 offset.render(ctx, f)?;
10297 }
10298 Ok(())
10299 }
10300 PipeOperator::Join { join, .. } => {
10301 f.write_str("|> ")?;
10304 join.render(ctx, f)
10305 }
10306 PipeOperator::SetOperation {
10307 op,
10308 quantifier,
10309 queries,
10310 ..
10311 } => {
10312 f.write_str("|> ")?;
10313 op.render(ctx, f)?;
10314 if let Some(quantifier) = quantifier {
10315 f.write_str(" ")?;
10316 quantifier.render(ctx, f)?;
10317 }
10318 f.write_str(" ")?;
10319 for (index, query) in queries.iter().enumerate() {
10322 if index > 0 {
10323 f.write_str(", ")?;
10324 }
10325 f.write_str("(")?;
10326 query.render(ctx, f)?;
10327 f.write_str(")")?;
10328 }
10329 Ok(())
10330 }
10331 PipeOperator::Set { assignments, .. } => {
10332 f.write_str("|> SET ")?;
10333 render_comma_separated(assignments, ctx, f)
10334 }
10335 PipeOperator::Call { call, alias, .. } => {
10336 f.write_str("|> CALL ")?;
10337 call.render(ctx, f)?;
10338 if let Some(alias) = alias {
10339 f.write_str(" AS ")?;
10340 alias.render(ctx, f)?;
10341 }
10342 Ok(())
10343 }
10344 PipeOperator::Aggregate {
10345 aggregates,
10346 group_by,
10347 ..
10348 } => {
10349 f.write_str("|> AGGREGATE")?;
10352 if !aggregates.is_empty() {
10353 f.write_str(" ")?;
10354 render_comma_separated(aggregates, ctx, f)?;
10355 }
10356 if !group_by.is_empty() {
10357 f.write_str(" GROUP BY ")?;
10358 render_comma_separated(group_by, ctx, f)?;
10359 }
10360 Ok(())
10361 }
10362 PipeOperator::Drop { columns, .. } => {
10363 f.write_str("|> DROP ")?;
10364 render_comma_separated(columns, ctx, f)
10365 }
10366 PipeOperator::Rename { renames, .. } => {
10367 f.write_str("|> RENAME ")?;
10368 render_comma_separated(renames, ctx, f)
10369 }
10370 PipeOperator::Pivot {
10371 aggregates, column, ..
10372 } => {
10373 f.write_str("|> PIVOT (")?;
10374 render_comma_separated(aggregates, ctx, f)?;
10375 f.write_str(" FOR ")?;
10376 column.render(ctx, f)?;
10378 f.write_str(")")
10379 }
10380 PipeOperator::Unpivot {
10381 value,
10382 name,
10383 columns,
10384 ..
10385 } => {
10386 f.write_str("|> UNPIVOT (")?;
10387 render_unpivot_name_list(value, ctx, f)?;
10388 f.write_str(" FOR ")?;
10389 render_unpivot_name_list(name, ctx, f)?;
10390 f.write_str(" IN (")?;
10391 render_comma_separated(columns, ctx, f)?;
10392 f.write_str("))")
10393 }
10394 PipeOperator::TableSample { sample, .. } => {
10395 f.write_str("|>")?;
10398 sample.render(ctx, f)
10399 }
10400 }
10401 }
10402}
10403
10404impl<X: Extension + Render> Render for SemiStructuredAccessExpr<X> {
10405 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10406 let full = ctx.mode() == RenderMode::Parenthesized;
10407 open_group(full, f)?;
10408 render_operand(
10409 &self.base,
10410 operand_needs_parens(
10411 &ctx.target().binding_powers,
10412 ctx.target().binding_powers.subscript,
10413 &self.base,
10414 Side::Left,
10415 ),
10416 ctx,
10417 f,
10418 )?;
10419 let mut segments = self.path.iter();
10420 if let Some(first) = segments.next() {
10421 f.write_str(":")?;
10422 render_semi_structured_path_segment(first, false, ctx, f)?;
10423 }
10424 for segment in segments {
10425 render_semi_structured_path_segment(segment, true, ctx, f)?;
10426 }
10427 close_group(full, f)
10428 }
10429}
10430
10431fn render_semi_structured_path_segment<X: Extension + Render>(
10432 segment: &SemiStructuredPathSegment<X>,
10433 suffix: bool,
10434 ctx: &RenderCtx<'_>,
10435 f: &mut fmt::Formatter<'_>,
10436) -> fmt::Result {
10437 match segment {
10438 SemiStructuredPathSegment::Key { key, .. } => {
10439 if suffix {
10440 f.write_str(".")?;
10441 }
10442 key.render(ctx, f)
10443 }
10444 SemiStructuredPathSegment::Index { index, .. } => {
10445 f.write_str("[")?;
10446 index.render(ctx, f)?;
10447 f.write_str("]")
10448 }
10449 }
10450}
10451
10452impl<X: Extension + Render> Render for PipeAggregateExpr<X> {
10453 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10454 self.expr.render(ctx, f)?;
10455 if let Some(alias) = &self.alias {
10456 f.write_str(" AS ")?;
10457 alias.render(ctx, f)?;
10458 }
10459 render_sort_direction(self.asc, self.nulls_first, f)
10460 }
10461}
10462
10463impl Render for PipeRenameItem {
10464 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10465 self.old.render(ctx, f)?;
10466 f.write_str(" AS ")?;
10467 self.new.render(ctx, f)
10468 }
10469}
10470
10471impl Render for LockingClause {
10472 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10473 match self.spelling {
10474 LockingSpelling::LockInShareMode => return f.write_str("LOCK IN SHARE MODE"),
10477 LockingSpelling::Modern => {}
10478 }
10479 f.write_str(match self.strength {
10480 LockStrength::Update => "FOR UPDATE",
10481 LockStrength::NoKeyUpdate => "FOR NO KEY UPDATE",
10482 LockStrength::Share => "FOR SHARE",
10483 LockStrength::KeyShare => "FOR KEY SHARE",
10484 })?;
10485 if !self.of.is_empty() {
10486 f.write_str(" OF ")?;
10487 render_comma_separated(&self.of, ctx, f)?;
10488 }
10489 match self.wait {
10490 Some(LockWait::NoWait) => f.write_str(" NOWAIT")?,
10491 Some(LockWait::SkipLocked) => f.write_str(" SKIP LOCKED")?,
10492 None => {}
10493 }
10494 Ok(())
10495 }
10496}
10497
10498impl Render for IndexHint {
10499 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10500 f.write_str(match self.action {
10501 IndexHintAction::Use => "USE ",
10502 IndexHintAction::Ignore => "IGNORE ",
10503 IndexHintAction::Force => "FORCE ",
10504 })?;
10505 f.write_str(match self.keyword {
10506 IndexHintKeyword::Index => "INDEX",
10507 IndexHintKeyword::Key => "KEY",
10508 })?;
10509 if let Some(scope) = self.scope {
10510 f.write_str(match scope {
10511 IndexHintScope::Join => " FOR JOIN",
10512 IndexHintScope::OrderBy => " FOR ORDER BY",
10513 IndexHintScope::GroupBy => " FOR GROUP BY",
10514 })?;
10515 }
10516 f.write_str(" (")?;
10519 render_comma_separated(&self.indexes, ctx, f)?;
10520 f.write_str(")")
10521 }
10522}
10523
10524impl Render for IndexedBy {
10525 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10526 match self {
10527 IndexedBy::Named { index, .. } => {
10528 f.write_str("INDEXED BY ")?;
10529 index.render(ctx, f)
10530 }
10531 IndexedBy::NotIndexed { .. } => f.write_str("NOT INDEXED"),
10532 }
10533 }
10534}
10535
10536impl Render for TableHint {
10537 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10538 match self {
10539 TableHint::Keyword { keyword, .. } => f.write_str(keyword.as_str()),
10540 TableHint::Index {
10543 equals, indexes, ..
10544 } => {
10545 if *equals && indexes.len() == 1 {
10546 f.write_str("INDEX = ")?;
10547 indexes[0].render(ctx, f)
10548 } else {
10549 f.write_str(if *equals { "INDEX = (" } else { "INDEX (" })?;
10550 render_comma_separated(indexes, ctx, f)?;
10551 f.write_str(")")
10552 }
10553 }
10554 TableHint::ForceSeek { target: None, .. } => f.write_str("FORCESEEK"),
10555 TableHint::ForceSeek {
10556 target: Some(target),
10557 ..
10558 } => {
10559 f.write_str("FORCESEEK (")?;
10560 target.index.render(ctx, f)?;
10561 f.write_str(" (")?;
10562 render_comma_separated(&target.columns, ctx, f)?;
10563 f.write_str("))")
10564 }
10565 TableHint::Other { ident, .. } => ident.render(ctx, f),
10566 }
10567 }
10568}
10569
10570impl<X: Extension + Render> Render for TableVersion<X> {
10571 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10572 match self {
10573 TableVersion::ForSystemTimeAsOf { point, .. } => {
10574 f.write_str("FOR SYSTEM_TIME AS OF ")?;
10575 point.render(ctx, f)
10576 }
10577 TableVersion::ForSystemTimeFromTo { start, end, .. } => {
10578 f.write_str("FOR SYSTEM_TIME FROM ")?;
10579 start.render(ctx, f)?;
10580 f.write_str(" TO ")?;
10581 end.render(ctx, f)
10582 }
10583 TableVersion::ForSystemTimeBetween { start, end, .. } => {
10584 f.write_str("FOR SYSTEM_TIME BETWEEN ")?;
10585 start.render(ctx, f)?;
10586 f.write_str(" AND ")?;
10587 end.render(ctx, f)
10588 }
10589 TableVersion::ForSystemTimeContainedIn { start, end, .. } => {
10590 f.write_str("FOR SYSTEM_TIME CONTAINED IN (")?;
10591 start.render(ctx, f)?;
10592 f.write_str(", ")?;
10593 end.render(ctx, f)?;
10594 f.write_str(")")
10595 }
10596 TableVersion::ForSystemTimeAll { .. } => f.write_str("FOR SYSTEM_TIME ALL"),
10597 TableVersion::VersionAsOf { version, .. } => {
10598 f.write_str("VERSION AS OF ")?;
10599 version.render(ctx, f)
10600 }
10601 TableVersion::TimestampAsOf { point, .. } => {
10602 f.write_str("TIMESTAMP AS OF ")?;
10603 point.render(ctx, f)
10604 }
10605 }
10606 }
10607}
10608
10609impl<X: Extension + Render> Render for SetExpr<X> {
10610 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10611 match self {
10612 SetExpr::Select { select, .. } => select.render(ctx, f),
10613 SetExpr::Values { values, .. } => values.render(ctx, f),
10614 SetExpr::Query { query, .. } => {
10617 f.write_str("(")?;
10618 query.render(ctx, f)?;
10619 f.write_str(")")
10620 }
10621 SetExpr::SetOperation {
10622 op,
10623 all,
10624 by_name,
10625 left,
10626 right,
10627 ..
10628 } => {
10629 render_set_operand(op, left, Side::Left, ctx, f)?;
10630 f.write_str(" ")?;
10631 op.render(ctx, f)?;
10632 if *all {
10633 f.write_str(" ALL")?;
10634 }
10635 if *by_name {
10638 f.write_str(" BY NAME")?;
10639 }
10640 f.write_str(" ")?;
10641 render_set_operand(op, right, Side::Right, ctx, f)
10642 }
10643 SetExpr::Pivot { pivot, .. } => pivot.render(ctx, f),
10647 SetExpr::Unpivot { unpivot, .. } => unpivot.render(ctx, f),
10648 }
10649 }
10650}
10651
10652fn render_set_operand<X: Extension + Render>(
10659 parent: &SetOperator,
10660 child: &SetExpr<X>,
10661 side: Side,
10662 ctx: &RenderCtx<'_>,
10663 f: &mut fmt::Formatter<'_>,
10664) -> fmt::Result {
10665 let wrap = match ctx.mode() {
10666 RenderMode::Parenthesized => matches!(child, SetExpr::SetOperation { .. }),
10667 RenderMode::Canonical | RenderMode::Redacted => {
10668 set_child_needs_parens(&ctx.target().set_operation_powers, parent, child, side)
10669 }
10670 };
10671 open_group(wrap, f)?;
10672 child.render(ctx, f)?;
10673 close_group(wrap, f)
10674}
10675
10676fn set_child_needs_parens<X: Extension>(
10678 bp: &SetOperationBindingPowerTable,
10679 parent: &SetOperator,
10680 child: &SetExpr<X>,
10681 side: Side,
10682) -> bool {
10683 match child {
10684 SetExpr::SetOperation { op, .. } => bp.needs_parens(parent, op, side),
10685 _ => false,
10686 }
10687}
10688
10689impl<X: Extension + Render> Render for With<X> {
10690 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10691 f.write_str("WITH")?;
10692 if self.recursive {
10693 f.write_str(" RECURSIVE")?;
10694 }
10695 render_leading_space_comma_separated(&self.ctes, ctx, f)
10696 }
10697}
10698
10699impl<X: Extension + Render> Render for Cte<X> {
10700 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10701 self.name.render(ctx, f)?;
10702 if !self.columns.is_empty() {
10703 f.write_str("(")?;
10704 render_ident_list(&self.columns, ctx, f)?;
10705 f.write_str(")")?;
10706 }
10707 if let Some(key_columns) = &self.using_key {
10709 f.write_str(" USING KEY (")?;
10710 render_ident_list(key_columns, ctx, f)?;
10711 f.write_str(")")?;
10712 }
10713 f.write_str(" AS")?;
10714 match self.materialized {
10715 Some(true) => f.write_str(" MATERIALIZED")?,
10716 Some(false) => f.write_str(" NOT MATERIALIZED")?,
10717 None => {}
10718 }
10719 f.write_str(" (")?;
10720 self.body.render(ctx, f)?;
10721 f.write_str(")")?;
10722 if let Some(search) = &self.search {
10724 f.write_str(" ")?;
10725 search.render(ctx, f)?;
10726 }
10727 if let Some(cycle) = &self.cycle {
10728 f.write_str(" ")?;
10729 cycle.render(ctx, f)?;
10730 }
10731 Ok(())
10732 }
10733}
10734
10735impl Render for CteSearchClause {
10736 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10737 f.write_str(if self.breadth_first {
10738 "SEARCH BREADTH FIRST BY "
10739 } else {
10740 "SEARCH DEPTH FIRST BY "
10741 })?;
10742 render_ident_list(&self.columns, ctx, f)?;
10743 f.write_str(" SET ")?;
10744 self.set_column.render(ctx, f)
10745 }
10746}
10747
10748impl<X: Extension + Render> Render for CteCycleClause<X> {
10749 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10750 f.write_str("CYCLE ")?;
10751 render_ident_list(&self.columns, ctx, f)?;
10752 f.write_str(" SET ")?;
10753 self.mark_column.render(ctx, f)?;
10754 if let Some(mark) = &self.mark {
10757 mark.render(ctx, f)?;
10758 }
10759 f.write_str(" USING ")?;
10760 self.path_column.render(ctx, f)
10761 }
10762}
10763
10764impl<X: Extension + Render> Render for CteCycleMark<X> {
10765 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10766 f.write_str(" TO ")?;
10767 self.value.render(ctx, f)?;
10768 f.write_str(" DEFAULT ")?;
10769 self.default.render(ctx, f)
10770 }
10771}
10772
10773impl<X: Extension + Render> Render for CteBody<X> {
10774 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10775 match self {
10778 Self::Query { query, .. } => query.render(ctx, f),
10779 Self::Insert { insert, .. } => insert.render(ctx, f),
10780 Self::Update { update, .. } => update.render(ctx, f),
10781 Self::Delete { delete, .. } => delete.render(ctx, f),
10782 Self::Merge { merge, .. } => merge.render(ctx, f),
10783 }
10784 }
10785}
10786
10787impl<X: Extension + Render> Render for Values<X> {
10788 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10789 f.write_str("VALUES ")?;
10790 render_values_rows(&self.rows, self.explicit_row, ctx, f)
10791 }
10792}
10793
10794impl<X: Extension + Render> Render for ValuesItem<X> {
10795 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10796 match self {
10797 Self::Expr { expr, .. } => expr.render(ctx, f),
10798 Self::Default { default, .. } => default.render(ctx, f),
10799 }
10800 }
10801}
10802
10803fn render_select_projection_clause<X: Extension + Render>(
10807 select: &Select<X>,
10808 ctx: &RenderCtx<'_>,
10809 f: &mut fmt::Formatter<'_>,
10810) -> fmt::Result {
10811 f.write_str("SELECT")?;
10812 match &select.distinct {
10813 None => {}
10814 Some(SelectDistinct::Quantifier { quantifier, .. }) => {
10815 f.write_str(" ")?;
10816 quantifier.render(ctx, f)?;
10817 }
10818 Some(SelectDistinct::On { exprs, .. }) => {
10819 f.write_str(" DISTINCT ON (")?;
10820 render_comma_separated(exprs, ctx, f)?;
10821 f.write_str(")")?;
10822 }
10823 }
10824 if select.straight_join {
10826 f.write_str(" STRAIGHT_JOIN")?;
10827 }
10828 render_leading_space_comma_separated(&select.projection, ctx, f)
10829}
10830
10831fn render_select_body_tail<X: Extension + Render>(
10835 select: &Select<X>,
10836 ctx: &RenderCtx<'_>,
10837 f: &mut fmt::Formatter<'_>,
10838) -> fmt::Result {
10839 for view in &select.lateral_views {
10842 f.write_str(" ")?;
10843 view.render(ctx, f)?;
10844 }
10845 if let Some(selection) = &select.selection {
10846 f.write_str(" WHERE ")?;
10847 selection.render(ctx, f)?;
10848 }
10849 if let Some(connect_by) = &select.connect_by {
10852 f.write_str(" ")?;
10853 connect_by.render(ctx, f)?;
10854 }
10855 if !select.group_by.is_empty() {
10856 f.write_str(" GROUP BY ")?;
10857 if let Some(quantifier) = &select.group_by_quantifier {
10860 quantifier.render(ctx, f)?;
10861 f.write_str(" ")?;
10862 }
10863 render_comma_separated(&select.group_by, ctx, f)?;
10864 }
10865 if let Some(spelling) = select.group_by_all {
10870 let bare_star = spelling == GroupByAllSpelling::Star && honours_source_spelling(ctx);
10871 f.write_str(if bare_star {
10872 " GROUP BY *"
10873 } else {
10874 " GROUP BY ALL"
10875 })?;
10876 }
10877 if let Some(having) = &select.having {
10878 f.write_str(" HAVING ")?;
10879 having.render(ctx, f)?;
10880 }
10881 if !select.windows.is_empty() {
10882 f.write_str(" WINDOW ")?;
10883 render_comma_separated(&select.windows, ctx, f)?;
10884 }
10885 if let Some(qualify) = &select.qualify {
10888 f.write_str(" QUALIFY ")?;
10889 qualify.render(ctx, f)?;
10890 }
10891 if let Some(sample) = &select.sample {
10894 f.write_str(" USING SAMPLE ")?;
10895 sample.render(ctx, f)?;
10896 }
10897 Ok(())
10898}
10899
10900fn from_first_projection_is_implicit<X: Extension>(select: &Select<X>) -> bool {
10906 select.distinct.is_none()
10907 && matches!(select.projection.as_slice(), [SelectItem::Wildcard { .. }])
10908}
10909
10910impl<X: Extension + Render> Render for Select<X> {
10911 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10912 match self.spelling {
10913 SelectSpelling::TableCommand => {
10918 f.write_str("TABLE ")?;
10919 if let Some(table) = self.from.first() {
10920 table.relation.render(ctx, f)?;
10921 }
10922 Ok(())
10923 }
10924 SelectSpelling::FromFirst => {
10928 f.write_str("FROM ")?;
10929 render_comma_separated(&self.from, ctx, f)?;
10930 if !from_first_projection_is_implicit(self) {
10931 f.write_str(" ")?;
10932 render_select_projection_clause(self, ctx, f)?;
10933 }
10934 render_select_body_tail(self, ctx, f)
10935 }
10936 SelectSpelling::Select => {
10937 render_select_projection_clause(self, ctx, f)?;
10938 if let Some(into) = &self.into {
10940 f.write_str(" ")?;
10941 into.render(ctx, f)?;
10942 }
10943 if !self.from.is_empty() {
10944 f.write_str(" FROM ")?;
10945 render_comma_separated(&self.from, ctx, f)?;
10946 }
10947 render_select_body_tail(self, ctx, f)
10948 }
10949 }
10950 }
10951}
10952
10953impl<X: Extension + Render> Render for LateralView<X> {
10954 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10955 f.write_str("LATERAL VIEW ")?;
10956 if self.outer {
10957 f.write_str("OUTER ")?;
10958 }
10959 self.function.render(ctx, f)?;
10960 f.write_str(" ")?;
10961 self.alias.render(ctx, f)?;
10962 if !self.columns.is_empty() {
10963 f.write_str(" AS ")?;
10966 render_comma_separated(&self.columns, ctx, f)?;
10967 }
10968 Ok(())
10969 }
10970}
10971
10972impl<X: Extension + Render> Render for HierarchicalClause<X> {
10973 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10974 let render_start_with = |f: &mut fmt::Formatter<'_>| -> fmt::Result {
10977 if let Some(start_with) = &self.start_with {
10978 f.write_str("START WITH ")?;
10979 start_with.render(ctx, f)?;
10980 }
10981 Ok(())
10982 };
10983 let render_connect_by = |f: &mut fmt::Formatter<'_>| -> fmt::Result {
10984 f.write_str("CONNECT BY ")?;
10985 if self.nocycle {
10986 f.write_str("NOCYCLE ")?;
10987 }
10988 self.connect_by.render(ctx, f)
10989 };
10990 if self.start_with_leads && self.start_with.is_some() {
10991 render_start_with(f)?;
10992 f.write_str(" ")?;
10993 render_connect_by(f)
10994 } else if self.start_with.is_some() {
10995 render_connect_by(f)?;
10996 f.write_str(" ")?;
10997 render_start_with(f)
10998 } else {
10999 render_connect_by(f)
11000 }
11001 }
11002}
11003
11004impl Render for IntoTarget {
11005 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11006 f.write_str("INTO ")?;
11007 if let Some(temporary) = self.temporary {
11008 temporary.render(ctx, f)?;
11009 f.write_str(" ")?;
11010 }
11011 self.name.render(ctx, f)
11012 }
11013}
11014
11015impl<X: Extension + Render> Render for SelectItem<X> {
11016 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11017 match self {
11018 SelectItem::Wildcard {
11019 options,
11020 alias,
11021 alias_spelling,
11022 ..
11023 } => {
11024 f.write_str("*")?;
11025 render_optional_wildcard_options(options.as_deref(), ctx, f)?;
11026 render_alias(alias.as_ref(), *alias_spelling, ctx, f)
11027 }
11028 SelectItem::QualifiedWildcard {
11029 name,
11030 options,
11031 alias,
11032 alias_spelling,
11033 ..
11034 } => {
11035 name.render(ctx, f)?;
11036 f.write_str(".*")?;
11037 render_optional_wildcard_options(options.as_deref(), ctx, f)?;
11038 render_alias(alias.as_ref(), *alias_spelling, ctx, f)
11039 }
11040 SelectItem::Expr {
11041 expr,
11042 alias,
11043 alias_spelling,
11044 ..
11045 } => {
11046 if let (Some(alias), AliasSpelling::PrefixColon) = (alias.as_ref(), alias_spelling)
11051 {
11052 if honours_alias_spelling(ctx) {
11053 alias.render(ctx, f)?;
11054 f.write_str(": ")?;
11055 return expr.render(ctx, f);
11056 }
11057 }
11058 expr.render(ctx, f)?;
11059 if let Some(alias) = alias {
11060 f.write_str(alias_lead(*alias_spelling, ctx))?;
11061 alias.render(ctx, f)?;
11062 }
11063 Ok(())
11064 }
11065 }
11066 }
11067}
11068
11069fn render_wildcard_options<X: Extension + Render>(
11074 options: &WildcardOptions<X>,
11075 ctx: &RenderCtx<'_>,
11076 f: &mut fmt::Formatter<'_>,
11077) -> fmt::Result {
11078 if !options.exclude.is_empty() {
11079 f.write_str(" EXCLUDE (")?;
11080 render_comma_separated(&options.exclude, ctx, f)?;
11081 f.write_str(")")?;
11082 }
11083 if !options.replace.is_empty() {
11084 f.write_str(" REPLACE (")?;
11085 render_comma_separated(&options.replace, ctx, f)?;
11086 f.write_str(")")?;
11087 }
11088 if !options.rename.is_empty() {
11089 f.write_str(" RENAME (")?;
11090 render_comma_separated(&options.rename, ctx, f)?;
11091 f.write_str(")")?;
11092 }
11093 Ok(())
11094}
11095
11096fn render_optional_wildcard_options<X: Extension + Render>(
11097 options: Option<&WildcardOptions<X>>,
11098 ctx: &RenderCtx<'_>,
11099 f: &mut fmt::Formatter<'_>,
11100) -> fmt::Result {
11101 match options {
11102 Some(options) => render_wildcard_options(options, ctx, f),
11103 None => Ok(()),
11104 }
11105}
11106
11107fn render_comprehension_source<X: Extension + Render>(
11110 source: &ComprehensionSource<X>,
11111 ctx: &RenderCtx<'_>,
11112 f: &mut fmt::Formatter<'_>,
11113) -> fmt::Result {
11114 match source {
11115 ComprehensionSource::Expr { expr, .. } => expr.render(ctx, f),
11116 ComprehensionSource::Star {
11117 parenthesized,
11118 options,
11119 ..
11120 } => {
11121 if *parenthesized {
11122 f.write_str("(*")?;
11123 render_optional_wildcard_options(options.as_deref(), ctx, f)?;
11124 f.write_str(")")
11125 } else {
11126 f.write_str("*")?;
11127 render_optional_wildcard_options(options.as_deref(), ctx, f)
11128 }
11129 }
11130 }
11131}
11132
11133impl<X: Extension + Render> Render for WildcardReplace<X> {
11134 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11135 self.expr.render(ctx, f)?;
11136 f.write_str(" AS ")?;
11137 self.column.render(ctx, f)
11138 }
11139}
11140
11141impl Render for WildcardRename {
11142 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11143 self.column.render(ctx, f)?;
11144 f.write_str(" AS ")?;
11145 self.alias.render(ctx, f)
11146 }
11147}
11148
11149impl<X: Extension + Render> Render for GroupByItem<X> {
11150 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11151 match self {
11152 GroupByItem::Expr { expr, .. } => expr.render(ctx, f),
11153 GroupByItem::Rollup {
11154 exprs, spelling, ..
11155 } => match spelling {
11156 RollupSpelling::Function => {
11157 f.write_str("ROLLUP (")?;
11158 render_comma_separated(exprs, ctx, f)?;
11159 f.write_str(")")
11160 }
11161 RollupSpelling::WithRollup => {
11167 render_comma_separated(exprs, ctx, f)?;
11168 f.write_str(" WITH ROLLUP")
11169 }
11170 },
11171 GroupByItem::Cube { exprs, .. } => {
11172 f.write_str("CUBE (")?;
11173 render_comma_separated(exprs, ctx, f)?;
11174 f.write_str(")")
11175 }
11176 GroupByItem::GroupingSets { sets, .. } => {
11177 f.write_str("GROUPING SETS (")?;
11178 render_comma_separated(sets, ctx, f)?;
11179 f.write_str(")")
11180 }
11181 GroupByItem::Empty { .. } => f.write_str("()"),
11182 }
11183 }
11184}
11185
11186impl<X: Extension + Render> Render for TableWithJoins<X> {
11191 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11192 self.relation.render(ctx, f)?;
11193 for join in &self.joins {
11194 f.write_str(" ")?;
11195 join.render(ctx, f)?;
11196 }
11197 Ok(())
11198 }
11199}
11200
11201impl<X: Extension + Render> Render for TableFactor<X> {
11202 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11203 match self {
11204 TableFactor::Table {
11205 name,
11206 inheritance,
11207 json_path,
11208 version,
11209 partition,
11210 alias,
11211 indexed_by,
11212 index_hints,
11213 sample,
11214 table_hints,
11215 ..
11216 } => {
11217 render_relation_inheritance(inheritance, name, ctx, f)?;
11218 for segment in json_path {
11222 render_semi_structured_path_segment(segment, true, ctx, f)?;
11223 }
11224 if let Some(version) = version {
11226 f.write_str(" ")?;
11227 version.render(ctx, f)?;
11228 }
11229 if !partition.is_empty() {
11231 f.write_str(" PARTITION (")?;
11232 render_comma_separated(partition, ctx, f)?;
11233 f.write_str(")")?;
11234 }
11235 render_table_alias(alias.as_deref(), ctx, f)?;
11236 if let Some(indexed_by) = indexed_by {
11238 f.write_str(" ")?;
11239 indexed_by.render(ctx, f)?;
11240 }
11241 for hint in index_hints {
11243 f.write_str(" ")?;
11244 hint.render(ctx, f)?;
11245 }
11246 if let Some(sample) = sample {
11247 sample.render(ctx, f)?;
11248 }
11249 if !table_hints.is_empty() {
11252 f.write_str(" WITH (")?;
11253 render_comma_separated(table_hints, ctx, f)?;
11254 f.write_str(")")?;
11255 }
11256 Ok(())
11257 }
11258 TableFactor::Derived {
11259 lateral,
11260 subquery,
11261 alias,
11262 spelling,
11263 ..
11264 } => {
11265 if *lateral {
11266 f.write_str("LATERAL ")?;
11267 }
11268 match spelling {
11269 DerivedSpelling::Parenthesized => {
11270 f.write_str("(")?;
11271 subquery.render(ctx, f)?;
11272 f.write_str(")")?;
11273 }
11274 DerivedSpelling::BareValues => subquery.render(ctx, f)?,
11278 }
11279 render_table_alias(alias.as_deref(), ctx, f)
11280 }
11281 TableFactor::Function {
11282 lateral,
11283 function,
11284 with_ordinality,
11285 alias,
11286 column_defs,
11287 ..
11288 } => {
11289 if *lateral {
11290 f.write_str("LATERAL ")?;
11291 }
11292 function.render(ctx, f)?;
11293 if *with_ordinality {
11294 f.write_str(" WITH ORDINALITY")?;
11295 }
11296 render_function_alias(alias.as_deref(), column_defs, ctx, f)
11297 }
11298 TableFactor::RowsFrom {
11299 lateral,
11300 functions,
11301 with_ordinality,
11302 alias,
11303 ..
11304 } => {
11305 if *lateral {
11306 f.write_str("LATERAL ")?;
11307 }
11308 f.write_str("ROWS FROM (")?;
11309 render_comma_separated(functions, ctx, f)?;
11310 f.write_str(")")?;
11311 if *with_ordinality {
11312 f.write_str(" WITH ORDINALITY")?;
11313 }
11314 render_table_alias(alias.as_deref(), ctx, f)
11315 }
11316 TableFactor::Unnest {
11317 lateral,
11318 array_exprs,
11319 with_ordinality,
11320 alias,
11321 column_defs,
11322 with_offset,
11323 with_offset_alias,
11324 ..
11325 } => {
11326 if *lateral {
11327 f.write_str("LATERAL ")?;
11328 }
11329 f.write_str("UNNEST(")?;
11330 render_comma_separated(array_exprs, ctx, f)?;
11331 f.write_str(")")?;
11332 if *with_ordinality {
11336 f.write_str(" WITH ORDINALITY")?;
11337 }
11338 render_function_alias(alias.as_deref(), column_defs, ctx, f)?;
11339 if *with_offset {
11340 f.write_str(" WITH OFFSET")?;
11341 render_alias(with_offset_alias.as_ref(), AliasSpelling::As, ctx, f)?;
11344 }
11345 Ok(())
11346 }
11347 TableFactor::NestedJoin { table, alias, .. } => {
11348 f.write_str("(")?;
11349 table.render(ctx, f)?;
11350 f.write_str(")")?;
11351 render_table_alias(alias.as_deref(), ctx, f)
11352 }
11353 TableFactor::SpecialFunction {
11354 keyword,
11355 precision,
11356 alias,
11357 ..
11358 } => {
11359 f.write_str(special_function_keyword(*keyword))?;
11360 if let Some(precision) = precision {
11361 write!(f, "({precision})")?;
11362 }
11363 render_table_alias(alias.as_deref(), ctx, f)
11364 }
11365 TableFactor::Pivot { pivot, alias, .. } => {
11369 if matches!(pivot.spelling, PivotSpelling::Statement) {
11370 f.write_str("(")?;
11371 pivot.render(ctx, f)?;
11372 f.write_str(")")?;
11373 } else {
11374 pivot.render(ctx, f)?;
11375 }
11376 render_table_alias(alias.as_deref(), ctx, f)
11377 }
11378 TableFactor::Unpivot { unpivot, alias, .. } => {
11379 if matches!(unpivot.spelling, UnpivotSpelling::Statement) {
11380 f.write_str("(")?;
11381 unpivot.render(ctx, f)?;
11382 f.write_str(")")?;
11383 } else {
11384 unpivot.render(ctx, f)?;
11385 }
11386 render_table_alias(alias.as_deref(), ctx, f)
11387 }
11388 TableFactor::MatchRecognize {
11389 match_recognize,
11390 alias,
11391 ..
11392 } => {
11393 match_recognize.render(ctx, f)?;
11394 render_table_alias(alias.as_deref(), ctx, f)
11395 }
11396 TableFactor::ShowRef { show, alias, .. } => {
11401 f.write_str("(")?;
11402 show.render(ctx, f)?;
11403 f.write_str(")")?;
11404 render_table_alias(alias.as_deref(), ctx, f)
11405 }
11406 TableFactor::JsonTable {
11407 json_table, alias, ..
11408 } => {
11409 json_table.render(ctx, f)?;
11410 render_table_alias(alias.as_deref(), ctx, f)
11411 }
11412 TableFactor::XmlTable {
11413 xml_table, alias, ..
11414 } => {
11415 xml_table.render(ctx, f)?;
11416 render_table_alias(alias.as_deref(), ctx, f)
11417 }
11418 TableFactor::OpenJson {
11419 open_json, alias, ..
11420 } => {
11421 open_json.render(ctx, f)?;
11422 render_table_alias(alias.as_deref(), ctx, f)
11423 }
11424 TableFactor::TableExpr { expr, alias, .. } => {
11425 f.write_str("TABLE(")?;
11426 expr.render(ctx, f)?;
11427 f.write_str(")")?;
11428 render_table_alias(alias.as_deref(), ctx, f)
11429 }
11430 TableFactor::Other { ext, .. } => ext.render(ctx, f),
11431 }
11432 }
11433}
11434
11435impl<X: Extension + Render> Render for ShowRef<X> {
11436 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11437 f.write_str(match self.kind {
11438 ShowRefKind::Describe => "DESCRIBE ",
11439 ShowRefKind::Show => "SHOW ",
11440 ShowRefKind::Summarize => "SUMMARIZE ",
11441 })?;
11442 match &self.target {
11443 ShowRefTarget::Query { query, .. } => query.render(ctx, f),
11444 ShowRefTarget::Name { name, .. } => name.render(ctx, f),
11445 }
11446 }
11447}
11448
11449impl<X: Extension + Render> Render for JsonTable<X> {
11450 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11451 if self.lateral {
11452 f.write_str("LATERAL ")?;
11453 }
11454 f.write_str("JSON_TABLE(")?;
11455 self.context.render(ctx, f)?;
11456 f.write_str(", ")?;
11457 self.path.render(ctx, f)?;
11458 if let Some(name) = &self.path_name {
11459 f.write_str(" AS ")?;
11460 name.render(ctx, f)?;
11461 }
11462 if !self.passing.is_empty() {
11463 f.write_str(" PASSING ")?;
11464 render_comma_separated(&self.passing, ctx, f)?;
11465 }
11466 f.write_str(" COLUMNS (")?;
11467 render_comma_separated(&self.columns, ctx, f)?;
11468 f.write_str(")")?;
11469 render_json_on_behavior(&self.on_error, "ERROR", ctx, f)?;
11470 f.write_str(")")
11471 }
11472}
11473
11474impl<X: Extension + Render> Render for JsonTableColumn<X> {
11475 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11476 match self {
11477 JsonTableColumn::ForOrdinality { name, .. } => {
11478 name.render(ctx, f)?;
11479 f.write_str(" FOR ORDINALITY")
11480 }
11481 JsonTableColumn::Regular {
11482 name,
11483 data_type,
11484 format,
11485 path,
11486 wrapper,
11487 quotes,
11488 on_empty,
11489 on_error,
11490 ..
11491 } => {
11492 name.render(ctx, f)?;
11493 f.write_str(" ")?;
11494 data_type.render(ctx, f)?;
11495 if let Some(format) = format {
11496 f.write_str(" ")?;
11497 format.render(ctx, f)?;
11498 }
11499 if let Some(path) = path {
11500 f.write_str(" PATH ")?;
11501 path.render(ctx, f)?;
11502 }
11503 render_json_wrapper(*wrapper, f)?;
11504 render_json_quotes(*quotes, f)?;
11505 render_json_on_behavior(on_empty, "EMPTY", ctx, f)?;
11506 render_json_on_behavior(on_error, "ERROR", ctx, f)
11507 }
11508 JsonTableColumn::Exists {
11509 name,
11510 data_type,
11511 path,
11512 on_error,
11513 ..
11514 } => {
11515 name.render(ctx, f)?;
11516 f.write_str(" ")?;
11517 data_type.render(ctx, f)?;
11518 f.write_str(" EXISTS")?;
11519 if let Some(path) = path {
11520 f.write_str(" PATH ")?;
11521 path.render(ctx, f)?;
11522 }
11523 render_json_on_behavior(on_error, "ERROR", ctx, f)
11524 }
11525 JsonTableColumn::Nested {
11526 path,
11527 path_name,
11528 columns,
11529 ..
11530 } => {
11531 f.write_str("NESTED PATH ")?;
11532 path.render(ctx, f)?;
11533 if let Some(name) = path_name {
11534 f.write_str(" AS ")?;
11535 name.render(ctx, f)?;
11536 }
11537 f.write_str(" COLUMNS (")?;
11538 render_comma_separated(columns, ctx, f)?;
11539 f.write_str(")")
11540 }
11541 }
11542 }
11543}
11544
11545fn render_c_expr_operand<X: Extension + Render>(
11552 expr: &Expr<X>,
11553 ctx: &RenderCtx<'_>,
11554 f: &mut fmt::Formatter<'_>,
11555) -> fmt::Result {
11556 let is_primary = matches!(
11557 expr,
11558 Expr::Column { .. }
11559 | Expr::Literal { .. }
11560 | Expr::Function { .. }
11561 | Expr::Parameter { .. }
11562 | Expr::PositionalColumn { .. }
11563 | Expr::SessionVariable { .. }
11564 | Expr::SpecialFunction { .. }
11565 );
11566 if is_primary {
11567 expr.render(ctx, f)
11568 } else {
11569 f.write_str("(")?;
11570 expr.render(ctx, f)?;
11571 f.write_str(")")
11572 }
11573}
11574
11575impl<X: Extension + Render> Render for XmlTable<X> {
11576 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11577 if self.lateral {
11578 f.write_str("LATERAL ")?;
11579 }
11580 f.write_str("XMLTABLE(")?;
11581 if !self.namespaces.is_empty() {
11582 f.write_str("XMLNAMESPACES(")?;
11583 render_comma_separated(&self.namespaces, ctx, f)?;
11584 f.write_str("), ")?;
11585 }
11586 render_c_expr_operand(&self.row_expr, ctx, f)?;
11587 f.write_str(" PASSING")?;
11588 render_xml_passing_mechanism(&self.passing_mechanism_before, f)?;
11589 f.write_str(" ")?;
11590 render_c_expr_operand(&self.document, ctx, f)?;
11591 render_xml_passing_mechanism(&self.passing_mechanism_after, f)?;
11592 f.write_str(" COLUMNS ")?;
11593 render_comma_separated(&self.columns, ctx, f)?;
11594 f.write_str(")")
11595 }
11596}
11597
11598impl<X: Extension + Render> Render for XmlNamespace<X> {
11599 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11600 match &self.name {
11601 Some(name) => {
11602 self.uri.render(ctx, f)?;
11603 f.write_str(" AS ")?;
11604 name.render(ctx, f)
11605 }
11606 None => {
11607 f.write_str("DEFAULT ")?;
11608 self.uri.render(ctx, f)
11609 }
11610 }
11611 }
11612}
11613
11614impl<X: Extension + Render> Render for XmlTableColumn<X> {
11615 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11616 match self {
11617 XmlTableColumn::ForOrdinality { name, .. } => {
11618 name.render(ctx, f)?;
11619 f.write_str(" FOR ORDINALITY")
11620 }
11621 XmlTableColumn::Regular {
11622 name,
11623 data_type,
11624 path,
11625 default,
11626 not_null,
11627 ..
11628 } => {
11629 name.render(ctx, f)?;
11630 f.write_str(" ")?;
11631 data_type.render(ctx, f)?;
11632 if let Some(path) = path {
11636 f.write_str(" PATH ")?;
11637 path.render(ctx, f)?;
11638 }
11639 if let Some(default) = default {
11640 f.write_str(" DEFAULT ")?;
11641 default.render(ctx, f)?;
11642 }
11643 match not_null {
11644 Some(true) => f.write_str(" NOT NULL"),
11645 Some(false) => f.write_str(" NULL"),
11646 None => Ok(()),
11647 }
11648 }
11649 }
11650 }
11651}
11652
11653impl<X: Extension + Render> Render for OpenJson<X> {
11654 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11655 f.write_str("OPENJSON(")?;
11656 self.json_expr.render(ctx, f)?;
11657 if let Some(path) = &self.path {
11658 f.write_str(", ")?;
11659 path.render(ctx, f)?;
11660 }
11661 f.write_str(")")?;
11662 if !self.columns.is_empty() {
11665 f.write_str(" WITH (")?;
11666 render_comma_separated(&self.columns, ctx, f)?;
11667 f.write_str(")")?;
11668 }
11669 Ok(())
11670 }
11671}
11672
11673impl<X: Extension + Render> Render for OpenJsonColumn<X> {
11674 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11675 self.name.render(ctx, f)?;
11676 f.write_str(" ")?;
11677 self.data_type.render(ctx, f)?;
11678 if let Some(path) = &self.path {
11679 f.write_str(" ")?;
11680 path.render(ctx, f)?;
11681 }
11682 if self.as_json {
11683 f.write_str(" AS JSON")?;
11684 }
11685 Ok(())
11686 }
11687}
11688
11689impl<X: Extension + Render> Render for Pivot<X> {
11690 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11691 match self.spelling {
11692 PivotSpelling::Statement => {
11696 if let Some(with) = &self.with {
11697 with.render(ctx, f)?;
11698 f.write_str(" ")?;
11699 }
11700 f.write_str("PIVOT ")?;
11701 self.source.render(ctx, f)?;
11702 if !self.pivot_on.is_empty() {
11703 f.write_str(" ON ")?;
11704 render_comma_separated(&self.pivot_on, ctx, f)?;
11705 }
11706 if !self.aggregates.is_empty() {
11707 f.write_str(" USING ")?;
11708 render_comma_separated(&self.aggregates, ctx, f)?;
11709 }
11710 if !self.group_by.is_empty() {
11711 f.write_str(" GROUP BY ")?;
11712 render_comma_separated(&self.group_by, ctx, f)?;
11713 }
11714 render_pivot_statement_tail(
11715 &self.order_by,
11716 self.order_by_all.as_deref(),
11717 self.limit.as_deref(),
11718 ctx,
11719 f,
11720 )
11721 }
11722 PivotSpelling::TableFactor => {
11726 self.source.render(ctx, f)?;
11727 f.write_str(" PIVOT (")?;
11728 render_comma_separated(&self.aggregates, ctx, f)?;
11729 for (index, column) in self.pivot_on.iter().enumerate() {
11732 f.write_str(if index == 0 { " FOR " } else { " " })?;
11733 column.render(ctx, f)?;
11734 }
11735 if !self.group_by.is_empty() {
11736 f.write_str(" GROUP BY ")?;
11737 render_comma_separated(&self.group_by, ctx, f)?;
11738 }
11739 if let Some(default) = &self.default_on_null {
11740 f.write_str(" DEFAULT ON NULL (")?;
11741 default.render(ctx, f)?;
11742 f.write_str(")")?;
11743 }
11744 f.write_str(")")
11745 }
11746 }
11747 }
11748}
11749
11750impl<X: Extension + Render> Render for Unpivot<X> {
11751 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11752 match self.spelling {
11753 UnpivotSpelling::Statement => {
11756 if let Some(with) = &self.with {
11757 with.render(ctx, f)?;
11758 f.write_str(" ")?;
11759 }
11760 f.write_str("UNPIVOT ")?;
11761 self.source.render(ctx, f)?;
11762 f.write_str(" ON ")?;
11763 render_comma_separated(&self.columns, ctx, f)?;
11764 if !self.name.is_empty() || !self.value.is_empty() {
11765 f.write_str(" INTO NAME ")?;
11766 render_comma_separated(&self.name, ctx, f)?;
11767 f.write_str(" VALUE ")?;
11768 render_comma_separated(&self.value, ctx, f)?;
11769 }
11770 render_pivot_statement_tail(
11771 &self.order_by,
11772 self.order_by_all.as_deref(),
11773 self.limit.as_deref(),
11774 ctx,
11775 f,
11776 )
11777 }
11778 UnpivotSpelling::TableFactor => {
11780 self.source.render(ctx, f)?;
11781 f.write_str(" UNPIVOT ")?;
11782 match self.null_inclusion {
11785 Some(NullInclusion::IncludeNulls) => f.write_str("INCLUDE NULLS ")?,
11786 Some(NullInclusion::ExcludeNulls) => f.write_str("EXCLUDE NULLS ")?,
11787 None => {}
11788 }
11789 f.write_str("(")?;
11790 render_unpivot_name_list(&self.value, ctx, f)?;
11791 f.write_str(" FOR ")?;
11792 render_unpivot_name_list(&self.name, ctx, f)?;
11793 f.write_str(" IN (")?;
11794 render_comma_separated(&self.columns, ctx, f)?;
11795 f.write_str("))")
11796 }
11797 }
11798 }
11799}
11800
11801fn render_row_patterns(
11804 patterns: &[MatchRecognizePattern],
11805 separator: &str,
11806 ctx: &RenderCtx<'_>,
11807 f: &mut fmt::Formatter<'_>,
11808) -> fmt::Result {
11809 for (index, pattern) in patterns.iter().enumerate() {
11810 if index > 0 {
11811 f.write_str(separator)?;
11812 }
11813 pattern.render(ctx, f)?;
11814 }
11815 Ok(())
11816}
11817
11818impl<X: Extension + Render> Render for MatchRecognize<X> {
11819 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11820 self.source.render(ctx, f)?;
11825 f.write_str(" MATCH_RECOGNIZE (")?;
11826 let mut wrote = false;
11827 if !self.partition_by.is_empty() {
11828 f.write_str("PARTITION BY ")?;
11829 render_comma_separated(&self.partition_by, ctx, f)?;
11830 wrote = true;
11831 }
11832 if !self.order_by.is_empty() {
11833 if wrote {
11834 f.write_str(" ")?;
11835 }
11836 f.write_str("ORDER BY ")?;
11837 render_comma_separated(&self.order_by, ctx, f)?;
11838 wrote = true;
11839 }
11840 if !self.measures.is_empty() {
11841 if wrote {
11842 f.write_str(" ")?;
11843 }
11844 f.write_str("MEASURES ")?;
11845 render_comma_separated(&self.measures, ctx, f)?;
11846 wrote = true;
11847 }
11848 if let Some(rows_per_match) = &self.rows_per_match {
11849 if wrote {
11850 f.write_str(" ")?;
11851 }
11852 rows_per_match.render(ctx, f)?;
11853 wrote = true;
11854 }
11855 if let Some(after_match_skip) = &self.after_match_skip {
11856 if wrote {
11857 f.write_str(" ")?;
11858 }
11859 after_match_skip.render(ctx, f)?;
11860 wrote = true;
11861 }
11862 if wrote {
11863 f.write_str(" ")?;
11864 }
11865 f.write_str("PATTERN (")?;
11866 self.pattern.render(ctx, f)?;
11867 f.write_str(")")?;
11868 if !self.subsets.is_empty() {
11869 f.write_str(" SUBSET ")?;
11870 render_comma_separated(&self.subsets, ctx, f)?;
11871 }
11872 if !self.define.is_empty() {
11873 f.write_str(" DEFINE ")?;
11874 render_comma_separated(&self.define, ctx, f)?;
11875 }
11876 f.write_str(")")
11877 }
11878}
11879
11880impl<X: Extension + Render> Render for Measure<X> {
11881 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11882 self.expr.render(ctx, f)?;
11883 f.write_str(" AS ")?;
11884 self.alias.render(ctx, f)
11885 }
11886}
11887
11888impl Render for RowsPerMatch {
11889 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11890 match self {
11891 RowsPerMatch::OneRow => f.write_str("ONE ROW PER MATCH"),
11892 RowsPerMatch::AllRows(mode) => {
11893 f.write_str("ALL ROWS PER MATCH")?;
11894 if let Some(mode) = mode {
11895 f.write_str(" ")?;
11896 mode.render(ctx, f)?;
11897 }
11898 Ok(())
11899 }
11900 }
11901 }
11902}
11903
11904impl Render for EmptyMatchesMode {
11905 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11906 f.write_str(match self {
11907 EmptyMatchesMode::Show => "SHOW EMPTY MATCHES",
11908 EmptyMatchesMode::Omit => "OMIT EMPTY MATCHES",
11909 EmptyMatchesMode::WithUnmatched => "WITH UNMATCHED ROWS",
11910 })
11911 }
11912}
11913
11914impl Render for AfterMatchSkip {
11915 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11916 f.write_str("AFTER MATCH SKIP ")?;
11917 match self {
11918 AfterMatchSkip::PastLastRow { .. } => f.write_str("PAST LAST ROW"),
11919 AfterMatchSkip::ToNextRow { .. } => f.write_str("TO NEXT ROW"),
11920 AfterMatchSkip::ToFirst { symbol, .. } => {
11921 f.write_str("TO FIRST ")?;
11922 symbol.render(ctx, f)
11923 }
11924 AfterMatchSkip::ToLast { symbol, .. } => {
11925 f.write_str("TO LAST ")?;
11926 symbol.render(ctx, f)
11927 }
11928 }
11929 }
11930}
11931
11932impl Render for SubsetDefinition {
11933 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11934 self.name.render(ctx, f)?;
11935 f.write_str(" = (")?;
11936 render_comma_separated(&self.members, ctx, f)?;
11937 f.write_str(")")
11938 }
11939}
11940
11941impl<X: Extension + Render> Render for SymbolDefinition<X> {
11942 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11943 self.symbol.render(ctx, f)?;
11944 f.write_str(" AS ")?;
11945 self.definition.render(ctx, f)
11946 }
11947}
11948
11949impl Render for MatchRecognizePattern {
11950 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11951 match self {
11952 MatchRecognizePattern::Symbol { symbol, .. } => symbol.render(ctx, f),
11953 MatchRecognizePattern::Start { .. } => f.write_str("^"),
11954 MatchRecognizePattern::End { .. } => f.write_str("$"),
11955 MatchRecognizePattern::Concat { patterns, .. } => {
11956 render_row_patterns(patterns, " ", ctx, f)
11957 }
11958 MatchRecognizePattern::Alternation { patterns, .. } => {
11959 render_row_patterns(patterns, " | ", ctx, f)
11960 }
11961 MatchRecognizePattern::Group { pattern, .. } => {
11962 f.write_str("(")?;
11963 pattern.render(ctx, f)?;
11964 f.write_str(")")
11965 }
11966 MatchRecognizePattern::Exclude { pattern, .. } => {
11967 f.write_str("{- ")?;
11968 pattern.render(ctx, f)?;
11969 f.write_str(" -}")
11970 }
11971 MatchRecognizePattern::Permute { patterns, .. } => {
11972 f.write_str("PERMUTE(")?;
11973 render_row_patterns(patterns, ", ", ctx, f)?;
11974 f.write_str(")")
11975 }
11976 MatchRecognizePattern::Repetition {
11977 pattern,
11978 quantifier,
11979 ..
11980 } => {
11981 pattern.render(ctx, f)?;
11982 quantifier.render(ctx, f)
11983 }
11984 }
11985 }
11986}
11987
11988impl Render for RepetitionQuantifier {
11989 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11990 match self {
11991 RepetitionQuantifier::ZeroOrMore => f.write_str("*"),
11992 RepetitionQuantifier::OneOrMore => f.write_str("+"),
11993 RepetitionQuantifier::AtMostOne => f.write_str("?"),
11994 RepetitionQuantifier::Exactly(n) => write!(f, "{{{n}}}"),
11995 RepetitionQuantifier::AtLeast(n) => write!(f, "{{{n},}}"),
11996 RepetitionQuantifier::AtMost(m) => write!(f, "{{,{m}}}"),
11997 RepetitionQuantifier::Range(n, m) => write!(f, "{{{n},{m}}}"),
11998 }
11999 }
12000}
12001
12002impl<X: Extension + Render> Render for PivotExpr<X> {
12003 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12004 self.expr.render(ctx, f)?;
12005 render_alias(self.alias.as_ref(), self.alias_spelling, ctx, f)
12006 }
12007}
12008
12009impl<X: Extension + Render> Render for PivotValueSource<X> {
12010 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12011 match self {
12012 PivotValueSource::Any { order_by, .. } => {
12013 f.write_str("ANY")?;
12014 if !order_by.is_empty() {
12015 f.write_str(" ORDER BY ")?;
12016 render_comma_separated(order_by, ctx, f)?;
12017 }
12018 Ok(())
12019 }
12020 PivotValueSource::Subquery { query, .. } => query.render(ctx, f),
12021 }
12022 }
12023}
12024
12025impl<X: Extension + Render> Render for PivotColumn<X> {
12026 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12027 if let Some(enum_source) = &self.enum_source {
12028 self.expr.render(ctx, f)?;
12029 f.write_str(" IN ")?;
12030 return enum_source.render(ctx, f);
12031 }
12032 if let Some(value_source) = &self.value_source {
12035 render_predicate_operand(
12036 &self.expr,
12037 ctx.target().binding_powers.range_predicate(),
12038 Side::Left,
12039 ctx,
12040 f,
12041 )?;
12042 f.write_str(" IN (")?;
12043 value_source.render(ctx, f)?;
12044 return f.write_str(")");
12045 }
12046 if self.values.is_empty() {
12047 return self.expr.render(ctx, f);
12048 }
12049 render_predicate_operand(
12055 &self.expr,
12056 ctx.target().binding_powers.range_predicate(),
12057 Side::Left,
12058 ctx,
12059 f,
12060 )?;
12061 f.write_str(" IN (")?;
12062 render_comma_separated(&self.values, ctx, f)?;
12063 f.write_str(")")
12064 }
12065}
12066
12067impl<X: Extension + Render> Render for UnpivotColumn<X> {
12068 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12069 if self.columns.len() == 1 {
12071 self.columns[0].render(ctx, f)?;
12072 } else {
12073 f.write_str("(")?;
12074 render_comma_separated(&self.columns, ctx, f)?;
12075 f.write_str(")")?;
12076 }
12077 render_alias(self.alias.as_ref(), self.alias_spelling, ctx, f)
12078 }
12079}
12080
12081fn render_unpivot_name_list(
12084 names: &[Ident],
12085 ctx: &RenderCtx<'_>,
12086 f: &mut fmt::Formatter<'_>,
12087) -> fmt::Result {
12088 if names.len() == 1 {
12089 names[0].render(ctx, f)
12090 } else {
12091 f.write_str("(")?;
12092 render_comma_separated(names, ctx, f)?;
12093 f.write_str(")")
12094 }
12095}
12096
12097fn render_pivot_statement_tail<X: Extension + Render>(
12102 order_by: &[OrderByExpr<X>],
12103 order_by_all: Option<&OrderByAll>,
12104 limit: Option<&Limit<X>>,
12105 ctx: &RenderCtx<'_>,
12106 f: &mut fmt::Formatter<'_>,
12107) -> fmt::Result {
12108 if !order_by.is_empty() {
12109 f.write_str(" ORDER BY ")?;
12110 render_comma_separated(order_by, ctx, f)?;
12111 }
12112 if let Some(all) = order_by_all {
12113 f.write_str(" ORDER BY ")?;
12114 all.render(ctx, f)?;
12115 }
12116 if let Some(limit) = limit {
12117 f.write_str(" ")?;
12118 limit.render(ctx, f)?;
12119 }
12120 Ok(())
12121}
12122
12123impl<X: Extension + Render> Render for RowsFromItem<X> {
12124 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12125 self.function.render(ctx, f)?;
12126 if !self.column_defs.is_empty() {
12127 f.write_str(" AS (")?;
12128 render_comma_separated(&self.column_defs, ctx, f)?;
12129 f.write_str(")")?;
12130 }
12131 Ok(())
12132 }
12133}
12134
12135impl<X: Extension + Render> Render for TableFunctionColumn<X> {
12136 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12137 self.name.render(ctx, f)?;
12138 f.write_str(" ")?;
12139 self.data_type.render(ctx, f)
12140 }
12141}
12142
12143impl Render for TableAlias {
12144 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12145 self.name.render(ctx, f)?;
12146 if !self.columns.is_empty() {
12147 f.write_str("(")?;
12148 render_ident_list(&self.columns, ctx, f)?;
12149 f.write_str(")")?;
12150 }
12151 Ok(())
12152 }
12153}
12154
12155impl<X: Extension + Render> Render for TableSample<X> {
12156 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12157 f.write_str(" TABLESAMPLE ")?;
12158 self.method.render(ctx, f)?;
12159 f.write_str(" (")?;
12160 render_comma_separated(&self.args, ctx, f)?;
12161 f.write_str(")")?;
12162 if let Some(repeatable) = &self.repeatable {
12163 f.write_str(" REPEATABLE (")?;
12164 repeatable.render(ctx, f)?;
12165 f.write_str(")")?;
12166 }
12167 Ok(())
12168 }
12169}
12170
12171impl Render for SampleClause {
12172 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12173 if let Some(method) = &self.method {
12178 method.render(ctx, f)?;
12179 f.write_str("(")?;
12180 self.size.render(ctx, f)?;
12181 self.unit.render(ctx, f)?;
12182 f.write_str(")")?;
12183 if let Some(seed) = &self.seed {
12184 f.write_str(" REPEATABLE (")?;
12185 seed.render(ctx, f)?;
12186 f.write_str(")")?;
12187 }
12188 } else {
12189 self.size.render(ctx, f)?;
12190 self.unit.render(ctx, f)?;
12191 }
12192 Ok(())
12193 }
12194}
12195
12196impl Render for SampleUnit {
12197 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12198 f.write_str(match self {
12199 SampleUnit::Count => "",
12200 SampleUnit::Rows => " ROWS",
12201 SampleUnit::Percent => " PERCENT",
12202 SampleUnit::PercentSign => "%",
12203 })
12204 }
12205}
12206
12207fn honours_alias_spelling(ctx: &RenderCtx<'_>) -> bool {
12217 honours_source_spelling(ctx)
12218}
12219
12220fn honours_source_spelling(ctx: &RenderCtx<'_>) -> bool {
12231 ctx.spelling() == RenderSpelling::PreserveSource && ctx.mode() != RenderMode::Redacted
12232}
12233
12234fn alias_lead(spelling: AliasSpelling, ctx: &RenderCtx<'_>) -> &'static str {
12239 if !honours_alias_spelling(ctx) {
12240 return " AS ";
12241 }
12242 match spelling {
12243 AliasSpelling::Bare => " ",
12244 AliasSpelling::As | AliasSpelling::PrefixColon => " AS ",
12245 }
12246}
12247
12248fn render_table_alias(
12249 alias: Option<&TableAlias>,
12250 ctx: &RenderCtx<'_>,
12251 f: &mut fmt::Formatter<'_>,
12252) -> fmt::Result {
12253 if let Some(alias) = alias {
12254 f.write_str(alias_lead(alias.spelling, ctx))?;
12255 alias.render(ctx, f)?;
12256 }
12257 Ok(())
12258}
12259
12260fn render_function_alias<X: Extension + Render>(
12265 alias: Option<&TableAlias>,
12266 column_defs: &[TableFunctionColumn<X>],
12267 ctx: &RenderCtx<'_>,
12268 f: &mut fmt::Formatter<'_>,
12269) -> fmt::Result {
12270 if column_defs.is_empty() {
12271 return render_table_alias(alias, ctx, f);
12272 }
12273 f.write_str(alias.map_or(" AS ", |a| alias_lead(a.spelling, ctx)))?;
12277 if let Some(alias) = alias {
12278 alias.name.render(ctx, f)?;
12279 }
12280 f.write_str("(")?;
12281 render_comma_separated(column_defs, ctx, f)?;
12282 f.write_str(")")
12283}
12284
12285fn render_alias(
12286 alias: Option<&Ident>,
12287 spelling: AliasSpelling,
12288 ctx: &RenderCtx<'_>,
12289 f: &mut fmt::Formatter<'_>,
12290) -> fmt::Result {
12291 if let Some(alias) = alias {
12292 f.write_str(alias_lead(spelling, ctx))?;
12293 alias.render(ctx, f)?;
12294 }
12295 Ok(())
12296}
12297
12298fn render_relation_inheritance(
12302 inheritance: &RelationInheritance,
12303 name: &ObjectName,
12304 ctx: &RenderCtx<'_>,
12305 f: &mut fmt::Formatter<'_>,
12306) -> fmt::Result {
12307 match inheritance {
12308 RelationInheritance::Plain => name.render(ctx, f),
12309 RelationInheritance::Descendants => {
12310 name.render(ctx, f)?;
12311 f.write_str(" *")
12312 }
12313 RelationInheritance::Only(OnlySyntax::Bare) => {
12314 f.write_str("ONLY ")?;
12315 name.render(ctx, f)
12316 }
12317 RelationInheritance::Only(OnlySyntax::Parenthesized) => {
12318 f.write_str("ONLY (")?;
12319 name.render(ctx, f)?;
12320 f.write_str(")")
12321 }
12322 }
12323}
12324
12325fn render_ident_list(
12326 items: &[Ident],
12327 ctx: &RenderCtx<'_>,
12328 f: &mut fmt::Formatter<'_>,
12329) -> fmt::Result {
12330 render_comma_separated(items, ctx, f)
12331}
12332
12333fn render_comma_separated<T: Render>(
12335 items: &[T],
12336 ctx: &RenderCtx<'_>,
12337 f: &mut fmt::Formatter<'_>,
12338) -> fmt::Result {
12339 for (i, item) in items.iter().enumerate() {
12340 if i > 0 {
12341 f.write_str(", ")?;
12342 }
12343 item.render(ctx, f)?;
12344 }
12345 Ok(())
12346}
12347
12348fn render_leading_space_comma_separated<T: Render>(
12352 items: &[T],
12353 ctx: &RenderCtx<'_>,
12354 f: &mut fmt::Formatter<'_>,
12355) -> fmt::Result {
12356 if items.is_empty() {
12357 return Ok(());
12358 }
12359 f.write_str(" ")?;
12360 render_comma_separated(items, ctx, f)
12361}
12362
12363fn render_values_rows<T: Render>(
12368 rows: &[ThinVec<T>],
12369 explicit_row: bool,
12370 ctx: &RenderCtx<'_>,
12371 f: &mut fmt::Formatter<'_>,
12372) -> fmt::Result {
12373 let open = if explicit_row { "ROW(" } else { "(" };
12376 for (i, row) in rows.iter().enumerate() {
12377 if i > 0 {
12378 f.write_str(", ")?;
12379 }
12380 f.write_str(open)?;
12381 render_comma_separated(row, ctx, f)?;
12382 f.write_str(")")?;
12383 }
12384 Ok(())
12385}
12386
12387impl<X: Extension + Render> Render for Join<X> {
12388 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12389 self.operator.render(ctx, f)?;
12392 f.write_str(" ")?;
12393 self.relation.render(ctx, f)?;
12394 if let Some(constraint) = self.operator.constraint() {
12395 constraint.render(ctx, f)?;
12396 }
12397 Ok(())
12398 }
12399}
12400
12401impl<X: Extension> JoinOperator<X> {
12402 fn constraint(&self) -> Option<&JoinConstraint<X>> {
12404 match self {
12405 JoinOperator::Inner { constraint, .. }
12406 | JoinOperator::LeftOuter { constraint, .. }
12407 | JoinOperator::RightOuter { constraint, .. }
12408 | JoinOperator::FullOuter { constraint, .. }
12409 | JoinOperator::AsOf { constraint, .. }
12410 | JoinOperator::Semi { constraint, .. }
12411 | JoinOperator::Anti { constraint, .. } => Some(constraint),
12412 JoinOperator::Cross { .. }
12413 | JoinOperator::Positional { .. }
12414 | JoinOperator::Apply { .. } => None,
12415 }
12416 }
12417}
12418
12419impl<X: Extension + Render> Render for JoinOperator<X> {
12420 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12421 if matches!(self.constraint(), Some(JoinConstraint::Natural { .. })) {
12423 f.write_str("NATURAL ")?;
12424 }
12425 let fidelity = honours_source_spelling(ctx);
12429 f.write_str(match self {
12430 JoinOperator::Inner { straight: true, .. } => "STRAIGHT_JOIN",
12433 JoinOperator::Inner {
12434 straight: false,
12435 inner: true,
12436 ..
12437 } if fidelity => "INNER JOIN",
12438 JoinOperator::Inner {
12439 straight: false, ..
12440 } => "JOIN",
12441 JoinOperator::LeftOuter { outer: true, .. } if fidelity => "LEFT OUTER JOIN",
12442 JoinOperator::LeftOuter { .. } => "LEFT JOIN",
12443 JoinOperator::RightOuter { outer: true, .. } if fidelity => "RIGHT OUTER JOIN",
12444 JoinOperator::RightOuter { .. } => "RIGHT JOIN",
12445 JoinOperator::FullOuter { outer: true, .. } if fidelity => "FULL OUTER JOIN",
12446 JoinOperator::FullOuter { .. } => "FULL JOIN",
12447 JoinOperator::AsOf { kind, .. } => match kind {
12450 AsOfJoinKind::Inner => "ASOF JOIN",
12451 AsOfJoinKind::Left => "ASOF LEFT JOIN",
12452 AsOfJoinKind::Right => "ASOF RIGHT JOIN",
12453 AsOfJoinKind::Full => "ASOF FULL JOIN",
12454 },
12455 JoinOperator::Cross { .. } => "CROSS JOIN",
12456 JoinOperator::Positional { .. } => "POSITIONAL JOIN",
12457 JoinOperator::Semi { asof, side, .. } => match (side, asof) {
12463 (SemiAntiSide::Sideless, false) => "SEMI JOIN",
12464 (SemiAntiSide::Sideless, true) => "ASOF SEMI JOIN",
12465 (SemiAntiSide::Left, _) => "LEFT SEMI JOIN",
12466 (SemiAntiSide::Right, _) => "RIGHT SEMI JOIN",
12467 },
12468 JoinOperator::Anti { asof, side, .. } => match (side, asof) {
12469 (SemiAntiSide::Sideless, false) => "ANTI JOIN",
12470 (SemiAntiSide::Sideless, true) => "ASOF ANTI JOIN",
12471 (SemiAntiSide::Left, _) => "LEFT ANTI JOIN",
12472 (SemiAntiSide::Right, _) => "RIGHT ANTI JOIN",
12473 },
12474 JoinOperator::Apply { kind, .. } => match kind {
12477 ApplyKind::Cross => "CROSS APPLY",
12478 ApplyKind::Outer => "OUTER APPLY",
12479 },
12480 })
12481 }
12482}
12483
12484impl<X: Extension + Render> Render for JoinConstraint<X> {
12485 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12486 match self {
12487 JoinConstraint::On { expr, .. } => {
12488 f.write_str(" ON ")?;
12489 expr.render(ctx, f)
12490 }
12491 JoinConstraint::Using { columns, alias, .. } => {
12492 f.write_str(" USING (")?;
12493 render_comma_separated(columns, ctx, f)?;
12494 f.write_str(")")?;
12495 if let Some(alias) = alias {
12496 f.write_str(" AS ")?;
12497 alias.render(ctx, f)?;
12498 }
12499 Ok(())
12500 }
12501 JoinConstraint::Natural { .. } | JoinConstraint::None { .. } => Ok(()),
12503 }
12504 }
12505}
12506
12507impl<X: Extension + Render> Render for ExtractExpr<X> {
12512 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12513 f.write_str("EXTRACT(")?;
12514 self.field.render(ctx, f)?;
12515 f.write_str(" FROM ")?;
12516 self.source.render(ctx, f)?;
12517 f.write_str(")")
12518 }
12519}
12520
12521impl Render for NullTreatment {
12522 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12523 f.write_str(match self {
12524 NullTreatment::IgnoreNulls => "IGNORE NULLS",
12525 NullTreatment::RespectNulls => "RESPECT NULLS",
12526 })
12527 }
12528}
12529
12530impl Render for JsonEncoding {
12535 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12536 f.write_str(match self {
12537 JsonEncoding::Utf8 => "UTF8",
12538 JsonEncoding::Utf16 => "UTF16",
12539 JsonEncoding::Utf32 => "UTF32",
12540 })
12541 }
12542}
12543
12544impl Render for JsonFormat {
12545 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12547 f.write_str("FORMAT JSON")?;
12548 if let Some(encoding) = &self.encoding {
12549 f.write_str(" ENCODING ")?;
12550 encoding.render(ctx, f)?;
12551 }
12552 Ok(())
12553 }
12554}
12555
12556impl<X: Extension + Render> Render for JsonValueExpr<X> {
12557 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12558 self.expr.render(ctx, f)?;
12559 if let Some(format) = &self.format {
12560 f.write_str(" ")?;
12561 format.render(ctx, f)?;
12562 }
12563 Ok(())
12564 }
12565}
12566
12567impl<X: Extension + Render> Render for JsonReturning<X> {
12568 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12570 f.write_str("RETURNING ")?;
12571 self.data_type.render(ctx, f)?;
12572 if let Some(format) = &self.format {
12573 f.write_str(" ")?;
12574 format.render(ctx, f)?;
12575 }
12576 Ok(())
12577 }
12578}
12579
12580impl<X: Extension + Render> Render for JsonPassingArg<X> {
12581 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12582 self.value.render(ctx, f)?;
12583 f.write_str(" AS ")?;
12584 self.name.render(ctx, f)
12585 }
12586}
12587
12588impl<X: Extension + Render> Render for JsonBehavior<X> {
12589 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12591 match self.kind {
12592 JsonBehaviorKind::Error => f.write_str("ERROR"),
12593 JsonBehaviorKind::Null => f.write_str("NULL"),
12594 JsonBehaviorKind::True => f.write_str("TRUE"),
12595 JsonBehaviorKind::False => f.write_str("FALSE"),
12596 JsonBehaviorKind::Unknown => f.write_str("UNKNOWN"),
12597 JsonBehaviorKind::Empty => f.write_str("EMPTY"),
12598 JsonBehaviorKind::EmptyArray => f.write_str("EMPTY ARRAY"),
12599 JsonBehaviorKind::EmptyObject => f.write_str("EMPTY OBJECT"),
12600 JsonBehaviorKind::Default => {
12601 f.write_str("DEFAULT ")?;
12602 if let Some(expr) = &self.default_expr {
12605 expr.render(ctx, f)?;
12606 }
12607 Ok(())
12608 }
12609 }
12610 }
12611}
12612
12613fn render_json_on_behavior<X: Extension + Render>(
12615 behavior: &Option<JsonBehavior<X>>,
12616 slot: &str,
12617 ctx: &RenderCtx<'_>,
12618 f: &mut fmt::Formatter<'_>,
12619) -> fmt::Result {
12620 if let Some(behavior) = behavior {
12621 f.write_str(" ")?;
12622 behavior.render(ctx, f)?;
12623 f.write_str(" ON ")?;
12624 f.write_str(slot)?;
12625 }
12626 Ok(())
12627}
12628
12629fn render_json_wrapper(wrapper: JsonWrapperBehavior, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12631 match wrapper {
12632 JsonWrapperBehavior::Unspecified => Ok(()),
12633 JsonWrapperBehavior::Without => f.write_str(" WITHOUT WRAPPER"),
12634 JsonWrapperBehavior::Unconditional => f.write_str(" WITH WRAPPER"),
12635 JsonWrapperBehavior::Conditional => f.write_str(" WITH CONDITIONAL WRAPPER"),
12636 }
12637}
12638
12639fn render_json_quotes(quotes: JsonQuotesBehavior, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12641 match quotes {
12642 JsonQuotesBehavior::Unspecified => Ok(()),
12643 JsonQuotesBehavior::Keep => f.write_str(" KEEP QUOTES"),
12644 JsonQuotesBehavior::Omit => f.write_str(" OMIT QUOTES"),
12645 }
12646}
12647
12648fn render_json_null_clause(
12650 clause: &Option<JsonNullClause>,
12651 f: &mut fmt::Formatter<'_>,
12652) -> fmt::Result {
12653 match clause {
12654 Some(JsonNullClause::AbsentOnNull) => f.write_str(" ABSENT ON NULL"),
12655 Some(JsonNullClause::NullOnNull) => f.write_str(" NULL ON NULL"),
12656 None => Ok(()),
12657 }
12658}
12659
12660fn render_json_unique(unique_keys: Option<bool>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12662 match unique_keys {
12663 Some(true) => f.write_str(" WITH UNIQUE KEYS"),
12664 Some(false) => f.write_str(" WITHOUT UNIQUE KEYS"),
12665 None => Ok(()),
12666 }
12667}
12668
12669impl<X: Extension + Render> Render for JsonFuncExpr<X> {
12670 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12671 f.write_str(match self.kind {
12672 JsonFuncKind::Value => "JSON_VALUE(",
12673 JsonFuncKind::Query => "JSON_QUERY(",
12674 JsonFuncKind::Exists => "JSON_EXISTS(",
12675 })?;
12676 self.context.render(ctx, f)?;
12677 f.write_str(", ")?;
12678 self.path.render(ctx, f)?;
12679 if !self.passing.is_empty() {
12680 f.write_str(" PASSING ")?;
12681 render_comma_separated(&self.passing, ctx, f)?;
12682 }
12683 if let Some(returning) = &self.returning {
12684 f.write_str(" ")?;
12685 returning.render(ctx, f)?;
12686 }
12687 render_json_wrapper(self.wrapper, f)?;
12688 render_json_quotes(self.quotes, f)?;
12689 render_json_on_behavior(&self.on_empty, "EMPTY", ctx, f)?;
12690 render_json_on_behavior(&self.on_error, "ERROR", ctx, f)?;
12691 f.write_str(")")
12692 }
12693}
12694
12695impl<X: Extension + Render> Render for JsonKeyValue<X> {
12696 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12697 self.key.render(ctx, f)?;
12698 f.write_str(match self.spelling {
12699 JsonKeyValueSpelling::Colon => ": ",
12700 JsonKeyValueSpelling::Value => " VALUE ",
12701 })?;
12702 self.value.render(ctx, f)
12703 }
12704}
12705
12706impl<X: Extension + Render> Render for JsonObjectExpr<X> {
12707 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12708 f.write_str("JSON_OBJECT(")?;
12709 render_comma_separated(&self.entries, ctx, f)?;
12710 render_json_null_clause(&self.null_clause, f)?;
12711 render_json_unique(self.unique_keys, f)?;
12712 if let Some(returning) = &self.returning {
12713 if !self.entries.is_empty() || self.null_clause.is_some() || self.unique_keys.is_some()
12714 {
12715 f.write_str(" ")?;
12716 }
12717 returning.render(ctx, f)?;
12718 }
12719 f.write_str(")")
12720 }
12721}
12722
12723impl<X: Extension + Render> Render for JsonArrayExpr<X> {
12724 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12725 f.write_str("JSON_ARRAY(")?;
12726 let empty_body = match &self.body {
12727 JsonArrayBody::Values {
12728 items, null_clause, ..
12729 } => {
12730 render_comma_separated(items, ctx, f)?;
12731 render_json_null_clause(null_clause, f)?;
12732 items.is_empty() && null_clause.is_none()
12733 }
12734 JsonArrayBody::Query { query, format, .. } => {
12735 query.render(ctx, f)?;
12736 if let Some(format) = format {
12737 f.write_str(" ")?;
12738 format.render(ctx, f)?;
12739 }
12740 false
12741 }
12742 };
12743 if let Some(returning) = &self.returning {
12744 if !empty_body {
12745 f.write_str(" ")?;
12746 }
12747 returning.render(ctx, f)?;
12748 }
12749 f.write_str(")")
12750 }
12751}
12752
12753impl<X: Extension + Render> Render for JsonAggregateExpr<X> {
12754 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12755 match &self.body {
12756 JsonAggregateBody::Object {
12757 entry, unique_keys, ..
12758 } => {
12759 f.write_str("JSON_OBJECTAGG(")?;
12760 entry.render(ctx, f)?;
12761 render_json_null_clause(&self.null_clause, f)?;
12762 render_json_unique(*unique_keys, f)?;
12763 }
12764 JsonAggregateBody::Array {
12765 value, order_by, ..
12766 } => {
12767 f.write_str("JSON_ARRAYAGG(")?;
12768 value.render(ctx, f)?;
12769 if !order_by.is_empty() {
12770 f.write_str(" ORDER BY ")?;
12771 render_comma_separated(order_by, ctx, f)?;
12772 }
12773 render_json_null_clause(&self.null_clause, f)?;
12774 }
12775 }
12776 if let Some(returning) = &self.returning {
12777 f.write_str(" ")?;
12778 returning.render(ctx, f)?;
12779 }
12780 f.write_str(")")?;
12781 if let Some(filter) = &self.filter {
12782 f.write_str(" FILTER (WHERE ")?;
12783 filter.render(ctx, f)?;
12784 f.write_str(")")?;
12785 }
12786 if let Some(over) = &self.over {
12787 f.write_str(" OVER ")?;
12788 over.render(ctx, f)?;
12789 }
12790 Ok(())
12791 }
12792}
12793
12794impl<X: Extension + Render> Render for JsonConstructorExpr<X> {
12795 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12796 f.write_str(match self.kind {
12797 JsonConstructorKind::Json => "JSON(",
12798 JsonConstructorKind::Scalar => "JSON_SCALAR(",
12799 JsonConstructorKind::Serialize => "JSON_SERIALIZE(",
12800 })?;
12801 self.value.render(ctx, f)?;
12802 render_json_unique(self.unique_keys, f)?;
12803 if let Some(returning) = &self.returning {
12804 f.write_str(" ")?;
12805 returning.render(ctx, f)?;
12806 }
12807 f.write_str(")")
12808 }
12809}
12810
12811impl<X: Extension + Render> Render for IsJsonExpr<X> {
12812 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12813 let full = ctx.mode() == RenderMode::Parenthesized;
12814 open_group(full, f)?;
12815 render_predicate_operand(
12816 &self.expr,
12817 ctx.target().binding_powers.predicate(),
12818 Side::Left,
12819 ctx,
12820 f,
12821 )?;
12822 f.write_str(if self.negated {
12823 " IS NOT JSON"
12824 } else {
12825 " IS JSON"
12826 })?;
12827 f.write_str(match self.item_type {
12828 JsonItemType::Any => "",
12829 JsonItemType::Value => " VALUE",
12830 JsonItemType::Array => " ARRAY",
12831 JsonItemType::Object => " OBJECT",
12832 JsonItemType::Scalar => " SCALAR",
12833 })?;
12834 if self.unique_keys {
12835 f.write_str(" WITH UNIQUE KEYS")?;
12836 }
12837 close_group(full, f)
12838 }
12839}
12840
12841impl Render for XmlDocumentOrContent {
12846 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12847 f.write_str(match self {
12848 XmlDocumentOrContent::Document => "DOCUMENT",
12849 XmlDocumentOrContent::Content => "CONTENT",
12850 })
12851 }
12852}
12853
12854impl<X: Extension + Render> Render for XmlAttribute<X> {
12855 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12857 self.value.render(ctx, f)?;
12858 if let Some(name) = &self.name {
12859 f.write_str(" AS ")?;
12860 name.render(ctx, f)?;
12861 }
12862 Ok(())
12863 }
12864}
12865
12866fn render_xml_passing_mechanism(
12868 mechanism: &Option<XmlPassingMechanism>,
12869 f: &mut fmt::Formatter<'_>,
12870) -> fmt::Result {
12871 match mechanism {
12872 Some(XmlPassingMechanism::ByRef) => f.write_str(" BY REF"),
12873 Some(XmlPassingMechanism::ByValue) => f.write_str(" BY VALUE"),
12874 None => Ok(()),
12875 }
12876}
12877
12878impl<X: Extension + Render> Render for XmlFunc<X> {
12879 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12880 match self {
12881 XmlFunc::Element {
12882 name,
12883 attributes,
12884 content,
12885 ..
12886 } => {
12887 f.write_str("xmlelement(NAME ")?;
12888 name.render(ctx, f)?;
12889 if !attributes.is_empty() {
12890 f.write_str(", xmlattributes(")?;
12891 render_comma_separated(attributes, ctx, f)?;
12892 f.write_str(")")?;
12893 }
12894 if !content.is_empty() {
12895 f.write_str(", ")?;
12896 render_comma_separated(content, ctx, f)?;
12897 }
12898 f.write_str(")")
12899 }
12900 XmlFunc::Forest { elements, .. } => {
12901 f.write_str("xmlforest(")?;
12902 render_comma_separated(elements, ctx, f)?;
12903 f.write_str(")")
12904 }
12905 XmlFunc::Concat { args, .. } => {
12906 f.write_str("xmlconcat(")?;
12907 render_comma_separated(args, ctx, f)?;
12908 f.write_str(")")
12909 }
12910 XmlFunc::Parse {
12911 option,
12912 arg,
12913 whitespace,
12914 ..
12915 } => {
12916 f.write_str("xmlparse(")?;
12917 option.render(ctx, f)?;
12918 f.write_str(" ")?;
12919 arg.render(ctx, f)?;
12920 match whitespace {
12921 XmlWhitespaceOption::Unspecified => {}
12922 XmlWhitespaceOption::Preserve => f.write_str(" PRESERVE WHITESPACE")?,
12923 XmlWhitespaceOption::Strip => f.write_str(" STRIP WHITESPACE")?,
12924 }
12925 f.write_str(")")
12926 }
12927 XmlFunc::Pi { name, content, .. } => {
12928 f.write_str("xmlpi(NAME ")?;
12929 name.render(ctx, f)?;
12930 if let Some(content) = content {
12931 f.write_str(", ")?;
12932 content.render(ctx, f)?;
12933 }
12934 f.write_str(")")
12935 }
12936 XmlFunc::Root {
12937 arg,
12938 version,
12939 standalone,
12940 ..
12941 } => {
12942 f.write_str("xmlroot(")?;
12943 arg.render(ctx, f)?;
12944 f.write_str(", VERSION ")?;
12945 match version {
12946 Some(expr) => expr.render(ctx, f)?,
12947 None => f.write_str("NO VALUE")?,
12948 }
12949 match standalone {
12950 XmlStandalone::Unspecified => {}
12951 XmlStandalone::Yes => f.write_str(", STANDALONE YES")?,
12952 XmlStandalone::No => f.write_str(", STANDALONE NO")?,
12953 XmlStandalone::NoValue => f.write_str(", STANDALONE NO VALUE")?,
12954 }
12955 f.write_str(")")
12956 }
12957 XmlFunc::Serialize {
12958 option,
12959 arg,
12960 data_type,
12961 indent,
12962 ..
12963 } => {
12964 f.write_str("xmlserialize(")?;
12965 option.render(ctx, f)?;
12966 f.write_str(" ")?;
12967 arg.render(ctx, f)?;
12968 f.write_str(" AS ")?;
12969 data_type.render(ctx, f)?;
12970 match indent {
12971 XmlIndentOption::Unspecified => {}
12972 XmlIndentOption::Indent => f.write_str(" INDENT")?,
12973 XmlIndentOption::NoIndent => f.write_str(" NO INDENT")?,
12974 }
12975 f.write_str(")")
12976 }
12977 XmlFunc::Exists {
12978 path,
12979 mechanism_before,
12980 arg,
12981 mechanism_after,
12982 ..
12983 } => {
12984 f.write_str("xmlexists(")?;
12985 path.render(ctx, f)?;
12986 f.write_str(" PASSING")?;
12987 render_xml_passing_mechanism(mechanism_before, f)?;
12988 f.write_str(" ")?;
12989 arg.render(ctx, f)?;
12990 render_xml_passing_mechanism(mechanism_after, f)?;
12991 f.write_str(")")
12992 }
12993 }
12994 }
12995}
12996
12997impl<X: Extension + Render> Render for StringFunc<X> {
12998 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12999 match self {
13000 StringFunc::Substring {
13004 expr, start, count, ..
13005 } => {
13006 f.write_str("SUBSTRING(")?;
13007 expr.render(ctx, f)?;
13008 if let Some(start) = start {
13009 f.write_str(" FROM ")?;
13010 start.render(ctx, f)?;
13011 }
13012 if let Some(count) = count {
13013 f.write_str(" FOR ")?;
13014 count.render(ctx, f)?;
13015 }
13016 f.write_str(")")
13017 }
13018 StringFunc::SubstringSimilar {
13019 expr,
13020 pattern,
13021 escape,
13022 ..
13023 } => {
13024 f.write_str("SUBSTRING(")?;
13025 expr.render(ctx, f)?;
13026 f.write_str(" SIMILAR ")?;
13027 pattern.render(ctx, f)?;
13028 f.write_str(" ESCAPE ")?;
13029 escape.render(ctx, f)?;
13030 f.write_str(")")
13031 }
13032 StringFunc::Position { substr, string, .. } => {
13033 f.write_str("POSITION(")?;
13034 substr.render(ctx, f)?;
13035 f.write_str(" IN ")?;
13036 string.render(ctx, f)?;
13037 f.write_str(")")
13038 }
13039 StringFunc::Overlay {
13040 target,
13041 replacement,
13042 start,
13043 count,
13044 ..
13045 } => {
13046 f.write_str("OVERLAY(")?;
13047 target.render(ctx, f)?;
13048 f.write_str(" PLACING ")?;
13049 replacement.render(ctx, f)?;
13050 f.write_str(" FROM ")?;
13051 start.render(ctx, f)?;
13052 if let Some(count) = count {
13053 f.write_str(" FOR ")?;
13054 count.render(ctx, f)?;
13055 }
13056 f.write_str(")")
13057 }
13058 StringFunc::Trim {
13059 side,
13060 trim_chars,
13061 from,
13062 sources,
13063 ..
13064 } => {
13065 f.write_str("TRIM(")?;
13066 if let Some(side) = side {
13067 side.render(ctx, f)?;
13068 f.write_str(" ")?;
13069 }
13070 if let Some(trim_chars) = trim_chars {
13071 trim_chars.render(ctx, f)?;
13072 f.write_str(" ")?;
13073 }
13074 if *from {
13075 f.write_str("FROM ")?;
13076 }
13077 render_comma_separated(sources, ctx, f)?;
13078 f.write_str(")")
13079 }
13080 StringFunc::CollationFor { expr, .. } => {
13081 f.write_str("COLLATION FOR (")?;
13082 expr.render(ctx, f)?;
13083 f.write_str(")")
13084 }
13085 StringFunc::ConvertUsing { expr, charset, .. } => {
13086 f.write_str("CONVERT(")?;
13087 expr.render(ctx, f)?;
13088 f.write_str(" USING ")?;
13089 charset.render(ctx, f)?;
13090 f.write_str(")")
13091 }
13092 StringFunc::MatchAgainst {
13093 columns,
13094 against,
13095 modifier,
13096 ..
13097 } => {
13098 f.write_str("MATCH(")?;
13099 render_comma_separated(columns, ctx, f)?;
13100 f.write_str(") AGAINST(")?;
13101 against.render(ctx, f)?;
13102 if let Some(modifier) = modifier {
13103 f.write_str(" ")?;
13104 modifier.render(ctx, f)?;
13105 }
13106 f.write_str(")")
13107 }
13108 StringFunc::CeilTo {
13109 expr,
13110 field,
13111 spelling,
13112 ..
13113 } => {
13114 f.write_str(match spelling {
13115 CeilSpelling::Ceil => "CEIL(",
13116 CeilSpelling::Ceiling => "CEILING(",
13117 })?;
13118 expr.render(ctx, f)?;
13119 f.write_str(" TO ")?;
13120 field.render(ctx, f)?;
13121 f.write_str(")")
13122 }
13123 StringFunc::FloorTo { expr, field, .. } => {
13124 f.write_str("FLOOR(")?;
13125 expr.render(ctx, f)?;
13126 f.write_str(" TO ")?;
13127 field.render(ctx, f)?;
13128 f.write_str(")")
13129 }
13130 }
13131 }
13132}
13133
13134impl Render for MatchSearchModifier {
13135 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13136 f.write_str(match self {
13137 MatchSearchModifier::NaturalLanguage => "IN NATURAL LANGUAGE MODE",
13138 MatchSearchModifier::NaturalLanguageQueryExpansion => {
13139 "IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION"
13140 }
13141 MatchSearchModifier::Boolean => "IN BOOLEAN MODE",
13142 MatchSearchModifier::QueryExpansion => "WITH QUERY EXPANSION",
13143 })
13144 }
13145}
13146
13147impl Render for TrimSide {
13148 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13149 f.write_str(match self {
13150 TrimSide::Both => "BOTH",
13151 TrimSide::Leading => "LEADING",
13152 TrimSide::Trailing => "TRAILING",
13153 })
13154 }
13155}
13156
13157impl<X: Extension + Render> Render for CaseExpr<X> {
13158 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13159 f.write_str("CASE")?;
13160 if let Some(operand) = &self.operand {
13161 f.write_str(" ")?;
13162 operand.render(ctx, f)?;
13163 }
13164 for clause in &self.when_clauses {
13165 f.write_str(" WHEN ")?;
13166 clause.condition.render(ctx, f)?;
13167 f.write_str(" THEN ")?;
13168 clause.result.render(ctx, f)?;
13169 }
13170 if let Some(else_result) = &self.else_result {
13171 f.write_str(" ELSE ")?;
13172 else_result.render(ctx, f)?;
13173 }
13174 f.write_str(" END")
13175 }
13176}
13177
13178impl<X: Extension + Render> Render for FunctionCall<X> {
13179 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13180 self.name.render(ctx, f)?;
13181 f.write_str("(")?;
13182 if let Some(quantifier) = &self.quantifier {
13183 quantifier.render(ctx, f)?;
13184 f.write_str(" ")?;
13185 }
13186 if self.wildcard {
13187 f.write_str("*")?;
13188 } else {
13189 render_comma_separated(&self.args, ctx, f)?;
13190 }
13191 if !self.order_by.is_empty() {
13192 if self.wildcard || !self.args.is_empty() {
13197 f.write_str(" ")?;
13198 }
13199 f.write_str("ORDER BY ")?;
13200 render_comma_separated(&self.order_by, ctx, f)?;
13201 }
13202 if let Some(separator) = &self.separator {
13205 f.write_str(" SEPARATOR ")?;
13206 separator.render(ctx, f)?;
13207 }
13208 if let Some(null_treatment) = &self.null_treatment {
13212 f.write_str(" ")?;
13213 null_treatment.render(ctx, f)?;
13214 }
13215 f.write_str(")")?;
13216 if let Some(tail) = &self.window_tail {
13220 if let Some(from_first_last) = tail.from_first_last {
13221 f.write_str(match from_first_last {
13222 FromFirstLast::First => " FROM FIRST",
13223 FromFirstLast::Last => " FROM LAST",
13224 })?;
13225 }
13226 if let Some(null_treatment) = &tail.null_treatment {
13227 f.write_str(" ")?;
13228 null_treatment.render(ctx, f)?;
13229 }
13230 }
13231 if let Some(within_group) = &self.within_group {
13234 f.write_str(" WITHIN GROUP (ORDER BY ")?;
13235 render_comma_separated(within_group, ctx, f)?;
13236 f.write_str(")")?;
13237 }
13238 if let Some(filter) = &self.filter {
13239 match self.filter_where {
13242 FilterWhereSpelling::Where => f.write_str(" FILTER (WHERE ")?,
13243 FilterWhereSpelling::Omitted => f.write_str(" FILTER (")?,
13244 }
13245 filter.render(ctx, f)?;
13246 f.write_str(")")?;
13247 }
13248 if let Some(over) = &self.over {
13249 f.write_str(" OVER ")?;
13250 over.render(ctx, f)?;
13251 }
13252 Ok(())
13253 }
13254}
13255
13256impl<X: Extension + Render> Render for FunctionArg<X> {
13257 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13258 if self.variadic {
13262 f.write_str("VARIADIC ")?;
13263 }
13264 if let Some(name) = self.name {
13268 if ctx.mode() == RenderMode::Redacted {
13269 f.write_str("id")?;
13270 } else {
13271 f.write_str(ctx.resolve(name))?;
13272 }
13273 f.write_str(match self.syntax {
13274 ArgSyntax::ColonEquals => " := ",
13275 ArgSyntax::Arrow | ArgSyntax::Positional => " => ",
13278 })?;
13279 }
13280 self.value.render(ctx, f)
13281 }
13282}
13283
13284impl<X: Extension + Render> Render for StructField<X> {
13285 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13286 if ctx.mode() == RenderMode::Redacted {
13291 f.write_str("id")?;
13292 } else {
13293 let text = ctx.resolve(self.key);
13294 match self.key_spelling {
13295 StructKeySpelling::Bare => f.write_str(text)?,
13296 StructKeySpelling::SingleQuoted => {
13297 if text.contains('\'') {
13298 write!(f, "'{}'", text.replace('\'', "''"))?;
13299 } else {
13300 write!(f, "'{text}'")?;
13301 }
13302 }
13303 StructKeySpelling::DoubleQuoted => {
13304 if text.contains('"') {
13305 write!(f, "\"{}\"", text.replace('"', "\"\""))?;
13306 } else {
13307 write!(f, "\"{text}\"")?;
13308 }
13309 }
13310 }
13311 }
13312 f.write_str(": ")?;
13313 self.value.render(ctx, f)
13314 }
13315}
13316
13317impl<X: Extension + Render> Render for StructConstructorField<X> {
13318 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13319 if let Some(name) = &self.name {
13320 name.render(ctx, f)?;
13321 f.write_str(" ")?;
13322 }
13323 self.ty.render(ctx, f)
13324 }
13325}
13326
13327impl<X: Extension + Render> Render for StructConstructorArg<X> {
13328 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13329 self.value.render(ctx, f)?;
13330 if let Some(alias) = &self.alias {
13331 f.write_str(" AS ")?;
13332 alias.render(ctx, f)?;
13333 }
13334 Ok(())
13335 }
13336}
13337
13338impl<X: Extension + Render> Render for WindowSpec<X> {
13339 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13340 match self {
13341 WindowSpec::Named { name, .. } => name.render(ctx, f),
13342 WindowSpec::Inline { definition, .. } => {
13343 f.write_str("(")?;
13344 definition.render(ctx, f)?;
13345 f.write_str(")")
13346 }
13347 }
13348 }
13349}
13350
13351impl<X: Extension + Render> Render for WindowDefinition<X> {
13352 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13353 let mut wrote = false;
13354 if let Some(existing) = &self.existing {
13355 existing.render(ctx, f)?;
13356 wrote = true;
13357 }
13358 if !self.partition_by.is_empty() {
13359 if wrote {
13360 f.write_str(" ")?;
13361 }
13362 f.write_str("PARTITION BY ")?;
13363 render_comma_separated(&self.partition_by, ctx, f)?;
13364 wrote = true;
13365 }
13366 if !self.order_by.is_empty() {
13367 if wrote {
13368 f.write_str(" ")?;
13369 }
13370 f.write_str("ORDER BY ")?;
13371 render_comma_separated(&self.order_by, ctx, f)?;
13372 wrote = true;
13373 }
13374 if let Some(frame) = &self.frame {
13375 if wrote {
13376 f.write_str(" ")?;
13377 }
13378 frame.render(ctx, f)?;
13379 }
13380 Ok(())
13381 }
13382}
13383
13384impl<X: Extension + Render> Render for WindowFrame<X> {
13385 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13386 self.units.render(ctx, f)?;
13387 f.write_str(" ")?;
13388 if let Some(end) = &self.end {
13389 f.write_str("BETWEEN ")?;
13390 self.start.render(ctx, f)?;
13391 f.write_str(" AND ")?;
13392 end.render(ctx, f)?;
13393 } else {
13394 self.start.render(ctx, f)?;
13395 }
13396 if let Some(exclusion) = &self.exclusion {
13397 f.write_str(" EXCLUDE ")?;
13398 exclusion.render(ctx, f)?;
13399 }
13400 Ok(())
13401 }
13402}
13403
13404impl Render for WindowFrameUnits {
13405 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13406 f.write_str(match self {
13407 WindowFrameUnits::Rows => "ROWS",
13408 WindowFrameUnits::Range => "RANGE",
13409 WindowFrameUnits::Groups => "GROUPS",
13410 })
13411 }
13412}
13413
13414impl<X: Extension + Render> Render for WindowFrameBound<X> {
13415 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13416 match self {
13417 WindowFrameBound::CurrentRow { .. } => f.write_str("CURRENT ROW"),
13418 WindowFrameBound::UnboundedPreceding { .. } => f.write_str("UNBOUNDED PRECEDING"),
13419 WindowFrameBound::UnboundedFollowing { .. } => f.write_str("UNBOUNDED FOLLOWING"),
13420 WindowFrameBound::Preceding { offset, .. } => {
13421 offset.render(ctx, f)?;
13422 f.write_str(" PRECEDING")
13423 }
13424 WindowFrameBound::Following { offset, .. } => {
13425 offset.render(ctx, f)?;
13426 f.write_str(" FOLLOWING")
13427 }
13428 }
13429 }
13430}
13431
13432impl Render for WindowFrameExclusion {
13433 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13434 f.write_str(match self {
13435 WindowFrameExclusion::CurrentRow => "CURRENT ROW",
13436 WindowFrameExclusion::Group => "GROUP",
13437 WindowFrameExclusion::Ties => "TIES",
13438 WindowFrameExclusion::NoOthers => "NO OTHERS",
13439 })
13440 }
13441}
13442
13443impl<X: Extension + Render> Render for NamedWindow<X> {
13444 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13445 self.name.render(ctx, f)?;
13446 f.write_str(" AS (")?;
13447 self.definition.render(ctx, f)?;
13448 f.write_str(")")
13449 }
13450}
13451
13452impl<X: Extension + Render> Render for OrderByExpr<X> {
13453 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13454 self.expr.render(ctx, f)?;
13455 if let Some(using) = &self.using {
13459 f.write_str(" USING ")?;
13460 using.render(ctx, f)?;
13461 }
13462 render_sort_direction(self.asc, self.nulls_first, f)
13463 }
13464}
13465
13466impl Render for OrderByUsing {
13467 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13468 let Some(schema) = &self.schema else {
13473 return f.write_str(ctx.resolve(self.op));
13474 };
13475 f.write_str("OPERATOR(")?;
13476 for part in &schema.0 {
13477 part.render(ctx, f)?;
13478 f.write_str(".")?;
13479 }
13480 f.write_str(ctx.resolve(self.op))?;
13481 f.write_str(")")
13482 }
13483}
13484
13485impl Render for OrderByAll {
13486 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13487 f.write_str("ALL")?;
13488 render_sort_direction(self.asc, self.nulls_first, f)
13489 }
13490}
13491
13492impl<X: Extension + Render> Render for Limit<X> {
13493 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13494 match self.syntax {
13495 LimitSyntax::CommaOffset if honours_source_spelling(ctx) => {
13499 f.write_str("LIMIT ")?;
13500 if let Some(offset) = &self.offset {
13501 offset.render(ctx, f)?;
13502 }
13503 f.write_str(", ")?;
13504 if let Some(limit) = &self.limit {
13505 limit.render(ctx, f)?;
13506 }
13507 Ok(())
13508 }
13509 LimitSyntax::LimitOffset | LimitSyntax::CommaOffset => {
13510 let mut wrote = false;
13511 if let Some(limit) = &self.limit {
13512 f.write_str("LIMIT ")?;
13513 match self.percent {
13524 Some(marker) => {
13525 render_pg_operand(
13526 limit,
13527 ctx.target().binding_powers.multiplicative,
13528 Side::Right,
13529 ctx,
13530 f,
13531 )?;
13532 f.write_str(match marker {
13533 LimitPercent::Symbol => "%",
13534 LimitPercent::Keyword => " PERCENT",
13535 })?;
13536 }
13537 None => limit.render(ctx, f)?,
13538 }
13539 wrote = true;
13540 }
13541 if let Some(offset) = &self.offset {
13542 if wrote {
13543 f.write_str(" ")?;
13544 }
13545 f.write_str("OFFSET ")?;
13546 offset.render(ctx, f)?;
13547 }
13548 Ok(())
13549 }
13550 LimitSyntax::FetchFirst => {
13551 let fidelity = honours_source_spelling(ctx);
13557 let mut wrote = false;
13558 if let Some(offset) = &self.offset {
13559 f.write_str("OFFSET ")?;
13560 offset.render(ctx, f)?;
13561 f.write_str(" ROWS")?;
13562 wrote = true;
13563 }
13564 if let Some(with_ties) = self.with_ties {
13569 if wrote {
13570 f.write_str(" ")?;
13571 }
13572 let spelling = if fidelity {
13573 self.fetch_spelling
13574 } else {
13575 FetchSpelling::FirstRows
13576 };
13577 f.write_str(spelling.fetch_keyword())?;
13578 if let Some(limit) = &self.limit {
13579 f.write_str(" ")?;
13580 limit.render(ctx, f)?;
13581 }
13582 f.write_str(spelling.row_word())?;
13583 f.write_str(if with_ties { "WITH TIES" } else { "ONLY" })?;
13584 }
13585 Ok(())
13586 }
13587 }
13588 }
13589}
13590
13591impl<X: Extension + Render> Render for LimitBy<X> {
13592 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13593 f.write_str("LIMIT ")?;
13594 self.limit.render(ctx, f)?;
13595 if let Some(offset) = &self.offset {
13596 f.write_str(" OFFSET ")?;
13597 offset.render(ctx, f)?;
13598 }
13599 f.write_str(" BY ")?;
13600 render_comma_separated(&self.by, ctx, f)
13601 }
13602}
13603
13604impl<X: Extension + Render> Render for Setting<X> {
13605 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13606 self.name.render(ctx, f)?;
13607 f.write_str(" = ")?;
13608 self.value.render(ctx, f)
13609 }
13610}
13611
13612impl Render for FormatClause {
13613 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13614 f.write_str("FORMAT ")?;
13615 self.name.render(ctx, f)
13616 }
13617}
13618
13619impl Render for ForClause {
13620 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13624 match self {
13625 ForClause::Xml {
13626 mode,
13627 elements,
13628 binary_base64,
13629 typed,
13630 root,
13631 ..
13632 } => {
13633 f.write_str("FOR XML ")?;
13634 mode.render(ctx, f)?;
13635 if *binary_base64 {
13636 f.write_str(", BINARY BASE64")?;
13637 }
13638 if *typed {
13639 f.write_str(", TYPE")?;
13640 }
13641 if let Some(root) = root {
13642 f.write_str(", ")?;
13643 root.render(ctx, f)?;
13644 }
13645 if let Some(elements) = elements {
13646 f.write_str(", ")?;
13647 elements.render(ctx, f)?;
13648 }
13649 Ok(())
13650 }
13651 ForClause::Json {
13652 mode,
13653 root,
13654 include_null_values,
13655 without_array_wrapper,
13656 ..
13657 } => {
13658 f.write_str("FOR JSON ")?;
13659 mode.render(ctx, f)?;
13660 if let Some(root) = root {
13661 f.write_str(", ")?;
13662 root.render(ctx, f)?;
13663 }
13664 if *include_null_values {
13665 f.write_str(", INCLUDE_NULL_VALUES")?;
13666 }
13667 if *without_array_wrapper {
13668 f.write_str(", WITHOUT_ARRAY_WRAPPER")?;
13669 }
13670 Ok(())
13671 }
13672 }
13673 }
13674}
13675
13676impl Render for ForXmlMode {
13677 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13678 match self {
13679 ForXmlMode::Raw { name, .. } => {
13680 f.write_str("RAW")?;
13681 render_optional_for_name(name.as_ref(), ctx, f)
13682 }
13683 ForXmlMode::Auto { .. } => f.write_str("AUTO"),
13684 ForXmlMode::Explicit { .. } => f.write_str("EXPLICIT"),
13685 ForXmlMode::Path { name, .. } => {
13686 f.write_str("PATH")?;
13687 render_optional_for_name(name.as_ref(), ctx, f)
13688 }
13689 }
13690 }
13691}
13692
13693impl Render for ForXmlElements {
13694 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13695 f.write_str(match self {
13696 ForXmlElements::Plain => "ELEMENTS",
13697 ForXmlElements::XsiNil => "ELEMENTS XSINIL",
13698 ForXmlElements::Absent => "ELEMENTS ABSENT",
13699 })
13700 }
13701}
13702
13703impl Render for ForJsonMode {
13704 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13705 f.write_str(match self {
13706 ForJsonMode::Auto => "AUTO",
13707 ForJsonMode::Path => "PATH",
13708 })
13709 }
13710}
13711
13712impl Render for ForRoot {
13713 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13714 f.write_str("ROOT")?;
13715 render_optional_for_name(self.name.as_ref(), ctx, f)
13716 }
13717}
13718
13719fn render_optional_for_name(
13722 name: Option<&Literal>,
13723 ctx: &RenderCtx<'_>,
13724 f: &mut fmt::Formatter<'_>,
13725) -> fmt::Result {
13726 if let Some(name) = name {
13727 f.write_str("(")?;
13728 name.render(ctx, f)?;
13729 f.write_str(")")?;
13730 }
13731 Ok(())
13732}