0

I have a SQL string, for example

SELECT * FROM benchmark WHERE xversion = 1.0

And actually, xversion is aliased variable, and self.alias has all the alias info something like

{'CompilationParameters_Family': 'chip_name', 
 'xversion': 'CompilationParameters_XilinxVersion', 'opt_param':  
  ....
 'chip_name': 'CompilationParameters_Family', 
 'CompilationParameters_Device': 'device'}

Using this alias, I should change the string into as follows.

SELECT * FROM benchmark WHERE CompilationParameters_XilinxVersion = 1.0

For this change, I came up with the following.

def processAliasString(self, sqlString):
    components = sqlString.split(' ')
    resList = []
    for comp in components:
        if comp in self.alias:
            resList.append(self.alias[comp])
        else:
            resList.append(comp)
    resString = " ".join(resList)
    return resString

But, I expect better code not using for loop. What do you think?

1
  • I can see one potential weakness in your code. Think about what happens if self.alias is say, like this: {'SELECT': 'DROP', '*': 'TABLE', 'FROM': '', 'WHERE': ';--' }. Commented Sep 13, 2010 at 2:45

2 Answers 2

1

If you could change your input string's format to make the replacements more clearly visible, e.g.

s = 'SELECT * FROM benchmark WHERE %(xversion)s = 1.0'

then s % self.alias would suffice (there are some other alternatives available depending on your favorite formatting syntax and Python level).

If the input string format is "nailed down", re can help because of the ease it offers to identify word boundaries (so you won't e.g. unexpectedly miss a replacement if an otherwise insignificant space is missing, for example after xversion). Consider (with s having its original form, with substitutables mixed in haphazardly with non-substitutables):

import re
sre = re.compile('|'.join(r'\b%s\b' % re.escape(s) for s in self.alias))
def repl(mo):
    return self.alias[mo.group()]
news = sre.sub(repl, s)

These approaches are fast, since %-formatting and res' sub are really well optimized for such tasks.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the wonderful tip. Unfortunately, the user gives me SQL command, so to use your code, I should parse to know exactly which part of the string should be modified, which is practically impossible now.
@prosseek, you can, however, use the re-based code in the second part of my answer (without risks from missing insignificant spaces, as would be with a .split()-based approach).
1

This should do it:

def processAliasString(self, sqlString):
    return ' '.join(self.alias.get(comp, comp) for comp in sqlString.split(' '))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.