Changeset: 1c372527aeac for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=1c372527aeac
Modified Files:
testing/mktest.py
testing/sqllogictest.py
Branch: mtest
Log Message:
Reimplemented recognition of SQL functions and procedures.
It now also recognizes embedded languages and properly counts
non-quoted braces.
diffs (168 lines):
diff --git a/testing/mktest.py b/testing/mktest.py
--- a/testing/mktest.py
+++ b/testing/mktest.py
@@ -51,23 +51,38 @@ else:
port=opts.port)
crs = MapiCursor(dbh)
-query = []
-
-def is_psm_stmt(stmt:str):
+def is_complete_stmt(query, line:str):
+ stmt = query + [line]
+ stmt = '\n'.join(stmt)
if opts.language == 'sql':
- rgx =
re.compile(r'(create|create\s+or\s+replace)\s+(function|procedure|aggregate|filter|window|loader|trigger)\b',
re.I)
- return rgx.match(stmt) is not None
- else:
- return re.match(r'\s*function\s', stmt) is not None
-
-def is_psm_stmt_end(stmt:str):
- if opts.language == 'sql':
- return re.search(r'end;$', stmt, re.I) is not None
- else:
- return re.match(r'\s*end(\s+\w+)?\s*;', stmt) is not None
-
-def is_complete_psm_stmt(stmt:str):
- if opts.language == 'sql':
+ res =
re.match(r'create(\s+or\d+replace)?\s+(function|procedure|aggregate|filter|window|loader)\b[^;]*\blanguage\s+\S+\s*\{',
stmt, re.IGNORECASE)
+ if res is not None:
+ q = None
+ skip = False
+ n = 0
+ hash = False
+ for c in stmt:
+ if skip:
+ skip = False
+ elif hash:
+ if c == '\n':
+ hash = False
+ elif c == q:
+ q = None
+ elif q is not None:
+ if c == '\\':
+ skip = True
+ elif c == "'" or c == '"':
+ q = c
+ elif c == '{':
+ n += 1
+ elif c == '}':
+ n -= 1
+ elif c == ';' and n == 0:
+ return True
+ elif c == '#':
+ hash = True
+ return False
if
re.match(r'create(\s+or\d+replace)?\s+(function|procedure|aggregate|filter|window|loader|trigger)\b[^;]*\bbegin\b.*?\bend\b\s*;',
stmt, re.DOTALL|re.IGNORECASE) is not None:
return True
if
re.match(r'create(\s+or\d+replace)?\s+(function|procedure|aggregate|filter|window|loader|trigger)\b[^;]*\bbegin\b',
stmt, re.IGNORECASE) is not None:
@@ -75,9 +90,12 @@ def is_complete_psm_stmt(stmt:str):
return False
if
re.match(r'create(\s+or\d+replace)?\s+(function|procedure|aggregate|filter|window|loader|trigger)\b[^;]*;',
stmt, re.IGNORECASE) is not None:
return True
- return False
+ if
re.match(r'create(\s+or\d+replace)?\s+(function|procedure|aggregate|filter|window|loader|trigger)\b',
stmt, re.IGNORECASE) is not None:
+ return False
else:
- return re.match(r'\s*function\s.*\bend(\s+\w+)?\s*;', stmt, re.DOTALL)
is not None
+ if re.match(r'\s*function\s', stmt) is not None:
+ return re.match(r'\s*function\s.*\bend(\s+\w+)?\s*;', stmt,
re.DOTALL) is not None
+ return re.match(r'[^;]*;', stmt) is not None
def is_copyfrom_stmt(stmt:str):
# TODO fix need stronger regex
@@ -99,9 +117,7 @@ def convertresult(columns, data):
else:
nrow.append('%d' % row[i])
elif columns[i] == 'T':
- if row[i] == '':
- nrow.append('(empty)')
- elif row[i] == b'':
+ if not row[i]:
nrow.append('(empty)')
else:
nval = []
@@ -205,13 +221,12 @@ def process_copyfrom_stmt(query):
to_sqllogic_test(query, copy_into_stmt=copy_into_stmt,
copy_into_data=copy_into_data)
+query = []
incomment = False
-inpsm = False
while True:
line = sys.stdin.readline()
if not line:
break
- line = line.rstrip()
if incomment:
if '*/' in line:
line = line[line.find('*/') + 2:]
@@ -222,39 +237,27 @@ while True:
if '/*' in line:
line = line[:line.find('/*')]
incomment = True
- if not line or line.lstrip().startswith('--') or
line.lstrip().startswith('#'):
- if len(query) > 0:
- if is_copyfrom_stmt('\n'.join(query)):
+ line = line.rstrip()
+ if not line:
+ continue
+ if (opts.language == 'sql' and line.lstrip().startswith('--')) or
line.lstrip().startswith('#'):
+ if query:
+ if opts.language == 'sql' and is_copyfrom_stmt('\n'.join(query)):
process_copyfrom_stmt(query)
query = []
+ else:
+ query.append(line)
continue
# when copyfrom stmt from stdin skip because data may contain --
if opts.language == 'sql' and '--' in line and not
is_copyfrom_stmt('\n'.join(query)):
line = line[:line.index('--')].rstrip()
- res = re.match('[^\'"]*((\'[^\']*\'|"[^"]*")[^\'"]*)*#', line)
- if res is not None:
- line = res.group(0)[:-1].rstrip()
- if (inpsm and is_psm_stmt_end(line)) or (not inpsm and line.endswith(';')):
- inpsm = False
- tmp = ([] + query)
- tmp.append(line)
- stmt = '\n'.join(tmp)
- if is_copyfrom_stmt(stmt):
- query.append(line)
- continue
- if is_psm_stmt(stmt):
- if is_complete_psm_stmt(stmt):
- stmt = stmt.rstrip(';')
- to_sqllogic_test(stmt)
- query = []
- else:
- query.append(line)
- inpsm = True
- continue
- stripped = line.rstrip(';')
- query.append(stripped)
- query = '\n'.join(query)
- to_sqllogic_test(query)
+ if not query:
+ res = re.match('[^\'"]*((\'[^\']*\'|"[^"]*")[^\'"]*)*#', line)
+ if res is not None:
+ line = res.group(0)[:-1].rstrip()
+ if is_complete_stmt(query, line):
+ query.append(line.rstrip(';'))
+ to_sqllogic_test('\n'.join(query))
query = []
else:
query.append(line)
diff --git a/testing/sqllogictest.py b/testing/sqllogictest.py
--- a/testing/sqllogictest.py
+++ b/testing/sqllogictest.py
@@ -131,9 +131,7 @@ class SQLLogic:
else:
nrow.append('%d' % row[i])
elif columns[i] == 'T':
- if row[i] == '':
- nrow.append('(empty)')
- elif row[i] == b'':
+ if not row[i]:
nrow.append('(empty)')
else:
nval = []
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list