xref: /sqlite-3.40.0/tool/mkpragmatab.tcl (revision 2ca62cb1)
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: legacy_file_format
45  TYPE: FLAG
46  ARG:  SQLITE_LegacyFileFmt
47  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
48
49  NAME: fullfsync
50  TYPE: FLAG
51  ARG:  SQLITE_FullFSync
52  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
53
54  NAME: checkpoint_fullfsync
55  TYPE: FLAG
56  ARG:  SQLITE_CkptFullFSync
57  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
58
59  NAME: cache_spill
60  FLAG: Result0 SchemaReq NoColumns1
61  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
62
63  NAME: reverse_unordered_selects
64  TYPE: FLAG
65  ARG:  SQLITE_ReverseOrder
66  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
67
68  NAME: query_only
69  TYPE: FLAG
70  ARG:  SQLITE_QueryOnly
71  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
72
73  NAME: automatic_index
74  TYPE: FLAG
75  ARG:  SQLITE_AutoIndex
76  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
77  IF:   !defined(SQLITE_OMIT_AUTOMATIC_INDEX)
78
79  NAME: sql_trace
80  TYPE: FLAG
81  ARG:  SQLITE_SqlTrace
82  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
83  IF:   defined(SQLITE_DEBUG)
84
85  NAME: vdbe_listing
86  TYPE: FLAG
87  ARG:  SQLITE_VdbeListing
88  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
89  IF:   defined(SQLITE_DEBUG)
90
91  NAME: vdbe_trace
92  TYPE: FLAG
93  ARG:  SQLITE_VdbeTrace
94  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
95  IF:   defined(SQLITE_DEBUG)
96
97  NAME: vdbe_addoptrace
98  TYPE: FLAG
99  ARG:  SQLITE_VdbeAddopTrace
100  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
101  IF:   defined(SQLITE_DEBUG)
102
103  NAME: vdbe_debug
104  TYPE: FLAG
105  ARG:  SQLITE_SqlTrace|SQLITE_VdbeListing|SQLITE_VdbeTrace
106  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
107  IF:   defined(SQLITE_DEBUG)
108
109  NAME: vdbe_eqp
110  TYPE: FLAG
111  ARG:  SQLITE_VdbeEQP
112  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
113  IF:   defined(SQLITE_DEBUG)
114
115  NAME: ignore_check_constraints
116  TYPE: FLAG
117  ARG:  SQLITE_IgnoreChecks
118  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
119  IF:   !defined(SQLITE_OMIT_CHECK)
120
121  NAME: writable_schema
122  TYPE: FLAG
123  ARG:  SQLITE_WriteSchema
124  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
125
126  NAME: read_uncommitted
127  TYPE: FLAG
128  ARG:  SQLITE_ReadUncommit
129  IF:   !defined(SQLITE_OMIT_FLAG_PRAGMAS)
130
131  NAME: recursive_triggers
132  TYPE: FLAG
133  ARG:  SQLITE_RecTriggers
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  COLS: cid name type notnull dflt_value pk
224  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
225
226  NAME: stats
227  FLAG: NeedSchema Result0 SchemaReq
228  COLS: tbl idx wdth hght flgs
229  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
230
231  NAME: index_info
232  TYPE: INDEX_INFO
233  ARG:  0
234  FLAG: NeedSchema Result1 SchemaOpt
235  COLS: seqno cid name
236  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
237
238  NAME: index_xinfo
239  TYPE: INDEX_INFO
240  ARG:  1
241  FLAG: NeedSchema Result1 SchemaOpt
242  COLS: seqno cid name desc coll key
243  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
244
245  NAME: index_list
246  FLAG: NeedSchema Result1 SchemaOpt
247  COLS: seq name unique origin partial
248  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
249
250  NAME: database_list
251  FLAG: NeedSchema Result0
252  COLS: seq name file
253  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
254
255  NAME: collation_list
256  FLAG: Result0
257  COLS: seq name
258  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
259
260  NAME: foreign_key_list
261  FLAG: NeedSchema Result1 SchemaOpt
262  COLS: id seq table from to on_update on_delete match
263  IF:   !defined(SQLITE_OMIT_FOREIGN_KEY)
264
265  NAME: foreign_key_check
266  FLAG: NeedSchema Result0
267  COLS: table rowid parent fkid
268  IF:   !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
269
270  NAME: parser_trace
271  IF:   defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_PARSER_TRACE)
272
273  NAME: case_sensitive_like
274  FLAG: NoColumns
275
276  NAME: integrity_check
277  FLAG: NeedSchema Result0 Result1
278  IF:   !defined(SQLITE_OMIT_INTEGRITY_CHECK)
279
280  NAME: quick_check
281  TYPE: INTEGRITY_CHECK
282  FLAG: NeedSchema Result0 Result1
283  IF:   !defined(SQLITE_OMIT_INTEGRITY_CHECK)
284
285  NAME: encoding
286  FLAG: Result0 NoColumns1
287  IF:   !defined(SQLITE_OMIT_UTF16)
288
289  NAME: schema_version
290  TYPE: HEADER_VALUE
291  ARG:  BTREE_SCHEMA_VERSION
292  FLAG: NoColumns1 Result0
293  IF:   !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
294
295  NAME: user_version
296  TYPE: HEADER_VALUE
297  ARG:  BTREE_USER_VERSION
298  FLAG: NoColumns1 Result0
299  IF:   !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
300
301  NAME: data_version
302  TYPE: HEADER_VALUE
303  ARG:  BTREE_DATA_VERSION
304  FLAG: ReadOnly Result0
305  IF:   !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
306
307  NAME: freelist_count
308  TYPE: HEADER_VALUE
309  ARG:  BTREE_FREE_PAGE_COUNT
310  FLAG: ReadOnly Result0
311  IF:   !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
312
313  NAME: application_id
314  TYPE: HEADER_VALUE
315  ARG:  BTREE_APPLICATION_ID
316  FLAG: NoColumns1 Result0
317  IF:   !defined(SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS)
318
319  NAME: compile_options
320  FLAG: Result0
321  IF:   !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
322
323  NAME: wal_checkpoint
324  FLAG: NeedSchema
325  COLS: busy log checkpointed
326  IF:   !defined(SQLITE_OMIT_WAL)
327
328  NAME: wal_autocheckpoint
329  IF:   !defined(SQLITE_OMIT_WAL)
330
331  NAME: shrink_memory
332  FLAG: NoColumns
333
334  NAME: busy_timeout
335  FLAG: Result0
336  COLS: timeout
337
338  NAME: lock_status
339  FLAG: Result0
340  COLS: database status
341  IF:   defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
342
343  NAME: key
344  IF:   defined(SQLITE_HAS_CODEC)
345
346  NAME: rekey
347  IF:   defined(SQLITE_HAS_CODEC)
348
349  NAME: hexkey
350  IF:   defined(SQLITE_HAS_CODEC)
351
352  NAME: hexrekey
353  TYPE: HEXKEY
354  IF:   defined(SQLITE_HAS_CODEC)
355
356  NAME: activate_extensions
357  IF:   defined(SQLITE_HAS_CODEC) || defined(SQLITE_ENABLE_CEROD)
358
359  NAME: soft_heap_limit
360  FLAG: Result0
361
362  NAME: threads
363  FLAG: Result0
364
365  NAME: optimize
366  FLAG: Result1 NeedSchema
367}
368
369# Open the output file
370#
371set destfile "[file dir [file dir [file normal $argv0]]]/src/pragma.h"
372puts "Overwriting $destfile with new pragma table..."
373set fd [open $destfile wb]
374puts $fd {/* DO NOT EDIT!
375** This file is automatically generated by the script at
376** ../tool/mkpragmatab.tcl.  To update the set of pragmas, edit
377** that script and rerun it.
378*/}
379
380# Parse the PRAGMA table above.
381#
382set name {}
383set type {}
384set if {}
385set flags {}
386set cols {}
387set cols_list {}
388set arg 0
389proc record_one {} {
390  global name type if arg allbyname typebyif flags cols allcols
391  global cols_list colUsedBy
392  if {$name==""} return
393  if {$cols!=""} {
394    if {![info exists allcols($cols)]} {
395      lappend cols_list $cols
396      set allcols($cols) [llength $cols_list]
397    }
398    set cx $allcols($cols)
399    lappend colUsedBy($cols) $name
400  } else {
401    set cx 0
402  }
403  set allbyname($name) [list $type $arg $if $flags $cx]
404  set name {}
405  set type {}
406  set if {}
407  set flags {}
408  set cols {}
409  set arg 0
410}
411foreach line [split $pragma_def \n] {
412  set line [string trim $line]
413  if {$line==""} continue
414  foreach {id val} [split $line :] break
415  set val [string trim $val]
416  if {$id=="NAME"} {
417    record_one
418    set name $val
419    set type [string toupper $val]
420  } elseif {$id=="TYPE"} {
421    set type $val
422    if {$type=="FLAG"} {
423      lappend flags Result0 NoColumns1
424    }
425  } elseif {$id=="ARG"} {
426    set arg $val
427  } elseif {$id=="COLS"} {
428    set cols $val
429  } elseif {$id=="IF"} {
430    lappend if $val
431  } elseif {$id=="FLAG"} {
432    foreach term [split $val] {
433      lappend flags $term
434      set allflags($term) 1
435    }
436  } else {
437    error "bad pragma_def line: $line"
438  }
439}
440record_one
441set allnames [lsort [array names allbyname]]
442
443# Generate #defines for all pragma type names.  Group the pragmas that are
444# omit in default builds (defined(SQLITE_DEBUG) and defined(SQLITE_HAS_CODEC))
445# at the end.
446#
447puts $fd "\n/* The various pragma types */"
448set pnum 0
449foreach name $allnames {
450  set type [lindex $allbyname($name) 0]
451  if {[info exists seentype($type)]} continue
452  set if [lindex $allbyname($name) 2]
453  if {[regexp SQLITE_DEBUG $if] || [regexp SQLITE_HAS_CODEC $if]} continue
454  set seentype($type) 1
455  puts $fd [format {#define %-35s %4d} PragTyp_$type $pnum]
456  incr pnum
457}
458foreach name $allnames {
459  set type [lindex $allbyname($name) 0]
460  if {[info exists seentype($type)]} continue
461  set if [lindex $allbyname($name) 2]
462  if {[regexp SQLITE_DEBUG $if]} continue
463  set seentype($type) 1
464  puts $fd [format {#define %-35s %4d} PragTyp_$type $pnum]
465  incr pnum
466}
467foreach name $allnames {
468  set type [lindex $allbyname($name) 0]
469  if {[info exists seentype($type)]} continue
470  set seentype($type) 1
471  puts $fd [format {#define %-35s %4d} PragTyp_$type $pnum]
472  incr pnum
473}
474
475# Generate #defines for flags
476#
477puts $fd "\n/* Property flags associated with various pragma. */"
478set fv 1
479foreach f [lsort [array names allflags]] {
480  puts $fd [format {#define PragFlg_%-10s 0x%02x /* %s */} \
481             $f $fv $flagMeaning($f)]
482  set fv [expr {$fv*2}]
483}
484
485# Generate the array of column names used by pragmas that act like
486# queries.
487#
488puts $fd "\n/* Names of columns for pragmas that return multi-column result"
489puts $fd "** or that return single-column results where the name of the"
490puts $fd "** result column is different from the name of the pragma\n*/"
491puts $fd "static const char *const pragCName\[\] = {"
492set offset 0
493foreach cols $cols_list {
494  set cols_offset($allcols($cols)) $offset
495  set ub " /* Used by: $colUsedBy($cols) */"
496  foreach c $cols {
497    puts $fd [format "  /* %3d */ %-14s%s" $offset \"$c\", $ub]
498    set ub ""
499    incr offset
500  }
501}
502puts $fd "\175;"
503
504# Generate the lookup table
505#
506puts $fd "\n/* Definitions of all built-in pragmas */"
507puts $fd "typedef struct PragmaName \173"
508puts $fd "  const char *const zName; /* Name of pragma */"
509puts $fd "  u8 ePragTyp;             /* PragTyp_XXX value */"
510puts $fd "  u8 mPragFlg;             /* Zero or more PragFlg_XXX values */"
511puts $fd {  u8 iPragCName;           /* Start of column names in pragCName[] */}
512puts $fd "  u8 nPragCName;          \
513/* Num of col names. 0 means use pragma name */"
514puts $fd "  u32 iArg;                /* Extra argument */"
515puts $fd "\175 PragmaName;"
516puts $fd "static const PragmaName aPragmaName\[\] = \173"
517
518set current_if {}
519set spacer [format {    %26s } {}]
520foreach name $allnames {
521  foreach {type arg if flag cx} $allbyname($name) break
522  if {$cx==0} {
523    set cy 0
524    set nx 0
525  } else {
526    set cy $cols_offset($cx)
527    set nx [llength [lindex $cols_list [expr {$cx-1}]]]
528  }
529  if {$if!=$current_if} {
530    if {$current_if!=""} {
531      foreach this_if $current_if {
532        puts $fd "#endif"
533      }
534    }
535    set current_if $if
536    if {$current_if!=""} {
537      foreach this_if $current_if {
538        puts $fd "#if $this_if"
539      }
540    }
541  }
542  set typex [format PragTyp_%-23s $type,]
543  if {$flag==""} {
544    set flagx "0"
545  } else {
546    set flagx PragFlg_[join $flag {|PragFlg_}]
547  }
548  puts $fd " \173/* zName:     */ \"$name\","
549  puts $fd "  /* ePragTyp:  */ PragTyp_$type,"
550  puts $fd "  /* ePragFlg:  */ $flagx,"
551  puts $fd "  /* ColNames:  */ $cy, $nx,"
552  puts $fd "  /* iArg:      */ $arg \175,"
553}
554if {$current_if!=""} {
555  foreach this_if $current_if {
556    puts $fd "#endif"
557  }
558}
559puts $fd "\175;"
560
561# count the number of pragmas, for information purposes
562#
563set allcnt 0
564set dfltcnt 0
565foreach name $allnames {
566  incr allcnt
567  set if [lindex $allbyname($name) 2]
568  if {[regexp {^defined} $if] || [regexp {[^!]defined} $if]} continue
569  incr dfltcnt
570}
571puts $fd "/* Number of pragmas: $dfltcnt on by default, $allcnt total. */"
572