summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/make_errorcodes.py57
1 files changed, 54 insertions, 3 deletions
diff --git a/scripts/make_errorcodes.py b/scripts/make_errorcodes.py
index d284293..fa45ea4 100755
--- a/scripts/make_errorcodes.py
+++ b/scripts/make_errorcodes.py
@@ -16,6 +16,7 @@ The script can be run at a new PostgreSQL release to refresh the module.
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details.
+import re
import sys
import urllib2
from collections import defaultdict
@@ -48,7 +49,46 @@ def read_base_file(filename):
raise ValueError("can't find the separator. Is this the right file?")
-def parse_errors(url):
+def parse_errors_txt(url):
+ classes = {}
+ errors = defaultdict(dict)
+
+ page = urllib2.urlopen(url)
+ for line in page:
+ # Strip comments and skip blanks
+ line = line.split('#')[0].strip()
+ if not line:
+ continue
+
+ # Parse a section
+ m = re.match(r"Section: (Class (..) - .+)", line)
+ if m:
+ label, class_ = m.groups()
+ classes[class_] = label
+ continue
+
+ # Parse an error
+ m = re.match(r"(.....)\s+(?:E|W|S)\s+ERRCODE_(\S+)(?:\s+(\S+))?$", line)
+ if m:
+ errcode, macro, spec = m.groups()
+ # error 22008 has 2 macros and 1 def: give priority to the def
+ # as it's the one we used to parse from sgml
+ if not spec:
+ if errcode in errors[class_]:
+ continue
+ errlabel = macro.upper()
+ else:
+ errlabel = spec.upper()
+
+ errors[class_][errcode] = errlabel
+ continue
+
+ # We don't expect anything else
+ raise ValueError("unexpected line:\n%s" % line)
+
+ return classes, errors
+
+def parse_errors_sgml(url):
page = BS(urllib2.urlopen(url))
table = page('table')[1]('tbody')[0]
@@ -87,14 +127,25 @@ def parse_errors(url):
return classes, errors
-errors_url="http://www.postgresql.org/docs/%s/static/errcodes-appendix.html"
+errors_sgml_url = \
+ "http://www.postgresql.org/docs/%s/static/errcodes-appendix.html"
+
+errors_txt_url = \
+ "http://git.postgresql.org/gitweb/?p=postgresql.git;a=blob_plain;" \
+ "f=src/backend/utils/errcodes.txt;hb=REL%s_STABLE"
def fetch_errors(versions):
classes = {}
errors = defaultdict(dict)
for version in versions:
- c1, e1 = parse_errors(errors_url % version)
+ print >> sys.stderr, version
+ tver = tuple(map(int, version.split('.')))
+ if tver < (9, 1):
+ c1, e1 = parse_errors_sgml(errors_sgml_url % version)
+ else:
+ c1, e1 = parse_errors_txt(
+ errors_txt_url % version.replace('.', '_'))
classes.update(c1)
for c, cerrs in e1.iteritems():
errors[c].update(cerrs)