#!/usr/bin/perl # # Generate the keywords table for the documentation's SQL Key Words appendix # # Copyright (c) 2019-2024, PostgreSQL Global Development Group use strict; use warnings FATAL => 'all'; my @sql_versions = reverse sort ('1992', '2016', '2023'); my $srcdir = $ARGV[0]; my %keywords; my %as_keywords; # read SQL-spec keywords foreach my $ver (@sql_versions) { foreach my $res ('reserved', 'nonreserved') { foreach my $file (glob "$srcdir/keywords/sql${ver}*-${res}.txt") { open my $fh, '<', $file or die; while (<$fh>) { chomp; $keywords{$_}{$ver}{$res} = 1; } close $fh; } } } # read PostgreSQL keywords open my $fh, '<', "$srcdir/../../../src/include/parser/kwlist.h" or die; while (<$fh>) { if (/^PG_KEYWORD\("(\w+)", \w+, (\w+)_KEYWORD\, (\w+)\)/) { $keywords{ uc $1 }{'pg'}{ lc $2 } = 1; $as_keywords{ uc $1 } = 1 if $3 eq 'AS_LABEL'; } } close $fh; # print output print "\n"; print < <acronym>SQL</acronym> Key Words Key Word PostgreSQL END foreach my $ver (@sql_versions) { my $s = ($ver eq '1992' ? 'SQL-92' : "SQL:$ver"); print " $s\n"; } print < END foreach my $word (sort keys %keywords) { # Insert zwsp's into very long keywords, so that they can be broken # into multiple lines in PDF format (or narrow HTML windows). my $printword = $word; $printword =~ s/_/_&zwsp;/g if (length($printword) > 20); print " \n"; print " $printword\n"; print " "; if ($keywords{$word}{pg}{'unreserved'}) { print "non-reserved"; } elsif ($keywords{$word}{pg}{'col_name'}) { print "non-reserved (cannot be function or type)"; } elsif ($keywords{$word}{pg}{'type_func_name'}) { print "reserved (can be function or type)"; } elsif ($keywords{$word}{pg}{'reserved'}) { print "reserved"; } if ($as_keywords{$word}) { print ", requires AS"; } print "\n"; foreach my $ver (@sql_versions) { print " "; if ($keywords{$word}{$ver}{'reserved'}) { print "reserved"; } elsif ($keywords{$word}{$ver}{'nonreserved'}) { print "non-reserved"; } print "\n"; } print " \n"; } print < END