def parse(self, f, approve=None): self.approve = approve self.initfile(f) while True: skipping = False line = self.readline() if not line: break if line[0] == '#': # skip mal comments break conn = None # look for connection string if line.startswith('@connection'): conn_params = parse_connection_string(line) conn = self.get_connection( conn_params.get('conn_id')) or self.add_connection( **conn_params) self.writeline(line) line = self.readline() words = line.split() if not words: continue while words[0] == 'skipif' or words[0] == 'onlyif': if words[0] == 'skipif' and words[1] == 'MonetDB': skipping = True elif words[0] == 'onlyif' and words[1] != 'MonetDB': skipping = True self.writeline(line) line = self.readline() words = line.split() hashlabel = None if words[0] == 'hash-threshold': self.threshold = int(words[1]) self.writeline(line) elif words[0] == 'statement': expected_err_code = None expected_err_msg = None expected_rowcount = None expectok = words[1] == 'ok' if len(words) > 2: if expectok: if words[2] == 'rowcount': expected_rowcount = int(words[3]) else: err_str = " ".join(words[2:]) expected_err_code, expected_err_msg = utils.parse_mapi_err_msg( err_str) statement = [] self.qline = self.line + 1 stline = line while True: line = self.readline() if not line or line == '\n': break statement.append(line.rstrip('\n')) if not skipping: if is_copyfrom_stmt(statement): stmt, stmt_less_data = prepare_copyfrom_stmt(statement) result = self.exec_statement( stmt, expectok, err_stmt=stmt_less_data, expected_err_code=expected_err_code, expected_err_msg=expected_err_msg, expected_rowcount=expected_rowcount, conn=conn) else: result = self.exec_statement( '\n'.join(statement), expectok, expected_err_code=expected_err_code, expected_err_msg=expected_err_msg, expected_rowcount=expected_rowcount, conn=conn) self.writeline(' '.join(result)) else: self.writeline(stline) for line in statement: self.writeline(line) self.writeline() elif words[0] == 'query': columns = words[1] pyscript = None if len(words) > 2: sorting = words[2] # nosort,rowsort,valuesort if sorting == 'python': pyscript = words[3] if len(words) > 4: hashlabel = words[4] elif len(words) > 3: hashlabel = words[3] else: sorting = 'nosort' query = [] self.qline = self.line + 1 qrline = line while True: line = self.readline() if not line or line == '\n' or line.startswith('----'): break query.append(line.rstrip('\n')) if not line.startswith('----'): raise SQLLogicSyntaxError('---- expected') line = self.readline() if not line: line = '\n' if 'values hashing to' in line: words = line.split() hash = words[4] expected = None nresult = int(words[0]) else: hash = None expected = [] while line and line != '\n': expected.append(line.rstrip('\n')) line = self.readline() nresult = len(expected) if not skipping: result1, result2 = self.exec_query('\n'.join(query), columns, sorting, pyscript, hashlabel, nresult, hash, expected, conn=conn) self.writeline(' '.join(result1)) for line in query: self.writeline(line) self.writeline('----') for line in result2: self.writeline(line) else: self.writeline(qrline) for line in query: self.writeline(line) self.writeline('----') if hash: self.writeline('{} values hashing to {}'.format( nresult, hash)) else: for line in expected: self.writeline(line) self.writeline()
def exec_statement(self, statement, expectok, err_stmt=None, expected_err_code=None, expected_err_msg=None, expected_rowcount=None, conn=None): crs = conn.cursor() if conn else self.crs if skipidx.search(statement) is not None: # skip creation of ascending or descending index return ['statement', 'ok'] try: affected_rowcount = crs.execute(statement) except (pymonetdb.Error, ValueError) as e: msg = e.args[0] if not expectok: result = ['statement', 'error'] if expected_err_code or expected_err_msg: # check whether failed as expected err_code_received, err_msg_received = utils.parse_mapi_err_msg( msg) if expected_err_code and expected_err_msg: result.append(err_code_received + '!' + err_msg_received) if expected_err_code == err_code_received and expected_err_msg.lower( ) == err_msg_received.lower(): return result else: if expected_err_code: result.append(err_code_received + '!') if expected_err_code == err_code_received: return result if expected_err_msg: result.append(err_msg_received) if expected_err_msg.lower( ) == err_msg_received.lower(): return result msg = "statement was expected to fail with" \ + (" error code {}".format(expected_err_code) if expected_err_code else '')\ + (", error message {}".format(str(expected_err_msg)) if expected_err_msg else '') self.query_error(err_stmt or statement, str(msg), str(e)) return result except ConnectionError as e: self.query_error(err_stmt or statement, 'Server may have crashed', str(e)) return ['statenent', 'crash'] # should never be approved else: result = ['statement', 'ok'] if expectok: if expected_rowcount: result.append('rowcount') result.append('{}'.format(affected_rowcount)) if expected_rowcount != affected_rowcount: self.query_error( err_stmt or statement, "statement was expecting to succeed with {} rows but received {} rows!" .format(expected_rowcount, affected_rowcount)) return result msg = None self.query_error( err_stmt or statement, expectok and "statement was expected to succeed but didn't" or "statement was expected to fail but didn't", msg) return ['statement', 'error']