xref: /sqlite-3.40.0/tool/mkpragmatab.tcl (revision f2a777fa)
1#!/usr/bin/tclsh
2#
3# Run this script to generate the pragma name lookup table C code.
4#
5# To add new pragmas, first add the name and other relevant attributes
6# of the pragma to the "pragma_def" object below.  Then run this script
7# to generate the ../src/pragma.h header file that contains macros and
8# the lookup table needed for pragma name lookup in the pragma.c module.
9# Then add the extra "case PragTyp_XXXXX:" and subsequent code for the
10# new pragma in ../src/pragma.c.
11#
12
13# Flag meanings:
14set flagMeaning(NeedSchema) {Force schema load before running}
15set flagMeaning(ReadOnly)   {Read-only HEADER_VALUE}
16set flagMeaning(Result0)    {Acts as query when no argument}
17set flagMeaning(Result1)    {Acts as query when has one argument}
18set flagMeaning(SchemaReq)  {Schema required - "main" is default}
19set flagMeaning(SchemaOpt)  {Schema restricts name search if present}
20set flagMeaning(NoColumns)  {OP_ResultRow called with zero columns}
21set flagMeaning(NoColumns1) {zero columns if RHS argument is present}
22
23set pragma_def {
24  NAME: full_column_names
25  TYPE: FLAG
26  ARG:  SQLITE_FullColNames
27  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
28
29  NAME: short_column_names
30  TYPE: FLAG
31  ARG:  SQLITE_ShortColNames
32  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
33
34  NAME: count_changes
35  TYPE: FLAG
36  ARG:  SQLITE_CountRows
37  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
38
39  NAME: empty_result_callbacks
40  TYPE: FLAG
41  ARG:  SQLITE_NullCallback
42  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
43
44  NAME: fullfsync
45  TYPE: FLAG
46  ARG:  SQLITE_FullFSync
47  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
48
49  NAME: checkpoint_fullfsync
50  TYPE: FLAG
51  ARG:  SQLITE_CkptFullFSync
52  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
53
54  NAME: cache_spill
55  FLAG: Result0 SchemaReq NoColumns1
56  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
57
58  NAME: reverse_unordered_selects
59  TYPE: FLAG
60  ARG:  SQLITE_ReverseOrder
61  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
62
63  NAME: query_only
64  TYPE: FLAG
65  ARG:  SQLITE_QueryOnly
66  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
67
68  NAME: automatic_index
69  TYPE: FLAG
70  ARG:  SQLITE_AutoIndex
71  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
72  IF:   !defined(SQLITE_OMIT_AUTOMATIC_INDEX)
73
74  NAME: sql_trace
75  TYPE: FLAG
76  ARG:  SQLITE_SqlTrace
77  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
78  IF:   defined(SQLITE_DEBUG)
79
80  NAME: vdbe_listing
81  TYPE: FLAG
82  ARG:  SQLITE_VdbeListing
83  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
84  IF:   defined(SQLITE_DEBUG)
85
86  NAME: vdbe_trace
87  TYPE: FLAG
88  ARG:  SQLITE_VdbeTrace
89  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
90  IF:   defined(SQLITE_DEBUG)
91
92  NAME: vdbe_addoptrace
93  TYPE: FLAG
94  ARG:  SQLITE_VdbeAddopTrace
95  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
96  IF:   defined(SQLITE_DEBUG)
97
98  NAME: vdbe_debug
99  TYPE: FLAG
100  ARG:  SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace
101  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
102  IF:   defined(SQLITE_DEBUG)
103
104  NAME: vdbe_eqp
105  TYPE: FLAG
106  ARG:  SQLITE_VdbeEQP
107  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
108  IF:   defined(SQLITE_DEBUG)
109
110  NAME: ignore_check_constraints
111  TYPE: FLAG
112  ARG:  SQLITE_IgnoreChecks
113  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
114  IF:   !defined(SQLITE_OMIT_CHECK)
115
116  NAME: writable_schema
117  TYPE: FLAG
118  ARG:  SQLITE_WriteSchema|SQLITE_NoSchemaError
119  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
120
121  NAME: read_uncommitted
122  TYPE: FLAG
123  ARG:  SQLITE_ReadUncommit
124  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
125
126  NAME: recursive_triggers
127  TYPE: FLAG
128  ARG:  SQLITE_RecTriggers
129  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
130
131  NAME: trusted_schema
132  TYPE: FLAG
133  ARG:  SQLITE_TrustedSchema
134  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
135
136  NAME: foreign_keys
137  TYPE: FLAG
138  ARG:  SQLITE_ForeignKeys
139  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
140  IF:   !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
141
142  NAME: defer_foreign_keys
143  TYPE: FLAG
144  ARG:  SQLITE_DeferFKs
145  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
146  IF:   !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
147
148  NAME: cell_size_check
149  TYPE: FLAG
150  ARG:  SQLITE_CellSizeCk
151
152  NAME: default_cache_size
153  FLAG: NeedSchema Result0 SchemaReq NoColumns1
154  COLS: cache_size
155  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
156
157  NAME: page_size
158  FLAG: Result0 SchemaReq NoColumns1
159  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
160
161  NAME: secure_delete
162  FLAG: Result0
163  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
164
165  NAME: page_count
166  FLAG: NeedSchema Result0 SchemaReq
167  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
168
169  NAME: max_page_count
170  TYPE: PAGE_COUNT
171  FLAG: NeedSchema Result0 SchemaReq
172  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
173
174  NAME: locking_mode
175  FLAG: Result0 SchemaReq
176  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
177
178  NAME: journal_mode
179  FLAG: NeedSchema Result0 SchemaReq
180  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
181
182  NAME: journal_size_limit
183  FLAG: Result0 SchemaReq
184  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
185
186  NAME: cache_size
187  FLAG: NeedSchema Result0 SchemaReq NoColumns1
188  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
189
190  NAME: mmap_size
191  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
192
193  NAME: auto_vacuum
194  FLAG: NeedSchema Result0 SchemaReq NoColumns1
195  IF:   !defined(SQLITE_OMIT_AUTOVACUUM)
196
197  NAME: incremental_vacuum
198  FLAG: NeedSchema NoColumns
199  IF:   !defined(SQLITE_OMIT_AUTOVACUUM)
200
201  NAME: temp_store
202  FLAG: Result0 NoColumns1
203  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
204
205  NAME: temp_store_directory
206  FLAG: NoColumns1
207  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
208
209  NAME: data_store_directory
210  FLAG: NoColumns1
211  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_OS_WIN
212
213  NAME: lock_proxy_file
214  FLAG: NoColumns1
215  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS) && SQLITE_ENABLE_LOCKING_STYLE
216
217  NAME: synchronous
218  FLAG: NeedSchema Result0 SchemaReq NoColumns1
219  IF:   !defined(SQLITE_OMIT_PAGER_PRAGMAS)
220
221  NAME: table_info
222  FLAG: NeedSchema Result1 SchemaOpt
223  ARG:  0
224  COLS: cid name type notnull dflt_value pk
225  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
226
227  NAME: table_xinfo
228  TYPE: TABLE_INFO
229  FLAG: NeedSchema Result1 SchemaOpt
230  ARG:  1
231  COLS: cid name type notnull dflt_value pk hidden
232  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
233
234  NAME: table_list
235  TYPE: TABLE_LIST
236  FLAG: NeedSchema Result1
237  COLS: schema name type ncol wr strict
238  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
239
240  NAME: stats
241  FLAG: NeedSchema Result0 SchemaReq
242  COLS: tbl idx wdth hght flgs
243  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
244
245  NAME: index_info
246  TYPE: INDEX_INFO
247  ARG:  0
248  FLAG: NeedSchema Result1 SchemaOpt
249  COLS: seqno cid name
250  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
251
252  NAME: index_xinfo
253  TYPE: INDEX_INFO
254  ARG:  1
255  FLAG: NeedSchema Result1 SchemaOpt
256  COLS: seqno cid name desc coll key
257  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
258
259  NAME: index_list
260  FLAG: NeedSchema Result1 SchemaOpt
261  COLS: seq name unique origin partial
262  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
263
264  NAME: database_list
265  FLAG: Result0
266  COLS: seq name file
267  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
268
269  NAME: function_list
270  FLAG: Result0
271  COLS: name builtin type enc narg flags
272  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
273  IF:   !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
274
275  NAME: module_list
276  FLAG: Result0
277  COLS: name
278  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
279  IF:   !defined(SQLITE_OMIT_VIRTUALTABLE)
280  IF:   !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
281
282  NAME: pragma_list
283  FLAG: Result0
284  COLS: name
285  IF:   !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
286
287  NAME: collation_list
288  FLAG: Result0
289  COLS: seq name
290  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
291
292  NAME: foreign_key_list
293  FLAG: NeedSchema Result1 SchemaOpt
294  COLS: id seq table from to on_update on_delete match
295  IF:   !defined(SQLITE_OMIT_FOREIGN_KEY)
296
297  NAME: foreign_key_check
298  FLAG: NeedSchema Result0 Result1 SchemaOpt
299  COLS: table rowid parent fkid
300  IF:   !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
301
302  NAME: parser_trace
303  TYPE: FLAG
304  ARG:  SQLITE_ParserTrace
305  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
306  IF:   defined(SQLITE_DEBUG)
307
308  NAME: case_sensitive_like
309  FLAG: NoColumns
310  IF:   !defined(SQLITE_OMIT_CASE_SENSITIVE_LIKE_PRAGMA)
311
312  NAME: integrity_check
313  FLAG: NeedSchema Result0 Result1 SchemaOpt
314  IF:   !defined(SQLITE_OMIT_INTEGRITY_CHECK)
315
316  NAME: quick_check
317  TYPE: INTEGRITY_CHECK
318  FLAG: NeedSchema Result0 Result1 SchemaOpt
319  IF:   !defined(SQLITE_OMIT_INTEGRITY_CHECK)
320
321  NAME: encoding
322  FLAG: Result0 NoColumns1
323  IF:   !defined(SQLITE_OMIT_UTF16)
324
325  NAME: schema_version
326  TYPE: HEADER_VALUE
327  ARG:  BTREE_SCHEMA_VERSION
328  FLAG: NoColumns1 Result0
329  IF:   !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
330
331  NAME: user_version
332  TYPE: HEADER_VALUE
333  ARG:  BTREE_USER_VERSION
334  FLAG: NoColumns1 Result0
335  IF:   !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
336
337  NAME: data_version
338  TYPE: HEADER_VALUE
339  ARG:  BTREE_DATA_VERSION
340  FLAG: ReadOnly Result0
341  IF:   !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
342
343  NAME: freelist_count
344  TYPE: HEADER_VALUE
345  ARG:  BTREE_FREE_PAGE_COUNT
346  FLAG: ReadOnly Result0
347  IF:   !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
348
349  NAME: application_id
350  TYPE: HEADER_VALUE
351  ARG:  BTREE_APPLICATION_ID
352  FLAG: NoColumns1 Result0
353  IF:   !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
354
355  NAME: compile_options
356  FLAG: Result0
357  IF:   !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
358
359  NAME: wal_checkpoint
360  FLAG: NeedSchema
361  COLS: busy log checkpointed
362  IF:   !defined(SQLITE_OMIT_WAL)
363
364  NAME: wal_autocheckpoint
365  IF:   !defined(SQLITE_OMIT_WAL)
366
367  NAME: shrink_memory
368  FLAG: NoColumns
369
370  NAME: busy_timeout
371  FLAG: Result0
372  COLS: timeout
373
374  NAME: lock_status
375  FLAG: Result0
376  COLS: database status
377  IF:   defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
378
379  NAME: activate_extensions
380  IF:   defined(SQLITE_ENABLE_CEROD)
381
382  NAME: soft_heap_limit
383  FLAG: Result0
384
385  NAME: hard_heap_limit
386  FLAG: Result0
387
388  NAME: threads
389  FLAG: Result0
390
391  NAME: analysis_limit
392  FLAG: Result0
393
394  NAME: optimize
395  FLAG: Result1 NeedSchema
396
397  NAME: legacy_alter_table
398  TYPE: FLAG
399  ARG:  SQLITE_LegacyAlter
400  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
401}
402
403# Open the output file
404#
405set destfile "[file dir [file dir [file normal $argv0]]]/src/pragma.h"
406puts "Overwriting $destfile with new pragma table..."
407set fd [open $destfile wb]
408puts $fd {/* DO NOT EDIT!
409** This file is automatically generated by the script at
410** ../tool/mkpragmatab.tcl.  To update the set of pragmas, edit
411** that script and rerun it.
412*/}
413
414# Parse the PRAGMA table above.
415#
416set name {}
417set type {}
418set if {}
419set flags {}
420set cols {}
421set cols_list {}
422set arg 0
423proc record_one {} {
424  global name type if arg allbyname typebyif flags cols all_cols
425  global cols_list colUsedBy
426  if {$name==""} return
427  if {$cols!=""} {
428    if {![info exists all_cols($cols)]} {
429      set all_cols($cols) 1
430      lappend cols_list $cols
431    }
432    set cx $cols
433    lappend colUsedBy($cols) $name
434  } else {
435    set cx 0
436  }
437  set allbyname($name) [list $type $arg $if $flags $cols]
438  set name {}
439  set type {}
440  set if {}
441  set flags {}
442  set cols {}
443  set arg 0
444}
445foreach line [split $pragma_def \n] {
446  set line [string trim $line]
447  if {$line==""} continue
448  foreach {id val} [split $line :] break
449  set val [string trim $val]
450  if {$id=="NAME"} {
451    record_one
452    set name $val
453    set type [string toupper $val]
454  } elseif {$id=="TYPE"} {
455    set type $val
456    if {$type=="FLAG"} {
457      lappend flags Result0 NoColumns1
458    }
459  } elseif {$id=="ARG"} {
460    set arg $val
461  } elseif {$id=="COLS"} {
462    set cols $val
463  } elseif {$id=="IF"} {
464    lappend if $val
465  } elseif {$id=="FLAG"} {
466    foreach term [split $val] {
467      lappend flags $term
468      set allflags($term) 1
469    }
470  } else {
471    error "bad pragma_def line: $line"
472  }
473}
474record_one
475set allnames [lsort [array names allbyname]]
476
477# Generate #defines for all pragma type names.  Group the pragmas that are
478# omit in default builds (ex: defined(SQLITE_DEBUG))
479# at the end.
480#
481puts $fd "\n/* The various pragma types */"
482set pnum 0
483foreach name $allnames {
484  set type [lindex $allbyname($name) 0]
485  if {[info exists seentype($type)]} continue
486  set if [lindex $allbyname($name) 2]
487  if {[regexp SQLITE_DEBUG $if] || [regexp SQLITE_HAS_CODEC $if]} continue
488  set seentype($type) 1
489  puts $fd [format {#define %-35s %4d} PragTyp_$type $pnum]
490  incr pnum
491}
492foreach name $allnames {
493  set type [lindex $allbyname($name) 0]
494  if {[info exists seentype($type)]} continue
495  set if [lindex $allbyname($name) 2]
496  if {[regexp SQLITE_DEBUG $if]} continue
497  set seentype($type) 1
498  puts $fd [format {#define %-35s %4d} PragTyp_$type $pnum]
499  incr pnum
500}
501foreach name $allnames {
502  set type [lindex $allbyname($name) 0]
503  if {[info exists seentype($type)]} continue
504  set seentype($type) 1
505  puts $fd [format {#define %-35s %4d} PragTyp_$type $pnum]
506  incr pnum
507}
508
509# Generate #defines for flags
510#
511puts $fd "\n/* Property flags associated with various pragma. */"
512set fv 1
513foreach f [lsort [array names allflags]] {
514  puts $fd [format {#define PragFlg_%-10s 0x%02x /* %s */} \
515             $f $fv $flagMeaning($f)]
516  set fv [expr {$fv*2}]
517}
518
519# Sort the column lists so that longer column lists occur first
520#
521proc colscmp {a b} {
522  return [expr {[llength $b] - [llength $a]}]
523}
524set cols_list [lsort -command colscmp $cols_list]
525
526# Generate the array of column names used by pragmas that act like
527# queries.
528#
529puts $fd "\n/* Names of columns for pragmas that return multi-column result"
530puts $fd "** or that return single-column results where the name of the"
531puts $fd "** result column is different from the name of the pragma\n*/"
532puts $fd "static const char *const pragCName\[\] = {"
533set offset 0
534set allcollist {}
535foreach cols $cols_list {
536  set n [llength $cols]
537  set limit [expr {[llength $allcollist] - $n}]
538  for {set i 0} {$i<$limit} {incr i} {
539    set sublist [lrange $allcollist $i [expr {$i+$n-1}]]
540    if {$sublist==$cols} {
541      puts $fd [format "%27s/* $colUsedBy($cols) reuses $i */" ""]
542      set cols_offset($cols) $i
543      break
544    }
545  }
546  if {$i<$limit} continue
547  set cols_offset($cols) $offset
548  set ub " /* Used by: $colUsedBy($cols) */"
549  foreach c $cols {
550    lappend allcollist $c
551    puts $fd [format "  /* %3d */ %-14s%s" $offset \"$c\", $ub]
552    set ub ""
553    incr offset
554  }
555}
556puts $fd "\175;"
557
558# Generate the lookup table
559#
560puts $fd "\n/* Definitions of all built-in pragmas */"
561puts $fd "typedef struct PragmaName \173"
562puts $fd "  const char *const zName; /* Name of pragma */"
563puts $fd "  u8 ePragTyp;             /* PragTyp_XXX value */"
564puts $fd "  u8 mPragFlg;             /* Zero or more PragFlg_XXX values */"
565puts $fd {  u8 iPragCName;           /* Start of column names in pragCName[] */}
566puts $fd "  u8 nPragCName;          \
567/* Num of col names. 0 means use pragma name */"
568puts $fd "  u64 iArg;                /* Extra argument */"
569puts $fd "\175 PragmaName;"
570puts $fd "static const PragmaName aPragmaName\[\] = \173"
571
572set current_if {}
573set spacer [format {    %26s } {}]
574foreach name $allnames {
575  foreach {type arg if flag cx} $allbyname($name) break
576  if {$cx==0 || $cx==""} {
577    set cy 0
578    set nx 0
579  } else {
580    set cy $cols_offset($cx)
581    set nx [llength $cx]
582  }
583  if {$if!=$current_if} {
584    if {$current_if!=""} {
585      foreach this_if $current_if {
586        puts $fd "#endif"
587      }
588    }
589    set current_if $if
590    if {$current_if!=""} {
591      foreach this_if $current_if {
592        puts $fd "#if $this_if"
593      }
594    }
595  }
596  set typex [format PragTyp_%-23s $type,]
597  if {$flag==""} {
598    set flagx "0"
599  } else {
600    set flagx PragFlg_[join $flag {|PragFlg_}]
601  }
602  puts $fd " \173/* zName:     */ \"$name\","
603  puts $fd "  /* ePragTyp:  */ PragTyp_$type,"
604  puts $fd "  /* ePragFlg:  */ $flagx,"
605  puts $fd "  /* ColNames:  */ $cy, $nx,"
606  puts $fd "  /* iArg:      */ $arg \175,"
607}
608if {$current_if!=""} {
609  foreach this_if $current_if {
610    puts $fd "#endif"
611  }
612}
613puts $fd "\175;"
614
615# count the number of pragmas, for information purposes
616#
617set allcnt 0
618set dfltcnt 0
619foreach name $allnames {
620  incr allcnt
621  set if [lindex $allbyname($name) 2]
622  if {[regexp {^defined} $if] || [regexp {[^!]defined} $if]} continue
623  incr dfltcnt
624}
625puts $fd "/* Number of pragmas: $dfltcnt on by default, $allcnt total. */"
626