查询可重复利用的外部表,只指定location、data format和error limit相同
# Fast path to find out whether we have an existing external table in the # catalog which could be reused for this operation. we only make sure the # location, data format and error limit are same. we don't check column # names and types # # This function will return the SQL to run in order to find out whether # such a table exists. The results of this SQl are table names without schema # def get_fast_match_exttable_query(self, formatType, formatOpts, limitStr, schemaName, log_errors, encodingCode): sqlFormat = """select relname from pg_class join pg_exttable pgext on(pg_class.oid = pgext.reloid) %s where relstorage = 'x' and relname like 'ext_gpload_reusable_%%' and %s """ joinStr = "" conditionStr = "" # if schemaName is None, find the resuable ext table which is visible to # current search path. Else find the resuable ext table under the specific # schema, and this needs to join pg_namespace. if schemaName is None: joinStr = "" conditionStr = "pg_table_is_visible(pg_class.oid)" else: joinStr = """join pg_namespace pgns on(pg_class.relnamespace = pgns.oid)""" conditionStr = "pgns.nspname = '%s'" % schemaName sql = sqlFormat % (joinStr, conditionStr) if self.gpdb_version < "6.0.0": if log_errors: sql += " and pgext.fmterrtbl = pgext.reloid " else: sql += " and pgext.fmterrtbl IS NULL " else: if log_errors: sql += " and pgext.logerrors " else: sql += " and NOT pgext.logerrors " for i, l in enumerate(self.locations): sql += " and pgext.urilocation[%s] = %s\n" % (i + 1, quote(l)) sql+= """and pgext.fmttype = %s and pgext.writable = false and pgext.fmtopts like %s """ % (quote(formatType[0]),quote("%" + quote_unident(formatOpts.rstrip()) +"%")) if limitStr: sql += "and pgext.rejectlimit = %s " % limitStr else: sql += "and pgext.rejectlimit IS NULL " if encodingCode: sql += "and pgext.encoding = %s " % encodingCode sql+= "limit 1;" self.log(self.DEBUG, "query used to fast match external relations:\n %s" % sql) return sql
查询可重复利用的外部表,指定column names and types, the same data format, and location specification, and single row error handling specs相同
def get_reuse_exttable_query(self, formatType, formatOpts, limitStr, from_cols, schemaName, log_errors, encodingCode): sqlFormat = """select attrelid::regclass from ( select attrelid, row_number() over (partition by attrelid order by attnum) as attord, attnum, attname, atttypid::regtype from pg_attribute join pg_class on (pg_class.oid = attrelid) %s where relstorage = 'x' and relname like 'ext_gpload_reusable_%%' and attnum > 0 and not attisdropped and %s ) pgattr join pg_exttable pgext on(pgattr.attrelid = pgext.reloid) """ joinStr = "" conditionStr = "" # if schemaName is None, find the resuable ext table which is visible to # current search path. Else find the resuable ext table under the specific # schema, and this needs to join pg_namespace. if schemaName is None: joinStr = "" conditionStr = "pg_table_is_visible(pg_class.oid)" else: joinStr = """join pg_namespace pgns on(pg_class.relnamespace = pgns.oid) """ conditionStr = "pgns.nspname = '%s'" % schemaName sql = sqlFormat % (joinStr, conditionStr) if self.gpdb_version < "6.0.0": if log_errors: sql += " WHERE pgext.fmterrtbl = pgext.reloid " else: sql += " WHERE pgext.fmterrtbl IS NULL " else: if log_errors: sql += " WHERE pgext.logerrors " else: sql += " WHERE NOT pgext.logerrors " for i, l in enumerate(self.locations): sql += " and pgext.urilocation[%s] = %s\n" % (i + 1, quote(l)) sql+= """and pgext.fmttype = %s and pgext.writable = false and pgext.fmtopts like %s """ % (quote(formatType[0]),quote("%" + quote_unident(formatOpts.rstrip()) +"%")) if limitStr: sql += "and pgext.rejectlimit = %s " % limitStr else: sql += "and pgext.rejectlimit IS NULL " if encodingCode: sql += "and pgext.encoding = %s " % encodingCode sql+= "group by attrelid " sql+= """having count(*) = %s and bool_and(case """ % len(from_cols) for i, c in enumerate(from_cols): name = c[0] typ = c[1] sql+= "when attord = %s then atttypid = %s::regtype and attname = %s\n" % (i+1, quote(typ), quote(quote_unident(name))) sql+= """else true end) limit 1;""" self.log(self.DEBUG, "query used to identify reusable external relations: %s" % sql) return sql