Rewriting some query crafting parts (especially those .find(' FROM '))

This commit is contained in:
Miroslav Stampar 2013-01-21 16:15:38 +01:00
parent 832d95984c
commit 1e3f68c7ff

View File

@ -17,6 +17,8 @@ from lib.core.common import randomInt
from lib.core.common import randomStr from lib.core.common import randomStr
from lib.core.common import safeSQLIdentificatorNaming from lib.core.common import safeSQLIdentificatorNaming
from lib.core.common import singleTimeWarnMessage from lib.core.common import singleTimeWarnMessage
from lib.core.common import unArrayizeValue
from lib.core.common import zeroDepthSearch
from lib.core.data import conf from lib.core.data import conf
from lib.core.data import kb from lib.core.data import kb
from lib.core.data import queries from lib.core.data import queries
@ -384,15 +386,7 @@ class Agent(object):
else: else:
fields = fields.replace(", ", ',') fields = fields.replace(", ", ',')
commas = [-1, len(fields)] commas = [-1, len(fields)]
depth = 0 commas.extend(zeroDepthSearch(fields, ','))
for index in xrange(len(fields)):
char = fields[index]
if char == '(':
depth += 1
elif char == ')':
depth -= 1
elif depth == 0 and char == ',':
commas.append(index)
commas = sorted(commas) commas = sorted(commas)
fieldsSplitted = [fields[x + 1:y] for (x, y) in zip(commas, commas[1:])] fieldsSplitted = [fields[x + 1:y] for (x, y) in zip(commas, commas[1:])]
dbmsDelimiter = queries[Backend.getIdentifiedDbms()].delimiter.query dbmsDelimiter = queries[Backend.getIdentifiedDbms()].delimiter.query
@ -423,15 +417,15 @@ class Agent(object):
@rtype: C{str} @rtype: C{str}
""" """
prefixRegex = "(?:\s+(?:FIRST|SKIP)\s+\d+)*" prefixRegex = r"(?:\s+(?:FIRST|SKIP)\s+\d+)*"
fieldsSelectTop = re.search("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", query, re.I) fieldsSelectTop = re.search(r"\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", query, re.I)
fieldsSelectDistinct = re.search("\ASELECT%s\s+DISTINCT\((.+?)\)\s+FROM" % prefixRegex, query, re.I) fieldsSelectDistinct = re.search(r"\ASELECT%s\s+DISTINCT\((.+?)\)\s+FROM" % prefixRegex, query, re.I)
fieldsSelectCase = re.search("\ASELECT%s\s+(\(CASE WHEN\s+.+\s+END\))" % prefixRegex, query, re.I) fieldsSelectCase = re.search(r"\ASELECT%s\s+(\(CASE WHEN\s+.+\s+END\))" % prefixRegex, query, re.I)
fieldsSelectFrom = re.search("\ASELECT%s\s+(.+?)\s+FROM\s+" % prefixRegex, query, re.I) fieldsSelectFrom = re.search(r"\ASELECT%s\s+(.+?)\s+FROM " % prefixRegex, query, re.I)
fieldsExists = re.search("EXISTS(.*)", query, re.I) fieldsExists = re.search(r"EXISTS\(([^)]*)\)\Z", query, re.I)
fieldsSelect = re.search("\ASELECT%s\s+(.*)" % prefixRegex, query, re.I) fieldsSelect = re.search(r"\ASELECT%s\s+(.*)" % prefixRegex, query, re.I)
fieldsSubstr = re.search("\A(SUBSTR|MID\()", query, re.I) fieldsSubstr = re.search(r"\A(SUBSTR|MID\()", query, re.I)
fieldsMinMaxstr = re.search("(?:MIN|MAX)\(([^\(\)]+)\)", query, re.I) fieldsMinMaxstr = re.search(r"(?:MIN|MAX)\(([^\(\)]+)\)", query, re.I)
fieldsNoSelect = query fieldsNoSelect = query
if fieldsSubstr: if fieldsSubstr:
@ -447,7 +441,9 @@ class Agent(object):
elif fieldsSelectCase: elif fieldsSelectCase:
fieldsToCastStr = fieldsSelectCase.groups()[0] fieldsToCastStr = fieldsSelectCase.groups()[0]
elif fieldsSelectFrom: elif fieldsSelectFrom:
fieldsToCastStr = fieldsSelectFrom.groups()[0] _ = zeroDepthSearch(query, " FROM ")
fieldsToCastStr = query[:unArrayizeValue(_)] if _ else query
fieldsToCastStr = re.sub(r"\ASELECT\s+", "", fieldsToCastStr)
elif fieldsSelect: elif fieldsSelect:
fieldsToCastStr = fieldsSelect.groups()[0] fieldsToCastStr = fieldsSelect.groups()[0]
else: else:
@ -528,8 +524,8 @@ class Agent(object):
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.chars.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.chars.start, 1)
concatenatedQuery += ",'%s')" % kb.chars.stop concatenatedQuery += ",'%s')" % kb.chars.stop
elif fieldsSelectFrom: elif fieldsSelectFrom:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.chars.start, 1) _ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM "))
concatenatedQuery = concatenatedQuery.replace(" FROM ", ",'%s') FROM " % kb.chars.stop, 1) concatenatedQuery = "%s,'%s')%s" % (concatenatedQuery[:_].replace("SELECT ", "CONCAT('%s'," % kb.chars.start, 1), kb.chars.stop, concatenatedQuery[_:])
elif fieldsSelect: elif fieldsSelect:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.chars.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % kb.chars.start, 1)
concatenatedQuery += ",'%s')" % kb.chars.stop concatenatedQuery += ",'%s')" % kb.chars.stop
@ -545,7 +541,8 @@ class Agent(object):
concatenatedQuery += ")||'%s'" % kb.chars.stop concatenatedQuery += ")||'%s'" % kb.chars.stop
elif fieldsSelectFrom: elif fieldsSelectFrom:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
concatenatedQuery = concatenatedQuery.replace(" FROM ", "||'%s' FROM " % kb.chars.stop, 1) _ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM "))
concatenatedQuery = "%s||'%s'%s" % (concatenatedQuery[:_], kb.chars.stop, concatenatedQuery[_:])
elif fieldsSelect: elif fieldsSelect:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
concatenatedQuery += "||'%s'" % kb.chars.stop concatenatedQuery += "||'%s'" % kb.chars.stop
@ -565,7 +562,8 @@ class Agent(object):
concatenatedQuery += "+'%s'" % kb.chars.stop concatenatedQuery += "+'%s'" % kb.chars.stop
elif fieldsSelectFrom: elif fieldsSelectFrom:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.chars.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.chars.start, 1)
concatenatedQuery = concatenatedQuery.replace(" FROM ", "+'%s' FROM " % kb.chars.stop, 1) _ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM "))
concatenatedQuery = "%s+'%s'%s" % (concatenatedQuery[:_], kb.chars.stop, concatenatedQuery[_:])
elif fieldsSelect: elif fieldsSelect:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.chars.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % kb.chars.start, 1)
concatenatedQuery += "+'%s'" % kb.chars.stop concatenatedQuery += "+'%s'" % kb.chars.stop
@ -581,7 +579,8 @@ class Agent(object):
concatenatedQuery += ")&'%s'" % kb.chars.stop concatenatedQuery += ")&'%s'" % kb.chars.stop
elif fieldsSelectFrom: elif fieldsSelectFrom:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'&" % kb.chars.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'&" % kb.chars.start, 1)
concatenatedQuery = concatenatedQuery.replace(" FROM ", "&'%s' FROM " % kb.chars.stop, 1) _ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM "))
concatenatedQuery = "%s&'%s'%s" % (concatenatedQuery[:_], kb.chars.stop, concatenatedQuery[_:])
elif fieldsSelect: elif fieldsSelect:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'&" % kb.chars.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'&" % kb.chars.start, 1)
concatenatedQuery += "&'%s'" % kb.chars.stop concatenatedQuery += "&'%s'" % kb.chars.stop
@ -600,7 +599,8 @@ class Agent(object):
concatenatedQuery += ")||'%s'" % kb.chars.stop concatenatedQuery += ")||'%s'" % kb.chars.stop
elif fieldsSelectFrom: elif fieldsSelectFrom:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
concatenatedQuery = concatenatedQuery.replace(" FROM ", "||'%s' FROM " % kb.chars.stop, 1) _ = unArrayizeValue(zeroDepthSearch(concatenatedQuery, " FROM "))
concatenatedQuery = "%s||'%s'%s" % (concatenatedQuery[:_], kb.chars.stop, concatenatedQuery[_:])
elif fieldsSelect: elif fieldsSelect:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1) concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % kb.chars.start, 1)
concatenatedQuery += "||'%s'" % kb.chars.stop concatenatedQuery += "||'%s'" % kb.chars.stop
@ -653,6 +653,13 @@ class Agent(object):
unionQuery = self.suffixQuery(unionQuery, comment, suffix) unionQuery = self.suffixQuery(unionQuery, comment, suffix)
return unionQuery return unionQuery
else:
_ = zeroDepthSearch(query, " FROM ")
if _:
fromTable = query[_[0]:]
if fromTable and query.endswith(fromTable):
query = query[:-len(fromTable)]
topNumRegex = re.search("\ATOP\s+([\d]+)\s+", query, re.I) topNumRegex = re.search("\ATOP\s+([\d]+)\s+", query, re.I)
if topNumRegex: if topNumRegex:
@ -666,29 +673,17 @@ class Agent(object):
intoRegExp = intoRegExp.group(1) intoRegExp = intoRegExp.group(1)
query = query[:query.index(intoRegExp)] query = query[:query.index(intoRegExp)]
if fromTable and unionQuery.endswith(fromTable):
unionQuery = unionQuery[:-len(fromTable)]
for element in xrange(0, count): for element in xrange(0, count):
if element > 0: if element > 0:
unionQuery += ',' unionQuery += ','
if element == position: if element == position:
if " FROM " in query and ("(CASE " not in query or ("(CASE " in query and "WHEN use" in query)) and "EXISTS(" not in query and not query.startswith("SELECT "): unionQuery += query
conditionIndex = query.index(" FROM ")
unionQuery += query[:conditionIndex]
else:
unionQuery += query
else: else:
unionQuery += char unionQuery += char
if " FROM " in query and ("(CASE " not in query or ("(CASE " in query and "WHEN use" in query)) and "EXISTS(" not in query and not query.startswith("SELECT "): if fromTable and not unionQuery.endswith(fromTable):
conditionIndex = query.index(" FROM ") unionQuery += fromTable
unionQuery += query[conditionIndex:]
if fromTable:
if " FROM " not in unionQuery or "(CASE " in unionQuery or "(IIF" in unionQuery:
unionQuery += fromTable
if intoRegExp: if intoRegExp:
unionQuery += intoRegExp unionQuery += intoRegExp