mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 10:30:33 +03:00 
			
		
		
		
	Fix parsetree representation of XMLTABLE(XMLNAMESPACES(DEFAULT ...)).
The original coding for XMLTABLE thought it could represent a default namespace by a T_String Value node with a null string pointer. That's not okay, though; in particular outfuncs.c/readfuncs.c are not on board with such a representation, meaning you'll get a null pointer crash if you try to store a view or rule containing this construct. To fix, change the parsetree representation so that we have a NULL list element, instead of a bogus Value node. This isn't really a functional limitation since default XML namespaces aren't yet implemented in the executor; you'd just get "DEFAULT namespace is not supported" anyway. But crashes are not nice, so back-patch to v10 where this syntax was added. Ordinarily we'd consider a parsetree representation change to be un-backpatchable; but since existing releases would crash on the way to storing such constructs, there can't be any existing views/rules to be incompatible with. Per report from Andrey Lepikhov. Discussion: https://postgr.es/m/3690074f-abd2-56a9-144a-aa5545d7a291@postgrespro.ru
This commit is contained in:
		| @@ -779,7 +779,7 @@ transformRangeTableFunc(ParseState *pstate, RangeTableFunc *rtf) | ||||
| 	/* undef ordinality column number */ | ||||
| 	tf->ordinalitycol = -1; | ||||
|  | ||||
|  | ||||
| 	/* Process column specs */ | ||||
| 	names = palloc(sizeof(char *) * list_length(rtf->columns)); | ||||
|  | ||||
| 	colno = 0; | ||||
| @@ -900,15 +900,15 @@ transformRangeTableFunc(ParseState *pstate, RangeTableFunc *rtf) | ||||
| 			{ | ||||
| 				foreach(lc2, ns_names) | ||||
| 				{ | ||||
| 					char	   *name = strVal(lfirst(lc2)); | ||||
| 					Value	   *ns_node = (Value *) lfirst(lc2); | ||||
|  | ||||
| 					if (name == NULL) | ||||
| 					if (ns_node == NULL) | ||||
| 						continue; | ||||
| 					if (strcmp(name, r->name) == 0) | ||||
| 					if (strcmp(strVal(ns_node), r->name) == 0) | ||||
| 						ereport(ERROR, | ||||
| 								(errcode(ERRCODE_SYNTAX_ERROR), | ||||
| 								 errmsg("namespace name \"%s\" is not unique", | ||||
| 										name), | ||||
| 										r->name), | ||||
| 								 parser_errposition(pstate, r->location))); | ||||
| 				} | ||||
| 			} | ||||
| @@ -922,8 +922,9 @@ transformRangeTableFunc(ParseState *pstate, RangeTableFunc *rtf) | ||||
| 				default_ns_seen = true; | ||||
| 			} | ||||
|  | ||||
| 			/* Note the string may be NULL */ | ||||
| 			ns_names = lappend(ns_names, makeString(r->name)); | ||||
| 			/* We represent DEFAULT by a null pointer */ | ||||
| 			ns_names = lappend(ns_names, | ||||
| 							   r->name ? makeString(r->name) : NULL); | ||||
| 		} | ||||
|  | ||||
| 		tf->ns_uris = ns_uris; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user