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, ColocationPartitionKind,
33 ColumnConstraint, ColumnDef, ColumnOption, ColumnsSpelling, CommentOnStatement, CommentTarget,
34 CompoundStatement, ComprehensionSource, ConditionInfoItem, ConditionInfoItemName,
35 ConditionValue, ConditionalBranch, ConfigParameter, ConflictAction, ConflictResolution,
36 ConflictTarget, ConstraintCharacteristics, ConstraintCheckTime, ConstraintsTarget,
37 CopyDirection, CopyIntoSource, CopyIntoStatement, CopyIntoTarget, CopyOption, CopyOptionValue,
38 CopySource, CopyStatement, CopyTarget, CreateColocationGroup, CreateDatabase, CreateEvent,
39 CreateExtension, CreateExtensionOption, CreateFunction, CreateIndex, CreateLogfileGroup,
40 CreateMacro, CreateProcedure, CreateResourceGroup, CreateSchema, CreateSecret, CreateSequence,
41 CreateServer, 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, DropColocationGroup,
49 DropDatabase, DropEvent, DropIndexOnTable, DropLogfileGroup, DropObjectKind, DropResourceGroup,
50 DropSecretStmt, DropServer, DropSpatialReferenceSystem, DropStatement, DropTablespace,
51 DropTransform, 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, InsertModifier,
67 InsertOverriding, InsertSource, InsertTarget, InsertValue, InsertValues, InsertVerb,
68 InstallComponentSetElement, InstallComponentSetScope, InstallComponentSetValue,
69 InstallStatement, InstanceLockStatement, IntWidth, IntegerDivideSpelling, IntegerTypeName,
70 IntervalFields, IntoTarget, IoThreadKeyword, IsDistinctFromSpelling, IsJsonExpr,
71 IsNotDistinctFromSpelling, IsolationLevel, IterateStatement, Join, JoinConstraint,
72 JoinOperator, JsonAggregateBody, JsonAggregateExpr, JsonArrayBody, JsonArrayExpr, JsonBehavior,
73 JsonBehaviorKind, JsonConstructorExpr, JsonConstructorKind, JsonEncoding, JsonFormat,
74 JsonFuncExpr, JsonFuncKind, JsonItemType, JsonKeyValue, JsonKeyValueSpelling, JsonNullClause,
75 JsonObjectExpr, JsonPassingArg, JsonQuotesBehavior, JsonReturning, JsonTable, JsonTableColumn,
76 JsonValueExpr, JsonWrapperBehavior, KeyCacheName, KillStatement, KillTarget,
77 LambdaParamSpelling, LanguageName, LateralView, LeaveStatement, LikeSpelling, Limit, LimitBy,
78 LimitPercent, LimitSyntax, Literal, LiteralKind, LoadDataConcurrency, LoadDataDuplicate,
79 LoadDataEnclosed, LoadDataFieldOrVar, LoadDataFields, LoadDataFormat, LoadDataIgnoreRows,
80 LoadDataIgnoreUnit, LoadDataLines, LoadDataStatement, LoadFieldsSpelling, LoadIndexStatement,
81 LoadIndexTable, LoadIndexTargets, LoadStatement, LoadTarget, LockStrength, LockTablesStatement,
82 LockWait, 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, RefreshMaterializedView, RegexpSpelling,
95 ReindexStatement, RelationInheritance, RenameStatement, RepairTableOption, RepeatStatement,
96 RepetitionQuantifier, ReplicaSpelling, ReplicaThreadOption, ReplicaUntilCondition,
97 ReplicationFilterRule, ReplicationStatement, RequirePrimaryKeyCheck, ResourceGroupState,
98 ResourceGroupThreadPriority, ResourceGroupType, ResourceGroupVcpu, ResourceLimit,
99 ReturnStatement, Returning, RewriteDbPair, RoleSpec, RollupSpelling, RoutineKind,
100 RoutineObjectKind, RoutineSignature, RowsFromItem, RowsPerMatch, SampleClause, SampleUnit,
101 SchemaObjectKind, SchemaRelocationObject, SecretOption, SecretPersistence, Select,
102 SelectDistinct, SelectItem, SelectSpelling, SemiAntiSide, SemiStructuredAccessExpr,
103 SemiStructuredPathSegment, ServerOption, ServerOptionKind, SessionStatement,
104 SessionVariableKind, SetAssignment, SetCharacterSetValue, SetExpr, SetNamesValue, SetOperator,
105 SetParameterValue, SetQuantifier, SetScope, SetValue, SetVariableAssignment,
106 SetVariableKeyword, SetVariableValue, Setting, ShowBare, ShowColumnsSpelling, ShowCreateKind,
107 ShowDiagnosticKind, ShowEngineArtifact, ShowFilter, ShowFrom, ShowFromKeyword,
108 ShowFunctionsFilter, ShowFunctionsScope, ShowIndexSpelling, ShowLimit, ShowListing,
109 ShowProfileType, ShowRef, ShowRefKind, ShowRefTarget, ShowRoutineKind, ShowScope,
110 ShowStatement, ShowTarget, SignalItem, SignalItemName, SignalStatement, Signedness,
111 SizeLiteral, SizeUnit, SpecialFunctionKeyword, SpecialSetValue, SqlDataAccess,
112 SqlSecurityContext, SrsAttribute, Statement, StatementInfoItem, StatementInfoItemName,
113 StringFunc, StructConstructorArg, StructConstructorField, StructField, StructKeySpelling,
114 StructTypeField, StructTypeSpelling, SubscriptKind, SubsetDefinition, SymbolDefinition,
115 SystemVariableScope, SystemVariableScopeKind, TableAlias, TableConstraint, TableConstraintDef,
116 TableElement, TableFactor, TableFunctionColumn, TableHint, TableKeyword, TableLikeAction,
117 TableLikeFeature, TableLikeOption, TableLock, TableLockKind, TableMaintenanceKind,
118 TableMaintenanceStatement, TableOption, TableOptionValue, TableRename, TableSample,
119 TableStorageParameter, TableVersion, TableWithJoins, TablespaceOption, TablespaceSizeOption,
120 TemporaryTableKind, TextTypeName, TimeTypeName, TimeZone, TimestampTypeName, TlsOption,
121 TlsRequirement, TransactionAccessMode, TransactionBlockKeyword, TransactionCommitKeyword,
122 TransactionMode, TransactionModeKind, TransactionRollbackKeyword, TransactionStart,
123 TransactionStatement, TriggerEvent, TriggerOrder, TriggerTiming, TrimSide, TruthValue,
124 UnaryOperator, UndoTablespaceState, UninstallStatement, UnlockTablesStatement, Unpivot,
125 UnpivotColumn, UnpivotSpelling, Update, UpdateAssignment, UpdateExtensionsStatement,
126 UpdateTupleSource, UpdateValue, Upsert, UseStatement, UserAttribute, UserRename, UserRoleList,
127 UserRoleListKind, UserSpec, VacuumAnalyze, VacuumStatement, Values, ValuesItem, VcpuRange,
128 ViewAlgorithm, ViewCheckOption, ViewOptions, WhileStatement, WildcardOptions, WildcardRename,
129 WildcardReplace, WindowDefinition, WindowFrame, WindowFrameBound, WindowFrameExclusion,
130 WindowFrameUnits, WindowSpec, With, WithRoleSpec, WrappedTypeKind, XaAssociation,
131 XaStartKeyword, XaStatement, XaSuspend, Xid, XmlAttribute, XmlDocumentOrContent, XmlFunc,
132 XmlIndentOption, XmlNamespace, XmlPassingMechanism, XmlStandalone, XmlTable, XmlTableColumn,
133 XmlWhitespaceOption,
134};
135use crate::dialect::TargetSpelling;
136use crate::precedence::{
137 BindingPower, BindingPowerTable, SetOperationBindingPowerTable, Side, UNPARENTHESIZED_IN_LIST,
138 needs_parens_between,
139};
140use std::fmt;
141use thin_vec::ThinVec;
142
143#[cfg(test)]
172use crate::generated::render_skeleton as skeleton;
173#[cfg(test)]
174const _: skeleton::RenderShapeFingerprint<0x0bc66b9b4759b4e4> = skeleton::CURRENT_RENDER_SHAPE_DCL;
175#[cfg(test)]
176const _: skeleton::RenderShapeFingerprint<0xb7fb9938befad896> = skeleton::CURRENT_RENDER_SHAPE_DDL;
177#[cfg(test)]
178const _: skeleton::RenderShapeFingerprint<0x5bdcbbc8cc864aec> = skeleton::CURRENT_RENDER_SHAPE_DML;
179#[cfg(test)]
180const _: skeleton::RenderShapeFingerprint<0xde8cec2513ed42e5> = skeleton::CURRENT_RENDER_SHAPE_EXPR;
181#[cfg(test)]
182const _: skeleton::RenderShapeFingerprint<0xffd1225e92e4dab2> = skeleton::CURRENT_RENDER_SHAPE_EXT;
183#[cfg(test)]
184const _: skeleton::RenderShapeFingerprint<0xbc5427055a4e813c> =
185 skeleton::CURRENT_RENDER_SHAPE_IDENT;
186#[cfg(test)]
187const _: skeleton::RenderShapeFingerprint<0x509ea17dec9af986> =
188 skeleton::CURRENT_RENDER_SHAPE_LITERAL;
189#[cfg(test)]
190const _: skeleton::RenderShapeFingerprint<0x8b1ed704455adf27> =
191 skeleton::CURRENT_RENDER_SHAPE_MATCH_RECOGNIZE;
192#[cfg(test)]
193const _: skeleton::RenderShapeFingerprint<0x5ebfaa9fb0c1caf9> =
194 skeleton::CURRENT_RENDER_SHAPE_PIPE_OPS;
195#[cfg(test)]
196const _: skeleton::RenderShapeFingerprint<0xd3444362d3f03fe8> =
197 skeleton::CURRENT_RENDER_SHAPE_PIVOT;
198#[cfg(test)]
199const _: skeleton::RenderShapeFingerprint<0xe6cc8d2df67c101c> =
200 skeleton::CURRENT_RENDER_SHAPE_QUERY;
201#[cfg(test)]
202const _: skeleton::RenderShapeFingerprint<0x957db431c4a1db51> = skeleton::CURRENT_RENDER_SHAPE_STMT;
203#[cfg(test)]
204const _: skeleton::RenderShapeFingerprint<0xfb50d22f049b4cc7> =
205 skeleton::CURRENT_RENDER_SHAPE_STORED_PROGRAM;
206#[cfg(test)]
207const _: skeleton::RenderShapeFingerprint<0x1a58662f47080916> = skeleton::CURRENT_RENDER_SHAPE_TCL;
208#[cfg(test)]
209const _: skeleton::RenderShapeFingerprint<0x03efd7c0644eb26a> = skeleton::CURRENT_RENDER_SHAPE_TY;
210#[cfg(test)]
211const _: skeleton::RenderShapeFingerprint<0x30c6b7a3fb94d049> = skeleton::CURRENT_RENDER_SHAPE_UTIL;
212#[cfg(test)]
213const _: skeleton::RenderShapeFingerprint<0x585b3bd313272236> =
214 skeleton::CURRENT_RENDER_SHAPE_WINDOW;
215
216impl Render for NoExt {
221 fn render(&self, _ctx: &RenderCtx<'_>, _f: &mut fmt::Formatter<'_>) -> fmt::Result {
222 match *self {}
224 }
225}
226
227impl Render for Ident {
228 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
229 if ctx.mode() == RenderMode::Redacted {
237 return f.write_str("id");
238 }
239 let text = ctx.resolve(self.sym);
240 let (open, close, doubled) = match self.quote {
244 QuoteStyle::None => return f.write_str(text),
245 QuoteStyle::UnicodeDouble => {
252 if honours_source_spelling(ctx) {
253 if let Some(src) = ctx.slice(self.meta.span) {
254 return f.write_str(src);
255 }
256 }
257 ('"', '"', "\"\"")
258 }
259 QuoteStyle::Single => ('\'', '\'', "''"),
260 QuoteStyle::Double => ('"', '"', "\"\""),
261 QuoteStyle::Backtick => ('`', '`', "``"),
262 QuoteStyle::Bracket => ('[', ']', "]]"),
263 };
264 if text.contains(close) {
267 let escaped = text.replace(close, doubled);
268 write!(f, "{open}{escaped}{close}")
269 } else {
270 write!(f, "{open}{text}{close}")
271 }
272 }
273}
274
275impl Render for ObjectName {
276 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
277 for (i, part) in self.0.iter().enumerate() {
278 if i > 0 {
279 f.write_str(".")?;
280 }
281 part.render(ctx, f)?;
282 }
283 Ok(())
284 }
285}
286
287impl Render for Literal {
288 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
289 if ctx.mode() == RenderMode::Redacted {
290 return f.write_str("?");
291 }
292 if let Some(text) = ctx.slice(self.meta.span) {
293 return f.write_str(text);
295 }
296 match &self.kind {
301 LiteralKind::Null => f.write_str("NULL"),
302 LiteralKind::Boolean(true) => f.write_str("TRUE"),
303 LiteralKind::Boolean(false) => f.write_str("FALSE"),
304 LiteralKind::Integer | LiteralKind::Float | LiteralKind::Decimal => f.write_str("0"),
305 LiteralKind::String => f.write_str("''"),
306 LiteralKind::Date => f.write_str("DATE '1970-01-01'"),
307 LiteralKind::Time { time_zone } => {
308 f.write_str("TIME")?;
309 render_time_zone_suffix(*time_zone, f)?;
310 f.write_str(" '00:00:00'")
311 }
312 LiteralKind::Timestamp { time_zone } => {
313 f.write_str("TIMESTAMP")?;
314 render_time_zone_suffix(*time_zone, f)?;
315 f.write_str(" '1970-01-01 00:00:00'")
316 }
317 LiteralKind::Interval { fields, .. } => {
318 f.write_str("INTERVAL '0'")?;
319 match fields {
320 Some(fields) => f.write_str(interval_fields_suffix(*fields)),
321 None => Ok(()),
322 }
323 }
324 LiteralKind::BitString { radix } => f.write_str(match radix {
325 BitStringRadix::Binary => "B'0'",
326 BitStringRadix::Hex => "X'0'",
327 }),
328 LiteralKind::Money => f.write_str("$0"),
329 }
330 }
331}
332
333impl<X: Extension + Render> Render for DataType<X> {
334 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
335 let target = type_render_target(ctx);
336 match self {
337 DataType::Boolean { spelling, .. } => f.write_str(boolean_type_name(target, *spelling)),
338 DataType::TinyInt { display_width, .. } => render_sized(f, "TINYINT", *display_width),
339 DataType::SmallInt { display_width, .. } => render_sized(f, "SMALLINT", *display_width),
340 DataType::MediumInt { display_width, .. } => {
341 render_sized(f, "MEDIUMINT", *display_width)
342 }
343 DataType::Integer {
344 spelling,
345 display_width,
346 ..
347 } => render_sized(f, integer_type_name(target, *spelling), *display_width),
348 DataType::BigInt { display_width, .. } => render_sized(f, "BIGINT", *display_width),
349 DataType::Decimal {
350 spelling,
351 precision,
352 scale,
353 ..
354 } => {
355 render_precision_scale(f, decimal_type_name(target, *spelling), *precision, *scale)
356 }
357 DataType::Float { precision, .. } => render_sized(f, "FLOAT", *precision),
358 DataType::Real { .. } => f.write_str("REAL"),
359 DataType::Double { spelling, .. } => f.write_str(double_type_name(*spelling)),
360 DataType::Text {
361 spelling, charset, ..
362 } => {
363 f.write_str(text_type_name(target, *spelling))?;
364 render_optional_charset_annotation(ctx, target, charset.as_deref(), f)
365 }
366 DataType::Blob { spelling, .. } => f.write_str(blob_type_name(target, *spelling)),
367 DataType::Character {
368 spelling,
369 size,
370 charset,
371 ..
372 } => {
373 render_sized(f, character_type_name(target, *spelling), *size)?;
374 render_optional_charset_annotation(ctx, target, charset.as_deref(), f)
375 }
376 DataType::Binary { spelling, size, .. } => {
377 render_sized(f, binary_type_name(target, *spelling), *size)
378 }
379 DataType::Bit { varying, size, .. } => {
380 render_sized(f, if *varying { "BIT VARYING" } else { "BIT" }, *size)
381 }
382 DataType::Json { .. } => f.write_str("JSON"),
383 DataType::Uuid { .. } => f.write_str("UUID"),
384 DataType::Date { .. } => f.write_str("DATE"),
385 DataType::Time {
386 spelling,
387 precision,
388 time_zone,
389 ..
390 } => render_time_type(target, *spelling, *precision, *time_zone, f),
391 DataType::Timestamp {
392 spelling,
393 precision,
394 time_zone,
395 ..
396 } => render_timestamp_type(target, *spelling, *precision, *time_zone, f),
397 DataType::Interval {
398 fields, precision, ..
399 } => render_interval_type(*fields, *precision, f),
400 DataType::Enum {
401 values, charset, ..
402 } => {
403 render_value_list_type(ctx, "ENUM", values, f)?;
404 render_optional_charset_annotation(ctx, target, charset.as_deref(), f)
405 }
406 DataType::Set {
407 values, charset, ..
408 } => {
409 render_value_list_type(ctx, "SET", values, f)?;
410 render_optional_charset_annotation(ctx, target, charset.as_deref(), f)
411 }
412 DataType::NumericModifier {
413 element,
414 signedness,
415 zerofill,
416 ..
417 } => render_numeric_modifier_type(ctx, element.as_deref(), *signedness, *zerofill, f),
418 DataType::Array {
419 element,
420 size,
421 spelling,
422 ..
423 } => render_array_type(ctx, element, *size, *spelling, f),
424 DataType::Struct {
425 fields, spelling, ..
426 } => match spelling {
427 StructTypeSpelling::AngleBracket => {
428 render_composite_type_angle(ctx, "STRUCT", fields, f)
429 }
430 _ => render_composite_type(ctx, struct_type_keyword(*spelling), fields, f),
431 },
432 DataType::Union { members, .. } => render_composite_type(ctx, "UNION", members, f),
433 DataType::Map { key, value, .. } => {
434 f.write_str("MAP(")?;
435 key.render(ctx, f)?;
436 f.write_str(", ")?;
437 value.render(ctx, f)?;
438 f.write_str(")")
439 }
440 DataType::Wrapped { kind, inner, .. } => {
441 f.write_str(wrapped_type_keyword(*kind))?;
442 f.write_str("(")?;
443 inner.render(ctx, f)?;
444 f.write_str(")")
445 }
446 DataType::FixedString { length, .. } => write!(f, "FixedString({length})"),
449 DataType::DateTime64 {
452 precision,
453 timezone,
454 ..
455 } => {
456 write!(f, "DateTime64({precision}")?;
457 if let Some(timezone) = timezone {
458 f.write_str(", ")?;
459 timezone.render(ctx, f)?;
460 }
461 f.write_str(")")
462 }
463 DataType::Nested { fields, .. } => render_composite_type(ctx, "Nested", fields, f),
467 DataType::FixedWidthInt { signed, width, .. } => {
470 f.write_str(fixed_width_int_name(*signed, *width))
471 }
472 DataType::UserDefined {
473 name, modifiers, ..
474 } => {
475 name.render(ctx, f)?;
476 render_literal_modifiers(ctx, f, modifiers)
477 }
478 DataType::Liberal { words, args, .. } => {
483 for (index, word) in words.iter().enumerate() {
484 if index > 0 {
485 f.write_str(" ")?;
486 }
487 word.render(ctx, f)?;
488 }
489 render_numeric_modifiers(f, args)
490 }
491 DataType::Other { ext, .. } => ext.render(ctx, f),
494 }
495 }
496}
497
498impl<X: Extension + Render> Render for StructTypeField<X> {
499 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
500 self.name.render(ctx, f)?;
501 f.write_str(" ")?;
502 self.ty.render(ctx, f)
503 }
504}
505
506#[derive(Clone, Copy, Debug, PartialEq, Eq)]
515enum TypeRenderTarget {
516 PreserveSource,
517 Ansi,
518 Postgres,
519}
520
521fn type_render_target(ctx: &RenderCtx<'_>) -> TypeRenderTarget {
522 match ctx.spelling() {
526 RenderSpelling::PreserveSource => TypeRenderTarget::PreserveSource,
527 RenderSpelling::TargetDialect => match ctx.target().target_spelling {
528 TargetSpelling::Ansi => TypeRenderTarget::Ansi,
529 TargetSpelling::Postgres => TypeRenderTarget::Postgres,
530 },
531 }
532}
533
534fn boolean_type_name(target: TypeRenderTarget, spelling: BooleanTypeName) -> &'static str {
535 match target {
536 TypeRenderTarget::PreserveSource => match spelling {
537 BooleanTypeName::Boolean => "BOOLEAN",
538 BooleanTypeName::Bool => "BOOL",
539 },
540 TypeRenderTarget::Ansi => "BOOLEAN",
541 TypeRenderTarget::Postgres => "BOOLEAN",
542 }
543}
544
545fn integer_type_name(target: TypeRenderTarget, spelling: IntegerTypeName) -> &'static str {
546 match target {
547 TypeRenderTarget::PreserveSource => match spelling {
548 IntegerTypeName::Int => "INT",
549 IntegerTypeName::Integer => "INTEGER",
550 },
551 TypeRenderTarget::Ansi => "INTEGER",
552 TypeRenderTarget::Postgres => "INTEGER",
553 }
554}
555
556fn decimal_type_name(target: TypeRenderTarget, spelling: DecimalTypeName) -> &'static str {
557 match target {
558 TypeRenderTarget::PreserveSource => match spelling {
559 DecimalTypeName::Decimal => "DECIMAL",
560 DecimalTypeName::Dec => "DEC",
561 DecimalTypeName::Numeric => "NUMERIC",
562 },
563 TypeRenderTarget::Ansi => "DECIMAL",
564 TypeRenderTarget::Postgres => "NUMERIC",
565 }
566}
567
568fn double_type_name(spelling: DoubleTypeName) -> &'static str {
569 match spelling {
570 DoubleTypeName::DoublePrecision => "DOUBLE PRECISION",
571 DoubleTypeName::Double => "DOUBLE",
572 }
573}
574
575fn text_type_name(target: TypeRenderTarget, spelling: TextTypeName) -> &'static str {
576 match target {
577 TypeRenderTarget::PreserveSource => match spelling {
578 TextTypeName::Text => "TEXT",
579 TextTypeName::TinyText => "TINYTEXT",
580 TextTypeName::MediumText => "MEDIUMTEXT",
581 TextTypeName::LongText => "LONGTEXT",
582 },
583 TypeRenderTarget::Ansi | TypeRenderTarget::Postgres => "TEXT",
586 }
587}
588
589fn blob_type_name(target: TypeRenderTarget, spelling: BlobTypeName) -> &'static str {
590 match target {
591 TypeRenderTarget::PreserveSource => match spelling {
592 BlobTypeName::Blob => "BLOB",
593 BlobTypeName::TinyBlob => "TINYBLOB",
594 BlobTypeName::MediumBlob => "MEDIUMBLOB",
595 BlobTypeName::LongBlob => "LONGBLOB",
596 },
597 TypeRenderTarget::Ansi => "BLOB",
600 TypeRenderTarget::Postgres => "BYTEA",
601 }
602}
603
604fn character_type_name(target: TypeRenderTarget, spelling: CharacterTypeName) -> &'static str {
605 let varying = matches!(
608 spelling,
609 CharacterTypeName::CharVarying
610 | CharacterTypeName::CharacterVarying
611 | CharacterTypeName::Varchar
612 | CharacterTypeName::NcharVarying
613 | CharacterTypeName::NationalCharVarying
614 | CharacterTypeName::NationalCharacterVarying
615 );
616 match target {
617 TypeRenderTarget::PreserveSource => match spelling {
618 CharacterTypeName::Char => "CHAR",
619 CharacterTypeName::Character => "CHARACTER",
620 CharacterTypeName::CharVarying => "CHAR VARYING",
621 CharacterTypeName::CharacterVarying => "CHARACTER VARYING",
622 CharacterTypeName::Varchar => "VARCHAR",
623 CharacterTypeName::Nchar => "NCHAR",
624 CharacterTypeName::NcharVarying => "NCHAR VARYING",
625 CharacterTypeName::NationalChar => "NATIONAL CHAR",
626 CharacterTypeName::NationalCharVarying => "NATIONAL CHAR VARYING",
627 CharacterTypeName::NationalCharacter => "NATIONAL CHARACTER",
628 CharacterTypeName::NationalCharacterVarying => "NATIONAL CHARACTER VARYING",
629 },
630 TypeRenderTarget::Ansi => {
631 if varying {
632 "CHARACTER VARYING"
633 } else {
634 "CHARACTER"
635 }
636 }
637 TypeRenderTarget::Postgres => {
638 if varying {
639 "VARCHAR"
640 } else {
641 "CHAR"
642 }
643 }
644 }
645}
646
647fn render_optional_charset_annotation(
658 ctx: &RenderCtx<'_>,
659 target: TypeRenderTarget,
660 annotation: Option<&CharsetAnnotation>,
661 f: &mut fmt::Formatter<'_>,
662) -> fmt::Result {
663 let Some(annotation) = annotation else {
664 return Ok(());
665 };
666 if target != TypeRenderTarget::PreserveSource {
667 return Ok(());
668 }
669 match annotation.charset {
670 Some(Charset::Named) => {
671 f.write_str(" CHARACTER SET ")?;
672 if let Some(name) = &annotation.name {
675 name.render(ctx, f)?;
676 }
677 }
678 Some(Charset::Ascii) => f.write_str(" ASCII")?,
679 Some(Charset::Unicode) => f.write_str(" UNICODE")?,
680 Some(Charset::Byte) => f.write_str(" BYTE")?,
681 None => {}
682 }
683 if annotation.binary {
684 f.write_str(" BINARY")?;
685 }
686 Ok(())
687}
688
689fn binary_type_name(target: TypeRenderTarget, spelling: BinaryTypeName) -> &'static str {
690 match target {
691 TypeRenderTarget::PreserveSource => match spelling {
692 BinaryTypeName::Binary => "BINARY",
693 BinaryTypeName::BinaryVarying => "BINARY VARYING",
694 BinaryTypeName::Varbinary => "VARBINARY",
695 BinaryTypeName::Bytea => "BYTEA",
696 },
697 TypeRenderTarget::Ansi => match spelling {
698 BinaryTypeName::Binary => "BINARY",
699 BinaryTypeName::BinaryVarying => "BINARY VARYING",
700 BinaryTypeName::Varbinary => "BINARY VARYING",
701 BinaryTypeName::Bytea => "BYTEA",
702 },
703 TypeRenderTarget::Postgres => match spelling {
704 BinaryTypeName::Binary => "BYTEA",
705 BinaryTypeName::BinaryVarying => "BYTEA",
706 BinaryTypeName::Varbinary => "BYTEA",
707 BinaryTypeName::Bytea => "BYTEA",
708 },
709 }
710}
711
712fn render_time_type(
713 target: TypeRenderTarget,
714 spelling: TimeTypeName,
715 precision: Option<u32>,
716 time_zone: TimeZone,
717 f: &mut fmt::Formatter<'_>,
718) -> fmt::Result {
719 match target {
720 TypeRenderTarget::PreserveSource => match spelling {
721 TimeTypeName::Time => {
722 render_sized(f, "TIME", precision)?;
723 render_time_zone_suffix(time_zone, f)
724 }
725 TimeTypeName::Timetz => render_sized(f, "TIMETZ", precision),
726 },
727 TypeRenderTarget::Ansi => {
728 render_sized(f, "TIME", precision)?;
729 render_time_zone_suffix(time_zone_from_spelling(time_zone, spelling), f)
730 }
731 TypeRenderTarget::Postgres => match time_zone_from_spelling(time_zone, spelling) {
732 TimeZone::Unspecified => render_sized(f, "TIME", precision),
733 TimeZone::WithTimeZone => render_sized(f, "TIMETZ", precision),
734 TimeZone::WithoutTimeZone => {
735 render_sized(f, "TIME", precision)?;
736 f.write_str(" WITHOUT TIME ZONE")
737 }
738 },
739 }
740}
741
742fn render_timestamp_type(
743 target: TypeRenderTarget,
744 spelling: TimestampTypeName,
745 precision: Option<u32>,
746 time_zone: TimeZone,
747 f: &mut fmt::Formatter<'_>,
748) -> fmt::Result {
749 match target {
750 TypeRenderTarget::PreserveSource => match spelling {
751 TimestampTypeName::Timestamp => {
752 render_sized(f, "TIMESTAMP", precision)?;
753 render_time_zone_suffix(time_zone, f)
754 }
755 TimestampTypeName::Timestamptz => render_sized(f, "TIMESTAMPTZ", precision),
756 TimestampTypeName::Datetime => render_sized(f, "DATETIME", precision),
757 },
758 TypeRenderTarget::Ansi => {
759 render_sized(f, "TIMESTAMP", precision)?;
760 render_time_zone_suffix(time_zone_from_timestamp_spelling(time_zone, spelling), f)
761 }
762 TypeRenderTarget::Postgres => {
763 match time_zone_from_timestamp_spelling(time_zone, spelling) {
764 TimeZone::Unspecified => render_sized(f, "TIMESTAMP", precision),
765 TimeZone::WithTimeZone => render_sized(f, "TIMESTAMPTZ", precision),
766 TimeZone::WithoutTimeZone => {
767 render_sized(f, "TIMESTAMP", precision)?;
768 f.write_str(" WITHOUT TIME ZONE")
769 }
770 }
771 }
772 }
773}
774
775fn time_zone_from_spelling(time_zone: TimeZone, spelling: TimeTypeName) -> TimeZone {
776 match spelling {
777 TimeTypeName::Time => time_zone,
778 TimeTypeName::Timetz => TimeZone::WithTimeZone,
779 }
780}
781
782fn time_zone_from_timestamp_spelling(time_zone: TimeZone, spelling: TimestampTypeName) -> TimeZone {
783 match spelling {
784 TimestampTypeName::Timestamp => time_zone,
785 TimestampTypeName::Timestamptz => TimeZone::WithTimeZone,
786 TimestampTypeName::Datetime => TimeZone::Unspecified,
789 }
790}
791
792fn render_time_zone_suffix(time_zone: TimeZone, f: &mut fmt::Formatter<'_>) -> fmt::Result {
793 match time_zone {
794 TimeZone::Unspecified => Ok(()),
795 TimeZone::WithTimeZone => f.write_str(" WITH TIME ZONE"),
796 TimeZone::WithoutTimeZone => f.write_str(" WITHOUT TIME ZONE"),
797 }
798}
799
800fn render_interval_type(
801 fields: Option<IntervalFields>,
802 precision: Option<u32>,
803 f: &mut fmt::Formatter<'_>,
804) -> fmt::Result {
805 f.write_str("INTERVAL")?;
806 match fields {
807 Some(IntervalFields::Year) => render_interval_field(f, "YEAR", precision),
808 Some(IntervalFields::Month) => render_interval_field(f, "MONTH", precision),
809 Some(IntervalFields::Day) => render_interval_field(f, "DAY", precision),
810 Some(IntervalFields::Hour) => render_interval_field(f, "HOUR", precision),
811 Some(IntervalFields::Minute) => render_interval_field(f, "MINUTE", precision),
812 Some(IntervalFields::Second) => render_interval_field(f, "SECOND", precision),
813 Some(IntervalFields::YearToMonth) => f.write_str(" YEAR TO MONTH"),
814 Some(IntervalFields::DayToHour) => f.write_str(" DAY TO HOUR"),
815 Some(IntervalFields::DayToMinute) => f.write_str(" DAY TO MINUTE"),
816 Some(IntervalFields::DayToSecond) => {
817 f.write_str(" DAY TO ")?;
818 render_sized(f, "SECOND", precision)
819 }
820 Some(IntervalFields::HourToMinute) => f.write_str(" HOUR TO MINUTE"),
821 Some(IntervalFields::HourToSecond) => {
822 f.write_str(" HOUR TO ")?;
823 render_sized(f, "SECOND", precision)
824 }
825 Some(IntervalFields::MinuteToSecond) => {
826 f.write_str(" MINUTE TO ")?;
827 render_sized(f, "SECOND", precision)
828 }
829 Some(IntervalFields::Week) => render_interval_field(f, "WEEK", precision),
830 Some(IntervalFields::Quarter) => render_interval_field(f, "QUARTER", precision),
831 Some(IntervalFields::Decade) => render_interval_field(f, "DECADE", precision),
832 Some(IntervalFields::Century) => render_interval_field(f, "CENTURY", precision),
833 Some(IntervalFields::Millennium) => render_interval_field(f, "MILLENNIUM", precision),
834 Some(IntervalFields::Millisecond) => render_interval_field(f, "MILLISECOND", precision),
835 Some(IntervalFields::Microsecond) => render_interval_field(f, "MICROSECOND", precision),
836 Some(IntervalFields::DayToMicrosecond) => {
841 render_interval_field(f, "DAY TO MICROSECOND", precision)
842 }
843 Some(IntervalFields::HourToMicrosecond) => {
844 render_interval_field(f, "HOUR TO MICROSECOND", precision)
845 }
846 Some(IntervalFields::MinuteToMicrosecond) => {
847 render_interval_field(f, "MINUTE TO MICROSECOND", precision)
848 }
849 Some(IntervalFields::SecondToMicrosecond) => {
850 render_interval_field(f, "SECOND TO MICROSECOND", precision)
851 }
852 None => match precision {
853 Some(precision) => write!(f, "({precision})"),
854 None => Ok(()),
855 },
856 }
857}
858
859fn render_interval_field(
860 f: &mut fmt::Formatter<'_>,
861 name: &str,
862 precision: Option<u32>,
863) -> fmt::Result {
864 f.write_str(" ")?;
865 render_sized(f, name, precision)
866}
867
868fn interval_fields_suffix(fields: IntervalFields) -> &'static str {
872 match fields {
873 IntervalFields::Year => " YEAR",
874 IntervalFields::Month => " MONTH",
875 IntervalFields::Day => " DAY",
876 IntervalFields::Hour => " HOUR",
877 IntervalFields::Minute => " MINUTE",
878 IntervalFields::Second => " SECOND",
879 IntervalFields::YearToMonth => " YEAR TO MONTH",
880 IntervalFields::DayToHour => " DAY TO HOUR",
881 IntervalFields::DayToMinute => " DAY TO MINUTE",
882 IntervalFields::DayToSecond => " DAY TO SECOND",
883 IntervalFields::HourToMinute => " HOUR TO MINUTE",
884 IntervalFields::HourToSecond => " HOUR TO SECOND",
885 IntervalFields::MinuteToSecond => " MINUTE TO SECOND",
886 IntervalFields::Week => " WEEK",
887 IntervalFields::Quarter => " QUARTER",
888 IntervalFields::Decade => " DECADE",
889 IntervalFields::Century => " CENTURY",
890 IntervalFields::Millennium => " MILLENNIUM",
891 IntervalFields::Millisecond => " MILLISECOND",
892 IntervalFields::Microsecond => " MICROSECOND",
893 IntervalFields::DayToMicrosecond => " DAY TO MICROSECOND",
894 IntervalFields::HourToMicrosecond => " HOUR TO MICROSECOND",
895 IntervalFields::MinuteToMicrosecond => " MINUTE TO MICROSECOND",
896 IntervalFields::SecondToMicrosecond => " SECOND TO MICROSECOND",
897 }
898}
899
900fn mysql_interval_unit_suffix(unit: IntervalFields) -> &'static str {
909 match unit {
910 IntervalFields::Year => " YEAR",
911 IntervalFields::Month => " MONTH",
912 IntervalFields::Day => " DAY",
913 IntervalFields::Hour => " HOUR",
914 IntervalFields::Minute => " MINUTE",
915 IntervalFields::Second => " SECOND",
916 IntervalFields::Week => " WEEK",
917 IntervalFields::Quarter => " QUARTER",
918 IntervalFields::Microsecond => " MICROSECOND",
919 IntervalFields::YearToMonth => " YEAR_MONTH",
920 IntervalFields::DayToHour => " DAY_HOUR",
921 IntervalFields::DayToMinute => " DAY_MINUTE",
922 IntervalFields::DayToSecond => " DAY_SECOND",
923 IntervalFields::HourToMinute => " HOUR_MINUTE",
924 IntervalFields::HourToSecond => " HOUR_SECOND",
925 IntervalFields::MinuteToSecond => " MINUTE_SECOND",
926 IntervalFields::DayToMicrosecond => " DAY_MICROSECOND",
927 IntervalFields::HourToMicrosecond => " HOUR_MICROSECOND",
928 IntervalFields::MinuteToMicrosecond => " MINUTE_MICROSECOND",
929 IntervalFields::SecondToMicrosecond => " SECOND_MICROSECOND",
930 IntervalFields::Decade
932 | IntervalFields::Century
933 | IntervalFields::Millennium
934 | IntervalFields::Millisecond => " MICROSECOND",
935 }
936}
937
938fn render_sized(f: &mut fmt::Formatter<'_>, name: &str, size: Option<u32>) -> fmt::Result {
939 match size {
940 Some(size) => write!(f, "{name}({size})"),
941 None => f.write_str(name),
942 }
943}
944
945fn render_precision_scale(
946 f: &mut fmt::Formatter<'_>,
947 name: &str,
948 precision: Option<i32>,
949 scale: Option<i32>,
950) -> fmt::Result {
951 f.write_str(name)?;
952 match (precision, scale) {
953 (Some(precision), Some(scale)) => write!(f, "({precision}, {scale})"),
954 (Some(precision), None) => write!(f, "({precision})"),
955 (None, Some(scale)) => write!(f, "(*, {scale})"),
956 (None, None) => Ok(()),
957 }
958}
959
960fn render_literal_modifiers(
971 ctx: &RenderCtx<'_>,
972 f: &mut fmt::Formatter<'_>,
973 modifiers: &[Literal],
974) -> fmt::Result {
975 if modifiers.is_empty() {
976 return Ok(());
977 }
978 f.write_str("(")?;
979 for (index, modifier) in modifiers.iter().enumerate() {
980 if index > 0 {
981 f.write_str(", ")?;
982 }
983 if let Some(text) = ctx.slice(modifier.meta.span) {
984 f.write_str(text)?;
985 } else {
986 modifier.render(ctx, f)?;
987 }
988 }
989 f.write_str(")")
990}
991
992fn render_numeric_modifiers(f: &mut fmt::Formatter<'_>, modifiers: &[u32]) -> fmt::Result {
993 if modifiers.is_empty() {
994 return Ok(());
995 }
996 f.write_str("(")?;
997 for (index, modifier) in modifiers.iter().enumerate() {
998 if index > 0 {
999 f.write_str(", ")?;
1000 }
1001 write!(f, "{modifier}")?;
1002 }
1003 f.write_str(")")
1004}
1005
1006fn render_value_list_type(
1009 ctx: &RenderCtx<'_>,
1010 name: &str,
1011 values: &[Literal],
1012 f: &mut fmt::Formatter<'_>,
1013) -> fmt::Result {
1014 f.write_str(name)?;
1015 f.write_str("(")?;
1016 render_comma_separated(values, ctx, f)?;
1017 f.write_str(")")
1018}
1019
1020fn wrapped_type_keyword(kind: WrappedTypeKind) -> &'static str {
1026 match kind {
1027 WrappedTypeKind::Nullable => "Nullable",
1028 WrappedTypeKind::LowCardinality => "LowCardinality",
1029 }
1030}
1031
1032fn fixed_width_int_name(signed: bool, width: IntWidth) -> &'static str {
1037 match (signed, width) {
1038 (true, IntWidth::W8) => "Int8",
1039 (true, IntWidth::W16) => "Int16",
1040 (true, IntWidth::W32) => "Int32",
1041 (true, IntWidth::W64) => "Int64",
1042 (true, IntWidth::W128) => "Int128",
1043 (true, IntWidth::W256) => "Int256",
1044 (false, IntWidth::W8) => "UInt8",
1045 (false, IntWidth::W16) => "UInt16",
1046 (false, IntWidth::W32) => "UInt32",
1047 (false, IntWidth::W64) => "UInt64",
1048 (false, IntWidth::W128) => "UInt128",
1049 (false, IntWidth::W256) => "UInt256",
1050 }
1051}
1052
1053fn struct_type_keyword(spelling: StructTypeSpelling) -> &'static str {
1054 match spelling {
1055 StructTypeSpelling::Struct | StructTypeSpelling::AngleBracket => "STRUCT",
1056 StructTypeSpelling::Row => "ROW",
1057 }
1058}
1059
1060fn render_composite_type_angle<X: Extension + Render>(
1062 ctx: &RenderCtx<'_>,
1063 keyword: &str,
1064 fields: &[StructTypeField<X>],
1065 f: &mut fmt::Formatter<'_>,
1066) -> fmt::Result {
1067 f.write_str(keyword)?;
1068 f.write_str("<")?;
1069 render_comma_separated(fields, ctx, f)?;
1070 f.write_str(">")
1071}
1072
1073fn render_composite_type<X: Extension + Render>(
1077 ctx: &RenderCtx<'_>,
1078 keyword: &str,
1079 fields: &[StructTypeField<X>],
1080 f: &mut fmt::Formatter<'_>,
1081) -> fmt::Result {
1082 f.write_str(keyword)?;
1083 f.write_str("(")?;
1084 render_comma_separated(fields, ctx, f)?;
1085 f.write_str(")")
1086}
1087
1088fn render_array_type<X: Extension + Render>(
1091 ctx: &RenderCtx<'_>,
1092 element: &DataType<X>,
1093 size: Option<u32>,
1094 spelling: ArrayTypeSpelling,
1095 f: &mut fmt::Formatter<'_>,
1096) -> fmt::Result {
1097 if matches!(spelling, ArrayTypeSpelling::AngleBracket) {
1098 f.write_str("ARRAY<")?;
1099 element.render(ctx, f)?;
1100 return f.write_str(">");
1101 }
1102 element.render(ctx, f)?;
1103 match spelling {
1104 ArrayTypeSpelling::Bracket => match size {
1105 Some(n) => write!(f, "[{n}]"),
1106 None => f.write_str("[]"),
1107 },
1108 ArrayTypeSpelling::Keyword => {
1109 f.write_str(" ARRAY")?;
1110 match size {
1111 Some(n) => write!(f, "[{n}]"),
1112 None => Ok(()),
1113 }
1114 }
1115 ArrayTypeSpelling::AngleBracket => unreachable!("handled above"),
1116 }
1117}
1118
1119fn render_numeric_modifier_type<X: Extension + Render>(
1123 ctx: &RenderCtx<'_>,
1124 element: Option<&DataType<X>>,
1125 signedness: Signedness,
1126 zerofill: bool,
1127 f: &mut fmt::Formatter<'_>,
1128) -> fmt::Result {
1129 let mut wrote = false;
1130 if let Some(element) = element {
1131 element.render(ctx, f)?;
1132 wrote = true;
1133 }
1134 let sign = match signedness {
1135 Signedness::Unspecified => None,
1136 Signedness::Signed => Some("SIGNED"),
1137 Signedness::Unsigned => Some("UNSIGNED"),
1138 };
1139 if let Some(sign) = sign {
1140 if wrote {
1141 f.write_str(" ")?;
1142 }
1143 f.write_str(sign)?;
1144 wrote = true;
1145 }
1146 if zerofill {
1147 if wrote {
1148 f.write_str(" ")?;
1149 }
1150 f.write_str("ZEROFILL")?;
1151 }
1152 Ok(())
1153}
1154
1155impl Render for BinaryOperator {
1156 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1157 f.write_str(match self {
1160 BinaryOperator::Plus => "+",
1161 BinaryOperator::Minus => "-",
1162 BinaryOperator::Multiply => "*",
1163 BinaryOperator::Divide => "/",
1164 BinaryOperator::Modulo(ModuloSpelling::Percent) => "%",
1167 BinaryOperator::Modulo(ModuloSpelling::Mod) => "MOD",
1168 BinaryOperator::IntegerDivide(IntegerDivideSpelling::Div) => "DIV",
1172 BinaryOperator::IntegerDivide(IntegerDivideSpelling::SlashSlash) => "//",
1173 BinaryOperator::Exponent => "^",
1176 BinaryOperator::StringConcat => "||",
1177 BinaryOperator::Contains => "@>",
1178 BinaryOperator::ContainedBy => "<@",
1179 BinaryOperator::Overlap => "&&",
1180 BinaryOperator::JsonGet => "->",
1181 BinaryOperator::JsonGetText => "->>",
1182 BinaryOperator::JsonExists => "?",
1183 BinaryOperator::JsonExistsAny => "?|",
1184 BinaryOperator::JsonExistsAll => "?&",
1185 BinaryOperator::JsonPathExists => "@?",
1186 BinaryOperator::JsonPathMatch => "@@",
1187 BinaryOperator::JsonExtractPath => "#>",
1188 BinaryOperator::JsonExtractPathText => "#>>",
1189 BinaryOperator::JsonDeletePath => "#-",
1190 BinaryOperator::BitwiseOr => "|",
1191 BinaryOperator::BitwiseAnd => "&",
1192 BinaryOperator::BitwiseShiftLeft => "<<",
1193 BinaryOperator::BitwiseShiftRight => ">>",
1194 BinaryOperator::BitwiseXor(BitwiseXorSpelling::Hash) => "#",
1197 BinaryOperator::BitwiseXor(BitwiseXorSpelling::Caret) => "^",
1198 BinaryOperator::Eq(EqualsSpelling::Single) => "=",
1201 BinaryOperator::Eq(EqualsSpelling::Double) => "==",
1202 BinaryOperator::NotEq(NotEqSpelling::Bang) if honours_source_spelling(ctx) => "!=",
1208 BinaryOperator::NotEq(_) => "<>",
1209 BinaryOperator::Lt => "<",
1210 BinaryOperator::LtEq => "<=",
1211 BinaryOperator::Gt => ">",
1212 BinaryOperator::GtEq => ">=",
1213 BinaryOperator::IsDistinctFrom(IsDistinctFromSpelling::Keyword) => "IS DISTINCT FROM",
1216 BinaryOperator::IsDistinctFrom(IsDistinctFromSpelling::Is) => "IS NOT",
1217 BinaryOperator::IsNotDistinctFrom(IsNotDistinctFromSpelling::Keyword) => {
1222 "IS NOT DISTINCT FROM"
1223 }
1224 BinaryOperator::IsNotDistinctFrom(IsNotDistinctFromSpelling::NullSafeEq) => "<=>",
1225 BinaryOperator::IsNotDistinctFrom(IsNotDistinctFromSpelling::Is) => "IS",
1226 BinaryOperator::Regexp(RegexpSpelling::Rlike) => "RLIKE",
1227 BinaryOperator::Regexp(RegexpSpelling::Regexp) => "REGEXP",
1228 BinaryOperator::Glob => "GLOB",
1229 BinaryOperator::StartsWith => "^@",
1230 BinaryOperator::Match => "MATCH",
1231 BinaryOperator::Overlaps => "OVERLAPS",
1232 BinaryOperator::And => "AND",
1233 BinaryOperator::Xor => "XOR",
1234 BinaryOperator::Or => "OR",
1235 })
1236 }
1237}
1238
1239impl Render for UnaryOperator {
1240 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1241 f.write_str(match self {
1242 UnaryOperator::Not => "NOT",
1243 UnaryOperator::Minus => "-",
1244 UnaryOperator::Plus => "+",
1245 UnaryOperator::BitwiseNot => "~",
1246 UnaryOperator::Prior => "PRIOR",
1247 })
1248 }
1249}
1250
1251impl Render for SetOperator {
1252 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1253 f.write_str(match self {
1254 SetOperator::Union => "UNION",
1255 SetOperator::Intersect => "INTERSECT",
1256 SetOperator::Except => "EXCEPT",
1257 })
1258 }
1259}
1260
1261impl Render for Quantifier {
1262 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1263 f.write_str(match self {
1264 Quantifier::Any => "ANY",
1265 Quantifier::All => "ALL",
1266 Quantifier::Some => "SOME",
1267 })
1268 }
1269}
1270
1271impl Render for SetQuantifier {
1272 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1273 f.write_str(match self {
1274 SetQuantifier::All => "ALL",
1275 SetQuantifier::Distinct => "DISTINCT",
1276 })
1277 }
1278}
1279
1280impl<X: Extension + Render> Render for Expr<X> {
1285 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1286 match self {
1287 Expr::Column { name, .. } => name.render(ctx, f),
1288 Expr::Literal { literal, .. } => literal.render(ctx, f),
1289 Expr::BinaryOp {
1290 left, op, right, ..
1291 } => {
1292 let full = ctx.mode() == RenderMode::Parenthesized;
1293 open_group(full, f)?;
1294 render_operand(
1295 left,
1296 binary_child_needs_parens(&ctx.target().binding_powers, op, left, Side::Left),
1297 ctx,
1298 f,
1299 )?;
1300 f.write_str(" ")?;
1301 op.render(ctx, f)?;
1302 f.write_str(" ")?;
1303 render_operand(
1304 right,
1305 binary_child_needs_parens(&ctx.target().binding_powers, op, right, Side::Right),
1306 ctx,
1307 f,
1308 )?;
1309 close_group(full, f)
1310 }
1311 Expr::UnaryOp { op, expr, .. } => {
1312 let full = ctx.mode() == RenderMode::Parenthesized;
1313 open_group(full, f)?;
1314 op.render(ctx, f)?;
1315 if matches!(op, UnaryOperator::Not | UnaryOperator::Prior) {
1318 f.write_str(" ")?;
1319 }
1320 render_operand(
1321 expr,
1322 prefix_operand_needs_parens(&ctx.target().binding_powers, op, expr),
1323 ctx,
1324 f,
1325 )?;
1326 close_group(full, f)
1327 }
1328 Expr::Function { call, .. } => call.render(ctx, f),
1329 Expr::Case { case, .. } => case.render(ctx, f),
1330 Expr::Extract { extract, .. } => extract.render(ctx, f),
1331 Expr::JsonFunc { json_func, .. } => json_func.render(ctx, f),
1332 Expr::JsonObject { json_object, .. } => json_object.render(ctx, f),
1333 Expr::JsonArray { json_array, .. } => json_array.render(ctx, f),
1334 Expr::JsonAggregate { json_aggregate, .. } => json_aggregate.render(ctx, f),
1335 Expr::JsonConstructor {
1336 json_constructor, ..
1337 } => json_constructor.render(ctx, f),
1338 Expr::IsJson { is_json, .. } => is_json.render(ctx, f),
1339 Expr::XmlFunc { xml_func, .. } => xml_func.render(ctx, f),
1340 Expr::StringFunc { string_func, .. } => string_func.render(ctx, f),
1341 Expr::IsDocument { expr, negated, .. } => {
1342 let full = ctx.mode() == RenderMode::Parenthesized;
1343 open_group(full, f)?;
1344 render_predicate_operand(
1345 expr,
1346 ctx.target().binding_powers.predicate(),
1347 Side::Left,
1348 ctx,
1349 f,
1350 )?;
1351 f.write_str(if *negated {
1352 " IS NOT DOCUMENT"
1353 } else {
1354 " IS DOCUMENT"
1355 })?;
1356 close_group(full, f)
1357 }
1358 Expr::Cast {
1359 expr,
1360 data_type,
1361 syntax,
1362 try_cast,
1363 ..
1364 } => match syntax {
1365 CastSyntax::Call => {
1368 f.write_str(if *try_cast { "TRY_CAST(" } else { "CAST(" })?;
1369 expr.render(ctx, f)?;
1370 f.write_str(" AS ")?;
1371 data_type.render(ctx, f)?;
1372 f.write_str(")")
1373 }
1374 CastSyntax::DoubleColon => {
1375 let full = ctx.mode() == RenderMode::Parenthesized;
1376 open_group(full, f)?;
1377 render_pg_operand(
1378 expr,
1379 ctx.target().binding_powers.typecast,
1380 Side::Left,
1381 ctx,
1382 f,
1383 )?;
1384 f.write_str("::")?;
1385 data_type.render(ctx, f)?;
1386 close_group(full, f)
1387 }
1388 CastSyntax::PrefixTyped => {
1393 data_type.render(ctx, f)?;
1394 f.write_str(" ")?;
1395 expr.render(ctx, f)
1396 }
1397 CastSyntax::Convert => {
1400 f.write_str("CONVERT(")?;
1401 expr.render(ctx, f)?;
1402 f.write_str(", ")?;
1403 data_type.render(ctx, f)?;
1404 f.write_str(")")
1405 }
1406 },
1407 Expr::IsNull {
1408 expr,
1409 negated,
1410 spelling,
1411 ..
1412 } => {
1413 let full = ctx.mode() == RenderMode::Parenthesized;
1414 open_group(full, f)?;
1415 render_predicate_operand(
1416 expr,
1417 ctx.target().binding_powers.predicate(),
1418 Side::Left,
1419 ctx,
1420 f,
1421 )?;
1422 f.write_str(match (spelling, negated) {
1423 (NullTestSpelling::Is, false) => " IS NULL",
1424 (NullTestSpelling::Is, true) => " IS NOT NULL",
1425 (NullTestSpelling::Postfix, false) => " ISNULL",
1426 (NullTestSpelling::Postfix, true) => " NOTNULL",
1427 (NullTestSpelling::PostfixNotNull, _) => " NOT NULL",
1429 })?;
1430 close_group(full, f)
1431 }
1432 Expr::IsTruth {
1433 expr,
1434 value,
1435 negated,
1436 ..
1437 } => {
1438 let full = ctx.mode() == RenderMode::Parenthesized;
1439 open_group(full, f)?;
1440 render_predicate_operand(
1441 expr,
1442 ctx.target().binding_powers.predicate(),
1443 Side::Left,
1444 ctx,
1445 f,
1446 )?;
1447 f.write_str(match (negated, value) {
1448 (false, TruthValue::True) => " IS TRUE",
1449 (true, TruthValue::True) => " IS NOT TRUE",
1450 (false, TruthValue::False) => " IS FALSE",
1451 (true, TruthValue::False) => " IS NOT FALSE",
1452 (false, TruthValue::Unknown) => " IS UNKNOWN",
1453 (true, TruthValue::Unknown) => " IS NOT UNKNOWN",
1454 })?;
1455 close_group(full, f)
1456 }
1457 Expr::IsNormalized {
1458 expr,
1459 form,
1460 negated,
1461 ..
1462 } => {
1463 let full = ctx.mode() == RenderMode::Parenthesized;
1464 open_group(full, f)?;
1465 render_predicate_operand(
1466 expr,
1467 ctx.target().binding_powers.predicate(),
1468 Side::Left,
1469 ctx,
1470 f,
1471 )?;
1472 f.write_str(if *negated { " IS NOT " } else { " IS " })?;
1473 if let Some(form) = form {
1474 f.write_str(match form {
1475 NormalizationForm::Nfc => "NFC ",
1476 NormalizationForm::Nfd => "NFD ",
1477 NormalizationForm::Nfkc => "NFKC ",
1478 NormalizationForm::Nfkd => "NFKD ",
1479 })?;
1480 }
1481 f.write_str("NORMALIZED")?;
1482 close_group(full, f)
1483 }
1484 Expr::Between {
1485 expr,
1486 low,
1487 high,
1488 negated,
1489 symmetric,
1490 ..
1491 } => {
1492 let full = ctx.mode() == RenderMode::Parenthesized;
1493 open_group(full, f)?;
1494 let range = ctx.target().binding_powers.range_predicate();
1495 render_predicate_operand(expr, range, Side::Left, ctx, f)?;
1496 f.write_str(if *negated {
1497 " NOT BETWEEN "
1498 } else {
1499 " BETWEEN "
1500 })?;
1501 if *symmetric {
1502 f.write_str("SYMMETRIC ")?;
1503 }
1504 render_predicate_operand(low, range, Side::Right, ctx, f)?;
1505 f.write_str(" AND ")?;
1506 render_predicate_operand(high, range, Side::Right, ctx, f)?;
1507 close_group(full, f)
1508 }
1509 Expr::Like {
1510 expr,
1511 pattern,
1512 escape,
1513 negated,
1514 spelling,
1515 ..
1516 } => {
1517 let full = ctx.mode() == RenderMode::Parenthesized;
1518 open_group(full, f)?;
1519 let range = ctx.target().binding_powers.range_predicate();
1520 render_predicate_operand(expr, range, Side::Left, ctx, f)?;
1521 f.write_str(match (negated, spelling) {
1522 (false, LikeSpelling::Like) => " LIKE ",
1523 (true, LikeSpelling::Like) => " NOT LIKE ",
1524 (false, LikeSpelling::ILike) => " ILIKE ",
1525 (true, LikeSpelling::ILike) => " NOT ILIKE ",
1526 (false, LikeSpelling::SimilarTo) => " SIMILAR TO ",
1527 (true, LikeSpelling::SimilarTo) => " NOT SIMILAR TO ",
1528 })?;
1529 render_predicate_operand(pattern, range, Side::Right, ctx, f)?;
1530 if let Some(escape) = escape {
1531 f.write_str(" ESCAPE ")?;
1532 render_predicate_operand(escape, range, Side::Right, ctx, f)?;
1533 }
1534 close_group(full, f)
1535 }
1536 Expr::InList {
1537 expr,
1538 list,
1539 negated,
1540 ..
1541 } => {
1542 let full = ctx.mode() == RenderMode::Parenthesized;
1543 open_group(full, f)?;
1544 render_predicate_operand(
1545 expr,
1546 ctx.target().binding_powers.range_predicate(),
1547 Side::Left,
1548 ctx,
1549 f,
1550 )?;
1551 f.write_str(if *negated { " NOT IN (" } else { " IN (" })?;
1552 render_comma_separated(list, ctx, f)?;
1553 f.write_str(")")?;
1554 close_group(full, f)
1555 }
1556 Expr::InSubquery {
1557 expr,
1558 subquery,
1559 negated,
1560 ..
1561 } => {
1562 let full = ctx.mode() == RenderMode::Parenthesized;
1563 open_group(full, f)?;
1564 render_predicate_operand(
1565 expr,
1566 ctx.target().binding_powers.range_predicate(),
1567 Side::Left,
1568 ctx,
1569 f,
1570 )?;
1571 f.write_str(if *negated { " NOT IN " } else { " IN " })?;
1572 render_query_in_parens(subquery, ctx, f)?;
1573 close_group(full, f)
1574 }
1575 Expr::InExpr {
1576 expr, rhs, negated, ..
1577 } => {
1578 let table = &ctx.target().binding_powers;
1583 let full = ctx.mode() == RenderMode::Parenthesized;
1584 open_group(full, f)?;
1585 render_operand(
1586 expr,
1587 operand_needs_parens(table, UNPARENTHESIZED_IN_LIST, expr, Side::Left),
1588 ctx,
1589 f,
1590 )?;
1591 f.write_str(if *negated { " NOT IN " } else { " IN " })?;
1592 render_operand(
1593 rhs,
1594 operand_needs_parens(table, UNPARENTHESIZED_IN_LIST, rhs, Side::Right),
1595 ctx,
1596 f,
1597 )?;
1598 close_group(full, f)
1599 }
1600 Expr::Exists { query, .. } => {
1601 let full = ctx.mode() == RenderMode::Parenthesized;
1602 open_group(full, f)?;
1603 f.write_str("EXISTS ")?;
1604 render_query_in_parens(query, ctx, f)?;
1605 close_group(full, f)
1606 }
1607 Expr::QuantifiedComparison {
1608 left,
1609 op,
1610 quantifier,
1611 subquery,
1612 ..
1613 } => {
1614 let full = ctx.mode() == RenderMode::Parenthesized;
1615 open_group(full, f)?;
1616 render_predicate_operand(
1617 left,
1618 ctx.target().binding_powers.comparison,
1619 Side::Left,
1620 ctx,
1621 f,
1622 )?;
1623 f.write_str(" ")?;
1624 op.render(ctx, f)?;
1625 f.write_str(" ")?;
1626 quantifier.render(ctx, f)?;
1627 f.write_str(" ")?;
1628 render_query_in_parens(subquery, ctx, f)?;
1629 close_group(full, f)
1630 }
1631 Expr::QuantifiedList {
1632 left,
1633 op,
1634 quantifier,
1635 array,
1636 ..
1637 } => {
1638 let full = ctx.mode() == RenderMode::Parenthesized;
1639 open_group(full, f)?;
1640 render_predicate_operand(
1641 left,
1642 ctx.target().binding_powers.comparison,
1643 Side::Left,
1644 ctx,
1645 f,
1646 )?;
1647 f.write_str(" ")?;
1648 op.render(ctx, f)?;
1649 f.write_str(" ")?;
1650 quantifier.render(ctx, f)?;
1651 f.write_str(" (")?;
1652 array.render(ctx, f)?;
1653 f.write_str(")")?;
1654 close_group(full, f)
1655 }
1656 Expr::QuantifiedLike {
1657 left,
1658 pattern,
1659 quantifier,
1660 negated,
1661 spelling,
1662 ..
1663 } => {
1664 let full = ctx.mode() == RenderMode::Parenthesized;
1665 open_group(full, f)?;
1666 render_predicate_operand(
1667 left,
1668 ctx.target().binding_powers.range_predicate(),
1669 Side::Left,
1670 ctx,
1671 f,
1672 )?;
1673 f.write_str(match (negated, spelling) {
1674 (false, LikeSpelling::Like) => " LIKE ",
1675 (true, LikeSpelling::Like) => " NOT LIKE ",
1676 (false, LikeSpelling::ILike) => " ILIKE ",
1677 (true, LikeSpelling::ILike) => " NOT ILIKE ",
1678 (false, LikeSpelling::SimilarTo) => " SIMILAR TO ",
1681 (true, LikeSpelling::SimilarTo) => " NOT SIMILAR TO ",
1682 })?;
1683 quantifier.render(ctx, f)?;
1684 f.write_str(" (")?;
1685 pattern.render(ctx, f)?;
1686 f.write_str(")")?;
1687 close_group(full, f)
1688 }
1689 Expr::Subquery { query, .. } => render_query_in_parens(query, ctx, f),
1690 Expr::Parameter { kind, .. } => render_parameter_kind(*kind, ctx, f),
1693 Expr::PositionalColumn { index, .. } => write!(f, "#{index}"),
1697 Expr::SessionVariable { kind, name, .. } => {
1703 let prefix = match kind {
1704 SessionVariableKind::User => "@",
1705 SessionVariableKind::System => "@@",
1706 SessionVariableKind::SystemGlobal => "@@global.",
1707 SessionVariableKind::SystemSession => "@@session.",
1708 };
1709 write!(f, "{prefix}{}", ctx.resolve(*name))
1710 }
1711 Expr::Subscript { subscript, .. } => {
1712 let full = ctx.mode() == RenderMode::Parenthesized;
1713 open_group(full, f)?;
1714 let base_needs_parens = matches!(
1721 subscript.base,
1722 Expr::Cast {
1723 syntax: CastSyntax::DoubleColon,
1724 ..
1725 }
1726 ) || operand_needs_parens(
1727 &ctx.target().binding_powers,
1728 ctx.target().binding_powers.subscript,
1729 &subscript.base,
1730 Side::Left,
1731 );
1732 render_operand(&subscript.base, base_needs_parens, ctx, f)?;
1733 f.write_str("[")?;
1734 match subscript.kind {
1735 SubscriptKind::Index => {
1736 if let Some(index) = &subscript.lower {
1738 index.render(ctx, f)?;
1739 }
1740 }
1741 SubscriptKind::Slice => {
1742 if let Some(lower) = &subscript.lower {
1743 lower.render(ctx, f)?;
1744 }
1745 f.write_str(":")?;
1746 if let Some(upper) = &subscript.upper {
1747 upper.render(ctx, f)?;
1748 }
1749 }
1750 SubscriptKind::SliceWithStep => {
1751 if let Some(lower) = &subscript.lower {
1752 lower.render(ctx, f)?;
1753 }
1754 f.write_str(":")?;
1755 match &subscript.upper {
1758 Some(upper) => upper.render(ctx, f)?,
1759 None => f.write_str("-")?,
1760 }
1761 f.write_str(":")?;
1762 if let Some(step) = &subscript.step {
1763 step.render(ctx, f)?;
1764 }
1765 }
1766 }
1767 f.write_str("]")?;
1768 close_group(full, f)
1769 }
1770 Expr::SemiStructuredAccess {
1771 semi_structured_access,
1772 ..
1773 } => semi_structured_access.render(ctx, f),
1774 Expr::Collate { collate, .. } => {
1775 let full = ctx.mode() == RenderMode::Parenthesized;
1776 open_group(full, f)?;
1777 render_pg_operand(
1778 &collate.expr,
1779 ctx.target().binding_powers.collate,
1780 Side::Left,
1781 ctx,
1782 f,
1783 )?;
1784 f.write_str(" COLLATE ")?;
1785 collate.collation.render(ctx, f)?;
1786 close_group(full, f)
1787 }
1788 Expr::AtTimeZone { at_time_zone, .. } => {
1789 let full = ctx.mode() == RenderMode::Parenthesized;
1790 open_group(full, f)?;
1791 let bp = ctx.target().binding_powers.at_time_zone;
1792 render_pg_operand(&at_time_zone.expr, bp, Side::Left, ctx, f)?;
1793 f.write_str(" AT TIME ZONE ")?;
1794 render_pg_operand(&at_time_zone.zone, bp, Side::Right, ctx, f)?;
1797 close_group(full, f)
1798 }
1799 Expr::Interval { value, unit, .. } => {
1800 let full = ctx.mode() == RenderMode::Parenthesized;
1806 open_group(full, f)?;
1807 f.write_str("INTERVAL ")?;
1808 value.render(ctx, f)?;
1809 f.write_str(mysql_interval_unit_suffix(*unit))?;
1810 close_group(full, f)
1811 }
1812 Expr::Array { array, .. } => match &**array {
1813 ArrayExpr::Elements {
1814 elements, spelling, ..
1815 } => {
1816 f.write_str(match spelling {
1817 ArraySpelling::Keyword => "ARRAY[",
1818 ArraySpelling::Bracket => "[",
1819 })?;
1820 render_comma_separated(elements, ctx, f)?;
1821 f.write_str("]")
1822 }
1823 ArrayExpr::Subquery { query, .. } => {
1824 f.write_str("ARRAY")?;
1825 render_query_in_parens(query, ctx, f)
1826 }
1827 ArrayExpr::Comprehension { comprehension, .. } => {
1828 f.write_str("[")?;
1829 comprehension.element.render(ctx, f)?;
1830 f.write_str(" for ")?;
1831 render_ident_list(&comprehension.vars, ctx, f)?;
1832 f.write_str(" in ")?;
1833 render_comprehension_source(&comprehension.source, ctx, f)?;
1834 if let Some(filter) = &comprehension.filter {
1835 f.write_str(" if ")?;
1836 filter.render(ctx, f)?;
1837 }
1838 f.write_str("]")
1839 }
1840 },
1841 Expr::Struct { r#struct, .. } => {
1842 f.write_str("{")?;
1843 for (i, field) in r#struct.fields.iter().enumerate() {
1844 if i > 0 {
1845 f.write_str(", ")?;
1846 }
1847 field.render(ctx, f)?;
1848 }
1849 f.write_str("}")
1850 }
1851 Expr::StructConstructor { constructor, .. } => {
1852 f.write_str("STRUCT")?;
1853 if !constructor.fields.is_empty() {
1854 f.write_str("<")?;
1855 render_comma_separated(&constructor.fields, ctx, f)?;
1856 f.write_str(">")?;
1857 }
1858 f.write_str("(")?;
1859 render_comma_separated(&constructor.args, ctx, f)?;
1860 f.write_str(")")
1861 }
1862 Expr::Map { map, .. } => {
1863 f.write_str("MAP {")?;
1864 for (i, entry) in map.entries.iter().enumerate() {
1865 if i > 0 {
1866 f.write_str(", ")?;
1867 }
1868 entry.key.render(ctx, f)?;
1869 f.write_str(": ")?;
1870 entry.value.render(ctx, f)?;
1871 }
1872 f.write_str("}")
1873 }
1874 Expr::Row { row, .. } => {
1875 f.write_str(if row.explicit { "ROW(" } else { "(" })?;
1876 render_comma_separated(&row.fields, ctx, f)?;
1877 f.write_str(")")
1878 }
1879 Expr::FieldSelection {
1880 field_selection, ..
1881 } => {
1882 f.write_str("(")?;
1886 field_selection.base.render(ctx, f)?;
1887 f.write_str(").")?;
1888 match &field_selection.selector {
1889 FieldSelector::Field { field, .. } => field.render(ctx, f),
1890 FieldSelector::Star { .. } => f.write_str("*"),
1891 }
1892 }
1893 Expr::SpecialFunction {
1894 keyword, precision, ..
1895 } => {
1896 f.write_str(special_function_keyword(*keyword))?;
1897 if let Some(precision) = precision {
1898 write!(f, "({precision})")?;
1899 }
1900 Ok(())
1901 }
1902 Expr::NamedOperator { named_operator, .. } => render_extension_infix(
1911 ctx,
1912 f,
1913 ctx.target().binding_powers.any_operator,
1914 (&named_operator.left, &named_operator.right),
1915 |f| match named_operator.spelling {
1916 NamedOperatorSpelling::Bare => {
1917 f.write_str(" ")?;
1918 f.write_str(ctx.resolve(named_operator.op))?;
1919 f.write_str(" ")
1920 }
1921 NamedOperatorSpelling::OperatorKeyword => {
1922 f.write_str(" OPERATOR(")?;
1923 for part in &named_operator.schema.0 {
1924 part.render(ctx, f)?;
1925 f.write_str(".")?;
1926 }
1927 f.write_str(ctx.resolve(named_operator.op))?;
1928 f.write_str(") ")
1929 }
1930 },
1931 ),
1932 Expr::PrefixOperator {
1937 prefix_operator, ..
1938 } => render_extension_prefix(
1939 ctx,
1940 f,
1941 ctx.target().binding_powers.any_operator.left,
1942 |f| {
1943 f.write_str(ctx.resolve(prefix_operator.op))?;
1944 f.write_str(" ")
1945 },
1946 &prefix_operator.operand,
1947 ),
1948 Expr::PostfixOperator {
1952 postfix_operator, ..
1953 } => render_extension_postfix(
1954 ctx,
1955 f,
1956 ctx.target().binding_powers.any_operator,
1957 &postfix_operator.operand,
1958 |f| {
1959 f.write_str(" ")?;
1960 f.write_str(ctx.resolve(postfix_operator.op))
1961 },
1962 ),
1963 Expr::Lambda { lambda, .. } => {
1968 let full = ctx.mode() == RenderMode::Parenthesized;
1969 open_group(full, f)?;
1970 match lambda.spelling {
1971 LambdaParamSpelling::Keyword => {
1975 f.write_str("lambda ")?;
1976 render_comma_separated(&lambda.params, ctx, f)?;
1977 f.write_str(": ")?;
1978 lambda.body.render(ctx, f)?;
1979 }
1980 arrow => {
1981 match arrow {
1982 LambdaParamSpelling::Bare if lambda.params.len() == 1 => {
1986 lambda.params[0].render(ctx, f)?;
1987 }
1988 LambdaParamSpelling::RowKeyword => {
1989 f.write_str("ROW(")?;
1990 render_comma_separated(&lambda.params, ctx, f)?;
1991 f.write_str(")")?;
1992 }
1993 _ => {
1995 f.write_str("(")?;
1996 render_comma_separated(&lambda.params, ctx, f)?;
1997 f.write_str(")")?;
1998 }
1999 }
2000 f.write_str(" -> ")?;
2001 render_pg_operand(
2002 &lambda.body,
2003 ctx.target().binding_powers.binary(&BinaryOperator::JsonGet),
2004 Side::Right,
2005 ctx,
2006 f,
2007 )?;
2008 }
2009 }
2010 close_group(full, f)
2011 }
2012 Expr::Columns {
2019 qualifier,
2020 pattern,
2021 options,
2022 spelling,
2023 ..
2024 } => {
2025 if matches!(spelling, ColumnsSpelling::Star) {
2026 if let Some(qualifier) = qualifier {
2028 qualifier.render(ctx, f)?;
2029 f.write_str(".")?;
2030 }
2031 f.write_str("*")?;
2032 if let Some(options) = options {
2033 render_wildcard_options(options, ctx, f)?;
2034 }
2035 return Ok(());
2036 }
2037 if matches!(spelling, ColumnsSpelling::Unpack) {
2038 f.write_str("*")?;
2039 }
2040 f.write_str("COLUMNS(")?;
2041 match pattern {
2042 Some(pattern) => pattern.render(ctx, f)?,
2043 None => {
2044 if let Some(qualifier) = qualifier {
2045 qualifier.render(ctx, f)?;
2046 f.write_str(".")?;
2047 }
2048 f.write_str("*")?;
2049 if let Some(options) = options {
2050 render_wildcard_options(options, ctx, f)?;
2051 }
2052 }
2053 }
2054 f.write_str(")")
2055 }
2056 Expr::Other { ext, .. } => ext.render(ctx, f),
2057 }
2058 }
2059}
2060
2061fn special_function_keyword(keyword: SpecialFunctionKeyword) -> &'static str {
2063 match keyword {
2064 SpecialFunctionKeyword::CurrentCatalog => "CURRENT_CATALOG",
2065 SpecialFunctionKeyword::CurrentDate => "CURRENT_DATE",
2066 SpecialFunctionKeyword::CurrentRole => "CURRENT_ROLE",
2067 SpecialFunctionKeyword::CurrentSchema => "CURRENT_SCHEMA",
2068 SpecialFunctionKeyword::CurrentTime => "CURRENT_TIME",
2069 SpecialFunctionKeyword::CurrentTimestamp => "CURRENT_TIMESTAMP",
2070 SpecialFunctionKeyword::CurrentUser => "CURRENT_USER",
2071 SpecialFunctionKeyword::LocalTime => "LOCALTIME",
2072 SpecialFunctionKeyword::LocalTimestamp => "LOCALTIMESTAMP",
2073 SpecialFunctionKeyword::SessionUser => "SESSION_USER",
2074 SpecialFunctionKeyword::SystemUser => "SYSTEM_USER",
2075 SpecialFunctionKeyword::User => "USER",
2076 SpecialFunctionKeyword::UtcDate => "UTC_DATE",
2077 SpecialFunctionKeyword::UtcTime => "UTC_TIME",
2078 SpecialFunctionKeyword::UtcTimestamp => "UTC_TIMESTAMP",
2079 }
2080}
2081
2082fn open_group(group: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2083 if group {
2084 f.write_str("(")?;
2085 }
2086 Ok(())
2087}
2088
2089fn close_group(group: bool, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2090 if group {
2091 f.write_str(")")?;
2092 }
2093 Ok(())
2094}
2095
2096fn render_operand<X: Extension + Render>(
2102 child: &Expr<X>,
2103 canonical_parens: bool,
2104 ctx: &RenderCtx<'_>,
2105 f: &mut fmt::Formatter<'_>,
2106) -> fmt::Result {
2107 let wrap = match ctx.mode() {
2108 RenderMode::Parenthesized => false,
2109 RenderMode::Canonical | RenderMode::Redacted => canonical_parens,
2110 };
2111 open_group(wrap, f)?;
2112 child.render(ctx, f)?;
2113 close_group(wrap, f)
2114}
2115
2116fn render_predicate_operand<X: Extension + Render>(
2131 child: &Expr<X>,
2132 parent: BindingPower,
2133 side: Side,
2134 ctx: &RenderCtx<'_>,
2135 f: &mut fmt::Formatter<'_>,
2136) -> fmt::Result {
2137 render_operand(
2138 child,
2139 operand_needs_parens(&ctx.target().binding_powers, parent, child, side),
2140 ctx,
2141 f,
2142 )
2143}
2144
2145fn render_query_in_parens<X: Extension + Render>(
2146 query: &Query<X>,
2147 ctx: &RenderCtx<'_>,
2148 f: &mut fmt::Formatter<'_>,
2149) -> fmt::Result {
2150 f.write_str("(")?;
2151 query.render(ctx, f)?;
2152 f.write_str(")")
2153}
2154
2155fn binary_child_needs_parens<X: Extension + Render>(
2167 bp: &BindingPowerTable,
2168 parent: &BinaryOperator,
2169 child: &Expr<X>,
2170 side: Side,
2171) -> bool {
2172 match child {
2173 Expr::BinaryOp { op, .. } => bp.needs_parens(parent, op, side),
2174 Expr::UnaryOp { op, .. } => match side {
2175 Side::Right => false,
2176 Side::Left => bp.prefix(op) < bp.binary(parent).left,
2177 },
2178 Expr::Between { .. }
2179 | Expr::Like { .. }
2180 | Expr::QuantifiedLike { .. }
2181 | Expr::InList { .. }
2182 | Expr::InSubquery { .. } => {
2183 needs_parens_between(bp.binary(parent), bp.range_predicate(), side)
2184 }
2185 Expr::IsNull { .. } | Expr::IsTruth { .. } | Expr::IsNormalized { .. } => {
2186 needs_parens_between(bp.binary(parent), bp.predicate(), side)
2187 }
2188 Expr::QuantifiedComparison { .. } => {
2191 needs_parens_between(bp.binary(parent), bp.comparison, side)
2192 }
2193 Expr::InExpr { .. } => {
2194 needs_parens_between(bp.binary(parent), UNPARENTHESIZED_IN_LIST, side)
2195 }
2196 Expr::NamedOperator { .. } => {
2197 needs_parens_between(bp.binary(parent), bp.any_operator, side)
2198 }
2199 Expr::PrefixOperator { .. } => match side {
2200 Side::Right => false,
2201 Side::Left => bp.any_operator.left < bp.binary(parent).left,
2202 },
2203 Expr::PostfixOperator { .. } => match side {
2206 Side::Left => false,
2207 Side::Right => bp.any_operator.left < bp.binary(parent).right,
2208 },
2209 Expr::Lambda { .. } => {
2212 needs_parens_between(bp.binary(parent), bp.binary(&BinaryOperator::JsonGet), side)
2213 }
2214 Expr::Other { ext, .. } => match ext.operand_binding_power() {
2215 Some(child) => needs_parens_between(bp.binary(parent), child, side),
2216 None => false,
2217 },
2218 _ => false,
2219 }
2220}
2221
2222fn prefix_operand_needs_parens<X: Extension + Render>(
2232 bp: &BindingPowerTable,
2233 op: &UnaryOperator,
2234 operand: &Expr<X>,
2235) -> bool {
2236 match operand {
2237 Expr::BinaryOp { op: child, .. } => bp.binary(child).left < bp.prefix(op),
2238 Expr::UnaryOp { op: inner, .. } => is_sign(op) && is_sign(inner),
2239 Expr::Between { .. }
2240 | Expr::Like { .. }
2241 | Expr::QuantifiedLike { .. }
2242 | Expr::InList { .. }
2243 | Expr::InSubquery { .. } => bp.range_predicate().left < bp.prefix(op),
2244 Expr::IsNull { .. } | Expr::IsTruth { .. } | Expr::IsNormalized { .. } => {
2245 bp.predicate().left < bp.prefix(op)
2246 }
2247 Expr::QuantifiedComparison { .. } => bp.comparison.left < bp.prefix(op),
2250 Expr::InExpr { .. } => UNPARENTHESIZED_IN_LIST.left < bp.prefix(op),
2251 Expr::NamedOperator { .. } => bp.any_operator.left < bp.prefix(op),
2252 Expr::PrefixOperator { .. } => bp.any_operator.left < bp.prefix(op),
2255 Expr::PostfixOperator { .. } => bp.any_operator.left < bp.prefix(op),
2258 Expr::Lambda { .. } => bp.binary(&BinaryOperator::JsonGet).left < bp.prefix(op),
2260 Expr::Other { ext, .. } => ext
2261 .operand_binding_power()
2262 .is_some_and(|child| child.left < bp.prefix(op)),
2263 _ => false,
2264 }
2265}
2266
2267fn is_sign(op: &UnaryOperator) -> bool {
2268 matches!(op, UnaryOperator::Minus | UnaryOperator::Plus)
2269}
2270
2271fn render_pg_operand<X: Extension + Render>(
2275 child: &Expr<X>,
2276 parent: BindingPower,
2277 side: Side,
2278 ctx: &RenderCtx<'_>,
2279 f: &mut fmt::Formatter<'_>,
2280) -> fmt::Result {
2281 let canonical = operand_needs_parens(&ctx.target().binding_powers, parent, child, side);
2282 render_operand(child, canonical, ctx, f)
2283}
2284
2285fn operand_needs_parens<X: Extension + Render>(
2299 bp: &BindingPowerTable,
2300 parent: BindingPower,
2301 child: &Expr<X>,
2302 side: Side,
2303) -> bool {
2304 let child_bp = match child {
2305 Expr::BinaryOp { op, .. } => bp.binary(op),
2306 Expr::UnaryOp { op, .. } => {
2307 return side == Side::Left && bp.prefix(op) < parent.left;
2308 }
2309 Expr::Between { .. }
2310 | Expr::Like { .. }
2311 | Expr::QuantifiedLike { .. }
2312 | Expr::InList { .. }
2313 | Expr::InSubquery { .. } => bp.range_predicate(),
2314 Expr::IsNull { .. } | Expr::IsTruth { .. } | Expr::IsNormalized { .. } => bp.predicate(),
2315 Expr::QuantifiedComparison { .. } => bp.comparison,
2318 Expr::InExpr { .. } => UNPARENTHESIZED_IN_LIST,
2319 Expr::Cast {
2320 syntax: CastSyntax::DoubleColon,
2321 ..
2322 } => bp.typecast,
2323 Expr::Subscript { .. } => bp.subscript,
2324 Expr::Collate { .. } => bp.collate,
2325 Expr::AtTimeZone { .. } => bp.at_time_zone,
2326 Expr::FieldSelection { .. } => bp.field_selection,
2327 Expr::NamedOperator { .. } => bp.any_operator,
2330 Expr::PrefixOperator { .. } => {
2333 return side == Side::Left && bp.any_operator.left < parent.left;
2334 }
2335 Expr::PostfixOperator { .. } => {
2338 return side == Side::Right && bp.any_operator.left < parent.right;
2339 }
2340 Expr::Lambda { .. } => bp.binary(&BinaryOperator::JsonGet),
2342 Expr::Other { ext, .. } => match ext.operand_binding_power() {
2343 Some(child_bp) => child_bp,
2344 None => return false,
2345 },
2346 _ => return false,
2347 };
2348 needs_parens_between(parent, child_bp, side)
2349}
2350
2351pub fn render_extension_infix<X: Extension + Render>(
2368 ctx: &RenderCtx<'_>,
2369 f: &mut fmt::Formatter<'_>,
2370 bp: BindingPower,
2371 operands: (&Expr<X>, &Expr<X>),
2372 op: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
2373) -> fmt::Result {
2374 let (left, right) = operands;
2375 let table = &ctx.target().binding_powers;
2376 let full = ctx.mode() == RenderMode::Parenthesized;
2377 open_group(full, f)?;
2378 render_operand(
2379 left,
2380 operand_needs_parens(table, bp, left, Side::Left),
2381 ctx,
2382 f,
2383 )?;
2384 op(f)?;
2385 render_operand(
2386 right,
2387 operand_needs_parens(table, bp, right, Side::Right),
2388 ctx,
2389 f,
2390 )?;
2391 close_group(full, f)
2392}
2393
2394pub fn render_extension_prefix<X: Extension + Render>(
2401 ctx: &RenderCtx<'_>,
2402 f: &mut fmt::Formatter<'_>,
2403 bp: u8,
2404 op: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
2405 operand: &Expr<X>,
2406) -> fmt::Result {
2407 let full = ctx.mode() == RenderMode::Parenthesized;
2408 open_group(full, f)?;
2409 op(f)?;
2410 render_operand(
2411 operand,
2412 prefix_extension_operand_needs_parens(&ctx.target().binding_powers, bp, operand),
2413 ctx,
2414 f,
2415 )?;
2416 close_group(full, f)
2417}
2418
2419pub fn render_extension_postfix<X: Extension + Render>(
2430 ctx: &RenderCtx<'_>,
2431 f: &mut fmt::Formatter<'_>,
2432 bp: BindingPower,
2433 operand: &Expr<X>,
2434 op: impl FnOnce(&mut fmt::Formatter<'_>) -> fmt::Result,
2435) -> fmt::Result {
2436 let table = &ctx.target().binding_powers;
2437 let full = ctx.mode() == RenderMode::Parenthesized;
2438 open_group(full, f)?;
2439 render_operand(
2440 operand,
2441 operand_needs_parens(table, bp, operand, Side::Left),
2442 ctx,
2443 f,
2444 )?;
2445 op(f)?;
2446 close_group(full, f)
2447}
2448
2449fn prefix_extension_operand_needs_parens<X: Extension + Render>(
2455 table: &BindingPowerTable,
2456 bp: u8,
2457 operand: &Expr<X>,
2458) -> bool {
2459 match operand {
2460 Expr::BinaryOp { op, .. } => table.binary(op).left < bp,
2461 Expr::IsNull { .. } | Expr::IsTruth { .. } | Expr::IsNormalized { .. } => {
2462 table.predicate().left < bp
2463 }
2464 Expr::Between { .. }
2467 | Expr::Like { .. }
2468 | Expr::QuantifiedLike { .. }
2469 | Expr::InList { .. }
2470 | Expr::InSubquery { .. } => table.range_predicate().left < bp,
2471 Expr::QuantifiedComparison { .. } => table.comparison.left < bp,
2472 Expr::InExpr { .. } => UNPARENTHESIZED_IN_LIST.left < bp,
2473 Expr::NamedOperator { .. } => table.any_operator.left < bp,
2474 Expr::PrefixOperator { .. } => table.any_operator.left < bp,
2475 Expr::PostfixOperator { .. } => table.any_operator.left < bp,
2476 Expr::Lambda { .. } => table.binary(&BinaryOperator::JsonGet).left < bp,
2478 Expr::Other { ext, .. } => ext
2479 .operand_binding_power()
2480 .is_some_and(|child| child.left < bp),
2481 _ => false,
2482 }
2483}
2484
2485impl<X: Extension + Render> Render for Statement<X> {
2490 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2491 match self {
2492 Statement::Query { query, .. } => query.render(ctx, f),
2493 Statement::CreateTable { create, .. } => create.render(ctx, f),
2494 Statement::AlterTable { alter, .. } => alter.render(ctx, f),
2495 Statement::Drop { drop, .. } => drop.render(ctx, f),
2496 Statement::CreateSchema { schema, .. } => schema.render(ctx, f),
2497 Statement::CreateView { view, .. } => view.render(ctx, f),
2498 Statement::RefreshMaterializedView { refresh, .. } => refresh.render(ctx, f),
2499 Statement::CreateColocationGroup { create, .. } => create.render(ctx, f),
2500 Statement::DropColocationGroup { drop, .. } => drop.render(ctx, f),
2501 Statement::AlterView { alter, .. } => alter.render(ctx, f),
2502 Statement::CreateIndex { index, .. } => index.render(ctx, f),
2503 Statement::CreateFunction { create, .. } => create.render(ctx, f),
2504 Statement::CreateProcedure { create, .. } => create.render(ctx, f),
2505 Statement::AlterRoutine { alter, .. } => alter.render(ctx, f),
2506 Statement::CreateEvent { create, .. } => create.render(ctx, f),
2507 Statement::AlterEvent { alter, .. } => alter.render(ctx, f),
2508 Statement::DropEvent { drop, .. } => drop.render(ctx, f),
2509 Statement::DropDatabase { drop, .. } => drop.render(ctx, f),
2510 Statement::DropIndex { drop, .. } => drop.render(ctx, f),
2511 Statement::CreateDatabase { create, .. } => create.render(ctx, f),
2512 Statement::DropRoutine {
2513 kind,
2514 if_exists,
2515 routines,
2516 behavior,
2517 ..
2518 } => {
2519 f.write_str("DROP ")?;
2520 kind.render(ctx, f)?;
2521 if *if_exists {
2522 f.write_str(" IF EXISTS")?;
2523 }
2524 f.write_str(" ")?;
2525 render_comma_separated(routines, ctx, f)?;
2526 render_drop_behavior(*behavior, ctx, f)
2527 }
2528 Statement::DropTransform { drop, .. } => drop.render(ctx, f),
2529 Statement::Truncate {
2530 tables,
2531 table_keyword,
2532 restart_identity,
2533 behavior,
2534 ..
2535 } => {
2536 if *table_keyword || !honours_source_spelling(ctx) {
2539 f.write_str("TRUNCATE TABLE ")?;
2540 } else {
2541 f.write_str("TRUNCATE ")?;
2542 }
2543 render_comma_separated(tables, ctx, f)?;
2544 match restart_identity {
2545 Some(true) => f.write_str(" RESTART IDENTITY")?,
2546 Some(false) => f.write_str(" CONTINUE IDENTITY")?,
2547 None => {}
2548 }
2549 render_drop_behavior(*behavior, ctx, f)
2550 }
2551 Statement::CommentOn { comment, .. } => {
2552 let CommentOnStatement {
2553 if_exists,
2554 target,
2555 name,
2556 constraint_table,
2557 comment,
2558 ..
2559 } = comment.as_ref();
2560 f.write_str("COMMENT ")?;
2561 if *if_exists {
2562 f.write_str("IF EXISTS ")?;
2563 }
2564 f.write_str("ON ")?;
2565 f.write_str(match target {
2566 CommentTarget::Table => "TABLE ",
2567 CommentTarget::Column => "COLUMN ",
2568 CommentTarget::Database => "DATABASE ",
2569 CommentTarget::View => "VIEW ",
2570 CommentTarget::MaterializedView => "MATERIALIZED VIEW ",
2571 CommentTarget::Index => "INDEX ",
2572 CommentTarget::Constraint => "CONSTRAINT ",
2573 CommentTarget::Procedure { .. } => "PROCEDURE ",
2574 })?;
2575 name.render(ctx, f)?;
2576 if let Some(table) = constraint_table {
2577 f.write_str(" ON ")?;
2578 table.render(ctx, f)?;
2579 }
2580 if let CommentTarget::Procedure {
2581 arg_types: Some(arg_types),
2582 } = target
2583 {
2584 f.write_str("(")?;
2585 render_comma_separated(arg_types, ctx, f)?;
2586 f.write_str(")")?;
2587 }
2588 f.write_str(" IS ")?;
2589 match comment {
2590 Some(literal) => literal.render(ctx, f)?,
2591 None => f.write_str("NULL")?,
2592 }
2593 Ok(())
2594 }
2595 Statement::Insert { insert, .. } => insert.render(ctx, f),
2596 Statement::Update { update, .. } => update.render(ctx, f),
2597 Statement::Delete { delete, .. } => delete.render(ctx, f),
2598 Statement::Merge { merge, .. } => merge.render(ctx, f),
2599 Statement::Transaction { transaction, .. } => transaction.render(ctx, f),
2600 Statement::Xa { xa, .. } => xa.render(ctx, f),
2601 Statement::Session { session, .. } => session.render(ctx, f),
2602 Statement::AccessControl { access, .. } => access.render(ctx, f),
2603 Statement::Copy { copy, .. } => copy.render(ctx, f),
2604 Statement::CopyInto { copy, .. } => copy.render(ctx, f),
2605 Statement::Export { export, .. } => export.render(ctx, f),
2606 Statement::Import { import, .. } => import.render(ctx, f),
2607 Statement::Explain { explain, .. } => explain.render(ctx, f),
2608 Statement::Describe { describe, .. } => describe.render(ctx, f),
2609 Statement::Show { show, .. } => show.render(ctx, f),
2610 Statement::Kill { kill, .. } => kill.render(ctx, f),
2611 Statement::Handler { handler, .. } => handler.render(ctx, f),
2612 Statement::Install { install, .. } => install.render(ctx, f),
2613 Statement::Uninstall { uninstall, .. } => uninstall.render(ctx, f),
2614 Statement::Shutdown { .. } => f.write_str("SHUTDOWN"),
2615 Statement::Restart { .. } => f.write_str("RESTART"),
2616 Statement::Clone { clone, .. } => clone.render(ctx, f),
2617 Statement::ImportTable { import_table, .. } => import_table.render(ctx, f),
2618 Statement::Help { help, .. } => help.render(ctx, f),
2619 Statement::Binlog { binlog, .. } => binlog.render(ctx, f),
2620 Statement::Pragma { pragma, .. } => pragma.render(ctx, f),
2621 Statement::Attach { attach, .. } => attach.render(ctx, f),
2622 Statement::Detach { detach, .. } => detach.render(ctx, f),
2623 Statement::Checkpoint { checkpoint, .. } => checkpoint.render(ctx, f),
2624 Statement::Load { load, .. } => load.render(ctx, f),
2625 Statement::LoadData { load_data, .. } => load_data.render(ctx, f),
2626 Statement::UpdateExtensions {
2627 update_extensions, ..
2628 } => update_extensions.render(ctx, f),
2629 Statement::Vacuum { vacuum, .. } => vacuum.render(ctx, f),
2630 Statement::Reindex { reindex, .. } => reindex.render(ctx, f),
2631 Statement::Analyze { analyze, .. } => analyze.render(ctx, f),
2632 Statement::TableMaintenance {
2633 table_maintenance, ..
2634 } => table_maintenance.render(ctx, f),
2635 Statement::CacheIndex { cache_index, .. } => cache_index.render(ctx, f),
2636 Statement::LoadIndex { load_index, .. } => load_index.render(ctx, f),
2637 Statement::Rename { rename, .. } => rename.render(ctx, f),
2638 Statement::Flush { flush, .. } => flush.render(ctx, f),
2639 Statement::Purge { purge, .. } => purge.render(ctx, f),
2640 Statement::Replication { replication, .. } => replication.render(ctx, f),
2641 Statement::CreateUser { create, .. } => create.render(ctx, f),
2642 Statement::AlterUser { alter, .. } => alter.render(ctx, f),
2643 Statement::UserRoleList { statement, .. } => statement.render(ctx, f),
2644 Statement::Use { use_statement, .. } => use_statement.render(ctx, f),
2645 Statement::CreateTrigger { create, .. } => create.render(ctx, f),
2646 Statement::CreateStoredTrigger { create, .. } => create.render(ctx, f),
2647 Statement::CreateMacro { create, .. } => create.render(ctx, f),
2648 Statement::CreateSecret { create, .. } => create.render(ctx, f),
2649 Statement::DropSecret { drop, .. } => drop.render(ctx, f),
2650 Statement::CreateType { create, .. } => create.render(ctx, f),
2651 Statement::CreateVirtualTable { create, .. } => create.render(ctx, f),
2652 Statement::CreateSequence { create, .. } => create.render(ctx, f),
2653 Statement::CreateExtension { create, .. } => create.render(ctx, f),
2654 Statement::AlterExtension { alter, .. } => alter.render(ctx, f),
2655 Statement::CreateTablespace { create, .. } => create.render(ctx, f),
2656 Statement::AlterTablespace { alter, .. } => alter.render(ctx, f),
2657 Statement::DropTablespace { drop, .. } => drop.render(ctx, f),
2658 Statement::CreateLogfileGroup { create, .. } => create.render(ctx, f),
2659 Statement::AlterLogfileGroup { alter, .. } => alter.render(ctx, f),
2660 Statement::DropLogfileGroup { drop, .. } => drop.render(ctx, f),
2661 Statement::AlterObjectDepends { alter, .. } => alter.render(ctx, f),
2662 Statement::AlterSystem { alter, .. } => alter.render(ctx, f),
2663 Statement::AlterDatabase { alter, .. } => alter.render(ctx, f),
2664 Statement::AlterDatabaseOptions { alter, .. } => alter.render(ctx, f),
2665 Statement::CreateServer { create, .. } => create.render(ctx, f),
2666 Statement::AlterServer { alter, .. } => alter.render(ctx, f),
2667 Statement::DropServer { drop, .. } => drop.render(ctx, f),
2668 Statement::AlterInstance { alter, .. } => alter.render(ctx, f),
2669 Statement::CreateSpatialReferenceSystem { create, .. } => create.render(ctx, f),
2670 Statement::DropSpatialReferenceSystem { drop, .. } => drop.render(ctx, f),
2671 Statement::CreateResourceGroup { create, .. } => create.render(ctx, f),
2672 Statement::AlterResourceGroup { alter, .. } => alter.render(ctx, f),
2673 Statement::DropResourceGroup { drop, .. } => drop.render(ctx, f),
2674 Statement::AlterSequence { alter, .. } => alter.render(ctx, f),
2675 Statement::AlterObjectSchema { alter, .. } => alter.render(ctx, f),
2676 Statement::Pivot { pivot, .. } => pivot.render(ctx, f),
2677 Statement::Unpivot { unpivot, .. } => unpivot.render(ctx, f),
2678 Statement::ShowRef { show, .. } => show.render(ctx, f),
2682 Statement::Prepare { prepare, .. } => prepare.render(ctx, f),
2683 Statement::Execute { execute, .. } => execute.render(ctx, f),
2684 Statement::PrepareFrom { prepare_from, .. } => prepare_from.render(ctx, f),
2685 Statement::ExecuteUsing { execute_using, .. } => execute_using.render(ctx, f),
2686 Statement::Deallocate { deallocate, .. } => deallocate.render(ctx, f),
2687 Statement::Call { call, .. } => call.render(ctx, f),
2688 Statement::Do { do_block, .. } => do_block.render(ctx, f),
2689 Statement::DoExpressions { do_expressions, .. } => do_expressions.render(ctx, f),
2690 Statement::LockTables { lock_tables, .. } => lock_tables.render(ctx, f),
2691 Statement::UnlockTables { unlock_tables, .. } => unlock_tables.render(ctx, f),
2692 Statement::InstanceLock { instance_lock, .. } => instance_lock.render(ctx, f),
2693 Statement::Compound { compound, .. } => compound.render(ctx, f),
2694 Statement::If { if_statement, .. } => if_statement.render(ctx, f),
2695 Statement::Case { case_statement, .. } => case_statement.render(ctx, f),
2696 Statement::Loop { loop_statement, .. } => loop_statement.render(ctx, f),
2697 Statement::While {
2698 while_statement, ..
2699 } => while_statement.render(ctx, f),
2700 Statement::Repeat { repeat, .. } => repeat.render(ctx, f),
2701 Statement::Leave { leave, .. } => leave.render(ctx, f),
2702 Statement::Iterate { iterate, .. } => iterate.render(ctx, f),
2703 Statement::Return {
2704 return_statement, ..
2705 } => return_statement.render(ctx, f),
2706 Statement::OpenCursor { open, .. } => open.render(ctx, f),
2707 Statement::FetchCursor { fetch, .. } => fetch.render(ctx, f),
2708 Statement::CloseCursor { close, .. } => close.render(ctx, f),
2709 Statement::Signal { signal, .. } => signal.render_as(ctx, f, "SIGNAL"),
2710 Statement::Resignal { resignal, .. } => resignal.render_as(ctx, f, "RESIGNAL"),
2711 Statement::GetDiagnostics {
2712 get_diagnostics, ..
2713 } => get_diagnostics.render(ctx, f),
2714 Statement::Other { ext, .. } => ext.render(ctx, f),
2715 }
2716 }
2717}
2718
2719impl Render for RefreshMaterializedView {
2720 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2721 f.write_str("REFRESH MATERIALIZED VIEW")?;
2722 if self.concurrently {
2723 f.write_str(" CONCURRENTLY")?;
2724 }
2725 f.write_str(" ")?;
2726 self.name.render(ctx, f)?;
2727 match self.with_data {
2728 Some(true) => f.write_str(" WITH DATA"),
2729 Some(false) => f.write_str(" WITH NO DATA"),
2730 None => Ok(()),
2731 }
2732 }
2733}
2734
2735impl Render for CreateColocationGroup {
2736 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2737 f.write_str("CREATE COLOCATION GROUP")?;
2738 if self.if_not_exists {
2739 f.write_str(" IF NOT EXISTS")?;
2740 }
2741 f.write_str(" ")?;
2742 self.name.render(ctx, f)?;
2743 f.write_str(match self.partition {
2744 ColocationPartitionKind::Hash => " PARTITION BY HASH (",
2745 ColocationPartitionKind::Range => " PARTITION BY RANGE (",
2746 })?;
2747 render_ident_list(&self.columns, ctx, f)?;
2748 f.write_str(") SHARDS ")?;
2749 self.shards.render(ctx, f)
2750 }
2751}
2752
2753impl Render for DropColocationGroup {
2754 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2755 f.write_str("DROP COLOCATION GROUP")?;
2756 if self.if_exists {
2757 f.write_str(" IF EXISTS")?;
2758 }
2759 f.write_str(" ")?;
2760 self.name.render(ctx, f)
2761 }
2762}
2763
2764impl<X: Extension + Render> Render for Insert<X> {
2765 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2766 if let Some(with) = &self.with {
2767 with.render(ctx, f)?;
2768 f.write_str(" ")?;
2769 }
2770 f.write_str(match self.verb {
2776 InsertVerb::Insert => "INSERT",
2777 InsertVerb::Replace => "REPLACE",
2778 })?;
2779 if let Some(modifier) = self.modifier {
2780 f.write_str(match modifier {
2781 InsertModifier::Ignore => " IGNORE",
2782 InsertModifier::Overwrite => " OVERWRITE",
2783 })?;
2784 }
2785 if let Some(or_action) = self.or_action {
2786 f.write_str(" OR ")?;
2787 or_action.render(ctx, f)?;
2788 }
2789 f.write_str(" INTO ")?;
2790 self.target.render(ctx, f)?;
2791 if let Some(mode) = self.column_matching {
2792 f.write_str(match mode {
2793 InsertColumnMatching::ByName => " BY NAME",
2794 InsertColumnMatching::ByPosition => " BY POSITION",
2795 })?;
2796 }
2797 if let Some(overriding) = self.overriding {
2798 f.write_str(" ")?;
2799 overriding.render(ctx, f)?;
2800 }
2801 f.write_str(" ")?;
2802 self.source.render(ctx, f)?;
2803 render_table_alias(self.row_alias.as_ref(), ctx, f)?;
2806 if let Some(upsert) = &self.upsert {
2807 f.write_str(" ")?;
2808 upsert.render(ctx, f)?;
2809 }
2810 render_returning_clause(self.returning.as_ref(), ctx, f)
2811 }
2812}
2813
2814impl Render for InsertTarget {
2815 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2816 self.name.render(ctx, f)?;
2817 render_alias(self.alias.as_ref(), self.alias_spelling, ctx, f)?;
2818 if !self.columns.is_empty() {
2819 f.write_str(" (")?;
2820 render_ident_list(&self.columns, ctx, f)?;
2821 f.write_str(")")?;
2822 }
2823 Ok(())
2824 }
2825}
2826
2827impl Render for InsertOverriding {
2828 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2829 f.write_str(match self {
2830 Self::SystemValue => "OVERRIDING SYSTEM VALUE",
2831 Self::UserValue => "OVERRIDING USER VALUE",
2832 })
2833 }
2834}
2835
2836impl Render for ConflictResolution {
2837 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2838 f.write_str(match self {
2839 Self::Rollback => "ROLLBACK",
2840 Self::Abort => "ABORT",
2841 Self::Fail => "FAIL",
2842 Self::Ignore => "IGNORE",
2843 Self::Replace => "REPLACE",
2844 })
2845 }
2846}
2847
2848impl<X: Extension + Render> Render for InsertSource<X> {
2849 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2850 match self {
2851 Self::DefaultValues { default, .. } => {
2852 default.render(ctx, f)?;
2853 f.write_str(" VALUES")
2854 }
2855 Self::Values { values, .. } => values.render(ctx, f),
2856 Self::Query { query, .. } => query.render(ctx, f),
2857 Self::Set { assignments, .. } => {
2858 f.write_str("SET ")?;
2859 render_update_assignments(assignments, ctx, f)
2860 }
2861 }
2862 }
2863}
2864
2865impl<X: Extension + Render> Render for InsertValues<X> {
2866 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2867 f.write_str("VALUES ")?;
2869 render_values_rows(&self.rows, false, ctx, f)
2870 }
2871}
2872
2873impl<X: Extension + Render> Render for InsertValue<X> {
2874 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2875 match self {
2876 Self::Expr { expr, .. } => expr.render(ctx, f),
2877 Self::Default { default, .. } => default.render(ctx, f),
2878 }
2879 }
2880}
2881
2882impl Render for DefaultValue {
2883 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2884 f.write_str("DEFAULT")
2885 }
2886}
2887
2888impl Render for DmlTarget {
2889 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2890 render_relation_inheritance(&self.inheritance, &self.name, ctx, f)?;
2891 render_alias(self.alias.as_ref(), self.alias_spelling, ctx, f)
2892 }
2893}
2894
2895impl<X: Extension + Render> Render for Update<X> {
2896 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2897 if let Some(with) = &self.with {
2898 with.render(ctx, f)?;
2899 f.write_str(" ")?;
2900 }
2901 f.write_str("UPDATE")?;
2902 if let Some(or_action) = self.or_action {
2903 f.write_str(" OR ")?;
2904 or_action.render(ctx, f)?;
2905 }
2906 f.write_str(" ")?;
2907 self.target.render(ctx, f)?;
2908 for join in &self.target_joins {
2909 f.write_str(" ")?;
2910 join.render(ctx, f)?;
2911 }
2912 f.write_str(" SET ")?;
2913 render_update_assignments(&self.assignments, ctx, f)?;
2914 if !self.from.is_empty() {
2915 f.write_str(" FROM ")?;
2916 render_comma_separated(&self.from, ctx, f)?;
2917 }
2918 render_dml_selection(self.selection.as_ref(), ctx, f)?;
2919 render_mutation_order_by_limit(&self.order_by, self.limit.as_ref(), ctx, f)?;
2920 render_returning_clause(self.returning.as_ref(), ctx, f)
2921 }
2922}
2923
2924impl<X: Extension + Render> Render for UpdateAssignment<X> {
2925 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2926 match self {
2927 Self::Single { target, value, .. } => {
2928 target.render(ctx, f)?;
2929 f.write_str(" = ")?;
2930 value.render(ctx, f)
2931 }
2932 Self::Tuple {
2933 targets, source, ..
2934 } => {
2935 f.write_str("(")?;
2936 render_comma_separated(targets, ctx, f)?;
2937 f.write_str(") = ")?;
2938 source.render(ctx, f)
2939 }
2940 }
2941 }
2942}
2943
2944impl<X: Extension + Render> Render for UpdateValue<X> {
2945 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2946 match self {
2947 Self::Expr { expr, .. } => expr.render(ctx, f),
2948 Self::Default { default, .. } => default.render(ctx, f),
2949 }
2950 }
2951}
2952
2953impl<X: Extension + Render> Render for UpdateTupleSource<X> {
2954 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2955 match self {
2956 Self::Row {
2957 explicit, values, ..
2958 } => {
2959 f.write_str(if *explicit { "ROW(" } else { "(" })?;
2960 render_comma_separated(values, ctx, f)?;
2961 f.write_str(")")
2962 }
2963 Self::Subquery { query, .. } => {
2964 f.write_str("(")?;
2965 query.render(ctx, f)?;
2966 f.write_str(")")
2967 }
2968 Self::Default { default, .. } => default.render(ctx, f),
2969 }
2970 }
2971}
2972
2973impl<X: Extension + Render> Render for Delete<X> {
2974 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2975 if let Some(with) = &self.with {
2976 with.render(ctx, f)?;
2977 f.write_str(" ")?;
2978 }
2979 f.write_str("DELETE FROM ")?;
2980 self.target.render(ctx, f)?;
2981 for target in &self.additional_targets {
2982 f.write_str(", ")?;
2983 target.render(ctx, f)?;
2984 }
2985 for join in &self.target_joins {
2986 f.write_str(" ")?;
2987 join.render(ctx, f)?;
2988 }
2989 if !self.using.is_empty() {
2990 f.write_str(" USING ")?;
2991 render_comma_separated(&self.using, ctx, f)?;
2992 }
2993 render_dml_selection(self.selection.as_ref(), ctx, f)?;
2994 render_mutation_order_by_limit(&self.order_by, self.limit.as_ref(), ctx, f)?;
2995 render_returning_clause(self.returning.as_ref(), ctx, f)
2996 }
2997}
2998
2999fn render_update_assignments<X: Extension + Render>(
3006 assignments: &[UpdateAssignment<X>],
3007 ctx: &RenderCtx<'_>,
3008 f: &mut fmt::Formatter<'_>,
3009) -> fmt::Result {
3010 for (i, assignment) in assignments.iter().enumerate() {
3011 if i > 0 {
3012 f.write_str(", ")?;
3013 }
3014 assignment.render(ctx, f)?;
3015 }
3016 Ok(())
3017}
3018
3019fn render_dml_selection<X: Extension + Render>(
3020 selection: Option<&DmlSelection<X>>,
3021 ctx: &RenderCtx<'_>,
3022 f: &mut fmt::Formatter<'_>,
3023) -> fmt::Result {
3024 if let Some(selection) = selection {
3025 f.write_str(" WHERE ")?;
3026 selection.render(ctx, f)?;
3027 }
3028 Ok(())
3029}
3030
3031impl<X: Extension + Render> Render for DmlSelection<X> {
3032 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3033 match self {
3034 Self::Where { condition, .. } => condition.render(ctx, f),
3035 Self::CurrentOf { cursor, .. } => {
3036 f.write_str("CURRENT OF ")?;
3037 cursor.render(ctx, f)
3038 }
3039 }
3040 }
3041}
3042
3043fn render_mutation_order_by_limit<X: Extension + Render>(
3047 order_by: &[OrderByExpr<X>],
3048 limit: Option<&Limit<X>>,
3049 ctx: &RenderCtx<'_>,
3050 f: &mut fmt::Formatter<'_>,
3051) -> fmt::Result {
3052 if !order_by.is_empty() {
3053 f.write_str(" ORDER BY ")?;
3054 render_comma_separated(order_by, ctx, f)?;
3055 }
3056 if let Some(limit) = limit {
3057 f.write_str(" ")?;
3058 limit.render(ctx, f)?;
3059 }
3060 Ok(())
3061}
3062
3063fn render_returning_clause<X: Extension + Render>(
3066 returning: Option<&Returning<X>>,
3067 ctx: &RenderCtx<'_>,
3068 f: &mut fmt::Formatter<'_>,
3069) -> fmt::Result {
3070 if let Some(returning) = returning {
3071 f.write_str(" ")?;
3072 returning.render(ctx, f)?;
3073 }
3074 Ok(())
3075}
3076
3077impl<X: Extension + Render> Render for Returning<X> {
3078 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3079 f.write_str("RETURNING ")?;
3080 render_comma_separated(&self.items, ctx, f)
3081 }
3082}
3083
3084impl<X: Extension + Render> Render for Upsert<X> {
3085 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3086 match self {
3087 Upsert::OnConflict { conflict, .. } => conflict.render(ctx, f),
3088 Upsert::OnDuplicateKeyUpdate { assignments, .. } => {
3089 f.write_str("ON DUPLICATE KEY UPDATE ")?;
3090 render_update_assignments(assignments, ctx, f)
3091 }
3092 }
3093 }
3094}
3095
3096impl<X: Extension + Render> Render for OnConflict<X> {
3097 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3098 f.write_str("ON CONFLICT")?;
3099 if let Some(target) = &self.target {
3100 f.write_str(" ")?;
3101 target.render(ctx, f)?;
3102 }
3103 f.write_str(" ")?;
3104 self.action.render(ctx, f)
3105 }
3106}
3107
3108impl<X: Extension + Render> Render for ConflictTarget<X> {
3109 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3110 match self {
3111 ConflictTarget::Index {
3112 columns, predicate, ..
3113 } => {
3114 f.write_str("(")?;
3115 render_comma_separated(columns, ctx, f)?;
3116 f.write_str(")")?;
3117 if let Some(predicate) = predicate {
3118 f.write_str(" WHERE ")?;
3119 predicate.render(ctx, f)?;
3120 }
3121 Ok(())
3122 }
3123 ConflictTarget::Constraint { name, .. } => {
3124 f.write_str("ON CONSTRAINT ")?;
3125 name.render(ctx, f)
3126 }
3127 }
3128 }
3129}
3130
3131impl<X: Extension + Render> Render for ConflictAction<X> {
3132 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3133 match self {
3134 ConflictAction::Nothing { .. } => f.write_str("DO NOTHING"),
3135 ConflictAction::Update {
3136 assignments,
3137 selection,
3138 ..
3139 } => {
3140 f.write_str("DO UPDATE SET ")?;
3141 render_update_assignments(assignments, ctx, f)?;
3142 if let Some(selection) = selection {
3143 f.write_str(" WHERE ")?;
3144 selection.render(ctx, f)?;
3145 }
3146 Ok(())
3147 }
3148 }
3149 }
3150}
3151
3152impl<X: Extension + Render> Render for Merge<X> {
3153 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3154 if let Some(with) = &self.with {
3155 with.render(ctx, f)?;
3156 f.write_str(" ")?;
3157 }
3158 f.write_str("MERGE INTO ")?;
3159 self.target.render(ctx, f)?;
3160 f.write_str(" USING ")?;
3161 self.using.render(ctx, f)?;
3162 f.write_str(" ON ")?;
3163 self.on.render(ctx, f)?;
3164 for clause in &self.clauses {
3165 f.write_str(" ")?;
3166 clause.render(ctx, f)?;
3167 }
3168 render_returning_clause(self.returning.as_ref(), ctx, f)
3169 }
3170}
3171
3172impl<X: Extension + Render> Render for MergeWhenClause<X> {
3173 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3174 f.write_str(match self.match_kind {
3178 MergeMatchKind::Matched => "WHEN MATCHED",
3179 MergeMatchKind::NotMatchedByTarget => "WHEN NOT MATCHED",
3180 MergeMatchKind::NotMatchedBySource => "WHEN NOT MATCHED BY SOURCE",
3181 })?;
3182 if let Some(condition) = &self.condition {
3183 f.write_str(" AND ")?;
3184 condition.render(ctx, f)?;
3185 }
3186 f.write_str(" THEN ")?;
3187 self.action.render(ctx, f)
3188 }
3189}
3190
3191impl<X: Extension + Render> Render for MergeAction<X> {
3192 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3193 match self {
3194 MergeAction::Insert {
3195 columns,
3196 overriding,
3197 values,
3198 additional_rows,
3199 ..
3200 } => {
3201 f.write_str("INSERT")?;
3202 if !columns.is_empty() {
3203 f.write_str(" (")?;
3204 render_ident_list(columns, ctx, f)?;
3205 f.write_str(")")?;
3206 }
3207 if let Some(overriding) = overriding {
3208 f.write_str(" ")?;
3209 overriding.render(ctx, f)?;
3210 }
3211 f.write_str(" VALUES (")?;
3212 render_comma_separated(values, ctx, f)?;
3213 f.write_str(")")?;
3214 for row in additional_rows {
3215 f.write_str(", (")?;
3216 render_comma_separated(row, ctx, f)?;
3217 f.write_str(")")?;
3218 }
3219 Ok(())
3220 }
3221 MergeAction::InsertDefault { default, .. } => {
3222 f.write_str("INSERT ")?;
3223 default.render(ctx, f)?;
3224 f.write_str(" VALUES")
3225 }
3226 MergeAction::Update { assignments, .. } => {
3227 f.write_str("UPDATE SET ")?;
3228 render_update_assignments(assignments, ctx, f)
3229 }
3230 MergeAction::UpdateStar { .. } => f.write_str("UPDATE SET *"),
3231 MergeAction::InsertStar { .. } => f.write_str("INSERT *"),
3232 MergeAction::InsertByName { star, .. } => {
3233 f.write_str("INSERT BY NAME")?;
3234 if *star {
3235 f.write_str(" *")?;
3236 }
3237 Ok(())
3238 }
3239 MergeAction::Error { .. } => f.write_str("ERROR"),
3240 MergeAction::Delete { .. } => f.write_str("DELETE"),
3241 MergeAction::DoNothing { .. } => f.write_str("DO NOTHING"),
3242 }
3243 }
3244}
3245
3246impl Render for TransactionStatement {
3247 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3248 match self {
3249 Self::Begin {
3250 syntax,
3251 mode,
3252 block,
3253 name,
3254 modes,
3255 ..
3256 } => {
3257 match syntax {
3258 TransactionStart::Begin => f.write_str("BEGIN")?,
3259 TransactionStart::Start => {
3260 f.write_str("START")?;
3261 if honours_source_spelling(ctx) {
3262 render_transaction_block_keyword(*block, f)?;
3263 } else {
3264 f.write_str(" TRANSACTION")?;
3265 }
3266 }
3267 }
3268 if let Some(mode) = mode {
3269 f.write_str(" ")?;
3270 mode.render(ctx, f)?;
3271 }
3272 if *syntax == TransactionStart::Begin {
3277 render_transaction_block_and_name(*block, name.as_deref(), ctx, f)?;
3278 }
3279 render_transaction_modes(modes, ctx, f)
3280 }
3281 Self::Commit {
3282 syntax,
3283 block,
3284 name,
3285 chain,
3286 release,
3287 ..
3288 } => {
3289 if honours_source_spelling(ctx) && *syntax == TransactionCommitKeyword::End {
3290 f.write_str("END")?;
3291 } else {
3292 f.write_str("COMMIT")?;
3293 }
3294 render_transaction_block_and_name(*block, name.as_deref(), ctx, f)?;
3295 render_transaction_completion(*chain, *release, f)
3296 }
3297 Self::Rollback {
3298 syntax,
3299 block,
3300 name,
3301 savepoint_keyword,
3302 to_savepoint,
3303 chain,
3304 release,
3305 ..
3306 } => {
3307 if honours_source_spelling(ctx) && *syntax == TransactionRollbackKeyword::Abort {
3308 f.write_str("ABORT")?;
3309 } else {
3310 f.write_str("ROLLBACK")?;
3311 }
3312 render_transaction_block_and_name(*block, name.as_deref(), ctx, f)?;
3313 if let Some(name) = to_savepoint {
3314 if *savepoint_keyword || !honours_source_spelling(ctx) {
3318 f.write_str(" TO SAVEPOINT ")?;
3319 } else {
3320 f.write_str(" TO ")?;
3321 }
3322 name.render(ctx, f)?;
3323 }
3324 render_transaction_completion(*chain, *release, f)
3325 }
3326 Self::Savepoint { name, .. } => {
3327 f.write_str("SAVEPOINT ")?;
3328 name.render(ctx, f)
3329 }
3330 Self::Release {
3331 savepoint_keyword,
3332 savepoint,
3333 ..
3334 } => {
3335 if *savepoint_keyword || !honours_source_spelling(ctx) {
3338 f.write_str("RELEASE SAVEPOINT ")?;
3339 } else {
3340 f.write_str("RELEASE ")?;
3341 }
3342 savepoint.render(ctx, f)
3343 }
3344 Self::SetCharacteristics { modes, .. } => {
3345 f.write_str("SET TRANSACTION")?;
3346 render_transaction_modes(modes, ctx, f)
3347 }
3348 }
3349 }
3350}
3351
3352fn render_transaction_chain(chain: Option<bool>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3353 match chain {
3354 Some(true) => f.write_str(" AND CHAIN"),
3355 Some(false) => f.write_str(" AND NO CHAIN"),
3356 None => Ok(()),
3357 }
3358}
3359
3360fn render_transaction_completion(
3361 chain: Option<bool>,
3362 release: Option<bool>,
3363 f: &mut fmt::Formatter<'_>,
3364) -> fmt::Result {
3365 render_transaction_chain(chain, f)?;
3366 match release {
3367 Some(true) => f.write_str(" RELEASE"),
3368 Some(false) => f.write_str(" NO RELEASE"),
3369 None => Ok(()),
3370 }
3371}
3372
3373fn render_transaction_block_keyword(
3378 block: Option<TransactionBlockKeyword>,
3379 f: &mut fmt::Formatter<'_>,
3380) -> fmt::Result {
3381 match block {
3382 Some(TransactionBlockKeyword::Transaction) => f.write_str(" TRANSACTION"),
3383 Some(TransactionBlockKeyword::Work) => f.write_str(" WORK"),
3384 None => Ok(()),
3385 }
3386}
3387
3388fn render_transaction_block_and_name(
3389 block: Option<TransactionBlockKeyword>,
3390 name: Option<&Ident>,
3391 ctx: &RenderCtx<'_>,
3392 f: &mut fmt::Formatter<'_>,
3393) -> fmt::Result {
3394 if let Some(name) = name {
3395 f.write_str(" TRANSACTION ")?;
3396 name.render(ctx, f)
3397 } else if honours_source_spelling(ctx) {
3398 render_transaction_block_keyword(block, f)
3399 } else {
3400 Ok(())
3401 }
3402}
3403
3404fn render_transaction_modes(
3407 modes: &[TransactionMode],
3408 ctx: &RenderCtx<'_>,
3409 f: &mut fmt::Formatter<'_>,
3410) -> fmt::Result {
3411 render_leading_space_comma_separated(modes, ctx, f)
3412}
3413
3414impl Render for TransactionModeKind {
3415 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3416 f.write_str(match self {
3417 Self::Deferred => "DEFERRED",
3418 Self::Immediate => "IMMEDIATE",
3419 Self::Exclusive => "EXCLUSIVE",
3420 })
3421 }
3422}
3423
3424impl Render for TransactionMode {
3425 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3426 match self {
3427 Self::IsolationLevel { level, .. } => {
3428 f.write_str("ISOLATION LEVEL ")?;
3429 level.render(ctx, f)
3430 }
3431 Self::AccessMode { access, .. } => access.render(ctx, f),
3432 Self::Deferrable { deferrable, .. } => f.write_str(if *deferrable {
3433 "DEFERRABLE"
3434 } else {
3435 "NOT DEFERRABLE"
3436 }),
3437 Self::ConsistentSnapshot { .. } => f.write_str("WITH CONSISTENT SNAPSHOT"),
3438 }
3439 }
3440}
3441
3442impl Render for IsolationLevel {
3443 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3444 f.write_str(match self {
3445 Self::ReadUncommitted => "READ UNCOMMITTED",
3446 Self::ReadCommitted => "READ COMMITTED",
3447 Self::RepeatableRead => "REPEATABLE READ",
3448 Self::Serializable => "SERIALIZABLE",
3449 })
3450 }
3451}
3452
3453impl Render for TransactionAccessMode {
3454 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3455 f.write_str(match self {
3456 Self::ReadOnly => "READ ONLY",
3457 Self::ReadWrite => "READ WRITE",
3458 })
3459 }
3460}
3461
3462impl Render for XaStatement {
3463 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3464 match self {
3465 Self::Start {
3466 keyword,
3467 xid,
3468 association,
3469 ..
3470 } => {
3471 f.write_str(match keyword {
3472 XaStartKeyword::Start => "XA START ",
3473 XaStartKeyword::Begin => "XA BEGIN ",
3474 })?;
3475 xid.render(ctx, f)?;
3476 if let Some(association) = association {
3477 f.write_str(match association {
3478 XaAssociation::Join => " JOIN",
3479 XaAssociation::Resume => " RESUME",
3480 })?;
3481 }
3482 Ok(())
3483 }
3484 Self::End { xid, suspend, .. } => {
3485 f.write_str("XA END ")?;
3486 xid.render(ctx, f)?;
3487 if let Some(suspend) = suspend {
3488 f.write_str(match suspend {
3489 XaSuspend::Suspend => " SUSPEND",
3490 XaSuspend::SuspendForMigrate => " SUSPEND FOR MIGRATE",
3491 })?;
3492 }
3493 Ok(())
3494 }
3495 Self::Prepare { xid, .. } => {
3496 f.write_str("XA PREPARE ")?;
3497 xid.render(ctx, f)
3498 }
3499 Self::Commit { xid, one_phase, .. } => {
3500 f.write_str("XA COMMIT ")?;
3501 xid.render(ctx, f)?;
3502 if *one_phase {
3503 f.write_str(" ONE PHASE")?;
3504 }
3505 Ok(())
3506 }
3507 Self::Rollback { xid, .. } => {
3508 f.write_str("XA ROLLBACK ")?;
3509 xid.render(ctx, f)
3510 }
3511 Self::Recover { convert_xid, .. } => {
3512 f.write_str("XA RECOVER")?;
3513 if *convert_xid {
3514 f.write_str(" CONVERT XID")?;
3515 }
3516 Ok(())
3517 }
3518 }
3519 }
3520}
3521
3522impl Render for Xid {
3523 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3524 self.gtrid.render(ctx, f)?;
3525 if let Some(bqual) = &self.bqual {
3526 f.write_str(", ")?;
3527 bqual.render(ctx, f)?;
3528 }
3529 if let Some(format_id) = &self.format_id {
3530 f.write_str(", ")?;
3531 format_id.render(ctx, f)?;
3532 }
3533 Ok(())
3534 }
3535}
3536
3537impl<X: Extension + Render> Render for SessionStatement<X> {
3538 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3539 match self {
3540 Self::Set {
3541 scope,
3542 name,
3543 assignment,
3544 value,
3545 ..
3546 } => {
3547 f.write_str("SET")?;
3548 render_set_scope(*scope, ctx, f)?;
3549 f.write_str(" ")?;
3550 name.render(ctx, f)?;
3551 f.write_str(match assignment {
3554 SetAssignment::Equals if honours_source_spelling(ctx) => " = ",
3555 _ => " TO ",
3556 })?;
3557 value.render(ctx, f)
3558 }
3559 Self::SetTimeZone { scope, value, .. } => {
3560 f.write_str("SET")?;
3561 render_set_scope(*scope, ctx, f)?;
3562 f.write_str(" TIME ZONE ")?;
3563 value.render(ctx, f)
3564 }
3565 Self::SetRole { scope, role, .. } => {
3566 f.write_str("SET")?;
3567 render_set_scope(*scope, ctx, f)?;
3568 f.write_str(" ROLE ")?;
3569 role.render(ctx, f)
3570 }
3571 Self::SetSessionAuthorization { scope, user, .. } => {
3572 f.write_str("SET")?;
3573 render_set_scope(*scope, ctx, f)?;
3574 f.write_str(" SESSION AUTHORIZATION ")?;
3575 user.render(ctx, f)
3576 }
3577 Self::SetConstraints {
3578 constraints,
3579 check_time,
3580 ..
3581 } => {
3582 f.write_str("SET CONSTRAINTS ")?;
3583 constraints.render(ctx, f)?;
3584 f.write_str(" ")?;
3585 check_time.render(ctx, f)
3586 }
3587 Self::SetNames { value, .. } => {
3588 f.write_str("SET NAMES ")?;
3589 value.render(ctx, f)
3590 }
3591 Self::SetSessionCharacteristics { modes, .. } => {
3592 f.write_str("SET SESSION CHARACTERISTICS AS TRANSACTION")?;
3593 render_transaction_modes(modes, ctx, f)
3594 }
3595 Self::Reset { scope, target, .. } => {
3596 f.write_str("RESET")?;
3597 render_set_scope(*scope, ctx, f)?;
3598 f.write_str(" ")?;
3599 target.render(ctx, f)
3600 }
3601 Self::Show {
3602 target, verbose, ..
3603 } => {
3604 f.write_str("SHOW ")?;
3605 target.render(ctx, f)?;
3606 if *verbose {
3607 f.write_str(" VERBOSE")?;
3608 }
3609 Ok(())
3610 }
3611 Self::SetVariables { assignments, .. } => {
3612 f.write_str("SET ")?;
3613 render_comma_separated(assignments, ctx, f)
3614 }
3615 Self::SetCharacterSet { keyword, value, .. } => {
3616 f.write_str(match keyword {
3617 CharacterSetKeyword::CharacterSet => "SET CHARACTER SET ",
3618 CharacterSetKeyword::Charset => "SET CHARSET ",
3619 })?;
3620 value.render(ctx, f)
3621 }
3622 Self::SetResourceGroup {
3623 name, thread_ids, ..
3624 } => {
3625 f.write_str("SET RESOURCE GROUP ")?;
3626 name.render(ctx, f)?;
3627 if let Some(thread_ids) = thread_ids {
3628 f.write_str(" FOR ")?;
3629 render_comma_separated(thread_ids, ctx, f)?;
3630 }
3631 Ok(())
3632 }
3633 }
3634 }
3635}
3636
3637impl<X: Extension + Render> Render for SetVariableAssignment<X> {
3638 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3639 match self {
3640 Self::SystemVariable {
3641 scope,
3642 name,
3643 assignment,
3644 value,
3645 ..
3646 } => {
3647 scope.render_prefix(name, ctx, f)?;
3648 render_mysql_set_assignment(*assignment, ctx, f)?;
3649 value.render(ctx, f)
3650 }
3651 Self::UserVariable {
3652 name,
3653 assignment,
3654 value,
3655 ..
3656 } => {
3657 f.write_str("@")?;
3658 name.render(ctx, f)?;
3659 render_mysql_set_assignment(*assignment, ctx, f)?;
3660 value.render(ctx, f)
3661 }
3662 }
3663 }
3664}
3665
3666fn render_mysql_set_assignment(
3670 assignment: SetAssignment,
3671 ctx: &RenderCtx<'_>,
3672 f: &mut fmt::Formatter<'_>,
3673) -> fmt::Result {
3674 f.write_str(match assignment {
3675 SetAssignment::ColonEquals if honours_source_spelling(ctx) => " := ",
3676 _ => " = ",
3677 })
3678}
3679
3680impl SystemVariableScope {
3681 fn render_prefix(
3684 self,
3685 name: &ObjectName,
3686 ctx: &RenderCtx<'_>,
3687 f: &mut fmt::Formatter<'_>,
3688 ) -> fmt::Result {
3689 match self {
3690 Self::Implicit => name.render(ctx, f),
3691 Self::Keyword(kind) => {
3692 kind.render(ctx, f)?;
3693 f.write_str(" ")?;
3694 name.render(ctx, f)
3695 }
3696 Self::AtAt => {
3697 f.write_str("@@")?;
3698 name.render(ctx, f)
3699 }
3700 Self::AtAtScoped(kind) => {
3701 f.write_str("@@")?;
3704 f.write_str(kind.at_at_prefix())?;
3705 f.write_str(".")?;
3706 name.render(ctx, f)
3707 }
3708 }
3709 }
3710}
3711
3712impl SystemVariableScopeKind {
3713 fn at_at_prefix(self) -> &'static str {
3716 match self {
3717 Self::Global => "global",
3718 Self::Session => "session",
3719 Self::Local => "local",
3720 Self::Persist => "persist",
3721 Self::PersistOnly => "persist_only",
3722 }
3723 }
3724}
3725
3726impl Render for SystemVariableScopeKind {
3727 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3729 f.write_str(match self {
3730 Self::Global => "GLOBAL",
3731 Self::Session => "SESSION",
3732 Self::Local => "LOCAL",
3733 Self::Persist => "PERSIST",
3734 Self::PersistOnly => "PERSIST_ONLY",
3735 })
3736 }
3737}
3738
3739impl<X: Extension + Render> Render for SetVariableValue<X> {
3740 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3741 match self {
3742 Self::Default { .. } => f.write_str("DEFAULT"),
3743 Self::Keyword { keyword, .. } => keyword.render(ctx, f),
3744 Self::Expr { expr, .. } => expr.render(ctx, f),
3745 }
3746 }
3747}
3748
3749impl Render for SetVariableKeyword {
3750 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3751 f.write_str(match self {
3752 Self::On => "ON",
3753 Self::All => "ALL",
3754 Self::Binary => "BINARY",
3755 Self::Row => "ROW",
3756 Self::System => "SYSTEM",
3757 })
3758 }
3759}
3760
3761impl Render for SetCharacterSetValue {
3762 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3763 match self {
3764 Self::Default { .. } => f.write_str("DEFAULT"),
3765 Self::Charset { charset, .. } => charset.render(ctx, f),
3766 }
3767 }
3768}
3769
3770impl Render for AlterSystem {
3771 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3772 f.write_str("ALTER SYSTEM ")?;
3773 match &self.action {
3774 AlterSystemAction::Set {
3775 name,
3776 assignment,
3777 value,
3778 ..
3779 } => {
3780 f.write_str("SET ")?;
3781 name.render(ctx, f)?;
3782 f.write_str(match assignment {
3785 SetAssignment::Equals if honours_source_spelling(ctx) => " = ",
3786 _ => " TO ",
3787 })?;
3788 value.render(ctx, f)
3789 }
3790 AlterSystemAction::Reset { target, .. } => {
3791 f.write_str("RESET ")?;
3792 target.render(ctx, f)
3793 }
3794 }
3795 }
3796}
3797
3798impl Render for AlterDatabase {
3799 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3800 f.write_str("ALTER DATABASE ")?;
3801 if self.if_exists {
3802 f.write_str("IF EXISTS ")?;
3803 }
3804 self.name.render(ctx, f)?;
3805 match &self.action {
3806 AlterDatabaseAction::SetAlias { new_name, .. } => {
3807 f.write_str(" SET ALIAS TO ")?;
3808 new_name.render(ctx, f)
3809 }
3810 }
3811 }
3812}
3813
3814impl Render for AlterDatabaseOptions {
3815 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3816 f.write_str(match self.spelling {
3817 DatabaseKeyword::Database => "ALTER DATABASE",
3818 DatabaseKeyword::Schema => "ALTER SCHEMA",
3819 })?;
3820 if let Some(name) = &self.name {
3821 f.write_str(" ")?;
3822 name.render(ctx, f)?;
3823 }
3824 for option in &self.options {
3825 f.write_str(" ")?;
3826 option.render(ctx, f)?;
3827 }
3828 Ok(())
3829 }
3830}
3831
3832impl Render for AlterDatabaseOption {
3833 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3834 let sep = |equals: bool| if equals { " = " } else { " " };
3837 match self {
3838 Self::CharacterSet {
3839 default,
3840 keyword,
3841 equals,
3842 charset,
3843 ..
3844 } => {
3845 if *default {
3846 f.write_str("DEFAULT ")?;
3847 }
3848 f.write_str(match keyword {
3849 CharsetKeyword::CharacterSet => "CHARACTER SET",
3850 CharsetKeyword::Charset => "CHARSET",
3851 })?;
3852 f.write_str(sep(*equals))?;
3853 charset.render(ctx, f)
3854 }
3855 Self::Collate {
3856 default,
3857 equals,
3858 collation,
3859 ..
3860 } => {
3861 if *default {
3862 f.write_str("DEFAULT ")?;
3863 }
3864 f.write_str("COLLATE")?;
3865 f.write_str(sep(*equals))?;
3866 collation.render(ctx, f)
3867 }
3868 Self::Encryption {
3869 default,
3870 equals,
3871 value,
3872 ..
3873 } => {
3874 if *default {
3875 f.write_str("DEFAULT ")?;
3876 }
3877 f.write_str("ENCRYPTION")?;
3878 f.write_str(sep(*equals))?;
3879 value.render(ctx, f)
3880 }
3881 Self::ReadOnly { equals, value, .. } => {
3882 f.write_str("READ ONLY")?;
3883 f.write_str(sep(*equals))?;
3884 f.write_str(match value {
3885 ReadOnlyValue::Default => "DEFAULT",
3886 ReadOnlyValue::Off => "0",
3887 ReadOnlyValue::On => "1",
3888 })
3889 }
3890 }
3891 }
3892}
3893
3894impl Render for CreateServer {
3895 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3896 f.write_str("CREATE SERVER ")?;
3897 self.name.render(ctx, f)?;
3898 f.write_str(" FOREIGN DATA WRAPPER ")?;
3899 self.wrapper.render(ctx, f)?;
3900 f.write_str(" OPTIONS (")?;
3901 render_server_options(&self.options, ctx, f)?;
3902 f.write_str(")")
3903 }
3904}
3905
3906impl Render for AlterServer {
3907 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3908 f.write_str("ALTER SERVER ")?;
3909 self.name.render(ctx, f)?;
3910 f.write_str(" OPTIONS (")?;
3911 render_server_options(&self.options, ctx, f)?;
3912 f.write_str(")")
3913 }
3914}
3915
3916impl Render for DropServer {
3917 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3918 f.write_str("DROP SERVER ")?;
3919 if self.if_exists {
3920 f.write_str("IF EXISTS ")?;
3921 }
3922 self.name.render(ctx, f)
3923 }
3924}
3925
3926fn render_server_options(
3929 options: &[ServerOption],
3930 ctx: &RenderCtx<'_>,
3931 f: &mut fmt::Formatter<'_>,
3932) -> fmt::Result {
3933 for (i, option) in options.iter().enumerate() {
3934 if i > 0 {
3935 f.write_str(", ")?;
3936 }
3937 option.render(ctx, f)?;
3938 }
3939 Ok(())
3940}
3941
3942impl Render for ServerOption {
3943 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3944 f.write_str(match self.kind {
3945 ServerOptionKind::Host => "HOST ",
3946 ServerOptionKind::Database => "DATABASE ",
3947 ServerOptionKind::User => "USER ",
3948 ServerOptionKind::Password => "PASSWORD ",
3949 ServerOptionKind::Socket => "SOCKET ",
3950 ServerOptionKind::Owner => "OWNER ",
3951 ServerOptionKind::Port => "PORT ",
3952 })?;
3953 self.value.render(ctx, f)
3954 }
3955}
3956
3957impl Render for CreateSpatialReferenceSystem {
3958 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3959 f.write_str("CREATE ")?;
3960 if self.or_replace {
3961 f.write_str("OR REPLACE ")?;
3962 }
3963 f.write_str("SPATIAL REFERENCE SYSTEM ")?;
3964 if self.if_not_exists {
3965 f.write_str("IF NOT EXISTS ")?;
3966 }
3967 self.srid.render(ctx, f)?;
3968 for attribute in &self.attributes {
3969 f.write_str(" ")?;
3970 attribute.render(ctx, f)?;
3971 }
3972 Ok(())
3973 }
3974}
3975
3976impl Render for SrsAttribute {
3977 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3978 match self {
3979 Self::Name { value, .. } => {
3980 f.write_str("NAME ")?;
3981 value.render(ctx, f)
3982 }
3983 Self::Definition { value, .. } => {
3984 f.write_str("DEFINITION ")?;
3985 value.render(ctx, f)
3986 }
3987 Self::Organization {
3988 organization,
3989 identifier,
3990 ..
3991 } => {
3992 f.write_str("ORGANIZATION ")?;
3993 organization.render(ctx, f)?;
3994 f.write_str(" IDENTIFIED BY ")?;
3995 identifier.render(ctx, f)
3996 }
3997 Self::Description { value, .. } => {
3998 f.write_str("DESCRIPTION ")?;
3999 value.render(ctx, f)
4000 }
4001 }
4002 }
4003}
4004
4005impl Render for DropSpatialReferenceSystem {
4006 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4007 f.write_str("DROP SPATIAL REFERENCE SYSTEM ")?;
4008 if self.if_exists {
4009 f.write_str("IF EXISTS ")?;
4010 }
4011 self.srid.render(ctx, f)
4012 }
4013}
4014
4015impl Render for CreateResourceGroup {
4016 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4017 f.write_str("CREATE RESOURCE GROUP ")?;
4018 self.name.render(ctx, f)?;
4019 f.write_str(if self.type_equals {
4020 " TYPE = "
4021 } else {
4022 " TYPE "
4023 })?;
4024 self.group_type.render(ctx, f)?;
4025 if let Some(vcpu) = &self.vcpu {
4026 f.write_str(" ")?;
4027 vcpu.render(ctx, f)?;
4028 }
4029 if let Some(priority) = &self.thread_priority {
4030 f.write_str(" ")?;
4031 priority.render(ctx, f)?;
4032 }
4033 if let Some(state) = &self.state {
4034 f.write_str(" ")?;
4035 state.render(ctx, f)?;
4036 }
4037 Ok(())
4038 }
4039}
4040
4041impl Render for AlterResourceGroup {
4042 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4043 f.write_str("ALTER RESOURCE GROUP ")?;
4044 self.name.render(ctx, f)?;
4045 if let Some(vcpu) = &self.vcpu {
4046 f.write_str(" ")?;
4047 vcpu.render(ctx, f)?;
4048 }
4049 if let Some(priority) = &self.thread_priority {
4050 f.write_str(" ")?;
4051 priority.render(ctx, f)?;
4052 }
4053 if let Some(state) = &self.state {
4054 f.write_str(" ")?;
4055 state.render(ctx, f)?;
4056 }
4057 if self.force {
4058 f.write_str(" FORCE")?;
4059 }
4060 Ok(())
4061 }
4062}
4063
4064impl Render for DropResourceGroup {
4065 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4066 f.write_str("DROP RESOURCE GROUP ")?;
4067 self.name.render(ctx, f)?;
4068 if self.force {
4069 f.write_str(" FORCE")?;
4070 }
4071 Ok(())
4072 }
4073}
4074
4075impl Render for ResourceGroupType {
4076 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4077 f.write_str(match self {
4078 Self::System => "SYSTEM",
4079 Self::User => "USER",
4080 })
4081 }
4082}
4083
4084impl Render for ResourceGroupState {
4085 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4086 f.write_str(match self {
4087 Self::Enable => "ENABLE",
4088 Self::Disable => "DISABLE",
4089 })
4090 }
4091}
4092
4093impl Render for ResourceGroupVcpu {
4094 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4095 f.write_str(if self.equals { "VCPU = " } else { "VCPU " })?;
4096 for (i, range) in self.ranges.iter().enumerate() {
4097 if i > 0 {
4098 f.write_str(", ")?;
4099 }
4100 range.render(ctx, f)?;
4101 }
4102 Ok(())
4103 }
4104}
4105
4106impl Render for VcpuRange {
4107 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4108 self.start.render(ctx, f)?;
4109 if let Some(end) = &self.end {
4110 f.write_str("-")?;
4111 end.render(ctx, f)?;
4112 }
4113 Ok(())
4114 }
4115}
4116
4117impl Render for ResourceGroupThreadPriority {
4118 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4119 f.write_str(if self.equals {
4120 "THREAD_PRIORITY = "
4121 } else {
4122 "THREAD_PRIORITY "
4123 })?;
4124 if self.negative {
4125 f.write_str("-")?;
4126 }
4127 self.value.render(ctx, f)
4128 }
4129}
4130
4131impl Render for AlterInstance {
4132 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4133 f.write_str("ALTER INSTANCE ")?;
4134 self.action.render(ctx, f)
4135 }
4136}
4137
4138impl Render for AlterInstanceAction {
4139 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4140 match self {
4141 Self::RotateInnodbMasterKey { .. } => f.write_str("ROTATE INNODB MASTER KEY"),
4142 Self::RotateBinlogMasterKey { .. } => f.write_str("ROTATE BINLOG MASTER KEY"),
4143 Self::ReloadTls {
4144 channel,
4145 no_rollback_on_error,
4146 ..
4147 } => {
4148 f.write_str("RELOAD TLS")?;
4149 if let Some(channel) = channel {
4150 f.write_str(" FOR CHANNEL ")?;
4151 channel.render(ctx, f)?;
4152 }
4153 if *no_rollback_on_error {
4154 f.write_str(" NO ROLLBACK ON ERROR")?;
4155 }
4156 Ok(())
4157 }
4158 Self::ReloadKeyring { .. } => f.write_str("RELOAD KEYRING"),
4159 Self::EnableInnodbRedoLog { .. } => f.write_str("ENABLE INNODB REDO_LOG"),
4160 Self::DisableInnodbRedoLog { .. } => f.write_str("DISABLE INNODB REDO_LOG"),
4161 }
4162 }
4163}
4164
4165impl<X: Extension + Render> Render for AlterSequence<X> {
4166 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4167 f.write_str("ALTER SEQUENCE ")?;
4168 if self.if_exists {
4169 f.write_str("IF EXISTS ")?;
4170 }
4171 self.name.render(ctx, f)?;
4172 for option in &self.options {
4175 f.write_str(" ")?;
4176 option.render(ctx, f)?;
4177 }
4178 Ok(())
4179 }
4180}
4181
4182impl<X: Extension + Render> Render for AlterSequenceOption<X> {
4183 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4184 match self {
4185 Self::Common { option, .. } => option.render(ctx, f),
4186 Self::Restart { value: None, .. } => f.write_str("RESTART"),
4187 Self::Restart {
4188 value: Some(expr), ..
4189 } => {
4190 f.write_str("RESTART WITH ")?;
4191 expr.render(ctx, f)
4192 }
4193 Self::As { data_type, .. } => {
4194 f.write_str("AS ")?;
4195 data_type.render(ctx, f)
4196 }
4197 Self::OwnedBy { owner: None, .. } => f.write_str("OWNED BY NONE"),
4198 Self::OwnedBy {
4199 owner: Some(name), ..
4200 } => {
4201 f.write_str("OWNED BY ")?;
4202 name.render(ctx, f)
4203 }
4204 Self::SequenceName { name, .. } => {
4205 f.write_str("SEQUENCE NAME ")?;
4206 name.render(ctx, f)
4207 }
4208 }
4209 }
4210}
4211
4212impl Render for AlterObjectSchema {
4213 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4214 f.write_str("ALTER ")?;
4215 f.write_str(match self.object_type {
4216 SchemaRelocationObject::Table => "TABLE ",
4217 SchemaRelocationObject::View => "VIEW ",
4218 SchemaRelocationObject::Sequence => "SEQUENCE ",
4219 })?;
4220 if self.if_exists {
4221 f.write_str("IF EXISTS ")?;
4222 }
4223 self.name.render(ctx, f)?;
4224 f.write_str(" SET SCHEMA ")?;
4225 self.new_schema.render(ctx, f)
4226 }
4227}
4228
4229fn render_set_scope(
4232 scope: Option<SetScope>,
4233 ctx: &RenderCtx<'_>,
4234 f: &mut fmt::Formatter<'_>,
4235) -> fmt::Result {
4236 if let Some(scope) = scope {
4237 f.write_str(" ")?;
4238 scope.render(ctx, f)?;
4239 }
4240 Ok(())
4241}
4242
4243impl Render for SpecialSetValue {
4244 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4245 match self {
4246 Self::Default { .. } => f.write_str("DEFAULT"),
4247 Self::Local { .. } => f.write_str("LOCAL"),
4248 Self::None { .. } => f.write_str("NONE"),
4249 Self::Value { value, .. } => value.render(ctx, f),
4250 }
4251 }
4252}
4253
4254impl Render for ConstraintsTarget {
4255 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4256 match self {
4257 Self::All { .. } => f.write_str("ALL"),
4258 Self::Names { names, .. } => render_comma_separated(names, ctx, f),
4259 }
4260 }
4261}
4262
4263impl Render for ConstraintCheckTime {
4264 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4265 f.write_str(match self {
4266 Self::Deferred => "DEFERRED",
4267 Self::Immediate => "IMMEDIATE",
4268 })
4269 }
4270}
4271
4272impl Render for SetNamesValue {
4273 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4274 match self {
4275 Self::Default { .. } => f.write_str("DEFAULT"),
4276 Self::Charset {
4277 charset, collation, ..
4278 } => {
4279 charset.render(ctx, f)?;
4280 if let Some(collation) = collation {
4281 f.write_str(" COLLATE ")?;
4282 collation.render(ctx, f)?;
4283 }
4284 Ok(())
4285 }
4286 }
4287 }
4288}
4289
4290impl Render for SetScope {
4291 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4292 f.write_str(match self {
4293 Self::Session => "SESSION",
4294 Self::Local => "LOCAL",
4295 Self::Global => "GLOBAL",
4296 })
4297 }
4298}
4299
4300impl Render for SetValue {
4301 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4302 match self {
4303 Self::Default { .. } => f.write_str("DEFAULT"),
4304 Self::Values { values, .. } => render_comma_separated(values, ctx, f),
4305 }
4306 }
4307}
4308
4309impl Render for SetParameterValue {
4310 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4311 match self {
4312 Self::Literal { literal, .. } => literal.render(ctx, f),
4313 Self::Name { name, .. } => name.render(ctx, f),
4314 Self::Parameter { kind, .. } => render_parameter_kind(*kind, ctx, f),
4315 Self::List { values, .. } => {
4316 f.write_str("[")?;
4317 render_comma_separated(values, ctx, f)?;
4318 f.write_str("]")
4319 }
4320 }
4321 }
4322}
4323
4324fn render_parameter_kind(
4325 kind: ParameterKind,
4326 ctx: &RenderCtx<'_>,
4327 f: &mut fmt::Formatter<'_>,
4328) -> fmt::Result {
4329 match kind {
4330 ParameterKind::Positional(index) => write!(f, "${index}"),
4331 ParameterKind::PositionalLarge { digits } => write!(f, "${}", ctx.resolve(digits)),
4332 ParameterKind::Numbered(index) => write!(f, "?{index}"),
4333 ParameterKind::Anonymous => f.write_str("?"),
4334 ParameterKind::Named { name, sigil } => {
4335 let sigil = match sigil {
4336 ParameterSigil::Colon => ':',
4337 ParameterSigil::At => '@',
4338 ParameterSigil::Dollar => '$',
4339 };
4340 write!(f, "{sigil}{}", ctx.resolve(name))
4341 }
4342 }
4343}
4344
4345impl Render for ConfigParameter {
4346 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4347 match self {
4348 Self::All { .. } => f.write_str("ALL"),
4349 Self::Named { name, .. } => name.render(ctx, f),
4350 }
4351 }
4352}
4353
4354impl<X: Extension + Render> Render for AccessControlStatement<X> {
4355 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4356 match self {
4357 Self::AlterRoleRename { name, new_name, .. } => {
4358 f.write_str("ALTER ROLE ")?;
4359 name.render(ctx, f)?;
4360 f.write_str(" RENAME TO ")?;
4361 new_name.render(ctx, f)
4362 }
4363 Self::Grant {
4364 privileges,
4365 object,
4366 grantees,
4367 with_grant_option,
4368 granted_by,
4369 ..
4370 } => {
4371 f.write_str("GRANT ")?;
4372 privileges.render(ctx, f)?;
4373 f.write_str(" ON ")?;
4374 object.render(ctx, f)?;
4375 f.write_str(" TO ")?;
4376 render_comma_separated(grantees, ctx, f)?;
4377 if *with_grant_option {
4378 f.write_str(" WITH GRANT OPTION")?;
4379 }
4380 render_granted_by(granted_by, ctx, f)
4381 }
4382 Self::Revoke {
4383 grant_option_for,
4384 privileges,
4385 object,
4386 grantees,
4387 granted_by,
4388 behavior,
4389 ..
4390 } => {
4391 f.write_str("REVOKE ")?;
4392 if *grant_option_for {
4393 f.write_str("GRANT OPTION FOR ")?;
4394 }
4395 privileges.render(ctx, f)?;
4396 f.write_str(" ON ")?;
4397 object.render(ctx, f)?;
4398 f.write_str(" FROM ")?;
4399 render_comma_separated(grantees, ctx, f)?;
4400 render_granted_by(granted_by, ctx, f)?;
4401 render_drop_behavior(*behavior, ctx, f)
4402 }
4403 Self::GrantRole {
4404 roles,
4405 grantees,
4406 with_admin_option,
4407 granted_by,
4408 ..
4409 } => {
4410 f.write_str("GRANT ")?;
4411 render_ident_list(roles, ctx, f)?;
4412 f.write_str(" TO ")?;
4413 render_comma_separated(grantees, ctx, f)?;
4414 if *with_admin_option {
4415 f.write_str(" WITH ADMIN OPTION")?;
4416 }
4417 render_granted_by(granted_by, ctx, f)
4418 }
4419 Self::RevokeRole {
4420 admin_option_for,
4421 roles,
4422 grantees,
4423 granted_by,
4424 behavior,
4425 ..
4426 } => {
4427 f.write_str("REVOKE ")?;
4428 if *admin_option_for {
4429 f.write_str("ADMIN OPTION FOR ")?;
4430 }
4431 render_ident_list(roles, ctx, f)?;
4432 f.write_str(" FROM ")?;
4433 render_comma_separated(grantees, ctx, f)?;
4434 render_granted_by(granted_by, ctx, f)?;
4435 render_drop_behavior(*behavior, ctx, f)
4436 }
4437 Self::AccountGrantPrivilege {
4438 privileges,
4439 object,
4440 grantees,
4441 with_grant_option,
4442 grant_as,
4443 ..
4444 } => {
4445 f.write_str("GRANT ")?;
4446 privileges.render(ctx, f)?;
4447 f.write_str(" ON ")?;
4448 object.render(ctx, f)?;
4449 f.write_str(" TO ")?;
4450 render_comma_separated(grantees, ctx, f)?;
4451 if *with_grant_option {
4452 f.write_str(" WITH GRANT OPTION")?;
4453 }
4454 if let Some(grant_as) = grant_as {
4455 f.write_str(" ")?;
4456 grant_as.render(ctx, f)?;
4457 }
4458 Ok(())
4459 }
4460 Self::AccountGrantProxy {
4461 proxy,
4462 grantees,
4463 with_grant_option,
4464 ..
4465 } => {
4466 f.write_str("GRANT PROXY ON ")?;
4467 proxy.render(ctx, f)?;
4468 f.write_str(" TO ")?;
4469 render_comma_separated(grantees, ctx, f)?;
4470 if *with_grant_option {
4471 f.write_str(" WITH GRANT OPTION")?;
4472 }
4473 Ok(())
4474 }
4475 Self::AccountGrantRole {
4476 roles,
4477 grantees,
4478 with_admin_option,
4479 ..
4480 } => {
4481 f.write_str("GRANT ")?;
4482 render_comma_separated(roles, ctx, f)?;
4483 f.write_str(" TO ")?;
4484 render_comma_separated(grantees, ctx, f)?;
4485 if *with_admin_option {
4486 f.write_str(" WITH ADMIN OPTION")?;
4487 }
4488 Ok(())
4489 }
4490 Self::AccountRevokePrivilege {
4491 if_exists,
4492 privileges,
4493 object,
4494 grantees,
4495 ignore_unknown_user,
4496 ..
4497 } => {
4498 f.write_str("REVOKE ")?;
4499 if *if_exists {
4500 f.write_str("IF EXISTS ")?;
4501 }
4502 privileges.render(ctx, f)?;
4503 f.write_str(" ON ")?;
4504 object.render(ctx, f)?;
4505 f.write_str(" FROM ")?;
4506 render_comma_separated(grantees, ctx, f)?;
4507 render_ignore_unknown_user(*ignore_unknown_user, f)
4508 }
4509 Self::AccountRevokeAll {
4510 if_exists,
4511 privileges_keyword,
4512 grantees,
4513 ignore_unknown_user,
4514 ..
4515 } => {
4516 f.write_str("REVOKE ")?;
4517 if *if_exists {
4518 f.write_str("IF EXISTS ")?;
4519 }
4520 if *privileges_keyword || !honours_source_spelling(ctx) {
4523 f.write_str("ALL PRIVILEGES, GRANT OPTION FROM ")?;
4524 } else {
4525 f.write_str("ALL, GRANT OPTION FROM ")?;
4526 }
4527 render_comma_separated(grantees, ctx, f)?;
4528 render_ignore_unknown_user(*ignore_unknown_user, f)
4529 }
4530 Self::AccountRevokeProxy {
4531 if_exists,
4532 proxy,
4533 grantees,
4534 ignore_unknown_user,
4535 ..
4536 } => {
4537 f.write_str("REVOKE ")?;
4538 if *if_exists {
4539 f.write_str("IF EXISTS ")?;
4540 }
4541 f.write_str("PROXY ON ")?;
4542 proxy.render(ctx, f)?;
4543 f.write_str(" FROM ")?;
4544 render_comma_separated(grantees, ctx, f)?;
4545 render_ignore_unknown_user(*ignore_unknown_user, f)
4546 }
4547 Self::AccountRevokeRole {
4548 if_exists,
4549 roles,
4550 grantees,
4551 ignore_unknown_user,
4552 ..
4553 } => {
4554 f.write_str("REVOKE ")?;
4555 if *if_exists {
4556 f.write_str("IF EXISTS ")?;
4557 }
4558 render_comma_separated(roles, ctx, f)?;
4559 f.write_str(" FROM ")?;
4560 render_comma_separated(grantees, ctx, f)?;
4561 render_ignore_unknown_user(*ignore_unknown_user, f)
4562 }
4563 }
4564 }
4565}
4566
4567fn render_ignore_unknown_user(
4569 ignore_unknown_user: bool,
4570 f: &mut fmt::Formatter<'_>,
4571) -> fmt::Result {
4572 if ignore_unknown_user {
4573 f.write_str(" IGNORE UNKNOWN USER")?;
4574 }
4575 Ok(())
4576}
4577
4578impl Render for PrivilegeLevelObject {
4579 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4580 match self.object_type {
4581 PrivilegeObjectType::Table { explicit } => {
4582 if explicit {
4583 f.write_str("TABLE ")?;
4584 }
4585 }
4586 PrivilegeObjectType::Function => f.write_str("FUNCTION ")?,
4587 PrivilegeObjectType::Procedure => f.write_str("PROCEDURE ")?,
4588 }
4589 self.level.render(ctx, f)
4590 }
4591}
4592
4593impl Render for PrivilegeLevel {
4594 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4595 match self {
4596 Self::Global { .. } => f.write_str("*.*"),
4597 Self::CurrentDatabase { .. } => f.write_str("*"),
4598 Self::Database { database, .. } => {
4599 database.render(ctx, f)?;
4600 f.write_str(".*")
4601 }
4602 Self::Object { name, .. } => name.render(ctx, f),
4603 }
4604 }
4605}
4606
4607impl Render for GrantAs {
4608 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4609 f.write_str("AS ")?;
4610 self.user.render(ctx, f)?;
4611 if let Some(with_role) = &self.with_role {
4612 f.write_str(" WITH ROLE ")?;
4613 with_role.render(ctx, f)?;
4614 }
4615 Ok(())
4616 }
4617}
4618
4619impl Render for WithRoleSpec {
4620 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4621 match self {
4622 Self::Roles { roles, .. } => render_comma_separated(roles, ctx, f),
4623 Self::All { except, .. } => {
4624 f.write_str("ALL")?;
4625 if !except.is_empty() {
4626 f.write_str(" EXCEPT ")?;
4627 render_comma_separated(except, ctx, f)?;
4628 }
4629 Ok(())
4630 }
4631 Self::None { .. } => f.write_str("NONE"),
4632 Self::Default { .. } => f.write_str("DEFAULT"),
4633 }
4634 }
4635}
4636
4637fn render_granted_by(
4639 granted_by: &Option<RoleSpec>,
4640 ctx: &RenderCtx<'_>,
4641 f: &mut fmt::Formatter<'_>,
4642) -> fmt::Result {
4643 if let Some(grantor) = granted_by {
4644 f.write_str(" GRANTED BY ")?;
4645 grantor.render(ctx, f)?;
4646 }
4647 Ok(())
4648}
4649
4650impl Render for Privileges {
4651 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4652 match self {
4653 Self::All {
4656 privileges_keyword, ..
4657 } => {
4658 if *privileges_keyword || !honours_source_spelling(ctx) {
4659 f.write_str("ALL PRIVILEGES")
4660 } else {
4661 f.write_str("ALL")
4662 }
4663 }
4664 Self::List { privileges, .. } => render_comma_separated(privileges, ctx, f),
4665 }
4666 }
4667}
4668
4669impl Render for Privilege {
4670 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4671 match self {
4672 Self::Known { kind, columns, .. } => {
4673 kind.render(ctx, f)?;
4674 render_privilege_columns(columns, ctx, f)
4675 }
4676 Self::Other { name, columns, .. } => {
4677 name.render(ctx, f)?;
4678 render_privilege_columns(columns, ctx, f)
4679 }
4680 }
4681 }
4682}
4683
4684fn render_privilege_columns(
4686 columns: &[Ident],
4687 ctx: &RenderCtx<'_>,
4688 f: &mut fmt::Formatter<'_>,
4689) -> fmt::Result {
4690 if !columns.is_empty() {
4691 f.write_str(" (")?;
4692 render_ident_list(columns, ctx, f)?;
4693 f.write_str(")")?;
4694 }
4695 Ok(())
4696}
4697
4698impl Render for PrivilegeKind {
4699 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4700 f.write_str(match self {
4701 Self::Select => "SELECT",
4702 Self::Insert => "INSERT",
4703 Self::Update => "UPDATE",
4704 Self::Delete => "DELETE",
4705 Self::Truncate => "TRUNCATE",
4706 Self::References => "REFERENCES",
4707 Self::Trigger => "TRIGGER",
4708 Self::Usage => "USAGE",
4709 Self::Execute => "EXECUTE",
4710 Self::Create => "CREATE",
4711 Self::Connect => "CONNECT",
4712 Self::Temporary => "TEMPORARY",
4713 Self::Temp => "TEMP",
4714 Self::Maintain => "MAINTAIN",
4715 Self::Index => "INDEX",
4716 Self::Alter => "ALTER",
4717 Self::Drop => "DROP",
4718 Self::Reload => "RELOAD",
4719 Self::Shutdown => "SHUTDOWN",
4720 Self::Process => "PROCESS",
4721 Self::File => "FILE",
4722 Self::Super => "SUPER",
4723 Self::Event => "EVENT",
4724 Self::GrantOption => "GRANT OPTION",
4725 Self::ShowDatabases => "SHOW DATABASES",
4726 Self::CreateTemporaryTables => "CREATE TEMPORARY TABLES",
4727 Self::LockTables => "LOCK TABLES",
4728 Self::ReplicationSlave => "REPLICATION SLAVE",
4729 Self::ReplicationClient => "REPLICATION CLIENT",
4730 Self::CreateView => "CREATE VIEW",
4731 Self::ShowView => "SHOW VIEW",
4732 Self::CreateRoutine => "CREATE ROUTINE",
4733 Self::AlterRoutine => "ALTER ROUTINE",
4734 Self::CreateUser => "CREATE USER",
4735 Self::CreateTablespace => "CREATE TABLESPACE",
4736 Self::CreateRole => "CREATE ROLE",
4737 Self::DropRole => "DROP ROLE",
4738 })
4739 }
4740}
4741
4742impl<X: Extension + Render> Render for GrantObject<X> {
4743 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4744 match self {
4745 Self::Table {
4746 explicit, names, ..
4747 } => {
4748 if *explicit {
4749 f.write_str("TABLE ")?;
4750 }
4751 render_comma_separated(names, ctx, f)
4752 }
4753 Self::Named { kind, names, .. } => {
4754 kind.render(ctx, f)?;
4755 f.write_str(" ")?;
4756 render_comma_separated(names, ctx, f)
4757 }
4758 Self::Routines { kind, routines, .. } => {
4759 kind.render(ctx, f)?;
4760 f.write_str(" ")?;
4761 render_comma_separated(routines, ctx, f)
4762 }
4763 Self::AllInSchema { kind, schemas, .. } => {
4764 f.write_str("ALL ")?;
4765 kind.render(ctx, f)?;
4766 f.write_str(" IN SCHEMA ")?;
4767 render_comma_separated(schemas, ctx, f)
4768 }
4769 }
4770 }
4771}
4772
4773impl Render for NamedObjectKind {
4774 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4775 f.write_str(match self {
4776 Self::Sequence => "SEQUENCE",
4777 Self::Database => "DATABASE",
4778 Self::Schema => "SCHEMA",
4779 Self::Domain => "DOMAIN",
4780 Self::Type => "TYPE",
4781 Self::Language => "LANGUAGE",
4782 Self::Tablespace => "TABLESPACE",
4783 Self::ForeignDataWrapper => "FOREIGN DATA WRAPPER",
4784 Self::ForeignServer => "FOREIGN SERVER",
4785 })
4786 }
4787}
4788
4789impl Render for RoutineObjectKind {
4790 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4791 f.write_str(match self {
4792 Self::Function => "FUNCTION",
4793 Self::Procedure => "PROCEDURE",
4794 Self::Routine => "ROUTINE",
4795 })
4796 }
4797}
4798
4799impl Render for SchemaObjectKind {
4800 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4801 f.write_str(match self {
4802 Self::Tables => "TABLES",
4803 Self::Sequences => "SEQUENCES",
4804 Self::Functions => "FUNCTIONS",
4805 Self::Procedures => "PROCEDURES",
4806 Self::Routines => "ROUTINES",
4807 })
4808 }
4809}
4810
4811impl<X: Extension + Render> Render for RoutineSignature<X> {
4812 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4813 self.name.render(ctx, f)?;
4814 if let Some(arg_types) = &self.arg_types {
4815 f.write_str("(")?;
4816 render_comma_separated(arg_types, ctx, f)?;
4817 f.write_str(")")?;
4818 }
4819 Ok(())
4820 }
4821}
4822
4823impl Render for Grantee {
4824 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4825 if self.group {
4826 f.write_str("GROUP ")?;
4827 }
4828 self.spec.render(ctx, f)
4829 }
4830}
4831
4832impl Render for RoleSpec {
4833 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4834 match self {
4835 Self::Public { .. } => f.write_str("PUBLIC"),
4836 Self::CurrentRole { .. } => f.write_str("CURRENT_ROLE"),
4837 Self::CurrentUser { .. } => f.write_str("CURRENT_USER"),
4838 Self::SessionUser { .. } => f.write_str("SESSION_USER"),
4839 Self::Name { name, .. } => name.render(ctx, f),
4840 }
4841 }
4842}
4843
4844impl<X: Extension + Render> Render for CopyStatement<X> {
4845 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4846 f.write_str("COPY ")?;
4847 if self.binary {
4849 f.write_str("BINARY ")?;
4850 }
4851 self.source.render(ctx, f)?;
4852 f.write_str(" ")?;
4853 self.direction.render(ctx, f)?;
4854 f.write_str(" ")?;
4855 self.target.render(ctx, f)?;
4856 if let Some(delimiters) = &self.delimiters {
4859 f.write_str(" DELIMITERS ")?;
4860 delimiters.render(ctx, f)?;
4861 }
4862 if !self.options.is_empty() {
4867 if self.parenthesized {
4868 f.write_str(" WITH (")?;
4869 render_comma_separated(&self.options, ctx, f)?;
4870 f.write_str(")")?;
4871 } else {
4872 for option in &self.options {
4873 f.write_str(" ")?;
4874 option.render(ctx, f)?;
4875 }
4876 }
4877 }
4878 if let Some(filter) = &self.filter {
4881 f.write_str(" WHERE ")?;
4882 filter.render(ctx, f)?;
4883 }
4884 Ok(())
4885 }
4886}
4887
4888impl<X: Extension + Render> Render for CopySource<X> {
4889 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4890 match self {
4891 Self::Table { table, columns, .. } => {
4892 table.render(ctx, f)?;
4893 if !columns.is_empty() {
4894 f.write_str(" (")?;
4895 render_ident_list(columns, ctx, f)?;
4896 f.write_str(")")?;
4897 }
4898 Ok(())
4899 }
4900 Self::Query { query, .. } => {
4901 f.write_str("(")?;
4902 query.render(ctx, f)?;
4903 f.write_str(")")
4904 }
4905 }
4906 }
4907}
4908
4909impl Render for CopyDirection {
4910 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4911 f.write_str(match self {
4912 Self::From => "FROM",
4913 Self::To => "TO",
4914 })
4915 }
4916}
4917
4918impl Render for CopyTarget {
4919 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4920 match self {
4921 Self::File { path, .. } => path.render(ctx, f),
4922 Self::Stdin { .. } => f.write_str("STDIN"),
4923 Self::Stdout { .. } => f.write_str("STDOUT"),
4924 Self::Program { command, .. } => {
4925 f.write_str("PROGRAM ")?;
4926 command.render(ctx, f)
4927 }
4928 }
4929 }
4930}
4931
4932impl Render for CopyOption {
4933 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4934 self.name.render(ctx, f)?;
4935 if let Some(value) = &self.value {
4936 f.write_str(" ")?;
4937 value.render(ctx, f)?;
4938 }
4939 Ok(())
4940 }
4941}
4942
4943impl Render for CopyOptionValue {
4944 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4945 match self {
4946 Self::Word { word, .. } => word.render(ctx, f),
4947 Self::String { value, .. } => value.render(ctx, f),
4948 Self::Number { value, .. } => value.render(ctx, f),
4949 Self::Star { .. } => f.write_str("*"),
4950 Self::List { values, .. } => {
4951 f.write_str("(")?;
4952 render_comma_separated(values, ctx, f)?;
4953 f.write_str(")")
4954 }
4955 Self::OptionList { options, .. } => {
4959 f.write_str("(")?;
4960 render_copy_into_options(options, ctx, f)?;
4961 f.write_str(")")
4962 }
4963 Self::Force { kind, columns, .. } => {
4964 kind.render(ctx, f)?;
4965 f.write_str(" ")?;
4966 if columns.is_empty() {
4968 f.write_str("*")
4969 } else {
4970 render_ident_list(columns, ctx, f)
4971 }
4972 }
4973 }
4974 }
4975}
4976
4977impl Render for ForceKind {
4978 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
4979 f.write_str(match self {
4980 Self::Quote => "QUOTE",
4981 Self::Null => "NULL",
4982 Self::NotNull => "NOT NULL",
4983 })
4984 }
4985}
4986
4987fn render_copy_into_options(
4993 options: &[CopyOption],
4994 ctx: &RenderCtx<'_>,
4995 f: &mut fmt::Formatter<'_>,
4996) -> fmt::Result {
4997 for (i, option) in options.iter().enumerate() {
4998 if i > 0 {
4999 f.write_str(" ")?;
5000 }
5001 option.name.render(ctx, f)?;
5002 if let Some(value) = &option.value {
5003 f.write_str(" = ")?;
5004 value.render(ctx, f)?;
5005 }
5006 }
5007 Ok(())
5008}
5009
5010impl<X: Extension + Render> Render for CopyIntoStatement<X> {
5011 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5012 f.write_str("COPY INTO ")?;
5013 self.target.render(ctx, f)?;
5014 f.write_str(" FROM ")?;
5015 self.source.render(ctx, f)?;
5016 if !self.options.is_empty() {
5017 f.write_str(" ")?;
5018 render_copy_into_options(&self.options, ctx, f)?;
5019 }
5020 Ok(())
5021 }
5022}
5023
5024impl Render for ExportStatement {
5025 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5026 f.write_str("EXPORT DATABASE ")?;
5027 if let Some(database) = &self.database {
5030 database.render(ctx, f)?;
5031 f.write_str(" TO ")?;
5032 }
5033 self.path.render(ctx, f)?;
5034 if !self.options.is_empty() {
5038 if self.parenthesized {
5039 f.write_str(" (")?;
5040 render_comma_separated(&self.options, ctx, f)?;
5041 f.write_str(")")?;
5042 } else {
5043 for option in &self.options {
5044 f.write_str(" ")?;
5045 option.render(ctx, f)?;
5046 }
5047 }
5048 }
5049 Ok(())
5050 }
5051}
5052
5053impl Render for ImportStatement {
5054 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5055 f.write_str("IMPORT DATABASE ")?;
5056 self.path.render(ctx, f)
5057 }
5058}
5059
5060impl Render for CopyIntoTarget {
5061 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5062 match self {
5063 Self::Table { table, columns, .. } => {
5064 table.render(ctx, f)?;
5065 if !columns.is_empty() {
5066 f.write_str(" (")?;
5067 render_ident_list(columns, ctx, f)?;
5068 f.write_str(")")?;
5069 }
5070 Ok(())
5071 }
5072 Self::External { location, .. } => location.render(ctx, f),
5073 Self::Stage { reference, .. } => reference.render(ctx, f),
5074 }
5075 }
5076}
5077
5078impl<X: Extension + Render> Render for CopyIntoSource<X> {
5079 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5080 match self {
5081 Self::Table { table, .. } => table.render(ctx, f),
5082 Self::External { location, .. } => location.render(ctx, f),
5083 Self::Stage { reference, .. } => reference.render(ctx, f),
5084 Self::Query { query, .. } => {
5085 f.write_str("(")?;
5086 query.render(ctx, f)?;
5087 f.write_str(")")
5088 }
5089 }
5090 }
5091}
5092
5093impl Render for ExplainKeyword {
5094 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5095 f.write_str(match self {
5096 Self::Explain => "EXPLAIN",
5097 Self::Describe => "DESCRIBE",
5098 Self::Desc => "DESC",
5099 })
5100 }
5101}
5102
5103impl<X: Extension + Render> Render for ExplainStatement<X> {
5104 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5105 self.spelling.render(ctx, f)?;
5106 if self.parenthesized {
5107 f.write_str(" (")?;
5108 render_comma_separated(&self.options, ctx, f)?;
5109 f.write_str(")")?;
5110 } else {
5111 for option in &self.options {
5113 f.write_str(" ")?;
5114 option.render(ctx, f)?;
5115 }
5116 }
5117 f.write_str(" ")?;
5118 self.statement.render(ctx, f)
5119 }
5120}
5121
5122impl Render for ExplainOption {
5123 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5124 match self {
5125 Self::Analyze { value, .. } => {
5126 render_explain_word_option("ANALYZE", value.as_ref(), ctx, f)
5127 }
5128 Self::Verbose { value, .. } => {
5129 render_explain_word_option("VERBOSE", value.as_ref(), ctx, f)
5130 }
5131 Self::Format { format, .. } => {
5132 f.write_str("FORMAT ")?;
5133 format.render(ctx, f)
5134 }
5135 Self::Other { name, value, .. } => {
5136 name.render(ctx, f)?;
5137 if let Some(value) = value {
5138 f.write_str(" ")?;
5139 value.render(ctx, f)?;
5140 }
5141 Ok(())
5142 }
5143 }
5144 }
5145}
5146
5147fn render_explain_word_option(
5149 keyword: &str,
5150 value: Option<&Ident>,
5151 ctx: &RenderCtx<'_>,
5152 f: &mut fmt::Formatter<'_>,
5153) -> fmt::Result {
5154 f.write_str(keyword)?;
5155 if let Some(value) = value {
5156 f.write_str(" ")?;
5157 value.render(ctx, f)?;
5158 }
5159 Ok(())
5160}
5161
5162impl Render for ExplainFormat {
5163 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5164 f.write_str(match self {
5165 Self::Text => "TEXT",
5166 Self::Xml => "XML",
5167 Self::Json => "JSON",
5168 Self::Yaml => "YAML",
5169 })
5170 }
5171}
5172
5173impl Render for DescribeStatement {
5174 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5175 self.keyword.render(ctx, f)?;
5176 f.write_str(" ")?;
5177 self.table.render(ctx, f)?;
5178 if let Some(column) = &self.column {
5179 f.write_str(" ")?;
5180 column.render(ctx, f)?;
5181 }
5182 Ok(())
5183 }
5184}
5185
5186impl Render for DescribeColumn {
5187 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5188 match self {
5189 Self::Name { name, .. } => name.render(ctx, f),
5190 Self::Wild { pattern, .. } => pattern.render(ctx, f),
5191 }
5192 }
5193}
5194
5195impl<X: Extension + Render> Render for ShowStatement<X> {
5196 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5197 self.target.render(ctx, f)
5198 }
5199}
5200
5201impl<X: Extension + Render> Render for ShowTarget<X> {
5202 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5203 match self {
5204 Self::Tables {
5205 extended,
5206 full,
5207 all,
5208 from,
5209 filter,
5210 ..
5211 } => {
5212 f.write_str("SHOW ")?;
5213 if *extended {
5214 f.write_str("EXTENDED ")?;
5215 }
5216 if *full {
5217 f.write_str("FULL ")?;
5218 }
5219 if *all {
5220 f.write_str("ALL ")?;
5221 }
5222 f.write_str("TABLES")?;
5223 if let Some(from) = from {
5224 f.write_str(" ")?;
5225 from.render(ctx, f)?;
5226 }
5227 if let Some(filter) = filter {
5228 f.write_str(" ")?;
5229 filter.render(ctx, f)?;
5230 }
5231 Ok(())
5232 }
5233 Self::Columns {
5234 extended,
5235 full,
5236 spelling,
5237 table,
5238 database,
5239 filter,
5240 ..
5241 } => {
5242 f.write_str("SHOW ")?;
5243 if *extended {
5244 f.write_str("EXTENDED ")?;
5245 }
5246 if *full {
5247 f.write_str("FULL ")?;
5248 }
5249 f.write_str(match spelling {
5250 ShowColumnsSpelling::Columns => "COLUMNS ",
5251 ShowColumnsSpelling::Fields => "FIELDS ",
5252 })?;
5253 table.render(ctx, f)?;
5254 if let Some(database) = database {
5255 f.write_str(" ")?;
5256 database.render(ctx, f)?;
5257 }
5258 if let Some(filter) = filter {
5259 f.write_str(" ")?;
5260 filter.render(ctx, f)?;
5261 }
5262 Ok(())
5263 }
5264 Self::Create {
5265 kind,
5266 name,
5267 if_not_exists,
5268 ..
5269 } => {
5270 f.write_str("SHOW CREATE ")?;
5271 f.write_str(match kind {
5272 ShowCreateKind::Table => "TABLE ",
5273 ShowCreateKind::View => "VIEW ",
5274 ShowCreateKind::Database { schema: false } => "DATABASE ",
5275 ShowCreateKind::Database { schema: true } => "SCHEMA ",
5276 ShowCreateKind::Event => "EVENT ",
5277 ShowCreateKind::Procedure => "PROCEDURE ",
5278 ShowCreateKind::Function => "FUNCTION ",
5279 ShowCreateKind::Trigger => "TRIGGER ",
5280 })?;
5281 if *if_not_exists {
5282 f.write_str("IF NOT EXISTS ")?;
5283 }
5284 name.render(ctx, f)
5285 }
5286 Self::Functions {
5287 kind, from, filter, ..
5288 } => {
5289 f.write_str("SHOW ")?;
5290 if let Some(kind) = kind {
5291 f.write_str(match kind {
5292 ShowFunctionsScope::User => "USER ",
5293 ShowFunctionsScope::System => "SYSTEM ",
5294 ShowFunctionsScope::All => "ALL ",
5295 })?;
5296 }
5297 f.write_str("FUNCTIONS")?;
5298 if let Some(from) = from {
5299 f.write_str(" ")?;
5300 from.render(ctx, f)?;
5301 }
5302 if let Some(filter) = filter {
5303 f.write_str(" ")?;
5304 filter.render(ctx, f)?;
5305 }
5306 Ok(())
5307 }
5308 Self::RoutineStatus { kind, filter, .. } => {
5309 f.write_str(match kind {
5310 ShowRoutineKind::Function => "SHOW FUNCTION STATUS",
5311 ShowRoutineKind::Procedure => "SHOW PROCEDURE STATUS",
5312 })?;
5313 if let Some(filter) = filter {
5314 f.write_str(" ")?;
5315 filter.render(ctx, f)?;
5316 }
5317 Ok(())
5318 }
5319 Self::Listing {
5320 kind, from, filter, ..
5321 } => {
5322 f.write_str("SHOW ")?;
5323 match kind {
5324 ShowListing::Databases { schemas } => {
5325 f.write_str(if *schemas { "SCHEMAS" } else { "DATABASES" })?;
5326 }
5327 ShowListing::CharacterSet { charset } => {
5328 f.write_str(if *charset { "CHARSET" } else { "CHARACTER SET" })?;
5329 }
5330 ShowListing::Collation => f.write_str("COLLATION")?,
5331 ShowListing::Status { scope } => {
5332 render_show_scope(*scope, f)?;
5333 f.write_str("STATUS")?;
5334 }
5335 ShowListing::Variables { scope } => {
5336 render_show_scope(*scope, f)?;
5337 f.write_str("VARIABLES")?;
5338 }
5339 ShowListing::Events => f.write_str("EVENTS")?,
5340 ShowListing::TableStatus => f.write_str("TABLE STATUS")?,
5341 ShowListing::OpenTables => f.write_str("OPEN TABLES")?,
5342 ShowListing::Triggers { full } => {
5343 if *full {
5344 f.write_str("FULL ")?;
5345 }
5346 f.write_str("TRIGGERS")?;
5347 }
5348 }
5349 if let Some(from) = from {
5350 f.write_str(" ")?;
5351 from.render(ctx, f)?;
5352 }
5353 if let Some(filter) = filter {
5354 f.write_str(" ")?;
5355 filter.render(ctx, f)?;
5356 }
5357 Ok(())
5358 }
5359 Self::Bare { kind, .. } => {
5360 f.write_str("SHOW ")?;
5361 f.write_str(match kind {
5362 ShowBare::Plugins => "PLUGINS",
5363 ShowBare::Engines { storage: true } => "STORAGE ENGINES",
5364 ShowBare::Engines { storage: false } => "ENGINES",
5365 ShowBare::Privileges => "PRIVILEGES",
5366 ShowBare::Profiles => "PROFILES",
5367 ShowBare::Processlist { full: true } => "FULL PROCESSLIST",
5368 ShowBare::Processlist { full: false } => "PROCESSLIST",
5369 ShowBare::BinaryLogs => "BINARY LOGS",
5370 ShowBare::Replicas => "REPLICAS",
5371 ShowBare::BinaryLogStatus => "BINARY LOG STATUS",
5372 })
5373 }
5374 Self::Index {
5375 spelling,
5376 extended,
5377 table,
5378 database,
5379 filter,
5380 ..
5381 } => {
5382 f.write_str("SHOW ")?;
5383 if *extended {
5384 f.write_str("EXTENDED ")?;
5385 }
5386 f.write_str(match spelling {
5387 ShowIndexSpelling::Index => "INDEX ",
5388 ShowIndexSpelling::Indexes => "INDEXES ",
5389 ShowIndexSpelling::Keys => "KEYS ",
5390 })?;
5391 table.render(ctx, f)?;
5392 if let Some(database) = database {
5393 f.write_str(" ")?;
5394 database.render(ctx, f)?;
5395 }
5396 if let Some(filter) = filter {
5397 f.write_str(" ")?;
5398 filter.render(ctx, f)?;
5399 }
5400 Ok(())
5401 }
5402 Self::Engine {
5403 engine, artifact, ..
5404 } => {
5405 f.write_str("SHOW ENGINE ")?;
5406 match engine {
5407 Some(name) => name.render(ctx, f)?,
5408 None => f.write_str("ALL")?,
5409 }
5410 f.write_str(match artifact {
5411 ShowEngineArtifact::Status => " STATUS",
5412 ShowEngineArtifact::Mutex => " MUTEX",
5413 ShowEngineArtifact::Logs => " LOGS",
5414 })
5415 }
5416 Self::ReplicaStatus { channel, .. } => {
5417 f.write_str("SHOW REPLICA STATUS")?;
5418 if let Some(channel) = channel {
5419 f.write_str(" FOR CHANNEL ")?;
5420 channel.render(ctx, f)?;
5421 }
5422 Ok(())
5423 }
5424 Self::Diagnostics {
5425 kind, count, limit, ..
5426 } => {
5427 f.write_str("SHOW ")?;
5428 if *count {
5429 f.write_str("COUNT(*) ")?;
5430 }
5431 f.write_str(match kind {
5432 ShowDiagnosticKind::Warnings => "WARNINGS",
5433 ShowDiagnosticKind::Errors => "ERRORS",
5434 })?;
5435 if let Some(limit) = limit {
5436 f.write_str(" ")?;
5437 render_show_limit(limit, ctx, f)?;
5438 }
5439 Ok(())
5440 }
5441 Self::RoutineCode { kind, name, .. } => {
5442 f.write_str(match kind {
5443 ShowRoutineKind::Function => "SHOW FUNCTION CODE ",
5444 ShowRoutineKind::Procedure => "SHOW PROCEDURE CODE ",
5445 })?;
5446 name.render(ctx, f)
5447 }
5448 Self::Grants {
5449 user, using_roles, ..
5450 } => {
5451 f.write_str("SHOW GRANTS")?;
5452 if let Some(user) = user {
5453 f.write_str(" FOR ")?;
5454 user.render(ctx, f)?;
5455 if !using_roles.is_empty() {
5456 f.write_str(" USING ")?;
5457 render_comma_separated(using_roles, ctx, f)?;
5458 }
5459 }
5460 Ok(())
5461 }
5462 Self::CreateUser { user, .. } => {
5463 f.write_str("SHOW CREATE USER ")?;
5464 user.render(ctx, f)
5465 }
5466 Self::Profile {
5467 types,
5468 query,
5469 limit,
5470 ..
5471 } => {
5472 f.write_str("SHOW PROFILE")?;
5473 for (index, ty) in types.iter().enumerate() {
5474 f.write_str(if index == 0 { " " } else { ", " })?;
5475 f.write_str(ty.keyword())?;
5476 }
5477 if let Some(query) = query {
5478 f.write_str(" FOR QUERY ")?;
5479 query.render(ctx, f)?;
5480 }
5481 if let Some(limit) = limit {
5482 f.write_str(" ")?;
5483 render_show_limit(limit, ctx, f)?;
5484 }
5485 Ok(())
5486 }
5487 Self::LogEvents {
5488 relay,
5489 log_name,
5490 position,
5491 limit,
5492 channel,
5493 ..
5494 } => {
5495 f.write_str(if *relay {
5496 "SHOW RELAYLOG EVENTS"
5497 } else {
5498 "SHOW BINLOG EVENTS"
5499 })?;
5500 if let Some(log_name) = log_name {
5501 f.write_str(" IN ")?;
5502 log_name.render(ctx, f)?;
5503 }
5504 if let Some(position) = position {
5505 f.write_str(" FROM ")?;
5506 position.render(ctx, f)?;
5507 }
5508 if let Some(limit) = limit {
5509 f.write_str(" ")?;
5510 render_show_limit(limit, ctx, f)?;
5511 }
5512 if let Some(channel) = channel {
5513 f.write_str(" FOR CHANNEL ")?;
5514 channel.render(ctx, f)?;
5515 }
5516 Ok(())
5517 }
5518 }
5519 }
5520}
5521
5522impl ShowProfileType {
5523 fn keyword(self) -> &'static str {
5525 match self {
5526 Self::All => "ALL",
5527 Self::BlockIo => "BLOCK IO",
5528 Self::ContextSwitches => "CONTEXT SWITCHES",
5529 Self::Cpu => "CPU",
5530 Self::Ipc => "IPC",
5531 Self::Memory => "MEMORY",
5532 Self::PageFaults => "PAGE FAULTS",
5533 Self::Source => "SOURCE",
5534 Self::Swaps => "SWAPS",
5535 }
5536 }
5537}
5538
5539fn render_show_limit(
5543 limit: &ShowLimit,
5544 ctx: &RenderCtx<'_>,
5545 f: &mut fmt::Formatter<'_>,
5546) -> fmt::Result {
5547 f.write_str("LIMIT ")?;
5548 match &limit.offset {
5549 Some(offset) if limit.offset_keyword => {
5550 limit.row_count.render(ctx, f)?;
5551 f.write_str(" OFFSET ")?;
5552 offset.render(ctx, f)
5553 }
5554 Some(offset) => {
5555 offset.render(ctx, f)?;
5556 f.write_str(", ")?;
5557 limit.row_count.render(ctx, f)
5558 }
5559 None => limit.row_count.render(ctx, f),
5560 }
5561}
5562
5563fn render_show_scope(scope: Option<ShowScope>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5566 if let Some(scope) = scope {
5567 f.write_str(match scope {
5568 ShowScope::Global => "GLOBAL ",
5569 ShowScope::Session => "SESSION ",
5570 ShowScope::Local => "LOCAL ",
5571 })?;
5572 }
5573 Ok(())
5574}
5575
5576impl Render for ShowFunctionsFilter {
5577 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5578 match self {
5579 Self::Name { like, name, .. } => {
5580 if *like {
5581 f.write_str("LIKE ")?;
5582 }
5583 name.render(ctx, f)
5584 }
5585 Self::Regex { like, pattern, .. } => {
5586 if *like {
5587 f.write_str("LIKE ")?;
5588 }
5589 pattern.render(ctx, f)
5590 }
5591 }
5592 }
5593}
5594
5595impl Render for ShowFrom {
5596 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5597 f.write_str(match self.keyword {
5598 ShowFromKeyword::From => "FROM ",
5599 ShowFromKeyword::In => "IN ",
5600 })?;
5601 self.name.render(ctx, f)
5602 }
5603}
5604
5605impl<X: Extension + Render> Render for ShowFilter<X> {
5606 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5607 match self {
5608 Self::Like { pattern, .. } => {
5609 f.write_str("LIKE ")?;
5610 pattern.render(ctx, f)
5611 }
5612 Self::Where { predicate, .. } => {
5613 f.write_str("WHERE ")?;
5614 predicate.render(ctx, f)
5615 }
5616 }
5617 }
5618}
5619
5620impl<X: Extension + Render> Render for KillStatement<X> {
5621 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5622 f.write_str("KILL")?;
5623 match self.target {
5624 KillTarget::Unspecified => {}
5625 KillTarget::Connection => f.write_str(" CONNECTION")?,
5626 KillTarget::Query => f.write_str(" QUERY")?,
5627 }
5628 f.write_str(" ")?;
5629 self.id.render(ctx, f)
5630 }
5631}
5632
5633impl<X: Extension + Render> Render for InstallStatement<X> {
5634 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5635 match self {
5636 InstallStatement::Plugin { name, soname, .. } => {
5637 f.write_str("INSTALL PLUGIN ")?;
5638 name.render(ctx, f)?;
5639 f.write_str(" SONAME ")?;
5640 soname.render(ctx, f)
5641 }
5642 InstallStatement::Component { urns, set, .. } => {
5643 f.write_str("INSTALL COMPONENT ")?;
5644 render_comma_separated(urns, ctx, f)?;
5645 if !set.is_empty() {
5646 f.write_str(" SET ")?;
5647 render_comma_separated(set, ctx, f)?;
5648 }
5649 Ok(())
5650 }
5651 }
5652 }
5653}
5654
5655impl Render for UninstallStatement {
5656 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5657 match self {
5658 UninstallStatement::Plugin { name, .. } => {
5659 f.write_str("UNINSTALL PLUGIN ")?;
5660 name.render(ctx, f)
5661 }
5662 UninstallStatement::Component { urns, .. } => {
5663 f.write_str("UNINSTALL COMPONENT ")?;
5664 render_comma_separated(urns, ctx, f)
5665 }
5666 }
5667 }
5668}
5669
5670impl<X: Extension + Render> Render for InstallComponentSetElement<X> {
5671 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5672 match self.scope {
5673 None => {}
5674 Some(InstallComponentSetScope::Global) => f.write_str("GLOBAL ")?,
5675 Some(InstallComponentSetScope::Persist) => f.write_str("PERSIST ")?,
5676 }
5677 self.name.render(ctx, f)?;
5678 render_mysql_set_assignment(self.assignment, ctx, f)?;
5679 self.value.render(ctx, f)
5680 }
5681}
5682
5683impl<X: Extension + Render> Render for InstallComponentSetValue<X> {
5684 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5685 match self {
5686 InstallComponentSetValue::On { .. } => f.write_str("ON"),
5687 InstallComponentSetValue::Expr { expr, .. } => expr.render(ctx, f),
5688 }
5689 }
5690}
5691
5692impl<X: Extension + Render> Render for HandlerStatement<X> {
5693 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5694 f.write_str("HANDLER ")?;
5695 self.table.render(ctx, f)?;
5696 f.write_str(" ")?;
5697 self.operation.render(ctx, f)
5698 }
5699}
5700
5701impl<X: Extension + Render> Render for HandlerOperation<X> {
5702 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5703 match self {
5704 HandlerOperation::Open {
5705 alias, as_keyword, ..
5706 } => {
5707 f.write_str("OPEN")?;
5708 if let Some(alias) = alias {
5709 f.write_str(if *as_keyword { " AS " } else { " " })?;
5711 alias.render(ctx, f)?;
5712 }
5713 Ok(())
5714 }
5715 HandlerOperation::Close { .. } => f.write_str("CLOSE"),
5716 HandlerOperation::Read {
5717 selector,
5718 selection,
5719 limit,
5720 ..
5721 } => {
5722 f.write_str("READ ")?;
5723 selector.render(ctx, f)?;
5724 if let Some(selection) = selection {
5725 f.write_str(" WHERE ")?;
5726 selection.render(ctx, f)?;
5727 }
5728 if let Some(limit) = limit {
5729 f.write_str(" ")?;
5730 limit.render(ctx, f)?;
5731 }
5732 Ok(())
5733 }
5734 }
5735 }
5736}
5737
5738impl<X: Extension + Render> Render for HandlerReadSelector<X> {
5739 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5740 match self {
5741 HandlerReadSelector::Scan { direction, .. } => f.write_str(match direction {
5742 HandlerScanDirection::First => "FIRST",
5743 HandlerScanDirection::Next => "NEXT",
5744 }),
5745 HandlerReadSelector::Index {
5746 index, direction, ..
5747 } => {
5748 index.render(ctx, f)?;
5749 f.write_str(match direction {
5750 HandlerIndexDirection::First => " FIRST",
5751 HandlerIndexDirection::Next => " NEXT",
5752 HandlerIndexDirection::Prev => " PREV",
5753 HandlerIndexDirection::Last => " LAST",
5754 })
5755 }
5756 HandlerReadSelector::Key {
5757 index,
5758 comparison,
5759 key,
5760 ..
5761 } => {
5762 index.render(ctx, f)?;
5763 f.write_str(match comparison {
5764 HandlerKeyComparison::Eq => " = (",
5765 HandlerKeyComparison::GreaterOrEqual => " >= (",
5766 HandlerKeyComparison::LessOrEqual => " <= (",
5767 HandlerKeyComparison::Greater => " > (",
5768 HandlerKeyComparison::Less => " < (",
5769 })?;
5770 render_comma_separated(key, ctx, f)?;
5771 f.write_str(")")
5772 }
5773 }
5774 }
5775}
5776
5777impl Render for CloneStatement {
5778 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5779 match self {
5780 CloneStatement::Local { data_directory, .. } => {
5781 f.write_str("CLONE LOCAL ")?;
5782 data_directory.render(ctx, f)
5783 }
5784 CloneStatement::Instance {
5785 source,
5786 port,
5787 password,
5788 data_directory,
5789 ssl,
5790 ..
5791 } => {
5792 f.write_str("CLONE INSTANCE FROM ")?;
5793 source.render(ctx, f)?;
5794 f.write_str(":")?;
5795 port.render(ctx, f)?;
5796 f.write_str(" IDENTIFIED BY ")?;
5797 password.render(ctx, f)?;
5798 if let Some(data_directory) = data_directory {
5799 f.write_str(" ")?;
5800 data_directory.render(ctx, f)?;
5801 }
5802 match ssl {
5803 CloneSsl::Unspecified => {}
5804 CloneSsl::Require => f.write_str(" REQUIRE SSL")?,
5805 CloneSsl::RequireNo => f.write_str(" REQUIRE NO SSL")?,
5806 }
5807 Ok(())
5808 }
5809 }
5810 }
5811}
5812
5813impl Render for CloneDataDirectory {
5814 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5815 f.write_str(if self.equals {
5816 "DATA DIRECTORY = "
5817 } else {
5818 "DATA DIRECTORY "
5819 })?;
5820 self.path.render(ctx, f)
5821 }
5822}
5823
5824impl Render for ImportTableStatement {
5825 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5826 f.write_str("IMPORT TABLE FROM ")?;
5827 render_comma_separated(&self.files, ctx, f)
5828 }
5829}
5830
5831impl Render for HelpStatement {
5832 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5833 f.write_str("HELP ")?;
5834 self.topic.render(ctx, f)
5835 }
5836}
5837
5838impl Render for BinlogStatement {
5839 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5840 f.write_str("BINLOG ")?;
5841 self.event.render(ctx, f)
5842 }
5843}
5844
5845impl Render for PragmaStatement {
5846 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5847 f.write_str("PRAGMA ")?;
5848 self.name.render(ctx, f)?;
5849 if let Some(value) = &self.value {
5850 if self.parenthesized {
5853 f.write_str("(")?;
5854 value.render(ctx, f)?;
5855 f.write_str(")")?;
5856 } else {
5857 f.write_str(" = ")?;
5858 value.render(ctx, f)?;
5859 }
5860 }
5861 Ok(())
5862 }
5863}
5864
5865impl<X: Extension + Render> Render for AttachStatement<X> {
5866 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5867 f.write_str("ATTACH ")?;
5868 if self.database_keyword {
5869 f.write_str("DATABASE ")?;
5870 }
5871 self.target.render(ctx, f)?;
5872 f.write_str(" AS ")?;
5873 self.schema.render(ctx, f)
5874 }
5875}
5876
5877impl Render for DetachStatement {
5878 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5879 f.write_str("DETACH ")?;
5880 if self.database_keyword {
5881 f.write_str("DATABASE ")?;
5882 }
5883 if self.if_exists {
5884 f.write_str("IF EXISTS ")?;
5885 }
5886 self.schema.render(ctx, f)
5887 }
5888}
5889
5890impl Render for CheckpointStatement {
5891 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5892 if self.force {
5893 f.write_str("FORCE ")?;
5894 }
5895 f.write_str("CHECKPOINT")?;
5896 if let Some(database) = &self.database {
5897 f.write_str(" ")?;
5898 database.render(ctx, f)?;
5899 }
5900 Ok(())
5901 }
5902}
5903
5904impl Render for LoadStatement {
5905 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5906 f.write_str("LOAD ")?;
5907 self.target.render(ctx, f)
5908 }
5909}
5910
5911impl Render for LoadTarget {
5912 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5913 match self {
5914 Self::Name { name, .. } => name.render(ctx, f),
5915 Self::Path { path, .. } => path.render(ctx, f),
5916 }
5917 }
5918}
5919
5920impl Render for UseStatement {
5921 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5922 f.write_str("USE ")?;
5923 self.name.render(ctx, f)
5924 }
5925}
5926
5927impl Render for UpdateExtensionsStatement {
5928 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5929 f.write_str("UPDATE EXTENSIONS")?;
5930 if !self.extensions.is_empty() {
5934 f.write_str(" (")?;
5935 render_comma_separated(&self.extensions, ctx, f)?;
5936 f.write_str(")")?;
5937 }
5938 Ok(())
5939 }
5940}
5941
5942impl<X: Extension + Render> Render for VacuumStatement<X> {
5943 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5944 f.write_str("VACUUM")?;
5945 match self.analyze {
5949 Some(VacuumAnalyze::Keyword) => f.write_str(" ANALYZE")?,
5950 Some(VacuumAnalyze::Parenthesized) => f.write_str(" (ANALYZE)")?,
5951 None => {}
5952 }
5953 if let Some(schema) = &self.schema {
5956 f.write_str(" ")?;
5957 schema.render(ctx, f)?;
5958 }
5959 if let Some(table) = &self.table {
5960 f.write_str(" ")?;
5961 table.render(ctx, f)?;
5962 }
5963 if let Some(columns) = &self.columns {
5965 f.write_str(" (")?;
5966 render_comma_separated(columns, ctx, f)?;
5967 f.write_str(")")?;
5968 }
5969 if let Some(into) = &self.into {
5971 f.write_str(" INTO ")?;
5972 into.render(ctx, f)?;
5973 }
5974 Ok(())
5975 }
5976}
5977
5978impl Render for ReindexStatement {
5979 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5980 f.write_str("REINDEX")?;
5981 if let Some(target) = &self.target {
5982 f.write_str(" ")?;
5983 target.render(ctx, f)?;
5984 }
5985 Ok(())
5986 }
5987}
5988
5989impl Render for AnalyzeStatement {
5990 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5991 f.write_str("ANALYZE")?;
5992 if let Some(target) = &self.target {
5993 f.write_str(" ")?;
5994 target.render(ctx, f)?;
5995 }
5996 if let Some(columns) = &self.columns {
5998 f.write_str(" (")?;
5999 render_comma_separated(columns, ctx, f)?;
6000 f.write_str(")")?;
6001 }
6002 Ok(())
6003 }
6004}
6005
6006impl Render for TableMaintenanceStatement {
6007 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6008 let (verb, prefix) = match &self.kind {
6010 TableMaintenanceKind::Analyze {
6011 no_write_to_binlog, ..
6012 } => ("ANALYZE", *no_write_to_binlog),
6013 TableMaintenanceKind::Check { .. } => ("CHECK", None),
6014 TableMaintenanceKind::Checksum { .. } => ("CHECKSUM", None),
6015 TableMaintenanceKind::Optimize {
6016 no_write_to_binlog, ..
6017 } => ("OPTIMIZE", *no_write_to_binlog),
6018 TableMaintenanceKind::Repair {
6019 no_write_to_binlog, ..
6020 } => ("REPAIR", *no_write_to_binlog),
6021 };
6022 f.write_str(verb)?;
6023 if let Some(prefix) = prefix {
6024 f.write_str(" ")?;
6025 f.write_str(no_write_to_binlog_keyword(prefix))?;
6026 }
6027 f.write_str(" ")?;
6028 f.write_str(table_keyword_str(self.table_keyword))?;
6029 f.write_str(" ")?;
6030 render_comma_separated(&self.tables, ctx, f)?;
6031 match &self.kind {
6033 TableMaintenanceKind::Analyze {
6034 histogram: Some(histogram),
6035 ..
6036 } => {
6037 f.write_str(" ")?;
6038 histogram.render(ctx, f)?;
6039 }
6040 TableMaintenanceKind::Check { options, .. } => {
6041 for option in options {
6042 f.write_str(" ")?;
6043 f.write_str(check_table_option_keyword(*option))?;
6044 }
6045 }
6046 TableMaintenanceKind::Checksum {
6047 option: Some(option),
6048 ..
6049 } => {
6050 f.write_str(" ")?;
6051 f.write_str(checksum_table_option_keyword(*option))?;
6052 }
6053 TableMaintenanceKind::Repair { options, .. } => {
6054 for option in options {
6055 f.write_str(" ")?;
6056 f.write_str(repair_table_option_keyword(*option))?;
6057 }
6058 }
6059 TableMaintenanceKind::Analyze {
6060 histogram: None, ..
6061 }
6062 | TableMaintenanceKind::Checksum { option: None, .. }
6063 | TableMaintenanceKind::Optimize { .. } => {}
6064 }
6065 Ok(())
6066 }
6067}
6068
6069impl Render for AnalyzeHistogram {
6070 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6071 match self {
6072 AnalyzeHistogram::Update {
6073 columns, buckets, ..
6074 } => {
6075 f.write_str("UPDATE HISTOGRAM ON ")?;
6076 render_comma_separated(columns, ctx, f)?;
6077 if let Some(buckets) = buckets {
6078 f.write_str(" WITH ")?;
6079 buckets.render(ctx, f)?;
6080 f.write_str(" BUCKETS")?;
6081 }
6082 }
6083 AnalyzeHistogram::Drop { columns, .. } => {
6084 f.write_str("DROP HISTOGRAM ON ")?;
6085 render_comma_separated(columns, ctx, f)?;
6086 }
6087 }
6088 Ok(())
6089 }
6090}
6091
6092impl Render for CacheIndexStatement {
6093 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6094 f.write_str("CACHE INDEX ")?;
6095 self.targets.render(ctx, f)?;
6096 f.write_str(" IN ")?;
6097 self.cache.render(ctx, f)
6098 }
6099}
6100
6101impl Render for CacheIndexTargets {
6102 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6103 match self {
6104 CacheIndexTargets::Tables { tables, .. } => render_comma_separated(tables, ctx, f),
6105 CacheIndexTargets::Partition {
6106 table,
6107 partition,
6108 keys,
6109 ..
6110 } => {
6111 table.render(ctx, f)?;
6112 f.write_str(" ")?;
6113 partition.render(ctx, f)?;
6114 if let Some(keys) = keys {
6115 f.write_str(" ")?;
6116 keys.render(ctx, f)?;
6117 }
6118 Ok(())
6119 }
6120 }
6121 }
6122}
6123
6124impl Render for CacheIndexTable {
6125 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6126 self.table.render(ctx, f)?;
6127 if let Some(keys) = &self.keys {
6128 f.write_str(" ")?;
6129 keys.render(ctx, f)?;
6130 }
6131 Ok(())
6132 }
6133}
6134
6135impl Render for LoadIndexStatement {
6136 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6137 f.write_str("LOAD INDEX INTO CACHE ")?;
6138 self.targets.render(ctx, f)
6139 }
6140}
6141
6142impl Render for LoadIndexTargets {
6143 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6144 match self {
6145 LoadIndexTargets::Tables { tables, .. } => render_comma_separated(tables, ctx, f),
6146 LoadIndexTargets::Partition {
6147 table,
6148 partition,
6149 keys,
6150 ignore_leaves,
6151 ..
6152 } => {
6153 table.render(ctx, f)?;
6154 f.write_str(" ")?;
6155 partition.render(ctx, f)?;
6156 if let Some(keys) = keys {
6157 f.write_str(" ")?;
6158 keys.render(ctx, f)?;
6159 }
6160 if *ignore_leaves {
6161 f.write_str(" IGNORE LEAVES")?;
6162 }
6163 Ok(())
6164 }
6165 }
6166 }
6167}
6168
6169impl Render for LoadIndexTable {
6170 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6171 self.table.render(ctx, f)?;
6172 if let Some(keys) = &self.keys {
6173 f.write_str(" ")?;
6174 keys.render(ctx, f)?;
6175 }
6176 if self.ignore_leaves {
6177 f.write_str(" IGNORE LEAVES")?;
6178 }
6179 Ok(())
6180 }
6181}
6182
6183impl Render for CacheIndexKeyList {
6184 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6185 f.write_str(match self.keyword {
6186 CacheIndexKeyword::Index => "INDEX",
6187 CacheIndexKeyword::Key => "KEY",
6188 })?;
6189 f.write_str(" (")?;
6190 render_comma_separated(&self.keys, ctx, f)?;
6191 f.write_str(")")
6192 }
6193}
6194
6195impl Render for KeyCacheName {
6196 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6197 match self {
6198 KeyCacheName::Named { name, .. } => name.render(ctx, f),
6199 KeyCacheName::Default { .. } => f.write_str("DEFAULT"),
6200 }
6201 }
6202}
6203
6204impl Render for PartitionSelection {
6205 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6206 match self {
6207 PartitionSelection::All { .. } => f.write_str("PARTITION (ALL)"),
6208 PartitionSelection::Names { names, .. } => {
6209 f.write_str("PARTITION (")?;
6210 render_comma_separated(names, ctx, f)?;
6211 f.write_str(")")
6212 }
6213 }
6214 }
6215}
6216
6217impl Render for RenameStatement {
6218 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6219 match self {
6220 RenameStatement::Table {
6221 table_keyword,
6222 renames,
6223 ..
6224 } => {
6225 f.write_str("RENAME ")?;
6226 f.write_str(table_keyword_str(*table_keyword))?;
6227 f.write_str(" ")?;
6228 render_comma_separated(renames, ctx, f)
6229 }
6230 RenameStatement::User { renames, .. } => {
6231 f.write_str("RENAME USER ")?;
6232 render_comma_separated(renames, ctx, f)
6233 }
6234 }
6235 }
6236}
6237
6238impl Render for TableRename {
6239 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6240 self.from.render(ctx, f)?;
6241 f.write_str(" TO ")?;
6242 self.to.render(ctx, f)
6243 }
6244}
6245
6246impl Render for UserRename {
6247 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6248 self.from.render(ctx, f)?;
6249 f.write_str(" TO ")?;
6250 self.to.render(ctx, f)
6251 }
6252}
6253
6254impl Render for FlushStatement {
6255 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6256 f.write_str("FLUSH")?;
6257 if let Some(prefix) = self.no_write_to_binlog {
6258 f.write_str(" ")?;
6259 f.write_str(no_write_to_binlog_keyword(prefix))?;
6260 }
6261 f.write_str(" ")?;
6262 self.target.render(ctx, f)
6263 }
6264}
6265
6266impl Render for FlushTarget {
6267 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6268 match self {
6269 FlushTarget::Tables {
6270 table_keyword,
6271 tables,
6272 lock,
6273 ..
6274 } => {
6275 f.write_str(table_keyword_str(*table_keyword))?;
6276 if !tables.is_empty() {
6277 f.write_str(" ")?;
6278 render_comma_separated(tables, ctx, f)?;
6279 }
6280 if let Some(lock) = lock {
6281 f.write_str(" ")?;
6282 f.write_str(match lock {
6283 FlushTablesLock::WithReadLock => "WITH READ LOCK",
6284 FlushTablesLock::ForExport => "FOR EXPORT",
6285 })?;
6286 }
6287 Ok(())
6288 }
6289 FlushTarget::Options { options, .. } => render_comma_separated(options, ctx, f),
6290 }
6291 }
6292}
6293
6294impl Render for FlushOption {
6295 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6296 match self {
6297 FlushOption::Privileges { .. } => f.write_str("PRIVILEGES"),
6298 FlushOption::Logs { .. } => f.write_str("LOGS"),
6299 FlushOption::BinaryLogs { .. } => f.write_str("BINARY LOGS"),
6300 FlushOption::EngineLogs { .. } => f.write_str("ENGINE LOGS"),
6301 FlushOption::ErrorLogs { .. } => f.write_str("ERROR LOGS"),
6302 FlushOption::GeneralLogs { .. } => f.write_str("GENERAL LOGS"),
6303 FlushOption::SlowLogs { .. } => f.write_str("SLOW LOGS"),
6304 FlushOption::RelayLogs { channel, .. } => {
6305 f.write_str("RELAY LOGS")?;
6306 if let Some(channel) = channel {
6307 f.write_str(" FOR CHANNEL ")?;
6308 channel.render(ctx, f)?;
6309 }
6310 Ok(())
6311 }
6312 FlushOption::Status { .. } => f.write_str("STATUS"),
6313 FlushOption::UserResources { .. } => f.write_str("USER_RESOURCES"),
6314 FlushOption::OptimizerCosts { .. } => f.write_str("OPTIMIZER_COSTS"),
6315 }
6316 }
6317}
6318
6319impl<X: Extension + Render> Render for PurgeStatement<X> {
6320 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6321 f.write_str("PURGE BINARY LOGS ")?;
6322 self.target.render(ctx, f)
6323 }
6324}
6325
6326impl<X: Extension + Render> Render for PurgeTarget<X> {
6327 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6328 match self {
6329 PurgeTarget::To { log, .. } => {
6330 f.write_str("TO ")?;
6331 log.render(ctx, f)
6332 }
6333 PurgeTarget::Before { datetime, .. } => {
6334 f.write_str("BEFORE ")?;
6335 datetime.render(ctx, f)
6336 }
6337 }
6338 }
6339}
6340
6341fn render_for_channel(
6344 channel: &Option<Literal>,
6345 ctx: &RenderCtx<'_>,
6346 f: &mut fmt::Formatter<'_>,
6347) -> fmt::Result {
6348 if let Some(channel) = channel {
6349 f.write_str(" FOR CHANNEL ")?;
6350 channel.render(ctx, f)?;
6351 }
6352 Ok(())
6353}
6354
6355fn render_replica_connection_option(
6358 keyword: &str,
6359 value: &Option<Literal>,
6360 ctx: &RenderCtx<'_>,
6361 f: &mut fmt::Formatter<'_>,
6362) -> fmt::Result {
6363 if let Some(value) = value {
6364 f.write_str(keyword)?;
6365 value.render(ctx, f)?;
6366 }
6367 Ok(())
6368}
6369
6370impl Render for ReplicationStatement {
6371 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6372 match self {
6373 ReplicationStatement::ChangeSource {
6374 options, channel, ..
6375 } => {
6376 f.write_str("CHANGE REPLICATION SOURCE TO ")?;
6377 render_comma_separated(options, ctx, f)?;
6378 render_for_channel(channel, ctx, f)
6379 }
6380 ReplicationStatement::ChangeFilter { rules, channel, .. } => {
6381 f.write_str("CHANGE REPLICATION FILTER ")?;
6382 render_comma_separated(rules, ctx, f)?;
6383 render_for_channel(channel, ctx, f)
6384 }
6385 ReplicationStatement::StartReplica {
6386 threads,
6387 until,
6388 user,
6389 password,
6390 default_auth,
6391 plugin_dir,
6392 channel,
6393 ..
6394 } => {
6395 f.write_str("START REPLICA")?;
6396 if !threads.is_empty() {
6397 f.write_str(" ")?;
6398 render_comma_separated(threads, ctx, f)?;
6399 }
6400 if !until.is_empty() {
6401 f.write_str(" UNTIL ")?;
6402 render_comma_separated(until, ctx, f)?;
6403 }
6404 render_replica_connection_option(" USER = ", user, ctx, f)?;
6405 render_replica_connection_option(" PASSWORD = ", password, ctx, f)?;
6406 render_replica_connection_option(" DEFAULT_AUTH = ", default_auth, ctx, f)?;
6407 render_replica_connection_option(" PLUGIN_DIR = ", plugin_dir, ctx, f)?;
6408 render_for_channel(channel, ctx, f)
6409 }
6410 ReplicationStatement::StopReplica {
6411 threads, channel, ..
6412 } => {
6413 f.write_str("STOP REPLICA")?;
6414 if !threads.is_empty() {
6415 f.write_str(" ")?;
6416 render_comma_separated(threads, ctx, f)?;
6417 }
6418 render_for_channel(channel, ctx, f)
6419 }
6420 ReplicationStatement::StartGroupReplication { options, .. } => {
6421 f.write_str("START GROUP_REPLICATION")?;
6422 if !options.is_empty() {
6423 f.write_str(" ")?;
6424 render_comma_separated(options, ctx, f)?;
6425 }
6426 Ok(())
6427 }
6428 ReplicationStatement::StopGroupReplication { .. } => {
6429 f.write_str("STOP GROUP_REPLICATION")
6430 }
6431 }
6432 }
6433}
6434
6435impl Render for ChangeReplicationSourceOption {
6436 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6437 f.write_str(self.name.keyword())?;
6438 f.write_str(" = ")?;
6439 self.value.render(ctx, f)
6440 }
6441}
6442
6443impl Render for ChangeReplicationSourceOptionValue {
6444 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6445 match self {
6446 Self::String { value, .. } | Self::Number { value, .. } => value.render(ctx, f),
6447 Self::NullableString { value, .. } => match value {
6448 Some(value) => value.render(ctx, f),
6449 None => f.write_str("NULL"),
6450 },
6451 Self::User { account, .. } => match account {
6452 Some(account) => account.render(ctx, f),
6453 None => f.write_str("NULL"),
6454 },
6455 Self::ServerIds { ids, .. } => {
6456 f.write_str("(")?;
6457 render_comma_separated(ids, ctx, f)?;
6458 f.write_str(")")
6459 }
6460 Self::PrimaryKeyCheck { check, .. } => f.write_str(match check {
6461 RequirePrimaryKeyCheck::On => "ON",
6462 RequirePrimaryKeyCheck::Off => "OFF",
6463 RequirePrimaryKeyCheck::Stream => "STREAM",
6464 RequirePrimaryKeyCheck::Generate => "GENERATE",
6465 }),
6466 Self::AssignGtids { kind, uuid, .. } => match kind {
6467 AssignGtidsKind::Off => f.write_str("OFF"),
6468 AssignGtidsKind::Local => f.write_str("LOCAL"),
6469 AssignGtidsKind::Uuid => match uuid {
6470 Some(uuid) => uuid.render(ctx, f),
6471 None => Ok(()),
6472 },
6473 },
6474 }
6475 }
6476}
6477
6478impl Render for ReplicationFilterRule {
6479 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6480 match self {
6481 Self::DoDb { databases, .. } => {
6482 f.write_str("REPLICATE_DO_DB = (")?;
6483 render_comma_separated(databases, ctx, f)?;
6484 f.write_str(")")
6485 }
6486 Self::IgnoreDb { databases, .. } => {
6487 f.write_str("REPLICATE_IGNORE_DB = (")?;
6488 render_comma_separated(databases, ctx, f)?;
6489 f.write_str(")")
6490 }
6491 Self::DoTable { tables, .. } => {
6492 f.write_str("REPLICATE_DO_TABLE = (")?;
6493 render_comma_separated(tables, ctx, f)?;
6494 f.write_str(")")
6495 }
6496 Self::IgnoreTable { tables, .. } => {
6497 f.write_str("REPLICATE_IGNORE_TABLE = (")?;
6498 render_comma_separated(tables, ctx, f)?;
6499 f.write_str(")")
6500 }
6501 Self::WildDoTable { patterns, .. } => {
6502 f.write_str("REPLICATE_WILD_DO_TABLE = (")?;
6503 render_comma_separated(patterns, ctx, f)?;
6504 f.write_str(")")
6505 }
6506 Self::WildIgnoreTable { patterns, .. } => {
6507 f.write_str("REPLICATE_WILD_IGNORE_TABLE = (")?;
6508 render_comma_separated(patterns, ctx, f)?;
6509 f.write_str(")")
6510 }
6511 Self::RewriteDb { pairs, .. } => {
6512 f.write_str("REPLICATE_REWRITE_DB = (")?;
6513 render_comma_separated(pairs, ctx, f)?;
6514 f.write_str(")")
6515 }
6516 }
6517 }
6518}
6519
6520impl Render for RewriteDbPair {
6521 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6522 f.write_str("(")?;
6523 self.from.render(ctx, f)?;
6524 f.write_str(", ")?;
6525 self.to.render(ctx, f)?;
6526 f.write_str(")")
6527 }
6528}
6529
6530impl Render for ReplicaThreadOption {
6531 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6532 f.write_str(match self {
6533 Self::Sql { .. } => "SQL_THREAD",
6534 Self::Io {
6535 keyword: IoThreadKeyword::Io,
6536 ..
6537 } => "IO_THREAD",
6538 Self::Io {
6539 keyword: IoThreadKeyword::Relay,
6540 ..
6541 } => "RELAY_THREAD",
6542 })
6543 }
6544}
6545
6546impl Render for ReplicaUntilCondition {
6547 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6548 match self {
6549 Self::SourceLogFile { value, .. } => {
6550 f.write_str("SOURCE_LOG_FILE = ")?;
6551 value.render(ctx, f)
6552 }
6553 Self::SourceLogPos { value, .. } => {
6554 f.write_str("SOURCE_LOG_POS = ")?;
6555 value.render(ctx, f)
6556 }
6557 Self::RelayLogFile { value, .. } => {
6558 f.write_str("RELAY_LOG_FILE = ")?;
6559 value.render(ctx, f)
6560 }
6561 Self::RelayLogPos { value, .. } => {
6562 f.write_str("RELAY_LOG_POS = ")?;
6563 value.render(ctx, f)
6564 }
6565 Self::SqlBeforeGtids { value, .. } => {
6566 f.write_str("SQL_BEFORE_GTIDS = ")?;
6567 value.render(ctx, f)
6568 }
6569 Self::SqlAfterGtids { value, .. } => {
6570 f.write_str("SQL_AFTER_GTIDS = ")?;
6571 value.render(ctx, f)
6572 }
6573 Self::SqlAfterMtsGaps { .. } => f.write_str("SQL_AFTER_MTS_GAPS"),
6574 }
6575 }
6576}
6577
6578impl Render for GroupReplicationOption {
6579 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6580 match self {
6581 Self::User { value, .. } => {
6582 f.write_str("USER = ")?;
6583 value.render(ctx, f)
6584 }
6585 Self::Password { value, .. } => {
6586 f.write_str("PASSWORD = ")?;
6587 value.render(ctx, f)
6588 }
6589 Self::DefaultAuth { value, .. } => {
6590 f.write_str("DEFAULT_AUTH = ")?;
6591 value.render(ctx, f)
6592 }
6593 }
6594 }
6595}
6596
6597impl Render for AccountName {
6598 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6599 match self {
6600 Self::Account { user, host, .. } => {
6601 user.render(ctx, f)?;
6602 if let Some(host) = host {
6603 f.write_str("@")?;
6604 host.render(ctx, f)?;
6605 }
6606 Ok(())
6607 }
6608 Self::CurrentUser { parens, .. } => {
6609 f.write_str("CURRENT_USER")?;
6610 if *parens {
6611 f.write_str("()")?;
6612 }
6613 Ok(())
6614 }
6615 }
6616 }
6617}
6618
6619struct UserOptionTail<'a> {
6625 require: &'a Option<TlsRequirement>,
6626 resource_options: &'a [ResourceLimit],
6627 password_lock_options: &'a [PasswordLockOption],
6628 attribute: &'a Option<UserAttribute>,
6629}
6630
6631fn render_user_option_tail(
6634 tail: UserOptionTail<'_>,
6635 ctx: &RenderCtx<'_>,
6636 f: &mut fmt::Formatter<'_>,
6637) -> fmt::Result {
6638 if let Some(require) = tail.require {
6639 f.write_str(" ")?;
6640 require.render(ctx, f)?;
6641 }
6642 if !tail.resource_options.is_empty() {
6643 f.write_str(" WITH")?;
6645 for option in tail.resource_options {
6646 f.write_str(" ")?;
6647 option.render(ctx, f)?;
6648 }
6649 }
6650 for option in tail.password_lock_options {
6651 f.write_str(" ")?;
6652 option.render(ctx, f)?;
6653 }
6654 if let Some(attribute) = tail.attribute {
6655 f.write_str(" ")?;
6656 attribute.render(ctx, f)?;
6657 }
6658 Ok(())
6659}
6660
6661impl Render for CreateUser {
6662 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6663 f.write_str("CREATE USER ")?;
6664 if self.if_not_exists {
6665 f.write_str("IF NOT EXISTS ")?;
6666 }
6667 render_comma_separated(&self.users, ctx, f)?;
6668 if !self.default_roles.is_empty() {
6669 f.write_str(" DEFAULT ROLE ")?;
6670 render_comma_separated(&self.default_roles, ctx, f)?;
6671 }
6672 render_user_option_tail(
6673 UserOptionTail {
6674 require: &self.require,
6675 resource_options: &self.resource_options,
6676 password_lock_options: &self.password_lock_options,
6677 attribute: &self.attribute,
6678 },
6679 ctx,
6680 f,
6681 )
6682 }
6683}
6684
6685impl Render for UserSpec {
6686 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6687 self.account.render(ctx, f)?;
6688 if let Some(auth) = &self.auth {
6689 f.write_str(" ")?;
6690 auth.render(ctx, f)?;
6691 }
6692 Ok(())
6693 }
6694}
6695
6696impl Render for AuthOption {
6697 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6698 match self {
6699 Self::Password { password, .. } => {
6700 f.write_str("IDENTIFIED BY ")?;
6701 password.render(ctx, f)
6702 }
6703 Self::RandomPassword { .. } => f.write_str("IDENTIFIED BY RANDOM PASSWORD"),
6704 Self::Plugin { plugin, .. } => {
6705 f.write_str("IDENTIFIED WITH ")?;
6706 plugin.render(ctx, f)
6707 }
6708 Self::PluginAs {
6709 plugin,
6710 auth_string,
6711 ..
6712 } => {
6713 f.write_str("IDENTIFIED WITH ")?;
6714 plugin.render(ctx, f)?;
6715 f.write_str(" AS ")?;
6716 auth_string.render(ctx, f)
6717 }
6718 Self::PluginByPassword {
6719 plugin, password, ..
6720 } => {
6721 f.write_str("IDENTIFIED WITH ")?;
6722 plugin.render(ctx, f)?;
6723 f.write_str(" BY ")?;
6724 password.render(ctx, f)
6725 }
6726 Self::PluginByRandomPassword { plugin, .. } => {
6727 f.write_str("IDENTIFIED WITH ")?;
6728 plugin.render(ctx, f)?;
6729 f.write_str(" BY RANDOM PASSWORD")
6730 }
6731 }
6732 }
6733}
6734
6735impl Render for TlsRequirement {
6736 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6737 f.write_str("REQUIRE ")?;
6738 match self {
6739 Self::None { .. } => f.write_str("NONE"),
6740 Self::Ssl { .. } => f.write_str("SSL"),
6741 Self::X509 { .. } => f.write_str("X509"),
6742 Self::Options { options, .. } => {
6743 for (i, option) in options.iter().enumerate() {
6744 if i > 0 {
6745 f.write_str(" AND ")?;
6746 }
6747 option.render(ctx, f)?;
6748 }
6749 Ok(())
6750 }
6751 }
6752 }
6753}
6754
6755impl Render for TlsOption {
6756 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6757 match self {
6758 Self::Subject { value, .. } => {
6759 f.write_str("SUBJECT ")?;
6760 value.render(ctx, f)
6761 }
6762 Self::Issuer { value, .. } => {
6763 f.write_str("ISSUER ")?;
6764 value.render(ctx, f)
6765 }
6766 Self::Cipher { value, .. } => {
6767 f.write_str("CIPHER ")?;
6768 value.render(ctx, f)
6769 }
6770 }
6771 }
6772}
6773
6774impl Render for ResourceLimit {
6775 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6776 let (keyword, value) = match self {
6777 Self::MaxQueriesPerHour { value, .. } => ("MAX_QUERIES_PER_HOUR", value),
6778 Self::MaxUpdatesPerHour { value, .. } => ("MAX_UPDATES_PER_HOUR", value),
6779 Self::MaxConnectionsPerHour { value, .. } => ("MAX_CONNECTIONS_PER_HOUR", value),
6780 Self::MaxUserConnections { value, .. } => ("MAX_USER_CONNECTIONS", value),
6781 };
6782 f.write_str(keyword)?;
6783 f.write_str(" ")?;
6784 value.render(ctx, f)
6785 }
6786}
6787
6788impl Render for PasswordLockOption {
6789 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6790 match self {
6791 Self::AccountLock { .. } => f.write_str("ACCOUNT LOCK"),
6792 Self::AccountUnlock { .. } => f.write_str("ACCOUNT UNLOCK"),
6793 Self::PasswordExpire { .. } => f.write_str("PASSWORD EXPIRE"),
6794 Self::PasswordExpireDefault { .. } => f.write_str("PASSWORD EXPIRE DEFAULT"),
6795 Self::PasswordExpireNever { .. } => f.write_str("PASSWORD EXPIRE NEVER"),
6796 Self::PasswordExpireInterval { days, .. } => {
6797 f.write_str("PASSWORD EXPIRE INTERVAL ")?;
6798 days.render(ctx, f)?;
6799 f.write_str(" DAY")
6800 }
6801 Self::PasswordHistory { count, .. } => {
6802 f.write_str("PASSWORD HISTORY ")?;
6803 count.render(ctx, f)
6804 }
6805 Self::PasswordHistoryDefault { .. } => f.write_str("PASSWORD HISTORY DEFAULT"),
6806 Self::PasswordReuseInterval { days, .. } => {
6807 f.write_str("PASSWORD REUSE INTERVAL ")?;
6808 days.render(ctx, f)?;
6809 f.write_str(" DAY")
6810 }
6811 Self::PasswordReuseIntervalDefault { .. } => {
6812 f.write_str("PASSWORD REUSE INTERVAL DEFAULT")
6813 }
6814 Self::PasswordRequireCurrent { .. } => f.write_str("PASSWORD REQUIRE CURRENT"),
6815 Self::PasswordRequireCurrentDefault { .. } => {
6816 f.write_str("PASSWORD REQUIRE CURRENT DEFAULT")
6817 }
6818 Self::PasswordRequireCurrentOptional { .. } => {
6819 f.write_str("PASSWORD REQUIRE CURRENT OPTIONAL")
6820 }
6821 Self::FailedLoginAttempts { count, .. } => {
6822 f.write_str("FAILED_LOGIN_ATTEMPTS ")?;
6823 count.render(ctx, f)
6824 }
6825 Self::PasswordLockTime { days, .. } => {
6826 f.write_str("PASSWORD_LOCK_TIME ")?;
6827 days.render(ctx, f)
6828 }
6829 Self::PasswordLockTimeUnbounded { .. } => f.write_str("PASSWORD_LOCK_TIME UNBOUNDED"),
6830 }
6831 }
6832}
6833
6834impl Render for UserAttribute {
6835 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6836 match self {
6837 Self::Comment { comment, .. } => {
6838 f.write_str("COMMENT ")?;
6839 comment.render(ctx, f)
6840 }
6841 Self::Attribute { attribute, .. } => {
6842 f.write_str("ATTRIBUTE ")?;
6843 attribute.render(ctx, f)
6844 }
6845 }
6846 }
6847}
6848
6849impl Render for AlterUser {
6850 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6851 f.write_str("ALTER USER ")?;
6852 match self {
6853 Self::Modify {
6854 if_exists,
6855 users,
6856 require,
6857 resource_options,
6858 password_lock_options,
6859 attribute,
6860 ..
6861 } => {
6862 if *if_exists {
6863 f.write_str("IF EXISTS ")?;
6864 }
6865 render_comma_separated(users, ctx, f)?;
6866 render_user_option_tail(
6867 UserOptionTail {
6868 require,
6869 resource_options,
6870 password_lock_options,
6871 attribute,
6872 },
6873 ctx,
6874 f,
6875 )
6876 }
6877 Self::DefaultRole {
6878 if_exists,
6879 user,
6880 roles,
6881 ..
6882 } => {
6883 if *if_exists {
6884 f.write_str("IF EXISTS ")?;
6885 }
6886 user.render(ctx, f)?;
6887 f.write_str(" DEFAULT ROLE ")?;
6888 roles.render(ctx, f)
6889 }
6890 }
6891 }
6892}
6893
6894impl Render for AlterUserSpec {
6895 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6896 self.account.render(ctx, f)?;
6897 if let Some(auth) = &self.auth {
6898 f.write_str(" ")?;
6899 auth.render(ctx, f)?;
6900 }
6901 if let Some(replace) = &self.replace {
6902 f.write_str(" REPLACE ")?;
6903 replace.render(ctx, f)?;
6904 }
6905 if self.retain_current_password {
6906 f.write_str(" RETAIN CURRENT PASSWORD")?;
6907 }
6908 if self.discard_old_password {
6909 f.write_str(" DISCARD OLD PASSWORD")?;
6910 }
6911 Ok(())
6912 }
6913}
6914
6915impl Render for DefaultRoleTarget {
6916 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6917 match self {
6918 Self::All { .. } => f.write_str("ALL"),
6919 Self::None { .. } => f.write_str("NONE"),
6920 Self::Roles { roles, .. } => render_comma_separated(roles, ctx, f),
6921 }
6922 }
6923}
6924
6925impl Render for UserRoleList {
6926 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6927 let (verb, guard) = match self.kind {
6928 UserRoleListKind::DropUser => ("DROP USER ", "IF EXISTS "),
6929 UserRoleListKind::CreateRole => ("CREATE ROLE ", "IF NOT EXISTS "),
6930 UserRoleListKind::DropRole => ("DROP ROLE ", "IF EXISTS "),
6931 };
6932 f.write_str(verb)?;
6933 if self.if_guard {
6934 f.write_str(guard)?;
6935 }
6936 render_comma_separated(&self.names, ctx, f)
6937 }
6938}
6939
6940fn no_write_to_binlog_keyword(prefix: NoWriteToBinlog) -> &'static str {
6942 match prefix {
6943 NoWriteToBinlog::NoWriteToBinlog => "NO_WRITE_TO_BINLOG",
6944 NoWriteToBinlog::Local => "LOCAL",
6945 }
6946}
6947
6948fn table_keyword_str(keyword: TableKeyword) -> &'static str {
6950 match keyword {
6951 TableKeyword::Table => "TABLE",
6952 TableKeyword::Tables => "TABLES",
6953 }
6954}
6955
6956fn check_table_option_keyword(option: CheckTableOption) -> &'static str {
6958 match option {
6959 CheckTableOption::ForUpgrade => "FOR UPGRADE",
6960 CheckTableOption::Quick => "QUICK",
6961 CheckTableOption::Fast => "FAST",
6962 CheckTableOption::Medium => "MEDIUM",
6963 CheckTableOption::Extended => "EXTENDED",
6964 CheckTableOption::Changed => "CHANGED",
6965 }
6966}
6967
6968fn checksum_table_option_keyword(option: ChecksumTableOption) -> &'static str {
6970 match option {
6971 ChecksumTableOption::Quick => "QUICK",
6972 ChecksumTableOption::Extended => "EXTENDED",
6973 }
6974}
6975
6976fn repair_table_option_keyword(option: RepairTableOption) -> &'static str {
6978 match option {
6979 RepairTableOption::Quick => "QUICK",
6980 RepairTableOption::Extended => "EXTENDED",
6981 RepairTableOption::UseFrm => "USE_FRM",
6982 }
6983}
6984
6985impl<X: Extension + Render> Render for PrepareStatement<X> {
6986 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
6987 f.write_str("PREPARE ")?;
6988 self.name.render(ctx, f)?;
6989 if !self.parameter_types.is_empty() {
6993 f.write_str("(")?;
6994 render_comma_separated(&self.parameter_types, ctx, f)?;
6995 f.write_str(")")?;
6996 }
6997 f.write_str(" AS ")?;
6998 self.statement.render(ctx, f)
6999 }
7000}
7001
7002impl<X: Extension + Render> Render for ExecuteStatement<X> {
7003 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7004 f.write_str("EXECUTE ")?;
7005 self.name.render(ctx, f)?;
7006 if !self.args.is_empty() {
7009 f.write_str("(")?;
7010 render_comma_separated(&self.args, ctx, f)?;
7011 f.write_str(")")?;
7012 }
7013 Ok(())
7014 }
7015}
7016
7017impl Render for DeallocateStatement {
7018 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7019 f.write_str(match self.keyword {
7022 DeallocateKeyword::Deallocate => "DEALLOCATE ",
7023 DeallocateKeyword::Drop => "DROP ",
7024 })?;
7025 if self.prepare_keyword {
7026 f.write_str("PREPARE ")?;
7027 }
7028 self.name.render(ctx, f)
7029 }
7030}
7031
7032impl Render for PrepareFromStatement {
7033 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7034 f.write_str("PREPARE ")?;
7035 self.name.render(ctx, f)?;
7036 f.write_str(" FROM ")?;
7037 self.source.render(ctx, f)
7038 }
7039}
7040
7041impl Render for PrepareSource {
7042 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7043 match self {
7044 PrepareSource::Text { source, .. } => source.render(ctx, f),
7046 PrepareSource::Variable { name, .. } => {
7049 f.write_str("@")?;
7050 name.render(ctx, f)
7051 }
7052 }
7053 }
7054}
7055
7056impl Render for ExecuteUsingStatement {
7057 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7058 f.write_str("EXECUTE ")?;
7059 self.name.render(ctx, f)?;
7060 if let Some((first, rest)) = self.using.split_first() {
7063 f.write_str(" USING @")?;
7064 first.render(ctx, f)?;
7065 for name in rest {
7066 f.write_str(", @")?;
7067 name.render(ctx, f)?;
7068 }
7069 }
7070 Ok(())
7071 }
7072}
7073
7074impl<X: Extension + Render> Render for CallStatement<X> {
7075 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7076 f.write_str("CALL ")?;
7077 self.name.render(ctx, f)?;
7078 if self.parenthesized {
7081 f.write_str("(")?;
7082 render_comma_separated(&self.args, ctx, f)?;
7083 f.write_str(")")?;
7084 }
7085 Ok(())
7086 }
7087}
7088
7089impl Render for DoStatement {
7090 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7091 f.write_str("DO")?;
7092 for arg in &self.args {
7096 f.write_str(" ")?;
7097 arg.render(ctx, f)?;
7098 }
7099 Ok(())
7100 }
7101}
7102
7103impl Render for DoArg {
7104 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7105 match self {
7106 DoArg::Body { body, .. } => body.render(ctx, f),
7107 DoArg::Language { name, .. } => {
7108 f.write_str("LANGUAGE ")?;
7109 name.render(ctx, f)
7110 }
7111 }
7112 }
7113}
7114
7115impl Render for LanguageName {
7116 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7117 match self {
7118 Self::Word { word, .. } => word.render(ctx, f),
7119 Self::String { value, .. } => value.render(ctx, f),
7120 }
7121 }
7122}
7123
7124impl<X: Extension + Render> Render for DoExpressionsStatement<X> {
7125 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7126 f.write_str("DO ")?;
7128 render_comma_separated(&self.items, ctx, f)
7129 }
7130}
7131
7132impl Render for LockTablesStatement {
7133 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7134 f.write_str(if self.plural {
7137 "LOCK TABLES "
7138 } else {
7139 "LOCK TABLE "
7140 })?;
7141 render_comma_separated(&self.tables, ctx, f)
7142 }
7143}
7144
7145impl Render for TableLock {
7146 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7147 self.name.render(ctx, f)?;
7148 if let Some(alias) = &self.alias {
7149 f.write_str(" ")?;
7152 alias.render(ctx, f)?;
7153 }
7154 f.write_str(" ")?;
7155 self.kind.render(ctx, f)
7156 }
7157}
7158
7159impl Render for TableLockKind {
7160 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7161 f.write_str(match self {
7162 TableLockKind::Read => "READ",
7163 TableLockKind::ReadLocal => "READ LOCAL",
7164 TableLockKind::Write => "WRITE",
7165 })
7166 }
7167}
7168
7169impl Render for UnlockTablesStatement {
7170 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7171 f.write_str(if self.plural {
7172 "UNLOCK TABLES"
7173 } else {
7174 "UNLOCK TABLE"
7175 })
7176 }
7177}
7178
7179impl Render for InstanceLockStatement {
7180 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7181 f.write_str(if self.acquire {
7182 "LOCK INSTANCE FOR BACKUP"
7183 } else {
7184 "UNLOCK INSTANCE"
7185 })
7186 }
7187}
7188
7189impl<X: Extension + Render> Render for LoadDataStatement<X> {
7190 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7191 f.write_str("LOAD ")?;
7194 self.format.render(ctx, f)?;
7195 if let Some(concurrency) = self.concurrency {
7196 f.write_str(" ")?;
7197 concurrency.render(ctx, f)?;
7198 }
7199 if self.local {
7200 f.write_str(" LOCAL")?;
7201 }
7202 f.write_str(" INFILE ")?;
7203 self.file.render(ctx, f)?;
7204 if let Some(on_duplicate) = self.on_duplicate {
7205 f.write_str(" ")?;
7206 on_duplicate.render(ctx, f)?;
7207 }
7208 f.write_str(" INTO TABLE ")?;
7209 self.table.render(ctx, f)?;
7210 if !self.partitions.is_empty() {
7211 f.write_str(" PARTITION (")?;
7212 render_comma_separated(&self.partitions, ctx, f)?;
7213 f.write_str(")")?;
7214 }
7215 if let Some(charset) = &self.charset {
7216 f.write_str(" CHARACTER SET ")?;
7217 charset.render(ctx, f)?;
7218 }
7219 if let Some(tag) = &self.rows_identified_by {
7220 f.write_str(" ROWS IDENTIFIED BY ")?;
7221 tag.render(ctx, f)?;
7222 }
7223 if let Some(fields) = &self.fields {
7224 f.write_str(" ")?;
7225 fields.render(ctx, f)?;
7226 }
7227 if let Some(lines) = &self.lines {
7228 f.write_str(" ")?;
7229 lines.render(ctx, f)?;
7230 }
7231 if let Some(ignore_rows) = &self.ignore_rows {
7232 f.write_str(" ")?;
7233 ignore_rows.render(ctx, f)?;
7234 }
7235 if !self.columns.is_empty() {
7236 f.write_str(" (")?;
7237 render_comma_separated(&self.columns, ctx, f)?;
7238 f.write_str(")")?;
7239 }
7240 if !self.set.is_empty() {
7241 f.write_str(" SET ")?;
7242 render_comma_separated(&self.set, ctx, f)?;
7243 }
7244 Ok(())
7245 }
7246}
7247
7248impl Render for LoadDataFormat {
7249 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7250 f.write_str(match self {
7251 LoadDataFormat::Data => "DATA",
7252 LoadDataFormat::Xml => "XML",
7253 })
7254 }
7255}
7256
7257impl Render for LoadDataConcurrency {
7258 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7259 f.write_str(match self {
7260 LoadDataConcurrency::LowPriority => "LOW_PRIORITY",
7261 LoadDataConcurrency::Concurrent => "CONCURRENT",
7262 })
7263 }
7264}
7265
7266impl Render for LoadDataDuplicate {
7267 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7268 f.write_str(match self {
7269 LoadDataDuplicate::Replace => "REPLACE",
7270 LoadDataDuplicate::Ignore => "IGNORE",
7271 })
7272 }
7273}
7274
7275impl Render for LoadDataFields {
7276 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7277 self.spelling.render(ctx, f)?;
7280 if let Some(terminated_by) = &self.terminated_by {
7281 f.write_str(" TERMINATED BY ")?;
7282 terminated_by.render(ctx, f)?;
7283 }
7284 if let Some(enclosed_by) = &self.enclosed_by {
7285 f.write_str(" ")?;
7286 enclosed_by.render(ctx, f)?;
7287 }
7288 if let Some(escaped_by) = &self.escaped_by {
7289 f.write_str(" ESCAPED BY ")?;
7290 escaped_by.render(ctx, f)?;
7291 }
7292 Ok(())
7293 }
7294}
7295
7296impl Render for LoadFieldsSpelling {
7297 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7298 f.write_str(match self {
7299 LoadFieldsSpelling::Fields => "FIELDS",
7300 LoadFieldsSpelling::Columns => "COLUMNS",
7301 })
7302 }
7303}
7304
7305impl Render for LoadDataEnclosed {
7306 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7307 if self.optionally {
7308 f.write_str("OPTIONALLY ")?;
7309 }
7310 f.write_str("ENCLOSED BY ")?;
7311 self.value.render(ctx, f)
7312 }
7313}
7314
7315impl Render for LoadDataLines {
7316 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7317 f.write_str("LINES")?;
7318 if let Some(starting_by) = &self.starting_by {
7319 f.write_str(" STARTING BY ")?;
7320 starting_by.render(ctx, f)?;
7321 }
7322 if let Some(terminated_by) = &self.terminated_by {
7323 f.write_str(" TERMINATED BY ")?;
7324 terminated_by.render(ctx, f)?;
7325 }
7326 Ok(())
7327 }
7328}
7329
7330impl Render for LoadDataIgnoreRows {
7331 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7332 f.write_str("IGNORE ")?;
7333 self.count.render(ctx, f)?;
7334 f.write_str(" ")?;
7335 self.unit.render(ctx, f)
7336 }
7337}
7338
7339impl Render for LoadDataIgnoreUnit {
7340 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7341 f.write_str(match self {
7342 LoadDataIgnoreUnit::Lines => "LINES",
7343 LoadDataIgnoreUnit::Rows => "ROWS",
7344 })
7345 }
7346}
7347
7348impl Render for LoadDataFieldOrVar {
7349 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7350 match self {
7351 LoadDataFieldOrVar::Column { name, .. } => name.render(ctx, f),
7352 LoadDataFieldOrVar::Variable { name, .. } => {
7355 f.write_str("@")?;
7356 name.render(ctx, f)
7357 }
7358 }
7359 }
7360}
7361
7362impl<X: Extension + Render> Render for CreateTrigger<X> {
7363 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7364 f.write_str("CREATE")?;
7365 if let Some(temporary) = self.temporary {
7366 f.write_str(" ")?;
7367 temporary.render(ctx, f)?;
7368 }
7369 f.write_str(" TRIGGER")?;
7370 if self.if_not_exists {
7371 f.write_str(" IF NOT EXISTS")?;
7372 }
7373 f.write_str(" ")?;
7374 self.name.render(ctx, f)?;
7375 if let Some(timing) = self.timing {
7376 f.write_str(" ")?;
7377 timing.render(ctx, f)?;
7378 }
7379 f.write_str(" ")?;
7380 self.event.render(ctx, f)?;
7381 f.write_str(" ON ")?;
7382 self.table.render(ctx, f)?;
7383 if self.for_each_row {
7384 f.write_str(" FOR EACH ROW")?;
7385 }
7386 if let Some(when) = &self.when {
7387 f.write_str(" WHEN ")?;
7388 when.render(ctx, f)?;
7389 }
7390 f.write_str(" BEGIN ")?;
7391 for statement in &self.body {
7392 statement.render(ctx, f)?;
7393 f.write_str("; ")?;
7394 }
7395 f.write_str("END")
7396 }
7397}
7398
7399impl Render for TriggerTiming {
7400 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7401 f.write_str(match self {
7402 TriggerTiming::Before => "BEFORE",
7403 TriggerTiming::After => "AFTER",
7404 TriggerTiming::InsteadOf => "INSTEAD OF",
7405 })
7406 }
7407}
7408
7409impl Render for TriggerEvent {
7410 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7411 match self {
7412 TriggerEvent::Delete { .. } => f.write_str("DELETE"),
7413 TriggerEvent::Insert { .. } => f.write_str("INSERT"),
7414 TriggerEvent::Update { columns, .. } => {
7415 f.write_str("UPDATE")?;
7416 if !columns.is_empty() {
7417 f.write_str(" OF ")?;
7418 render_ident_list(columns, ctx, f)?;
7419 }
7420 Ok(())
7421 }
7422 }
7423 }
7424}
7425
7426impl<X: Extension + Render> Render for CreateStoredTrigger<X> {
7427 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7428 f.write_str("CREATE ")?;
7429 if let Some(definer) = &self.definer {
7430 definer.render(ctx, f)?;
7431 f.write_str(" ")?;
7432 }
7433 f.write_str("TRIGGER ")?;
7434 if self.if_not_exists {
7435 f.write_str("IF NOT EXISTS ")?;
7436 }
7437 self.name.render(ctx, f)?;
7438 f.write_str(" ")?;
7439 self.timing.render(ctx, f)?;
7440 f.write_str(" ")?;
7441 self.event.render(ctx, f)?;
7442 f.write_str(" ON ")?;
7443 self.table.render(ctx, f)?;
7444 f.write_str(" FOR EACH ROW")?;
7445 if let Some(ordering) = &self.ordering {
7446 f.write_str(" ")?;
7447 ordering.render(ctx, f)?;
7448 }
7449 f.write_str(" ")?;
7450 self.body.render(ctx, f)
7451 }
7452}
7453
7454impl Render for TriggerOrder {
7455 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7456 match self {
7457 TriggerOrder::Follows { anchor, .. } => {
7458 f.write_str("FOLLOWS ")?;
7459 anchor.render(ctx, f)
7460 }
7461 TriggerOrder::Precedes { anchor, .. } => {
7462 f.write_str("PRECEDES ")?;
7463 anchor.render(ctx, f)
7464 }
7465 }
7466 }
7467}
7468
7469fn render_compound_body<X: Extension + Render>(
7477 body: &[Statement<X>],
7478 ctx: &RenderCtx<'_>,
7479 f: &mut fmt::Formatter<'_>,
7480) -> fmt::Result {
7481 for statement in body {
7482 f.write_str(" ")?;
7483 statement.render(ctx, f)?;
7484 f.write_str(";")?;
7485 }
7486 Ok(())
7487}
7488
7489impl<X: Extension + Render> Render for CompoundStatement<X> {
7490 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7491 if let Some(label) = &self.label {
7492 label.render(ctx, f)?;
7493 f.write_str(": ")?;
7494 }
7495 f.write_str("BEGIN")?;
7496 for declaration in &self.declarations {
7497 f.write_str(" ")?;
7498 declaration.render(ctx, f)?;
7499 f.write_str(";")?;
7500 }
7501 render_compound_body(&self.body, ctx, f)?;
7502 f.write_str(" END")?;
7503 if let Some(end_label) = &self.end_label {
7504 f.write_str(" ")?;
7505 end_label.render(ctx, f)?;
7506 }
7507 Ok(())
7508 }
7509}
7510
7511impl<X: Extension + Render> Render for Declaration<X> {
7512 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7513 match self {
7514 Declaration::Variable {
7515 names,
7516 data_type,
7517 default,
7518 ..
7519 } => {
7520 f.write_str("DECLARE ")?;
7521 render_ident_list(names, ctx, f)?;
7522 f.write_str(" ")?;
7523 data_type.render(ctx, f)?;
7524 if let Some(default) = default {
7525 f.write_str(" DEFAULT ")?;
7526 default.render(ctx, f)?;
7527 }
7528 Ok(())
7529 }
7530 Declaration::Condition { name, value, .. } => {
7531 f.write_str("DECLARE ")?;
7532 name.render(ctx, f)?;
7533 f.write_str(" CONDITION FOR ")?;
7534 value.render(ctx, f)
7535 }
7536 Declaration::Cursor { name, query, .. } => {
7537 f.write_str("DECLARE ")?;
7538 name.render(ctx, f)?;
7539 f.write_str(" CURSOR FOR ")?;
7540 query.render(ctx, f)
7541 }
7542 Declaration::Handler {
7543 action,
7544 conditions,
7545 body,
7546 ..
7547 } => {
7548 f.write_str("DECLARE ")?;
7549 action.render(ctx, f)?;
7550 f.write_str(" HANDLER FOR ")?;
7551 render_comma_separated(conditions, ctx, f)?;
7552 f.write_str(" ")?;
7553 body.render(ctx, f)
7554 }
7555 }
7556 }
7557}
7558
7559impl Render for HandlerAction {
7560 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7561 f.write_str(match self {
7562 HandlerAction::Continue => "CONTINUE",
7563 HandlerAction::Exit => "EXIT",
7564 HandlerAction::Undo => "UNDO",
7565 })
7566 }
7567}
7568
7569impl Render for ConditionValue {
7570 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7571 match self {
7572 ConditionValue::SqlState {
7573 value_keyword,
7574 sqlstate,
7575 ..
7576 } => {
7577 f.write_str("SQLSTATE ")?;
7578 if *value_keyword {
7579 f.write_str("VALUE ")?;
7580 }
7581 sqlstate.render(ctx, f)
7582 }
7583 ConditionValue::ErrorCode { code, .. } => code.render(ctx, f),
7584 ConditionValue::ConditionName { name, .. } => name.render(ctx, f),
7585 }
7586 }
7587}
7588
7589impl Render for HandlerCondition {
7590 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7591 match self {
7592 HandlerCondition::SqlState {
7593 value_keyword,
7594 sqlstate,
7595 ..
7596 } => {
7597 f.write_str("SQLSTATE ")?;
7598 if *value_keyword {
7599 f.write_str("VALUE ")?;
7600 }
7601 sqlstate.render(ctx, f)
7602 }
7603 HandlerCondition::ErrorCode { code, .. } => code.render(ctx, f),
7604 HandlerCondition::ConditionName { name, .. } => name.render(ctx, f),
7605 HandlerCondition::SqlWarning { .. } => f.write_str("SQLWARNING"),
7606 HandlerCondition::NotFound { .. } => f.write_str("NOT FOUND"),
7607 HandlerCondition::SqlException { .. } => f.write_str("SQLEXCEPTION"),
7608 }
7609 }
7610}
7611
7612impl<X: Extension + Render> Render for ConditionalBranch<X> {
7613 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7614 self.guard.render(ctx, f)?;
7615 f.write_str(" THEN")?;
7616 render_compound_body(&self.body, ctx, f)
7617 }
7618}
7619
7620impl<X: Extension + Render> Render for IfStatement<X> {
7621 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7622 f.write_str("IF ")?;
7623 for (i, branch) in self.branches.iter().enumerate() {
7624 if i > 0 {
7625 f.write_str(" ELSEIF ")?;
7626 }
7627 branch.render(ctx, f)?;
7628 }
7629 if let Some(else_body) = &self.else_body {
7630 f.write_str(" ELSE")?;
7631 render_compound_body(else_body, ctx, f)?;
7632 }
7633 f.write_str(" END IF")
7634 }
7635}
7636
7637impl<X: Extension + Render> Render for CaseStatement<X> {
7638 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7639 f.write_str("CASE")?;
7640 if let Some(operand) = &self.operand {
7641 f.write_str(" ")?;
7642 operand.render(ctx, f)?;
7643 }
7644 for branch in &self.when_branches {
7645 f.write_str(" WHEN ")?;
7646 branch.render(ctx, f)?;
7647 }
7648 if let Some(else_body) = &self.else_body {
7649 f.write_str(" ELSE")?;
7650 render_compound_body(else_body, ctx, f)?;
7651 }
7652 f.write_str(" END CASE")
7653 }
7654}
7655
7656impl<X: Extension + Render> Render for LoopStatement<X> {
7657 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7658 if let Some(label) = &self.label {
7659 label.render(ctx, f)?;
7660 f.write_str(": ")?;
7661 }
7662 f.write_str("LOOP")?;
7663 render_compound_body(&self.body, ctx, f)?;
7664 f.write_str(" END LOOP")?;
7665 if let Some(end_label) = &self.end_label {
7666 f.write_str(" ")?;
7667 end_label.render(ctx, f)?;
7668 }
7669 Ok(())
7670 }
7671}
7672
7673impl<X: Extension + Render> Render for WhileStatement<X> {
7674 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7675 if let Some(label) = &self.label {
7676 label.render(ctx, f)?;
7677 f.write_str(": ")?;
7678 }
7679 f.write_str("WHILE ")?;
7680 self.condition.render(ctx, f)?;
7681 f.write_str(" DO")?;
7682 render_compound_body(&self.body, ctx, f)?;
7683 f.write_str(" END WHILE")?;
7684 if let Some(end_label) = &self.end_label {
7685 f.write_str(" ")?;
7686 end_label.render(ctx, f)?;
7687 }
7688 Ok(())
7689 }
7690}
7691
7692impl<X: Extension + Render> Render for RepeatStatement<X> {
7693 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7694 if let Some(label) = &self.label {
7695 label.render(ctx, f)?;
7696 f.write_str(": ")?;
7697 }
7698 f.write_str("REPEAT")?;
7699 render_compound_body(&self.body, ctx, f)?;
7700 f.write_str(" UNTIL ")?;
7701 self.condition.render(ctx, f)?;
7702 f.write_str(" END REPEAT")?;
7703 if let Some(end_label) = &self.end_label {
7704 f.write_str(" ")?;
7705 end_label.render(ctx, f)?;
7706 }
7707 Ok(())
7708 }
7709}
7710
7711impl Render for LeaveStatement {
7712 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7713 f.write_str("LEAVE ")?;
7714 self.label.render(ctx, f)
7715 }
7716}
7717
7718impl Render for IterateStatement {
7719 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7720 f.write_str("ITERATE ")?;
7721 self.label.render(ctx, f)
7722 }
7723}
7724
7725impl<X: Extension + Render> Render for ReturnStatement<X> {
7726 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7727 f.write_str("RETURN ")?;
7728 self.value.render(ctx, f)
7729 }
7730}
7731
7732impl Render for OpenCursorStatement {
7733 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7734 f.write_str("OPEN ")?;
7735 self.cursor.render(ctx, f)
7736 }
7737}
7738
7739impl Render for CloseCursorStatement {
7740 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7741 f.write_str("CLOSE ")?;
7742 self.cursor.render(ctx, f)
7743 }
7744}
7745
7746impl Render for FetchCursorStatement {
7747 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7748 f.write_str("FETCH ")?;
7749 if self.next_keyword {
7750 f.write_str("NEXT ")?;
7751 }
7752 if self.from_keyword {
7753 f.write_str("FROM ")?;
7754 }
7755 self.cursor.render(ctx, f)?;
7756 f.write_str(" INTO ")?;
7757 render_ident_list(&self.targets, ctx, f)
7758 }
7759}
7760
7761impl<X: Extension + Render> SignalStatement<X> {
7762 fn render_as(
7765 &self,
7766 ctx: &RenderCtx<'_>,
7767 f: &mut fmt::Formatter<'_>,
7768 keyword: &str,
7769 ) -> fmt::Result {
7770 f.write_str(keyword)?;
7771 if let Some(condition) = &self.condition {
7772 f.write_str(" ")?;
7773 condition.render(ctx, f)?;
7774 }
7775 if !self.set_items.is_empty() {
7776 f.write_str(" SET ")?;
7777 render_comma_separated(&self.set_items, ctx, f)?;
7778 }
7779 Ok(())
7780 }
7781}
7782
7783impl<X: Extension + Render> Render for SignalItem<X> {
7784 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7785 self.name.render(ctx, f)?;
7786 f.write_str(" = ")?;
7787 self.value.render(ctx, f)
7788 }
7789}
7790
7791impl Render for SignalItemName {
7792 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7793 f.write_str(match self {
7794 SignalItemName::ClassOrigin => "CLASS_ORIGIN",
7795 SignalItemName::SubclassOrigin => "SUBCLASS_ORIGIN",
7796 SignalItemName::ConstraintCatalog => "CONSTRAINT_CATALOG",
7797 SignalItemName::ConstraintSchema => "CONSTRAINT_SCHEMA",
7798 SignalItemName::ConstraintName => "CONSTRAINT_NAME",
7799 SignalItemName::CatalogName => "CATALOG_NAME",
7800 SignalItemName::SchemaName => "SCHEMA_NAME",
7801 SignalItemName::TableName => "TABLE_NAME",
7802 SignalItemName::ColumnName => "COLUMN_NAME",
7803 SignalItemName::CursorName => "CURSOR_NAME",
7804 SignalItemName::MessageText => "MESSAGE_TEXT",
7805 SignalItemName::MysqlErrno => "MYSQL_ERRNO",
7806 })
7807 }
7808}
7809
7810impl<X: Extension + Render> Render for GetDiagnosticsStatement<X> {
7811 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7812 f.write_str("GET")?;
7813 match self.area {
7814 DiagnosticsArea::Implicit => {}
7815 DiagnosticsArea::Current => f.write_str(" CURRENT")?,
7816 DiagnosticsArea::Stacked => f.write_str(" STACKED")?,
7817 }
7818 f.write_str(" DIAGNOSTICS ")?;
7819 self.info.render(ctx, f)
7820 }
7821}
7822
7823impl<X: Extension + Render> Render for DiagnosticsInfo<X> {
7824 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7825 match self {
7826 DiagnosticsInfo::Statement { items, .. } => render_comma_separated(items, ctx, f),
7827 DiagnosticsInfo::Condition { number, items, .. } => {
7828 f.write_str("CONDITION ")?;
7829 number.render(ctx, f)?;
7830 f.write_str(" ")?;
7831 render_comma_separated(items, ctx, f)
7832 }
7833 }
7834 }
7835}
7836
7837impl<X: Extension + Render> Render for StatementInfoItem<X> {
7838 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7839 self.target.render(ctx, f)?;
7840 f.write_str(" = ")?;
7841 self.name.render(ctx, f)
7842 }
7843}
7844
7845impl Render for StatementInfoItemName {
7846 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7847 f.write_str(match self {
7848 StatementInfoItemName::Number => "NUMBER",
7849 StatementInfoItemName::RowCount => "ROW_COUNT",
7850 })
7851 }
7852}
7853
7854impl<X: Extension + Render> Render for ConditionInfoItem<X> {
7855 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7856 self.target.render(ctx, f)?;
7857 f.write_str(" = ")?;
7858 self.name.render(ctx, f)
7859 }
7860}
7861
7862impl Render for ConditionInfoItemName {
7863 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7864 f.write_str(match self {
7865 ConditionInfoItemName::ClassOrigin => "CLASS_ORIGIN",
7866 ConditionInfoItemName::SubclassOrigin => "SUBCLASS_ORIGIN",
7867 ConditionInfoItemName::ConstraintCatalog => "CONSTRAINT_CATALOG",
7868 ConditionInfoItemName::ConstraintSchema => "CONSTRAINT_SCHEMA",
7869 ConditionInfoItemName::ConstraintName => "CONSTRAINT_NAME",
7870 ConditionInfoItemName::CatalogName => "CATALOG_NAME",
7871 ConditionInfoItemName::SchemaName => "SCHEMA_NAME",
7872 ConditionInfoItemName::TableName => "TABLE_NAME",
7873 ConditionInfoItemName::ColumnName => "COLUMN_NAME",
7874 ConditionInfoItemName::CursorName => "CURSOR_NAME",
7875 ConditionInfoItemName::MessageText => "MESSAGE_TEXT",
7876 ConditionInfoItemName::MysqlErrno => "MYSQL_ERRNO",
7877 ConditionInfoItemName::ReturnedSqlstate => "RETURNED_SQLSTATE",
7878 })
7879 }
7880}
7881
7882impl<X: Extension + Render> Render for CreateTable<X> {
7883 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7884 f.write_str("CREATE")?;
7885 if self.or_replace {
7886 f.write_str(" OR REPLACE")?;
7887 }
7888 if let Some(temporary) = self.temporary {
7889 f.write_str(" ")?;
7890 temporary.render(ctx, f)?;
7891 }
7892 if self.unlogged {
7895 f.write_str(" UNLOGGED")?;
7896 }
7897 f.write_str(" TABLE")?;
7898 if self.if_not_exists {
7899 f.write_str(" IF NOT EXISTS")?;
7900 }
7901 f.write_str(" ")?;
7902 self.name.render(ctx, f)?;
7903 match &self.body {
7904 CreateTableBody::Definition { .. }
7909 | CreateTableBody::PartitionOf { .. }
7910 | CreateTableBody::OfType { .. }
7911 | CreateTableBody::LikeSource { .. } => {
7915 self.body.render(ctx, f)?;
7916 render_inherits(&self.inherits, ctx, f)?;
7917 render_partition_by(&self.partition_by, ctx, f)?;
7918 render_access_method(&self.access_method, ctx, f)?;
7919 render_create_table_options(&self.options, ctx, f)?;
7920 }
7921 CreateTableBody::AsQuery {
7922 columns,
7923 query,
7924 with_data,
7925 ..
7926 } => {
7927 render_ctas_columns(columns, ctx, f)?;
7928 render_access_method(&self.access_method, ctx, f)?;
7931 render_create_table_options(&self.options, ctx, f)?;
7932 render_ctas_query_tail(query, *with_data, ctx, f)?;
7933 }
7934 CreateTableBody::AsExecute {
7935 columns,
7936 execute,
7937 with_data,
7938 ..
7939 } => {
7940 render_ctas_columns(columns, ctx, f)?;
7941 render_access_method(&self.access_method, ctx, f)?;
7942 render_create_table_options(&self.options, ctx, f)?;
7943 f.write_str(" AS ")?;
7944 execute.render(ctx, f)?;
7945 render_with_data(*with_data, f)?;
7946 }
7947 }
7948 Ok(())
7949 }
7950}
7951
7952fn render_inherits(
7955 inherits: &[ObjectName],
7956 ctx: &RenderCtx<'_>,
7957 f: &mut fmt::Formatter<'_>,
7958) -> fmt::Result {
7959 if !inherits.is_empty() {
7960 f.write_str(" INHERITS (")?;
7961 render_comma_separated(inherits, ctx, f)?;
7962 f.write_str(")")?;
7963 }
7964 Ok(())
7965}
7966
7967fn render_partition_by<X: Extension + Render>(
7970 partition_by: &Option<Box<PartitionSpec<X>>>,
7971 ctx: &RenderCtx<'_>,
7972 f: &mut fmt::Formatter<'_>,
7973) -> fmt::Result {
7974 if let Some(spec) = partition_by {
7975 f.write_str(" PARTITION BY ")?;
7976 spec.render(ctx, f)?;
7977 }
7978 Ok(())
7979}
7980
7981fn render_access_method(
7984 access_method: &Option<Box<Ident>>,
7985 ctx: &RenderCtx<'_>,
7986 f: &mut fmt::Formatter<'_>,
7987) -> fmt::Result {
7988 if let Some(method) = access_method {
7989 f.write_str(" USING ")?;
7990 method.render(ctx, f)?;
7991 }
7992 Ok(())
7993}
7994
7995impl Render for TemporaryTableKind {
7996 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7997 f.write_str(match self {
7998 Self::Temp => "TEMP",
7999 Self::Temporary => "TEMPORARY",
8000 })
8001 }
8002}
8003
8004fn render_create_table_options<X: Extension + Render>(
8010 options: &[CreateTableOption<X>],
8011 ctx: &RenderCtx<'_>,
8012 f: &mut fmt::Formatter<'_>,
8013) -> fmt::Result {
8014 for (index, option) in options.iter().enumerate() {
8015 let sqlite_option = matches!(
8016 option.kind,
8017 CreateTableOptionKind::WithoutRowid { .. } | CreateTableOptionKind::Strict { .. }
8018 );
8019 f.write_str(if index > 0 && sqlite_option {
8020 ", "
8021 } else {
8022 " "
8023 })?;
8024 option.render(ctx, f)?;
8025 }
8026 Ok(())
8027}
8028
8029impl<X: Extension + Render> Render for CreateTableBody<X> {
8030 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8031 match self {
8032 Self::Definition { elements, .. } => {
8033 f.write_str(" (")?;
8034 render_comma_separated(elements, ctx, f)?;
8035 f.write_str(")")
8036 }
8037 Self::AsQuery {
8038 columns,
8039 query,
8040 with_data,
8041 ..
8042 } => {
8043 render_ctas_columns(columns, ctx, f)?;
8044 render_ctas_query_tail(query, *with_data, ctx, f)
8045 }
8046 Self::AsExecute {
8047 columns,
8048 execute,
8049 with_data,
8050 ..
8051 } => {
8052 render_ctas_columns(columns, ctx, f)?;
8053 f.write_str(" AS ")?;
8054 execute.render(ctx, f)?;
8055 render_with_data(*with_data, f)
8056 }
8057 Self::PartitionOf {
8058 parent,
8059 elements,
8060 bound,
8061 ..
8062 } => {
8063 f.write_str(" PARTITION OF ")?;
8064 parent.render(ctx, f)?;
8065 if !elements.is_empty() {
8068 f.write_str(" (")?;
8069 render_comma_separated(elements, ctx, f)?;
8070 f.write_str(")")?;
8071 }
8072 f.write_str(" ")?;
8073 bound.render(ctx, f)
8074 }
8075 Self::OfType {
8076 type_name,
8077 elements,
8078 ..
8079 } => {
8080 f.write_str(" OF ")?;
8081 type_name.render(ctx, f)?;
8082 if !elements.is_empty() {
8085 f.write_str(" (")?;
8086 render_comma_separated(elements, ctx, f)?;
8087 f.write_str(")")?;
8088 }
8089 Ok(())
8090 }
8091 Self::LikeSource {
8092 source,
8093 parenthesized,
8094 ..
8095 } => {
8096 if *parenthesized {
8098 f.write_str(" (LIKE ")?;
8099 source.render(ctx, f)?;
8100 f.write_str(")")
8101 } else {
8102 f.write_str(" LIKE ")?;
8103 source.render(ctx, f)
8104 }
8105 }
8106 }
8107 }
8108}
8109
8110impl<X: Extension + Render> Render for PartitionSpec<X> {
8111 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8112 self.strategy.render(ctx, f)?;
8113 f.write_str(" (")?;
8114 render_comma_separated(&self.columns, ctx, f)?;
8115 f.write_str(")")
8116 }
8117}
8118
8119impl Render for PartitionStrategy {
8120 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8121 f.write_str(match self {
8122 Self::List => "LIST",
8123 Self::Range => "RANGE",
8124 Self::Hash => "HASH",
8125 })
8126 }
8127}
8128
8129impl<X: Extension + Render> Render for PartitionElem<X> {
8130 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8131 if self.parenthesized {
8136 f.write_str("(")?;
8137 self.expr.render(ctx, f)?;
8138 f.write_str(")")?;
8139 } else {
8140 self.expr.render(ctx, f)?;
8141 }
8142 if let Some(collation) = &self.collation {
8143 f.write_str(" COLLATE ")?;
8144 collation.render(ctx, f)?;
8145 }
8146 if let Some(opclass) = &self.opclass {
8147 f.write_str(" ")?;
8148 opclass.render(ctx, f)?;
8149 }
8150 Ok(())
8151 }
8152}
8153
8154impl<X: Extension + Render> Render for PartitionBound<X> {
8155 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8156 match self {
8157 Self::List { values, .. } => {
8158 f.write_str("FOR VALUES IN (")?;
8159 render_comma_separated(values, ctx, f)?;
8160 f.write_str(")")
8161 }
8162 Self::Range { from, to, .. } => {
8163 f.write_str("FOR VALUES FROM (")?;
8164 render_comma_separated(from, ctx, f)?;
8165 f.write_str(") TO (")?;
8166 render_comma_separated(to, ctx, f)?;
8167 f.write_str(")")
8168 }
8169 Self::Hash {
8170 modulus, remainder, ..
8171 } => {
8172 f.write_str("FOR VALUES WITH (MODULUS ")?;
8173 modulus.render(ctx, f)?;
8174 f.write_str(", REMAINDER ")?;
8175 remainder.render(ctx, f)?;
8176 f.write_str(")")
8177 }
8178 Self::Default { .. } => f.write_str("DEFAULT"),
8179 }
8180 }
8181}
8182
8183fn render_ctas_columns(
8184 columns: &[Ident],
8185 ctx: &RenderCtx<'_>,
8186 f: &mut fmt::Formatter<'_>,
8187) -> fmt::Result {
8188 if !columns.is_empty() {
8189 f.write_str(" (")?;
8190 render_ident_list(columns, ctx, f)?;
8191 f.write_str(")")?;
8192 }
8193 Ok(())
8194}
8195
8196fn render_ctas_query_tail<X: Extension + Render>(
8197 query: &Query<X>,
8198 with_data: Option<bool>,
8199 ctx: &RenderCtx<'_>,
8200 f: &mut fmt::Formatter<'_>,
8201) -> fmt::Result {
8202 f.write_str(" AS ")?;
8203 query.render(ctx, f)?;
8204 render_with_data(with_data, f)
8205}
8206
8207fn render_with_data(with_data: Option<bool>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8211 match with_data {
8212 Some(true) => f.write_str(" WITH DATA"),
8213 Some(false) => f.write_str(" WITH NO DATA"),
8214 None => Ok(()),
8215 }
8216}
8217
8218impl<X: Extension + Render> Render for TableElement<X> {
8219 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8220 match self {
8221 Self::Column { column, .. } => column.render(ctx, f),
8222 Self::Constraint { constraint, .. } => constraint.render(ctx, f),
8223 Self::Like {
8224 source, options, ..
8225 } => {
8226 f.write_str("LIKE ")?;
8227 source.render(ctx, f)?;
8228 for option in options {
8229 f.write_str(" ")?;
8230 option.render(ctx, f)?;
8231 }
8232 Ok(())
8233 }
8234 }
8235 }
8236}
8237
8238impl Render for TableLikeOption {
8239 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8240 self.action.render(ctx, f)?;
8241 f.write_str(" ")?;
8242 self.feature.render(ctx, f)
8243 }
8244}
8245
8246impl Render for TableLikeAction {
8247 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8248 f.write_str(match self {
8249 Self::Including => "INCLUDING",
8250 Self::Excluding => "EXCLUDING",
8251 })
8252 }
8253}
8254
8255impl Render for TableLikeFeature {
8256 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8257 f.write_str(match self {
8258 Self::Comments => "COMMENTS",
8259 Self::Compression => "COMPRESSION",
8260 Self::Constraints => "CONSTRAINTS",
8261 Self::Defaults => "DEFAULTS",
8262 Self::Generated => "GENERATED",
8263 Self::Identity => "IDENTITY",
8264 Self::Indexes => "INDEXES",
8265 Self::Statistics => "STATISTICS",
8266 Self::Storage => "STORAGE",
8267 Self::All => "ALL",
8268 })
8269 }
8270}
8271
8272impl<X: Extension + Render> Render for ColumnDef<X> {
8273 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8274 self.name.render(ctx, f)?;
8275 render_column_def_tail(self, ctx, f)
8279 }
8280}
8281
8282impl<X: Extension + Render> Render for ColumnConstraint<X> {
8283 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8284 if let Some(name) = &self.name {
8285 f.write_str("CONSTRAINT ")?;
8286 name.render(ctx, f)?;
8287 if !matches!(self.option, ColumnOption::Bare { .. }) {
8290 f.write_str(" ")?;
8291 }
8292 }
8293 self.option.render(ctx, f)?;
8294 if let Some(conflict) = self.conflict {
8295 f.write_str(" ON CONFLICT ")?;
8296 conflict.render(ctx, f)?;
8297 }
8298 render_constraint_characteristics(&self.characteristics, ctx, f)
8299 }
8300}
8301
8302fn render_constraint_characteristics(
8305 characteristics: &Option<Box<ConstraintCharacteristics>>,
8306 ctx: &RenderCtx<'_>,
8307 f: &mut fmt::Formatter<'_>,
8308) -> fmt::Result {
8309 if let Some(characteristics) = characteristics {
8310 f.write_str(" ")?;
8311 characteristics.render(ctx, f)?;
8312 }
8313 Ok(())
8314}
8315
8316impl Render for ConstraintCharacteristics {
8317 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8318 let mut written = false;
8321 if let Some(deferrable) = self.deferrable {
8322 f.write_str(if deferrable {
8323 "DEFERRABLE"
8324 } else {
8325 "NOT DEFERRABLE"
8326 })?;
8327 written = true;
8328 }
8329 if let Some(initially_deferred) = self.initially_deferred {
8330 if written {
8331 f.write_str(" ")?;
8332 }
8333 f.write_str(if initially_deferred {
8334 "INITIALLY DEFERRED"
8335 } else {
8336 "INITIALLY IMMEDIATE"
8337 })?;
8338 }
8339 Ok(())
8340 }
8341}
8342
8343impl<X: Extension + Render> Render for ColumnOption<X> {
8344 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8345 match self {
8346 Self::Null { .. } => f.write_str("NULL"),
8347 Self::NotNull { .. } => f.write_str("NOT NULL"),
8348 Self::Default { expr, .. } => {
8349 f.write_str("DEFAULT ")?;
8350 expr.render(ctx, f)
8351 }
8352 Self::Generated { generated, .. } => generated.render(ctx, f),
8353 Self::Identity { identity, .. } => identity.render(ctx, f),
8354 Self::PrimaryKey {
8355 ascending,
8356 index_tablespace,
8357 ..
8358 } => {
8359 f.write_str("PRIMARY KEY")?;
8360 match ascending {
8361 Some(true) => f.write_str(" ASC")?,
8362 Some(false) => f.write_str(" DESC")?,
8363 None => {}
8364 }
8365 render_using_index_tablespace(index_tablespace.as_deref(), ctx, f)
8366 }
8367 Self::Unique {
8368 nulls_not_distinct,
8369 index_tablespace,
8370 ..
8371 } => {
8372 f.write_str("UNIQUE")?;
8373 render_nulls_not_distinct(*nulls_not_distinct, f)?;
8374 render_using_index_tablespace(index_tablespace.as_deref(), ctx, f)
8375 }
8376 Self::AutoIncrement { spelling, .. } => spelling.render(ctx, f),
8377 Self::Collate { collation, .. } => {
8378 f.write_str("COLLATE ")?;
8379 collation.render(ctx, f)
8380 }
8381 Self::Check {
8382 expr, no_inherit, ..
8383 } => {
8384 f.write_str("CHECK (")?;
8385 expr.render(ctx, f)?;
8386 f.write_str(")")?;
8387 if *no_inherit {
8388 f.write_str(" NO INHERIT")?;
8389 }
8390 Ok(())
8391 }
8392 Self::References { reference, .. } => reference.render(ctx, f),
8393 Self::Bare { .. } => Ok(()),
8396 Self::Other { ext, .. } => ext.render(ctx, f),
8397 }
8398 }
8399}
8400
8401impl Render for AutoIncrementSpelling {
8402 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8403 f.write_str(match self {
8404 Self::Underscored => "AUTO_INCREMENT",
8405 Self::Joined => "AUTOINCREMENT",
8406 })
8407 }
8408}
8409
8410impl Render for ForeignKeyRef {
8411 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8412 f.write_str("REFERENCES ")?;
8413 self.table.render(ctx, f)?;
8414 if !self.columns.is_empty() {
8415 f.write_str(" (")?;
8416 render_ident_list(&self.columns, ctx, f)?;
8417 f.write_str(")")?;
8418 }
8419 if let Some(match_type) = self.match_type {
8423 f.write_str(" MATCH ")?;
8424 match_type.render(ctx, f)?;
8425 }
8426 let render_on_delete = |f: &mut fmt::Formatter<'_>| -> fmt::Result {
8427 if let Some(on_delete) = &self.on_delete {
8428 f.write_str(" ON DELETE ")?;
8429 on_delete.render(ctx, f)?;
8430 }
8431 Ok(())
8432 };
8433 let render_on_update = |f: &mut fmt::Formatter<'_>| -> fmt::Result {
8434 if let Some(on_update) = &self.on_update {
8435 f.write_str(" ON UPDATE ")?;
8436 on_update.render(ctx, f)?;
8437 }
8438 Ok(())
8439 };
8440 if self.update_before_delete && honours_source_spelling(ctx) {
8441 render_on_update(f)?;
8442 render_on_delete(f)?;
8443 } else {
8444 render_on_delete(f)?;
8445 render_on_update(f)?;
8446 }
8447 Ok(())
8448 }
8449}
8450
8451impl Render for ForeignKeyMatch {
8452 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8453 f.write_str(match self {
8454 Self::Full => "FULL",
8455 Self::Partial => "PARTIAL",
8456 Self::Simple => "SIMPLE",
8457 })
8458 }
8459}
8460
8461impl Render for ReferentialAction {
8462 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8463 match self {
8464 Self::NoAction { .. } => f.write_str("NO ACTION"),
8465 Self::Restrict { .. } => f.write_str("RESTRICT"),
8466 Self::Cascade { .. } => f.write_str("CASCADE"),
8467 Self::SetNull { columns, .. } => render_set_action(ctx, f, "SET NULL", columns),
8468 Self::SetDefault { columns, .. } => render_set_action(ctx, f, "SET DEFAULT", columns),
8469 }
8470 }
8471}
8472
8473fn render_set_action(
8475 ctx: &RenderCtx<'_>,
8476 f: &mut fmt::Formatter<'_>,
8477 keyword: &str,
8478 columns: &[Ident],
8479) -> fmt::Result {
8480 f.write_str(keyword)?;
8481 if !columns.is_empty() {
8482 f.write_str(" (")?;
8483 render_ident_list(columns, ctx, f)?;
8484 f.write_str(")")?;
8485 }
8486 Ok(())
8487}
8488
8489impl<X: Extension + Render> Render for GeneratedColumn<X> {
8490 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8491 f.write_str(match self.spelling {
8494 GeneratedColumnSpelling::GeneratedAlways => "GENERATED ALWAYS AS (",
8495 GeneratedColumnSpelling::Shorthand => "AS (",
8496 })?;
8497 self.expr.render(ctx, f)?;
8498 f.write_str(")")?;
8499 if let Some(storage) = self.storage {
8500 f.write_str(" ")?;
8501 storage.render(ctx, f)?;
8502 }
8503 Ok(())
8504 }
8505}
8506
8507impl Render for GeneratedColumnStorage {
8508 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8509 f.write_str(match self {
8510 Self::Stored => "STORED",
8511 Self::Virtual => "VIRTUAL",
8512 })
8513 }
8514}
8515
8516impl<X: Extension + Render> Render for IdentityColumn<X> {
8517 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8518 f.write_str("GENERATED ")?;
8519 self.generation.render(ctx, f)?;
8520 f.write_str(" AS IDENTITY")?;
8521 if !self.options.is_empty() {
8522 f.write_str(" (")?;
8523 for (index, option) in self.options.iter().enumerate() {
8524 if index > 0 {
8525 f.write_str(" ")?;
8526 }
8527 option.render(ctx, f)?;
8528 }
8529 f.write_str(")")?;
8530 }
8531 Ok(())
8532 }
8533}
8534
8535impl Render for IdentityGeneration {
8536 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8537 f.write_str(match self {
8538 Self::Always => "ALWAYS",
8539 Self::ByDefault => "BY DEFAULT",
8540 })
8541 }
8542}
8543
8544impl<X: Extension + Render> Render for IdentityOption<X> {
8545 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8546 match self {
8547 Self::StartWith { expr, .. } => {
8548 f.write_str("START WITH ")?;
8549 expr.render(ctx, f)
8550 }
8551 Self::IncrementBy { expr, .. } => {
8552 f.write_str("INCREMENT BY ")?;
8553 expr.render(ctx, f)
8554 }
8555 Self::MinValue {
8556 value: Some(expr), ..
8557 } => {
8558 f.write_str("MINVALUE ")?;
8559 expr.render(ctx, f)
8560 }
8561 Self::MinValue { value: None, .. } => f.write_str("NO MINVALUE"),
8562 Self::MaxValue {
8563 value: Some(expr), ..
8564 } => {
8565 f.write_str("MAXVALUE ")?;
8566 expr.render(ctx, f)
8567 }
8568 Self::MaxValue { value: None, .. } => f.write_str("NO MAXVALUE"),
8569 Self::Cache { expr, .. } => {
8570 f.write_str("CACHE ")?;
8571 expr.render(ctx, f)
8572 }
8573 Self::Cycle { cycle: true, .. } => f.write_str("CYCLE"),
8574 Self::Cycle { cycle: false, .. } => f.write_str("NO CYCLE"),
8575 }
8576 }
8577}
8578
8579impl<X: Extension + Render> Render for TableConstraintDef<X> {
8580 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8581 if let Some(name) = &self.name {
8582 f.write_str("CONSTRAINT ")?;
8583 name.render(ctx, f)?;
8584 if !matches!(self.constraint, TableConstraint::Bare { .. }) {
8587 f.write_str(" ")?;
8588 }
8589 }
8590 self.constraint.render(ctx, f)?;
8591 if self.no_inherit {
8595 f.write_str(" NO INHERIT")?;
8596 }
8597 if self.not_valid {
8598 f.write_str(" NOT VALID")?;
8599 }
8600 render_constraint_characteristics(&self.characteristics, ctx, f)
8601 }
8602}
8603
8604impl<X: Extension + Render> Render for TableConstraint<X> {
8605 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8606 match self {
8607 Self::PrimaryKey {
8608 columns, include, ..
8609 } => {
8610 f.write_str("PRIMARY KEY (")?;
8611 render_comma_separated(columns, ctx, f)?;
8612 f.write_str(")")?;
8613 render_include_columns(include, ctx, f)
8614 }
8615 Self::Unique {
8616 columns,
8617 nulls_not_distinct,
8618 include,
8619 ..
8620 } => {
8621 f.write_str("UNIQUE")?;
8622 render_nulls_not_distinct(*nulls_not_distinct, f)?;
8623 f.write_str(" (")?;
8624 render_comma_separated(columns, ctx, f)?;
8625 f.write_str(")")?;
8626 render_include_columns(include, ctx, f)
8627 }
8628 Self::Check { expr, .. } => {
8629 f.write_str("CHECK (")?;
8630 expr.render(ctx, f)?;
8631 f.write_str(")")
8632 }
8633 Self::Exclude { exclude, .. } => exclude.render(ctx, f),
8634 Self::ForeignKey {
8635 columns,
8636 references,
8637 ..
8638 } => {
8639 f.write_str("FOREIGN KEY (")?;
8640 render_ident_list(columns, ctx, f)?;
8641 f.write_str(") ")?;
8642 references.render(ctx, f)
8643 }
8644 Self::Bare { .. } => Ok(()),
8647 Self::Other { ext, .. } => ext.render(ctx, f),
8648 }
8649 }
8650}
8651
8652fn render_include_columns(
8655 include: &[Ident],
8656 ctx: &RenderCtx<'_>,
8657 f: &mut fmt::Formatter<'_>,
8658) -> fmt::Result {
8659 if !include.is_empty() {
8660 f.write_str(" INCLUDE (")?;
8661 render_ident_list(include, ctx, f)?;
8662 f.write_str(")")?;
8663 }
8664 Ok(())
8665}
8666
8667fn render_nulls_not_distinct(
8670 nulls_not_distinct: Option<bool>,
8671 f: &mut fmt::Formatter<'_>,
8672) -> fmt::Result {
8673 match nulls_not_distinct {
8674 Some(false) => f.write_str(" NULLS NOT DISTINCT"),
8675 Some(true) => f.write_str(" NULLS DISTINCT"),
8676 None => Ok(()),
8677 }
8678}
8679
8680fn render_using_index_tablespace(
8683 tablespace: Option<&Ident>,
8684 ctx: &RenderCtx<'_>,
8685 f: &mut fmt::Formatter<'_>,
8686) -> fmt::Result {
8687 if let Some(tablespace) = tablespace {
8688 f.write_str(" USING INDEX TABLESPACE ")?;
8689 tablespace.render(ctx, f)?;
8690 }
8691 Ok(())
8692}
8693
8694impl<X: Extension + Render> Render for ExcludeConstraint<X> {
8695 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8696 f.write_str("EXCLUDE")?;
8697 if let Some(method) = &self.method {
8698 f.write_str(" USING ")?;
8699 method.render(ctx, f)?;
8700 }
8701 f.write_str(" (")?;
8702 render_comma_separated(&self.elements, ctx, f)?;
8703 f.write_str(")")?;
8704 render_include_columns(&self.include, ctx, f)?;
8705 if !self.with_params.is_empty() {
8706 f.write_str(" WITH (")?;
8707 render_comma_separated(&self.with_params, ctx, f)?;
8708 f.write_str(")")?;
8709 }
8710 render_using_index_tablespace(self.index_tablespace.as_ref(), ctx, f)?;
8711 if let Some(predicate) = &self.predicate {
8712 f.write_str(" WHERE (")?;
8713 predicate.render(ctx, f)?;
8714 f.write_str(")")?;
8715 }
8716 Ok(())
8717 }
8718}
8719
8720impl<X: Extension + Render> Render for ExcludeElement<X> {
8721 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8722 if self.parenthesized {
8725 f.write_str("(")?;
8726 self.expr.render(ctx, f)?;
8727 f.write_str(")")?;
8728 } else {
8729 self.expr.render(ctx, f)?;
8730 }
8731 if let Some(collation) = &self.collation {
8732 f.write_str(" COLLATE ")?;
8733 collation.render(ctx, f)?;
8734 }
8735 if let Some(opclass) = &self.opclass {
8736 f.write_str(" ")?;
8737 opclass.render(ctx, f)?;
8738 if !self.opclass_params.is_empty() {
8739 f.write_str(" (")?;
8740 render_comma_separated(&self.opclass_params, ctx, f)?;
8741 f.write_str(")")?;
8742 }
8743 }
8744 match self.asc {
8745 Some(true) => f.write_str(" ASC")?,
8746 Some(false) => f.write_str(" DESC")?,
8747 None => {}
8748 }
8749 match self.nulls_first {
8750 Some(true) => f.write_str(" NULLS FIRST")?,
8751 Some(false) => f.write_str(" NULLS LAST")?,
8752 None => {}
8753 }
8754 f.write_str(" WITH ")?;
8755 self.operator.render(ctx, f)
8756 }
8757}
8758
8759impl Render for ExcludeOperator {
8760 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8761 match self.spelling {
8762 NamedOperatorSpelling::Bare => f.write_str(ctx.resolve(self.op)),
8764 NamedOperatorSpelling::OperatorKeyword => {
8767 f.write_str("OPERATOR(")?;
8768 for part in &self.schema.0 {
8769 part.render(ctx, f)?;
8770 f.write_str(".")?;
8771 }
8772 f.write_str(ctx.resolve(self.op))?;
8773 f.write_str(")")
8774 }
8775 }
8776 }
8777}
8778
8779impl<X: Extension + Render> Render for CreateTableOption<X> {
8780 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8781 self.kind.render(ctx, f)
8782 }
8783}
8784
8785impl<X: Extension + Render> Render for CreateTableOptionKind<X> {
8786 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8787 match self {
8788 Self::ColocateWith { table, columns, .. } => {
8789 f.write_str("COLOCATE WITH ")?;
8790 table.render(ctx, f)?;
8791 f.write_str(" ON (")?;
8792 render_ident_list(columns, ctx, f)?;
8793 f.write_str(")")
8794 }
8795 Self::InColocationGroup { group, columns, .. } => {
8796 f.write_str("IN COLOCATION GROUP ")?;
8797 group.render(ctx, f)?;
8798 if !columns.is_empty() {
8799 f.write_str(" ON (")?;
8800 render_ident_list(columns, ctx, f)?;
8801 f.write_str(")")?;
8802 }
8803 Ok(())
8804 }
8805 Self::With { params, .. } => {
8806 f.write_str("WITH (")?;
8807 render_comma_separated(params, ctx, f)?;
8808 f.write_str(")")
8809 }
8810 Self::OnCommit { action, .. } => {
8811 f.write_str("ON COMMIT ")?;
8812 action.render(ctx, f)
8813 }
8814 Self::Tablespace { tablespace, .. } => {
8815 f.write_str("TABLESPACE ")?;
8816 tablespace.render(ctx, f)
8817 }
8818 Self::KeyValue { option, .. } => option.render(ctx, f),
8819 Self::WithoutRowid { .. } => f.write_str("WITHOUT ROWID"),
8820 Self::Strict { .. } => f.write_str("STRICT"),
8821 Self::WithoutOids { .. } => f.write_str("WITHOUT OIDS"),
8822 }
8823 }
8824}
8825
8826impl Render for TableOption {
8827 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8828 self.name.render(ctx, f)?;
8832 f.write_str(" = ")?;
8833 self.value.render(ctx, f)
8834 }
8835}
8836
8837impl Render for TableOptionValue {
8838 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8839 match self {
8840 Self::Word { word, .. } => word.render(ctx, f),
8841 Self::String { value, .. } | Self::Number { value, .. } => value.render(ctx, f),
8842 }
8843 }
8844}
8845
8846impl Render for OnCommitAction {
8847 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8848 f.write_str(match self {
8849 Self::PreserveRows => "PRESERVE ROWS",
8850 Self::DeleteRows => "DELETE ROWS",
8851 Self::Drop => "DROP",
8852 })
8853 }
8854}
8855
8856impl<X: Extension + Render> Render for TableStorageParameter<X> {
8857 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8858 self.name.render(ctx, f)?;
8859 if let Some(value) = &self.value {
8860 f.write_str(" = ")?;
8861 value.render(ctx, f)?;
8862 }
8863 Ok(())
8864 }
8865}
8866
8867impl<X: Extension + Render> Render for AlterTable<X> {
8868 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8869 f.write_str("ALTER TABLE")?;
8870 if self.if_exists {
8871 f.write_str(" IF EXISTS")?;
8872 }
8873 f.write_str(" ")?;
8874 self.name.render(ctx, f)?;
8875 f.write_str(" ")?;
8876 render_comma_separated(&self.actions, ctx, f)
8877 }
8878}
8879
8880impl Render for AlterColumnTarget {
8881 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8882 for (i, part) in self.parts.iter().enumerate() {
8883 if i > 0 {
8884 f.write_str(".")?;
8885 }
8886 part.render(ctx, f)?;
8887 }
8888 Ok(())
8889 }
8890}
8891
8892fn render_optional_column_keyword(
8896 column_keyword: bool,
8897 ctx: &RenderCtx<'_>,
8898 f: &mut fmt::Formatter<'_>,
8899) -> fmt::Result {
8900 if column_keyword || !honours_source_spelling(ctx) {
8901 f.write_str(" COLUMN")?;
8902 }
8903 Ok(())
8904}
8905
8906fn render_column_def_tail<X: Extension + Render>(
8907 column: &ColumnDef<X>,
8908 ctx: &RenderCtx<'_>,
8909 f: &mut fmt::Formatter<'_>,
8910) -> fmt::Result {
8911 if let Some(data_type) = &column.data_type {
8912 f.write_str(" ")?;
8913 data_type.render(ctx, f)?;
8914 }
8915 if let Some(storage) = &column.storage {
8916 f.write_str(" STORAGE ")?;
8917 storage.render(ctx, f)?;
8918 }
8919 if let Some(compression) = &column.compression {
8920 f.write_str(" COMPRESSION ")?;
8921 compression.render(ctx, f)?;
8922 }
8923 for constraint in &column.constraints {
8924 f.write_str(" ")?;
8925 constraint.render(ctx, f)?;
8926 }
8927 Ok(())
8928}
8929
8930impl<X: Extension + Render> Render for AlterTableAction<X> {
8931 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8932 match self {
8933 Self::SetColocationGroup { group, .. } => {
8934 f.write_str("SET COLOCATION GROUP ")?;
8935 group.render(ctx, f)
8936 }
8937 Self::DropColocationGroup { .. } => f.write_str("DROP COLOCATION GROUP"),
8938 Self::AddColumn {
8941 if_not_exists,
8942 column_keyword,
8943 target,
8944 column,
8945 ..
8946 } => {
8947 f.write_str("ADD")?;
8948 render_optional_column_keyword(*column_keyword, ctx, f)?;
8949 if *if_not_exists {
8950 f.write_str(" IF NOT EXISTS")?;
8951 }
8952 f.write_str(" ")?;
8953 if let Some(target) = target {
8954 target.render(ctx, f)?;
8955 render_column_def_tail(column, ctx, f)
8956 } else {
8957 column.render(ctx, f)
8958 }
8959 }
8960 Self::DropColumn {
8961 if_exists,
8962 column_keyword,
8963 name,
8964 behavior,
8965 ..
8966 } => {
8967 f.write_str("DROP")?;
8968 render_optional_column_keyword(*column_keyword, ctx, f)?;
8969 if *if_exists {
8970 f.write_str(" IF EXISTS")?;
8971 }
8972 f.write_str(" ")?;
8973 name.render(ctx, f)?;
8974 render_drop_behavior(*behavior, ctx, f)
8975 }
8976 Self::AlterColumn {
8977 column_keyword,
8978 name,
8979 change,
8980 ..
8981 } => {
8982 f.write_str("ALTER")?;
8983 render_optional_column_keyword(*column_keyword, ctx, f)?;
8984 f.write_str(" ")?;
8985 name.render(ctx, f)?;
8986 f.write_str(" ")?;
8987 change.render(ctx, f)
8988 }
8989 Self::AddConstraint { constraint, .. } => {
8990 f.write_str("ADD ")?;
8991 constraint.render(ctx, f)
8992 }
8993 Self::DropConstraint {
8994 if_exists,
8995 name,
8996 behavior,
8997 ..
8998 } => {
8999 f.write_str("DROP CONSTRAINT")?;
9000 if *if_exists {
9001 f.write_str(" IF EXISTS")?;
9002 }
9003 f.write_str(" ")?;
9004 name.render(ctx, f)?;
9005 render_drop_behavior(*behavior, ctx, f)
9006 }
9007 Self::DropPrimaryKey { behavior, .. } => {
9008 f.write_str("DROP PRIMARY KEY")?;
9009 render_drop_behavior(*behavior, ctx, f)
9010 }
9011 Self::SetOptions { params, .. } => {
9012 f.write_str("SET (")?;
9013 render_comma_separated(params, ctx, f)?;
9014 f.write_str(")")
9015 }
9016 Self::RenameColumn {
9017 column_keyword,
9018 name,
9019 new_name,
9020 ..
9021 } => {
9022 f.write_str("RENAME")?;
9023 render_optional_column_keyword(*column_keyword, ctx, f)?;
9024 f.write_str(" ")?;
9025 name.render(ctx, f)?;
9026 f.write_str(" TO ")?;
9027 new_name.render(ctx, f)
9028 }
9029 Self::RenameConstraint { name, new_name, .. } => {
9030 f.write_str("RENAME CONSTRAINT ")?;
9031 name.render(ctx, f)?;
9032 f.write_str(" TO ")?;
9033 new_name.render(ctx, f)
9034 }
9035 Self::RenameTable { new_name, .. } => {
9036 f.write_str("RENAME TO ")?;
9037 new_name.render(ctx, f)
9038 }
9039 Self::AttachPartition {
9040 partition, bound, ..
9041 } => {
9042 f.write_str("ATTACH PARTITION ")?;
9043 partition.render(ctx, f)?;
9044 f.write_str(" ")?;
9045 bound.render(ctx, f)
9046 }
9047 Self::DetachPartition {
9048 partition, mode, ..
9049 } => {
9050 f.write_str("DETACH PARTITION ")?;
9051 partition.render(ctx, f)?;
9052 match mode {
9053 Some(DetachPartitionMode::Concurrently) => f.write_str(" CONCURRENTLY"),
9054 Some(DetachPartitionMode::Finalize) => f.write_str(" FINALIZE"),
9055 None => Ok(()),
9056 }
9057 }
9058 }
9059 }
9060}
9061
9062impl<X: Extension + Render> Render for AlterColumnAction<X> {
9063 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9064 match self {
9065 Self::SetDefault { expr, .. } => {
9066 f.write_str("SET DEFAULT ")?;
9067 expr.render(ctx, f)
9068 }
9069 Self::DropDefault { .. } => f.write_str("DROP DEFAULT"),
9070 Self::SetNotNull { .. } => f.write_str("SET NOT NULL"),
9071 Self::DropNotNull { .. } => f.write_str("DROP NOT NULL"),
9072 Self::AddIdentity { identity, .. } => {
9073 f.write_str("ADD ")?;
9074 identity.render(ctx, f)
9075 }
9076 Self::SetDataType {
9079 set_data,
9080 data_type,
9081 using,
9082 ..
9083 } => {
9084 if *set_data || !honours_source_spelling(ctx) {
9085 f.write_str("SET DATA TYPE ")?;
9086 } else {
9087 f.write_str("TYPE ")?;
9088 }
9089 data_type.render(ctx, f)?;
9090 if let Some(using) = using {
9091 f.write_str(" USING ")?;
9092 using.render(ctx, f)?;
9093 }
9094 Ok(())
9095 }
9096 }
9097 }
9098}
9099
9100impl Render for DropStatement {
9101 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9102 f.write_str("DROP ")?;
9103 self.object_kind.render(ctx, f)?;
9104 if self.if_exists {
9105 f.write_str(" IF EXISTS")?;
9106 }
9107 f.write_str(" ")?;
9108 render_comma_separated(&self.names, ctx, f)?;
9109 render_drop_behavior(self.behavior, ctx, f)
9110 }
9111}
9112
9113impl Render for DropObjectKind {
9114 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9115 f.write_str(match self {
9116 Self::Table => "TABLE",
9117 Self::View => "VIEW",
9118 Self::MaterializedView => "MATERIALIZED VIEW",
9119 Self::Index => "INDEX",
9120 Self::Schema => "SCHEMA",
9121 Self::Type => "TYPE",
9122 Self::Sequence => "SEQUENCE",
9123 Self::Macro => "MACRO",
9124 Self::MacroTable => "MACRO TABLE",
9125 Self::Trigger => "TRIGGER",
9126 })
9127 }
9128}
9129
9130impl Render for DropBehavior {
9131 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9132 f.write_str(match self {
9133 Self::Cascade => "CASCADE",
9134 Self::Restrict => "RESTRICT",
9135 })
9136 }
9137}
9138
9139fn render_drop_behavior(
9142 behavior: Option<DropBehavior>,
9143 ctx: &RenderCtx<'_>,
9144 f: &mut fmt::Formatter<'_>,
9145) -> fmt::Result {
9146 if let Some(behavior) = behavior {
9147 f.write_str(" ")?;
9148 behavior.render(ctx, f)?;
9149 }
9150 Ok(())
9151}
9152
9153impl<X: Extension + Render> Render for CreateSchema<X> {
9154 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9155 f.write_str("CREATE SCHEMA")?;
9156 if self.if_not_exists {
9157 f.write_str(" IF NOT EXISTS")?;
9158 }
9159 if let Some(name) = &self.name {
9160 f.write_str(" ")?;
9161 name.render(ctx, f)?;
9162 }
9163 if let Some(authorization) = &self.authorization {
9164 f.write_str(" AUTHORIZATION ")?;
9165 authorization.render(ctx, f)?;
9166 }
9167 for element in &self.elements {
9172 f.write_str(" ")?;
9173 element.render(ctx, f)?;
9174 }
9175 Ok(())
9176 }
9177}
9178
9179impl<X: Extension + Render> Render for CreateView<X> {
9180 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9181 f.write_str("CREATE")?;
9182 if self.or_replace {
9183 f.write_str(" OR REPLACE")?;
9184 }
9185 if let Some(temporary) = self.temporary {
9186 f.write_str(" ")?;
9187 temporary.render(ctx, f)?;
9188 }
9189 if self.materialized {
9190 f.write_str(" MATERIALIZED")?;
9191 }
9192 if self.recursive {
9195 f.write_str(" RECURSIVE")?;
9196 }
9197 self.options.render(ctx, f)?;
9200 f.write_str(" VIEW")?;
9201 if self.if_not_exists {
9202 f.write_str(" IF NOT EXISTS")?;
9203 }
9204 f.write_str(" ")?;
9205 self.name.render(ctx, f)?;
9206 if !self.columns.is_empty() {
9207 f.write_str(" (")?;
9208 render_ident_list(&self.columns, ctx, f)?;
9209 f.write_str(")")?;
9210 }
9211 if let Some(to) = &self.to {
9212 f.write_str(" TO ")?;
9213 to.render(ctx, f)?;
9214 }
9215 f.write_str(" AS ")?;
9216 self.query.render(ctx, f)?;
9217 if let Some(check_option) = self.check_option {
9218 f.write_str(" ")?;
9219 check_option.render(ctx, f)?;
9220 }
9221 render_with_data(self.with_data, f)
9222 }
9223}
9224
9225impl<X: Extension + Render> Render for AlterView<X> {
9226 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9227 f.write_str("ALTER")?;
9228 self.options.render(ctx, f)?;
9231 f.write_str(" VIEW ")?;
9232 self.name.render(ctx, f)?;
9233 if !self.columns.is_empty() {
9234 f.write_str(" (")?;
9235 render_ident_list(&self.columns, ctx, f)?;
9236 f.write_str(")")?;
9237 }
9238 f.write_str(" AS ")?;
9239 self.query.render(ctx, f)?;
9240 if let Some(check_option) = self.check_option {
9241 f.write_str(" ")?;
9242 check_option.render(ctx, f)?;
9243 }
9244 Ok(())
9245 }
9246}
9247
9248impl Render for ViewOptions {
9249 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9252 if let Some(algorithm) = self.algorithm {
9253 f.write_str(" ALGORITHM = ")?;
9254 algorithm.render(ctx, f)?;
9255 }
9256 if let Some(definer) = &self.definer {
9257 f.write_str(" ")?;
9258 definer.render(ctx, f)?;
9259 }
9260 if let Some(sql_security) = self.sql_security {
9261 f.write_str(" SQL SECURITY ")?;
9262 sql_security.render(ctx, f)?;
9263 }
9264 Ok(())
9265 }
9266}
9267
9268impl Render for ViewAlgorithm {
9269 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9270 f.write_str(match self {
9271 Self::Undefined => "UNDEFINED",
9272 Self::Merge => "MERGE",
9273 Self::TempTable => "TEMPTABLE",
9274 })
9275 }
9276}
9277
9278impl<X: Extension + Render> Render for CreateSecret<X> {
9279 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9280 f.write_str("CREATE ")?;
9281 if self.persistent {
9282 f.write_str("PERSISTENT ")?;
9283 }
9284 f.write_str("SECRET ")?;
9285 self.name.render(ctx, f)?;
9286 f.write_str(" (")?;
9287 render_comma_separated(&self.options, ctx, f)?;
9288 f.write_str(")")
9289 }
9290}
9291
9292impl<X: Extension + Render> Render for SecretOption<X> {
9293 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9294 self.name.render(ctx, f)?;
9295 f.write_str(" ")?;
9296 self.value.render(ctx, f)
9297 }
9298}
9299
9300impl Render for DropSecretStmt {
9301 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9302 f.write_str("DROP ")?;
9303 match self.persistence {
9304 SecretPersistence::Default => {}
9305 SecretPersistence::Temporary => f.write_str("TEMPORARY ")?,
9306 SecretPersistence::Persistent => f.write_str("PERSISTENT ")?,
9307 }
9308 f.write_str("SECRET ")?;
9309 if self.if_exists {
9310 f.write_str("IF EXISTS ")?;
9311 }
9312 self.name.render(ctx, f)?;
9313 if let Some(storage) = &self.storage {
9314 f.write_str(" FROM ")?;
9315 storage.render(ctx, f)?;
9316 }
9317 Ok(())
9318 }
9319}
9320
9321impl<X: Extension + Render> Render for CreateType<X> {
9322 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9323 f.write_str("CREATE")?;
9324 if self.or_replace {
9325 f.write_str(" OR REPLACE")?;
9326 }
9327 if let Some(temporary) = self.temporary {
9328 f.write_str(" ")?;
9329 temporary.render(ctx, f)?;
9330 }
9331 f.write_str(" TYPE")?;
9332 if self.if_not_exists {
9333 f.write_str(" IF NOT EXISTS")?;
9334 }
9335 f.write_str(" ")?;
9336 self.name.render(ctx, f)?;
9337 f.write_str(" AS ")?;
9338 self.definition.render(ctx, f)
9339 }
9340}
9341
9342impl Render for CreateVirtualTable {
9343 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9344 f.write_str("CREATE VIRTUAL TABLE ")?;
9345 if self.if_not_exists {
9346 f.write_str("IF NOT EXISTS ")?;
9347 }
9348 self.name.render(ctx, f)?;
9349 f.write_str(" USING ")?;
9350 self.module.render(ctx, f)?;
9351 if let Some(args) = &self.args {
9352 f.write_str("(")?;
9353 render_comma_separated(args, ctx, f)?;
9354 f.write_str(")")?;
9355 }
9356 Ok(())
9357 }
9358}
9359
9360impl Render for ModuleArg {
9361 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9362 if ctx.mode() == RenderMode::Redacted {
9367 return f.write_str("?");
9368 }
9369 f.write_str(ctx.resolve(self.text))
9372 }
9373}
9374
9375impl<X: Extension + Render> Render for CreateSequence<X> {
9376 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9377 f.write_str("CREATE")?;
9378 if let Some(temporary) = self.temporary {
9379 f.write_str(" ")?;
9380 temporary.render(ctx, f)?;
9381 }
9382 f.write_str(" SEQUENCE")?;
9383 if self.if_not_exists {
9384 f.write_str(" IF NOT EXISTS")?;
9385 }
9386 f.write_str(" ")?;
9387 self.name.render(ctx, f)?;
9388 for option in &self.options {
9391 f.write_str(" ")?;
9392 option.render(ctx, f)?;
9393 }
9394 Ok(())
9395 }
9396}
9397
9398impl Render for CreateExtension {
9399 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9400 f.write_str("CREATE EXTENSION")?;
9401 if self.if_not_exists {
9402 f.write_str(" IF NOT EXISTS")?;
9403 }
9404 f.write_str(" ")?;
9405 self.name.render(ctx, f)?;
9406 if self.with {
9408 f.write_str(" WITH")?;
9409 }
9410 for option in &self.options {
9411 f.write_str(" ")?;
9412 option.render(ctx, f)?;
9413 }
9414 Ok(())
9415 }
9416}
9417
9418impl Render for CreateExtensionOption {
9419 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9420 match self {
9421 Self::Schema { name, .. } => {
9422 f.write_str("SCHEMA ")?;
9423 name.render(ctx, f)
9424 }
9425 Self::Version { version, .. } => {
9426 f.write_str("VERSION ")?;
9427 version.render(ctx, f)
9428 }
9429 Self::Cascade { .. } => f.write_str("CASCADE"),
9430 }
9431 }
9432}
9433
9434impl Render for ExtensionVersion {
9435 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9436 match self {
9437 Self::Word { word, .. } => word.render(ctx, f),
9438 Self::String { value, .. } => value.render(ctx, f),
9439 }
9440 }
9441}
9442
9443impl<X: Extension + Render> Render for AlterExtension<X> {
9444 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9445 f.write_str("ALTER EXTENSION ")?;
9446 self.name.render(ctx, f)?;
9447 f.write_str(" ")?;
9448 self.action.render(ctx, f)
9449 }
9450}
9451
9452impl<X: Extension + Render> Render for AlterExtensionAction<X> {
9453 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9454 match self {
9455 Self::Update { version, .. } => {
9456 f.write_str("UPDATE")?;
9457 if let Some(version) = version {
9458 f.write_str(" TO ")?;
9459 version.render(ctx, f)?;
9460 }
9461 Ok(())
9462 }
9463 Self::Change { add, member, .. } => {
9464 f.write_str(if *add { "ADD " } else { "DROP " })?;
9465 member.render(ctx, f)
9466 }
9467 }
9468 }
9469}
9470
9471impl Render for SizeLiteral {
9472 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9473 if let Some(text) = ctx.slice(self.meta.span) {
9476 return f.write_str(text);
9477 }
9478 f.write_str("0")?;
9481 match self.unit {
9482 Some(SizeUnit::Kilo) => f.write_str("K"),
9483 Some(SizeUnit::Mega) => f.write_str("M"),
9484 Some(SizeUnit::Giga) => f.write_str("G"),
9485 None => Ok(()),
9486 }
9487 }
9488}
9489
9490impl Render for TablespaceOption {
9491 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9492 match self {
9493 Self::Size {
9494 kind, equals, size, ..
9495 } => {
9496 f.write_str(match kind {
9497 TablespaceSizeOption::InitialSize => "INITIAL_SIZE",
9498 TablespaceSizeOption::AutoextendSize => "AUTOEXTEND_SIZE",
9499 TablespaceSizeOption::MaxSize => "MAX_SIZE",
9500 TablespaceSizeOption::ExtentSize => "EXTENT_SIZE",
9501 TablespaceSizeOption::UndoBufferSize => "UNDO_BUFFER_SIZE",
9502 TablespaceSizeOption::RedoBufferSize => "REDO_BUFFER_SIZE",
9503 TablespaceSizeOption::FileBlockSize => "FILE_BLOCK_SIZE",
9504 })?;
9505 f.write_str(if *equals { " = " } else { " " })?;
9506 size.render(ctx, f)
9507 }
9508 Self::Nodegroup { equals, value, .. } => {
9509 f.write_str("NODEGROUP")?;
9510 f.write_str(if *equals { " = " } else { " " })?;
9511 value.render(ctx, f)
9512 }
9513 Self::Engine {
9514 storage,
9515 equals,
9516 name,
9517 ..
9518 } => {
9519 f.write_str(if *storage { "STORAGE ENGINE" } else { "ENGINE" })?;
9520 f.write_str(if *equals { " = " } else { " " })?;
9521 name.render(ctx, f)
9522 }
9523 Self::Wait { negated, .. } => f.write_str(if *negated { "NO_WAIT" } else { "WAIT" }),
9524 Self::Comment { equals, value, .. } => {
9525 f.write_str("COMMENT")?;
9526 f.write_str(if *equals { " = " } else { " " })?;
9527 value.render(ctx, f)
9528 }
9529 Self::Encryption { equals, value, .. } => {
9530 f.write_str("ENCRYPTION")?;
9531 f.write_str(if *equals { " = " } else { " " })?;
9532 value.render(ctx, f)
9533 }
9534 Self::EngineAttribute { equals, value, .. } => {
9535 f.write_str("ENGINE_ATTRIBUTE")?;
9536 f.write_str(if *equals { " = " } else { " " })?;
9537 value.render(ctx, f)
9538 }
9539 }
9540 }
9541}
9542
9543fn render_tablespace_options(
9547 options: &[TablespaceOption],
9548 ctx: &RenderCtx<'_>,
9549 f: &mut fmt::Formatter<'_>,
9550) -> fmt::Result {
9551 for option in options {
9552 f.write_str(" ")?;
9553 option.render(ctx, f)?;
9554 }
9555 Ok(())
9556}
9557
9558impl Render for CreateTablespace {
9559 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9560 f.write_str(if self.undo {
9561 "CREATE UNDO TABLESPACE "
9562 } else {
9563 "CREATE TABLESPACE "
9564 })?;
9565 self.name.render(ctx, f)?;
9566 if let Some(datafile) = &self.datafile {
9567 f.write_str(" ADD DATAFILE ")?;
9568 datafile.render(ctx, f)?;
9569 }
9570 if let Some(lg) = &self.use_logfile_group {
9571 f.write_str(" USE LOGFILE GROUP ")?;
9572 lg.render(ctx, f)?;
9573 }
9574 render_tablespace_options(&self.options, ctx, f)
9575 }
9576}
9577
9578impl Render for AlterTablespace {
9579 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9580 f.write_str(
9582 if matches!(self.action, AlterTablespaceAction::SetState { .. }) {
9583 "ALTER UNDO TABLESPACE "
9584 } else {
9585 "ALTER TABLESPACE "
9586 },
9587 )?;
9588 self.name.render(ctx, f)?;
9589 f.write_str(" ")?;
9590 self.action.render(ctx, f)
9591 }
9592}
9593
9594impl Render for AlterTablespaceAction {
9595 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9596 match self {
9597 Self::AddDatafile {
9598 datafile, options, ..
9599 } => {
9600 f.write_str("ADD DATAFILE ")?;
9601 datafile.render(ctx, f)?;
9602 render_tablespace_options(options, ctx, f)
9603 }
9604 Self::DropDatafile {
9605 datafile, options, ..
9606 } => {
9607 f.write_str("DROP DATAFILE ")?;
9608 datafile.render(ctx, f)?;
9609 render_tablespace_options(options, ctx, f)
9610 }
9611 Self::Rename { new_name, .. } => {
9612 f.write_str("RENAME TO ")?;
9613 new_name.render(ctx, f)
9614 }
9615 Self::Options { options, .. } => {
9616 let mut first = true;
9619 for option in options {
9620 if !first {
9621 f.write_str(" ")?;
9622 }
9623 first = false;
9624 option.render(ctx, f)?;
9625 }
9626 Ok(())
9627 }
9628 Self::SetState { state, options, .. } => {
9629 f.write_str(match state {
9630 UndoTablespaceState::Active => "SET ACTIVE",
9631 UndoTablespaceState::Inactive => "SET INACTIVE",
9632 })?;
9633 render_tablespace_options(options, ctx, f)
9634 }
9635 }
9636 }
9637}
9638
9639impl Render for DropTablespace {
9640 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9641 f.write_str(if self.undo {
9642 "DROP UNDO TABLESPACE "
9643 } else {
9644 "DROP TABLESPACE "
9645 })?;
9646 self.name.render(ctx, f)?;
9647 render_tablespace_options(&self.options, ctx, f)
9648 }
9649}
9650
9651impl Render for CreateLogfileGroup {
9652 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9653 f.write_str("CREATE LOGFILE GROUP ")?;
9654 self.name.render(ctx, f)?;
9655 f.write_str(" ADD UNDOFILE ")?;
9656 self.undofile.render(ctx, f)?;
9657 render_tablespace_options(&self.options, ctx, f)
9658 }
9659}
9660
9661impl Render for AlterLogfileGroup {
9662 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9663 f.write_str("ALTER LOGFILE GROUP ")?;
9664 self.name.render(ctx, f)?;
9665 f.write_str(" ADD UNDOFILE ")?;
9666 self.undofile.render(ctx, f)?;
9667 render_tablespace_options(&self.options, ctx, f)
9668 }
9669}
9670
9671impl Render for DropLogfileGroup {
9672 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9673 f.write_str("DROP LOGFILE GROUP ")?;
9674 self.name.render(ctx, f)?;
9675 render_tablespace_options(&self.options, ctx, f)
9676 }
9677}
9678
9679impl<X: Extension + Render> Render for ObjectReference<X> {
9680 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9681 match self {
9682 Self::Named { kind, name, .. } => {
9683 kind.render(ctx, f)?;
9684 f.write_str(" ")?;
9685 name.render(ctx, f)
9686 }
9687 Self::Routine {
9688 kind, signature, ..
9689 } => {
9690 kind.render(ctx, f)?;
9691 f.write_str(" ")?;
9692 signature.render(ctx, f)
9693 }
9694 Self::Aggregate { name, args, .. } => {
9695 f.write_str("AGGREGATE ")?;
9696 name.render(ctx, f)?;
9697 args.render(ctx, f)
9698 }
9699 Self::Operator {
9700 schema, op, args, ..
9701 } => {
9702 f.write_str("OPERATOR ")?;
9703 for part in &schema.0 {
9704 part.render(ctx, f)?;
9705 f.write_str(".")?;
9706 }
9707 f.write_str(ctx.resolve(*op))?;
9708 f.write_str(" ")?;
9709 args.render(ctx, f)
9710 }
9711 Self::OperatorClass {
9712 family,
9713 name,
9714 access_method,
9715 ..
9716 } => {
9717 f.write_str(if *family {
9718 "OPERATOR FAMILY "
9719 } else {
9720 "OPERATOR CLASS "
9721 })?;
9722 name.render(ctx, f)?;
9723 f.write_str(" USING ")?;
9724 access_method.render(ctx, f)
9725 }
9726 Self::Cast { from, to, .. } => {
9727 f.write_str("CAST (")?;
9728 from.render(ctx, f)?;
9729 f.write_str(" AS ")?;
9730 to.render(ctx, f)?;
9731 f.write_str(")")
9732 }
9733 Self::Type { domain, name, .. } => {
9734 f.write_str(if *domain { "DOMAIN " } else { "TYPE " })?;
9735 name.render(ctx, f)
9736 }
9737 Self::Transform {
9738 type_name,
9739 language,
9740 ..
9741 } => {
9742 f.write_str("TRANSFORM FOR ")?;
9743 type_name.render(ctx, f)?;
9744 f.write_str(" LANGUAGE ")?;
9745 language.render(ctx, f)
9746 }
9747 Self::Trigger { name, table, .. } => {
9748 f.write_str("TRIGGER ")?;
9749 name.render(ctx, f)?;
9750 f.write_str(" ON ")?;
9751 table.render(ctx, f)
9752 }
9753 }
9754 }
9755}
9756
9757impl<X: Extension + Render> Render for AlterObjectDepends<X> {
9758 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9759 f.write_str("ALTER ")?;
9760 self.object.render(ctx, f)?;
9761 if self.no {
9762 f.write_str(" NO")?;
9763 }
9764 f.write_str(" DEPENDS ON EXTENSION ")?;
9765 self.extension.render(ctx, f)
9766 }
9767}
9768
9769impl<X: Extension + Render> Render for DropTransform<X> {
9770 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9771 let ObjectReference::Transform {
9776 type_name,
9777 language,
9778 ..
9779 } = &self.object
9780 else {
9781 unreachable!("DROP TRANSFORM always carries an ObjectReference::Transform")
9782 };
9783 f.write_str("DROP TRANSFORM")?;
9784 if self.if_exists {
9785 f.write_str(" IF EXISTS")?;
9786 }
9787 f.write_str(" FOR ")?;
9788 type_name.render(ctx, f)?;
9789 f.write_str(" LANGUAGE ")?;
9790 language.render(ctx, f)?;
9791 render_drop_behavior(self.behavior, ctx, f)
9792 }
9793}
9794
9795impl Render for ObjectRefKind {
9796 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9797 f.write_str(match self {
9798 Self::Table => "TABLE",
9799 Self::Sequence => "SEQUENCE",
9800 Self::View => "VIEW",
9801 Self::MaterializedView => "MATERIALIZED VIEW",
9802 Self::Index => "INDEX",
9803 Self::ForeignTable => "FOREIGN TABLE",
9804 Self::Collation => "COLLATION",
9805 Self::Conversion => "CONVERSION",
9806 Self::Statistics => "STATISTICS",
9807 Self::TextSearchParser => "TEXT SEARCH PARSER",
9808 Self::TextSearchDictionary => "TEXT SEARCH DICTIONARY",
9809 Self::TextSearchTemplate => "TEXT SEARCH TEMPLATE",
9810 Self::TextSearchConfiguration => "TEXT SEARCH CONFIGURATION",
9811 Self::AccessMethod => "ACCESS METHOD",
9812 Self::EventTrigger => "EVENT TRIGGER",
9813 Self::Extension => "EXTENSION",
9814 Self::ForeignDataWrapper => "FOREIGN DATA WRAPPER",
9815 Self::Language => "LANGUAGE",
9817 Self::Publication => "PUBLICATION",
9818 Self::Schema => "SCHEMA",
9819 Self::Server => "SERVER",
9820 Self::Database => "DATABASE",
9821 Self::Role => "ROLE",
9822 Self::Tablespace => "TABLESPACE",
9823 })
9824 }
9825}
9826
9827impl<X: Extension + Render> Render for AggregateArgs<X> {
9828 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9829 match self {
9830 Self::Star { .. } => f.write_str("(*)"),
9831 Self::Types {
9832 direct, order_by, ..
9833 } => {
9834 f.write_str("(")?;
9835 render_comma_separated(direct, ctx, f)?;
9836 if let Some(order_by) = order_by {
9837 if !direct.is_empty() {
9838 f.write_str(" ")?;
9839 }
9840 f.write_str("ORDER BY ")?;
9841 render_comma_separated(order_by, ctx, f)?;
9842 }
9843 f.write_str(")")
9844 }
9845 }
9846 }
9847}
9848
9849impl<X: Extension + Render> Render for OperatorArgs<X> {
9850 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9851 f.write_str("(")?;
9852 match &self.left {
9853 Some(left) => left.render(ctx, f)?,
9854 None => f.write_str("NONE")?,
9855 }
9856 f.write_str(", ")?;
9857 match &self.right {
9858 Some(right) => right.render(ctx, f)?,
9859 None => f.write_str("NONE")?,
9860 }
9861 f.write_str(")")
9862 }
9863}
9864
9865impl<X: Extension + Render> Render for CreateTypeDefinition<X> {
9866 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9867 match self {
9868 Self::Enum { labels, .. } => render_value_list_type(ctx, "ENUM", labels, f),
9871 Self::EnumFromQuery { query, .. } => {
9872 f.write_str("ENUM (")?;
9873 query.render(ctx, f)?;
9874 f.write_str(")")
9875 }
9876 Self::Alias { data_type, .. } => data_type.render(ctx, f),
9877 }
9878 }
9879}
9880
9881impl Render for ViewCheckOption {
9882 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9883 f.write_str(match self {
9884 Self::Unspecified => "WITH CHECK OPTION",
9885 Self::Cascaded => "WITH CASCADED CHECK OPTION",
9886 Self::Local => "WITH LOCAL CHECK OPTION",
9887 })
9888 }
9889}
9890
9891impl<X: Extension + Render> Render for CreateIndex<X> {
9892 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9893 f.write_str("CREATE")?;
9894 if self.unique {
9895 f.write_str(" UNIQUE")?;
9896 }
9897 f.write_str(" INDEX")?;
9898 if self.concurrently {
9899 f.write_str(" CONCURRENTLY")?;
9900 }
9901 if self.if_not_exists {
9902 f.write_str(" IF NOT EXISTS")?;
9903 }
9904 if let Some(name) = &self.name {
9905 f.write_str(" ")?;
9906 name.render(ctx, f)?;
9907 }
9908 f.write_str(" ON ")?;
9909 self.table.render(ctx, f)?;
9910 if let Some(using) = &self.using {
9911 f.write_str(" USING ")?;
9912 using.render(ctx, f)?;
9913 }
9914 f.write_str(" (")?;
9915 render_comma_separated(&self.columns, ctx, f)?;
9916 f.write_str(")")?;
9917 if !self.with_params.is_empty() {
9918 f.write_str(" WITH (")?;
9919 render_comma_separated(&self.with_params, ctx, f)?;
9920 f.write_str(")")?;
9921 }
9922 if let Some(predicate) = &self.predicate {
9923 f.write_str(" WHERE ")?;
9924 predicate.render(ctx, f)?;
9925 }
9926 Ok(())
9927 }
9928}
9929
9930fn render_sort_direction(
9934 asc: Option<bool>,
9935 nulls_first: Option<bool>,
9936 f: &mut fmt::Formatter<'_>,
9937) -> fmt::Result {
9938 match asc {
9939 Some(true) => f.write_str(" ASC")?,
9940 Some(false) => f.write_str(" DESC")?,
9941 None => {}
9942 }
9943 match nulls_first {
9944 Some(true) => f.write_str(" NULLS FIRST")?,
9945 Some(false) => f.write_str(" NULLS LAST")?,
9946 None => {}
9947 }
9948 Ok(())
9949}
9950
9951impl<X: Extension + Render> Render for IndexColumn<X> {
9952 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9953 self.expr.render(ctx, f)?;
9954 render_sort_direction(self.asc, self.nulls_first, f)
9955 }
9956}
9957
9958impl Render for CreateDatabase {
9959 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9960 f.write_str("CREATE DATABASE ")?;
9961 if self.if_not_exists {
9962 f.write_str("IF NOT EXISTS ")?;
9963 }
9964 self.name.render(ctx, f)
9965 }
9966}
9967
9968impl<X: Extension + Render> Render for CreateFunction<X> {
9969 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
9970 f.write_str("CREATE ")?;
9971 if self.or_replace {
9972 f.write_str("OR REPLACE ")?;
9973 }
9974 if let Some(definer) = &self.definer {
9975 definer.render(ctx, f)?;
9976 f.write_str(" ")?;
9977 }
9978 f.write_str("FUNCTION ")?;
9979 if self.if_not_exists {
9980 f.write_str("IF NOT EXISTS ")?;
9981 }
9982 self.name.render(ctx, f)?;
9983 f.write_str("(")?;
9985 render_comma_separated(&self.params, ctx, f)?;
9986 f.write_str(")")?;
9987 if let Some(returns) = &self.returns {
9988 f.write_str(" RETURNS ")?;
9989 returns.render(ctx, f)?;
9990 }
9991 for option in &self.options {
9992 f.write_str(" ")?;
9993 option.render(ctx, f)?;
9994 }
9995 if let Some(body) = &self.body {
9998 f.write_str(" ")?;
9999 body.render(ctx, f)?;
10000 }
10001 Ok(())
10002 }
10003}
10004
10005impl<X: Extension + Render> Render for FunctionParam<X> {
10006 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10007 if let Some(mode) = &self.mode {
10008 f.write_str(match mode {
10009 FunctionParamMode::In => "IN ",
10010 FunctionParamMode::Out => "OUT ",
10011 FunctionParamMode::InOut => "INOUT ",
10012 FunctionParamMode::Variadic => "VARIADIC ",
10013 })?;
10014 }
10015 if let Some(name) = &self.name {
10016 name.render(ctx, f)?;
10017 f.write_str(" ")?;
10018 }
10019 self.data_type.render(ctx, f)?;
10020 if let Some(default) = &self.default {
10021 f.write_str(" ")?;
10022 default.render(ctx, f)?;
10023 }
10024 Ok(())
10025 }
10026}
10027
10028impl<X: Extension + Render> Render for FunctionParamDefault<X> {
10029 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10030 f.write_str(match self.spelling {
10031 FunctionParamDefaultSpelling::Default => "DEFAULT ",
10032 FunctionParamDefaultSpelling::Equals => "= ",
10033 })?;
10034 self.value.render(ctx, f)
10035 }
10036}
10037
10038impl<X: Extension + Render> Render for CreateMacro<X> {
10039 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10040 f.write_str("CREATE")?;
10041 if self.or_replace {
10042 f.write_str(" OR REPLACE")?;
10043 }
10044 if let Some(temporary) = self.temporary {
10045 f.write_str(" ")?;
10046 temporary.render(ctx, f)?;
10047 }
10048 f.write_str(match self.spelling {
10049 MacroSpelling::Macro => " MACRO",
10050 MacroSpelling::Function => " FUNCTION",
10051 })?;
10052 if self.if_not_exists {
10053 f.write_str(" IF NOT EXISTS")?;
10054 }
10055 f.write_str(" ")?;
10056 self.name.render(ctx, f)?;
10057 f.write_str("(")?;
10059 render_comma_separated(&self.params, ctx, f)?;
10060 f.write_str(") AS ")?;
10061 self.body.render(ctx, f)
10062 }
10063}
10064
10065impl<X: Extension + Render> Render for MacroParam<X> {
10066 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10067 self.name.render(ctx, f)?;
10068 if let Some(default) = &self.default {
10069 f.write_str(" := ")?;
10070 default.render(ctx, f)?;
10071 }
10072 Ok(())
10073 }
10074}
10075
10076impl<X: Extension + Render> Render for MacroBody<X> {
10077 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10078 match self {
10079 Self::Scalar { expr, .. } => expr.render(ctx, f),
10080 Self::Table { query, .. } => {
10081 f.write_str("TABLE ")?;
10082 query.render(ctx, f)
10083 }
10084 }
10085 }
10086}
10087
10088impl<X: Extension + Render> Render for FunctionOption<X> {
10089 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10090 match self {
10091 Self::Language { name, .. } => {
10092 f.write_str("LANGUAGE ")?;
10093 name.render(ctx, f)
10094 }
10095 Self::As { body, .. } => {
10096 f.write_str("AS ")?;
10097 body.render(ctx, f)
10098 }
10099 Self::NullBehavior { behavior, .. } => behavior.render(ctx, f),
10100 Self::Deterministic { not, .. } => f.write_str(if *not {
10101 "NOT DETERMINISTIC"
10102 } else {
10103 "DETERMINISTIC"
10104 }),
10105 Self::DataAccess { access, .. } => access.render(ctx, f),
10106 Self::SqlSecurity { context, .. } => {
10107 f.write_str("SQL SECURITY ")?;
10108 context.render(ctx, f)
10109 }
10110 Self::Comment { comment, .. } => {
10111 f.write_str("COMMENT ")?;
10112 comment.render(ctx, f)
10113 }
10114 }
10115 }
10116}
10117
10118impl Render for SqlDataAccess {
10119 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10120 f.write_str(match self {
10121 Self::ContainsSql => "CONTAINS SQL",
10122 Self::NoSql => "NO SQL",
10123 Self::ReadsSqlData => "READS SQL DATA",
10124 Self::ModifiesSqlData => "MODIFIES SQL DATA",
10125 })
10126 }
10127}
10128
10129impl Render for SqlSecurityContext {
10130 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10131 f.write_str(match self {
10132 Self::Definer => "DEFINER",
10133 Self::Invoker => "INVOKER",
10134 })
10135 }
10136}
10137
10138impl<X: Extension + Render> Render for FunctionBody<X> {
10139 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10140 match self {
10141 Self::Definition { definition, .. } => definition.render(ctx, f),
10144 Self::Return { expr, .. } => {
10146 f.write_str("RETURN ")?;
10147 expr.render(ctx, f)
10148 }
10149 Self::Block { body, .. } => body.render(ctx, f),
10151 }
10152 }
10153}
10154
10155impl Render for Definer {
10156 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10157 f.write_str("DEFINER = ")?;
10158 match self {
10159 Self::Account { user, host, .. } => {
10160 user.render(ctx, f)?;
10161 if let Some(host) = host {
10162 f.write_str("@")?;
10163 host.render(ctx, f)?;
10164 }
10165 Ok(())
10166 }
10167 Self::CurrentUser { parens, .. } => {
10168 f.write_str("CURRENT_USER")?;
10169 if *parens {
10170 f.write_str("()")?;
10171 }
10172 Ok(())
10173 }
10174 }
10175 }
10176}
10177
10178impl<X: Extension + Render> Render for CreateProcedure<X> {
10179 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10180 f.write_str("CREATE ")?;
10181 if let Some(definer) = &self.definer {
10182 definer.render(ctx, f)?;
10183 f.write_str(" ")?;
10184 }
10185 f.write_str("PROCEDURE ")?;
10186 if self.if_not_exists {
10187 f.write_str("IF NOT EXISTS ")?;
10188 }
10189 self.name.render(ctx, f)?;
10190 f.write_str("(")?;
10192 render_comma_separated(&self.params, ctx, f)?;
10193 f.write_str(")")?;
10194 for characteristic in &self.characteristics {
10195 f.write_str(" ")?;
10196 characteristic.render(ctx, f)?;
10197 }
10198 f.write_str(" ")?;
10199 self.body.render(ctx, f)
10200 }
10201}
10202
10203impl<X: Extension + Render> Render for AlterRoutine<X> {
10204 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10205 f.write_str(match self.kind {
10206 RoutineKind::Procedure => "ALTER PROCEDURE ",
10207 RoutineKind::Function => "ALTER FUNCTION ",
10208 })?;
10209 self.name.render(ctx, f)?;
10210 for characteristic in &self.characteristics {
10211 f.write_str(" ")?;
10212 characteristic.render(ctx, f)?;
10213 }
10214 Ok(())
10215 }
10216}
10217
10218impl Render for FunctionNullBehavior {
10219 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10220 f.write_str(match self {
10221 Self::CalledOnNull => "CALLED ON NULL INPUT",
10222 Self::ReturnsNullOnNull => "RETURNS NULL ON NULL INPUT",
10223 Self::Strict => "STRICT",
10224 })
10225 }
10226}
10227
10228impl<X: Extension + Render> Render for EventSchedule<X> {
10229 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10230 match self {
10231 Self::At { at, .. } => {
10232 f.write_str("AT ")?;
10233 at.render(ctx, f)
10234 }
10235 Self::Every {
10236 value,
10237 unit,
10238 starts,
10239 ends,
10240 ..
10241 } => {
10242 f.write_str("EVERY ")?;
10243 value.render(ctx, f)?;
10244 f.write_str(mysql_interval_unit_suffix(*unit))?;
10247 if let Some(starts) = starts {
10248 f.write_str(" STARTS ")?;
10249 starts.render(ctx, f)?;
10250 }
10251 if let Some(ends) = ends {
10252 f.write_str(" ENDS ")?;
10253 ends.render(ctx, f)?;
10254 }
10255 Ok(())
10256 }
10257 }
10258 }
10259}
10260
10261fn render_event_on_completion(
10264 on_completion: EventOnCompletion,
10265 f: &mut fmt::Formatter<'_>,
10266) -> fmt::Result {
10267 f.write_str(match on_completion {
10268 EventOnCompletion::Preserve => " ON COMPLETION PRESERVE",
10269 EventOnCompletion::NotPreserve => " ON COMPLETION NOT PRESERVE",
10270 })
10271}
10272
10273fn render_event_status(status: EventStatus, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10275 f.write_str(match status {
10276 EventStatus::Enable => " ENABLE",
10277 EventStatus::Disable => " DISABLE",
10278 EventStatus::DisableOnReplica(ReplicaSpelling::Slave) => " DISABLE ON SLAVE",
10279 EventStatus::DisableOnReplica(ReplicaSpelling::Replica) => " DISABLE ON REPLICA",
10280 })
10281}
10282
10283impl<X: Extension + Render> Render for CreateEvent<X> {
10284 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10285 f.write_str("CREATE ")?;
10286 if let Some(definer) = &self.definer {
10287 definer.render(ctx, f)?;
10288 f.write_str(" ")?;
10289 }
10290 f.write_str("EVENT ")?;
10291 if self.if_not_exists {
10292 f.write_str("IF NOT EXISTS ")?;
10293 }
10294 self.name.render(ctx, f)?;
10295 f.write_str(" ON SCHEDULE ")?;
10296 self.schedule.render(ctx, f)?;
10297 if let Some(on_completion) = self.on_completion {
10298 render_event_on_completion(on_completion, f)?;
10299 }
10300 if let Some(status) = self.status {
10301 render_event_status(status, f)?;
10302 }
10303 if let Some(comment) = &self.comment {
10304 f.write_str(" COMMENT ")?;
10305 comment.render(ctx, f)?;
10306 }
10307 f.write_str(" DO ")?;
10308 self.body.render(ctx, f)
10309 }
10310}
10311
10312impl<X: Extension + Render> Render for AlterEvent<X> {
10313 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10314 f.write_str("ALTER ")?;
10315 if let Some(definer) = &self.definer {
10316 definer.render(ctx, f)?;
10317 f.write_str(" ")?;
10318 }
10319 f.write_str("EVENT ")?;
10320 self.name.render(ctx, f)?;
10321 if let Some(schedule) = &self.schedule {
10322 f.write_str(" ON SCHEDULE ")?;
10323 schedule.render(ctx, f)?;
10324 }
10325 if let Some(on_completion) = self.on_completion {
10326 render_event_on_completion(on_completion, f)?;
10327 }
10328 if let Some(rename_to) = &self.rename_to {
10329 f.write_str(" RENAME TO ")?;
10330 rename_to.render(ctx, f)?;
10331 }
10332 if let Some(status) = self.status {
10333 render_event_status(status, f)?;
10334 }
10335 if let Some(comment) = &self.comment {
10336 f.write_str(" COMMENT ")?;
10337 comment.render(ctx, f)?;
10338 }
10339 if let Some(body) = &self.body {
10340 f.write_str(" DO ")?;
10341 body.render(ctx, f)?;
10342 }
10343 Ok(())
10344 }
10345}
10346
10347impl Render for DropEvent {
10348 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10349 f.write_str("DROP EVENT ")?;
10350 if self.if_exists {
10351 f.write_str("IF EXISTS ")?;
10352 }
10353 self.name.render(ctx, f)
10354 }
10355}
10356
10357impl Render for DropDatabase {
10358 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10359 f.write_str(match self.spelling {
10360 DatabaseKeyword::Database => "DROP DATABASE ",
10361 DatabaseKeyword::Schema => "DROP SCHEMA ",
10362 })?;
10363 if self.if_exists {
10364 f.write_str("IF EXISTS ")?;
10365 }
10366 self.name.render(ctx, f)
10367 }
10368}
10369
10370impl Render for DropIndexOnTable {
10371 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10372 f.write_str("DROP INDEX ")?;
10373 self.name.render(ctx, f)?;
10374 f.write_str(" ON ")?;
10375 self.table.render(ctx, f)?;
10376 for option in &self.options {
10377 f.write_str(" ")?;
10378 option.render(ctx, f)?;
10379 }
10380 Ok(())
10381 }
10382}
10383
10384impl Render for IndexLockAlgorithmOption {
10385 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10386 let (keyword, equals, value) = match self {
10387 Self::Algorithm { equals, value } => ("ALGORITHM", *equals, value.render_str()),
10388 Self::Lock { equals, value } => ("LOCK", *equals, value.render_str()),
10389 };
10390 f.write_str(keyword)?;
10391 f.write_str(if equals { " = " } else { " " })?;
10392 f.write_str(value)
10393 }
10394}
10395
10396impl IndexAlgorithm {
10397 fn render_str(self) -> &'static str {
10399 match self {
10400 Self::Default => "DEFAULT",
10401 Self::Inplace => "INPLACE",
10402 Self::Instant => "INSTANT",
10403 Self::Copy => "COPY",
10404 }
10405 }
10406}
10407
10408impl IndexLock {
10409 fn render_str(self) -> &'static str {
10411 match self {
10412 Self::Default => "DEFAULT",
10413 Self::None => "NONE",
10414 Self::Shared => "SHARED",
10415 Self::Exclusive => "EXCLUSIVE",
10416 }
10417 }
10418}
10419
10420impl<X: Extension + Render> Render for Query<X> {
10421 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10422 if let Some(with) = &self.with {
10423 with.render(ctx, f)?;
10424 f.write_str(" ")?;
10425 }
10426 self.body.render(ctx, f)?;
10427 if !self.order_by.is_empty() {
10428 f.write_str(" ORDER BY ")?;
10429 render_comma_separated(&self.order_by, ctx, f)?;
10430 }
10431 if let Some(all) = &self.order_by_all {
10434 f.write_str(" ORDER BY ")?;
10435 all.render(ctx, f)?;
10436 }
10437 if let Some(limit_by) = &self.limit_by {
10440 f.write_str(" ")?;
10441 limit_by.render(ctx, f)?;
10442 }
10443 if let Some(limit) = &self.limit {
10444 f.write_str(" ")?;
10445 limit.render(ctx, f)?;
10446 }
10447 if !self.settings.is_empty() {
10449 f.write_str(" SETTINGS ")?;
10450 render_comma_separated(&self.settings, ctx, f)?;
10451 }
10452 if let Some(format) = &self.format {
10454 f.write_str(" ")?;
10455 format.render(ctx, f)?;
10456 }
10457 for locking in &self.locking {
10460 f.write_str(" ")?;
10461 locking.render(ctx, f)?;
10462 }
10463 for op in &self.pipe_operators {
10466 f.write_str(" ")?;
10467 op.render(ctx, f)?;
10468 }
10469 if let Some(for_clause) = &self.for_clause {
10472 f.write_str(" ")?;
10473 for_clause.render(ctx, f)?;
10474 }
10475 Ok(())
10476 }
10477}
10478
10479impl<X: Extension + Render> Render for PipeOperator<X> {
10480 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10481 match self {
10485 PipeOperator::Where { predicate, .. } => {
10486 f.write_str("|> WHERE ")?;
10487 predicate.render(ctx, f)
10488 }
10489 PipeOperator::Select { items, .. } => {
10490 f.write_str("|> SELECT ")?;
10491 render_comma_separated(items, ctx, f)
10492 }
10493 PipeOperator::Extend { items, .. } => {
10494 f.write_str("|> EXTEND ")?;
10495 render_comma_separated(items, ctx, f)
10496 }
10497 PipeOperator::As { alias, .. } => {
10498 f.write_str("|> AS ")?;
10499 alias.render(ctx, f)
10500 }
10501 PipeOperator::OrderBy { keys, .. } => {
10502 f.write_str("|> ORDER BY ")?;
10503 render_comma_separated(keys, ctx, f)
10504 }
10505 PipeOperator::Limit { count, offset, .. } => {
10506 f.write_str("|> LIMIT ")?;
10507 count.render(ctx, f)?;
10508 if let Some(offset) = offset {
10509 f.write_str(" OFFSET ")?;
10510 offset.render(ctx, f)?;
10511 }
10512 Ok(())
10513 }
10514 PipeOperator::Join { join, .. } => {
10515 f.write_str("|> ")?;
10518 join.render(ctx, f)
10519 }
10520 PipeOperator::SetOperation {
10521 op,
10522 quantifier,
10523 queries,
10524 ..
10525 } => {
10526 f.write_str("|> ")?;
10527 op.render(ctx, f)?;
10528 if let Some(quantifier) = quantifier {
10529 f.write_str(" ")?;
10530 quantifier.render(ctx, f)?;
10531 }
10532 f.write_str(" ")?;
10533 for (index, query) in queries.iter().enumerate() {
10536 if index > 0 {
10537 f.write_str(", ")?;
10538 }
10539 f.write_str("(")?;
10540 query.render(ctx, f)?;
10541 f.write_str(")")?;
10542 }
10543 Ok(())
10544 }
10545 PipeOperator::Set { assignments, .. } => {
10546 f.write_str("|> SET ")?;
10547 render_comma_separated(assignments, ctx, f)
10548 }
10549 PipeOperator::Call { call, alias, .. } => {
10550 f.write_str("|> CALL ")?;
10551 call.render(ctx, f)?;
10552 if let Some(alias) = alias {
10553 f.write_str(" AS ")?;
10554 alias.render(ctx, f)?;
10555 }
10556 Ok(())
10557 }
10558 PipeOperator::Aggregate {
10559 aggregates,
10560 group_by,
10561 ..
10562 } => {
10563 f.write_str("|> AGGREGATE")?;
10566 if !aggregates.is_empty() {
10567 f.write_str(" ")?;
10568 render_comma_separated(aggregates, ctx, f)?;
10569 }
10570 if !group_by.is_empty() {
10571 f.write_str(" GROUP BY ")?;
10572 render_comma_separated(group_by, ctx, f)?;
10573 }
10574 Ok(())
10575 }
10576 PipeOperator::Drop { columns, .. } => {
10577 f.write_str("|> DROP ")?;
10578 render_comma_separated(columns, ctx, f)
10579 }
10580 PipeOperator::Rename { renames, .. } => {
10581 f.write_str("|> RENAME ")?;
10582 render_comma_separated(renames, ctx, f)
10583 }
10584 PipeOperator::Pivot {
10585 aggregates, column, ..
10586 } => {
10587 f.write_str("|> PIVOT (")?;
10588 render_comma_separated(aggregates, ctx, f)?;
10589 f.write_str(" FOR ")?;
10590 column.render(ctx, f)?;
10592 f.write_str(")")
10593 }
10594 PipeOperator::Unpivot {
10595 value,
10596 name,
10597 columns,
10598 ..
10599 } => {
10600 f.write_str("|> UNPIVOT (")?;
10601 render_unpivot_name_list(value, ctx, f)?;
10602 f.write_str(" FOR ")?;
10603 render_unpivot_name_list(name, ctx, f)?;
10604 f.write_str(" IN (")?;
10605 render_comma_separated(columns, ctx, f)?;
10606 f.write_str("))")
10607 }
10608 PipeOperator::TableSample { sample, .. } => {
10609 f.write_str("|>")?;
10612 sample.render(ctx, f)
10613 }
10614 }
10615 }
10616}
10617
10618impl<X: Extension + Render> Render for SemiStructuredAccessExpr<X> {
10619 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10620 let full = ctx.mode() == RenderMode::Parenthesized;
10621 open_group(full, f)?;
10622 render_operand(
10623 &self.base,
10624 operand_needs_parens(
10625 &ctx.target().binding_powers,
10626 ctx.target().binding_powers.subscript,
10627 &self.base,
10628 Side::Left,
10629 ),
10630 ctx,
10631 f,
10632 )?;
10633 let mut segments = self.path.iter();
10634 if let Some(first) = segments.next() {
10635 f.write_str(":")?;
10636 render_semi_structured_path_segment(first, false, ctx, f)?;
10637 }
10638 for segment in segments {
10639 render_semi_structured_path_segment(segment, true, ctx, f)?;
10640 }
10641 close_group(full, f)
10642 }
10643}
10644
10645fn render_semi_structured_path_segment<X: Extension + Render>(
10646 segment: &SemiStructuredPathSegment<X>,
10647 suffix: bool,
10648 ctx: &RenderCtx<'_>,
10649 f: &mut fmt::Formatter<'_>,
10650) -> fmt::Result {
10651 match segment {
10652 SemiStructuredPathSegment::Key { key, .. } => {
10653 if suffix {
10654 f.write_str(".")?;
10655 }
10656 key.render(ctx, f)
10657 }
10658 SemiStructuredPathSegment::Index { index, .. } => {
10659 f.write_str("[")?;
10660 index.render(ctx, f)?;
10661 f.write_str("]")
10662 }
10663 }
10664}
10665
10666impl<X: Extension + Render> Render for PipeAggregateExpr<X> {
10667 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10668 self.expr.render(ctx, f)?;
10669 if let Some(alias) = &self.alias {
10670 f.write_str(" AS ")?;
10671 alias.render(ctx, f)?;
10672 }
10673 render_sort_direction(self.asc, self.nulls_first, f)
10674 }
10675}
10676
10677impl Render for PipeRenameItem {
10678 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10679 self.old.render(ctx, f)?;
10680 f.write_str(" AS ")?;
10681 self.new.render(ctx, f)
10682 }
10683}
10684
10685impl Render for LockingClause {
10686 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10687 match self.spelling {
10688 LockingSpelling::LockInShareMode => return f.write_str("LOCK IN SHARE MODE"),
10691 LockingSpelling::Modern => {}
10692 }
10693 f.write_str(match self.strength {
10694 LockStrength::Update => "FOR UPDATE",
10695 LockStrength::NoKeyUpdate => "FOR NO KEY UPDATE",
10696 LockStrength::Share => "FOR SHARE",
10697 LockStrength::KeyShare => "FOR KEY SHARE",
10698 })?;
10699 if !self.of.is_empty() {
10700 f.write_str(" OF ")?;
10701 render_comma_separated(&self.of, ctx, f)?;
10702 }
10703 match self.wait {
10704 Some(LockWait::NoWait) => f.write_str(" NOWAIT")?,
10705 Some(LockWait::SkipLocked) => f.write_str(" SKIP LOCKED")?,
10706 None => {}
10707 }
10708 Ok(())
10709 }
10710}
10711
10712impl Render for IndexHint {
10713 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10714 f.write_str(match self.action {
10715 IndexHintAction::Use => "USE ",
10716 IndexHintAction::Ignore => "IGNORE ",
10717 IndexHintAction::Force => "FORCE ",
10718 })?;
10719 f.write_str(match self.keyword {
10720 IndexHintKeyword::Index => "INDEX",
10721 IndexHintKeyword::Key => "KEY",
10722 })?;
10723 if let Some(scope) = self.scope {
10724 f.write_str(match scope {
10725 IndexHintScope::Join => " FOR JOIN",
10726 IndexHintScope::OrderBy => " FOR ORDER BY",
10727 IndexHintScope::GroupBy => " FOR GROUP BY",
10728 })?;
10729 }
10730 f.write_str(" (")?;
10733 render_comma_separated(&self.indexes, ctx, f)?;
10734 f.write_str(")")
10735 }
10736}
10737
10738impl Render for IndexedBy {
10739 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10740 match self {
10741 IndexedBy::Named { index, .. } => {
10742 f.write_str("INDEXED BY ")?;
10743 index.render(ctx, f)
10744 }
10745 IndexedBy::NotIndexed { .. } => f.write_str("NOT INDEXED"),
10746 }
10747 }
10748}
10749
10750impl Render for TableHint {
10751 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10752 match self {
10753 TableHint::Keyword { keyword, .. } => f.write_str(keyword.as_str()),
10754 TableHint::Index {
10757 equals, indexes, ..
10758 } => {
10759 if *equals && indexes.len() == 1 {
10760 f.write_str("INDEX = ")?;
10761 indexes[0].render(ctx, f)
10762 } else {
10763 f.write_str(if *equals { "INDEX = (" } else { "INDEX (" })?;
10764 render_comma_separated(indexes, ctx, f)?;
10765 f.write_str(")")
10766 }
10767 }
10768 TableHint::ForceSeek { target: None, .. } => f.write_str("FORCESEEK"),
10769 TableHint::ForceSeek {
10770 target: Some(target),
10771 ..
10772 } => {
10773 f.write_str("FORCESEEK (")?;
10774 target.index.render(ctx, f)?;
10775 f.write_str(" (")?;
10776 render_comma_separated(&target.columns, ctx, f)?;
10777 f.write_str("))")
10778 }
10779 TableHint::Other { ident, .. } => ident.render(ctx, f),
10780 }
10781 }
10782}
10783
10784impl<X: Extension + Render> Render for TableVersion<X> {
10785 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10786 match self {
10787 TableVersion::ForSystemTimeAsOf { point, .. } => {
10788 f.write_str("FOR SYSTEM_TIME AS OF ")?;
10789 point.render(ctx, f)
10790 }
10791 TableVersion::ForSystemTimeFromTo { start, end, .. } => {
10792 f.write_str("FOR SYSTEM_TIME FROM ")?;
10793 start.render(ctx, f)?;
10794 f.write_str(" TO ")?;
10795 end.render(ctx, f)
10796 }
10797 TableVersion::ForSystemTimeBetween { start, end, .. } => {
10798 f.write_str("FOR SYSTEM_TIME BETWEEN ")?;
10799 start.render(ctx, f)?;
10800 f.write_str(" AND ")?;
10801 end.render(ctx, f)
10802 }
10803 TableVersion::ForSystemTimeContainedIn { start, end, .. } => {
10804 f.write_str("FOR SYSTEM_TIME CONTAINED IN (")?;
10805 start.render(ctx, f)?;
10806 f.write_str(", ")?;
10807 end.render(ctx, f)?;
10808 f.write_str(")")
10809 }
10810 TableVersion::ForSystemTimeAll { .. } => f.write_str("FOR SYSTEM_TIME ALL"),
10811 TableVersion::VersionAsOf { version, .. } => {
10812 f.write_str("VERSION AS OF ")?;
10813 version.render(ctx, f)
10814 }
10815 TableVersion::TimestampAsOf { point, .. } => {
10816 f.write_str("TIMESTAMP AS OF ")?;
10817 point.render(ctx, f)
10818 }
10819 }
10820 }
10821}
10822
10823impl<X: Extension + Render> Render for SetExpr<X> {
10824 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10825 match self {
10826 SetExpr::Select { select, .. } => select.render(ctx, f),
10827 SetExpr::Values { values, .. } => values.render(ctx, f),
10828 SetExpr::Query { query, .. } => {
10831 f.write_str("(")?;
10832 query.render(ctx, f)?;
10833 f.write_str(")")
10834 }
10835 SetExpr::SetOperation {
10836 op,
10837 all,
10838 by_name,
10839 left,
10840 right,
10841 ..
10842 } => {
10843 render_set_operand(op, left, Side::Left, ctx, f)?;
10844 f.write_str(" ")?;
10845 op.render(ctx, f)?;
10846 if *all {
10847 f.write_str(" ALL")?;
10848 }
10849 if *by_name {
10852 f.write_str(" BY NAME")?;
10853 }
10854 f.write_str(" ")?;
10855 render_set_operand(op, right, Side::Right, ctx, f)
10856 }
10857 SetExpr::Pivot { pivot, .. } => pivot.render(ctx, f),
10861 SetExpr::Unpivot { unpivot, .. } => unpivot.render(ctx, f),
10862 }
10863 }
10864}
10865
10866fn render_set_operand<X: Extension + Render>(
10873 parent: &SetOperator,
10874 child: &SetExpr<X>,
10875 side: Side,
10876 ctx: &RenderCtx<'_>,
10877 f: &mut fmt::Formatter<'_>,
10878) -> fmt::Result {
10879 let wrap = match ctx.mode() {
10880 RenderMode::Parenthesized => matches!(child, SetExpr::SetOperation { .. }),
10881 RenderMode::Canonical | RenderMode::Redacted => {
10882 set_child_needs_parens(&ctx.target().set_operation_powers, parent, child, side)
10883 }
10884 };
10885 open_group(wrap, f)?;
10886 child.render(ctx, f)?;
10887 close_group(wrap, f)
10888}
10889
10890fn set_child_needs_parens<X: Extension>(
10892 bp: &SetOperationBindingPowerTable,
10893 parent: &SetOperator,
10894 child: &SetExpr<X>,
10895 side: Side,
10896) -> bool {
10897 match child {
10898 SetExpr::SetOperation { op, .. } => bp.needs_parens(parent, op, side),
10899 _ => false,
10900 }
10901}
10902
10903impl<X: Extension + Render> Render for With<X> {
10904 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10905 f.write_str("WITH")?;
10906 if self.recursive {
10907 f.write_str(" RECURSIVE")?;
10908 }
10909 render_leading_space_comma_separated(&self.ctes, ctx, f)
10910 }
10911}
10912
10913impl<X: Extension + Render> Render for Cte<X> {
10914 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10915 self.name.render(ctx, f)?;
10916 if !self.columns.is_empty() {
10917 f.write_str("(")?;
10918 render_ident_list(&self.columns, ctx, f)?;
10919 f.write_str(")")?;
10920 }
10921 if let Some(key_columns) = &self.using_key {
10923 f.write_str(" USING KEY (")?;
10924 render_ident_list(key_columns, ctx, f)?;
10925 f.write_str(")")?;
10926 }
10927 f.write_str(" AS")?;
10928 match self.materialized {
10929 Some(true) => f.write_str(" MATERIALIZED")?,
10930 Some(false) => f.write_str(" NOT MATERIALIZED")?,
10931 None => {}
10932 }
10933 f.write_str(" (")?;
10934 self.body.render(ctx, f)?;
10935 f.write_str(")")?;
10936 if let Some(search) = &self.search {
10938 f.write_str(" ")?;
10939 search.render(ctx, f)?;
10940 }
10941 if let Some(cycle) = &self.cycle {
10942 f.write_str(" ")?;
10943 cycle.render(ctx, f)?;
10944 }
10945 Ok(())
10946 }
10947}
10948
10949impl Render for CteSearchClause {
10950 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10951 f.write_str(if self.breadth_first {
10952 "SEARCH BREADTH FIRST BY "
10953 } else {
10954 "SEARCH DEPTH FIRST BY "
10955 })?;
10956 render_ident_list(&self.columns, ctx, f)?;
10957 f.write_str(" SET ")?;
10958 self.set_column.render(ctx, f)
10959 }
10960}
10961
10962impl<X: Extension + Render> Render for CteCycleClause<X> {
10963 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10964 f.write_str("CYCLE ")?;
10965 render_ident_list(&self.columns, ctx, f)?;
10966 f.write_str(" SET ")?;
10967 self.mark_column.render(ctx, f)?;
10968 if let Some(mark) = &self.mark {
10971 mark.render(ctx, f)?;
10972 }
10973 f.write_str(" USING ")?;
10974 self.path_column.render(ctx, f)
10975 }
10976}
10977
10978impl<X: Extension + Render> Render for CteCycleMark<X> {
10979 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10980 f.write_str(" TO ")?;
10981 self.value.render(ctx, f)?;
10982 f.write_str(" DEFAULT ")?;
10983 self.default.render(ctx, f)
10984 }
10985}
10986
10987impl<X: Extension + Render> Render for CteBody<X> {
10988 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
10989 match self {
10992 Self::Query { query, .. } => query.render(ctx, f),
10993 Self::Insert { insert, .. } => insert.render(ctx, f),
10994 Self::Update { update, .. } => update.render(ctx, f),
10995 Self::Delete { delete, .. } => delete.render(ctx, f),
10996 Self::Merge { merge, .. } => merge.render(ctx, f),
10997 }
10998 }
10999}
11000
11001impl<X: Extension + Render> Render for Values<X> {
11002 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11003 f.write_str("VALUES ")?;
11004 render_values_rows(&self.rows, self.explicit_row, ctx, f)
11005 }
11006}
11007
11008impl<X: Extension + Render> Render for ValuesItem<X> {
11009 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11010 match self {
11011 Self::Expr { expr, .. } => expr.render(ctx, f),
11012 Self::Default { default, .. } => default.render(ctx, f),
11013 }
11014 }
11015}
11016
11017fn render_select_projection_clause<X: Extension + Render>(
11021 select: &Select<X>,
11022 ctx: &RenderCtx<'_>,
11023 f: &mut fmt::Formatter<'_>,
11024) -> fmt::Result {
11025 f.write_str("SELECT")?;
11026 match &select.distinct {
11027 None => {}
11028 Some(SelectDistinct::Quantifier { quantifier, .. }) => {
11029 f.write_str(" ")?;
11030 quantifier.render(ctx, f)?;
11031 }
11032 Some(SelectDistinct::On { exprs, .. }) => {
11033 f.write_str(" DISTINCT ON (")?;
11034 render_comma_separated(exprs, ctx, f)?;
11035 f.write_str(")")?;
11036 }
11037 }
11038 if select.straight_join {
11040 f.write_str(" STRAIGHT_JOIN")?;
11041 }
11042 render_leading_space_comma_separated(&select.projection, ctx, f)
11043}
11044
11045fn render_select_body_tail<X: Extension + Render>(
11049 select: &Select<X>,
11050 ctx: &RenderCtx<'_>,
11051 f: &mut fmt::Formatter<'_>,
11052) -> fmt::Result {
11053 for view in &select.lateral_views {
11056 f.write_str(" ")?;
11057 view.render(ctx, f)?;
11058 }
11059 if let Some(selection) = &select.selection {
11060 f.write_str(" WHERE ")?;
11061 selection.render(ctx, f)?;
11062 }
11063 if let Some(connect_by) = &select.connect_by {
11066 f.write_str(" ")?;
11067 connect_by.render(ctx, f)?;
11068 }
11069 if !select.group_by.is_empty() {
11070 f.write_str(" GROUP BY ")?;
11071 if let Some(quantifier) = &select.group_by_quantifier {
11074 quantifier.render(ctx, f)?;
11075 f.write_str(" ")?;
11076 }
11077 render_comma_separated(&select.group_by, ctx, f)?;
11078 }
11079 if let Some(spelling) = select.group_by_all {
11084 let bare_star = spelling == GroupByAllSpelling::Star && honours_source_spelling(ctx);
11085 f.write_str(if bare_star {
11086 " GROUP BY *"
11087 } else {
11088 " GROUP BY ALL"
11089 })?;
11090 }
11091 if let Some(having) = &select.having {
11092 f.write_str(" HAVING ")?;
11093 having.render(ctx, f)?;
11094 }
11095 if !select.windows.is_empty() {
11096 f.write_str(" WINDOW ")?;
11097 render_comma_separated(&select.windows, ctx, f)?;
11098 }
11099 if let Some(qualify) = &select.qualify {
11102 f.write_str(" QUALIFY ")?;
11103 qualify.render(ctx, f)?;
11104 }
11105 if let Some(sample) = &select.sample {
11108 f.write_str(" USING SAMPLE ")?;
11109 sample.render(ctx, f)?;
11110 }
11111 Ok(())
11112}
11113
11114fn from_first_projection_is_implicit<X: Extension>(select: &Select<X>) -> bool {
11120 select.distinct.is_none()
11121 && matches!(select.projection.as_slice(), [SelectItem::Wildcard { .. }])
11122}
11123
11124impl<X: Extension + Render> Render for Select<X> {
11125 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11126 match self.spelling {
11127 SelectSpelling::TableCommand => {
11132 f.write_str("TABLE ")?;
11133 if let Some(table) = self.from.first() {
11134 table.relation.render(ctx, f)?;
11135 }
11136 Ok(())
11137 }
11138 SelectSpelling::FromFirst => {
11142 f.write_str("FROM ")?;
11143 render_comma_separated(&self.from, ctx, f)?;
11144 if !from_first_projection_is_implicit(self) {
11145 f.write_str(" ")?;
11146 render_select_projection_clause(self, ctx, f)?;
11147 }
11148 render_select_body_tail(self, ctx, f)
11149 }
11150 SelectSpelling::Select => {
11151 render_select_projection_clause(self, ctx, f)?;
11152 if let Some(into) = &self.into {
11154 f.write_str(" ")?;
11155 into.render(ctx, f)?;
11156 }
11157 if !self.from.is_empty() {
11158 f.write_str(" FROM ")?;
11159 render_comma_separated(&self.from, ctx, f)?;
11160 }
11161 render_select_body_tail(self, ctx, f)
11162 }
11163 }
11164 }
11165}
11166
11167impl<X: Extension + Render> Render for LateralView<X> {
11168 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11169 f.write_str("LATERAL VIEW ")?;
11170 if self.outer {
11171 f.write_str("OUTER ")?;
11172 }
11173 self.function.render(ctx, f)?;
11174 f.write_str(" ")?;
11175 self.alias.render(ctx, f)?;
11176 if !self.columns.is_empty() {
11177 f.write_str(" AS ")?;
11180 render_comma_separated(&self.columns, ctx, f)?;
11181 }
11182 Ok(())
11183 }
11184}
11185
11186impl<X: Extension + Render> Render for HierarchicalClause<X> {
11187 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11188 let render_start_with = |f: &mut fmt::Formatter<'_>| -> fmt::Result {
11191 if let Some(start_with) = &self.start_with {
11192 f.write_str("START WITH ")?;
11193 start_with.render(ctx, f)?;
11194 }
11195 Ok(())
11196 };
11197 let render_connect_by = |f: &mut fmt::Formatter<'_>| -> fmt::Result {
11198 f.write_str("CONNECT BY ")?;
11199 if self.nocycle {
11200 f.write_str("NOCYCLE ")?;
11201 }
11202 self.connect_by.render(ctx, f)
11203 };
11204 if self.start_with_leads && self.start_with.is_some() {
11205 render_start_with(f)?;
11206 f.write_str(" ")?;
11207 render_connect_by(f)
11208 } else if self.start_with.is_some() {
11209 render_connect_by(f)?;
11210 f.write_str(" ")?;
11211 render_start_with(f)
11212 } else {
11213 render_connect_by(f)
11214 }
11215 }
11216}
11217
11218impl Render for IntoTarget {
11219 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11220 f.write_str("INTO ")?;
11221 if let Some(temporary) = self.temporary {
11222 temporary.render(ctx, f)?;
11223 f.write_str(" ")?;
11224 }
11225 self.name.render(ctx, f)
11226 }
11227}
11228
11229impl<X: Extension + Render> Render for SelectItem<X> {
11230 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11231 match self {
11232 SelectItem::Wildcard {
11233 options,
11234 alias,
11235 alias_spelling,
11236 ..
11237 } => {
11238 f.write_str("*")?;
11239 render_optional_wildcard_options(options.as_deref(), ctx, f)?;
11240 render_alias(alias.as_ref(), *alias_spelling, ctx, f)
11241 }
11242 SelectItem::QualifiedWildcard {
11243 name,
11244 options,
11245 alias,
11246 alias_spelling,
11247 ..
11248 } => {
11249 name.render(ctx, f)?;
11250 f.write_str(".*")?;
11251 render_optional_wildcard_options(options.as_deref(), ctx, f)?;
11252 render_alias(alias.as_ref(), *alias_spelling, ctx, f)
11253 }
11254 SelectItem::Expr {
11255 expr,
11256 alias,
11257 alias_spelling,
11258 ..
11259 } => {
11260 if let (Some(alias), AliasSpelling::PrefixColon) = (alias.as_ref(), alias_spelling)
11265 {
11266 if honours_alias_spelling(ctx) {
11267 alias.render(ctx, f)?;
11268 f.write_str(": ")?;
11269 return expr.render(ctx, f);
11270 }
11271 }
11272 expr.render(ctx, f)?;
11273 if let Some(alias) = alias {
11274 f.write_str(alias_lead(*alias_spelling, ctx))?;
11275 alias.render(ctx, f)?;
11276 }
11277 Ok(())
11278 }
11279 }
11280 }
11281}
11282
11283fn render_wildcard_options<X: Extension + Render>(
11288 options: &WildcardOptions<X>,
11289 ctx: &RenderCtx<'_>,
11290 f: &mut fmt::Formatter<'_>,
11291) -> fmt::Result {
11292 if !options.exclude.is_empty() {
11293 f.write_str(" EXCLUDE (")?;
11294 render_comma_separated(&options.exclude, ctx, f)?;
11295 f.write_str(")")?;
11296 }
11297 if !options.replace.is_empty() {
11298 f.write_str(" REPLACE (")?;
11299 render_comma_separated(&options.replace, ctx, f)?;
11300 f.write_str(")")?;
11301 }
11302 if !options.rename.is_empty() {
11303 f.write_str(" RENAME (")?;
11304 render_comma_separated(&options.rename, ctx, f)?;
11305 f.write_str(")")?;
11306 }
11307 Ok(())
11308}
11309
11310fn render_optional_wildcard_options<X: Extension + Render>(
11311 options: Option<&WildcardOptions<X>>,
11312 ctx: &RenderCtx<'_>,
11313 f: &mut fmt::Formatter<'_>,
11314) -> fmt::Result {
11315 match options {
11316 Some(options) => render_wildcard_options(options, ctx, f),
11317 None => Ok(()),
11318 }
11319}
11320
11321fn render_comprehension_source<X: Extension + Render>(
11324 source: &ComprehensionSource<X>,
11325 ctx: &RenderCtx<'_>,
11326 f: &mut fmt::Formatter<'_>,
11327) -> fmt::Result {
11328 match source {
11329 ComprehensionSource::Expr { expr, .. } => expr.render(ctx, f),
11330 ComprehensionSource::Star {
11331 parenthesized,
11332 options,
11333 ..
11334 } => {
11335 if *parenthesized {
11336 f.write_str("(*")?;
11337 render_optional_wildcard_options(options.as_deref(), ctx, f)?;
11338 f.write_str(")")
11339 } else {
11340 f.write_str("*")?;
11341 render_optional_wildcard_options(options.as_deref(), ctx, f)
11342 }
11343 }
11344 }
11345}
11346
11347impl<X: Extension + Render> Render for WildcardReplace<X> {
11348 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11349 self.expr.render(ctx, f)?;
11350 f.write_str(" AS ")?;
11351 self.column.render(ctx, f)
11352 }
11353}
11354
11355impl Render for WildcardRename {
11356 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11357 self.column.render(ctx, f)?;
11358 f.write_str(" AS ")?;
11359 self.alias.render(ctx, f)
11360 }
11361}
11362
11363impl<X: Extension + Render> Render for GroupByItem<X> {
11364 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11365 match self {
11366 GroupByItem::Expr { expr, .. } => expr.render(ctx, f),
11367 GroupByItem::Rollup {
11368 exprs, spelling, ..
11369 } => match spelling {
11370 RollupSpelling::Function => {
11371 f.write_str("ROLLUP (")?;
11372 render_comma_separated(exprs, ctx, f)?;
11373 f.write_str(")")
11374 }
11375 RollupSpelling::WithRollup => {
11381 render_comma_separated(exprs, ctx, f)?;
11382 f.write_str(" WITH ROLLUP")
11383 }
11384 },
11385 GroupByItem::Cube { exprs, .. } => {
11386 f.write_str("CUBE (")?;
11387 render_comma_separated(exprs, ctx, f)?;
11388 f.write_str(")")
11389 }
11390 GroupByItem::GroupingSets { sets, .. } => {
11391 f.write_str("GROUPING SETS (")?;
11392 render_comma_separated(sets, ctx, f)?;
11393 f.write_str(")")
11394 }
11395 GroupByItem::Empty { .. } => f.write_str("()"),
11396 }
11397 }
11398}
11399
11400impl<X: Extension + Render> Render for TableWithJoins<X> {
11405 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11406 self.relation.render(ctx, f)?;
11407 for join in &self.joins {
11408 f.write_str(" ")?;
11409 join.render(ctx, f)?;
11410 }
11411 Ok(())
11412 }
11413}
11414
11415impl<X: Extension + Render> Render for TableFactor<X> {
11416 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11417 match self {
11418 TableFactor::Table {
11419 name,
11420 inheritance,
11421 json_path,
11422 version,
11423 partition,
11424 alias,
11425 indexed_by,
11426 index_hints,
11427 sample,
11428 table_hints,
11429 ..
11430 } => {
11431 render_relation_inheritance(inheritance, name, ctx, f)?;
11432 for segment in json_path {
11436 render_semi_structured_path_segment(segment, true, ctx, f)?;
11437 }
11438 if let Some(version) = version {
11440 f.write_str(" ")?;
11441 version.render(ctx, f)?;
11442 }
11443 if !partition.is_empty() {
11445 f.write_str(" PARTITION (")?;
11446 render_comma_separated(partition, ctx, f)?;
11447 f.write_str(")")?;
11448 }
11449 render_table_alias(alias.as_deref(), ctx, f)?;
11450 if let Some(indexed_by) = indexed_by {
11452 f.write_str(" ")?;
11453 indexed_by.render(ctx, f)?;
11454 }
11455 for hint in index_hints {
11457 f.write_str(" ")?;
11458 hint.render(ctx, f)?;
11459 }
11460 if let Some(sample) = sample {
11461 sample.render(ctx, f)?;
11462 }
11463 if !table_hints.is_empty() {
11466 f.write_str(" WITH (")?;
11467 render_comma_separated(table_hints, ctx, f)?;
11468 f.write_str(")")?;
11469 }
11470 Ok(())
11471 }
11472 TableFactor::Derived {
11473 lateral,
11474 subquery,
11475 alias,
11476 spelling,
11477 ..
11478 } => {
11479 if *lateral {
11480 f.write_str("LATERAL ")?;
11481 }
11482 match spelling {
11483 DerivedSpelling::Parenthesized => {
11484 f.write_str("(")?;
11485 subquery.render(ctx, f)?;
11486 f.write_str(")")?;
11487 }
11488 DerivedSpelling::BareValues => subquery.render(ctx, f)?,
11492 }
11493 render_table_alias(alias.as_deref(), ctx, f)
11494 }
11495 TableFactor::Function {
11496 lateral,
11497 function,
11498 with_ordinality,
11499 alias,
11500 column_defs,
11501 ..
11502 } => {
11503 if *lateral {
11504 f.write_str("LATERAL ")?;
11505 }
11506 function.render(ctx, f)?;
11507 if *with_ordinality {
11508 f.write_str(" WITH ORDINALITY")?;
11509 }
11510 render_function_alias(alias.as_deref(), column_defs, ctx, f)
11511 }
11512 TableFactor::RowsFrom {
11513 lateral,
11514 functions,
11515 with_ordinality,
11516 alias,
11517 ..
11518 } => {
11519 if *lateral {
11520 f.write_str("LATERAL ")?;
11521 }
11522 f.write_str("ROWS FROM (")?;
11523 render_comma_separated(functions, ctx, f)?;
11524 f.write_str(")")?;
11525 if *with_ordinality {
11526 f.write_str(" WITH ORDINALITY")?;
11527 }
11528 render_table_alias(alias.as_deref(), ctx, f)
11529 }
11530 TableFactor::Unnest {
11531 lateral,
11532 array_exprs,
11533 with_ordinality,
11534 alias,
11535 column_defs,
11536 with_offset,
11537 with_offset_alias,
11538 ..
11539 } => {
11540 if *lateral {
11541 f.write_str("LATERAL ")?;
11542 }
11543 f.write_str("UNNEST(")?;
11544 render_comma_separated(array_exprs, ctx, f)?;
11545 f.write_str(")")?;
11546 if *with_ordinality {
11550 f.write_str(" WITH ORDINALITY")?;
11551 }
11552 render_function_alias(alias.as_deref(), column_defs, ctx, f)?;
11553 if *with_offset {
11554 f.write_str(" WITH OFFSET")?;
11555 render_alias(with_offset_alias.as_ref(), AliasSpelling::As, ctx, f)?;
11558 }
11559 Ok(())
11560 }
11561 TableFactor::NestedJoin { table, alias, .. } => {
11562 f.write_str("(")?;
11563 table.render(ctx, f)?;
11564 f.write_str(")")?;
11565 render_table_alias(alias.as_deref(), ctx, f)
11566 }
11567 TableFactor::SpecialFunction {
11568 keyword,
11569 precision,
11570 alias,
11571 ..
11572 } => {
11573 f.write_str(special_function_keyword(*keyword))?;
11574 if let Some(precision) = precision {
11575 write!(f, "({precision})")?;
11576 }
11577 render_table_alias(alias.as_deref(), ctx, f)
11578 }
11579 TableFactor::Pivot { pivot, alias, .. } => {
11583 if matches!(pivot.spelling, PivotSpelling::Statement) {
11584 f.write_str("(")?;
11585 pivot.render(ctx, f)?;
11586 f.write_str(")")?;
11587 } else {
11588 pivot.render(ctx, f)?;
11589 }
11590 render_table_alias(alias.as_deref(), ctx, f)
11591 }
11592 TableFactor::Unpivot { unpivot, alias, .. } => {
11593 if matches!(unpivot.spelling, UnpivotSpelling::Statement) {
11594 f.write_str("(")?;
11595 unpivot.render(ctx, f)?;
11596 f.write_str(")")?;
11597 } else {
11598 unpivot.render(ctx, f)?;
11599 }
11600 render_table_alias(alias.as_deref(), ctx, f)
11601 }
11602 TableFactor::MatchRecognize {
11603 match_recognize,
11604 alias,
11605 ..
11606 } => {
11607 match_recognize.render(ctx, f)?;
11608 render_table_alias(alias.as_deref(), ctx, f)
11609 }
11610 TableFactor::ShowRef { show, alias, .. } => {
11615 f.write_str("(")?;
11616 show.render(ctx, f)?;
11617 f.write_str(")")?;
11618 render_table_alias(alias.as_deref(), ctx, f)
11619 }
11620 TableFactor::JsonTable {
11621 json_table, alias, ..
11622 } => {
11623 json_table.render(ctx, f)?;
11624 render_table_alias(alias.as_deref(), ctx, f)
11625 }
11626 TableFactor::XmlTable {
11627 xml_table, alias, ..
11628 } => {
11629 xml_table.render(ctx, f)?;
11630 render_table_alias(alias.as_deref(), ctx, f)
11631 }
11632 TableFactor::OpenJson {
11633 open_json, alias, ..
11634 } => {
11635 open_json.render(ctx, f)?;
11636 render_table_alias(alias.as_deref(), ctx, f)
11637 }
11638 TableFactor::TableExpr { expr, alias, .. } => {
11639 f.write_str("TABLE(")?;
11640 expr.render(ctx, f)?;
11641 f.write_str(")")?;
11642 render_table_alias(alias.as_deref(), ctx, f)
11643 }
11644 TableFactor::Other { ext, .. } => ext.render(ctx, f),
11645 }
11646 }
11647}
11648
11649impl<X: Extension + Render> Render for ShowRef<X> {
11650 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11651 f.write_str(match self.kind {
11652 ShowRefKind::Describe => "DESCRIBE",
11653 ShowRefKind::Desc => "DESC",
11654 ShowRefKind::Show => "SHOW",
11655 ShowRefKind::Summarize => "SUMMARIZE",
11656 })?;
11657 match &self.target {
11658 ShowRefTarget::Empty { .. } => Ok(()),
11659 ShowRefTarget::Query { query, .. } => {
11660 f.write_str(" ")?;
11661 query.render(ctx, f)
11662 }
11663 ShowRefTarget::Name { name, .. } => {
11664 f.write_str(" ")?;
11665 name.render(ctx, f)
11666 }
11667 }
11668 }
11669}
11670
11671impl<X: Extension + Render> Render for JsonTable<X> {
11672 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11673 if self.lateral {
11674 f.write_str("LATERAL ")?;
11675 }
11676 f.write_str("JSON_TABLE(")?;
11677 self.context.render(ctx, f)?;
11678 f.write_str(", ")?;
11679 self.path.render(ctx, f)?;
11680 if let Some(name) = &self.path_name {
11681 f.write_str(" AS ")?;
11682 name.render(ctx, f)?;
11683 }
11684 if !self.passing.is_empty() {
11685 f.write_str(" PASSING ")?;
11686 render_comma_separated(&self.passing, ctx, f)?;
11687 }
11688 f.write_str(" COLUMNS (")?;
11689 render_comma_separated(&self.columns, ctx, f)?;
11690 f.write_str(")")?;
11691 render_json_on_behavior(&self.on_error, "ERROR", ctx, f)?;
11692 f.write_str(")")
11693 }
11694}
11695
11696impl<X: Extension + Render> Render for JsonTableColumn<X> {
11697 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11698 match self {
11699 JsonTableColumn::ForOrdinality { name, .. } => {
11700 name.render(ctx, f)?;
11701 f.write_str(" FOR ORDINALITY")
11702 }
11703 JsonTableColumn::Regular {
11704 name,
11705 data_type,
11706 format,
11707 path,
11708 wrapper,
11709 quotes,
11710 on_empty,
11711 on_error,
11712 ..
11713 } => {
11714 name.render(ctx, f)?;
11715 f.write_str(" ")?;
11716 data_type.render(ctx, f)?;
11717 if let Some(format) = format {
11718 f.write_str(" ")?;
11719 format.render(ctx, f)?;
11720 }
11721 if let Some(path) = path {
11722 f.write_str(" PATH ")?;
11723 path.render(ctx, f)?;
11724 }
11725 render_json_wrapper(*wrapper, f)?;
11726 render_json_quotes(*quotes, f)?;
11727 render_json_on_behavior(on_empty, "EMPTY", ctx, f)?;
11728 render_json_on_behavior(on_error, "ERROR", ctx, f)
11729 }
11730 JsonTableColumn::Exists {
11731 name,
11732 data_type,
11733 path,
11734 on_error,
11735 ..
11736 } => {
11737 name.render(ctx, f)?;
11738 f.write_str(" ")?;
11739 data_type.render(ctx, f)?;
11740 f.write_str(" EXISTS")?;
11741 if let Some(path) = path {
11742 f.write_str(" PATH ")?;
11743 path.render(ctx, f)?;
11744 }
11745 render_json_on_behavior(on_error, "ERROR", ctx, f)
11746 }
11747 JsonTableColumn::Nested {
11748 path,
11749 path_name,
11750 columns,
11751 ..
11752 } => {
11753 f.write_str("NESTED PATH ")?;
11754 path.render(ctx, f)?;
11755 if let Some(name) = path_name {
11756 f.write_str(" AS ")?;
11757 name.render(ctx, f)?;
11758 }
11759 f.write_str(" COLUMNS (")?;
11760 render_comma_separated(columns, ctx, f)?;
11761 f.write_str(")")
11762 }
11763 }
11764 }
11765}
11766
11767fn render_c_expr_operand<X: Extension + Render>(
11774 expr: &Expr<X>,
11775 ctx: &RenderCtx<'_>,
11776 f: &mut fmt::Formatter<'_>,
11777) -> fmt::Result {
11778 let is_primary = matches!(
11779 expr,
11780 Expr::Column { .. }
11781 | Expr::Literal { .. }
11782 | Expr::Function { .. }
11783 | Expr::Parameter { .. }
11784 | Expr::PositionalColumn { .. }
11785 | Expr::SessionVariable { .. }
11786 | Expr::SpecialFunction { .. }
11787 );
11788 if is_primary {
11789 expr.render(ctx, f)
11790 } else {
11791 f.write_str("(")?;
11792 expr.render(ctx, f)?;
11793 f.write_str(")")
11794 }
11795}
11796
11797impl<X: Extension + Render> Render for XmlTable<X> {
11798 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11799 if self.lateral {
11800 f.write_str("LATERAL ")?;
11801 }
11802 f.write_str("XMLTABLE(")?;
11803 if !self.namespaces.is_empty() {
11804 f.write_str("XMLNAMESPACES(")?;
11805 render_comma_separated(&self.namespaces, ctx, f)?;
11806 f.write_str("), ")?;
11807 }
11808 render_c_expr_operand(&self.row_expr, ctx, f)?;
11809 f.write_str(" PASSING")?;
11810 render_xml_passing_mechanism(&self.passing_mechanism_before, f)?;
11811 f.write_str(" ")?;
11812 render_c_expr_operand(&self.document, ctx, f)?;
11813 render_xml_passing_mechanism(&self.passing_mechanism_after, f)?;
11814 f.write_str(" COLUMNS ")?;
11815 render_comma_separated(&self.columns, ctx, f)?;
11816 f.write_str(")")
11817 }
11818}
11819
11820impl<X: Extension + Render> Render for XmlNamespace<X> {
11821 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11822 match &self.name {
11823 Some(name) => {
11824 self.uri.render(ctx, f)?;
11825 f.write_str(" AS ")?;
11826 name.render(ctx, f)
11827 }
11828 None => {
11829 f.write_str("DEFAULT ")?;
11830 self.uri.render(ctx, f)
11831 }
11832 }
11833 }
11834}
11835
11836impl<X: Extension + Render> Render for XmlTableColumn<X> {
11837 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11838 match self {
11839 XmlTableColumn::ForOrdinality { name, .. } => {
11840 name.render(ctx, f)?;
11841 f.write_str(" FOR ORDINALITY")
11842 }
11843 XmlTableColumn::Regular {
11844 name,
11845 data_type,
11846 path,
11847 default,
11848 not_null,
11849 ..
11850 } => {
11851 name.render(ctx, f)?;
11852 f.write_str(" ")?;
11853 data_type.render(ctx, f)?;
11854 if let Some(path) = path {
11858 f.write_str(" PATH ")?;
11859 path.render(ctx, f)?;
11860 }
11861 if let Some(default) = default {
11862 f.write_str(" DEFAULT ")?;
11863 default.render(ctx, f)?;
11864 }
11865 match not_null {
11866 Some(true) => f.write_str(" NOT NULL"),
11867 Some(false) => f.write_str(" NULL"),
11868 None => Ok(()),
11869 }
11870 }
11871 }
11872 }
11873}
11874
11875impl<X: Extension + Render> Render for OpenJson<X> {
11876 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11877 f.write_str("OPENJSON(")?;
11878 self.json_expr.render(ctx, f)?;
11879 if let Some(path) = &self.path {
11880 f.write_str(", ")?;
11881 path.render(ctx, f)?;
11882 }
11883 f.write_str(")")?;
11884 if !self.columns.is_empty() {
11887 f.write_str(" WITH (")?;
11888 render_comma_separated(&self.columns, ctx, f)?;
11889 f.write_str(")")?;
11890 }
11891 Ok(())
11892 }
11893}
11894
11895impl<X: Extension + Render> Render for OpenJsonColumn<X> {
11896 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11897 self.name.render(ctx, f)?;
11898 f.write_str(" ")?;
11899 self.data_type.render(ctx, f)?;
11900 if let Some(path) = &self.path {
11901 f.write_str(" ")?;
11902 path.render(ctx, f)?;
11903 }
11904 if self.as_json {
11905 f.write_str(" AS JSON")?;
11906 }
11907 Ok(())
11908 }
11909}
11910
11911impl<X: Extension + Render> Render for Pivot<X> {
11912 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11913 match self.spelling {
11914 PivotSpelling::Statement => {
11918 if let Some(with) = &self.with {
11919 with.render(ctx, f)?;
11920 f.write_str(" ")?;
11921 }
11922 f.write_str("PIVOT ")?;
11923 self.source.render(ctx, f)?;
11924 if !self.pivot_on.is_empty() {
11925 f.write_str(" ON ")?;
11926 render_comma_separated(&self.pivot_on, ctx, f)?;
11927 }
11928 if !self.aggregates.is_empty() {
11929 f.write_str(" USING ")?;
11930 render_comma_separated(&self.aggregates, ctx, f)?;
11931 }
11932 if !self.group_by.is_empty() {
11933 f.write_str(" GROUP BY ")?;
11934 render_comma_separated(&self.group_by, ctx, f)?;
11935 }
11936 render_pivot_statement_tail(
11937 &self.order_by,
11938 self.order_by_all.as_deref(),
11939 self.limit.as_deref(),
11940 ctx,
11941 f,
11942 )
11943 }
11944 PivotSpelling::TableFactor => {
11948 self.source.render(ctx, f)?;
11949 f.write_str(" PIVOT (")?;
11950 render_comma_separated(&self.aggregates, ctx, f)?;
11951 for (index, column) in self.pivot_on.iter().enumerate() {
11954 f.write_str(if index == 0 { " FOR " } else { " " })?;
11955 column.render(ctx, f)?;
11956 }
11957 if !self.group_by.is_empty() {
11958 f.write_str(" GROUP BY ")?;
11959 render_comma_separated(&self.group_by, ctx, f)?;
11960 }
11961 if let Some(default) = &self.default_on_null {
11962 f.write_str(" DEFAULT ON NULL (")?;
11963 default.render(ctx, f)?;
11964 f.write_str(")")?;
11965 }
11966 f.write_str(")")
11967 }
11968 }
11969 }
11970}
11971
11972impl<X: Extension + Render> Render for Unpivot<X> {
11973 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
11974 match self.spelling {
11975 UnpivotSpelling::Statement => {
11978 if let Some(with) = &self.with {
11979 with.render(ctx, f)?;
11980 f.write_str(" ")?;
11981 }
11982 f.write_str("UNPIVOT ")?;
11983 self.source.render(ctx, f)?;
11984 f.write_str(" ON ")?;
11985 render_comma_separated(&self.columns, ctx, f)?;
11986 if !self.name.is_empty() || !self.value.is_empty() {
11987 f.write_str(" INTO NAME ")?;
11988 render_comma_separated(&self.name, ctx, f)?;
11989 f.write_str(" VALUE ")?;
11990 render_comma_separated(&self.value, ctx, f)?;
11991 }
11992 render_pivot_statement_tail(
11993 &self.order_by,
11994 self.order_by_all.as_deref(),
11995 self.limit.as_deref(),
11996 ctx,
11997 f,
11998 )
11999 }
12000 UnpivotSpelling::TableFactor => {
12002 self.source.render(ctx, f)?;
12003 f.write_str(" UNPIVOT ")?;
12004 match self.null_inclusion {
12007 Some(NullInclusion::IncludeNulls) => f.write_str("INCLUDE NULLS ")?,
12008 Some(NullInclusion::ExcludeNulls) => f.write_str("EXCLUDE NULLS ")?,
12009 None => {}
12010 }
12011 f.write_str("(")?;
12012 render_unpivot_name_list(&self.value, ctx, f)?;
12013 f.write_str(" FOR ")?;
12014 render_unpivot_name_list(&self.name, ctx, f)?;
12015 f.write_str(" IN (")?;
12016 render_comma_separated(&self.columns, ctx, f)?;
12017 f.write_str("))")
12018 }
12019 }
12020 }
12021}
12022
12023fn render_row_patterns(
12026 patterns: &[MatchRecognizePattern],
12027 separator: &str,
12028 ctx: &RenderCtx<'_>,
12029 f: &mut fmt::Formatter<'_>,
12030) -> fmt::Result {
12031 for (index, pattern) in patterns.iter().enumerate() {
12032 if index > 0 {
12033 f.write_str(separator)?;
12034 }
12035 pattern.render(ctx, f)?;
12036 }
12037 Ok(())
12038}
12039
12040impl<X: Extension + Render> Render for MatchRecognize<X> {
12041 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12042 self.source.render(ctx, f)?;
12047 f.write_str(" MATCH_RECOGNIZE (")?;
12048 let mut wrote = false;
12049 if !self.partition_by.is_empty() {
12050 f.write_str("PARTITION BY ")?;
12051 render_comma_separated(&self.partition_by, ctx, f)?;
12052 wrote = true;
12053 }
12054 if !self.order_by.is_empty() {
12055 if wrote {
12056 f.write_str(" ")?;
12057 }
12058 f.write_str("ORDER BY ")?;
12059 render_comma_separated(&self.order_by, ctx, f)?;
12060 wrote = true;
12061 }
12062 if !self.measures.is_empty() {
12063 if wrote {
12064 f.write_str(" ")?;
12065 }
12066 f.write_str("MEASURES ")?;
12067 render_comma_separated(&self.measures, ctx, f)?;
12068 wrote = true;
12069 }
12070 if let Some(rows_per_match) = &self.rows_per_match {
12071 if wrote {
12072 f.write_str(" ")?;
12073 }
12074 rows_per_match.render(ctx, f)?;
12075 wrote = true;
12076 }
12077 if let Some(after_match_skip) = &self.after_match_skip {
12078 if wrote {
12079 f.write_str(" ")?;
12080 }
12081 after_match_skip.render(ctx, f)?;
12082 wrote = true;
12083 }
12084 if wrote {
12085 f.write_str(" ")?;
12086 }
12087 f.write_str("PATTERN (")?;
12088 self.pattern.render(ctx, f)?;
12089 f.write_str(")")?;
12090 if !self.subsets.is_empty() {
12091 f.write_str(" SUBSET ")?;
12092 render_comma_separated(&self.subsets, ctx, f)?;
12093 }
12094 if !self.define.is_empty() {
12095 f.write_str(" DEFINE ")?;
12096 render_comma_separated(&self.define, ctx, f)?;
12097 }
12098 f.write_str(")")
12099 }
12100}
12101
12102impl<X: Extension + Render> Render for Measure<X> {
12103 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12104 self.expr.render(ctx, f)?;
12105 f.write_str(" AS ")?;
12106 self.alias.render(ctx, f)
12107 }
12108}
12109
12110impl Render for RowsPerMatch {
12111 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12112 match self {
12113 RowsPerMatch::OneRow => f.write_str("ONE ROW PER MATCH"),
12114 RowsPerMatch::AllRows(mode) => {
12115 f.write_str("ALL ROWS PER MATCH")?;
12116 if let Some(mode) = mode {
12117 f.write_str(" ")?;
12118 mode.render(ctx, f)?;
12119 }
12120 Ok(())
12121 }
12122 }
12123 }
12124}
12125
12126impl Render for EmptyMatchesMode {
12127 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12128 f.write_str(match self {
12129 EmptyMatchesMode::Show => "SHOW EMPTY MATCHES",
12130 EmptyMatchesMode::Omit => "OMIT EMPTY MATCHES",
12131 EmptyMatchesMode::WithUnmatched => "WITH UNMATCHED ROWS",
12132 })
12133 }
12134}
12135
12136impl Render for AfterMatchSkip {
12137 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12138 f.write_str("AFTER MATCH SKIP ")?;
12139 match self {
12140 AfterMatchSkip::PastLastRow { .. } => f.write_str("PAST LAST ROW"),
12141 AfterMatchSkip::ToNextRow { .. } => f.write_str("TO NEXT ROW"),
12142 AfterMatchSkip::ToFirst { symbol, .. } => {
12143 f.write_str("TO FIRST ")?;
12144 symbol.render(ctx, f)
12145 }
12146 AfterMatchSkip::ToLast { symbol, .. } => {
12147 f.write_str("TO LAST ")?;
12148 symbol.render(ctx, f)
12149 }
12150 }
12151 }
12152}
12153
12154impl Render for SubsetDefinition {
12155 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12156 self.name.render(ctx, f)?;
12157 f.write_str(" = (")?;
12158 render_comma_separated(&self.members, ctx, f)?;
12159 f.write_str(")")
12160 }
12161}
12162
12163impl<X: Extension + Render> Render for SymbolDefinition<X> {
12164 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12165 self.symbol.render(ctx, f)?;
12166 f.write_str(" AS ")?;
12167 self.definition.render(ctx, f)
12168 }
12169}
12170
12171impl Render for MatchRecognizePattern {
12172 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12173 match self {
12174 MatchRecognizePattern::Symbol { symbol, .. } => symbol.render(ctx, f),
12175 MatchRecognizePattern::Start { .. } => f.write_str("^"),
12176 MatchRecognizePattern::End { .. } => f.write_str("$"),
12177 MatchRecognizePattern::Concat { patterns, .. } => {
12178 render_row_patterns(patterns, " ", ctx, f)
12179 }
12180 MatchRecognizePattern::Alternation { patterns, .. } => {
12181 render_row_patterns(patterns, " | ", ctx, f)
12182 }
12183 MatchRecognizePattern::Group { pattern, .. } => {
12184 f.write_str("(")?;
12185 pattern.render(ctx, f)?;
12186 f.write_str(")")
12187 }
12188 MatchRecognizePattern::Exclude { pattern, .. } => {
12189 f.write_str("{- ")?;
12190 pattern.render(ctx, f)?;
12191 f.write_str(" -}")
12192 }
12193 MatchRecognizePattern::Permute { patterns, .. } => {
12194 f.write_str("PERMUTE(")?;
12195 render_row_patterns(patterns, ", ", ctx, f)?;
12196 f.write_str(")")
12197 }
12198 MatchRecognizePattern::Repetition {
12199 pattern,
12200 quantifier,
12201 ..
12202 } => {
12203 pattern.render(ctx, f)?;
12204 quantifier.render(ctx, f)
12205 }
12206 }
12207 }
12208}
12209
12210impl Render for RepetitionQuantifier {
12211 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12212 match self {
12213 RepetitionQuantifier::ZeroOrMore => f.write_str("*"),
12214 RepetitionQuantifier::OneOrMore => f.write_str("+"),
12215 RepetitionQuantifier::AtMostOne => f.write_str("?"),
12216 RepetitionQuantifier::Exactly(n) => write!(f, "{{{n}}}"),
12217 RepetitionQuantifier::AtLeast(n) => write!(f, "{{{n},}}"),
12218 RepetitionQuantifier::AtMost(m) => write!(f, "{{,{m}}}"),
12219 RepetitionQuantifier::Range(n, m) => write!(f, "{{{n},{m}}}"),
12220 }
12221 }
12222}
12223
12224impl<X: Extension + Render> Render for PivotExpr<X> {
12225 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12226 self.expr.render(ctx, f)?;
12227 render_alias(self.alias.as_ref(), self.alias_spelling, ctx, f)
12228 }
12229}
12230
12231impl<X: Extension + Render> Render for PivotValueSource<X> {
12232 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12233 match self {
12234 PivotValueSource::Any { order_by, .. } => {
12235 f.write_str("ANY")?;
12236 if !order_by.is_empty() {
12237 f.write_str(" ORDER BY ")?;
12238 render_comma_separated(order_by, ctx, f)?;
12239 }
12240 Ok(())
12241 }
12242 PivotValueSource::Subquery { query, .. } => query.render(ctx, f),
12243 }
12244 }
12245}
12246
12247impl<X: Extension + Render> Render for PivotColumn<X> {
12248 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12249 if let Some(enum_source) = &self.enum_source {
12250 self.expr.render(ctx, f)?;
12251 f.write_str(" IN ")?;
12252 return enum_source.render(ctx, f);
12253 }
12254 if let Some(value_source) = &self.value_source {
12257 render_predicate_operand(
12258 &self.expr,
12259 ctx.target().binding_powers.range_predicate(),
12260 Side::Left,
12261 ctx,
12262 f,
12263 )?;
12264 f.write_str(" IN (")?;
12265 value_source.render(ctx, f)?;
12266 return f.write_str(")");
12267 }
12268 if self.values.is_empty() {
12269 return self.expr.render(ctx, f);
12270 }
12271 render_predicate_operand(
12277 &self.expr,
12278 ctx.target().binding_powers.range_predicate(),
12279 Side::Left,
12280 ctx,
12281 f,
12282 )?;
12283 f.write_str(" IN (")?;
12284 render_comma_separated(&self.values, ctx, f)?;
12285 f.write_str(")")
12286 }
12287}
12288
12289impl<X: Extension + Render> Render for UnpivotColumn<X> {
12290 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12291 if self.columns.len() == 1 {
12293 self.columns[0].render(ctx, f)?;
12294 } else {
12295 f.write_str("(")?;
12296 render_comma_separated(&self.columns, ctx, f)?;
12297 f.write_str(")")?;
12298 }
12299 render_alias(self.alias.as_ref(), self.alias_spelling, ctx, f)
12300 }
12301}
12302
12303fn render_unpivot_name_list(
12306 names: &[Ident],
12307 ctx: &RenderCtx<'_>,
12308 f: &mut fmt::Formatter<'_>,
12309) -> fmt::Result {
12310 if names.len() == 1 {
12311 names[0].render(ctx, f)
12312 } else {
12313 f.write_str("(")?;
12314 render_comma_separated(names, ctx, f)?;
12315 f.write_str(")")
12316 }
12317}
12318
12319fn render_pivot_statement_tail<X: Extension + Render>(
12324 order_by: &[OrderByExpr<X>],
12325 order_by_all: Option<&OrderByAll>,
12326 limit: Option<&Limit<X>>,
12327 ctx: &RenderCtx<'_>,
12328 f: &mut fmt::Formatter<'_>,
12329) -> fmt::Result {
12330 if !order_by.is_empty() {
12331 f.write_str(" ORDER BY ")?;
12332 render_comma_separated(order_by, ctx, f)?;
12333 }
12334 if let Some(all) = order_by_all {
12335 f.write_str(" ORDER BY ")?;
12336 all.render(ctx, f)?;
12337 }
12338 if let Some(limit) = limit {
12339 f.write_str(" ")?;
12340 limit.render(ctx, f)?;
12341 }
12342 Ok(())
12343}
12344
12345impl<X: Extension + Render> Render for RowsFromItem<X> {
12346 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12347 self.function.render(ctx, f)?;
12348 if !self.column_defs.is_empty() {
12349 f.write_str(" AS (")?;
12350 render_comma_separated(&self.column_defs, ctx, f)?;
12351 f.write_str(")")?;
12352 }
12353 Ok(())
12354 }
12355}
12356
12357impl<X: Extension + Render> Render for TableFunctionColumn<X> {
12358 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12359 self.name.render(ctx, f)?;
12360 f.write_str(" ")?;
12361 self.data_type.render(ctx, f)
12362 }
12363}
12364
12365impl Render for TableAlias {
12366 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12367 self.name.render(ctx, f)?;
12368 if !self.columns.is_empty() {
12369 f.write_str("(")?;
12370 render_ident_list(&self.columns, ctx, f)?;
12371 f.write_str(")")?;
12372 }
12373 Ok(())
12374 }
12375}
12376
12377impl<X: Extension + Render> Render for TableSample<X> {
12378 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12379 f.write_str(" TABLESAMPLE ")?;
12380 self.method.render(ctx, f)?;
12381 f.write_str(" (")?;
12382 render_comma_separated(&self.args, ctx, f)?;
12383 f.write_str(")")?;
12384 if let Some(repeatable) = &self.repeatable {
12385 f.write_str(" REPEATABLE (")?;
12386 repeatable.render(ctx, f)?;
12387 f.write_str(")")?;
12388 }
12389 Ok(())
12390 }
12391}
12392
12393impl Render for SampleClause {
12394 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12395 if let Some(method) = &self.method {
12400 method.render(ctx, f)?;
12401 f.write_str("(")?;
12402 self.size.render(ctx, f)?;
12403 self.unit.render(ctx, f)?;
12404 f.write_str(")")?;
12405 if let Some(seed) = &self.seed {
12406 f.write_str(" REPEATABLE (")?;
12407 seed.render(ctx, f)?;
12408 f.write_str(")")?;
12409 }
12410 } else {
12411 self.size.render(ctx, f)?;
12412 self.unit.render(ctx, f)?;
12413 }
12414 Ok(())
12415 }
12416}
12417
12418impl Render for SampleUnit {
12419 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12420 f.write_str(match self {
12421 SampleUnit::Count => "",
12422 SampleUnit::Rows => " ROWS",
12423 SampleUnit::Percent => " PERCENT",
12424 SampleUnit::PercentSign => "%",
12425 })
12426 }
12427}
12428
12429fn honours_alias_spelling(ctx: &RenderCtx<'_>) -> bool {
12439 honours_source_spelling(ctx)
12440}
12441
12442fn honours_source_spelling(ctx: &RenderCtx<'_>) -> bool {
12453 ctx.spelling() == RenderSpelling::PreserveSource && ctx.mode() != RenderMode::Redacted
12454}
12455
12456fn alias_lead(spelling: AliasSpelling, ctx: &RenderCtx<'_>) -> &'static str {
12461 if !honours_alias_spelling(ctx) {
12462 return " AS ";
12463 }
12464 match spelling {
12465 AliasSpelling::Bare => " ",
12466 AliasSpelling::As | AliasSpelling::PrefixColon => " AS ",
12467 }
12468}
12469
12470fn render_table_alias(
12471 alias: Option<&TableAlias>,
12472 ctx: &RenderCtx<'_>,
12473 f: &mut fmt::Formatter<'_>,
12474) -> fmt::Result {
12475 if let Some(alias) = alias {
12476 f.write_str(alias_lead(alias.spelling, ctx))?;
12477 alias.render(ctx, f)?;
12478 }
12479 Ok(())
12480}
12481
12482fn render_function_alias<X: Extension + Render>(
12487 alias: Option<&TableAlias>,
12488 column_defs: &[TableFunctionColumn<X>],
12489 ctx: &RenderCtx<'_>,
12490 f: &mut fmt::Formatter<'_>,
12491) -> fmt::Result {
12492 if column_defs.is_empty() {
12493 return render_table_alias(alias, ctx, f);
12494 }
12495 f.write_str(alias.map_or(" AS ", |a| alias_lead(a.spelling, ctx)))?;
12499 if let Some(alias) = alias {
12500 alias.name.render(ctx, f)?;
12501 }
12502 f.write_str("(")?;
12503 render_comma_separated(column_defs, ctx, f)?;
12504 f.write_str(")")
12505}
12506
12507fn render_alias(
12508 alias: Option<&Ident>,
12509 spelling: AliasSpelling,
12510 ctx: &RenderCtx<'_>,
12511 f: &mut fmt::Formatter<'_>,
12512) -> fmt::Result {
12513 if let Some(alias) = alias {
12514 f.write_str(alias_lead(spelling, ctx))?;
12515 alias.render(ctx, f)?;
12516 }
12517 Ok(())
12518}
12519
12520fn render_relation_inheritance(
12524 inheritance: &RelationInheritance,
12525 name: &ObjectName,
12526 ctx: &RenderCtx<'_>,
12527 f: &mut fmt::Formatter<'_>,
12528) -> fmt::Result {
12529 match inheritance {
12530 RelationInheritance::Plain => name.render(ctx, f),
12531 RelationInheritance::Descendants => {
12532 name.render(ctx, f)?;
12533 f.write_str(" *")
12534 }
12535 RelationInheritance::Only(OnlySyntax::Bare) => {
12536 f.write_str("ONLY ")?;
12537 name.render(ctx, f)
12538 }
12539 RelationInheritance::Only(OnlySyntax::Parenthesized) => {
12540 f.write_str("ONLY (")?;
12541 name.render(ctx, f)?;
12542 f.write_str(")")
12543 }
12544 }
12545}
12546
12547fn render_ident_list(
12548 items: &[Ident],
12549 ctx: &RenderCtx<'_>,
12550 f: &mut fmt::Formatter<'_>,
12551) -> fmt::Result {
12552 render_comma_separated(items, ctx, f)
12553}
12554
12555fn render_comma_separated<T: Render>(
12557 items: &[T],
12558 ctx: &RenderCtx<'_>,
12559 f: &mut fmt::Formatter<'_>,
12560) -> fmt::Result {
12561 for (i, item) in items.iter().enumerate() {
12562 if i > 0 {
12563 f.write_str(", ")?;
12564 }
12565 item.render(ctx, f)?;
12566 }
12567 Ok(())
12568}
12569
12570fn render_leading_space_comma_separated<T: Render>(
12574 items: &[T],
12575 ctx: &RenderCtx<'_>,
12576 f: &mut fmt::Formatter<'_>,
12577) -> fmt::Result {
12578 if items.is_empty() {
12579 return Ok(());
12580 }
12581 f.write_str(" ")?;
12582 render_comma_separated(items, ctx, f)
12583}
12584
12585fn render_values_rows<T: Render>(
12590 rows: &[ThinVec<T>],
12591 explicit_row: bool,
12592 ctx: &RenderCtx<'_>,
12593 f: &mut fmt::Formatter<'_>,
12594) -> fmt::Result {
12595 let open = if explicit_row { "ROW(" } else { "(" };
12598 for (i, row) in rows.iter().enumerate() {
12599 if i > 0 {
12600 f.write_str(", ")?;
12601 }
12602 f.write_str(open)?;
12603 render_comma_separated(row, ctx, f)?;
12604 f.write_str(")")?;
12605 }
12606 Ok(())
12607}
12608
12609impl<X: Extension + Render> Render for Join<X> {
12610 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12611 self.operator.render(ctx, f)?;
12614 f.write_str(" ")?;
12615 self.relation.render(ctx, f)?;
12616 if let Some(constraint) = self.operator.constraint() {
12617 constraint.render(ctx, f)?;
12618 }
12619 Ok(())
12620 }
12621}
12622
12623impl<X: Extension> JoinOperator<X> {
12624 fn constraint(&self) -> Option<&JoinConstraint<X>> {
12626 match self {
12627 JoinOperator::Inner { constraint, .. }
12628 | JoinOperator::LeftOuter { constraint, .. }
12629 | JoinOperator::RightOuter { constraint, .. }
12630 | JoinOperator::FullOuter { constraint, .. }
12631 | JoinOperator::AsOf { constraint, .. }
12632 | JoinOperator::Semi { constraint, .. }
12633 | JoinOperator::Anti { constraint, .. } => Some(constraint),
12634 JoinOperator::Cross { .. }
12635 | JoinOperator::Positional { .. }
12636 | JoinOperator::Apply { .. } => None,
12637 }
12638 }
12639}
12640
12641impl<X: Extension + Render> Render for JoinOperator<X> {
12642 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12643 if matches!(self.constraint(), Some(JoinConstraint::Natural { .. })) {
12645 f.write_str("NATURAL ")?;
12646 }
12647 let fidelity = honours_source_spelling(ctx);
12651 f.write_str(match self {
12652 JoinOperator::Inner { straight: true, .. } => "STRAIGHT_JOIN",
12655 JoinOperator::Inner {
12656 straight: false,
12657 inner: true,
12658 ..
12659 } if fidelity => "INNER JOIN",
12660 JoinOperator::Inner {
12661 straight: false, ..
12662 } => "JOIN",
12663 JoinOperator::LeftOuter { outer: true, .. } if fidelity => "LEFT OUTER JOIN",
12664 JoinOperator::LeftOuter { .. } => "LEFT JOIN",
12665 JoinOperator::RightOuter { outer: true, .. } if fidelity => "RIGHT OUTER JOIN",
12666 JoinOperator::RightOuter { .. } => "RIGHT JOIN",
12667 JoinOperator::FullOuter { outer: true, .. } if fidelity => "FULL OUTER JOIN",
12668 JoinOperator::FullOuter { .. } => "FULL JOIN",
12669 JoinOperator::AsOf { kind, .. } => match kind {
12672 AsOfJoinKind::Inner => "ASOF JOIN",
12673 AsOfJoinKind::Left => "ASOF LEFT JOIN",
12674 AsOfJoinKind::Right => "ASOF RIGHT JOIN",
12675 AsOfJoinKind::Full => "ASOF FULL JOIN",
12676 },
12677 JoinOperator::Cross { .. } => "CROSS JOIN",
12678 JoinOperator::Positional { .. } => "POSITIONAL JOIN",
12679 JoinOperator::Semi { asof, side, .. } => match (side, asof) {
12685 (SemiAntiSide::Sideless, false) => "SEMI JOIN",
12686 (SemiAntiSide::Sideless, true) => "ASOF SEMI JOIN",
12687 (SemiAntiSide::Left, _) => "LEFT SEMI JOIN",
12688 (SemiAntiSide::Right, _) => "RIGHT SEMI JOIN",
12689 },
12690 JoinOperator::Anti { asof, side, .. } => match (side, asof) {
12691 (SemiAntiSide::Sideless, false) => "ANTI JOIN",
12692 (SemiAntiSide::Sideless, true) => "ASOF ANTI JOIN",
12693 (SemiAntiSide::Left, _) => "LEFT ANTI JOIN",
12694 (SemiAntiSide::Right, _) => "RIGHT ANTI JOIN",
12695 },
12696 JoinOperator::Apply { kind, .. } => match kind {
12699 ApplyKind::Cross => "CROSS APPLY",
12700 ApplyKind::Outer => "OUTER APPLY",
12701 },
12702 })
12703 }
12704}
12705
12706impl<X: Extension + Render> Render for JoinConstraint<X> {
12707 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12708 match self {
12709 JoinConstraint::On { expr, .. } => {
12710 f.write_str(" ON ")?;
12711 expr.render(ctx, f)
12712 }
12713 JoinConstraint::Using { columns, alias, .. } => {
12714 f.write_str(" USING (")?;
12715 render_comma_separated(columns, ctx, f)?;
12716 f.write_str(")")?;
12717 if let Some(alias) = alias {
12718 f.write_str(" AS ")?;
12719 alias.render(ctx, f)?;
12720 }
12721 Ok(())
12722 }
12723 JoinConstraint::Natural { .. } | JoinConstraint::None { .. } => Ok(()),
12725 }
12726 }
12727}
12728
12729impl<X: Extension + Render> Render for ExtractExpr<X> {
12734 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12735 f.write_str("EXTRACT(")?;
12736 self.field.render(ctx, f)?;
12737 f.write_str(" FROM ")?;
12738 self.source.render(ctx, f)?;
12739 f.write_str(")")
12740 }
12741}
12742
12743impl Render for NullTreatment {
12744 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12745 f.write_str(match self {
12746 NullTreatment::IgnoreNulls => "IGNORE NULLS",
12747 NullTreatment::RespectNulls => "RESPECT NULLS",
12748 })
12749 }
12750}
12751
12752impl Render for JsonEncoding {
12757 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12758 f.write_str(match self {
12759 JsonEncoding::Utf8 => "UTF8",
12760 JsonEncoding::Utf16 => "UTF16",
12761 JsonEncoding::Utf32 => "UTF32",
12762 })
12763 }
12764}
12765
12766impl Render for JsonFormat {
12767 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12769 f.write_str("FORMAT JSON")?;
12770 if let Some(encoding) = &self.encoding {
12771 f.write_str(" ENCODING ")?;
12772 encoding.render(ctx, f)?;
12773 }
12774 Ok(())
12775 }
12776}
12777
12778impl<X: Extension + Render> Render for JsonValueExpr<X> {
12779 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12780 self.expr.render(ctx, f)?;
12781 if let Some(format) = &self.format {
12782 f.write_str(" ")?;
12783 format.render(ctx, f)?;
12784 }
12785 Ok(())
12786 }
12787}
12788
12789impl<X: Extension + Render> Render for JsonReturning<X> {
12790 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12792 f.write_str("RETURNING ")?;
12793 self.data_type.render(ctx, f)?;
12794 if let Some(format) = &self.format {
12795 f.write_str(" ")?;
12796 format.render(ctx, f)?;
12797 }
12798 Ok(())
12799 }
12800}
12801
12802impl<X: Extension + Render> Render for JsonPassingArg<X> {
12803 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12804 self.value.render(ctx, f)?;
12805 f.write_str(" AS ")?;
12806 self.name.render(ctx, f)
12807 }
12808}
12809
12810impl<X: Extension + Render> Render for JsonBehavior<X> {
12811 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12813 match self.kind {
12814 JsonBehaviorKind::Error => f.write_str("ERROR"),
12815 JsonBehaviorKind::Null => f.write_str("NULL"),
12816 JsonBehaviorKind::True => f.write_str("TRUE"),
12817 JsonBehaviorKind::False => f.write_str("FALSE"),
12818 JsonBehaviorKind::Unknown => f.write_str("UNKNOWN"),
12819 JsonBehaviorKind::Empty => f.write_str("EMPTY"),
12820 JsonBehaviorKind::EmptyArray => f.write_str("EMPTY ARRAY"),
12821 JsonBehaviorKind::EmptyObject => f.write_str("EMPTY OBJECT"),
12822 JsonBehaviorKind::Default => {
12823 f.write_str("DEFAULT ")?;
12824 if let Some(expr) = &self.default_expr {
12827 expr.render(ctx, f)?;
12828 }
12829 Ok(())
12830 }
12831 }
12832 }
12833}
12834
12835fn render_json_on_behavior<X: Extension + Render>(
12837 behavior: &Option<JsonBehavior<X>>,
12838 slot: &str,
12839 ctx: &RenderCtx<'_>,
12840 f: &mut fmt::Formatter<'_>,
12841) -> fmt::Result {
12842 if let Some(behavior) = behavior {
12843 f.write_str(" ")?;
12844 behavior.render(ctx, f)?;
12845 f.write_str(" ON ")?;
12846 f.write_str(slot)?;
12847 }
12848 Ok(())
12849}
12850
12851fn render_json_wrapper(wrapper: JsonWrapperBehavior, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12853 match wrapper {
12854 JsonWrapperBehavior::Unspecified => Ok(()),
12855 JsonWrapperBehavior::Without => f.write_str(" WITHOUT WRAPPER"),
12856 JsonWrapperBehavior::Unconditional => f.write_str(" WITH WRAPPER"),
12857 JsonWrapperBehavior::Conditional => f.write_str(" WITH CONDITIONAL WRAPPER"),
12858 }
12859}
12860
12861fn render_json_quotes(quotes: JsonQuotesBehavior, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12863 match quotes {
12864 JsonQuotesBehavior::Unspecified => Ok(()),
12865 JsonQuotesBehavior::Keep => f.write_str(" KEEP QUOTES"),
12866 JsonQuotesBehavior::Omit => f.write_str(" OMIT QUOTES"),
12867 }
12868}
12869
12870fn render_json_null_clause(
12872 clause: &Option<JsonNullClause>,
12873 f: &mut fmt::Formatter<'_>,
12874) -> fmt::Result {
12875 match clause {
12876 Some(JsonNullClause::AbsentOnNull) => f.write_str(" ABSENT ON NULL"),
12877 Some(JsonNullClause::NullOnNull) => f.write_str(" NULL ON NULL"),
12878 None => Ok(()),
12879 }
12880}
12881
12882fn render_json_unique(unique_keys: Option<bool>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12884 match unique_keys {
12885 Some(true) => f.write_str(" WITH UNIQUE KEYS"),
12886 Some(false) => f.write_str(" WITHOUT UNIQUE KEYS"),
12887 None => Ok(()),
12888 }
12889}
12890
12891impl<X: Extension + Render> Render for JsonFuncExpr<X> {
12892 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12893 f.write_str(match self.kind {
12894 JsonFuncKind::Value => "JSON_VALUE(",
12895 JsonFuncKind::Query => "JSON_QUERY(",
12896 JsonFuncKind::Exists => "JSON_EXISTS(",
12897 })?;
12898 self.context.render(ctx, f)?;
12899 f.write_str(", ")?;
12900 self.path.render(ctx, f)?;
12901 if !self.passing.is_empty() {
12902 f.write_str(" PASSING ")?;
12903 render_comma_separated(&self.passing, ctx, f)?;
12904 }
12905 if let Some(returning) = &self.returning {
12906 f.write_str(" ")?;
12907 returning.render(ctx, f)?;
12908 }
12909 render_json_wrapper(self.wrapper, f)?;
12910 render_json_quotes(self.quotes, f)?;
12911 render_json_on_behavior(&self.on_empty, "EMPTY", ctx, f)?;
12912 render_json_on_behavior(&self.on_error, "ERROR", ctx, f)?;
12913 f.write_str(")")
12914 }
12915}
12916
12917impl<X: Extension + Render> Render for JsonKeyValue<X> {
12918 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12919 self.key.render(ctx, f)?;
12920 f.write_str(match self.spelling {
12921 JsonKeyValueSpelling::Colon => ": ",
12922 JsonKeyValueSpelling::Value => " VALUE ",
12923 })?;
12924 self.value.render(ctx, f)
12925 }
12926}
12927
12928impl<X: Extension + Render> Render for JsonObjectExpr<X> {
12929 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12930 f.write_str("JSON_OBJECT(")?;
12931 render_comma_separated(&self.entries, ctx, f)?;
12932 render_json_null_clause(&self.null_clause, f)?;
12933 render_json_unique(self.unique_keys, f)?;
12934 if let Some(returning) = &self.returning {
12935 if !self.entries.is_empty() || self.null_clause.is_some() || self.unique_keys.is_some()
12936 {
12937 f.write_str(" ")?;
12938 }
12939 returning.render(ctx, f)?;
12940 }
12941 f.write_str(")")
12942 }
12943}
12944
12945impl<X: Extension + Render> Render for JsonArrayExpr<X> {
12946 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12947 f.write_str("JSON_ARRAY(")?;
12948 let empty_body = match &self.body {
12949 JsonArrayBody::Values {
12950 items, null_clause, ..
12951 } => {
12952 render_comma_separated(items, ctx, f)?;
12953 render_json_null_clause(null_clause, f)?;
12954 items.is_empty() && null_clause.is_none()
12955 }
12956 JsonArrayBody::Query { query, format, .. } => {
12957 query.render(ctx, f)?;
12958 if let Some(format) = format {
12959 f.write_str(" ")?;
12960 format.render(ctx, f)?;
12961 }
12962 false
12963 }
12964 };
12965 if let Some(returning) = &self.returning {
12966 if !empty_body {
12967 f.write_str(" ")?;
12968 }
12969 returning.render(ctx, f)?;
12970 }
12971 f.write_str(")")
12972 }
12973}
12974
12975impl<X: Extension + Render> Render for JsonAggregateExpr<X> {
12976 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
12977 match &self.body {
12978 JsonAggregateBody::Object {
12979 entry, unique_keys, ..
12980 } => {
12981 f.write_str("JSON_OBJECTAGG(")?;
12982 entry.render(ctx, f)?;
12983 render_json_null_clause(&self.null_clause, f)?;
12984 render_json_unique(*unique_keys, f)?;
12985 }
12986 JsonAggregateBody::Array {
12987 value, order_by, ..
12988 } => {
12989 f.write_str("JSON_ARRAYAGG(")?;
12990 value.render(ctx, f)?;
12991 if !order_by.is_empty() {
12992 f.write_str(" ORDER BY ")?;
12993 render_comma_separated(order_by, ctx, f)?;
12994 }
12995 render_json_null_clause(&self.null_clause, f)?;
12996 }
12997 }
12998 if let Some(returning) = &self.returning {
12999 f.write_str(" ")?;
13000 returning.render(ctx, f)?;
13001 }
13002 f.write_str(")")?;
13003 if let Some(filter) = &self.filter {
13004 f.write_str(" FILTER (WHERE ")?;
13005 filter.render(ctx, f)?;
13006 f.write_str(")")?;
13007 }
13008 if let Some(over) = &self.over {
13009 f.write_str(" OVER ")?;
13010 over.render(ctx, f)?;
13011 }
13012 Ok(())
13013 }
13014}
13015
13016impl<X: Extension + Render> Render for JsonConstructorExpr<X> {
13017 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13018 f.write_str(match self.kind {
13019 JsonConstructorKind::Json => "JSON(",
13020 JsonConstructorKind::Scalar => "JSON_SCALAR(",
13021 JsonConstructorKind::Serialize => "JSON_SERIALIZE(",
13022 })?;
13023 self.value.render(ctx, f)?;
13024 render_json_unique(self.unique_keys, f)?;
13025 if let Some(returning) = &self.returning {
13026 f.write_str(" ")?;
13027 returning.render(ctx, f)?;
13028 }
13029 f.write_str(")")
13030 }
13031}
13032
13033impl<X: Extension + Render> Render for IsJsonExpr<X> {
13034 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13035 let full = ctx.mode() == RenderMode::Parenthesized;
13036 open_group(full, f)?;
13037 render_predicate_operand(
13038 &self.expr,
13039 ctx.target().binding_powers.predicate(),
13040 Side::Left,
13041 ctx,
13042 f,
13043 )?;
13044 f.write_str(if self.negated {
13045 " IS NOT JSON"
13046 } else {
13047 " IS JSON"
13048 })?;
13049 f.write_str(match self.item_type {
13050 JsonItemType::Any => "",
13051 JsonItemType::Value => " VALUE",
13052 JsonItemType::Array => " ARRAY",
13053 JsonItemType::Object => " OBJECT",
13054 JsonItemType::Scalar => " SCALAR",
13055 })?;
13056 if self.unique_keys {
13057 f.write_str(" WITH UNIQUE KEYS")?;
13058 }
13059 close_group(full, f)
13060 }
13061}
13062
13063impl Render for XmlDocumentOrContent {
13068 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13069 f.write_str(match self {
13070 XmlDocumentOrContent::Document => "DOCUMENT",
13071 XmlDocumentOrContent::Content => "CONTENT",
13072 })
13073 }
13074}
13075
13076impl<X: Extension + Render> Render for XmlAttribute<X> {
13077 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13079 self.value.render(ctx, f)?;
13080 if let Some(name) = &self.name {
13081 f.write_str(" AS ")?;
13082 name.render(ctx, f)?;
13083 }
13084 Ok(())
13085 }
13086}
13087
13088fn render_xml_passing_mechanism(
13090 mechanism: &Option<XmlPassingMechanism>,
13091 f: &mut fmt::Formatter<'_>,
13092) -> fmt::Result {
13093 match mechanism {
13094 Some(XmlPassingMechanism::ByRef) => f.write_str(" BY REF"),
13095 Some(XmlPassingMechanism::ByValue) => f.write_str(" BY VALUE"),
13096 None => Ok(()),
13097 }
13098}
13099
13100impl<X: Extension + Render> Render for XmlFunc<X> {
13101 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13102 match self {
13103 XmlFunc::Element {
13104 name,
13105 attributes,
13106 content,
13107 ..
13108 } => {
13109 f.write_str("xmlelement(NAME ")?;
13110 name.render(ctx, f)?;
13111 if !attributes.is_empty() {
13112 f.write_str(", xmlattributes(")?;
13113 render_comma_separated(attributes, ctx, f)?;
13114 f.write_str(")")?;
13115 }
13116 if !content.is_empty() {
13117 f.write_str(", ")?;
13118 render_comma_separated(content, ctx, f)?;
13119 }
13120 f.write_str(")")
13121 }
13122 XmlFunc::Forest { elements, .. } => {
13123 f.write_str("xmlforest(")?;
13124 render_comma_separated(elements, ctx, f)?;
13125 f.write_str(")")
13126 }
13127 XmlFunc::Concat { args, .. } => {
13128 f.write_str("xmlconcat(")?;
13129 render_comma_separated(args, ctx, f)?;
13130 f.write_str(")")
13131 }
13132 XmlFunc::Parse {
13133 option,
13134 arg,
13135 whitespace,
13136 ..
13137 } => {
13138 f.write_str("xmlparse(")?;
13139 option.render(ctx, f)?;
13140 f.write_str(" ")?;
13141 arg.render(ctx, f)?;
13142 match whitespace {
13143 XmlWhitespaceOption::Unspecified => {}
13144 XmlWhitespaceOption::Preserve => f.write_str(" PRESERVE WHITESPACE")?,
13145 XmlWhitespaceOption::Strip => f.write_str(" STRIP WHITESPACE")?,
13146 }
13147 f.write_str(")")
13148 }
13149 XmlFunc::Pi { name, content, .. } => {
13150 f.write_str("xmlpi(NAME ")?;
13151 name.render(ctx, f)?;
13152 if let Some(content) = content {
13153 f.write_str(", ")?;
13154 content.render(ctx, f)?;
13155 }
13156 f.write_str(")")
13157 }
13158 XmlFunc::Root {
13159 arg,
13160 version,
13161 standalone,
13162 ..
13163 } => {
13164 f.write_str("xmlroot(")?;
13165 arg.render(ctx, f)?;
13166 f.write_str(", VERSION ")?;
13167 match version {
13168 Some(expr) => expr.render(ctx, f)?,
13169 None => f.write_str("NO VALUE")?,
13170 }
13171 match standalone {
13172 XmlStandalone::Unspecified => {}
13173 XmlStandalone::Yes => f.write_str(", STANDALONE YES")?,
13174 XmlStandalone::No => f.write_str(", STANDALONE NO")?,
13175 XmlStandalone::NoValue => f.write_str(", STANDALONE NO VALUE")?,
13176 }
13177 f.write_str(")")
13178 }
13179 XmlFunc::Serialize {
13180 option,
13181 arg,
13182 data_type,
13183 indent,
13184 ..
13185 } => {
13186 f.write_str("xmlserialize(")?;
13187 option.render(ctx, f)?;
13188 f.write_str(" ")?;
13189 arg.render(ctx, f)?;
13190 f.write_str(" AS ")?;
13191 data_type.render(ctx, f)?;
13192 match indent {
13193 XmlIndentOption::Unspecified => {}
13194 XmlIndentOption::Indent => f.write_str(" INDENT")?,
13195 XmlIndentOption::NoIndent => f.write_str(" NO INDENT")?,
13196 }
13197 f.write_str(")")
13198 }
13199 XmlFunc::Exists {
13200 path,
13201 mechanism_before,
13202 arg,
13203 mechanism_after,
13204 ..
13205 } => {
13206 f.write_str("xmlexists(")?;
13207 path.render(ctx, f)?;
13208 f.write_str(" PASSING")?;
13209 render_xml_passing_mechanism(mechanism_before, f)?;
13210 f.write_str(" ")?;
13211 arg.render(ctx, f)?;
13212 render_xml_passing_mechanism(mechanism_after, f)?;
13213 f.write_str(")")
13214 }
13215 }
13216 }
13217}
13218
13219impl<X: Extension + Render> Render for StringFunc<X> {
13220 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13221 match self {
13222 StringFunc::Substring {
13226 expr, start, count, ..
13227 } => {
13228 f.write_str("SUBSTRING(")?;
13229 expr.render(ctx, f)?;
13230 if let Some(start) = start {
13231 f.write_str(" FROM ")?;
13232 start.render(ctx, f)?;
13233 }
13234 if let Some(count) = count {
13235 f.write_str(" FOR ")?;
13236 count.render(ctx, f)?;
13237 }
13238 f.write_str(")")
13239 }
13240 StringFunc::SubstringSimilar {
13241 expr,
13242 pattern,
13243 escape,
13244 ..
13245 } => {
13246 f.write_str("SUBSTRING(")?;
13247 expr.render(ctx, f)?;
13248 f.write_str(" SIMILAR ")?;
13249 pattern.render(ctx, f)?;
13250 f.write_str(" ESCAPE ")?;
13251 escape.render(ctx, f)?;
13252 f.write_str(")")
13253 }
13254 StringFunc::Position { substr, string, .. } => {
13255 f.write_str("POSITION(")?;
13256 substr.render(ctx, f)?;
13257 f.write_str(" IN ")?;
13258 string.render(ctx, f)?;
13259 f.write_str(")")
13260 }
13261 StringFunc::Overlay {
13262 target,
13263 replacement,
13264 start,
13265 count,
13266 ..
13267 } => {
13268 f.write_str("OVERLAY(")?;
13269 target.render(ctx, f)?;
13270 f.write_str(" PLACING ")?;
13271 replacement.render(ctx, f)?;
13272 f.write_str(" FROM ")?;
13273 start.render(ctx, f)?;
13274 if let Some(count) = count {
13275 f.write_str(" FOR ")?;
13276 count.render(ctx, f)?;
13277 }
13278 f.write_str(")")
13279 }
13280 StringFunc::Trim {
13281 side,
13282 trim_chars,
13283 from,
13284 sources,
13285 ..
13286 } => {
13287 f.write_str("TRIM(")?;
13288 if let Some(side) = side {
13289 side.render(ctx, f)?;
13290 f.write_str(" ")?;
13291 }
13292 if let Some(trim_chars) = trim_chars {
13293 trim_chars.render(ctx, f)?;
13294 f.write_str(" ")?;
13295 }
13296 if *from {
13297 f.write_str("FROM ")?;
13298 }
13299 render_comma_separated(sources, ctx, f)?;
13300 f.write_str(")")
13301 }
13302 StringFunc::CollationFor { expr, .. } => {
13303 f.write_str("COLLATION FOR (")?;
13304 expr.render(ctx, f)?;
13305 f.write_str(")")
13306 }
13307 StringFunc::ConvertUsing { expr, charset, .. } => {
13308 f.write_str("CONVERT(")?;
13309 expr.render(ctx, f)?;
13310 f.write_str(" USING ")?;
13311 charset.render(ctx, f)?;
13312 f.write_str(")")
13313 }
13314 StringFunc::MatchAgainst {
13315 columns,
13316 against,
13317 modifier,
13318 ..
13319 } => {
13320 f.write_str("MATCH(")?;
13321 render_comma_separated(columns, ctx, f)?;
13322 f.write_str(") AGAINST(")?;
13323 against.render(ctx, f)?;
13324 if let Some(modifier) = modifier {
13325 f.write_str(" ")?;
13326 modifier.render(ctx, f)?;
13327 }
13328 f.write_str(")")
13329 }
13330 StringFunc::CeilTo {
13331 expr,
13332 field,
13333 spelling,
13334 ..
13335 } => {
13336 f.write_str(match spelling {
13337 CeilSpelling::Ceil => "CEIL(",
13338 CeilSpelling::Ceiling => "CEILING(",
13339 })?;
13340 expr.render(ctx, f)?;
13341 f.write_str(" TO ")?;
13342 field.render(ctx, f)?;
13343 f.write_str(")")
13344 }
13345 StringFunc::FloorTo { expr, field, .. } => {
13346 f.write_str("FLOOR(")?;
13347 expr.render(ctx, f)?;
13348 f.write_str(" TO ")?;
13349 field.render(ctx, f)?;
13350 f.write_str(")")
13351 }
13352 }
13353 }
13354}
13355
13356impl Render for MatchSearchModifier {
13357 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13358 f.write_str(match self {
13359 MatchSearchModifier::NaturalLanguage => "IN NATURAL LANGUAGE MODE",
13360 MatchSearchModifier::NaturalLanguageQueryExpansion => {
13361 "IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION"
13362 }
13363 MatchSearchModifier::Boolean => "IN BOOLEAN MODE",
13364 MatchSearchModifier::QueryExpansion => "WITH QUERY EXPANSION",
13365 })
13366 }
13367}
13368
13369impl Render for TrimSide {
13370 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13371 f.write_str(match self {
13372 TrimSide::Both => "BOTH",
13373 TrimSide::Leading => "LEADING",
13374 TrimSide::Trailing => "TRAILING",
13375 })
13376 }
13377}
13378
13379impl<X: Extension + Render> Render for CaseExpr<X> {
13380 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13381 f.write_str("CASE")?;
13382 if let Some(operand) = &self.operand {
13383 f.write_str(" ")?;
13384 operand.render(ctx, f)?;
13385 }
13386 for clause in &self.when_clauses {
13387 f.write_str(" WHEN ")?;
13388 clause.condition.render(ctx, f)?;
13389 f.write_str(" THEN ")?;
13390 clause.result.render(ctx, f)?;
13391 }
13392 if let Some(else_result) = &self.else_result {
13393 f.write_str(" ELSE ")?;
13394 else_result.render(ctx, f)?;
13395 }
13396 f.write_str(" END")
13397 }
13398}
13399
13400impl<X: Extension + Render> Render for FunctionCall<X> {
13401 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13402 self.name.render(ctx, f)?;
13403 f.write_str("(")?;
13404 if let Some(quantifier) = &self.quantifier {
13405 quantifier.render(ctx, f)?;
13406 f.write_str(" ")?;
13407 }
13408 if self.wildcard {
13409 f.write_str("*")?;
13410 } else {
13411 render_comma_separated(&self.args, ctx, f)?;
13412 }
13413 if !self.order_by.is_empty() {
13414 if self.wildcard || !self.args.is_empty() {
13419 f.write_str(" ")?;
13420 }
13421 f.write_str("ORDER BY ")?;
13422 render_comma_separated(&self.order_by, ctx, f)?;
13423 }
13424 if let Some(separator) = &self.separator {
13427 f.write_str(" SEPARATOR ")?;
13428 separator.render(ctx, f)?;
13429 }
13430 if let Some(null_treatment) = &self.null_treatment {
13434 f.write_str(" ")?;
13435 null_treatment.render(ctx, f)?;
13436 }
13437 f.write_str(")")?;
13438 if let Some(tail) = &self.window_tail {
13442 if let Some(from_first_last) = tail.from_first_last {
13443 f.write_str(match from_first_last {
13444 FromFirstLast::First => " FROM FIRST",
13445 FromFirstLast::Last => " FROM LAST",
13446 })?;
13447 }
13448 if let Some(null_treatment) = &tail.null_treatment {
13449 f.write_str(" ")?;
13450 null_treatment.render(ctx, f)?;
13451 }
13452 }
13453 if let Some(within_group) = &self.within_group {
13456 f.write_str(" WITHIN GROUP (ORDER BY ")?;
13457 render_comma_separated(within_group, ctx, f)?;
13458 f.write_str(")")?;
13459 }
13460 if let Some(filter) = &self.filter {
13461 match self.filter_where {
13464 FilterWhereSpelling::Where => f.write_str(" FILTER (WHERE ")?,
13465 FilterWhereSpelling::Omitted => f.write_str(" FILTER (")?,
13466 }
13467 filter.render(ctx, f)?;
13468 f.write_str(")")?;
13469 }
13470 if let Some(over) = &self.over {
13471 f.write_str(" OVER ")?;
13472 over.render(ctx, f)?;
13473 }
13474 Ok(())
13475 }
13476}
13477
13478impl<X: Extension + Render> Render for FunctionArg<X> {
13479 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13480 if self.variadic {
13484 f.write_str("VARIADIC ")?;
13485 }
13486 if let Some(name) = self.name {
13490 if ctx.mode() == RenderMode::Redacted {
13491 f.write_str("id")?;
13492 } else {
13493 f.write_str(ctx.resolve(name))?;
13494 }
13495 f.write_str(match self.syntax {
13496 ArgSyntax::ColonEquals => " := ",
13497 ArgSyntax::Arrow | ArgSyntax::Positional => " => ",
13500 })?;
13501 }
13502 self.value.render(ctx, f)
13503 }
13504}
13505
13506impl<X: Extension + Render> Render for StructField<X> {
13507 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13508 if ctx.mode() == RenderMode::Redacted {
13513 f.write_str("id")?;
13514 } else {
13515 let text = ctx.resolve(self.key);
13516 match self.key_spelling {
13517 StructKeySpelling::Bare => f.write_str(text)?,
13518 StructKeySpelling::SingleQuoted => {
13519 if text.contains('\'') {
13520 write!(f, "'{}'", text.replace('\'', "''"))?;
13521 } else {
13522 write!(f, "'{text}'")?;
13523 }
13524 }
13525 StructKeySpelling::DoubleQuoted => {
13526 if text.contains('"') {
13527 write!(f, "\"{}\"", text.replace('"', "\"\""))?;
13528 } else {
13529 write!(f, "\"{text}\"")?;
13530 }
13531 }
13532 }
13533 }
13534 f.write_str(": ")?;
13535 self.value.render(ctx, f)
13536 }
13537}
13538
13539impl<X: Extension + Render> Render for StructConstructorField<X> {
13540 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13541 if let Some(name) = &self.name {
13542 name.render(ctx, f)?;
13543 f.write_str(" ")?;
13544 }
13545 self.ty.render(ctx, f)
13546 }
13547}
13548
13549impl<X: Extension + Render> Render for StructConstructorArg<X> {
13550 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13551 self.value.render(ctx, f)?;
13552 if let Some(alias) = &self.alias {
13553 f.write_str(" AS ")?;
13554 alias.render(ctx, f)?;
13555 }
13556 Ok(())
13557 }
13558}
13559
13560impl<X: Extension + Render> Render for WindowSpec<X> {
13561 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13562 match self {
13563 WindowSpec::Named { name, .. } => name.render(ctx, f),
13564 WindowSpec::Inline { definition, .. } => {
13565 f.write_str("(")?;
13566 definition.render(ctx, f)?;
13567 f.write_str(")")
13568 }
13569 }
13570 }
13571}
13572
13573impl<X: Extension + Render> Render for WindowDefinition<X> {
13574 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13575 let mut wrote = false;
13576 if let Some(existing) = &self.existing {
13577 existing.render(ctx, f)?;
13578 wrote = true;
13579 }
13580 if !self.partition_by.is_empty() {
13581 if wrote {
13582 f.write_str(" ")?;
13583 }
13584 f.write_str("PARTITION BY ")?;
13585 render_comma_separated(&self.partition_by, ctx, f)?;
13586 wrote = true;
13587 }
13588 if !self.order_by.is_empty() {
13589 if wrote {
13590 f.write_str(" ")?;
13591 }
13592 f.write_str("ORDER BY ")?;
13593 render_comma_separated(&self.order_by, ctx, f)?;
13594 wrote = true;
13595 }
13596 if let Some(frame) = &self.frame {
13597 if wrote {
13598 f.write_str(" ")?;
13599 }
13600 frame.render(ctx, f)?;
13601 }
13602 Ok(())
13603 }
13604}
13605
13606impl<X: Extension + Render> Render for WindowFrame<X> {
13607 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13608 self.units.render(ctx, f)?;
13609 f.write_str(" ")?;
13610 if let Some(end) = &self.end {
13611 f.write_str("BETWEEN ")?;
13612 self.start.render(ctx, f)?;
13613 f.write_str(" AND ")?;
13614 end.render(ctx, f)?;
13615 } else {
13616 self.start.render(ctx, f)?;
13617 }
13618 if let Some(exclusion) = &self.exclusion {
13619 f.write_str(" EXCLUDE ")?;
13620 exclusion.render(ctx, f)?;
13621 }
13622 Ok(())
13623 }
13624}
13625
13626impl Render for WindowFrameUnits {
13627 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13628 f.write_str(match self {
13629 WindowFrameUnits::Rows => "ROWS",
13630 WindowFrameUnits::Range => "RANGE",
13631 WindowFrameUnits::Groups => "GROUPS",
13632 })
13633 }
13634}
13635
13636impl<X: Extension + Render> Render for WindowFrameBound<X> {
13637 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13638 match self {
13639 WindowFrameBound::CurrentRow { .. } => f.write_str("CURRENT ROW"),
13640 WindowFrameBound::UnboundedPreceding { .. } => f.write_str("UNBOUNDED PRECEDING"),
13641 WindowFrameBound::UnboundedFollowing { .. } => f.write_str("UNBOUNDED FOLLOWING"),
13642 WindowFrameBound::Preceding { offset, .. } => {
13643 offset.render(ctx, f)?;
13644 f.write_str(" PRECEDING")
13645 }
13646 WindowFrameBound::Following { offset, .. } => {
13647 offset.render(ctx, f)?;
13648 f.write_str(" FOLLOWING")
13649 }
13650 }
13651 }
13652}
13653
13654impl Render for WindowFrameExclusion {
13655 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13656 f.write_str(match self {
13657 WindowFrameExclusion::CurrentRow => "CURRENT ROW",
13658 WindowFrameExclusion::Group => "GROUP",
13659 WindowFrameExclusion::Ties => "TIES",
13660 WindowFrameExclusion::NoOthers => "NO OTHERS",
13661 })
13662 }
13663}
13664
13665impl<X: Extension + Render> Render for NamedWindow<X> {
13666 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13667 self.name.render(ctx, f)?;
13668 f.write_str(" AS (")?;
13669 self.definition.render(ctx, f)?;
13670 f.write_str(")")
13671 }
13672}
13673
13674impl<X: Extension + Render> Render for OrderByExpr<X> {
13675 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13676 self.expr.render(ctx, f)?;
13677 if let Some(using) = &self.using {
13681 f.write_str(" USING ")?;
13682 using.render(ctx, f)?;
13683 }
13684 render_sort_direction(self.asc, self.nulls_first, f)
13685 }
13686}
13687
13688impl Render for OrderByUsing {
13689 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13690 let Some(schema) = &self.schema else {
13695 return f.write_str(ctx.resolve(self.op));
13696 };
13697 f.write_str("OPERATOR(")?;
13698 for part in &schema.0 {
13699 part.render(ctx, f)?;
13700 f.write_str(".")?;
13701 }
13702 f.write_str(ctx.resolve(self.op))?;
13703 f.write_str(")")
13704 }
13705}
13706
13707impl Render for OrderByAll {
13708 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13709 f.write_str("ALL")?;
13710 render_sort_direction(self.asc, self.nulls_first, f)
13711 }
13712}
13713
13714impl<X: Extension + Render> Render for Limit<X> {
13715 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13716 match self.syntax {
13717 LimitSyntax::CommaOffset if honours_source_spelling(ctx) => {
13721 f.write_str("LIMIT ")?;
13722 if let Some(offset) = &self.offset {
13723 offset.render(ctx, f)?;
13724 }
13725 f.write_str(", ")?;
13726 if let Some(limit) = &self.limit {
13727 limit.render(ctx, f)?;
13728 }
13729 Ok(())
13730 }
13731 LimitSyntax::LimitOffset | LimitSyntax::CommaOffset => {
13732 let mut wrote = false;
13733 if let Some(limit) = &self.limit {
13734 f.write_str("LIMIT ")?;
13735 match self.percent {
13746 Some(marker) => {
13747 render_pg_operand(
13748 limit,
13749 ctx.target().binding_powers.multiplicative,
13750 Side::Right,
13751 ctx,
13752 f,
13753 )?;
13754 f.write_str(match marker {
13755 LimitPercent::Symbol => "%",
13756 LimitPercent::Keyword => " PERCENT",
13757 })?;
13758 }
13759 None => limit.render(ctx, f)?,
13760 }
13761 wrote = true;
13762 }
13763 if let Some(offset) = &self.offset {
13764 if wrote {
13765 f.write_str(" ")?;
13766 }
13767 f.write_str("OFFSET ")?;
13768 offset.render(ctx, f)?;
13769 }
13770 Ok(())
13771 }
13772 LimitSyntax::FetchFirst => {
13773 let fidelity = honours_source_spelling(ctx);
13779 let mut wrote = false;
13780 if let Some(offset) = &self.offset {
13781 f.write_str("OFFSET ")?;
13782 offset.render(ctx, f)?;
13783 f.write_str(" ROWS")?;
13784 wrote = true;
13785 }
13786 if let Some(with_ties) = self.with_ties {
13791 if wrote {
13792 f.write_str(" ")?;
13793 }
13794 let spelling = if fidelity {
13795 self.fetch_spelling
13796 } else {
13797 FetchSpelling::FirstRows
13798 };
13799 f.write_str(spelling.fetch_keyword())?;
13800 if let Some(limit) = &self.limit {
13801 f.write_str(" ")?;
13802 limit.render(ctx, f)?;
13803 }
13804 f.write_str(spelling.row_word())?;
13805 f.write_str(if with_ties { "WITH TIES" } else { "ONLY" })?;
13806 }
13807 Ok(())
13808 }
13809 }
13810 }
13811}
13812
13813impl<X: Extension + Render> Render for LimitBy<X> {
13814 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13815 f.write_str("LIMIT ")?;
13816 self.limit.render(ctx, f)?;
13817 if let Some(offset) = &self.offset {
13818 f.write_str(" OFFSET ")?;
13819 offset.render(ctx, f)?;
13820 }
13821 f.write_str(" BY ")?;
13822 render_comma_separated(&self.by, ctx, f)
13823 }
13824}
13825
13826impl<X: Extension + Render> Render for Setting<X> {
13827 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13828 self.name.render(ctx, f)?;
13829 f.write_str(" = ")?;
13830 self.value.render(ctx, f)
13831 }
13832}
13833
13834impl Render for FormatClause {
13835 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13836 f.write_str("FORMAT ")?;
13837 self.name.render(ctx, f)
13838 }
13839}
13840
13841impl Render for ForClause {
13842 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13846 match self {
13847 ForClause::Xml {
13848 mode,
13849 elements,
13850 binary_base64,
13851 typed,
13852 root,
13853 ..
13854 } => {
13855 f.write_str("FOR XML ")?;
13856 mode.render(ctx, f)?;
13857 if *binary_base64 {
13858 f.write_str(", BINARY BASE64")?;
13859 }
13860 if *typed {
13861 f.write_str(", TYPE")?;
13862 }
13863 if let Some(root) = root {
13864 f.write_str(", ")?;
13865 root.render(ctx, f)?;
13866 }
13867 if let Some(elements) = elements {
13868 f.write_str(", ")?;
13869 elements.render(ctx, f)?;
13870 }
13871 Ok(())
13872 }
13873 ForClause::Json {
13874 mode,
13875 root,
13876 include_null_values,
13877 without_array_wrapper,
13878 ..
13879 } => {
13880 f.write_str("FOR JSON ")?;
13881 mode.render(ctx, f)?;
13882 if let Some(root) = root {
13883 f.write_str(", ")?;
13884 root.render(ctx, f)?;
13885 }
13886 if *include_null_values {
13887 f.write_str(", INCLUDE_NULL_VALUES")?;
13888 }
13889 if *without_array_wrapper {
13890 f.write_str(", WITHOUT_ARRAY_WRAPPER")?;
13891 }
13892 Ok(())
13893 }
13894 }
13895 }
13896}
13897
13898impl Render for ForXmlMode {
13899 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13900 match self {
13901 ForXmlMode::Raw { name, .. } => {
13902 f.write_str("RAW")?;
13903 render_optional_for_name(name.as_ref(), ctx, f)
13904 }
13905 ForXmlMode::Auto { .. } => f.write_str("AUTO"),
13906 ForXmlMode::Explicit { .. } => f.write_str("EXPLICIT"),
13907 ForXmlMode::Path { name, .. } => {
13908 f.write_str("PATH")?;
13909 render_optional_for_name(name.as_ref(), ctx, f)
13910 }
13911 }
13912 }
13913}
13914
13915impl Render for ForXmlElements {
13916 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13917 f.write_str(match self {
13918 ForXmlElements::Plain => "ELEMENTS",
13919 ForXmlElements::XsiNil => "ELEMENTS XSINIL",
13920 ForXmlElements::Absent => "ELEMENTS ABSENT",
13921 })
13922 }
13923}
13924
13925impl Render for ForJsonMode {
13926 fn render(&self, _ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13927 f.write_str(match self {
13928 ForJsonMode::Auto => "AUTO",
13929 ForJsonMode::Path => "PATH",
13930 })
13931 }
13932}
13933
13934impl Render for ForRoot {
13935 fn render(&self, ctx: &RenderCtx<'_>, f: &mut fmt::Formatter<'_>) -> fmt::Result {
13936 f.write_str("ROOT")?;
13937 render_optional_for_name(self.name.as_ref(), ctx, f)
13938 }
13939}
13940
13941fn render_optional_for_name(
13944 name: Option<&Literal>,
13945 ctx: &RenderCtx<'_>,
13946 f: &mut fmt::Formatter<'_>,
13947) -> fmt::Result {
13948 if let Some(name) = name {
13949 f.write_str("(")?;
13950 name.render(ctx, f)?;
13951 f.write_str(")")?;
13952 }
13953 Ok(())
13954}