github.com/seashell-org/golang-migrate/v4@v4.15.3-0.20220722221203-6ab6c6c062d1/database/spanner/spansql/sql.go (about)

     1  /*
     2  Copyright 2019 Google LLC
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package spansql
    18  
    19  // This file holds SQL methods for rendering the types in types.go
    20  // as the SQL dialect that this package parses.
    21  //
    22  // Every exported type has an SQL method that returns a string.
    23  // Some also have an addSQL method that efficiently builds that string
    24  // in a provided strings.Builder.
    25  
    26  import (
    27  	"fmt"
    28  	"sort"
    29  	"strconv"
    30  	"strings"
    31  	"time"
    32  )
    33  
    34  func buildSQL(x interface{ addSQL(*strings.Builder) }) string {
    35  	var sb strings.Builder
    36  	x.addSQL(&sb)
    37  	return sb.String()
    38  }
    39  
    40  func (ct CreateTable) SQL() string {
    41  	str := "CREATE TABLE " + ct.Name.SQL() + " (\n"
    42  	for _, c := range ct.Columns {
    43  		str += "  " + c.SQL() + ",\n"
    44  	}
    45  	for _, tc := range ct.Constraints {
    46  		str += "  " + tc.SQL() + ",\n"
    47  	}
    48  	str += ") PRIMARY KEY("
    49  	for i, c := range ct.PrimaryKey {
    50  		if i > 0 {
    51  			str += ", "
    52  		}
    53  		str += c.SQL()
    54  	}
    55  	str += ")"
    56  	if il := ct.Interleave; il != nil {
    57  		str += ",\n  INTERLEAVE IN PARENT " + il.Parent.SQL() + " ON DELETE " + il.OnDelete.SQL()
    58  	}
    59  	if rdp := ct.RowDeletionPolicy; rdp != nil {
    60  		str += ",\n  " + rdp.SQL()
    61  	}
    62  	return str
    63  }
    64  
    65  func (ci CreateIndex) SQL() string {
    66  	str := "CREATE"
    67  	if ci.Unique {
    68  		str += " UNIQUE"
    69  	}
    70  	if ci.NullFiltered {
    71  		str += " NULL_FILTERED"
    72  	}
    73  	str += " INDEX " + ci.Name.SQL() + " ON " + ci.Table.SQL() + "("
    74  	for i, c := range ci.Columns {
    75  		if i > 0 {
    76  			str += ", "
    77  		}
    78  		str += c.SQL()
    79  	}
    80  	str += ")"
    81  	if len(ci.Storing) > 0 {
    82  		str += " STORING (" + idList(ci.Storing, ", ") + ")"
    83  	}
    84  	if ci.Interleave != "" {
    85  		str += ", INTERLEAVE IN " + ci.Interleave.SQL()
    86  	}
    87  	return str
    88  }
    89  
    90  func (cv CreateView) SQL() string {
    91  	str := "CREATE"
    92  	if cv.OrReplace {
    93  		str += " OR REPLACE"
    94  	}
    95  	str += " VIEW " + cv.Name.SQL() + " SQL SECURITY INVOKER AS " + cv.Query.SQL()
    96  	return str
    97  }
    98  
    99  func (dt DropTable) SQL() string {
   100  	return "DROP TABLE " + dt.Name.SQL()
   101  }
   102  
   103  func (di DropIndex) SQL() string {
   104  	return "DROP INDEX " + di.Name.SQL()
   105  }
   106  
   107  func (dv DropView) SQL() string {
   108  	return "DROP VIEW " + dv.Name.SQL()
   109  }
   110  
   111  func (at AlterTable) SQL() string {
   112  	return "ALTER TABLE " + at.Name.SQL() + " " + at.Alteration.SQL()
   113  }
   114  
   115  func (ac AddColumn) SQL() string {
   116  	return "ADD COLUMN " + ac.Def.SQL()
   117  }
   118  
   119  func (dc DropColumn) SQL() string {
   120  	return "DROP COLUMN " + dc.Name.SQL()
   121  }
   122  
   123  func (ac AddConstraint) SQL() string {
   124  	return "ADD " + ac.Constraint.SQL()
   125  }
   126  
   127  func (dc DropConstraint) SQL() string {
   128  	return "DROP CONSTRAINT " + dc.Name.SQL()
   129  }
   130  
   131  func (sod SetOnDelete) SQL() string {
   132  	return "SET ON DELETE " + sod.Action.SQL()
   133  }
   134  
   135  func (od OnDelete) SQL() string {
   136  	switch od {
   137  	case NoActionOnDelete:
   138  		return "NO ACTION"
   139  	case CascadeOnDelete:
   140  		return "CASCADE"
   141  	}
   142  	panic("unknown OnDelete")
   143  }
   144  
   145  func (ac AlterColumn) SQL() string {
   146  	return "ALTER COLUMN " + ac.Name.SQL() + " " + ac.Alteration.SQL()
   147  }
   148  
   149  func (ardp AddRowDeletionPolicy) SQL() string {
   150  	return "ADD " + ardp.RowDeletionPolicy.SQL()
   151  }
   152  
   153  func (rrdp ReplaceRowDeletionPolicy) SQL() string {
   154  	return "REPLACE " + rrdp.RowDeletionPolicy.SQL()
   155  }
   156  
   157  func (drdp DropRowDeletionPolicy) SQL() string {
   158  	return "DROP ROW DELETION POLICY"
   159  }
   160  
   161  func (sct SetColumnType) SQL() string {
   162  	str := sct.Type.SQL()
   163  	if sct.NotNull {
   164  		str += " NOT NULL"
   165  	}
   166  	if sct.Default != nil {
   167  		str += " DEFAULT (" + sct.Default.SQL() + ")"
   168  	}
   169  	return str
   170  }
   171  
   172  func (sco SetColumnOptions) SQL() string {
   173  	// TODO: not clear what to do for no options.
   174  	return "SET " + sco.Options.SQL()
   175  }
   176  
   177  func (sd SetDefault) SQL() string {
   178  	return "SET DEFAULT (" + sd.Default.SQL() + ")"
   179  }
   180  
   181  func (dp DropDefault) SQL() string {
   182  	return "DROP DEFAULT"
   183  }
   184  
   185  func (co ColumnOptions) SQL() string {
   186  	str := "OPTIONS ("
   187  	if co.AllowCommitTimestamp != nil {
   188  		if *co.AllowCommitTimestamp {
   189  			str += "allow_commit_timestamp = true"
   190  		} else {
   191  			str += "allow_commit_timestamp = null"
   192  		}
   193  	}
   194  	str += ")"
   195  	return str
   196  }
   197  
   198  func (ad AlterDatabase) SQL() string {
   199  	return "ALTER DATABASE " + ad.Name.SQL() + " " + ad.Alteration.SQL()
   200  }
   201  
   202  func (sdo SetDatabaseOptions) SQL() string {
   203  	return "SET " + sdo.Options.SQL()
   204  }
   205  
   206  func (do DatabaseOptions) SQL() string {
   207  	str := "OPTIONS ("
   208  	hasOpt := false
   209  	if do.OptimizerVersion != nil {
   210  		hasOpt = true
   211  		if *do.OptimizerVersion == 0 {
   212  			str += "optimizer_version=null"
   213  		} else {
   214  			str += fmt.Sprintf("optimizer_version=%v", *do.OptimizerVersion)
   215  		}
   216  	}
   217  	if do.VersionRetentionPeriod != nil {
   218  		if hasOpt {
   219  			str += ", "
   220  		}
   221  		hasOpt = true
   222  		if *do.VersionRetentionPeriod == "" {
   223  			str += "version_retention_period=null"
   224  		} else {
   225  			str += fmt.Sprintf("version_retention_period='%s'", *do.VersionRetentionPeriod)
   226  		}
   227  	}
   228  	if do.EnableKeyVisualizer != nil {
   229  		if hasOpt {
   230  			str += ", "
   231  		}
   232  		hasOpt = true
   233  		if *do.EnableKeyVisualizer {
   234  			str += "enable_key_visualizer=true"
   235  		} else {
   236  			str += "enable_key_visualizer=null"
   237  		}
   238  	}
   239  	str += ")"
   240  	return str
   241  }
   242  
   243  func (d *Delete) SQL() string {
   244  	return "DELETE FROM " + d.Table.SQL() + " WHERE " + d.Where.SQL()
   245  }
   246  
   247  func (u *Update) SQL() string {
   248  	str := "UPDATE " + u.Table.SQL() + " SET "
   249  	for i, item := range u.Items {
   250  		if i > 0 {
   251  			str += ", "
   252  		}
   253  		str += item.Column.SQL() + " = "
   254  		if item.Value != nil {
   255  			str += item.Value.SQL()
   256  		} else {
   257  			str += "DEFAULT"
   258  		}
   259  	}
   260  	str += " WHERE " + u.Where.SQL()
   261  	return str
   262  }
   263  
   264  func (i *Insert) SQL() string {
   265  	str := "INSERT INTO " + i.Table.SQL() + " ("
   266  	for i, column := range i.Columns {
   267  		if i > 0 {
   268  			str += ", "
   269  		}
   270  		str += column.SQL()
   271  	}
   272  	str += ") "
   273  	str += i.Input.SQL()
   274  	return str
   275  }
   276  
   277  func (v Values) SQL() string {
   278  	str := "VALUES "
   279  	for j, values := range v {
   280  		if j > 0 {
   281  			str += ", "
   282  		}
   283  		str += "("
   284  
   285  		for k, value := range values {
   286  			if k > 0 {
   287  				str += ", "
   288  			}
   289  			str += value.SQL()
   290  		}
   291  		str += ")"
   292  	}
   293  	return str
   294  }
   295  
   296  func (cd ColumnDef) SQL() string {
   297  	str := cd.Name.SQL() + " " + cd.Type.SQL()
   298  	if cd.NotNull {
   299  		str += " NOT NULL"
   300  	}
   301  	if cd.Default != nil {
   302  		str += " DEFAULT (" + cd.Default.SQL() + ")"
   303  	}
   304  	if cd.Generated != nil {
   305  		str += " AS (" + cd.Generated.SQL() + ") STORED"
   306  	}
   307  	if cd.Options != (ColumnOptions{}) {
   308  		str += " " + cd.Options.SQL()
   309  	}
   310  	return str
   311  }
   312  
   313  func (tc TableConstraint) SQL() string {
   314  	var str string
   315  	if tc.Name != "" {
   316  		str += "CONSTRAINT " + tc.Name.SQL() + " "
   317  	}
   318  	str += tc.Constraint.SQL()
   319  	return str
   320  }
   321  
   322  func (rdp RowDeletionPolicy) SQL() string {
   323  	return "ROW DELETION POLICY ( OLDER_THAN ( " + rdp.Column.SQL() + ", INTERVAL " + strconv.FormatInt(rdp.NumDays, 10) + " DAY ))"
   324  }
   325  
   326  func (fk ForeignKey) SQL() string {
   327  	str := "FOREIGN KEY (" + idList(fk.Columns, ", ")
   328  	str += ") REFERENCES " + fk.RefTable.SQL() + " ("
   329  	str += idList(fk.RefColumns, ", ") + ")"
   330  	return str
   331  }
   332  
   333  func (c Check) SQL() string {
   334  	return "CHECK (" + c.Expr.SQL() + ")"
   335  }
   336  
   337  func (t Type) SQL() string {
   338  	str := t.Base.SQL()
   339  	if t.Len > 0 && (t.Base == String || t.Base == Bytes) {
   340  		str += "("
   341  		if t.Len == MaxLen {
   342  			str += "MAX"
   343  		} else {
   344  			str += strconv.FormatInt(t.Len, 10)
   345  		}
   346  		str += ")"
   347  	}
   348  	if t.Array {
   349  		str = "ARRAY<" + str + ">"
   350  	}
   351  	return str
   352  }
   353  
   354  func (tb TypeBase) SQL() string {
   355  	switch tb {
   356  	case Bool:
   357  		return "BOOL"
   358  	case Int64:
   359  		return "INT64"
   360  	case Float64:
   361  		return "FLOAT64"
   362  	case Numeric:
   363  		return "NUMERIC"
   364  	case String:
   365  		return "STRING"
   366  	case Bytes:
   367  		return "BYTES"
   368  	case Date:
   369  		return "DATE"
   370  	case Timestamp:
   371  		return "TIMESTAMP"
   372  	case JSON:
   373  		return "JSON"
   374  	}
   375  	panic("unknown TypeBase")
   376  }
   377  
   378  func (kp KeyPart) SQL() string {
   379  	str := kp.Column.SQL()
   380  	if kp.Desc {
   381  		str += " DESC"
   382  	}
   383  	return str
   384  }
   385  
   386  func (q Query) SQL() string { return buildSQL(q) }
   387  func (q Query) addSQL(sb *strings.Builder) {
   388  	q.Select.addSQL(sb)
   389  	if len(q.Order) > 0 {
   390  		sb.WriteString(" ORDER BY ")
   391  		for i, o := range q.Order {
   392  			if i > 0 {
   393  				sb.WriteString(", ")
   394  			}
   395  			o.addSQL(sb)
   396  		}
   397  	}
   398  	if q.Limit != nil {
   399  		sb.WriteString(" LIMIT ")
   400  		sb.WriteString(q.Limit.SQL())
   401  		if q.Offset != nil {
   402  			sb.WriteString(" OFFSET ")
   403  			sb.WriteString(q.Offset.SQL())
   404  		}
   405  	}
   406  }
   407  
   408  func (sel Select) SQL() string { return buildSQL(sel) }
   409  func (sel Select) addSQL(sb *strings.Builder) {
   410  	sb.WriteString("SELECT ")
   411  	if sel.Distinct {
   412  		sb.WriteString("DISTINCT ")
   413  	}
   414  	for i, e := range sel.List {
   415  		if i > 0 {
   416  			sb.WriteString(", ")
   417  		}
   418  		e.addSQL(sb)
   419  		if len(sel.ListAliases) > 0 {
   420  			alias := sel.ListAliases[i]
   421  			if alias != "" {
   422  				sb.WriteString(" AS ")
   423  				sb.WriteString(alias.SQL())
   424  			}
   425  		}
   426  	}
   427  	if len(sel.From) > 0 {
   428  		sb.WriteString(" FROM ")
   429  		for i, f := range sel.From {
   430  			if i > 0 {
   431  				sb.WriteString(", ")
   432  			}
   433  			sb.WriteString(f.SQL())
   434  		}
   435  	}
   436  	if sel.Where != nil {
   437  		sb.WriteString(" WHERE ")
   438  		sel.Where.addSQL(sb)
   439  	}
   440  	if len(sel.GroupBy) > 0 {
   441  		sb.WriteString(" GROUP BY ")
   442  		addExprList(sb, sel.GroupBy, ", ")
   443  	}
   444  }
   445  
   446  func (sft SelectFromTable) SQL() string {
   447  	str := sft.Table.SQL()
   448  	if len(sft.Hints) > 0 {
   449  		str += "@{"
   450  		kvs := make([]string, len(sft.Hints))
   451  		i := 0
   452  		for k, v := range sft.Hints {
   453  			kvs[i] = fmt.Sprintf("%s=%s", k, v)
   454  			i++
   455  		}
   456  		sort.Strings(kvs)
   457  		str += strings.Join(kvs, ",")
   458  		str += "}"
   459  	}
   460  
   461  	if sft.Alias != "" {
   462  		str += " AS " + sft.Alias.SQL()
   463  	}
   464  	return str
   465  }
   466  
   467  func (sfj SelectFromJoin) SQL() string {
   468  	// TODO: The grammar permits arbitrary nesting. Does this need to add parens?
   469  	str := sfj.LHS.SQL() + " " + joinTypes[sfj.Type] + " JOIN "
   470  	// TODO: hints go here
   471  	str += sfj.RHS.SQL()
   472  	if sfj.On != nil {
   473  		str += " ON " + sfj.On.SQL()
   474  	} else if len(sfj.Using) > 0 {
   475  		str += " USING (" + idList(sfj.Using, ", ") + ")"
   476  	}
   477  	return str
   478  }
   479  
   480  var joinTypes = map[JoinType]string{
   481  	InnerJoin: "INNER",
   482  	CrossJoin: "CROSS",
   483  	FullJoin:  "FULL",
   484  	LeftJoin:  "LEFT",
   485  	RightJoin: "RIGHT",
   486  }
   487  
   488  func (sfu SelectFromUnnest) SQL() string {
   489  	str := "UNNEST(" + sfu.Expr.SQL() + ")"
   490  	if sfu.Alias != "" {
   491  		str += " AS " + sfu.Alias.SQL()
   492  	}
   493  	return str
   494  }
   495  
   496  func (o Order) SQL() string { return buildSQL(o) }
   497  func (o Order) addSQL(sb *strings.Builder) {
   498  	o.Expr.addSQL(sb)
   499  	if o.Desc {
   500  		sb.WriteString(" DESC")
   501  	}
   502  }
   503  
   504  var arithOps = map[ArithOperator]string{
   505  	// Binary operators only; unary operators are handled first.
   506  	Mul:    "*",
   507  	Div:    "/",
   508  	Concat: "||",
   509  	Add:    "+",
   510  	Sub:    "-",
   511  	BitShl: "<<",
   512  	BitShr: ">>",
   513  	BitAnd: "&",
   514  	BitXor: "^",
   515  	BitOr:  "|",
   516  }
   517  
   518  func (ao ArithOp) SQL() string { return buildSQL(ao) }
   519  func (ao ArithOp) addSQL(sb *strings.Builder) {
   520  	// Extra parens inserted to ensure the correct precedence.
   521  
   522  	switch ao.Op {
   523  	case Neg:
   524  		sb.WriteString("-(")
   525  		ao.RHS.addSQL(sb)
   526  		sb.WriteString(")")
   527  		return
   528  	case Plus:
   529  		sb.WriteString("+(")
   530  		ao.RHS.addSQL(sb)
   531  		sb.WriteString(")")
   532  		return
   533  	case BitNot:
   534  		sb.WriteString("~(")
   535  		ao.RHS.addSQL(sb)
   536  		sb.WriteString(")")
   537  		return
   538  	}
   539  	op, ok := arithOps[ao.Op]
   540  	if !ok {
   541  		panic("unknown ArithOp")
   542  	}
   543  	sb.WriteString("(")
   544  	ao.LHS.addSQL(sb)
   545  	sb.WriteString(")")
   546  	sb.WriteString(op)
   547  	sb.WriteString("(")
   548  	ao.RHS.addSQL(sb)
   549  	sb.WriteString(")")
   550  }
   551  
   552  func (lo LogicalOp) SQL() string { return buildSQL(lo) }
   553  func (lo LogicalOp) addSQL(sb *strings.Builder) {
   554  	switch lo.Op {
   555  	default:
   556  		panic("unknown LogicalOp")
   557  	case And:
   558  		lo.LHS.addSQL(sb)
   559  		sb.WriteString(" AND ")
   560  	case Or:
   561  		lo.LHS.addSQL(sb)
   562  		sb.WriteString(" OR ")
   563  	case Not:
   564  		sb.WriteString("NOT ")
   565  	}
   566  	lo.RHS.addSQL(sb)
   567  }
   568  
   569  var compOps = map[ComparisonOperator]string{
   570  	Lt:         "<",
   571  	Le:         "<=",
   572  	Gt:         ">",
   573  	Ge:         ">=",
   574  	Eq:         "=",
   575  	Ne:         "!=",
   576  	Like:       "LIKE",
   577  	NotLike:    "NOT LIKE",
   578  	Between:    "BETWEEN",
   579  	NotBetween: "NOT BETWEEN",
   580  }
   581  
   582  func (co ComparisonOp) SQL() string { return buildSQL(co) }
   583  func (co ComparisonOp) addSQL(sb *strings.Builder) {
   584  	op, ok := compOps[co.Op]
   585  	if !ok {
   586  		panic("unknown ComparisonOp")
   587  	}
   588  	co.LHS.addSQL(sb)
   589  	sb.WriteString(" ")
   590  	sb.WriteString(op)
   591  	sb.WriteString(" ")
   592  	co.RHS.addSQL(sb)
   593  	if co.Op == Between || co.Op == NotBetween {
   594  		sb.WriteString(" AND ")
   595  		co.RHS2.addSQL(sb)
   596  	}
   597  }
   598  
   599  func (io InOp) SQL() string { return buildSQL(io) }
   600  func (io InOp) addSQL(sb *strings.Builder) {
   601  	io.LHS.addSQL(sb)
   602  	if io.Neg {
   603  		sb.WriteString(" NOT")
   604  	}
   605  	sb.WriteString(" IN ")
   606  	if io.Unnest {
   607  		sb.WriteString("UNNEST")
   608  	}
   609  	sb.WriteString("(")
   610  	addExprList(sb, io.RHS, ", ")
   611  	sb.WriteString(")")
   612  }
   613  
   614  func (io IsOp) SQL() string { return buildSQL(io) }
   615  func (io IsOp) addSQL(sb *strings.Builder) {
   616  	io.LHS.addSQL(sb)
   617  	sb.WriteString(" IS ")
   618  	if io.Neg {
   619  		sb.WriteString("NOT ")
   620  	}
   621  	io.RHS.addSQL(sb)
   622  }
   623  
   624  func (f Func) SQL() string { return buildSQL(f) }
   625  func (f Func) addSQL(sb *strings.Builder) {
   626  	sb.WriteString(f.Name)
   627  	sb.WriteString("(")
   628  	addExprList(sb, f.Args, ", ")
   629  	sb.WriteString(")")
   630  }
   631  
   632  func (te TypedExpr) SQL() string { return buildSQL(te) }
   633  func (te TypedExpr) addSQL(sb *strings.Builder) {
   634  	te.Expr.addSQL(sb)
   635  	sb.WriteString(" AS ")
   636  	sb.WriteString(te.Type.SQL())
   637  }
   638  
   639  func (ee ExtractExpr) SQL() string { return buildSQL(ee) }
   640  func (ee ExtractExpr) addSQL(sb *strings.Builder) {
   641  	sb.WriteString(ee.Part)
   642  	sb.WriteString(" FROM ")
   643  	ee.Expr.addSQL(sb)
   644  }
   645  
   646  func (aze AtTimeZoneExpr) SQL() string { return buildSQL(aze) }
   647  func (aze AtTimeZoneExpr) addSQL(sb *strings.Builder) {
   648  	aze.Expr.addSQL(sb)
   649  	sb.WriteString(" AT TIME ZONE ")
   650  	sb.WriteString(aze.Zone)
   651  }
   652  
   653  func idList(l []ID, join string) string {
   654  	var ss []string
   655  	for _, s := range l {
   656  		ss = append(ss, s.SQL())
   657  	}
   658  	return strings.Join(ss, join)
   659  }
   660  
   661  func addExprList(sb *strings.Builder, l []Expr, join string) {
   662  	for i, s := range l {
   663  		if i > 0 {
   664  			sb.WriteString(join)
   665  		}
   666  		s.addSQL(sb)
   667  	}
   668  }
   669  
   670  func addIDList(sb *strings.Builder, l []ID, join string) {
   671  	for i, s := range l {
   672  		if i > 0 {
   673  			sb.WriteString(join)
   674  		}
   675  		s.addSQL(sb)
   676  	}
   677  }
   678  
   679  func (pe PathExp) SQL() string { return buildSQL(pe) }
   680  func (pe PathExp) addSQL(sb *strings.Builder) {
   681  	addIDList(sb, []ID(pe), ".")
   682  }
   683  
   684  func (p Paren) SQL() string { return buildSQL(p) }
   685  func (p Paren) addSQL(sb *strings.Builder) {
   686  	sb.WriteString("(")
   687  	p.Expr.addSQL(sb)
   688  	sb.WriteString(")")
   689  }
   690  
   691  func (a Array) SQL() string { return buildSQL(a) }
   692  func (a Array) addSQL(sb *strings.Builder) {
   693  	sb.WriteString("[")
   694  	addExprList(sb, []Expr(a), ", ")
   695  	sb.WriteString("]")
   696  }
   697  
   698  func (id ID) SQL() string { return buildSQL(id) }
   699  func (id ID) addSQL(sb *strings.Builder) {
   700  	// https://cloud.google.com/spanner/docs/lexical#identifiers
   701  
   702  	// TODO: If there are non-letters/numbers/underscores then this also needs quoting.
   703  
   704  	if IsKeyword(string(id)) {
   705  		// TODO: Escaping may be needed here.
   706  		sb.WriteString("`")
   707  		sb.WriteString(string(id))
   708  		sb.WriteString("`")
   709  		return
   710  	}
   711  
   712  	sb.WriteString(string(id))
   713  }
   714  
   715  func (p Param) SQL() string { return buildSQL(p) }
   716  func (p Param) addSQL(sb *strings.Builder) {
   717  	sb.WriteString("@")
   718  	sb.WriteString(string(p))
   719  }
   720  
   721  func (c Case) SQL() string { return buildSQL(c) }
   722  func (c Case) addSQL(sb *strings.Builder) {
   723  	sb.WriteString("CASE ")
   724  	if c.Expr != nil {
   725  		fmt.Fprintf(sb, "%s ", c.Expr.SQL())
   726  	}
   727  	for _, w := range c.WhenClauses {
   728  		fmt.Fprintf(sb, "WHEN %s THEN %s ", w.Cond.SQL(), w.Result.SQL())
   729  	}
   730  	if c.ElseResult != nil {
   731  		fmt.Fprintf(sb, "ELSE %s ", c.ElseResult.SQL())
   732  	}
   733  	sb.WriteString("END")
   734  }
   735  
   736  func (b BoolLiteral) SQL() string { return buildSQL(b) }
   737  func (b BoolLiteral) addSQL(sb *strings.Builder) {
   738  	if b {
   739  		sb.WriteString("TRUE")
   740  	} else {
   741  		sb.WriteString("FALSE")
   742  	}
   743  }
   744  
   745  func (NullLiteral) SQL() string                { return buildSQL(NullLiteral(0)) }
   746  func (NullLiteral) addSQL(sb *strings.Builder) { sb.WriteString("NULL") }
   747  
   748  func (StarExpr) SQL() string                { return buildSQL(StarExpr(0)) }
   749  func (StarExpr) addSQL(sb *strings.Builder) { sb.WriteString("*") }
   750  
   751  func (il IntegerLiteral) SQL() string                { return buildSQL(il) }
   752  func (il IntegerLiteral) addSQL(sb *strings.Builder) { fmt.Fprintf(sb, "%d", il) }
   753  
   754  func (fl FloatLiteral) SQL() string                { return buildSQL(fl) }
   755  func (fl FloatLiteral) addSQL(sb *strings.Builder) { fmt.Fprintf(sb, "%g", fl) }
   756  
   757  // TODO: provide correct string quote method and use it.
   758  
   759  func (sl StringLiteral) SQL() string                { return buildSQL(sl) }
   760  func (sl StringLiteral) addSQL(sb *strings.Builder) { fmt.Fprintf(sb, "%q", sl) }
   761  
   762  func (bl BytesLiteral) SQL() string                { return buildSQL(bl) }
   763  func (bl BytesLiteral) addSQL(sb *strings.Builder) { fmt.Fprintf(sb, "B%q", bl) }
   764  
   765  func (dl DateLiteral) SQL() string { return buildSQL(dl) }
   766  func (dl DateLiteral) addSQL(sb *strings.Builder) {
   767  	fmt.Fprintf(sb, "DATE '%04d-%02d-%02d'", dl.Year, dl.Month, dl.Day)
   768  }
   769  
   770  func (tl TimestampLiteral) SQL() string { return buildSQL(tl) }
   771  func (tl TimestampLiteral) addSQL(sb *strings.Builder) {
   772  	fmt.Fprintf(sb, "TIMESTAMP '%s'", time.Time(tl).Format("2006-01-02 15:04:05.000000-07:00"))
   773  }
   774  
   775  func (jl JSONLiteral) SQL() string { return buildSQL(jl) }
   776  func (jl JSONLiteral) addSQL(sb *strings.Builder) {
   777  	fmt.Fprintf(sb, "JSON '%s'", jl)
   778  }